@bleedingdev/modern-js-plugin-i18n 3.5.0-ultramodern.4 → 3.5.0-ultramodern.41
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/cjs/cli/index.js +2 -1
- package/dist/cjs/cli/locales.js +15 -15
- package/dist/cjs/runtime/Link.js +8 -89
- package/dist/cjs/runtime/context.js +18 -82
- package/dist/cjs/runtime/contextHelpers.js +137 -0
- package/dist/cjs/runtime/core.js +29 -132
- package/dist/cjs/runtime/i18n/backend/defaults.node.js +7 -7
- package/dist/cjs/runtime/i18n/detection/cache.js +150 -0
- package/dist/cjs/runtime/i18n/detection/detector.js +100 -0
- package/dist/cjs/runtime/i18n/detection/index.js +8 -263
- package/dist/cjs/runtime/i18n/detection/initOptions.js +69 -0
- package/dist/cjs/runtime/i18n/detection/language.js +62 -0
- package/dist/cjs/runtime/i18n/detection/path.js +49 -0
- package/dist/cjs/runtime/i18n/detection/priority.js +66 -0
- package/dist/cjs/runtime/i18n/detection/ssr.js +70 -0
- package/dist/cjs/runtime/i18n/detection/types.js +18 -0
- package/dist/cjs/runtime/i18n/instance.js +7 -7
- package/dist/cjs/runtime/linkHelpers.js +148 -0
- package/dist/cjs/runtime/pluginSetup.js +102 -0
- package/dist/cjs/runtime/providerComposition.js +114 -0
- package/dist/cjs/runtime/reactI18next.js +43 -0
- package/dist/cjs/runtime/utils.js +1 -9
- package/dist/cjs/server/apiPrefix.js +72 -0
- package/dist/cjs/server/detectorOptions.js +97 -0
- package/dist/cjs/server/index.js +17 -144
- package/dist/cjs/server/redirectPolicy.js +96 -0
- package/dist/cjs/shared/detection.js +2 -104
- package/dist/cjs/shared/localisedUrls/config.js +49 -0
- package/dist/cjs/shared/localisedUrls/index.js +91 -0
- package/dist/cjs/shared/localisedUrls/normalise.js +87 -0
- package/dist/cjs/shared/localisedUrls/pathname.js +68 -0
- package/dist/cjs/shared/localisedUrls/patterns.js +130 -0
- package/dist/cjs/shared/localisedUrls/redirect.js +95 -0
- package/dist/cjs/shared/localisedUrls/resolve.js +88 -0
- package/dist/cjs/shared/localisedUrls/routes.js +129 -0
- package/dist/cjs/shared/localisedUrls/types.js +18 -0
- package/dist/cjs/shared/localisedUrls.js +28 -294
- package/dist/cjs/shared/utils.js +2 -8
- package/dist/esm/cli/index.mjs +2 -1
- package/dist/esm/cli/locales.mjs +13 -13
- package/dist/esm/runtime/Link.mjs +1 -82
- package/dist/esm/runtime/context.mjs +18 -82
- package/dist/esm/runtime/contextHelpers.mjs +84 -0
- package/dist/esm/runtime/core.mjs +30 -133
- package/dist/esm/runtime/i18n/backend/defaults.node.mjs +5 -5
- package/dist/esm/runtime/i18n/detection/cache.mjs +103 -0
- package/dist/esm/runtime/i18n/detection/detector.mjs +62 -0
- package/dist/esm/runtime/i18n/detection/index.mjs +4 -260
- package/dist/esm/runtime/i18n/detection/initOptions.mjs +28 -0
- package/dist/esm/runtime/i18n/detection/language.mjs +21 -0
- package/dist/esm/runtime/i18n/detection/path.mjs +11 -0
- package/dist/esm/runtime/i18n/detection/priority.mjs +28 -0
- package/dist/esm/runtime/i18n/detection/ssr.mjs +26 -0
- package/dist/esm/runtime/i18n/detection/types.mjs +0 -0
- package/dist/esm/runtime/i18n/instance.mjs +8 -5
- package/dist/esm/runtime/linkHelpers.mjs +98 -0
- package/dist/esm/runtime/pluginSetup.mjs +64 -0
- package/dist/esm/runtime/providerComposition.mjs +76 -0
- package/dist/esm/runtime/reactI18next.mjs +5 -0
- package/dist/esm/runtime/utils.mjs +2 -10
- package/dist/esm/server/apiPrefix.mjs +31 -0
- package/dist/esm/server/detectorOptions.mjs +59 -0
- package/dist/esm/server/index.mjs +8 -135
- package/dist/esm/server/redirectPolicy.mjs +46 -0
- package/dist/esm/shared/detection.mjs +1 -71
- package/dist/esm/shared/localisedUrls/config.mjs +11 -0
- package/dist/esm/shared/localisedUrls/index.mjs +7 -0
- package/dist/esm/shared/localisedUrls/normalise.mjs +37 -0
- package/dist/esm/shared/localisedUrls/pathname.mjs +24 -0
- package/dist/esm/shared/localisedUrls/patterns.mjs +86 -0
- package/dist/esm/shared/localisedUrls/redirect.mjs +48 -0
- package/dist/esm/shared/localisedUrls/resolve.mjs +47 -0
- package/dist/esm/shared/localisedUrls/routes.mjs +88 -0
- package/dist/esm/shared/localisedUrls/types.mjs +0 -0
- package/dist/esm/shared/localisedUrls.mjs +1 -283
- package/dist/esm/shared/utils.mjs +1 -1
- package/dist/esm-node/cli/index.mjs +2 -1
- package/dist/esm-node/cli/locales.mjs +13 -13
- package/dist/esm-node/runtime/Link.mjs +1 -82
- package/dist/esm-node/runtime/context.mjs +18 -82
- package/dist/esm-node/runtime/contextHelpers.mjs +85 -0
- package/dist/esm-node/runtime/core.mjs +30 -133
- package/dist/esm-node/runtime/i18n/backend/defaults.node.mjs +5 -5
- package/dist/esm-node/runtime/i18n/detection/cache.mjs +104 -0
- package/dist/esm-node/runtime/i18n/detection/detector.mjs +63 -0
- package/dist/esm-node/runtime/i18n/detection/index.mjs +4 -260
- package/dist/esm-node/runtime/i18n/detection/initOptions.mjs +29 -0
- package/dist/esm-node/runtime/i18n/detection/language.mjs +22 -0
- package/dist/esm-node/runtime/i18n/detection/path.mjs +12 -0
- package/dist/esm-node/runtime/i18n/detection/priority.mjs +29 -0
- package/dist/esm-node/runtime/i18n/detection/ssr.mjs +27 -0
- package/dist/esm-node/runtime/i18n/detection/types.mjs +1 -0
- package/dist/esm-node/runtime/i18n/instance.mjs +8 -5
- package/dist/esm-node/runtime/linkHelpers.mjs +99 -0
- package/dist/esm-node/runtime/pluginSetup.mjs +65 -0
- package/dist/esm-node/runtime/providerComposition.mjs +77 -0
- package/dist/esm-node/runtime/reactI18next.mjs +6 -0
- package/dist/esm-node/runtime/utils.mjs +2 -10
- package/dist/esm-node/server/apiPrefix.mjs +32 -0
- package/dist/esm-node/server/detectorOptions.mjs +60 -0
- package/dist/esm-node/server/index.mjs +8 -135
- package/dist/esm-node/server/redirectPolicy.mjs +47 -0
- package/dist/esm-node/shared/detection.mjs +1 -71
- package/dist/esm-node/shared/localisedUrls/config.mjs +12 -0
- package/dist/esm-node/shared/localisedUrls/index.mjs +8 -0
- package/dist/esm-node/shared/localisedUrls/normalise.mjs +38 -0
- package/dist/esm-node/shared/localisedUrls/pathname.mjs +25 -0
- package/dist/esm-node/shared/localisedUrls/patterns.mjs +87 -0
- package/dist/esm-node/shared/localisedUrls/redirect.mjs +49 -0
- package/dist/esm-node/shared/localisedUrls/resolve.mjs +48 -0
- package/dist/esm-node/shared/localisedUrls/routes.mjs +89 -0
- package/dist/esm-node/shared/localisedUrls/types.mjs +1 -0
- package/dist/esm-node/shared/localisedUrls.mjs +1 -283
- package/dist/esm-node/shared/utils.mjs +1 -1
- package/dist/types/cli/locales.d.ts +1 -1
- package/dist/types/runtime/Link.d.ts +3 -7
- package/dist/types/runtime/context.d.ts +6 -5
- package/dist/types/runtime/contextHelpers.d.ts +28 -0
- package/dist/types/runtime/core.d.ts +3 -7
- package/dist/types/runtime/hooks.d.ts +5 -0
- package/dist/types/runtime/i18n/backend/middleware.common.d.ts +2 -1
- package/dist/types/runtime/i18n/detection/cache.d.ts +14 -0
- package/dist/types/runtime/i18n/detection/detector.d.ts +8 -0
- package/dist/types/runtime/i18n/detection/index.d.ts +5 -50
- package/dist/types/runtime/i18n/detection/initOptions.d.ts +10 -0
- package/dist/types/runtime/i18n/detection/language.d.ts +11 -0
- package/dist/types/runtime/i18n/detection/middleware.d.ts +4 -4
- package/dist/types/runtime/i18n/detection/middleware.node.d.ts +4 -4
- package/dist/types/runtime/i18n/detection/path.d.ts +5 -0
- package/dist/types/runtime/i18n/detection/priority.d.ts +10 -0
- package/dist/types/runtime/i18n/detection/ssr.d.ts +9 -0
- package/dist/types/runtime/i18n/detection/types.d.ts +32 -0
- package/dist/types/runtime/i18n/instance.d.ts +28 -26
- package/dist/types/runtime/i18n/react-i18next.d.ts +1 -6
- package/dist/types/runtime/i18n/utils.d.ts +14 -5
- package/dist/types/runtime/linkHelpers.d.ts +17 -0
- package/dist/types/runtime/pluginSetup.d.ts +32 -0
- package/dist/types/runtime/providerComposition.d.ts +16 -0
- package/dist/types/runtime/reactI18next.d.ts +7 -0
- package/dist/types/runtime/routerAdapter.d.ts +7 -6
- package/dist/types/runtime/utils.d.ts +7 -2
- package/dist/types/server/apiPrefix.d.ts +7 -0
- package/dist/types/server/detectorOptions.d.ts +21 -0
- package/dist/types/server/index.d.ts +1 -6
- package/dist/types/server/redirectPolicy.d.ts +22 -0
- package/dist/types/shared/detection.d.ts +1 -11
- package/dist/types/shared/localisedUrls/config.d.ts +9 -0
- package/dist/types/shared/localisedUrls/index.d.ts +9 -0
- package/dist/types/shared/localisedUrls/normalise.d.ts +10 -0
- package/dist/types/shared/localisedUrls/pathname.d.ts +4 -0
- package/dist/types/shared/localisedUrls/patterns.d.ts +5 -0
- package/dist/types/shared/localisedUrls/redirect.d.ts +11 -0
- package/dist/types/shared/localisedUrls/resolve.d.ts +7 -0
- package/dist/types/shared/localisedUrls/routes.d.ts +3 -0
- package/dist/types/shared/localisedUrls/types.d.ts +14 -0
- package/dist/types/shared/localisedUrls.d.ts +2 -36
- package/dist/types/shared/utils.d.ts +0 -2
- package/package.json +16 -18
- package/rstest.config.mts +1 -0
- package/src/cli/index.ts +5 -4
- package/src/cli/locales.ts +3 -3
- package/src/runtime/Link.tsx +11 -138
- package/src/runtime/context.tsx +45 -199
- package/src/runtime/contextHelpers.ts +232 -0
- package/src/runtime/core.tsx +43 -274
- package/src/runtime/hooks.ts +13 -2
- package/src/runtime/i18n/backend/defaults.node.ts +2 -2
- package/src/runtime/i18n/backend/middleware.common.ts +5 -4
- package/src/runtime/i18n/detection/cache.ts +189 -0
- package/src/runtime/i18n/detection/detector.ts +166 -0
- package/src/runtime/i18n/detection/index.ts +10 -641
- package/src/runtime/i18n/detection/initOptions.ts +74 -0
- package/src/runtime/i18n/detection/language.ts +64 -0
- package/src/runtime/i18n/detection/middleware.node.ts +26 -7
- package/src/runtime/i18n/detection/middleware.ts +15 -7
- package/src/runtime/i18n/detection/path.ts +41 -0
- package/src/runtime/i18n/detection/priority.ts +82 -0
- package/src/runtime/i18n/detection/ssr.ts +47 -0
- package/src/runtime/i18n/detection/types.ts +41 -0
- package/src/runtime/i18n/instance.ts +56 -31
- package/src/runtime/i18n/react-i18next.ts +1 -6
- package/src/runtime/i18n/utils.ts +18 -9
- package/src/runtime/linkHelpers.ts +174 -0
- package/src/runtime/pluginSetup.ts +189 -0
- package/src/runtime/providerComposition.tsx +144 -0
- package/src/runtime/reactI18next.ts +20 -0
- package/src/runtime/routerAdapter.tsx +6 -6
- package/src/runtime/utils.ts +13 -35
- package/src/server/apiPrefix.ts +67 -0
- package/src/server/detectorOptions.ts +105 -0
- package/src/server/index.ts +14 -319
- package/src/server/redirectPolicy.ts +127 -0
- package/src/shared/detection.ts +1 -1
- package/src/shared/localisedUrls/config.ts +18 -0
- package/src/shared/localisedUrls/index.ts +24 -0
- package/src/shared/localisedUrls/normalise.ts +67 -0
- package/src/shared/localisedUrls/pathname.ts +60 -0
- package/src/shared/localisedUrls/patterns.ts +160 -0
- package/src/shared/localisedUrls/redirect.ts +91 -0
- package/src/shared/localisedUrls/resolve.ts +135 -0
- package/src/shared/localisedUrls/routes.ts +226 -0
- package/src/shared/localisedUrls/types.ts +18 -0
- package/src/shared/localisedUrls.ts +26 -623
- package/src/shared/utils.ts +2 -2
- package/tests/fixtures/localised-routes.golden.json +156 -0
- package/tests/link.test.tsx +111 -0
- package/tests/linkTypes.test.ts +15 -4
- package/tests/localisedUrlRewriteMatrix.fork.test.ts +147 -0
- package/tests/localisedUrls.test.ts +129 -2
- package/tests/reactI18nextRuntimeBoundary.test.ts +6 -3
- package/tests/redirectPolicy.test.ts +43 -0
- package/tests/routerAdapter.test.tsx +85 -0
- package/tests/type-fixture/fixture-globals.d.ts +11 -0
- package/tests/type-fixture/tsconfig.json +1 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type LocalisedRoute = {
|
|
2
|
+
type: 'nested' | 'page';
|
|
3
|
+
path?: string;
|
|
4
|
+
id?: string;
|
|
5
|
+
children?: LocalisedRoute[];
|
|
6
|
+
[key: string]: any;
|
|
7
|
+
};
|
|
8
|
+
export type LocalisedUrlPathMap = Record<string, string>;
|
|
9
|
+
export type LocalisedUrlsMap = Record<string, LocalisedUrlPathMap>;
|
|
10
|
+
export type LocalisedUrlsOption = boolean | LocalisedUrlsMap;
|
|
11
|
+
export interface ResolvedLocalisedUrlsConfig {
|
|
12
|
+
enabled: boolean;
|
|
13
|
+
map: LocalisedUrlsMap;
|
|
14
|
+
}
|
|
@@ -1,36 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export type LocalisedUrlsMap = Record<string, LocalisedUrlPathMap>;
|
|
4
|
-
export type LocalisedUrlsOption = boolean | LocalisedUrlsMap;
|
|
5
|
-
export interface ResolvedLocalisedUrlsConfig {
|
|
6
|
-
enabled: boolean;
|
|
7
|
-
map: LocalisedUrlsMap;
|
|
8
|
-
}
|
|
9
|
-
export declare const normalisePathPattern: (path: string) => string;
|
|
10
|
-
/**
|
|
11
|
-
* Normalise a concrete request pathname: slash cleanup only. Unlike
|
|
12
|
-
* {@link normalisePathPattern} it must not rewrite literal `[x]` segments to
|
|
13
|
-
* `:x` params — pathnames are values, not patterns.
|
|
14
|
-
*/
|
|
15
|
-
export declare const normalisePathname: (pathname: string) => string;
|
|
16
|
-
/**
|
|
17
|
-
* Localised URLs are strictly opt-in: only an explicit, non-empty map enables
|
|
18
|
-
* route expansion and validation. `true`, `false`, an empty map and absence
|
|
19
|
-
* all resolve to disabled, so upstream-style configs (`localePathRedirect` +
|
|
20
|
-
* `languages` without a map) keep plain locale-prefix behavior instead of
|
|
21
|
-
* failing the build for every route missing from a map they never wrote.
|
|
22
|
-
*/
|
|
23
|
-
export declare const resolveLocalisedUrlsConfig: (option: LocalisedUrlsOption | undefined) => ResolvedLocalisedUrlsConfig;
|
|
24
|
-
export declare const validateLocalisedUrls: (routes: (NestedRouteForCli | PageRoute)[], languages: string[], localisedUrls: LocalisedUrlsMap) => void;
|
|
25
|
-
export declare const applyLocalisedUrlsToRoutes: (routes: (NestedRouteForCli | PageRoute)[], languages: string[], localisedUrls: LocalisedUrlsMap) => (NestedRouteForCli | PageRoute)[];
|
|
26
|
-
export declare const matchPathPattern: (pathname: string, pattern: string) => Record<string, string> | null;
|
|
27
|
-
export declare const buildPathFromPattern: (pattern: string, params: Record<string, string>) => string;
|
|
28
|
-
export declare const resolveLocalisedPath: (pathname: string, targetLanguage: string, languages: string[], localisedUrls: LocalisedUrlsMap) => string;
|
|
29
|
-
/**
|
|
30
|
-
* Reverse-map a language-specific pathname (without language prefix) back to
|
|
31
|
-
* the canonical, language-agnostic path: localized slug patterns are matched
|
|
32
|
-
* against every language variant and rebuilt from the canonical map key.
|
|
33
|
-
*/
|
|
34
|
-
export declare const resolveCanonicalLocalisedPath: (pathname: string, languages: string[], localisedUrls: LocalisedUrlsMap) => string;
|
|
35
|
-
export declare const localiseTargetPathname: (pathname: string, language: string, languages: string[], localisedUrls?: LocalisedUrlsOption) => string;
|
|
36
|
-
export declare const canonicalTargetPathname: (pathname: string, languages: string[], localisedUrls?: LocalisedUrlsOption) => string;
|
|
1
|
+
export type { LocaleRedirectSkipRule, LocalisedRoute, LocalisedUrlPathMap, LocalisedUrlsMap, LocalisedUrlsOption, ResolvedLocalisedUrlsConfig, } from './localisedUrls/index';
|
|
2
|
+
export { applyLocalisedUrlsToRoutes, buildPathFromPattern, canonicalTargetPathname, DEFAULT_LOCALE_REDIRECT_SKIP_RULES, isDefaultLocaleRedirectSkipPath, localiseTargetPathname, matchesPathPrefix, matchPathPattern, normalisePathname, normalisePathPattern, resolveCanonicalLocalisedPath, resolveLocalisedPath, resolveLocalisedUrlsConfig, shouldSkipLocaleRedirect, stripLanguagePrefix, validateLocalisedUrls, } from './localisedUrls/index';
|
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
import type { BaseBackendOptions, BaseLocaleDetectionOptions } from './type';
|
|
2
|
-
export declare function getEntryConfig<T extends Record<string, any>>(entryName: string, config: T, entryKey: string): T | undefined;
|
|
3
|
-
export declare function removeEntryConfigKey<T extends Record<string, any>>(config: T, entryKey: string): Omit<T, typeof entryKey>;
|
|
4
2
|
export declare function getLocaleDetectionOptions(entryName: string, localeDetection: BaseLocaleDetectionOptions): BaseLocaleDetectionOptions;
|
|
5
3
|
export declare function getBackendOptions(entryName: string, backend: BaseBackendOptions): BaseBackendOptions;
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"modern",
|
|
18
18
|
"modern.js"
|
|
19
19
|
],
|
|
20
|
-
"version": "3.5.0-ultramodern.
|
|
20
|
+
"version": "3.5.0-ultramodern.41",
|
|
21
21
|
"engines": {
|
|
22
22
|
"node": ">=20"
|
|
23
23
|
},
|
|
@@ -97,19 +97,18 @@
|
|
|
97
97
|
"i18next-fs-backend": "^2.6.6",
|
|
98
98
|
"i18next-http-backend": "^4.0.0",
|
|
99
99
|
"i18next-http-middleware": "^3.9.7",
|
|
100
|
-
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.5.0-ultramodern.
|
|
101
|
-
"@modern-js/
|
|
102
|
-
"@modern-js/server-
|
|
103
|
-
"@modern-js/
|
|
104
|
-
"@modern-js/
|
|
105
|
-
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.5.0-ultramodern.4"
|
|
100
|
+
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.5.0-ultramodern.41",
|
|
101
|
+
"@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.5.0-ultramodern.41",
|
|
102
|
+
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.5.0-ultramodern.41",
|
|
103
|
+
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.5.0-ultramodern.41",
|
|
104
|
+
"@modern-js/server-runtime": "npm:@bleedingdev/modern-js-server-runtime@3.5.0-ultramodern.41"
|
|
106
105
|
},
|
|
107
106
|
"peerDependencies": {
|
|
108
|
-
"@modern-js/runtime": "3.5.0-ultramodern.
|
|
107
|
+
"@modern-js/runtime": "3.5.0-ultramodern.41",
|
|
109
108
|
"i18next": ">=26.3.1",
|
|
110
109
|
"react": "^19.2.7",
|
|
111
110
|
"react-dom": "^19.2.7",
|
|
112
|
-
"react-i18next": "^17.0.
|
|
111
|
+
"react-i18next": "^17.0.9"
|
|
113
112
|
},
|
|
114
113
|
"peerDependenciesMeta": {
|
|
115
114
|
"i18next": {
|
|
@@ -120,17 +119,16 @@
|
|
|
120
119
|
}
|
|
121
120
|
},
|
|
122
121
|
"devDependencies": {
|
|
123
|
-
"@rslib/core": "0.23.
|
|
124
|
-
"@types/node": "^26.
|
|
125
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
126
|
-
"i18next": "26.3.
|
|
122
|
+
"@rslib/core": "0.23.2",
|
|
123
|
+
"@types/node": "^26.1.1",
|
|
124
|
+
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
125
|
+
"i18next": "26.3.6",
|
|
127
126
|
"react": "^19.2.7",
|
|
128
127
|
"react-dom": "^19.2.7",
|
|
129
|
-
"react-i18next": "17.0.
|
|
130
|
-
"
|
|
131
|
-
"
|
|
132
|
-
"@modern-js/
|
|
133
|
-
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.5.0-ultramodern.4"
|
|
128
|
+
"react-i18next": "17.0.9",
|
|
129
|
+
"typescript": "^7.0.2",
|
|
130
|
+
"@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.5.0-ultramodern.41",
|
|
131
|
+
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.5.0-ultramodern.41"
|
|
134
132
|
},
|
|
135
133
|
"sideEffects": false,
|
|
136
134
|
"publishConfig": {
|
package/rstest.config.mts
CHANGED
package/src/cli/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
1
3
|
import type { AppTools, CliPlugin } from '@modern-js/app-tools';
|
|
2
4
|
import { getPublicDirRoutePrefixes } from '@modern-js/server-core';
|
|
3
5
|
import type {
|
|
@@ -5,8 +7,6 @@ import type {
|
|
|
5
7
|
NestedRouteForCli,
|
|
6
8
|
PageRoute,
|
|
7
9
|
} from '@modern-js/types';
|
|
8
|
-
import fs from 'fs';
|
|
9
|
-
import path from 'path';
|
|
10
10
|
import {
|
|
11
11
|
applyLocalisedUrlsToRoutes,
|
|
12
12
|
resolveLocalisedUrlsConfig,
|
|
@@ -126,9 +126,10 @@ export const i18nPlugin = (
|
|
|
126
126
|
backend: backendOptions,
|
|
127
127
|
...extendedConfig,
|
|
128
128
|
};
|
|
129
|
+
const { reactI18next } = extendedConfig as { reactI18next?: boolean };
|
|
129
130
|
const runtimePluginPath =
|
|
130
131
|
customPlugin?.runtime?.path ||
|
|
131
|
-
(
|
|
132
|
+
(reactI18next === false
|
|
132
133
|
? `@${metaName}/plugin-i18n/runtime/no-react-i18next`
|
|
133
134
|
: `@${metaName}/plugin-i18n/runtime`);
|
|
134
135
|
|
|
@@ -173,7 +174,7 @@ export const i18nPlugin = (
|
|
|
173
174
|
routes as (NestedRouteForCli | PageRoute)[],
|
|
174
175
|
languages,
|
|
175
176
|
localisedUrlsConfig.map,
|
|
176
|
-
),
|
|
177
|
+
) as (NestedRouteForCli | PageRoute)[],
|
|
177
178
|
};
|
|
178
179
|
});
|
|
179
180
|
|
package/src/cli/locales.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
1
3
|
import {
|
|
2
4
|
getPublicDirRoutePrefixes,
|
|
3
5
|
normalizePublicDir,
|
|
4
6
|
normalizePublicDirPath,
|
|
5
7
|
} from '@modern-js/server-core';
|
|
6
|
-
import fs from 'fs';
|
|
7
|
-
import path from 'path';
|
|
8
8
|
import type { BackendOptions } from '../shared/type';
|
|
9
9
|
|
|
10
10
|
interface NormalizedConfigForLocales {
|
|
@@ -13,7 +13,7 @@ interface NormalizedConfigForLocales {
|
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
interface DetectedLocalesDirectory {
|
|
17
17
|
loadPath: string;
|
|
18
18
|
addPath: string;
|
|
19
19
|
serverLoadPath: string;
|
package/src/runtime/Link.tsx
CHANGED
|
@@ -6,96 +6,22 @@ import type {
|
|
|
6
6
|
ValidateLinkTo,
|
|
7
7
|
} from './canonicalRoutes';
|
|
8
8
|
import { useModernI18n } from './context';
|
|
9
|
+
import {
|
|
10
|
+
interpolateRouteParams,
|
|
11
|
+
type LinkParams,
|
|
12
|
+
mergeClassNames,
|
|
13
|
+
normalizeSearch,
|
|
14
|
+
splitActiveProps,
|
|
15
|
+
warnOnce,
|
|
16
|
+
} from './linkHelpers';
|
|
9
17
|
import { canonicalPath, type LocalizedPathsConfig } from './localizedPaths';
|
|
10
18
|
import { useI18nRouterAdapter } from './routerAdapter';
|
|
11
19
|
import { buildLocalizedUrl, splitUrlTarget } from './utils';
|
|
12
20
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const warnedTargets = new Set<string>();
|
|
16
|
-
|
|
17
|
-
const warnOnce = (key: string, message: string) => {
|
|
18
|
-
if (process.env.NODE_ENV !== 'development' || warnedTargets.has(key)) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
warnedTargets.add(key);
|
|
22
|
-
console.warn(message);
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export type LinkParams = Record<string, string | number | undefined>;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Interpolate `$param`, `:param`, optional (`{-$param}` / `:param?`) and splat
|
|
29
|
-
* (`$` / `*`) segments with concrete values before localization, so
|
|
30
|
-
* pattern-mapped slugs localize correctly.
|
|
31
|
-
*/
|
|
32
|
-
export const interpolateRouteParams = (
|
|
33
|
-
pathname: string,
|
|
34
|
-
params?: LinkParams,
|
|
35
|
-
): string => {
|
|
36
|
-
if (!/[$:*{]/.test(pathname)) {
|
|
37
|
-
return pathname;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const resolveParam = (name: string): string | undefined => {
|
|
41
|
-
const value = params?.[name];
|
|
42
|
-
return value === undefined ? undefined : String(value);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const segments = pathname
|
|
46
|
-
.split('/')
|
|
47
|
-
.map(segment => {
|
|
48
|
-
if (!segment) {
|
|
49
|
-
return segment;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (segment.startsWith('{-$') && segment.endsWith('}')) {
|
|
53
|
-
const value = resolveParam(segment.slice(3, -1));
|
|
54
|
-
return value === undefined ? null : encodeURIComponent(value);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (segment === '$' || segment === '*') {
|
|
58
|
-
const value = resolveParam('_splat') ?? resolveParam('*');
|
|
59
|
-
return value === undefined
|
|
60
|
-
? null
|
|
61
|
-
: value.split('/').map(encodeURIComponent).join('/');
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (segment.startsWith('$')) {
|
|
65
|
-
const value = resolveParam(segment.slice(1));
|
|
66
|
-
if (value === undefined) {
|
|
67
|
-
warnOnce(
|
|
68
|
-
`missing-param:${pathname}:${segment}`,
|
|
69
|
-
`[plugin-i18n] <Link to="${pathname}"> is missing required param "${segment.slice(1)}".`,
|
|
70
|
-
);
|
|
71
|
-
return segment;
|
|
72
|
-
}
|
|
73
|
-
return encodeURIComponent(value);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (segment.startsWith(':')) {
|
|
77
|
-
const optional = segment.endsWith('?');
|
|
78
|
-
const name = segment.slice(1, optional ? -1 : undefined);
|
|
79
|
-
const value = resolveParam(name);
|
|
80
|
-
if (value === undefined) {
|
|
81
|
-
if (optional) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
warnOnce(
|
|
85
|
-
`missing-param:${pathname}:${segment}`,
|
|
86
|
-
`[plugin-i18n] <Link to="${pathname}"> is missing required param "${name}".`,
|
|
87
|
-
);
|
|
88
|
-
return segment;
|
|
89
|
-
}
|
|
90
|
-
return encodeURIComponent(value);
|
|
91
|
-
}
|
|
21
|
+
export type { LinkParams };
|
|
22
|
+
export { interpolateRouteParams };
|
|
92
23
|
|
|
93
|
-
|
|
94
|
-
})
|
|
95
|
-
.filter(segment => segment !== null);
|
|
96
|
-
|
|
97
|
-
return segments.join('/') || '/';
|
|
98
|
-
};
|
|
24
|
+
const EXTERNAL_TARGET_RE = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
|
|
99
25
|
|
|
100
26
|
export interface LinkActiveOptions {
|
|
101
27
|
/**
|
|
@@ -142,59 +68,6 @@ export type LinkProps<TTo extends string = string> = LinkBaseProps & {
|
|
|
142
68
|
} & ValidateLinkTo<TTo> &
|
|
143
69
|
LinkParamsProp<LinkTargetPathname<TTo>>;
|
|
144
70
|
|
|
145
|
-
const normalizeSearch = (
|
|
146
|
-
search: string | Record<string, unknown> | undefined,
|
|
147
|
-
searchFromTo: string,
|
|
148
|
-
): {
|
|
149
|
-
searchString: string;
|
|
150
|
-
searchObject: Record<string, string> | undefined;
|
|
151
|
-
} => {
|
|
152
|
-
if (search && typeof search === 'object') {
|
|
153
|
-
const entries = Object.entries(search).filter(
|
|
154
|
-
([, value]) => value !== undefined && value !== null,
|
|
155
|
-
);
|
|
156
|
-
const searchObject = Object.fromEntries(
|
|
157
|
-
entries.map(([key, value]) => [key, String(value)]),
|
|
158
|
-
);
|
|
159
|
-
const params = new URLSearchParams(searchObject);
|
|
160
|
-
const serialized = params.toString();
|
|
161
|
-
return {
|
|
162
|
-
searchString: serialized ? `?${serialized}` : '',
|
|
163
|
-
searchObject,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const raw = typeof search === 'string' && search ? search : searchFromTo;
|
|
168
|
-
if (!raw) {
|
|
169
|
-
return { searchString: '', searchObject: undefined };
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const searchString = raw.startsWith('?') ? raw : `?${raw}`;
|
|
173
|
-
const searchObject: Record<string, string> = {};
|
|
174
|
-
new URLSearchParams(searchString).forEach((value, key) => {
|
|
175
|
-
searchObject[key] = value;
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
return { searchString, searchObject };
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
const splitActiveProps = (
|
|
182
|
-
active: boolean,
|
|
183
|
-
activeProps?: LinkBaseProps['activeProps'],
|
|
184
|
-
) => {
|
|
185
|
-
if (!active || !activeProps) {
|
|
186
|
-
return {};
|
|
187
|
-
}
|
|
188
|
-
return activeProps;
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
const mergeClassNames = (...values: Array<unknown>): string | undefined => {
|
|
192
|
-
const classNames = values.filter(
|
|
193
|
-
(value): value is string => typeof value === 'string' && value.length > 0,
|
|
194
|
-
);
|
|
195
|
-
return classNames.length > 0 ? classNames.join(' ') : undefined;
|
|
196
|
-
};
|
|
197
|
-
|
|
198
71
|
/**
|
|
199
72
|
* The standard UltraModern link: a vanilla link in every respect except that
|
|
200
73
|
* it localizes canonical, language-agnostic paths automatically.
|