@reekon-tools/boldr-utils 1.4.17 → 1.4.18

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.
@@ -102,6 +102,24 @@ export const calculateFormula = (formula, formulas, columns, tableConfig, measur
102
102
  currentMappings[variable] = mapping;
103
103
  }
104
104
  }
105
+ // Validate that all required inputs are filled out
106
+ const missingInputs = [];
107
+ for (const [variable, mapping] of Object.entries(currentMappings)) {
108
+ const mappingObj = typeof mapping === 'string'
109
+ ? { id: mapping, type: 'column' }
110
+ : mapping;
111
+ // Only check column references (formula references are handled separately)
112
+ if (mappingObj.type === 'column' || !mappingObj.type) {
113
+ const columnId = mappingObj.id;
114
+ if (!(columnId in valueMap)) {
115
+ missingInputs.push(variable);
116
+ }
117
+ }
118
+ }
119
+ if (missingInputs.length > 0) {
120
+ console.warn(`Not all inputs are filled out. Missing values for: ${missingInputs.join(', ')}`);
121
+ return null;
122
+ }
105
123
  const result = evaluateFormula({
106
124
  expression: formula.expression,
107
125
  mappings: currentMappings,
@@ -1,52 +1,8 @@
1
1
  import { Units } from '../types/firestore.js';
2
2
  import { create, all } from 'mathjs';
3
- // Helper to convert degrees to radians
4
- const degToRad = (degrees) => (degrees * Math.PI) / 180;
5
- // Helper to convert radians to degrees
6
- const radToDeg = (radians) => (radians * 180) / Math.PI;
7
- // Create a custom mathjs instance with degree-based trigonometric functions
8
- const math = create(all);
9
- // Create degree-based trigonometric functions that accept degrees as input
10
- // and return results in degrees for inverse functions
11
- // These functions handle mathjs types by converting to numbers
12
- const degreeTrigFunctions = {
13
- sin: (x) => {
14
- const degrees = typeof x === 'number' ? x : Number(x);
15
- return Math.sin(degToRad(degrees));
16
- },
17
- cos: (x) => {
18
- const degrees = typeof x === 'number' ? x : Number(x);
19
- return Math.cos(degToRad(degrees));
20
- },
21
- tan: (x) => {
22
- const degrees = typeof x === 'number' ? x : Number(x);
23
- return Math.tan(degToRad(degrees));
24
- },
25
- asin: (x) => {
26
- const value = typeof x === 'number' ? x : Number(x);
27
- return radToDeg(Math.asin(value));
28
- },
29
- acos: (x) => {
30
- const value = typeof x === 'number' ? x : Number(x);
31
- return radToDeg(Math.acos(value));
32
- },
33
- atan: (x) => {
34
- const value = typeof x === 'number' ? x : Number(x);
35
- return radToDeg(Math.atan(value));
36
- },
37
- atan2: (y, x) => {
38
- const yVal = typeof y === 'number' ? y : Number(y);
39
- const xVal = typeof x === 'number' ? x : Number(x);
40
- return radToDeg(Math.atan2(yVal, xVal));
41
- },
42
- };
43
- // Override the trigonometric functions in mathjs using import
44
- // The override: true option ensures existing functions are replaced
45
- math.import(degreeTrigFunctions, { override: true });
46
- // Verify the functions are overridden
47
- if (typeof math.sin !== 'function') {
48
- console.warn('Warning: math.sin override may have failed');
49
- }
3
+ // Create a custom mathjs instance configured to use degrees instead of radians
4
+ // @ts-ignore
5
+ const math = create(all, { angle: 'deg' });
50
6
  const compile = math.compile.bind(math);
51
7
  const mathUnit = math.unit.bind(math);
52
8
  // Cache for evaluated formulas to improve performance
@@ -169,30 +125,6 @@ export function evaluateFormula({ expression, mappings, valueMap, unit, formulas
169
125
  }
170
126
  evaluationStack.add(formulaId);
171
127
  try {
172
- // Validate that all required inputs are available before building scope
173
- const missingInputs = [];
174
- for (const [variable, rawMapping] of Object.entries(currentMappings)) {
175
- const mapping = normalizeMapping(rawMapping);
176
- if (mapping.type === 'measurement') {
177
- // Check if column reference exists in valueMap
178
- if (!(mapping.id in valueMap)) {
179
- missingInputs.push(variable);
180
- }
181
- }
182
- else if (mapping.type === 'formula') {
183
- // Check if formula reference exists
184
- const referencedFormula = formulas.find((f) => f.id === mapping.id);
185
- if (!referencedFormula) {
186
- missingInputs.push(variable);
187
- }
188
- // Note: We don't validate nested formula inputs here to avoid double evaluation
189
- // The nested formula will validate its own inputs when evaluated
190
- }
191
- }
192
- // If any direct inputs are missing, throw an error
193
- if (missingInputs.length > 0) {
194
- throw new Error(`Missing required inputs for formula ${formulaId}: ${missingInputs.join(', ')}`);
195
- }
196
128
  const scope = {};
197
129
  const normalizedUnit = normalizeUnitForMathJS(unit);
198
130
  // Build scope by resolving each variable
@@ -200,7 +132,6 @@ export function evaluateFormula({ expression, mappings, valueMap, unit, formulas
200
132
  const mapping = normalizeMapping(rawMapping);
201
133
  if (mapping.type === 'measurement') {
202
134
  // Handle measurement/column reference
203
- // At this point we know it exists (validated above), but use ?? 0 as fallback
204
135
  const micrometers = valueMap[mapping.id] ?? 0;
205
136
  if (micrometers === 0) {
206
137
  console.warn(`⚠️ Zero or missing value for mapping ID "${mapping.id}"`);
@@ -215,7 +146,6 @@ export function evaluateFormula({ expression, mappings, valueMap, unit, formulas
215
146
  throw new Error(`Referenced formula not found: ${mapping.id}`);
216
147
  }
217
148
  // Recursively evaluate the referenced formula
218
- // If it has missing inputs, it will throw an error which we'll catch
219
149
  const nestedResult = evaluateNestedFormula(referencedFormula.id, referencedFormula.expression, referencedFormula.variableToColumnMap);
220
150
  // Convert result to current unit with error handling
221
151
  let resultInUnit;
@@ -292,14 +222,8 @@ export function evaluateFormula({ expression, mappings, valueMap, unit, formulas
292
222
  return result;
293
223
  }
294
224
  catch (err) {
295
- const errorMessage = err instanceof Error ? err.message : String(err);
296
- // If the error is about missing inputs, return null to match the behavior in temp.ts
297
- if (errorMessage.includes('Missing required inputs') || errorMessage.includes('missing')) {
298
- console.warn('❌ Formula evaluation failed due to missing inputs:', errorMessage);
299
- return null;
300
- }
301
225
  console.warn('❌ Formula evaluation failed:', err);
302
- return errorMessage;
226
+ return err instanceof Error ? err.message : 'Error';
303
227
  }
304
228
  }
305
229
  // Legacy createFormulaScope function for backward compatibility
@@ -248,6 +248,29 @@ export interface Measurement extends FirestoreDoc, Timestamps, CreatedBy {
248
248
  type?: MeasurementType;
249
249
  note?: string;
250
250
  }
251
+ export interface Label extends FirestoreDoc, Timestamps {
252
+ name: string;
253
+ projectId: string;
254
+ jobId: string;
255
+ rows: LabelRow[];
256
+ rowSizes: number[];
257
+ isPublic: boolean;
258
+ }
259
+ export interface LabelRow {
260
+ id: string;
261
+ cells: LabelCell[];
262
+ colSizes: number[];
263
+ }
264
+ export interface LabelCell {
265
+ id: string;
266
+ type: 'none' | 'image' | 'text' | 'qr' | 'company' | 'icon' | 'measurement';
267
+ fileId?: string;
268
+ value?: string;
269
+ groupId?: string;
270
+ columnId?: string;
271
+ index?: number;
272
+ columnType?: ColumnType;
273
+ }
251
274
  export declare enum Units {
252
275
  Centimeters = "cm",
253
276
  Millimeters = "mm",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reekon-tools/boldr-utils",
3
- "version": "1.4.17",
3
+ "version": "1.4.18",
4
4
  "description": "Shared utilities for formulas and measurement conversion used in Reekon apps",
5
5
  "author": "REEKON Tools",
6
6
  "license": "MIT",