@digitaldefiance/i18n-lib 3.0.0 → 3.5.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/README.md +125 -0
- package/package.json +1 -1
- package/src/icu/ast.d.ts +48 -0
- package/src/icu/ast.d.ts.map +1 -0
- package/src/icu/ast.js +16 -0
- package/src/icu/ast.js.map +1 -0
- package/src/icu/compiler.d.ts +16 -0
- package/src/icu/compiler.d.ts.map +1 -0
- package/src/icu/compiler.js +81 -0
- package/src/icu/compiler.js.map +1 -0
- package/src/icu/formatter-registry.d.ts +10 -0
- package/src/icu/formatter-registry.d.ts.map +1 -0
- package/src/icu/formatter-registry.js +34 -0
- package/src/icu/formatter-registry.js.map +1 -0
- package/src/icu/formatters/base-formatter.d.ts +8 -0
- package/src/icu/formatters/base-formatter.d.ts.map +1 -0
- package/src/icu/formatters/base-formatter.js +3 -0
- package/src/icu/formatters/base-formatter.js.map +1 -0
- package/src/icu/formatters/date-formatter.d.ts +5 -0
- package/src/icu/formatters/date-formatter.d.ts.map +1 -0
- package/src/icu/formatters/date-formatter.js +31 -0
- package/src/icu/formatters/date-formatter.js.map +1 -0
- package/src/icu/formatters/number-formatter.d.ts +5 -0
- package/src/icu/formatters/number-formatter.d.ts.map +1 -0
- package/src/icu/formatters/number-formatter.js +30 -0
- package/src/icu/formatters/number-formatter.js.map +1 -0
- package/src/icu/formatters/plural-formatter.d.ts +5 -0
- package/src/icu/formatters/plural-formatter.d.ts.map +1 -0
- package/src/icu/formatters/plural-formatter.js +15 -0
- package/src/icu/formatters/plural-formatter.js.map +1 -0
- package/src/icu/formatters/select-formatter.d.ts +5 -0
- package/src/icu/formatters/select-formatter.d.ts.map +1 -0
- package/src/icu/formatters/select-formatter.js +10 -0
- package/src/icu/formatters/select-formatter.js.map +1 -0
- package/src/icu/formatters/selectordinal-formatter.d.ts +5 -0
- package/src/icu/formatters/selectordinal-formatter.d.ts.map +1 -0
- package/src/icu/formatters/selectordinal-formatter.js +22 -0
- package/src/icu/formatters/selectordinal-formatter.js.map +1 -0
- package/src/icu/formatters/time-formatter.d.ts +5 -0
- package/src/icu/formatters/time-formatter.d.ts.map +1 -0
- package/src/icu/formatters/time-formatter.js +31 -0
- package/src/icu/formatters/time-formatter.js.map +1 -0
- package/src/icu/helpers.d.ts +9 -0
- package/src/icu/helpers.d.ts.map +1 -0
- package/src/icu/helpers.js +31 -0
- package/src/icu/helpers.js.map +1 -0
- package/src/icu/parser.d.ts +29 -0
- package/src/icu/parser.d.ts.map +1 -0
- package/src/icu/parser.js +194 -0
- package/src/icu/parser.js.map +1 -0
- package/src/icu/runtime.d.ts +10 -0
- package/src/icu/runtime.d.ts.map +1 -0
- package/src/icu/runtime.js +28 -0
- package/src/icu/runtime.js.map +1 -0
- package/src/icu/tokenizer.d.ts +37 -0
- package/src/icu/tokenizer.d.ts.map +1 -0
- package/src/icu/tokenizer.js +187 -0
- package/src/icu/tokenizer.js.map +1 -0
- package/src/icu/validator.d.ts +11 -0
- package/src/icu/validator.d.ts.map +1 -0
- package/src/icu/validator.js +140 -0
- package/src/icu/validator.js.map +1 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValidationError = void 0;
|
|
4
|
+
exports.validate = validate;
|
|
5
|
+
const ast_1 = require("./ast");
|
|
6
|
+
class ValidationError extends Error {
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = 'ValidationError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.ValidationError = ValidationError;
|
|
13
|
+
const DEFAULT_OPTIONS = {
|
|
14
|
+
requireOtherCase: true,
|
|
15
|
+
allowCircularReferences: false,
|
|
16
|
+
maxDepth: 10,
|
|
17
|
+
};
|
|
18
|
+
function validate(ast, options = {}) {
|
|
19
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
20
|
+
const context = new ValidationContext(opts);
|
|
21
|
+
validateMessage(ast, context);
|
|
22
|
+
}
|
|
23
|
+
class ValidationContext {
|
|
24
|
+
options;
|
|
25
|
+
argumentNames = new Set();
|
|
26
|
+
currentDepth = 0;
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.options = options;
|
|
29
|
+
}
|
|
30
|
+
addArgument(name) {
|
|
31
|
+
this.argumentNames.add(name);
|
|
32
|
+
}
|
|
33
|
+
hasArgument(name) {
|
|
34
|
+
return this.argumentNames.has(name);
|
|
35
|
+
}
|
|
36
|
+
enterDepth() {
|
|
37
|
+
this.currentDepth++;
|
|
38
|
+
if (this.currentDepth > this.options.maxDepth) {
|
|
39
|
+
throw new ValidationError(`Maximum nesting depth of ${this.options.maxDepth} exceeded`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exitDepth() {
|
|
43
|
+
this.currentDepth--;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function validateMessage(node, context) {
|
|
47
|
+
for (const element of node.elements) {
|
|
48
|
+
validateNode(element, context);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function validateNode(node, context) {
|
|
52
|
+
switch (node.type) {
|
|
53
|
+
case ast_1.NodeType.LITERAL:
|
|
54
|
+
break;
|
|
55
|
+
case ast_1.NodeType.ARGUMENT:
|
|
56
|
+
validateArgument(node, context);
|
|
57
|
+
break;
|
|
58
|
+
case ast_1.NodeType.PLURAL:
|
|
59
|
+
validatePlural(node, context);
|
|
60
|
+
break;
|
|
61
|
+
case ast_1.NodeType.SELECT:
|
|
62
|
+
validateSelect(node, context);
|
|
63
|
+
break;
|
|
64
|
+
case ast_1.NodeType.SELECTORDINAL:
|
|
65
|
+
validateSelectOrdinal(node, context);
|
|
66
|
+
break;
|
|
67
|
+
default:
|
|
68
|
+
throw new ValidationError(`Unknown node type: ${node.type}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function validateArgument(node, context) {
|
|
72
|
+
if (!node.name || node.name.trim() === '') {
|
|
73
|
+
throw new ValidationError('Argument name cannot be empty');
|
|
74
|
+
}
|
|
75
|
+
context.addArgument(node.name);
|
|
76
|
+
}
|
|
77
|
+
function validatePlural(node, context) {
|
|
78
|
+
if (!node.name || node.name.trim() === '') {
|
|
79
|
+
throw new ValidationError('Plural variable name cannot be empty');
|
|
80
|
+
}
|
|
81
|
+
context.addArgument(node.name);
|
|
82
|
+
if (!node.cases || Object.keys(node.cases).length === 0) {
|
|
83
|
+
throw new ValidationError(`Plural '${node.name}' must have at least one case`);
|
|
84
|
+
}
|
|
85
|
+
if (context.options.requireOtherCase && !node.cases.other) {
|
|
86
|
+
throw new ValidationError(`Plural '${node.name}' must have an 'other' case`);
|
|
87
|
+
}
|
|
88
|
+
const validCases = ['zero', 'one', 'two', 'few', 'many', 'other'];
|
|
89
|
+
for (const caseName of Object.keys(node.cases)) {
|
|
90
|
+
if (!validCases.includes(caseName)) {
|
|
91
|
+
throw new ValidationError(`Invalid plural case '${caseName}' in '${node.name}'`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
context.enterDepth();
|
|
95
|
+
for (const caseMessage of Object.values(node.cases)) {
|
|
96
|
+
validateMessage(caseMessage, context);
|
|
97
|
+
}
|
|
98
|
+
context.exitDepth();
|
|
99
|
+
}
|
|
100
|
+
function validateSelect(node, context) {
|
|
101
|
+
if (!node.name || node.name.trim() === '') {
|
|
102
|
+
throw new ValidationError('Select variable name cannot be empty');
|
|
103
|
+
}
|
|
104
|
+
context.addArgument(node.name);
|
|
105
|
+
if (!node.cases || Object.keys(node.cases).length === 0) {
|
|
106
|
+
throw new ValidationError(`Select '${node.name}' must have at least one case`);
|
|
107
|
+
}
|
|
108
|
+
if (context.options.requireOtherCase && !node.cases.other) {
|
|
109
|
+
throw new ValidationError(`Select '${node.name}' must have an 'other' case`);
|
|
110
|
+
}
|
|
111
|
+
context.enterDepth();
|
|
112
|
+
for (const caseMessage of Object.values(node.cases)) {
|
|
113
|
+
validateMessage(caseMessage, context);
|
|
114
|
+
}
|
|
115
|
+
context.exitDepth();
|
|
116
|
+
}
|
|
117
|
+
function validateSelectOrdinal(node, context) {
|
|
118
|
+
if (!node.name || node.name.trim() === '') {
|
|
119
|
+
throw new ValidationError('SelectOrdinal variable name cannot be empty');
|
|
120
|
+
}
|
|
121
|
+
context.addArgument(node.name);
|
|
122
|
+
if (!node.cases || Object.keys(node.cases).length === 0) {
|
|
123
|
+
throw new ValidationError(`SelectOrdinal '${node.name}' must have at least one case`);
|
|
124
|
+
}
|
|
125
|
+
if (context.options.requireOtherCase && !node.cases.other) {
|
|
126
|
+
throw new ValidationError(`SelectOrdinal '${node.name}' must have an 'other' case`);
|
|
127
|
+
}
|
|
128
|
+
const validCases = ['zero', 'one', 'two', 'few', 'many', 'other'];
|
|
129
|
+
for (const caseName of Object.keys(node.cases)) {
|
|
130
|
+
if (!validCases.includes(caseName)) {
|
|
131
|
+
throw new ValidationError(`Invalid selectordinal case '${caseName}' in '${node.name}'`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
context.enterDepth();
|
|
135
|
+
for (const caseMessage of Object.values(node.cases)) {
|
|
136
|
+
validateMessage(caseMessage, context);
|
|
137
|
+
}
|
|
138
|
+
context.exitDepth();
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-i18n-lib/src/icu/validator.ts"],"names":[],"mappings":"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"}
|