@formatjs/icu-messageformat-parser 2.9.8 → 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.
package/index.d.ts CHANGED
@@ -4,3 +4,4 @@ export declare function parse(message: string, opts?: ParserOptions): MessageFor
4
4
  export * from './types';
5
5
  export type { ParserOptions };
6
6
  export declare const _Parser: typeof Parser;
7
+ export { isStructurallySame } from './manipulator';
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports._Parser = void 0;
3
+ exports.isStructurallySame = exports._Parser = void 0;
4
4
  exports.parse = parse;
5
5
  var tslib_1 = require("tslib");
6
6
  var error_1 = require("./error");
@@ -47,3 +47,5 @@ function parse(message, opts) {
47
47
  tslib_1.__exportStar(require("./types"), exports);
48
48
  // only for testing
49
49
  exports._Parser = parser_1.Parser;
50
+ var manipulator_1 = require("./manipulator");
51
+ Object.defineProperty(exports, "isStructurallySame", { enumerable: true, get: function () { return manipulator_1.isStructurallySame; } });
package/lib/index.d.ts CHANGED
@@ -4,3 +4,4 @@ export declare function parse(message: string, opts?: ParserOptions): MessageFor
4
4
  export * from './types';
5
5
  export type { ParserOptions };
6
6
  export declare const _Parser: typeof Parser;
7
+ export { isStructurallySame } from './manipulator';
package/lib/index.js CHANGED
@@ -43,3 +43,4 @@ export function parse(message, opts) {
43
43
  export * from './types';
44
44
  // only for testing
45
45
  export var _Parser = Parser;
46
+ export { isStructurallySame } from './manipulator';
@@ -11,3 +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
+ */
21
+ export declare function isStructurallySame(a: MessageFormatElement[], b: MessageFormatElement[]): boolean;
@@ -1,5 +1,5 @@
1
1
  import { __spreadArray } from "tslib";
2
- import { isPluralElement, isSelectElement, isTagElement, } 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,3 +65,52 @@ export function hoistSelectors(ast) {
65
65
  }
66
66
  return ast;
67
67
  }
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);
84
+ }
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
+ });
90
+ }
91
+ if (isTagElement(el)) {
92
+ vars.set(el.value, el.type);
93
+ collectVariables(el.children, vars);
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 false;
111
+ }
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
+ });
116
+ }
@@ -1,3 +1,4 @@
1
1
  export declare function parse(): void;
2
2
  export * from './types';
3
3
  export declare const _Parser: undefined;
4
+ export { isStructurallySame } from './manipulator';
package/lib/no-parser.js CHANGED
@@ -3,3 +3,4 @@ export function parse() {
3
3
  }
4
4
  export * from './types';
5
5
  export var _Parser = undefined;
6
+ export { isStructurallySame } from './manipulator';
package/lib/types.d.ts CHANGED
@@ -62,11 +62,8 @@ export interface BaseElement<T extends TYPE> {
62
62
  }
63
63
  export type LiteralElement = BaseElement<TYPE.literal>;
64
64
  export type ArgumentElement = BaseElement<TYPE.argument>;
65
- export interface TagElement {
66
- type: TYPE.tag;
67
- value: string;
65
+ export interface TagElement extends BaseElement<TYPE.tag> {
68
66
  children: MessageFormatElement[];
69
- location?: Location;
70
67
  }
71
68
  export interface SimpleFormatElement<T extends TYPE, S extends Skeleton> extends BaseElement<T> {
72
69
  style?: string | S | null;
package/manipulator.d.ts CHANGED
@@ -11,3 +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
+ */
21
+ export declare function isStructurallySame(a: MessageFormatElement[], b: MessageFormatElement[]): boolean;
package/manipulator.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hoistSelectors = hoistSelectors;
4
+ exports.isStructurallySame = isStructurallySame;
4
5
  var tslib_1 = require("tslib");
5
6
  var types_1 = require("./types");
6
7
  function cloneDeep(obj) {
@@ -68,3 +69,52 @@ function hoistSelectors(ast) {
68
69
  }
69
70
  return ast;
70
71
  }
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);
88
+ }
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
+ });
94
+ }
95
+ if ((0, types_1.isTagElement)(el)) {
96
+ vars.set(el.value, el.type);
97
+ collectVariables(el.children, vars);
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 false;
115
+ }
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
+ });
120
+ }
package/no-parser.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export declare function parse(): void;
2
2
  export * from './types';
3
3
  export declare const _Parser: undefined;
4
+ export { isStructurallySame } from './manipulator';
package/no-parser.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports._Parser = void 0;
3
+ exports.isStructurallySame = exports._Parser = void 0;
4
4
  exports.parse = parse;
5
5
  var tslib_1 = require("tslib");
6
6
  function parse() {
@@ -8,3 +8,5 @@ function parse() {
8
8
  }
9
9
  tslib_1.__exportStar(require("./types"), exports);
10
10
  exports._Parser = undefined;
11
+ var manipulator_1 = require("./manipulator");
12
+ Object.defineProperty(exports, "isStructurallySame", { enumerable: true, get: function () { return manipulator_1.isStructurallySame; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formatjs/icu-messageformat-parser",
3
- "version": "2.9.8",
3
+ "version": "2.10.1",
4
4
  "main": "index.js",
5
5
  "module": "lib/index.js",
6
6
  "types": "index.d.ts",
package/types.d.ts CHANGED
@@ -62,11 +62,8 @@ export interface BaseElement<T extends TYPE> {
62
62
  }
63
63
  export type LiteralElement = BaseElement<TYPE.literal>;
64
64
  export type ArgumentElement = BaseElement<TYPE.argument>;
65
- export interface TagElement {
66
- type: TYPE.tag;
67
- value: string;
65
+ export interface TagElement extends BaseElement<TYPE.tag> {
68
66
  children: MessageFormatElement[];
69
- location?: Location;
70
67
  }
71
68
  export interface SimpleFormatElement<T extends TYPE, S extends Skeleton> extends BaseElement<T> {
72
69
  style?: string | S | null;