@openlifelog/sdk 1.0.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/utils/units.ts ADDED
@@ -0,0 +1,279 @@
1
+ import type { MeasurementSystem } from '../types/common';
2
+
3
+ /**
4
+ * Unit conversion utilities for metric/imperial conversions
5
+ */
6
+
7
+ // Conversion constants
8
+ const KG_TO_LBS = 2.20462;
9
+ const LBS_TO_KG = 1 / KG_TO_LBS;
10
+ const METERS_TO_MILES = 0.000621371;
11
+ const MILES_TO_METERS = 1 / METERS_TO_MILES;
12
+ const METERS_TO_FEET = 3.28084;
13
+ const FEET_TO_METERS = 1 / METERS_TO_FEET;
14
+ const CM_TO_INCHES = 0.393701;
15
+ const INCHES_TO_CM = 1 / CM_TO_INCHES;
16
+
17
+ /**
18
+ * Weight conversion
19
+ */
20
+ export class WeightConverter {
21
+ /**
22
+ * Convert kilograms to pounds
23
+ */
24
+ static kgToLbs(kg: number): number {
25
+ return kg * KG_TO_LBS;
26
+ }
27
+
28
+ /**
29
+ * Convert pounds to kilograms
30
+ */
31
+ static lbsToKg(lbs: number): number {
32
+ return lbs * LBS_TO_KG;
33
+ }
34
+
35
+ /**
36
+ * Convert weight from metric to the target measurement system
37
+ */
38
+ static fromMetric(kg: number, targetSystem: MeasurementSystem): number {
39
+ if (targetSystem === 'imperial') {
40
+ return this.kgToLbs(kg);
41
+ }
42
+ return kg;
43
+ }
44
+
45
+ /**
46
+ * Convert weight to metric from the source measurement system
47
+ */
48
+ static toMetric(value: number, sourceSystem: MeasurementSystem): number {
49
+ if (sourceSystem === 'imperial') {
50
+ return this.lbsToKg(value);
51
+ }
52
+ return value;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Distance conversion
58
+ */
59
+ export class DistanceConverter {
60
+ /**
61
+ * Convert meters to miles
62
+ */
63
+ static metersToMiles(meters: number): number {
64
+ return meters * METERS_TO_MILES;
65
+ }
66
+
67
+ /**
68
+ * Convert miles to meters
69
+ */
70
+ static milesToMeters(miles: number): number {
71
+ return miles * MILES_TO_METERS;
72
+ }
73
+
74
+ /**
75
+ * Convert meters to feet
76
+ */
77
+ static metersToFeet(meters: number): number {
78
+ return meters * METERS_TO_FEET;
79
+ }
80
+
81
+ /**
82
+ * Convert feet to meters
83
+ */
84
+ static feetToMeters(feet: number): number {
85
+ return feet * FEET_TO_METERS;
86
+ }
87
+
88
+ /**
89
+ * Convert distance from metric to the target measurement system
90
+ * For larger distances (> 1000m), converts to miles, otherwise to feet
91
+ */
92
+ static fromMetric(meters: number, targetSystem: MeasurementSystem, preferMiles: boolean = false): number {
93
+ if (targetSystem === 'imperial') {
94
+ if (preferMiles || meters >= 1000) {
95
+ return this.metersToMiles(meters);
96
+ }
97
+ return this.metersToFeet(meters);
98
+ }
99
+ return meters;
100
+ }
101
+
102
+ /**
103
+ * Convert distance to metric from the source measurement system
104
+ */
105
+ static toMetric(value: number, sourceSystem: MeasurementSystem, isMiles: boolean = false): number {
106
+ if (sourceSystem === 'imperial') {
107
+ return isMiles ? this.milesToMeters(value) : this.feetToMeters(value);
108
+ }
109
+ return value;
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Height conversion
115
+ */
116
+ export class HeightConverter {
117
+ /**
118
+ * Convert centimeters to inches
119
+ */
120
+ static cmToInches(cm: number): number {
121
+ return cm * CM_TO_INCHES;
122
+ }
123
+
124
+ /**
125
+ * Convert inches to centimeters
126
+ */
127
+ static inchesToCm(inches: number): number {
128
+ return inches * INCHES_TO_CM;
129
+ }
130
+
131
+ /**
132
+ * Convert centimeters to feet and inches
133
+ */
134
+ static cmToFeetInches(cm: number): { feet: number; inches: number } {
135
+ const totalInches = this.cmToInches(cm);
136
+ const feet = Math.floor(totalInches / 12);
137
+ const inches = Math.round(totalInches % 12);
138
+ return { feet, inches };
139
+ }
140
+
141
+ /**
142
+ * Convert feet and inches to centimeters
143
+ */
144
+ static feetInchesToCm(feet: number, inches: number): number {
145
+ const totalInches = feet * 12 + inches;
146
+ return this.inchesToCm(totalInches);
147
+ }
148
+
149
+ /**
150
+ * Convert height from metric to the target measurement system
151
+ */
152
+ static fromMetric(cm: number, targetSystem: MeasurementSystem): number {
153
+ if (targetSystem === 'imperial') {
154
+ return this.cmToInches(cm);
155
+ }
156
+ return cm;
157
+ }
158
+
159
+ /**
160
+ * Convert height to metric from the source measurement system
161
+ */
162
+ static toMetric(value: number, sourceSystem: MeasurementSystem): number {
163
+ if (sourceSystem === 'imperial') {
164
+ return this.inchesToCm(value);
165
+ }
166
+ return value;
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Generic unit converter that handles all conversions
172
+ */
173
+ export class UnitConverter {
174
+ private measurementSystem: MeasurementSystem;
175
+
176
+ constructor(measurementSystem: MeasurementSystem = 'metric') {
177
+ this.measurementSystem = measurementSystem;
178
+ }
179
+
180
+ /**
181
+ * Update the measurement system
182
+ */
183
+ setMeasurementSystem(system: MeasurementSystem): void {
184
+ this.measurementSystem = system;
185
+ }
186
+
187
+ /**
188
+ * Get the current measurement system
189
+ */
190
+ getMeasurementSystem(): MeasurementSystem {
191
+ return this.measurementSystem;
192
+ }
193
+
194
+ /**
195
+ * Convert weight from metric (API storage format) to user preference
196
+ */
197
+ weightFromMetric(kg: number | null | undefined): number | null {
198
+ if (kg === null || kg === undefined) return null;
199
+ return WeightConverter.fromMetric(kg, this.measurementSystem);
200
+ }
201
+
202
+ /**
203
+ * Convert weight to metric (API storage format) from user preference
204
+ */
205
+ weightToMetric(value: number | null | undefined): number | null {
206
+ if (value === null || value === undefined) return null;
207
+ return WeightConverter.toMetric(value, this.measurementSystem);
208
+ }
209
+
210
+ /**
211
+ * Convert distance from metric to user preference
212
+ */
213
+ distanceFromMetric(meters: number | null | undefined, preferMiles: boolean = false): number | null {
214
+ if (meters === null || meters === undefined) return null;
215
+ return DistanceConverter.fromMetric(meters, this.measurementSystem, preferMiles);
216
+ }
217
+
218
+ /**
219
+ * Convert distance to metric from user preference
220
+ */
221
+ distanceToMetric(value: number | null | undefined, isMiles: boolean = false): number | null {
222
+ if (value === null || value === undefined) return null;
223
+ return DistanceConverter.toMetric(value, this.measurementSystem, isMiles);
224
+ }
225
+
226
+ /**
227
+ * Convert height from metric to user preference
228
+ */
229
+ heightFromMetric(cm: number | null | undefined): number | null {
230
+ if (cm === null || cm === undefined) return null;
231
+ return HeightConverter.fromMetric(cm, this.measurementSystem);
232
+ }
233
+
234
+ /**
235
+ * Convert height to metric from user preference
236
+ */
237
+ heightToMetric(value: number | null | undefined): number | null {
238
+ if (value === null || value === undefined) return null;
239
+ return HeightConverter.toMetric(value, this.measurementSystem);
240
+ }
241
+
242
+ /**
243
+ * Round number to specified decimal places
244
+ */
245
+ static round(value: number, decimals: number = 2): number {
246
+ return Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals);
247
+ }
248
+
249
+ /**
250
+ * Get the appropriate unit label for weight
251
+ */
252
+ getWeightUnit(): string {
253
+ return this.measurementSystem === 'imperial' ? 'lbs' : 'kg';
254
+ }
255
+
256
+ /**
257
+ * Get the appropriate unit label for distance
258
+ */
259
+ getDistanceUnit(preferMiles: boolean = false): string {
260
+ if (this.measurementSystem === 'imperial') {
261
+ return preferMiles ? 'mi' : 'ft';
262
+ }
263
+ return 'm';
264
+ }
265
+
266
+ /**
267
+ * Get the appropriate unit label for height
268
+ */
269
+ getHeightUnit(): string {
270
+ return this.measurementSystem === 'imperial' ? 'in' : 'cm';
271
+ }
272
+ }
273
+
274
+ /**
275
+ * Helper function to create a unit converter
276
+ */
277
+ export function createUnitConverter(measurementSystem: MeasurementSystem = 'metric'): UnitConverter {
278
+ return new UnitConverter(measurementSystem);
279
+ }