@formatjs/icu-messageformat-parser 2.10.0 → 2.10.1

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.
@@ -11,4 +11,11 @@ import { MessageFormatElement } from './types';
11
11
  * @param ast AST
12
12
  */
13
13
  export declare function hoistSelectors(ast: MessageFormatElement[]): MessageFormatElement[];
14
+ /**
15
+ * Check if 2 ASTs are structurally the same. This primarily means that
16
+ * they have the same variables with the same type
17
+ * @param a
18
+ * @param b
19
+ * @returns
20
+ */
14
21
  export declare function isStructurallySame(a: MessageFormatElement[], b: MessageFormatElement[]): boolean;
@@ -1,5 +1,5 @@
1
1
  import { __spreadArray } from "tslib";
2
- import { isArgumentElement, isDateElement, isLiteralElement, isNumberElement, isPluralElement, isPoundElement, isSelectElement, isTagElement, isTimeElement, } from './types';
2
+ import { isArgumentElement, isDateElement, isNumberElement, isPluralElement, isSelectElement, isTagElement, isTimeElement, } from './types';
3
3
  function cloneDeep(obj) {
4
4
  if (Array.isArray(obj)) {
5
5
  // @ts-expect-error meh
@@ -65,93 +65,52 @@ export function hoistSelectors(ast) {
65
65
  }
66
66
  return ast;
67
67
  }
68
- function isStructurallySamePluralOrSelect(el1, el2) {
69
- var options1 = el1.options;
70
- var options2 = el2.options;
71
- if (Object.keys(options1).length !== Object.keys(options2).length) {
72
- return false;
73
- }
74
- for (var key in options1) {
75
- if (!options2[key]) {
76
- 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"));
82
+ }
83
+ vars.set(el.value, el.type);
77
84
  }
78
- if (!isStructurallySame(options1[key].value, options2[key].value)) {
79
- return false;
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
+ });
80
90
  }
81
- }
82
- return true;
91
+ if (isTagElement(el)) {
92
+ vars.set(el.value, el.type);
93
+ collectVariables(el.children, vars);
94
+ }
95
+ });
83
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
+ */
84
104
  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) {
105
+ var aVars = new Map();
106
+ var bVars = new Map();
107
+ collectVariables(a, aVars);
108
+ collectVariables(b, bVars);
109
+ if (aVars.size !== bVars.size) {
88
110
  return false;
89
111
  }
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;
135
- }
136
- }
137
- if (isPluralElement(elA) &&
138
- isPluralElement(elB) &&
139
- !isStructurallySamePluralOrSelect(elA, elB)) {
140
- return false;
141
- }
142
- if (isSelectElement(elA) &&
143
- isSelectElement(elB) &&
144
- isStructurallySamePluralOrSelect(elA, elB)) {
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
- }
154
- }
155
- }
156
- return true;
112
+ return Array.from(aVars.entries()).every(function (_a) {
113
+ var key = _a[0], type = _a[1];
114
+ return bVars.has(key) && bVars.get(key) === type;
115
+ });
157
116
  }
package/manipulator.d.ts CHANGED
@@ -11,4 +11,11 @@ import { MessageFormatElement } from './types';
11
11
  * @param ast AST
12
12
  */
13
13
  export declare function hoistSelectors(ast: MessageFormatElement[]): MessageFormatElement[];
14
+ /**
15
+ * Check if 2 ASTs are structurally the same. This primarily means that
16
+ * they have the same variables with the same type
17
+ * @param a
18
+ * @param b
19
+ * @returns
20
+ */
14
21
  export declare function isStructurallySame(a: MessageFormatElement[], b: MessageFormatElement[]): boolean;
package/manipulator.js CHANGED
@@ -69,93 +69,52 @@ function hoistSelectors(ast) {
69
69
  }
70
70
  return ast;
71
71
  }
72
- function isStructurallySamePluralOrSelect(el1, el2) {
73
- var options1 = el1.options;
74
- var options2 = el2.options;
75
- if (Object.keys(options1).length !== Object.keys(options2).length) {
76
- return false;
77
- }
78
- for (var key in options1) {
79
- if (!options2[key]) {
80
- 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"));
86
+ }
87
+ vars.set(el.value, el.type);
81
88
  }
82
- if (!isStructurallySame(options1[key].value, options2[key].value)) {
83
- return false;
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
+ });
84
94
  }
85
- }
86
- return true;
95
+ if ((0, types_1.isTagElement)(el)) {
96
+ vars.set(el.value, el.type);
97
+ collectVariables(el.children, vars);
98
+ }
99
+ });
87
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
+ */
88
108
  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) {
109
+ var aVars = new Map();
110
+ var bVars = new Map();
111
+ collectVariables(a, aVars);
112
+ collectVariables(b, bVars);
113
+ if (aVars.size !== bVars.size) {
92
114
  return false;
93
115
  }
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;
139
- }
140
- }
141
- if ((0, types_1.isPluralElement)(elA) &&
142
- (0, types_1.isPluralElement)(elB) &&
143
- !isStructurallySamePluralOrSelect(elA, elB)) {
144
- return false;
145
- }
146
- if ((0, types_1.isSelectElement)(elA) &&
147
- (0, types_1.isSelectElement)(elB) &&
148
- isStructurallySamePluralOrSelect(elA, elB)) {
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
- }
158
- }
159
- }
160
- return true;
116
+ return Array.from(aVars.entries()).every(function (_a) {
117
+ var key = _a[0], type = _a[1];
118
+ return bVars.has(key) && bVars.get(key) === type;
119
+ });
161
120
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formatjs/icu-messageformat-parser",
3
- "version": "2.10.0",
3
+ "version": "2.10.1",
4
4
  "main": "index.js",
5
5
  "module": "lib/index.js",
6
6
  "types": "index.d.ts",