cloudflare-next-intl 0.10.20 → 0.10.22
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 +1 -1
- package/dist/src/client/components/client_provider.d.ts +2 -6
- package/dist/src/client/components/client_provider.js +3 -2
- package/dist/src/client/components/locale_provider.d.ts +13 -0
- package/dist/src/client/components/locale_provider.js +8 -0
- package/dist/src/firebase_auth/client/auth_user_provider.js +8 -3
- package/dist/src/firebase_auth/client/firebase_client.js +7 -13
- package/dist/src/firebase_auth/middleware/update_session.js +1 -1
- package/dist/src/server/components/server_provider.js +2 -1
- package/dist/src/vite/vinext_route_wiring_fix.js +11 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -516,7 +516,7 @@ Features include:
|
|
|
516
516
|
- `createForgotPasswordAction(locale, actionCodeSettings?)`: Accepts optional Firebase `AuthActionCodeSettings` (e.g. `url` redirect link).
|
|
517
517
|
- `sendVerificationEmail(actionCodeSettings?)` on `useAuthUser()`: Custom action email settings when resending email verification.
|
|
518
518
|
- `followSameOriginContinueUrl`: Automatically forwards emailed action links with `continueUrl` to the specified path (or external URL) directly from `intlMiddleware` (default `true`; set `false` on `firebaseAuth` config to disable). If `continueUrl` points to home root (`/`), it resolves to `actionLinkPath` (if set) or the mode target path (e.g. `/reset-password`).
|
|
519
|
-
- `appCheck`: Firebase App Check integration supporting reCAPTCHA Enterprise (`recaptchaEnterpriseSiteKey`) and reCAPTCHA v3 (`recaptchaV3SiteKey`). For reCAPTCHA v3, defaults to a `CustomProvider` using an explicit `render=explicit` script tag to avoid iframe/webworker CDN integrity issues in private windows (`useExplicitRecaptchaScript: false` to opt out). When `appCheck` is configured, `getFirebaseAuthClient()`
|
|
519
|
+
- `appCheck`: Firebase App Check integration supporting reCAPTCHA Enterprise (`recaptchaEnterpriseSiteKey`) and reCAPTCHA v3 (`recaptchaV3SiteKey`). For reCAPTCHA v3, defaults to a `CustomProvider` using an explicit `render=explicit` script tag to avoid iframe/webworker CDN integrity issues in private windows (`useExplicitRecaptchaScript: false` to opt out). When `appCheck` is configured, `getFirebaseAuthClient()` initializes App Check before it creates `auth`, so every request made through `auth` carries an `X-Firebase-AppCheck` header and passes App Check enforcement. That includes the `accounts:lookup` call Firebase makes on page load to restore a signed-in user, as well as sign-in. The trade-off: App Check (and, with token auto-refresh on, the reCAPTCHA script) now starts on the first `getFirebaseAuthClient()` call instead of the first token mint. If App Check initialization fails, the client is still returned, just without App Check. Supports server-side token minting via service accounts.
|
|
520
520
|
- `resolveOptionalAuthUser()` (`cloudflare-next-intl/resolveOptionalAuthUser`): best-effort variant of `getAuthUser()` for callers that want to *attach* the current user when one happens to be known — error/telemetry reporting, analytics, logging — without failing or changing behavior when no request/session context is available. Swallows every failure and resolves `{ user: null }` instead of throwing. Use `getAuthUser()` (not this) whenever your own output actually depends on who's signed in — `checkDynamicPages` (below) treats `getAuthUser()`/`useAuthUser()`/`withUserDb()` as page-blocking dynamic-API signals but does not follow into this helper, so it's also the way to read "whoever's signed in, if anyone" from a page or a module it imports without forcing that page dynamic.
|
|
521
521
|
- `resolveErrorReportingUser(useAuthUser?)` (same subpath): gated form of `resolveOptionalAuthUser()` for an `onError` sink — pass `ErrorHandlingParams.useAuthUser` straight through. Defaults to `false`: when not `true`, resolves `{ user: null }` immediately without calling `getAuthUser()` at all, so a page reached only through your `onError` sink's default path stays static-eligible. A specific `reportError({ ..., useAuthUser: true })` call site opts in per-call when it actually wants the user on that report.
|
|
522
522
|
|
|
@@ -3,11 +3,8 @@ import type { SerializedAuthUser } from "../../firebase_auth/types.js";
|
|
|
3
3
|
import type { CookieConsentAnalyticsConfig, AutoAnalyticsEventsConfig } from "../../types/types.js";
|
|
4
4
|
import type { CookieConsentDialogProps } from "../../cookie_consent/client/components/cookie_consent_dialog.js";
|
|
5
5
|
import type { PrivacyPolicyUpdateDialogProps } from "../../cookie_consent/client/components/privacy_policy_update_dialog.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
messages: TranslationObject;
|
|
9
|
-
}
|
|
10
|
-
export declare const LocaleContext: import("react").Context<LocaleContextType | undefined>;
|
|
6
|
+
import { LocaleContext } from "./locale_provider.js";
|
|
7
|
+
export { LocaleContext };
|
|
11
8
|
export default function LocationzationClientProvider({ language, messages, initialAuthUser, skipAuthProvider, analyticsConfig, autoAnalyticsEventsConfig, requiresConsent, autoWireDialogs, dialogProps, updateDialogProps, children }: {
|
|
12
9
|
language: string;
|
|
13
10
|
messages: TranslationObject;
|
|
@@ -21,4 +18,3 @@ export default function LocationzationClientProvider({ language, messages, initi
|
|
|
21
18
|
updateDialogProps?: PrivacyPolicyUpdateDialogProps;
|
|
22
19
|
children: React.ReactNode;
|
|
23
20
|
}): Component;
|
|
24
|
-
export {};
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { setLocaleCache, setMessageForLocaleCache } from "../../general/cache_variables.js";
|
|
4
|
-
import {
|
|
4
|
+
import { useEffect, useMemo, Suspense } from "react";
|
|
5
5
|
import dynamic from "next/dynamic.js";
|
|
6
6
|
import useLazyWrappingProvider from "./use_lazy_wrapping_provider.js";
|
|
7
7
|
import config from "@intl-config";
|
|
8
8
|
import installConsoleErrorOverride from "../../error_handling/install_console_error_override.js";
|
|
9
9
|
import installGlobalErrorOverride from "../../error_handling/install_global_error_override.js";
|
|
10
10
|
import AuthUserPendingProvider from "../../firebase_auth/client/auth_user_pending_provider.js";
|
|
11
|
-
|
|
11
|
+
import { LocaleContext } from "./locale_provider.js";
|
|
12
|
+
export { LocaleContext };
|
|
12
13
|
const loadAuthUserProvider = () => import("../../firebase_auth/client/auth_user_provider.js");
|
|
13
14
|
const AutoFirebasePerformanceEvents = dynamic(() => import("../../firebase_auth/client/components/auto_firebase_performance_events.js"));
|
|
14
15
|
const loadCookieConsentProvider = () => import("../../cookie_consent/client/cookie_consent_provider.js");
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { TranslationObject } from "../../types/types.js";
|
|
3
|
+
interface LocaleContextType {
|
|
4
|
+
language: string;
|
|
5
|
+
messages: TranslationObject;
|
|
6
|
+
}
|
|
7
|
+
export declare const LocaleContext: import("react").Context<LocaleContextType | undefined>;
|
|
8
|
+
export default function LocaleProvider({ language, messages, children }: {
|
|
9
|
+
language: string;
|
|
10
|
+
messages: TranslationObject;
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}): React.JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useMemo } from "react";
|
|
4
|
+
export const LocaleContext = createContext(undefined);
|
|
5
|
+
export default function LocaleProvider({ language, messages, children }) {
|
|
6
|
+
const value = useMemo(() => ({ language, messages }), [language, messages]);
|
|
7
|
+
return _jsx(LocaleContext.Provider, { value: value, children: children });
|
|
8
|
+
}
|
|
@@ -49,11 +49,13 @@ async function writeAppCheckTokenCookie(appCheckTokenCookieName, maxAge) {
|
|
|
49
49
|
console.error('AuthUserProvider: App Check token cookie sync failed', e);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
async function clearSession(sessionCookieName, refreshTokenCookieName, emailVerifiedHintCookieName, appCheckTokenCookieName, refreshTokenMaxAge) {
|
|
52
|
+
async function clearSession(sessionCookieName, refreshTokenCookieName, emailVerifiedHintCookieName, appCheckTokenCookieName, refreshTokenMaxAge, clearServerCookies = true) {
|
|
53
53
|
clearSessionCookie(sessionCookieName);
|
|
54
54
|
clearRefreshTokenCookie(refreshTokenCookieName);
|
|
55
55
|
clearAppCheckTokenCookie(appCheckTokenCookieName);
|
|
56
56
|
writeEmailVerifiedHintCookie(emailVerifiedHintCookieName, false, refreshTokenMaxAge);
|
|
57
|
+
if (!clearServerCookies)
|
|
58
|
+
return;
|
|
57
59
|
try {
|
|
58
60
|
await clearSessionAction();
|
|
59
61
|
}
|
|
@@ -98,6 +100,9 @@ export default function AuthUserProvider({ initialUser = null, children }) {
|
|
|
98
100
|
const signInCallbackFired = useRef(initialUser !== null);
|
|
99
101
|
const signOutCallbackFired = useRef(initialUser === null);
|
|
100
102
|
const emailVerifiedRef = useRef(initialUser?.emailVerified ?? false);
|
|
103
|
+
const isAuthPageRef = useRef(isAuthPage);
|
|
104
|
+
isAuthPageRef.current = isAuthPage;
|
|
105
|
+
const initialSignedIn = initialUser !== null;
|
|
101
106
|
const deferAuthSubscribe = initialUser === null && isWhiteListed && !isAuthPage && typeof window !== 'undefined';
|
|
102
107
|
useEffect(() => {
|
|
103
108
|
const { user, loading } = state;
|
|
@@ -131,7 +136,7 @@ export default function AuthUserProvider({ initialUser = null, children }) {
|
|
|
131
136
|
await writeSession(user, sessionCookieName, maxAge, refreshTokenCookieName, refreshTokenMaxAge, emailVerifiedHintCookieName, appCheckTokenCookieName, appCheckTokenMaxAge);
|
|
132
137
|
}
|
|
133
138
|
else {
|
|
134
|
-
await clearSession(sessionCookieName, refreshTokenCookieName, emailVerifiedHintCookieName, appCheckTokenCookieName, refreshTokenMaxAge);
|
|
139
|
+
await clearSession(sessionCookieName, refreshTokenCookieName, emailVerifiedHintCookieName, appCheckTokenCookieName, refreshTokenMaxAge, previous ?? (initialSignedIn || isAuthPageRef.current));
|
|
135
140
|
}
|
|
136
141
|
}
|
|
137
142
|
catch (e) {
|
|
@@ -211,7 +216,7 @@ export default function AuthUserProvider({ initialUser = null, children }) {
|
|
|
211
216
|
clearTimeout(timeoutHandle);
|
|
212
217
|
unsubscribe?.();
|
|
213
218
|
};
|
|
214
|
-
}, [deferAuthSubscribe, router, isAuthPage, isWhiteListed, maxAge, sessionCookieName, refreshTokenMaxAge, refreshTokenCookieName, emailVerifiedHintCookieName, appCheckTokenCookieName, appCheckTokenMaxAge, fa]);
|
|
219
|
+
}, [initialSignedIn, deferAuthSubscribe, router, isAuthPage, isWhiteListed, maxAge, sessionCookieName, refreshTokenMaxAge, refreshTokenCookieName, emailVerifiedHintCookieName, appCheckTokenCookieName, appCheckTokenMaxAge, fa]);
|
|
215
220
|
const reloadUser = useCallback(async () => {
|
|
216
221
|
const { auth } = await getFirebaseAuthClient();
|
|
217
222
|
const user = auth.currentUser;
|
|
@@ -122,15 +122,10 @@ async function initializeFirebaseAppCheck(app, appCheckConfig) {
|
|
|
122
122
|
}
|
|
123
123
|
const APP_CHECK_TOKEN_TIMEOUT_MS = 10000;
|
|
124
124
|
let appCheckInitPromise;
|
|
125
|
-
|
|
126
|
-
if (appCheckInitPromise)
|
|
127
|
-
return appCheckInitPromise;
|
|
125
|
+
function initAppCheckFor(app) {
|
|
128
126
|
const appCheckConfig = config.firebaseAuth?.appCheck;
|
|
129
127
|
if (!appCheckConfig || typeof window === 'undefined')
|
|
130
|
-
return;
|
|
131
|
-
const { app } = await loadFirebaseAuthClient();
|
|
132
|
-
if (appCheckInitPromise)
|
|
133
|
-
return appCheckInitPromise;
|
|
128
|
+
return undefined;
|
|
134
129
|
appCheckInitPromise = (async () => {
|
|
135
130
|
try {
|
|
136
131
|
cachedAppCheck = await initializeFirebaseAppCheck(app, appCheckConfig);
|
|
@@ -141,6 +136,9 @@ async function ensureAppCheck() {
|
|
|
141
136
|
})();
|
|
142
137
|
return appCheckInitPromise;
|
|
143
138
|
}
|
|
139
|
+
async function ensureAppCheck() {
|
|
140
|
+
await getFirebaseAuthClient();
|
|
141
|
+
}
|
|
144
142
|
export async function getAppCheckToken() {
|
|
145
143
|
await ensureAppCheck().catch(() => undefined);
|
|
146
144
|
if (!cachedAppCheck)
|
|
@@ -160,7 +158,7 @@ export async function getAppCheckToken() {
|
|
|
160
158
|
}
|
|
161
159
|
let cached;
|
|
162
160
|
let cachedPromise;
|
|
163
|
-
async function
|
|
161
|
+
export async function getFirebaseAuthClient() {
|
|
164
162
|
requireFirebaseAuthConfig(config.firebaseAuth);
|
|
165
163
|
if (cached)
|
|
166
164
|
return cached;
|
|
@@ -183,6 +181,7 @@ async function loadFirebaseAuthClient() {
|
|
|
183
181
|
measurementId: fa.measurementId,
|
|
184
182
|
};
|
|
185
183
|
const app = getApps().length ? getApp() : initializeApp(firebaseConfig);
|
|
184
|
+
await initAppCheckFor(app);
|
|
186
185
|
if (perfModule) {
|
|
187
186
|
cachedPerformance = perfModule.initializePerformance(app, { instrumentationEnabled: false });
|
|
188
187
|
}
|
|
@@ -204,11 +203,6 @@ async function loadFirebaseAuthClient() {
|
|
|
204
203
|
}
|
|
205
204
|
return cachedPromise;
|
|
206
205
|
}
|
|
207
|
-
export async function getFirebaseAuthClient() {
|
|
208
|
-
const client = await loadFirebaseAuthClient();
|
|
209
|
-
await ensureAppCheck().catch(() => undefined);
|
|
210
|
-
return client;
|
|
211
|
-
}
|
|
212
206
|
export function getFirebaseAuthClientSync() {
|
|
213
207
|
return cached;
|
|
214
208
|
}
|
|
@@ -283,7 +283,7 @@ export default async function updateSession(request, baseResponse, locale, rebui
|
|
|
283
283
|
else if (unverifiedEmail) {
|
|
284
284
|
response = buildRedirect(baseResponse, localeUrl(fa.verifyEmailPath), isPrefetch);
|
|
285
285
|
}
|
|
286
|
-
else if (
|
|
286
|
+
else if (isVerifyEmailPage && decodeTokenOnce(token)?.email_verified === true) {
|
|
287
287
|
response = buildRedirect(baseResponse, localeUrl(fa.homePath), isPrefetch);
|
|
288
288
|
}
|
|
289
289
|
else {
|
|
@@ -8,6 +8,7 @@ import config from "../../config/intl_config.js";
|
|
|
8
8
|
import installConsoleErrorOverride from "../../error_handling/install_console_error_override.js";
|
|
9
9
|
import reportError from "../../error_handling/report_error.js";
|
|
10
10
|
const LocationzationClientProvider = dynamic(() => import("../../client/components/client_provider.js"));
|
|
11
|
+
import LocaleProvider from "../../client/components/locale_provider.js";
|
|
11
12
|
let authUserServerProviderModule;
|
|
12
13
|
export default async function LocationzationProvider({ language, messages, staticSafe = true, children }) {
|
|
13
14
|
if (!localesSet.has(language)) {
|
|
@@ -59,5 +60,5 @@ export default async function LocationzationProvider({ language, messages, stati
|
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
|
-
return (_jsx(Suspense, { fallback: children, children: _jsx(LocationzationClientProvider, { language: language, messages: messagesValue, initialAuthUser: initialAuthUser, skipAuthProvider: !autoWireClientProvider, analyticsConfig: analyticsConfig, autoAnalyticsEventsConfig: config.cookieConsent?.autoAnalyticsEvents, requiresConsent: requiresConsent, autoWireDialogs: config.cookieConsent?.autoWireDialogs !== false, dialogProps: config.cookieConsent?.dialogProps, updateDialogProps: config.cookieConsent?.updateDialogProps, children: children }) }));
|
|
63
|
+
return (_jsx(LocaleProvider, { language: language, messages: messagesValue, children: _jsx(Suspense, { fallback: children, children: _jsx(LocationzationClientProvider, { language: language, messages: messagesValue, initialAuthUser: initialAuthUser, skipAuthProvider: !autoWireClientProvider, analyticsConfig: analyticsConfig, autoAnalyticsEventsConfig: config.cookieConsent?.autoAnalyticsEvents, requiresConsent: requiresConsent, autoWireDialogs: config.cookieConsent?.autoWireDialogs !== false, dialogProps: config.cookieConsent?.dialogProps, updateDialogProps: config.cookieConsent?.updateDialogProps, children: children }) }) }));
|
|
63
64
|
}
|
|
@@ -80,7 +80,7 @@ export function missingRequiredSymbols(code, patchName) {
|
|
|
80
80
|
return REQUIRED_SYMBOLS[patchName].filter((symbol) => !code.includes(symbol));
|
|
81
81
|
}
|
|
82
82
|
function warnIncompatible(filePath, patchName, code) {
|
|
83
|
-
console.warn(`
|
|
83
|
+
console.warn(`cfni:vinext-route-wiring-fix: ${filePath} no longer exposes ${missingRequiredSymbols(code, patchName).join(", ")} — this vinext version may have changed; the ${patchName} fix was NOT applied.`);
|
|
84
84
|
}
|
|
85
85
|
export function isAppPageRouteWiringAlreadyFixed(code, options = {}) {
|
|
86
86
|
const hasBuggyPrefetch = code.includes("firstNestedEntry") &&
|
|
@@ -611,7 +611,7 @@ export function syncPatchVinextOnDisk(root = process.cwd(), options = {}) {
|
|
|
611
611
|
changed = true;
|
|
612
612
|
}
|
|
613
613
|
else {
|
|
614
|
-
console.warn(`
|
|
614
|
+
console.warn(`cfni:vinext-route-wiring-fix: ${wiringPath} does not match the expected shape for patchAppPageRouteWiring — this vinext version may have changed; the route-wiring fix was NOT applied.`);
|
|
615
615
|
}
|
|
616
616
|
}
|
|
617
617
|
}
|
|
@@ -632,7 +632,7 @@ export function syncPatchVinextOnDisk(root = process.cwd(), options = {}) {
|
|
|
632
632
|
changed = true;
|
|
633
633
|
}
|
|
634
634
|
else {
|
|
635
|
-
console.warn(`
|
|
635
|
+
console.warn(`cfni:vinext-route-wiring-fix: ${matchingPath} does not match the expected shape for patchRouteMatching — this vinext version may have changed; the route-matching fix was NOT applied.`);
|
|
636
636
|
}
|
|
637
637
|
}
|
|
638
638
|
}
|
|
@@ -653,7 +653,7 @@ export function syncPatchVinextOnDisk(root = process.cwd(), options = {}) {
|
|
|
653
653
|
changed = true;
|
|
654
654
|
}
|
|
655
655
|
else {
|
|
656
|
-
console.warn(`
|
|
656
|
+
console.warn(`cfni:vinext-route-wiring-fix: ${optimisticPath} does not match the expected shape for patchOptimisticRouting — this vinext version may have changed; the optimistic-routing fix was NOT applied.`);
|
|
657
657
|
}
|
|
658
658
|
}
|
|
659
659
|
}
|
|
@@ -674,7 +674,7 @@ export function syncPatchVinextOnDisk(root = process.cwd(), options = {}) {
|
|
|
674
674
|
changed = true;
|
|
675
675
|
}
|
|
676
676
|
else {
|
|
677
|
-
console.warn(`
|
|
677
|
+
console.warn(`cfni:vinext-route-wiring-fix: ${browserEntryPath} does not match the expected shape for patchPrefetchLearning — this vinext version may have changed; the prefetch-learning fix was NOT applied.`);
|
|
678
678
|
}
|
|
679
679
|
}
|
|
680
680
|
}
|
|
@@ -695,7 +695,7 @@ export function syncPatchVinextOnDisk(root = process.cwd(), options = {}) {
|
|
|
695
695
|
changed = true;
|
|
696
696
|
}
|
|
697
697
|
else {
|
|
698
|
-
console.warn(`
|
|
698
|
+
console.warn(`cfni:vinext-route-wiring-fix: ${probePath} does not match the expected shape for patchAppPageProbe — this vinext version may have changed; the suspense-probe fix was NOT applied.`);
|
|
699
699
|
}
|
|
700
700
|
}
|
|
701
701
|
}
|
|
@@ -713,7 +713,7 @@ export function syncPatchVinextOnDisk(root = process.cwd(), options = {}) {
|
|
|
713
713
|
changed = true;
|
|
714
714
|
}
|
|
715
715
|
else {
|
|
716
|
-
console.warn(`
|
|
716
|
+
console.warn(`cfni:vinext-route-wiring-fix: ${renderDependencyPath} does not match the expected shape for patchRenderDependency — this vinext version may have changed; the render-dependency fix was NOT applied.`);
|
|
717
717
|
}
|
|
718
718
|
}
|
|
719
719
|
}
|
|
@@ -732,7 +732,7 @@ export function syncPatchVinextOnDisk(root = process.cwd(), options = {}) {
|
|
|
732
732
|
changed = true;
|
|
733
733
|
}
|
|
734
734
|
else {
|
|
735
|
-
console.warn(`
|
|
735
|
+
console.warn(`cfni:vinext-route-wiring-fix: ${optimisticLearningTimeoutPath} does not match the expected shape for patchOptimisticLearningTimeout — this vinext version may have changed; the optimistic-learning-timeout fix was NOT applied.`);
|
|
736
736
|
}
|
|
737
737
|
}
|
|
738
738
|
}
|
|
@@ -750,7 +750,7 @@ export function syncPatchVinextOnDisk(root = process.cwd(), options = {}) {
|
|
|
750
750
|
changed = true;
|
|
751
751
|
}
|
|
752
752
|
else {
|
|
753
|
-
console.warn(`
|
|
753
|
+
console.warn(`cfni:vinext-route-wiring-fix: ${pageInvokerSuspensionReleasePath} does not match the expected shape for patchPageInvokerSuspensionRelease — this vinext version may have changed; the page-invoker-suspension-release fix was NOT applied.`);
|
|
754
754
|
}
|
|
755
755
|
}
|
|
756
756
|
}
|
|
@@ -768,7 +768,7 @@ export function syncPatchVinextOnDisk(root = process.cwd(), options = {}) {
|
|
|
768
768
|
changed = true;
|
|
769
769
|
}
|
|
770
770
|
else {
|
|
771
|
-
console.warn(`
|
|
771
|
+
console.warn(`cfni:vinext-route-wiring-fix: ${navControllerPath} does not match the expected shape for patchRefreshDeferralNavController — this vinext version may have changed; the refresh-deferral fix was NOT applied.`);
|
|
772
772
|
}
|
|
773
773
|
}
|
|
774
774
|
const entryPath = resolveVinextBrowserEntryPath(root);
|
|
@@ -860,7 +860,7 @@ export function vinextRouteWiringFixPlugin(options = {}) {
|
|
|
860
860
|
if (changed || isVinextOptimizeDepsCacheStale(root, cacheDir)) {
|
|
861
861
|
const busted = bustVinextOptimizeDepsCache(cacheDir);
|
|
862
862
|
if (busted) {
|
|
863
|
-
console.log("
|
|
863
|
+
console.log("cfni:vinext-route-wiring-fix: patched vinext on disk and cleared its stale Vite optimizeDeps cache — dependencies will re-bundle on next request.");
|
|
864
864
|
}
|
|
865
865
|
}
|
|
866
866
|
},
|