intor 2.3.32 → 2.3.34
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/core/src/core/utils/resolve-loader-options.js +7 -3
- package/dist/core/src/server/messages/load-messages.js +5 -5
- package/dist/express/export/express/index.js +2 -2
- package/dist/express/src/adapters/express/{middleware/create-intor-middleware.js → create-intor-handler.js} +13 -12
- package/dist/express/src/adapters/express/{helpers/get-translator.js → get-translator.js} +2 -6
- package/dist/express/src/core/utils/resolve-loader-options.js +3 -1
- package/dist/express/src/routing/inbound/resolve-inbound.js +3 -4
- package/dist/express/src/routing/inbound/resolve-locale/resolve-locale.js +6 -5
- package/dist/express/src/routing/locale/get-locale-from-query.js +1 -9
- package/dist/express/src/server/messages/load-messages.js +5 -5
- package/dist/next/export/next/index.js +4 -3
- package/dist/next/src/adapters/next/{proxy/intor-proxy.js → create-intor-handler.js} +13 -12
- package/dist/next/src/adapters/next/{navigation/link.js → link.js} +6 -6
- package/dist/next/src/adapters/next/{navigation/redirect.js → redirect.js} +4 -4
- package/dist/next/src/adapters/next/server/get-translator.js +0 -4
- package/dist/next/src/adapters/next/{navigation/use-router.js → use-router.js} +10 -10
- package/dist/next/src/client/shared/navigation/execute-navigation.js +6 -6
- package/dist/next/src/core/utils/resolve-loader-options.js +7 -3
- package/dist/next/src/policies/shoud-full-reload.js +1 -1
- package/dist/next/src/routing/inbound/resolve-inbound.js +4 -5
- package/dist/next/src/routing/inbound/resolve-locale/resolve-locale.js +6 -5
- package/dist/next/src/routing/locale/get-locale-from-query.js +1 -9
- package/dist/next/src/routing/{navigation → outbound}/decide-strategy.js +2 -5
- package/dist/{svelte-kit/src/routing/navigation/derive-target.js → next/src/routing/outbound/determine-target.js} +3 -6
- package/dist/next/src/routing/outbound/resolve-outbound.js +23 -0
- package/dist/next/src/server/messages/load-messages.js +5 -5
- package/dist/react/src/client/react/helpers/use-intor.js +3 -8
- package/dist/react/src/client/react/provider/intor-provider.js +2 -2
- package/dist/react/src/client/shared/messages/create-refetch-messages.js +1 -1
- package/dist/react/src/core/utils/resolve-loader-options.js +4 -2
- package/dist/svelte/src/client/shared/messages/create-refetch-messages.js +1 -1
- package/dist/svelte/src/core/utils/resolve-loader-options.js +4 -2
- package/dist/svelte-kit/export/svelte-kit/index.js +1 -1
- package/dist/svelte-kit/export/svelte-kit/server/index.js +1 -1
- package/dist/svelte-kit/src/adapters/svelte-kit/server/{create-intor-handle.js → create-intor-handler.js} +10 -9
- package/dist/svelte-kit/src/adapters/svelte-kit/{navigation/use-navigation.js → use-navigation.js} +6 -6
- package/dist/svelte-kit/src/client/shared/navigation/execute-navigation.js +6 -6
- package/dist/svelte-kit/src/core/utils/resolve-loader-options.js +7 -3
- package/dist/svelte-kit/src/policies/shoud-full-reload.js +1 -1
- package/dist/svelte-kit/src/routing/inbound/resolve-inbound.js +3 -4
- package/dist/svelte-kit/src/routing/inbound/resolve-locale/resolve-locale.js +6 -5
- package/dist/svelte-kit/src/routing/locale/get-locale-from-query.js +1 -9
- package/dist/svelte-kit/src/routing/{navigation → outbound}/decide-strategy.js +2 -5
- package/dist/{next/src/routing/navigation/derive-target.js → svelte-kit/src/routing/outbound/determine-target.js} +3 -6
- package/dist/svelte-kit/src/routing/outbound/resolve-outbound.js +23 -0
- package/dist/svelte-kit/src/server/messages/load-messages.js +5 -5
- package/dist/types/export/express/index.d.ts +1 -1
- package/dist/types/export/index.d.ts +1 -1
- package/dist/types/export/next/index.d.ts +1 -1
- package/dist/types/export/svelte-kit/index.d.ts +1 -1
- package/dist/types/export/svelte-kit/server/index.d.ts +1 -1
- package/dist/types/src/adapters/express/{middleware/create-intor-middleware.d.ts → create-intor-handler.d.ts} +3 -3
- package/dist/types/src/adapters/express/{helpers/get-translator.d.ts → get-translator.d.ts} +3 -3
- package/dist/types/src/adapters/express/global.d.ts +5 -4
- package/dist/types/src/adapters/express/index.d.ts +2 -2
- package/dist/types/src/adapters/next/{proxy/intor-proxy.d.ts → create-intor-handler.d.ts} +2 -2
- package/dist/types/src/adapters/next/{navigation/index.d.ts → index.d.ts} +1 -0
- package/dist/types/src/adapters/next/{navigation/link.d.ts → link.d.ts} +1 -1
- package/dist/types/src/adapters/next/{navigation/redirect.d.ts → redirect.d.ts} +2 -2
- package/dist/types/src/adapters/next/{navigation/use-router.d.ts → use-router.d.ts} +1 -1
- package/dist/types/src/adapters/svelte-kit/server/{create-intor-handle.d.ts → create-intor-handler.d.ts} +1 -1
- package/dist/types/src/adapters/svelte-kit/server/index.d.ts +1 -1
- package/dist/types/src/adapters/svelte-kit/server/utils/is-svelte-kit-ssg.d.ts +1 -1
- package/dist/types/src/adapters/svelte-kit/{navigation/use-navigation.d.ts → use-navigation.d.ts} +1 -1
- package/dist/types/src/client/react/helpers/use-intor.d.ts +2 -2
- package/dist/types/src/client/react/provider/intor-provider.d.ts +1 -1
- package/dist/types/src/client/shared/messages/create-refetch-messages.d.ts +2 -2
- package/dist/types/src/client/shared/navigation/execute-navigation.d.ts +9 -8
- package/dist/types/src/client/shared/utils/locale/set-document-locale.d.ts +2 -1
- package/dist/types/src/client/shared/utils/locale/set-locale-cookie.d.ts +2 -1
- package/dist/types/src/client/vue/helpers/use-intor.d.ts +1 -1
- package/dist/types/src/config/types/intor-config.d.ts +2 -2
- package/dist/types/src/config/types/loader.d.ts +3 -3
- package/dist/types/src/config/validators/validate-default-locale.d.ts +2 -1
- package/dist/types/src/core/index.d.ts +1 -1
- package/dist/types/src/core/messages/load-remote-messages/collect-remote-resources.d.ts +2 -1
- package/dist/types/src/core/messages/load-remote-messages/types.d.ts +3 -2
- package/dist/types/src/core/utils/index.d.ts +1 -1
- package/dist/types/src/core/utils/normalizers/index.d.ts +1 -1
- package/dist/types/src/core/utils/normalizers/normalize-locale.d.ts +2 -1
- package/dist/types/src/core/utils/normalizers/normalize-query.d.ts +2 -1
- package/dist/types/src/policies/should-sync-locale.d.ts +2 -1
- package/dist/types/src/routing/inbound/index.d.ts +1 -1
- package/dist/types/src/routing/inbound/resolve-inbound.d.ts +12 -7
- package/dist/types/src/routing/inbound/resolve-locale/resolve-locale.d.ts +3 -3
- package/dist/types/src/routing/inbound/resolve-locale/types.d.ts +7 -6
- package/dist/types/src/routing/inbound/resolve-pathname/types.d.ts +2 -1
- package/dist/types/src/routing/inbound/types.d.ts +4 -3
- package/dist/types/src/routing/index.d.ts +2 -2
- package/dist/types/src/routing/locale/get-locale-from-query.d.ts +2 -5
- package/dist/types/src/routing/outbound/decide-strategy.d.ts +7 -0
- package/dist/types/src/routing/outbound/determine-target.d.ts +14 -0
- package/dist/types/src/routing/outbound/index.d.ts +1 -0
- package/dist/types/src/routing/outbound/resolve-outbound.d.ts +14 -0
- package/dist/types/src/server/helpers/get-translator.d.ts +2 -2
- package/dist/types/src/server/messages/load-local-messages/read-locale-messages/types.d.ts +2 -1
- package/dist/types/src/server/messages/load-local-messages/types.d.ts +2 -1
- package/dist/types/src/server/translator/create-translator.d.ts +2 -2
- package/dist/vue/src/client/shared/messages/create-refetch-messages.js +1 -1
- package/dist/vue/src/client/vue/helpers/use-intor.js +2 -10
- package/dist/vue/src/client/vue/provider/intor-provider.js +0 -1
- package/dist/vue/src/core/utils/resolve-loader-options.js +4 -2
- package/package.json +1 -5
- package/dist/next/export/next/proxy/index.js +0 -1
- package/dist/next/src/routing/navigation/resolve-navigation.js +0 -26
- package/dist/svelte-kit/src/routing/navigation/resolve-navigation.js +0 -26
- package/dist/types/export/next/proxy/index.d.ts +0 -1
- package/dist/types/src/adapters/express/helpers/index.d.ts +0 -1
- package/dist/types/src/adapters/express/middleware/index.d.ts +0 -1
- package/dist/types/src/adapters/next/proxy/index.d.ts +0 -1
- package/dist/types/src/routing/navigation/decide-strategy.d.ts +0 -17
- package/dist/types/src/routing/navigation/derive-target.d.ts +0 -17
- package/dist/types/src/routing/navigation/index.d.ts +0 -1
- package/dist/types/src/routing/navigation/resolve-navigation.d.ts +0 -25
- /package/dist/next/src/routing/{navigation → outbound}/utils/derive-host-destination.js +0 -0
- /package/dist/next/src/routing/{navigation → outbound}/utils/derive-query-destination.js +0 -0
- /package/dist/next/src/routing/{navigation → outbound}/utils/is-external-destination.js +0 -0
- /package/dist/svelte-kit/src/routing/{navigation → outbound}/utils/derive-host-destination.js +0 -0
- /package/dist/svelte-kit/src/routing/{navigation → outbound}/utils/derive-query-destination.js +0 -0
- /package/dist/svelte-kit/src/routing/{navigation → outbound}/utils/is-external-destination.js +0 -0
- /package/dist/types/src/adapters/svelte-kit/{navigation/index.d.ts → index.d.ts} +0 -0
- /package/dist/types/src/routing/{navigation → outbound}/utils/derive-host-destination.d.ts +0 -0
- /package/dist/types/src/routing/{navigation → outbound}/utils/derive-query-destination.d.ts +0 -0
- /package/dist/types/src/routing/{navigation → outbound}/utils/is-external-destination.d.ts +0 -0
|
@@ -18,16 +18,20 @@
|
|
|
18
18
|
* for the given runtime.
|
|
19
19
|
*/
|
|
20
20
|
const resolveLoaderOptions = (config, runtime) => {
|
|
21
|
-
//
|
|
21
|
+
// ------------------------------------------------
|
|
22
|
+
// runtime: client
|
|
23
|
+
// ------------------------------------------------
|
|
22
24
|
if (runtime === "client") {
|
|
23
25
|
const client = config.client?.loader;
|
|
24
26
|
if (client) {
|
|
25
27
|
// Client loader is always remote by design
|
|
26
|
-
return {
|
|
28
|
+
return { mode: "remote", ...client };
|
|
27
29
|
}
|
|
28
30
|
return config.server?.loader ?? config.loader;
|
|
29
31
|
}
|
|
30
|
-
//
|
|
32
|
+
// ------------------------------------------------
|
|
33
|
+
// runtime: server
|
|
34
|
+
// ------------------------------------------------
|
|
31
35
|
return config.server?.loader ?? config.loader;
|
|
32
36
|
};
|
|
33
37
|
|
|
@@ -29,12 +29,12 @@ const loadMessages = async ({ config, locale, readers, allowCacheWrite = false,
|
|
|
29
29
|
logger.warn("No loader options have been configured in the current config.");
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
-
const {
|
|
32
|
+
const { mode, namespaces, concurrency } = loader;
|
|
33
33
|
const fallbackLocales = config.fallbackLocales[locale] || [];
|
|
34
34
|
logger.info(`Loading messages for locale "${locale}".`);
|
|
35
35
|
logger.trace("Starting to load messages with runtime context.", {
|
|
36
|
-
|
|
37
|
-
...(
|
|
36
|
+
loaderMode: mode,
|
|
37
|
+
...(mode === "local" ? { rootDir: loader.rootDir } : {}),
|
|
38
38
|
locale,
|
|
39
39
|
fallbackLocales: fallbackLocales.join(", "),
|
|
40
40
|
namespaces: namespaces && namespaces.length > 0 ? [...namespaces] : "*",
|
|
@@ -43,7 +43,7 @@ const loadMessages = async ({ config, locale, readers, allowCacheWrite = false,
|
|
|
43
43
|
// Dispatch to loader implementation
|
|
44
44
|
// ---------------------------------------------------------------------------
|
|
45
45
|
let loadedMessages;
|
|
46
|
-
if (
|
|
46
|
+
if (mode === "local") {
|
|
47
47
|
loadedMessages = await loadLocalMessages({
|
|
48
48
|
id: config.id,
|
|
49
49
|
locale,
|
|
@@ -56,7 +56,7 @@ const loadMessages = async ({ config, locale, readers, allowCacheWrite = false,
|
|
|
56
56
|
loggerOptions: config.logger,
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
|
-
else if (
|
|
59
|
+
else if (mode === "remote") {
|
|
60
60
|
loadedMessages = await loadRemoteMessages({
|
|
61
61
|
locale,
|
|
62
62
|
fallbackLocales,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { getTranslator } from '../../src/adapters/express/
|
|
1
|
+
export { createIntorHandler } from '../../src/adapters/express/create-intor-handler.js';
|
|
2
|
+
export { getTranslator } from '../../src/adapters/express/get-translator.js';
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import '
|
|
2
|
-
import { normalizeQuery } from '
|
|
1
|
+
import '../../core/error/intor-error.js';
|
|
2
|
+
import { normalizeQuery } from '../../core/utils/normalizers/normalize-query.js';
|
|
3
3
|
import 'logry';
|
|
4
4
|
import 'p-limit';
|
|
5
5
|
import 'intor-translator';
|
|
6
|
-
import { resolveInbound } from '
|
|
7
|
-
import { getLocaleFromAcceptLanguage } from '
|
|
6
|
+
import { resolveInbound } from '../../routing/inbound/resolve-inbound.js';
|
|
7
|
+
import { getLocaleFromAcceptLanguage } from '../../routing/locale/get-locale-from-accept-language.js';
|
|
8
8
|
import 'node:path';
|
|
9
9
|
import 'node:fs/promises';
|
|
10
|
-
import { getTranslator } from '
|
|
11
|
-
import { parseCookieHeader } from '
|
|
10
|
+
import { getTranslator } from '../../server/helpers/get-translator.js';
|
|
11
|
+
import { parseCookieHeader } from '../../server/shared/utils/parse-cookie-header.js';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Resolves locale-aware routing for the current execution context.
|
|
@@ -20,15 +20,15 @@ import { parseCookieHeader } from '../../../server/shared/utils/parse-cookie-hea
|
|
|
20
20
|
*
|
|
21
21
|
* @platform Express
|
|
22
22
|
*/
|
|
23
|
-
function
|
|
24
|
-
return async function
|
|
23
|
+
function createIntorHandler(config, options) {
|
|
24
|
+
return async function intorHandler(req, _res, next) {
|
|
25
25
|
// Locale from Accept-Language header
|
|
26
26
|
const acceptLanguage = req.headers["accept-language"];
|
|
27
27
|
const localeFromAcceptLanguage = getLocaleFromAcceptLanguage(acceptLanguage, config.supportedLocales);
|
|
28
28
|
// ----------------------------------------------------------
|
|
29
29
|
// Resolve inbound routing decision (pure computation)
|
|
30
30
|
// ----------------------------------------------------------
|
|
31
|
-
const { locale, localeSource, pathname } = await resolveInbound(config, req.path,
|
|
31
|
+
const { locale, localeSource, pathname } = await resolveInbound(config, req.path, {
|
|
32
32
|
host: req.hostname,
|
|
33
33
|
query: normalizeQuery(req.query),
|
|
34
34
|
cookie: parseCookieHeader(req.headers.cookie)[config.cookie.name],
|
|
@@ -38,19 +38,20 @@ function createIntorMiddleware(config, options) {
|
|
|
38
38
|
// Bind inbound routing context
|
|
39
39
|
// --------------------------------------------------
|
|
40
40
|
req.intor = { locale, localeSource, pathname };
|
|
41
|
-
const { hasKey, t } =
|
|
41
|
+
const { hasKey, t, tRich } = await getTranslator(config, {
|
|
42
42
|
locale,
|
|
43
43
|
handlers: options?.handlers,
|
|
44
44
|
plugins: options?.plugins,
|
|
45
45
|
readers: options?.readers,
|
|
46
46
|
allowCacheWrite: true,
|
|
47
|
-
})
|
|
47
|
+
});
|
|
48
48
|
// DX shortcuts (optional)
|
|
49
49
|
req.locale = locale;
|
|
50
50
|
req.hasKey = hasKey;
|
|
51
51
|
req.t = t;
|
|
52
|
+
req.tRich = tRich;
|
|
52
53
|
return next();
|
|
53
54
|
};
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
export {
|
|
57
|
+
export { createIntorHandler };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import '
|
|
1
|
+
import '../../core/error/intor-error.js';
|
|
2
2
|
import 'logry';
|
|
3
3
|
import 'p-limit';
|
|
4
4
|
import 'intor-translator';
|
|
5
5
|
import 'node:path';
|
|
6
6
|
import 'node:fs/promises';
|
|
7
|
-
import { getTranslator as getTranslator$1 } from '
|
|
7
|
+
import { getTranslator as getTranslator$1 } from '../../server/helpers/get-translator.js';
|
|
8
8
|
|
|
9
9
|
// Implementation
|
|
10
10
|
async function getTranslator(config, req, params) {
|
|
@@ -16,10 +16,6 @@ async function getTranslator(config, req, params) {
|
|
|
16
16
|
plugins,
|
|
17
17
|
readers,
|
|
18
18
|
allowCacheWrite,
|
|
19
|
-
// NOTE:
|
|
20
|
-
// The runtime implementation is intentionally erased.
|
|
21
|
-
// Type safety is guaranteed by public type contracts.
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
19
|
});
|
|
24
20
|
}
|
|
25
21
|
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
* for the given runtime.
|
|
19
19
|
*/
|
|
20
20
|
const resolveLoaderOptions = (config, runtime) => {
|
|
21
|
-
//
|
|
21
|
+
// ------------------------------------------------
|
|
22
|
+
// runtime: server
|
|
23
|
+
// ------------------------------------------------
|
|
22
24
|
return config.server?.loader ?? config.loader;
|
|
23
25
|
};
|
|
24
26
|
|
|
@@ -13,7 +13,8 @@ import { resolvePathname } from './resolve-pathname/resolve-pathname.js';
|
|
|
13
13
|
*
|
|
14
14
|
* No side effects. No navigation.
|
|
15
15
|
*/
|
|
16
|
-
async function resolveInbound(config, rawPathname,
|
|
16
|
+
async function resolveInbound(config, rawPathname, localeInputs, options) {
|
|
17
|
+
const { queryKey } = config.routing.inbound;
|
|
17
18
|
const { host, query, cookie, detected } = localeInputs;
|
|
18
19
|
// ------------------------------------------------------
|
|
19
20
|
// Resolve locale from inbound inputs
|
|
@@ -22,9 +23,7 @@ async function resolveInbound(config, rawPathname, hasRedirected, localeInputs)
|
|
|
22
23
|
const { locale, localeSource } = resolveLocale(config, {
|
|
23
24
|
path: { locale: pathLocale },
|
|
24
25
|
host: { locale: getLocaleFromHost(host) },
|
|
25
|
-
query: {
|
|
26
|
-
locale: getLocaleFromQuery(query, config.routing.inbound.queryKey),
|
|
27
|
-
},
|
|
26
|
+
query: { locale: getLocaleFromQuery(query, queryKey) },
|
|
28
27
|
cookie: { locale: cookie },
|
|
29
28
|
detected: { locale: detected },
|
|
30
29
|
});
|
|
@@ -7,9 +7,9 @@ import 'intor-translator';
|
|
|
7
7
|
/**
|
|
8
8
|
* Resolve the active locale from inbound routing configuration.
|
|
9
9
|
*
|
|
10
|
-
* Iterates through configured locale sources and returns the first
|
|
11
|
-
*
|
|
12
|
-
* or the default locale if none match.
|
|
10
|
+
* Iterates through configured locale sources and returns the first normalized, supported locale.
|
|
11
|
+
*
|
|
12
|
+
* Falls back to the detected locale or the default locale if none match.
|
|
13
13
|
*/
|
|
14
14
|
function resolveLocale(config, context) {
|
|
15
15
|
const { localeSources } = config.routing.inbound;
|
|
@@ -24,9 +24,10 @@ function resolveLocale(config, context) {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
// Fallback: detected is always available
|
|
27
|
+
const fallback = normalizeLocale(context.detected.locale, config.supportedLocales) ||
|
|
28
|
+
config.defaultLocale;
|
|
27
29
|
return {
|
|
28
|
-
locale:
|
|
29
|
-
config.defaultLocale,
|
|
30
|
+
locale: fallback,
|
|
30
31
|
localeSource: "detected",
|
|
31
32
|
};
|
|
32
33
|
}
|
|
@@ -11,19 +11,11 @@
|
|
|
11
11
|
*
|
|
12
12
|
* getLocaleFromQuery({}, "locale")
|
|
13
13
|
* // => undefined
|
|
14
|
-
*
|
|
15
|
-
* getLocaleFromQuery({ locale: ["zh-TW"] }, "locale")
|
|
16
|
-
* // => "zh-TW"
|
|
17
|
-
* ```
|
|
18
14
|
*/
|
|
19
15
|
function getLocaleFromQuery(query, queryKey) {
|
|
20
16
|
if (!query)
|
|
21
17
|
return;
|
|
22
|
-
|
|
23
|
-
if (!raw)
|
|
24
|
-
return;
|
|
25
|
-
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
26
|
-
return value;
|
|
18
|
+
return query[queryKey];
|
|
27
19
|
}
|
|
28
20
|
|
|
29
21
|
export { getLocaleFromQuery };
|
|
@@ -29,12 +29,12 @@ const loadMessages = async ({ config, locale, readers, allowCacheWrite = false,
|
|
|
29
29
|
logger.warn("No loader options have been configured in the current config.");
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
-
const {
|
|
32
|
+
const { mode, namespaces, concurrency } = loader;
|
|
33
33
|
const fallbackLocales = config.fallbackLocales[locale] || [];
|
|
34
34
|
logger.info(`Loading messages for locale "${locale}".`);
|
|
35
35
|
logger.trace("Starting to load messages with runtime context.", {
|
|
36
|
-
|
|
37
|
-
...(
|
|
36
|
+
loaderMode: mode,
|
|
37
|
+
...(mode === "local" ? { rootDir: loader.rootDir } : {}),
|
|
38
38
|
locale,
|
|
39
39
|
fallbackLocales: fallbackLocales.join(", "),
|
|
40
40
|
namespaces: namespaces && namespaces.length > 0 ? [...namespaces] : "*",
|
|
@@ -43,7 +43,7 @@ const loadMessages = async ({ config, locale, readers, allowCacheWrite = false,
|
|
|
43
43
|
// Dispatch to loader implementation
|
|
44
44
|
// ---------------------------------------------------------------------------
|
|
45
45
|
let loadedMessages;
|
|
46
|
-
if (
|
|
46
|
+
if (mode === "local") {
|
|
47
47
|
loadedMessages = await loadLocalMessages({
|
|
48
48
|
id: config.id,
|
|
49
49
|
locale,
|
|
@@ -56,7 +56,7 @@ const loadMessages = async ({ config, locale, readers, allowCacheWrite = false,
|
|
|
56
56
|
loggerOptions: config.logger,
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
|
-
else if (
|
|
59
|
+
else if (mode === "remote") {
|
|
60
60
|
loadedMessages = await loadRemoteMessages({
|
|
61
61
|
locale,
|
|
62
62
|
fallbackLocales,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { Link } from '../../src/adapters/next/
|
|
2
|
-
export { useRouter } from '../../src/adapters/next/
|
|
3
|
-
export { redirect } from '../../src/adapters/next/
|
|
1
|
+
export { Link } from '../../src/adapters/next/link.js';
|
|
2
|
+
export { useRouter } from '../../src/adapters/next/use-router.js';
|
|
3
|
+
export { redirect } from '../../src/adapters/next/redirect.js';
|
|
4
|
+
export { createIntorHandler } from '../../src/adapters/next/create-intor-handler.js';
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server';
|
|
2
|
-
import { INTOR_HEADERS } from '
|
|
3
|
-
import '
|
|
4
|
-
import { normalizeQuery } from '
|
|
2
|
+
import { INTOR_HEADERS } from '../../core/constants/headers.js';
|
|
3
|
+
import '../../core/error/intor-error.js';
|
|
4
|
+
import { normalizeQuery } from '../../core/utils/normalizers/normalize-query.js';
|
|
5
5
|
import 'logry';
|
|
6
6
|
import 'p-limit';
|
|
7
7
|
import 'intor-translator';
|
|
8
|
-
import { resolveInbound } from '
|
|
9
|
-
import { getLocaleFromAcceptLanguage } from '
|
|
8
|
+
import { resolveInbound } from '../../routing/inbound/resolve-inbound.js';
|
|
9
|
+
import { getLocaleFromAcceptLanguage } from '../../routing/locale/get-locale-from-accept-language.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Resolves locale-aware routing for the current execution context.
|
|
@@ -17,21 +17,22 @@ import { getLocaleFromAcceptLanguage } from '../../../routing/locale/get-locale-
|
|
|
17
17
|
*
|
|
18
18
|
* @platform Next.js
|
|
19
19
|
*/
|
|
20
|
-
const
|
|
20
|
+
const createIntorHandler = async (config, request) => {
|
|
21
|
+
const { host, searchParams, pathname: rawPathname } = request.nextUrl;
|
|
21
22
|
// Locale from Accept-Language header
|
|
22
23
|
const acceptLanguageHeader = request.headers.get("accept-language");
|
|
23
24
|
const localeFromAcceptLanguage = getLocaleFromAcceptLanguage(acceptLanguageHeader, config.supportedLocales);
|
|
24
25
|
// Check whether this navigation flow has already redirected
|
|
25
|
-
const
|
|
26
|
+
const hasRedirected = request.headers.get(INTOR_HEADERS.REDIRECTED) === "1";
|
|
26
27
|
// ----------------------------------------------------------
|
|
27
28
|
// Resolve inbound routing decision (pure computation)
|
|
28
29
|
// ----------------------------------------------------------
|
|
29
|
-
const { locale, localeSource, pathname, shouldRedirect } = await resolveInbound(config,
|
|
30
|
-
host
|
|
31
|
-
query: normalizeQuery(Object.fromEntries(
|
|
30
|
+
const { locale, localeSource, pathname, shouldRedirect } = await resolveInbound(config, rawPathname, {
|
|
31
|
+
host,
|
|
32
|
+
query: normalizeQuery(Object.fromEntries(searchParams.entries())),
|
|
32
33
|
cookie: request.cookies.get(config.cookie.name)?.value,
|
|
33
34
|
detected: localeFromAcceptLanguage || config.defaultLocale,
|
|
34
|
-
});
|
|
35
|
+
}, { hasRedirected });
|
|
35
36
|
// ----------------------------------------------------------
|
|
36
37
|
// Prepare Next.js response (redirect or pass-through)
|
|
37
38
|
// ----------------------------------------------------------
|
|
@@ -52,4 +53,4 @@ const intorProxy = async (config, request) => {
|
|
|
52
53
|
return response;
|
|
53
54
|
};
|
|
54
55
|
|
|
55
|
-
export {
|
|
56
|
+
export { createIntorHandler };
|
|
@@ -4,13 +4,13 @@ import { formatUrl } from 'next/dist/shared/lib/router/utils/format-url';
|
|
|
4
4
|
import NextLink from 'next/link';
|
|
5
5
|
import { usePathname } from 'next/navigation';
|
|
6
6
|
import 'react';
|
|
7
|
-
import { executeNavigation } from '
|
|
7
|
+
import { executeNavigation } from '../../client/shared/navigation/execute-navigation.js';
|
|
8
8
|
import { useIntorContext } from 'intor/react';
|
|
9
|
-
import '
|
|
9
|
+
import '../../core/error/intor-error.js';
|
|
10
10
|
import 'logry';
|
|
11
11
|
import 'p-limit';
|
|
12
12
|
import 'intor-translator';
|
|
13
|
-
import {
|
|
13
|
+
import { resolveOutbound } from '../../routing/outbound/resolve-outbound.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Render a locale-aware link for the current execution context.
|
|
@@ -26,7 +26,7 @@ const Link = ({ href, locale, children, onClick, ...props }) => {
|
|
|
26
26
|
// Normalize href into a string destination
|
|
27
27
|
const rawDestination = typeof href === "string" ? href : href ? formatUrl(href) : undefined;
|
|
28
28
|
// Resolve navigation result for this link
|
|
29
|
-
const
|
|
29
|
+
const outboundResult = resolveOutbound(config, currentLocale, currentPathname, { destination: rawDestination, locale });
|
|
30
30
|
// --------------------------------------------------
|
|
31
31
|
// Execute navigation on user interaction
|
|
32
32
|
// --------------------------------------------------
|
|
@@ -34,9 +34,9 @@ const Link = ({ href, locale, children, onClick, ...props }) => {
|
|
|
34
34
|
onClick?.(e);
|
|
35
35
|
if (e.defaultPrevented)
|
|
36
36
|
return;
|
|
37
|
-
executeNavigation(
|
|
37
|
+
executeNavigation(outboundResult, { config, currentLocale, setLocale }, e);
|
|
38
38
|
};
|
|
39
|
-
return (jsx(NextLink, { href:
|
|
39
|
+
return (jsx(NextLink, { href: outboundResult.destination, onClick: handleClick, ...props, children: children }));
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
export { Link };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { redirect as redirect$1 } from 'next/navigation';
|
|
2
|
-
import '
|
|
2
|
+
import '../../core/error/intor-error.js';
|
|
3
3
|
import 'logry';
|
|
4
4
|
import 'p-limit';
|
|
5
5
|
import 'intor-translator';
|
|
6
|
-
import {
|
|
7
|
-
import { getLocale } from '
|
|
6
|
+
import { resolveOutbound } from '../../routing/outbound/resolve-outbound.js';
|
|
7
|
+
import { getLocale } from './server/get-locale.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Redirect to a locale-aware destination for the current execution context.
|
|
@@ -16,7 +16,7 @@ import { getLocale } from '../server/get-locale.js';
|
|
|
16
16
|
*/
|
|
17
17
|
const redirect = async (config, url, { locale, type }) => {
|
|
18
18
|
const currentLocale = await getLocale(config);
|
|
19
|
-
const { destination, kind } =
|
|
19
|
+
const { destination, kind } = resolveOutbound(config, currentLocale, url, {
|
|
20
20
|
locale,
|
|
21
21
|
});
|
|
22
22
|
if (kind === "external") {
|
|
@@ -17,10 +17,6 @@ async function getTranslator(config, params) {
|
|
|
17
17
|
plugins,
|
|
18
18
|
readers,
|
|
19
19
|
allowCacheWrite,
|
|
20
|
-
// NOTE:
|
|
21
|
-
// The runtime implementation is intentionally erased.
|
|
22
|
-
// Type safety is guaranteed by public type contracts.
|
|
23
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
24
20
|
});
|
|
25
21
|
}
|
|
26
22
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { usePathname, useRouter as useRouter$1 } from 'next/navigation';
|
|
2
|
-
import { executeNavigation } from '
|
|
2
|
+
import { executeNavigation } from '../../client/shared/navigation/execute-navigation.js';
|
|
3
3
|
import { useIntorContext } from 'intor/react';
|
|
4
|
-
import '
|
|
4
|
+
import '../../core/error/intor-error.js';
|
|
5
5
|
import 'logry';
|
|
6
6
|
import 'p-limit';
|
|
7
7
|
import 'intor-translator';
|
|
8
|
-
import {
|
|
8
|
+
import { resolveOutbound } from '../../routing/outbound/resolve-outbound.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Locale-aware router hook for the current execution context.
|
|
@@ -23,23 +23,23 @@ const useRouter = () => {
|
|
|
23
23
|
// push
|
|
24
24
|
// --------------------------------------------------
|
|
25
25
|
const push = (href, options) => {
|
|
26
|
-
const
|
|
27
|
-
executeNavigation(
|
|
28
|
-
nextRouterPush(
|
|
26
|
+
const outboundResult = resolveOutbound(config, currentLocale, currentPathname, { destination: href, locale: options?.locale });
|
|
27
|
+
executeNavigation(outboundResult, { config, currentLocale, setLocale });
|
|
28
|
+
nextRouterPush(outboundResult.destination, options);
|
|
29
29
|
};
|
|
30
30
|
// --------------------------------------------------
|
|
31
31
|
// replace
|
|
32
32
|
// --------------------------------------------------
|
|
33
33
|
const replace = (href, options) => {
|
|
34
|
-
const
|
|
35
|
-
executeNavigation(
|
|
36
|
-
nextRouterReplace(
|
|
34
|
+
const outboundResult = resolveOutbound(config, currentLocale, currentPathname, { destination: href, locale: options?.locale });
|
|
35
|
+
executeNavigation(outboundResult, { config, currentLocale, setLocale });
|
|
36
|
+
nextRouterReplace(outboundResult.destination, options);
|
|
37
37
|
};
|
|
38
38
|
// --------------------------------------------------
|
|
39
39
|
// prefetch
|
|
40
40
|
// --------------------------------------------------
|
|
41
41
|
const prefetch = (href, options) => {
|
|
42
|
-
const { kind, destination } =
|
|
42
|
+
const { kind, destination } = resolveOutbound(config, currentLocale, currentPathname, { destination: href, locale: options?.locale });
|
|
43
43
|
if (kind !== "client")
|
|
44
44
|
return; // Prefetch only makes sense for client-side navigation
|
|
45
45
|
nextRouterPrefetch(destination, options);
|
|
@@ -6,17 +6,17 @@ import { shouldSyncLocale } from '../../../policies/should-sync-locale.js';
|
|
|
6
6
|
import { setLocaleCookie } from '../utils/locale/set-locale-cookie.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* Executes a resolved
|
|
9
|
+
* Executes a resolved outbound routing result.
|
|
10
10
|
*
|
|
11
|
-
* Applies all imperative side effects required to
|
|
12
|
-
* including locale synchronization, cookie persistence, and full reloads.
|
|
11
|
+
* Applies all imperative side effects required to realize the outbound decision,
|
|
12
|
+
* including locale synchronization, cookie persistence, and full page reloads.
|
|
13
13
|
*
|
|
14
|
-
* This function must be called after `
|
|
14
|
+
* This function must be called after `resolveOutbound`.
|
|
15
15
|
*/
|
|
16
|
-
function executeNavigation(
|
|
16
|
+
function executeNavigation(outboundResult, context, e) {
|
|
17
17
|
const { config, currentLocale, setLocale } = context;
|
|
18
18
|
const { cookie } = config;
|
|
19
|
-
const { destination, kind, locale } =
|
|
19
|
+
const { destination, kind, locale } = outboundResult;
|
|
20
20
|
// ------------------------------------------------------
|
|
21
21
|
// External navigation: let browser handle it
|
|
22
22
|
// ------------------------------------------------------
|
|
@@ -18,16 +18,20 @@
|
|
|
18
18
|
* for the given runtime.
|
|
19
19
|
*/
|
|
20
20
|
const resolveLoaderOptions = (config, runtime) => {
|
|
21
|
-
//
|
|
21
|
+
// ------------------------------------------------
|
|
22
|
+
// runtime: client
|
|
23
|
+
// ------------------------------------------------
|
|
22
24
|
if (runtime === "client") {
|
|
23
25
|
const client = config.client?.loader;
|
|
24
26
|
if (client) {
|
|
25
27
|
// Client loader is always remote by design
|
|
26
|
-
return {
|
|
28
|
+
return { mode: "remote", ...client };
|
|
27
29
|
}
|
|
28
30
|
return config.server?.loader ?? config.loader;
|
|
29
31
|
}
|
|
30
|
-
//
|
|
32
|
+
// ------------------------------------------------
|
|
33
|
+
// runtime: server
|
|
34
|
+
// ------------------------------------------------
|
|
31
35
|
return config.server?.loader ?? config.loader;
|
|
32
36
|
};
|
|
33
37
|
|
|
@@ -9,7 +9,7 @@ import 'intor-translator';
|
|
|
9
9
|
*/
|
|
10
10
|
function shouldFullReload(config) {
|
|
11
11
|
const loader = resolveLoaderOptions(config, "client");
|
|
12
|
-
return (loader?.
|
|
12
|
+
return (loader?.mode === "local" || config.routing.outbound.forceFullReload === true);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export { shouldFullReload };
|
|
@@ -13,7 +13,8 @@ import { resolvePathname } from './resolve-pathname/resolve-pathname.js';
|
|
|
13
13
|
*
|
|
14
14
|
* No side effects. No navigation.
|
|
15
15
|
*/
|
|
16
|
-
async function resolveInbound(config, rawPathname,
|
|
16
|
+
async function resolveInbound(config, rawPathname, localeInputs, options) {
|
|
17
|
+
const { queryKey } = config.routing.inbound;
|
|
17
18
|
const { host, query, cookie, detected } = localeInputs;
|
|
18
19
|
// ------------------------------------------------------
|
|
19
20
|
// Resolve locale from inbound inputs
|
|
@@ -22,9 +23,7 @@ async function resolveInbound(config, rawPathname, hasRedirected, localeInputs)
|
|
|
22
23
|
const { locale, localeSource } = resolveLocale(config, {
|
|
23
24
|
path: { locale: pathLocale },
|
|
24
25
|
host: { locale: getLocaleFromHost(host) },
|
|
25
|
-
query: {
|
|
26
|
-
locale: getLocaleFromQuery(query, config.routing.inbound.queryKey),
|
|
27
|
-
},
|
|
26
|
+
query: { locale: getLocaleFromQuery(query, queryKey) },
|
|
28
27
|
cookie: { locale: cookie },
|
|
29
28
|
detected: { locale: detected },
|
|
30
29
|
});
|
|
@@ -35,7 +34,7 @@ async function resolveInbound(config, rawPathname, hasRedirected, localeInputs)
|
|
|
35
34
|
locale,
|
|
36
35
|
hasPathLocale: !!pathLocale,
|
|
37
36
|
hasPersisted: !!cookie,
|
|
38
|
-
hasRedirected,
|
|
37
|
+
hasRedirected: !!options?.hasRedirected,
|
|
39
38
|
});
|
|
40
39
|
return {
|
|
41
40
|
locale,
|
|
@@ -7,9 +7,9 @@ import 'intor-translator';
|
|
|
7
7
|
/**
|
|
8
8
|
* Resolve the active locale from inbound routing configuration.
|
|
9
9
|
*
|
|
10
|
-
* Iterates through configured locale sources and returns the first
|
|
11
|
-
*
|
|
12
|
-
* or the default locale if none match.
|
|
10
|
+
* Iterates through configured locale sources and returns the first normalized, supported locale.
|
|
11
|
+
*
|
|
12
|
+
* Falls back to the detected locale or the default locale if none match.
|
|
13
13
|
*/
|
|
14
14
|
function resolveLocale(config, context) {
|
|
15
15
|
const { localeSources } = config.routing.inbound;
|
|
@@ -24,9 +24,10 @@ function resolveLocale(config, context) {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
// Fallback: detected is always available
|
|
27
|
+
const fallback = normalizeLocale(context.detected.locale, config.supportedLocales) ||
|
|
28
|
+
config.defaultLocale;
|
|
27
29
|
return {
|
|
28
|
-
locale:
|
|
29
|
-
config.defaultLocale,
|
|
30
|
+
locale: fallback,
|
|
30
31
|
localeSource: "detected",
|
|
31
32
|
};
|
|
32
33
|
}
|
|
@@ -11,19 +11,11 @@
|
|
|
11
11
|
*
|
|
12
12
|
* getLocaleFromQuery({}, "locale")
|
|
13
13
|
* // => undefined
|
|
14
|
-
*
|
|
15
|
-
* getLocaleFromQuery({ locale: ["zh-TW"] }, "locale")
|
|
16
|
-
* // => "zh-TW"
|
|
17
|
-
* ```
|
|
18
14
|
*/
|
|
19
15
|
function getLocaleFromQuery(query, queryKey) {
|
|
20
16
|
if (!query)
|
|
21
17
|
return;
|
|
22
|
-
|
|
23
|
-
if (!raw)
|
|
24
|
-
return;
|
|
25
|
-
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
26
|
-
return value;
|
|
18
|
+
return query[queryKey];
|
|
27
19
|
}
|
|
28
20
|
|
|
29
21
|
export { getLocaleFromQuery };
|
|
@@ -2,16 +2,13 @@ import { shouldFullReload } from '../../policies/shoud-full-reload.js';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Decide how a resolved navigation target should be executed.
|
|
5
|
-
*
|
|
6
|
-
* This function determines whether navigation should be handled
|
|
7
|
-
* by the browser, performed client-side, or forced to reload.
|
|
8
5
|
*/
|
|
9
6
|
function decideStrategy(config, target) {
|
|
10
7
|
// External destinations are always handled by the browser
|
|
11
8
|
if (target.isExternal) {
|
|
12
|
-
return
|
|
9
|
+
return "external";
|
|
13
10
|
}
|
|
14
|
-
return shouldFullReload(config) ?
|
|
11
|
+
return shouldFullReload(config) ? "reload" : "client";
|
|
15
12
|
}
|
|
16
13
|
|
|
17
14
|
export { decideStrategy };
|
|
@@ -5,12 +5,9 @@ import { deriveQueryDestination } from './utils/derive-query-destination.js';
|
|
|
5
5
|
import { isExternalDestination } from './utils/is-external-destination.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* This function computes the final destination URL and execution flags
|
|
11
|
-
* based on the current routing configuration and locale context.
|
|
8
|
+
* Determines the outbound routing target.
|
|
12
9
|
*/
|
|
13
|
-
function
|
|
10
|
+
function determineTarget(config, currentLocale, currentPathname, intent) {
|
|
14
11
|
const { supportedLocales, routing } = config;
|
|
15
12
|
// ----------------------------------------------------------------
|
|
16
13
|
// Resolve effective locale
|
|
@@ -55,4 +52,4 @@ function deriveTarget(config, currentLocale, currentPathname, intent) {
|
|
|
55
52
|
};
|
|
56
53
|
}
|
|
57
54
|
|
|
58
|
-
export {
|
|
55
|
+
export { determineTarget };
|