@wxn0brp/vql 0.1.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.
Files changed (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +95 -0
  3. package/dist/apiAbstract.d.ts +17 -0
  4. package/dist/apiAbstract.js +25 -0
  5. package/dist/apiAbstract.js.map +1 -0
  6. package/dist/config.d.ts +7 -0
  7. package/dist/config.js +8 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/cpu/relation.d.ts +3 -0
  10. package/dist/cpu/relation.js +38 -0
  11. package/dist/cpu/relation.js.map +1 -0
  12. package/dist/cpu/request.d.ts +3 -0
  13. package/dist/cpu/request.js +66 -0
  14. package/dist/cpu/request.js.map +1 -0
  15. package/dist/cpu/string/index.d.ts +8 -0
  16. package/dist/cpu/string/index.js +55 -0
  17. package/dist/cpu/string/index.js.map +1 -0
  18. package/dist/cpu/string/json5.d.ts +2 -0
  19. package/dist/cpu/string/json5.js +9 -0
  20. package/dist/cpu/string/json5.js.map +1 -0
  21. package/dist/cpu/string/middle.d.ts +3 -0
  22. package/dist/cpu/string/middle.js +42 -0
  23. package/dist/cpu/string/middle.js.map +1 -0
  24. package/dist/cpu/string/simple.d.ts +2 -0
  25. package/dist/cpu/string/simple.js +152 -0
  26. package/dist/cpu/string/simple.js.map +1 -0
  27. package/dist/cpu/string/utils.d.ts +17 -0
  28. package/dist/cpu/string/utils.js +70 -0
  29. package/dist/cpu/string/utils.js.map +1 -0
  30. package/dist/cpu/string/yaml.d.ts +2 -0
  31. package/dist/cpu/string/yaml.js +20 -0
  32. package/dist/cpu/string/yaml.js.map +1 -0
  33. package/dist/cpu/utils.d.ts +1 -0
  34. package/dist/cpu/utils.js +15 -0
  35. package/dist/cpu/utils.js.map +1 -0
  36. package/dist/index.d.ts +6 -0
  37. package/dist/index.js +7 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/logger.d.ts +4 -0
  40. package/dist/logger.js +14 -0
  41. package/dist/logger.js.map +1 -0
  42. package/dist/permissions/index.d.ts +2 -0
  43. package/dist/permissions/index.js +3 -0
  44. package/dist/permissions/index.js.map +1 -0
  45. package/dist/permissions/relation.d.ts +3 -0
  46. package/dist/permissions/relation.js +53 -0
  47. package/dist/permissions/relation.js.map +1 -0
  48. package/dist/permissions/request.d.ts +18 -0
  49. package/dist/permissions/request.js +130 -0
  50. package/dist/permissions/request.js.map +1 -0
  51. package/dist/permissions/utils.d.ts +5 -0
  52. package/dist/permissions/utils.js +23 -0
  53. package/dist/permissions/utils.js.map +1 -0
  54. package/dist/processor.d.ts +11 -0
  55. package/dist/processor.js +44 -0
  56. package/dist/processor.js.map +1 -0
  57. package/dist/sheet/index.d.ts +2 -0
  58. package/dist/sheet/index.js +65 -0
  59. package/dist/sheet/index.js.map +1 -0
  60. package/dist/sheet/load.d.ts +3 -0
  61. package/dist/sheet/load.js +23 -0
  62. package/dist/sheet/load.js.map +1 -0
  63. package/dist/tests/customExe.d.ts +6 -0
  64. package/dist/tests/customExe.js +27 -0
  65. package/dist/tests/customExe.js.map +1 -0
  66. package/dist/tests/db.d.ts +1 -0
  67. package/dist/tests/db.js +33 -0
  68. package/dist/tests/db.js.map +1 -0
  69. package/dist/tests/index.d.ts +1 -0
  70. package/dist/tests/index.js +104 -0
  71. package/dist/tests/index.js.map +1 -0
  72. package/dist/types/perm.d.ts +7 -0
  73. package/dist/types/perm.js +9 -0
  74. package/dist/types/perm.js.map +1 -0
  75. package/dist/types/vql.d.ts +118 -0
  76. package/dist/types/vql.js +2 -0
  77. package/dist/types/vql.js.map +1 -0
  78. package/dist/valid.d.ts +17 -0
  79. package/dist/valid.js +51 -0
  80. package/dist/valid.js.map +1 -0
  81. package/package.json +33 -0
@@ -0,0 +1,70 @@
1
+ const opPrefix = {
2
+ "-": "remove",
3
+ "+": "add",
4
+ "~": "update",
5
+ };
6
+ /**
7
+ * Extracts metadata from a query string, including database name, operation,
8
+ * collection name, and the query body.
9
+ *
10
+ * @param input The input string to extract the information from.
11
+ * @returns An object with the following properties:
12
+ * - `db`: The database name.
13
+ * - `op`: The operation to perform, such as "find", "findOne", "add", "update", or "remove".
14
+ * - `collection`: The collection name.
15
+ * - `body`: The query body.
16
+ */
17
+ export function extractMeta(input) {
18
+ // Split the input into non-empty, trimmed lines and remove comments
19
+ const split = input
20
+ .split("\n")
21
+ .map(line => line.trim())
22
+ .filter(line => line.length > 0 && !line.startsWith("#") && !line.startsWith("//"))
23
+ .join(" ")
24
+ .split(/\s+/)
25
+ .filter(Boolean);
26
+ // Ensure the query has at least database and collection
27
+ if (split.length < 2)
28
+ throw new Error("Invalid query");
29
+ // Handle cases like "db users" or "db users!"
30
+ if (split.length === 2 && /^[A-Za-z]/.test(split[0])) {
31
+ let op = split[0].endsWith("!") ? "findOne" : "find";
32
+ return { db: split[0], op, collection: split[1].replace("!", ""), body: "" };
33
+ }
34
+ // Handle cases like "db find users"
35
+ if (split.length === 3 && /^[A-Za-z0-9_-]+$/.test(split[2])) {
36
+ return { db: split[0], op: split[1], collection: split[2], body: "" };
37
+ }
38
+ // Default operation and initialization
39
+ const db = split.shift();
40
+ let op = "find";
41
+ let collection = "";
42
+ let body = "";
43
+ // Determine operation and collection based on special characters
44
+ if (["!", "-", "+", "~"].some(c => split[0].includes(c)) || // Check if operation is indicated by special character
45
+ [".", ":", "{"].some(c => split[1].includes(c)) // Check if query body is indicated by special character
46
+ ) {
47
+ let temp = split.shift();
48
+ const firstChar = temp[0];
49
+ const lastChar = temp[temp.length - 1];
50
+ op = opPrefix[firstChar] || "find";
51
+ if (op !== "find")
52
+ temp = temp.slice(1); // Remove operation prefix if not "find"
53
+ if (lastChar === "!") {
54
+ if (op !== "add")
55
+ op += "One"; // Adjust operation for singular cases
56
+ collection = temp.slice(0, -1);
57
+ }
58
+ else {
59
+ collection = temp;
60
+ }
61
+ }
62
+ else {
63
+ op = split.shift(); // Assume second word is operation
64
+ collection = split.shift(); // Assume third word is collection
65
+ }
66
+ // Remaining words form the query body
67
+ body = split.join(" ");
68
+ return { db, op, collection, body };
69
+ }
70
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/cpu/string/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { VQL } from "../../types/vql.js";
2
+ export declare function parseVQLM(query: string): VQL;
@@ -0,0 +1,20 @@
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
+ }
20
+ //# sourceMappingURL=yaml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml.js","sourceRoot":"","sources":["../../../src/cpu/string/yaml.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,IAAI,MAAM,SAAS,CAAC;AAE3B,MAAM,UAAU,SAAS,CAAC,KAAa;IACnC,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAElD,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,IAAI,CAAC,kBAAkB,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,kBAAkB,GAAG,IAAI,CAAC;QACtI,IAAI,kBAAkB,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC1C,YAAY,GAAG,CAAC,CAAC;YACjB,MAAM;QACV,CAAC;IACL,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE/B,OAAO,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function parseSelect(select: object | object[]): any[];
@@ -0,0 +1,15 @@
1
+ import { VQLConfig } from "../config.js";
2
+ export function parseSelect(select) {
3
+ if (Array.isArray(select)) {
4
+ if (!VQLConfig.strictSelect && select.length === 0)
5
+ return undefined;
6
+ return select;
7
+ }
8
+ else {
9
+ const keys = Object.keys(select);
10
+ if (!VQLConfig.strictSelect && keys.length === 0)
11
+ return undefined;
12
+ return keys.filter(k => !!select[k]);
13
+ }
14
+ }
15
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/cpu/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,UAAU,WAAW,CAAC,MAAyB;IACjD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC,SAAS,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACrE,OAAO,MAAM,CAAC;IAClB,CAAC;SAAM,CAAC;QACJ,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,SAAS,CAAC,YAAY,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACnE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { VQLProcessor } from "./processor.js";
2
+ import { VQLConfig } from "./config.js";
3
+ import { createValtheraAdapter } from "./apiAbstract.js";
4
+ export default VQLProcessor;
5
+ export { createValtheraAdapter, VQLConfig };
6
+ export * as VQLSheet from "./sheet/load.js";
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ import { VQLProcessor } from "./processor.js";
2
+ import { VQLConfig } from "./config.js";
3
+ import { createValtheraAdapter } from "./apiAbstract.js";
4
+ export default VQLProcessor;
5
+ export { createValtheraAdapter, VQLConfig };
6
+ export * as VQLSheet from "./sheet/load.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEtD,eAAe,YAAY,CAAC;AAC5B,OAAO,EACH,qBAAqB,EACrB,SAAS,EACZ,CAAA;AACD,OAAO,KAAK,QAAQ,MAAM,cAAc,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Logger } from "@wxn0brp/wts-logger";
2
+ declare const logger: Logger;
3
+ export declare function logLog(instanceName: string, message: any): void;
4
+ export default logger;
package/dist/logger.js ADDED
@@ -0,0 +1,14 @@
1
+ import { ConsoleTransport, FileTransport, Logger } from "@wxn0brp/wts-logger";
2
+ const logger = new Logger({
3
+ transports: [
4
+ new ConsoleTransport(),
5
+ new FileTransport("data/execution.log")
6
+ ],
7
+ loggerName: "VQL"
8
+ });
9
+ export function logLog(instanceName, message) {
10
+ const logMessage = `[${instanceName}] ${message}`;
11
+ logger.info(logMessage);
12
+ }
13
+ export default logger;
14
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE9E,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;IACtB,UAAU,EAAE;QACR,IAAI,gBAAgB,EAAE;QACtB,IAAI,aAAa,CAAC,oBAAoB,CAAC;KAC1C;IACD,UAAU,EAAE,KAAK;CACpB,CAAC,CAAC;AAEH,MAAM,UAAU,MAAM,CAAC,YAAoB,EAAE,OAAY;IACrD,MAAM,UAAU,GAAG,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;IAClD,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC5B,CAAC;AAED,eAAe,MAAM,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./request.js";
2
+ export * from "./relation.js";
@@ -0,0 +1,3 @@
1
+ export * from "./request.js";
2
+ export * from "./relation.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/permissions/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { GateWarden } from "@wxn0brp/gate-warden";
2
+ import { RelationQuery } from "../types/vql.js";
3
+ export declare function checkRelationPermission(gw: GateWarden<any>, user: any, query: RelationQuery): Promise<boolean>;
@@ -0,0 +1,53 @@
1
+ import { PermCRUD } from "../types/perm.js";
2
+ import { extractPathsFromData, hashKey } from "./utils.js";
3
+ import { VQLConfig } from "../config.js";
4
+ export async function checkRelationPermission(gw, user, query) {
5
+ const { path, search, relations, select } = query.r;
6
+ // Helper function to recursively check permissions with fallback mechanism
7
+ const checkPermissionRecursively = async (entityId, fallbackLevels = []) => {
8
+ // Check if the user has access to the current entity
9
+ const result = await gw.hasAccess(user.id, entityId, PermCRUD.READ);
10
+ if (result.granted) {
11
+ return true;
12
+ }
13
+ // If the result is "entity-404", check the next fallback level
14
+ if (!VQLConfig.strictACL && result.via === "entity-404" && fallbackLevels.length > 0) {
15
+ const nextFallbackEntityId = hashKey(fallbackLevels.slice(0, -1));
16
+ return checkPermissionRecursively(nextFallbackEntityId, fallbackLevels.slice(0, -2));
17
+ }
18
+ // If no fallback levels are left or the result is not "entity-404", deny access
19
+ return false;
20
+ };
21
+ // Check permission for the relation field in the parent collection
22
+ if (!await checkPermissionRecursively(hashKey(path), path)) {
23
+ return false;
24
+ }
25
+ // Check permissions for search fields
26
+ const searchPaths = extractPathsFromData(search || {});
27
+ for (const searchPath of searchPaths) {
28
+ const key = [...path, ...searchPath.path, searchPath.key];
29
+ if (!await checkPermissionRecursively(hashKey(key), key)) {
30
+ return false;
31
+ }
32
+ }
33
+ // Check permissions for select fields
34
+ if (select) {
35
+ for (const fieldPath of select) {
36
+ const key = [...path, fieldPath];
37
+ if (!await checkPermissionRecursively(hashKey(key), key)) {
38
+ return false;
39
+ }
40
+ }
41
+ }
42
+ // Recursively check nested relations
43
+ if (relations) {
44
+ for (const relationKey in relations) {
45
+ const r = relations[relationKey];
46
+ if (!await checkRelationPermission(gw, user, { r })) {
47
+ return false;
48
+ }
49
+ }
50
+ }
51
+ return true;
52
+ }
53
+ //# sourceMappingURL=relation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation.js","sourceRoot":"","sources":["../../src/permissions/relation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,uBAAuB,CACzC,EAAmB,EACnB,IAAS,EACT,KAAoB;IAEpB,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;IAEpD,2EAA2E;IAC3E,MAAM,0BAA0B,GAAG,KAAK,EACpC,QAAgB,EAChB,iBAA2B,EAAE,EACb,EAAE;QAClB,qDAAqD;QACrD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEpE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,+DAA+D;QAC/D,IAAI,CAAC,SAAS,CAAC,SAAS,IAAI,MAAM,CAAC,GAAG,KAAK,YAAY,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnF,MAAM,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAClE,OAAO,0BAA0B,CAAC,oBAAoB,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACzF,CAAC;QAED,gFAAgF;QAChF,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC;IAEF,mEAAmE;IACnE,IAAI,CAAC,MAAM,0BAA0B,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;QACzD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,sCAAsC;IACtC,MAAM,WAAW,GAAG,oBAAoB,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IACvD,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,0BAA0B,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;YACvD,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED,sCAAsC;IACtC,IAAI,MAAM,EAAE,CAAC;QACT,KAAK,MAAM,SAAS,IAAI,MAAM,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,SAAS,CAAa,CAAC;YAC7C,IAAI,CAAC,MAAM,0BAA0B,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;gBACvD,OAAO,KAAK,CAAC;YACjB,CAAC;QACL,CAAC;IACL,CAAC;IAED,qCAAqC;IACrC,IAAI,SAAS,EAAE,CAAC;QACZ,KAAK,MAAM,WAAW,IAAI,SAAS,EAAE,CAAC;YAClC,MAAM,CAAC,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;YACjC,IAAI,CAAC,MAAM,uBAAuB,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,EAAS,CAAC,EAAE,CAAC;gBACzD,OAAO,KAAK,CAAC;YACjB,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { GateWarden } from "@wxn0brp/gate-warden";
2
+ import { PermCRUD } from "../types/perm.js";
3
+ import { VQLRequest } from "../types/vql.js";
4
+ export declare function extractPaths(query: VQLRequest): {
5
+ db: string;
6
+ c: string;
7
+ paths: {
8
+ filed?: string;
9
+ p?: PermCRUD;
10
+ c?: PermCRUD;
11
+ path?: string[];
12
+ }[];
13
+ };
14
+ export declare function processFieldPath(pathObj: {
15
+ path: string[];
16
+ key: string;
17
+ }): string[];
18
+ export declare function checkRequestPermission(gw: GateWarden<any>, user: any, query: VQLRequest): Promise<boolean>;
@@ -0,0 +1,130 @@
1
+ import { PermCRUD } from "../types/perm.js";
2
+ import { extractPathsFromData, hashKey } from "./utils.js";
3
+ import { VQLConfig } from "../config.js";
4
+ export function extractPaths(query) {
5
+ const operation = Object.keys(query.d)[0];
6
+ const collection = query.d[operation].collection;
7
+ const permPaths = {
8
+ db: hashKey(query.db),
9
+ c: collection,
10
+ paths: []
11
+ };
12
+ switch (operation) {
13
+ case "f":
14
+ case "find":
15
+ case "findOne":
16
+ const qf = query.d[operation];
17
+ permPaths.paths.push({ filed: extractPathsFromData(qf.search), p: PermCRUD.READ });
18
+ break;
19
+ case "add":
20
+ permPaths.paths.push({ c: PermCRUD.CREATE });
21
+ break;
22
+ case "update":
23
+ case "updateOne":
24
+ const qu = query.d[operation];
25
+ permPaths.paths.push({ filed: extractPathsFromData(qu.search), p: PermCRUD.READ });
26
+ permPaths.paths.push({ filed: extractPathsFromData(qu.updater), p: PermCRUD.UPDATE });
27
+ break;
28
+ case "remove":
29
+ case "removeOne":
30
+ permPaths.paths.push({ c: PermCRUD.DELETE });
31
+ break;
32
+ case "updateOneOrAdd":
33
+ const qo = query.d[operation];
34
+ permPaths.paths.push({ c: PermCRUD.CREATE });
35
+ permPaths.paths.push({ filed: extractPathsFromData(qo.search), p: PermCRUD.READ });
36
+ permPaths.paths.push({ filed: extractPathsFromData(qo.updater), p: PermCRUD.UPDATE });
37
+ break;
38
+ case "checkCollection":
39
+ case "getCollections":
40
+ case "issetCollection":
41
+ case "removeCollection":
42
+ permPaths.paths.push({ c: PermCRUD.COLLECTION });
43
+ break;
44
+ }
45
+ permPaths.paths = permPaths.paths.map(path => {
46
+ if (!path.filed)
47
+ return path;
48
+ return path.filed.map(filed => {
49
+ const processedPath = [query.db, collection, ...processFieldPath(filed)];
50
+ return { filed: hashKey(processedPath), path: processedPath, p: path.p };
51
+ });
52
+ }).flat();
53
+ return permPaths;
54
+ }
55
+ export function processFieldPath(pathObj) {
56
+ let subsetMode = false;
57
+ const processedPath = [];
58
+ for (const part of pathObj.path) {
59
+ if (subsetMode) {
60
+ processedPath.push(part);
61
+ }
62
+ else {
63
+ if (part.startsWith("$")) {
64
+ if (part === "$subset") {
65
+ subsetMode = true;
66
+ }
67
+ }
68
+ else {
69
+ processedPath.push(part);
70
+ }
71
+ }
72
+ }
73
+ if (subsetMode) {
74
+ processedPath.push(pathObj.key);
75
+ }
76
+ else {
77
+ if (!pathObj.key.startsWith("$")) {
78
+ processedPath.push(pathObj.key);
79
+ }
80
+ }
81
+ return processedPath;
82
+ }
83
+ export async function checkRequestPermission(gw, user, query) {
84
+ if (!query)
85
+ return false;
86
+ const permPaths = extractPaths(query);
87
+ // Helper function to recursively check permissions
88
+ const checkPermissionRecursively = async (entityId, requiredPerm, fallbackLevels = []) => {
89
+ // Check if the user has access to the current entity
90
+ const result = await gw.hasAccess(user.id, entityId, requiredPerm);
91
+ if (result.granted) {
92
+ return true;
93
+ }
94
+ // If the result is "entity-404", check the next fallback level
95
+ if (!VQLConfig.strictACL && result.via === "entity-404" && fallbackLevels.length > 0) {
96
+ const nextFallbackEntityId = hashKey(fallbackLevels.slice(0, -1));
97
+ return checkPermissionRecursively(nextFallbackEntityId, requiredPerm, fallbackLevels.slice(0, -2));
98
+ }
99
+ // If no fallback levels are left or the result is not "entity-404", deny access
100
+ return false;
101
+ };
102
+ debugger;
103
+ // Check each required permission
104
+ const results = [];
105
+ for (const path of permPaths.paths) {
106
+ let entityId;
107
+ let requiredPerm;
108
+ let fallbackLevels = [];
109
+ if ("c" in path) {
110
+ // Collection-level permission: hash the combination of db and collection
111
+ entityId = hashKey([query.db, permPaths.c]);
112
+ requiredPerm = path.c;
113
+ // Fallback to database level if needed
114
+ fallbackLevels = [query.db];
115
+ }
116
+ else {
117
+ // Field-level permission: use the hashed field path
118
+ entityId = path.filed;
119
+ requiredPerm = path.p;
120
+ // Fallback to collection and then database level if needed
121
+ fallbackLevels = path.path;
122
+ }
123
+ // Check permissions recursively
124
+ const result = await checkPermissionRecursively(entityId, requiredPerm, fallbackLevels);
125
+ results.push(result);
126
+ }
127
+ // All permissions must be granted
128
+ return results.every(result => result);
129
+ }
130
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/permissions/request.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,UAAU,YAAY,CAAC,KAAiB;IAU1C,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAmB,CAAC;IAC5D,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC;IACjD,MAAM,SAAS,GAAG;QACd,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,CAAC,EAAE,UAAU;QACb,KAAK,EAAE,EAAE;KACZ,CAAA;IAED,QAAQ,SAAS,EAAE,CAAC;QAChB,KAAK,GAAG,CAAC;QACT,KAAK,MAAM,CAAC;QACZ,KAAK,SAAS;YACV,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAyB,CAAC;YACtD,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YACnF,MAAM;QACV,KAAK,KAAK;YACN,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7C,MAAM;QACV,KAAK,QAAQ,CAAC;QACd,KAAK,WAAW;YACZ,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAA6B,CAAC;YAC1D,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YACnF,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACtF,MAAM;QACV,KAAK,QAAQ,CAAC;QACd,KAAK,WAAW;YACZ,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7C,MAAM;QACV,KAAK,gBAAgB;YACjB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAsB,CAAC;YACnD,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7C,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YACnF,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACtF,MAAM;QACV,KAAK,iBAAiB,CAAC;QACvB,KAAK,gBAAgB,CAAC;QACtB,KAAK,iBAAiB,CAAC;QACvB,KAAK,kBAAkB;YACnB,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YACjD,MAAM;IACd,CAAC;IAED,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QACzC,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAE7B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YAC1B,MAAM,aAAa,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;YACzE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAC7E,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAEV,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAAwC;IACrE,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,MAAM,aAAa,GAAa,EAAE,CAAC;IAEnC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,UAAU,EAAE,CAAC;YACb,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACJ,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBACrB,UAAU,GAAG,IAAI,CAAC;gBACtB,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;QACL,CAAC;IACL,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACb,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;SAAM,CAAC;QACJ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC;IACL,CAAC;IAED,OAAO,aAAa,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CACxC,EAAmB,EACnB,IAAS,EACT,KAAiB;IAEjB,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEzB,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAEtC,mDAAmD;IACnD,MAAM,0BAA0B,GAAG,KAAK,EACpC,QAAgB,EAChB,YAAoB,EACpB,iBAA2B,EAAE,EACb,EAAE;QAClB,qDAAqD;QACrD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QAEnE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,+DAA+D;QAC/D,IAAI,CAAC,SAAS,CAAC,SAAS,IAAI,MAAM,CAAC,GAAG,KAAK,YAAY,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnF,MAAM,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAClE,OAAO,0BAA0B,CAAC,oBAAoB,EAAE,YAAY,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvG,CAAC;QAED,gFAAgF;QAChF,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC;IAEF,QAAQ,CAAA;IACR,iCAAiC;IACjC,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;QACjC,IAAI,QAAgB,CAAC;QACrB,IAAI,YAAoB,CAAC;QACzB,IAAI,cAAc,GAAa,EAAE,CAAC;QAElC,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YACd,yEAAyE;YACzE,QAAQ,GAAG,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC;YAEtB,uCAAuC;YACvC,cAAc,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACJ,oDAAoD;YACpD,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;YACtB,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC;YAEtB,2DAA2D;YAC3D,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC;QAC/B,CAAC;QAED,gCAAgC;QAChC,MAAM,MAAM,GAAG,MAAM,0BAA0B,CAAC,QAAQ,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;QACxF,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;IAED,kCAAkC;IAClC,OAAO,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function hashKey(path: any): string;
2
+ export declare function extractPathsFromData(data: any, stack?: string[]): {
3
+ path: string[];
4
+ key: string;
5
+ }[];
@@ -0,0 +1,23 @@
1
+ import crypto from "crypto";
2
+ import { VQLConfig } from "../config.js";
3
+ export function hashKey(path) {
4
+ const json = JSON.stringify(path);
5
+ if (VQLConfig.hidePath)
6
+ return crypto.createHash("sha256").update(json).digest("hex");
7
+ else
8
+ return json;
9
+ }
10
+ export function extractPathsFromData(data, stack = []) {
11
+ const paths = [];
12
+ for (const key in data) {
13
+ const value = data[key];
14
+ if (typeof value === "object") {
15
+ paths.push(...extractPathsFromData(value, [...stack, key]));
16
+ }
17
+ else {
18
+ paths.push({ path: stack, key });
19
+ }
20
+ }
21
+ return paths;
22
+ }
23
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/permissions/utils.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,UAAU,OAAO,CAAC,IAAS;IAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,SAAS,CAAC,QAAQ;QAClB,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;;QAE9D,OAAO,IAAI,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAS,EAAE,QAAkB,EAAE;IAChE,MAAM,KAAK,GAAsC,EAAE,CAAC;IACpD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,KAAK,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACJ,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QACrC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Relation, ValtheraCompatible } from "@wxn0brp/db";
2
+ import { GateWarden } from "@wxn0brp/gate-warden";
3
+ import { VQL, VQLR } from "./types/vql.js";
4
+ export declare class VQLProcessor<GW = any> {
5
+ dbInstances: Record<string, ValtheraCompatible>;
6
+ gw: GateWarden<GW>;
7
+ relation: Relation;
8
+ preDefinedSheets: Map<string, VQL>;
9
+ constructor(dbInstances: Record<string, ValtheraCompatible>, gw?: GateWarden<GW>);
10
+ execute(queryRaw: VQLR | string, user: any): Promise<any>;
11
+ }
@@ -0,0 +1,44 @@
1
+ import { Relation } from "@wxn0brp/db";
2
+ import { validateRaw, validateVql } from "./valid.js";
3
+ import { executeSheet } from "./sheet/index.js";
4
+ import { executeQuery } from "./cpu/request.js";
5
+ import { executeRelation } from "./cpu/relation.js";
6
+ import { parseStringQuery } from "./cpu/string/index.js";
7
+ export class VQLProcessor {
8
+ dbInstances;
9
+ gw;
10
+ relation;
11
+ preDefinedSheets = new Map();
12
+ constructor(dbInstances, gw = null) {
13
+ this.dbInstances = dbInstances;
14
+ this.gw = gw;
15
+ this.relation = new Relation(dbInstances);
16
+ }
17
+ async execute(queryRaw, user) {
18
+ if (typeof queryRaw === "string") {
19
+ try {
20
+ queryRaw = parseStringQuery(queryRaw);
21
+ }
22
+ catch (e) {
23
+ return { err: true, msg: "Invalid query", c: 400, why: `String query parsing error: ${e.message}` };
24
+ }
25
+ }
26
+ const validateRawResult = validateRaw(queryRaw);
27
+ if (validateRawResult !== true)
28
+ return validateRawResult;
29
+ const query = executeSheet(queryRaw, this.preDefinedSheets);
30
+ const validateVqlResult = validateVql(query);
31
+ if (validateVqlResult !== true)
32
+ return validateVqlResult;
33
+ if ("r" in query) {
34
+ return await executeRelation(this, query, user);
35
+ }
36
+ else if ("d" in query) {
37
+ return await executeQuery(this, query, user);
38
+ }
39
+ else {
40
+ return { err: true, msg: "Invalid query", c: 400 };
41
+ }
42
+ }
43
+ }
44
+ //# sourceMappingURL=processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processor.js","sourceRoot":"","sources":["../src/processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAsB,MAAM,aAAa,CAAC;AAG3D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,OAAO,YAAY;IAKV;IACA;IALJ,QAAQ,CAAW;IACnB,gBAAgB,GAAqB,IAAI,GAAG,EAAE,CAAC;IAEtD,YACW,WAA+C,EAC/C,KAAqB,IAAI;QADzB,gBAAW,GAAX,WAAW,CAAoC;QAC/C,OAAE,GAAF,EAAE,CAAuB;QAEhC,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAAuB,EAAE,IAAS;QAC5C,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACD,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC1C,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,eAAe,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,+BAA+B,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YACxG,CAAC;QACL,CAAC;QAED,MAAM,iBAAiB,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,iBAAiB,KAAK,IAAI;YAAE,OAAO,iBAAiB,CAAC;QAEzD,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAE5D,MAAM,iBAAiB,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,iBAAiB,KAAK,IAAI;YAAE,OAAO,iBAAiB,CAAC;QAEzD,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;YACf,OAAO,MAAM,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACpD,CAAC;aAAM,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;YACtB,OAAO,MAAM,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACJ,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,eAAe,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;QACvD,CAAC;IACL,CAAC;CACJ"}
@@ -0,0 +1,2 @@
1
+ import { VQL, VQLR } from "../types/vql.js";
2
+ export declare function executeSheet(query: VQLR, preDefinedSheets: Map<string, VQL>): VQL;
@@ -0,0 +1,65 @@
1
+ import { deepMerge } from "@wxn0brp/wts-deep-merge";
2
+ function trimPath(path) {
3
+ return path && path.length > 2 ? path.slice(0, 2) : path;
4
+ }
5
+ function relationFix(relations) {
6
+ for (const key in relations) {
7
+ const value = relations[key];
8
+ value.path = trimPath(value.path);
9
+ if (value.relations) {
10
+ relationFix(value.relations);
11
+ }
12
+ }
13
+ }
14
+ function pathFix(vql) {
15
+ if ("d" in vql) {
16
+ const key = Object.keys(vql.d)[0];
17
+ const value = vql.d[key];
18
+ value.path = trimPath(value.path);
19
+ }
20
+ else if ("r" in vql) {
21
+ const value = vql.r;
22
+ value.path = trimPath(value.path);
23
+ if (value.relations) {
24
+ relationFix(value.relations);
25
+ }
26
+ }
27
+ }
28
+ function replaceVariables(obj, variables) {
29
+ if (typeof obj === "string") {
30
+ if (obj.startsWith("$")) {
31
+ return variables[obj.slice(1)] || variables[obj];
32
+ }
33
+ return obj;
34
+ }
35
+ else if (Array.isArray(obj)) {
36
+ return obj.map((item) => replaceVariables(item, variables));
37
+ }
38
+ else if (typeof obj === "object") {
39
+ const newObj = {};
40
+ for (const key in obj) {
41
+ newObj[key] = replaceVariables(obj[key], variables);
42
+ }
43
+ return newObj;
44
+ }
45
+ else {
46
+ return obj;
47
+ }
48
+ }
49
+ export function executeSheet(query, preDefinedSheets) {
50
+ if ("ref" in query) {
51
+ if (preDefinedSheets.has(query.ref)) {
52
+ const ref = preDefinedSheets.get(query.ref);
53
+ const merge = deepMerge(query, ref);
54
+ pathFix(merge);
55
+ query = merge;
56
+ }
57
+ delete query.ref;
58
+ }
59
+ if ("var" in query) {
60
+ query = replaceVariables(query, query.var);
61
+ delete query.var;
62
+ }
63
+ return query;
64
+ }
65
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sheet/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAIpD,SAAS,QAAQ,CAAC,IAAoC;IAClD,OAAO,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAuB,CAAC,CAAC,CAAC,IAAI,CAAC;AACnF,CAAC;AAED,SAAS,WAAW,CAAC,SAAiC;IAClD,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAC7B,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAClB,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACjC,CAAC;IACL,CAAC;AACL,CAAC;AAED,SAAS,OAAO,CAAC,GAAQ;IACrB,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACzB,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;SAAM,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC;QACpB,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAClB,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACjC,CAAC;IACL,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAQ,EAAE,SAA8B;IAC9D,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC1B,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IACrE,CAAC;SAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,MAAM,GAAQ,EAAE,CAAC;QACvB,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;SAAM,CAAC;QACJ,OAAO,GAAG,CAAC;IACf,CAAC;AACL,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAW,EAAE,gBAAkC;IACxE,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACjB,IAAI,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,GAAG,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,GAAG,CAAQ,CAAC;YAC3C,OAAO,CAAC,KAAK,CAAC,CAAC;YACf,KAAK,GAAG,KAAK,CAAC;QAClB,CAAC;QACD,OAAO,KAAK,CAAC,GAAG,CAAC;IACrB,CAAC;IAED,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACjB,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3C,OAAO,KAAK,CAAC,GAAG,CAAC;IACrB,CAAC;IAED,OAAO,KAAY,CAAC;AACxB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { VQL } from "../types/vql.js";
2
+ export declare function loadSheetsFromDir(dir: string): Map<string, VQL>;
3
+ export declare function loadSheetFromFile(file: string): Map<string, VQL>;
@@ -0,0 +1,23 @@
1
+ import { existsSync, readdirSync, readFileSync } from "fs";
2
+ function loadSheet(map, file) {
3
+ if (!existsSync(file)) {
4
+ throw new Error(`Sheet ${file} not found`);
5
+ }
6
+ const sheet = JSON.parse(readFileSync(file, "utf-8"));
7
+ for (const key in sheet) {
8
+ map.set(key, sheet[key]);
9
+ }
10
+ }
11
+ export function loadSheetsFromDir(dir) {
12
+ const map = new Map();
13
+ for (const file of readdirSync(dir)) {
14
+ loadSheet(map, `${dir}/${file}`);
15
+ }
16
+ return map;
17
+ }
18
+ export function loadSheetFromFile(file) {
19
+ const map = new Map();
20
+ loadSheet(map, file);
21
+ return map;
22
+ }
23
+ //# sourceMappingURL=load.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/sheet/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAG3D,SAAS,SAAS,CAAC,GAAqB,EAAE,IAAY;IAClD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,YAAY,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAwB,CAAC;IAE7E,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,CAAC;AACL,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAW;IACzC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAe,CAAC;IAEnC,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,GAAG,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAe,CAAC;IACnC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACrB,OAAO,GAAG,CAAC;AACf,CAAC"}
@@ -0,0 +1,6 @@
1
+ import executorC from "@wxn0brp/db/executor.js";
2
+ export declare class CustomExecutor extends executorC {
3
+ name: string;
4
+ constructor(name: string);
5
+ execute(): Promise<void>;
6
+ }