next-intl 4.2.0 → 4.3.1

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.
@@ -35,39 +35,38 @@ function compileLocalizedPathname({
35
35
  pathnames,
36
36
  query
37
37
  }) {
38
- function getNamedPath(value) {
39
- let namedPath = pathnames[value];
40
- if (!namedPath) {
41
- // Unknown pathnames
42
- namedPath = value;
43
- }
44
- return namedPath;
45
- }
46
- function compilePath(namedPath, internalPathname) {
47
- const template = getLocalizedTemplate(namedPath, locale, internalPathname);
48
- let compiled = template;
49
- if (params) {
50
- Object.entries(params).forEach(([key, value]) => {
51
- let regexp, replacer;
52
- if (Array.isArray(value)) {
53
- regexp = `(\\[)?\\[...${key}\\](\\])?`;
54
- replacer = value.map(v => String(v)).join('/');
55
- } else {
56
- regexp = `\\[${key}\\]`;
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
- // Clean up optional catch-all segments that were not replaced
64
- compiled = compiled.replace(/\[\[\.\.\..+\]\]/g, '');
65
- if (compiled.includes('[')) {
66
- // Next.js throws anyway, therefore better provide a more helpful error message
67
- throw new Error(`Insufficient params provided for localized pathname.\nTemplate: ${template}\nParams: ${JSON.stringify(params)}`);
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
- const namedPath = getNamedPath(pathname);
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 namedPath = getNamedPath(internalPathname);
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
- if (pathname !== '/') {
46
- const pathnameEndsWithSlash = pathname.endsWith('/');
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
- pathname += '/';
51
+ normalizedPath += '/';
49
52
  } else if (!trailingSlash && pathnameEndsWithSlash) {
50
- pathname = pathname.slice(0, -1);
53
+ normalizedPath = normalizedPath.slice(0, -1);
51
54
  }
52
55
  }
53
- return pathname;
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{getSortedPathnames as e,matchesPathname as n,isLocalizableHref as t,prefixPathname as r,getLocalizedTemplate as o,normalizeTrailingSlash 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){let n=r[e];return n||(n=e),n}function f(e,r){let c=o(e,n,r);return 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)),c=c.replace(new RegExp(t,"g"),r)})),c=c.replace(/\[\[\.\.\..+\]\]/g,""),c=a(c),c=function(e){return e.split("/").map((e=>encodeURIComponent(e))).join("/")}(c),i&&(c+=s(i)),c}if("string"==typeof e){return f(c(e),e)}{const{pathname:n,...t}=e;return{...t,pathname:f(c(n),n)}}}function u(t,r,a){const i=e(Object.keys(a)),c=decodeURI(r);for(const e of i){const r=a[e];if("string"==typeof r){if(n(r,c))return e}else if(n(o(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
+ 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("/"!==n){const e=n.endsWith("/");t&&!e?n+="/":!t&&e&&(n=n.slice(0,-1))}return n}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};
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.2.0",
3
+ "version": "4.3.1",
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.2.0"
115
+ "use-intl": "^4.3.1"
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": "e303923f7339356cf2c1d64adcdc9498531d8db8"
127
+ "gitHead": "8925941c6bfd341a3fd422835195d0a29a28e3dd"
128
128
  }