@windrun-huaiin/third-ui 11.1.0 → 12.0.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.
Files changed (37) hide show
  1. package/dist/clerk/clerk-optional-auth.d.ts +12 -0
  2. package/dist/clerk/clerk-optional-auth.js +33 -0
  3. package/dist/clerk/clerk-optional-auth.mjs +31 -0
  4. package/dist/clerk/clerk-provider-client.d.ts +3 -1
  5. package/dist/clerk/clerk-provider-client.js +22 -12
  6. package/dist/clerk/clerk-provider-client.mjs +22 -12
  7. package/dist/clerk/optional-auth.d.ts +12 -0
  8. package/dist/clerk/optional-auth.js +47 -0
  9. package/dist/clerk/optional-auth.mjs +45 -0
  10. package/dist/clerk/patch/optional-auth.d.ts +11 -0
  11. package/dist/clerk/patch/optional-auth.js +27 -0
  12. package/dist/clerk/patch/optional-auth.mjs +25 -0
  13. package/dist/fuma/base/custom-home-layout.d.ts +9 -1
  14. package/dist/fuma/base/custom-home-layout.js +2 -2
  15. package/dist/fuma/base/custom-home-layout.mjs +2 -2
  16. package/dist/fuma/fuma-page-genarator.d.ts +3 -1
  17. package/dist/fuma/fuma-page-genarator.js +8 -3
  18. package/dist/fuma/fuma-page-genarator.mjs +8 -3
  19. package/dist/lib/seo-util.d.ts +6 -2
  20. package/dist/lib/seo-util.js +21 -11
  21. package/dist/lib/seo-util.mjs +21 -11
  22. package/dist/main/credit/credit-overview-client.js +2 -2
  23. package/dist/main/credit/credit-overview-client.mjs +2 -2
  24. package/dist/main/footer-email.js +1 -1
  25. package/dist/main/footer-email.mjs +1 -1
  26. package/dist/main/footer.d.ts +6 -2
  27. package/dist/main/footer.js +3 -2
  28. package/dist/main/footer.mjs +3 -2
  29. package/package.json +8 -3
  30. package/src/clerk/clerk-provider-client.tsx +37 -12
  31. package/src/clerk/patch/optional-auth.ts +24 -0
  32. package/src/fuma/base/custom-home-layout.tsx +11 -1
  33. package/src/fuma/fuma-page-genarator.tsx +19 -4
  34. package/src/lib/seo-util.ts +27 -13
  35. package/src/main/credit/credit-overview-client.tsx +4 -4
  36. package/src/main/footer-email.tsx +1 -1
  37. package/src/main/footer.tsx +10 -3
@@ -0,0 +1,12 @@
1
+ import { auth } from '@clerk/nextjs/server';
2
+ export type OptionalAuthResult = {
3
+ userId: string | null;
4
+ sessionId: string | null;
5
+ raw: Awaited<ReturnType<typeof auth>> | null;
6
+ hasClerkHeader: boolean;
7
+ };
8
+ /**
9
+ * 安全的可选鉴权:调用 auth(),若缺少 Clerk 标记或其他原因抛错则兜底返回 null。
10
+ * 用于公开页/可选登录场景,避免因缺少中间件标记导致页面崩溃。
11
+ */
12
+ export declare function getOptionalAuth(): Promise<OptionalAuthResult>;
@@ -0,0 +1,33 @@
1
+ 'use strict';
2
+
3
+ var tslib_es6 = require('../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js');
4
+ var server = require('@clerk/nextjs/server');
5
+
6
+ /**
7
+ * 安全的可选鉴权:调用 auth(),若缺少 Clerk 标记或其他原因抛错则兜底返回 null。
8
+ * 用于公开页/可选登录场景,避免因缺少中间件标记导致页面崩溃。
9
+ */
10
+ function getOptionalAuth() {
11
+ return tslib_es6.__awaiter(this, void 0, void 0, function* () {
12
+ var _a, _b;
13
+ try {
14
+ const res = yield server.auth();
15
+ return {
16
+ userId: (_a = res.userId) !== null && _a !== void 0 ? _a : null,
17
+ sessionId: (_b = res.sessionId) !== null && _b !== void 0 ? _b : null,
18
+ raw: res,
19
+ hasClerkHeader: true,
20
+ };
21
+ }
22
+ catch (_c) {
23
+ return {
24
+ userId: null,
25
+ sessionId: null,
26
+ raw: null,
27
+ hasClerkHeader: false,
28
+ };
29
+ }
30
+ });
31
+ }
32
+
33
+ exports.getOptionalAuth = getOptionalAuth;
@@ -0,0 +1,31 @@
1
+ import { __awaiter } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.mjs';
2
+ import { auth } from '@clerk/nextjs/server';
3
+
4
+ /**
5
+ * 安全的可选鉴权:调用 auth(),若缺少 Clerk 标记或其他原因抛错则兜底返回 null。
6
+ * 用于公开页/可选登录场景,避免因缺少中间件标记导致页面崩溃。
7
+ */
8
+ function getOptionalAuth() {
9
+ return __awaiter(this, void 0, void 0, function* () {
10
+ var _a, _b;
11
+ try {
12
+ const res = yield auth();
13
+ return {
14
+ userId: (_a = res.userId) !== null && _a !== void 0 ? _a : null,
15
+ sessionId: (_b = res.sessionId) !== null && _b !== void 0 ? _b : null,
16
+ raw: res,
17
+ hasClerkHeader: true,
18
+ };
19
+ }
20
+ catch (_c) {
21
+ return {
22
+ userId: null,
23
+ sessionId: null,
24
+ raw: null,
25
+ hasClerkHeader: false,
26
+ };
27
+ }
28
+ });
29
+ }
30
+
31
+ export { getOptionalAuth };
@@ -2,11 +2,13 @@ import React from 'react';
2
2
  interface ClerkProviderClientProps {
3
3
  children: React.ReactNode;
4
4
  locale: string;
5
+ localPrefixAsNeeded?: boolean;
6
+ defaultLocale?: string;
5
7
  signInUrl?: string;
6
8
  signUpUrl?: string;
7
9
  fallbackSignInUrl?: string;
8
10
  fallbackSignUpUrl?: string;
9
11
  waitlistUrl?: string;
10
12
  }
