@jarenjs/locales 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Joham
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.
package/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # @jarenjs/locales
2
+
3
+ Locale packs (message catalogs) for the error messages of
4
+ [`@jarenjs/validate`](../validate/README.md) and
5
+ [`@jarenjs/forms`](../forms/README.md).
6
+
7
+ Jaren validators and form checks never bake prose into the hot path: every
8
+ failure carries a stable message key (`msgid`) plus raw structured
9
+ `params`, and human text is produced at report/render time through a
10
+ **catalog** - a plain flat object of closures. This package is the home of
11
+ the non-English catalogs. The normative contract (message-key registry,
12
+ template syntax, resolution precedence) lives in
13
+ [`packages/validate/docs/ERROR-MESSAGES.md`](../validate/docs/ERROR-MESSAGES.md).
14
+
15
+ ## Usage
16
+
17
+ Post-hoc localization of a collect-mode validation result:
18
+
19
+ ```js
20
+ import { JarenValidator, compileMessageCatalog, localizeErrors } from '@jarenjs/validate';
21
+ import { nl } from '@jarenjs/locales';
22
+
23
+ const catalog = compileMessageCatalog(nl);
24
+ const validator = new JarenValidator({ collectErrors: true });
25
+ const validate = validator.compile({ type: 'string', minLength: 2 });
26
+
27
+ const result = validate('x');
28
+ localizeErrors(result.errors, catalog);
29
+ // result.errors[0].message === 'mag niet minder dan 2 tekens bevatten'
30
+ ```
31
+
32
+ Per-keystroke form feedback in Dutch:
33
+
34
+ ```js
35
+ import { buildFormModel, validateAllFields, compileMessageCatalog } from '@jarenjs/forms';
36
+ import { nl } from '@jarenjs/locales';
37
+
38
+ const catalog = compileMessageCatalog(nl);
39
+ const errors = validateAllFields(model, data, catalog);
40
+ // errors['/name'][0].message === 'Dit veld is verplicht'
41
+ ```
42
+
43
+ Subpath import when you only want one pack (tree-shaking friendly either
44
+ way - the package is `sideEffects: false`):
45
+
46
+ ```js
47
+ import { nl } from '@jarenjs/locales/nl';
48
+ ```
49
+
50
+ ## Authoring a pack
51
+
52
+ A catalog is a plain flat object; each entry is either a **template
53
+ string** or a **closure**:
54
+
55
+ ```js
56
+ export const xx = {
57
+ // template string: {name} substitutes the params member 'name';
58
+ // {{ escapes a literal brace; unknown names stay literal
59
+ pattern: 'must match pattern "{pattern}"',
60
+
61
+ // closure: full control, receives (params, error)
62
+ minLength: (p) => `at least ${p.limit} character${p.limit === 1 ? '' : 's'}`,
63
+ };
64
+ ```
65
+
66
+ Rules of the road:
67
+
68
+ 1. **Key parity.** Cover every key of validate's `messagesEn`, every
69
+ `form/*` key of forms' `formsMessagesEn`, plus `x-form/assert` and the
70
+ `JQ2xxx` query runtime codes. The repo enforces this with tests
71
+ (`test/locales/`); missing keys silently fall back to English.
72
+ 2. **Never depend on a consumer.** A pack must stay importable without
73
+ dragging in `@jarenjs/validate` or `@jarenjs/forms`, so that either one
74
+ can serve any pack. The platform and `@jarenjs/core` are the only things
75
+ a pack may reach for - core is where the shared value renderer lives, so
76
+ a pack cannot drift from the catalog contract by re-implementing it.
77
+ 3. **Use `Intl`, as module-level singletons.** `Intl.PluralRules` for
78
+ plural categories (see `nl.js`: "1 teken" / "2 tekens"),
79
+ `Intl.NumberFormat` for `{limit}`-style numbers, `Intl.ListFormat` for
80
+ enum lists. Construct them once at module level - catalog entries run
81
+ on the failure path, which is cheap, but allocation discipline is the
82
+ house rule.
83
+ 4. **Bidi.** Packs targeting RTL scripts should isolate interpolated user
84
+ values with FSI/PDI (U+2068/U+2069) so a Latin value cannot reorder
85
+ the surrounding text. That call belongs to the pack author, not core.
86
+ The harder rule, paid for by `ar.js`: **an ASCII comparison operator
87
+ placed between RTL text and a number displays flipped** - the
88
+ operator is bidi-neutral, so `>=` before a Latin-digit limit reorders
89
+ and reads as `=<`. Never interpolate `{comparison}` as a symbol.
90
+ Arabic therefore renders the four operators validate emits for
91
+ `minimum`/`maximum`/`exclusiveMinimum`/`exclusiveMaximum` as whole
92
+ **phrases** ("يجب ألا تقل القيمة عن 2" - "the value must not be less
93
+ than 2"), and falls back for an operator it does not know to the
94
+ symbol wrapped in a directional isolate (U+2066 … U+2069) so it at
95
+ least still reads left-to-right inside the RTL sentence. Do the same
96
+ before shipping a Hebrew, Farsi or Urdu pack, and always eyeball the
97
+ rendered strings - a flipped operator is silently *valid* text.
98
+ 5. **Voice.** Validate keys speak about the document ("must have required
99
+ property 'x'"); `form/*` keys speak to the person filling the field
100
+ ("This field is required"). Keep both voices.
101
+
102
+ ## Available packs
103
+
104
+ | Export | Subpath | Locale |
105
+ |--------|---------|--------|
106
+ | `ar` | `./ar` | Arabic (العربية) - RTL |
107
+ | `de` | `./de` | German (Deutsch) |
108
+ | `es` | `./es` | Spanish (Español) |
109
+ | `fr` | `./fr` | French (Français) |
110
+ | `ja` | `./ja` | Japanese (日本語) |
111
+ | `ko` | `./ko` | Korean (한국어) |
112
+ | `nl` | `./nl` | Dutch (Nederlands) |
113
+ | `pt` | `./pt` | Portuguese (Português) |
114
+ | `ru` | `./ru` | Russian (Русский) |
115
+ | `tr` | `./tr` | Turkish (Türkçe) |
116
+ | `zhTW` | `./zh-tw` | Traditional Chinese, Taiwan (繁體中文) |
117
+
118
+ The named export is the locale tag camel-cased (`zhTW`), the subpath keeps
119
+ the tag itself (`@jarenjs/locales/zh-tw`).
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The Arabic catalog. Covers every key of validate's `messagesEn`,
3
+ * every `form/*` key of forms' `formsMessagesEn`, `x-form/assert`, and
4
+ * the `JQ2xxx` codes reachable through `$query`.
5
+ * @type {Record<string, string | ((params: any, error?: object) => string)>}
6
+ */
7
+ export declare const ar: Record<string, string | ((params: any, error?: object) => string)>;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The German catalog. Covers every key of validate's `messagesEn`, every
3
+ * `form/*` key of forms' `formsMessagesEn`, `x-form/assert`, and the
4
+ * `JQ2xxx` codes reachable through `$query`.
5
+ * @type {Record<string, string | ((params: any, error?: object) => string)>}
6
+ */
7
+ export declare const de: Record<string, string | ((params: any, error?: object) => string)>;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The Spanish catalog. Covers every key of validate's `messagesEn`, every
3
+ * `form/*` key of forms' `formsMessagesEn`, `x-form/assert`, and the
4
+ * `JQ2xxx` codes reachable through `$query`.
5
+ * @type {Record<string, string | ((params: any, error?: object) => string)>}
6
+ */
7
+ export declare const es: Record<string, string | ((params: any, error?: object) => string)>;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The French catalog. Covers every key of validate's `messagesEn`, every
3
+ * `form/*` key of forms' `formsMessagesEn`, `x-form/assert`, and the
4
+ * `JQ2xxx` codes reachable through `$query`.
5
+ * @type {Record<string, string | ((params: any, error?: object) => string)>}
6
+ */
7
+ export declare const fr: Record<string, string | ((params: any, error?: object) => string)>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * The pack-authoring toolkit: the rendering steps every locale pack
3
+ * performs identically, parameterised by the one thing that is actually
4
+ * per-language.
5
+ *
6
+ * Each factory takes a pack's own `Intl` singleton or translated table
7
+ * and returns the render closure the catalog entries call. Building the
8
+ * closure once at module load keeps the packs' allocation discipline:
9
+ * nothing is constructed per message. This module is internal to
10
+ * `@jarenjs/locales` - packs import it, consumers never see it.
11
+ */
12
+ export { formatMessageValue } from '@jarenjs/core/message';
13
+ /**
14
+ * Build a numeric-limit renderer over a pack's number format. Values
15
+ * that are not numbers (e.g. an unresolved $data pointer) render as-is,
16
+ * so a limit is always readable even when it never resolved.
17
+ *
18
+ * @param {Intl.NumberFormat} numberFormat - The pack's number format
19
+ * @returns {(value: unknown) => string} The limit renderer
20
+ */
21
+ export declare function makeNumberRenderer(numberFormat: Intl.NumberFormat): (value: unknown) => string;
22
+ /**
23
+ * Build a two-form noun picker over a pack's plural rules: the count's
24
+ * CLDR category selects the `one` form, everything else the `other`
25
+ * form. Only for languages whose counted messages need exactly two
26
+ * forms - a pack that needs more categories, or that avoids agreement
27
+ * altogether by phrasing around a fixed noun, does not use this.
28
+ *
29
+ * @param {Intl.PluralRules} pluralRules - The pack's plural rules
30
+ * @returns {(count: number, one: string, other: string) => string} The form picker
31
+ */
32
+ export declare function makePluralPicker(pluralRules: Intl.PluralRules): (count: number, one: string, other: string) => string;
33
+ /**
34
+ * Build a type-name renderer over a pack's translated table. An
35
+ * unlisted type (a custom or future keyword value) renders under its
36
+ * JSON Schema name rather than disappearing.
37
+ *
38
+ * @param {Record<string, string>} typeNames - The pack's translated type names
39
+ * @returns {(type: string) => string} The type-name renderer
40
+ */
41
+ export declare function makeTypeNamer(typeNames: Record<string, string>): (type: string) => string;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @jarenjs/locales - locale packs (message catalogs) for the error
3
+ * messages of @jarenjs/validate and @jarenjs/forms.
4
+ *
5
+ * Each pack is a plain flat object of message-key -> closure/template
6
+ * entries (the catalog contract of
7
+ * packages/validate/docs/ERROR-MESSAGES.md); compile them with
8
+ * `compileMessageCatalog` from the consuming package. A pack holds its
9
+ * own translations and `Intl` singletons, and imports nothing but the
10
+ * rendering helpers of `./helpers.js` - never a consumer package, so
11
+ * either consumer can serve any pack.
12
+ */
13
+ export { ar } from './ar.js';
14
+ export { de } from './de.js';
15
+ export { es } from './es.js';
16
+ export { fr } from './fr.js';
17
+ export { ja } from './ja.js';
18
+ export { ko } from './ko.js';
19
+ export { nl } from './nl.js';
20
+ export { pt } from './pt.js';
21
+ export { ru } from './ru.js';
22
+ export { tr } from './tr.js';
23
+ export { zhTW } from './zh-tw.js';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The Japanese catalog. Covers every key of validate's `messagesEn`,
3
+ * every `form/*` key of forms' `formsMessagesEn`, `x-form/assert`, and
4
+ * the `JQ2xxx` codes reachable through `$query`.
5
+ * @type {Record<string, string | ((params: any, error?: object) => string)>}
6
+ */
7
+ export declare const ja: Record<string, string | ((params: any, error?: object) => string)>;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The Korean catalog. Covers every key of validate's `messagesEn`,
3
+ * every `form/*` key of forms' `formsMessagesEn`, `x-form/assert`, and
4
+ * the `JQ2xxx` codes reachable through `$query`.
5
+ * @type {Record<string, string | ((params: any, error?: object) => string)>}
6
+ */
7
+ export declare const ko: Record<string, string | ((params: any, error?: object) => string)>;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The Dutch catalog. Covers every key of validate's `messagesEn`, every
3
+ * `form/*` key of forms' `formsMessagesEn`, `x-form/assert`, and the
4
+ * `JQ2xxx` codes reachable through `$query`.
5
+ * @type {Record<string, string | ((params: any, error?: object) => string)>}
6
+ */
7
+ export declare const nl: Record<string, string | ((params: any, error?: object) => string)>;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The Portuguese catalog. Covers every key of validate's `messagesEn`,
3
+ * every `form/*` key of forms' `formsMessagesEn`, `x-form/assert`, and
4
+ * the `JQ2xxx` codes reachable through `$query`.
5
+ * @type {Record<string, string | ((params: any, error?: object) => string)>}
6
+ */
7
+ export declare const pt: Record<string, string | ((params: any, error?: object) => string)>;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The Russian catalog. Covers every key of validate's `messagesEn`,
3
+ * every `form/*` key of forms' `formsMessagesEn`, `x-form/assert`, and
4
+ * the `JQ2xxx` codes reachable through `$query`.
5
+ * @type {Record<string, string | ((params: any, error?: object) => string)>}
6
+ */
7
+ export declare const ru: Record<string, string | ((params: any, error?: object) => string)>;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The Turkish catalog. Covers every key of validate's `messagesEn`,
3
+ * every `form/*` key of forms' `formsMessagesEn`, `x-form/assert`, and
4
+ * the `JQ2xxx` codes reachable through `$query`.
5
+ * @type {Record<string, string | ((params: any, error?: object) => string)>}
6
+ */
7
+ export declare const tr: Record<string, string | ((params: any, error?: object) => string)>;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The zh-TW catalog. Covers every key of validate's `messagesEn`,
3
+ * every `form/*` key of forms' `formsMessagesEn`, `x-form/assert`, and
4
+ * the `JQ2xxx` codes reachable through `$query`.
5
+ * @type {Record<string, string | ((params: any, error?: object) => string)>}
6
+ */
7
+ export declare const zhTW: Record<string, string | ((params: any, error?: object) => string)>;
package/package.json ADDED
@@ -0,0 +1,95 @@
1
+ {
2
+ "name": "@jarenjs/locales",
3
+ "private": false,
4
+ "version": "0.34.0",
5
+ "type": "module",
6
+ "main": "./src/index.js",
7
+ "types": "./dist/types/index.d.ts",
8
+ "sideEffects": false,
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/types/index.d.ts",
12
+ "default": "./src/index.js"
13
+ },
14
+ "./ar": {
15
+ "types": "./dist/types/ar.d.ts",
16
+ "default": "./src/ar.js"
17
+ },
18
+ "./de": {
19
+ "types": "./dist/types/de.d.ts",
20
+ "default": "./src/de.js"
21
+ },
22
+ "./es": {
23
+ "types": "./dist/types/es.d.ts",
24
+ "default": "./src/es.js"
25
+ },
26
+ "./fr": {
27
+ "types": "./dist/types/fr.d.ts",
28
+ "default": "./src/fr.js"
29
+ },
30
+ "./ja": {
31
+ "types": "./dist/types/ja.d.ts",
32
+ "default": "./src/ja.js"
33
+ },
34
+ "./ko": {
35
+ "types": "./dist/types/ko.d.ts",
36
+ "default": "./src/ko.js"
37
+ },
38
+ "./nl": {
39
+ "types": "./dist/types/nl.d.ts",
40
+ "default": "./src/nl.js"
41
+ },
42
+ "./pt": {
43
+ "types": "./dist/types/pt.d.ts",
44
+ "default": "./src/pt.js"
45
+ },
46
+ "./ru": {
47
+ "types": "./dist/types/ru.d.ts",
48
+ "default": "./src/ru.js"
49
+ },
50
+ "./tr": {
51
+ "types": "./dist/types/tr.d.ts",
52
+ "default": "./src/tr.js"
53
+ },
54
+ "./zh-tw": {
55
+ "types": "./dist/types/zh-tw.d.ts",
56
+ "default": "./src/zh-tw.js"
57
+ },
58
+ "./package.json": "./package.json"
59
+ },
60
+ "files": [
61
+ "dist/types/",
62
+ "src/"
63
+ ],
64
+ "description": "Locale packs (message catalogs) for @jarenjs/validate and @jarenjs/forms error messages",
65
+ "author": "joham",
66
+ "repository": {
67
+ "type": "git",
68
+ "url": "git+https://github.com/jklarenbeek/jarenjs.git",
69
+ "directory": "packages/locales"
70
+ },
71
+ "license": "MIT",
72
+ "engines": {
73
+ "node": ">=24"
74
+ },
75
+ "publishConfig": {
76
+ "access": "public",
77
+ "registry": "https://registry.npmjs.org/"
78
+ },
79
+ "keywords": [
80
+ "jaren",
81
+ "json-schema",
82
+ "i18n",
83
+ "l10n",
84
+ "locales",
85
+ "error-messages"
86
+ ],
87
+ "scripts": {
88
+ "build": "npm run build:types",
89
+ "build:types": "tsc -p tsconfig.json",
90
+ "prepack": "npm run build:types"
91
+ },
92
+ "dependencies": {
93
+ "@jarenjs/core": "^0.34.0"
94
+ }
95
+ }
package/src/ar.js ADDED
@@ -0,0 +1,159 @@
1
+ //@ts-check
2
+
3
+ /**
4
+ * Arabic (ar) message catalog for @jarenjs/validate and @jarenjs/forms.
5
+ *
6
+ * A catalog is a plain flat object `{ [key]: closure | template string }`;
7
+ * compile it with `compileMessageCatalog` from either consumer package
8
+ * and hand it to `localizeErrors` (validate) or the `catalog` parameters
9
+ * of `validateField` / `evaluateFormRules` (forms). A pack imports only
10
+ * the shared rendering helpers; key parity with the built-in English
11
+ * catalogs is enforced by tests in the repo, not by imports.
12
+ *
13
+ * Globalization mechanics (the pack-authoring pattern - see
14
+ * packages/validate/docs/ERROR-MESSAGES.md):
15
+ * - Arabic pluralizes across six categories, so counted messages phrase
16
+ * around a fixed "عدد" (count-of) noun ("يجب ألا يقل عدد الأحرف عن 2")
17
+ * instead of agreeing the noun with the number - the standard
18
+ * software-string convention; no plural helper is needed,
19
+ * - `Intl.NumberFormat` is pinned to Latin digits (`numberingSystem:
20
+ * 'latn'`): the limits describe JSON documents, which are written in
21
+ * Latin digits regardless of UI language,
22
+ * - `Intl.ListFormat` renders enum alternatives ("a أو b أو c"),
23
+ * all held as module-level singletons (allocation discipline).
24
+ */
25
+
26
+ import {
27
+ formatMessageValue,
28
+ makeNumberRenderer,
29
+ makeTypeNamer,
30
+ } from './helpers.js';
31
+
32
+ //#region Intl singletons
33
+
34
+ const numberFormat = new Intl.NumberFormat('ar', { numberingSystem: 'latn' });
35
+ const listFormat = new Intl.ListFormat('ar', { style: 'long', type: 'disjunction' });
36
+
37
+ /**
38
+ * Render a numeric limit through the Arabic (Latin-digit) number
39
+ * format; non-numbers (e.g. an unresolved $data pointer) render as-is.
40
+ */
41
+ const num = makeNumberRenderer(numberFormat);
42
+
43
+ /** Arabic names for the JSON Schema type keyword values. */
44
+ const TYPE_NAMES = {
45
+ string: 'نص (string)',
46
+ number: 'رقم',
47
+ integer: 'عدد صحيح',
48
+ boolean: 'قيمة منطقية',
49
+ array: 'مصفوفة (array)',
50
+ object: 'كائن',
51
+ null: 'null',
52
+ };
53
+
54
+ /** Type keyword values under their Arabic display name. */
55
+ const typeName = makeTypeNamer(TYPE_NAMES);
56
+
57
+ /**
58
+ * The limit comparisons in words: an ASCII operator between RTL text
59
+ * and a number falls to the bidi algorithm's neutral reordering and
60
+ * displays flipped ("=<"), so the four operators validate emits render
61
+ * as phrases instead.
62
+ */
63
+ const COMPARISON_PHRASES = {
64
+ '>=': 'يجب ألا تقل القيمة عن',
65
+ '<=': 'يجب ألا تزيد القيمة عن',
66
+ '>': 'يجب أن تكون القيمة أكبر من',
67
+ '<': 'يجب أن تكون القيمة أصغر من',
68
+ };
69
+
70
+ /**
71
+ * Render a limit comparison; an unexpected operator falls back to the
72
+ * symbol wrapped in a left-to-right isolate (U+2066 LRI … U+2069 PDI) so
73
+ * it still reads left-to-right inside the RTL sentence. LRI rather than
74
+ * the first-strong FSI on purpose: an operator has no strong character
75
+ * for FSI to sample, so the direction has to be stated outright.
76
+ * @param {{ comparison: string, limit: unknown }} p - The message params
77
+ * @returns {string}
78
+ */
79
+ function compareLimit(p) {
80
+ const phrase = COMPARISON_PHRASES[p.comparison];
81
+ return phrase !== undefined
82
+ ? `${phrase} ${num(p.limit)}`
83
+ : `يجب أن تكون القيمة ⁦${p.comparison} ${num(p.limit)}⁩`;
84
+ }
85
+
86
+ //#endregion
87
+
88
+ /**
89
+ * The Arabic catalog. Covers every key of validate's `messagesEn`,
90
+ * every `form/*` key of forms' `formsMessagesEn`, `x-form/assert`, and
91
+ * the `JQ2xxx` codes reachable through `$query`.
92
+ * @type {Record<string, string | ((params: any, error?: object) => string)>}
93
+ */
94
+ export const ar = {
95
+ //#region @jarenjs/validate (document voice)
96
+ type: (p) => p.types
97
+ ? `يجب أن تكون القيمة من أحد الأنواع التالية: ${p.types.join(', ')}`
98
+ : `يجب أن تكون القيمة من نوع ${typeName(p.type)}`,
99
+ required: (p) => p.missingProperty
100
+ ? `يجب أن تحتوي على الخاصية الإلزامية '${p.missingProperty}'`
101
+ : 'يجب أن تحتوي على الخصائص الإلزامية',
102
+ minimum: compareLimit,
103
+ maximum: compareLimit,
104
+ exclusiveMinimum: compareLimit,
105
+ exclusiveMaximum: compareLimit,
106
+ multipleOf: (p) => `يجب أن تكون القيمة من مضاعفات ${num(p.multipleOf)}`,
107
+ minLength: (p) => `يجب ألا يقل عدد الأحرف عن ${num(p.limit)}`,
108
+ maxLength: (p) => `يجب ألا يزيد عدد الأحرف عن ${num(p.limit)}`,
109
+ pattern: 'يجب أن تطابق النمط "{pattern}"',
110
+ additionalProperties: (p) => p.additionalProperty
111
+ ? `يجب ألا تحتوي على الخاصية الإضافية '${p.additionalProperty}'`
112
+ : 'يجب ألا تحتوي على خصائص إضافية',
113
+ minProperties: (p) => `يجب ألا يقل عدد الخصائص عن ${num(p.limit)}`,
114
+ maxProperties: (p) => `يجب ألا يزيد عدد الخصائص عن ${num(p.limit)}`,
115
+ minItems: (p) => `يجب ألا يقل عدد العناصر عن ${num(p.limit)}`,
116
+ maxItems: (p) => `يجب ألا يزيد عدد العناصر عن ${num(p.limit)}`,
117
+ uniqueItems: 'يجب ألا تحتوي على عناصر مكررة',
118
+ contains: 'يجب أن تحتوي على عنصر صالح واحد على الأقل',
119
+ items: 'عناصر المصفوفة غير صالحة',
120
+ allOf: 'يجب أن تطابق جميع المخططات الفرعية',
121
+ anyOf: 'يجب أن تطابق أحد المخططات الفرعية في anyOf',
122
+ oneOf: 'يجب أن تطابق مخططًا فرعيًا واحدًا بالضبط في oneOf',
123
+ not: 'يجب ألا تطابق المخطط الفرعي',
124
+ format: 'يجب أن تطابق التنسيق "{format}"',
125
+ if: 'يجب أن تطابق مخطط "if"',
126
+ then: 'يجب أن تطابق مخطط "then"',
127
+ else: 'يجب أن تطابق مخطط "else"',
128
+ 'false schema': 'المخطط المنطقي false غير صالح دائمًا',
129
+ $query: (p) => p.code
130
+ ? `أثار تأكيد '$query' الخطأ ${p.code} في '${p.docPath}'`
131
+ : "يجب أن تحقق تأكيد '$query'",
132
+ JQ2001: (p) => `تعذر تقييم تأكيد '$query' (${p.code} في '${p.docPath}')`,
133
+ JQ2003: (p) => `أرجع تأكيد '$query' نتائج متعددة (${p.code} في '${p.docPath}')`,
134
+ //#endregion
135
+
136
+ //#region @jarenjs/forms (second-person field voice)
137
+ 'form/required': 'هذا الحقل إلزامي',
138
+ 'form/type': (p) => `يجب أن تكون القيمة من نوع ${typeName(p.type)}`,
139
+ 'form/const': (p) => `يجب أن تكون القيمة ${formatMessageValue(p.constValue)}`,
140
+ 'form/enum': (p) => `يجب أن تكون القيمة ${Array.isArray(p.enumValues) ? listFormat.format(p.enumValues.map(formatMessageValue)) : formatMessageValue(p.enumValues)}`,
141
+ 'form/minLength': (p) => `يجب ألا يقل عدد الأحرف عن ${num(p.limit)} (حاليًا ${num(p.len)})`,
142
+ 'form/maxLength': (p) => `يجب ألا يزيد عدد الأحرف عن ${num(p.limit)} (حاليًا ${num(p.len)})`,
143
+ 'form/pattern': 'يجب أن تطابق القيمة النمط {pattern}',
144
+ 'form/format': (p) => `يجب أن تكون القيمة بتنسيق ${p.format} صالح`,
145
+ 'form/minimum': (p) => `يجب ألا تقل القيمة عن ${num(p.limit)}`,
146
+ 'form/maximum': (p) => `يجب ألا تزيد القيمة عن ${num(p.limit)}`,
147
+ 'form/exclusiveMinimum': (p) => `يجب أن تكون القيمة أكبر من ${num(p.limit)}`,
148
+ 'form/exclusiveMaximum': (p) => `يجب أن تكون القيمة أصغر من ${num(p.limit)}`,
149
+ 'form/multipleOf': (p) => `يجب أن تكون القيمة من مضاعفات ${num(p.multipleOf)}`,
150
+ 'form/minItems': (p) => `يجب ألا يقل عدد العناصر عن ${num(p.limit)}`,
151
+ 'form/maxItems': (p) => `يجب ألا يزيد عدد العناصر عن ${num(p.limit)}`,
152
+ 'form/uniqueItems': 'يجب أن تكون العناصر فريدة',
153
+ 'form/minProperties': (p) => `يجب ألا يقل عدد الخصائص عن ${num(p.limit)}`,
154
+ 'form/maxProperties': (p) => `يجب ألا يزيد عدد الخصائص عن ${num(p.limit)}`,
155
+ 'x-form/assert': 'قيمة غير صالحة',
156
+ 'form/addItem': 'إضافة عنصر',
157
+ 'form/removeItem': 'إزالة عنصر',
158
+ //#endregion
159
+ };