qlcodes 1.2.0 → 1.3.1
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/README.md +50 -1
- package/dist/index.mjs +101 -50
- package/dist/qlCodes.json +37539 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,9 +55,58 @@ Output :
|
|
|
55
55
|
}
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
Alternatively, you may need to retrive matching codes via a known key for some technologies
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
import { lens } from "qlcodes";
|
|
62
|
+
|
|
63
|
+
const state = lens("insufficient_privilege");
|
|
64
|
+
|
|
65
|
+
console.log(state);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Output :
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
{
|
|
72
|
+
"key": "insufficient_privilege",
|
|
73
|
+
"qlcs": "qlcodes_success",
|
|
74
|
+
"matches": [
|
|
75
|
+
{
|
|
76
|
+
"code": "42501",
|
|
77
|
+
"keys": [
|
|
78
|
+
"insufficient_privilege",
|
|
79
|
+
"authorization_id_does_not_have_privilege_to_perform_specified_operation_on_identified_object"
|
|
80
|
+
],
|
|
81
|
+
"reasons": [
|
|
82
|
+
"The authorization ID does not have the privilege to perform the specified operation on the identified object."
|
|
83
|
+
],
|
|
84
|
+
"use": [
|
|
85
|
+
"pgsql",
|
|
86
|
+
"ibm"
|
|
87
|
+
],
|
|
88
|
+
"class": "42 - Syntax Error or Access Rule Violation"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"code": "258",
|
|
92
|
+
"keys": [
|
|
93
|
+
"insufficient_privilege"
|
|
94
|
+
],
|
|
95
|
+
"reasons": [
|
|
96
|
+
"Insufficient privilege"
|
|
97
|
+
],
|
|
98
|
+
"use": [
|
|
99
|
+
"sap_hana"
|
|
100
|
+
],
|
|
101
|
+
"class": "NA - Non associable class codes"
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
58
107
|
### Mismatches
|
|
59
108
|
|
|
60
|
-
If the provided SQLSTATE does not match any known entry, we return a normalized fallback object
|
|
109
|
+
If the provided SQLSTATE code or provided key does not match any known entry, we return a normalized fallback object
|
|
61
110
|
This guarantees that lens() always returns a predictable object shape.
|
|
62
111
|
|
|
63
112
|
There are three mismatch levels that we detect.
|
package/dist/index.mjs
CHANGED
|
@@ -1,69 +1,120 @@
|
|
|
1
|
-
import
|
|
1
|
+
import data from "./qlCodes.json" with { type: "json" };
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const keyRegex = /^[a-zA-Z0-9_]+$/;
|
|
4
|
+
const codeRegex = /^[A-Z0-9]{5}$/;
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
let response = {
|
|
7
|
-
code,
|
|
8
|
-
qlcs: "",
|
|
9
|
-
matches: [],
|
|
10
|
-
};
|
|
6
|
+
const NON_ASSOCIATED_CLASS = "NA";
|
|
11
7
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
12
|
+
const QLCODES_SUCCESS = "qlcodes_success";
|
|
23
13
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
+
return cls.data.messageSet.filter(
|
|
38
|
+
response.key ? matchingInKeys : matchingCode
|
|
39
|
+
);
|
|
40
|
+
};
|
|
37
41
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
+
return classesToSearch;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const _classesForKeySearche = (entries) => {
|
|
75
|
+
const classesToSearch = [];
|
|
76
|
+
entries.forEach(([id]) => {
|
|
77
|
+
classesToSearch.push({
|
|
78
|
+
id,
|
|
79
|
+
data: data[id],
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
return classesToSearch;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const lens = (search) => {
|
|
86
|
+
let response = {
|
|
87
|
+
code: undefined,
|
|
88
|
+
key: undefined,
|
|
89
|
+
qlcs: "",
|
|
90
|
+
matches: [],
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
_validateSearch(search, response);
|
|
95
|
+
|
|
96
|
+
const paddedSearch = `${search}`.padStart(5, "0");
|
|
97
|
+
const classes = Object.entries(data);
|
|
98
|
+
|
|
99
|
+
const classesToSearch = response.code
|
|
100
|
+
? _classesForCodeSearch(classes, paddedSearch)
|
|
101
|
+
: response.key
|
|
102
|
+
? _classesForKeySearche(classes)
|
|
103
|
+
: [];
|
|
104
|
+
|
|
105
|
+
response.matches = _collectAllMatches(
|
|
106
|
+
classesToSearch,
|
|
107
|
+
response,
|
|
108
|
+
paddedSearch
|
|
109
|
+
);
|
|
59
110
|
|
|
60
111
|
if (response.matches.length === 0) {
|
|
61
|
-
throw
|
|
112
|
+
throw QLCODES_ERR_NOT_FOUND;
|
|
62
113
|
}
|
|
63
114
|
|
|
64
|
-
response.qlcs =
|
|
115
|
+
response.qlcs = QLCODES_SUCCESS;
|
|
65
116
|
} catch (err) {
|
|
66
|
-
response.qlcs = typeof err === "string" ? err :
|
|
117
|
+
response.qlcs = typeof err === "string" ? err : QLCODES_ERR_UNEXPECTED_ERR;
|
|
67
118
|
}
|
|
68
119
|
|
|
69
120
|
return response;
|