@wxn0brp/vql 0.5.1 → 0.6.0-alpha.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 +2 -27
- package/dist/config.d.ts +0 -2
- package/dist/config.js +4 -5
- package/dist/cpu/relation.js +1 -1
- package/dist/cpu/request.js +1 -1
- package/dist/cpu/string/index.d.ts +1 -7
- package/dist/cpu/string/index.js +140 -43
- package/dist/cpu/string/utils.d.ts +1 -0
- package/dist/cpu/string/utils.js +14 -0
- package/dist/falconFrame.js +2 -2
- package/dist/gw.d.ts +3 -0
- package/dist/gw.js +5 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/permissions/relation.d.ts +2 -2
- package/dist/permissions/relation.js +8 -7
- package/dist/permissions/request.d.ts +4 -5
- package/dist/permissions/request.js +8 -7
- package/dist/permissions/utils.d.ts +2 -1
- package/dist/permissions/utils.js +15 -3
- package/dist/processor.d.ts +8 -9
- package/dist/processor.js +12 -13
- package/dist/sheet.d.ts +2 -0
- package/dist/sheet.js +34 -0
- package/dist/types/perm.d.ts +5 -0
- package/dist/types/vql.d.ts +4 -13
- package/dist/valid.d.ts +2 -5
- package/dist/valid.js +55 -33
- package/dist/vql.d.ts +4 -13
- package/package.json +10 -12
- package/dist/ajv.d.ts +0 -2
- package/dist/ajv.js +0 -80
- package/dist/cpu/string/json5.d.ts +0 -2
- package/dist/cpu/string/json5.js +0 -8
- package/dist/cpu/string/middle.d.ts +0 -3
- package/dist/cpu/string/middle.js +0 -41
- package/dist/cpu/string/simple.d.ts +0 -2
- package/dist/cpu/string/simple.js +0 -155
- package/dist/cpu/string/yaml.d.ts +0 -2
- package/dist/cpu/string/yaml.js +0 -19
- package/dist/schema.json +0 -1
- package/dist/sheet/index.d.ts +0 -2
- package/dist/sheet/index.js +0 -70
- package/dist/sheet/load.d.ts +0 -3
- package/dist/sheet/load.js +0 -22
package/dist/sheet.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
function replaceVariables(obj, variables) {
|
|
2
|
+
if (typeof obj === "object" && !Array.isArray(obj) && obj !== null && "__" in obj) {
|
|
3
|
+
const varKey = obj.__;
|
|
4
|
+
return variables[varKey] ?? obj;
|
|
5
|
+
}
|
|
6
|
+
if (typeof obj === "string") {
|
|
7
|
+
if (obj.startsWith("$"))
|
|
8
|
+
return variables[obj.slice(1)] ?? obj;
|
|
9
|
+
return obj;
|
|
10
|
+
}
|
|
11
|
+
if (Array.isArray(obj))
|
|
12
|
+
return obj.map((item) => replaceVariables(item, variables));
|
|
13
|
+
if (typeof obj === "object" && obj !== null) {
|
|
14
|
+
const newObj = {};
|
|
15
|
+
for (const key in obj) {
|
|
16
|
+
newObj[key] = replaceVariables(obj[key], variables);
|
|
17
|
+
}
|
|
18
|
+
return newObj;
|
|
19
|
+
}
|
|
20
|
+
return obj;
|
|
21
|
+
}
|
|
22
|
+
export function replaceVars(query, user) {
|
|
23
|
+
query.var = {
|
|
24
|
+
_me: user?.id || user?._id || user,
|
|
25
|
+
_now: Date.now(),
|
|
26
|
+
_nowShort: Math.floor(Date.now() / 1000),
|
|
27
|
+
__now: Date.now().toString(),
|
|
28
|
+
__nowShort: Math.floor(Date.now() / 1000).toString(),
|
|
29
|
+
...(query.var || {})
|
|
30
|
+
};
|
|
31
|
+
query = replaceVariables(query, query.var);
|
|
32
|
+
delete query.var;
|
|
33
|
+
return query;
|
|
34
|
+
}
|
package/dist/types/perm.d.ts
CHANGED
package/dist/types/vql.d.ts
CHANGED
|
@@ -8,9 +8,9 @@ export interface VQLQuery<T = any> {
|
|
|
8
8
|
f: VQLFindOne<T>;
|
|
9
9
|
add: VQLAdd<T>;
|
|
10
10
|
update: VQLUpdate<T>;
|
|
11
|
-
updateOne:
|
|
11
|
+
updateOne: VQLUpdate<T>;
|
|
12
12
|
remove: VQLRemove<T>;
|
|
13
|
-
removeOne:
|
|
13
|
+
removeOne: VQLRemove<T>;
|
|
14
14
|
updateOneOrAdd: VQLUpdateOneOrAdd<T>;
|
|
15
15
|
removeCollection: VQLCollectionOperation;
|
|
16
16
|
ensureCollection: VQLCollectionOperation;
|
|
@@ -28,11 +28,11 @@ export type VQLQueryData<T = any> = {
|
|
|
28
28
|
} | {
|
|
29
29
|
update: VQLUpdate<T>;
|
|
30
30
|
} | {
|
|
31
|
-
updateOne:
|
|
31
|
+
updateOne: VQLUpdate<T>;
|
|
32
32
|
} | {
|
|
33
33
|
remove: VQLRemove<T>;
|
|
34
34
|
} | {
|
|
35
|
-
removeOne:
|
|
35
|
+
removeOne: VQLRemove<T>;
|
|
36
36
|
} | {
|
|
37
37
|
updateOneOrAdd: VQLUpdateOneOrAdd<T>;
|
|
38
38
|
} | {
|
|
@@ -76,19 +76,10 @@ export interface VQLUpdate<T = any> {
|
|
|
76
76
|
search: Search<T>;
|
|
77
77
|
updater: UpdaterArg<T>;
|
|
78
78
|
}
|
|
79
|
-
export interface VQLUpdateOne<T = any> {
|
|
80
|
-
collection: string;
|
|
81
|
-
search: Search<T>;
|
|
82
|
-
updater: UpdaterArg<T>;
|
|
83
|
-
}
|
|
84
79
|
export interface VQLRemove<T = any> {
|
|
85
80
|
collection: string;
|
|
86
81
|
search: Search<T>;
|
|
87
82
|
}
|
|
88
|
-
export interface VQLRemoveOne<T = any> {
|
|
89
|
-
collection: string;
|
|
90
|
-
search: Search<T>;
|
|
91
|
-
}
|
|
92
83
|
export interface VQLUpdateOneOrAdd<T = any> {
|
|
93
84
|
collection: string;
|
|
94
85
|
search: Search<T>;
|
package/dist/valid.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import Ajv from "ajv";
|
|
2
|
-
import { VQLConfig } from "./config.js";
|
|
3
1
|
import { VQL, VQLError, VQLR } from "./types/vql.js";
|
|
4
|
-
export declare
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function validateVql(config: VQLConfig, query: VQL): true | VQLError;
|
|
2
|
+
export declare function validateRaw(query: VQLR): true | VQLError;
|
|
3
|
+
export declare function validateVql(query: VQL): true | VQLError;
|
package/dist/valid.js
CHANGED
|
@@ -1,38 +1,60 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (!
|
|
23
|
-
|
|
24
|
-
why = config.formatAjv ? buildAjvErrorTree(why) : why;
|
|
25
|
-
why = deepMerge(why, query);
|
|
26
|
-
return { err: true, msg: "Invalid query raw", c: 400, why };
|
|
27
|
-
}
|
|
1
|
+
function emptyErr() {
|
|
2
|
+
return {
|
|
3
|
+
err: true,
|
|
4
|
+
msg: "Bad query",
|
|
5
|
+
c: 400
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
function isObj(obj, one = true) {
|
|
9
|
+
return typeof obj === "object" && obj !== null && !Array.isArray(obj) && (!one || Object.keys(obj).length !== 0);
|
|
10
|
+
}
|
|
11
|
+
export function validateRaw(query) {
|
|
12
|
+
if (("r" in query && isObj(query.r)) ||
|
|
13
|
+
("db" in query && typeof query.db === "string" && isObj(query.d)) ||
|
|
14
|
+
("ref" in query && isObj(query.ref)))
|
|
15
|
+
return true;
|
|
16
|
+
return emptyErr();
|
|
17
|
+
}
|
|
18
|
+
function validR(query) {
|
|
19
|
+
const { r } = query;
|
|
20
|
+
if (!("path" in r) || !Array.isArray(r.path) || r.path.length !== 2)
|
|
21
|
+
return emptyErr();
|
|
22
|
+
if (!isObj(r.search, false))
|
|
23
|
+
return emptyErr();
|
|
28
24
|
return true;
|
|
29
25
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
function validD(query) {
|
|
27
|
+
const { d } = query;
|
|
28
|
+
const key = Object.keys(d)[0];
|
|
29
|
+
if (key === "getCollection")
|
|
30
|
+
return true;
|
|
31
|
+
const value = d[key];
|
|
32
|
+
if (typeof value.collection !== "string" || value.collection.trim() === "")
|
|
33
|
+
return emptyErr();
|
|
34
|
+
if (key === "issetCollection" || key === "ensureCollection" || key === "removeCollection")
|
|
35
|
+
return true;
|
|
36
|
+
if (key === "add") {
|
|
37
|
+
if (!isObj(value.data))
|
|
38
|
+
return emptyErr();
|
|
39
|
+
else
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
if ("search" in value && !isObj(value.search, false))
|
|
43
|
+
return emptyErr();
|
|
44
|
+
if (key === "find" || key === "findOne" || key === "f" || key === "remove" || key === "removeOne")
|
|
45
|
+
return true;
|
|
46
|
+
if (key === "update" || key === "updateOne" || key === "updateOneOrAdd") {
|
|
47
|
+
if (!isObj(value.updater, false))
|
|
48
|
+
return emptyErr();
|
|
49
|
+
else
|
|
50
|
+
return true;
|
|
36
51
|
}
|
|
37
52
|
return true;
|
|
38
53
|
}
|
|
54
|
+
export function validateVql(query) {
|
|
55
|
+
if ("r" in query && isObj(query.r))
|
|
56
|
+
return validR(query);
|
|
57
|
+
if ("d" in query && isObj(query.d))
|
|
58
|
+
return validD(query);
|
|
59
|
+
return emptyErr();
|
|
60
|
+
}
|
package/dist/vql.d.ts
CHANGED
|
@@ -195,9 +195,9 @@ export interface VQLQuery<T = any> {
|
|
|
195
195
|
f: VQLFindOne<T>;
|
|
196
196
|
add: VQLAdd<T>;
|
|
197
197
|
update: VQLUpdate<T>;
|
|
198
|
-
updateOne:
|
|
198
|
+
updateOne: VQLUpdate<T>;
|
|
199
199
|
remove: VQLRemove<T>;
|
|
200
|
-
removeOne:
|
|
200
|
+
removeOne: VQLRemove<T>;
|
|
201
201
|
updateOneOrAdd: VQLUpdateOneOrAdd<T>;
|
|
202
202
|
removeCollection: VQLCollectionOperation;
|
|
203
203
|
ensureCollection: VQLCollectionOperation;
|
|
@@ -215,11 +215,11 @@ export type VQLQueryData<T = any> = {
|
|
|
215
215
|
} | {
|
|
216
216
|
update: VQLUpdate<T>;
|
|
217
217
|
} | {
|
|
218
|
-
updateOne:
|
|
218
|
+
updateOne: VQLUpdate<T>;
|
|
219
219
|
} | {
|
|
220
220
|
remove: VQLRemove<T>;
|
|
221
221
|
} | {
|
|
222
|
-
removeOne:
|
|
222
|
+
removeOne: VQLRemove<T>;
|
|
223
223
|
} | {
|
|
224
224
|
updateOneOrAdd: VQLUpdateOneOrAdd<T>;
|
|
225
225
|
} | {
|
|
@@ -263,19 +263,10 @@ export interface VQLUpdate<T = any> {
|
|
|
263
263
|
search: Search<T>;
|
|
264
264
|
updater: UpdaterArg<T>;
|
|
265
265
|
}
|
|
266
|
-
export interface VQLUpdateOne<T = any> {
|
|
267
|
-
collection: string;
|
|
268
|
-
search: Search<T>;
|
|
269
|
-
updater: UpdaterArg<T>;
|
|
270
|
-
}
|
|
271
266
|
export interface VQLRemove<T = any> {
|
|
272
267
|
collection: string;
|
|
273
268
|
search: Search<T>;
|
|
274
269
|
}
|
|
275
|
-
export interface VQLRemoveOne<T = any> {
|
|
276
|
-
collection: string;
|
|
277
|
-
search: Search<T>;
|
|
278
|
-
}
|
|
279
270
|
export interface VQLUpdateOneOrAdd<T = any> {
|
|
280
271
|
collection: string;
|
|
281
272
|
search: Search<T>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wxn0brp/vql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0-alpha.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"author": "wxn0brP",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
"dist"
|
|
16
16
|
],
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"@wxn0brp/db-core": ">=0.1.
|
|
19
|
-
"@wxn0brp/falcon-frame": ">=0.0.20"
|
|
18
|
+
"@wxn0brp/db-core": ">=0.1.4",
|
|
19
|
+
"@wxn0brp/falcon-frame": ">=0.0.20",
|
|
20
|
+
"@wxn0brp/gate-warden": ">=0.4.0"
|
|
20
21
|
},
|
|
21
22
|
"peerDependenciesMeta": {
|
|
22
23
|
"@wxn0brp/falcon-frame": {
|
|
@@ -24,26 +25,23 @@
|
|
|
24
25
|
},
|
|
25
26
|
"@wxn0brp/db-core": {
|
|
26
27
|
"optional": false
|
|
28
|
+
},
|
|
29
|
+
"@wxn0brp/gate-warden": {
|
|
30
|
+
"optional": true
|
|
27
31
|
}
|
|
28
32
|
},
|
|
29
33
|
"devDependencies": {
|
|
30
34
|
"@types/node": "^24.1.0",
|
|
31
35
|
"@wxn0brp/db": "^0.30.0",
|
|
32
36
|
"@wxn0brp/falcon-frame": "0.0.20",
|
|
37
|
+
"@wxn0brp/gate-warden": "^0.4.0",
|
|
33
38
|
"dotenv": "^17.2.0",
|
|
34
39
|
"esbuild": "^0.25.8",
|
|
35
|
-
"source-map-support": "^0.5.21",
|
|
36
40
|
"tsc-alias": "^1.8.10",
|
|
37
|
-
"typescript": "^5.7.3"
|
|
38
|
-
"typescript-json-schema": "^0.65.1"
|
|
41
|
+
"typescript": "^5.7.3"
|
|
39
42
|
},
|
|
40
43
|
"dependencies": {
|
|
41
|
-
"@wxn0brp/
|
|
42
|
-
"@wxn0brp/lucerna-log": "^0.1.1",
|
|
43
|
-
"ajv": "^8.17.1",
|
|
44
|
-
"ajv-formats": "^3.0.1",
|
|
45
|
-
"js-yaml": "^4.1.0",
|
|
46
|
-
"json5": "^2.2.3"
|
|
44
|
+
"@wxn0brp/lucerna-log": "^0.1.1"
|
|
47
45
|
},
|
|
48
46
|
"exports": {
|
|
49
47
|
".": {
|
package/dist/ajv.d.ts
DELETED
package/dist/ajv.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
function parseInstancePath(path) {
|
|
2
|
-
if (!path)
|
|
3
|
-
return [];
|
|
4
|
-
const unescaped = path.slice(1).replace(/~0/g, "~").replace(/~1/g, "/");
|
|
5
|
-
return unescaped.split("/").filter(seg => seg !== "");
|
|
6
|
-
}
|
|
7
|
-
function formatSingleError(error) {
|
|
8
|
-
const { keyword, params, message } = error;
|
|
9
|
-
switch (keyword) {
|
|
10
|
-
case "type":
|
|
11
|
-
return `expected type: ${params.type}`;
|
|
12
|
-
case "required":
|
|
13
|
-
return `missing required property: ${params.missingProperty}`;
|
|
14
|
-
case "additionalProperties":
|
|
15
|
-
return `unexpected property: ${params.additionalProperty}`;
|
|
16
|
-
case "enum":
|
|
17
|
-
const allowedValues = params.allowedValues.join(", ");
|
|
18
|
-
return `value not in: [${allowedValues}]`;
|
|
19
|
-
case "minLength":
|
|
20
|
-
return `too short (min ${params.limit} characters)`;
|
|
21
|
-
case "maxLength":
|
|
22
|
-
return `too long (max ${params.limit} characters)`;
|
|
23
|
-
case "minimum":
|
|
24
|
-
return `value < ${params.limit}`;
|
|
25
|
-
case "maximum":
|
|
26
|
-
return `value > ${params.limit}`;
|
|
27
|
-
case "pattern":
|
|
28
|
-
return `does not match pattern`;
|
|
29
|
-
case "anyOf":
|
|
30
|
-
return `value does not satisfy any of the variants`;
|
|
31
|
-
case "oneOf":
|
|
32
|
-
return `value satisfies multiple variants`;
|
|
33
|
-
case "allOf":
|
|
34
|
-
return `value does not satisfy all conditions`;
|
|
35
|
-
default:
|
|
36
|
-
return message || `validation error: ${keyword}`;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
// Recursively remove error types and leave only messages
|
|
40
|
-
function finalizeNode(node) {
|
|
41
|
-
if (node.__errors) {
|
|
42
|
-
node.__errors = node.__errors.map((e) => e.message);
|
|
43
|
-
}
|
|
44
|
-
for (const key in node) {
|
|
45
|
-
if (key !== "__errors" && typeof node[key] === "object") {
|
|
46
|
-
finalizeNode(node[key]);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
export function buildAjvErrorTree(errors) {
|
|
51
|
-
const errorTree = {};
|
|
52
|
-
for (const error of errors) {
|
|
53
|
-
const segments = parseInstancePath(error.instancePath);
|
|
54
|
-
let currentNode = errorTree;
|
|
55
|
-
for (const segment of segments) {
|
|
56
|
-
if (!(segment in currentNode)) {
|
|
57
|
-
currentNode[segment] = {};
|
|
58
|
-
}
|
|
59
|
-
currentNode = currentNode[segment];
|
|
60
|
-
}
|
|
61
|
-
const formattedMessage = formatSingleError(error);
|
|
62
|
-
const isComposite = ["anyOf", "oneOf", "allOf"].includes(error.keyword);
|
|
63
|
-
if (!currentNode.__errors) {
|
|
64
|
-
currentNode.__errors = [];
|
|
65
|
-
}
|
|
66
|
-
if (isComposite) {
|
|
67
|
-
// Replace all previous errors with only this general one
|
|
68
|
-
currentNode.__errors = [{ keyword: error.keyword, message: formattedMessage }];
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
// Check if there is already a general error
|
|
72
|
-
const hasComposite = currentNode.__errors.some((e) => ["anyOf", "oneOf", "allOf"].includes(e.keyword));
|
|
73
|
-
if (!hasComposite) {
|
|
74
|
-
currentNode.__errors.push({ keyword: error.keyword, message: formattedMessage });
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
finalizeNode(errorTree);
|
|
79
|
-
return errorTree;
|
|
80
|
-
}
|
package/dist/cpu/string/json5.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import JSON5 from "json5";
|
|
2
|
-
import { extractMeta } from "./utils.js";
|
|
3
|
-
import { processVQL_MB } from "./middle.js";
|
|
4
|
-
export function parseVQLB(query) {
|
|
5
|
-
const { db, op, collection, body } = extractMeta(query);
|
|
6
|
-
const parsed = JSON5.parse(body);
|
|
7
|
-
return processVQL_MB(db, op, collection, parsed);
|
|
8
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { VQL } from "../../types/vql.js";
|
|
2
|
-
export declare function processVQL_MB(db: string, op: string, collection: string, parsed: Record<string, any>): VQL;
|
|
3
|
-
export declare function convertSearchObjToSearchArray(obj: Record<string, any>, parentKeys?: string[]): string[][];
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
export function processVQL_MB(db, op, collection, parsed) {
|
|
2
|
-
return "relations" in parsed ?
|
|
3
|
-
processRelation_MB(db, collection, parsed) :
|
|
4
|
-
processQuery_MB(db, op, collection, parsed);
|
|
5
|
-
}
|
|
6
|
-
export function convertSearchObjToSearchArray(obj, parentKeys = []) {
|
|
7
|
-
return Object.entries(obj).reduce((acc, [key, value]) => {
|
|
8
|
-
const currentPath = [...parentKeys, key];
|
|
9
|
-
if (!value) {
|
|
10
|
-
return acc;
|
|
11
|
-
}
|
|
12
|
-
else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
13
|
-
return [...acc, ...convertSearchObjToSearchArray(value, currentPath)];
|
|
14
|
-
}
|
|
15
|
-
else {
|
|
16
|
-
return [...acc, currentPath];
|
|
17
|
-
}
|
|
18
|
-
}, []);
|
|
19
|
-
}
|
|
20
|
-
function processRelation_MB(db, collection, parsed) {
|
|
21
|
-
if ("select" in parsed && typeof parsed.select === "object" && !Array.isArray(parsed.select)) {
|
|
22
|
-
parsed.select = convertSearchObjToSearchArray(parsed.select);
|
|
23
|
-
}
|
|
24
|
-
return {
|
|
25
|
-
r: {
|
|
26
|
-
path: [parsed.db || db, parsed.c || collection],
|
|
27
|
-
...parsed
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
function processQuery_MB(db, op, collection, parsed) {
|
|
32
|
-
return {
|
|
33
|
-
db,
|
|
34
|
-
d: {
|
|
35
|
-
[op]: {
|
|
36
|
-
collection,
|
|
37
|
-
...parsed
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { extractMeta } from "./utils.js";
|
|
2
|
-
import JSON5 from "json5";
|
|
3
|
-
import { convertSearchObjToSearchArray } from "./middle.js";
|
|
4
|
-
const aliases = {
|
|
5
|
-
s: "search",
|
|
6
|
-
f: "fields",
|
|
7
|
-
o: "options",
|
|
8
|
-
r: "relations",
|
|
9
|
-
d: "data",
|
|
10
|
-
e: "select",
|
|
11
|
-
u: "updater",
|
|
12
|
-
};
|
|
13
|
-
function parseArgs(input) {
|
|
14
|
-
const result = {};
|
|
15
|
-
const tokens = [];
|
|
16
|
-
let current = "";
|
|
17
|
-
let inQuotes = false;
|
|
18
|
-
let escape = false;
|
|
19
|
-
for (let i = 0; i < input.length; i++) {
|
|
20
|
-
const char = input[i];
|
|
21
|
-
if (escape) {
|
|
22
|
-
current += char;
|
|
23
|
-
escape = false;
|
|
24
|
-
}
|
|
25
|
-
else if (char === "\\") {
|
|
26
|
-
escape = true;
|
|
27
|
-
}
|
|
28
|
-
else if (char === "\"") {
|
|
29
|
-
inQuotes = !inQuotes;
|
|
30
|
-
}
|
|
31
|
-
else if (!inQuotes && (char === " " || char === "=")) {
|
|
32
|
-
if (current !== "") {
|
|
33
|
-
tokens.push(current);
|
|
34
|
-
current = "";
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
current += char;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
if (current !== "") {
|
|
42
|
-
tokens.push(current);
|
|
43
|
-
}
|
|
44
|
-
for (let i = 0; i < tokens.length; i += 2) {
|
|
45
|
-
const key = tokens[i];
|
|
46
|
-
let value = tokens[i + 1] ?? true;
|
|
47
|
-
if (typeof value === "string") {
|
|
48
|
-
const trimmed = value.trim();
|
|
49
|
-
if (trimmed === "") {
|
|
50
|
-
value = true;
|
|
51
|
-
}
|
|
52
|
-
else if (/^".*"$/.test(trimmed)) {
|
|
53
|
-
value = trimmed.slice(1, -1);
|
|
54
|
-
}
|
|
55
|
-
else if (trimmed.toLowerCase() === "true") {
|
|
56
|
-
value = true;
|
|
57
|
-
}
|
|
58
|
-
else if (trimmed.toLowerCase() === "false") {
|
|
59
|
-
value = false;
|
|
60
|
-
}
|
|
61
|
-
else if (!isNaN(Number(trimmed))) {
|
|
62
|
-
value = Number(trimmed);
|
|
63
|
-
}
|
|
64
|
-
else if ((trimmed.startsWith("{") && trimmed.endsWith("}")) || (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
|
|
65
|
-
try {
|
|
66
|
-
value = JSON5.parse(trimmed);
|
|
67
|
-
}
|
|
68
|
-
catch { }
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
result[key] = value;
|
|
72
|
-
}
|
|
73
|
-
return result;
|
|
74
|
-
}
|
|
75
|
-
function buildVQL(db, op, collection, query) {
|
|
76
|
-
const hasRelations = "relations" in query;
|
|
77
|
-
if (hasRelations) {
|
|
78
|
-
const relations = {};
|
|
79
|
-
for (const key in query.relations) {
|
|
80
|
-
const value = query.relations[key];
|
|
81
|
-
relations[key] = {
|
|
82
|
-
path: [value.db || db, value.c || key],
|
|
83
|
-
...value
|
|
84
|
-
};
|
|
85
|
-
delete relations[key].db;
|
|
86
|
-
delete relations[key].c;
|
|
87
|
-
}
|
|
88
|
-
if ("select" in query) {
|
|
89
|
-
query.select = convertSearchObjToSearchArray(query.select);
|
|
90
|
-
}
|
|
91
|
-
return {
|
|
92
|
-
r: {
|
|
93
|
-
path: [db, collection],
|
|
94
|
-
...query,
|
|
95
|
-
relations,
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
if (query.fields && !query.select) {
|
|
101
|
-
query.select = query.fields;
|
|
102
|
-
delete query.fields;
|
|
103
|
-
}
|
|
104
|
-
if ("select" in query) {
|
|
105
|
-
query.select = [...new Set(convertSearchObjToSearchArray(query.select).map(k => k[0]).flat())];
|
|
106
|
-
}
|
|
107
|
-
return {
|
|
108
|
-
db,
|
|
109
|
-
d: {
|
|
110
|
-
[op]: {
|
|
111
|
-
collection,
|
|
112
|
-
...query,
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
export function parseVQLS(query) {
|
|
119
|
-
const { db, op, collection, body } = extractMeta(query);
|
|
120
|
-
const parsed = parseArgs(body);
|
|
121
|
-
for (const keysRaw of Object.keys(parsed)) {
|
|
122
|
-
const keys = keysRaw.split(".");
|
|
123
|
-
if (keys.length === 1) {
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
let obj = parsed;
|
|
127
|
-
for (let i = 0; i < keys.length; i++) {
|
|
128
|
-
const key = keys[i];
|
|
129
|
-
if (i < keys.length - 1) {
|
|
130
|
-
if (!(key in obj)) {
|
|
131
|
-
obj[key] = {};
|
|
132
|
-
}
|
|
133
|
-
obj = obj[key];
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
obj[key] = parsed[keysRaw];
|
|
137
|
-
delete parsed[keysRaw];
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
for (const key in aliases) {
|
|
142
|
-
if (key in parsed) {
|
|
143
|
-
parsed[aliases[key]] = parsed[key];
|
|
144
|
-
delete parsed[key];
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
if ((op === "find" || op === "findOne") && !("search" in parsed)) {
|
|
148
|
-
parsed.search = {};
|
|
149
|
-
}
|
|
150
|
-
if ((op === "update" || op === "remove") && !("updater" in parsed) && ("data" in parsed)) {
|
|
151
|
-
parsed.updater = parsed.data;
|
|
152
|
-
delete parsed.data;
|
|
153
|
-
}
|
|
154
|
-
return buildVQL(db, op, collection, parsed);
|
|
155
|
-
}
|
package/dist/cpu/string/yaml.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { processVQL_MB } from "./middle.js";
|
|
2
|
-
import { extractMeta } from "./utils.js";
|
|
3
|
-
import yaml from "js-yaml";
|
|
4
|
-
export function parseVQLM(query) {
|
|
5
|
-
const { db, op, collection } = extractMeta(query);
|
|
6
|
-
let lineEndIndex = 0;
|
|
7
|
-
let foundNonWhitespace = false;
|
|
8
|
-
for (let i = 0; i < query.length; i++) {
|
|
9
|
-
if (!foundNonWhitespace && query[i] !== " " && query[i] !== "\t" && query[i] !== "\r" && query[i] !== "\n")
|
|
10
|
-
foundNonWhitespace = true;
|
|
11
|
-
if (foundNonWhitespace && query[i] === "\n") {
|
|
12
|
-
lineEndIndex = i;
|
|
13
|
-
break;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
const body = query.slice(lineEndIndex + 1);
|
|
17
|
-
const parsed = yaml.load(body);
|
|
18
|
-
return processVQL_MB(db, op, collection, parsed);
|
|
19
|
-
}
|