dff-util 1.3.5 → 1.3.7
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 +214 -16
- package/dist/main/const-type.d.ts +19 -11
- package/dist/main/query-cond.d.ts +6 -0
- package/dist/main/query-cond.js +306 -0
- package/dist/main/util.d.ts +2 -1
- package/dist/main/util.js +40 -38
- package/dist/tests/util.js +35 -17
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -279,6 +279,12 @@ export type CountryType = {
|
|
|
279
279
|
};
|
|
280
280
|
```
|
|
281
281
|
|
|
282
|
+
### List of country and Locaion
|
|
283
|
+
```
|
|
284
|
+
const countriesList = countries;
|
|
285
|
+
|
|
286
|
+
countries: CountryType[] = [ ..., ..., ... ];
|
|
287
|
+
```
|
|
282
288
|
## LangDirType, OrderType, ThemeType, UnixTimestampType, OptionType, FileType
|
|
283
289
|
```
|
|
284
290
|
export type LangDirType = "ltr" | "rtl";
|
|
@@ -335,26 +341,32 @@ export type ResponseType = {
|
|
|
335
341
|
total?: number;
|
|
336
342
|
skip?: number;
|
|
337
343
|
limit?: number;
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
344
|
+
meta?: {
|
|
345
|
+
traceId?: string | number;
|
|
346
|
+
timestamp?: string | number;
|
|
347
|
+
duration?: number;
|
|
348
|
+
};
|
|
342
349
|
}
|
|
343
350
|
|
|
344
|
-
export type
|
|
351
|
+
export type SearchType = {
|
|
352
|
+
limit?: number;
|
|
353
|
+
skip?: number;
|
|
345
354
|
orderBy?: string;
|
|
346
|
-
order?:
|
|
355
|
+
order?: 'ASC' | 'DESC';
|
|
347
356
|
searchTerm?: string;
|
|
348
|
-
|
|
357
|
+
active?: boolean;
|
|
358
|
+
filters?: string;
|
|
349
359
|
};
|
|
350
360
|
|
|
351
|
-
export type
|
|
352
|
-
limit: number;
|
|
353
|
-
skip: number;
|
|
354
|
-
orderBy?: string;
|
|
355
|
-
order?: "ASC" | "DESC";
|
|
356
|
-
searchTerm?: string;
|
|
361
|
+
export type KeyValueType = {
|
|
357
362
|
[key: string]: any;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export type JsonValueType = string | number | boolean | null | JsonValueType[] | { [key: string]: JsonValueType };
|
|
366
|
+
export type RequestBodyType = Record<string, JsonValueType>;
|
|
367
|
+
export type RequestQueryType = Record<string, string | number | boolean | null>;
|
|
368
|
+
export type RequestByIdType = {
|
|
369
|
+
id: string | number;
|
|
358
370
|
};
|
|
359
371
|
|
|
360
372
|
```
|
|
@@ -601,12 +613,12 @@ const original = "Hello World! @#$% 😊";
|
|
|
601
613
|
|
|
602
614
|
// Encode
|
|
603
615
|
const safe = safeEncode(original);
|
|
604
|
-
console.log(safe);
|
|
616
|
+
console.log(safe);
|
|
605
617
|
// Output: "U0dWc2JHOGdWMjl5YkdRPQ%3D%3D"
|
|
606
618
|
|
|
607
619
|
// Decode
|
|
608
620
|
const decoded = safeDecode(safe);
|
|
609
|
-
console.log(decoded);
|
|
621
|
+
console.log(decoded);
|
|
610
622
|
// Output: "Hello World! @#$% 😊"
|
|
611
623
|
|
|
612
624
|
// Multiple encode/decode calls (idempotent)
|
|
@@ -936,4 +948,190 @@ toSchemaMapper(viewObj) -->
|
|
|
936
948
|
}
|
|
937
949
|
}
|
|
938
950
|
|
|
939
|
-
```
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
```
|
|
954
|
+
const got = QueryCond(input);
|
|
955
|
+
|
|
956
|
+
example:
|
|
957
|
+
QueryCond input: isApproved=true,status!=false,age>18,score<100,height>=170,weight<=80,type=["accept","inprogress"],type!=["accept","inprogress"],role in ["admin","editor"],role not in ["admin","editor"],role notin ["admin","editor"],deletedAt is null,deletedAt is not null,deletedAt isnull,updatedAt isnotnull,deletedAt=null,deletedAt!=null,age between [18,30],createdAt between 2020-01-01..2020-01-31,name like "Jo%",email ilike "%@gmail.com",title contains "hello",code startswith "AB",code endswith "99",path regex "^/api/.*$",archivedAt,!archivedAt,name="a,b",meta={"a":1,"b":true},tags=["x,y","z"]
|
|
958
|
+
QueryCond output: [
|
|
959
|
+
{
|
|
960
|
+
"key": "isApproved",
|
|
961
|
+
"opt": "=",
|
|
962
|
+
"value": true
|
|
963
|
+
},
|
|
964
|
+
{
|
|
965
|
+
"key": "status",
|
|
966
|
+
"opt": "!=",
|
|
967
|
+
"value": false
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
"key": "age",
|
|
971
|
+
"opt": ">",
|
|
972
|
+
"value": 18
|
|
973
|
+
},
|
|
974
|
+
{
|
|
975
|
+
"key": "score",
|
|
976
|
+
"opt": "<",
|
|
977
|
+
"value": 100
|
|
978
|
+
},
|
|
979
|
+
{
|
|
980
|
+
"key": "height",
|
|
981
|
+
"opt": ">=",
|
|
982
|
+
"value": 170
|
|
983
|
+
},
|
|
984
|
+
{
|
|
985
|
+
"key": "weight",
|
|
986
|
+
"opt": "<=",
|
|
987
|
+
"value": 80
|
|
988
|
+
},
|
|
989
|
+
{
|
|
990
|
+
"key": "type",
|
|
991
|
+
"opt": "in",
|
|
992
|
+
"value": [
|
|
993
|
+
"accept",
|
|
994
|
+
"inprogress"
|
|
995
|
+
]
|
|
996
|
+
},
|
|
997
|
+
{
|
|
998
|
+
"key": "type",
|
|
999
|
+
"opt": "not in",
|
|
1000
|
+
"value": [
|
|
1001
|
+
"accept",
|
|
1002
|
+
"inprogress"
|
|
1003
|
+
]
|
|
1004
|
+
},
|
|
1005
|
+
{
|
|
1006
|
+
"key": "role",
|
|
1007
|
+
"opt": "in",
|
|
1008
|
+
"value": [
|
|
1009
|
+
"admin",
|
|
1010
|
+
"editor"
|
|
1011
|
+
]
|
|
1012
|
+
},
|
|
1013
|
+
{
|
|
1014
|
+
"key": "role",
|
|
1015
|
+
"opt": "not in",
|
|
1016
|
+
"value": [
|
|
1017
|
+
"admin",
|
|
1018
|
+
"editor"
|
|
1019
|
+
]
|
|
1020
|
+
},
|
|
1021
|
+
{
|
|
1022
|
+
"key": "role",
|
|
1023
|
+
"opt": "not in",
|
|
1024
|
+
"value": [
|
|
1025
|
+
"admin",
|
|
1026
|
+
"editor"
|
|
1027
|
+
]
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
"key": "deletedAt",
|
|
1031
|
+
"opt": "is null",
|
|
1032
|
+
"value": null
|
|
1033
|
+
},
|
|
1034
|
+
{
|
|
1035
|
+
"key": "deletedAt",
|
|
1036
|
+
"opt": "is not null",
|
|
1037
|
+
"value": null
|
|
1038
|
+
},
|
|
1039
|
+
{
|
|
1040
|
+
"key": "deletedAt",
|
|
1041
|
+
"opt": "is null",
|
|
1042
|
+
"value": null
|
|
1043
|
+
},
|
|
1044
|
+
{
|
|
1045
|
+
"key": "updatedAt",
|
|
1046
|
+
"opt": "is not null",
|
|
1047
|
+
"value": null
|
|
1048
|
+
},
|
|
1049
|
+
{
|
|
1050
|
+
"key": "deletedAt",
|
|
1051
|
+
"opt": "is null",
|
|
1052
|
+
"value": null
|
|
1053
|
+
},
|
|
1054
|
+
{
|
|
1055
|
+
"key": "deletedAt",
|
|
1056
|
+
"opt": "is not null",
|
|
1057
|
+
"value": null
|
|
1058
|
+
},
|
|
1059
|
+
{
|
|
1060
|
+
"key": "age",
|
|
1061
|
+
"opt": "between",
|
|
1062
|
+
"value": [
|
|
1063
|
+
18,
|
|
1064
|
+
30
|
|
1065
|
+
]
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
"key": "createdAt",
|
|
1069
|
+
"opt": "between",
|
|
1070
|
+
"value": [
|
|
1071
|
+
"2020-01-01",
|
|
1072
|
+
"2020-01-31"
|
|
1073
|
+
]
|
|
1074
|
+
},
|
|
1075
|
+
{
|
|
1076
|
+
"key": "name",
|
|
1077
|
+
"opt": "like",
|
|
1078
|
+
"value": "Jo%"
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
"key": "email",
|
|
1082
|
+
"opt": "ilike",
|
|
1083
|
+
"value": "%@gmail.com"
|
|
1084
|
+
},
|
|
1085
|
+
{
|
|
1086
|
+
"key": "title",
|
|
1087
|
+
"opt": "contains",
|
|
1088
|
+
"value": "hello"
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
"key": "code",
|
|
1092
|
+
"opt": "startswith",
|
|
1093
|
+
"value": "AB"
|
|
1094
|
+
},
|
|
1095
|
+
{
|
|
1096
|
+
"key": "code",
|
|
1097
|
+
"opt": "endswith",
|
|
1098
|
+
"value": "99"
|
|
1099
|
+
},
|
|
1100
|
+
{
|
|
1101
|
+
"key": "path",
|
|
1102
|
+
"opt": "regex",
|
|
1103
|
+
"value": "^/api/.*$"
|
|
1104
|
+
},
|
|
1105
|
+
{
|
|
1106
|
+
"key": "archivedAt",
|
|
1107
|
+
"opt": "exists",
|
|
1108
|
+
"value": true
|
|
1109
|
+
},
|
|
1110
|
+
{
|
|
1111
|
+
"key": "archivedAt",
|
|
1112
|
+
"opt": "exists",
|
|
1113
|
+
"value": false
|
|
1114
|
+
},
|
|
1115
|
+
{
|
|
1116
|
+
"key": "name",
|
|
1117
|
+
"opt": "=",
|
|
1118
|
+
"value": "a,b"
|
|
1119
|
+
},
|
|
1120
|
+
{
|
|
1121
|
+
"key": "meta",
|
|
1122
|
+
"opt": "=",
|
|
1123
|
+
"value": {
|
|
1124
|
+
"a": 1,
|
|
1125
|
+
"b": true
|
|
1126
|
+
}
|
|
1127
|
+
},
|
|
1128
|
+
{
|
|
1129
|
+
"key": "tags",
|
|
1130
|
+
"opt": "in",
|
|
1131
|
+
"value": [
|
|
1132
|
+
"x,y",
|
|
1133
|
+
"z"
|
|
1134
|
+
]
|
|
1135
|
+
}
|
|
1136
|
+
]
|
|
1137
|
+
```
|
|
@@ -26,24 +26,32 @@ export type ResponseType = {
|
|
|
26
26
|
total?: number;
|
|
27
27
|
skip?: number;
|
|
28
28
|
limit?: number;
|
|
29
|
+
meta?: {
|
|
30
|
+
traceId?: string | number;
|
|
31
|
+
timestamp?: string | number;
|
|
32
|
+
duration?: number;
|
|
33
|
+
};
|
|
29
34
|
};
|
|
30
|
-
export type
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
searchTerm?: string;
|
|
34
|
-
[key: string]: any;
|
|
35
|
-
};
|
|
36
|
-
export type SearchByLimitType = {
|
|
37
|
-
limit: number;
|
|
38
|
-
skip: number;
|
|
35
|
+
export type SearchType = {
|
|
36
|
+
limit?: number;
|
|
37
|
+
skip?: number;
|
|
39
38
|
orderBy?: string;
|
|
40
|
-
order?:
|
|
39
|
+
order?: 'ASC' | 'DESC';
|
|
41
40
|
searchTerm?: string;
|
|
42
|
-
|
|
41
|
+
active?: boolean;
|
|
42
|
+
filters?: string;
|
|
43
43
|
};
|
|
44
44
|
export type KeyValueType = {
|
|
45
45
|
[key: string]: any;
|
|
46
46
|
};
|
|
47
|
+
export type JsonValueType = string | number | boolean | null | JsonValueType[] | {
|
|
48
|
+
[key: string]: JsonValueType;
|
|
49
|
+
};
|
|
50
|
+
export type RequestBodyType = Record<string, JsonValueType>;
|
|
51
|
+
export type RequestQueryType = Record<string, string | number | boolean | null>;
|
|
52
|
+
export type RequestByIdType = {
|
|
53
|
+
id: string | number;
|
|
54
|
+
};
|
|
47
55
|
export type CountryType = {
|
|
48
56
|
code: string;
|
|
49
57
|
name: string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type QueryCondItem = {
|
|
2
|
+
key: string;
|
|
3
|
+
opt: '=' | '!=' | '>' | '<' | '>=' | '<=' | 'in' | 'not in' | 'notin' | 'between' | 'isnull' | 'isnotnull' | 'is null' | 'is not null' | 'like' | 'ilike' | 'contains' | 'startswith' | 'endswith' | 'regex' | 'exists';
|
|
4
|
+
value: any;
|
|
5
|
+
};
|
|
6
|
+
export declare function QueryCond(input: string): QueryCondItem[];
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QueryCond = QueryCond;
|
|
4
|
+
function splitTopLevel(input, delimiter) {
|
|
5
|
+
const parts = [];
|
|
6
|
+
let buf = '';
|
|
7
|
+
let quote = null;
|
|
8
|
+
let escape = false;
|
|
9
|
+
let square = 0;
|
|
10
|
+
let curly = 0;
|
|
11
|
+
let paren = 0;
|
|
12
|
+
for (let i = 0; i < input.length; i++) {
|
|
13
|
+
const ch = input[i];
|
|
14
|
+
if (escape) {
|
|
15
|
+
buf += ch;
|
|
16
|
+
escape = false;
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
if (quote) {
|
|
20
|
+
if (ch === '\\') {
|
|
21
|
+
buf += ch;
|
|
22
|
+
escape = true;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
buf += ch;
|
|
26
|
+
if (ch === quote)
|
|
27
|
+
quote = null;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (ch === '"' || ch === "'") {
|
|
31
|
+
quote = ch;
|
|
32
|
+
buf += ch;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (ch === '[')
|
|
36
|
+
square++;
|
|
37
|
+
if (ch === ']')
|
|
38
|
+
square = Math.max(0, square - 1);
|
|
39
|
+
if (ch === '{')
|
|
40
|
+
curly++;
|
|
41
|
+
if (ch === '}')
|
|
42
|
+
curly = Math.max(0, curly - 1);
|
|
43
|
+
if (ch === '(')
|
|
44
|
+
paren++;
|
|
45
|
+
if (ch === ')')
|
|
46
|
+
paren = Math.max(0, paren - 1);
|
|
47
|
+
if (ch === delimiter && square === 0 && curly === 0 && paren === 0) {
|
|
48
|
+
const seg = buf.trim();
|
|
49
|
+
if (seg)
|
|
50
|
+
parts.push(seg);
|
|
51
|
+
buf = '';
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
buf += ch;
|
|
55
|
+
}
|
|
56
|
+
const last = buf.trim();
|
|
57
|
+
if (last)
|
|
58
|
+
parts.push(last);
|
|
59
|
+
return parts;
|
|
60
|
+
}
|
|
61
|
+
function parseMaybeJson(raw) {
|
|
62
|
+
const s = raw.trim();
|
|
63
|
+
if (!s)
|
|
64
|
+
return '';
|
|
65
|
+
if (s === 'null')
|
|
66
|
+
return null;
|
|
67
|
+
if (s === 'true')
|
|
68
|
+
return true;
|
|
69
|
+
if (s === 'false')
|
|
70
|
+
return false;
|
|
71
|
+
if (/^-?\d+(\.\d+)?$/.test(s))
|
|
72
|
+
return Number(s);
|
|
73
|
+
const first = s[0];
|
|
74
|
+
const last = s[s.length - 1];
|
|
75
|
+
if ((first === '"' && last === '"') || (first === "'" && last === "'")) {
|
|
76
|
+
if (first === '"') {
|
|
77
|
+
try {
|
|
78
|
+
return JSON.parse(s);
|
|
79
|
+
}
|
|
80
|
+
catch (_a) {
|
|
81
|
+
return s.slice(1, -1);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const inner = s.slice(1, -1);
|
|
85
|
+
return inner.replace(/\\'/g, "'").replace(/\\\\/g, '\\');
|
|
86
|
+
}
|
|
87
|
+
if ((first === '[' && last === ']') || (first === '{' && last === '}')) {
|
|
88
|
+
try {
|
|
89
|
+
return JSON.parse(s);
|
|
90
|
+
}
|
|
91
|
+
catch (_b) {
|
|
92
|
+
if (s.includes("'") && !s.includes('"')) {
|
|
93
|
+
try {
|
|
94
|
+
return JSON.parse(s.replace(/'/g, '"'));
|
|
95
|
+
}
|
|
96
|
+
catch (_c) {
|
|
97
|
+
return s;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return s;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return s;
|
|
104
|
+
}
|
|
105
|
+
function findTopLevelOpIndex(expr, ops) {
|
|
106
|
+
let quote = null;
|
|
107
|
+
let escape = false;
|
|
108
|
+
let square = 0;
|
|
109
|
+
let curly = 0;
|
|
110
|
+
let paren = 0;
|
|
111
|
+
for (let i = 0; i < expr.length; i++) {
|
|
112
|
+
const ch = expr[i];
|
|
113
|
+
if (escape) {
|
|
114
|
+
escape = false;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (quote) {
|
|
118
|
+
if (ch === '\\') {
|
|
119
|
+
escape = true;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (ch === quote)
|
|
123
|
+
quote = null;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (ch === '"' || ch === "'") {
|
|
127
|
+
quote = ch;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (ch === '[')
|
|
131
|
+
square++;
|
|
132
|
+
else if (ch === ']')
|
|
133
|
+
square = Math.max(0, square - 1);
|
|
134
|
+
else if (ch === '{')
|
|
135
|
+
curly++;
|
|
136
|
+
else if (ch === '}')
|
|
137
|
+
curly = Math.max(0, curly - 1);
|
|
138
|
+
else if (ch === '(')
|
|
139
|
+
paren++;
|
|
140
|
+
else if (ch === ')')
|
|
141
|
+
paren = Math.max(0, paren - 1);
|
|
142
|
+
if (square !== 0 || curly !== 0 || paren !== 0)
|
|
143
|
+
continue;
|
|
144
|
+
for (const op of ops) {
|
|
145
|
+
if (expr.startsWith(op, i)) {
|
|
146
|
+
return { op, idx: i };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
function findTopLevelTokenIndex(expr, token) {
|
|
153
|
+
let quote = null;
|
|
154
|
+
let escape = false;
|
|
155
|
+
let square = 0;
|
|
156
|
+
let curly = 0;
|
|
157
|
+
let paren = 0;
|
|
158
|
+
for (let i = 0; i < expr.length; i++) {
|
|
159
|
+
const ch = expr[i];
|
|
160
|
+
if (escape) {
|
|
161
|
+
escape = false;
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (quote) {
|
|
165
|
+
if (ch === '\\') {
|
|
166
|
+
escape = true;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (ch === quote)
|
|
170
|
+
quote = null;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (ch === '"' || ch === "'") {
|
|
174
|
+
quote = ch;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (ch === '[')
|
|
178
|
+
square++;
|
|
179
|
+
else if (ch === ']')
|
|
180
|
+
square = Math.max(0, square - 1);
|
|
181
|
+
else if (ch === '{')
|
|
182
|
+
curly++;
|
|
183
|
+
else if (ch === '}')
|
|
184
|
+
curly = Math.max(0, curly - 1);
|
|
185
|
+
else if (ch === '(')
|
|
186
|
+
paren++;
|
|
187
|
+
else if (ch === ')')
|
|
188
|
+
paren = Math.max(0, paren - 1);
|
|
189
|
+
if (square !== 0 || curly !== 0 || paren !== 0)
|
|
190
|
+
continue;
|
|
191
|
+
if (expr.startsWith(token, i))
|
|
192
|
+
return i;
|
|
193
|
+
}
|
|
194
|
+
return -1;
|
|
195
|
+
}
|
|
196
|
+
function parseBetweenValue(raw) {
|
|
197
|
+
const s = raw.trim();
|
|
198
|
+
if (!s)
|
|
199
|
+
return [];
|
|
200
|
+
if (s.startsWith('[') && s.endsWith(']')) {
|
|
201
|
+
const parsed = parseMaybeJson(s);
|
|
202
|
+
if (Array.isArray(parsed))
|
|
203
|
+
return parsed.slice(0, 2);
|
|
204
|
+
}
|
|
205
|
+
const idx = findTopLevelTokenIndex(s, '..');
|
|
206
|
+
if (idx >= 0) {
|
|
207
|
+
const left = s.slice(0, idx).trim();
|
|
208
|
+
const right = s.slice(idx + 2).trim();
|
|
209
|
+
return [parseMaybeJson(left), parseMaybeJson(right)];
|
|
210
|
+
}
|
|
211
|
+
return [parseMaybeJson(s)];
|
|
212
|
+
}
|
|
213
|
+
function normalizeOpt(opt) {
|
|
214
|
+
const o = opt.trim().toLowerCase();
|
|
215
|
+
if (o === '==')
|
|
216
|
+
return '=';
|
|
217
|
+
if (o === 'notin')
|
|
218
|
+
return 'not in';
|
|
219
|
+
if (o === 'is null')
|
|
220
|
+
return 'is null';
|
|
221
|
+
if (o === 'is not null')
|
|
222
|
+
return 'is not null';
|
|
223
|
+
if (o === 'isnull')
|
|
224
|
+
return 'is null';
|
|
225
|
+
if (o === 'isnotnull')
|
|
226
|
+
return 'is not null';
|
|
227
|
+
if (o === 'in')
|
|
228
|
+
return 'in';
|
|
229
|
+
if (o === 'not in')
|
|
230
|
+
return 'not in';
|
|
231
|
+
if (o === 'notin')
|
|
232
|
+
return 'not in';
|
|
233
|
+
if (o === 'between')
|
|
234
|
+
return 'between';
|
|
235
|
+
if (o === 'like')
|
|
236
|
+
return 'like';
|
|
237
|
+
if (o === 'ilike')
|
|
238
|
+
return 'ilike';
|
|
239
|
+
if (o === 'contains')
|
|
240
|
+
return 'contains';
|
|
241
|
+
if (o === 'startswith')
|
|
242
|
+
return 'startswith';
|
|
243
|
+
if (o === 'endswith')
|
|
244
|
+
return 'endswith';
|
|
245
|
+
if (o === 'regex')
|
|
246
|
+
return 'regex';
|
|
247
|
+
if (o === 'exists')
|
|
248
|
+
return 'exists';
|
|
249
|
+
if (opt === '>=')
|
|
250
|
+
return '>=';
|
|
251
|
+
if (opt === '<=')
|
|
252
|
+
return '<=';
|
|
253
|
+
if (opt === '!=')
|
|
254
|
+
return '!=';
|
|
255
|
+
if (opt === '>')
|
|
256
|
+
return '>';
|
|
257
|
+
if (opt === '<')
|
|
258
|
+
return '<';
|
|
259
|
+
return '=';
|
|
260
|
+
}
|
|
261
|
+
function parseOneCond(segment) {
|
|
262
|
+
const s = segment.trim();
|
|
263
|
+
if (!s)
|
|
264
|
+
return null;
|
|
265
|
+
const unaryMatch = s.match(/^(.+?)\s+(isnull|isnotnull|is\s+null|is\s+not\s+null)\s*$/i);
|
|
266
|
+
if (unaryMatch) {
|
|
267
|
+
const key = unaryMatch[1].trim();
|
|
268
|
+
const opt = normalizeOpt(unaryMatch[2]);
|
|
269
|
+
return { key, opt, value: null };
|
|
270
|
+
}
|
|
271
|
+
const keywordMatch = s.match(/^(.+?)\s+(not\s+in|notin|in|between|ilike|like|contains|startswith|endswith|regex)\s+([\s\S]+)$/i);
|
|
272
|
+
if (keywordMatch) {
|
|
273
|
+
const key = keywordMatch[1].trim();
|
|
274
|
+
const opt = normalizeOpt(keywordMatch[2]);
|
|
275
|
+
const rawVal = keywordMatch[3].trim();
|
|
276
|
+
const value = opt === 'between' ? parseBetweenValue(rawVal) : parseMaybeJson(rawVal);
|
|
277
|
+
return { key, opt, value };
|
|
278
|
+
}
|
|
279
|
+
const opInfo = findTopLevelOpIndex(s, ['>=', '<=', '!=', '==', '>', '<', '=']);
|
|
280
|
+
if (opInfo) {
|
|
281
|
+
const key = s.slice(0, opInfo.idx).trim();
|
|
282
|
+
const rhs = s.slice(opInfo.idx + opInfo.op.length).trim();
|
|
283
|
+
let opt = normalizeOpt(opInfo.op);
|
|
284
|
+
let value = rhs ? parseMaybeJson(rhs) : null;
|
|
285
|
+
if (opt === '=' && Array.isArray(value))
|
|
286
|
+
opt = 'in';
|
|
287
|
+
if (opt === '!=' && Array.isArray(value))
|
|
288
|
+
opt = 'not in';
|
|
289
|
+
if (opt === '=' && value === null)
|
|
290
|
+
opt = 'is null';
|
|
291
|
+
if (opt === '!=' && value === null)
|
|
292
|
+
opt = 'is not null';
|
|
293
|
+
return { key, opt, value };
|
|
294
|
+
}
|
|
295
|
+
if (/^!\s*\w/.test(s)) {
|
|
296
|
+
const key = s.replace(/^!\s*/, '').trim();
|
|
297
|
+
return { key, opt: 'exists', value: false };
|
|
298
|
+
}
|
|
299
|
+
return { key: s, opt: 'exists', value: true };
|
|
300
|
+
}
|
|
301
|
+
function QueryCond(input) {
|
|
302
|
+
if (!input)
|
|
303
|
+
return [];
|
|
304
|
+
const segments = splitTopLevel(input, ',');
|
|
305
|
+
return segments.map(parseOneCond).filter((x) => Boolean(x));
|
|
306
|
+
}
|
package/dist/main/util.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LangCountryType } from
|
|
1
|
+
import { LangCountryType } from './const-type';
|
|
2
2
|
export declare const AppRandomString: (length: number, charset: string) => string;
|
|
3
3
|
export declare const AppUniqueCode: () => string;
|
|
4
4
|
export declare const AppCodeByType: (name: string, type?: null) => string;
|
|
@@ -20,3 +20,4 @@ export declare function EncodeURL(input: string): string;
|
|
|
20
20
|
export declare function DecodeURL(input: string): string;
|
|
21
21
|
export declare function SafeEncode(input: string): string;
|
|
22
22
|
export declare function SafeDecode(encoded: string): string;
|
|
23
|
+
export { QueryCond, type QueryCondItem } from './query-cond';
|
package/dist/main/util.js
CHANGED
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.CurrencyConvert = exports.LangCountryCode = exports.LangText = exports.TimeAgo = exports.DateAndTime = exports.DateTime12HrFormat = exports.DateTime24HrFormat = exports.TruncateText = exports.AppUUID4 = exports.AppAddDays = exports.AppDaysBack = exports.AppCode = exports.AppCodeByType = exports.AppUniqueCode = exports.AppRandomString = void 0;
|
|
12
|
+
exports.QueryCond = exports.CurrencyConvert = exports.LangCountryCode = exports.LangText = exports.TimeAgo = exports.DateAndTime = exports.DateTime12HrFormat = exports.DateTime24HrFormat = exports.TruncateText = exports.AppUUID4 = exports.AppAddDays = exports.AppDaysBack = exports.AppCode = exports.AppCodeByType = exports.AppUniqueCode = exports.AppRandomString = void 0;
|
|
13
13
|
exports.EncodeBase64 = EncodeBase64;
|
|
14
14
|
exports.DecodeBase64 = DecodeBase64;
|
|
15
15
|
exports.EncodeURL = EncodeURL;
|
|
@@ -17,10 +17,10 @@ exports.DecodeURL = DecodeURL;
|
|
|
17
17
|
exports.SafeEncode = SafeEncode;
|
|
18
18
|
exports.SafeDecode = SafeDecode;
|
|
19
19
|
const randomstring_1 = require("randomstring");
|
|
20
|
-
const
|
|
20
|
+
const const_value_1 = require("./const-value");
|
|
21
21
|
const countries_1 = require("./countries");
|
|
22
22
|
const languages_1 = require("./languages");
|
|
23
|
-
const
|
|
23
|
+
const reg_exr_1 = require("./reg-exr");
|
|
24
24
|
const AppRandomString = (length, charset) => {
|
|
25
25
|
return (0, randomstring_1.generate)({ length: length, charset: charset });
|
|
26
26
|
};
|
|
@@ -37,15 +37,15 @@ const AppUniqueCode = () => {
|
|
|
37
37
|
};
|
|
38
38
|
exports.AppUniqueCode = AppUniqueCode;
|
|
39
39
|
const AppCodeByType = (name, type = null) => {
|
|
40
|
-
let str =
|
|
40
|
+
let str = '';
|
|
41
41
|
if (type) {
|
|
42
|
-
str = type +
|
|
42
|
+
str = type + '_' + name;
|
|
43
43
|
}
|
|
44
44
|
else {
|
|
45
|
-
str = name +
|
|
45
|
+
str = name + '_' + (0, exports.AppUniqueCode)();
|
|
46
46
|
}
|
|
47
|
-
str = str.replace(reg_exr_1.RegExp.NON_ALPHA_NUMERIC,
|
|
48
|
-
str = str.replace(/\s/g,
|
|
47
|
+
str = str.replace(reg_exr_1.RegExp.NON_ALPHA_NUMERIC, '_');
|
|
48
|
+
str = str.replace(/\s/g, '_');
|
|
49
49
|
str = str.substr(0, 128);
|
|
50
50
|
return str.toUpperCase();
|
|
51
51
|
};
|
|
@@ -53,10 +53,10 @@ exports.AppCodeByType = AppCodeByType;
|
|
|
53
53
|
const AppCode = (name) => {
|
|
54
54
|
if (name == null)
|
|
55
55
|
return null;
|
|
56
|
-
let str =
|
|
56
|
+
let str = '';
|
|
57
57
|
str = name.trim();
|
|
58
|
-
str = str.replace(reg_exr_1.RegExp.NON_ALPHA_NUMERIC,
|
|
59
|
-
str = str.replace(/\s/g,
|
|
58
|
+
str = str.replace(reg_exr_1.RegExp.NON_ALPHA_NUMERIC, '_');
|
|
59
|
+
str = str.replace(/\s/g, '_');
|
|
60
60
|
return str.toUpperCase();
|
|
61
61
|
};
|
|
62
62
|
exports.AppCode = AppCode;
|
|
@@ -85,54 +85,54 @@ const AppAddDays = (date, addDays, isDays = true) => {
|
|
|
85
85
|
};
|
|
86
86
|
exports.AppAddDays = AppAddDays;
|
|
87
87
|
const AppUUID4 = () => {
|
|
88
|
-
return
|
|
88
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
89
89
|
const r = (Math.random() * 16) | 0;
|
|
90
|
-
const v = c ==
|
|
90
|
+
const v = c == 'x' ? r : (r & 0x3) | 0x8;
|
|
91
91
|
return v.toString(16);
|
|
92
92
|
});
|
|
93
93
|
};
|
|
94
94
|
exports.AppUUID4 = AppUUID4;
|
|
95
95
|
const TruncateText = (input, maxLength) => {
|
|
96
96
|
if ((input === null || input === void 0 ? void 0 : input.length) > maxLength) {
|
|
97
|
-
return input.substring(0, maxLength) +
|
|
97
|
+
return input.substring(0, maxLength) + '...';
|
|
98
98
|
}
|
|
99
99
|
return input;
|
|
100
100
|
};
|
|
101
101
|
exports.TruncateText = TruncateText;
|
|
102
102
|
const DateTime24HrFormat = (time) => {
|
|
103
|
-
const [timeStr, modifier] = time.split(
|
|
104
|
-
let [hours, minutes] = timeStr.split(
|
|
105
|
-
if (modifier ===
|
|
103
|
+
const [timeStr, modifier] = time.split(' ');
|
|
104
|
+
let [hours, minutes] = timeStr.split(':').map(Number);
|
|
105
|
+
if (modifier === 'AM') {
|
|
106
106
|
if (hours === 12)
|
|
107
107
|
hours = 0;
|
|
108
108
|
}
|
|
109
|
-
else if (modifier ===
|
|
109
|
+
else if (modifier === 'PM') {
|
|
110
110
|
if (hours !== 12)
|
|
111
111
|
hours += 12;
|
|
112
112
|
}
|
|
113
|
-
return `${hours.toString().padStart(2,
|
|
113
|
+
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:00`;
|
|
114
114
|
};
|
|
115
115
|
exports.DateTime24HrFormat = DateTime24HrFormat;
|
|
116
116
|
const DateTime12HrFormat = (timestamp, showDate = true, showTime) => {
|
|
117
117
|
const newDate = new Date(timestamp);
|
|
118
118
|
const months = const_value_1.ConstValue.MonthNames;
|
|
119
|
-
const day = String(newDate.getDate()).padStart(2,
|
|
119
|
+
const day = String(newDate.getDate()).padStart(2, '0');
|
|
120
120
|
const month = months[newDate.getMonth()];
|
|
121
121
|
const year = newDate.getFullYear();
|
|
122
122
|
let hours = newDate.getHours();
|
|
123
|
-
const minutes = String(newDate.getMinutes()).padStart(2,
|
|
124
|
-
const ampm = hours >= 12 ?
|
|
123
|
+
const minutes = String(newDate.getMinutes()).padStart(2, '0');
|
|
124
|
+
const ampm = hours >= 12 ? 'PM' : 'AM';
|
|
125
125
|
hours = hours % 12;
|
|
126
126
|
hours = hours ? hours : 12;
|
|
127
|
-
const date = showDate ? `${day} ${month} ${year}` :
|
|
128
|
-
const time = showTime ? `${hours}:${minutes} ${ampm}` :
|
|
127
|
+
const date = showDate ? `${day} ${month} ${year}` : '';
|
|
128
|
+
const time = showTime ? `${hours}:${minutes} ${ampm}` : '';
|
|
129
129
|
return `${date} ${time}`;
|
|
130
130
|
};
|
|
131
131
|
exports.DateTime12HrFormat = DateTime12HrFormat;
|
|
132
132
|
const DateAndTime = (dateString, timeString) => {
|
|
133
133
|
if (!dateString)
|
|
134
134
|
return null;
|
|
135
|
-
const validTimeString = timeString ||
|
|
135
|
+
const validTimeString = timeString || '00:00:00';
|
|
136
136
|
const combined = new Date(`${dateString}T${validTimeString}Z`);
|
|
137
137
|
return isNaN(combined.getTime()) ? null : combined;
|
|
138
138
|
};
|
|
@@ -146,31 +146,31 @@ const TimeAgo = (date) => {
|
|
|
146
146
|
if (days > 1)
|
|
147
147
|
return `${days} days ago`;
|
|
148
148
|
if (days === 1)
|
|
149
|
-
return
|
|
149
|
+
return '1 day ago';
|
|
150
150
|
if (hours > 1)
|
|
151
151
|
return `${hours} hours ago`;
|
|
152
152
|
if (hours === 1)
|
|
153
|
-
return
|
|
153
|
+
return '1 hour ago';
|
|
154
154
|
if (minutes > 1)
|
|
155
155
|
return `${minutes} minutes ago`;
|
|
156
156
|
if (minutes === 1)
|
|
157
|
-
return
|
|
158
|
-
return
|
|
157
|
+
return '1 minute ago';
|
|
158
|
+
return 'Just now';
|
|
159
159
|
};
|
|
160
160
|
exports.TimeAgo = TimeAgo;
|
|
161
161
|
const LangText = (data, source, target) => __awaiter(void 0, void 0, void 0, function* () {
|
|
162
162
|
if (!data || !source || !target) {
|
|
163
|
-
throw new Error(
|
|
163
|
+
throw new Error('Invalid input: data, source, or target is missing');
|
|
164
164
|
}
|
|
165
|
-
const src = source.split(
|
|
166
|
-
const tgt = target.split(
|
|
165
|
+
const src = source.split('-')[0]; // e.g., "en-US" -> "en"
|
|
166
|
+
const tgt = target.split('-')[0]; // e.g., "te-IN" -> "te"
|
|
167
167
|
if (!/^[a-zA-Z]{2}$/.test(src) || !/^[a-zA-Z]{2}$/.test(tgt)) {
|
|
168
|
-
throw new Error(
|
|
168
|
+
throw new Error('Invalid language code format');
|
|
169
169
|
}
|
|
170
170
|
const encodedData = encodeURIComponent(data);
|
|
171
171
|
const url = `https://lingva.ml/api/v1/${src}/${tgt}/${encodedData}`;
|
|
172
172
|
const res = yield fetch(url, {
|
|
173
|
-
method:
|
|
173
|
+
method: 'GET',
|
|
174
174
|
});
|
|
175
175
|
if (!res.ok) {
|
|
176
176
|
throw new Error(`Translation failed: ${res.status} ${res.statusText}`);
|
|
@@ -179,11 +179,11 @@ const LangText = (data, source, target) => __awaiter(void 0, void 0, void 0, fun
|
|
|
179
179
|
if (json.error) {
|
|
180
180
|
throw new Error(`API error: ${json.error}`);
|
|
181
181
|
}
|
|
182
|
-
return json.translation ||
|
|
182
|
+
return json.translation || '';
|
|
183
183
|
});
|
|
184
184
|
exports.LangText = LangText;
|
|
185
185
|
const LangCountryCode = (lang) => {
|
|
186
|
-
const countryCode = lang.split(
|
|
186
|
+
const countryCode = lang.split('-')[1];
|
|
187
187
|
const country = countries_1.countries.find((c) => c.code === countryCode) || {};
|
|
188
188
|
const language = languages_1.languages.find((l) => l.lang === lang) || {};
|
|
189
189
|
return {
|
|
@@ -201,7 +201,7 @@ const LangCountryCode = (lang) => {
|
|
|
201
201
|
exports.LangCountryCode = LangCountryCode;
|
|
202
202
|
const CurrencyConvert = (from, to) => __awaiter(void 0, void 0, void 0, function* () {
|
|
203
203
|
if (!from || !to) {
|
|
204
|
-
throw new Error(
|
|
204
|
+
throw new Error('Invalid input: from or to is missing');
|
|
205
205
|
}
|
|
206
206
|
if (from === to) {
|
|
207
207
|
return 1;
|
|
@@ -209,7 +209,7 @@ const CurrencyConvert = (from, to) => __awaiter(void 0, void 0, void 0, function
|
|
|
209
209
|
try {
|
|
210
210
|
const url = `https://api.frankfurter.app/latest?from=${from}&to=${to}`;
|
|
211
211
|
const res = yield fetch(url, {
|
|
212
|
-
method:
|
|
212
|
+
method: 'GET',
|
|
213
213
|
});
|
|
214
214
|
if (!res.ok) {
|
|
215
215
|
throw new Error(`Currency conversion failed: ${res.status} ${res.statusText}`);
|
|
@@ -251,3 +251,5 @@ function SafeEncode(input) {
|
|
|
251
251
|
function SafeDecode(encoded) {
|
|
252
252
|
return DecodeBase64(DecodeURL(encoded));
|
|
253
253
|
}
|
|
254
|
+
var query_cond_1 = require("./query-cond");
|
|
255
|
+
Object.defineProperty(exports, "QueryCond", { enumerable: true, get: function () { return query_cond_1.QueryCond; } });
|
package/dist/tests/util.js
CHANGED
|
@@ -11,23 +11,41 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
const util_1 = require("../main/util");
|
|
14
|
-
const CallLangCountry = () => {
|
|
15
|
-
const lang = "en-US";
|
|
16
|
-
const country = (0, util_1.LangCountryCode)(lang);
|
|
17
|
-
console.log("LangCountryCode:: ", country);
|
|
18
|
-
};
|
|
19
|
-
const CallLangText = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
-
const resp = yield (0, util_2.LangText)("Hello, how are you?", "en-US", "hi-IN");
|
|
21
|
-
console.log("Resp Kannada:: ", resp);
|
|
22
|
-
});
|
|
23
|
-
const CallCurrencyConvert = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
24
|
-
const resp = yield (0, util_1.CurrencyConvert)("USD", "INR");
|
|
25
|
-
console.log("Resp Currency:: ", resp);
|
|
26
|
-
});
|
|
27
|
-
const util_2 = require("../main/util");
|
|
28
14
|
const run = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
15
|
+
const input = [
|
|
16
|
+
'isApproved=true',
|
|
17
|
+
'status!=false',
|
|
18
|
+
'age>18',
|
|
19
|
+
'score<100',
|
|
20
|
+
'height>=170',
|
|
21
|
+
'weight<=80',
|
|
22
|
+
'type=["accept","inprogress"]',
|
|
23
|
+
'type!=["accept","inprogress"]',
|
|
24
|
+
'role in ["admin","editor"]',
|
|
25
|
+
'role not in ["admin","editor"]',
|
|
26
|
+
'role notin ["admin","editor"]',
|
|
27
|
+
'deletedAt is null',
|
|
28
|
+
'deletedAt is not null',
|
|
29
|
+
'deletedAt isnull',
|
|
30
|
+
'updatedAt isnotnull',
|
|
31
|
+
'deletedAt=null',
|
|
32
|
+
'deletedAt!=null',
|
|
33
|
+
'age between [18,30]',
|
|
34
|
+
'createdAt between 2020-01-01..2020-01-31',
|
|
35
|
+
'name like "Jo%"',
|
|
36
|
+
'email ilike "%@gmail.com"',
|
|
37
|
+
'title contains "hello"',
|
|
38
|
+
'code startswith "AB"',
|
|
39
|
+
'code endswith "99"',
|
|
40
|
+
'path regex "^/api/.*$"',
|
|
41
|
+
'archivedAt',
|
|
42
|
+
'!archivedAt',
|
|
43
|
+
'name="a,b"',
|
|
44
|
+
'meta={"a":1,"b":true}',
|
|
45
|
+
'tags=["x,y","z"]',
|
|
46
|
+
].join(',');
|
|
47
|
+
const got = (0, util_1.QueryCond)(input);
|
|
48
|
+
console.log('QueryCond input:', input);
|
|
49
|
+
console.log('QueryCond output:', JSON.stringify(got, null, 2));
|
|
32
50
|
});
|
|
33
51
|
run();
|
package/package.json
CHANGED