@formatjs/icu-messageformat-parser 2.10.0 → 2.11.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/lib/manipulator.d.ts +13 -1
- package/lib/manipulator.js +63 -85
- package/manipulator.d.ts +13 -1
- package/manipulator.js +62 -84
- package/package.json +1 -1
package/lib/manipulator.d.ts
CHANGED
|
@@ -11,4 +11,16 @@ import { MessageFormatElement } from './types';
|
|
|
11
11
|
* @param ast AST
|
|
12
12
|
*/
|
|
13
13
|
export declare function hoistSelectors(ast: MessageFormatElement[]): MessageFormatElement[];
|
|
14
|
-
|
|
14
|
+
interface IsStructurallySameResult {
|
|
15
|
+
error?: Error;
|
|
16
|
+
success: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Check if 2 ASTs are structurally the same. This primarily means that
|
|
20
|
+
* they have the same variables with the same type
|
|
21
|
+
* @param a
|
|
22
|
+
* @param b
|
|
23
|
+
* @returns
|
|
24
|
+
*/
|
|
25
|
+
export declare function isStructurallySame(a: MessageFormatElement[], b: MessageFormatElement[]): IsStructurallySameResult;
|
|
26
|
+
export {};
|
package/lib/manipulator.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __spreadArray } from "tslib";
|
|
2
|
-
import { isArgumentElement, isDateElement,
|
|
2
|
+
import { isArgumentElement, isDateElement, isNumberElement, isPluralElement, isSelectElement, isTagElement, isTimeElement, TYPE, } from './types';
|
|
3
3
|
function cloneDeep(obj) {
|
|
4
4
|
if (Array.isArray(obj)) {
|
|
5
5
|
// @ts-expect-error meh
|
|
@@ -65,93 +65,71 @@ export function hoistSelectors(ast) {
|
|
|
65
65
|
}
|
|
66
66
|
return ast;
|
|
67
67
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return true;
|
|
83
|
-
}
|
|
84
|
-
export function isStructurallySame(a, b) {
|
|
85
|
-
var aWithoutLiteral = a.filter(function (el) { return !isLiteralElement(el); });
|
|
86
|
-
var bWithoutLiteral = b.filter(function (el) { return !isLiteralElement(el); });
|
|
87
|
-
if (aWithoutLiteral.length !== bWithoutLiteral.length) {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
var elementsMapInA = aWithoutLiteral.reduce(function (all, el) {
|
|
91
|
-
if (isPoundElement(el)) {
|
|
92
|
-
all['#'] = el;
|
|
93
|
-
return all;
|
|
94
|
-
}
|
|
95
|
-
all[el.value] = el;
|
|
96
|
-
return all;
|
|
97
|
-
}, {});
|
|
98
|
-
var elementsMapInB = bWithoutLiteral.reduce(function (all, el) {
|
|
99
|
-
if (isPoundElement(el)) {
|
|
100
|
-
all['#'] = el;
|
|
101
|
-
return all;
|
|
102
|
-
}
|
|
103
|
-
all[el.value] = el;
|
|
104
|
-
return all;
|
|
105
|
-
}, {});
|
|
106
|
-
for (var _i = 0, _a = Object.keys(elementsMapInA); _i < _a.length; _i++) {
|
|
107
|
-
var varName = _a[_i];
|
|
108
|
-
var elA = elementsMapInA[varName];
|
|
109
|
-
var elB = elementsMapInB[varName];
|
|
110
|
-
if (!elB) {
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
if (elA.type !== elB.type) {
|
|
114
|
-
return false;
|
|
115
|
-
}
|
|
116
|
-
if (isLiteralElement(elA) || isLiteralElement(elB)) {
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
if (isArgumentElement(elA) &&
|
|
120
|
-
isArgumentElement(elB) &&
|
|
121
|
-
elA.value !== elB.value) {
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
|
-
if (isPoundElement(elA) || isPoundElement(elB)) {
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
if (isDateElement(elA) ||
|
|
128
|
-
isTimeElement(elA) ||
|
|
129
|
-
isNumberElement(elA) ||
|
|
130
|
-
isDateElement(elB) ||
|
|
131
|
-
isTimeElement(elB) ||
|
|
132
|
-
isNumberElement(elB)) {
|
|
133
|
-
if (elA.value !== elB.value) {
|
|
134
|
-
return false;
|
|
68
|
+
/**
|
|
69
|
+
* Collect all variables in an AST to Record<string, TYPE>
|
|
70
|
+
* @param ast AST to collect variables from
|
|
71
|
+
* @param vars Record of variable name to variable type
|
|
72
|
+
*/
|
|
73
|
+
function collectVariables(ast, vars) {
|
|
74
|
+
if (vars === void 0) { vars = new Map(); }
|
|
75
|
+
ast.forEach(function (el) {
|
|
76
|
+
if (isArgumentElement(el) ||
|
|
77
|
+
isDateElement(el) ||
|
|
78
|
+
isTimeElement(el) ||
|
|
79
|
+
isNumberElement(el)) {
|
|
80
|
+
if (el.value in vars && vars.get(el.value) !== el.type) {
|
|
81
|
+
throw new Error("Variable ".concat(el.value, " has conflicting types"));
|
|
135
82
|
}
|
|
83
|
+
vars.set(el.value, el.type);
|
|
136
84
|
}
|
|
137
|
-
if (isPluralElement(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
85
|
+
if (isPluralElement(el) || isSelectElement(el)) {
|
|
86
|
+
vars.set(el.value, el.type);
|
|
87
|
+
Object.keys(el.options).forEach(function (k) {
|
|
88
|
+
collectVariables(el.options[k].value, vars);
|
|
89
|
+
});
|
|
141
90
|
}
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
if (isTagElement(elA) && isTagElement(elB)) {
|
|
148
|
-
if (elA.value !== elB.value) {
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
|
-
if (!isStructurallySame(elA.children, elB.children)) {
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
91
|
+
if (isTagElement(el)) {
|
|
92
|
+
vars.set(el.value, el.type);
|
|
93
|
+
collectVariables(el.children, vars);
|
|
154
94
|
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Check if 2 ASTs are structurally the same. This primarily means that
|
|
99
|
+
* they have the same variables with the same type
|
|
100
|
+
* @param a
|
|
101
|
+
* @param b
|
|
102
|
+
* @returns
|
|
103
|
+
*/
|
|
104
|
+
export function isStructurallySame(a, b) {
|
|
105
|
+
var aVars = new Map();
|
|
106
|
+
var bVars = new Map();
|
|
107
|
+
collectVariables(a, aVars);
|
|
108
|
+
collectVariables(b, bVars);
|
|
109
|
+
if (aVars.size !== bVars.size) {
|
|
110
|
+
return {
|
|
111
|
+
success: false,
|
|
112
|
+
error: new Error("Different number of variables: [".concat(Array.from(aVars.keys()).join(', '), "] vs [").concat(Array.from(bVars.keys()).join(', '), "]")),
|
|
113
|
+
};
|
|
155
114
|
}
|
|
156
|
-
return
|
|
115
|
+
return Array.from(aVars.entries()).reduce(function (result, _a) {
|
|
116
|
+
var key = _a[0], type = _a[1];
|
|
117
|
+
if (!result.success) {
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
var bType = bVars.get(key);
|
|
121
|
+
if (bType == null) {
|
|
122
|
+
return {
|
|
123
|
+
success: false,
|
|
124
|
+
error: new Error("Missing variable ".concat(key, " in message")),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
if (bType !== type) {
|
|
128
|
+
return {
|
|
129
|
+
success: false,
|
|
130
|
+
error: new Error("Variable ".concat(key, " has conflicting types: ").concat(TYPE[type], " vs ").concat(TYPE[bType])),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
134
|
+
}, { success: true });
|
|
157
135
|
}
|
package/manipulator.d.ts
CHANGED
|
@@ -11,4 +11,16 @@ import { MessageFormatElement } from './types';
|
|
|
11
11
|
* @param ast AST
|
|
12
12
|
*/
|
|
13
13
|
export declare function hoistSelectors(ast: MessageFormatElement[]): MessageFormatElement[];
|
|
14
|
-
|
|
14
|
+
interface IsStructurallySameResult {
|
|
15
|
+
error?: Error;
|
|
16
|
+
success: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Check if 2 ASTs are structurally the same. This primarily means that
|
|
20
|
+
* they have the same variables with the same type
|
|
21
|
+
* @param a
|
|
22
|
+
* @param b
|
|
23
|
+
* @returns
|
|
24
|
+
*/
|
|
25
|
+
export declare function isStructurallySame(a: MessageFormatElement[], b: MessageFormatElement[]): IsStructurallySameResult;
|
|
26
|
+
export {};
|
package/manipulator.js
CHANGED
|
@@ -69,93 +69,71 @@ function hoistSelectors(ast) {
|
|
|
69
69
|
}
|
|
70
70
|
return ast;
|
|
71
71
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return true;
|
|
87
|
-
}
|
|
88
|
-
function isStructurallySame(a, b) {
|
|
89
|
-
var aWithoutLiteral = a.filter(function (el) { return !(0, types_1.isLiteralElement)(el); });
|
|
90
|
-
var bWithoutLiteral = b.filter(function (el) { return !(0, types_1.isLiteralElement)(el); });
|
|
91
|
-
if (aWithoutLiteral.length !== bWithoutLiteral.length) {
|
|
92
|
-
return false;
|
|
93
|
-
}
|
|
94
|
-
var elementsMapInA = aWithoutLiteral.reduce(function (all, el) {
|
|
95
|
-
if ((0, types_1.isPoundElement)(el)) {
|
|
96
|
-
all['#'] = el;
|
|
97
|
-
return all;
|
|
98
|
-
}
|
|
99
|
-
all[el.value] = el;
|
|
100
|
-
return all;
|
|
101
|
-
}, {});
|
|
102
|
-
var elementsMapInB = bWithoutLiteral.reduce(function (all, el) {
|
|
103
|
-
if ((0, types_1.isPoundElement)(el)) {
|
|
104
|
-
all['#'] = el;
|
|
105
|
-
return all;
|
|
106
|
-
}
|
|
107
|
-
all[el.value] = el;
|
|
108
|
-
return all;
|
|
109
|
-
}, {});
|
|
110
|
-
for (var _i = 0, _a = Object.keys(elementsMapInA); _i < _a.length; _i++) {
|
|
111
|
-
var varName = _a[_i];
|
|
112
|
-
var elA = elementsMapInA[varName];
|
|
113
|
-
var elB = elementsMapInB[varName];
|
|
114
|
-
if (!elB) {
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
if (elA.type !== elB.type) {
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
if ((0, types_1.isLiteralElement)(elA) || (0, types_1.isLiteralElement)(elB)) {
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
if ((0, types_1.isArgumentElement)(elA) &&
|
|
124
|
-
(0, types_1.isArgumentElement)(elB) &&
|
|
125
|
-
elA.value !== elB.value) {
|
|
126
|
-
return false;
|
|
127
|
-
}
|
|
128
|
-
if ((0, types_1.isPoundElement)(elA) || (0, types_1.isPoundElement)(elB)) {
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
131
|
-
if ((0, types_1.isDateElement)(elA) ||
|
|
132
|
-
(0, types_1.isTimeElement)(elA) ||
|
|
133
|
-
(0, types_1.isNumberElement)(elA) ||
|
|
134
|
-
(0, types_1.isDateElement)(elB) ||
|
|
135
|
-
(0, types_1.isTimeElement)(elB) ||
|
|
136
|
-
(0, types_1.isNumberElement)(elB)) {
|
|
137
|
-
if (elA.value !== elB.value) {
|
|
138
|
-
return false;
|
|
72
|
+
/**
|
|
73
|
+
* Collect all variables in an AST to Record<string, TYPE>
|
|
74
|
+
* @param ast AST to collect variables from
|
|
75
|
+
* @param vars Record of variable name to variable type
|
|
76
|
+
*/
|
|
77
|
+
function collectVariables(ast, vars) {
|
|
78
|
+
if (vars === void 0) { vars = new Map(); }
|
|
79
|
+
ast.forEach(function (el) {
|
|
80
|
+
if ((0, types_1.isArgumentElement)(el) ||
|
|
81
|
+
(0, types_1.isDateElement)(el) ||
|
|
82
|
+
(0, types_1.isTimeElement)(el) ||
|
|
83
|
+
(0, types_1.isNumberElement)(el)) {
|
|
84
|
+
if (el.value in vars && vars.get(el.value) !== el.type) {
|
|
85
|
+
throw new Error("Variable ".concat(el.value, " has conflicting types"));
|
|
139
86
|
}
|
|
87
|
+
vars.set(el.value, el.type);
|
|
140
88
|
}
|
|
141
|
-
if ((0, types_1.isPluralElement)(
|
|
142
|
-
(
|
|
143
|
-
|
|
144
|
-
|
|
89
|
+
if ((0, types_1.isPluralElement)(el) || (0, types_1.isSelectElement)(el)) {
|
|
90
|
+
vars.set(el.value, el.type);
|
|
91
|
+
Object.keys(el.options).forEach(function (k) {
|
|
92
|
+
collectVariables(el.options[k].value, vars);
|
|
93
|
+
});
|
|
145
94
|
}
|
|
146
|
-
if ((0, types_1.
|
|
147
|
-
(
|
|
148
|
-
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
|
-
if ((0, types_1.isTagElement)(elA) && (0, types_1.isTagElement)(elB)) {
|
|
152
|
-
if (elA.value !== elB.value) {
|
|
153
|
-
return false;
|
|
154
|
-
}
|
|
155
|
-
if (!isStructurallySame(elA.children, elB.children)) {
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
95
|
+
if ((0, types_1.isTagElement)(el)) {
|
|
96
|
+
vars.set(el.value, el.type);
|
|
97
|
+
collectVariables(el.children, vars);
|
|
158
98
|
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Check if 2 ASTs are structurally the same. This primarily means that
|
|
103
|
+
* they have the same variables with the same type
|
|
104
|
+
* @param a
|
|
105
|
+
* @param b
|
|
106
|
+
* @returns
|
|
107
|
+
*/
|
|
108
|
+
function isStructurallySame(a, b) {
|
|
109
|
+
var aVars = new Map();
|
|
110
|
+
var bVars = new Map();
|
|
111
|
+
collectVariables(a, aVars);
|
|
112
|
+
collectVariables(b, bVars);
|
|
113
|
+
if (aVars.size !== bVars.size) {
|
|
114
|
+
return {
|
|
115
|
+
success: false,
|
|
116
|
+
error: new Error("Different number of variables: [".concat(Array.from(aVars.keys()).join(', '), "] vs [").concat(Array.from(bVars.keys()).join(', '), "]")),
|
|
117
|
+
};
|
|
159
118
|
}
|
|
160
|
-
return
|
|
119
|
+
return Array.from(aVars.entries()).reduce(function (result, _a) {
|
|
120
|
+
var key = _a[0], type = _a[1];
|
|
121
|
+
if (!result.success) {
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
var bType = bVars.get(key);
|
|
125
|
+
if (bType == null) {
|
|
126
|
+
return {
|
|
127
|
+
success: false,
|
|
128
|
+
error: new Error("Missing variable ".concat(key, " in message")),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
if (bType !== type) {
|
|
132
|
+
return {
|
|
133
|
+
success: false,
|
|
134
|
+
error: new Error("Variable ".concat(key, " has conflicting types: ").concat(types_1.TYPE[type], " vs ").concat(types_1.TYPE[bType])),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}, { success: true });
|
|
161
139
|
}
|