├── .eslintrc.js
├── .github
├── FUNDING.yml
├── dependabot.yml
└── workflows
│ ├── build.yml
│ └── publish.yml
├── .gitignore
├── .gitmodules
├── .npmrc
├── .prettierignore
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── karma.conf.js
├── localize
├── .eslintrc.yml
├── README.md
├── index.d.jst
├── index.jst
├── localize.d.jst
├── localize.jst
└── types.d.ts
├── messages
├── index.js
└── jtd.js
├── package.json
├── scripts
├── .eslintrc.yml
├── compile-locales.js
└── prepare-tests
└── spec
├── .eslintrc.yml
├── localize-jtd.spec.js
├── localize.spec.js
└── style.spec.js
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | const jsConfig = require("@ajv-validator/config/.eslintrc_js")
2 |
3 | module.exports = {
4 | env: {
5 | es6: true,
6 | node: true,
7 | },
8 | overrides: [
9 | {
10 | ...jsConfig,
11 | rules: {
12 | semi: [2, "never"],
13 | },
14 | },
15 | ],
16 | }
17 |
18 | // extends: eslint:recommended
19 | // env:
20 | // node: true
21 | // browser: true
22 | // parserOptions:
23 | // ecmaVersion: 2018
24 | // rules:
25 | // block-scoped-var: 2
26 | // callback-return: 2
27 | // curly: [2, multi-or-nest, consistent]
28 | // dot-location: [2, property]
29 | // dot-notation: 2
30 | // indent-legacy: [2, 2, SwitchCase: 1]
31 | // linebreak-style: [2, unix]
32 | // new-cap: 2
33 | // no-console: [2, allow: [warn, error]]
34 | // no-else-return: 2
35 | // no-eq-null: 2
36 | // no-fallthrough: 2
37 | // no-invalid-this: 2
38 | // no-return-assign: 2
39 | // no-shadow: 1
40 | // no-trailing-spaces: 2
41 | // no-use-before-define: [2, nofunc]
42 | // quotes: [2, single, avoid-escape]
43 | // semi: [2, always]
44 | // strict: [2, global]
45 | // valid-jsdoc: [2, requireReturn: false]
46 | // no-control-regex: 0
47 | // no-useless-escape: 2
48 | // no-tabs: 2
49 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: epoberezkin
2 | tidelift: "npm/ajv-i18n"
3 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | open-pull-requests-limit: 10
8 | ignore:
9 | - dependency-name: karma
10 | versions:
11 | - 6.0.3
12 | - 6.0.4
13 | - 6.1.0
14 | - 6.1.1
15 | - 6.1.2
16 | - 6.2.0
17 | - 6.3.0
18 | - 6.3.1
19 | - dependency-name: ajv
20 | versions:
21 | - 7.0.3
22 | - 7.0.4
23 | - 7.1.0
24 | - 7.1.1
25 | - 7.2.1
26 | - 7.2.3
27 | - dependency-name: browserify
28 | versions:
29 | - 17.0.0
30 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: build
2 |
3 | on:
4 | push:
5 | branches: [master]
6 | pull_request:
7 | branches: ["*"]
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 |
13 | strategy:
14 | matrix:
15 | node-version: [10.x, 12.x, 14.x]
16 |
17 | steps:
18 | - uses: actions/checkout@v2
19 | - name: Use Node.js ${{ matrix.node-version }}
20 | uses: actions/setup-node@v1
21 | with:
22 | node-version: ${{ matrix.node-version }}
23 | - run: npm install
24 | - run: git submodule update --init
25 | - run: npm test
26 | - name: Coveralls
27 | uses: coverallsapp/github-action@master
28 | with:
29 | github-token: ${{ secrets.GITHUB_TOKEN }}
30 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: publish
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | jobs:
8 | publish-npm:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v2
12 | - uses: actions/setup-node@v1
13 | with:
14 | node-version: 14
15 | registry-url: https://registry.npmjs.org/
16 | - run: npm install
17 | - run: git submodule update --init
18 | - run: npm test
19 | - name: Publish beta version to npm
20 | if: "github.event.release.prerelease"
21 | run: npm publish --tag beta
22 | env:
23 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
24 | - name: Publish to npm
25 | if: "!github.event.release.prerelease"
26 | run: npm publish
27 | env:
28 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 | .nyc_output
16 |
17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18 | .grunt
19 |
20 | # node-waf configuration
21 | .lock-wscript
22 |
23 | # Compiled binary addons (http://nodejs.org/api/addons.html)
24 | build/Release
25 |
26 | # Dependency directory
27 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
28 | node_modules
29 |
30 | .DS_Store
31 |
32 | # Compiled templates
33 | localize/**/*.js
34 | localize/**/*.d.ts
35 | !localize/types.d.ts
36 |
37 | # Browserified tests
38 | .browser
39 |
40 | # bundles
41 | dist/
42 |
43 | # IDE files
44 | .idea
45 |
46 | package-lock.json
47 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "spec/JSON-Schema-Test-Suite"]
2 | path = spec/JSON-Schema-Test-Suite
3 | url = https://github.com/json-schema/JSON-Schema-Test-Suite.git
4 | [submodule "spec/json-typedef-spec"]
5 | path = spec/json-typedef-spec
6 | url = https://github.com/jsontypedef/json-typedef-spec.git
7 | [submodule "spec/ajv-keywords"]
8 | path = spec/ajv-keywords
9 | url = https://github.com/ajv-validator/ajv-keywords.git
10 | [submodule "spec/ajv-formats"]
11 | path = spec/ajv-formats
12 | url = https://github.com/ajv-validator/ajv-formats
13 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | package-lock=false
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | spec/JSON-Schema-Test-Suite
2 | spec/json-typedef-spec
3 | spec/ajv-keywords
4 | spec/ajv-formats
5 | .browser
6 | coverage
7 | bundle
8 | .nyc_output
9 | localize
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at ajv.validator@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Evgeny Poberezkin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ajv-i18n
2 |
3 | Internationalised error messages for [Ajv](https://github.com/ajv-validator/ajv) - superfast JSON validator for JSON Schema and JSON Type Definition.
4 |
5 | [](https://travis-ci.org/ajv-validator/ajv-i18n)
6 | [](https://www.npmjs.com/package/ajv-i18n)
7 | [](https://coveralls.io/github/ajv-validator/ajv-i18n?branch=master)
8 | [](https://gitter.im/ajv-validator/ajv)
9 |
10 | ## Supported locales
11 |
12 | |locale|language |contributor|draft-04|draft-061|draft-072|draft
2019-093
/2020-124|JTD5
13 | |------|:-------:|:---------:|:------:|:------:|:------:|:------:|:------:|
14 | |🇬🇧 en|English | |✓|✓|✓|✓|✓|
15 | |AR ar|Arabic |[Mahmoud-Mardeni](https://github.com/Mahmoud-Mardeni)|✓|✓|✓|-|-|
16 | |CA ca|Catalan |[alexandreec](https://github.com/alexandreec)|✓|✓|✓|-|*|
17 | |🇨🇿 cs|Czech |[kiskovacs](https://github.com/kiskovacs)
[NAM0007](https://github.com/NAM0007)|✓
|✓
|
✓|-|*|
18 | |🇩🇪 de|German |[jmtoball](https://github.com/jmtoball)
[gflohr](https://github.com/gflohr)|✓
|✓
|
✓|✓
|✓
|
19 | |🇪🇸 es|Spanish |[jpablom](https://github.com/jpablom)|✓|✓|✓|-|*|
20 | |🇫🇮 fi|Finnish |[saulipurhonen](https://github.com/saulipurhonen)|✓|✓|✓|✓|✓|
21 | |🇫🇷 fr|French |[monlouisj](https://github.com/monlouisj)
[Telokis](https://github.com/Telokis)|✓
|✓
|
✓|-|*|
22 | |🇭🇺 hu|Hungarian|[szilveszter9](https://github.com/szilveszter9)|✓|-|-|-|*|
23 | |🇮🇩 id|Indonesian|[ekoeryanto](https://github.com/ekoeryanto)|✓|✓|✓|-|*|
24 | |🇮🇹 it|Italian |[jasoniangreen](https://github.com/jasoniangreen)
[lucacorti](https://github.com/lucacorti)|✓
|
✓|
✓|
✓|
✓|
25 | |🇯🇵 ja|Japanese |[gilgongo](https://github.com/gilgongo)|✓|-|-|-|*|
26 | |🇰🇷 ko|Korean |[MinByeongDon](https://github.com/MinByeongDon)|✓|✓|✓|✓|✓|
27 | |🇳🇴 nb|Norwegian bokmål|[mtramm](https://github.com/mtramm)|✓|✓|-|-|*|
28 | |🇳🇱 nl|Dutch |[pimlie](https://github.com/pimlie)
[niekvb](https://github.com/niekvb)|✓|✓|✓|
✓|
✓|
29 | |🇵🇱 pl|Polish |[danielzurawski](https://github.com/danielzurawski)|✓|-|-|-|*|
30 | |🇧🇷 pt-BR|Português - Brasil|[marcosrava](https://github.com/marcosrava)
[ggondim](https://github.com/ggondim)|✓|✓|✓|
✓|
✓|
31 | |🇷🇺 ru|Russian | |✓|✓|✓|✓|✓|
32 | |🇸🇰 sk|Slovak |[kiskovacs](https://github.com/kiskovacs)|✓|✓|-|-|*|
33 | |🇸🇪 sv|Swedish |[limmen](https://github.com/Limmen)|✓|✓|-|-|*|
34 | |🇹🇭 th|Thai |[encX](https://github.com/encX)|✓|✓|✓|✓|✓|
35 | |🇨🇳 zh|Chinese |[jinzhubaofu](https://github.com/jinzhubaofu)
[leuction](https://github.com/leuction)|✓
|
✓|
✓|
✓|
✓|
36 | |🇹🇼 zh-TW|Chinese - Taiwan|[minipai](https://github.com/minipai)|✓|✓|✓|✓|✓|
37 |
38 |
39 | 1 added boolean schema, keywords `const`, `contains`, `propertyNames`
40 |
41 | 2 added keywords `if`/`then`/`else`
42 |
43 | 3 added messages for keywords `unevaluatedProperties`, `unevaluatedItems`, `dependentRequired`
44 |
45 | 4 keyword `items` messages
46 |
47 | 5 JSON Type Definition
48 |
49 | \* `discriminator` form messages are not translated
50 |
51 | Please contribute locales that you need to use if they are missing or incomplete.
52 |
53 | ## Install
54 |
55 | Using npm:
56 |
57 | ```
58 | npm install ajv-i18n
59 | ```
60 |
61 | ## Usage
62 |
63 | In node:
64 |
65 | ```javascript
66 | const Ajv = require("ajv") // version >= 8.0.0
67 | const localize = require("ajv-i18n")
68 | // or for JSON Type Definition
69 | // const localize = require("ajv-i18n/localize/jtd")
70 |
71 | const ajv = Ajv({allErrors: true, messages: false})
72 | const validate = ajv.compile(schema)
73 | const valid = validate(data)
74 |
75 | if (!valid) {
76 | // ru for Russian
77 | localize.ru(validate.errors)
78 | // string with all errors and data paths
79 | console.log(ajv.errorsText(validate.errors, {separator: '\n'}))
80 | }
81 | ```
82 |
83 | To require only necessary locales (e.g., with browserify):
84 |
85 | ```javascript
86 | const localize_ru = require('ajv-i18n/localize/ru')
87 | // or for JSON Type Definition
88 | // const localize_ru = require('ajv-i18n/localize/ru/jtd')
89 | ```
90 |
91 | or
92 |
93 | ```javascript
94 | const localize = {
95 | en: require('ajv-i18n/localize/en'),
96 | ru: require('ajv-i18n/localize/ru'),
97 | }
98 | ```
99 |
100 | See [Ajv docs](https://github.com/ajv-validator/ajv) for more information.
101 |
102 | ## Tests
103 |
104 | ```
105 | npm install
106 | git submodule update --init
107 | npm test
108 | ```
109 |
110 | ## Contributing
111 |
112 | Functions that localize error messages are generated using doT template [localize.jst](https://github.com/ajv-validator/ajv-i18n/tree/master/localize/localize.jst), [JSON Schema messages](https://github.com/ajv-validator/ajv-i18n/tree/master/messages/index.js) and [JSON Type Definition messages](https://github.com/ajv-validator/ajv-i18n/tree/master/messages/jtd.js). Templates are pre-compiled, so doT is not a run-time dependency.
113 |
114 | `npm run build` - compiles functions to [localize](https://github.com/ajv-validator/ajv/tree/master/localize) folder.
115 |
116 | ## Contributors of locales
117 |
118 | [](https://github.com/danielzurawski "danielzurawski")
119 | [](https://github.com/szilveszter9 "szilveszter9")
120 | [](https://github.com/jmtoball "jmtoball")
121 | [](https://github.com/gilgongo "gilgongo")
122 | [](https://github.com/jasoniangreen "jasoniangreen")
123 | [](https://github.com/jpablom "jpablom")
124 | [](https://github.com/Limmen "Limmen")
125 | [](https://github.com/jinzhubaofu "jinzhubaofu")
126 | [](https://github.com/kiskovacs "kiskovacs")
127 | [](https://github.com/Mahmoud-Mardeni "mahmoud-mardeni")
128 | [](https://github.com/monlouisj "monlouisj")
129 | [](https://github.com/marcosrava "marcosrava")
130 | [](https://github.com/mtramm "mtramm")
131 | [](https://github.com/Mahmoud-Mardeni "Mahmoud-Mardeni")
132 | [](https://github.com/leuction "leuction")
133 | [](https://github.com/lucacorti "lucacorti")
134 | [](https://github.com/minipai "minipai")
135 | [](https://github.com/encX "encX")
136 | [
](https://github.com/pimlie "pimlie")
137 | [](https://github.com/MinByeongDon "MinByeongDon")
138 | [](https://github.com/gflohr "gflohr")
139 | [](https://github.com/ekoeryanto "ekoeryanto")
140 | [](https://github.com/Telokis "Telokis")
141 | [
](https://github.com/alexandreec "alexandreec")
142 | [](https://github.com/ggondim "ggondim")
143 | [](https://github.com/niekvb "niekvb")
144 | [](https://github.com/NAM0007 "NAM0007")
145 | [](https://github.com/saulipurhonen "saulipurhonen")
146 |
147 | ## Enterprise support
148 |
149 | ajv-i18n package is a part of [Tidelift enterprise subscription](https://tidelift.com/subscription/pkg/npm-ajv-i18n?utm_source=npm-ajv-i18n&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) - it provides a centralised commercial support to open-source software users, in addition to the support provided by software maintainers.
150 |
151 | ## Security contact
152 |
153 | To report a security vulnerability, please use the
154 | [Tidelift security contact](https://tidelift.com/security).
155 | Tidelift will coordinate the fix and disclosure. Please do NOT report security vulnerability via GitHub issues.
156 |
157 | ## License
158 |
159 | [MIT](https://github.com/ajv-validator/ajv-i18n/blob/master/LICENSE)
160 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | // Generated on Fri Feb 26 2016 16:59:16 GMT+0900 (JST)
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | // base path that will be used to resolve all patterns (eg. files, exclude)
7 | basePath: "",
8 |
9 | // frameworks to use
10 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
11 | frameworks: ["mocha"],
12 |
13 | // list of files / patterns to load in the browser
14 | files: ["dist/ajv-i18n.test.min.js", ".browser/*.spec.js"],
15 |
16 | // test results reporter to use
17 | // possible values: 'dots', 'progress'
18 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
19 | reporters: ["dots"],
20 |
21 | // web server port
22 | port: 9876,
23 |
24 | // enable / disable colors in the output (reporters and logs)
25 | colors: true,
26 |
27 | // level of logging
28 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
29 | logLevel: config.LOG_INFO,
30 |
31 | // enable / disable watching file and executing tests whenever any file changes
32 | autoWatch: false,
33 |
34 | // start these browsers
35 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
36 | browsers: ["Chrome"],
37 |
38 | // Continuous Integration mode
39 | // if true, Karma captures browsers, runs the tests and exits
40 | singleRun: true,
41 |
42 | browserNoActivityTimeout: 90000,
43 | })
44 | }
45 |
--------------------------------------------------------------------------------
/localize/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | rules:
2 | no-redeclare: 0
--------------------------------------------------------------------------------
/localize/README.md:
--------------------------------------------------------------------------------
1 | This folder contains compiled localization functions.
2 |
3 | Do not edit `*.js` files directly, edit JSON Schema messages in [messages/index.js](https://github.com/epoberezkin/ajv-i18n/tree/master/messages/index.js) and JSON Type Definition messages in [messages/jtd.js](https://github.com/epoberezkin/ajv-i18n/tree/master/messages/jtd.js).
4 |
5 | If this folder doesn't have any locale sub-folders, run `npm run build`.
6 |
--------------------------------------------------------------------------------
/localize/index.d.jst:
--------------------------------------------------------------------------------
1 | import {Localize} from "./types";
2 |
3 | type Language =
4 | {{~ it.locales:locale }}
5 | | "{{=locale}}"
6 | {{~}};
7 |
8 | declare const def: Record;
9 | export default def;
10 |
--------------------------------------------------------------------------------
/localize/index.jst:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | {{
4 | const IDENT = /^[a-z_$][a-z0-9_$]*$/i;
5 | }}
6 |
7 | module.exports = {
8 | {{~ it.locales:locale }}
9 | {{? IDENT.test(locale) }}
10 | {{=locale}}:
11 | {{??}}
12 | "{{=locale}}":
13 | {{?}}
14 | require("./{{=locale}}{{=it.importFile}}"),
15 | {{~}}
16 | };
17 |
--------------------------------------------------------------------------------
/localize/localize.d.jst:
--------------------------------------------------------------------------------
1 | import {Localize} from "../types";
2 | declare const localize: Localize;
3 | export default localize;
4 |
--------------------------------------------------------------------------------
/localize/localize.jst:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | {{
4 | const STRIP_FUNCTION = /function\s+anonymous\s*\(it[^)]*\)\s*{|return\s+out;\s*}/g;
5 | const VAR_OUT = /var\s+out/;
6 | const OUT_EMPTY_STRING = /out\s*\+=\s*\'\'\s*\+\s*/g;
7 | }}
8 |
9 | {{ var name = 'localize_' + it.locale.replace('-','_'); }}
10 | module.exports = function {{=name}}(errors) {
11 | if (!(errors && errors.length)) return;
12 | for (const e of errors) {
13 | let out;
14 | switch (e.keyword) {
15 | {{~ it.messages:msg }}
16 | case "{{= msg.keyword }}":
17 | {{~ msg.keywords:kwd }}
18 | case '{{= kwd }}':
19 | {{~}}
20 | {{? typeof msg.msgFunc == "function" }}
21 | {{= stripFunction(msg.msgFunc) }}
22 | {{?? msg.msgFunc.length }}
23 | switch (e.params.error) {
24 | {{~ msg.msgFunc:err }}
25 | case "{{= err.error }}":
26 | {{= stripFunction(err.func) }}
27 | break;
28 | {{~}}
29 | default:
30 | {{? it.typeMessage }}
31 | {{= stripFunction(it.typeMessage) }}
32 | {{??}}
33 | {{= stripFunction(it.defaultMessage) }}
34 | {{?}}
35 | }
36 | {{??}}
37 | {{= stripFunction(it.typeMessage) }}
38 | {{?}}
39 | break;
40 | {{~}}
41 | default:
42 | {{= stripFunction(it.defaultMessage) }}
43 | }
44 | e.message = out;
45 | }
46 | };
47 |
48 | {{
49 | function stripFunction(code) {
50 | return code.toString()
51 | .replace(STRIP_FUNCTION, '')
52 | .replace(VAR_OUT, 'out')
53 | .replace(OUT_EMPTY_STRING, 'out += ');
54 | }
55 | }}
56 |
--------------------------------------------------------------------------------
/localize/types.d.ts:
--------------------------------------------------------------------------------
1 | import {ErrorObject} from "ajv"
2 |
3 | export interface Localize {
4 | (errors?: null | ErrorObject[]): void
5 | }
6 |
--------------------------------------------------------------------------------
/messages/index.js:
--------------------------------------------------------------------------------
1 | "use strict"
2 |
3 | /**
4 | * When adding new locales, please maintain alphabetic ordering.
5 | * "en" must remain in the first position.
6 | * Tests will fail otherwise.
7 | */
8 |
9 | module.exports = {
10 | // supported locales
11 | _locales: [
12 | "en",
13 | "ar",
14 | "ca",
15 | "cs",
16 | "de",
17 | "es",
18 | "fi",
19 | "fr",
20 | "hu",
21 | "id",
22 | "it",
23 | "ja",
24 | "ko",
25 | "nb",
26 | "nl",
27 | "pl",
28 | "pt-BR",
29 | "ru",
30 | "sk",
31 | "sv",
32 | "th",
33 | "zh",
34 | "zh-TW",
35 | ],
36 |
37 | // shared defines
38 | _defs: {
39 | n: "{{var n = e.params.limit;}}",
40 | mPlural: {
41 | // plural for the words item (element) and character
42 | en: "{{? n!=1 }}s{{?}}",
43 | ar: "{{? n!=1 }}عناصر{{?}}",
44 | ca: "{{? n!=1 }}s{{?}}",
45 | cs: "{{? n>=2 && n<=4 }}ky{{?? n!=1 }}ek{{??}}ků{{?}}",
46 | de: "{{? n!=1 }}e{{?}}",
47 | es: "{{? n!=1 }}s{{?}}", //only item (element)
48 | fr: "{{? n!=1 }}s{{?}}",
49 | it: "{{? n==1 }}o{{??}}i{{?}}",
50 | nb: "{{? n!=1 }}er{{?}}",
51 | nl: "{{? n!=1 }}s{{?}}",
52 | pl: "{{? n==1 }}u{{??}}ów{{?}}",
53 | "pt-BR": "{{? n!=1 }}s{{?}}",
54 | ru: "{{? n>=2 && n<=4 }}а{{?? n!=1 }}ов{{?}}",
55 | sk: "{{? n==1 }}ok{{??}}kov{{?}}",
56 | sv: "{{? n!=1 }}er{{?}}",
57 | },
58 | propPlural: {
59 | // plural for the word property (attribute)
60 | en: "{{? n==1 }}y{{??}}ies{{?}}",
61 | ar: "{{? n!=1 }}خصائص{{?}}",
62 | ca: "{{? n!=1 }}s{{?}}",
63 | cs: "{{? n>=2 && n<=4 }}ky{{?? n!=1 }}ek{{??}}ka{{?}}",
64 | de: "{{? n!=1 }}e{{?}}",
65 | es: "{{? n!=1 }}es{{?}}",
66 | fr: "{{? n!=1 }}s{{?}}",
67 | hu: "{{? n!=1 }}i{{?}}",
68 | it: "{{? n==1 }}o{{??}}i{{?}}",
69 | nb: "{{? n==1 }}en{{??}}er{{?}}",
70 | nl: "{{? n!=1 }}pen{{?}}",
71 | pl: "{{? n==1 }}e{{??}}a{{?}}",
72 | "pt-BR": "{{? n!=1 }}s{{?}}",
73 | ru: "{{? n==1 }}е{{?? n>=2 && n<=4 }}я{{??}}ей{{?}}",
74 | sk: "{{? n>=2 && n<=4 }}ky{{?? n!=1 }}iek{{??}}ka{{?}}",
75 | sv: "{{? n!=1 }}er{{?}}",
76 | },
77 | },
78 |
79 | // error messages
80 | _defaultMessage: {
81 | en: 'must pass "{{=e.keyword}}" keyword validation',
82 | ar: 'يجب أن تمرر كلمة التحقق المفتاحية "{{=e.keyword}}"',
83 | ca: 'ha de passar la validació de la clau "{{=e.keyword}}"',
84 | cs: 'musí vyhovět "{{=e.keyword}}" validaci',
85 | de: 'muss die Validierung "{{=e.keyword}}" bestehen',
86 | es: 'debe pasar la validación de palabra clave "{{=e.keyword}}"',
87 | fi: 'täytyy läpäistä "{{=e.keyword}}" avainsanatarkistus',
88 | fr: 'doit être valide selon le critère "{{=e.keyword}}"',
89 | id: 'harus lulus validasi kata kunci "{{=e.keyword}}"',
90 | it: 'deve essere valido secondo il criterio "{{=e.keyword}}"',
91 | ko: '"{{=e.keyword}}"키워드 검사를 통과해야 합니다',
92 | nb: "må samsvare med valideringen for {{=e.keyword}}",
93 | nl: 'moet sleutelwoord validatie "{{=e.keyword}}" doorstaan',
94 | pl: 'powinien przejść walidację "{{=e.keyword}}"',
95 | "pt-BR": 'deve passar a validação da keyword "{{=e.keyword}}"',
96 | ru: 'должно соответствовать правилу "{{=e.keyword}}"',
97 | sk: 'musí splniť "{{=e.keyword}}" validáciu',
98 | sv: 'bör passera "{{=e.keyword}}" nyckelord validering',
99 | th: 'ต้องผ่านคีย์เวิร์ด "{{=e.keyword}}"',
100 | zh: '应当通过 "{{=e.keyword}} 关键词校验"',
101 | "zh-TW": '應該通過 "{{=e.keyword}} 關鍵詞檢驗"',
102 | },
103 |
104 | "false schema": {
105 | en: "boolean schema is false",
106 | ar: "المخطط المنطقي غير صحيح",
107 | ca: "l’esquema és fals",
108 | cs: "schéma je false",
109 | de: "boolesches Schema ist falsch",
110 | es: "el esquema és falso",
111 | fi: "boolean skeema on väärä",
112 | fr: 'le schema est "false"',
113 | id: "skema boolean salah",
114 | it: "lo schema booleano è falso",
115 | ko: "boolean 스키마는 올바르지 않습니다",
116 | nb: "boolsk schema er usannt",
117 | nl: "boolean schema is fout",
118 | "pt-BR": 'o schema booleano é "false"',
119 | ru: "схема равна false",
120 | sk: "schéma je false",
121 | sv: "boolean schema är falskt",
122 | th: "schema เป็น false",
123 | zh: "布尔模式出错",
124 | "zh-TW": "布林模式不正確",
125 | },
126 | additionalItems: {
127 | _keywords: ["items"], // for JSON Schema draft-2020-12
128 | en: "{{#def.n}}must NOT have more than {{=n}} item{{#def.mPlural}}",
129 | ar: "{{#def.n}} يجب أن لا يحوي أكثر من {{=n}} عنصر",
130 | ca: "{{#def.n}}no ha de tenir més de {{=n}} element{{#def.mPlural}}",
131 | cs: "{{#def.n}}nemůže mít víc, než {{=n}} prv{{#def.mPlural}}",
132 | de: "{{#def.n}}darf nicht mehr als {{=n}} Element{{#def.mPlural}} enthalten",
133 | es: "{{#def.n}}no debe tener más de {{=n}} elemento{{#def.mPlural}}",
134 | fi: "{{#def.n}}saa sisältää enintään {{=n}}{{? n==1 }}:n elementin{{??}} elementtiä{{?}}",
135 | fr: "{{#def.n}}ne doit pas contenir plus de {{=n}} élémént{{#def.mPlural}}",
136 | hu: "{{#def.n}}nem lehet több, mint {{=n}} eleme",
137 | id: "{{#def.n}} tidak boleh memiliki lebih dari {{=n}} item",
138 | it: "{{#def.n}}non dovrebbe avere più di {{=n}} element{{#def.mPlural}}",
139 | ja: "{{#def.n}}は{{=n}}以上あってはいけない",
140 | ko: "{{#def.n}} 항목은 아이템을 {{=n}}개 이상 가질 수 없습니다",
141 | nb: "{{#def.n}}kan ikke ha mer enn {{=n}} element{{#def.mPlural}}",
142 | nl: "{{#def.n}}mag niet meer dan {{=n}} item{{#def.mPlural}} bevatten",
143 | pl: "{{#def.n}}nie powinien mieć więcej niż {{=n}} element{{#def.mPlural}}",
144 | "pt-BR": "não são permitidos itens adicionais (mais do que {{=n}})",
145 | ru: "{{#def.n}}должно иметь не более, чем {{=n}} элемент{{#def.mPlural}}",
146 | sk: "{{#def.n}}nemôže obsahovať viac, než {{=n}} prv{{#def.mPlural}}",
147 | sv: "{{#def.n}}borde ha fler än {{=n}} sak{{#def.mPlural}}",
148 | th: "{{#def.n}}ต้องมีสมาชิกไม่เกิน {{=n}} ตัว",
149 | zh: "{{#def.n}}不允许超过{{=n}}个元素",
150 | "zh-TW": "{{#def.n}}不可以超過{{=n}}個元素",
151 | },
152 | additionalProperties: {
153 | en: "must NOT have additional properties",
154 | ar: "يجب أن لا يحوي خصائص إضافية",
155 | ca: "no ha de tenir propietats addicionals",
156 | cs: "nemůže mít další položky",
157 | de: "darf keine zusätzlichen Attribute haben",
158 | es: "no debe tener propiedades adicionales",
159 | fi: "ei saa sisältää ylimääräisiä ominaisuuksia",
160 | fr: "ne doit pas contenir de propriétés additionnelles",
161 | hu: "nem lehetnek további elemei",
162 | id: "tidak boleh memiliki properti tambahan",
163 | it: "non deve avere attributi aggiuntivi",
164 | ja: "追加してはいけない",
165 | ko: "추가적인 속성은 허용되지 않습니다",
166 | nb: "kan ikke ha flere egenskaper",
167 | nl: "mag geen extra eigenschappen bevatten",
168 | pl: "nie powinien zawierać dodatkowych pól",
169 | "pt-BR": "não são permitidas propriedades adicionais",
170 | ru: "не должно иметь дополнительных полей",
171 | sk: "nemôže obsahovať ďalšie položky",
172 | sv: "borde inte ha fler egenskaper",
173 | th: "ต้องไม่มี property อื่นๆ นอกเหนีอจากที่กำหนดไว้",
174 | zh: "不允许有额外的属性",
175 | "zh-TW": "不可以有額外的屬性",
176 | },
177 | anyOf: {
178 | en: 'must match a schema in "anyOf"',
179 | ar: 'يجب أن يوافق أحد المخططات الموجودة في "anyOf"',
180 | ca: 'ha de coincidir amb algun esquema definit a "anyOf"',
181 | cs: 'musí vyhovět alespoň jednomu schématu v "anyOf"',
182 | de: 'muss einem der Schemata in "anyOf" entsprechen',
183 | es: 'debe coincidir con algún esquema en "anyOf"',
184 | fi: 'täytyy vastata "anyOf" skeemaa',
185 | fr: 'doit correspondre à un schéma de "anyOf"',
186 | hu: 'meg kell feleljen legalább egy "anyOf" alaknak',
187 | id: 'harus cocok dengan beberapa skema pada "anyOf"',
188 | it: 'deve corrispondere ad uno degli schema in "anyOf"',
189 | ja: '"anyOf"のスキーマとマッチしなくてはいけない',
190 | ko: '"anyOf"의 스키마와 일치해야 합니다',
191 | nb: 'må samsvare med et schema i "anyOf"',
192 | nl: 'moet overeenkomen met een schema in "anyOf"',
193 | pl: 'powinien pasować do wzoru z sekcji "anyOf"',
194 | "pt-BR": 'os dados não correspondem a nenhum schema de "anyOf"',
195 | ru: 'должно соответствовать одной их схем в "anyOf"',
196 | sk: 'musí splňovať aspoň jednu zo schém v "anyOf"',
197 | sv: 'borde matcha något schema i "anyOf"',
198 | th: 'ต้องตรงกับหนึ่งใน schema ที่กำหนดไว้ใน "anyOf"',
199 | zh: "数据应为 anyOf 所指定的其中一个",
200 | "zh-TW": "不符合 anyOf 指定的模式",
201 | },
202 | dependencies: {
203 | _keywords: ["dependentRequired"],
204 | _defs: {
205 | n: "{{var n = e.params.depsCount;}}",
206 | },
207 | en: "{{#def.n}}must have propert{{#def.propPlural}} {{=e.params.deps}} when property {{=e.params.property}} is present",
208 | ar: "{{#def.n}} يجب أن يحوي الخصائص {{=e.params.deps}} عندما تكون الخاصية {{=e.params.property}} موجودة",
209 | ca: "{{#def.n}}ha de contenir la propietat{{#def.propPlural}} {{=e.params.deps}} quan la propietat {{=e.params.property}} és present",
210 | cs: "{{#def.n}}musí mít polož{{#def.propPlural}}: {{=e.params.deps}}, pokud obsahuje {{=e.params.property}}",
211 | de: "{{#def.n}}muss Attribut{{#def.propPlural}} {{=e.params.deps}} aufweisen, wenn Attribut {{=e.params.property}} gesetzt ist",
212 | es: "{{#def.n}}debe contener la{{#def.mPlural}} propiedad{{#def.propPlural}} {{=e.params.deps}} cuando la propiedad {{=e.params.property}} se encuentra presente",
213 | fi: "{{#def.n}}täytyy sisältää {{=e.params.deps}} ominaisuu{{? n==1 }}s{{??}}det{{?}} kun {{=e.params.property}}-ominaisuus on läsnä",
214 | fr: "{{#def.n}}doit avoir la propriété {{=e.params.deps}} quand la propriété {{=e.params.property}} est présente",
215 | hu: "{{#def.n}}-nak kell legyen{{? n>1 }}ek{{?}} a következő tulajdonsága{{#def.propPlural}}: {{=e.params.deps}}, ha van {{=e.params.property}} tulajdonsága",
216 | id: "{{#def.n}} harus memiliki properti {{=e.params.deps}} ketika properti {{=e.params.property}} hadir",
217 | it: "{{#def.n}}dovrebbe avere {{? n==1 }}l'{{??}}gli {{?}}attribut{{#def.propPlural}} {{=e.params.deps}} quando l'attributo {{=e.params.property}} è presente",
218 | ja: "{{=e.params.property}}がある場合、{{#def.n}}は{{=e.params.deps}}をつけなければいけない",
219 | ko: "{{#def.n}}{{=e.params.property}}속성이 있는 경우, {{=e.params.deps}} 속성이 있어야합니다",
220 | nb: "{{#def.n}}må ha egenskapen{{? n != 1}}e{{?}} {{=e.params.deps}} når egenskapen {{=e.params.property}} er angitt",
221 | nl: "{{#def.n}}moet de eigenschap{{#def.propPlural}} {{=e.params.deps}} bevatten als {{=e.params.property}} is gedefinieerd",
222 | pl: "{{#def.n}}powinien zawierać pol{{#def.propPlural}} {{=e.params.deps}} kiedy pole {{=e.params.property}} jest obecne",
223 | "pt-BR":
224 | "{{#def.n}} deve ter propriedade{{#def.propPlural}} {{=e.params.deps}} quando a propriedade {{=e.params.property}} estiver presente",
225 | ru: "{{#def.n}}должно иметь пол{{? n==1 }}е{{??}}я{{?}} {{=e.params.deps}}, когда присутствует поле {{=e.params.property}}",
226 | sk: "{{#def.n}} musí obsahovať polož{{#def.propPlural}}: {{=e.params.deps}}, ak obsahuje {{=e.params.property}}",
227 | sv: "{{#def.n}}borde ha egenskap{{#def.propPlural}} {{=e.params.deps}} när egenskap {{=e.params.property}} finns tillgängligt",
228 | th: "{{#def.n}}เมื่อมี property {{=e.params.property}} แล้วจะต้องมี property {{=e.params.deps}} ด้วย",
229 | zh: "{{#def.n}}应当拥有属性{{=e.params.property}}的依赖属性{{=e.params.deps}}",
230 | "zh-TW": "{{#def.n}}應該要有屬性{{=e.params.property}}的依賴屬性{{=e.params.deps}}",
231 | },
232 | enum: {
233 | en: "must be equal to one of the allowed values",
234 | ar: "قيمة هذا الحقل يجب أن تكون مساوية لأحد القيم المعرفة مسبقاً",
235 | ca: "ha de ser igual a un dels valors predefinits",
236 | cs: "musí být rovno jedné hodnotě z výčtu",
237 | de: "muss einem der vorgegebenen Werte entsprechen",
238 | es: "deber ser igual a uno de los valores predefinidos",
239 | fi: "täytyy olla yhtä kuin jokin sallituista arvoista",
240 | fr: "doit être égal à une des valeurs prédéfinies",
241 | hu: "egyenlő kell legyen valamely előre meghatározott értékkel",
242 | id: "harus sama dengan salah satu dari nilai yang telah ditentukan",
243 | it: "deve essere uguale ad uno dei valori consentiti",
244 | ja: "事前に定義された値のいずれかに等しくなければいけない",
245 | ko: "미리 정의된 값중 하나여야 합니다",
246 | nb: "må være lik en av de forhåndsdefinerte verdiene",
247 | nl: "moet overeenkomen met één van de voorgedefinieerde waarden",
248 | pl: "powinien być równy jednej z predefiniowanych wartości",
249 | "pt-BR": "deve ser igual a um dos valores permitidos",
250 | ru: "должно быть равно одному из разрешенных значений",
251 | sk: "musí byť jedna z definovaných hodnôt",
252 | sv: "borde vara ekvivalent med en av dess fördefinierade värden",
253 | th: "ต้องตรงกับหนึ่งในค่าที่กำหนดไว้",
254 | zh: "应当是预设定的枚举值之一",
255 | "zh-TW": "應該要在預設的值之中",
256 | },
257 | format: {
258 | en: 'must match format "{{=e.params.format}}"',
259 | ar: 'يجب أن يوافق الصيغة "{{=e.params.format}}"',
260 | ca: 'ha de coincidir amb el format "{{=e.params.format}}"',
261 | cs: 'musí být ve formátu "{{=e.params.format}}"',
262 | de: 'muss diesem Format entsprechen: "{{=e.params.format}}"',
263 | es: 'debe coincidir con el formato "{{=e.params.format}}"',
264 | fi: 'täytyy vastata muotoa "{{=e.params.format}}"',
265 | fr: 'doit correspondre au format "{{=e.params.format}}"',
266 | hu: 'meg kell feleljen a következő formátumnak: "{{=e.params.format}}"',
267 | id: 'harus cocok dengan format "{{=e.params.format}}"',
268 | it: 'deve corrispondere al formato "{{=e.params.format}}"',
269 | ja: '"{{=e.params.format}}"形式に揃えなければいけない',
270 | ko: '"{{=e.params.format}}" 포맷과 일치해야 합니다',
271 | nb: 'må stemme overens med formatet "{{=e.params.format}}"',
272 | nl: 'moet overeenkomen met het volgende formaat: "{{=e.params.format}}"',
273 | pl: 'powinien zgadzać się z formatem "{{=e.params.format}}"',
274 | "pt-BR": 'deve corresponder ao formato "{{=e.params.format}}"',
275 | ru: 'должно соответствовать формату "{{=e.params.format}}"',
276 | sk: 'musí obsahovať formát "{{=e.params.format}}"',
277 | sv: 'borde matcha formatet "{{=e.params.format}}"',
278 | th: 'ต้องเป็นรูปแบบ "{{=e.params.format}}"',
279 | zh: '应当匹配格式 "{{=e.params.format}}"',
280 | "zh-TW": "應該要符合{{=e.params.format}}格式",
281 | },
282 | maximum: {
283 | _keywords: ["exclusiveMaximum"],
284 | _defs: {
285 | c: '{{var cond = e.params.comparison + " " + e.params.limit;}}',
286 | },
287 | en: "{{#def.c}}must be {{=cond}}",
288 | ar: "{{#def.c}} يجب أن يكون {{=cond}}",
289 | ca: "{{#def.c}}ha de ser {{=cond}}",
290 | cs: "{{#def.c}}musí být {{=cond}}",
291 | de: "{{#def.c}}muss {{=cond}} sein",
292 | es: "{{#def.c}}debe ser {{=cond}}",
293 | fi: "{{#def.c}}täytyy olla {{=cond}}",
294 | fr: "{{#def.c}}doit être {{=cond}}",
295 | hu: "{{#def.c}}kell legyen {{=cond}}",
296 | id: "{{#def.c}}harus {{=cond}}",
297 | it: "{{#def.c}}deve essere {{=cond}}",
298 | ja: "{{#def.c}}{{=cond}}でなければいけない",
299 | ko: "{{#def.c}} {{=cond}} 이여야 합니다",
300 | nb: "{{#def.c}}må være {{=cond}}",
301 | nl: "{{#def.c}}moet {{=cond}} zijn",
302 | pl: "{{#def.c}}powinien być {{=cond}}",
303 | "pt-BR": "{{#def.c}}deve ser {{=cond}}",
304 | ru: "{{#def.c}}должно быть {{=cond}}",
305 | sk: "{{#def.c}}musí byť {{=cond}}",
306 | sv: "{{#def.c}}borde vara {{=cond}}",
307 | th: "{{#def.c}}ต้อง {{=cond}}",
308 | zh: "{{#def.c}}应当为 {{=cond}}",
309 | "zh-TW": "{{#def.c}}應該要 {{=cond}}",
310 | },
311 | minimum: {
312 | _keywords: ["exclusiveMinimum"],
313 | _defs: {
314 | c: '{{var cond = e.params.comparison + " " + e.params.limit;}}',
315 | },
316 | en: "{{#def.c}}must be {{=cond}}",
317 | ar: "{{#def.c}} يجب أن يكون {{=cond}}",
318 | ca: "{{#def.c}}ha de ser {{=cond}}",
319 | cs: "{{#def.c}}musí být {{=cond}}",
320 | de: "{{#def.c}}muss {{=cond}} sein",
321 | es: "{{#def.c}}debe ser {{=cond}}",
322 | fi: "{{#def.c}}täytyy olla {{=cond}}",
323 | fr: "{{#def.c}}doit être {{=cond}}",
324 | hu: "{{#def.c}}kell legyen {{=cond}}",
325 | id: "{{#def.c}}harus {{=cond}}",
326 | it: "{{#def.c}}deve essere {{=cond}}",
327 | ja: "{{#def.c}}{{=cond}}でなければいけない",
328 | ko: "{{#def.c}} {{=cond}} 이여야 합니다",
329 | nb: "{{#def.c}}må være {{=cond}}",
330 | nl: "{{#def.c}}moet {{=cond}} zijn",
331 | pl: "{{#def.c}}powinien być {{=cond}}",
332 | "pt-BR": "{{#def.c}}deve ser {{=cond}}",
333 | ru: "{{#def.c}}должно быть {{=cond}}",
334 | sk: "{{#def.c}}musí byť {{=cond}}",
335 | sv: "{{#def.c}}borde vara {{=cond}}",
336 | th: "{{#def.c}}ต้อง {{=cond}}",
337 | zh: "{{#def.c}}应当为 {{=cond}}",
338 | "zh-TW": "{{#def.c}}應該要 {{=cond}}",
339 | },
340 | maxItems: {
341 | en: "{{#def.n}}must NOT have more than {{=n}} item{{#def.mPlural}}",
342 | ar: "{{#def.n}} يجب أن لا يحوي أكثر من {{=n}} عنصر",
343 | ca: "{{#def.n}}no ha de tenir més de {{=n}} ítem{{#def.mPlural}}",
344 | cs: "{{#def.n}}nesmí obsahovat víc než {{=n}} prv{{#def.mPlural}}",
345 | de: "{{#def.n}}darf nicht mehr als {{=n}} Element{{#def.mPlural}} haben",
346 | es: "{{#def.n}}no debe contener más de {{=n}} elemento{{#def.mPlural}}",
347 | fi: "{{#def.n}}tulee sisältää enintään {{=n}} {{? n==1 }}elementti{{??}}elementtiä{{?}}",
348 | fr: "{{#def.n}}ne doit pas contenir plus de {{=n}} élément{{#def.mPlural}}",
349 | hu: "{{#def.n}}nem lehet több, mint {{=n}} eleme",
350 | id: "{{#def.n}} tidak boleh memiliki lebih dari {{=n}} item",
351 | it: "{{#def.n}}non deve avere più di {{=n}} element{{#def.mPlural}}",
352 | ja: "{{#def.n}}は{{=n}}個以上であってはいけない",
353 | ko: "{{#def.n}}아이템이 최대 {{=n}}개이여야 합니다",
354 | nb: "{{#def.n}}kan ikke ha fler enn {{=n}} element{{#def.mPlural}}",
355 | nl: "{{#def.n}}mag niet meer dan {{=n}} item{{#def.mPlural}} bevatten",
356 | pl: "{{#def.n}}nie powinien mieć więcej niż {{=n}} element{{#def.mPlural}}",
357 | "pt-BR": "{{#def.n}}não deve ter mais que {{=n}} elemento{{#def.mPlural}}",
358 | ru: "{{#def.n}}должно иметь не более, чем {{=n}} элемент{{#def.mPlural}}",
359 | sk: "{{#def.n}}nesmie obsahovať viac než {{=n}} prv{{#def.mPlural}}",
360 | sv: "{{#def.n}}borde inte ha fler än {{=n}} sak{{#def.mPlural}}",
361 | th: "{{#def.n}}ต้องมีสมาชิกไม่เกิน {{=n}}",
362 | zh: "{{#def.n}}不应多于 {{=n}} 个项",
363 | "zh-TW": "{{#def.n}}不應該多於 {{=n}} 個",
364 | },
365 | minItems: {
366 | en: "{{#def.n}}must NOT have less than {{=n}} item{{#def.mPlural}}",
367 | ar: "{{#def.n}} يجب أن لا يحوي أقل من {{=n}} عنصر",
368 | ca: "{{#def.n}}no ha de tenir menys de {{=n}} ítem{{#def.mPlural}}",
369 | cs: "{{#def.n}}nesmí obsahovat méně než {{=n}} prv{{#def.mPlural}}",
370 | de: "{{#def.n}}darf nicht weniger als {{=n}} Element{{#def.mPlural}} haben",
371 | es: "{{#def.n}}no debe contener menos de {{=n}} elemento{{#def.mPlural}}",
372 | fi: "{{#def.n}}tulee sisältää vähintään {{=n}} {{? n==1 }}elementti{{??}}elementtiä{{?}}",
373 | fr: "{{#def.n}}ne doit pas contenir moins de {{=n}} élément{{#def.mPlural}}",
374 | hu: "{{#def.n}}nem lehet kevesebb, mint {{=n}} eleme",
375 | id: "{{#def.n}} tidak boleh kurang dari {{=n}} item",
376 | it: "{{#def.n}}non deve avere meno di {{=n}} element{{#def.mPlural}}",
377 | ja: "{{#def.n}}は{{=n}}個以下であってはいけない",
378 | ko: "{{#def.n}}아이템이 최소 {{=n}}개이여야 합니다",
379 | nb: "{{#def.n}}kan ikke ha færre enn {{=n}} element{{#def.mPlural}}",
380 | nl: "{{#def.n}}mag niet minder dan {{=n}} item{{#def.mPlural}} bevatten",
381 | pl: "{{#def.n}}nie powinien mieć mniej niż {{=n}} element{{#def.mPlural}}",
382 | "pt-BR": "{{#def.n}}não deve ter menos que {{=n}} elemento{{#def.mPlural}}",
383 | ru: "{{#def.n}}должно иметь не менее, чем {{=n}} элемент{{#def.mPlural}}",
384 | sk: "{{#def.n}}nesmie obsahovať menej než {{=n}} prv{{#def.mPlural}}",
385 | sv: "{{#def.n}}borde inte ha färre än {{=n}} sak{{#def.mPlural}}",
386 | th: "{{#def.n}}ควรมีสมาชิกไม่น้อยกว่า {{=n}}",
387 | zh: "{{#def.n}}不应少于 {{=n}} 个项",
388 | "zh-TW": "{{#def.n}}不應該少於 {{=n}} 個",
389 | },
390 | maxLength: {
391 | en: "{{#def.n}}must NOT be longer than {{=n}} character{{#def.mPlural}}",
392 | ar: "{{#def.n}} يجب أن لا يحوي أكثر من {{=n}} محرف",
393 | ca: "{{#def.n}}no pot contenir més de {{=n}} caràcter{{#def.mPlural}}",
394 | cs: "{{#def.n}}nesmí být delší než {{=n}} zna{{? n>=2 && n<=4 }}ky{{?? n!=1 }}k{{??}}ků{{?}}",
395 | de: "{{#def.n}}darf nicht länger als {{=n}} Zeichen sein",
396 | es: "{{#def.n}}no debe contener más de {{=n}} caracter{{? n!=1 }}es{{?}}",
397 | fi: "{{#def.n}}ei saa olla pidempi kuin {{=n}} merkki{{? n!=1 }}ä{{?}}",
398 | fr: "{{#def.n}}ne doit pas dépasser {{=n}} caractère{{#def.mPlural}}",
399 | hu: "{{#def.n}}nem lehet hosszabb, mint {{=n}} szimbólum",
400 | id: "{{#def.n}} tidak boleh lebih dari {{=n}} karakter",
401 | it: "{{#def.n}}non deve essere più lungo di {{=n}} caratter{{? n==1 }}e{{??}}i{{?}}",
402 | ja: "{{#def.n}}は{{=n}}文字以上であってはいけない",
403 | ko: "{{#def.n}}최대 {{=n}}글자여야 합니다",
404 | nb: "{{#def.n}}kan ikke være lengre enn {{=n}} tegn",
405 | nl: "{{#def.n}}mag niet langer dan {{=n}} karakter{{#def.mPlural}} zijn",
406 | pl: "{{#def.n}}nie powinien być dłuższy niż {{=n}} znak{{? n!=1 }}ów{{?}}",
407 | "pt-BR": "{{#def.n}}não deve ser maior que {{=n}} caracter{{? n!=1 }}es{{?}}",
408 | ru: "{{#def.n}}должно быть не длиннее, чем {{=n}} символ{{#def.mPlural}}",
409 | sk: "{{#def.n}}nesmie byť dlhší než {{=n}} znak{{? n!=1 }}ov{{?}}",
410 | sv: "{{#def.n}}borde inte vara längre än {{=n}} tecken",
411 | th: "{{#def.n}}ต้องยาวไม่เกิน {{=n}} ตัวอักษร",
412 | zh: "{{#def.n}}不应多于 {{=n}} 个字符",
413 | "zh-TW": "{{#def.n}}不應該多於 {{=n}} 個字元",
414 | },
415 | minLength: {
416 | en: "{{#def.n}}must NOT be shorter than {{=n}} character{{#def.mPlural}}",
417 | ar: "{{#def.n}} يجب أن لا يحوي أقل من {{=n}} محرف",
418 | ca: "{{#def.n}}no pot contenir menys de {{=n}} caràcter{{#def.mPlural}}",
419 | cs: "{{#def.n}}nesmí být kratší než {{=n}} zna{{? n>=2 && n<=4 }}ky{{?? n!=1 }}k{{??}}ků{{?}}",
420 | de: "{{#def.n}}darf nicht kürzer als {{=n}} Zeichen sein",
421 | es: "{{#def.n}}no debe contener menos de {{=n}} caracter{{? n!=1 }}es{{?}}",
422 | fi: "{{#def.n}}ei saa olla lyhyempi kuin {{=n}} merkki{{? n!=1 }}ä{{?}}",
423 | fr: "{{#def.n}}ne doit pas faire moins de {{=n}} caractère{{#def.mPlural}}",
424 | hu: "{{#def.n}}nem lehet rövidebb, mint {{=n}} szimbólum",
425 | id: "{{#def.n}} tidak boleh lebih pendek dari {{=n}} karakter",
426 | it: "{{#def.n}}non deve essere meno lungo di {{=n}} caratter{{? n==1 }}e{{??}}i{{?}}",
427 | ja: "{{#def.n}}は{{=n}}文字以下であってはいけない",
428 | ko: "{{#def.n}}최소 {{=n}}글자여야 합니다",
429 | nb: "{{#def.n}}kan ikke være kortere enn {{=n}} tegn",
430 | nl: "{{#def.n}}mag niet korter dan {{=n}} karakter{{#def.mPlural}} zijn",
431 | pl: "{{#def.n}}nie powinien być krótszy niż {{=n}} znak{{? n!=1 }}ów{{?}}",
432 | "pt-BR": "{{#def.n}}não deve ser mais curta que {{=n}} caracter{{? n!=1 }}es{{?}}",
433 | ru: "{{#def.n}}должно быть не короче, чем {{=n}} символ{{#def.mPlural}}",
434 | sk: "{{#def.n}}nesmie byť kratší než {{=n}} znak{{? n!=1 }}ov{{?}}",
435 | sv: "{{#def.n}}borde inte vara kortare än {{=n}} tecken",
436 | th: "{{#def.n}}ต้องมีอย่างน้อย {{=n}} ตัวอักษร",
437 | zh: "{{#def.n}}不应少于 {{=n}} 个字符",
438 | "zh-TW": "{{#def.n}}不應該少於 {{=n}} 個字元",
439 | },
440 | maxProperties: {
441 | en: "{{#def.n}}must NOT have more than {{=n}} propert{{#def.propPlural}}",
442 | ar: "{{#def.n}} يجب أن لا يحوي أكثر من {{=n}} خصائص",
443 | ca: "{{#def.n}}no pot contenir més de {{=n}} propietat{{#def.mPlural}}",
444 | cs: "{{#def.n}}nesmí mít víc než {{=n}} polož{{#def.propPlural}}",
445 | de: "{{#def.n}}darf nicht mehr als {{=n}} Attribut{{#def.propPlural}} haben",
446 | es: "{{#def.n}}no debe contener más de {{=n}} propiedad{{#def.propPlural}}",
447 | fi: "{{#def.n}}tulee sisältää enintään {{=n}} {{? n==1 }}ominaisuus{{??}}ominaisuutta{{?}}",
448 | fr: "{{#def.n}}ne doit pas contenir plus de {{=n}} propriété{{#def.propPlural}}",
449 | hu: "{{#def.n}}nem lehet több, mint {{=n}} tulajdonsága",
450 | id: "{{#def.n}} tidak boleh memiliki lebih dari {{=n}} properti",
451 | it: "{{#def.n}}non deve avere più di {{=n}} attribut{{#def.propPlural}}",
452 | ja: "{{#def.n}}は{{=n}}個以上のプロパティを有してはいけない",
453 | ko: "{{#def.n}}속성은 최대 {{=n}}개 이내여야 합니다",
454 | nb: "{{#def.n}}kan ikke ha mer enn {{=n}} egenskap{{#def.mPlural}}",
455 | nl: "{{#def.n}}mag niet meer dan {{=n}} eigenschap{{#def.propPlural}} bevatten",
456 | pl: "{{#def.n}}nie powinien zawierać więcej niż {{=n}} {{? n==1 }}pole{{??}}pól{{?}}",
457 | "pt-BR": "{{#def.n}}não deve ter mais que {{=n}} propriedade{{#def.propPlural}}",
458 | ru: "{{#def.n}}должно иметь не более, чем {{=n}} пол{{#def.propPlural}}",
459 | sk: "{{#def.n}}nesmie obsahovať viac než {{=n}} polož{{#def.propPlural}}",
460 | sv: "{{#def.n}}borde inte ha fler än {{=n}} egenskap{{#def.propPlural}}",
461 | th: "{{#def.n}}ต้องมี property ไม่เกิน {{=n}} ตัว",
462 | zh: "{{#def.n}}不应有多于 {{=n}} 个属性",
463 | "zh-TW": "{{#def.n}}不應該多於 {{=n}} 個屬性",
464 | },
465 | minProperties: {
466 | en: "{{#def.n}}must NOT have less than {{=n}} propert{{#def.propPlural}}",
467 | ar: "{{#def.n}} يجب أن لا يحوي أقل من {{=n}} خصائص",
468 | ca: "{{#def.n}}no pot contenir menys de {{=n}} propietat{{#def.mPlural}}",
469 | cs: "{{#def.n}}nesmí mít méně než {{=n}} polož{{#def.propPlural}}",
470 | de: "{{#def.n}}darf nicht weniger als {{=n}} Attribut{{#def.propPlural}} haben",
471 | es: "{{#def.n}}no debe contener menos de {{=n}} propiedad{{#def.propPlural}}",
472 | fi: "{{#def.n}}tulee sisältää vähintään {{=n}} {{? n==1 }}ominaisuus{{??}}ominaisuutta{{?}}",
473 | fr: "{{#def.n}}ne doit pas contenir moins de {{=n}} propriété{{#def.propPlural}}",
474 | hu: "{{#def.n}}nem lehet kevesebb, mint {{=n}} tulajdonsága",
475 | id: "{{#def.n}} tidak boleh kurang dari {{=n}} properti",
476 | it: "{{#def.n}}non deve avere meno di {{=n}} attribut{{#def.propPlural}}",
477 | ja: "{{#def.n}}は{{=n}}個以下のプロパティを有してはいけない",
478 | ko: "{{#def.n}}속성은 최소 {{=n}}개 이상이여야 합니다",
479 | nb: "{{#def.n}}kan ikke ha mindre enn {{=n}} egenskap{{#def.mPlural}}",
480 | nl: "{{#def.n}}mag niet minder dan {{=n}} eigenschap{{#def.propPlural}} bevatten",
481 | pl: "{{#def.n}}nie powinien zawierać mniej niż {{=n}} {{? n==1 }}pole{{??}}pól{{?}}",
482 | "pt-BR": "{{#def.n}}não deve ter menos que {{=n}} propriedade{{#def.propPlural}}",
483 | ru: "{{#def.n}}должно иметь не менее, чем {{=n}} пол{{#def.propPlural}}",
484 | sk: "{{#def.n}}nesmie obsahovať menej než {{=n}} polož{{#def.propPlural}}",
485 | sv: "{{#def.n}}borde inte ha färre än {{=n}} egenskap{{#def.propPlural}}",
486 | th: "{{#def.n}}ต้องมี property อย่างน้อย {{=n}} ตัว",
487 | zh: "{{#def.n}}不应有少于 {{=n}} 个属性",
488 | "zh-TW": "{{#def.n}}不應該少於 {{=n}} 個屬性",
489 | },
490 | multipleOf: {
491 | en: "must be a multiple of {{=e.params.multipleOf}}",
492 | ar: " يجب أن يحوي أكثر من {{=e.params.multipleOf}}",
493 | ca: "ha de ser múltiple de {{=e.params.multipleOf}}",
494 | cs: "musí být násobkem {{=e.params.multipleOf}}",
495 | de: "muss ein Vielfaches von {{=e.params.multipleOf}} sein",
496 | es: "debe ser múltiplo de {{=e.params.multipleOf}}",
497 | fi: "täytyy olla moninkertainen: {{=e.params.multipleOf}}",
498 | fr: "doit être un multiple de {{=e.params.multipleOf}}",
499 | hu: "a többszöröse kell legyen a következő számnak: {{=e.params.multipleOf}}",
500 | id: "harus merupakan kelipatan dari {{=e.params.multipleOf}}",
501 | it: "deve essere un multiplo di {{=e.params.multipleOf}}",
502 | ja: "{{=e.params.multipleOf}}の倍数でなければいけない",
503 | ko: "{{=e.params.multipleOf}}의 배수여야 합니다",
504 | nb: "må være et multiplum av {{=e.params.multipleOf}}",
505 | nl: "moet een veelvoud van {{=e.params.multipleOf}} zijn",
506 | pl: "powinien być wielokrotnością {{=e.params.multipleOf}}",
507 | "pt-BR": "deve ser múltiplo de {{=e.params.multipleOf}}",
508 | ru: "должно быть кратным {{=e.params.multipleOf}}",
509 | sk: "musí byť násobkom {{=e.params.multipleOf}}",
510 | sv: "borde vara en multipel av {{=e.params.multipleOf}}",
511 | th: "ต้องเป็นเลขที่หาร {{=e.params.multipleOf}} ลงตัว",
512 | zh: "应当是 {{=e.params.multipleOf}} 的整数倍",
513 | "zh-TW": "應該是 {{=e.params.multipleOf}} 的整數倍",
514 | },
515 | not: {
516 | en: 'must NOT be valid according to schema in "not"',
517 | ar: 'يجب أن يكون غير صحيح وفقاً للمخطط "not"',
518 | ca: 'no ha de ser vàlid d’acord amb l’esquema definit a "not"',
519 | cs: 'nesmí vyhovět schématu v "not"',
520 | de: 'muss dem in "not" angegebenen Schema widersprechen',
521 | es: 'no debe ser válido según el esquema en "not"',
522 | fi: 'ei saa olla hyväksytty skeeman "not" mukaan',
523 | fr: 'est invalide selon le schéma "not"',
524 | hu: 'nem lehet érvényes a "not" alaknak megfelelően',
525 | id: 'tidak boleh valid sesuai dengan skema pada "not"',
526 | it: 'non deve essere valido in base allo schema di "non"',
527 | ja: '"not"のスキーマに従って有効としてはいけない',
528 | ko: '"not"스키마에 따라 유효하지 않아야 합니다',
529 | nb: 'kan ikke samsvare med schema i "not"',
530 | nl: 'mag niet overeenkomen met een schema in "not"',
531 | pl: 'nie powinien pasować do wzoru z sekcji "not"',
532 | "pt-BR": 'não deve ser valido segundo o schema em "not"',
533 | ru: 'должно не соответствовать схеме в "not"',
534 | sk: 'nesmie splňovať schému v "not"',
535 | sv: 'borde inte vara giltigt enligt schema i "not"',
536 | th: 'ต้องไม่ผ่าน schema ที่กำหนดไว้ใน "not"',
537 | zh: '不应当匹配 "not" schema',
538 | "zh-TW": '不應該符合 "not" schema',
539 | },
540 | oneOf: {
541 | en: 'must match exactly one schema in "oneOf"',
542 | ar: 'يجب أن يوافق مخطط واحد فقط موجود في "oneOf"',
543 | ca: 'ha de coincidir només amb un esquema definit a "oneOf"',
544 | cs: 'musí vyhovět právě jednomu schématu v "oneOf"',
545 | de: 'muss genau einem der Schemata in "oneOf" entsprechen',
546 | es: 'debe coincidir con un solo esquema en "oneOf"',
547 | fi: 'täytyy vastata täsmälleen yhtä "oneOf" -kohdassa määriteltyä skeemaa',
548 | fr: 'doit correspondre à exactement un schéma de "oneOf"',
549 | hu: 'meg kell feleljen pontosan egy "oneOf" alaknak',
550 | id: 'harus sama persis dengan satu skema pada "oneOf"',
551 | it: 'deve corrispondere esattamente ad uno degli schema in "oneOf"',
552 | ja: '"oneOf"のスキーマと完全に一致しなくてはいけない',
553 | ko: '"oneOf" 스키마중 하나와 정확하게 일치해야 합니다',
554 | nb: 'må samsvare med nøyaktig ett schema i "oneOf"',
555 | nl: 'moet overeenkomen met één schema in "oneOf"',
556 | pl: 'powinien pasować do jednego wzoru z sekcji "oneOf"',
557 | "pt-BR": 'deve corresponder exatamente com um schema em "oneOf"',
558 | ru: 'должно соответствовать в точности одной схемe в "oneOf"',
559 | sk: 'musí splňovať práve jednu schému v "oneOf"',
560 | sv: 'borde matcha exakt ett schema i "oneOf"',
561 | th: 'ต้องตรงกับ schema ตัวเดียวใน "oneOf" เท่านั้น',
562 | zh: '只能匹配一个 "oneOf" 中的 schema',
563 | "zh-TW": '只能符合一個 "oneOf" 中的 schema',
564 | },
565 | pattern: {
566 | en: 'must match pattern "{{=e.params.pattern}}"',
567 | ar: 'يجب أن يوافق النمط "{{=e.params.pattern}}"',
568 | ca: 'ha de coincidir amb el patró "{{=e.params.pattern}}"',
569 | cs: 'musí vyhovět regulárnímu výrazu "{{=e.params.pattern}}"',
570 | de: 'muss diesem Muster entsprechen: "{{=e.params.pattern}}"',
571 | es: 'debe coincidir con el patron "{{=e.params.pattern}}"',
572 | fi: 'täytyy vastata muotoa "{{=e.params.pattern}}"',
573 | fr: 'doit correspondre au format "{{=e.params.pattern}}"',
574 | hu: 'meg kell feleljen a következő mintának: "{{=e.params.pattern}}"',
575 | id: 'harus cocok dengan pola "{{=e.params.pattern}}"',
576 | it: 'deve corrispondere al formato "{{=e.params.pattern}}"',
577 | ja: '"{{=e.params.pattern}}"のパターンと一致しなければいけない',
578 | ko: '"{{=e.params.pattern}}"패턴과 일치해야 합니다',
579 | nb: 'må samsvare med mønsteret "{{=e.params.pattern}}"',
580 | nl: 'moet overeenkomen met het volgende patroon: "{{=e.params.pattern}}"',
581 | pl: 'powinien zgadzać się ze wzorem "{{=e.params.pattern}}"',
582 | "pt-BR": 'deve corresponder ao padrão "{{=e.params.pattern}}"',
583 | ru: 'должно соответствовать образцу "{{=e.params.pattern}}"',
584 | sk: 'musí splňovať regulárny výraz "{{=e.params.pattern}}"',
585 | sv: 'borde matcha mönstret "{{=e.params.pattern}}"',
586 | th: 'ต้องตรงตาม pattern "{{=e.params.pattern}}"',
587 | zh: '应当匹配模式 "{{=e.params.pattern}}"',
588 | "zh-TW": '應該符合模式 "{{=e.params.pattern}}"',
589 | },
590 | required: {
591 | en: "must have required property {{=e.params.missingProperty}}",
592 | ar: "هذا الحقل إلزامي",
593 | ca: "ha de tenir la propietat requerida {{=e.params.missingProperty}}",
594 | cs: "musí obsahovat požadovanou položku {{=e.params.missingProperty}}",
595 | de: "muss das erforderliche Attribut {{=e.params.missingProperty}} enthalten",
596 | es: "debe tener la propiedad requerida {{=e.params.missingProperty}}",
597 | fi: "täytyy sisältää vaadittu ominaisuus {{=e.params.missingProperty}}",
598 | fr: "requiert la propriété {{=e.params.missingProperty}}",
599 | hu: "kell legyen {{=e.params.missingProperty}} tulajdonsága",
600 | id: "harus memiliki properti {{=e.params.missingProperty}}",
601 | it: "deve avere l'attributo obbligatorio {{=e.params.missingProperty}}",
602 | ja: "必要なプロパティ{{=e.params.missingProperty}}がなければいけない",
603 | ko: "{{=e.params.missingProperty}} 속성은 필수입니다",
604 | nb: "må ha den påkrevde egenskapen {{=e.params.missingProperty}}",
605 | nl: "moet de eigenschap {{=e.params.missingProperty}} bevatten",
606 | pl: "powinien zawierać wymagane pole {{=e.params.missingProperty}}",
607 | "pt-BR": "deve ter a propriedade obrigatória {{=e.params.missingProperty}}",
608 | ru: "должно иметь обязательное поле {{=e.params.missingProperty}}",
609 | sk: "musí obsahovať požadovanú položku {{=e.params.missingProperty}}",
610 | sv: "borde ha den nödvändiga egenskapen {{=e.params.missingProperty}}",
611 | th: "ต้องมี property {{=e.params.missingProperty}} ด้วย",
612 | zh: "应当有必需属性 {{=e.params.missingProperty}}",
613 | "zh-TW": "應該有必須屬性 {{=e.params.missingProperty}}",
614 | },
615 | type: {
616 | _defs: {
617 | t: "{{var t = e.params.type;}}",
618 | },
619 | en: "must be {{=e.params.type}}",
620 | ar: "قيمة هذا الحقل غير صالحة",
621 | ca: "ha de ser del tipus {{=e.params.type}}",
622 | cs: "musí být {{=e.params.type}}",
623 | de: "muss sein: {{=e.params.type}}",
624 | es: "debe ser {{=e.params.type}}",
625 | fi: '{{#def.t}}täytyy olla {{? t == "number" }}numero{{?? t == "integer"}}kokonaisluku{{?? t == "string"}}merkkijono{{?? t == "boolean"}}boolean{{??}}{{=t}}{{?}}',
626 | fr: "doit être de type {{=e.params.type}}",
627 | hu: "{{=e.params.type}} kell legyen",
628 | id: "harus berupa {{=e.params.type}}",
629 | it: "deve essere di tipo {{=e.params.type}}",
630 | ja: "{{=e.params.type}}でなければいけない",
631 | ko: "{{=e.params.type}}이여야 합니다",
632 | nb: '{{#def.t}}må være {{? t == "number" }}et tall{{?? t == "integer"}}et heltall{{?? t == "string"}}en streng{{?? t == "boolean"}}ja eller nei{{??}}{{=t}}{{?}}',
633 | nl: '{{#def.t}}moet een {{? t == "number" }}nummer{{?? t == "integer"}}geheel getal{{?? t == "string"}}tekenreeks{{?? t == "boolean"}}ja of nee waarde{{?}} ({{=t}}) bevatten',
634 | pl: "powinien być {{=e.params.type}}",
635 | "pt-BR":
636 | '{{#def.t}}deve ser {{? t == "number" }}um número{{?? t == "integer"}}um número inteiro{{?? t == "string"}}um texto{{?? t == "boolean"}}um booleano{{??}}{{=t}}{{?}}',
637 | ru: "должно быть {{=e.params.type}}",
638 | sk: "musí byť {{=e.params.type}}",
639 | sv: "borde vara {{=e.params.type}}",
640 | th: "ต้องเป็น {{=e.params.type}}",
641 | zh: "应当是 {{=e.params.type}} 类型",
642 | "zh-TW": "應該是 {{=e.params.type}} 類型",
643 | },
644 | unevaluatedProperties: {
645 | en: "must NOT have unevaluated properties",
646 | de: "darf keine unausgewerteten Attribute haben",
647 | fi: "ei saa sisältää arvioimattomia ominaisuuksia",
648 | it: "non deve avere attributi non valutati",
649 | ko: "평가되지 않은 속성이 없어야합니다.",
650 | nl: "mag geen ongecontroleerde eigenschappen bevatten",
651 | "pt-BR": "não pode possuir propridades não avaliadas",
652 | ru: "не должно иметь непроверенных полей",
653 | th: "ต้องไม่มี property ที่ยังไม่ได้ผ่านการตรวจสอบเงื่อนไขใดๆ",
654 | zh: "不允许存在未求值的属性",
655 | "zh-TW": "不應該有未驗證的屬性",
656 | },
657 | unevaluatedItems: {
658 | _defs: {
659 | n: "{{var n = e.params.len;}}",
660 | },
661 | en: "{{#def.n}}must NOT have more than {{=n}} item{{#def.mPlural}}",
662 | de: "{{#def.n}}darf nicht mehr als {{=n}} Element{{#def.mPlural}} haben",
663 | fi: "{{#def.n}}ei saa olla enemmän kuin {{=n}} elementti{{? n!=1 }}ä{{?}}",
664 | it: "{{#def.n}}non deve avere più di {{=n}} elementi{{#def.mPlural}}",
665 | ko: "{{#def.n}}항목이 {{=n}}개 아이템을 초과하면 안됩니다",
666 | nl: "{{#def.n}}mag niet meer dan {{= n}} item{{#def.mPlural}} bevatten",
667 | "pt-BR": "{{#def.n}}não pode possuir mais que {{=n}} {{? n==1 }}item{{??}}itens{{?}}",
668 | ru: "{{#def.n}}должно иметь не более, чем {{=n}} элемент{{#def.mPlural}}",
669 | th: "{{#def.n}}ต้องมีไม่เกิน {{=n}} ตัว",
670 | zh: "{{#def.n}} 不允许有超过 {{=n}} 个元素",
671 | "zh-TW": "{{#def.n}} 的元素不可以超過 {{=n}} 個",
672 | },
673 | uniqueItems: {
674 | en: "must NOT have duplicate items (items ## {{=e.params.j}} and {{=e.params.i}} are identical)",
675 | ar: "يجب أن لا يحوي عناصر مكررة (العنصر ## {{=e.params.j}} و {{=e.params.i}} متطابقة)",
676 | ca: "no ha de tenir ítems duplicats (els ítems ## {{=e.params.j}} i {{=e.params.i}} són idèntics)",
677 | cs: "nesmí obsahovat duplicitní prvky (prvky ## {{=e.params.j}} a {{=e.params.i}} jsou identické)",
678 | de: "darf keine Duplikate enthalten (Elemente #{{=e.params.j}} und #{{=e.params.i}} sind gleich)",
679 | es: "no debe contener elementos duplicados, (los elementos ## {{=e.params.j}} y {{=e.params.i}} son idénticos)",
680 | fi: "ei saa sisältää duplikaatteja (elementit ## {{=e.params.j}} ja {{=e.params.i}} ovat identtiset)",
681 | fr: "ne doit pas contenir de doublons (les éléments ## {{=e.params.j}} et {{=e.params.i}} sont identiques)",
682 | hu: "nem lehetnek azonos elemei ({{=e.params.j}} és {{=e.params.i}} elemek azonosak)",
683 | id: "tidak boleh memiliki item duplikat (item ## {{=e.params.j}} dan {{=e.params.i}} identik)",
684 | it: "non deve avere duplicati (gli elementi ## {{=e.params.j}} e {{=e.params.i}} sono uguali)",
685 | ja: "重複するアイテムがあってはいけない({{=e.params.j}}と{{=e.params.i}}は同じである)",
686 | ko: "중복 아이템이 없어야 합니다 (아이템{{=e.params.j}}과 아이템{{=e.params.i}}가 동일합니다)",
687 | nb: "kan ikke ha duplikate elemeneter (elementene ## {{=e.params.j}} og {{=e.params.i}} er identiske)",
688 | nl: "mag geen gedupliceerde items bevatten (items ## {{=e.params.j}} en {{=e.params.i}} zijn identiek)",
689 | pl: "nie powinien zawierać elementów które się powtarzają (elementy {{=e.params.j}} i {{=e.params.i}} są identyczne)",
690 | "pt-BR":
691 | "não deve ter itens duplicados (os itens ## {{=e.params.j}} e {{=e.params.i}} são idênticos)",
692 | ru: "не должно иметь повторяющихся элементов (элементы {{=e.params.j}} и {{=e.params.i}} идентичны)",
693 | sk: "nesmie obsahovať duplicitné prvky (prvky ## {{=e.params.j}} a {{=e.params.i}} sú rovnaké)",
694 | sv: "borde inte ha duplicerade saker (sakerna ## {{=e.params.j}} och {{=e.params.i}} är identiska)",
695 | th: "ต้องมีสมาชิกไม่ซ้ำักัน (ลำดับที่ {{=e.params.j}} กับ {{=e.params.i}} ซ้ำกัน)",
696 | zh: "不应当含有重复项 (第 {{=e.params.j}} 项与第 {{=e.params.i}} 项是重复的)",
697 | "zh-TW": "不應該有重複項目 (第 {{=e.params.j}} 項和第 {{=e.params.i}} 項是重複的)",
698 | },
699 | propertyNames: {
700 | en: "property name is invalid",
701 | ar: "اسم الخاصية غير صالح",
702 | ca: "la propietat no és vàlida",
703 | cs: "název položky není platný",
704 | de: "Attributname ist ungültig",
705 | es: "la propiedad no és válida",
706 | fi: "ominaisuuden nimi on virheellinen",
707 | fr: "le nom de propriété est invalide",
708 | id: "nama properti tidak valid",
709 | it: "il nome dell'attritbuto non è valido",
710 | ko: "속성명이 올바르지 않습니다",
711 | nb: "egenskapen med navnet '{{e.params.propertyName}}' er ugyldig",
712 | nl: "eigenschapnaam is ongeldig",
713 | "pt-BR": "o nome da propriedade é inválido",
714 | ru: "имя поля не соответствует схеме",
715 | sk: "názov položky nezodpovedá schéme",
716 | sv: "egenskap med namnet är inte giltig",
717 | th: "ชื่อ property ไม่ถูกต้อง",
718 | zh: "属性名 无效",
719 | "zh-TW": "属性名 無效",
720 | },
721 | patternRequired: {
722 | en: 'must have property matching pattern "{{=e.params.missingPattern}}"',
723 | ar: 'يجب أن يحوي خاصية توافق النمط "{{=e.params.missingPattern}}"',
724 | ca: 'la propietat ha de coincidir amb el patró "{{=e.params.missingPattern}}"',
725 | cs: 'musí obsahovat položku vyhovující regulárnímu výrazu "{{=e.params.missingPattern}}"',
726 | de: 'muss ein Attribut nach folgendem Muster haben "{{=e.params.missingPattern}}"',
727 | es: 'la propiedad debe coincidir con el patrón "{{=e.params.missingPattern}}"',
728 | fi: 'täytyy sisältää ominaisuus joka vastaa kaavaa "{{=e.params.missingPattern}}"',
729 | fr: 'la propriété doit correspondre au format "{{=e.params.missingPattern}}"',
730 | id: 'harus memiliki pola pencocokan properti "{{=e.params.missingPattern}}"',
731 | it: 'deve avere un attributo che corrisponda al formato "{{=e.params.missingPattern}}"',
732 | ko: '"{{=e.params.missingPattern}}"패턴과 일치하는 속성을 가져야 합니다',
733 | nb: 'må ha en egenskap som samsvarer med mønsteret "{{=e.params.missingPattern}}',
734 | nl: 'moet een eigenschap bevatten die overeenkomt met het pattroon: "{{=e.params.missingPattern}}"',
735 | pl: 'powinien mieć pole pasujące do wzorca "{{=e.params.missingPattern}}"',
736 | "pt-BR": 'deve ter a propriedade correspondente ao padrão "{{=e.params.missingPattern}}"',
737 | ru: 'должно иметь поле, соответствующее образцу "{{=e.params.missingPattern}}"',
738 | sk: 'musí obsahovať položku splňjúcu regulárny výraz "{{=e.params.missingPattern}}"',
739 | sv: 'bör ha en egenskap som matchar mönstret "{{=e.params.missingPattern}}"',
740 | th: 'ต้องมี property ที่มีชื่อตรงตาม pattern "{{=e.params.missingPattern}}"',
741 | zh: "应当有属性匹配模式 {{=e.params.missingPattern}}",
742 | "zh-TW": "應該有屬性對應模式 {{=e.params.missingPattern}}",
743 | },
744 | const: {
745 | en: "must be equal to constant",
746 | ar: "يجب أن يكون ثابتاً",
747 | ca: "ha de ser igual a la constant",
748 | cs: "musí být roven konstantě",
749 | de: "muss gleich der Konstanten sein",
750 | es: "debe ser igual a la constante",
751 | fi: "täytyy olla yhtä kuin vakio",
752 | fr: "doit être égal à la constante",
753 | id: "harus sama dengan konstan",
754 | it: "deve essere uguale alla costante",
755 | ko: "상수와 같아야합니다",
756 | nb: "må være lik konstanten",
757 | nl: "moet gelijk zijn aan constante",
758 | pl: "powinien być równy stałej",
759 | "pt-BR": "deve ser igual à constante",
760 | ru: "должно быть равно заданному значению",
761 | sk: "musí byť konštanta",
762 | sv: "bör vara en konstant",
763 | th: "ต้องเท่ากับค่าคงที่",
764 | zh: "应当等于常量",
765 | "zh-TW": "應該等於常數",
766 | },
767 | contains: {
768 | en: "must contain a valid item",
769 | ar: "يجب أن يحوي عنصرا صحيح",
770 | ca: "ha de contenir un ítem vàlid",
771 | cs: "musí obsahovat prvek odpovídající schématu",
772 | de: "muss ein valides Element enthalten",
773 | es: "debe contener un elemento válido",
774 | fi: "täytyy sisältää kelvollinen elementti",
775 | fr: "doit contenir un élément valide",
776 | id: "harus berisi item yang valid",
777 | it: "deve contentere un elemento valido",
778 | ko: "올바른 아이템을 포함해야 합니다",
779 | nb: "må inneholde et gyldig element",
780 | nl: "moet een geldig item bevatten",
781 | "pt-BR": "deve conter um item válido",
782 | ru: "должно содержать значение соответствующее схеме",
783 | sk: "musí obsahovať prvok zodpovedajúci schéme",
784 | sv: "bör innehålla ett giltigt objekt",
785 | th: "ต้องมีสมาชิกที่ผ่านเงื่อนไขอยู่",
786 | zh: "应当包含一个有效项",
787 | "zh-TW": "應該包含一個有效元素",
788 | },
789 | formatMaximum: {
790 | _keywords: ["formatExclusiveMaximum"],
791 | _defs: {
792 | c: '{{var cond = e.params.comparison + " " + e.params.limit;}}',
793 | },
794 | en: "{{#def.c}}must be {{=cond}}",
795 | ar: "{{#def.c}} يجب أن يكون {{=cond}}",
796 | ca: "{{#def.c}}ha de ser {{=cond}}",
797 | cs: "{{#def.c}}musí být {{=cond}}",
798 | de: "{{#def.c}}muss {{=cond}} sein",
799 | es: "{{#def.c}}debe ser {{=cond}}",
800 | fi: "{{#def.c}}täytyy olla {{=cond}}",
801 | fr: "{{#def.c}}doit être {{=cond}}",
802 | id: "{{#def.c}}harus {{=cond}}",
803 | it: "{{#def.c}}deve essere {{=cond}}",
804 | ko: "{{#def.c}} {{=cond}} 이여야 합니다",
805 | nb: "{{#def.c}}må være {{=cond}}",
806 | nl: "{{#def.c}}moet {{=cond}} zijn",
807 | pl: "{{#def.c}}powinien być {{=cond}}",
808 | "pt-BR": "{{#def.c}}deve ser {{=cond}}",
809 | ru: "{{#def.c}}должно быть {{=cond}}",
810 | sk: "{{#def.c}}musí byť {{=cond}}",
811 | sv: "{{#def.c}}bör vara {{=cond}}",
812 | th: "{{#def.c}}ต้อง {{=cond}}",
813 | zh: "{{#def.c}}应当是 {{=cond}}",
814 | "zh-TW": "{{#def.c}}應該是 {{=cond}}",
815 | },
816 | formatMinimum: {
817 | _keywords: ["formatExclusiveMinimum"],
818 | _defs: {
819 | c: '{{var cond = e.params.comparison + " " + e.params.limit;}}',
820 | },
821 | en: "{{#def.c}}must be {{=cond}}",
822 | ar: "{{#def.c}} يجب أن يكون {{=cond}}",
823 | ca: "{{#def.c}}ha de ser {{=cond}}",
824 | cs: "{{#def.c}}musí být {{=cond}}",
825 | de: "{{#def.c}}muss {{=cond}} sein",
826 | es: "{{#def.c}}debe ser {{=cond}}",
827 | fi: "{{#def.c}}täytyy olla {{=cond}}",
828 | fr: "{{#def.c}}doit être {{=cond}}",
829 | id: "{{#def.c}}harus {{=cond}}",
830 | it: "{{#def.c}}deve essere {{=cond}}",
831 | ko: "{{#def.c}} {{=cond}} 이여야 합니다",
832 | nb: "{{#def.c}}må være {{=cond}}",
833 | nl: "{{#def.c}}moet {{=cond}} zijn",
834 | pl: "{{#def.c}}powinien być {{=cond}}",
835 | "pt-BR": "{{#def.c}}deve ser {{=cond}}",
836 | ru: "{{#def.c}}должно быть {{=cond}}",
837 | sk: "{{#def.c}}musí byť {{=cond}}",
838 | sv: "{{#def.c}}bör vara {{=cond}}",
839 | th: "{{#def.c}}ต้อง {{=cond}}",
840 | zh: "{{#def.c}}应当是 {{=cond}}",
841 | "zh-TW": "{{#def.c}}應該是 {{=cond}}",
842 | },
843 | if: {
844 | en: 'must match "{{=e.params.failingKeyword}}" schema',
845 | ar: 'يجب أن توافق المخطط "{{=e.params.failingKeyword}}"',
846 | ca: 'ha de correspondre’s amb l’esquema "{{=e.params.failingKeyword}}"',
847 | cs: 'musí vyhovět "{{=e.params.failingKeyword}}" schématu',
848 | de: 'muss dem Schema "{{=e.params.failingKeyword}}" entsprechen',
849 | es: 'debe corresponderse con el esquema "{{=e.params.failingKeyword}}"',
850 | fi: 'täytyy vastata "{{=e.params.failingKeyword}}" skeemaa',
851 | fr: 'doit correspondre au schéma "{{=e.params.failingKeyword}}"',
852 | id: 'harus cocok dengan skema "{{=e.params.failingKeyword}}"',
853 | it: 'deve corrispondere allo schema "{{=e.params.failingKeyword}}"',
854 | ko: '"{{=e.params.failingKeyword}}" 스키마와 일치해야 합니다',
855 | nl: 'moet overeenkomen met "{{=e.params.failingKeyword}}" schema',
856 | "pt-BR": 'deve corresponder ao schema "{{=e.params.failingKeyword}}"',
857 | ru: 'должно соответствовать схемe "{{=e.params.failingKeyword}}"',
858 | th: 'ต้องตรงกับ schema "{{=e.params.failingKeyword}}"',
859 | zh: '应当匹配模式 "{{=e.params.failingKeyword}}" ',
860 | "zh-TW": '應該符合 "{{=e.params.failingKeyword}}" schema',
861 | },
862 | discriminator: {
863 | _type: false,
864 | tag: {
865 | en: 'tag "{{=e.params.tag}}" must be string',
866 | de: 'der Tag "{{=e.params.tag}}" muss eine Zeichenkette sein',
867 | fi: 'tunniste "{{=e.params.tag}}" täytyy olla merkkijono',
868 | it: 'il tag "{{=e.params.tag}}" deve essere di tipo stringa',
869 | ko: '"{{=e.params.tag}}"태그는 반드시 문자열이여야 합니다',
870 | nl: 'tag "{{=e.params.tag}}" moet een tekenreeks zijn',
871 | "pt-BR": 'a tag "{{=e.params.tag}}" deve ser uma string',
872 | ru: 'поле "{{=e.params.tag}}" должно быть строкой',
873 | th: 'tag "{{=e.params.tag}}" ต้องเป็น string',
874 | zh: '标签 "{{=e.params.tag}}" 的类型必须为字符串',
875 | "zh-TW": '標籤 "{{=e.params.tag}}" 的類型必須是字串',
876 | },
877 | mapping: {
878 | en: 'value of tag "{{=e.params.tag}}" must be in oneOf',
879 | de: 'der Wert vom Tag "{{=e.params.tag}}" muss im oneOf enthalten sein',
880 | fi: 'tunnisteen "{{=e.params.tag}}" arvon muoto pitää olla oneOf',
881 | it: 'il valore del tag "{{=e.params.tag}}" deve essere nei oneOf',
882 | ko: '"{{=e.params.tag}}"태그의 값은 반드시 oneOf에 있어야 합니다',
883 | nl: 'de waarde van het veld "{{= e.params.tag}}" moet voorkomen in de oneOf',
884 | "pt-BR": 'o valor da tag "{{=e.params.tag}}" deve estar no oneOf',
885 | ru: 'значение поля "{{=e.params.tag}}" должно быть в одной из oneOf схем ',
886 | th: 'ต้องมีค่าของ tag "{{=e.params.tag}}" ใน oneOf',
887 | zh: '标签 "{{=e.params.tag}}" 的值必须在 oneOf 之中',
888 | "zh-TW": '標籤 "{{=e.params.tag}}" 必須在 oneOf 其中之一',
889 | },
890 | },
891 | }
892 |
--------------------------------------------------------------------------------
/messages/jtd.js:
--------------------------------------------------------------------------------
1 | "use strict"
2 |
3 | /**
4 | * When adding new locales, please maintain alphabetic ordering.
5 | * "en" should remain in the first position.
6 | * Tests will fail otherwise.
7 | */
8 |
9 | module.exports = {
10 | // supported locales
11 | _locales: [
12 | "en",
13 | "ca",
14 | "cs",
15 | "de",
16 | "es",
17 | "fi",
18 | "fr",
19 | "hu",
20 | "id",
21 | "it",
22 | "ja",
23 | "ko",
24 | "nb",
25 | "nl",
26 | "pl",
27 | "pt-BR",
28 | "ru",
29 | "sk",
30 | "sv",
31 | "th",
32 | "zh",
33 | "zh-TW",
34 | ],
35 |
36 | // shared defines
37 | _defs: {},
38 |
39 | // error messages
40 | _defaultMessage: {
41 | en: 'must pass "{{=e.keyword}}" keyword validation',
42 | ca: 'ha de passar la validació de la clau "{{=e.keyword}}"',
43 | cs: 'musí vyhovět "{{=e.keyword}}" validaci',
44 | de: 'muss die Validierung "{{=e.keyword}}" bestehen',
45 | es: 'debe pasar la validación de palabra clave "{{=e.keyword}}"',
46 | fi: 'täytyy läpäistä "{{=e.keyword}}" avainsanatarkistus',
47 | fr: 'doit être valide selon le critère "{{=e.keyword}}"',
48 | id: 'harus lulus validasi kata kunci "{{=e.keyword}}"',
49 | it: 'deve essere valido secondo il criterio "{{=e.keyword}}"',
50 | ko: '"{{=e.keyword}}"키워드 검사를 통과해야 합니다',
51 | nb: "må samsvare med valideringen for {{=e.keyword}}",
52 | nl: 'moet sleutelwoord validatie "{{=e.keyword}}" doorstaan',
53 | pl: 'powinien przejść walidację "{{=e.keyword}}"',
54 | "pt-BR": 'deve passar a validação da keyword "{{=e.keyword}}"',
55 | ru: 'должно соответствовать правилу "{{=e.keyword}}"',
56 | sk: 'musí splniť "{{=e.keyword}}" validáciu',
57 | sv: 'bör passera "{{=e.keyword}}" nyckelord validering',
58 | th: 'ต้องผ่านคีย์เวิร์ด "{{=e.keyword}}"',
59 | zh: '应当通过 "{{=e.keyword}} 关键词校验"',
60 | "zh-TW": '應該通過 "{{=e.keyword}} 關鍵詞檢驗"',
61 | },
62 |
63 | _type: {
64 | _defs: {
65 | t: "{{var t = e.params.type; var n = e.params.nullable ? '/null' : '';}}",
66 | },
67 | en: "{{#def.t}}must be {{=t+n}}",
68 | ca: "{{#def.t}}ha de ser del tipus {{=t+n}}",
69 | cs: "{{#def.t}}musí být {{=t+n}}",
70 | de: "{{#def.t}}muss sein: {{=t+n}}",
71 | es: "{{#def.t}}debe ser {{=t+n}}",
72 | fi: "{{#def.t}}täytyy olla {{=t+n}}",
73 | fr: "{{#def.t}}doit être de type {{=t+n}}",
74 | hu: "{{#def.t}}{{=t+n}} kell legyen",
75 | id: "{{#def.t}}harus berupa {{=t+n}}",
76 | it: "{{#def.t}}deve essere di tipo {{=t+n}}",
77 | ja: "{{#def.t}}{{=t+n}}でなければいけない",
78 | ko: "{{#def.t}}{{=t+n}}이여야 합니다",
79 | nb: '{{#def.t}}må være {{? t == "number" }}et tall{{?? t == "integer"}}et heltall{{?? t == "string"}}en streng{{?? t == "boolean"}}ja eller nei{{??}}{{=t}}{{?}}{{=n}}',
80 | nl: '{{#def.t}}moet een {{? t == "number" }}nummer{{?? t == "integer"}}geheel getal{{?? t == "string"}}tekenreeks{{?? t == "boolean"}}ja of nee waarde{{?}}{{=n}} ({{=t}}) bevatten',
81 | pl: "{{#def.t}}powinien być {{=t+n}}",
82 | "pt-BR":
83 | '{{#def.t}}deve ser {{? t == "number" }}um número{{?? t == "integer"}}um número inteiro{{?? t == "string"}}um texto{{?? t == "boolean"}}um booleano{{??}}{{=t}}{{?}}{{=n}}',
84 | ru: "{{#def.t}}должно быть {{=t+n}}",
85 | sk: "{{#def.t}}musí byť {{=t+n}}",
86 | sv: "{{#def.t}}borde vara {{=t+n}}",
87 | th: "{{#def.t}}ต้องเป็น {{=t+n}}",
88 | zh: "{{#def.t}}应当是 {{=t+n}} 类型",
89 | "zh-TW": "{{#def.t}}應該是 {{=t+n}} 類型",
90 | },
91 |
92 | type: {
93 | _keywords: ["elements", "values"],
94 | _type: true,
95 | },
96 |
97 | properties: {
98 | _type: true,
99 | additional: {
100 | en: "must NOT have additional properties",
101 | ca: "no ha de tenir propietats addicionals",
102 | cs: "nemůže mít další položky",
103 | de: "darf keine zusätzlichen Attribute haben",
104 | es: "no debe tener propiedades adicionales",
105 | fi: "ei saa sisältää ylimääräisiä ominaisuuksia",
106 | fr: "ne doit pas contenir de propriétés additionnelles",
107 | hu: "nem lehetnek további elemei",
108 | id: "tidak boleh memiliki properti tambahan",
109 | it: "non deve avere attributi addizionali",
110 | ja: "追加してはいけない",
111 | ko: "추가적인 속성은 허용되지 않습니다",
112 | nb: "kan ikke ha flere egenskaper",
113 | nl: "mag geen extra eigenschappen bevatten",
114 | pl: "nie powinien zawierać dodatkowych pól",
115 | "pt-BR": "não deve ter propriedades adicionais",
116 | ru: "не должно иметь дополнительных полей",
117 | sk: "nemôže obsahovať ďalšie položky",
118 | sv: "borde inte ha fler egenskaper",
119 | th: "ต้องไม่มี property อื่นๆ นอกเหนีอจากที่กำหนดไว้",
120 | zh: "不允许有额外的属性",
121 | "zh-TW": "不可以有額外的屬性",
122 | },
123 | missing: {
124 | en: "must have property {{=e.params.missingProperty}}",
125 | ca: "ha de tenir la propietat requerida {{=e.params.missingProperty}}",
126 | cs: "musí obsahovat požadovanou položku {{=e.params.missingProperty}}",
127 | de: "muss das erforderliche Attribut {{=e.params.missingProperty}} enthalten",
128 | es: "debe tener la propiedad requerida {{=e.params.missingProperty}}",
129 | fi: "täytyy sisältää ominaisuus {{=e.params.missingProperty}}",
130 | fr: "requiert la propriété {{=e.params.missingProperty}}",
131 | hu: "kell legyen {{=e.params.missingProperty}} tulajdonsága",
132 | id: "harus memiliki properti {{=e.params.missingProperty}}",
133 | it: "deve avere l'attributo obbligatorio {{=e.params.missingProperty}}",
134 | ja: "必要なプロパティ{{=e.params.missingProperty}}がなければいけない",
135 | ko: "{{=e.params.missingProperty}} 속성은 필수입니다",
136 | nb: "må ha den påkrevde egenskapen {{=e.params.missingProperty}}",
137 | nl: "moet de eigenschap {{=e.params.missingProperty}} bevatten",
138 | pl: "powinien zawierać wymagane pole {{=e.params.missingProperty}}",
139 | "pt-BR": "deve ter a propriedade obrigatória {{=e.params.missingProperty}}",
140 | ru: "должно иметь обязательное поле {{=e.params.missingProperty}}",
141 | sk: "musí obsahovať požadovanú položku {{=e.params.missingProperty}}",
142 | sv: "borde ha den nödvändiga egenskapen {{=e.params.missingProperty}}",
143 | th: "ต้องมี property {{=e.params.missingProperty}} ด้วย",
144 | zh: "应当有必需属性 {{=e.params.missingProperty}}",
145 | "zh-TW": "應該有必須屬性 {{=e.params.missingProperty}}",
146 | },
147 | },
148 |
149 | discriminator: {
150 | _type: true,
151 | tag: {
152 | en: 'tag "{{=e.params.tag}}" must be string',
153 | de: 'der Tag "{{=e.params.tag}}" muss eine Zeichenkette sein',
154 | fi: 'tunniste "{{=e.params.tag}}" täytyy olla merkkijono',
155 | it: 'il tag "{{=e.params.tag}}" deve essere di tipo stringa',
156 | ko: '"{{=e.params.tag}}"태그는 문자열이여야 합니다',
157 | nl: 'tag "{{=e.params.tag}}" moet een tekenreeks zijn',
158 | "pt-BR": 'a tag "{{=e.params.tag}}" deve ser uma string',
159 | ru: 'поле "{{=e.params.tag}}" должно быть строкой',
160 | th: 'tag "{{=e.params.tag}}" ต้องเป็น string',
161 | zh: '标签 "{{=e.params.tag}}" 的类型必须为字符串',
162 | "zh-TW": '標籤 "{{=e.params.tag}}" 的類型必須是字串',
163 | },
164 | mapping: {
165 | en: 'value of tag "{{=e.params.tag}}" must be in mapping',
166 | de: 'der Wert vom Tag "{{=e.params.tag}}" muss im Mapping enthalten sein',
167 | fi: 'tunnisteen arvon "{{=e.params.tag}}" on oltava kartoituksessa',
168 | it: 'il valore del tag "{{=e.params.tag}}" deve essere nei mapping',
169 | ko: '"{{=e.params.tag}}"태그의 값은 반드시 매핑에 있어야합니다.',
170 | nl: 'de waarde van het veld "{{= e.params.tag}}" moet voorkomen in de mapping',
171 | "pt-BR": 'o valor da tag "{{=e.params.tag}}" deve estar no mapping',
172 | ru: 'значение поля "{{=e.params.tag}}" должно быть ключом одной из схем',
173 | th: 'ต้องมีค่าของ tag "{{=e.params.tag}}" ใน mapping',
174 | zh: '标签 "{{=e.params.tag}}" 的值必须在 mapping 之中',
175 | "zh-TW": '標籤 "{{=e.params.tag}}" 必須在 mapping 其中之一',
176 | },
177 | },
178 |
179 | enum: {
180 | en: "must be equal to one of the allowed values",
181 | ca: "ha de ser igual a un dels valors predefinits",
182 | cs: "musí být rovno jedné hodnotě z výčtu",
183 | de: "muss einem der vorgegebenen Werte entsprechen",
184 | es: "deber ser igual a uno de los valores predefinidos",
185 | fi: "täytyy olla yhtä kuin jokin sallituista arvoista",
186 | fr: "doit être égal à une des valeurs prédéfinies",
187 | hu: "egyenlő kell legyen valamely előre meghatározott értékkel",
188 | id: "harus sama dengan salah satu dari nilai yang telah ditentukan",
189 | it: "dovrebbe essere uguale ad uno dei valori predefiniti",
190 | ja: "事前に定義された値のいずれかに等しくなければいけない",
191 | ko: "미리 정의된 값중 하나여야 합니다",
192 | nb: "må være lik en av de forhåndsdefinerte verdiene",
193 | nl: "moet overeenkomen met één van de voorgedefinieerde waarden",
194 | pl: "powinien być równy jednej z predefiniowanych wartości",
195 | "pt-BR": "deve ser igual a um dos valores permitidos",
196 | ru: "должно быть равно одному из разрешенных значений",
197 | sk: "musí byť jedna z definovaných hodnôt",
198 | sv: "borde vara ekvivalent med en av dess fördefinierade värden",
199 | th: "ต้องตรงกับหนึ่งในค่าที่กำหนดไว้",
200 | zh: "应当是预设定的枚举值之一",
201 | "zh-TW": "應該要在預設的值之中",
202 | },
203 |
204 | union: {
205 | en: 'must match a schema in "union"',
206 | ca: 'ha de coincidir amb algun esquema definit a "union"',
207 | cs: 'musí vyhovět alespoň jednomu schématu v "union"',
208 | de: 'muss einem der Schemata in "union" entsprechen',
209 | es: 'debe coincidir con algún esquema en "union"',
210 | fi: 'täytyy vastata "union" skeemaa',
211 | fr: 'doit correspondre à un schéma de "union"',
212 | hu: 'meg kell feleljen legalább egy "union" alaknak',
213 | id: 'harus cocok dengan beberapa skema pada "union"',
214 | it: 'deve corrispondere ad uno schema in "union"',
215 | ja: '"union"のスキーマとマッチしなくてはいけない',
216 | ko: '"union"의 스키마와 일치해야 합니다',
217 | nb: 'må samsvare med et schema i "union"',
218 | nl: 'moet overeenkomen met een schema in "union"',
219 | pl: 'powinien pasować do wzoru z sekcji "union"',
220 | "pt-BR": 'os dados não correspondem a nenhum schema de "union"',
221 | ru: 'должно соответствовать одной их схем в "union"',
222 | sk: 'musí splňovať aspoň jednu zo schém v "union"',
223 | sv: 'borde matcha något schema i "union"',
224 | th: 'ต้องตรงกับหนึ่งใน schema ที่กำหนดไว้ใน "union"',
225 | zh: "数据应为 union 所指定的其中一个",
226 | "zh-TW": "不符合 union 指定的模式",
227 | },
228 | }
229 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ajv-i18n",
3 | "version": "4.2.0",
4 | "description": "Internationalised error messages for Ajv JSON validator",
5 | "main": "localize/index.js",
6 | "types": "localize/index.d.ts",
7 | "files": [
8 | "localize/",
9 | "LICENSE"
10 | ],
11 | "scripts": {
12 | "build": "npm run build:json-schema && npm run build:jtd",
13 | "build:json-schema": "node scripts/compile-locales.js '' index",
14 | "build:jtd": "node scripts/compile-locales.js '/jtd' jtd",
15 | "eslint": "eslint messages scripts spec/*.js",
16 | "prepublish": "npm run build",
17 | "test": "npm run prettier:check && npm run eslint && npm run build && npm run test-cov",
18 | "test-spec": "mocha spec/*.spec.js -R dot",
19 | "test-cov": "nyc npm run test-spec",
20 | "prettier:write": "prettier --write \"./**/*.{json,yaml,js,ts}\"",
21 | "prettier:check": "prettier --list-different \"./**/*.{json,yaml,js,ts}\""
22 | },
23 | "repository": {
24 | "type": "git",
25 | "url": "git+https://github.com/epoberezkin/ajv-i18n.git"
26 | },
27 | "keywords": [
28 | "ajv",
29 | "JSON",
30 | "schema",
31 | "i18n",
32 | "internationalisation"
33 | ],
34 | "author": "Evgeny Poberezkin",
35 | "license": "MIT",
36 | "bugs": {
37 | "url": "https://github.com/epoberezkin/ajv-i18n/issues"
38 | },
39 | "homepage": "https://github.com/epoberezkin/ajv-i18n#readme",
40 | "devDependencies": {
41 | "@ajv-validator/config": "^0.3.0",
42 | "ajv": "^8.0.0",
43 | "ajv-formats": "^2.0.0",
44 | "ajv-keywords": "^5.0.0",
45 | "dot": "^1.0.3",
46 | "eslint": "^7.8.1",
47 | "eslint-config-prettier": "^8.1.0",
48 | "husky": "^7.0.1",
49 | "json-schema-test": "^2.0.0",
50 | "lint-staged": "^11.1.1",
51 | "mocha": "^9.0.3",
52 | "nyc": "^15.0.0",
53 | "prettier": "^2.2.1"
54 | },
55 | "peerDependencies": {
56 | "ajv": "^8.0.0-beta.0"
57 | },
58 | "nyc": {
59 | "exclude": [
60 | "**/spec/**",
61 | "node_modules"
62 | ],
63 | "reporter": [
64 | "lcov",
65 | "text-summary"
66 | ]
67 | },
68 | "prettier": "@ajv-validator/config/prettierrc.json",
69 | "husky": {
70 | "hooks": {
71 | "pre-commit": "lint-staged && npm test"
72 | }
73 | },
74 | "lint-staged": {
75 | "*.{json,yaml,js,ts}": "prettier --write"
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/scripts/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | rules:
2 | no-console: 0
3 | no-empty: [2, allowEmptyCatch: true]
4 | dot-notation: [2, allowPattern: "^en$"]
5 |
--------------------------------------------------------------------------------
/scripts/compile-locales.js:
--------------------------------------------------------------------------------
1 | "use strict"
2 |
3 | const doT = require("dot")
4 | const prettier = require("prettier")
5 | const fs = require("fs")
6 | const path = require("path")
7 | let totalMissing = 0
8 |
9 | const [, , importFile, localeFileName] = process.argv
10 | const localeFile = `${localeFileName}.js`
11 | const localeDefFile = `${localeFileName}.d.ts`
12 |
13 | const errorMessages = require(path.join("../messages", importFile))
14 |
15 | const localize = getTemplate("localize.jst")
16 | const localizeDef = getTemplate("localize.d.jst")
17 |
18 | errorMessages._locales.forEach(compileMessages)
19 | saveLocales()
20 | console.log("Total missing messages:", totalMissing)
21 |
22 | function compileMessages(locale) {
23 | const localeDirPath = path.join(__dirname, "..", "localize", locale)
24 | const localePath = path.join(localeDirPath, localeFile)
25 | const localeDefPath = path.join(localeDirPath, localeDefFile)
26 |
27 | try {
28 | fs.mkdirSync(localeDirPath)
29 | } catch (e) {}
30 | const code = localize(localeMessages(locale))
31 | const defCode = localizeDef()
32 | saveCode(localePath, code)
33 | saveCode(localeDefPath, defCode)
34 | }
35 |
36 | function saveLocales() {
37 | const indexDirPath = path.join(__dirname, "..", "localize")
38 | const indexPath = path.join(indexDirPath, localeFile)
39 | const indexDefPath = path.join(indexDirPath, localeDefFile)
40 | const renderIndex = getTemplate("index.jst")
41 | const renderDefIndex = getTemplate("index.d.jst")
42 |
43 | const code = renderIndex({locales: errorMessages._locales, importFile})
44 | const defCode = renderDefIndex({locales: errorMessages._locales, importFile})
45 | saveCode(indexPath, code)
46 | saveCode(indexDefPath, defCode)
47 | }
48 |
49 | function saveCode(filepath, code) {
50 | code = prettier.format(code, {semi: false, filepath})
51 | fs.writeFileSync(filepath, code)
52 | }
53 |
54 | function localeMessages(locale) {
55 | const messages = []
56 | const localeDefs = getLocaleDefs(errorMessages._defs, locale)
57 | const enDefs = getLocaleDefs(errorMessages._defs, "en")
58 |
59 | for (const keyword in errorMessages) {
60 | if (keyword[0] === "_") continue
61 | const msgFunc = compileMessage(keyword)
62 | if (msgFunc) messages.push({keyword, msgFunc, keywords: errorMessages[keyword]._keywords})
63 | }
64 | messages.sort(byKeyword)
65 | return {
66 | locale,
67 | messages,
68 | defaultMessage: compileMessage("_defaultMessage"),
69 | typeMessage: compileMessage("_type"),
70 | }
71 |
72 | function compileMessage(keyword) {
73 | const keyMsgs = errorMessages[keyword]
74 | if (!keyMsgs) return undefined
75 | if (keyMsgs._type !== undefined) {
76 | const msgFuncs = []
77 | for (const error in keyMsgs) {
78 | if (error[0] === "_") continue
79 | const func = compileMsgFunc(keyMsgs[error], `${keyword}/${error}`)
80 | msgFuncs.push({error, func})
81 | }
82 | return msgFuncs
83 | } else {
84 | return compileMsgFunc(keyMsgs, keyword)
85 | }
86 | }
87 |
88 | function compileMsgFunc(_keyMsgs, keyword) {
89 | const keyDefs = _keyMsgs._defs
90 | let msg = _keyMsgs[locale]
91 | let defs
92 |
93 | if (msg) {
94 | defs = localeDefs
95 | } else {
96 | defs = enDefs
97 | totalMissing++
98 | msg = _keyMsgs["en"]
99 | const errorMsg = `message for locale "${locale}" keyword "${keyword}"`
100 | if (msg) {
101 | console.warn(`Warning: Replaced with "en" ${errorMsg}`)
102 | } else {
103 | throw new Error(`Error: No ${errorMsg}`)
104 | }
105 | }
106 |
107 | if (keyDefs) defs = {...defs, ...keyDefs}
108 |
109 | return doT.compile(msg, defs)
110 | }
111 | }
112 |
113 | function getLocaleDefs(defs, locale) {
114 | const localeDefs = {}
115 | for (const key in defs) {
116 | const def = defs[key]
117 | localeDefs[key] = typeof def == "string" ? def : def[locale]
118 | }
119 | return localeDefs
120 | }
121 |
122 | function byKeyword(a, b) {
123 | return a.keyword.localeCompare(b.keyword)
124 | }
125 |
126 | function getTemplate(fileName) {
127 | const tmplStr = fs.readFileSync(path.join(__dirname, "..", "localize", fileName))
128 | return doT.compile(tmplStr)
129 | }
130 |
--------------------------------------------------------------------------------
/scripts/prepare-tests:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | mkdir -p .browser
6 |
7 | ls spec | grep .spec.js | \
8 | xargs -I {} sh -c \
9 | 'export f="{}"; browserify spec/$f -t require-globify -t brfs -x ajv -o .browser/$f;'
10 |
11 |
--------------------------------------------------------------------------------
/spec/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | globals:
2 | describe: false
3 | it: false
4 | before: false
5 |
--------------------------------------------------------------------------------
/spec/localize-jtd.spec.js:
--------------------------------------------------------------------------------
1 | const AjvJTD = require("ajv/dist/jtd").default
2 | const jtdValidationTests = require("./json-typedef-spec/tests/validation.json")
3 | const assert = require("assert")
4 | const localize = require("../localize/jtd")
5 |
6 | const ONLY = []
7 |
8 | describe("JSON Type Definition errors with ajv-i18n", function () {
9 | let ajvs
10 | this.timeout(30000)
11 |
12 | before(() => {
13 | ajvs = [getAjv(false, false), getAjv(false, true), getAjv(true, false), getAjv(true, true)]
14 | })
15 |
16 | for (const testName in jtdValidationTests) {
17 | const {schema, instance, errors} = jtdValidationTests[testName]
18 | const valid = errors.length === 0
19 | describeOnly(testName, () => {
20 | if (valid) {
21 | it("should be valid", () =>
22 | ajvs.forEach((ajv) => assert.strictEqual(ajv.validate(schema, instance), valid)))
23 | } else {
24 | it("should be invalid", () => {
25 | ajvs.forEach((ajv) => {
26 | assert.strictEqual(ajv.validate(schema, instance), valid)
27 | for (const locale in localize) {
28 | localize[locale](ajv.errors)
29 | ajv.errors.forEach((err) => assertStr(err.message))
30 | const text = ajv.errorsText(undefined, {separator: "\n"})
31 | // if (locale == "en") console.log(text)
32 | assertStr(text)
33 | ajv.errors.forEach((err) => {
34 | delete err.message
35 | })
36 | }
37 | })
38 | })
39 | }
40 | })
41 | }
42 | })
43 |
44 | function getAjv(allErrors, verbose) {
45 | return new AjvJTD({allErrors, verbose, messages: false})
46 | }
47 |
48 | function assertStr(str) {
49 | assert.strictEqual(typeof str, "string")
50 | assert(str.length > 0)
51 | assert.strictEqual(str.indexOf("undefined"), -1)
52 | }
53 |
54 | function describeOnly(name, func) {
55 | if (ONLY.length === 0 || ONLY.some((p) => p.test(name))) {
56 | describe(name, func)
57 | } else {
58 | describe.skip(name, func)
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/spec/localize.spec.js:
--------------------------------------------------------------------------------
1 | "use strict"
2 |
3 | const localize = require("../localize")
4 |
5 | const jsonSchemaTest = require("json-schema-test")
6 | const Ajv = require("ajv").default
7 | const Ajv2019 = require("ajv/dist/2019").default
8 | const ajvKeywords = require("ajv-keywords")
9 | const ajvFormats = require("ajv-formats")
10 | const assert = require("assert")
11 | const {toHash} = require("ajv/dist/compile/util")
12 |
13 | const remoteRefs = {
14 | "http://localhost:1234/integer.json": require("./JSON-Schema-Test-Suite/remotes/integer.json"),
15 | "http://localhost:1234/subSchemas.json": require("./JSON-Schema-Test-Suite/remotes/subSchemas.json"),
16 | "http://localhost:1234/subSchemas-defs.json": require("./JSON-Schema-Test-Suite/remotes/subSchemas-defs.json"),
17 | "http://localhost:1234/baseUriChange/folderInteger.json": require("./JSON-Schema-Test-Suite/remotes/baseUriChange/folderInteger.json"),
18 | "http://localhost:1234/baseUriChangeFolder/folderInteger.json": require("./JSON-Schema-Test-Suite/remotes/baseUriChangeFolder/folderInteger.json"),
19 | "http://localhost:1234/baseUriChangeFolderInSubschema/folderInteger.json": require("./JSON-Schema-Test-Suite/remotes/baseUriChangeFolderInSubschema/folderInteger.json"),
20 | "http://localhost:1234/name.json": require("./JSON-Schema-Test-Suite/remotes/name.json"),
21 | "http://localhost:1234/name-defs.json": require("./JSON-Schema-Test-Suite/remotes/name-defs.json"),
22 | }
23 |
24 | const SKIP_DRAFT7 = [
25 | "format/idn-email",
26 | "format/idn-hostname",
27 | "format/iri",
28 | "format/iri-reference",
29 | "optional/content",
30 | "optional/float-overflow",
31 | ]
32 |
33 | const SKIP = {
34 | draft6: ["optional/float-overflow"],
35 | draft7: SKIP_DRAFT7,
36 | "draft2019-09": [...SKIP_DRAFT7, "recursiveRef"],
37 | }
38 |
39 | const DEFAULT_META = {
40 | draft6: "http://json-schema.org/draft-06/schema#",
41 | }
42 |
43 | const suites = {
44 | draft6: "./JSON-Schema-Test-Suite/tests/draft6/{**/,}*.json",
45 | draft7: "./JSON-Schema-Test-Suite/tests/draft7/{**/,}*.json",
46 | "draft2019-09": "./JSON-Schema-Test-Suite/tests/draft2019-09/{**/,}*.json",
47 | "ajv-keywords": "./ajv-keywords/spec/tests/patternRequired.json",
48 | "ajv-formats": "./ajv-formats/tests/extras/format{Minimum,Maximum}.json",
49 | }
50 |
51 | for (const s in suites) runTests(s)
52 |
53 | function runTests(suite) {
54 | const instances = [
55 | getAjv(suite, false, false),
56 | getAjv(suite, false, true),
57 | getAjv(suite, true, false),
58 | getAjv(suite, true, true),
59 | ]
60 |
61 | instances.forEach((ajv) => {
62 | addRemoteRefs(ajv)
63 | if (DEFAULT_META[suite]) {
64 | ajv.opts.defaultMeta = DEFAULT_META[suite]
65 | }
66 | })
67 |
68 | const tests = {}
69 | tests[suite] = suites[suite]
70 |
71 | jsonSchemaTest(instances, {
72 | description: "Schema tests of " + instances.length + " ajv instances with ajv-i18n",
73 | suites: tests,
74 | afterEach: afterEach,
75 | skip: SKIP[suite],
76 | assert: assert,
77 | cwd: __dirname,
78 | hideFolder: `${suite}/`,
79 | timeout: 30000,
80 | })
81 | }
82 |
83 | function getAjv(suite, allErrors, verbose) {
84 | let ajv
85 | const options = {
86 | strict: false,
87 | logger: false,
88 | messages: false,
89 | allErrors,
90 | verbose,
91 | formats: toHash(["idn-email", "idn-hostname", "iri", "iri-reference"]),
92 | }
93 | switch (suite) {
94 | case "draft2019-09":
95 | ajv = new Ajv2019(options)
96 | break
97 | default:
98 | ajv = new Ajv({...options, ignoreKeywordsWithRef: true})
99 | ajv.addMetaSchema(require("ajv/lib/refs/json-schema-draft-06.json"))
100 | }
101 | ajvFormats(ajvKeywords(ajv, ["patternRequired"]), {keywords: true})
102 | return ajv
103 | }
104 |
105 | function afterEach(res) {
106 | if (res.valid) return
107 | for (const locale in localize) {
108 | localize[locale](res.errors)
109 | res.errors.forEach((err) => {
110 | assertStr(err.message)
111 | })
112 | const text = res.validator.errorsText(undefined, {separator: "\n"})
113 | // if (locale == 'en') console.log(text);
114 | assertStr(text)
115 | res.errors.forEach((err) => {
116 | delete err.message
117 | })
118 | }
119 | }
120 |
121 | function assertStr(str) {
122 | assert.strictEqual(typeof str, "string")
123 | assert(str.length > 0)
124 | // TODO enable this check - fails on unevaluatedItems
125 | // assert.strictEqual(str.indexOf("undefined"), -1)
126 | }
127 |
128 | function addRemoteRefs(ajv) {
129 | for (const id in remoteRefs) {
130 | ajv.addSchema(remoteRefs[id], id)
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/spec/style.spec.js:
--------------------------------------------------------------------------------
1 | "use strict"
2 |
3 | const messages = require("../messages")
4 | const jtdMessages = require("../messages/jtd")
5 | const localize = require("../localize")
6 | const jtdLocalize = require("../localize/jtd")
7 | const assert = require("assert")
8 |
9 | describe("code style: ordering of locales", () => {
10 | describe("JSON Schema", () => {
11 | it("locales in index.js should be ordered (en first)", () => testLocalesProperties(localize))
12 |
13 | it("_locales should be ordered (en first)", () => testLocalesOrder(messages._locales))
14 |
15 | it("locales in _defs should be ordered (en first)", () => {
16 | testLocalesProperties(messages._defs.mPlural, "_defs.mPlural")
17 | testLocalesProperties(messages._defs.propPlural, "_defs.propPlural")
18 | })
19 |
20 | it("locales in keywords should be ordered (en first)", () => {
21 | for (const keyword in messages) {
22 | if (keyword[0] === "_") continue
23 | testLocalesProperties(messages[keyword], "keyword " + keyword)
24 | }
25 | })
26 | })
27 |
28 | describe("JSON Type Definition", () => {
29 | it("locales in index.js should be ordered (en first)", () => testLocalesProperties(jtdLocalize))
30 |
31 | it("_locales should be ordered (en first)", () => testLocalesOrder(jtdMessages._locales))
32 |
33 | it("locales in keywords should be ordered (en first)", () => {
34 | for (const keyword in jtdMessages) {
35 | if (keyword[0] === "_") continue
36 | testLocalesProperties(jtdMessages[keyword], "keyword " + keyword)
37 | }
38 | })
39 | })
40 | })
41 |
42 | function testLocalesOrder(locales, message) {
43 | assert.strictEqual(locales[0], "en", message)
44 | const ordered = ["en"].concat(locales.slice(1).sort())
45 | assert.deepStrictEqual(locales, ordered, message)
46 | }
47 |
48 | function testLocalesProperties(obj, message) {
49 | if (obj && obj._type !== undefined) {
50 | for (const errorType in obj) {
51 | if (errorType[0] === "_") continue
52 | testLocalesProperties(obj[errorType], `${message} (${errorType})`)
53 | }
54 | } else {
55 | const props = Object.keys(obj)
56 | while (props[0][0] === "_") props.shift()
57 | testLocalesOrder(props, message)
58 | }
59 | }
60 |
--------------------------------------------------------------------------------