update tests

This commit is contained in:
wxzhang 2022-08-29 08:59:18 +08:00
parent 74096ea312
commit f59e6a23ef
5 changed files with 471 additions and 83 deletions

View File

@ -9,7 +9,8 @@
- 本质上是一个普通的同步函数
- 支持有参和无参两种调用方式
- 支持通过管道符`|`进行链式调用
- 可以通过`$config`为格式化器传入配置参数
- 格式化器函数最后一个参数是当前语言的格式化器配置参数`$config`
- 格式化器函数`this`指向`scope`实例
## 指南
@ -20,17 +21,15 @@
- 无参数的格式化器:`(value,$config)=>{....返回格式化的结果...}`
- 带参数的格式化器:`(value,arg1,...,$config)=>{....返回格式化的结果...}`,其中`value`是上一个格式化器的输出结果。
格式化器函数的第一个参数是上一个格式化器的输出,最后一个参数是定义在`$config`中的配置参数。
格式化器函数的第一个参数是上一个格式化器的输出,最后一个参数是当前语言的格式化器配置参数`$config`
**调用方式:**
```javascript | pure
t("商品价格:{ value | currency }") // 参数调用
t("商品价格:{ value | currency('long') }") /// 有参调用
t("商品价格:{ value | currency('long') | prefix('人民币') }") /// 有参调用且链式调用
t("商品价格:{ value | currency }",1234.88) // 参数调用
t("商品价格:{ value | currency('long') }",1234.88) /// 有参调用
t("商品价格:{ value | currency('long') | prefix('人民币') }",1234.88) /// 有参调用且链式调用
t("商品价格:{ value | currency({ symbol:'¥¥',prefix:'人民币:',suffix:'元整',unit:2 }) } ") /// 对象参数
```
### 类型格式化器
@ -76,10 +75,10 @@ t("灯状态:{status}",false) // === 灯状态OFF
**说明:**
- 在匹配应用格式化时会先在当前语言的`$types`中查找匹配的格式化器。
- 类型格式化器是**默认执行的,不需要指定名称**。
- 当前作用域的格式化器优先于全局的格式化器。
- 当指定了其他格式化器时,类型格式化器就失败,比如`t("灯状态:{status | xxx}",true)`时,上面定义的`$types.Boolean`就无效。
- 类型格式化器仅在无参调用时才生效,当指定了其他格式化器时,类型格式化器无效,比如`t("灯状态:{status | xxx}",true)`时,上面定义的`$types.Boolean`就无效。
### 通用的格式化器
@ -93,30 +92,220 @@ t("灯状态:{status}",false) // === 灯状态OFF
export default {
$config:{...},
$types:{...},
[格式化名称]:(value)=>{.....},
[格式化名称]:(value,$config)=>{.....}
}
// languages/formatters/en.js
export default {
$config:{...},
$types:{....},
[格式化名称]:(value)=>{.....},
[格式化名称]:(value,arg)=>{.....},
[格式化名称]:(value,$config)=>{.....},
[格式化名称]:(value,arg,$config)=>{.....}
}
```
如果要注册在所有语言中均生效的,可以声明在`languages/formatters/global.js`
如果要注册在所有语言中均生效的,可以声明在`languages/formatters/en.js`中,因为所有语言均的默认`fallback`语言均是`en`
### 可配置
#### 引入配置机制
格式化器是一个普通的的同步函数,我们只需要针对不同的语言编写相对应的格式化器函数,当切换语言时,就会自动调用相应的格式化器函数进行格式化输出。
例如:我们开发一个转换数字的格式化器,在中文下显示`一、二、三`,在英文下显示`One、Two、Three`
```javascript | pure
// languages/formatters/global.js
export default {
$config:{...},
$types:{....},
[格式化名称]:(value)=>{.....},
[格式化名称]:(value,arg)=>{.....},
// languages/formatters/zh.js
export default {
uppercase:(value)=> ["一","二","三"][value-1]
}
// languages/formatters/en.js
export default {
uppercase:(value)=> ["One","Two","Three"][value-1]
}
```
上面这个格式化器非常简单,以至于为不同语言编写对应的语言格式化也是非常容易的,比如可以增加`de`语言。
```javascript | pure
// languages/formatters/de.js
export default {
uppercase:(value)=> ["Eins", "zwei", "drei"][value-1]
}
```
但是明显上面的格式化器还存在一些瑕疵,比如没有做类型检查,这样容易出错。因此,我们来增加相应的类型检查。
```javascript | pure
// languages/formatters/zh.js
export default {
uppercase:(value)=>{
let index = parentInt(value)
if(index<0 || index>3 || isNaN(index)) index = 0
return ["一","二","三"][index]
}
}
// languages/formatters/en.js
export default {
uppercase:(value)=>{
let index = parentInt(value)
if(index<0 || index>3 || isNaN(index)) index = 0
return ["One","Two","Three"][index]
}
}
```
问题开始显现,`zh``en`两种语言中存在了同样的类型检查逻辑如果要支持10种语言就得重复同样的逻辑。
所以问题关键就是无法复用逻辑,而引入**格式化可配置机制**就是为了解决多语言场景下,格式化器的逻辑复用问题。
#### 实现机制
**格式化可配置机制**事实上很简单,就是两个关键步骤:
- **第一步:在每个语言格式化器文件,指定`$config`用来保存配置参数**
```javascript | pure
// languages/formatters/zh.js
export default {
$config:{ .... }
}
// languages/formatters/en.js
export default {
$config:{ .... }
}
```
- **第二步:在执行格式化函数时传入$config**
```javascript | pure
// languages/formatters/zh.js
export default {
$config:{ .... },
[格式化名称]:(value,...args,$config)=>{...}
}
// languages/formatters/en.js
export default {
$config:{ .... }
[格式化名称]:(value,...args,$config)=>{...}
}
```
当执行格式化器函数时,总是**将当前语言激活的格式化器声明中的$config作为最后一个参数传递给执行格式化器函数**。
这样格式化器函数就可以读取配置。
下面我们来重写`uppercase`格式化器:
```javascript | pure
// languages/formatters/en.js
export default {
$config:{
values:["One","Two","Three"]
},
uppercase:(value,$config)=>{
let index = parentInt(value)
if(index<0 || index>3 || isNaN(index)) index = 0
return $config.values[index]
}
}
// languages/formatters/zh.js
export default {
$config:{
values:["一","二","三"]
}
}
// languages/formatters/de.js
export default {
$config:{
values:["Eins", "zwei", "drei"]
}
}
```
可以看到,引入配置机制后,只需要在`en`语言中定义格式化器,让该格式化器中与语言相关的参数从配置中读取,然后在其他语言中只需要声明$config就可以实现不同语言下的输出逻辑得到重用。
#### **合并配置**
格式化器配置机制的重点在于:
**当切换语言时,`voerkai18n`会将当前`scope.activeFormaters`切换到对应的`languages/formatters/<语言名称>.js`,这样在执行格式化器函数时,就总是可以得到当前语言的格式化器配置。**
格式化器配置机制还支持配置的合并机制,在上例中,当我们切换到`de`语言时,`voerkai18n`会依次合并:
```javascript | pure
const finalConfig = deepMerge(
scope.global.formatters["en"].$config, // 优先级最低
scope.global.formatters["*"].$config,
scope.formatters["en"].$config,
scope.formatters["*"].$config,
scope.global.formatters["de"].$config,
scope.formatters["de"].$config // 优先级最高
)
```
按照这样的合并机制,在扩展配置时就不需要指定所有配置项,只需要按需配置即可。
例如:`currency`格式化器的完整配置是:
```javascript | pure
export default {
currency:{
default : "{symbol}{value}{unit}",
long : "{prefix} {symbol}{value}{unit}{suffix}",
short : "{symbol}{value}{unit}",
custom : "{prefix} {symbol}{value}{unit}{suffix}",
format : "default",
//--
units : [""," thousands"," millions"," billions"," trillions"], //千,百万,十亿,万亿
radix : 3, // 进制即三位一进中文是4位一进
symbol : "$", // 符号
prefix : "USD", // 前缀
suffix : "", // 后缀
division : 3, // ,分割位
precision : 2, // 精度
}
}
```
如果我们要增加`de`语言,则只需要配置`untis`,`symbol`,`prefix`等需要的参数即可、
### 查找格式化器
上节中,我们说只需要在`en`语言中定义格式化器,其他语言只需要配置就可以,原因就在于`en`语言是所有语言的默认回退语言fallback
`voerkai18n`按以下顺序查找指定名称的格式化器:
- `scope.activeFormatters` :当前语言中声明的,即`languages/formatters/<语言名称>.js`
- `scope.formatters[fallbackLanguage]` 当前语言的回退语言
- `scope.formatters["*"]` 声明在`languages/formatters/<语言名称>.js`中的`{"*":{....}}`
- `scope.global.formatters[activeLanguage]` 注册在Voerkai18n实例中的当前语言格式化器
- `scope.global.formatters[fallbackLanguage]` 注册在Voerkai18n实例中的当前语言回退语言的格式化器
- `scope.global.formatters["*"]` 注册在Voerkai18n实例中的所有语言的格式化器
按照这样的搜索顺序,大部份语言的格式化器均只需要声明在`languages/formatters/en.js`中,然后为格式化增加可配置支持,然后只需要在其他语言的`languages/formatters/<语言名称>.js`声明一下配置就可以复用格式化器。
### 格式化器作用域
定义在`languages/formatters/<语言名称>.js`里面的格式化器仅在当前`i18nScope`实例中生效,也就是仅在当前作用域生效。
### 全局格式化器
定义在`@voerkai18n/runtime`里面的格式化器则全局有效,在所有场合均可以使用,但是其优先级低于`i18nScope`作用域内的同名格式化器。
目前内置的全局格式化器请参阅API参考
### 扩展格式化器
除了可以在当前项目`languages/formatters/<语言名称>.js`自定义格式化器和`@voerkai18n/runtime`里面的全局格式化器外,计划单列了`@voerkai18n/formatters`项目用来包含了一些不常用的格式化器。
目前`@voerkai18n/formatters`还是空项目,作为开源项目,欢迎大家提交贡献更多的格式化器。
## 开发格式化器
### 普通格式化器
普通格式化器就是一个很简单的同步函数,其输入是插值变量值或者上一个格式化器的输出。
**例:** 开发一个转换数字的格式化器,在中文下显示`一、二、三`,在英文下显示`One、Two、Three`
```javascript | pure
// languages/formatters/zh.js
export default {
uppercase:(value)=> ["一","二","三"][value-1]
}
// languages/formatters/en.js
export default {
uppercase:(value)=> ["One","Two","Three"][value-1]
}
// 当切换到中文时
t("{value | uppercase}",1) // == 一
t("{value | uppercase}",2) // == 二
@ -127,14 +316,176 @@ t("{value | uppercase}",1) // == One
t("{value | uppercase}",2) // == Two
t("{value | uppercase}",3) // == Three
// 当切换到日文时由于在该语言下没有定义uppercase因此到global中查找
t("{value | uppercase}",1) // == 1
t("{value | uppercase}",2) // == 2
t("{value | uppercase}",3) // == 3
// 当切换到日文时由于在该语言下没有定义uppercase因此到`fallback`语言中查找
t("{value | uppercase}",1) // == One
t("{value | uppercase}",2) // == Two
t("{value | uppercase}",3) // == Three
```
**注意:**
- 普通格式化器是同步函数,不支持异步函数
### 自定义格式化器
### 变参格式化器
如果需要格式化器支持变参调用,像这样:
```javascript | pure
t("{value | uppercase}",1)
t("{value | uppercase(a)}",2)
t("{value | uppercase(a,b,c)}",3)
```
那么就需要自己在格式化函数中处理,一般可以像这样:
```javascript | pure
// languages/formatters/zh.js
export default {
uppercase:(value,...args)=>{
// 最后后一个参数总是$config
let $config = args[args.length-1]
let params = args.slice(0,args.length-1)
//....
}
}
```
### Formatter
为简化编写格式化器函数时对输入值进行值检查、变参处理、默认值处理等通用逻辑,`voerkai18n`提供了`createFormater``Formatter`函数帮助创建格式化函数。
```javascript | pure
// languages/formatters/en.js
import { Formatter } from "../runtime"
export default {
$config{
sum:{
a:0,
b:0,
c:0,
format:"Sum={result}"
},
},
sum: Formatter((value,a,b,c,$config)=>{
// $config指向的是当前配置的sum
return $config.format.replace("{result}",value + a + b + c)
},{
normalize:(value)=>parentInt(value),
params:["a","b","c"],
configKey:"sum" // 声明该配置化器的配置参数位置
})
}
```
以上创建了一个名叫`sum`的格式化器该格式化器支持3个参数然后会计算`value`+`a`+`b`+`c`,然后输出`Sum={result}`
```javascript | pure
t("{value | sum }",1) // a=0,b=0,c=0
t("{value | sum(1)}",1) // a=1,b=0,c=0
t("{value | sum(1,2)}",1) // a=1,b=2,c=0
t("{value | sum(1,2,3)}",1) // a=1,b=2,c=3
```
`Formatter``createFormater`的别名,其参数说明如下:
- **normalize**
`Function`,可选,提供一个函数来对输入值进行规范化处理,并返回规范化后的值。如上例中需要输入参数是一个数字,因为就需要转换为数字。
- **params**
`Array`,可选,用来声明该格式化器支持的参数列表。
`params`的作用除了是用来声明该格式化器支持多少个参数外,`Formatter`还支持从配置中读取这些参数的默认值。
如上例中在`$config.sum`中配置了`a`,`b`,`c`三个参数的默认值。
**当指定`params`参数时**:
- 格式化器函数总是可以接收到与`params`参数匹配的参数,并且最后一个参数是`$config`,格式化函数就不需要处理变参的情况了。
- 接收到的参数已经自动填入了从`$config[configKey]`中读取到的默认值。
**当没有指定`params`参数时**:
- 格式化器函数接收到的是`(value,...args,$config)`,这就意味着,你需要自己处理变参的情况了。
利用这个特性,我们就可以为不同语言下格式化器的默认参数。例如`currency`格式化器的`symbol`参数在不同语言下的值。如下:
```javascript | pure
// languages/formatters/zh.js
export default {
$config:{
currency{
symbol : "¥"
}
}
}
// languages/formatters/en.js
export default {
$config:{
currency{
symbol : "$"
}
}
}
```
- **configKey**
`configKey`用来指定当前格式化器函数的配置参数位置,上例中`configKey="sum"`,则`(value,a,b,c,$config)=>{....}`中传入的`$config`就是`scope.activeFormatterConfig.sum`,也就是`languages/formatters/en.js`中的`$config.sum`
如果没有指定`configKey`,则传入`$config`值就是`scope.activeFormatterConfig`,此时就无法为`a`,`b`,`c`指定默认参数了。
### FlexFormatter
大部份情况下,使用`Formatter`就可以比较方便地创建格式化器了。
当某个格式化器的可配置参数很多时,如`currency`格式化器,支持`format`,`unit`,`precision`,`prefix`,`suffix`,`division`,`symbol`,`radix`共8个位置参数用户可以通过以下方式调用
```javascript | pure
t("{ value | currency('long',1)}",1234.56) // 长格式: 万元
t("{ value | currency('long',1,2,'人民币')}",1234.56)
t("{ value | currency('long',1,2,'人民币','元',3,'')}",1234.56)
```
如果我们只需要变更`symbol`参数,由于`symbol`参数是第七个参数,使用位置参数就不得不这样调用。
```javascript | pure
t("{ value | currency(,,,,,,,'¥')}",1234.56)
```
很丑陋的,因此,我们希望支持像这样:
```javascript | pure
t("{ value | currency({symbol:'¥')}",1234.56)
```
也就是说,格式化器即支持可选位置传参,也支持`{...}`传参,基于上述已经介绍的格式化机制,您完全可以自己来处理这样的参数处理功能。
`FlexFormatter`则封装了这样的功能,其即支持可选位置传参,也支持`{...}`传参。用法如下:
```javascript | pure
// languages/formatters/en.js
import { FlexFormatter } from "../runtime"
export default {
$config{
sum:{
a:0,
b:0,
c:0,
format:"Sum={result}"
},
},
sum: FlexFormatter((value,params,$config)=>{
return $config.format.replace("{result}",value + params.a + params.b + params.c)
},{
normalize:(value)=>parentInt(value),
params:["a","b","c"],
configKey:"sum" // 声明该配置化器的配置参数位置
})
}
```
经过上述改造过,上例中的`sum`格式化器就可以支持以下方式进行调用:
```javascript | pure
t("{value | sum }",1) // a=0,b=0,c=0
t("{value | sum(1)}",1) // a=1,b=0,c=0
t("{value | sum(1,2)}",1) // a=1,b=2,c=0
t("{value | sum(1,2,3)}",1) // a=1,b=2,c=3
t("{value | sum({a:1})}",1) // a=1,b=0,c=0
t("{value | sum({a:1,b:2})}",1) // a=1,b=2,c=0
t("{value | sum({a:1,b:2,c:3})}",1) // a=1,b=2,c=3
```
## 部署格式化器
上面我们已经介绍了如何开发格式化器和配置相关,一般我们需要为特定语言的格式化器的配置和函数声明在`languages/formatters/<语言名称>.js`中,下面进一步介绍一下格式化器应该在哪里进行声明。
当使用`voerkai18n compile`后,项目结构中会生成`formatters`如下:
@ -142,59 +493,64 @@ t("{value | uppercase}",3) // == 3
<myapp>
|--src
| |-- languages
| | |-- formatters
| | | |-- zh.js
| | | |-- en.js
| | | |-- de.js
....
|-- formatters
| |-- zh.js
| |-- en.js
| |-- de.js
......
```
您可以在`formatters`文件夹中的`zh.js``en.js``de.js`文件中配置或者增加自己的自定义的格式化器。
`languages/formatters/<语言名称>.js`内容大概如下:
您可以在`formatters`文件夹中的`zh.js``en.js``de.js`文件中**配置**或者**新增**自己的自定义格式化器。
当切换到指定的语言时,就会`voerkai18n`会切换到对应的`languages/formatters/<语言名称>.js`,从而该语言的格式化器生效,并且会按一下的顺序进行查找格式化器。
打开`languages/formatters/<语言名称>.js`内容大概如下:
```javascript | pure
export default {
$config:{
// 在此配置各格式化器的参数
},
// 在所有语言下只作用于特定数据类型的格式化器
// 只作用于特定数据类型的格式化器
$types:{
// [数据类型名称]:(value)=>{...},
// [数据类型名称]:(value)=>{...},
},
},
// 自定义的格式化器
[格式化名称]:(value,$config)=>{.....},
[格式化名称]:(value,$config)=>{.....},
[格式化名称]:(value,$config)=>{.....},
[格式化名称]:(value,...args,$config)=>{.....},
[格式化名称]:(value,...args,$config)=>{.....},
[格式化名称]:(value,...args,$config)=>{.....},
//.....更多的格式化器.....
}
```
### 配置机制
`languages/formatters/<语言名称>.js`中定义的格式化器会被注册到当有`i18nScope`实例中。如此,在多包工程中,其他包/库就无法共享当前应用的格式式化器。
因此,您想注册一个格式化器可以在所有库/包中均可以使用,则需要将格式器注册到全局`VoerkaI18n`实例中。方法有两种是:
- 指定`global=true`将该文件声明的所有格式化器均注册到全局中
```javascript | pure
export default {
$config:{...},
$types:{... },
[格式化名称]:(value,...args,$config)=>{.....},
//.........
}
```
- 在`global`对象明中声明的所有全局格式化器
```javascript | pure
export default {
$config:{...},
$types:{... },
[格式化名称]:(value,...args,$config)=>{.....},
global:{
$config:{...},
$types:{... },
[格式化名称]:(value,...args,$config)=>{.....},
}
//.........
}
```
### 格式化器作用域
定义在`languages/formatters/<语言名称>.js`里面的格式化器仅在当前工程生效,也就是仅在当前作用域生效。
### 全局格式化器
定义在`@voerkai18n/runtime`里面的格式化器则全局有效,在所有场合均可以使用,但是其优先级低于作用域内的同名格式化器。
目前内置的全局格式化器请参阅API参考
### 扩展格式化器
除了可以在当前项目`languages/formatters/<语言名称>.js`自定义格式化器和`@voerkai18n/runtime`里面的全局格式化器外,计划单列了`@voerkai18n/formatters`项目用来包含了一些不常用的格式化器。
目前`@voerkai18n/formatters`还是空项目,作为开源项目,欢迎大家提交贡献更多的格式化器。
## 开发格式化器

View File

@ -2,10 +2,10 @@
| 包| 版本号| 最后更新|说明|
| --- | :---:| --- |---|
|**@voerkai18n/utils**|1.0.13|2022/08/20|公共工具库|
|**@voerkai18n/runtime**|1.1.5|2022/08/25|核心运行时|
|**@voerkai18n/runtime**|1.1.6|2022/08/26|核心运行时|
|**@voerkai18n/formatters**|1.0.6|2022/04/15|格式化器,提供对要翻译文本的转换功能|
|**@voerkai18n/react**|1.0.4|2022/04/16|React支持,提供语言切换等功能|
|**@voerkai18n/cli**|1.0.38|2022/08/25|命令行工具,用来初始化/提取/编译/自动翻译等工具链|
|**@voerkai18n/cli**|1.0.39|2022/08/26|命令行工具,用来初始化/提取/编译/自动翻译等工具链|
|**@voerkai18n/babel**|1.0.24|2022/08/20|Babel插件实现自动导入t函数和自动文本映射|
|**@voerkai18n/vite**|1.0.13|2022/08/20|Vite插件,提供自动插入翻译函数和文本映射等功能|
|**@voerkai18n/vue**|1.0.6|2022/08/20|Vue3插件,提供自动插件翻译函数和语言切换功能|

View File

@ -576,7 +576,7 @@ const formatterNestingParamsRegex = String.raw`((([\'\"])(.*?)\3))|__TAG_REGEXP_
}
return fn.call(this,finalValue,...finalArgs,formatterConfig)
};
$formatter.configurable = true; // 当函数是可配置时才在最后一个参数中传入$config
$formatter.configurable = true;
return $formatter
}
@ -618,10 +618,6 @@ const createFlexFormatter$1 = function(fn,options={},defaultParams={}){
if(args[i]!==undefined) finalParams[options.params[i]] = args[i];
}
}
if(finalParams.format in $config){
finalParams.format = $config[finalParams.format];
}
return fn.call(this,value,finalParams,$config)
},{...options,params:null}); // 变参工式化器需要指定params=null
return $flexFormatter
@ -850,6 +846,7 @@ function getFormatter(scope, activeLanguage, name) {
const range = [
scope.activeFormatters,
scope.formatters[fallbackLanguage], // 如果指定了回退语言时,也在该回退语言中查找
scope.formatters["*"],
scope.global.formatters[activeLanguage], // 适用于activeLanguage全局格式化器
scope.global.formatters[fallbackLanguage],
scope.global.formatters["*"], // 适用于所有语言的格式化器
@ -1432,6 +1429,10 @@ function addSplitChars(str,bits=3){
.replace("{unit}",unitName)
}
const currencyFormatter$1 = FlexFormatter$2((value,params={},$config)=>{
// format可以取预设值的名称如long,short等
if(params.format in $config){
params.format = $config[params.format];
}
params.unit = parseInt(params.unit) || 0;
if(params.unit>$config.units.length-1) params.unit = $config.units.length-1;
if(params.unit<0) params.unit = 0;
@ -1644,8 +1645,7 @@ var en = {
prefix : "USD", // 前缀
suffix : "", // 后缀
division : 3, // ,分割位
precision : 2, // 精度
precision : 2, // 精度
},
number : {
division : 3, // , 分割位3代表每3位添加一个,
@ -2190,6 +2190,7 @@ var scope = class i18nScope {
this.global.registerFormatter(name, formatter, { language });
} else {
language.forEach((lng) => {
if(!(lng in this._formatters)) this._formatters[lng] = {};
if (DataTypes$1.includes(name)) {
this._formatters[lng].$types[name] = formatter;
} else {
@ -2276,16 +2277,25 @@ var scope = class i18nScope {
* - scope.activeFormatters.$config 当前优先
*/
_generateFormatterConfig(language){
let options;
try{
options = deepClone(getByPath(this._global.formatters,`*.$config`,{}));
deepMixin$1(options,getByPath(this._global.formatters,`${language}.$config`,{}));
deepMixin$1(options,getByPath(this._activeFormatters,"$config",{}));
const fallbackLanguage = this.getLanguage(language).fallback;
let configSources = [
getByPath(this._global.formatters,`${fallbackLanguage}.$config`,{}),
getByPath(this._global.formatters,"*.$config",{}),
getByPath(this._formatters,`${fallbackLanguage}.$config`,{}),
getByPath(this._formatter,"*.$config",{}),
getByPath(this._global.formatters,`${language}.$config`,{}),
getByPath(this._activeFormatters,"$config",{})
];
return this._activeFormatterConfig = configSources.reduce((finalConfig, config)=>{
if(isPlainObject$2(config)) deepMixin$1(finalConfig,config);
return finalConfig
},deepClone(getByPath(this._global.formatters,`*.$config`,{})))
}catch(e){
if(this.debug) console.error(`Error while generate <${language}> formatter options: `,e);
if(!options) options = this._activeFormatters.$config || {};
return this._activeFormatters.$config || {}
}
return this._activeFormatterConfig = options
}
/**

View File

@ -1,6 +1,6 @@
{
"name": "@voerkai18n/cli",
"version": "1.0.38",
"version": "1.0.39",
"description": "命令行工具,用来初始化/提取/编译/自动翻译等工具链",
"main": "index.js",
"homepage": "https://gitee.com/zhangfisher/voerka-i18n",
@ -50,5 +50,5 @@
"devDependencies": {
"@voerkai18n/autopublish": "workspace:^1.0.2"
},
"lastPublish": "2022-08-25T22:07:13+08:00"
"lastPublish": "2022-08-26T17:39:52+08:00"
}

View File

@ -280,7 +280,7 @@ const formatters = {
book:(v)=>`${v}`,
},
en:{
$config:{},
$config:{a:1},
$types:{ },
book:(v)=>`<${v}>`,
},
@ -483,7 +483,7 @@ describe("翻译函数",()=>{
})
test("日期时间格式化",async ()=>{
let zhTranslatedResults = zhDatetimes.map(v=>t(v,NOW))
let p = diffArray(zhTranslatedResults,expectZhDatetimes)
// let p = diffArray(zhTranslatedResults,expectZhDatetimes)
expect(zhTranslatedResults).toStrictEqual(expectZhDatetimes)
await scope.change("en")
let enTranslatedResults = zhDatetimes.map(v=>t(v,NOW))
@ -649,4 +649,26 @@ describe("翻译函数",()=>{
})
test("注册普通格式化器",async ()=>{
const f1 = (value,$config) => value + 1
scope.registerFormatter("f1",f1)
expect(t("{value | f1}",1)).toBe("2")
expect(t("{value | f1}","1")).toBe("11")
const f2 = (value,arg,$config) => value + arg
scope.registerFormatter("f2",f2)
expect(t("{value | f2('*')}","1")).toBe("1*")
const f3 = (value,args,$config) => value + args.name
scope.registerFormatter("f3",f3)
expect(t("{value | f3({name:'x'})}","1")).toBe("1x")
const f4 = (value,$config) => value + 1
scope.registerFormatter("f4",f4,{languages:"en"})
expect(t("{value | f4(1)}",1)).toBe("2")
})
})