@sylphx/sdk 0.3.3 → 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 +73 -28
- package/dist/index.d.ts +73 -28
- package/dist/index.js +104 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +103 -14
- package/dist/index.mjs.map +1 -1
- package/dist/nextjs/index.d.cts +14 -11
- package/dist/nextjs/index.d.ts +14 -11
- package/dist/nextjs/index.js +55 -22
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/index.mjs +55 -22
- package/dist/nextjs/index.mjs.map +1 -1
- package/dist/react/index.d.cts +35 -37
- package/dist/react/index.d.ts +35 -37
- package/dist/react/index.js +110 -21
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +110 -21
- package/dist/react/index.mjs.map +1 -1
- package/dist/server/index.d.cts +35 -25
- package/dist/server/index.d.ts +35 -25
- package/dist/server/index.js +60 -23
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +60 -23
- package/dist/server/index.mjs.map +1 -1
- package/dist/web-analytics.js.map +1 -1
- package/dist/web-analytics.mjs.map +1 -1
- package/package.json +1 -1
package/dist/server/index.d.cts
CHANGED
|
@@ -18405,7 +18405,7 @@ interface components {
|
|
|
18405
18405
|
OrgInvitation: {
|
|
18406
18406
|
/**
|
|
18407
18407
|
* @description Invitation ID
|
|
18408
|
-
* @example
|
|
18408
|
+
* @example inv_3Zb83qVQxkHMJPZ8VrJfQ2
|
|
18409
18409
|
*/
|
|
18410
18410
|
id: string
|
|
18411
18411
|
/**
|
|
@@ -18475,7 +18475,7 @@ interface components {
|
|
|
18475
18475
|
/**
|
|
18476
18476
|
* Format: uuid
|
|
18477
18477
|
* @description Invitation token (ID)
|
|
18478
|
-
* @example
|
|
18478
|
+
* @example inv_3Zb83qVQxkHMJPZ8VrJfQ2
|
|
18479
18479
|
*/
|
|
18480
18480
|
token: string
|
|
18481
18481
|
}
|
|
@@ -19782,18 +19782,20 @@ interface AccessTokenPayload {
|
|
|
19782
19782
|
* 4. No silent fixes - Transparency over convenience (but warn + continue)
|
|
19783
19783
|
* 5. Single Source of Truth - All key logic in one place
|
|
19784
19784
|
*
|
|
19785
|
-
* Key Formats (
|
|
19786
|
-
* -
|
|
19787
|
-
* - Secret Key:
|
|
19785
|
+
* Key Formats (ADR-021):
|
|
19786
|
+
* - Publishable key: pk_(dev|stg|prod)_{ref}_{32hex} — client-safe (new)
|
|
19787
|
+
* - Secret Key: sk_(dev|stg|prod)_{ref}_{64hex} — server-side only
|
|
19788
19788
|
*
|
|
19789
|
-
*
|
|
19790
|
-
* -
|
|
19791
|
-
*
|
|
19789
|
+
* Legacy Key Formats (backward-compat):
|
|
19790
|
+
* - App ID (old): app_(dev|stg|prod)_[identifier] — Public identifier
|
|
19791
|
+
*
|
|
19792
|
+
* Special Internal Formats (NOT rotated):
|
|
19793
|
+
* - Console bootstrap: app_prod_platform_{slug} / sk_prod_platform_{slug}
|
|
19792
19794
|
*/
|
|
19793
19795
|
/** Environment type derived from key prefix */
|
|
19794
19796
|
type EnvironmentType = 'development' | 'staging' | 'production';
|
|
19795
|
-
/** Key type - appId (
|
|
19796
|
-
type KeyType = 'appId' | 'secret';
|
|
19797
|
+
/** Key type - publicKey (pk_*), appId (legacy app_*), or secret (sk_*) */
|
|
19798
|
+
type KeyType = 'publicKey' | 'appId' | 'secret';
|
|
19797
19799
|
/** Validation result with clear error information */
|
|
19798
19800
|
interface KeyValidationResult {
|
|
19799
19801
|
/** Whether the key is valid (possibly after sanitization) */
|
|
@@ -19812,7 +19814,9 @@ interface KeyValidationResult {
|
|
|
19812
19814
|
issues?: string[];
|
|
19813
19815
|
}
|
|
19814
19816
|
/**
|
|
19815
|
-
* Validate
|
|
19817
|
+
* Validate a legacy App ID (app_*) and return detailed results.
|
|
19818
|
+
*
|
|
19819
|
+
* @deprecated Use validatePublicKey() for new pk_* keys (ADR-021).
|
|
19816
19820
|
*
|
|
19817
19821
|
* @example
|
|
19818
19822
|
* ```typescript
|
|
@@ -19827,8 +19831,9 @@ interface KeyValidationResult {
|
|
|
19827
19831
|
*/
|
|
19828
19832
|
declare function validateAppId(key: string | undefined | null): KeyValidationResult;
|
|
19829
19833
|
/**
|
|
19830
|
-
* Validate and sanitize App ID, logging warnings
|
|
19834
|
+
* Validate and sanitize App ID, logging warnings.
|
|
19831
19835
|
*
|
|
19836
|
+
* @deprecated Use validateAndSanitizePublicKey() for new pk_* keys (ADR-021).
|
|
19832
19837
|
* @throws Error if the key is invalid and cannot be sanitized
|
|
19833
19838
|
* @returns The sanitized App ID
|
|
19834
19839
|
*/
|
|
@@ -19887,17 +19892,19 @@ declare function isProductionKey(key: string): boolean;
|
|
|
19887
19892
|
*/
|
|
19888
19893
|
declare function getCookieNamespace(secretKey: string): string;
|
|
19889
19894
|
/**
|
|
19890
|
-
* Detect the type of key
|
|
19895
|
+
* Detect the type of key.
|
|
19891
19896
|
*
|
|
19892
|
-
* @returns 'appId', 'secret', or null if unknown
|
|
19897
|
+
* @returns 'publicKey' (pk_*), 'appId' (legacy app_*), 'secret' (sk_*), or null if unknown
|
|
19893
19898
|
*/
|
|
19894
19899
|
declare function detectKeyType(key: string): KeyType | null;
|
|
19895
19900
|
/**
|
|
19896
|
-
* Check if a key is an App ID
|
|
19901
|
+
* Check if a key is an App ID (legacy app_* format)
|
|
19902
|
+
*
|
|
19903
|
+
* @deprecated Use isPublishableKey() to also accept new pk_* keys
|
|
19897
19904
|
*/
|
|
19898
19905
|
declare function isAppId(key: string): boolean;
|
|
19899
19906
|
/**
|
|
19900
|
-
* Check if a key is a secret key
|
|
19907
|
+
* Check if a key is a secret key (sk_*)
|
|
19901
19908
|
*/
|
|
19902
19909
|
declare function isSecretKey(key: string): boolean;
|
|
19903
19910
|
/**
|
|
@@ -19931,33 +19938,36 @@ declare function isDevelopmentRuntime(): boolean;
|
|
|
19931
19938
|
* Platform ID utilities for the Sylphx SDK
|
|
19932
19939
|
*
|
|
19933
19940
|
* Converts between raw UUIDs (used internally / in JWT sub claims) and
|
|
19934
|
-
* prefixed
|
|
19941
|
+
* prefixed TypeID strings (used in all API responses and JWT pid claims).
|
|
19942
|
+
*
|
|
19943
|
+
* Uses TypeID spec v0.3.0 (Crockford base32, case-insensitive).
|
|
19944
|
+
* Also accepts legacy base58 format for backward compatibility.
|
|
19935
19945
|
*
|
|
19936
|
-
*
|
|
19937
|
-
* No external dependencies — pure TypeScript.
|
|
19946
|
+
* No external dependencies — pure TypeScript implementation of Crockford base32.
|
|
19938
19947
|
*
|
|
19939
19948
|
* @example
|
|
19940
19949
|
* ```ts
|
|
19941
19950
|
* import { encodeUserId, decodeUserId } from '@sylphx/sdk/nextjs'
|
|
19942
19951
|
*
|
|
19943
19952
|
* const prefixed = encodeUserId('018f4a3b-1c2d-7000-9abc-def012345678')
|
|
19944
|
-
* // => '
|
|
19953
|
+
* // => 'user_01h2xcejqtf2nbrexx3vqjhp41'
|
|
19945
19954
|
*
|
|
19946
|
-
* const uuid = decodeUserId('
|
|
19955
|
+
* const uuid = decodeUserId('user_01h2xcejqtf2nbrexx3vqjhp41')
|
|
19947
19956
|
* // => '018f4a3b-1c2d-7000-9abc-def012345678'
|
|
19948
19957
|
* ```
|
|
19949
19958
|
*/
|
|
19950
19959
|
/**
|
|
19951
|
-
* Encode a raw UUID as a prefixed
|
|
19960
|
+
* Encode a raw UUID as a prefixed TypeID user ID.
|
|
19952
19961
|
*
|
|
19953
19962
|
* @param uuid - Raw UUID string (with or without dashes)
|
|
19954
|
-
* @returns Prefixed
|
|
19963
|
+
* @returns Prefixed TypeID: `user_<crockford_base32>`
|
|
19955
19964
|
*/
|
|
19956
19965
|
declare function encodeUserId(uuid: string): string;
|
|
19957
19966
|
/**
|
|
19958
|
-
* Decode a prefixed
|
|
19967
|
+
* Decode a prefixed user ID back to a raw UUID.
|
|
19968
|
+
* Accepts both TypeID (current) and base58 (legacy) formats.
|
|
19959
19969
|
*
|
|
19960
|
-
* @param prefixedId - Prefixed
|
|
19970
|
+
* @param prefixedId - Prefixed user ID: `user_<encoded>`
|
|
19961
19971
|
* @returns Raw UUID string, or null if invalid
|
|
19962
19972
|
*/
|
|
19963
19973
|
declare function decodeUserId(prefixedId: string): string | null;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -18405,7 +18405,7 @@ interface components {
|
|
|
18405
18405
|
OrgInvitation: {
|
|
18406
18406
|
/**
|
|
18407
18407
|
* @description Invitation ID
|
|
18408
|
-
* @example
|
|
18408
|
+
* @example inv_3Zb83qVQxkHMJPZ8VrJfQ2
|
|
18409
18409
|
*/
|
|
18410
18410
|
id: string
|
|
18411
18411
|
/**
|
|
@@ -18475,7 +18475,7 @@ interface components {
|
|
|
18475
18475
|
/**
|
|
18476
18476
|
* Format: uuid
|
|
18477
18477
|
* @description Invitation token (ID)
|
|
18478
|
-
* @example
|
|
18478
|
+
* @example inv_3Zb83qVQxkHMJPZ8VrJfQ2
|
|
18479
18479
|
*/
|
|
18480
18480
|
token: string
|
|
18481
18481
|
}
|
|
@@ -19782,18 +19782,20 @@ interface AccessTokenPayload {
|
|
|
19782
19782
|
* 4. No silent fixes - Transparency over convenience (but warn + continue)
|
|
19783
19783
|
* 5. Single Source of Truth - All key logic in one place
|
|
19784
19784
|
*
|
|
19785
|
-
* Key Formats (
|
|
19786
|
-
* -
|
|
19787
|
-
* - Secret Key:
|
|
19785
|
+
* Key Formats (ADR-021):
|
|
19786
|
+
* - Publishable key: pk_(dev|stg|prod)_{ref}_{32hex} — client-safe (new)
|
|
19787
|
+
* - Secret Key: sk_(dev|stg|prod)_{ref}_{64hex} — server-side only
|
|
19788
19788
|
*
|
|
19789
|
-
*
|
|
19790
|
-
* -
|
|
19791
|
-
*
|
|
19789
|
+
* Legacy Key Formats (backward-compat):
|
|
19790
|
+
* - App ID (old): app_(dev|stg|prod)_[identifier] — Public identifier
|
|
19791
|
+
*
|
|
19792
|
+
* Special Internal Formats (NOT rotated):
|
|
19793
|
+
* - Console bootstrap: app_prod_platform_{slug} / sk_prod_platform_{slug}
|
|
19792
19794
|
*/
|
|
19793
19795
|
/** Environment type derived from key prefix */
|
|
19794
19796
|
type EnvironmentType = 'development' | 'staging' | 'production';
|
|
19795
|
-
/** Key type - appId (
|
|
19796
|
-
type KeyType = 'appId' | 'secret';
|
|
19797
|
+
/** Key type - publicKey (pk_*), appId (legacy app_*), or secret (sk_*) */
|
|
19798
|
+
type KeyType = 'publicKey' | 'appId' | 'secret';
|
|
19797
19799
|
/** Validation result with clear error information */
|
|
19798
19800
|
interface KeyValidationResult {
|
|
19799
19801
|
/** Whether the key is valid (possibly after sanitization) */
|
|
@@ -19812,7 +19814,9 @@ interface KeyValidationResult {
|
|
|
19812
19814
|
issues?: string[];
|
|
19813
19815
|
}
|
|
19814
19816
|
/**
|
|
19815
|
-
* Validate
|
|
19817
|
+
* Validate a legacy App ID (app_*) and return detailed results.
|
|
19818
|
+
*
|
|
19819
|
+
* @deprecated Use validatePublicKey() for new pk_* keys (ADR-021).
|
|
19816
19820
|
*
|
|
19817
19821
|
* @example
|
|
19818
19822
|
* ```typescript
|
|
@@ -19827,8 +19831,9 @@ interface KeyValidationResult {
|
|
|
19827
19831
|
*/
|
|
19828
19832
|
declare function validateAppId(key: string | undefined | null): KeyValidationResult;
|
|
19829
19833
|
/**
|
|
19830
|
-
* Validate and sanitize App ID, logging warnings
|
|
19834
|
+
* Validate and sanitize App ID, logging warnings.
|
|
19831
19835
|
*
|
|
19836
|
+
* @deprecated Use validateAndSanitizePublicKey() for new pk_* keys (ADR-021).
|
|
19832
19837
|
* @throws Error if the key is invalid and cannot be sanitized
|
|
19833
19838
|
* @returns The sanitized App ID
|
|
19834
19839
|
*/
|
|
@@ -19887,17 +19892,19 @@ declare function isProductionKey(key: string): boolean;
|
|
|
19887
19892
|
*/
|
|
19888
19893
|
declare function getCookieNamespace(secretKey: string): string;
|
|
19889
19894
|
/**
|
|
19890
|
-
* Detect the type of key
|
|
19895
|
+
* Detect the type of key.
|
|
19891
19896
|
*
|
|
19892
|
-
* @returns 'appId', 'secret', or null if unknown
|
|
19897
|
+
* @returns 'publicKey' (pk_*), 'appId' (legacy app_*), 'secret' (sk_*), or null if unknown
|
|
19893
19898
|
*/
|
|
19894
19899
|
declare function detectKeyType(key: string): KeyType | null;
|
|
19895
19900
|
/**
|
|
19896
|
-
* Check if a key is an App ID
|
|
19901
|
+
* Check if a key is an App ID (legacy app_* format)
|
|
19902
|
+
*
|
|
19903
|
+
* @deprecated Use isPublishableKey() to also accept new pk_* keys
|
|
19897
19904
|
*/
|
|
19898
19905
|
declare function isAppId(key: string): boolean;
|
|
19899
19906
|
/**
|
|
19900
|
-
* Check if a key is a secret key
|
|
19907
|
+
* Check if a key is a secret key (sk_*)
|
|
19901
19908
|
*/
|
|
19902
19909
|
declare function isSecretKey(key: string): boolean;
|
|
19903
19910
|
/**
|
|
@@ -19931,33 +19938,36 @@ declare function isDevelopmentRuntime(): boolean;
|
|
|
19931
19938
|
* Platform ID utilities for the Sylphx SDK
|
|
19932
19939
|
*
|
|
19933
19940
|
* Converts between raw UUIDs (used internally / in JWT sub claims) and
|
|
19934
|
-
* prefixed
|
|
19941
|
+
* prefixed TypeID strings (used in all API responses and JWT pid claims).
|
|
19942
|
+
*
|
|
19943
|
+
* Uses TypeID spec v0.3.0 (Crockford base32, case-insensitive).
|
|
19944
|
+
* Also accepts legacy base58 format for backward compatibility.
|
|
19935
19945
|
*
|
|
19936
|
-
*
|
|
19937
|
-
* No external dependencies — pure TypeScript.
|
|
19946
|
+
* No external dependencies — pure TypeScript implementation of Crockford base32.
|
|
19938
19947
|
*
|
|
19939
19948
|
* @example
|
|
19940
19949
|
* ```ts
|
|
19941
19950
|
* import { encodeUserId, decodeUserId } from '@sylphx/sdk/nextjs'
|
|
19942
19951
|
*
|
|
19943
19952
|
* const prefixed = encodeUserId('018f4a3b-1c2d-7000-9abc-def012345678')
|
|
19944
|
-
* // => '
|
|
19953
|
+
* // => 'user_01h2xcejqtf2nbrexx3vqjhp41'
|
|
19945
19954
|
*
|
|
19946
|
-
* const uuid = decodeUserId('
|
|
19955
|
+
* const uuid = decodeUserId('user_01h2xcejqtf2nbrexx3vqjhp41')
|
|
19947
19956
|
* // => '018f4a3b-1c2d-7000-9abc-def012345678'
|
|
19948
19957
|
* ```
|
|
19949
19958
|
*/
|
|
19950
19959
|
/**
|
|
19951
|
-
* Encode a raw UUID as a prefixed
|
|
19960
|
+
* Encode a raw UUID as a prefixed TypeID user ID.
|
|
19952
19961
|
*
|
|
19953
19962
|
* @param uuid - Raw UUID string (with or without dashes)
|
|
19954
|
-
* @returns Prefixed
|
|
19963
|
+
* @returns Prefixed TypeID: `user_<crockford_base32>`
|
|
19955
19964
|
*/
|
|
19956
19965
|
declare function encodeUserId(uuid: string): string;
|
|
19957
19966
|
/**
|
|
19958
|
-
* Decode a prefixed
|
|
19967
|
+
* Decode a prefixed user ID back to a raw UUID.
|
|
19968
|
+
* Accepts both TypeID (current) and base58 (legacy) formats.
|
|
19959
19969
|
*
|
|
19960
|
-
* @param prefixedId - Prefixed
|
|
19970
|
+
* @param prefixedId - Prefixed user ID: `user_<encoded>`
|
|
19961
19971
|
* @returns Raw UUID string, or null if invalid
|
|
19962
19972
|
*/
|
|
19963
19973
|
declare function decodeUserId(prefixedId: string): string | null;
|
package/dist/server/index.js
CHANGED
|
@@ -1413,6 +1413,7 @@ function exponentialBackoff(attempt, baseDelay = BASE_RETRY_DELAY_MS, maxDelay =
|
|
|
1413
1413
|
}
|
|
1414
1414
|
|
|
1415
1415
|
// src/key-validation.ts
|
|
1416
|
+
var PUBLIC_KEY_PATTERN = /^pk_(dev|stg|prod)_[a-z0-9]{12}_[a-f0-9]{32}$/;
|
|
1416
1417
|
var APP_ID_PATTERN = /^app_(dev|stg|prod)_[a-z0-9_-]+$/;
|
|
1417
1418
|
var SECRET_KEY_PATTERN = /^sk_(dev|stg|prod)_[a-z0-9_-]+$/;
|
|
1418
1419
|
var ENV_PREFIX_MAP = {
|
|
@@ -1503,6 +1504,9 @@ function validateKeyForType(key, keyType, pattern, envVarName) {
|
|
|
1503
1504
|
issues: [...issues, "invalid-format"]
|
|
1504
1505
|
};
|
|
1505
1506
|
}
|
|
1507
|
+
function validatePublicKey(key) {
|
|
1508
|
+
return validateKeyForType(key, "publicKey", PUBLIC_KEY_PATTERN, "NEXT_PUBLIC_SYLPHX_KEY");
|
|
1509
|
+
}
|
|
1506
1510
|
function validateAppId(key) {
|
|
1507
1511
|
return validateKeyForType(key, "appId", APP_ID_PATTERN, "NEXT_PUBLIC_SYLPHX_APP_ID");
|
|
1508
1512
|
}
|
|
@@ -1531,22 +1535,23 @@ function validateAndSanitizeSecretKey(key) {
|
|
|
1531
1535
|
}
|
|
1532
1536
|
function detectEnvironment(key) {
|
|
1533
1537
|
const sanitized = key.trim().toLowerCase();
|
|
1538
|
+
if (sanitized.startsWith("pk_")) {
|
|
1539
|
+
const result = validatePublicKey(sanitized);
|
|
1540
|
+
if (!result.valid) throw new Error(result.error);
|
|
1541
|
+
return result.environment;
|
|
1542
|
+
}
|
|
1534
1543
|
if (sanitized.startsWith("sk_")) {
|
|
1535
1544
|
const result = validateSecretKey(sanitized);
|
|
1536
|
-
if (!result.valid)
|
|
1537
|
-
throw new Error(result.error);
|
|
1538
|
-
}
|
|
1545
|
+
if (!result.valid) throw new Error(result.error);
|
|
1539
1546
|
return result.environment;
|
|
1540
1547
|
}
|
|
1541
1548
|
if (sanitized.startsWith("app_")) {
|
|
1542
1549
|
const result = validateAppId(sanitized);
|
|
1543
|
-
if (!result.valid)
|
|
1544
|
-
throw new Error(result.error);
|
|
1545
|
-
}
|
|
1550
|
+
if (!result.valid) throw new Error(result.error);
|
|
1546
1551
|
return result.environment;
|
|
1547
1552
|
}
|
|
1548
1553
|
throw new Error(
|
|
1549
|
-
`[Sylphx] Invalid key format. Key must start with 'sk_' (secret) or 'app_' (App ID).`
|
|
1554
|
+
`[Sylphx] Invalid key format. Key must start with 'pk_' (publishable), 'sk_' (secret), or 'app_' (legacy App ID).`
|
|
1550
1555
|
);
|
|
1551
1556
|
}
|
|
1552
1557
|
function isDevelopmentKey(key) {
|
|
@@ -1562,6 +1567,7 @@ function getCookieNamespace(secretKey) {
|
|
|
1562
1567
|
}
|
|
1563
1568
|
function detectKeyType(key) {
|
|
1564
1569
|
const sanitized = key.trim().toLowerCase();
|
|
1570
|
+
if (sanitized.startsWith("pk_")) return "publicKey";
|
|
1565
1571
|
if (sanitized.startsWith("app_")) return "appId";
|
|
1566
1572
|
if (sanitized.startsWith("sk_")) return "secret";
|
|
1567
1573
|
return null;
|
|
@@ -1574,6 +1580,9 @@ function isSecretKey(key) {
|
|
|
1574
1580
|
}
|
|
1575
1581
|
function validateKey(key) {
|
|
1576
1582
|
const keyType = key ? detectKeyType(key) : null;
|
|
1583
|
+
if (keyType === "publicKey") {
|
|
1584
|
+
return validatePublicKey(key);
|
|
1585
|
+
}
|
|
1577
1586
|
if (keyType === "appId") {
|
|
1578
1587
|
return validateAppId(key);
|
|
1579
1588
|
}
|
|
@@ -1583,7 +1592,7 @@ function validateKey(key) {
|
|
|
1583
1592
|
return {
|
|
1584
1593
|
valid: false,
|
|
1585
1594
|
sanitizedKey: "",
|
|
1586
|
-
error: key ? `Invalid key format. Keys must start with 'app_' (
|
|
1595
|
+
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.",
|
|
1587
1596
|
issues: key ? ["invalid_format"] : ["missing"]
|
|
1588
1597
|
};
|
|
1589
1598
|
}
|
|
@@ -1981,31 +1990,41 @@ function createDynamicRestClient(config) {
|
|
|
1981
1990
|
}
|
|
1982
1991
|
|
|
1983
1992
|
// src/lib/ids.ts
|
|
1993
|
+
var CB32 = "0123456789abcdefghjkmnpqrstvwxyz";
|
|
1994
|
+
var CB32_MAP = Object.fromEntries([...CB32].map((c, i) => [c, i]));
|
|
1984
1995
|
var B58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
1985
1996
|
var B58_MAP = Object.fromEntries([...B58].map((c, i) => [c, i]));
|
|
1986
|
-
function
|
|
1987
|
-
const
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
let
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1997
|
+
function cb32Encode(hex) {
|
|
1998
|
+
const num = BigInt(`0x${hex}`);
|
|
1999
|
+
const chars = [];
|
|
2000
|
+
let n = num;
|
|
2001
|
+
for (let i = 0; i < 26; i++) {
|
|
2002
|
+
chars.unshift(CB32[Number(n & 0x1fn)]);
|
|
2003
|
+
n >>= 5n;
|
|
2004
|
+
}
|
|
2005
|
+
return chars.join("");
|
|
2006
|
+
}
|
|
2007
|
+
function cb32Decode(str) {
|
|
2008
|
+
if (str.length !== 26) return null;
|
|
2009
|
+
let n = 0n;
|
|
2010
|
+
for (const c of str.toLowerCase()) {
|
|
2011
|
+
const idx = CB32_MAP[c];
|
|
2012
|
+
if (idx === void 0) return null;
|
|
2013
|
+
n = n << 5n | BigInt(idx);
|
|
1995
2014
|
}
|
|
1996
|
-
return
|
|
2015
|
+
return n.toString(16).padStart(32, "0");
|
|
1997
2016
|
}
|
|
1998
|
-
function
|
|
1999
|
-
if (!prefixedId.startsWith("user_")) return null;
|
|
2000
|
-
const enc = prefixedId.slice(5);
|
|
2001
|
-
if (!enc) return null;
|
|
2017
|
+
function b58Decode(str) {
|
|
2002
2018
|
let n = 0n;
|
|
2003
|
-
for (const c of
|
|
2019
|
+
for (const c of str) {
|
|
2004
2020
|
const i = B58_MAP[c] ?? -1;
|
|
2005
2021
|
if (i === -1) return null;
|
|
2006
2022
|
n = n * 58n + BigInt(i);
|
|
2007
2023
|
}
|
|
2008
2024
|
const hex = n.toString(16).padStart(32, "0");
|
|
2025
|
+
return hex.length === 32 ? hex : null;
|
|
2026
|
+
}
|
|
2027
|
+
function hexToUuid(hex) {
|
|
2009
2028
|
return [
|
|
2010
2029
|
hex.slice(0, 8),
|
|
2011
2030
|
hex.slice(8, 12),
|
|
@@ -2014,6 +2033,24 @@ function decodeUserId(prefixedId) {
|
|
|
2014
2033
|
hex.slice(20)
|
|
2015
2034
|
].join("-");
|
|
2016
2035
|
}
|
|
2036
|
+
function encodeUserId(uuid) {
|
|
2037
|
+
const hex = uuid.replace(/-/g, "");
|
|
2038
|
+
if (hex.length !== 32)
|
|
2039
|
+
throw new Error("Invalid UUID: expected 32 hex chars after stripping dashes");
|
|
2040
|
+
return `user_${cb32Encode(hex)}`;
|
|
2041
|
+
}
|
|
2042
|
+
function decodeUserId(prefixedId) {
|
|
2043
|
+
if (!prefixedId.startsWith("user_")) return null;
|
|
2044
|
+
const enc = prefixedId.slice(5);
|
|
2045
|
+
if (!enc) return null;
|
|
2046
|
+
if (enc.length === 26) {
|
|
2047
|
+
const hex2 = cb32Decode(enc);
|
|
2048
|
+
if (hex2) return hexToUuid(hex2);
|
|
2049
|
+
}
|
|
2050
|
+
const hex = b58Decode(enc);
|
|
2051
|
+
if (hex) return hexToUuid(hex);
|
|
2052
|
+
return null;
|
|
2053
|
+
}
|
|
2017
2054
|
|
|
2018
2055
|
// src/server/ai.ts
|
|
2019
2056
|
function createAI(options = {}) {
|