refact(es6): use es6 syntax.
* fixed #10, But iojs-2 not support Object.assign, so use object-assign shim instead for now. * use es6 syntax. * use eslint to instead jshint.master
parent
eae25a474d
commit
36bd1d5202
|
@ -0,0 +1,190 @@
|
|||
{
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
"parser": "espree",
|
||||
"env": {
|
||||
"amd": false,
|
||||
"jasmine": false,
|
||||
"node": true,
|
||||
"mocha": true,
|
||||
"browser": true,
|
||||
"builtin": true,
|
||||
"es6": true
|
||||
},
|
||||
"rules": {
|
||||
"no-alert": 2,
|
||||
"no-array-constructor": 2,
|
||||
"no-bitwise": 2,
|
||||
"no-caller": 2,
|
||||
"no-catch-shadow": 2,
|
||||
"no-cond-assign": [2, "except-parens"],
|
||||
"no-constant-condition": 2,
|
||||
"no-continue": 0,
|
||||
"no-control-regex": 2,
|
||||
"no-debugger": 2,
|
||||
"no-delete-var": 2,
|
||||
"no-div-regex": 0,
|
||||
"no-dupe-keys": 2,
|
||||
"no-dupe-args": 2,
|
||||
"no-duplicate-case": 2,
|
||||
"no-else-return": 0,
|
||||
"no-empty": 2,
|
||||
"no-empty-character-class": 2,
|
||||
"no-empty-label": 2,
|
||||
"no-eq-null": 0,
|
||||
"no-eval": 2,
|
||||
"no-ex-assign": 2,
|
||||
"no-extend-native": 2,
|
||||
"no-extra-bind": 2,
|
||||
"no-extra-boolean-cast": 2,
|
||||
"no-extra-parens": 2,
|
||||
"no-extra-semi": 2,
|
||||
"no-fallthrough": 2,
|
||||
"no-floating-decimal": 0,
|
||||
"no-func-assign": 2,
|
||||
"no-implied-eval": 2,
|
||||
"no-inline-comments": 0,
|
||||
"no-inner-declarations": [2, "functions"],
|
||||
"no-invalid-regexp": 2,
|
||||
"no-irregular-whitespace": 2,
|
||||
"no-iterator": 0,
|
||||
"no-label-var": 2,
|
||||
"no-labels": 2,
|
||||
"no-lone-blocks": 2,
|
||||
"no-lonely-if": 0,
|
||||
"no-loop-func": 2,
|
||||
"no-mixed-requires": [0, false],
|
||||
"no-mixed-spaces-and-tabs": [2, false],
|
||||
"linebreak-style": [0, "unix"],
|
||||
"no-multi-spaces": 2,
|
||||
"no-multi-str": 2,
|
||||
"no-multiple-empty-lines": [0, {
|
||||
"max": 2
|
||||
}],
|
||||
"no-native-reassign": 2,
|
||||
"no-negated-in-lhs": 2,
|
||||
"no-nested-ternary": 0,
|
||||
"no-new": 0,
|
||||
"no-new-func": 2,
|
||||
"no-new-object": 2,
|
||||
"no-new-require": 0,
|
||||
"no-new-wrappers": 2,
|
||||
"no-obj-calls": 2,
|
||||
"no-octal": 2,
|
||||
"no-octal-escape": 2,
|
||||
"no-param-reassign": 0,
|
||||
"no-path-concat": 0,
|
||||
"no-plusplus": 0,
|
||||
"no-process-env": 0,
|
||||
"no-process-exit": 0,
|
||||
"no-proto": 2,
|
||||
"no-redeclare": 2,
|
||||
"no-regex-spaces": 2,
|
||||
"no-restricted-modules": 0,
|
||||
"no-return-assign": 0,
|
||||
"no-script-url": 2,
|
||||
"no-self-compare": 0,
|
||||
"no-sequences": 2,
|
||||
"no-shadow": 0,
|
||||
"no-shadow-restricted-names": 2,
|
||||
"no-spaced-func": 2,
|
||||
"no-sparse-arrays": 2,
|
||||
"no-sync": 0,
|
||||
"no-ternary": 0,
|
||||
"no-trailing-spaces": 2,
|
||||
"no-this-before-super": 0,
|
||||
"no-throw-literal": 0,
|
||||
"no-undef": 2,
|
||||
"no-undef-init": 2,
|
||||
"no-undefined": 0,
|
||||
"no-unexpected-multiline": 0,
|
||||
"no-underscore-dangle": 0,
|
||||
"no-unneeded-ternary": 0,
|
||||
"no-unreachable": 2,
|
||||
"no-unused-expressions": 0,
|
||||
"no-unused-vars": 2,
|
||||
"no-use-before-define": [2, "nofunc"],
|
||||
"no-void": 0,
|
||||
"no-var": 2,
|
||||
"no-const-assign": 2,
|
||||
"prefer-const": 2,
|
||||
"no-warning-comments": [0, {
|
||||
"terms": ["todo", "fixme", "xxx"],
|
||||
"location": "start"
|
||||
}],
|
||||
"no-with": 2,
|
||||
"array-bracket-spacing": [0, "never"],
|
||||
"accessor-pairs": 0,
|
||||
"block-scoped-var": 0,
|
||||
"brace-style": [0, "1tbs"],
|
||||
"camelcase": 0,
|
||||
"comma-dangle": [2, "always-multiline"],
|
||||
"comma-spacing": 2,
|
||||
"comma-style": 0,
|
||||
"complexity": [0, 11],
|
||||
"computed-property-spacing": [0, "never"],
|
||||
"consistent-return": 0,
|
||||
"consistent-this": [0, "that"],
|
||||
"constructor-super": 0,
|
||||
"curly": [2, "multi-line"],
|
||||
"default-case": 0,
|
||||
"dot-location": 0,
|
||||
"dot-notation": 0,
|
||||
"eol-last": 2,
|
||||
"eqeqeq": 2,
|
||||
"func-names": 0,
|
||||
"func-style": [0, "declaration"],
|
||||
"generator-star-spacing": 0,
|
||||
"guard-for-in": 0,
|
||||
"handle-callback-err": 0,
|
||||
"indent": [2, 2],
|
||||
"key-spacing": [2, {
|
||||
"beforeColon": false,
|
||||
"afterColon": true
|
||||
}],
|
||||
"lines-around-comment": 0,
|
||||
"max-depth": [0, 4],
|
||||
"max-len": [0, 80, 4],
|
||||
"max-nested-callbacks": [0, 2],
|
||||
"max-params": [0, 3],
|
||||
"max-statements": [0, 10],
|
||||
"new-cap": 0,
|
||||
"new-parens": 2,
|
||||
"newline-after-var": 0,
|
||||
"object-curly-spacing": [0, "never"],
|
||||
"object-shorthand": 0,
|
||||
"one-var": 0,
|
||||
"operator-assignment": [0, "always"],
|
||||
"operator-linebreak": 0,
|
||||
"padded-blocks": 0,
|
||||
"quote-props": 0,
|
||||
"quotes": [2, "single"],
|
||||
"radix": 0,
|
||||
"semi": 2,
|
||||
"semi-spacing": [2, {
|
||||
"before": false,
|
||||
"after": true
|
||||
}],
|
||||
"sort-vars": 0,
|
||||
"space-after-keywords": [0, "always"],
|
||||
"space-before-blocks": [0, "always"],
|
||||
"space-before-function-paren": [0, "always"],
|
||||
"space-in-parens": [0, "never"],
|
||||
"space-infix-ops": 2,
|
||||
"space-return-throw-case": 2,
|
||||
"space-unary-ops": [2, {
|
||||
"words": true,
|
||||
"nonwords": false
|
||||
}],
|
||||
"spaced-comment": 0,
|
||||
"strict": [2, "global"],
|
||||
"use-isnan": 2,
|
||||
"valid-jsdoc": 0,
|
||||
"valid-typeof": 0,
|
||||
"vars-on-top": 0,
|
||||
"wrap-iife": 0,
|
||||
"wrap-regex": 0,
|
||||
"yoda": [2, "never"]
|
||||
}
|
||||
}
|
95
.jshintrc
95
.jshintrc
|
@ -1,95 +0,0 @@
|
|||
{
|
||||
// JSHint Default Configuration File (as on JSHint website)
|
||||
// See http://jshint.com/docs/ for more details
|
||||
|
||||
"maxerr" : 50, // {int} Maximum error before stopping
|
||||
|
||||
// Enforcing
|
||||
"bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
|
||||
"camelcase" : false, // true: Identifiers must be in camelCase
|
||||
"curly" : true, // true: Require {} for every new block or scope
|
||||
"eqeqeq" : true, // true: Require triple equals (===) for comparison
|
||||
"forin" : false, // true: Require filtering for..in loops with obj.hasOwnProperty()
|
||||
"immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
|
||||
"indent" : false, // {int} Number of spaces to use for indentation
|
||||
"latedef" : false, // true: Require variables/functions to be defined before being used
|
||||
"newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()`
|
||||
"noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
|
||||
"noempty" : true, // true: Prohibit use of empty blocks
|
||||
"nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment)
|
||||
"plusplus" : false, // true: Prohibit use of `++` & `--`
|
||||
"quotmark" : false, // Quotation mark consistency:
|
||||
// false : do nothing (default)
|
||||
// true : ensure whatever is used is consistent
|
||||
// "single" : require single quotes
|
||||
// "double" : require double quotes
|
||||
"undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
|
||||
"unused" : true, // true: Require all defined variables be used
|
||||
"strict" : true, // true: Requires all functions run in ES5 Strict Mode
|
||||
"trailing" : false, // true: Prohibit trailing whitespaces
|
||||
"maxparams" : false, // {int} Max number of formal params allowed per function
|
||||
"maxdepth" : false, // {int} Max depth of nested blocks (within functions)
|
||||
"maxstatements" : false, // {int} Max number statements per function
|
||||
"maxcomplexity" : false, // {int} Max cyclomatic complexity per function
|
||||
"maxlen" : false, // {int} Max number of characters per line
|
||||
|
||||
// Relaxing
|
||||
"asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
|
||||
"boss" : true, // true: Tolerate assignments where comparisons would be expected
|
||||
"debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
|
||||
"eqnull" : false, // true: Tolerate use of `== null`
|
||||
"es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
|
||||
"esnext" : true, // true: Allow ES.next (ES6) syntax (ex: `const`)
|
||||
"moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
|
||||
// (ex: `for each`, multiple try/catch, function expression…)
|
||||
"evil" : false, // true: Tolerate use of `eval` and `new Function()`
|
||||
"expr" : true, // true: Tolerate `ExpressionStatement` as Programs
|
||||
"funcscope" : false, // true: Tolerate defining variables inside control statements"
|
||||
"globalstrict" : false, // true: Allow global "use strict" (also enables 'strict')
|
||||
"iterator" : false, // true: Tolerate using the `__iterator__` property
|
||||
"lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
|
||||
"laxbreak" : true, // true: Tolerate possibly unsafe line breakings
|
||||
"laxcomma" : false, // true: Tolerate comma-first style coding
|
||||
"loopfunc" : false, // true: Tolerate functions being defined in loops
|
||||
"multistr" : true, // true: Tolerate multi-line strings
|
||||
"proto" : false, // true: Tolerate using the `__proto__` property
|
||||
"scripturl" : false, // true: Tolerate script-targeted URLs
|
||||
"smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment
|
||||
"shadow" : true, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
|
||||
"sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
|
||||
"supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
|
||||
"validthis" : false, // true: Tolerate using this in a non-constructor function
|
||||
|
||||
// Environments
|
||||
"browser" : true, // Web Browser (window, document, etc)
|
||||
"couch" : false, // CouchDB
|
||||
"devel" : true, // Development/debugging (alert, confirm, etc)
|
||||
"dojo" : false, // Dojo Toolkit
|
||||
"jquery" : false, // jQuery
|
||||
"mootools" : false, // MooTools
|
||||
"node" : true, // Node.js
|
||||
"nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
|
||||
"prototypejs" : false, // Prototype and Scriptaculous
|
||||
"rhino" : false, // Rhino
|
||||
"worker" : false, // Web Workers
|
||||
"wsh" : false, // Windows Scripting Host
|
||||
"yui" : false, // Yahoo User Interface
|
||||
"noyield" : true, // allow generators without a yield
|
||||
|
||||
// Legacy
|
||||
"nomen" : false, // true: Prohibit dangling `_` in variables
|
||||
"onevar" : false, // true: Allow only one `var` statement per function
|
||||
"passfail" : false, // true: Stop on first error
|
||||
"white" : false, // true: Check against strict whitespace and indentation rules
|
||||
|
||||
// Custom Globals
|
||||
"globals" : { // additional predefined global variables
|
||||
// mocha
|
||||
"describe": true,
|
||||
"it": true,
|
||||
"before": true,
|
||||
"afterEach": true,
|
||||
"beforeEach": true,
|
||||
"after": true
|
||||
}
|
||||
}
|
|
@ -53,7 +53,7 @@ Patch locales functions to koa app.
|
|||
- {Application} app: koa app instance.
|
||||
- {Object} options: optional params
|
||||
- {String} functionName: locale function name patch on koa context. Optional, default is `__`.
|
||||
- {String} dir: locales resources store directory. Optional, default is `$PWD/locales`.
|
||||
- {String} dirs: locales resources store directories. Optional, default is `['$PWD/locales']`.
|
||||
- {String} defaultLocale: default locale. Optional, default is `en-US`.
|
||||
- {String} queryField: locale field name on query. Optional, default is `locale`.
|
||||
- {String} cookieField: locale field name on cookie. Optional, default is `locale`.
|
||||
|
@ -63,7 +63,7 @@ Patch locales functions to koa app.
|
|||
locales({
|
||||
app: app,
|
||||
dirs: [__dirname + '/app/locales'],
|
||||
defaultLocale: 'zh-CN'
|
||||
defaultLocale: 'zh-CN',
|
||||
}));
|
||||
```
|
||||
|
||||
|
@ -74,7 +74,7 @@ Get current request locale text.
|
|||
```js
|
||||
function* home() {
|
||||
this.body = {
|
||||
message: this.__('Hello, %s', 'fengmk2')
|
||||
message: this.__('Hello, %s', 'fengmk2'),
|
||||
};
|
||||
}
|
||||
```
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
var Benchmark = require('benchmark');
|
||||
var benchmarks = require('beautify-benchmark');
|
||||
var util = require('util');
|
||||
'use strict';
|
||||
|
||||
var suite = new Benchmark.Suite();
|
||||
const Benchmark = require('benchmark');
|
||||
const benchmarks = require('beautify-benchmark');
|
||||
const util = require('util');
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
|
||||
function normal(text) {
|
||||
if (arguments.length === 2) {
|
||||
|
@ -17,13 +19,13 @@ function normal(text) {
|
|||
}
|
||||
|
||||
function apply() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
const args = Array.prototype.slice.call(arguments);
|
||||
return util.format.apply(util, args);
|
||||
}
|
||||
|
||||
function apply2() {
|
||||
var args = new Array(arguments.length);
|
||||
for (var i = 0, l = arguments.length; i < l; i++) {
|
||||
const args = new Array(arguments.length);
|
||||
for (let i = 0, l = arguments.length; i < l; i++) {
|
||||
args[i] = arguments[i];
|
||||
}
|
||||
return util.format.apply(util, args);
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
var Benchmark = require('benchmark');
|
||||
var benchmarks = require('beautify-benchmark');
|
||||
'use strict';
|
||||
|
||||
var suite = new Benchmark.Suite();
|
||||
const Benchmark = require('benchmark');
|
||||
const benchmarks = require('beautify-benchmark');
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
|
||||
function slice() {
|
||||
return Array.prototype.slice.call(arguments);
|
||||
|
@ -12,8 +14,8 @@ function slice0() {
|
|||
}
|
||||
|
||||
function forLoop() {
|
||||
var args = new Array(arguments.length);
|
||||
for(var i = 0; i < args.length; i++) {
|
||||
const args = new Array(arguments.length);
|
||||
for(let i = 0; i < args.length; i++) {
|
||||
args[i] = arguments[i];
|
||||
}
|
||||
return args;
|
||||
|
@ -31,7 +33,7 @@ suite
|
|||
.add('Array.prototype.slice.call(arguments, 0)', function() {
|
||||
slice0(0, 1, 2, 3, 4, 5, 6, 7);
|
||||
})
|
||||
.add('for(var i = 0; i < args.length; i++) {}', function() {
|
||||
.add('for(let i = 0; i < args.length; i++) {}', function() {
|
||||
forLoop(0, 1, 2, 3, 4, 5, 6, 7);
|
||||
})
|
||||
|
||||
|
@ -58,4 +60,4 @@ suite
|
|||
//
|
||||
// Array.prototype.slice.call(arguments) x 4,537,649 ops/sec ±1.18% (94 runs sampled)
|
||||
// Array.prototype.slice.call(arguments, 0) x 4,605,132 ops/sec ±0.87% (96 runs sampled)
|
||||
// for(var i = 0; i < args.length; i++) {} x 30,435,436 ops/sec ±0.91% (93 runs sampled)
|
||||
// for(let i = 0; i < args.length; i++) {} x 30,435,436 ops/sec ±0.91% (93 runs sampled)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
var Benchmark = require('benchmark');
|
||||
var benchmarks = require('beautify-benchmark');
|
||||
'use strict';
|
||||
|
||||
var suite = new Benchmark.Suite();
|
||||
const Benchmark = require('benchmark');
|
||||
const benchmarks = require('beautify-benchmark');
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
|
||||
function endsWith(str) {
|
||||
return str.endsWith('.properties');
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
'use strict';
|
||||
|
||||
const Benchmark = require('benchmark');
|
||||
const benchmarks = require('beautify-benchmark');
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
|
||||
function isObject(obj) {
|
||||
return Object.prototype.toString.call(obj) === '[object Object]';
|
||||
}
|
||||
|
||||
function flattening(data) {
|
||||
|
||||
const result = {};
|
||||
|
||||
function deepFlat (data, keys) {
|
||||
Object.keys(data).forEach(function(key) {
|
||||
const value = data[key];
|
||||
const k = keys ? key : keys + '.' + key;
|
||||
if (!isObject(value)) {
|
||||
return result[k] = String(value);
|
||||
}
|
||||
deepFlat(value, k);
|
||||
});
|
||||
}
|
||||
|
||||
deepFlat(data, '');
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function flattening_1(data) {
|
||||
|
||||
const result = {};
|
||||
|
||||
function deepFlat (data, keys) {
|
||||
Object.keys(data).forEach(function(key) {
|
||||
const value = data[key];
|
||||
const k = keys.concat(key);
|
||||
if (isObject(value)) {
|
||||
deepFlat(value, k);
|
||||
} else {
|
||||
result[k.join('.')] = String(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
deepFlat(data, []);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function flattening_2(data) {
|
||||
|
||||
const result = {};
|
||||
|
||||
function deepFlat (data, flatKey, key) {
|
||||
const value = data[key];
|
||||
if (isObject(value)) {
|
||||
Object.keys(value).forEach(function(k) {
|
||||
deepFlat(value, flatKey + '.' + k, k);
|
||||
});
|
||||
} else {
|
||||
result[flatKey] = String(value);
|
||||
}
|
||||
}
|
||||
|
||||
Object.keys(data).forEach(function(key) {
|
||||
deepFlat(data, key, key);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
const resource = {
|
||||
'model.user.foo.bar.aa': 'Hello',
|
||||
model: {
|
||||
user: {
|
||||
fields: {
|
||||
name: 'Real Name',
|
||||
age: 'Age',
|
||||
a: {
|
||||
b: {
|
||||
c: {
|
||||
d: {
|
||||
e: {
|
||||
f: 'fff',
|
||||
},
|
||||
},
|
||||
model: {
|
||||
user: {
|
||||
fields: {
|
||||
name: 'Real Name',
|
||||
age: 'Age',
|
||||
a: {
|
||||
b: {
|
||||
c: {
|
||||
d: {
|
||||
e: {
|
||||
f: 'fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
post: {
|
||||
fields: {
|
||||
title: 'Subject',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
model: {
|
||||
user: {
|
||||
fields: {
|
||||
name: 'Real Name',
|
||||
age: 'Age',
|
||||
a: {
|
||||
b: {
|
||||
c: {
|
||||
d: {
|
||||
e: {
|
||||
f: 'fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
post: {
|
||||
fields: {
|
||||
title: 'Subject',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
post: {
|
||||
fields: {
|
||||
title: 'Subject',
|
||||
},
|
||||
},
|
||||
model: {
|
||||
user: {
|
||||
fields: {
|
||||
name: 'Real Name',
|
||||
age: 'Age',
|
||||
a: {
|
||||
b: {
|
||||
c: {
|
||||
d: {
|
||||
e: {
|
||||
f: 'fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
post: {
|
||||
fields: {
|
||||
title: 'Subject',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
//console.log('flattening:', flattening(resource));
|
||||
//console.log('flattening_1:', flattening_1(resource));
|
||||
//console.log('flattening_2:', flattening_2(resource));
|
||||
|
||||
suite
|
||||
|
||||
.add('flattening', function() {
|
||||
flattening(resource);
|
||||
})
|
||||
.add('flattening_1', function() {
|
||||
flattening_1(resource);
|
||||
})
|
||||
.add('flattening_2', function() {
|
||||
flattening_2(resource);
|
||||
})
|
||||
.on('cycle', function(event) {
|
||||
benchmarks.add(event.target);
|
||||
})
|
||||
.on('complete', function done() {
|
||||
benchmarks.log();
|
||||
})
|
||||
.run({ async: false });
|
||||
|
||||
//$ node benchmark/flattening.js
|
||||
//
|
||||
// 3 tests completed.
|
||||
//
|
||||
// flattening x 32,863 ops/sec ±0.83% (98 runs sampled)
|
||||
// flattening_1 x 10,434 ops/sec ±0.73% (96 runs sampled)
|
||||
// flattening_2 x 21,734 ops/sec ±1.04% (95 runs sampled)
|
|
@ -1,17 +1,19 @@
|
|||
var Benchmark = require('benchmark');
|
||||
var benchmarks = require('beautify-benchmark');
|
||||
'use strict';
|
||||
|
||||
var suite = new Benchmark.Suite();
|
||||
const Benchmark = require('benchmark');
|
||||
const benchmarks = require('beautify-benchmark');
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
|
||||
function getNestedValue(data, key) {
|
||||
var keys = key.split('.');
|
||||
for (var i = 0; typeof data === 'object' && i < keys.length; i++) {
|
||||
const keys = key.split('.');
|
||||
for (let i = 0; typeof data === 'object' && i < keys.length; i++) {
|
||||
data = data[keys[i]];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
var resource = {
|
||||
const resource = {
|
||||
'model.user.foo.bar.aa': 'Hello',
|
||||
model: {
|
||||
user: {
|
||||
|
@ -23,8 +25,8 @@ var resource = {
|
|||
c: {
|
||||
d: {
|
||||
e: {
|
||||
f: "fff"
|
||||
}
|
||||
f: 'fff',
|
||||
},
|
||||
},
|
||||
model: {
|
||||
user: {
|
||||
|
@ -36,23 +38,23 @@ var resource = {
|
|||
c: {
|
||||
d: {
|
||||
e: {
|
||||
f: "fff"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
f: 'fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
post: {
|
||||
fields: {
|
||||
title: 'Subject'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
title: 'Subject',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
model: {
|
||||
user: {
|
||||
|
@ -64,25 +66,25 @@ var resource = {
|
|||
c: {
|
||||
d: {
|
||||
e: {
|
||||
f: "fff"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
f: 'fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
post: {
|
||||
fields: {
|
||||
title: 'Subject'
|
||||
}
|
||||
}
|
||||
}
|
||||
title: 'Subject',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
post: {
|
||||
fields: {
|
||||
title: 'Subject'
|
||||
}
|
||||
title: 'Subject',
|
||||
},
|
||||
},
|
||||
model: {
|
||||
user: {
|
||||
|
@ -94,24 +96,24 @@ var resource = {
|
|||
c: {
|
||||
d: {
|
||||
e: {
|
||||
f: "fff"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
f: 'fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
post: {
|
||||
fields: {
|
||||
title: 'Subject'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
title: 'Subject',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
var fullKey = 'model.user.fields.a.b.c.d.e.f';
|
||||
const fullKey = 'model.user.fields.a.b.c.d.e.f';
|
||||
|
||||
console.log('Deeps: ', fullKey.split('.').length);
|
||||
|
||||
|
|
147
index.js
147
index.js
|
@ -14,43 +14,56 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var debug = require('debug')('koa-locales');
|
||||
var ini = require('ini');
|
||||
var util = require('util');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var ms = require('humanize-ms');
|
||||
var merge = require('merge-descriptors');
|
||||
const debug = require('debug')('koa-locales');
|
||||
const ini = require('ini');
|
||||
const util = require('util');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const ms = require('humanize-ms');
|
||||
const assign = require('object-assign');
|
||||
|
||||
const DEFAULT_OPTIONS = {
|
||||
defaultLocale: 'en-US',
|
||||
queryField: 'locale',
|
||||
cookieField: 'locale',
|
||||
cookieMaxAge: '1y',
|
||||
dir: undefined,
|
||||
dirs: [path.join(process.cwd(), 'locales')],
|
||||
functionName: '__',
|
||||
};
|
||||
|
||||
module.exports = function (app, options) {
|
||||
options = options || {};
|
||||
var defaultLocale = formatLocale(options.defaultLocale || 'en-US');
|
||||
var queryField = options.queryField || 'locale';
|
||||
var cookieField = options.cookieField || 'locale';
|
||||
var cookieMaxAge = ms(options.cookieMaxAge || '1y');
|
||||
var localeDir = options.dir;
|
||||
var localeDirs = options.dirs || [path.join(process.cwd(), 'locales')];
|
||||
var functionName = options.functionName || '__';
|
||||
var resources = {};
|
||||
options = assign({}, DEFAULT_OPTIONS, options);
|
||||
const defaultLocale = formatLocale(options.defaultLocale);
|
||||
const queryField = options.queryField;
|
||||
const cookieField = options.cookieField;
|
||||
const cookieMaxAge = ms(options.cookieMaxAge);
|
||||
const localeDir = options.dir;
|
||||
const localeDirs = options.dirs;
|
||||
const functionName = options.functionName;
|
||||
const resources = {};
|
||||
|
||||
/**
|
||||
* @Deprecated Use options.dirs instead.
|
||||
*/
|
||||
if (localeDir && localeDirs.indexOf(localeDir) === -1) {
|
||||
localeDirs.push(localeDir);
|
||||
}
|
||||
|
||||
for (var i = 0; i < localeDirs.length; i ++) {
|
||||
var dir = localeDirs[i];
|
||||
for (let i = 0; i < localeDirs.length; i++) {
|
||||
const dir = localeDirs[i];
|
||||
|
||||
if (!fs.existsSync(dir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var names = fs.readdirSync(dir);
|
||||
for (var j = 0; j < names.length; j++) {
|
||||
var name = names[j];
|
||||
var filepath = path.join(dir, name);
|
||||
const names = fs.readdirSync(dir);
|
||||
for (let j = 0; j < names.length; j++) {
|
||||
const name = names[j];
|
||||
const filepath = path.join(dir, name);
|
||||
// support en_US.js => en-US.js
|
||||
var locale = formatLocale(name.split('.')[0]);
|
||||
var resource = {};
|
||||
const locale = formatLocale(name.split('.')[0]);
|
||||
let resource = {};
|
||||
|
||||
if (name.endsWith('.js') || name.endsWith('.json')) {
|
||||
resource = flattening(require(filepath));
|
||||
|
@ -59,46 +72,22 @@ module.exports = function (app, options) {
|
|||
}
|
||||
|
||||
resources[locale] = resources[locale] || {};
|
||||
merge(resources[locale], resource);
|
||||
assign(resources[locale], resource);
|
||||
}
|
||||
}
|
||||
|
||||
debug('init locales with %j, got %j resources', options, Object.keys(resources));
|
||||
|
||||
var ARRAY_INDEX_RE = /\{(\d+)\}/g;
|
||||
function formatWithArray(text, values) {
|
||||
return text.replace(ARRAY_INDEX_RE, function (orignal, matched) {
|
||||
var index = parseInt(matched);
|
||||
if (index < values.length) {
|
||||
return values[index];
|
||||
}
|
||||
// not match index, return orignal text
|
||||
return orignal;
|
||||
});
|
||||
}
|
||||
|
||||
var Object_INDEX_RE = /\{(.+?)\}/g;
|
||||
function formatWithObject(text, values) {
|
||||
return text.replace(Object_INDEX_RE, function (orignal, matched) {
|
||||
var value = values[matched];
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
// not match index, return orignal text
|
||||
return orignal;
|
||||
});
|
||||
}
|
||||
|
||||
app.context[functionName] = function (key, value) {
|
||||
if (arguments.length === 0) {
|
||||
// __()
|
||||
return '';
|
||||
}
|
||||
|
||||
var locale = this.__getLocale();
|
||||
var resource = resources[locale] || {};
|
||||
const locale = this.__getLocale();
|
||||
const resource = resources[locale] || {};
|
||||
|
||||
var text = resource[key] || key;
|
||||
const text = resource[key] || key;
|
||||
debug('%s: %j => %j', locale, key, text);
|
||||
if (!text) {
|
||||
return '';
|
||||
|
@ -130,9 +119,9 @@ module.exports = function (app, options) {
|
|||
}
|
||||
|
||||
// __(key, value1, ...)
|
||||
var args = new Array(arguments.length);
|
||||
const args = new Array(arguments.length);
|
||||
args[0] = text;
|
||||
for(var i = 1; i < args.length; i++) {
|
||||
for(let i = 1; i < args.length; i++) {
|
||||
args[i] = arguments[i];
|
||||
}
|
||||
return util.format.apply(util, args);
|
||||
|
@ -146,20 +135,20 @@ module.exports = function (app, options) {
|
|||
return this.__locale;
|
||||
}
|
||||
|
||||
var cookieLocale = this.cookies.get(cookieField);
|
||||
var locale = this.query[queryField] || cookieLocale;
|
||||
const cookieLocale = this.cookies.get(cookieField);
|
||||
let locale = this.query[queryField] || cookieLocale;
|
||||
if (!locale) {
|
||||
// Accept-Language: zh-CN,zh;q=0.5
|
||||
// Accept-Language: zh-CN
|
||||
var languages = this.acceptsLanguages();
|
||||
let languages = this.acceptsLanguages();
|
||||
if (languages) {
|
||||
if (Array.isArray(languages)) {
|
||||
if (languages[0] === '*') {
|
||||
languages = languages.slice(1);
|
||||
}
|
||||
if (languages.length > 0) {
|
||||
for (var i = 0; i < languages.length; i++) {
|
||||
var lang = formatLocale(languages[i]);
|
||||
for (let i = 0; i < languages.length; i++) {
|
||||
const lang = formatLocale(languages[i]);
|
||||
if (resources[lang]) {
|
||||
locale = lang;
|
||||
break;
|
||||
|
@ -199,25 +188,49 @@ module.exports = function (app, options) {
|
|||
this.__locale = locale;
|
||||
return locale;
|
||||
};
|
||||
|
||||
function formatLocale(locale) {
|
||||
// support zh_CN, en_US => zh-CN, en-US
|
||||
return locale.replace('_', '-').toLowerCase();
|
||||
}
|
||||
};
|
||||
|
||||
function isObject(obj) {
|
||||
return Object.prototype.toString.call(obj) === '[object Object]';
|
||||
}
|
||||
|
||||
const ARRAY_INDEX_RE = /\{(\d+)\}/g;
|
||||
function formatWithArray(text, values) {
|
||||
return text.replace(ARRAY_INDEX_RE, function (orignal, matched) {
|
||||
const index = parseInt(matched);
|
||||
if (index < values.length) {
|
||||
return values[index];
|
||||
}
|
||||
// not match index, return orignal text
|
||||
return orignal;
|
||||
});
|
||||
}
|
||||
|
||||
const Object_INDEX_RE = /\{(.+?)\}/g;
|
||||
function formatWithObject(text, values) {
|
||||
return text.replace(Object_INDEX_RE, function (orignal, matched) {
|
||||
const value = values[matched];
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
// not match index, return orignal text
|
||||
return orignal;
|
||||
});
|
||||
}
|
||||
|
||||
function formatLocale(locale) {
|
||||
// support zh_CN, en_US => zh-CN, en-US
|
||||
return locale.replace('_', '-').toLowerCase();
|
||||
}
|
||||
|
||||
function flattening(data) {
|
||||
|
||||
var result = {};
|
||||
const result = {};
|
||||
|
||||
function deepFlat (data, keys) {
|
||||
Object.keys(data).forEach(function(key) {
|
||||
var value = data[key];
|
||||
var k = keys ? keys + '.' + key : key;
|
||||
const value = data[key];
|
||||
const k = keys ? keys + '.' + key : key;
|
||||
if (isObject(value)) {
|
||||
deepFlat(value, k);
|
||||
} else {
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
"index.js"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "mocha --harmony --check-leaks -R spec -t 5000 test/*.test.js",
|
||||
"test": "eslint . && mocha --harmony --check-leaks -R spec -t 5000 test/*.test.js",
|
||||
"test-cov": "node --harmony node_modules/.bin/istanbul cover node_modules/.bin/_mocha -- --check-leaks -t 5000 test/*.test.js",
|
||||
"jshint": "jshint .",
|
||||
"lint": "eslint .",
|
||||
"autod": "autod -w --prefix '~'",
|
||||
"cnpm": "npm install --registry=https://registry.npm.taobao.org",
|
||||
"contributors": "contributors -f plain -o AUTHORS"
|
||||
|
@ -18,15 +18,15 @@
|
|||
"debug": "~2.2.0",
|
||||
"humanize-ms": "~1.0.1",
|
||||
"ini": "~1.3.4",
|
||||
"merge-descriptors": "~1.0.0"
|
||||
"object-assign": "~4.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autod": "*",
|
||||
"beautify-benchmark": "0",
|
||||
"benchmark": "1",
|
||||
"contributors": "*",
|
||||
"eslint": "~1.5.0",
|
||||
"istanbul-harmony": "*",
|
||||
"jshint": "*",
|
||||
"koa": "1",
|
||||
"mm": "1",
|
||||
"mocha": "*",
|
||||
|
|
|
@ -14,19 +14,19 @@
|
|||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var assert = require('assert');
|
||||
var koa = require('koa');
|
||||
var request = require('supertest');
|
||||
var pedding = require('pedding');
|
||||
var mm = require('mm');
|
||||
var locales = require('../');
|
||||
const assert = require('assert');
|
||||
const koa = require('koa');
|
||||
const request = require('supertest');
|
||||
const pedding = require('pedding');
|
||||
const mm = require('mm');
|
||||
const locales = require('../');
|
||||
|
||||
describe('koa-locales.test.js', function () {
|
||||
|
||||
afterEach(mm.restore);
|
||||
|
||||
describe('default options', function () {
|
||||
var app = createApp();
|
||||
const app = createApp();
|
||||
|
||||
it('should use default locale: en-US', function (done) {
|
||||
request(app.callback())
|
||||
|
@ -45,8 +45,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "model.user.fields.gender",
|
||||
"name": "model.user.fields.name"
|
||||
'gender': 'model.user.fields.gender',
|
||||
'name': 'model.user.fields.name',
|
||||
})
|
||||
.expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/)
|
||||
.expect(200, done);
|
||||
|
@ -54,8 +54,8 @@ describe('koa-locales.test.js', function () {
|
|||
});
|
||||
|
||||
describe('custom options', function () {
|
||||
var app = createApp({
|
||||
dirs: [__dirname + '/locales', __dirname + '/other-locales']
|
||||
const app = createApp({
|
||||
dirs: [__dirname + '/locales', __dirname + '/other-locales'],
|
||||
});
|
||||
|
||||
it('should use default locale: en-US', function (done) {
|
||||
|
@ -75,8 +75,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "model.user.fields.gender",
|
||||
"name": "model.user.fields.name"
|
||||
'gender': 'model.user.fields.gender',
|
||||
'name': 'model.user.fields.name',
|
||||
})
|
||||
.expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/)
|
||||
.expect(200, done);
|
||||
|
@ -100,8 +100,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "性别",
|
||||
"name": "姓名"
|
||||
'gender': '性别',
|
||||
'name': '姓名',
|
||||
})
|
||||
.expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/)
|
||||
.expect(200, done);
|
||||
|
@ -124,8 +124,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "model.user.fields.gender",
|
||||
"name": "model.user.fields.name"
|
||||
'gender': 'model.user.fields.gender',
|
||||
'name': 'model.user.fields.name',
|
||||
})
|
||||
.expect('Set-Cookie', /^locale=de; path=\/; expires=\w+/)
|
||||
.expect(200, done);
|
||||
|
@ -149,8 +149,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "性别",
|
||||
"name": "姓名"
|
||||
'gender': '性别',
|
||||
'name': '姓名',
|
||||
})
|
||||
.expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/)
|
||||
.expect(200, done);
|
||||
|
@ -173,8 +173,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "model.user.fields.gender",
|
||||
"name": "model.user.fields.name"
|
||||
'gender': 'model.user.fields.gender',
|
||||
'name': 'model.user.fields.name',
|
||||
})
|
||||
.expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/)
|
||||
.expect(200, done);
|
||||
|
@ -200,8 +200,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "性别",
|
||||
"name": "姓名"
|
||||
'gender': '性别',
|
||||
'name': '姓名',
|
||||
})
|
||||
.expect(function (res) {
|
||||
assert(!res.headers['set-cookie']);
|
||||
|
@ -231,8 +231,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "性别",
|
||||
"name": "姓名"
|
||||
'gender': '性别',
|
||||
'name': '姓名',
|
||||
})
|
||||
.expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/)
|
||||
.expect(200, done);
|
||||
|
@ -254,8 +254,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "性别",
|
||||
"name": "姓名"
|
||||
'gender': '性别',
|
||||
'name': '姓名',
|
||||
})
|
||||
.expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/)
|
||||
.expect(200, done);
|
||||
|
@ -277,8 +277,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "性别",
|
||||
"name": "姓名"
|
||||
'gender': '性别',
|
||||
'name': '姓名',
|
||||
})
|
||||
.expect('Set-Cookie', /^locale=zh\-cn; path=\/; expires=\w+/)
|
||||
.expect(200, done);
|
||||
|
@ -302,8 +302,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "model.user.fields.gender",
|
||||
"name": "model.user.fields.name"
|
||||
'gender': 'model.user.fields.gender',
|
||||
'name': 'model.user.fields.name',
|
||||
})
|
||||
.expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/)
|
||||
.expect(200, done);
|
||||
|
@ -327,8 +327,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "model.user.fields.gender",
|
||||
"name": "model.user.fields.name"
|
||||
'gender': 'model.user.fields.gender',
|
||||
'name': 'model.user.fields.name',
|
||||
})
|
||||
.expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/)
|
||||
.expect(200, done);
|
||||
|
@ -354,8 +354,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "性別",
|
||||
"name": "姓名"
|
||||
'gender': '性別',
|
||||
'name': '姓名',
|
||||
})
|
||||
.expect('Set-Cookie', /^locale=zh\-tw; path=\/; expires=\w+/)
|
||||
.expect(200, done);
|
||||
|
@ -381,8 +381,8 @@ describe('koa-locales.test.js', function () {
|
|||
arguments6: '1 2 3 4 5. 6',
|
||||
values: 'foo bar foo bar {2} {100}',
|
||||
object: 'foo bar foo bar {z}',
|
||||
"gender": "model.user.fields.gender",
|
||||
"name": "model.user.fields.name"
|
||||
'gender': 'model.user.fields.gender',
|
||||
'name': 'model.user.fields.name',
|
||||
})
|
||||
.expect('Set-Cookie', /^locale=en\-us; path=\/; expires=\w+/)
|
||||
.expect(200, done);
|
||||
|
@ -392,9 +392,9 @@ describe('koa-locales.test.js', function () {
|
|||
});
|
||||
|
||||
function createApp(options) {
|
||||
var app = koa();
|
||||
const app = koa();
|
||||
locales(app, options);
|
||||
var fname = options && options.functionName || '__';
|
||||
const fname = options && options.functionName || '__';
|
||||
|
||||
app.use(function* () {
|
||||
this.body = {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
Email: '邮箱',
|
||||
'Hello %s, how are you today?': '%s,今天过得如何?',
|
||||
|
@ -5,8 +7,8 @@ module.exports = {
|
|||
user: {
|
||||
fields: {
|
||||
name: '姓名',
|
||||
gender: '性别'
|
||||
}
|
||||
}
|
||||
}
|
||||
gender: '性别',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
Email: '邮箱1'
|
||||
}
|
||||
Email: '邮箱1',
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue