@lobb-js/lobb-ext-reports 0.11.0 → 0.11.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.
@@ -0,0 +1,73 @@
1
+ import type { Lobb, Workflow } from "@lobb-js/core";
2
+ import type { Context } from "hono";
3
+
4
+ export const workflows: Workflow[] = [
5
+ {
6
+ // Intercept GET /api/collections/reports_charts/:id when ?action=run_query
7
+ // is present — runs the chart's parsed function and short-circuits the
8
+ // default findOne behaviour by throwing a Response.
9
+ name: "reports_chartsRunQueryHandler",
10
+ eventName: "core.controllers.preFindOne",
11
+ handler: async (input, ctx) => {
12
+ if (input.collectionName !== "reports_charts") return input;
13
+
14
+ const c = input.context as Context;
15
+ const actionQuery = c.req.query("action");
16
+ if (!actionQuery) return input;
17
+
18
+ if (actionQuery !== "run_query") {
19
+ throw new ctx.LobbError({
20
+ code: "BAD_REQUEST",
21
+ message: `The passed (${actionQuery}) action query param is not supported`,
22
+ });
23
+ }
24
+
25
+ const lobb = c.get("lobb") as Lobb;
26
+ const reportRecordId = input.id;
27
+ const contextParam = c.req.query("context");
28
+ const context = JSON.parse(contextParam ?? "{}");
29
+
30
+ const driver = lobb.databaseService.getDriver();
31
+ const pool = driver.getConnection();
32
+ using client = await pool.connect();
33
+
34
+ const chartRecord = (await lobb.collectionService.findOne({
35
+ collectionName: "reports_charts",
36
+ client,
37
+ id: reportRecordId,
38
+ })).data;
39
+
40
+ if (!chartRecord) {
41
+ throw new ctx.LobbError({
42
+ code: "NOT_FOUND",
43
+ message: `The chart you are looking for does not exist.`,
44
+ });
45
+ }
46
+
47
+ const pendingQueries: Promise<unknown>[] = [];
48
+
49
+ async function query(sql: string, args: Record<string, any>) {
50
+ const promise = client.query(sql, args).then((result) => result.rows);
51
+ pendingQueries.push(promise);
52
+ return await promise;
53
+ }
54
+
55
+ try {
56
+ const chartReturnedValue = await lobb.utils.runParsedFunction(
57
+ chartRecord.chart,
58
+ query,
59
+ context,
60
+ );
61
+ await Promise.allSettled(pendingQueries);
62
+ throw new Response(JSON.stringify(chartReturnedValue), {
63
+ status: 200,
64
+ headers: { "Content-Type": "application/json" },
65
+ });
66
+ } catch (error) {
67
+ if (error instanceof Response) throw error;
68
+ await Promise.allSettled(pendingQueries);
69
+ throw error;
70
+ }
71
+ },
72
+ },
73
+ ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobb-js/lobb-ext-reports",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -32,7 +32,7 @@
32
32
  "package": "svelte-package --input extensions/reports/studio"
33
33
  },
34
34
  "dependencies": {
35
- "@lobb-js/core": "^0.31.9",
35
+ "@lobb-js/core": "^0.32.1",
36
36
  "chart.js": "^4.4.8",
37
37
  "gridstack": "^12.6.0",
38
38
  "hono": "^4.7.0",
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "devDependencies": {
45
45
  "@faker-js/faker": "^9.6.0",
46
- "@lobb-js/studio": "^0.29.0",
46
+ "@lobb-js/studio": "^0.29.1",
47
47
  "@lucide/svelte": "^0.563.1",
48
48
  "@sveltejs/adapter-node": "^5.5.4",
49
49
  "@sveltejs/kit": "^2.60.1",
@@ -1,10 +0,0 @@
1
- import type { Hono } from "hono";
2
-
3
- import { ChartsController } from "./controllers/chartsController.ts";
4
-
5
- export function collectionRoutes(route: Hono) {
6
- route.get(
7
- "/reports_charts/:id",
8
- ChartsController.findOne,
9
- );
10
- }
@@ -1,78 +0,0 @@
1
- import type { Context } from "hono";
2
- import type { Lobb } from "@lobb-js/core";
3
- import { LobbError } from "@lobb-js/core";
4
-
5
- export class ChartsController {
6
- public static async findOne(c: Context) {
7
- const lobb = c.get("lobb") as Lobb;
8
- const reportRecordId = c.req.param("id");
9
- const actionQuery = c.req.query("action");
10
- const context = c.req.query("context");
11
-
12
- if (actionQuery) {
13
- if (actionQuery === "run_query") {
14
- return await handleRunQuery(
15
- reportRecordId,
16
- lobb,
17
- c,
18
- JSON.parse(context ?? "{}"),
19
- );
20
- } else {
21
- throw new LobbError({
22
- code: "BAD_REQUEST",
23
- message:
24
- `The passed (${actionQuery}) action query param is not supported`,
25
- });
26
- }
27
- }
28
-
29
- return await lobb.collectionControllers.findOne(
30
- c,
31
- ) as Response;
32
- }
33
- }
34
-
35
- async function handleRunQuery(
36
- reportRecordId: string,
37
- lobb: Lobb,
38
- c: Context,
39
- context: Record<string, unknown>,
40
- ) {
41
- const driver = lobb.databaseService.getDriver();
42
- const pool = driver.getConnection();
43
- using client = await pool.connect();
44
-
45
- const chartRecord = (await lobb.collectionService.findOne({
46
- collectionName: "reports_charts",
47
- client,
48
- id: reportRecordId,
49
- })).data;
50
-
51
- if (!chartRecord) {
52
- throw new LobbError({
53
- code: "NOT_FOUND",
54
- message: `The chart you are looking for does not exist.`,
55
- });
56
- }
57
-
58
- const pendingQueries: Promise<unknown>[] = [];
59
-
60
- async function query(sql: string, args: Record<string, any>) {
61
- const promise = client.query(sql, args).then((result) => result.rows);
62
- pendingQueries.push(promise);
63
- return await promise;
64
- }
65
-
66
- try {
67
- const chartReturnedValue = await lobb.utils.runParsedFunction(
68
- chartRecord.chart,
69
- query,
70
- context,
71
- );
72
- await Promise.allSettled(pendingQueries);
73
- return c.json(chartReturnedValue, 200);
74
- } catch (error) {
75
- await Promise.allSettled(pendingQueries);
76
- throw error;
77
- }
78
- }