intor 2.0.3 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/index.cjs +4 -8
- package/dist/config/index.d.cts +3 -3
- package/dist/config/index.d.ts +3 -3
- package/dist/config/index.js +4 -8
- package/dist/index.cjs +142 -132
- package/dist/index.d.cts +119 -28
- package/dist/index.d.ts +119 -28
- package/dist/index.js +142 -132
- package/dist/next/index.cjs +292 -188
- package/dist/next/index.d.cts +101 -31
- package/dist/next/index.d.ts +101 -31
- package/dist/next/index.js +292 -189
- package/dist/next/middleware/index.cjs +28 -37
- package/dist/next/middleware/index.d.cts +6 -6
- package/dist/next/middleware/index.d.ts +6 -6
- package/dist/next/middleware/index.js +28 -37
- package/dist/next/server/index.cjs +133 -154
- package/dist/next/server/index.d.cts +77 -18
- package/dist/next/server/index.d.ts +77 -18
- package/dist/next/server/index.js +132 -152
- package/package.json +14 -10
package/dist/next/index.cjs
CHANGED
|
@@ -4,9 +4,10 @@ var React7 = require('react');
|
|
|
4
4
|
var logry = require('logry');
|
|
5
5
|
var Keyv = require('keyv');
|
|
6
6
|
var intorTranslator = require('intor-translator');
|
|
7
|
+
var formatUrl = require('next/dist/shared/lib/router/utils/format-url');
|
|
7
8
|
var NextLink = require('next/link');
|
|
8
9
|
var navigation = require('next/navigation');
|
|
9
|
-
var
|
|
10
|
+
var headers = require('next/headers');
|
|
10
11
|
|
|
11
12
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
13
|
|
|
@@ -47,66 +48,6 @@ function useConfig() {
|
|
|
47
48
|
return context;
|
|
48
49
|
}
|
|
49
50
|
var LocaleContext = React7__namespace.createContext(void 0);
|
|
50
|
-
|
|
51
|
-
// src/adapters/next/shared/utils/build-cookie-string.ts
|
|
52
|
-
var buildCookieString = (cookie, locale) => {
|
|
53
|
-
const parts = [];
|
|
54
|
-
parts.push(`${cookie.name}=${encodeURIComponent(locale)}`);
|
|
55
|
-
if (cookie.maxAge) {
|
|
56
|
-
const expires = new Date(Date.now() + cookie.maxAge * 1e3).toUTCString();
|
|
57
|
-
parts.push(`expires=${expires}`);
|
|
58
|
-
parts.push(`max-age=${cookie.maxAge}`);
|
|
59
|
-
}
|
|
60
|
-
parts.push(`path=${cookie.path ?? "/"}`);
|
|
61
|
-
if (cookie.domain) {
|
|
62
|
-
parts.push(`domain=${cookie.domain}`);
|
|
63
|
-
}
|
|
64
|
-
if (cookie.sameSite) {
|
|
65
|
-
parts.push(
|
|
66
|
-
`SameSite=${cookie.sameSite[0].toUpperCase()}${cookie.sameSite.slice(1).toLowerCase()}`
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
if (cookie.secure !== false) {
|
|
70
|
-
parts.push(`Secure`);
|
|
71
|
-
}
|
|
72
|
-
return parts.join("; ");
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
// src/adapters/next/shared/utils/set-locale-cookie-browser.ts
|
|
76
|
-
var setLocaleCookieBrowser = ({
|
|
77
|
-
cookie,
|
|
78
|
-
locale
|
|
79
|
-
}) => {
|
|
80
|
-
if (typeof window === "undefined") return;
|
|
81
|
-
if (cookie.disabled || !cookie.autoSetCookie) return;
|
|
82
|
-
const cookieString = buildCookieString(cookie, locale);
|
|
83
|
-
document.cookie = cookieString;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
// src/adapters/next/contexts/locale/utils/change-locale.ts
|
|
87
|
-
var changeLocale = ({
|
|
88
|
-
currentLocale,
|
|
89
|
-
newLocale,
|
|
90
|
-
loaderOptions,
|
|
91
|
-
cookie,
|
|
92
|
-
setLocale,
|
|
93
|
-
refetchMessages
|
|
94
|
-
}) => {
|
|
95
|
-
if (typeof document === "undefined") return;
|
|
96
|
-
const loaderType = loaderOptions?.type;
|
|
97
|
-
if (newLocale === currentLocale) return;
|
|
98
|
-
if (loaderType === "import") {
|
|
99
|
-
console.warn(
|
|
100
|
-
`[Intor] You are using dynamic import to switch languages. Please make sure to use the wrapped <Link> component to trigger a page reload, ensuring that the translation data is dynamically updated.`
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
setLocale(newLocale);
|
|
104
|
-
setLocaleCookieBrowser({ cookie, locale: newLocale });
|
|
105
|
-
document.documentElement.lang = newLocale;
|
|
106
|
-
if (loaderType === "api" && refetchMessages) {
|
|
107
|
-
void refetchMessages(newLocale);
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
51
|
var MessagesContext = React7__namespace.createContext(void 0);
|
|
111
52
|
|
|
112
53
|
// src/modules/config/constants/cache.constants.ts
|
|
@@ -130,16 +71,22 @@ var DEFAULT_FORMATTER_CONFIG = {
|
|
|
130
71
|
};
|
|
131
72
|
function getLogger({
|
|
132
73
|
id,
|
|
133
|
-
formatterConfig
|
|
74
|
+
formatterConfig,
|
|
75
|
+
preset,
|
|
134
76
|
...options
|
|
135
77
|
}) {
|
|
136
78
|
const pool = getGlobalLoggerPool();
|
|
137
79
|
let logger = pool.get(id);
|
|
138
80
|
if (!logger) {
|
|
139
|
-
logger = logry.logry({
|
|
81
|
+
logger = logry.logry({
|
|
82
|
+
id,
|
|
83
|
+
formatterConfig: !formatterConfig && !preset ? DEFAULT_FORMATTER_CONFIG : formatterConfig,
|
|
84
|
+
preset,
|
|
85
|
+
...options
|
|
86
|
+
});
|
|
140
87
|
pool.set(id, logger);
|
|
141
88
|
if (pool.size > 1e3) {
|
|
142
|
-
const keys =
|
|
89
|
+
const keys = [...pool.keys()];
|
|
143
90
|
for (const key of keys.slice(0, 200)) pool.delete(key);
|
|
144
91
|
}
|
|
145
92
|
}
|
|
@@ -154,7 +101,7 @@ function getGlobalMessagesPool() {
|
|
|
154
101
|
|
|
155
102
|
// src/shared/utils/merge-messages.ts
|
|
156
103
|
var mergeMessages = (staticMessages = {}, loadedMessages = {}) => {
|
|
157
|
-
const result = Object.keys(staticMessages).length ? { ...staticMessages } : {};
|
|
104
|
+
const result = Object.keys(staticMessages).length > 0 ? { ...staticMessages } : {};
|
|
158
105
|
for (const locale in loadedMessages) {
|
|
159
106
|
const loaded = loadedMessages[locale];
|
|
160
107
|
if (!result[locale]) {
|
|
@@ -173,7 +120,7 @@ var mergeMessages = (staticMessages = {}, loadedMessages = {}) => {
|
|
|
173
120
|
var CACHE_KEY_DELIMITER = "|";
|
|
174
121
|
var sanitize = (k) => k.replaceAll(/[\u200B-\u200D\uFEFF]/g, "").replaceAll(/[\r\n]/g, "").trim();
|
|
175
122
|
var normalizeCacheKey = (key, delimiter = CACHE_KEY_DELIMITER) => {
|
|
176
|
-
if (
|
|
123
|
+
if (key === null || key === void 0) return null;
|
|
177
124
|
if (Array.isArray(key)) {
|
|
178
125
|
if (key.length === 0) return null;
|
|
179
126
|
const normalized = key.map((k) => {
|
|
@@ -197,53 +144,90 @@ var resolveNamespaces = ({
|
|
|
197
144
|
pathname
|
|
198
145
|
}) => {
|
|
199
146
|
const { loader } = config;
|
|
200
|
-
const {
|
|
201
|
-
|
|
202
|
-
namespaces: fallbackNamespaces
|
|
203
|
-
} = loader;
|
|
204
|
-
const { unprefixedPathname } = extractPathname({ config, pathname });
|
|
205
|
-
const standardizedPathname = standardizePathname({
|
|
206
|
-
config,
|
|
207
|
-
pathname: unprefixedPathname
|
|
208
|
-
});
|
|
147
|
+
const { routeNamespaces = {}, namespaces } = loader || {};
|
|
148
|
+
const standardizedPathname = standardizePathname({ config, pathname });
|
|
209
149
|
const placeholderRemovedPathname = standardizedPathname.replace(
|
|
210
150
|
`/${PREFIX_PLACEHOLDER}`,
|
|
211
151
|
""
|
|
212
152
|
);
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
153
|
+
const collected = [
|
|
154
|
+
...routeNamespaces.default || [],
|
|
155
|
+
// default
|
|
156
|
+
...namespaces || [],
|
|
157
|
+
// default
|
|
158
|
+
...routeNamespaces[standardizedPathname] || [],
|
|
159
|
+
// exact match
|
|
160
|
+
...routeNamespaces[placeholderRemovedPathname] || []
|
|
161
|
+
// exact match
|
|
162
|
+
];
|
|
220
163
|
const prefixPatterns = Object.keys(routeNamespaces).filter(
|
|
221
164
|
(pattern) => pattern.endsWith("/*")
|
|
222
165
|
);
|
|
223
166
|
for (const pattern of prefixPatterns) {
|
|
224
167
|
const basePath = pattern.replace(/\/\*$/, "");
|
|
225
|
-
if (standardizedPathname.startsWith(basePath)) {
|
|
226
|
-
|
|
227
|
-
bestMatch = basePath;
|
|
228
|
-
bestNamespaces = routeNamespaces[pattern];
|
|
229
|
-
}
|
|
168
|
+
if (standardizedPathname.startsWith(basePath) || placeholderRemovedPathname.startsWith(basePath)) {
|
|
169
|
+
collected.push(...routeNamespaces[pattern] || []);
|
|
230
170
|
}
|
|
231
171
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
172
|
+
return [...new Set(collected)];
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// src/shared/utils/locale/normalize-locale.ts
|
|
176
|
+
var toCanonical = (input) => {
|
|
177
|
+
try {
|
|
178
|
+
return Intl.getCanonicalLocales(input)[0]?.toLowerCase();
|
|
179
|
+
} catch {
|
|
180
|
+
return;
|
|
237
181
|
}
|
|
238
182
|
};
|
|
183
|
+
var normalizeLocale = (locale = "", supportedLocales = []) => {
|
|
184
|
+
if (!locale || supportedLocales.length === 0) return;
|
|
185
|
+
const canonicalLocale = toCanonical(locale);
|
|
186
|
+
if (!canonicalLocale) return;
|
|
187
|
+
const supportedCanonicalMap = /* @__PURE__ */ new Map();
|
|
188
|
+
for (const l of supportedLocales) {
|
|
189
|
+
const normalized = toCanonical(l);
|
|
190
|
+
if (normalized) {
|
|
191
|
+
supportedCanonicalMap.set(normalized, l);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (supportedCanonicalMap.has(canonicalLocale)) {
|
|
195
|
+
return supportedCanonicalMap.get(canonicalLocale);
|
|
196
|
+
}
|
|
197
|
+
const baseLang = canonicalLocale.split("-")[0];
|
|
198
|
+
for (const [key, original] of supportedCanonicalMap) {
|
|
199
|
+
const supportedBase = key.split("-")[0];
|
|
200
|
+
if (supportedBase === baseLang) {
|
|
201
|
+
return original;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// src/shared/utils/locale/resolve-preferred-locale.ts
|
|
208
|
+
var resolvePreferredLocale = (acceptLanguageHeader, supportedLocales) => {
|
|
209
|
+
if (!acceptLanguageHeader || !supportedLocales || supportedLocales.length === 0) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const supportedLocalesSet = new Set(supportedLocales);
|
|
213
|
+
const preferred = acceptLanguageHeader.split(",").map((part) => {
|
|
214
|
+
const [lang, qValue] = part.split(";");
|
|
215
|
+
const q = qValue ? Number.parseFloat(qValue.split("=")[1]) : 1;
|
|
216
|
+
if (Number.isNaN(q)) {
|
|
217
|
+
return { lang: lang.trim(), q: 0 };
|
|
218
|
+
}
|
|
219
|
+
return { lang: lang.trim(), q };
|
|
220
|
+
}).toSorted((a, b) => b.q - a.q).find(({ lang }) => supportedLocalesSet.has(lang))?.lang;
|
|
221
|
+
return preferred;
|
|
222
|
+
};
|
|
239
223
|
|
|
240
224
|
// src/shared/utils/pathname/normalize-pathname.ts
|
|
241
225
|
var normalizePathname = (rawPathname, options = {}) => {
|
|
242
226
|
const length = rawPathname.length;
|
|
243
227
|
let start = 0;
|
|
244
228
|
let end = length - 1;
|
|
245
|
-
while (start <= end && rawPathname.
|
|
246
|
-
while (end >= start && rawPathname.
|
|
229
|
+
while (start <= end && (rawPathname.codePointAt(start) ?? 0) <= 32) start++;
|
|
230
|
+
while (end >= start && (rawPathname.codePointAt(end) ?? 0) <= 32) end--;
|
|
247
231
|
if (start > end) return "/";
|
|
248
232
|
let result = "";
|
|
249
233
|
let hasSlash = false;
|
|
@@ -254,11 +238,7 @@ var normalizePathname = (rawPathname, options = {}) => {
|
|
|
254
238
|
hasSlash = true;
|
|
255
239
|
}
|
|
256
240
|
} else {
|
|
257
|
-
|
|
258
|
-
result += "/" + char;
|
|
259
|
-
} else {
|
|
260
|
-
result += char;
|
|
261
|
-
}
|
|
241
|
+
result += hasSlash || result === "" ? "/" + char : char;
|
|
262
242
|
hasSlash = false;
|
|
263
243
|
}
|
|
264
244
|
}
|
|
@@ -282,8 +262,8 @@ var extractPathname = ({
|
|
|
282
262
|
} else if (basePath && normalizedPathname === basePath) {
|
|
283
263
|
prefixedPathname = "/";
|
|
284
264
|
}
|
|
285
|
-
const
|
|
286
|
-
const maybeLocale =
|
|
265
|
+
const pathPart = prefixedPathname.split("/").find(Boolean);
|
|
266
|
+
const maybeLocale = pathPart || "";
|
|
287
267
|
const isLocalePrefixed = config.supportedLocales?.includes(maybeLocale);
|
|
288
268
|
let unprefixedPathname = prefixedPathname;
|
|
289
269
|
if (prefix === "all") {
|
|
@@ -316,7 +296,7 @@ var standardizePathname = ({
|
|
|
316
296
|
PREFIX_PLACEHOLDER,
|
|
317
297
|
normalizePathname(pathname)
|
|
318
298
|
];
|
|
319
|
-
const standardizedPathname = parts.join("/").
|
|
299
|
+
const standardizedPathname = parts.join("/").replaceAll(/\/{2,}/g, "/");
|
|
320
300
|
return normalizePathname(standardizedPathname);
|
|
321
301
|
};
|
|
322
302
|
|
|
@@ -334,13 +314,13 @@ var fetchMessages = async ({
|
|
|
334
314
|
const params = new URLSearchParams(searchParams);
|
|
335
315
|
params.append("locale", locale);
|
|
336
316
|
const url = `${apiUrl}?${params.toString()}`;
|
|
337
|
-
const
|
|
317
|
+
const headers2 = {
|
|
338
318
|
"Content-Type": "application/json",
|
|
339
319
|
...apiHeaders
|
|
340
320
|
};
|
|
341
321
|
const response = await fetch(url, {
|
|
342
322
|
method: "GET",
|
|
343
|
-
headers,
|
|
323
|
+
headers: headers2,
|
|
344
324
|
cache: "no-store"
|
|
345
325
|
});
|
|
346
326
|
if (!response.ok) {
|
|
@@ -420,16 +400,19 @@ var loadApiMessages = async ({
|
|
|
420
400
|
logger.warn("No apiUrl provided. Skipping fetch.");
|
|
421
401
|
return;
|
|
422
402
|
}
|
|
423
|
-
|
|
403
|
+
let pool;
|
|
404
|
+
if (cache.enabled) {
|
|
405
|
+
pool = getGlobalMessagesPool();
|
|
406
|
+
}
|
|
424
407
|
const key = normalizeCacheKey([
|
|
425
408
|
loggerOptions.id,
|
|
426
409
|
basePath,
|
|
427
410
|
locale,
|
|
428
|
-
|
|
429
|
-
|
|
411
|
+
(fallbackLocales ?? []).toSorted().join(","),
|
|
412
|
+
(namespaces ?? []).toSorted().join(",")
|
|
430
413
|
]);
|
|
431
414
|
if (cache.enabled && key) {
|
|
432
|
-
const cached = await pool
|
|
415
|
+
const cached = await pool?.get(key);
|
|
433
416
|
if (cached) {
|
|
434
417
|
logger.debug("Messages cache hit.", { key });
|
|
435
418
|
return cached;
|
|
@@ -445,7 +428,7 @@ var loadApiMessages = async ({
|
|
|
445
428
|
});
|
|
446
429
|
if (messages) {
|
|
447
430
|
if (cache.enabled && key) {
|
|
448
|
-
await pool
|
|
431
|
+
await pool?.set(key, messages, cache.ttl);
|
|
449
432
|
}
|
|
450
433
|
return messages;
|
|
451
434
|
}
|
|
@@ -463,7 +446,7 @@ var loadApiMessages = async ({
|
|
|
463
446
|
searchParams: decodeURIComponent(searchParams.toString())
|
|
464
447
|
});
|
|
465
448
|
if (cache.enabled && key) {
|
|
466
|
-
await pool
|
|
449
|
+
await pool?.set(key, fallbackResult.messages, cache.ttl);
|
|
467
450
|
}
|
|
468
451
|
return fallbackResult.messages;
|
|
469
452
|
}
|
|
@@ -547,6 +530,8 @@ function useMessages() {
|
|
|
547
530
|
throw new Error("useMessages must be used within a MessagesProvider");
|
|
548
531
|
return context;
|
|
549
532
|
}
|
|
533
|
+
|
|
534
|
+
// src/adapters/next/contexts/locale/utils/use-init-lazy-load.ts
|
|
550
535
|
var useInitLazyLoad = ({
|
|
551
536
|
loaderOptions,
|
|
552
537
|
currentLocale
|
|
@@ -561,6 +546,41 @@ var useInitLazyLoad = ({
|
|
|
561
546
|
}
|
|
562
547
|
}, [lazyLoad, currentLocale, refetchMessages, isFirstLoadedRef]);
|
|
563
548
|
};
|
|
549
|
+
|
|
550
|
+
// src/adapters/next/shared/utils/build-cookie-string.ts
|
|
551
|
+
var buildCookieString = (cookie, locale) => {
|
|
552
|
+
const parts = [`${cookie.name}=${encodeURIComponent(locale)}`];
|
|
553
|
+
if (cookie.maxAge) {
|
|
554
|
+
const expires = new Date(Date.now() + cookie.maxAge * 1e3).toUTCString();
|
|
555
|
+
parts.push(`expires=${expires}`, `max-age=${cookie.maxAge}`);
|
|
556
|
+
}
|
|
557
|
+
parts.push(`path=${cookie.path ?? "/"}`);
|
|
558
|
+
if (cookie.domain) {
|
|
559
|
+
parts.push(`domain=${cookie.domain}`);
|
|
560
|
+
}
|
|
561
|
+
if (cookie.sameSite) {
|
|
562
|
+
parts.push(
|
|
563
|
+
`SameSite=${cookie.sameSite[0].toUpperCase()}${cookie.sameSite.slice(1).toLowerCase()}`
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
if (cookie.secure !== false) {
|
|
567
|
+
parts.push(`Secure`);
|
|
568
|
+
}
|
|
569
|
+
return parts.join("; ");
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
// src/adapters/next/shared/utils/set-locale-cookie-browser.ts
|
|
573
|
+
var setLocaleCookieBrowser = ({
|
|
574
|
+
cookie,
|
|
575
|
+
locale
|
|
576
|
+
}) => {
|
|
577
|
+
if (globalThis.window === void 0) return;
|
|
578
|
+
if (cookie.disabled || !cookie.autoSetCookie) return;
|
|
579
|
+
const cookieString = buildCookieString(cookie, locale);
|
|
580
|
+
document.cookie = cookieString;
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
// src/adapters/next/contexts/locale/utils/use-init-locale-cookie.ts
|
|
564
584
|
var useInitLocaleCookie = ({
|
|
565
585
|
config,
|
|
566
586
|
locale
|
|
@@ -569,8 +589,8 @@ var useInitLocaleCookie = ({
|
|
|
569
589
|
if (typeof document === "undefined") return;
|
|
570
590
|
const { cookie, routing } = config;
|
|
571
591
|
const { firstVisit } = routing;
|
|
572
|
-
const
|
|
573
|
-
const isCookieExists =
|
|
592
|
+
const cookies2 = document.cookie.split(";").map((c) => c.trim());
|
|
593
|
+
const isCookieExists = cookies2.some((c) => c.startsWith(`${cookie.name}=`));
|
|
574
594
|
if (isCookieExists) return;
|
|
575
595
|
if (!firstVisit.redirect) return;
|
|
576
596
|
if (cookie.disabled || !cookie.autoSetCookie) return;
|
|
@@ -578,6 +598,31 @@ var useInitLocaleCookie = ({
|
|
|
578
598
|
}, []);
|
|
579
599
|
};
|
|
580
600
|
|
|
601
|
+
// src/adapters/next/contexts/locale/utils/change-locale.ts
|
|
602
|
+
var changeLocale = ({
|
|
603
|
+
currentLocale,
|
|
604
|
+
newLocale,
|
|
605
|
+
loaderOptions,
|
|
606
|
+
cookie,
|
|
607
|
+
setLocale,
|
|
608
|
+
refetchMessages
|
|
609
|
+
}) => {
|
|
610
|
+
if (typeof document === "undefined") return;
|
|
611
|
+
const loaderType = loaderOptions?.type;
|
|
612
|
+
if (newLocale === currentLocale) return;
|
|
613
|
+
if (loaderType === "import") {
|
|
614
|
+
console.warn(
|
|
615
|
+
`[Intor] You are using dynamic import to switch languages. Please make sure to use the wrapped <Link> component to trigger a page reload, ensuring that the translation data is dynamically updated.`
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
setLocale(newLocale);
|
|
619
|
+
setLocaleCookieBrowser({ cookie, locale: newLocale });
|
|
620
|
+
document.documentElement.lang = newLocale;
|
|
621
|
+
if (loaderType === "api" && refetchMessages) {
|
|
622
|
+
void refetchMessages(newLocale);
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
|
|
581
626
|
// src/adapters/next/contexts/locale/provider.tsx
|
|
582
627
|
function LocaleProvider({
|
|
583
628
|
value: { initialLocale },
|
|
@@ -676,7 +721,7 @@ function useTranslator() {
|
|
|
676
721
|
const context = React7__namespace.useContext(TranslatorContext);
|
|
677
722
|
if (!context)
|
|
678
723
|
throw new Error(
|
|
679
|
-
"
|
|
724
|
+
"useTranslator must be used within IntorTranslatorProvider"
|
|
680
725
|
);
|
|
681
726
|
return context;
|
|
682
727
|
}
|
|
@@ -689,23 +734,22 @@ var IntorProvider = ({
|
|
|
689
734
|
return /* @__PURE__ */ React7__namespace.createElement(ConfigProvider, { value: { config, pathname } }, /* @__PURE__ */ React7__namespace.createElement(MessagesProvider, { value: { messages } }, /* @__PURE__ */ React7__namespace.createElement(LocaleProvider, { value: { initialLocale } }, /* @__PURE__ */ React7__namespace.createElement(TranslatorProvider, null, children))));
|
|
690
735
|
};
|
|
691
736
|
|
|
692
|
-
// src/adapters/next/hooks/use-
|
|
693
|
-
function
|
|
737
|
+
// src/adapters/next/hooks/use-translator/use-translator.ts
|
|
738
|
+
function useTranslator2(preKey) {
|
|
694
739
|
const { translator } = useTranslator();
|
|
695
740
|
const { setLocale } = useLocale();
|
|
696
|
-
const
|
|
741
|
+
const props = {
|
|
697
742
|
messages: translator.messages,
|
|
698
743
|
locale: translator.locale,
|
|
699
744
|
isLoading: translator.isLoading,
|
|
700
745
|
setLocale
|
|
701
746
|
};
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
}
|
|
747
|
+
const scoped = translator.scoped(preKey);
|
|
748
|
+
return {
|
|
749
|
+
...props,
|
|
750
|
+
hasKey: preKey ? scoped.hasKey : translator.hasKey,
|
|
751
|
+
t: preKey ? scoped.t : translator.t
|
|
752
|
+
};
|
|
709
753
|
}
|
|
710
754
|
|
|
711
755
|
// src/adapters/next/shared/utils/locale-prefix-pathname.ts
|
|
@@ -725,15 +769,11 @@ var localePrefixPathname = ({
|
|
|
725
769
|
);
|
|
726
770
|
}
|
|
727
771
|
if (prefix === "except-default") {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
)
|
|
732
|
-
|
|
733
|
-
return normalizePathname(
|
|
734
|
-
standardizedPathname.replaceAll(PREFIX_PLACEHOLDER, locale)
|
|
735
|
-
);
|
|
736
|
-
}
|
|
772
|
+
return locale === config.defaultLocale ? normalizePathname(
|
|
773
|
+
standardizedPathname.replaceAll(`/${PREFIX_PLACEHOLDER}`, "")
|
|
774
|
+
) : normalizePathname(
|
|
775
|
+
standardizedPathname.replaceAll(PREFIX_PLACEHOLDER, locale)
|
|
776
|
+
);
|
|
737
777
|
}
|
|
738
778
|
return normalizePathname(
|
|
739
779
|
standardizedPathname.replaceAll(`/${PREFIX_PLACEHOLDER}`, "")
|
|
@@ -766,10 +806,7 @@ var localizePathname = ({
|
|
|
766
806
|
};
|
|
767
807
|
};
|
|
768
808
|
|
|
769
|
-
// src/adapters/next/
|
|
770
|
-
var shouldFullReload = (loaderOptions) => {
|
|
771
|
-
return loaderOptions?.type === "import" || loaderOptions?.type === "api" && loaderOptions.fullReload === true;
|
|
772
|
-
};
|
|
809
|
+
// src/adapters/next/navigation/use-pathname.ts
|
|
773
810
|
var usePathname = () => {
|
|
774
811
|
const { config } = useConfig();
|
|
775
812
|
const { locale } = useLocale();
|
|
@@ -781,75 +818,90 @@ var usePathname = () => {
|
|
|
781
818
|
});
|
|
782
819
|
return localePrefixedPathname;
|
|
783
820
|
};
|
|
784
|
-
|
|
785
|
-
|
|
821
|
+
|
|
822
|
+
// src/adapters/next/navigation/utils/should-full-reload.ts
|
|
823
|
+
var shouldFullReload = ({
|
|
824
|
+
config,
|
|
825
|
+
targetPathname,
|
|
786
826
|
locale,
|
|
787
|
-
|
|
788
|
-
onClick,
|
|
789
|
-
...props
|
|
827
|
+
currentLocale
|
|
790
828
|
}) => {
|
|
829
|
+
const loader = config.loader;
|
|
830
|
+
if (!loader || !loader.type) return false;
|
|
831
|
+
if (loader.type === "api" && !loader.fullReload) return false;
|
|
832
|
+
const { maybeLocale, isLocalePrefixed } = extractPathname({
|
|
833
|
+
config,
|
|
834
|
+
pathname: targetPathname
|
|
835
|
+
});
|
|
836
|
+
const isDifferentLocale = locale && locale !== currentLocale || isLocalePrefixed && maybeLocale !== currentLocale;
|
|
837
|
+
return isDifferentLocale ? true : false;
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
// src/adapters/next/navigation/utils/use-locale-switch.ts
|
|
841
|
+
var useLocaleSwitch = () => {
|
|
791
842
|
const { config } = useConfig();
|
|
792
843
|
const { locale: currentLocale, setLocale } = useLocale();
|
|
793
|
-
const targetLocale = locale || currentLocale;
|
|
794
844
|
const pathname = usePathname();
|
|
795
|
-
const
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
locale
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
845
|
+
const resolveHref = ({
|
|
846
|
+
href,
|
|
847
|
+
locale
|
|
848
|
+
}) => {
|
|
849
|
+
const isLocaleValid = locale && config.supportedLocales?.includes(locale);
|
|
850
|
+
const targetLocale = isLocaleValid ? locale : currentLocale;
|
|
851
|
+
const targetPathname = href ?? pathname;
|
|
852
|
+
const isExternal = targetPathname.startsWith("http");
|
|
853
|
+
const resolvedHref = !isExternal ? localizePathname({
|
|
854
|
+
config,
|
|
855
|
+
pathname: targetPathname,
|
|
856
|
+
locale: targetLocale
|
|
857
|
+
}).localePrefixedPathname : targetPathname;
|
|
858
|
+
return { resolvedHref, isExternal, targetLocale, targetPathname };
|
|
859
|
+
};
|
|
860
|
+
const switchLocale = ({
|
|
861
|
+
href,
|
|
862
|
+
locale
|
|
863
|
+
}) => {
|
|
864
|
+
const { resolvedHref, isExternal, targetLocale, targetPathname } = resolveHref({ href, locale });
|
|
865
|
+
if (isExternal) return;
|
|
866
|
+
if (shouldFullReload({ config, targetPathname, locale, currentLocale })) {
|
|
805
867
|
setLocaleCookieBrowser({ cookie: config.cookie, locale: targetLocale });
|
|
806
|
-
|
|
868
|
+
globalThis.location.href = resolvedHref;
|
|
807
869
|
return;
|
|
808
870
|
} else {
|
|
809
871
|
setLocale(targetLocale);
|
|
810
872
|
}
|
|
873
|
+
return resolvedHref;
|
|
874
|
+
};
|
|
875
|
+
return { resolveHref, switchLocale };
|
|
876
|
+
};
|
|
877
|
+
|
|
878
|
+
// src/adapters/next/navigation/link.tsx
|
|
879
|
+
var Link = ({
|
|
880
|
+
href,
|
|
881
|
+
locale,
|
|
882
|
+
children,
|
|
883
|
+
onClick,
|
|
884
|
+
...props
|
|
885
|
+
}) => {
|
|
886
|
+
const formatted = typeof href === "string" ? href : href ? formatUrl.formatUrl(href) : void 0;
|
|
887
|
+
const { resolveHref, switchLocale } = useLocaleSwitch();
|
|
888
|
+
const { resolvedHref } = resolveHref({ href: formatted, locale });
|
|
889
|
+
const handleClick = (e) => {
|
|
890
|
+
onClick?.(e);
|
|
891
|
+
switchLocale({ href: formatted, locale });
|
|
811
892
|
};
|
|
812
893
|
return /* @__PURE__ */ React7__namespace.createElement(NextLink__default.default, { href: resolvedHref, onClick: handleClick, ...props }, children);
|
|
813
894
|
};
|
|
814
895
|
var useRouter = () => {
|
|
815
|
-
const { config } = useConfig();
|
|
816
|
-
const { locale: currentLocale, setLocale } = useLocale();
|
|
817
896
|
const { push, replace, ...rest } = navigation.useRouter();
|
|
897
|
+
const { switchLocale } = useLocaleSwitch();
|
|
818
898
|
const pushWithLocale = (href, options) => {
|
|
819
|
-
const
|
|
820
|
-
if (options
|
|
821
|
-
const { localePrefixedPathname } = localizePathname({
|
|
822
|
-
config,
|
|
823
|
-
pathname: href,
|
|
824
|
-
locale: targetLocale
|
|
825
|
-
});
|
|
826
|
-
href = localePrefixedPathname;
|
|
827
|
-
}
|
|
828
|
-
if (shouldFullReload(config.loader)) {
|
|
829
|
-
window.location.href = href;
|
|
830
|
-
return;
|
|
831
|
-
} else {
|
|
832
|
-
setLocale(targetLocale);
|
|
833
|
-
}
|
|
834
|
-
push(href, options);
|
|
899
|
+
const resolvedHref = switchLocale({ href, locale: options?.locale });
|
|
900
|
+
if (resolvedHref) push(resolvedHref, options);
|
|
835
901
|
};
|
|
836
902
|
const replaceWithLocale = (href, options) => {
|
|
837
|
-
const
|
|
838
|
-
if (options
|
|
839
|
-
const { localePrefixedPathname } = localizePathname({
|
|
840
|
-
config,
|
|
841
|
-
pathname: href,
|
|
842
|
-
locale: targetLocale
|
|
843
|
-
});
|
|
844
|
-
href = localePrefixedPathname;
|
|
845
|
-
}
|
|
846
|
-
if (shouldFullReload(config.loader)) {
|
|
847
|
-
window.location.href = href;
|
|
848
|
-
return;
|
|
849
|
-
} else {
|
|
850
|
-
setLocale(targetLocale);
|
|
851
|
-
}
|
|
852
|
-
replace(href, options);
|
|
903
|
+
const resolvedHref = switchLocale({ href, locale: options?.locale });
|
|
904
|
+
if (resolvedHref) replace(resolvedHref, options);
|
|
853
905
|
};
|
|
854
906
|
return {
|
|
855
907
|
push: pushWithLocale,
|
|
@@ -861,10 +913,62 @@ var useRouter = () => {
|
|
|
861
913
|
// src/adapters/next/shared/constants/pathname-header-name.ts
|
|
862
914
|
var PATHNAME_HEADER_NAME = "x-intor-pathname";
|
|
863
915
|
|
|
916
|
+
// src/adapters/next/server/get-i18n-context.ts
|
|
917
|
+
var getI18nContext = async (config) => {
|
|
918
|
+
const baseLogger = getLogger({ id: config.id, ...config.logger });
|
|
919
|
+
const logger = baseLogger.child({ scope: "next-adapter" });
|
|
920
|
+
const cookiesStore = await headers.cookies();
|
|
921
|
+
const headersStore = await headers.headers();
|
|
922
|
+
const { defaultLocale, supportedLocales = [], cookie, routing } = config;
|
|
923
|
+
let locale;
|
|
924
|
+
if (!cookie.disabled) {
|
|
925
|
+
const localeFromCookie = cookiesStore.get(cookie.name)?.value;
|
|
926
|
+
locale = normalizeLocale(localeFromCookie, supportedLocales);
|
|
927
|
+
if (locale) {
|
|
928
|
+
logger.trace("Locale retrieved from cookie.", { locale });
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
if (!locale && routing.firstVisit.localeSource === "browser") {
|
|
932
|
+
const aLHeader = headersStore.get("accept-language") || void 0;
|
|
933
|
+
const preferredLocale = resolvePreferredLocale(aLHeader, supportedLocales);
|
|
934
|
+
locale = normalizeLocale(preferredLocale, supportedLocales);
|
|
935
|
+
logger.trace("Locale retrieved from header.", { locale });
|
|
936
|
+
}
|
|
937
|
+
const pathname = headersStore.get(PATHNAME_HEADER_NAME);
|
|
938
|
+
if (pathname) {
|
|
939
|
+
logger.trace("Pathname retrieved from header.", { pathname });
|
|
940
|
+
}
|
|
941
|
+
return {
|
|
942
|
+
locale: locale || defaultLocale,
|
|
943
|
+
pathname: pathname || ""
|
|
944
|
+
};
|
|
945
|
+
};
|
|
946
|
+
|
|
947
|
+
// src/adapters/next/navigation/redirect.ts
|
|
948
|
+
var redirect = async ({
|
|
949
|
+
config,
|
|
950
|
+
locale,
|
|
951
|
+
url,
|
|
952
|
+
type
|
|
953
|
+
}) => {
|
|
954
|
+
if (url.startsWith("http")) {
|
|
955
|
+
navigation.redirect(url);
|
|
956
|
+
}
|
|
957
|
+
const isLocaleValid = locale && config.supportedLocales?.includes(locale);
|
|
958
|
+
const { locale: detectedLocale } = await getI18nContext(config);
|
|
959
|
+
const { localePrefixedPathname } = localizePathname({
|
|
960
|
+
config,
|
|
961
|
+
pathname: url,
|
|
962
|
+
locale: isLocaleValid ? locale : detectedLocale
|
|
963
|
+
});
|
|
964
|
+
navigation.redirect(localePrefixedPathname, type);
|
|
965
|
+
};
|
|
966
|
+
|
|
864
967
|
exports.IntorProvider = IntorProvider;
|
|
865
968
|
exports.Link = Link;
|
|
866
969
|
exports.PATHNAME_HEADER_NAME = PATHNAME_HEADER_NAME;
|
|
867
970
|
exports.TranslateHandlersProvider = TranslateHandlersProvider;
|
|
868
|
-
exports.
|
|
971
|
+
exports.redirect = redirect;
|
|
869
972
|
exports.usePathname = usePathname;
|
|
870
973
|
exports.useRouter = useRouter;
|
|
974
|
+
exports.useTranslator = useTranslator2;
|