11
- export declare function ClerkProviderClient({ children, locale, signInUrl, signUpUrl, fallbackSignInUrl, fallbackSignUpUrl, waitlistUrl, }: ClerkProviderClientProps): import("react/jsx-runtime").JSX.Element;
13
+ export declare function ClerkProviderClient({ children, locale, localPrefixAsNeeded, defaultLocale, signInUrl, signUpUrl, fallbackSignInUrl, fallbackSignUpUrl, waitlistUrl, }: ClerkProviderClientProps): import("react/jsx-runtime").JSX.Element;
12
14
  export {};
@@ -5,27 +5,37 @@ var jsxRuntime = require('react/jsx-runtime');
5
5
  var clerkIntl = require('../lib/clerk-intl.js');
6
6
  var nextjs = require('@clerk/nextjs');
7
7
 
8
- function ClerkProviderClient({ children, locale, signInUrl, signUpUrl, fallbackSignInUrl, fallbackSignUpUrl, waitlistUrl, }) {
9
- const currentLocalization = clerkIntl.clerkIntl[locale];
8
+ function ClerkProviderClient({ children, locale, localPrefixAsNeeded = true, defaultLocale = 'en', signInUrl, signUpUrl, fallbackSignInUrl, fallbackSignUpUrl, waitlistUrl, }) {
9
+ var _a, _b;
10
+ const currentLocalization = (_b = (_a = clerkIntl.clerkIntl[locale]) !== null && _a !== void 0 ? _a : clerkIntl.clerkIntl[defaultLocale]) !== null && _b !== void 0 ? _b : clerkIntl.clerkIntl.en;
11
+ // In as-needed mode, skip prefixing for the default locale so /sign-in stays unprefixed.
12
+ const shouldPrefixLocale = localPrefixAsNeeded ? locale !== defaultLocale : true;
13
+ const localeSegment = shouldPrefixLocale && locale ? `/${locale}` : '';
14
+ const buildUrl = (path) => path ? `${localeSegment}${path}` : undefined;
10
15
  // build the ClerkProvider props, only add when the parameter is not empty
11
16
  const clerkProviderProps = {
12
17
  localization: currentLocalization,
13
18
  };
14
19
  // Only add URL when the parameter is not empty
15
- if (signInUrl) {
16
- clerkProviderProps.signInUrl = `/${locale}${signInUrl}`;
20
+ const signInWithLocale = buildUrl(signInUrl);
21
+ if (signInWithLocale) {
22
+ clerkProviderProps.signInUrl = signInWithLocale;
17
23
  }
18
- if (signUpUrl) {
19
- clerkProviderProps.signUpUrl = `/${locale}${signUpUrl}`;
24
+ const signUpWithLocale = buildUrl(signUpUrl);
25
+ if (signUpWithLocale) {
26
+ clerkProviderProps.signUpUrl = signUpWithLocale;
20
27
  }
21
- if (fallbackSignInUrl) {
22
- clerkProviderProps.signInFallbackRedirectUrl = `/${locale}${fallbackSignInUrl}`;
28
+ const signInFallbackWithLocale = buildUrl(fallbackSignInUrl);
29
+ if (signInFallbackWithLocale) {
30
+ clerkProviderProps.signInFallbackRedirectUrl = signInFallbackWithLocale;
23
31
  }
24
- if (fallbackSignUpUrl) {
25
- clerkProviderProps.signUpFallbackRedirectUrl = `/${locale}${fallbackSignUpUrl}`;
32
+ const signUpFallbackWithLocale = buildUrl(fallbackSignUpUrl);
33
+ if (signUpFallbackWithLocale) {
34
+ clerkProviderProps.signUpFallbackRedirectUrl = signUpFallbackWithLocale;
26
35
  }
27
- if (waitlistUrl) {
28
- clerkProviderProps.waitlistUrl = `/${locale}${waitlistUrl}`;
36
+ const waitlistWithLocale = buildUrl(waitlistUrl);
37
+ if (waitlistWithLocale) {
38
+ clerkProviderProps.waitlistUrl = waitlistWithLocale;
29
39
  }
30
40
  // console.log('ClerkProviderClient props:', clerkProviderProps);
31
41
  return (jsxRuntime.jsx(nextjs.ClerkProvider, Object.assign({}, clerkProviderProps, { children: children })));
@@ -3,27 +3,37 @@ import { jsx } from 'react/jsx-runtime';
3
3
  import { clerkIntl } from '../lib/clerk-intl.mjs';
4
4
  import { ClerkProvider } from '@clerk/nextjs';
5
5
 
6
- function ClerkProviderClient({ children, locale, signInUrl, signUpUrl, fallbackSignInUrl, fallbackSignUpUrl, waitlistUrl, }) {
7
- const currentLocalization = clerkIntl[locale];
6
+ function ClerkProviderClient({ children, locale, localPrefixAsNeeded = true, defaultLocale = 'en', signInUrl, signUpUrl, fallbackSignInUrl, fallbackSignUpUrl, waitlistUrl, }) {
7
+ var _a, _b;
8
+ const currentLocalization = (_b = (_a = clerkIntl[locale]) !== null && _a !== void 0 ? _a : clerkIntl[defaultLocale]) !== null && _b !== void 0 ? _b : clerkIntl.en;
9
+ // In as-needed mode, skip prefixing for the default locale so /sign-in stays unprefixed.
10
+ const shouldPrefixLocale = localPrefixAsNeeded ? locale !== defaultLocale : true;
11
+ const localeSegment = shouldPrefixLocale && locale ? `/${locale}` : '';
12
+ const buildUrl = (path) => path ? `${localeSegment}${path}` : undefined;
8
13
  // build the ClerkProvider props, only add when the parameter is not empty
9
14
  const clerkProviderProps = {
10
15
  localization: currentLocalization,
11
16
  };
12
17
  // Only add URL when the parameter is not empty
13
- if (signInUrl) {
14
- clerkProviderProps.signInUrl = `/${locale}${signInUrl}`;
18
+ const signInWithLocale = buildUrl(signInUrl);
19
+ if (signInWithLocale) {
20
+ clerkProviderProps.signInUrl = signInWithLocale;
15
21
  }
16
- if (signUpUrl) {
17
- clerkProviderProps.signUpUrl = `/${locale}${signUpUrl}`;
22
+ const signUpWithLocale = buildUrl(signUpUrl);
23
+ if (signUpWithLocale) {
24
+ clerkProviderProps.signUpUrl = signUpWithLocale;
18
25
  }
19
- if (fallbackSignInUrl) {
20
- clerkProviderProps.signInFallbackRedirectUrl = `/${locale}${fallbackSignInUrl}`;
26
+ const signInFallbackWithLocale = buildUrl(fallbackSignInUrl);
27
+ if (signInFallbackWithLocale) {
28
+ clerkProviderProps.signInFallbackRedirectUrl = signInFallbackWithLocale;
21
29
  }
22
- if (fallbackSignUpUrl) {
23
- clerkProviderProps.signUpFallbackRedirectUrl = `/${locale}${fallbackSignUpUrl}`;
30
+ const signUpFallbackWithLocale = buildUrl(fallbackSignUpUrl);
31
+ if (signUpFallbackWithLocale) {
32
+ clerkProviderProps.signUpFallbackRedirectUrl = signUpFallbackWithLocale;
24
33
  }
25
- if (waitlistUrl) {
26
- clerkProviderProps.waitlistUrl = `/${locale}${waitlistUrl}`;
34
+ const waitlistWithLocale = buildUrl(waitlistUrl);
35
+ if (waitlistWithLocale) {
36
+ clerkProviderProps.waitlistUrl = waitlistWithLocale;
27
37
  }
28
38
  // console.log('ClerkProviderClient props:', clerkProviderProps);
29
39
  return (jsx(ClerkProvider, Object.assign({}, clerkProviderProps, { children: children })));
@@ -0,0 +1,12 @@
1
+ import { auth } from '@clerk/nextjs/server';
2
+ export type OptionalAuthResult = {
3
+ userId: string | null;
4
+ sessionId: string | null;
5
+ raw: Awaited<ReturnType<typeof auth>> | null;
6
+ hasClerkHeader: boolean;
7
+ };
8
+ /**
9
+ * 安全的可选鉴权:只有在请求头已包含 Clerk 标记时才调用 auth()。
10
+ * 用于公开页/可选登录场景,避免因缺少中间件标记导致 auth() 抛错。
11
+ */
12
+ export declare function getOptionalAuth(): Promise<OptionalAuthResult>;
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ var tslib_es6 = require('../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js');
4
+ var server = require('@clerk/nextjs/server');
5
+ var headers = require('next/headers');
6
+
7
+ /**
8
+ * 安全的可选鉴权:只有在请求头已包含 Clerk 标记时才调用 auth()。
9
+ * 用于公开页/可选登录场景,避免因缺少中间件标记导致 auth() 抛错。
10
+ */
11
+ function getOptionalAuth() {
12
+ return tslib_es6.__awaiter(this, void 0, void 0, function* () {
13
+ var _a, _b, _c;
14
+ const h = yield headers.headers();
15
+ const hasClerkHeader = Boolean(h.get('x-clerk-auth-status')) ||
16
+ Boolean(h.get('x-clerk-user-id')) ||
17
+ Boolean(h.get('authorization')) ||
18
+ Boolean((_a = h.get('cookie')) === null || _a === void 0 ? void 0 : _a.includes('__session'));
19
+ if (!hasClerkHeader) {
20
+ return {
21
+ userId: null,
22
+ sessionId: null,
23
+ raw: null,
24
+ hasClerkHeader: false,
25
+ };
26
+ }
27
+ try {
28
+ const res = yield server.auth();
29
+ return {
30
+ userId: (_b = res.userId) !== null && _b !== void 0 ? _b : null,
31
+ sessionId: (_c = res.sessionId) !== null && _c !== void 0 ? _c : null,
32
+ raw: res,
33
+ hasClerkHeader: true,
34
+ };
35
+ }
36
+ catch (_d) {
37
+ return {
38
+ userId: null,
39
+ sessionId: null,
40
+ raw: null,
41
+ hasClerkHeader: true,
42
+ };
43
+ }
44
+ });
45
+ }
46
+
47
+ exports.getOptionalAuth = getOptionalAuth;
@@ -0,0 +1,45 @@
1
+ import { __awaiter } from '../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.mjs';
2
+ import { auth } from '@clerk/nextjs/server';
3
+ import { headers } from 'next/headers';
4
+
5
+ /**
6
+ * 安全的可选鉴权:只有在请求头已包含 Clerk 标记时才调用 auth()。
7
+ * 用于公开页/可选登录场景,避免因缺少中间件标记导致 auth() 抛错。
8
+ */
9
+ function getOptionalAuth() {
10
+ return __awaiter(this, void 0, void 0, function* () {
11
+ var _a, _b, _c;
12
+ const h = yield headers();
13
+ const hasClerkHeader = Boolean(h.get('x-clerk-auth-status')) ||
14
+ Boolean(h.get('x-clerk-user-id')) ||
15
+ Boolean(h.get('authorization')) ||
16
+ Boolean((_a = h.get('cookie')) === null || _a === void 0 ? void 0 : _a.includes('__session'));
17
+ if (!hasClerkHeader) {
18
+ return {
19
+ userId: null,
20
+ sessionId: null,
21
+ raw: null,
22
+ hasClerkHeader: false,
23
+ };
24
+ }
25
+ try {
26
+ const res = yield auth();
27
+ return {
28
+ userId: (_b = res.userId) !== null && _b !== void 0 ? _b : null,
29
+ sessionId: (_c = res.sessionId) !== null && _c !== void 0 ? _c : null,
30
+ raw: res,
31
+ hasClerkHeader: true,
32
+ };
33
+ }
34
+ catch (_d) {
35
+ return {
36
+ userId: null,
37
+ sessionId: null,
38
+ raw: null,
39
+ hasClerkHeader: true,
40
+ };
41
+ }
42
+ });
43
+ }
44
+
45
+ export { getOptionalAuth };
@@ -0,0 +1,11 @@
1
+ import { auth } from '@clerk/nextjs/server';
2
+ export type OptionalAuthResult = {
3
+ userId: string | null;
4
+ sessionId: string | null;
5
+ raw: Awaited<ReturnType<typeof auth>> | null;
6
+ };
7
+ /**
8
+ * 可选鉴权:在缺少 Clerk 标记或未登录时返回 null,避免 auth() 抛错。
9
+ * 仅供服务端使用,请从 @third-ui/clerk/patch/optional-auth 导入。
10
+ */
11
+ export declare function getOptionalAuth(): Promise<OptionalAuthResult>;
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ var tslib_es6 = require('../../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js');
4
+ var server = require('@clerk/nextjs/server');
5
+
6
+ /**
7
+ * 可选鉴权:在缺少 Clerk 标记或未登录时返回 null,避免 auth() 抛错。
8
+ * 仅供服务端使用,请从 @third-ui/clerk/patch/optional-auth 导入。
9
+ */
10
+ function getOptionalAuth() {
11
+ return tslib_es6.__awaiter(this, void 0, void 0, function* () {
12
+ var _a, _b;
13
+ try {
14
+ const res = yield server.auth();
15
+ return {
16
+ userId: (_a = res.userId) !== null && _a !== void 0 ? _a : null,
17
+ sessionId: (_b = res.sessionId) !== null && _b !== void 0 ? _b : null,
18
+ raw: res,
19
+ };
20
+ }
21
+ catch (_c) {
22
+ return { userId: null, sessionId: null, raw: null };
23
+ }
24
+ });
25
+ }
26
+
27
+ exports.getOptionalAuth = getOptionalAuth;
@@ -0,0 +1,25 @@
1
+ import { __awaiter } from '../../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.mjs';
2
+ import { auth } from '@clerk/nextjs/server';
3
+
4
+ /**
5
+ * 可选鉴权:在缺少 Clerk 标记或未登录时返回 null,避免 auth() 抛错。
6
+ * 仅供服务端使用,请从 @third-ui/clerk/patch/optional-auth 导入。
7
+ */
8
+ function getOptionalAuth() {
9
+ return __awaiter(this, void 0, void 0, function* () {
10
+ var _a, _b;
11
+ try {
12
+ const res = yield auth();
13
+ return {
14
+ userId: (_a = res.userId) !== null && _a !== void 0 ? _a : null,
15
+ sessionId: (_b = res.sessionId) !== null && _b !== void 0 ? _b : null,
16
+ raw: res,
17
+ };
18
+ }
19
+ catch (_c) {
20
+ return { userId: null, sessionId: null, raw: null };
21
+ }
22
+ });
23
+ }
24
+
25
+ export { getOptionalAuth };
@@ -72,6 +72,14 @@ export interface CustomHomeLayoutProps {
72
72
  * Customize the order of header action items.
73
73
  */
74
74
  actionOrders?: HeaderActionOrders;
75
+ /**
76
+ * Whether localePrefix is set to 'as-needed' (default: true)
77
+ */
78
+ localPrefixAsNeeded?: boolean;
79
+ /**
80
+ * The default locale for the application (default: 'en')
81
+ */
82
+ defaultLocale?: string;
75
83
  children?: ReactNode;
76
84
  }
77
85
  export interface HeaderActionOrders {
@@ -79,7 +87,7 @@ export interface HeaderActionOrders {
79
87
  mobileBar?: MobileBarAction[];
80
88
  mobileMenu?: MobileMenuAction[];
81
89
  }
82
- export declare function CustomHomeLayout({ locale, options, children, showBanner, bannerHeight, headerHeight, headerPaddingTop, navbarClassName, banner, footer, goToTop, showFooter, showGoToTop, style, floatingNav, actionOrders, }: CustomHomeLayoutProps): import("react/jsx-runtime").JSX.Element;
90
+ export declare function CustomHomeLayout({ locale, options, children, showBanner, bannerHeight, headerHeight, headerPaddingTop, navbarClassName, banner, footer, goToTop, showFooter, showGoToTop, style, floatingNav, actionOrders, localPrefixAsNeeded, defaultLocale, }: CustomHomeLayoutProps): import("react/jsx-runtime").JSX.Element;
83
91
  export declare function HomeTitle({ children, className, }: {
84
92
  children: ReactNode;
85
93
  className?: string;
@@ -8,7 +8,7 @@ var footer = require('../../main/footer.js');
8
8
  var goToTop = require('../../main/go-to-top.js');
9
9
  var customHeader = require('./custom-header.js');
10
10
 
11
- function CustomHomeLayout({ locale, options, children, showBanner = false, bannerHeight, headerHeight = 2.5, headerPaddingTop, navbarClassName, banner, footer: footer$1, goToTop: goToTop$1, showFooter = true, showGoToTop = true, style, floatingNav = false, actionOrders, }) {
11
+ function CustomHomeLayout({ locale, options, children, showBanner = false, bannerHeight, headerHeight = 2.5, headerPaddingTop, navbarClassName, banner, footer: footer$1, goToTop: goToTop$1, showFooter = true, showGoToTop = true, style, floatingNav = false, actionOrders, localPrefixAsNeeded = true, defaultLocale = 'en', }) {
12
12
  const resolvedBannerHeight = bannerHeight !== null && bannerHeight !== void 0 ? bannerHeight : (showBanner ? 3 : 0.5);
13
13
  const resolvedPaddingTop = headerPaddingTop !== null && headerPaddingTop !== void 0 ? headerPaddingTop : (showBanner ? 0 : 0.5);
14
14
  const layoutStyle = Object.assign({ '--fd-banner-height': `${resolvedBannerHeight}rem`, '--fd-nav-height': `${headerHeight}rem`, paddingTop: floatingNav
@@ -17,7 +17,7 @@ function CustomHomeLayout({ locale, options, children, showBanner = false, banne
17
17
  const { nav } = options, homeLayoutProps = tslib_es6.__rest(options, ["nav"]);
18
18
  const navOptions = nav !== null && nav !== void 0 ? nav : {};
19
19
  const header = (jsxRuntime.jsx(customHeader.CustomHomeHeader, Object.assign({}, homeLayoutProps, { nav: navOptions, bannerHeight: resolvedBannerHeight, headerHeight: headerHeight, navbarClassName: navbarClassName, floating: floatingNav, desktopActionsOrder: actionOrders === null || actionOrders === void 0 ? void 0 : actionOrders.desktop, mobileBarActionsOrder: actionOrders === null || actionOrders === void 0 ? void 0 : actionOrders.mobileBar, mobileMenuActionsOrder: actionOrders === null || actionOrders === void 0 ? void 0 : actionOrders.mobileMenu })));
20
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [banner !== null && banner !== void 0 ? banner : (jsxRuntime.jsx(fumaBannerSuit.FumaBannerSuit, { locale: locale, showBanner: showBanner, floating: floatingNav })), jsxRuntime.jsxs(home.HomeLayout, Object.assign({}, homeLayoutProps, { nav: Object.assign(Object.assign({}, navOptions), { component: header }), className: 'bg-neutral-100 dark:bg-neutral-900', style: layoutStyle, children: [children, showFooter ? footer$1 !== null && footer$1 !== void 0 ? footer$1 : jsxRuntime.jsx(footer.Footer, { locale: locale }) : null, showGoToTop ? goToTop$1 !== null && goToTop$1 !== void 0 ? goToTop$1 : jsxRuntime.jsx(goToTop.GoToTop, {}) : null] }))] }));
20
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [banner !== null && banner !== void 0 ? banner : (jsxRuntime.jsx(fumaBannerSuit.FumaBannerSuit, { locale: locale, showBanner: showBanner, floating: floatingNav })), jsxRuntime.jsxs(home.HomeLayout, Object.assign({}, homeLayoutProps, { nav: Object.assign(Object.assign({}, navOptions), { component: header }), className: 'bg-neutral-100 dark:bg-neutral-900', style: layoutStyle, children: [children, showFooter ? footer$1 !== null && footer$1 !== void 0 ? footer$1 : jsxRuntime.jsx(footer.Footer, { locale: locale, localPrefixAsNeeded: localPrefixAsNeeded, defaultLocale: defaultLocale }) : null, showGoToTop ? goToTop$1 !== null && goToTop$1 !== void 0 ? goToTop$1 : jsxRuntime.jsx(goToTop.GoToTop, {}) : null] }))] }));
21
21
  }
22
22
  function HomeTitle({ children, className, }) {
23
23
  return (jsxRuntime.jsx("span", { className: `font-medium in-[.uwu]:hidden in-[header]:text-[clamp(12px,3vw,15px)]! ${className !== null && className !== void 0 ? className : ''}`, children: children }));
@@ -6,7 +6,7 @@ import { Footer } from '../../main/footer.mjs';
6
6
  import { GoToTop } from '../../main/go-to-top.mjs';
7
7
  import { CustomHomeHeader } from './custom-header.mjs';
8
8
 
9
- function CustomHomeLayout({ locale, options, children, showBanner = false, bannerHeight, headerHeight = 2.5, headerPaddingTop, navbarClassName, banner, footer, goToTop, showFooter = true, showGoToTop = true, style, floatingNav = false, actionOrders, }) {
9
+ function CustomHomeLayout({ locale, options, children, showBanner = false, bannerHeight, headerHeight = 2.5, headerPaddingTop, navbarClassName, banner, footer, goToTop, showFooter = true, showGoToTop = true, style, floatingNav = false, actionOrders, localPrefixAsNeeded = true, defaultLocale = 'en', }) {
10
10
  const resolvedBannerHeight = bannerHeight !== null && bannerHeight !== void 0 ? bannerHeight : (showBanner ? 3 : 0.5);
11
11
  const resolvedPaddingTop = headerPaddingTop !== null && headerPaddingTop !== void 0 ? headerPaddingTop : (showBanner ? 0 : 0.5);
12
12
  const layoutStyle = Object.assign({ '--fd-banner-height': `${resolvedBannerHeight}rem`, '--fd-nav-height': `${headerHeight}rem`, paddingTop: floatingNav
@@ -15,7 +15,7 @@ function CustomHomeLayout({ locale, options, children, showBanner = false, banne
15
15
  const { nav } = options, homeLayoutProps = __rest(options, ["nav"]);
16
16
  const navOptions = nav !== null && nav !== void 0 ? nav : {};
17
17
  const header = (jsx(CustomHomeHeader, Object.assign({}, homeLayoutProps, { nav: navOptions, bannerHeight: resolvedBannerHeight, headerHeight: headerHeight, navbarClassName: navbarClassName, floating: floatingNav, desktopActionsOrder: actionOrders === null || actionOrders === void 0 ? void 0 : actionOrders.desktop, mobileBarActionsOrder: actionOrders === null || actionOrders === void 0 ? void 0 : actionOrders.mobileBar, mobileMenuActionsOrder: actionOrders === null || actionOrders === void 0 ? void 0 : actionOrders.mobileMenu })));
18
- return (jsxs(Fragment, { children: [banner !== null && banner !== void 0 ? banner : (jsx(FumaBannerSuit, { locale: locale, showBanner: showBanner, floating: floatingNav })), jsxs(HomeLayout, Object.assign({}, homeLayoutProps, { nav: Object.assign(Object.assign({}, navOptions), { component: header }), className: 'bg-neutral-100 dark:bg-neutral-900', style: layoutStyle, children: [children, showFooter ? footer !== null && footer !== void 0 ? footer : jsx(Footer, { locale: locale }) : null, showGoToTop ? goToTop !== null && goToTop !== void 0 ? goToTop : jsx(GoToTop, {}) : null] }))] }));
18
+ return (jsxs(Fragment, { children: [banner !== null && banner !== void 0 ? banner : (jsx(FumaBannerSuit, { locale: locale, showBanner: showBanner, floating: floatingNav })), jsxs(HomeLayout, Object.assign({}, homeLayoutProps, { nav: Object.assign(Object.assign({}, navOptions), { component: header }), className: 'bg-neutral-100 dark:bg-neutral-900', style: layoutStyle, children: [children, showFooter ? footer !== null && footer !== void 0 ? footer : jsx(Footer, { locale: locale, localPrefixAsNeeded: localPrefixAsNeeded, defaultLocale: defaultLocale }) : null, showGoToTop ? goToTop !== null && goToTop !== void 0 ? goToTop : jsx(GoToTop, {}) : null] }))] }));
19
19
  }
20
20
  function HomeTitle({ children, className, }) {
21
21
  return (jsx("span", { className: `font-medium in-[.uwu]:hidden in-[header]:text-[clamp(12px,3vw,15px)]! ${className !== null && className !== void 0 ? className : ''}`, children: children }));
@@ -15,8 +15,10 @@ interface FumaPageParams {
15
15
  showBreadcrumb?: boolean;
16
16
  showTableOfContent?: boolean;
17
17
  showTableOfContentPopover?: boolean;
18
+ localPrefixAsNeeded?: boolean;
19
+ defaultLocale?: string;
18
20
  }
19
- export declare function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, siteIcon, FallbackPage, supportedLocales, showBreadcrumb, showTableOfContent, showTableOfContentPopover, }: FumaPageParams): {
21
+ export declare function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, siteIcon, FallbackPage, supportedLocales, showBreadcrumb, showTableOfContent, showTableOfContentPopover, localPrefixAsNeeded, defaultLocale, }: FumaPageParams): {
20
22
  Page: ({ params }: {
21
23
  params: Promise<{
22
24
  locale: string;
@@ -5,13 +5,16 @@ var jsxRuntime = require('react/jsx-runtime');
5
5
  var page = require('fumadocs-ui/page');
6
6
  var React = require('react');
7
7
  var tocFooterWrapper = require('./mdx/toc-footer-wrapper.js');
8
+ var lib = require('@windrun-huaiin/lib');
8
9
 
9
- function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, siteIcon, FallbackPage, supportedLocales = ['en'], showBreadcrumb = true, showTableOfContent = true, showTableOfContentPopover = false, }) {
10
+ function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, siteIcon, FallbackPage, supportedLocales = ['en'], showBreadcrumb = true, showTableOfContent = true, showTableOfContentPopover = false, localPrefixAsNeeded = true, defaultLocale = 'en', }) {
10
11
  const Page = function Page(_a) {
11
12
  return tslib_es6.__awaiter(this, arguments, void 0, function* ({ params }) {
13
+ var _b, _c, _d;
12
14
  const { slug, locale } = yield params;
13
15
  const page$1 = mdxContentSource.getPage(slug, locale);
14
16
  if (!page$1) {
17
+ console.log('[FumaPage] missing page', { slug, locale, available: (_d = (_c = (_b = mdxContentSource.pageTree) === null || _b === void 0 ? void 0 : _b[locale]) === null || _c === void 0 ? void 0 : _c.children) === null || _d === void 0 ? void 0 : _d.map((c) => c.url) });
15
18
  return jsxRuntime.jsx(FallbackPage, { siteIcon: siteIcon });
16
19
  }
17
20
  const path = githubBaseUrl ? `${mdxSourceDir}/${page$1.path}` : undefined;
@@ -47,11 +50,13 @@ function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSour
47
50
  const baseRoute = mdxSourceDir.replace('src/mdx/', '');
48
51
  // build the current page path
49
52
  const currentPath = slug ? slug.join('/') : '';
50
- const currentUrl = `${baseUrl}/${locale}/${baseRoute}${currentPath ? `/${currentPath}` : ''}`;
53
+ const localizedPath = lib.getAsNeededLocalizedUrl(locale || defaultLocale, `/${baseRoute}${currentPath ? `/${currentPath}` : ''}`, localPrefixAsNeeded, defaultLocale);
54
+ const currentUrl = `${baseUrl}${localizedPath}`;
51
55
  // generate the seo language map
52
56
  const seoLanguageMap = {};
53
57
  supportedLocales.forEach(loc => {
54
- seoLanguageMap[loc] = `${baseUrl}/${loc}/${baseRoute}${currentPath ? `/${currentPath}` : ''}`;
58
+ const seoPath = lib.getAsNeededLocalizedUrl(loc, `/${baseRoute}${currentPath ? `/${currentPath}` : ''}`, localPrefixAsNeeded, defaultLocale);
59
+ seoLanguageMap[loc] = `${baseUrl}${seoPath}`;
55
60
  });
56
61
  return {
57
62
  metadataBase: new URL(baseUrl),
@@ -3,13 +3,16 @@ import { jsx, jsxs } from 'react/jsx-runtime';
3
3
  import { DocsPage, DocsTitle, DocsDescription, DocsBody } from 'fumadocs-ui/page';
4
4
  import { cloneElement } from 'react';
5
5
  import { TocFooterWrapper } from './mdx/toc-footer-wrapper.mjs';
6
+ import { getAsNeededLocalizedUrl } from '@windrun-huaiin/lib';
6
7
 
7
- function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, siteIcon, FallbackPage, supportedLocales = ['en'], showBreadcrumb = true, showTableOfContent = true, showTableOfContentPopover = false, }) {
8
+ function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, siteIcon, FallbackPage, supportedLocales = ['en'], showBreadcrumb = true, showTableOfContent = true, showTableOfContentPopover = false, localPrefixAsNeeded = true, defaultLocale = 'en', }) {
8
9
  const Page = function Page(_a) {
9
10
  return __awaiter(this, arguments, void 0, function* ({ params }) {
11
+ var _b, _c, _d;
10
12
  const { slug, locale } = yield params;
11
13
  const page = mdxContentSource.getPage(slug, locale);
12
14
  if (!page) {
15
+ console.log('[FumaPage] missing page', { slug, locale, available: (_d = (_c = (_b = mdxContentSource.pageTree) === null || _b === void 0 ? void 0 : _b[locale]) === null || _c === void 0 ? void 0 : _c.children) === null || _d === void 0 ? void 0 : _d.map((c) => c.url) });
13
16
  return jsx(FallbackPage, { siteIcon: siteIcon });
14
17
  }
15
18
  const path = githubBaseUrl ? `${mdxSourceDir}/${page.path}` : undefined;
@@ -45,11 +48,13 @@ function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSour
45
48
  const baseRoute = mdxSourceDir.replace('src/mdx/', '');
46
49
  // build the current page path
47
50
  const currentPath = slug ? slug.join('/') : '';
48
- const currentUrl = `${baseUrl}/${locale}/${baseRoute}${currentPath ? `/${currentPath}` : ''}`;
51
+ const localizedPath = getAsNeededLocalizedUrl(locale || defaultLocale, `/${baseRoute}${currentPath ? `/${currentPath}` : ''}`, localPrefixAsNeeded, defaultLocale);
52
+ const currentUrl = `${baseUrl}${localizedPath}`;
49
53
  // generate the seo language map
50
54
  const seoLanguageMap = {};
51
55
  supportedLocales.forEach(loc => {
52
- seoLanguageMap[loc] = `${baseUrl}/${loc}/${baseRoute}${currentPath ? `/${currentPath}` : ''}`;
56
+ const seoPath = getAsNeededLocalizedUrl(loc, `/${baseRoute}${currentPath ? `/${currentPath}` : ''}`, localPrefixAsNeeded, defaultLocale);
57
+ seoLanguageMap[loc] = `${baseUrl}${seoPath}`;
53
58
  });
54
59
  return {
55
60
  metadataBase: new URL(baseUrl),
@@ -11,9 +11,11 @@ export declare function generateRobots(baseUrl: string): MetadataRoute.Robots;
11
11
  * @param locales - Supported locales array
12
12
  * @param mdxSourceDir - MDX source directory path
13
13
  * @param openMdxSEOSiteMap - Whether to include MDX content in sitemap, default is true
14
+ * @param localPrefixAsNeeded - Whether localePrefix is set to 'as-needed' (default: true)
15
+ * @param defaultLocale - The default locale for the application (default: 'en')
14
16
  * @returns Sitemap entries
15
17
  */
16
- export declare function generateSitemap(baseUrl: string, locales: string[], mdxSourceDir: string, openMdxSEOSiteMap?: boolean): MetadataRoute.Sitemap;
18
+ export declare function generateSitemap(baseUrl: string, locales: string[], mdxSourceDir: string, openMdxSEOSiteMap?: boolean, localPrefixAsNeeded?: boolean, defaultLocale?: string): MetadataRoute.Sitemap;
17
19
  /**
18
20
  * Create robots.txt handler function
19
21
  * @param baseUrl - The base URL of the website
@@ -26,6 +28,8 @@ export declare function createRobotsHandler(baseUrl: string): () => MetadataRout
26
28
  * @param locales - Supported locales array
27
29
  * @param mdxSourceDir - MDX source directory path, default is empty
28
30
  * @param openMdxSEOSiteMap - Whether to include MDX content in sitemap, default is true
31
+ * @param localPrefixAsNeeded - Whether localePrefix is set to 'as-needed' (default: true)
32
+ * @param defaultLocale - The default locale for the application (default: 'en')
29
33
  * @returns Sitemap handler function
30
34
  */
31
- export declare function createSitemapHandler(baseUrl: string, locales: string[], mdxSourceDir?: string, openMdxSEOSiteMap?: boolean): () => MetadataRoute.Sitemap;
35
+ export declare function createSitemapHandler(baseUrl: string, locales: string[], mdxSourceDir?: string, openMdxSEOSiteMap?: boolean, localPrefixAsNeeded?: boolean, defaultLocale?: string): () => MetadataRoute.Sitemap;
@@ -2,6 +2,7 @@
2
2
 
3
3
  var fs = require('fs');
4
4
  var path = require('path');
5
+ var lib = require('@windrun-huaiin/lib');
5
6
 
6
7
  /**
7
8
  * Generate robots.txt content
@@ -23,9 +24,11 @@ function generateRobots(baseUrl) {
23
24
  * @param locales - Supported locales array
24
25
  * @param mdxSourceDir - MDX source directory path
25
26
  * @param openMdxSEOSiteMap - Whether to include MDX content in sitemap, default is true
27
+ * @param localPrefixAsNeeded - Whether localePrefix is set to 'as-needed' (default: true)
28
+ * @param defaultLocale - The default locale for the application (default: 'en')
26
29
  * @returns Sitemap entries
27
30
  */
28
- function generateSitemap(baseUrl, locales, mdxSourceDir, openMdxSEOSiteMap = true) {
31
+ function generateSitemap(baseUrl, locales, mdxSourceDir, openMdxSEOSiteMap = true, localPrefixAsNeeded = true, defaultLocale = 'en') {
29
32
  // 2. handle index.mdx (blog start page) and other slugs
30
33
  const blogRoutes = [];
31
34
  // 1. read all blog mdx file names with error handling
@@ -38,8 +41,9 @@ function generateSitemap(baseUrl, locales, mdxSourceDir, openMdxSEOSiteMap = tru
38
41
  for (const locale of locales) {
39
42
  for (const f of blogFiles) {
40
43
  if (f === 'index.mdx') {
44
+ const localizedPath = lib.getAsNeededLocalizedUrl(locale, '/blog', localPrefixAsNeeded, defaultLocale);
41
45
  blogRoutes.push({
42
- url: `${baseUrl}/${locale}/blog`,
46
+ url: `${baseUrl}${localizedPath}`,
43
47
  lastModified: new Date(),
44
48
  changeFrequency: 'daily',
45
49
  priority: 1.0
@@ -47,8 +51,9 @@ function generateSitemap(baseUrl, locales, mdxSourceDir, openMdxSEOSiteMap = tru
47
51
  }
48
52
  else {
49
53
  const slug = f.replace(/\.mdx$/, '');
54
+ const localizedPath = lib.getAsNeededLocalizedUrl(locale, `/blog/${slug}`, localPrefixAsNeeded, defaultLocale);
50
55
  blogRoutes.push({
51
- url: `${baseUrl}/${locale}/blog/${slug}`,
56
+ url: `${baseUrl}${localizedPath}`,
52
57
  lastModified: new Date(),
53
58
  changeFrequency: f === 'ioc.mdx' ? 'daily' : 'monthly',
54
59
  priority: 0.8
@@ -64,12 +69,15 @@ function generateSitemap(baseUrl, locales, mdxSourceDir, openMdxSEOSiteMap = tru
64
69
  }
65
70
  }
66
71
  // 3. main page (all language versions)
67
- const mainRoutes = locales.map(locale => ({
68
- url: `${baseUrl}/${locale}`,
69
- lastModified: new Date(),
70
- changeFrequency: 'weekly',
71
- priority: 1.0
72
- }));
72
+ const mainRoutes = locales.map(locale => {
73
+ const localizedPath = lib.getAsNeededLocalizedUrl(locale, '/', localPrefixAsNeeded, defaultLocale);
74
+ return {
75
+ url: `${baseUrl}${localizedPath}`,
76
+ lastModified: new Date(),
77
+ changeFrequency: 'weekly',
78
+ priority: 1.0
79
+ };
80
+ });
73
81
  return openMdxSEOSiteMap ? [...mainRoutes, ...blogRoutes] : [...mainRoutes];
74
82
  }
75
83
  /**
@@ -88,12 +96,14 @@ function createRobotsHandler(baseUrl) {
88
96
  * @param locales - Supported locales array
89
97
  * @param mdxSourceDir - MDX source directory path, default is empty
90
98
  * @param openMdxSEOSiteMap - Whether to include MDX content in sitemap, default is true
99
+ * @param localPrefixAsNeeded - Whether localePrefix is set to 'as-needed' (default: true)
100
+ * @param defaultLocale - The default locale for the application (default: 'en')
91
101
  * @returns Sitemap handler function
92
102
  */
93
- function createSitemapHandler(baseUrl, locales, mdxSourceDir = '', openMdxSEOSiteMap = true) {
103
+ function createSitemapHandler(baseUrl, locales, mdxSourceDir = '', openMdxSEOSiteMap = true, localPrefixAsNeeded = true, defaultLocale = 'en') {
94
104
  // force static generation
95
105
  const sitemapHandler = function sitemap() {
96
- return generateSitemap(baseUrl, locales, mdxSourceDir, openMdxSEOSiteMap);
106
+ return generateSitemap(baseUrl, locales, mdxSourceDir, openMdxSEOSiteMap, localPrefixAsNeeded, defaultLocale);
97
107
  };
98
108
  // Add static generation directive
99
109
  sitemapHandler.dynamic = 'force-static';