next-intl 4.9.1 → 4.9.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.
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var plugin = require('./plugin-YzBhQjAo.cjs');
3
+ var plugin = require('./plugin-Har7Ebj3.cjs');
4
4
  var ExtractorCodec = require('./ExtractorCodec-D9Tw618d.cjs');
5
5
  require('fs/promises');
6
6
  require('path');
@@ -35,6 +35,9 @@ var JSONCodec = ExtractorCodec.defineCodec(() => ({
35
35
  function traverseMessages(obj, callback, path = '') {
36
36
  const NAMESPACE_SEPARATOR = '.';
37
37
  for (const key of Object.keys(obj)) {
38
+ if (plugin.isForbiddenObjectKey(key)) {
39
+ throw new Error(`Invalid message catalog key: \`${key}\`.`);
40
+ }
38
41
  const newPath = path ? path + NAMESPACE_SEPARATOR + key : key;
39
42
  const value = obj[key];
40
43
  if (typeof value === 'string') {
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var POParser = require('po-parser');
4
- var plugin = require('./plugin-YzBhQjAo.cjs');
4
+ var plugin = require('./plugin-Har7Ebj3.cjs');
5
5
  var ExtractorCodec = require('./ExtractorCodec-D9Tw618d.cjs');
6
6
  require('fs/promises');
7
7
  require('path');
@@ -122,11 +122,11 @@ export default messages;`;
122
122
 
123
123
  const formats = {
124
124
  json: {
125
- codec: () => Promise.resolve().then(function () { return require('./JSONCodec-rhejs716.cjs'); }),
125
+ codec: () => Promise.resolve().then(function () { return require('./JSONCodec-XU-elSg6.cjs'); }),
126
126
  extension: '.json'
127
127
  },
128
128
  po: {
129
- codec: () => Promise.resolve().then(function () { return require('./POCodec-Cv3VdXQG.cjs'); }),
129
+ codec: () => Promise.resolve().then(function () { return require('./POCodec-cA1pxFGQ.cjs'); }),
130
130
  extension: '.po'
131
131
  }
132
132
  };
@@ -342,15 +342,24 @@ function normalizePathToPosix(filePath) {
342
342
  // always use POSIX separators, regardless of the OS that ran extraction.
343
343
  return path__default.default.posix.normalize(filePath.split(path__default.default.win32.sep).join(path__default.default.posix.sep));
344
344
  }
345
+ const FORBIDDEN_OBJECT_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
346
+ function isForbiddenObjectKey(key) {
347
+ return FORBIDDEN_OBJECT_KEYS.has(key);
348
+ }
345
349
 
346
350
  // Essentialls lodash/set, but we avoid this dependency
347
351
  function setNestedProperty(obj, keyPath, value) {
348
352
  const keys = keyPath.split('.');
353
+ for (const key of keys) {
354
+ if (isForbiddenObjectKey(key)) {
355
+ throw new Error(`Invalid message id segment: ${key}`);
356
+ }
357
+ }
349
358
  let current = obj;
350
359
  for (let i = 0; i < keys.length - 1; i++) {
351
360
  const key = keys[i];
352
- if (!(key in current) || typeof current[key] !== 'object' || current[key] === null) {
353
- current[key] = {};
361
+ if (!Object.prototype.hasOwnProperty.call(current, key) || typeof current[key] !== 'object' || current[key] === null) {
362
+ current[key] = Object.create(null);
354
363
  }
355
364
  current = current[key];
356
365
  }
@@ -990,7 +999,7 @@ class LRUCache {
990
999
  }
991
1000
  }
992
1001
 
993
- const require$2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('plugin-YzBhQjAo.cjs', document.baseURI).href)));
1002
+ const require$2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('plugin-Har7Ebj3.cjs', document.baseURI).href)));
994
1003
  class MessageExtractor {
995
1004
  compileCache = new LRUCache(750);
996
1005
  constructor(opts) {
@@ -1148,7 +1157,7 @@ function initExtractionCompiler(pluginConfig) {
1148
1157
 
1149
1158
  function getCurrentVersion() {
1150
1159
  try {
1151
- const require$1 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('plugin-YzBhQjAo.cjs', document.baseURI).href)));
1160
+ const require$1 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('plugin-Har7Ebj3.cjs', document.baseURI).href)));
1152
1161
  const pkg = require$1('next/package.json');
1153
1162
  return pkg.version;
1154
1163
  } catch (error) {
@@ -1175,7 +1184,7 @@ function isNextJs16OrHigher() {
1175
1184
  return compareVersions(getCurrentVersion(), '16.0.0') >= 0;
1176
1185
  }
1177
1186
 
1178
- const require$1 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('plugin-YzBhQjAo.cjs', document.baseURI).href)));
1187
+ const require$1 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('plugin-Har7Ebj3.cjs', document.baseURI).href)));
1179
1188
  function withExtensions(localPath) {
1180
1189
  return [`${localPath}.ts`, `${localPath}.tsx`, `${localPath}.js`, `${localPath}.jsx`];
1181
1190
  }
@@ -1454,4 +1463,5 @@ function createNextIntlPlugin(i18nPathOrConfig = {}) {
1454
1463
 
1455
1464
  exports.createNextIntlPlugin = createNextIntlPlugin;
1456
1465
  exports.getSortedMessages = getSortedMessages;
1466
+ exports.isForbiddenObjectKey = isForbiddenObjectKey;
1457
1467
  exports.setNestedProperty = setNestedProperty;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var plugin = require('./plugin-YzBhQjAo.cjs');
3
+ var plugin = require('./plugin-Har7Ebj3.cjs');
4
4
  require('fs/promises');
5
5
  require('path');
6
6
  require('@parcel/watcher');
@@ -60,7 +60,7 @@ function catalogLoader(source) {
60
60
  * using icu-minify/compile for smaller runtime bundles.
61
61
  */
62
62
  function precompileMessages(messages, cache) {
63
- const result = {};
63
+ const result = Object.create(null);
64
64
  const cacheKeysToEvict = new Set(cache.keys());
65
65
  for (const message of messages) {
66
66
  cacheKeysToEvict.delete(message.id);
@@ -1,4 +1,4 @@
1
- import { getSortedMessages, setNestedProperty } from '../../utils.js';
1
+ import { getSortedMessages, setNestedProperty, isForbiddenObjectKey } from '../../utils.js';
2
2
  import { defineCodec } from '../ExtractorCodec.js';
3
3
 
4
4
  var JSONCodec = defineCodec(() => ({
@@ -27,6 +27,9 @@ var JSONCodec = defineCodec(() => ({
27
27
  function traverseMessages(obj, callback, path = '') {
28
28
  const NAMESPACE_SEPARATOR = '.';
29
29
  for (const key of Object.keys(obj)) {
30
+ if (isForbiddenObjectKey(key)) {
31
+ throw new Error(`Invalid message catalog key: \`${key}\`.`);
32
+ }
30
33
  const newPath = path ? path + NAMESPACE_SEPARATOR + key : key;
31
34
  const value = obj[key];
32
35
  if (typeof value === 'string') {
@@ -5,15 +5,24 @@ function normalizePathToPosix(filePath) {
5
5
  // always use POSIX separators, regardless of the OS that ran extraction.
6
6
  return path.posix.normalize(filePath.split(path.win32.sep).join(path.posix.sep));
7
7
  }
8
+ const FORBIDDEN_OBJECT_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
9
+ function isForbiddenObjectKey(key) {
10
+ return FORBIDDEN_OBJECT_KEYS.has(key);
11
+ }
8
12
 
9
13
  // Essentialls lodash/set, but we avoid this dependency
10
14
  function setNestedProperty(obj, keyPath, value) {
11
15
  const keys = keyPath.split('.');
16
+ for (const key of keys) {
17
+ if (isForbiddenObjectKey(key)) {
18
+ throw new Error(`Invalid message id segment: ${key}`);
19
+ }
20
+ }
12
21
  let current = obj;
13
22
  for (let i = 0; i < keys.length - 1; i++) {
14
23
  const key = keys[i];
15
- if (!(key in current) || typeof current[key] !== 'object' || current[key] === null) {
16
- current[key] = {};
24
+ if (!Object.prototype.hasOwnProperty.call(current, key) || typeof current[key] !== 'object' || current[key] === null) {
25
+ current[key] = Object.create(null);
17
26
  }
18
27
  current = current[key];
19
28
  }
@@ -43,4 +52,4 @@ function getDefaultProjectRoot() {
43
52
  return process.cwd();
44
53
  }
45
54
 
46
- export { compareReferences, getDefaultProjectRoot, getSortedMessages, localeCompare, normalizePathToPosix, setNestedProperty };
55
+ export { compareReferences, getDefaultProjectRoot, getSortedMessages, isForbiddenObjectKey, localeCompare, normalizePathToPosix, setNestedProperty };
@@ -1 +1 @@
1
- import e from"path";import t from"icu-minify/compile";import{getFormatExtension as s,resolveCodec as o}from"./format/index.js";import{setNestedProperty as r}from"./utils.js";let a=null;const n=new Map;function i(i){const c=this.getOptions(),l=this.async(),f=s(c.messages.format);(async function(e,t){return a||(a=await o(e.messages.format,t)),a})(c,this.rootContext).then((s=>{const o=e.basename(this.resourcePath,f);let a;if(c.messages.precompile){const e=function(e,s){const o={},a=new Set(s.keys());for(const n of e){a.delete(n.id);const e=n.message;if(Array.isArray(e))throw new Error(`Message at \`${n.id}\` resolved to an array, but only strings are supported. See https://next-intl.dev/docs/usage/translations#arrays-of-messages`);if("object"==typeof e)throw new Error(`Message at \`${n.id}\` resolved to \`${typeof e}\`, but only strings are supported. Use a \`.\` to retrieve nested messages. See https://next-intl.dev/docs/usage/translations#structuring-messages`);const i=s.get(n.id);let c;i?.messageValue===e?c=i.compiledMessage:(c=t(e),s.set(n.id,{compiledMessage:c,messageValue:e})),r(o,n.id,c)}for(const e of a)s.delete(e);return o}(s.decode(i,{locale:o}),function(e){let t=n.get(e);return t||(t=new Map,n.set(e,t)),t}(this.resourcePath));a=JSON.stringify(e)}else a=s.toJSONString(i,{locale:o});const m=`export default JSON.parse(${JSON.stringify(a)});`;l(null,m)})).catch(l)}export{i as default};
1
+ import e from"path";import t from"icu-minify/compile";import{getFormatExtension as s,resolveCodec as o}from"./format/index.js";import{setNestedProperty as r}from"./utils.js";let a=null;const n=new Map;function i(i){const c=this.getOptions(),l=this.async(),f=s(c.messages.format);(async function(e,t){return a||(a=await o(e.messages.format,t)),a})(c,this.rootContext).then((s=>{const o=e.basename(this.resourcePath,f);let a;if(c.messages.precompile){const e=function(e,s){const o=Object.create(null),a=new Set(s.keys());for(const n of e){a.delete(n.id);const e=n.message;if(Array.isArray(e))throw new Error(`Message at \`${n.id}\` resolved to an array, but only strings are supported. See https://next-intl.dev/docs/usage/translations#arrays-of-messages`);if("object"==typeof e)throw new Error(`Message at \`${n.id}\` resolved to \`${typeof e}\`, but only strings are supported. Use a \`.\` to retrieve nested messages. See https://next-intl.dev/docs/usage/translations#structuring-messages`);const i=s.get(n.id);let c;i?.messageValue===e?c=i.compiledMessage:(c=t(e),s.set(n.id,{compiledMessage:c,messageValue:e})),r(o,n.id,c)}for(const e of a)s.delete(e);return o}(s.decode(i,{locale:o}),function(e){let t=n.get(e);return t||(t=new Map,n.set(e,t)),t}(this.resourcePath));a=JSON.stringify(e)}else a=s.toJSONString(i,{locale:o});const m=`export default JSON.parse(${JSON.stringify(a)});`;l(null,m)})).catch(l)}export{i as default};
@@ -1 +1 @@
1
- import{getSortedMessages as e,setNestedProperty as r}from"../../utils.js";import{defineCodec as s}from"../ExtractorCodec.js";var t=s((()=>({decode(e){const r=JSON.parse(e),s=[];return o(r,((e,r)=>{s.push({id:r,message:e})})),s},encode(s){const t={};for(const o of e(s))r(t,o.id,o.message);return JSON.stringify(t,null,2)+"\n"},toJSONString:e=>e})));function o(e,r,s=""){for(const t of Object.keys(e)){const n=s?s+"."+t:t,a=e[t];if("string"==typeof a)r(a,n);else{if(Array.isArray(a))throw new Error(`Message at \`${n}\` resolved to an array, but only strings are supported. See https://next-intl.dev/docs/usage/translations#arrays-of-messages`);"object"==typeof a&&o(a,r,n)}}}export{t as default};
1
+ import{getSortedMessages as e,setNestedProperty as r,isForbiddenObjectKey as s}from"../../utils.js";import{defineCodec as t}from"../ExtractorCodec.js";var o=t((()=>({decode(e){const r=JSON.parse(e),s=[];return a(r,((e,r)=>{s.push({id:r,message:e})})),s},encode(s){const t={};for(const o of e(s))r(t,o.id,o.message);return JSON.stringify(t,null,2)+"\n"},toJSONString:e=>e})));function a(e,r,t=""){for(const o of Object.keys(e)){if(s(o))throw new Error(`Invalid message catalog key: \`${o}\`.`);const n=t?t+"."+o:o,i=e[o];if("string"==typeof i)r(i,n);else{if(Array.isArray(i))throw new Error(`Message at \`${n}\` resolved to an array, but only strings are supported. See https://next-intl.dev/docs/usage/translations#arrays-of-messages`);"object"==typeof i&&a(i,r,n)}}}export{o as default};
@@ -1 +1 @@
1
- import n from"path";function e(e){return n.posix.normalize(e.split(n.win32.sep).join(n.posix.sep))}function t(n,e,t){const o=e.split(".");let r=n;for(let n=0;n<o.length-1;n++){const e=o[n];e in r&&"object"==typeof r[e]&&null!==r[e]||(r[e]={}),r=r[e]}r[o[o.length-1]]=t}function o(n){return n.toSorted(((n,e)=>{const t=n.references?.[0],o=e.references?.[0];return t&&o?i(t,o):0}))}function r(n,e){return n.localeCompare(e,"en")}function i(n,e){const t=r(n.path,e.path);return 0!==t?t:(n.line??0)-(e.line??0)}function c(){return process.cwd()}export{i as compareReferences,c as getDefaultProjectRoot,o as getSortedMessages,r as localeCompare,e as normalizePathToPosix,t as setNestedProperty};
1
+ import t from"path";function e(e){return t.posix.normalize(e.split(t.win32.sep).join(t.posix.sep))}const n=new Set(["__proto__","constructor","prototype"]);function o(t){return n.has(t)}function r(t,e,n){const r=e.split(".");for(const t of r)if(o(t))throw new Error(`Invalid message id segment: ${t}`);let c=t;for(let t=0;t<r.length-1;t++){const e=r[t];Object.prototype.hasOwnProperty.call(c,e)&&"object"==typeof c[e]&&null!==c[e]||(c[e]=Object.create(null)),c=c[e]}c[r[r.length-1]]=n}function c(t){return t.toSorted(((t,e)=>{const n=t.references?.[0],o=e.references?.[0];return n&&o?i(n,o):0}))}function s(t,e){return t.localeCompare(e,"en")}function i(t,e){const n=s(t.path,e.path);return 0!==n?n:(t.line??0)-(e.line??0)}function p(){return process.cwd()}export{i as compareReferences,p as getDefaultProjectRoot,c as getSortedMessages,o as isForbiddenObjectKey,s as localeCompare,e as normalizePathToPosix,r as setNestedProperty};
@@ -1,5 +1,6 @@
1
1
  import type { ExtractorMessage, ExtractorMessageReference } from './types.js';
2
2
  export declare function normalizePathToPosix(filePath: string): string;
3
+ export declare function isForbiddenObjectKey(key: string): boolean;
3
4
  export declare function setNestedProperty(obj: Record<string, any>, keyPath: string, value: any): void;
4
5
  export declare function getSortedMessages(messages: Array<ExtractorMessage>): Array<ExtractorMessage>;
5
6
  export declare function localeCompare(a: string, b: string): number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-intl",
3
- "version": "4.9.1",
3
+ "version": "4.9.2",
4
4
  "sideEffects": false,
5
5
  "author": "Jan Amann <jan@amann.work>",
6
6
  "funding": [
@@ -127,11 +127,11 @@
127
127
  "@formatjs/intl-localematcher": "^0.8.1",
128
128
  "@parcel/watcher": "^2.4.1",
129
129
  "@swc/core": "^1.15.2",
130
- "icu-minify": "^4.9.1",
130
+ "icu-minify": "^4.9.2",
131
131
  "negotiator": "^1.0.0",
132
- "next-intl-swc-plugin-extractor": "^4.9.1",
132
+ "next-intl-swc-plugin-extractor": "^4.9.2",
133
133
  "po-parser": "^2.1.1",
134
- "use-intl": "^4.9.1"
134
+ "use-intl": "^4.9.2"
135
135
  },
136
136
  "peerDependencies": {
137
137
  "next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
@@ -142,5 +142,5 @@
142
142
  "optional": true
143
143
  }
144
144
  },
145
- "gitHead": "b4aa5380c50ad59a80d1dfdbc229590a4e0133a3"
145
+ "gitHead": "e1b18258075017216165735212568c8f795e1660"
146
146
  }