qlcodes 1.2.0 → 1.3.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/dist/index.mjs CHANGED
@@ -1,69 +1,119 @@
1
- import { readFileSync } from "fs";
1
+ import data from "./qlCodes.json" with {type : "json"}
2
2
 
3
- const data = JSON.parse(readFileSync("./qlCodes.json"));
3
+ const keyRegex = /^[a-zA-Z0-9_]+$/;
4
+ const codeRegex = /^[A-Z0-9]{5}$/;
4
5
 
5
- export const lens = (code) => {
6
- let response = {
7
- code,
8
- qlcs: "",
9
- matches: [],
10
- };
6
+ const NON_ASSOCIATED_CLASS = "NA";
11
7
 
12
- try {
13
- // ---- validation ----
14
- if (
15
- code === "" ||
16
- (!code && code !== "0") ||
17
- !/^[A-Z0-9]{5}$/.test(`${code}`.padStart(5, "0"))
18
- ) {
19
- throw "qlcodes_malformed";
20
- }
8
+ const QLCODES_ERR_MALFORMED = "qlcodes_malformed"
9
+ const QLCODES_ERR_NOT_FOUND = "qlcodes_no_code_found"
10
+ const QLCODES_ERR_UNEXPECTED_ERR = "qlcodes_unexpected_error"
21
11
 
22
- const paddedCode = `${code}`.padStart(5, "0");
12
+ const QLCODES_SUCCESS = "qlcodes_success"
23
13
 
24
- // ---- find matching class ----
25
- const classEntry = Object.entries(data).find(([id]) =>
26
- paddedCode.startsWith(id)
27
- );
14
+ const _validateSearch = (search, response) => {
15
+ if (
16
+ search === "" ||
17
+ (!search && search !== "0") ||
18
+ (!codeRegex.test(`${search}`.padStart(5, "0")) &&
19
+ !keyRegex.test(`${search}`))
20
+ ) {
21
+ throw QLCODES_ERR_MALFORMED;
22
+ } else if (codeRegex.test(`${search}`)) {
23
+ response.code = search;
24
+ } else {
25
+ response.key = search;
26
+ }
27
+ };
28
28
 
29
- const classesToSearch = [];
29
+ const _getHitKeyOrCode = (cls, response, paddedSearch) => {
30
+ if (!response.key && !response.code) {
31
+ return [];
32
+ }
33
+ const matchingInKeys = (x) => x.keys.find((k) => paddedSearch === k);
34
+ const matchingCode = (x) =>
35
+ x.code === paddedSearch || x.code === paddedSearch;
30
36
 
31
- if (classEntry) {
32
- classesToSearch.push({
33
- id: classEntry[0],
34
- data: classEntry[1],
35
- });
36
- }
37
+ return cls.data.messageSet.filter(
38
+ response.key ? matchingInKeys : matchingCode
39
+ );
40
+ };
37
41
 
38
- // Always include NA as fallback / collision source
39
- if (data["NA"]) {
40
- classesToSearch.push({
41
- id: "NA",
42
- data: data["NA"],
42
+ const _collectAllMatches = (classesToSearch, response, paddedSearch) => {
43
+ const matches = [];
44
+ for (const cls of classesToSearch) {
45
+ for (const hit of _getHitKeyOrCode(cls, response, paddedSearch)) {
46
+ matches.push({
47
+ ...hit,
48
+ class: `${cls.id} - ${cls.data.label}`,
43
49
  });
44
50
  }
51
+ }
52
+ return matches;
53
+ };
45
54
 
46
- // ---- collect all matches ----
47
- for (const cls of classesToSearch) {
48
- const hits = cls.data.messageSet.filter(
49
- (x) => x.code === paddedCode || x.code === code
50
- );
51
-
52
- for (const hit of hits) {
53
- response.matches.push({
54
- ...hit,
55
- class: `${cls.id} - ${cls.data.label}`,
56
- });
57
- }
58
- }
55
+ const _classesForCodeSearch = (entries, paddedSearch) => {
56
+ const classesToSearch = [];
57
+ const classEntry = entries.find(([id]) => paddedSearch.startsWith(id));
58
+ if (classEntry) {
59
+ classesToSearch.push({
60
+ id: classEntry[0],
61
+ data: classEntry[1],
62
+ });
63
+ }
64
+ // Always include NA as fallback / collision source
65
+ if (data[NON_ASSOCIATED_CLASS]) {
66
+ classesToSearch.push({
67
+ id: NON_ASSOCIATED_CLASS,
68
+ data: data[NON_ASSOCIATED_CLASS],
69
+ });
70
+ }
71
+ };
72
+
73
+ const _classesForKeySearche = (entries) => {
74
+ const classesToSearch = [];
75
+ entries.forEach(([id]) => {
76
+ classesToSearch.push({
77
+ id,
78
+ data: data[id],
79
+ });
80
+ });
81
+ return classesToSearch;
82
+ };
83
+
84
+ export const lens = (search) => {
85
+ let response = {
86
+ code: undefined,
87
+ key: undefined,
88
+ qlcs: "",
89
+ matches: [],
90
+ };
91
+
92
+ try {
93
+ _validateSearch(search, response);
94
+
95
+ const paddedSearch = `${search}`.padStart(5, "0");
96
+ const classes = Object.entries(data);
97
+
98
+ const classesToSearch = response.code
99
+ ? _classesForCodeSearch(classes, paddedSearch)
100
+ : response.key
101
+ ? _classesForKeySearche(classes)
102
+ : [];
103
+
104
+ response.matches = _collectAllMatches(
105
+ classesToSearch,
106
+ response,
107
+ paddedSearch
108
+ );
59
109
 
60
110
  if (response.matches.length === 0) {
61
- throw "qlcodes_no_code_found";
111
+ throw QLCODES_ERR_NOT_FOUND;
62
112
  }
63
113
 
64
- response.qlcs = "qlcodes_success";
114
+ response.qlcs = QLCODES_SUCCESS;
65
115
  } catch (err) {
66
- response.qlcs = typeof err === "string" ? err : "qlcodes_unexpected_error";
116
+ response.qlcs = typeof err === "string" ? err : QLCODES_ERR_UNEXPECTED_ERR;
67
117
  }
68
118
 
69
119
  return response;