@sylphx/sdk 0.10.7 → 0.11.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 +6 -0
- package/dist/health/index.d.ts +681 -0
- package/dist/health/index.mjs.map +1 -1
- package/dist/index.d.ts +64 -98
- package/dist/index.mjs +16 -15
- package/dist/index.mjs.map +1 -1
- package/dist/nextjs/index.d.ts +19 -0
- package/dist/nextjs/index.mjs +52 -12
- package/dist/nextjs/index.mjs.map +1 -1
- package/dist/react/index.d.ts +6 -10
- package/dist/react/index.mjs +4 -4
- package/dist/react/index.mjs.map +1 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.mjs.map +1 -1
- package/dist/web-analytics.d.ts +90 -0
- package/package.json +4 -4
package/dist/nextjs/index.d.ts
CHANGED
|
@@ -116,6 +116,25 @@ interface SylphxMiddlewareConfig {
|
|
|
116
116
|
* @default process.env.SYLPHX_SECRET_URL
|
|
117
117
|
*/
|
|
118
118
|
secretUrl?: string;
|
|
119
|
+
/**
|
|
120
|
+
* Publishable key for browser-safe auth routes.
|
|
121
|
+
*
|
|
122
|
+
* Public auth handlers (`/auth/login`, `/auth/oauth-providers`,
|
|
123
|
+
* `/auth/oauth/authorize`, password reset, passkeys) call runtime routes
|
|
124
|
+
* guarded by projectAuth, which accepts pk_* only.
|
|
125
|
+
*
|
|
126
|
+
* @default credential parsed from process.env.SYLPHX_URL or
|
|
127
|
+
* process.env.NEXT_PUBLIC_SYLPHX_URL
|
|
128
|
+
*/
|
|
129
|
+
publishableKey?: string;
|
|
130
|
+
/**
|
|
131
|
+
* Public connection URL for browser-safe auth routes.
|
|
132
|
+
*
|
|
133
|
+
* Format: sylphx://pk_<env>_<hex>@<tenant>.api.sylphx.com
|
|
134
|
+
*
|
|
135
|
+
* @default process.env.SYLPHX_URL or process.env.NEXT_PUBLIC_SYLPHX_URL
|
|
136
|
+
*/
|
|
137
|
+
publicUrl?: string;
|
|
119
138
|
/**
|
|
120
139
|
* Platform URL for API calls.
|
|
121
140
|
* Override for self-hosted or same-origin deployments.
|
package/dist/nextjs/index.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { NextResponse } from "next/server";
|
|
|
3
3
|
|
|
4
4
|
// src/constants.ts
|
|
5
5
|
var ENV_URL = "SYLPHX_URL";
|
|
6
|
+
var ENV_PUBLIC_URL = "NEXT_PUBLIC_SYLPHX_URL";
|
|
6
7
|
var ENV_SECRET_URL = "SYLPHX_SECRET_URL";
|
|
7
8
|
var DEFAULT_SDK_API_HOST = "api.sylphx.com";
|
|
8
9
|
var SDK_PLATFORM = typeof window !== "undefined" ? "browser" : typeof process !== "undefined" && process.versions?.node ? "node" : "unknown";
|
|
@@ -127,6 +128,12 @@ function validateKeyForType(key, keyType, pattern, envVarName) {
|
|
|
127
128
|
function validatePublicKey(key) {
|
|
128
129
|
return validateKeyForType(key, "publicKey", PUBLIC_KEY_PATTERN, "publishable credential");
|
|
129
130
|
}
|
|
131
|
+
function validateAndSanitizePublicKey(key) {
|
|
132
|
+
const result = validatePublicKey(key);
|
|
133
|
+
if (!result.valid) throw new Error(result.error);
|
|
134
|
+
if (result.warning) console.warn(result.warning);
|
|
135
|
+
return result.sanitizedKey;
|
|
136
|
+
}
|
|
130
137
|
function validateAppId(key) {
|
|
131
138
|
return validateKeyForType(key, "appId", APP_ID_PATTERN, "NEXT_PUBLIC_SYLPHX_APP_ID");
|
|
132
139
|
}
|
|
@@ -427,6 +434,11 @@ function secretKeyFromConnectionUrl(value) {
|
|
|
427
434
|
if (!parsed || parsed.credentialType !== "sk") return null;
|
|
428
435
|
return parsed.credential;
|
|
429
436
|
}
|
|
437
|
+
function publishableKeyFromConnectionUrl(value) {
|
|
438
|
+
const parsed = parseConnection(value);
|
|
439
|
+
if (!parsed || parsed.credentialType !== "pk") return null;
|
|
440
|
+
return parsed.credential;
|
|
441
|
+
}
|
|
430
442
|
function resolveNextjsPlatformUrl(options) {
|
|
431
443
|
if (options.explicitPlatformUrl) return normalizePlatformUrl(options.explicitPlatformUrl);
|
|
432
444
|
const fromExplicitSecretUrl = platformUrlFromConnectionUrl(options.secretUrl);
|
|
@@ -451,6 +463,16 @@ function resolveNextjsSecretKey(options) {
|
|
|
451
463
|
if (fromGenericUrl) return fromGenericUrl;
|
|
452
464
|
return null;
|
|
453
465
|
}
|
|
466
|
+
function resolveNextjsPublishableKey(options) {
|
|
467
|
+
if (options.explicitPublishableKey?.trim()) return options.explicitPublishableKey.trim();
|
|
468
|
+
const fromExplicitPublicUrl = publishableKeyFromConnectionUrl(options.explicitPublicUrl);
|
|
469
|
+
if (fromExplicitPublicUrl) return fromExplicitPublicUrl;
|
|
470
|
+
const fromPublicUrl = publishableKeyFromConnectionUrl(process.env[ENV_URL]);
|
|
471
|
+
if (fromPublicUrl) return fromPublicUrl;
|
|
472
|
+
const fromNextPublicUrl = publishableKeyFromConnectionUrl(process.env[ENV_PUBLIC_URL]);
|
|
473
|
+
if (fromNextPublicUrl) return fromNextPublicUrl;
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
454
476
|
|
|
455
477
|
// src/nextjs/middleware.ts
|
|
456
478
|
var OAUTH_PKCE_TTL_SECONDS = 10 * 60;
|
|
@@ -639,10 +661,10 @@ function authCookieJsonResponse(ctx, data) {
|
|
|
639
661
|
setAuthCookiesMiddleware(response, ctx.namespace, data);
|
|
640
662
|
return response;
|
|
641
663
|
}
|
|
642
|
-
function
|
|
664
|
+
function headersForProjectAuth(ctx) {
|
|
643
665
|
return {
|
|
644
666
|
"Content-Type": "application/json",
|
|
645
|
-
"x-app-secret": ctx.
|
|
667
|
+
"x-app-secret": ctx.publishableKey
|
|
646
668
|
};
|
|
647
669
|
}
|
|
648
670
|
async function handleRegister(request, ctx) {
|
|
@@ -652,7 +674,7 @@ async function handleRegister(request, ctx) {
|
|
|
652
674
|
const body = await parseJsonObject(request);
|
|
653
675
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/register`, {
|
|
654
676
|
method: "POST",
|
|
655
|
-
headers:
|
|
677
|
+
headers: headersForProjectAuth(ctx),
|
|
656
678
|
body: JSON.stringify(body ?? {})
|
|
657
679
|
});
|
|
658
680
|
const data = await res.json().catch(() => ({}));
|
|
@@ -670,7 +692,7 @@ async function handleLogin(request, ctx) {
|
|
|
670
692
|
}
|
|
671
693
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/login`, {
|
|
672
694
|
method: "POST",
|
|
673
|
-
headers:
|
|
695
|
+
headers: headersForProjectAuth(ctx),
|
|
674
696
|
body: JSON.stringify({ email, password })
|
|
675
697
|
});
|
|
676
698
|
const data = await res.json().catch(() => ({}));
|
|
@@ -696,7 +718,7 @@ async function handleVerifyEmail(request, ctx) {
|
|
|
696
718
|
}
|
|
697
719
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/verify-email`, {
|
|
698
720
|
method: "POST",
|
|
699
|
-
headers:
|
|
721
|
+
headers: headersForProjectAuth(ctx),
|
|
700
722
|
body: JSON.stringify({ token })
|
|
701
723
|
});
|
|
702
724
|
const data = await res.json().catch(() => ({}));
|
|
@@ -714,7 +736,7 @@ async function handleVerifyTwoFactor(request, ctx) {
|
|
|
714
736
|
}
|
|
715
737
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/verify-2fa`, {
|
|
716
738
|
method: "POST",
|
|
717
|
-
headers:
|
|
739
|
+
headers: headersForProjectAuth(ctx),
|
|
718
740
|
body: JSON.stringify({ userId, code })
|
|
719
741
|
});
|
|
720
742
|
const data = await res.json().catch(() => ({}));
|
|
@@ -759,7 +781,7 @@ function handleSession(request, ctx) {
|
|
|
759
781
|
async function handleOAuthProviders(ctx) {
|
|
760
782
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/oauth-providers`, {
|
|
761
783
|
method: "GET",
|
|
762
|
-
headers:
|
|
784
|
+
headers: headersForProjectAuth(ctx)
|
|
763
785
|
});
|
|
764
786
|
const data = await res.json().catch(() => ({}));
|
|
765
787
|
return NextResponse.json(data, { status: res.status });
|
|
@@ -782,7 +804,7 @@ async function handleOAuthAuthorize(request, ctx) {
|
|
|
782
804
|
const scopes = Array.isArray(body?.scopes) ? body.scopes.filter((scope) => typeof scope === "string") : void 0;
|
|
783
805
|
const res = await fetch(`${ctx.platformUrl}/v1/oauth/authorize`, {
|
|
784
806
|
method: "POST",
|
|
785
|
-
headers:
|
|
807
|
+
headers: headersForProjectAuth(ctx),
|
|
786
808
|
body: JSON.stringify({
|
|
787
809
|
provider,
|
|
788
810
|
redirect_uri: redirectUri.toString(),
|
|
@@ -811,7 +833,7 @@ async function handlePasskeyOptions(request, ctx) {
|
|
|
811
833
|
const body = await parseJsonObject(request);
|
|
812
834
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/passkey/options`, {
|
|
813
835
|
method: "POST",
|
|
814
|
-
headers:
|
|
836
|
+
headers: headersForProjectAuth(ctx),
|
|
815
837
|
body: JSON.stringify(body ?? {})
|
|
816
838
|
});
|
|
817
839
|
const data = await res.json().catch(() => ({}));
|
|
@@ -824,7 +846,7 @@ async function handlePasskeyAuthenticate(request, ctx) {
|
|
|
824
846
|
const body = await parseJsonObject(request);
|
|
825
847
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/passkey/authenticate`, {
|
|
826
848
|
method: "POST",
|
|
827
|
-
headers:
|
|
849
|
+
headers: headersForProjectAuth(ctx),
|
|
828
850
|
body: JSON.stringify(body ?? {})
|
|
829
851
|
});
|
|
830
852
|
const data = await res.json().catch(() => ({}));
|
|
@@ -852,7 +874,7 @@ async function handleForgotPassword(request, ctx) {
|
|
|
852
874
|
}
|
|
853
875
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/forgot-password`, {
|
|
854
876
|
method: "POST",
|
|
855
|
-
headers:
|
|
877
|
+
headers: headersForProjectAuth(ctx),
|
|
856
878
|
body: JSON.stringify({ email, redirectUrl })
|
|
857
879
|
});
|
|
858
880
|
const data = await res.json().catch(() => ({}));
|
|
@@ -870,7 +892,7 @@ async function handleResetPassword(request, ctx) {
|
|
|
870
892
|
}
|
|
871
893
|
const res = await fetch(`${ctx.platformUrl}/v1/auth/reset-password`, {
|
|
872
894
|
method: "POST",
|
|
873
|
-
headers:
|
|
895
|
+
headers: headersForProjectAuth(ctx),
|
|
874
896
|
body: JSON.stringify({ token, password })
|
|
875
897
|
});
|
|
876
898
|
const data = await res.json().catch(() => ({}));
|
|
@@ -1281,6 +1303,21 @@ function createSylphxMiddleware(userConfig = {}) {
|
|
|
1281
1303
|
secretKey = validateAndSanitizeSecretKey(rawSecretKey);
|
|
1282
1304
|
return secretKey;
|
|
1283
1305
|
}
|
|
1306
|
+
let publishableKey = null;
|
|
1307
|
+
function resolvePublishableKey() {
|
|
1308
|
+
if (publishableKey) return publishableKey;
|
|
1309
|
+
const rawPublishableKey = resolveNextjsPublishableKey({
|
|
1310
|
+
explicitPublishableKey: userConfig.publishableKey,
|
|
1311
|
+
explicitPublicUrl: userConfig.publicUrl
|
|
1312
|
+
});
|
|
1313
|
+
if (!rawPublishableKey) {
|
|
1314
|
+
throw new Error(
|
|
1315
|
+
"[Sylphx] Publishable connection URL is required for public auth routes.\nEither pass publicUrl/publishableKey in config or set SYLPHX_URL/NEXT_PUBLIC_SYLPHX_URL."
|
|
1316
|
+
);
|
|
1317
|
+
}
|
|
1318
|
+
publishableKey = validateAndSanitizePublicKey(rawPublishableKey);
|
|
1319
|
+
return publishableKey;
|
|
1320
|
+
}
|
|
1284
1321
|
let platformUrl;
|
|
1285
1322
|
let namespace;
|
|
1286
1323
|
let cookieNames;
|
|
@@ -1328,6 +1365,9 @@ function createSylphxMiddleware(userConfig = {}) {
|
|
|
1328
1365
|
get secretKey() {
|
|
1329
1366
|
return secretKey;
|
|
1330
1367
|
},
|
|
1368
|
+
get publishableKey() {
|
|
1369
|
+
return resolvePublishableKey();
|
|
1370
|
+
},
|
|
1331
1371
|
get platformUrl() {
|
|
1332
1372
|
return platformUrl;
|
|
1333
1373
|
},
|