@openfn/language-varo 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/LICENSE +674 -0
- package/LICENSE.LESSER +165 -0
- package/README.md +243 -0
- package/ast.json +670 -0
- package/configuration-schema.json +7 -0
- package/dist/index.cjs +392 -0
- package/dist/index.js +373 -0
- package/package.json +47 -0
- package/types/Adaptor.d.ts +19 -0
- package/types/FridgeTagUtils.d.ts +5 -0
- package/types/Utils.d.ts +1 -0
- package/types/VaroEmsUtils.d.ts +23 -0
- package/types/index.d.ts +3 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/index.js
|
|
20
|
+
var src_exports = {};
|
|
21
|
+
__export(src_exports, {
|
|
22
|
+
alterState: () => import_language_common2.alterState,
|
|
23
|
+
combine: () => import_language_common2.combine,
|
|
24
|
+
convertToEms: () => convertToEms,
|
|
25
|
+
cursor: () => import_language_common2.cursor,
|
|
26
|
+
dataPath: () => import_language_common2.dataPath,
|
|
27
|
+
dataValue: () => import_language_common2.dataValue,
|
|
28
|
+
default: () => src_default,
|
|
29
|
+
each: () => import_language_common2.each,
|
|
30
|
+
field: () => import_language_common2.field,
|
|
31
|
+
fields: () => import_language_common2.fields,
|
|
32
|
+
fn: () => import_language_common2.fn,
|
|
33
|
+
fnIf: () => import_language_common2.fnIf,
|
|
34
|
+
http: () => import_language_common2.http,
|
|
35
|
+
lastReferenceValue: () => import_language_common2.lastReferenceValue,
|
|
36
|
+
merge: () => import_language_common2.merge,
|
|
37
|
+
sourceValue: () => import_language_common2.sourceValue
|
|
38
|
+
});
|
|
39
|
+
module.exports = __toCommonJS(src_exports);
|
|
40
|
+
|
|
41
|
+
// src/Adaptor.js
|
|
42
|
+
var Adaptor_exports = {};
|
|
43
|
+
__export(Adaptor_exports, {
|
|
44
|
+
alterState: () => import_language_common2.alterState,
|
|
45
|
+
combine: () => import_language_common2.combine,
|
|
46
|
+
convertToEms: () => convertToEms,
|
|
47
|
+
cursor: () => import_language_common2.cursor,
|
|
48
|
+
dataPath: () => import_language_common2.dataPath,
|
|
49
|
+
dataValue: () => import_language_common2.dataValue,
|
|
50
|
+
each: () => import_language_common2.each,
|
|
51
|
+
field: () => import_language_common2.field,
|
|
52
|
+
fields: () => import_language_common2.fields,
|
|
53
|
+
fn: () => import_language_common2.fn,
|
|
54
|
+
fnIf: () => import_language_common2.fnIf,
|
|
55
|
+
http: () => import_language_common2.http,
|
|
56
|
+
lastReferenceValue: () => import_language_common2.lastReferenceValue,
|
|
57
|
+
merge: () => import_language_common2.merge,
|
|
58
|
+
sourceValue: () => import_language_common2.sourceValue
|
|
59
|
+
});
|
|
60
|
+
var import_language_common = require("@openfn/language-common");
|
|
61
|
+
var import_util = require("@openfn/language-common/util");
|
|
62
|
+
|
|
63
|
+
// src/Utils.js
|
|
64
|
+
function parseMetadata(message) {
|
|
65
|
+
var _a;
|
|
66
|
+
if (!((_a = message.metadata) == null ? void 0 : _a.content)) {
|
|
67
|
+
console.error("No metadata supplied.");
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
return JSON.parse(message.metadata.content);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error("Invalid metadata JSON.", error);
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// src/VaroEmsUtils.js
|
|
79
|
+
function parseVaroEmsToEms(metadata, data, dataPath2) {
|
|
80
|
+
const result = {
|
|
81
|
+
CID: null,
|
|
82
|
+
LAT: metadata.location.used.latitude,
|
|
83
|
+
LNG: metadata.location.used.longitude,
|
|
84
|
+
ADOP: data.ADOP,
|
|
85
|
+
AMFR: data.AMFR,
|
|
86
|
+
AMOD: data.AMOD,
|
|
87
|
+
APQS: data.APQS,
|
|
88
|
+
ASER: data.ASER,
|
|
89
|
+
EDOP: null,
|
|
90
|
+
EMFR: null,
|
|
91
|
+
EMOD: null,
|
|
92
|
+
EPQS: null,
|
|
93
|
+
ESER: null,
|
|
94
|
+
EMSV: null,
|
|
95
|
+
LDOP: data.LDOP,
|
|
96
|
+
LMFR: data.LMFR,
|
|
97
|
+
LMOD: data.LMOD,
|
|
98
|
+
LPQS: data.LPQS,
|
|
99
|
+
LSER: data.LSER,
|
|
100
|
+
LSV: data.LSV,
|
|
101
|
+
records: []
|
|
102
|
+
};
|
|
103
|
+
const deviceDate = parseRelativeDateFromUsbPluggedInfo(dataPath2);
|
|
104
|
+
for (const item of data.records) {
|
|
105
|
+
const durations = [item.RELT];
|
|
106
|
+
const absoluteDate = parseAdjustedDate(deviceDate, durations);
|
|
107
|
+
const abst = parseIsoToAbbreviatedIso(absoluteDate);
|
|
108
|
+
const record = {
|
|
109
|
+
ABST: abst,
|
|
110
|
+
ALRM: null,
|
|
111
|
+
BEMD: null,
|
|
112
|
+
BLOG: item.BLOG,
|
|
113
|
+
CMPR: null,
|
|
114
|
+
DORV: item.DORV,
|
|
115
|
+
HAMB: null,
|
|
116
|
+
HOLD: item.HOLD,
|
|
117
|
+
LERR: item.LERR,
|
|
118
|
+
EERR: null,
|
|
119
|
+
SVA: null,
|
|
120
|
+
TAMB: item.TAMB,
|
|
121
|
+
TVC: item.TVC
|
|
122
|
+
};
|
|
123
|
+
result.records.push(record);
|
|
124
|
+
}
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
function parseRelativeDateFromUsbPluggedInfo(path) {
|
|
128
|
+
const regex = /_CURRENT_DATA_(?<duration>\w+?)_(?<date>\w+?)\.json$/;
|
|
129
|
+
const match = path.match(regex);
|
|
130
|
+
if (!match) {
|
|
131
|
+
throw new Error(`Path format is incorrect: ${path}`);
|
|
132
|
+
}
|
|
133
|
+
const usbPluggedInfo = {
|
|
134
|
+
date: match.groups.date,
|
|
135
|
+
duration: match.groups.duration
|
|
136
|
+
};
|
|
137
|
+
const isoDate = parseAbbreviatedIsoToIso(usbPluggedInfo.date);
|
|
138
|
+
return parseAdjustedDate(isoDate, [usbPluggedInfo.duration], true);
|
|
139
|
+
}
|
|
140
|
+
function parseAdjustedDate(incomingDate, durations, subtract = false) {
|
|
141
|
+
function parseDuration(duration) {
|
|
142
|
+
const regex = /^P((?<days>\d+)D)?(T((?<hours>\d+)H)?((?<minutes>\d+)M)?((?<seconds>\d+)S)?)?$/;
|
|
143
|
+
const match = duration.match(regex);
|
|
144
|
+
if (!match) {
|
|
145
|
+
throw new Error(`Invalid duration format: ${duration}`);
|
|
146
|
+
}
|
|
147
|
+
const multiplier = subtract ? -1 : 1;
|
|
148
|
+
const days = parseInt(match.groups.days || 0, 10) * multiplier;
|
|
149
|
+
const hours = parseInt(match.groups.hours || 0, 10) * multiplier;
|
|
150
|
+
const minutes = parseInt(match.groups.minutes || 0, 10) * multiplier;
|
|
151
|
+
const seconds = parseInt(match.groups.seconds || 0, 10) * multiplier;
|
|
152
|
+
if (days === 0 && hours === 0 && minutes === 0 && seconds === 0) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
return { days, hours, minutes, seconds };
|
|
156
|
+
}
|
|
157
|
+
function applyDuration(date, duration) {
|
|
158
|
+
date.setDate(date.getDate() + duration.days);
|
|
159
|
+
date.setHours(date.getHours() + duration.hours);
|
|
160
|
+
date.setMinutes(date.getMinutes() + duration.minutes);
|
|
161
|
+
date.setSeconds(date.getSeconds() + duration.seconds);
|
|
162
|
+
}
|
|
163
|
+
const adjustedDate = new Date(incomingDate);
|
|
164
|
+
for (const duration of durations) {
|
|
165
|
+
if (!duration)
|
|
166
|
+
continue;
|
|
167
|
+
const parsedDuration = parseDuration(duration);
|
|
168
|
+
if (!parsedDuration)
|
|
169
|
+
continue;
|
|
170
|
+
applyDuration(adjustedDate, parsedDuration);
|
|
171
|
+
}
|
|
172
|
+
return adjustedDate;
|
|
173
|
+
}
|
|
174
|
+
function parseAbbreviatedIsoToIso(abbreviatedIso) {
|
|
175
|
+
const regex = /^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z$/;
|
|
176
|
+
const match = abbreviatedIso.match(regex);
|
|
177
|
+
if (!match) {
|
|
178
|
+
throw new Error(`Invalid abbreviated ISO date format: ${abbreviatedIso}`);
|
|
179
|
+
}
|
|
180
|
+
return `${match[1]}-${match[2]}-${match[3]}T${match[4]}:${match[5]}:${match[6]}Z`;
|
|
181
|
+
}
|
|
182
|
+
function parseIsoToAbbreviatedIso(iso) {
|
|
183
|
+
return iso.toISOString().replace(/[\-\:]/g, "").replace(".000Z", "Z");
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// src/FridgeTagUtils.js
|
|
187
|
+
function parseFridgeTagToEms(metadata, nodes) {
|
|
188
|
+
const result = {
|
|
189
|
+
records: [],
|
|
190
|
+
reports: []
|
|
191
|
+
};
|
|
192
|
+
applyMetadataToResult();
|
|
193
|
+
applyNodesToResult();
|
|
194
|
+
function applyMetadataToResult() {
|
|
195
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
196
|
+
applyPropertyToResult("AMFR", (_a = metadata == null ? void 0 : metadata.refrigerator) == null ? void 0 : _a.manufacturer);
|
|
197
|
+
applyPropertyToResult("AMOD", (_b = metadata == null ? void 0 : metadata.refrigerator) == null ? void 0 : _b.model);
|
|
198
|
+
applyPropertyToResult("LMFR", (_c = metadata == null ? void 0 : metadata.refrigerator) == null ? void 0 : _c.deviceManufacturer);
|
|
199
|
+
applyPropertyToResult("CID", (_d = metadata == null ? void 0 : metadata.facility) == null ? void 0 : _d.country);
|
|
200
|
+
applyPropertyToResult("LAT", (_f = (_e = metadata == null ? void 0 : metadata.location) == null ? void 0 : _e.used) == null ? void 0 : _f.latitude);
|
|
201
|
+
applyPropertyToResult("LNG", (_h = (_g = metadata == null ? void 0 : metadata.location) == null ? void 0 : _g.used) == null ? void 0 : _h.longitude);
|
|
202
|
+
applyPropertyToResult("LACC", (_j = (_i = metadata == null ? void 0 : metadata.location) == null ? void 0 : _i.used) == null ? void 0 : _j.accuracy);
|
|
203
|
+
}
|
|
204
|
+
function applyNodesToResult() {
|
|
205
|
+
var _a, _b, _c;
|
|
206
|
+
applyPropertyToResult("LMOD", nodes["Device"]);
|
|
207
|
+
applyPropertyToResult("LSER", (_a = nodes["Conf"]) == null ? void 0 : _a["Serial"]);
|
|
208
|
+
applyPropertyToResult("LSV", nodes["Fw Vers"]);
|
|
209
|
+
let productionDate = (_b = nodes["Conf"]) == null ? void 0 : _b["Test TS"];
|
|
210
|
+
productionDate = productionDate ? new Date(productionDate) : null;
|
|
211
|
+
applyPropertyToResult("LDOP", productionDate);
|
|
212
|
+
let dayIndex = 1;
|
|
213
|
+
let dayNode;
|
|
214
|
+
while ((dayNode = (_c = nodes["Hist"]) == null ? void 0 : _c[dayIndex++]) !== void 0) {
|
|
215
|
+
applyDayToRecords(dayNode);
|
|
216
|
+
applyDayToReports(dayNode);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function applyPropertyToResult(property, text) {
|
|
220
|
+
if (!text)
|
|
221
|
+
return;
|
|
222
|
+
result[property] = text;
|
|
223
|
+
}
|
|
224
|
+
function applyDayToRecords(dayNode) {
|
|
225
|
+
applyNodeToRecords(dayNode, "TS Min T", "Min T", "0", "FRZE");
|
|
226
|
+
applyNodeToRecords(dayNode, "TS Max T", "Max T", "1", "HEAT");
|
|
227
|
+
function applyNodeToRecords(dayNode2, timeField, tempField, alarmField, alarmDescription) {
|
|
228
|
+
var _a;
|
|
229
|
+
const date = dayNode2["Date"];
|
|
230
|
+
const time = dayNode2[timeField];
|
|
231
|
+
const dateTime = new Date(`${date}T${time}:00Z`);
|
|
232
|
+
const temp = parseFloat(dayNode2[tempField]);
|
|
233
|
+
const alarm = parseAlarm(
|
|
234
|
+
(_a = dayNode2["Alarm"]) == null ? void 0 : _a[alarmField],
|
|
235
|
+
alarmDescription
|
|
236
|
+
);
|
|
237
|
+
result.records.push({
|
|
238
|
+
ABST: dateTime,
|
|
239
|
+
TVC: temp,
|
|
240
|
+
ALRM: alarm,
|
|
241
|
+
description: date + " " + tempField
|
|
242
|
+
});
|
|
243
|
+
function parseAlarm(alarmNode, description) {
|
|
244
|
+
if (alarmNode["t Acc"] === "0")
|
|
245
|
+
return null;
|
|
246
|
+
return description + (alarmNode["C A"] !== "0" ? "ACK" : "");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function applyDayToReports(dayNode) {
|
|
251
|
+
const report = {
|
|
252
|
+
date: new Date(dayNode["Date"]),
|
|
253
|
+
duration: "1D",
|
|
254
|
+
alarms: [],
|
|
255
|
+
aggregates: []
|
|
256
|
+
};
|
|
257
|
+
applyAlarmsToReport(dayNode);
|
|
258
|
+
applyAggregatesToReport(dayNode);
|
|
259
|
+
result.reports.push(report);
|
|
260
|
+
function applyAlarmsToReport(dayNode2) {
|
|
261
|
+
var _a, _b;
|
|
262
|
+
const date = dayNode2["Date"];
|
|
263
|
+
applyAlarmToAlarms((_a = dayNode2["Alarm"]) == null ? void 0 : _a["0"], "FRZE");
|
|
264
|
+
applyAlarmToAlarms((_b = dayNode2["Alarm"]) == null ? void 0 : _b["1"], "HEAT");
|
|
265
|
+
function applyAlarmToAlarms(alarmNode, description) {
|
|
266
|
+
if (!alarmNode)
|
|
267
|
+
return;
|
|
268
|
+
const minutes = parseInt(alarmNode["t Acc"]);
|
|
269
|
+
if (!minutes)
|
|
270
|
+
return;
|
|
271
|
+
const alarm = {
|
|
272
|
+
condition: description,
|
|
273
|
+
conditionMinutes: minutes
|
|
274
|
+
};
|
|
275
|
+
const time = alarmNode["TS A"];
|
|
276
|
+
if (time) {
|
|
277
|
+
alarm.alarmTime = new Date(`${date}T${time}:00Z`);
|
|
278
|
+
}
|
|
279
|
+
const count = parseInt(alarmNode["C A"]);
|
|
280
|
+
if (count) {
|
|
281
|
+
alarm.count = count;
|
|
282
|
+
}
|
|
283
|
+
report.alarms.push(alarm);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function applyAggregatesToReport(dayNode2) {
|
|
287
|
+
applyTvcToAggregates(dayNode2);
|
|
288
|
+
function applyTvcToAggregates(dayNode3) {
|
|
289
|
+
report.aggregates.push({
|
|
290
|
+
id: "TVC",
|
|
291
|
+
min: parseFloat(dayNode3["Min T"]),
|
|
292
|
+
max: parseFloat(dayNode3["Max T"]),
|
|
293
|
+
average: parseFloat(dayNode3["Avrg T"])
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return result;
|
|
299
|
+
}
|
|
300
|
+
function parseFridgeTag(text) {
|
|
301
|
+
const result = {};
|
|
302
|
+
const properties = [{ indent: -1, property: result }];
|
|
303
|
+
for (const line of text.split("\n")) {
|
|
304
|
+
const trimmedLine = line.trim();
|
|
305
|
+
if (!trimmedLine)
|
|
306
|
+
continue;
|
|
307
|
+
const indent = line.search(/\S/);
|
|
308
|
+
while (indent <= properties[properties.length - 1].indent) {
|
|
309
|
+
properties.pop();
|
|
310
|
+
}
|
|
311
|
+
const property = properties[properties.length - 1].property;
|
|
312
|
+
const segments = trimmedLine.split(",").map((s) => s.trim());
|
|
313
|
+
for (const segment of segments) {
|
|
314
|
+
const pair = getKeyValuePair(segment);
|
|
315
|
+
if (!pair)
|
|
316
|
+
continue;
|
|
317
|
+
if (pair.value) {
|
|
318
|
+
property[pair.key] = pair.value;
|
|
319
|
+
} else {
|
|
320
|
+
property[pair.key] = {};
|
|
321
|
+
properties.push({ indent, property: property[pair.key] });
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return result;
|
|
326
|
+
function getKeyValuePair(segment) {
|
|
327
|
+
const colonIndex = segment.indexOf(":");
|
|
328
|
+
if (colonIndex === -1)
|
|
329
|
+
return null;
|
|
330
|
+
const key = segment.slice(0, colonIndex).trim();
|
|
331
|
+
const value = segment.slice(colonIndex + 1).trim();
|
|
332
|
+
return { key, value };
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// src/Adaptor.js
|
|
337
|
+
var import_language_common2 = require("@openfn/language-common");
|
|
338
|
+
function convertToEms(messageContents) {
|
|
339
|
+
return async (state) => {
|
|
340
|
+
var _a, _b;
|
|
341
|
+
const [resolvedMessageContents] = (0, import_util.expandReferences)(state, messageContents);
|
|
342
|
+
const results = [];
|
|
343
|
+
console.log("Incoming message contents", resolvedMessageContents.length);
|
|
344
|
+
for (const content of resolvedMessageContents) {
|
|
345
|
+
if ((_a = content.fridgeTag) == null ? void 0 : _a.content) {
|
|
346
|
+
const metadata = parseMetadata(content);
|
|
347
|
+
if (!metadata)
|
|
348
|
+
continue;
|
|
349
|
+
const fridgeTagNodes = parseFridgeTag(content.fridgeTag.content);
|
|
350
|
+
const result = parseFridgeTagToEms(metadata, fridgeTagNodes);
|
|
351
|
+
results.push(result);
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
if ((_b = content.data) == null ? void 0 : _b.content) {
|
|
355
|
+
const metadata = parseMetadata(content);
|
|
356
|
+
if (!metadata)
|
|
357
|
+
continue;
|
|
358
|
+
const data = JSON.parse(content.data.content);
|
|
359
|
+
const dataPath2 = content.data.filename;
|
|
360
|
+
const result = parseVaroEmsToEms(metadata, data, dataPath2);
|
|
361
|
+
results.push(result);
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
console.error(
|
|
365
|
+
`Insufficient content found for MessageID: ${content.messageId}`
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
console.log("Converted message contents", results.length);
|
|
369
|
+
return { ...(0, import_language_common.composeNextState)(state, results) };
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// src/index.js
|
|
374
|
+
var src_default = Adaptor_exports;
|
|
375
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
376
|
+
0 && (module.exports = {
|
|
377
|
+
alterState,
|
|
378
|
+
combine,
|
|
379
|
+
convertToEms,
|
|
380
|
+
cursor,
|
|
381
|
+
dataPath,
|
|
382
|
+
dataValue,
|
|
383
|
+
each,
|
|
384
|
+
field,
|
|
385
|
+
fields,
|
|
386
|
+
fn,
|
|
387
|
+
fnIf,
|
|
388
|
+
http,
|
|
389
|
+
lastReferenceValue,
|
|
390
|
+
merge,
|
|
391
|
+
sourceValue
|
|
392
|
+
});
|