mashpie / i18n-node

Lightweight simple translation module for node.js / express.js with dynamic json storage. Uses common __('...') syntax in app and templates.
MIT License
3.09k stars 421 forks source link

`__n` not working as per documentation in the description #519

Open mathmul opened 7 months ago

mathmul commented 7 months ago

__n not working as per documentation in the description

Device specifications

Probably not all of the following is needed but her's the info just to be safe.

user@device tmp % system_profiler SPHardwareDataType
Hardware:

    Hardware Overview:

      Model Name: MacBook Pro
      Model Identifier: MacBookPro16,1
      Processor Name: 6-Core Intel Core i7
      Processor Speed: 2,6 GHz
      Number of Processors: 1
      Total Number of Cores: 6
      L2 Cache (per Core): 256 KB
      L3 Cache: 12 MB
      Hyper-Threading Technology: Enabled
      Memory: 16 GB
      System Firmware Version: 2022.100.22.0.0 (iBridge: 21.16.4222.0.0,0)
      OS Loader Version: 580~1678
      ...

user@device tmp % nvm -v
0.39.1
user@device tmp % npm -v
9.8.1
user@device tmp % node -v
v21.6.2
user@device tmp % npm list 
tmp@1.0.0 /Users/user/.../tmp
└── i18n@0.15.1

Minimal project

Initial files

package.json

{
  "name": "tmp",
  "version": "1.0.0",
  "description": "",
  "type": "module",
  "main": "index.js",
  "scripts": {
    "test": "test"
  },
  "author": "me",
  "license": "ISC",
  "dependencies": {
    "i18n": "^0.15.1"
  }
}

index.js

import i18n from 'i18n';
import path from 'path';
import { fileURLToPath } from 'url'

const __dirname = path.dirname( fileURLToPath( import.meta.url ) )

i18n.configure( {
  locales: ['en', 'de'],
  fallbacks: { 'en-*': 'en', 'de-*': 'de' },
  defaultLocale: 'en',
  register: global,
  queryParameter: 'lang',
  directory: path.join( __dirname, 'locales' ),
} );

console.log( "current locale:", i18n.getLocale() )
console.log( "__   :", i18n.__( '%s cat', 1 ) )
console.log( "__mf :", i18n.__mf( '{one} cat', {one:1} ) )
console.log( "__n  :", i18n.__n( '%s cat', '%s cats', 1 ) )
console.log( "__n  :", i18n.__n( '%s cat', 1 ) )
console.log( "__n  :", i18n.__n( '%s dog', '%s dogs', 1 ) )
console.log( "__n  :", i18n.__n( '%s dog', 1 ) )

Generated after running node index.js in the Terminal

locale/de.json

{}

locale/en.json

{
    "%s cat": "%s cat",
    "{one} cat": "{one} cat",
    "%s dog": {
        "one": "%s dog",
        "other": "%s dogs"
    }
}

Issue

__n function doesn't know how to consume the JSON generated by the i18n package itself. The console.log( "__n :", i18n.__n( '%s cat', '%s cats', 1 ) ) line only works because the console.log( "__ :", i18n.__( '%s cat', 1 ) ) line causes "%s cat": "%s cat" to be generated in the JSON before it being called, and reads from this key. When essentially the same line, i.e., console.log( "__n :", i18n.__n( '%s dog', '%s dogs', 1 ) ) is being it generates a different (and logical) hash map in JSON for the key "%s dog", and then for some reason it cannot read it.

CLI output

user@device tmp % node index.js                     
current locale: en
__   : 1 cat
__mf : 1 cat
__n  : 1 cat
__n  : 1 cat
/Users/user/.../tmp/node_modules/i18n/i18n.js:451
          .toLowerCase()
           ^

TypeError: Cannot read properties of undefined (reading 'toLowerCase')
    at Object.i18nTranslatePlural [as __n] (/Users/user/.../tmp/node_modules/i18n/i18n.js:451:12)
    at file:///Users/user/.../tmp/index.js:21:29
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:323:24)
    at async loadESM (node:internal/process/esm_loader:28:7)
    at async handleMainPromise (node:internal/modules/run_main:120:12)

Node.js v21.6.2

Also if I comment out the console.log( "__n :", i18n.__n( '%s dog', '%s dogs', 1 ) ) line after en.json has been generated, the executions fails in the same way at the line console.log( "__n :", i18n.__n( '%s dog', 1 ) ).

Note

Using __n in different manner works, but it's too unreadable for normal usage.

console.log( "__n  :", i18n.__n( { singular: '%s bird', plural: '%s birds', locale: 'en' }, 1 ) )

adds to en.json

    "%s bird": {
        "one": "%s bird",
        "other": "%s birds"
    }

and outputs

__n  : 1 bird

as expected.