@wxn0brp/vql 0.8.3 → 0.8.4
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/cpu/request.js +4 -0
- package/dist/cpu/string/args.d.ts +1 -0
- package/dist/cpu/string/args.js +102 -0
- package/dist/cpu/string/build.d.ts +2 -0
- package/dist/cpu/string/build.js +44 -0
- package/dist/cpu/string/index.js +6 -148
- package/dist/cpu/string/utils.js +5 -3
- package/dist/helpers/valid.js +9 -0
- package/dist/permissions/request.js +7 -0
- package/dist/types/vql.d.ts +8 -0
- package/dist/vql.d.ts +17 -1
- package/package.json +11 -10
package/dist/cpu/request.js
CHANGED
|
@@ -51,6 +51,10 @@ export async function executeQuery(cpu, query, user) {
|
|
|
51
51
|
opts.id_gen = params.id_gen;
|
|
52
52
|
return db.updateOneOrAdd(params.collection, params.search, params.updater, opts);
|
|
53
53
|
}
|
|
54
|
+
else if (operation === "toggleOne") {
|
|
55
|
+
const params = query.d[operation];
|
|
56
|
+
return db.toggleOne(params.collection, params.search, params.data);
|
|
57
|
+
}
|
|
54
58
|
else if (operation === "removeCollection") {
|
|
55
59
|
const params = query.d[operation];
|
|
56
60
|
return db.removeCollection(params.collection);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function parseArgs(input: string): Record<string, any>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
export function parseArgs(input) {
|
|
2
|
+
const result = {};
|
|
3
|
+
const tokens = [];
|
|
4
|
+
let current = "";
|
|
5
|
+
let inQuotes = false;
|
|
6
|
+
let escape = false;
|
|
7
|
+
let objTree = 0;
|
|
8
|
+
for (let i = 0; i < input.length; i++) {
|
|
9
|
+
const char = input[i];
|
|
10
|
+
if (escape) {
|
|
11
|
+
current += char;
|
|
12
|
+
escape = false;
|
|
13
|
+
}
|
|
14
|
+
else if (char === "\\") {
|
|
15
|
+
escape = true;
|
|
16
|
+
}
|
|
17
|
+
else if (!inQuotes && (char === "{" || char === "[")) {
|
|
18
|
+
objTree++;
|
|
19
|
+
current += char;
|
|
20
|
+
}
|
|
21
|
+
else if (!inQuotes && (char === "}" || char === "]")) {
|
|
22
|
+
objTree--;
|
|
23
|
+
current += char;
|
|
24
|
+
if (objTree === 0) {
|
|
25
|
+
tokens.push(current);
|
|
26
|
+
current = "";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else if (!objTree && (char === "'" || char === '"' || char === "`")) {
|
|
30
|
+
if (inQuotes === char) {
|
|
31
|
+
inQuotes = false;
|
|
32
|
+
tokens.push(`"` + current + `"`);
|
|
33
|
+
current = "";
|
|
34
|
+
}
|
|
35
|
+
else if (typeof inQuotes === "boolean") {
|
|
36
|
+
inQuotes = char;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
current += char;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (!inQuotes && (char === " " || char === "=" || char === "<" || char === ">")) {
|
|
43
|
+
if (current !== "") {
|
|
44
|
+
if (char === "<" || char === ">") {
|
|
45
|
+
let type = char === ">" ? "gt" : "lt";
|
|
46
|
+
if (i < input.length - 1 && input[i + 1] === "=") {
|
|
47
|
+
type += "e";
|
|
48
|
+
i++;
|
|
49
|
+
}
|
|
50
|
+
const split = current.split(".");
|
|
51
|
+
if (split.length > 1) {
|
|
52
|
+
const original = split.shift();
|
|
53
|
+
const operation = "$" + type;
|
|
54
|
+
split.unshift(operation);
|
|
55
|
+
split.unshift(original);
|
|
56
|
+
current = split.join(".");
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
current = "$" + type + "." + current;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
tokens.push(current);
|
|
63
|
+
current = "";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
current += char;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (current !== "")
|
|
71
|
+
tokens.push(current);
|
|
72
|
+
for (let i = 0; i < tokens.length; i += 2) {
|
|
73
|
+
const key = tokens[i];
|
|
74
|
+
let value = tokens[i + 1] ?? true;
|
|
75
|
+
if (typeof value === "string") {
|
|
76
|
+
const trimmed = value.trim();
|
|
77
|
+
if (trimmed === "") {
|
|
78
|
+
value = true;
|
|
79
|
+
}
|
|
80
|
+
else if (/^".*"$/.test(trimmed)) {
|
|
81
|
+
value = trimmed.slice(1, -1);
|
|
82
|
+
}
|
|
83
|
+
else if (trimmed.toLowerCase() === "true") {
|
|
84
|
+
value = true;
|
|
85
|
+
}
|
|
86
|
+
else if (trimmed.toLowerCase() === "false") {
|
|
87
|
+
value = false;
|
|
88
|
+
}
|
|
89
|
+
else if (!isNaN(Number(trimmed))) {
|
|
90
|
+
value = Number(trimmed);
|
|
91
|
+
}
|
|
92
|
+
else if ((trimmed.startsWith("{") && trimmed.endsWith("}")) || (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
|
|
93
|
+
try {
|
|
94
|
+
value = JSON.parse(trimmed);
|
|
95
|
+
}
|
|
96
|
+
catch { }
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
result[key] = value;
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { convertSearchObjToSearchArray } from "./utils.js";
|
|
2
|
+
export function buildVQL(db, op, collection, query) {
|
|
3
|
+
return "relations" in query ?
|
|
4
|
+
buildRelation(db, collection, query) :
|
|
5
|
+
buildQuery(db, op, collection, query);
|
|
6
|
+
}
|
|
7
|
+
function buildRelation(db, collection, query) {
|
|
8
|
+
const relations = {};
|
|
9
|
+
for (const key in query.relations) {
|
|
10
|
+
const value = query.relations[key];
|
|
11
|
+
relations[key] = {
|
|
12
|
+
path: [value.db || db, value.c || key],
|
|
13
|
+
...value
|
|
14
|
+
};
|
|
15
|
+
delete relations[key].db;
|
|
16
|
+
delete relations[key].c;
|
|
17
|
+
}
|
|
18
|
+
if ("select" in query)
|
|
19
|
+
query.select = convertSearchObjToSearchArray(query.select);
|
|
20
|
+
return {
|
|
21
|
+
r: {
|
|
22
|
+
path: [db, collection],
|
|
23
|
+
...query,
|
|
24
|
+
relations,
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function buildQuery(db, op, collection, query) {
|
|
29
|
+
if (query.fields && !query.select) {
|
|
30
|
+
query.select = query.fields;
|
|
31
|
+
delete query.fields;
|
|
32
|
+
}
|
|
33
|
+
if ("select" in query)
|
|
34
|
+
query.select = [...new Set(convertSearchObjToSearchArray(query.select).map(k => k[0]).flat())];
|
|
35
|
+
return {
|
|
36
|
+
db,
|
|
37
|
+
d: {
|
|
38
|
+
[op]: {
|
|
39
|
+
collection,
|
|
40
|
+
...query,
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
package/dist/cpu/string/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseArgs } from "./args.js";
|
|
2
|
+
import { buildVQL } from "./build.js";
|
|
3
|
+
import { extractMeta } from "./utils.js";
|
|
2
4
|
const aliases = {
|
|
3
5
|
s: "search",
|
|
4
6
|
f: "fields",
|
|
@@ -8,152 +10,6 @@ const aliases = {
|
|
|
8
10
|
e: "select",
|
|
9
11
|
u: "updater",
|
|
10
12
|
};
|
|
11
|
-
function parseArgs(input) {
|
|
12
|
-
const result = {};
|
|
13
|
-
const tokens = [];
|
|
14
|
-
let current = "";
|
|
15
|
-
let inQuotes = false;
|
|
16
|
-
let escape = false;
|
|
17
|
-
let objTree = 0;
|
|
18
|
-
for (let i = 0; i < input.length; i++) {
|
|
19
|
-
const char = input[i];
|
|
20
|
-
if (escape) {
|
|
21
|
-
current += char;
|
|
22
|
-
escape = false;
|
|
23
|
-
}
|
|
24
|
-
else if (char === "\\") {
|
|
25
|
-
escape = true;
|
|
26
|
-
}
|
|
27
|
-
else if (!inQuotes && (char === "{" || char === "[")) {
|
|
28
|
-
objTree++;
|
|
29
|
-
current += char;
|
|
30
|
-
}
|
|
31
|
-
else if (!inQuotes && (char === "}" || char === "]")) {
|
|
32
|
-
objTree--;
|
|
33
|
-
current += char;
|
|
34
|
-
if (objTree === 0) {
|
|
35
|
-
tokens.push(current);
|
|
36
|
-
current = "";
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
else if (!objTree && (char === "'" || char === '"' || char === "`")) {
|
|
40
|
-
if (inQuotes === char) {
|
|
41
|
-
inQuotes = false;
|
|
42
|
-
tokens.push(`"` + current + `"`);
|
|
43
|
-
current = "";
|
|
44
|
-
}
|
|
45
|
-
else if (typeof inQuotes === "boolean") {
|
|
46
|
-
inQuotes = char;
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
current += char;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
else if (!inQuotes && (char === " " || char === "=" || char === "<" || char === ">")) {
|
|
53
|
-
if (current !== "") {
|
|
54
|
-
if (char === "<" || char === ">") {
|
|
55
|
-
let type = char === ">" ? "gt" : "lt";
|
|
56
|
-
if (i < input.length - 1 && input[i + 1] === "=") {
|
|
57
|
-
type += "e";
|
|
58
|
-
i++;
|
|
59
|
-
}
|
|
60
|
-
const split = current.split(".");
|
|
61
|
-
if (split.length > 1) {
|
|
62
|
-
const original = split.shift();
|
|
63
|
-
const operation = "$" + type;
|
|
64
|
-
split.unshift(operation);
|
|
65
|
-
split.unshift(original);
|
|
66
|
-
current = split.join(".");
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
current = "$" + type + "." + current;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
tokens.push(current);
|
|
73
|
-
current = "";
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
current += char;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (current !== "") {
|
|
81
|
-
tokens.push(current);
|
|
82
|
-
}
|
|
83
|
-
for (let i = 0; i < tokens.length; i += 2) {
|
|
84
|
-
const key = tokens[i];
|
|
85
|
-
let value = tokens[i + 1] ?? true;
|
|
86
|
-
if (typeof value === "string") {
|
|
87
|
-
const trimmed = value.trim();
|
|
88
|
-
if (trimmed === "") {
|
|
89
|
-
value = true;
|
|
90
|
-
}
|
|
91
|
-
else if (/^".*"$/.test(trimmed)) {
|
|
92
|
-
value = trimmed.slice(1, -1);
|
|
93
|
-
}
|
|
94
|
-
else if (trimmed.toLowerCase() === "true") {
|
|
95
|
-
value = true;
|
|
96
|
-
}
|
|
97
|
-
else if (trimmed.toLowerCase() === "false") {
|
|
98
|
-
value = false;
|
|
99
|
-
}
|
|
100
|
-
else if (!isNaN(Number(trimmed))) {
|
|
101
|
-
value = Number(trimmed);
|
|
102
|
-
}
|
|
103
|
-
else if ((trimmed.startsWith("{") && trimmed.endsWith("}")) || (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
|
|
104
|
-
try {
|
|
105
|
-
value = JSON.parse(trimmed);
|
|
106
|
-
}
|
|
107
|
-
catch { }
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
result[key] = value;
|
|
111
|
-
}
|
|
112
|
-
return result;
|
|
113
|
-
}
|
|
114
|
-
function buildVQL(db, op, collection, query) {
|
|
115
|
-
const hasRelations = "relations" in query;
|
|
116
|
-
if (hasRelations) {
|
|
117
|
-
const relations = {};
|
|
118
|
-
for (const key in query.relations) {
|
|
119
|
-
const value = query.relations[key];
|
|
120
|
-
relations[key] = {
|
|
121
|
-
path: [value.db || db, value.c || key],
|
|
122
|
-
...value
|
|
123
|
-
};
|
|
124
|
-
delete relations[key].db;
|
|
125
|
-
delete relations[key].c;
|
|
126
|
-
}
|
|
127
|
-
if ("select" in query) {
|
|
128
|
-
query.select = convertSearchObjToSearchArray(query.select);
|
|
129
|
-
}
|
|
130
|
-
return {
|
|
131
|
-
r: {
|
|
132
|
-
path: [db, collection],
|
|
133
|
-
...query,
|
|
134
|
-
relations,
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
if (query.fields && !query.select) {
|
|
140
|
-
query.select = query.fields;
|
|
141
|
-
delete query.fields;
|
|
142
|
-
}
|
|
143
|
-
if ("select" in query) {
|
|
144
|
-
query.select = [...new Set(convertSearchObjToSearchArray(query.select).map(k => k[0]).flat())];
|
|
145
|
-
}
|
|
146
|
-
return {
|
|
147
|
-
db,
|
|
148
|
-
d: {
|
|
149
|
-
[op]: {
|
|
150
|
-
collection,
|
|
151
|
-
...query,
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
13
|
export function parseVQLS(query) {
|
|
158
14
|
const { db, op, collection, body } = extractMeta(query);
|
|
159
15
|
const parsed = parseArgs(body);
|
|
@@ -167,7 +23,9 @@ export function parseVQLS(query) {
|
|
|
167
23
|
const key = keys[i];
|
|
168
24
|
if (i < keys.length - 1) {
|
|
169
25
|
if (!(key in obj)) {
|
|
170
|
-
|
|
26
|
+
const nextKey = keys[i + 1];
|
|
27
|
+
const isArrayIndex = /^\d+$/.test(nextKey);
|
|
28
|
+
obj[key] = isArrayIndex ? [] : {};
|
|
171
29
|
}
|
|
172
30
|
obj = obj[key];
|
|
173
31
|
}
|
package/dist/cpu/string/utils.js
CHANGED
|
@@ -2,13 +2,15 @@ const opPrefix = {
|
|
|
2
2
|
"-": "remove",
|
|
3
3
|
"+": "add",
|
|
4
4
|
"~": "update",
|
|
5
|
+
"?": "updateOneOrAdd",
|
|
6
|
+
"^": "toggleOne"
|
|
5
7
|
};
|
|
6
8
|
const operations = [
|
|
7
9
|
"add",
|
|
8
10
|
"find", "findOne",
|
|
9
11
|
"update", "updateOne",
|
|
10
12
|
"remove", "removeOne",
|
|
11
|
-
"updateOneOrAdd",
|
|
13
|
+
"updateOneOrAdd", "toggleOne",
|
|
12
14
|
"ensureCollection", "issetCollection",
|
|
13
15
|
];
|
|
14
16
|
/**
|
|
@@ -55,7 +57,7 @@ export function extractMeta(input) {
|
|
|
55
57
|
let collection = "";
|
|
56
58
|
let body = "";
|
|
57
59
|
// Determine operation and collection based on special characters
|
|
58
|
-
if (["!", "-", "+", "~"].some(c => split[0].includes(c)) || // Check if operation is indicated by special character
|
|
60
|
+
if (["!", "-", "+", "~", "?", "^"].some(c => split[0].includes(c)) || // Check if operation is indicated by special character
|
|
59
61
|
[".", ":", "{"].some(c => split[1].includes(c)) // Check if query body is indicated by special character
|
|
60
62
|
) {
|
|
61
63
|
let temp = split.shift();
|
|
@@ -93,7 +95,7 @@ export function convertSearchObjToSearchArray(obj, parentKeys = []) {
|
|
|
93
95
|
if (!value) {
|
|
94
96
|
return acc;
|
|
95
97
|
}
|
|
96
|
-
else if (typeof value ===
|
|
98
|
+
else if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
97
99
|
return [...acc, ...convertSearchObjToSearchArray(value, currentPath)];
|
|
98
100
|
}
|
|
99
101
|
else {
|
package/dist/helpers/valid.js
CHANGED
|
@@ -131,6 +131,15 @@ function validD(query) {
|
|
|
131
131
|
return emptyErr("'updateOneOrAdd' operation 'id_gen' property must be a boolean.");
|
|
132
132
|
return true;
|
|
133
133
|
}
|
|
134
|
+
if (key === "toggleOne") {
|
|
135
|
+
const op = d.toggleOne;
|
|
136
|
+
if (!isObj(op.search, false))
|
|
137
|
+
return emptyErr("'toggleOne' operation requires a 'search' object.");
|
|
138
|
+
if ("data" in op && !isObj(op.data, false))
|
|
139
|
+
return emptyErr("'toggleOne' operation 'data' property must be an object.");
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
const n = key;
|
|
134
143
|
return emptyErr(`Unknown or invalid CRUD operation: '${key}'`);
|
|
135
144
|
}
|
|
136
145
|
export function validateVql(query) {
|
|
@@ -34,12 +34,19 @@ export async function extractPaths(config, query) {
|
|
|
34
34
|
permPaths.paths.push({ filed: extractPathsFromData(qo.search), p: PermCRUD.READ });
|
|
35
35
|
permPaths.paths.push({ filed: extractPathsFromData(qo.updater), p: PermCRUD.UPDATE });
|
|
36
36
|
break;
|
|
37
|
+
case "toggleOne":
|
|
38
|
+
permPaths.paths.push({ c: PermCRUD.DELETE });
|
|
39
|
+
permPaths.paths.push({ c: PermCRUD.CREATE });
|
|
40
|
+
break;
|
|
37
41
|
case "ensureCollection":
|
|
38
42
|
case "getCollections":
|
|
39
43
|
case "issetCollection":
|
|
40
44
|
case "removeCollection":
|
|
41
45
|
permPaths.paths.push({ c: PermCRUD.COLLECTION });
|
|
42
46
|
break;
|
|
47
|
+
default:
|
|
48
|
+
const n = operation;
|
|
49
|
+
break;
|
|
43
50
|
}
|
|
44
51
|
permPaths.paths = (await Promise.all(permPaths.paths.map(async (path) => {
|
|
45
52
|
if (!path.filed)
|
package/dist/types/vql.d.ts
CHANGED
|
@@ -39,6 +39,11 @@ export interface VQL_OP_UpdateOneOrAdd<T = any> {
|
|
|
39
39
|
add_arg?: Arg<T>;
|
|
40
40
|
id_gen?: boolean;
|
|
41
41
|
}
|
|
42
|
+
export interface VQL_OP_ToggleOne<T = any> {
|
|
43
|
+
collection: string;
|
|
44
|
+
search: Search<T>;
|
|
45
|
+
data?: Arg<T>;
|
|
46
|
+
}
|
|
42
47
|
export interface VQL_OP_CollectionOperation {
|
|
43
48
|
collection: string;
|
|
44
49
|
}
|
|
@@ -61,6 +66,8 @@ export type VQL_Query_CRUD_Data<T = any> = {
|
|
|
61
66
|
removeOne: VQL_OP_Remove<T>;
|
|
62
67
|
} | {
|
|
63
68
|
updateOneOrAdd: VQL_OP_UpdateOneOrAdd<T>;
|
|
69
|
+
} | {
|
|
70
|
+
toggleOne: VQL_OP_ToggleOne<T>;
|
|
64
71
|
} | {
|
|
65
72
|
removeCollection: VQL_OP_CollectionOperation;
|
|
66
73
|
} | {
|
|
@@ -70,6 +77,7 @@ export type VQL_Query_CRUD_Data<T = any> = {
|
|
|
70
77
|
} | {
|
|
71
78
|
getCollections: {};
|
|
72
79
|
};
|
|
80
|
+
export type VQL_Query_CRUD_Keys = VQL_Query_CRUD_Data extends infer U ? U extends Record<string, unknown> ? keyof U : never : never;
|
|
73
81
|
export interface VQL_Query_CRUD<T = any> {
|
|
74
82
|
db: string;
|
|
75
83
|
d: VQL_Query_CRUD_Data<T>;
|
package/dist/vql.d.ts
CHANGED
|
@@ -41,6 +41,10 @@ export type ComparisonOperators<T = any> = {
|
|
|
41
41
|
], number>;
|
|
42
42
|
$in?: Partial<Record<keyof T, T[keyof T][]>>;
|
|
43
43
|
$nin?: Partial<Record<keyof T, T[keyof T][]>>;
|
|
44
|
+
$idGt?: PartialOfType<T, string | number>;
|
|
45
|
+
$idLt?: PartialOfType<T, string | number>;
|
|
46
|
+
$idGte?: PartialOfType<T, string | number>;
|
|
47
|
+
$idLte?: PartialOfType<T, string | number>;
|
|
44
48
|
};
|
|
45
49
|
/** Type and Existence Operators */
|
|
46
50
|
export type TypeAndExistenceOperators<T = any> = {
|
|
@@ -79,7 +83,8 @@ export type ArrayUpdater<T = any> = {
|
|
|
79
83
|
};
|
|
80
84
|
/** Objects */
|
|
81
85
|
export type ObjectUpdater<T = any> = {
|
|
82
|
-
$merge?: PartialOfType<T, any
|
|
86
|
+
$merge?: PartialOfType<T, any>;
|
|
87
|
+
$deepMerge?: PartialOfType<T, any>;
|
|
83
88
|
};
|
|
84
89
|
/** Values */
|
|
85
90
|
export type ValueUpdater<T = any> = {
|
|
@@ -87,6 +92,8 @@ export type ValueUpdater<T = any> = {
|
|
|
87
92
|
$dec?: PartialOfType<T, number>;
|
|
88
93
|
$unset?: PartialOfType<T, any>;
|
|
89
94
|
$rename?: PartialOfType<T, any>;
|
|
95
|
+
/** same as { name: value } */
|
|
96
|
+
$set?: PartialOfType<T, any>;
|
|
90
97
|
};
|
|
91
98
|
export type UpdaterArg<T = any> = ArrayUpdater<T> & ObjectUpdater<T> & ValueUpdater<T> & Arg<T>;
|
|
92
99
|
export type Arg<T = any> = {
|
|
@@ -159,6 +166,7 @@ export interface ValtheraCompatible {
|
|
|
159
166
|
removeOne<T = Data>(collection: string, search: Search<T>, context?: VContext): Promise<boolean>;
|
|
160
167
|
removeCollection(collection: string): Promise<boolean>;
|
|
161
168
|
updateOneOrAdd<T = Data>(collection: string, search: Search<T>, updater: Updater<T>, opts?: UpdateOneOrAdd<T>): Promise<boolean>;
|
|
169
|
+
toggleOne<T = Data>(collection: string, search: Search<T>, data?: Arg<T>, context?: VContext): Promise<boolean>;
|
|
162
170
|
}
|
|
163
171
|
export interface UpdateOneOrAdd<T> {
|
|
164
172
|
add_arg?: Arg<T>;
|
|
@@ -231,6 +239,11 @@ export interface VQL_OP_UpdateOneOrAdd<T = any> {
|
|
|
231
239
|
add_arg?: Arg<T>;
|
|
232
240
|
id_gen?: boolean;
|
|
233
241
|
}
|
|
242
|
+
export interface VQL_OP_ToggleOne<T = any> {
|
|
243
|
+
collection: string;
|
|
244
|
+
search: Search<T>;
|
|
245
|
+
data?: Arg<T>;
|
|
246
|
+
}
|
|
234
247
|
export interface VQL_OP_CollectionOperation {
|
|
235
248
|
collection: string;
|
|
236
249
|
}
|
|
@@ -253,6 +266,8 @@ export type VQL_Query_CRUD_Data<T = any> = {
|
|
|
253
266
|
removeOne: VQL_OP_Remove<T>;
|
|
254
267
|
} | {
|
|
255
268
|
updateOneOrAdd: VQL_OP_UpdateOneOrAdd<T>;
|
|
269
|
+
} | {
|
|
270
|
+
toggleOne: VQL_OP_ToggleOne<T>;
|
|
256
271
|
} | {
|
|
257
272
|
removeCollection: VQL_OP_CollectionOperation;
|
|
258
273
|
} | {
|
|
@@ -262,6 +277,7 @@ export type VQL_Query_CRUD_Data<T = any> = {
|
|
|
262
277
|
} | {
|
|
263
278
|
getCollections: {};
|
|
264
279
|
};
|
|
280
|
+
export type VQL_Query_CRUD_Keys = VQL_Query_CRUD_Data extends infer U ? U extends Record<string, unknown> ? keyof U : never : never;
|
|
265
281
|
export interface VQL_Query_CRUD<T = any> {
|
|
266
282
|
db: string;
|
|
267
283
|
d: VQL_Query_CRUD_Data<T>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wxn0brp/vql",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"author": "wxn0brP",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"query-language"
|
|
28
28
|
],
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"@wxn0brp/db-core": ">=0.2.
|
|
31
|
-
"@wxn0brp/falcon-frame": ">=0.5.
|
|
32
|
-
"@wxn0brp/gate-warden": ">=0.
|
|
30
|
+
"@wxn0brp/db-core": ">=0.2.11",
|
|
31
|
+
"@wxn0brp/falcon-frame": ">=0.5.3",
|
|
32
|
+
"@wxn0brp/gate-warden": ">=0.5.0"
|
|
33
33
|
},
|
|
34
34
|
"peerDependenciesMeta": {
|
|
35
35
|
"@wxn0brp/falcon-frame": {
|
|
@@ -43,17 +43,18 @@
|
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
+
"@types/bun": "*",
|
|
46
47
|
"@types/node": "*",
|
|
47
|
-
"@wxn0brp/db": "^0.40.
|
|
48
|
-
"@wxn0brp/db-core": "^0.2.
|
|
49
|
-
"@wxn0brp/falcon-frame": "^0.5.
|
|
50
|
-
"@wxn0brp/gate-warden": "^0.
|
|
51
|
-
"esbuild": "
|
|
48
|
+
"@wxn0brp/db": "^0.40.3",
|
|
49
|
+
"@wxn0brp/db-core": "^0.2.11",
|
|
50
|
+
"@wxn0brp/falcon-frame": "^0.5.3",
|
|
51
|
+
"@wxn0brp/gate-warden": "^0.5.0",
|
|
52
|
+
"esbuild": "*",
|
|
52
53
|
"tsc-alias": "*",
|
|
53
54
|
"typescript": "*"
|
|
54
55
|
},
|
|
55
56
|
"dependencies": {
|
|
56
|
-
"@wxn0brp/lucerna-log": "^0.2.
|
|
57
|
+
"@wxn0brp/lucerna-log": "^0.2.2"
|
|
57
58
|
},
|
|
58
59
|
"exports": {
|
|
59
60
|
".": {
|