@hello.nrfcloud.com/proto-map 16.1.40 → 16.2.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.
Files changed (84) hide show
  1. package/api/DeviceJWT.ts +1 -1
  2. package/api/Devices.ts +1 -1
  3. package/api/Email.spec.ts +3 -3
  4. package/api/IsoDateType.spec.ts +2 -2
  5. package/api/UserDevices.ts +1 -1
  6. package/api/index.ts +5 -5
  7. package/dist/api/DeviceJWT.js +1 -1
  8. package/dist/api/Devices.js +1 -1
  9. package/dist/api/Email.spec.js +3 -3
  10. package/dist/api/IsoDateType.spec.js +2 -2
  11. package/dist/api/UserDevices.js +1 -1
  12. package/dist/api/index.js +5 -5
  13. package/dist/generator/generateLwM2MDefinitions.js +1 -1
  14. package/dist/generator/generateLwM2MDefinitions.spec.js +1 -1
  15. package/dist/generator/generateModels.js +1 -1
  16. package/dist/generator/generateType.js +2 -2
  17. package/dist/generator/generateValidator.js +1 -1
  18. package/dist/generator/generateValidators.js +1 -1
  19. package/dist/generator/lwm2m.js +4 -4
  20. package/dist/generator/tokenizeName.spec.js +2 -2
  21. package/dist/generator/types.js +4 -5
  22. package/dist/lwm2m/InvalidTimeError.js +119 -0
  23. package/dist/lwm2m/aws/NoHistoryMeasuresError.js +119 -0
  24. package/dist/lwm2m/aws/instanceMeasuresToRecord.js +48 -0
  25. package/dist/lwm2m/aws/instanceMeasuresToRecord.spec.js +39 -0
  26. package/dist/lwm2m/aws/instanceToMeasure.spec.js +50 -0
  27. package/dist/lwm2m/aws/instanceToMeasures.js +112 -0
  28. package/dist/lwm2m/aws/objectsToShadow.spec.js +3 -3
  29. package/dist/lwm2m/aws/shadowToObjects.spec.js +3 -3
  30. package/dist/lwm2m/check-lwm2m-rules.js +4 -4
  31. package/dist/lwm2m/correctOffset.js +12 -0
  32. package/dist/lwm2m/correctOffset.spec.js +11 -0
  33. package/dist/lwm2m/fromXML2JSON.js +1 -1
  34. package/dist/lwm2m/index.js +11 -7
  35. package/dist/lwm2m/instanceTs.spec.js +1 -1
  36. package/dist/lwm2m/isNumber.js +3 -0
  37. package/dist/lwm2m/isNumeric.js +15 -0
  38. package/dist/lwm2m/isNumeric.spec.js +38 -0
  39. package/dist/lwm2m/isUnixTimeInSeconds.js +7 -0
  40. package/dist/lwm2m/isUnixTimeInSeconds.spec.js +14 -0
  41. package/dist/lwm2m/parseRangeEnumeration.spec.js +2 -2
  42. package/dist/lwm2m/unwrapNestedArray.spec.js +1 -1
  43. package/dist/lwm2m/validate.spec.js +1 -1
  44. package/dist/models/check-model-rules.js +1 -1
  45. package/dist/senml/SenMLSchema.spec.js +2 -2
  46. package/dist/senml/hasValue.spec.js +1 -1
  47. package/dist/senml/index.js +2 -2
  48. package/dist/senml/lwm2mToSenML.js +2 -2
  49. package/dist/senml/lwm2mToSenML.spec.js +2 -2
  50. package/dist/senml/validateSenML.spec.js +1 -1
  51. package/lwm2m/InvalidTimeError.ts +6 -0
  52. package/lwm2m/LwM2MObject.ts +1 -1
  53. package/lwm2m/aws/NoHistoryMeasuresError.ts +6 -0
  54. package/lwm2m/aws/instanceMeasuresToRecord.spec.ts +37 -0
  55. package/lwm2m/aws/instanceMeasuresToRecord.ts +62 -0
  56. package/lwm2m/aws/instanceToMeasure.spec.ts +53 -0
  57. package/lwm2m/aws/instanceToMeasures.ts +72 -0
  58. package/lwm2m/aws/objectsToShadow.spec.ts +3 -3
  59. package/lwm2m/aws/shadowToObjects.spec.ts +3 -3
  60. package/lwm2m/aws/shadowToObjects.ts +1 -1
  61. package/lwm2m/check-lwm2m-rules.ts +4 -4
  62. package/lwm2m/correctOffset.spec.ts +24 -0
  63. package/lwm2m/correctOffset.ts +12 -0
  64. package/lwm2m/fromXML2JSON.ts +1 -1
  65. package/lwm2m/index.ts +11 -7
  66. package/lwm2m/instanceTs.spec.ts +1 -1
  67. package/lwm2m/isNumber.ts +2 -0
  68. package/lwm2m/isNumeric.spec.ts +30 -0
  69. package/lwm2m/isNumeric.ts +17 -0
  70. package/lwm2m/isUnixTimeInSeconds.spec.ts +16 -0
  71. package/lwm2m/isUnixTimeInSeconds.ts +8 -0
  72. package/lwm2m/parseRangeEnumeration.spec.ts +2 -2
  73. package/lwm2m/unwrapNestedArray.spec.ts +1 -1
  74. package/lwm2m/validate.spec.ts +1 -1
  75. package/lwm2m/validate.ts +1 -1
  76. package/lwm2m/validation.ts +1 -1
  77. package/models/check-model-rules.ts +1 -1
  78. package/package.json +5 -4
  79. package/senml/SenMLSchema.spec.ts +2 -2
  80. package/senml/hasValue.spec.ts +1 -1
  81. package/senml/index.ts +2 -2
  82. package/senml/lwm2mToSenML.spec.ts +5 -5
  83. package/senml/lwm2mToSenML.ts +3 -3
  84. package/senml/validateSenML.spec.ts +2 -2
