@fw-components/formula-editor 2.3.5-linting.0 → 2.4.1-handle-unary-prefixes.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.
@@ -19,6 +19,22 @@ export class Parser {
19
19
  return false;
20
20
  return !Number.isNaN(Number(value));
21
21
  }
22
+ /**
23
+ * Checks whether a token (possibly prefixed with a unary operator from buildRPN pre-processing)
24
+ * is a valid operand: a known variable, a number, or a unary-prefixed variable like "-DIST".
25
+ */
26
+ isOperand(token) {
27
+ if (!token.trim().length)
28
+ return false;
29
+ if (!Number.isNaN(Number(token)) || this.variables.has(token))
30
+ return true;
31
+ // Handle tokens combined with a unary prefix during buildRPN pre-processing (e.g. "-DIST")
32
+ if (token.length > 1 && unaryOperators.includes(token[0])) {
33
+ const inner = token.substring(1);
34
+ return !Number.isNaN(Number(inner)) || this.variables.has(inner);
35
+ }
36
+ return false;
37
+ }
22
38
  formatFormulaToken(token) {
23
39
  for (const existingKey of this.variables.keys()) {
24
40
  if (existingKey.toLowerCase() === token.toLowerCase()) {
@@ -179,7 +195,8 @@ export class Parser {
179
195
  let carriedToken = null;
180
196
  const parsedTokens = [];
181
197
  let currentTokens = "";
182
- // Check if variables include unary operators `-` and `+`.
198
+ // Combine unary operators with the following operand (e.g. "-" + "DIST" → "-DIST").
199
+ // This mirrors parseInput's validation: unary +/- is legal at the start, after "(" or after an operator.
183
200
  for (const token of tokens) {
184
201
  if (unaryOperators.includes(token) && (!currentTokens.trim() || previousToken === "(" || this.allowedOperators.has(previousToken))) {
185
202
  carriedToken = token;
@@ -215,7 +232,7 @@ export class Parser {
215
232
  }
216
233
  operatorStack.push(token);
217
234
  }
218
- else if ((!Number.isNaN(Number(token)) || this.variables.has(token)) && token.trim().length) {
235
+ else if (this.isOperand(token)) {
219
236
  outputQueue.enqueue(token);
220
237
  }
221
238
  }
@@ -237,10 +254,7 @@ export class Parser {
237
254
  lexedRPN.forEach((symbol) => {
238
255
  let parsedLeftExpression;
239
256
  let parsedRightExpression;
240
- // check if the symbol is a number or variable or unaryOperatorPreceded Variable
241
- if ((unaryOperators.includes(symbol[0]) && this.variables.has(symbol.substring(1))) ||
242
- this.variables.has(symbol) ||
243
- (!Number.isNaN(parseFloat(symbol)) && Number.isFinite(parseFloat(symbol)))) {
257
+ if (this.isOperand(symbol)) {
244
258
  resultStack.push(symbol);
245
259
  operatorStack.push(null);
246
260
  }
@@ -280,8 +294,8 @@ export class Parser {
280
294
  const calcStack = new Stack();
281
295
  while (!formulaRPN.isEmpty()) {
282
296
  const frontItem = formulaRPN.dequeue();
283
- if (!this.allowedOperators.has(frontItem)) {
284
- const [sign, variableKey] = /^[+-]/.test(frontItem) ? [frontItem[0], frontItem.slice(1)] : ["", frontItem];
297
+ if (this.isOperand(frontItem)) {
298
+ const [sign, variableKey] = /^[+-]/.test(frontItem) && frontItem.length > 1 ? [frontItem[0], frontItem.slice(1)] : ["", frontItem];
285
299
  const operandValue = Number.parseFloat(this.variables.get(variableKey)?.toString() ?? variableKey);
286
300
  const number = Number.parseFloat(`${sign}1`) * operandValue;
287
301
  calcStack.push(Big(number));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fw-components/formula-editor",
3
- "version": "2.3.5-linting.0",
3
+ "version": "2.4.1-handle-unary-prefixes.0",
4
4
  "description": "A WYSIWYG type formula editor",
5
5
  "main": "dist/formula-editor/src/formula-editor.js",
6
6
  "exports": {
@@ -15,10 +15,12 @@
15
15
  "scripts": {
16
16
  "build": "tsc --composite false",
17
17
  "dev": "tsc -w --composite false",
18
+ "test": "vitest run",
19
+ "test:watch": "vitest",
18
20
  "prepublishOnly": "npm run build"
19
21
  },
20
22
  "dependencies": {
21
- "@fw-components/styles": "^2.3.5-linting.0",
23
+ "@fw-components/styles": "^2.4.0",
22
24
  "big.js": "6.2.2",
23
25
  "lit": "3.3.3",
24
26
  "match-sorter": "8.3.0"
@@ -32,7 +34,8 @@
32
34
  "devDependencies": {
33
35
  "@types/big.js": "6.2.2",
34
36
  "es-dev-server": "2.1.0",
35
- "typescript": "5.9.3"
37
+ "typescript": "5.9.3",
38
+ "vitest": "2.1.9"
36
39
  },
37
- "gitHead": "7f525eaed933492d04f38d07f9c3e2f01d12084f"
40
+ "gitHead": "63182a0895c61c558359cfd9db69ef0f15f5f727"
38
41
  }