next-intl 4.14.1 β†’ 4.14.3

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/README.md CHANGED
@@ -24,6 +24,8 @@ Internationalization (i18n) is an essential part of the user experience, therefo
24
24
  - πŸš€ **Next.js-native and performance-obsessed**: App Router, Server Components, static renderingβ€”pick the right tool for the right job, next-intl works everywhere.
25
25
  - 🌍 **Internationalized routing**: Provide unique pathnames per language and optionally localize pathnames for search engine optimization.
26
26
 
27
+ [β†’ Read the docs](https://next-intl.dev)
28
+
27
29
  ## What does it look like?
28
30
 
29
31
  ```jsx
@@ -58,7 +60,35 @@ export default function UserProfile({user}) {
58
60
  }
59
61
  ```
60
62
 
61
- ### [β†’ Read the docs](https://next-intl.dev)
63
+ ## Lint your messages
64
+
65
+ As an app grows, messages may drift and become inconsistent.
66
+
67
+ A companion tool, [`eloqnt/cli`](https://cli.eloqnt.dev/docs), catches this by analyzing your source code and messages statically:
68
+
69
+ ```console
70
+ $ eloqnt lint
71
+
72
+ messages/de.json
73
+ β”‚
74
+ β”‚ "UserProfile.title": "Dein Profil"
75
+ β”‚ ─┬──────────
76
+ β”‚ ╰─ Inconsistent ICU arguments: missing {firstName} (inconsistent-args)
77
+ β”‚
78
+ β”‚ "UserProfile.membership": "Member since {memberSince, date, short}"
79
+ β”‚ ─┬──────────────────────
80
+ β”‚ ╰─ Missing translation for de (missing-translation)
81
+
82
+ βœ— 1 error
83
+ ! 1 warning
84
+
85
+ β†’ Rule details: https://cli.eloqnt.dev/docs/lint-rules/<rule>
86
+ β†’ Run `eloqnt translate` to fill in 1 missing translation
87
+ ```
88
+
89
+ It can optionally also fill in missing translations with [`eloqnt translate`](https://cli.eloqnt.dev/docs/cli/translate), using your source code as context.
90
+
91
+ ---
62
92
 
63
93
  <div align="center">
64
94
  <a href="https://next-intl.dev/redirect?href=https://crowdin.com" target="_blank">
@@ -139,7 +139,7 @@ function formatPathnameTemplate(template, params) {
139
139
  template = template.replace(/\[\[/g, '[').replace(/\]\]/g, ']');
140
140
  let result = template;
141
141
  Object.entries(params).forEach(([key, value]) => {
142
- result = result.replace(`[${key}]`, value);
142
+ result = result.replace(`[${key}]`, () => value);
143
143
  });
144
144
  return result;
145
145
  }
@@ -51,7 +51,7 @@ function compileLocalizedPathname({
51
51
  regexp = `\\[${key}\\]`;
52
52
  replacer = String(paramValue);
53
53
  }
54
- compiled = compiled.replace(new RegExp(regexp, 'g'), replacer);
54
+ compiled = compiled.replace(new RegExp(regexp, 'g'), () => replacer);
55
55
  });
56
56
  }
57
57
 
@@ -1 +1 @@
1
- import{normalizeTrailingSlash as e,getSortedPathnames as t,matchesPathname as n,prefixPathname as r,getLocalePrefix as o,templateToRegex as c,getLocalizedTemplate as i}from"../shared/utils.js";function s(e,r,o){const c=t(Object.keys(e));for(const t of c){const c=e[t];if("string"==typeof c){if(n(c,r))return[void 0,t]}else{const s=Object.entries(c),f=s.findIndex((([e])=>e===o));f>0&&s.unshift(s.splice(f,1)[0]);for(const[o]of s){const c=i(e[t],o,t);if(n(c,r))return[o,t]}}}for(const t of Object.keys(e))if(n(t,r))return[void 0,t];return[void 0,void 0]}function f(t,n,r,o){let c="";return c+=p(r,d(n,t)),c=e(c),c}function l(t,n,r){t.endsWith("/")||(t+="/");const o=u(n,r),c=new RegExp(`^(${o.map((([,e])=>e.replaceAll("/","\\/"))).join("|")})/(.*)`,"i"),i=t.match(c);let s=i?"/"+i[2]:t;return"/"!==s&&(s=e(s)),s}function u(e,t,n=!0){const r=e.map((e=>[e,o(e,t)]));return n&&r.sort(((e,t)=>t[1].length-e[1].length)),r}function a(e,t,n,r){const o=u(t,n);r&&o.sort((([e],[t])=>{if(e===r.defaultLocale)return-1;if(t===r.defaultLocale)return 1;const n=r.locales.includes(e),o=r.locales.includes(t);return n&&!o?-1:!n&&o?1:0}));for(const[t,n]of o){let r,o;if(e===n||e.startsWith(n+"/"))r=o=!0;else{const t=e.toLowerCase(),c=n.toLowerCase();(t===c||t.startsWith(c+"/"))&&(r=!1,o=!0)}if(o)return{locale:t,prefix:n,matchedPrefix:e.slice(0,n.length),exact:r}}}function d(t,n){const r=e(n),o=e(t),i=c(o).exec(r);if(!i)return;const s={},f=o.match(/\[([^\]]+)\]/g)??[];for(let e=1;e<i.length;e++){const t=f[e-1];if(!t)continue;const n=t.replace(/[[\]]/g,""),r=i[e]??"";s[n]=r}return s}function p(e,t){if(!t)return e;let n=e=e.replace(/\[\[/g,"[").replace(/\]\]/g,"]");return Object.entries(t).forEach((([e,t])=>{n=n.replace(`[${e}]`,t)})),n}function g(e,t,n){let o=e;return t&&(o=r(t,o)),n&&(o+=n),o}function h(e){return e.get("x-forwarded-host")??e.get("host")??void 0}function x(e,t){return t.defaultLocale===e||t.locales.includes(e)}function m(e,t,n){let r;return e&&x(t,e)&&(r=e),r||(r=n.find((e=>e.defaultLocale===t))),r||(r=n.find((e=>e.locales.includes(t)))),r}function j(t,n){return e(n+t)}function L(e){return`/${e}`}function v(e){return e.replace(/\\/g,"%5C").replace(/[\t\n\r]/g,"").replace(/\/+/g,"/")}export{j as applyBasePath,g as formatPathname,p as formatPathnameTemplate,f as formatTemplatePathname,m as getBestMatchingDomain,h as getHost,s as getInternalTemplate,L as getLocaleAsPrefix,u as getLocalePrefixes,l as getNormalizedPathname,a as getPathnameMatch,d as getRouteParams,x as isLocaleSupportedOnDomain,v as sanitizePathname};
1
+ import{normalizeTrailingSlash as e,getSortedPathnames as t,matchesPathname as n,prefixPathname as r,getLocalePrefix as o,templateToRegex as c,getLocalizedTemplate as i}from"../shared/utils.js";function s(e,r,o){const c=t(Object.keys(e));for(const t of c){const c=e[t];if("string"==typeof c){if(n(c,r))return[void 0,t]}else{const s=Object.entries(c),f=s.findIndex((([e])=>e===o));f>0&&s.unshift(s.splice(f,1)[0]);for(const[o]of s){const c=i(e[t],o,t);if(n(c,r))return[o,t]}}}for(const t of Object.keys(e))if(n(t,r))return[void 0,t];return[void 0,void 0]}function f(t,n,r,o){let c="";return c+=p(r,d(n,t)),c=e(c),c}function l(t,n,r){t.endsWith("/")||(t+="/");const o=u(n,r),c=new RegExp(`^(${o.map((([,e])=>e.replaceAll("/","\\/"))).join("|")})/(.*)`,"i"),i=t.match(c);let s=i?"/"+i[2]:t;return"/"!==s&&(s=e(s)),s}function u(e,t,n=!0){const r=e.map((e=>[e,o(e,t)]));return n&&r.sort(((e,t)=>t[1].length-e[1].length)),r}function a(e,t,n,r){const o=u(t,n);r&&o.sort((([e],[t])=>{if(e===r.defaultLocale)return-1;if(t===r.defaultLocale)return 1;const n=r.locales.includes(e),o=r.locales.includes(t);return n&&!o?-1:!n&&o?1:0}));for(const[t,n]of o){let r,o;if(e===n||e.startsWith(n+"/"))r=o=!0;else{const t=e.toLowerCase(),c=n.toLowerCase();(t===c||t.startsWith(c+"/"))&&(r=!1,o=!0)}if(o)return{locale:t,prefix:n,matchedPrefix:e.slice(0,n.length),exact:r}}}function d(t,n){const r=e(n),o=e(t),i=c(o).exec(r);if(!i)return;const s={},f=o.match(/\[([^\]]+)\]/g)??[];for(let e=1;e<i.length;e++){const t=f[e-1];if(!t)continue;const n=t.replace(/[[\]]/g,""),r=i[e]??"";s[n]=r}return s}function p(e,t){if(!t)return e;let n=e=e.replace(/\[\[/g,"[").replace(/\]\]/g,"]");return Object.entries(t).forEach((([e,t])=>{n=n.replace(`[${e}]`,(()=>t))})),n}function g(e,t,n){let o=e;return t&&(o=r(t,o)),n&&(o+=n),o}function h(e){return e.get("x-forwarded-host")??e.get("host")??void 0}function x(e,t){return t.defaultLocale===e||t.locales.includes(e)}function m(e,t,n){let r;return e&&x(t,e)&&(r=e),r||(r=n.find((e=>e.defaultLocale===t))),r||(r=n.find((e=>e.locales.includes(t)))),r}function j(t,n){return e(n+t)}function L(e){return`/${e}`}function v(e){return e.replace(/\\/g,"%5C").replace(/[\t\n\r]/g,"").replace(/\/+/g,"/")}export{j as applyBasePath,g as formatPathname,p as formatPathnameTemplate,f as formatTemplatePathname,m as getBestMatchingDomain,h as getHost,s as getInternalTemplate,L as getLocaleAsPrefix,u as getLocalePrefixes,l as getNormalizedPathname,a as getPathnameMatch,d as getRouteParams,x as isLocaleSupportedOnDomain,v as sanitizePathname};
@@ -1 +1 @@
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 new URL(e,"http://l").pathname}(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 l(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 u(e,n=window.location.pathname){return"/"===e?n:n.replace(e,"")}function p(e,n,o,a){const{mode:c}=o.localePrefix;let s;if(void 0!==a)s=a;else if(t(e)){const e=o.domains?.find((e=>e.locales.includes(n))),t=e?.localePrefix||c;"always"===t?s=!0:"as-needed"===t&&(s=e?n!==e.defaultLocale:n!==o.defaultLocale)}return s?r(i(n,o.localePrefix),e):e}export{p as applyPathnamePrefix,f as compileLocalizedPathname,u as getBasePath,l 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 new URL(e,"http://l").pathname}(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 l(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 u(e,n=window.location.pathname){return"/"===e?n:n.replace(e,"")}function p(e,n,o,a){const{mode:c}=o.localePrefix;let s;if(void 0!==a)s=a;else if(t(e)){const e=o.domains?.find((e=>e.locales.includes(n))),t=e?.localePrefix||c;"always"===t?s=!0:"as-needed"===t&&(s=e?n!==e.defaultLocale:n!==o.defaultLocale)}return s?r(i(n,o.localePrefix),e):e}export{p as applyPathnamePrefix,f as compileLocalizedPathname,u as getBasePath,l as getRoute,c as normalizeNameOrNameWithParams,s as serializeSearchParams};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-intl",
3
- "version": "4.14.1",
3
+ "version": "4.14.3",
4
4
  "sideEffects": false,
5
5
  "author": "Jan Amann <jan@amann.work>",
6
6
  "funding": [
@@ -124,20 +124,20 @@
124
124
  "next.js"
125
125
  ],
126
126
  "dependencies": {
127
- "@eloqnt/config": "^0.0.2",
128
- "@eloqnt/format-json": "^0.0.3",
129
- "@eloqnt/format-po": "^0.0.3",
127
+ "@eloqnt/config": "^0.1.0",
128
+ "@eloqnt/format-json": "^0.1.0",
129
+ "@eloqnt/format-po": "^0.1.0",
130
130
  "@formatjs/intl-localematcher": "^0.8.1",
131
131
  "@parcel/watcher": "^2.4.1",
132
132
  "@swc/core": "~1.16.0",
133
- "icu-minify": "^4.14.1",
133
+ "icu-minify": "^4.14.3",
134
134
  "negotiator": "^1.0.0",
135
- "next-intl-swc-plugin-extractor": "4.14.1",
136
- "use-intl": "^4.14.1"
135
+ "next-intl-swc-plugin-extractor": "4.14.3",
136
+ "use-intl": "^4.14.3"
137
137
  },
138
138
  "peerDependencies": {
139
139
  "next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
140
140
  "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0"
141
141
  },
142
- "gitHead": "58b92226b44cfae981a860f76efb7f920cd0fd9c"
142
+ "gitHead": "e9b1637796481a96b15dd081d5b92a5b1fa8ca02"
143
143
  }