@@ -0,0 +1,112 @@
1
+ function _array_like_to_array(arr, len) {
2
+ if (len == null || len > arr.length) len = arr.length;
3
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
4
+ return arr2;
5
+ }
6
+ function _array_with_holes(arr) {
7
+ if (Array.isArray(arr)) return arr;
8
+ }
9
+ function _iterable_to_array_limit(arr, i) {
10
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
11
+ if (_i == null) return;
12
+ var _arr = [];
13
+ var _n = true;
14
+ var _d = false;
15
+ var _s, _e;
16
+ try {
17
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
18
+ _arr.push(_s.value);
19
+ if (i && _arr.length === i) break;
20
+ }
21
+ } catch (err) {
22
+ _d = true;
23
+ _e = err;
24
+ } finally{
25
+ try {
26
+ if (!_n && _i["return"] != null) _i["return"]();
27
+ } finally{
28
+ if (_d) throw _e;
29
+ }
30
+ }
31
+ return _arr;
32
+ }
33
+ function _non_iterable_rest() {
34
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
35
+ }
36
+ function _sliced_to_array(arr, i) {
37
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
38
+ }
39
+ function _unsupported_iterable_to_array(o, minLen) {
40
+ if (!o) return;
41
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
42
+ var n = Object.prototype.toString.call(o).slice(8, -1);
43
+ if (n === "Object" && o.constructor) n = o.constructor.name;
44
+ if (n === "Map" || n === "Set") return Array.from(n);
45
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
46
+ }
47
+ import { MeasureValueType } from '@aws-sdk/client-timestream-write';
48
+ import { correctOffset } from 'lwm2m/correctOffset.js';
49
+ import { definitions } from 'lwm2m/definitions.js';
50
+ import { InvalidTimeError } from 'lwm2m/InvalidTimeError.js';
51
+ import { isNumber } from 'lwm2m/isNumber.js';
52
+ import { isNumeric } from 'lwm2m/isNumeric.js';
53
+ import { isUnixTimeInSeconds } from 'lwm2m/isUnixTimeInSeconds.js';
54
+ import { timestampResources } from 'lwm2m/timestampResources.js';
55
+ export var instanceToMeasures = function(param) {
56
+ var Resources = param.Resources, ObjectID = param.ObjectID, ObjectInstanceID = param.ObjectInstanceID, ObjectVersion = param.ObjectVersion;
57
+ var measures = [];
58
+ var tsResource = timestampResources.get(ObjectID);
59
+ var ts = Resources[tsResource];
60
+ if (ts === undefined) {
61
+ return {
62
+ error: new InvalidTimeError("No timestamp resource defined for ".concat(ObjectID, "!"))
63
+ };
64
+ }
65
+ if (!isNumber(ts)) {
66
+ return {
67
+ error: new InvalidTimeError("Not a timestamp resource defined for ".concat(ObjectID, ": ").concat(ts.toString(), "!"))
68
+ };
69
+ }
70
+ var correctedTs = correctOffset(ts);
71
+ if (!isUnixTimeInSeconds(correctedTs)) {
72
+ return {
73
+ error: new InvalidTimeError("Timestamp ".concat(JSON.stringify(ts), " for ").concat(ObjectID, " is not a valid unix time in seconds!"))
74
+ };
75
+ }
76
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
77
+ try {
78
+ for(var _iterator = Object.entries(Resources)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
79
+ var _step_value = _sliced_to_array(_step.value, 2), ResourceID = _step_value[0], Value = _step_value[1];
80
+ var def = definitions[ObjectID].Resources[parseInt(ResourceID, 10)];
81
+ if (def === undefined) {
82
+ return {
83
+ error: new Error("No definition found for ".concat(ObjectID, "/").concat(ObjectInstanceID, "/").concat(ResourceID))
84
+ };
85
+ }
86
+ if (Value === null) continue;
87
+ if (Value === undefined) continue;
88
+ if (!isNumeric(def)) continue;
89
+ measures.push({
90
+ Name: "".concat(ObjectID, "/").concat(ObjectVersion, "/").concat(ResourceID),
91
+ Value: Value.toString(),
92
+ Type: MeasureValueType.DOUBLE
93
+ });
94
+ }
95
+ } catch (err) {
96
+ _didIteratorError = true;
97
+ _iteratorError = err;
98
+ } finally{
99
+ try {
100
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
101
+ _iterator.return();
102
+ }
103
+ } finally{
104
+ if (_didIteratorError) {
105
+ throw _iteratorError;
106
+ }
107
+ }
108
+ }
109
+ return {
110
+ measures: measures
111
+ };
112
+ };
@@ -1,7 +1,7 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import { describe, it } from 'node:test';
3
- import { objectsToShadow } from './objectsToShadow.js';
4
3
  import { LwM2MObjectID } from '../LwM2MObjectID.js';
