@windrun-huaiin/third-ui 30.1.0 → 31.0.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 +109 -143
- package/dist/ai/ai-prompt-textarea.js +5 -5
- package/dist/ai/ai-prompt-textarea.mjs +5 -5
- package/dist/clerk/clerk-auth-appearance.d.ts +13 -0
- package/dist/clerk/clerk-auth-appearance.js +19 -0
- package/dist/clerk/clerk-auth-appearance.mjs +15 -0
- package/dist/clerk/clerk-auth-modal-appearance.d.ts +12 -0
- package/dist/clerk/clerk-auth-modal-appearance.js +17 -0
- package/dist/clerk/clerk-auth-modal-appearance.mjs +14 -0
- package/dist/clerk/clerk-page-context-generator.js +3 -3
- package/dist/clerk/clerk-page-context-generator.mjs +3 -3
- package/dist/clerk/clerk-page-generator.js +4 -4
- package/dist/clerk/clerk-page-generator.mjs +4 -4
- package/dist/clerk/clerk-user-client.js +2 -1
- package/dist/clerk/clerk-user-client.mjs +2 -1
- package/dist/clerk/fingerprint/fingerprint-client.d.ts +10 -10
- package/dist/clerk/fingerprint/fingerprint-client.js +20 -20
- package/dist/clerk/fingerprint/fingerprint-client.mjs +20 -20
- package/dist/clerk/fingerprint/fingerprint-provider.d.ts +3 -3
- package/dist/clerk/fingerprint/fingerprint-provider.js +8 -8
- package/dist/clerk/fingerprint/fingerprint-provider.mjs +8 -8
- package/dist/clerk/fingerprint/fingerprint-server.d.ts +12 -12
- package/dist/clerk/fingerprint/fingerprint-server.js +17 -17
- package/dist/clerk/fingerprint/fingerprint-server.mjs +17 -17
- package/dist/clerk/fingerprint/fingerprint-shared.d.ts +3 -3
- package/dist/clerk/fingerprint/fingerprint-shared.js +10 -10
- package/dist/clerk/fingerprint/fingerprint-shared.mjs +10 -10
- package/dist/clerk/fingerprint/types.d.ts +0 -1
- package/dist/clerk/fingerprint/use-fingerprint.js +7 -7
- package/dist/clerk/fingerprint/use-fingerprint.mjs +7 -7
- package/dist/clerk/signin-with-fingerprint-client.d.ts +2 -2
- package/dist/clerk/signin-with-fingerprint-client.js +7 -6
- package/dist/clerk/signin-with-fingerprint-client.mjs +7 -6
- package/dist/clerk/signup-button-with-fingerprint-client.js +6 -4
- package/dist/clerk/signup-button-with-fingerprint-client.mjs +6 -4
- package/dist/clerk/signup-with-fingerprint-client.d.ts +2 -2
- package/dist/clerk/signup-with-fingerprint-client.js +7 -6
- package/dist/clerk/signup-with-fingerprint-client.mjs +7 -6
- package/dist/fuma/heavy/mermaid.js +1 -1
- package/dist/fuma/heavy/mermaid.mjs +1 -1
- package/dist/fuma/mdx/fuma-github-info.d.ts +1 -2
- package/dist/fuma/mdx/fuma-github-info.js +3 -6
- package/dist/fuma/mdx/fuma-github-info.mjs +3 -6
- package/dist/fuma/site-x.js +0 -1
- package/dist/fuma/site-x.mjs +0 -1
- package/dist/main/calendar/calendar-date-range-input.js +1 -1
- package/dist/main/calendar/calendar-date-range-input.mjs +1 -1
- package/dist/main/credit/credit-overview-nav-client.d.ts +12 -0
- package/dist/main/credit/credit-overview-nav-client.js +65 -0
- package/dist/main/credit/credit-overview-nav-client.mjs +63 -0
- package/dist/main/credit/index.d.ts +2 -0
- package/dist/main/credit/index.js +2 -0
- package/dist/main/credit/index.mjs +1 -0
- package/dist/main/credit/types.d.ts +8 -8
- package/dist/main/money-price/index.d.ts +1 -1
- package/dist/main/money-price/money-price-button.js +10 -10
- package/dist/main/money-price/money-price-button.mjs +10 -10
- package/dist/main/money-price/money-price-config-util.d.ts +30 -30
- package/dist/main/money-price/money-price-config-util.js +48 -48
- package/dist/main/money-price/money-price-config-util.mjs +48 -48
- package/dist/main/money-price/money-price-interactive.js +30 -18
- package/dist/main/money-price/money-price-interactive.mjs +30 -18
- package/dist/main/money-price/money-price-types.d.ts +7 -1
- package/dist/main/money-price/money-price-types.js +2 -2
- package/dist/main/money-price/money-price-types.mjs +2 -2
- package/dist/main/money-price/server.d.ts +1 -1
- package/dist/main/pill-select/x-pill-select.js +2 -2
- package/dist/main/pill-select/x-pill-select.mjs +2 -2
- package/dist/main/server.d.ts +1 -1
- package/package.json +13 -7
- package/src/ai/ai-prompt-textarea.tsx +6 -6
- package/src/clerk/clerk-auth-appearance.ts +16 -0
- package/src/clerk/clerk-page-context-generator.tsx +3 -5
- package/src/clerk/clerk-page-generator.tsx +9 -8
- package/src/clerk/clerk-user-client.tsx +14 -5
- package/src/clerk/fingerprint/fingerprint-client.ts +20 -20
- package/src/clerk/fingerprint/fingerprint-provider.tsx +11 -11
- package/src/clerk/fingerprint/fingerprint-server.ts +17 -17
- package/src/clerk/fingerprint/fingerprint-shared.ts +10 -10
- package/src/clerk/fingerprint/types.ts +0 -1
- package/src/clerk/fingerprint/use-fingerprint.ts +7 -7
- package/src/clerk/signin-with-fingerprint-client.tsx +7 -7
- package/src/clerk/signup-button-with-fingerprint-client.tsx +7 -5
- package/src/clerk/signup-with-fingerprint-client.tsx +7 -7
- package/src/fuma/base/custom-home-layout.tsx +4 -4
- package/src/fuma/heavy/mermaid.tsx +1 -1
- package/src/fuma/mdx/fuma-github-info.tsx +3 -8
- package/src/fuma/site-x.tsx +0 -1
- package/src/main/calendar/calendar-date-range-input.tsx +1 -1
- package/src/main/credit/credit-overview-nav-client.tsx +95 -0
- package/src/main/credit/index.ts +5 -0
- package/src/main/credit/types.ts +8 -8
- package/src/main/gallery/gallery-mobile-swiper.tsx +0 -1
- package/src/main/gallery/gallery-server.tsx +2 -2
- package/src/main/money-price/index.ts +2 -0
- package/src/main/money-price/money-price-button.tsx +10 -10
- package/src/main/money-price/money-price-config-util.ts +49 -49
- package/src/main/money-price/money-price-interactive.tsx +40 -20
- package/src/main/money-price/money-price-types.ts +21 -14
- package/src/main/money-price/server.ts +2 -0
- package/src/main/pill-select/x-pill-select.tsx +2 -2
- package/src/main/server.ts +3 -1
- package/src/styles/third-ui.css +8 -0
|
@@ -2,30 +2,30 @@ import { FINGERPRINT_HEADER_NAME, isValidFingerprintId, FINGERPRINT_COOKIE_NAME
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Fingerprint Server Utilities
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Server-only fingerprint ID extraction and validation logic.
|
|
6
|
+
* Safe for server usage without browser APIs or FingerprintJS.
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Extract fingerprint ID from a request.
|
|
10
|
+
* Priority: header > cookie > query parameter.
|
|
11
|
+
* Safe to use on the server.
|
|
12
12
|
*/
|
|
13
13
|
function extractFingerprintId(headers, cookies, query) {
|
|
14
|
-
// 1.
|
|
14
|
+
// 1. Read from header.
|
|
15
15
|
const headerValue = headers instanceof Headers
|
|
16
16
|
? headers.get(FINGERPRINT_HEADER_NAME)
|
|
17
17
|
: headers[FINGERPRINT_HEADER_NAME];
|
|
18
18
|
if (headerValue && isValidFingerprintId(headerValue)) {
|
|
19
19
|
return headerValue;
|
|
20
20
|
}
|
|
21
|
-
// 2.
|
|
21
|
+
// 2. Read from cookie.
|
|
22
22
|
if (cookies) {
|
|
23
23
|
const cookieValue = cookies[FINGERPRINT_COOKIE_NAME];
|
|
24
24
|
if (cookieValue && isValidFingerprintId(cookieValue)) {
|
|
25
25
|
return cookieValue;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
// 3.
|
|
28
|
+
// 3. Read from query parameters.
|
|
29
29
|
if (query) {
|
|
30
30
|
const queryValue = query.fingerprint_id || query.fp_id;
|
|
31
31
|
if (queryValue && isValidFingerprintId(queryValue)) {
|
|
@@ -35,20 +35,20 @@ function extractFingerprintId(headers, cookies, query) {
|
|
|
35
35
|
return null;
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
38
|
+
* Generate a server-side fallback fingerprint ID.
|
|
39
|
+
* Used when the client cannot generate a fingerprint.
|
|
40
|
+
* Safe to use on the server.
|
|
41
41
|
*/
|
|
42
42
|
function generateServerFingerprintId() {
|
|
43
43
|
return `fp_server_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
46
|
+
* Extract fingerprint ID from a Next.js Request object.
|
|
47
|
+
* Convenience helper for Next.js API routes.
|
|
48
48
|
*/
|
|
49
49
|
function extractFingerprintFromNextRequest(request) {
|
|
50
50
|
const headers = request.headers;
|
|
51
|
-
//
|
|
51
|
+
// Try cookies by parsing the cookie header.
|
|
52
52
|
const cookieHeader = headers.get('cookie');
|
|
53
53
|
const cookies = {};
|
|
54
54
|
if (cookieHeader) {
|
|
@@ -59,7 +59,7 @@ function extractFingerprintFromNextRequest(request) {
|
|
|
59
59
|
}
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
|
-
//
|
|
62
|
+
// Try URL query parameters.
|
|
63
63
|
const url = new URL(request.url);
|
|
64
64
|
const query = {};
|
|
65
65
|
url.searchParams.forEach((value, key) => {
|
|
@@ -68,8 +68,8 @@ function extractFingerprintFromNextRequest(request) {
|
|
|
68
68
|
return extractFingerprintId(headers, cookies, query);
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
71
|
+
* Extract fingerprint ID from Next.js runtime headers/cookies stores.
|
|
72
|
+
* Reusable in App Router server components and Server Actions.
|
|
73
73
|
*/
|
|
74
74
|
function extractFingerprintFromNextStores(params) {
|
|
75
75
|
const cookieMap = params.cookies
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Fingerprint Shared Utilities
|
|
3
|
-
*
|
|
3
|
+
* Shared constants, types, and validation logic for client and server.
|
|
4
4
|
*/
|
|
5
5
|
export declare const FINGERPRINT_STORAGE_KEY = "__x_fingerprint_id";
|
|
6
6
|
export declare const FINGERPRINT_DEBUG_OVERRIDE_STORAGE_KEY = "__x_fingerprint_debug_override";
|
|
@@ -12,8 +12,8 @@ export declare const FINGERPRINT_FIRST_TOUCH_COOKIE_NAME = "__x_first_touch";
|
|
|
12
12
|
export declare const FINGERPRINT_FIRST_TOUCH_HEADER = "x-first-touch";
|
|
13
13
|
export declare const FINGERPRINT_DEBUG_PREFIX = "fp_test_dbg_";
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* Validate fingerprint ID format.
|
|
16
|
+
* Safe to use on both client and server.
|
|
17
17
|
*/
|
|
18
18
|
export declare function isValidFingerprintId(fingerprintId: string): boolean;
|
|
19
19
|
export declare function isDebugFingerprintId(fingerprintId: string | null | undefined): boolean;
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Fingerprint Shared Utilities
|
|
5
|
-
*
|
|
5
|
+
* Shared constants, types, and validation logic for client and server.
|
|
6
6
|
*/
|
|
7
|
-
//
|
|
7
|
+
// Storage keys and header names for fingerprint IDs.
|
|
8
8
|
const FINGERPRINT_STORAGE_KEY = '__x_fingerprint_id';
|
|
9
9
|
const FINGERPRINT_DEBUG_OVERRIDE_STORAGE_KEY = '__x_fingerprint_debug_override';
|
|
10
10
|
const FINGERPRINT_HEADER_NAME = 'x-fingerprint-id-v8';
|
|
@@ -15,17 +15,17 @@ const FINGERPRINT_FIRST_TOUCH_COOKIE_NAME = '__x_first_touch';
|
|
|
15
15
|
const FINGERPRINT_FIRST_TOUCH_HEADER = 'x-first-touch';
|
|
16
16
|
const FINGERPRINT_DEBUG_PREFIX = 'fp_test_dbg_';
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
18
|
+
* Validate fingerprint ID format.
|
|
19
|
+
* Safe to use on both client and server.
|
|
20
20
|
*/
|
|
21
21
|
function isValidFingerprintId(fingerprintId) {
|
|
22
22
|
if (!fingerprintId)
|
|
23
23
|
return false;
|
|
24
|
-
//
|
|
25
|
-
// - fp_ + FingerprintJS visitorId
|
|
26
|
-
// - fp_fallback_ +
|
|
27
|
-
// - fp_server_ +
|
|
28
|
-
// - fp_test_dbg_ +
|
|
24
|
+
// Supported formats:
|
|
25
|
+
// - fp_ + FingerprintJS visitorId with variable length.
|
|
26
|
+
// - fp_fallback_ + timestamp + random string for client fallback.
|
|
27
|
+
// - fp_server_ + timestamp + random string for server fallback.
|
|
28
|
+
// - fp_test_dbg_ + timestamp + random string for debug concurrency tests.
|
|
29
29
|
return /^fp(_fallback|_server|_test_dbg)?_[a-zA-Z0-9_]+$/.test(fingerprintId);
|
|
30
30
|
}
|
|
31
31
|
function isDebugFingerprintId(fingerprintId) {
|
|
@@ -34,7 +34,7 @@ function isDebugFingerprintId(fingerprintId) {
|
|
|
34
34
|
}
|
|
35
35
|
return fingerprintId.startsWith(FINGERPRINT_DEBUG_PREFIX);
|
|
36
36
|
}
|
|
37
|
-
//
|
|
37
|
+
// Exported constants.
|
|
38
38
|
const FINGERPRINT_CONSTANTS = {
|
|
39
39
|
STORAGE_KEY: FINGERPRINT_STORAGE_KEY,
|
|
40
40
|
DEBUG_OVERRIDE_STORAGE_KEY: FINGERPRINT_DEBUG_OVERRIDE_STORAGE_KEY,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Fingerprint Shared Utilities
|
|
3
|
-
*
|
|
3
|
+
* Shared constants, types, and validation logic for client and server.
|
|
4
4
|
*/
|
|
5
|
-
//
|
|
5
|
+
// Storage keys and header names for fingerprint IDs.
|
|
6
6
|
const FINGERPRINT_STORAGE_KEY = '__x_fingerprint_id';
|
|
7
7
|
const FINGERPRINT_DEBUG_OVERRIDE_STORAGE_KEY = '__x_fingerprint_debug_override';
|
|
8
8
|
const FINGERPRINT_HEADER_NAME = 'x-fingerprint-id-v8';
|
|
@@ -13,17 +13,17 @@ const FINGERPRINT_FIRST_TOUCH_COOKIE_NAME = '__x_first_touch';
|
|
|
13
13
|
const FINGERPRINT_FIRST_TOUCH_HEADER = 'x-first-touch';
|
|
14
14
|
const FINGERPRINT_DEBUG_PREFIX = 'fp_test_dbg_';
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* Validate fingerprint ID format.
|
|
17
|
+
* Safe to use on both client and server.
|
|
18
18
|
*/
|
|
19
19
|
function isValidFingerprintId(fingerprintId) {
|
|
20
20
|
if (!fingerprintId)
|
|
21
21
|
return false;
|
|
22
|
-
//
|
|
23
|
-
// - fp_ + FingerprintJS visitorId
|
|
24
|
-
// - fp_fallback_ +
|
|
25
|
-
// - fp_server_ +
|
|
26
|
-
// - fp_test_dbg_ +
|
|
22
|
+
// Supported formats:
|
|
23
|
+
// - fp_ + FingerprintJS visitorId with variable length.
|
|
24
|
+
// - fp_fallback_ + timestamp + random string for client fallback.
|
|
25
|
+
// - fp_server_ + timestamp + random string for server fallback.
|
|
26
|
+
// - fp_test_dbg_ + timestamp + random string for debug concurrency tests.
|
|
27
27
|
return /^fp(_fallback|_server|_test_dbg)?_[a-zA-Z0-9_]+$/.test(fingerprintId);
|
|
28
28
|
}
|
|
29
29
|
function isDebugFingerprintId(fingerprintId) {
|
|
@@ -32,7 +32,7 @@ function isDebugFingerprintId(fingerprintId) {
|
|
|
32
32
|
}
|
|
33
33
|
return fingerprintId.startsWith(FINGERPRINT_DEBUG_PREFIX);
|
|
34
34
|
}
|
|
35
|
-
//
|
|
35
|
+
// Exported constants.
|
|
36
36
|
const FINGERPRINT_CONSTANTS = {
|
|
37
37
|
STORAGE_KEY: FINGERPRINT_STORAGE_KEY,
|
|
38
38
|
DEBUG_OVERRIDE_STORAGE_KEY: FINGERPRINT_DEBUG_OVERRIDE_STORAGE_KEY,
|
|
@@ -11,7 +11,7 @@ var fingerprintShared = require('./fingerprint-shared.js');
|
|
|
11
11
|
* Accepts configuration to customize API endpoint and behavior
|
|
12
12
|
*/
|
|
13
13
|
function useFingerprint(config) {
|
|
14
|
-
//
|
|
14
|
+
// Server-side rendering guard.
|
|
15
15
|
if (typeof window === 'undefined') {
|
|
16
16
|
return {
|
|
17
17
|
fingerprintId: null,
|
|
@@ -39,7 +39,7 @@ function useFingerprint(config) {
|
|
|
39
39
|
setError(null);
|
|
40
40
|
}, []);
|
|
41
41
|
/**
|
|
42
|
-
*
|
|
42
|
+
* Phase 1: initialize fingerprint ID.
|
|
43
43
|
*/
|
|
44
44
|
const initializeFingerprintId = React.useCallback(() => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
45
45
|
try {
|
|
@@ -56,7 +56,7 @@ function useFingerprint(config) {
|
|
|
56
56
|
}
|
|
57
57
|
}), []);
|
|
58
58
|
/**
|
|
59
|
-
*
|
|
59
|
+
* Phase 2: initialize anonymous user.
|
|
60
60
|
*/
|
|
61
61
|
const initializeAnonymousUser = React.useCallback(() => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
62
62
|
var _a;
|
|
@@ -117,7 +117,7 @@ function useFingerprint(config) {
|
|
|
117
117
|
}
|
|
118
118
|
}), [fingerprintId, config.apiEndpoint, isInitialized]);
|
|
119
119
|
/**
|
|
120
|
-
*
|
|
120
|
+
* Refresh user data with a POST request; the backend supports upsert semantics.
|
|
121
121
|
*/
|
|
122
122
|
const refreshUserData = React.useCallback(() => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
123
123
|
if (!fingerprintId) {
|
|
@@ -150,7 +150,7 @@ function useFingerprint(config) {
|
|
|
150
150
|
setError(err instanceof Error ? err.message : 'Unknown error');
|
|
151
151
|
}
|
|
152
152
|
}), [fingerprintId, config.apiEndpoint]);
|
|
153
|
-
//
|
|
153
|
+
// Phase 1: generate fingerprint ID after page load.
|
|
154
154
|
React.useEffect(() => {
|
|
155
155
|
const initFingerprint = () => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
156
156
|
setIsLoading(true);
|
|
@@ -159,11 +159,11 @@ function useFingerprint(config) {
|
|
|
159
159
|
});
|
|
160
160
|
initFingerprint();
|
|
161
161
|
}, [initializeFingerprintId]);
|
|
162
|
-
//
|
|
162
|
+
// Phase 2: initialize the user once a fingerprint ID is available; the backend supports upsert semantics.
|
|
163
163
|
React.useEffect(() => {
|
|
164
164
|
if (!fingerprintId || isInitialized || isLoading || error || config.autoInitialize === false)
|
|
165
165
|
return;
|
|
166
|
-
//
|
|
166
|
+
// Use POST directly; the backend handles lookup and create-if-missing behavior.
|
|
167
167
|
initializeAnonymousUser();
|
|
168
168
|
}, [fingerprintId, isInitialized, isLoading, error, initializeAnonymousUser, config.autoInitialize]);
|
|
169
169
|
return {
|
|
@@ -9,7 +9,7 @@ import { FINGERPRINT_SOURCE_REFER, isValidFingerprintId, isDebugFingerprintId }
|
|
|
9
9
|
* Accepts configuration to customize API endpoint and behavior
|
|
10
10
|
*/
|
|
11
11
|
function useFingerprint(config) {
|
|
12
|
-
//
|
|
12
|
+
// Server-side rendering guard.
|
|
13
13
|
if (typeof window === 'undefined') {
|
|
14
14
|
return {
|
|
15
15
|
fingerprintId: null,
|
|
@@ -37,7 +37,7 @@ function useFingerprint(config) {
|
|
|
37
37
|
setError(null);
|
|
38
38
|
}, []);
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* Phase 1: initialize fingerprint ID.
|
|
41
41
|
*/
|
|
42
42
|
const initializeFingerprintId = useCallback(() => __awaiter(this, void 0, void 0, function* () {
|
|
43
43
|
try {
|
|
@@ -54,7 +54,7 @@ function useFingerprint(config) {
|
|
|
54
54
|
}
|
|
55
55
|
}), []);
|
|
56
56
|
/**
|
|
57
|
-
*
|
|
57
|
+
* Phase 2: initialize anonymous user.
|
|
58
58
|
*/
|
|
59
59
|
const initializeAnonymousUser = useCallback(() => __awaiter(this, void 0, void 0, function* () {
|
|
60
60
|
var _a;
|
|
@@ -115,7 +115,7 @@ function useFingerprint(config) {
|
|
|
115
115
|
}
|
|
116
116
|
}), [fingerprintId, config.apiEndpoint, isInitialized]);
|
|
117
117
|
/**
|
|
118
|
-
*
|
|
118
|
+
* Refresh user data with a POST request; the backend supports upsert semantics.
|
|
119
119
|
*/
|
|
120
120
|
const refreshUserData = useCallback(() => __awaiter(this, void 0, void 0, function* () {
|
|
121
121
|
if (!fingerprintId) {
|
|
@@ -148,7 +148,7 @@ function useFingerprint(config) {
|
|
|
148
148
|
setError(err instanceof Error ? err.message : 'Unknown error');
|
|
149
149
|
}
|
|
150
150
|
}), [fingerprintId, config.apiEndpoint]);
|
|
151
|
-
//
|
|
151
|
+
// Phase 1: generate fingerprint ID after page load.
|
|
152
152
|
useEffect(() => {
|
|
153
153
|
const initFingerprint = () => __awaiter(this, void 0, void 0, function* () {
|
|
154
154
|
setIsLoading(true);
|
|
@@ -157,11 +157,11 @@ function useFingerprint(config) {
|
|
|
157
157
|
});
|
|
158
158
|
initFingerprint();
|
|
159
159
|
}, [initializeFingerprintId]);
|
|
160
|
-
//
|
|
160
|
+
// Phase 2: initialize the user once a fingerprint ID is available; the backend supports upsert semantics.
|
|
161
161
|
useEffect(() => {
|
|
162
162
|
if (!fingerprintId || isInitialized || isLoading || error || config.autoInitialize === false)
|
|
163
163
|
return;
|
|
164
|
-
//
|
|
164
|
+
// Use POST directly; the backend handles lookup and create-if-missing behavior.
|
|
165
165
|
initializeAnonymousUser();
|
|
166
166
|
}, [fingerprintId, isInitialized, isLoading, error, initializeAnonymousUser, config.autoInitialize]);
|
|
167
167
|
return {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SignIn component with fingerprint awareness
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Falls back to the standard SignIn component when FingerprintProvider is absent.
|
|
4
|
+
* Handles fingerprint-related metadata when FingerprintProvider is available.
|
|
5
5
|
*/
|
|
6
6
|
export declare function SignInWithFingerprint(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,29 +5,30 @@ var tslib = require('tslib');
|
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var nextjs = require('@clerk/nextjs');
|
|
7
7
|
var React = require('react');
|
|
8
|
+
var clerkAuthAppearance = require('./clerk-auth-appearance.js');
|
|
8
9
|
var fingerprintProvider = require('./fingerprint/fingerprint-provider.js');
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* SignIn component with fingerprint awareness
|
|
12
|
-
*
|
|
13
|
-
*
|
|
13
|
+
* Falls back to the standard SignIn component when FingerprintProvider is absent.
|
|
14
|
+
* Handles fingerprint-related metadata when FingerprintProvider is available.
|
|
14
15
|
*/
|
|
15
16
|
function SignInWithFingerprint() {
|
|
16
17
|
const fingerprintContext = fingerprintProvider.useFingerprintContextSafe();
|
|
17
|
-
//
|
|
18
|
+
// Use defaults when fingerprint context is unavailable.
|
|
18
19
|
const { fingerprintId = null, xUser = null, isInitialized = false, initializeAnonymousUser = () => tslib.__awaiter(this, void 0, void 0, function* () { }) } = fingerprintContext || {};
|
|
19
|
-
//
|
|
20
|
+
// Prepare Clerk metadata with anonymous user information.
|
|
20
21
|
const unsafeMetadata = {
|
|
21
22
|
user_id: (xUser === null || xUser === void 0 ? void 0 : xUser.userId) || null,
|
|
22
23
|
fingerprint_id: fingerprintId || null,
|
|
23
24
|
};
|
|
24
|
-
//
|
|
25
|
+
// Ensure the anonymous user has been initialized.
|
|
25
26
|
React.useEffect(() => {
|
|
26
27
|
if (!isInitialized && fingerprintId) {
|
|
27
28
|
initializeAnonymousUser();
|
|
28
29
|
}
|
|
29
30
|
}, [fingerprintId, isInitialized, initializeAnonymousUser]);
|
|
30
|
-
return jsxRuntime.jsx(nextjs.SignIn, { unsafeMetadata: unsafeMetadata });
|
|
31
|
+
return jsxRuntime.jsx(nextjs.SignIn, { appearance: clerkAuthAppearance.clerkAuthPageAppearance, unsafeMetadata: unsafeMetadata });
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
exports.SignInWithFingerprint = SignInWithFingerprint;
|
|
@@ -3,29 +3,30 @@ import { __awaiter } from 'tslib';
|
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
import { SignIn } from '@clerk/nextjs';
|
|
5
5
|
import { useEffect } from 'react';
|
|
6
|
+
import { clerkAuthPageAppearance } from './clerk-auth-appearance.mjs';
|
|
6
7
|
import { useFingerprintContextSafe } from './fingerprint/fingerprint-provider.mjs';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* SignIn component with fingerprint awareness
|
|
10
|
-
*
|
|
11
|
-
*
|
|
11
|
+
* Falls back to the standard SignIn component when FingerprintProvider is absent.
|
|
12
|
+
* Handles fingerprint-related metadata when FingerprintProvider is available.
|
|
12
13
|
*/
|
|
13
14
|
function SignInWithFingerprint() {
|
|
14
15
|
const fingerprintContext = useFingerprintContextSafe();
|
|
15
|
-
//
|
|
16
|
+
// Use defaults when fingerprint context is unavailable.
|
|
16
17
|
const { fingerprintId = null, xUser = null, isInitialized = false, initializeAnonymousUser = () => __awaiter(this, void 0, void 0, function* () { }) } = fingerprintContext || {};
|
|
17
|
-
//
|
|
18
|
+
// Prepare Clerk metadata with anonymous user information.
|
|
18
19
|
const unsafeMetadata = {
|
|
19
20
|
user_id: (xUser === null || xUser === void 0 ? void 0 : xUser.userId) || null,
|
|
20
21
|
fingerprint_id: fingerprintId || null,
|
|
21
22
|
};
|
|
22
|
-
//
|
|
23
|
+
// Ensure the anonymous user has been initialized.
|
|
23
24
|
useEffect(() => {
|
|
24
25
|
if (!isInitialized && fingerprintId) {
|
|
25
26
|
initializeAnonymousUser();
|
|
26
27
|
}
|
|
27
28
|
}, [fingerprintId, isInitialized, initializeAnonymousUser]);
|
|
28
|
-
return jsx(SignIn, { unsafeMetadata: unsafeMetadata });
|
|
29
|
+
return jsx(SignIn, { appearance: clerkAuthPageAppearance, unsafeMetadata: unsafeMetadata });
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
export { SignInWithFingerprint };
|
|
@@ -5,24 +5,25 @@ var tslib = require('tslib');
|
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var nextjs = require('@clerk/nextjs');
|
|
7
7
|
var React = require('react');
|
|
8
|
+
var clerkAuthAppearance = require('./clerk-auth-appearance.js');
|
|
8
9
|
var fingerprintProvider = require('./fingerprint/fingerprint-provider.js');
|
|
9
10
|
|
|
10
11
|
function SignUpButtonWithFingerprint({ mode, signUp, }) {
|
|
11
12
|
if (mode === 'redirect') {
|
|
12
13
|
return (
|
|
13
|
-
//
|
|
14
|
+
// Redirect mode navigates directly to the custom sign-up page.
|
|
14
15
|
jsxRuntime.jsx(nextjs.SignUpButton, { children: jsxRuntime.jsx("button", { className: "w-16 sm:w-20 h-8 sm:h-9 px-1.5 sm:px-2 border border-gray-300 rounded-full hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-800 text-center text-xs sm:text-sm whitespace-nowrap", children: signUp }) }));
|
|
15
16
|
}
|
|
16
|
-
//
|
|
17
|
+
// Modal mode requires a custom sign-up button.
|
|
17
18
|
const fingerprintContext = fingerprintProvider.useFingerprintContextSafe();
|
|
18
|
-
//
|
|
19
|
+
// Use defaults when fingerprint context is unavailable.
|
|
19
20
|
const { fingerprintId = null, xUser = null, isInitialized = false, initializeAnonymousUser = () => tslib.__awaiter(this, void 0, void 0, function* () { }) } = fingerprintContext || {};
|
|
20
21
|
const userId = (xUser === null || xUser === void 0 ? void 0 : xUser.userId) || null;
|
|
21
22
|
const unsafeMetadata = {
|
|
22
23
|
user_id: userId,
|
|
23
24
|
fingerprint_id: fingerprintId || null,
|
|
24
25
|
};
|
|
25
|
-
//
|
|
26
|
+
// Ensure the anonymous user has been initialized.
|
|
26
27
|
React.useEffect(() => {
|
|
27
28
|
if (!isInitialized && fingerprintId) {
|
|
28
29
|
initializeAnonymousUser();
|
|
@@ -31,6 +32,7 @@ function SignUpButtonWithFingerprint({ mode, signUp, }) {
|
|
|
31
32
|
const { openSignUp } = nextjs.useClerk();
|
|
32
33
|
const handleClick = () => {
|
|
33
34
|
openSignUp({
|
|
35
|
+
appearance: clerkAuthAppearance.clerkAuthModalAppearance,
|
|
34
36
|
unsafeMetadata,
|
|
35
37
|
});
|
|
36
38
|
};
|
|
@@ -3,24 +3,25 @@ import { __awaiter } from 'tslib';
|
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
import { SignUpButton, useClerk } from '@clerk/nextjs';
|
|
5
5
|
import { useEffect } from 'react';
|
|
6
|
+
import { clerkAuthModalAppearance } from './clerk-auth-appearance.mjs';
|
|
6
7
|
import { useFingerprintContextSafe } from './fingerprint/fingerprint-provider.mjs';
|
|
7
8
|
|
|
8
9
|
function SignUpButtonWithFingerprint({ mode, signUp, }) {
|
|
9
10
|
if (mode === 'redirect') {
|
|
10
11
|
return (
|
|
11
|
-
//
|
|
12
|
+
// Redirect mode navigates directly to the custom sign-up page.
|
|
12
13
|
jsx(SignUpButton, { children: jsx("button", { className: "w-16 sm:w-20 h-8 sm:h-9 px-1.5 sm:px-2 border border-gray-300 rounded-full hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-800 text-center text-xs sm:text-sm whitespace-nowrap", children: signUp }) }));
|
|
13
14
|
}
|
|
14
|
-
//
|
|
15
|
+
// Modal mode requires a custom sign-up button.
|
|
15
16
|
const fingerprintContext = useFingerprintContextSafe();
|
|
16
|
-
//
|
|
17
|
+
// Use defaults when fingerprint context is unavailable.
|
|
17
18
|
const { fingerprintId = null, xUser = null, isInitialized = false, initializeAnonymousUser = () => __awaiter(this, void 0, void 0, function* () { }) } = fingerprintContext || {};
|
|
18
19
|
const userId = (xUser === null || xUser === void 0 ? void 0 : xUser.userId) || null;
|
|
19
20
|
const unsafeMetadata = {
|
|
20
21
|
user_id: userId,
|
|
21
22
|
fingerprint_id: fingerprintId || null,
|
|
22
23
|
};
|
|
23
|
-
//
|
|
24
|
+
// Ensure the anonymous user has been initialized.
|
|
24
25
|
useEffect(() => {
|
|
25
26
|
if (!isInitialized && fingerprintId) {
|
|
26
27
|
initializeAnonymousUser();
|
|
@@ -29,6 +30,7 @@ function SignUpButtonWithFingerprint({ mode, signUp, }) {
|
|
|
29
30
|
const { openSignUp } = useClerk();
|
|
30
31
|
const handleClick = () => {
|
|
31
32
|
openSignUp({
|
|
33
|
+
appearance: clerkAuthModalAppearance,
|
|
32
34
|
unsafeMetadata,
|
|
33
35
|
});
|
|
34
36
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SignUp component with fingerprint awareness
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Falls back to the standard SignUp component when FingerprintProvider is absent.
|
|
4
|
+
* Handles fingerprint-related metadata when FingerprintProvider is available.
|
|
5
5
|
*/
|
|
6
6
|
export declare function SignUpWithFingerprint(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,29 +5,30 @@ var tslib = require('tslib');
|
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var nextjs = require('@clerk/nextjs');
|
|
7
7
|
var React = require('react');
|
|
8
|
+
var clerkAuthAppearance = require('./clerk-auth-appearance.js');
|
|
8
9
|
var fingerprintProvider = require('./fingerprint/fingerprint-provider.js');
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* SignUp component with fingerprint awareness
|
|
12
|
-
*
|
|
13
|
-
*
|
|
13
|
+
* Falls back to the standard SignUp component when FingerprintProvider is absent.
|
|
14
|
+
* Handles fingerprint-related metadata when FingerprintProvider is available.
|
|
14
15
|
*/
|
|
15
16
|
function SignUpWithFingerprint() {
|
|
16
17
|
const fingerprintContext = fingerprintProvider.useFingerprintContextSafe();
|
|
17
|
-
//
|
|
18
|
+
// Use defaults when fingerprint context is unavailable.
|
|
18
19
|
const { fingerprintId = null, xUser = null, isInitialized = false, initializeAnonymousUser = () => tslib.__awaiter(this, void 0, void 0, function* () { }) } = fingerprintContext || {};
|
|
19
|
-
//
|
|
20
|
+
// Prepare Clerk metadata with anonymous user information.
|
|
20
21
|
const unsafeMetadata = {
|
|
21
22
|
user_id: (xUser === null || xUser === void 0 ? void 0 : xUser.userId) || null,
|
|
22
23
|
fingerprint_id: fingerprintId || null,
|
|
23
24
|
};
|
|
24
|
-
//
|
|
25
|
+
// Ensure the anonymous user has been initialized.
|
|
25
26
|
React.useEffect(() => {
|
|
26
27
|
if (!isInitialized && fingerprintId) {
|
|
27
28
|
initializeAnonymousUser();
|
|
28
29
|
}
|
|
29
30
|
}, [fingerprintId, isInitialized, initializeAnonymousUser]);
|
|
30
|
-
return jsxRuntime.jsx(nextjs.SignUp, { unsafeMetadata: unsafeMetadata });
|
|
31
|
+
return jsxRuntime.jsx(nextjs.SignUp, { appearance: clerkAuthAppearance.clerkAuthPageAppearance, unsafeMetadata: unsafeMetadata });
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
exports.SignUpWithFingerprint = SignUpWithFingerprint;
|
|
@@ -3,29 +3,30 @@ import { __awaiter } from 'tslib';
|
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
import { SignUp } from '@clerk/nextjs';
|
|
5
5
|
import { useEffect } from 'react';
|
|
6
|
+
import { clerkAuthPageAppearance } from './clerk-auth-appearance.mjs';
|
|
6
7
|
import { useFingerprintContextSafe } from './fingerprint/fingerprint-provider.mjs';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* SignUp component with fingerprint awareness
|
|
10
|
-
*
|
|
11
|
-
*
|
|
11
|
+
* Falls back to the standard SignUp component when FingerprintProvider is absent.
|
|
12
|
+
* Handles fingerprint-related metadata when FingerprintProvider is available.
|
|
12
13
|
*/
|
|
13
14
|
function SignUpWithFingerprint() {
|
|
14
15
|
const fingerprintContext = useFingerprintContextSafe();
|
|
15
|
-
//
|
|
16
|
+
// Use defaults when fingerprint context is unavailable.
|
|
16
17
|
const { fingerprintId = null, xUser = null, isInitialized = false, initializeAnonymousUser = () => __awaiter(this, void 0, void 0, function* () { }) } = fingerprintContext || {};
|
|
17
|
-
//
|
|
18
|
+
// Prepare Clerk metadata with anonymous user information.
|
|
18
19
|
const unsafeMetadata = {
|
|
19
20
|
user_id: (xUser === null || xUser === void 0 ? void 0 : xUser.userId) || null,
|
|
20
21
|
fingerprint_id: fingerprintId || null,
|
|
21
22
|
};
|
|
22
|
-
//
|
|
23
|
+
// Ensure the anonymous user has been initialized.
|
|
23
24
|
useEffect(() => {
|
|
24
25
|
if (!isInitialized && fingerprintId) {
|
|
25
26
|
initializeAnonymousUser();
|
|
26
27
|
}
|
|
27
28
|
}, [fingerprintId, isInitialized, initializeAnonymousUser]);
|
|
28
|
-
return jsx(SignUp, { unsafeMetadata: unsafeMetadata });
|
|
29
|
+
return jsx(SignUp, { appearance: clerkAuthPageAppearance, unsafeMetadata: unsafeMetadata });
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
export { SignUpWithFingerprint };
|
|
@@ -159,7 +159,7 @@ function Mermaid({ chart, title, watermarkEnabled, watermarkText, handDrawn = tr
|
|
|
159
159
|
React.useEffect(() => {
|
|
160
160
|
if (!open)
|
|
161
161
|
return;
|
|
162
|
-
//
|
|
162
|
+
// Init default zoom out 400%
|
|
163
163
|
resetTransform();
|
|
164
164
|
const onGlobalWheel = (ev) => {
|
|
165
165
|
if (ev.ctrlKey || ev.metaKey) {
|
|
@@ -157,7 +157,7 @@ function Mermaid({ chart, title, watermarkEnabled, watermarkText, handDrawn = tr
|
|
|
157
157
|
useEffect(() => {
|
|
158
158
|
if (!open)
|
|
159
159
|
return;
|
|
160
|
-
//
|
|
160
|
+
// Init default zoom out 400%
|
|
161
161
|
resetTransform();
|
|
162
162
|
const onGlobalWheel = (ev) => {
|
|
163
163
|
if (ev.ctrlKey || ev.metaKey) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
interface FumaGithubInfoProps {
|
|
2
2
|
owner: string;
|
|
3
3
|
repo: string;
|
|
4
|
-
token?: string;
|
|
5
4
|
className?: string;
|
|
6
5
|
}
|
|
7
6
|
/**
|
|
@@ -14,5 +13,5 @@ interface FumaGithubInfoProps {
|
|
|
14
13
|
* - 🎨 Three states: loading, success, error
|
|
15
14
|
* - 💯 Not affected by network issues causing page crashes
|
|
16
15
|
*/
|
|
17
|
-
export declare function FumaGithubInfo({ owner, repo,
|
|
16
|
+
export declare function FumaGithubInfo({ owner, repo, className }: FumaGithubInfoProps): import("react/jsx-runtime").JSX.Element;
|
|
18
17
|
export {};
|
|
@@ -7,7 +7,7 @@ var React = require('react');
|
|
|
7
7
|
var icons = require('@windrun-huaiin/base-ui/icons');
|
|
8
8
|
|
|
9
9
|
// Loading state component
|
|
10
|
-
function GitHubInfoSkeleton({
|
|
10
|
+
function GitHubInfoSkeleton({ className }) {
|
|
11
11
|
return (jsxRuntime.jsxs("div", { className: `flex flex-col gap-1.5 p-2 rounded-lg text-sm text-fd-foreground/80 lg:flex-row lg:items-center animate-pulse ${className}`, children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx("div", { className: "size-3.5 bg-fd-muted rounded" }), jsxRuntime.jsx("div", { className: "h-4 bg-fd-muted rounded w-20" })] }), jsxRuntime.jsx("div", { className: "h-3 bg-fd-muted rounded w-8" })] }));
|
|
12
12
|
}
|
|
13
13
|
// Error state component - graceful fallback
|
|
@@ -46,7 +46,7 @@ function humanizeNumber(num) {
|
|
|
46
46
|
* - 🎨 Three states: loading, success, error
|
|
47
47
|
* - 💯 Not affected by network issues causing page crashes
|
|
48
48
|
*/
|
|
49
|
-
function FumaGithubInfo({ owner, repo,
|
|
49
|
+
function FumaGithubInfo({ owner, repo, className }) {
|
|
50
50
|
const [data, setData] = React.useState(null);
|
|
51
51
|
const [loading, setLoading] = React.useState(true);
|
|
52
52
|
const [error, setError] = React.useState(null);
|
|
@@ -61,9 +61,6 @@ function FumaGithubInfo({ owner, repo, token, className }) {
|
|
|
61
61
|
const headers = new Headers({
|
|
62
62
|
'Accept': 'application/vnd.github.v3+json',
|
|
63
63
|
});
|
|
64
|
-
if (token) {
|
|
65
|
-
headers.set('Authorization', `Bearer ${token}`);
|
|
66
|
-
}
|
|
67
64
|
const response = yield fetch(`https://api.github.com/repos/${owner}/${repo}`, {
|
|
68
65
|
signal: controller.signal,
|
|
69
66
|
headers,
|
|
@@ -97,7 +94,7 @@ function FumaGithubInfo({ owner, repo, token, className }) {
|
|
|
97
94
|
}
|
|
98
95
|
});
|
|
99
96
|
fetchRepoData();
|
|
100
|
-
}, [owner, repo
|
|
97
|
+
}, [owner, repo]);
|
|
101
98
|
// Loading state
|
|
102
99
|
if (loading) {
|
|
103
100
|
return jsxRuntime.jsx(GitHubInfoSkeleton, { owner: owner, repo: repo, className: className });
|