@ya-modbus/cli 0.7.1 → 0.9.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 (83) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +85 -0
  3. package/dist/cjs/src/commands/discover.d.ts +3 -0
  4. package/dist/cjs/src/commands/discover.d.ts.map +1 -1
  5. package/dist/cjs/src/commands/discover.js +29 -0
  6. package/dist/cjs/src/commands/discover.js.map +1 -1
  7. package/dist/cjs/src/discovery/parameter-generator-utils.d.ts +5 -2
  8. package/dist/cjs/src/discovery/parameter-generator-utils.d.ts.map +1 -1
  9. package/dist/cjs/src/discovery/parameter-generator-utils.js +54 -27
  10. package/dist/cjs/src/discovery/parameter-generator-utils.js.map +1 -1
  11. package/dist/cjs/src/discovery/parameter-generator.d.ts +6 -0
  12. package/dist/cjs/src/discovery/parameter-generator.d.ts.map +1 -1
  13. package/dist/cjs/src/discovery/parameter-generator.js +43 -17
  14. package/dist/cjs/src/discovery/parameter-generator.js.map +1 -1
  15. package/dist/cjs/src/index.d.ts.map +1 -1
  16. package/dist/cjs/src/index.js +3 -0
  17. package/dist/cjs/src/index.js.map +1 -1
  18. package/dist/cjs/src/utils/merge-specs.d.ts +34 -0
  19. package/dist/cjs/src/utils/merge-specs.d.ts.map +1 -0
  20. package/dist/cjs/src/utils/merge-specs.js +53 -0
  21. package/dist/cjs/src/utils/merge-specs.js.map +1 -0
  22. package/dist/cjs/src/utils/parse-baud-rate.d.ts +14 -0
  23. package/dist/cjs/src/utils/parse-baud-rate.d.ts.map +1 -0
  24. package/dist/cjs/src/utils/parse-baud-rate.js +52 -0
  25. package/dist/cjs/src/utils/parse-baud-rate.js.map +1 -0
  26. package/dist/cjs/src/utils/parse-id-range.d.ts +13 -0
  27. package/dist/cjs/src/utils/parse-id-range.d.ts.map +1 -0
  28. package/dist/cjs/src/utils/parse-id-range.js +49 -0
  29. package/dist/cjs/src/utils/parse-id-range.js.map +1 -0
  30. package/dist/cjs/src/utils/parse-integer.d.ts +15 -0
  31. package/dist/cjs/src/utils/parse-integer.d.ts.map +1 -0
  32. package/dist/cjs/src/utils/parse-integer.js +27 -0
  33. package/dist/cjs/src/utils/parse-integer.js.map +1 -0
  34. package/dist/cjs/src/utils/parse-parity.d.ts +18 -0
  35. package/dist/cjs/src/utils/parse-parity.d.ts.map +1 -0
  36. package/dist/cjs/src/utils/parse-parity.js +46 -0
  37. package/dist/cjs/src/utils/parse-parity.js.map +1 -0
  38. package/dist/cjs/src/utils/parse-spec.d.ts +73 -0
  39. package/dist/cjs/src/utils/parse-spec.d.ts.map +1 -0
  40. package/dist/cjs/src/utils/parse-spec.js +47 -0
  41. package/dist/cjs/src/utils/parse-spec.js.map +1 -0
  42. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  43. package/dist/esm/src/commands/discover.d.ts +3 -0
  44. package/dist/esm/src/commands/discover.d.ts.map +1 -1
  45. package/dist/esm/src/commands/discover.js +29 -0
  46. package/dist/esm/src/commands/discover.js.map +1 -1
  47. package/dist/esm/src/discovery/parameter-generator-utils.d.ts +5 -2
  48. package/dist/esm/src/discovery/parameter-generator-utils.d.ts.map +1 -1
  49. package/dist/esm/src/discovery/parameter-generator-utils.js +54 -27
  50. package/dist/esm/src/discovery/parameter-generator-utils.js.map +1 -1
  51. package/dist/esm/src/discovery/parameter-generator.d.ts +6 -0
  52. package/dist/esm/src/discovery/parameter-generator.d.ts.map +1 -1
  53. package/dist/esm/src/discovery/parameter-generator.js +43 -17
  54. package/dist/esm/src/discovery/parameter-generator.js.map +1 -1
  55. package/dist/esm/src/index.d.ts.map +1 -1
  56. package/dist/esm/src/index.js +3 -0
  57. package/dist/esm/src/index.js.map +1 -1
  58. package/dist/esm/src/utils/merge-specs.d.ts +34 -0
  59. package/dist/esm/src/utils/merge-specs.d.ts.map +1 -0
  60. package/dist/esm/src/utils/merge-specs.js +50 -0
  61. package/dist/esm/src/utils/merge-specs.js.map +1 -0
  62. package/dist/esm/src/utils/parse-baud-rate.d.ts +14 -0
  63. package/dist/esm/src/utils/parse-baud-rate.d.ts.map +1 -0
  64. package/dist/esm/src/utils/parse-baud-rate.js +49 -0
  65. package/dist/esm/src/utils/parse-baud-rate.js.map +1 -0
  66. package/dist/esm/src/utils/parse-id-range.d.ts +13 -0
  67. package/dist/esm/src/utils/parse-id-range.d.ts.map +1 -0
  68. package/dist/esm/src/utils/parse-id-range.js +46 -0
  69. package/dist/esm/src/utils/parse-id-range.js.map +1 -0
  70. package/dist/esm/src/utils/parse-integer.d.ts +15 -0
  71. package/dist/esm/src/utils/parse-integer.d.ts.map +1 -0
  72. package/dist/esm/src/utils/parse-integer.js +24 -0
  73. package/dist/esm/src/utils/parse-integer.js.map +1 -0
  74. package/dist/esm/src/utils/parse-parity.d.ts +18 -0
  75. package/dist/esm/src/utils/parse-parity.d.ts.map +1 -0
  76. package/dist/esm/src/utils/parse-parity.js +42 -0
  77. package/dist/esm/src/utils/parse-parity.js.map +1 -0
  78. package/dist/esm/src/utils/parse-spec.d.ts +73 -0
  79. package/dist/esm/src/utils/parse-spec.d.ts.map +1 -0
  80. package/dist/esm/src/utils/parse-spec.js +44 -0
  81. package/dist/esm/src/utils/parse-spec.js.map +1 -0
  82. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  83. package/package.json +2 -2
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergeSpecs = mergeSpecs;
4
+ /**
5
+ * Merges multiple specification strings (from repeated CLI flags) into a
6
+ * single deduplicated, sorted array.
7
+ *
8
+ * Handles:
9
+ * - Single string or array of strings
10
+ * - Deduplication across all specifications
11
+ * - Custom sorting
12
+ *
13
+ * @param specs - Single spec string, array of spec strings, or undefined
14
+ * @param parser - Function that parses a single spec string
15
+ * @param sorter - Optional function to sort the final array
16
+ * @returns Merged and sorted array, or undefined if specs is undefined
17
+ *
18
+ * @example
19
+ * // Merge multiple --id specifications
20
+ * const ids = mergeSpecs(
21
+ * ['1,2', '3-5'],
22
+ * parseIdRange,
23
+ * (items) => items.sort((a, b) => a - b)
24
+ * )
25
+ * // Result: [1, 2, 3, 4, 5]
26
+ *
27
+ * @example
28
+ * // Merge multiple --parity specifications
29
+ * const parities = mergeSpecs(
30
+ * ['none', 'even,odd'],
31
+ * parseParity,
32
+ * sortParitiesInStandardOrder
33
+ * )
34
+ * // Result: ['none', 'even', 'odd']
35
+ */
36
+ function mergeSpecs(specs, parser, sorter) {
37
+ if (specs === undefined) {
38
+ return undefined;
39
+ }
40
+ // Normalize to array
41
+ const specArray = Array.isArray(specs) ? specs : [specs];
42
+ // Parse and merge into Set for deduplication
43
+ const allValues = new Set();
44
+ for (const spec of specArray) {
45
+ const values = parser(spec);
46
+ values.forEach((value) => allValues.add(value));
47
+ }
48
+ // Convert to array
49
+ const result = Array.from(allValues);
50
+ // Apply custom sorter if provided, otherwise return unsorted
51
+ return sorter ? sorter(result) : result;
52
+ }
53
+ //# sourceMappingURL=merge-specs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-specs.js","sourceRoot":"","sources":["../../../../src/utils/merge-specs.ts"],"names":[],"mappings":";;AAgCA,gCAwBC;AAxDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,SAAgB,UAAU,CACxB,KAAoC,EACpC,MAA6B,EAC7B,MAA4B;IAE5B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,qBAAqB;IACrB,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;IAExD,6CAA6C;IAC7C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAK,CAAA;IAC9B,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;QAC3B,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;IACjD,CAAC;IAED,mBAAmB;IACnB,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAEpC,6DAA6D;IAC7D,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;AACzC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { BaudRate } from '@ya-modbus/driver-types';
2
+ /**
3
+ * Parses a comma-separated list of baud rates and ranges into a sorted array of unique baud rates.
4
+ *
5
+ * @param spec - Baud rate specification string (e.g., "9600,19200" or "9600-38400")
6
+ * @returns Sorted array of unique baud rates from STANDARD_BAUD_RATES
7
+ *
8
+ * @example
9
+ * parseBaudRate("9600,19200") // [9600, 19200]
10
+ * parseBaudRate("9600-19200") // [9600, 14400, 19200]
11
+ * parseBaudRate("19200,9600") // [9600, 19200]
12
+ */
13
+ export declare function parseBaudRate(spec: string): BaudRate[];
14
+ //# sourceMappingURL=parse-baud-rate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-baud-rate.d.ts","sourceRoot":"","sources":["../../../../src/utils/parse-baud-rate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAOvD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,CA2BtD"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseBaudRate = parseBaudRate;
4
+ const constants_js_1 = require("../discovery/constants.js");
5
+ const parse_integer_js_1 = require("./parse-integer.js");
6
+ const parse_spec_js_1 = require("./parse-spec.js");
7
+ /**
8
+ * Parses a comma-separated list of baud rates and ranges into a sorted array of unique baud rates.
9
+ *
10
+ * @param spec - Baud rate specification string (e.g., "9600,19200" or "9600-38400")
11
+ * @returns Sorted array of unique baud rates from STANDARD_BAUD_RATES
12
+ *
13
+ * @example
14
+ * parseBaudRate("9600,19200") // [9600, 19200]
15
+ * parseBaudRate("9600-19200") // [9600, 14400, 19200]
16
+ * parseBaudRate("19200,9600") // [9600, 19200]
17
+ */
18
+ function parseBaudRate(spec) {
19
+ return (0, parse_spec_js_1.parseSpec)({
20
+ spec,
21
+ label: 'baud rate',
22
+ formatExamples: ['"9600,19200"', '"9600-19200"'],
23
+ skipEmptyParts: true,
24
+ parseSingle: (value, context) => {
25
+ const rate = (0, parse_integer_js_1.parseInteger)(value, context, 'baud rate');
26
+ validateBaudRate(rate, context);
27
+ return rate;
28
+ },
29
+ parseRange: (start, end, context) => {
30
+ const startRate = (0, parse_integer_js_1.parseInteger)(start, context, 'baud rate');
31
+ const endRate = (0, parse_integer_js_1.parseInteger)(end, context, 'baud rate');
32
+ if (startRate > endRate) {
33
+ throw new Error(`Invalid range: "${context}". Start must be less than or equal to end`);
34
+ }
35
+ validateBaudRate(startRate, context);
36
+ validateBaudRate(endRate, context);
37
+ // Extract baud rates between start and end from STANDARD_BAUD_RATES
38
+ return constants_js_1.STANDARD_BAUD_RATES.filter((rate) => rate >= startRate && rate <= endRate);
39
+ },
40
+ sortItems: (items) => items.sort((a, b) => a - b),
41
+ });
42
+ }
43
+ /**
44
+ * Validates that a number is a supported baud rate.
45
+ */
46
+ function validateBaudRate(rate, context) {
47
+ if (!constants_js_1.STANDARD_BAUD_RATES.includes(rate)) {
48
+ throw new Error(`Unsupported baud rate: ${rate} in "${context}". ` +
49
+ `Supported rates are: ${constants_js_1.STANDARD_BAUD_RATES.join(', ')}`);
50
+ }
51
+ }
52
+ //# sourceMappingURL=parse-baud-rate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-baud-rate.js","sourceRoot":"","sources":["../../../../src/utils/parse-baud-rate.ts"],"names":[],"mappings":";;AAkBA,sCA2BC;AA3CD,4DAA+D;AAE/D,yDAAiD;AACjD,mDAA2C;AAE3C;;;;;;;;;;GAUG;AACH,SAAgB,aAAa,CAAC,IAAY;IACxC,OAAO,IAAA,yBAAS,EAAC;QACf,IAAI;QACJ,KAAK,EAAE,WAAW;QAClB,cAAc,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC;QAChD,cAAc,EAAE,IAAI;QACpB,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAC9B,MAAM,IAAI,GAAG,IAAA,+BAAY,EAAC,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC,CAAA;YACtD,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;YAC/B,OAAO,IAAI,CAAA;QACb,CAAC;QACD,UAAU,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;YAClC,MAAM,SAAS,GAAG,IAAA,+BAAY,EAAC,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC,CAAA;YAC3D,MAAM,OAAO,GAAG,IAAA,+BAAY,EAAC,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC,CAAA;YAEvD,IAAI,SAAS,GAAG,OAAO,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,mBAAmB,OAAO,4CAA4C,CAAC,CAAA;YACzF,CAAC;YAED,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;YACpC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAElC,oEAAoE;YACpE,OAAO,kCAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,SAAS,IAAI,IAAI,IAAI,OAAO,CAAC,CAAA;QACnF,CAAC;QACD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;KAClD,CAAC,CAAA;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,IAAY,EAAE,OAAe;IACrD,IAAI,CAAC,kCAAmB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,0BAA0B,IAAI,QAAQ,OAAO,KAAK;YAChD,wBAAwB,kCAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC3D,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Parses a comma-separated list of IDs and ranges into a sorted array of unique IDs.
3
+ *
4
+ * @param spec - ID specification string (e.g., "1,2,3-5")
5
+ * @returns Sorted array of unique Modbus slave IDs (1-247)
6
+ *
7
+ * @example
8
+ * parseIdRange("1,2,3-5") // [1, 2, 3, 4, 5]
9
+ * parseIdRange("5,1,3") // [1, 3, 5]
10
+ * parseIdRange("1-3,2-4") // [1, 2, 3, 4]
11
+ */
12
+ export declare function parseIdRange(spec: string): number[];
13
+ //# sourceMappingURL=parse-id-range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-id-range.d.ts","sourceRoot":"","sources":["../../../../src/utils/parse-id-range.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BnD"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseIdRange = parseIdRange;
4
+ const parse_integer_js_1 = require("./parse-integer.js");
5
+ const parse_spec_js_1 = require("./parse-spec.js");
6
+ /**
7
+ * Parses a comma-separated list of IDs and ranges into a sorted array of unique IDs.
8
+ *
9
+ * @param spec - ID specification string (e.g., "1,2,3-5")
10
+ * @returns Sorted array of unique Modbus slave IDs (1-247)
11
+ *
12
+ * @example
13
+ * parseIdRange("1,2,3-5") // [1, 2, 3, 4, 5]
14
+ * parseIdRange("5,1,3") // [1, 3, 5]
15
+ * parseIdRange("1-3,2-4") // [1, 2, 3, 4]
16
+ */
17
+ function parseIdRange(spec) {
18
+ return (0, parse_spec_js_1.parseSpec)({
19
+ spec,
20
+ label: 'ID',
21
+ formatExamples: ['"1,2,3"', '"1-5"'],
22
+ skipEmptyParts: true,
23
+ parseSingle: (value, context) => {
24
+ const id = (0, parse_integer_js_1.parseInteger)(value, context, 'ID');
25
+ validateModbusAddress(id, context);
26
+ return id;
27
+ },
28
+ parseRange: (start, end, context) => {
29
+ const startId = (0, parse_integer_js_1.parseInteger)(start, context, 'ID');
30
+ const endId = (0, parse_integer_js_1.parseInteger)(end, context, 'ID');
31
+ if (startId > endId) {
32
+ throw new Error(`Invalid range: "${context}". Start must be less than or equal to end`);
33
+ }
34
+ validateModbusAddress(startId, context);
35
+ validateModbusAddress(endId, context);
36
+ return Array.from({ length: endId - startId + 1 }, (_, i) => startId + i);
37
+ },
38
+ sortItems: (items) => items.sort((a, b) => a - b),
39
+ });
40
+ }
41
+ /**
42
+ * Validates that a number is a valid Modbus slave address (1-247).
43
+ */
44
+ function validateModbusAddress(id, context) {
45
+ if (id < 1 || id > 247) {
46
+ throw new Error(`Invalid Modbus slave address: ${id} in "${context}". ` + `Valid addresses are 1-247`);
47
+ }
48
+ }
49
+ //# sourceMappingURL=parse-id-range.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-id-range.js","sourceRoot":"","sources":["../../../../src/utils/parse-id-range.ts"],"names":[],"mappings":";;AAcA,oCA0BC;AAxCD,yDAAiD;AACjD,mDAA2C;AAE3C;;;;;;;;;;GAUG;AACH,SAAgB,YAAY,CAAC,IAAY;IACvC,OAAO,IAAA,yBAAS,EAAC;QACf,IAAI;QACJ,KAAK,EAAE,IAAI;QACX,cAAc,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC;QACpC,cAAc,EAAE,IAAI;QACpB,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAC9B,MAAM,EAAE,GAAG,IAAA,+BAAY,EAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;YAC7C,qBAAqB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;YAClC,OAAO,EAAE,CAAA;QACX,CAAC;QACD,UAAU,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;YAClC,MAAM,OAAO,GAAG,IAAA,+BAAY,EAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;YAClD,MAAM,KAAK,GAAG,IAAA,+BAAY,EAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;YAE9C,IAAI,OAAO,GAAG,KAAK,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,mBAAmB,OAAO,4CAA4C,CAAC,CAAA;YACzF,CAAC;YAED,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YACvC,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;YAErC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,OAAO,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,GAAG,CAAC,CAAC,CAAA;QAC3E,CAAC;QACD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;KAClD,CAAC,CAAA;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,EAAU,EAAE,OAAe;IACxD,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,iCAAiC,EAAE,QAAQ,OAAO,KAAK,GAAG,2BAA2B,CACtF,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Parses a string to an integer with validation.
3
+ * Rejects decimal numbers explicitly.
4
+ *
5
+ * @param str - String to parse
6
+ * @param context - Context string for error messages
7
+ * @param label - Label for the value type (e.g., "ID", "baud rate")
8
+ * @returns Parsed integer
9
+ *
10
+ * @example
11
+ * parseInteger("123", "1-5", "ID") // 123
12
+ * parseInteger("12.5", "1-5", "ID") // throws Error
13
+ */
14
+ export declare function parseInteger(str: string, context: string, label: string): number;
15
+ //# sourceMappingURL=parse-integer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-integer.d.ts","sourceRoot":"","sources":["../../../../src/utils/parse-integer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAahF"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseInteger = parseInteger;
4
+ /**
5
+ * Parses a string to an integer with validation.
6
+ * Rejects decimal numbers explicitly.
7
+ *
8
+ * @param str - String to parse
9
+ * @param context - Context string for error messages
10
+ * @param label - Label for the value type (e.g., "ID", "baud rate")
11
+ * @returns Parsed integer
12
+ *
13
+ * @example
14
+ * parseInteger("123", "1-5", "ID") // 123
15
+ * parseInteger("12.5", "1-5", "ID") // throws Error
16
+ */
17
+ function parseInteger(str, context, label) {
18
+ if (str.includes('.')) {
19
+ throw new Error(`Invalid ${label} format: "${context}". Decimal numbers not allowed, expected whole numbers only`);
20
+ }
21
+ const num = parseInt(str, 10);
22
+ if (isNaN(num)) {
23
+ throw new Error(`Invalid ${label} format: "${context}". Expected a number`);
24
+ }
25
+ return num;
26
+ }
27
+ //# sourceMappingURL=parse-integer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-integer.js","sourceRoot":"","sources":["../../../../src/utils/parse-integer.ts"],"names":[],"mappings":";;AAaA,oCAaC;AA1BD;;;;;;;;;;;;GAYG;AACH,SAAgB,YAAY,CAAC,GAAW,EAAE,OAAe,EAAE,KAAa;IACtE,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,aAAa,OAAO,6DAA6D,CAClG,CAAA;IACH,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;IAC7B,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,aAAa,OAAO,sBAAsB,CAAC,CAAA;IAC7E,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Parity } from '@ya-modbus/driver-types';
2
+ /**
3
+ * Parses a comma-separated list of parity values into a sorted array of unique parities.
4
+ *
5
+ * @param spec - Parity specification string (e.g., "none,even,odd")
6
+ * @returns Sorted array of unique parity values in standard order (none, even, odd)
7
+ *
8
+ * @example
9
+ * parseParity("none,even") // ["none", "even"]
10
+ * parseParity("odd,none") // ["none", "odd"]
11
+ * parseParity("even,even") // ["even"]
12
+ */
13
+ export declare function parseParity(spec: string): Parity[];
14
+ /**
15
+ * Sorts parities in standard order (none, even, odd)
16
+ */
17
+ export declare function sortParitiesInStandardOrder(parities: Parity[]): Parity[];
18
+ //# sourceMappingURL=parse-parity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-parity.d.ts","sourceRoot":"","sources":["../../../../src/utils/parse-parity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAMrD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAmBlD;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAExE"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseParity = parseParity;
4
+ exports.sortParitiesInStandardOrder = sortParitiesInStandardOrder;
5
+ const constants_js_1 = require("../discovery/constants.js");
6
+ const parse_spec_js_1 = require("./parse-spec.js");
7
+ /**
8
+ * Parses a comma-separated list of parity values into a sorted array of unique parities.
9
+ *
10
+ * @param spec - Parity specification string (e.g., "none,even,odd")
11
+ * @returns Sorted array of unique parity values in standard order (none, even, odd)
12
+ *
13
+ * @example
14
+ * parseParity("none,even") // ["none", "even"]
15
+ * parseParity("odd,none") // ["none", "odd"]
16
+ * parseParity("even,even") // ["even"]
17
+ */
18
+ function parseParity(spec) {
19
+ return (0, parse_spec_js_1.parseSpec)({
20
+ spec,
21
+ label: 'parity',
22
+ formatExamples: ['"none,even,odd"'],
23
+ skipEmptyParts: false, // Throw error on empty parts for explicit validation
24
+ parseSingle: (value, context) => {
25
+ const normalized = value.toLowerCase();
26
+ if (!isValidParity(normalized)) {
27
+ throw new Error(`Invalid parity value: "${value}" in "${context}". Valid values are: ${constants_js_1.STANDARD_PARITY.join(', ')}`);
28
+ }
29
+ return normalized;
30
+ },
31
+ sortItems: (items) => sortParitiesInStandardOrder(items),
32
+ });
33
+ }
34
+ /**
35
+ * Sorts parities in standard order (none, even, odd)
36
+ */
37
+ function sortParitiesInStandardOrder(parities) {
38
+ return constants_js_1.STANDARD_PARITY.filter((p) => parities.includes(p));
39
+ }
40
+ /**
41
+ * Type guard to check if a string is a valid parity value.
42
+ */
43
+ function isValidParity(value) {
44
+ return constants_js_1.STANDARD_PARITY.includes(value);
45
+ }
46
+ //# sourceMappingURL=parse-parity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-parity.js","sourceRoot":"","sources":["../../../../src/utils/parse-parity.ts"],"names":[],"mappings":";;AAiBA,kCAmBC;AAKD,kEAEC;AAzCD,4DAA2D;AAE3D,mDAA2C;AAE3C;;;;;;;;;;GAUG;AACH,SAAgB,WAAW,CAAC,IAAY;IACtC,OAAO,IAAA,yBAAS,EAAC;QACf,IAAI;QACJ,KAAK,EAAE,QAAQ;QACf,cAAc,EAAE,CAAC,iBAAiB,CAAC;QACnC,cAAc,EAAE,KAAK,EAAE,qDAAqD;QAC5E,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAC9B,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA;YAEtC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CACb,0BAA0B,KAAK,SAAS,OAAO,wBAAwB,8BAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACpG,CAAA;YACH,CAAC;YAED,OAAO,UAAU,CAAA;QACnB,CAAC;QACD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,2BAA2B,CAAC,KAAK,CAAC;KACzD,CAAC,CAAA;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,2BAA2B,CAAC,QAAkB;IAC5D,OAAO,8BAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;AAC5D,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,8BAAe,CAAC,QAAQ,CAAC,KAAe,CAAC,CAAA;AAClD,CAAC"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Generic utility for parsing comma-separated specification strings
3
+ * with optional range support.
4
+ *
5
+ * Handles:
6
+ * - Empty string validation
7
+ * - Comma-separated list parsing
8
+ * - Optional range expansion (e.g., "1-5")
9
+ * - Deduplication via Set
10
+ * - Custom sorting/ordering
11
+ *
12
+ * @example
13
+ * const parseIds = (spec: string) => parseSpec({
14
+ * spec,
15
+ * label: 'ID',
16
+ * formatExamples: ['"1,2,3"', '"1-5"'],
17
+ * parseSingle: (value, context) => {
18
+ * const id = parseInteger(value, context, 'ID')
19
+ * if (id < 1 || id > 247) throw new Error(...)
20
+ * return id
21
+ * },
22
+ * parseRange: (start, end, context) => {
23
+ * const startId = parseInteger(start, context, 'ID')
24
+ * const endId = parseInteger(end, context, 'ID')
25
+ * return Array.from({length: endId - startId + 1}, (_, i) => startId + i)
26
+ * },
27
+ * sortItems: (items) => items.sort((a, b) => a - b)
28
+ * })
29
+ */
30
+ export interface ParseSpecOptions<T> {
31
+ /** The specification string to parse (e.g., "1,2,3" or "none,even") */
32
+ spec: string;
33
+ /** Label for the value type (e.g., "ID", "parity", "baud rate") */
34
+ label: string;
35
+ /** Example formats to show in error messages (e.g., ['"1,2,3"', '"1-5"']) */
36
+ formatExamples: string[];
37
+ /**
38
+ * Parse a single value from the spec
39
+ * @param value - The trimmed value to parse
40
+ * @param context - The original part for error context
41
+ * @returns The parsed value
42
+ */
43
+ parseSingle: (value: string, context: string) => T;
44
+ /**
45
+ * Optional: Parse a range (e.g., "1-5")
46
+ * @param start - The start value string
47
+ * @param end - The end value string
48
+ * @param context - The original range string for error context
49
+ * @returns Array of values in the range
50
+ */
51
+ parseRange?: (start: string, end: string, context: string) => T[];
52
+ /**
53
+ * Sort/order the final array of values
54
+ * @param items - Deduplicated array of items
55
+ * @returns Sorted array
56
+ */
57
+ sortItems: (items: T[]) => T[];
58
+ /**
59
+ * Optional: Skip empty parts in comma-separated list instead of throwing error
60
+ * Default: false (throw error on empty parts)
61
+ */
62
+ skipEmptyParts?: boolean;
63
+ }
64
+ /**
65
+ * Generic parser for comma-separated specification strings
66
+ *
67
+ * @param options - Parsing options
68
+ * @returns Sorted array of unique values
69
+ *
70
+ * @throws Error if spec is empty or contains invalid values
71
+ */
72
+ export declare function parseSpec<T>(options: ParseSpecOptions<T>): T[];
73
+ //# sourceMappingURL=parse-spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-spec.d.ts","sourceRoot":"","sources":["../../../../src/utils/parse-spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAA;IAEZ,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAA;IAEb,6EAA6E;IAC7E,cAAc,EAAE,MAAM,EAAE,CAAA;IAExB;;;;;OAKG;IACH,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC,CAAA;IAElD;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC,EAAE,CAAA;IAEjE;;;;OAIG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAAA;IAE9B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAoD9D"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSpec = parseSpec;
4
+ /**
5
+ * Generic parser for comma-separated specification strings
6
+ *
7
+ * @param options - Parsing options
8
+ * @returns Sorted array of unique values
9
+ *
10
+ * @throws Error if spec is empty or contains invalid values
11
+ */
12
+ function parseSpec(options) {
13
+ const { spec, label, formatExamples, parseSingle, parseRange, sortItems, skipEmptyParts = false, } = options;
14
+ const trimmed = spec.trim();
15
+ if (!trimmed) {
16
+ throw new Error(`Invalid ${label} specification: empty string. Expected format: ${formatExamples.join(' or ')}`);
17
+ }
18
+ const items = new Set();
19
+ const parts = trimmed.split(',');
20
+ for (const part of parts) {
21
+ const normalized = part.trim();
22
+ if (!normalized) {
23
+ if (skipEmptyParts) {
24
+ continue;
25
+ }
26
+ else {
27
+ throw new Error(`Invalid ${label} specification: empty value in "${spec}". Expected format: ${formatExamples.join(' or ')}`);
28
+ }
29
+ }
30
+ // Check if it's a range (contains hyphen)
31
+ if (normalized.includes('-') && parseRange) {
32
+ const rangeParts = normalized.split('-').map((s) => s.trim());
33
+ if (rangeParts.length !== 2 || !rangeParts[0] || !rangeParts[1]) {
34
+ throw new Error(`Invalid range format: "${part}". Expected format: "start-end"`);
35
+ }
36
+ const rangeValues = parseRange(rangeParts[0], rangeParts[1], part);
37
+ rangeValues.forEach((value) => items.add(value));
38
+ }
39
+ else {
40
+ // Single value
41
+ const value = parseSingle(normalized, part);
42
+ items.add(value);
43
+ }
44
+ }
45
+ return sortItems(Array.from(items));
46
+ }
47
+ //# sourceMappingURL=parse-spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-spec.js","sourceRoot":"","sources":["../../../../src/utils/parse-spec.ts"],"names":[],"mappings":";;AA8EA,8BAoDC;AA5DD;;;;;;;GAOG;AACH,SAAgB,SAAS,CAAI,OAA4B;IACvD,MAAM,EACJ,IAAI,EACJ,KAAK,EACL,cAAc,EACd,WAAW,EACX,UAAU,EACV,SAAS,EACT,cAAc,GAAG,KAAK,GACvB,GAAG,OAAO,CAAA;IAEX,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,kDAAkD,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAChG,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,GAAG,EAAK,CAAA;IAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAEhC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAE9B,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,IAAI,cAAc,EAAE,CAAC;gBACnB,SAAQ;YACV,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,mCAAmC,IAAI,uBAAuB,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAC5G,CAAA;YACH,CAAC;QACH,CAAC;QAED,0CAA0C;QAC1C,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3C,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;YAE7D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChE,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,iCAAiC,CAAC,CAAA;YAClF,CAAC;YAED,MAAM,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;YAClE,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;QAClD,CAAC;aAAM,CAAC;YACN,eAAe;YACf,MAAM,KAAK,GAAG,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;YAC3C,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAClB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;AACrC,CAAC"}