4
+ import { objectsToShadow } from './objectsToShadow.js';
5
5
  void describe('objectsToShadow()', function() {
6
6
  void it('should convert a list of LwM2M objects to a shadow document', function() {
7
7
  return assert.deepEqual(objectsToShadow([
@@ -47,7 +47,7 @@ void describe('objectsToShadow()', function() {
47
47
  'MODEM',
48
48
  'APP'
49
49
  ],
50
- 99: 1717409966 * 1000
50
+ 99: 1717409966
51
51
  }
52
52
  }
53
53
  ]), {
@@ -88,7 +88,7 @@ void describe('objectsToShadow()', function() {
88
88
  'MODEM',
89
89
  'APP'
90
90
  ],
91
- 99: 1717409966 * 1000
91
+ 99: 1717409966
92
92
  }
93
93
  }
94
94
  });
@@ -1,7 +1,7 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import { describe, it } from 'node:test';
3
- import { shadowToObjects } from './shadowToObjects.js';
4
3
  import { LwM2MObjectID } from '../LwM2MObjectID.js';
4
+ import { shadowToObjects } from './shadowToObjects.js';
5
5
  void describe('shadowToObjects()', function() {
6
6
  void it('should convert a shadow to LwM2M objects', function() {
7
7
  return assert.deepEqual(shadowToObjects({
@@ -46,7 +46,7 @@ void describe('shadowToObjects()', function() {
46
46
  'MODEM',
47
47
  'APP'
48
48
  ],
49
- 99: 1717409966 * 1000
49
+ 99: 1717409966
50
50
  }
51
51
  }
52
52
  }), [
@@ -104,7 +104,7 @@ void describe('shadowToObjects()', function() {
104
104
  'MODEM',
105
105
  'APP'
106
106
  ],
107
- 99: 1717409966 * 1000
107
+ 99: 1717409966
108
108
  }
109
109
  }
110
110
  ]);
@@ -262,15 +262,15 @@ function _ts_values(o) {
262
262
  throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
263
263
  }
264
264
  import chalk from 'chalk';
265
+ import assert from 'node:assert/strict';
266
+ import { exec } from 'node:child_process';
265
267
  import { readFile, readdir, stat } from 'node:fs/promises';
266
268
  import path, { parse } from 'node:path';
267
- import assert from 'node:assert/strict';
268
269
  import xml2js from 'xml2js';
269
- import { exec } from 'node:child_process';
270
- import { unwrapNestedArray } from './unwrapNestedArray.js';
271
- import { LWM2MObjectDefinition } from './LWM2MObjectDefinition.js';
272
270
  import { validate } from '../validate.js';
271
+ import { LWM2MObjectDefinition } from './LWM2MObjectDefinition.js';
273
272
  import { parseRangeEnumeration } from './parseRangeEnumeration.js';
273
+ import { unwrapNestedArray } from './unwrapNestedArray.js';
274
274
  var v = validate(LWM2MObjectDefinition);
275
275
  var listLwm2mDefinitions = /*#__PURE__*/ function() {
276
276
  var _ref = _async_to_generator(function(modelDir) {
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Corrects an offset of up to 60 seconds in the future.
3
+ * This is needed because some devices clocks drift, and they report timestamps in the future.
4
+ */ export var correctOffset = function(ts) {
5
+ var maxOffsetSeconds = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 60;
6
+ var nowSeconds = Math.ceil(Date.now() / 1000);
7
+ var offset = ts * 1000 - nowSeconds;
8
+ if (offset < 0) {
9
+ return ts;
10
+ }
11
+ return ts - Math.min(offset, maxOffsetSeconds);
12
+ };
@@ -0,0 +1,11 @@
1
+ import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
+ import { correctOffset } from './correctOffset.js';
4
+ import { isUnixTimeInSeconds } from './isUnixTimeInSeconds.js';
5
+ void describe('correctOffset()', function() {
6
+ void it('should correct timestamps in the future of up to 60 seconds', function() {
7
+ assert.equal(isUnixTimeInSeconds(correctOffset(Date.now() / 1000 + 1)), true, 'should correct 1 second in the future');
8
+ assert.equal(isUnixTimeInSeconds(correctOffset(Date.now() / 1000 + 60)), true, 'should correct 60 seconds in the future');
9
+ assert.equal(isUnixTimeInSeconds(correctOffset(Date.now() / 1000 + 61)), false, 'should not correct 61 seconds in the future');
10
+ });
11
+ });
@@ -147,9 +147,9 @@ function _ts_generator(thisArg, body) {
147
147
  };
148
148
  }
149
149
  }
150
- import xml2js from 'xml2js';
151
150
  import { readFile } from 'node:fs/promises';
152
151
  import path from 'node:path';
152
+ import xml2js from 'xml2js';
153
153
  /**
154
154
  * From XML to JSON
155
155
  */ export var fromXML2JSON = /*#__PURE__*/ function() {
@@ -1,11 +1,15 @@
1
- export * from './validate.js';
2
- export * from './timestampResources.js';
1
+ export * from './definitions.js';
2
+ export * from './instanceTs.js';
3
+ export * from './InvalidTimeError.js';
4
+ export * from './isLwM2MObjectID.js';
5
+ export * from './isNumber.js';
6
+ export * from './isNumeric.js';
7
+ export * from './isUnixTimeInSeconds.js';
3
8
  export * from './LwM2MObject.js';
4
9
  export * from './LwM2MObjectID.js';
5
- export * from './objects.js';
6
- export * from './definitions.js';
7
10
  export * from './LWM2MObjectInfo.js';
8
- export * from './validators.js';
9
- export * from './instanceTs.js';
10
11
  export * from './LwM2MObjectInstance.js';
11
- export * from './isLwM2MObjectID.js';
12
+ export * from './objects.js';
13
+ export * from './timestampResources.js';
14
+ export * from './validate.js';
15
+ export * from './validators.js';
@@ -1,5 +1,5 @@
1
- import { describe, it } from 'node:test';
2
1
  import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
3
  import { instanceTs, instanceTsAsDate } from './instanceTs.js';
4
4
  void describe('instanceTs()', function() {
5
5
  void it('should return the timestamp of the instance', function() {
@@ -0,0 +1,3 @@
1
+ export var isNumber = function(value) {
2
+ return Number.isFinite(value);
3
+ };
@@ -0,0 +1,15 @@
1
+ import { ResourceType } from './LWM2MObjectInfo.js';
2
+ /**
3
+ * Only store numeric values, because you cannot create statistics about strings, or boolean
4
+ */ export var isNumeric = function(def) {
5
+ switch(def.Type){
6
+ case ResourceType.Float:
7
+ case ResourceType.Integer:
8
+ return true;
9
+ case ResourceType.String:
10
+ case ResourceType.Opaque:
11
+ case ResourceType.Boolean:
12
+ case ResourceType.Time:
13
+ return false;
14
+ }
15
+ };
@@ -0,0 +1,38 @@
1
+ import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
+ import { isNumeric } from './isNumeric.js';
4
+ import { ResourceType } from './LWM2MObjectInfo.js';
5
+ void describe('isNumeric', function() {
6
+ void it('should return true for numeric types', function() {
7
+ var numericTypes = [
8
+ {
9
+ Type: ResourceType.Float
10
+ },
11
+ {
12
+ Type: ResourceType.Integer
13
+ }
14
+ ];
15
+ numericTypes.forEach(function(def) {
16
+ assert.strictEqual(isNumeric(def), true);
17
+ });
18
+ });
19
+ void it('should return false for non-numeric types', function() {
20
+ var nonNumericTypes = [
21
+ {
22
+ Type: ResourceType.String
23
+ },
24
+ {
25
+ Type: ResourceType.Opaque
26
+ },
27
+ {
28
+ Type: ResourceType.Boolean
29
+ },
30
+ {
31
+ Type: ResourceType.Time
32
+ }
33
+ ];
34
+ nonNumericTypes.forEach(function(def) {
35
+ assert.strictEqual(isNumeric(def), false);
36
+ });
37
+ });
38
+ });
@@ -0,0 +1,7 @@
1
+ import { isNumber } from './isNumber.js';
2
+ export var isUnixTimeInSeconds = function(value) {
3
+ if (!isNumber(value)) return false;
4
+ if (value < 1700000000) return false;
5
+ if (value * 1000 > Date.now()) return false;
6
+ return true;
7
+ };
@@ -0,0 +1,14 @@
1
+ import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
+ import { isUnixTimeInSeconds } from './isUnixTimeInSeconds.js';
4
+ void describe('isUnixTimeInSeconds()', function() {
5
+ void it('should return true for valid Unix time in seconds', function() {
6
+ assert.equal(isUnixTimeInSeconds(1700000000), true);
7
+ assert.equal(isUnixTimeInSeconds(Date.now() / 1000), true);
8
+ });
9
+ void it('should return false for invalid Unix time in seconds', function() {
10
+ assert.equal(isUnixTimeInSeconds('1700000000'), false);
11
+ assert.equal(isUnixTimeInSeconds(1699999999), false);
12
+ assert.equal(isUnixTimeInSeconds(Date.now()), false);
13
+ });
14
+ });
@@ -1,7 +1,7 @@
1
- import { describe, it } from 'node:test';
2
1
  import assert from 'node:assert/strict';
3
- import { parseRangeEnumeration } from './parseRangeEnumeration.js';
2
+ import { describe, it } from 'node:test';
4
3
  import { RangeEnumerationRegExp } from './LWM2MObjectDefinition.js';
4
+ import { parseRangeEnumeration } from './parseRangeEnumeration.js';
5
5
  void describe('parseRangeEnumeration()', function() {
6
6
  void it('should parse valid range enumeration', function() {
7
7
  var result = parseRangeEnumeration('1..10');
@@ -1,5 +1,5 @@
1
- import { describe, it } from 'node:test';
2
1
  import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
3
  import { unwrapNestedArray } from './unwrapNestedArray.js';
4
4
  void describe('unwrapNestedArray()', function() {
5
5
  void it('should unwrap an array', function() {
@@ -1,7 +1,7 @@
1
+ import assert from 'node:assert';
1
2
  import { describe, it } from 'node:test';
2
3
  import { validate } from './validate.js';
3
4
  import { validators } from './validators.js';
4
- import assert from 'node:assert';
5
5
  void describe('validate()', function() {
6
6
  var v = validate(validators);
7
7
  void it('should validate a LwM2M object instance', function() {
@@ -1,9 +1,9 @@
1
1
  import chalk from 'chalk';
2
+ import { parseREADME } from 'markdown/parseREADME.js';
2
3
  import assert from 'node:assert/strict';
3
4
  import { readFile, readdir, stat } from 'node:fs/promises';
4
5
  import path from 'node:path';
5
6
  import { ModelIDRegExp } from './types.js';
6
- import { parseREADME } from 'markdown/parseREADME.js';
7
7
  console.log(chalk.gray('Models rules check'));
8
8
  console.log('');
9
9
  var modelsDir = path.join(process.cwd(), 'models');
@@ -1,7 +1,7 @@
1
- import { describe, it } from 'node:test';
2
- import { SenML } from './SenMLSchema.js';
3
1
  import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
4
3
  import { validate } from '../validate.js';
4
+ import { SenML } from './SenMLSchema.js';
5
5
  void describe('SenMLType', function() {
6
6
  void it('it should validate a SenML payload', function() {
7
7
  var example = [
@@ -44,8 +44,8 @@ function _unsupported_iterable_to_array(o, minLen) {
44
44
  if (n === "Map" || n === "Set") return Array.from(n);
45
45
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
46
46
  }
47
- import { describe, it } from 'node:test';
48
47
  import assert from 'node:assert/strict';
48
+ import { describe, it } from 'node:test';
49
49
  import { hasValue } from './hasValue.js';
50
50
  void describe('hasValue() should determine whether an object has a value', function() {
51
51
  var _loop = function(_i, _iter) {
@@ -1,4 +1,4 @@
1
+ export * from './fromCBOR.js';
2
+ export * from './lwm2mToSenML.js';
1
3
  export * from './SenMLSchema.js';
2
4
  export * from './senMLtoLwM2M.js';
3
- export * from './lwm2mToSenML.js';
4
- export * from './fromCBOR.js';
@@ -75,10 +75,10 @@ function _unsupported_iterable_to_array(o, minLen) {
75
75
  if (n === "Map" || n === "Set") return Array.from(n);
76
76
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
77
77
  }
78
- import { instanceTs } from '../lwm2m/instanceTs.js';
79
- import { timestampResources } from '../lwm2m/timestampResources.js';
80
78
  import { definitions } from '../lwm2m/definitions.js';
79
+ import { instanceTs } from '../lwm2m/instanceTs.js';
81
80
  import { ResourceType } from '../lwm2m/LWM2MObjectInfo.js';
81
+ import { timestampResources } from '../lwm2m/timestampResources.js';
82
82
  /**
83
83
  * Convert LwM2M Object Instances to senML
84
84
  */ export var lwm2mToSenML = function(lwm2m) {
@@ -1,6 +1,6 @@
1
- import { it, describe } from 'node:test';
2
- import { LwM2MObjectID } from '../lwm2m/LwM2MObjectID.js';
3
1
  import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
+ import { LwM2MObjectID } from '../lwm2m/LwM2MObjectID.js';
4
4
  import { lwm2mToSenML } from './lwm2mToSenML.js';
5
5
  void describe('lwm2mToSenML()', function() {
6
6
  void it('should convert LwM2M to SenML', function() {
@@ -1,5 +1,5 @@
1
- import { describe, it } from 'node:test';
2
1
  import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
3
  import { validateSenML } from './validateSenML.js';
4
4
  void describe('validateSenML()', function() {
5
5
  void it('should validate', function() {
@@ -0,0 +1,6 @@
1
+ export class InvalidTimeError extends Error {
2
+ constructor(message: string) {
3
+ super(message)
4
+ this.name = 'InvalidTimeError'
5
+ }
6
+ }
@@ -1,5 +1,5 @@
1
- import type { LwM2MResourceValue } from './LwM2MObjectInstance.js'
2
1
  import type { LwM2MObjectID } from './LwM2MObjectID.js'
2
+ import type { LwM2MResourceValue } from './LwM2MObjectInstance.js'
3
3
 
4
4
  export type LwM2MObject<
5
5
  ObjectDef extends {
@@ -0,0 +1,6 @@
1
+ export class NoHistoryMeasuresError extends Error {
2
+ constructor(message: string) {
3
+ super(message)
4
+ this.name = 'NoHistoryMeasuresError'
5
+ }
6
+ }
@@ -0,0 +1,37 @@
1
+ import { InvalidTimeError } from 'lwm2m/InvalidTimeError.js'
2
+ import { LwM2MObjectID } from 'lwm2m/LwM2MObjectID.js'
3
+ import assert from 'node:assert/strict'
4
+ import { describe, it } from 'node:test'
5
+ import { instanceMeasuresToRecord } from './instanceMeasuresToRecord.js'
6
+ import { NoHistoryMeasuresError } from './NoHistoryMeasuresError.js'
7
+
8
+ void describe('instanceMeasuresToRecord()', () => {
9
+ void it('should return an error if no measures are found', () => {
10
+ const res = instanceMeasuresToRecord({
11
+ ObjectID: LwM2MObjectID.DeviceInformation_14204,
12
+ Resources: {
13
+ '0': '352656108602296',
14
+ '1': '89457387300008502299',
15
+ '2': 'mfw_nrf9160_1.3.5',
16
+ '3': 'v1.3.1+thingy91.sol.lp.mmflt',
17
+ '4': 'thingy91_nrf9160',
18
+ '99': 1717419305,
19
+ },
20
+ })
21
+ assert.equal(
22
+ 'error' in res && res.error instanceof NoHistoryMeasuresError,
23
+ true,
24
+ )
25
+ })
26
+
27
+ void it('should return an error if the timestamp is invalid', () => {
28
+ const res = instanceMeasuresToRecord({
29
+ ObjectID: LwM2MObjectID.Environment_14205,
30
+ Resources: {
31
+ '0': 13.8,
32
+ '99': 1718878270596,
33
+ },
34
+ })
35
+ assert.equal('error' in res && res.error instanceof InvalidTimeError, true)
36
+ })
37
+ })
@@ -0,0 +1,62 @@
1
+ import {
2
+ MeasureValueType,
3
+ TimeUnit,
4
+ type _Record,
5
+ } from '@aws-sdk/client-timestream-write'
6
+ import { instanceTsAsDate } from 'lwm2m/instanceTs.js'
7
+ import type { LwM2MObjectInstance } from 'lwm2m/LwM2MObjectInstance.js'
8
+ import { instanceToMeasures } from './instanceToMeasures.js'
9
+ import { NoHistoryMeasuresError } from './NoHistoryMeasuresError.js'
10
+
11
+ export const instanceMeasuresToRecord = ({
12
+ ObjectID,
13
+ ObjectInstanceID,
14
+ ObjectVersion,
15
+ Resources,
16
+ }: LwM2MObjectInstance):
17
+ | { error: Error | NoHistoryMeasuresError }
18
+ | { record: _Record } => {
19
+ const maybeMeasures = instanceToMeasures({
20
+ ObjectID,
21
+ ObjectInstanceID,
22
+ ObjectVersion,
23
+ Resources,
24
+ })
25
+ if ('error' in maybeMeasures) return maybeMeasures
26
+ if (maybeMeasures.measures.length === 0)
27
+ return {
28
+ error: new NoHistoryMeasuresError(
29
+ `No measure to be stored in history for object ${ObjectID}!`,
30
+ ),
31
+ }
32
+ const instanceTs = instanceTsAsDate({
33
+ ObjectID,
34
+ ObjectInstanceID,
35
+ Resources,
36
+ })
37
+ if (instanceTs === undefined)
38
+ return { error: new Error(`No timestamp found for ${ObjectID}!`) }
39
+ return {
40
+ record: {
41
+ Dimensions: [
42
+ {
43
+ Name: 'ObjectID',
44
+ Value: ObjectID.toString(),
45
+ },
46
+ {
47
+ Name: 'ObjectInstanceID',
48
+ Value: (ObjectInstanceID ?? 0).toString(),
49
+ },
50
+ {
51
+ Name: 'ObjectVersion',
52
+ Value: ObjectVersion,
53
+ },
54
+ ],
55
+ MeasureName: `${ObjectID}/${ObjectInstanceID ?? 0}`,
56
+ MeasureValues: maybeMeasures.measures,
57
+ MeasureValueType: MeasureValueType.MULTI,
58
+ Time: instanceTs.getTime().toString(),
59
+ TimeUnit: TimeUnit.MILLISECONDS,
60
+ },
61
+ }
62
+ }
@@ -0,0 +1,53 @@
1
+ import { LwM2MObjectID } from 'lwm2m/LwM2MObjectID.js'
2
+ import type { Environment_14205 } from 'lwm2m/objects.js'
3
+ import assert from 'node:assert'
4
+ import { describe, it } from 'node:test'
5
+ import { instanceMeasuresToRecord } from './instanceMeasuresToRecord.js'
6
+
7
+ void describe('instanceMeasuresToRecord()', () => {
8
+ void it('should convert LwM2M object instance to Timestream records', () => {
9
+ const env: Environment_14205 = {
10
+ ObjectID: LwM2MObjectID.Environment_14205,
11
+ ObjectVersion: '1.0',
12
+ Resources: {
13
+ 0: 21,
14
+ 1: 45,
15
+ '99': 1717419305,
16
+ },
17
+ }
18
+
19
+ const maybeRecord = instanceMeasuresToRecord(env)
20
+ assert.deepEqual('record' in maybeRecord && maybeRecord.record, {
21
+ Dimensions: [
22
+ {
23
+ Name: 'ObjectID',
24
+ Value: LwM2MObjectID.Environment_14205,
25
+ },
26
+ {
27
+ Name: 'ObjectInstanceID',
28
+ Value: '0',
29
+ },
30
+ {
31
+ Name: 'ObjectVersion',
32
+ Value: '1.0',
33
+ },
34
+ ],
35
+ MeasureName: '14205/0',
36
+ MeasureValueType: 'MULTI',
37
+ MeasureValues: [
38
+ {
39
+ Name: '14205/1.0/0',
40
+ Type: 'DOUBLE',
41
+ Value: '21',
42
+ },
43
+ {
44
+ Name: '14205/1.0/1',
45
+ Type: 'DOUBLE',
46
+ Value: '45',
47
+ },
48
+ ],
49
+ Time: '1717419305000',
50
+ TimeUnit: 'MILLISECONDS',
51
+ })
52
+ })
53
+ })