next-intl 4.3.0 → 4.3.2
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/esm/development/navigation/react-client/createNavigation.js +1 -1
- package/dist/esm/development/navigation/shared/utils.js +31 -35
- package/dist/esm/development/shared/utils.js +11 -5
- package/dist/esm/production/navigation/react-client/createNavigation.js +1 -1
- package/dist/esm/production/navigation/shared/utils.js +1 -1
- package/dist/esm/production/shared/utils.js +1 -1
- package/package.json +3 -3
|
@@ -35,39 +35,38 @@ function compileLocalizedPathname({
|
|
|
35
35
|
pathnames,
|
|
36
36
|
query
|
|
37
37
|
}) {
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
replacer = String(value);
|
|
58
|
-
}
|
|
59
|
-
compiled = compiled.replace(new RegExp(regexp, 'g'), replacer);
|
|
60
|
-
});
|
|
61
|
-
}
|
|
38
|
+
function compilePath(value) {
|
|
39
|
+
const pathnameConfig = pathnames[value];
|
|
40
|
+
let compiled;
|
|
41
|
+
if (pathnameConfig) {
|
|
42
|
+
const template = getLocalizedTemplate(pathnameConfig, locale, value);
|
|
43
|
+
compiled = template;
|
|
44
|
+
if (params) {
|
|
45
|
+
Object.entries(params).forEach(([key, paramValue]) => {
|
|
46
|
+
let regexp, replacer;
|
|
47
|
+
if (Array.isArray(paramValue)) {
|
|
48
|
+
regexp = `(\\[)?\\[...${key}\\](\\])?`;
|
|
49
|
+
replacer = paramValue.map(v => String(v)).join('/');
|
|
50
|
+
} else {
|
|
51
|
+
regexp = `\\[${key}\\]`;
|
|
52
|
+
replacer = String(paramValue);
|
|
53
|
+
}
|
|
54
|
+
compiled = compiled.replace(new RegExp(regexp, 'g'), replacer);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
62
57
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
58
|
+
// Clean up optional catch-all segments that were not replaced
|
|
59
|
+
compiled = compiled.replace(/\[\[\.\.\..+\]\]/g, '');
|
|
60
|
+
if (compiled.includes('[')) {
|
|
61
|
+
// Next.js throws anyway, therefore better provide a more helpful error message
|
|
62
|
+
throw new Error(`Insufficient params provided for localized pathname.\nTemplate: ${template}\nParams: ${JSON.stringify(params)}`);
|
|
63
|
+
}
|
|
64
|
+
compiled = encodePathname(compiled);
|
|
65
|
+
} else {
|
|
66
|
+
// Unknown pathnames
|
|
67
|
+
compiled = value;
|
|
68
68
|
}
|
|
69
69
|
compiled = normalizeTrailingSlash(compiled);
|
|
70
|
-
compiled = encodePathname(compiled);
|
|
71
70
|
if (query) {
|
|
72
71
|
// This also encodes non-ASCII characters by
|
|
73
72
|
// using `new URLSearchParams()` internally
|
|
@@ -76,16 +75,13 @@ function compileLocalizedPathname({
|
|
|
76
75
|
return compiled;
|
|
77
76
|
}
|
|
78
77
|
if (typeof pathname === 'string') {
|
|
79
|
-
|
|
80
|
-
const compiled = compilePath(namedPath, pathname);
|
|
81
|
-
return compiled;
|
|
78
|
+
return compilePath(pathname);
|
|
82
79
|
} else {
|
|
83
80
|
const {
|
|
84
81
|
pathname: internalPathname,
|
|
85
82
|
...rest
|
|
86
83
|
} = pathname;
|
|
87
|
-
const
|
|
88
|
-
const compiled = compilePath(namedPath, internalPathname);
|
|
84
|
+
const compiled = compilePath(internalPathname);
|
|
89
85
|
const result = {
|
|
90
86
|
...rest,
|
|
91
87
|
pathname: compiled
|
|
@@ -42,15 +42,21 @@ function getLocalizedTemplate(pathnameConfig, locale, internalTemplate) {
|
|
|
42
42
|
}
|
|
43
43
|
function normalizeTrailingSlash(pathname) {
|
|
44
44
|
const trailingSlash = hasTrailingSlash();
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
const [path, ...hashParts] = pathname.split('#');
|
|
46
|
+
const hash = hashParts.join('#');
|
|
47
|
+
let normalizedPath = path;
|
|
48
|
+
if (normalizedPath !== '/') {
|
|
49
|
+
const pathnameEndsWithSlash = normalizedPath.endsWith('/');
|
|
47
50
|
if (trailingSlash && !pathnameEndsWithSlash) {
|
|
48
|
-
|
|
51
|
+
normalizedPath += '/';
|
|
49
52
|
} else if (!trailingSlash && pathnameEndsWithSlash) {
|
|
50
|
-
|
|
53
|
+
normalizedPath = normalizedPath.slice(0, -1);
|
|
51
54
|
}
|
|
52
55
|
}
|
|
53
|
-
|
|
56
|
+
if (hash) {
|
|
57
|
+
normalizedPath += '#' + hash;
|
|
58
|
+
}
|
|
59
|
+
return normalizedPath;
|
|
54
60
|
}
|
|
55
61
|
function matchesPathname(/** E.g. `/users/[userId]-[userName]` */
|
|
56
62
|
template, /** E.g. `/users/23-jane` */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useRouter as e,usePathname as t}from"next/navigation";import{useMemo as r}from"react";import{useLocale as n}from"use-intl";import o from"../shared/createSharedNavigationFns.js";import a from"../shared/syncLocaleCookie.js";import{getRoute as s}from"../shared/utils.js";import i from"./useBasePathname.js";function c(c){const{Link:m,config:u,getPathname:f,...h}=o(n,c);return{...h,Link:m,usePathname:function(){const e=i(u),t=n();return r((()=>e&&u.pathnames?s(t,e,u.pathnames):e),[t,e])},useRouter:function(){const o=e(),s=n(),i=t();return r((()=>{function e(e){return function(t,r){const{locale:n,...o}=r||{},c=[f({href:t,locale:n||s})];Object.keys(o).length>0&&c.push(o),
|
|
1
|
+
import{useRouter as e,usePathname as t}from"next/navigation";import{useMemo as r}from"react";import{useLocale as n}from"use-intl";import o from"../shared/createSharedNavigationFns.js";import a from"../shared/syncLocaleCookie.js";import{getRoute as s}from"../shared/utils.js";import i from"./useBasePathname.js";function c(c){const{Link:m,config:u,getPathname:f,...h}=o(n,c);return{...h,Link:m,usePathname:function(){const e=i(u),t=n();return r((()=>e&&u.pathnames?s(t,e,u.pathnames):e),[t,e])},useRouter:function(){const o=e(),s=n(),i=t();return r((()=>{function e(e){return function(t,r){const{locale:n,...o}=r||{},c=[f({href:t,locale:n||s})];Object.keys(o).length>0&&c.push(o),a(u.localeCookie,i,s,n),e(...c)}}return{...o,push:e(o.push),replace:e(o.replace),prefetch:e(o.prefetch)}}),[s,i,o])},getPathname:f}}export{c as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getSortedPathnames as e,matchesPathname as n,isLocalizableHref as t,prefixPathname as r,
|
|
1
|
+
import{getSortedPathnames as e,matchesPathname as n,isLocalizableHref as t,prefixPathname as r,normalizeTrailingSlash as o,getLocalizedTemplate as a,getLocalePrefix as i}from"../../shared/utils.js";function c(e){return"string"==typeof e?{pathname:e}:e}function s(e){function n(e){return String(e)}const t=new URLSearchParams;for(const[r,o]of Object.entries(e))Array.isArray(o)?o.forEach((e=>{t.append(r,n(e))})):t.set(r,n(o));return"?"+t.toString()}function f({pathname:e,locale:n,params:t,pathnames:r,query:i}){function c(e){const c=r[e];let f;if(c){const r=a(c,n,e);f=r,t&&Object.entries(t).forEach((([e,n])=>{let t,r;Array.isArray(n)?(t=`(\\[)?\\[...${e}\\](\\])?`,r=n.map((e=>String(e))).join("/")):(t=`\\[${e}\\]`,r=String(n)),f=f.replace(new RegExp(t,"g"),r)})),f=f.replace(/\[\[\.\.\..+\]\]/g,""),f=function(e){return e.split("/").map((e=>encodeURIComponent(e))).join("/")}(f)}else f=e;return f=o(f),i&&(f+=s(i)),f}if("string"==typeof e)return c(e);{const{pathname:n,...t}=e;return{...t,pathname:c(n)}}}function u(t,r,o){const i=e(Object.keys(o)),c=decodeURI(r);for(const e of i){const r=o[e];if("string"==typeof r){if(n(r,c))return e}else if(n(a(r,t,e),c))return e}return r}function l(e,n=window.location.pathname){return"/"===e?n:n.replace(e,"")}function p(e,n,o,a){const{mode:c}=o.localePrefix;let s;return void 0!==a?s=a:t(e)&&("always"===c?s=!0:"as-needed"===c&&(s=o.domains?!o.domains.some((e=>e.defaultLocale===n)):n!==o.defaultLocale)),s?r(i(n,o.localePrefix),e):e}export{p as applyPathnamePrefix,f as compileLocalizedPathname,l as getBasePath,u as getRoute,c as normalizeNameOrNameWithParams,s as serializeSearchParams};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function n(n){return function(n){return"object"==typeof n?null==n.host&&null==n.hostname:!/^[a-z]+:/i.test(n)}(n)&&!function(n){const t="object"==typeof n?n.pathname:n;return null!=t&&!t.startsWith("/")}(n)}function t(n,t){return n.replace(new RegExp(`^${t}`),"")||"/"}function e(n,t){let e=n;return/^\/(\?.*)?$/.test(t)&&(t=t.slice(1)),e+=t,e}function r(n,t){return t===n||t.startsWith(`${n}/`)}function u(n,t,e){return"string"==typeof n?n:n[t]||e}function i(n){const t=function(){try{return"true"===process.env._next_intl_trailing_slash}catch{return!1}}();if("/"!==
|
|
1
|
+
function n(n){return function(n){return"object"==typeof n?null==n.host&&null==n.hostname:!/^[a-z]+:/i.test(n)}(n)&&!function(n){const t="object"==typeof n?n.pathname:n;return null!=t&&!t.startsWith("/")}(n)}function t(n,t){return n.replace(new RegExp(`^${t}`),"")||"/"}function e(n,t){let e=n;return/^\/(\?.*)?$/.test(t)&&(t=t.slice(1)),e+=t,e}function r(n,t){return t===n||t.startsWith(`${n}/`)}function u(n,t,e){return"string"==typeof n?n:n[t]||e}function i(n){const t=function(){try{return"true"===process.env._next_intl_trailing_slash}catch{return!1}}(),[e,...r]=n.split("#"),u=r.join("#");let i=e;if("/"!==i){const n=i.endsWith("/");t&&!n?i+="/":!t&&n&&(i=i.slice(0,-1))}return u&&(i+="#"+u),i}function c(n,t){const e=i(n),r=i(t);return s(e).test(r)}function o(n,t){return"never"!==t.mode&&t.prefixes?.[n]||f(n)}function f(n){return"/"+n}function s(n){const t=n.replace(/\[\[(\.\.\.[^\]]+)\]\]/g,"?(.*)").replace(/\[(\.\.\.[^\]]+)\]/g,"(.+)").replace(/\[([^\]]+)\]/g,"([^/]+)");return new RegExp(`^${t}$`)}function l(n){return n.includes("[[...")}function p(n){return n.includes("[...")}function a(n){return n.includes("[")}function h(n,t){const e=n.split("/"),r=t.split("/"),u=Math.max(e.length,r.length);for(let n=0;n<u;n++){const t=e[n],u=r[n];if(!t&&u)return-1;if(t&&!u)return 1;if(t||u){if(!a(t)&&a(u))return-1;if(a(t)&&!a(u))return 1;if(!p(t)&&p(u))return-1;if(p(t)&&!p(u))return 1;if(!l(t)&&l(u))return-1;if(l(t)&&!l(u))return 1}}return 0}function g(n){return n.sort(h)}function x(n){return"function"==typeof n.then}export{f as getLocaleAsPrefix,o as getLocalePrefix,u as getLocalizedTemplate,g as getSortedPathnames,r as hasPathnamePrefixed,n as isLocalizableHref,x as isPromise,c as matchesPathname,i as normalizeTrailingSlash,e as prefixPathname,s as templateToRegex,t as unprefixPathname};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-intl",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.2",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"author": "Jan Amann <jan@amann.work>",
|
|
6
6
|
"funding": [
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"dependencies": {
|
|
113
113
|
"@formatjs/intl-localematcher": "^0.5.4",
|
|
114
114
|
"negotiator": "^1.0.0",
|
|
115
|
-
"use-intl": "^4.3.
|
|
115
|
+
"use-intl": "^4.3.2"
|
|
116
116
|
},
|
|
117
117
|
"peerDependencies": {
|
|
118
118
|
"next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0",
|
|
@@ -124,5 +124,5 @@
|
|
|
124
124
|
"optional": true
|
|
125
125
|
}
|
|
126
126
|
},
|
|
127
|
-
"gitHead": "
|
|
127
|
+
"gitHead": "112b4e686f4c7fdb4921db78b9c83a53c86f53fc"
|
|
128
128
|
}
|