@ketrics/ketrics-cli 0.2.2 → 0.3.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 (37) hide show
  1. package/README.md +623 -607
  2. package/dist/src/cli.d.ts.map +1 -1
  3. package/dist/src/cli.js +2 -2
  4. package/dist/src/cli.js.map +1 -1
  5. package/dist/src/version.d.ts +2 -0
  6. package/dist/src/version.d.ts.map +1 -0
  7. package/dist/src/version.js +6 -0
  8. package/dist/src/version.js.map +1 -0
  9. package/package.json +3 -2
  10. package/templates/HelloWorld/README.md +83 -106
  11. package/templates/HelloWorld/backend/package.json +1 -1
  12. package/templates/HelloWorld/backend/src/database.ts +108 -0
  13. package/templates/HelloWorld/backend/src/excel.ts +118 -0
  14. package/templates/HelloWorld/backend/src/http.ts +22 -0
  15. package/templates/HelloWorld/backend/src/index.ts +105 -29
  16. package/templates/HelloWorld/backend/src/jobs.ts +47 -0
  17. package/templates/HelloWorld/backend/src/messages.ts +59 -0
  18. package/templates/HelloWorld/backend/src/pdf.ts +212 -0
  19. package/templates/HelloWorld/backend/src/secrets.ts +21 -14
  20. package/templates/HelloWorld/backend/src/volumes.ts +107 -0
  21. package/templates/HelloWorld/frontend/package.json +1 -3
  22. package/templates/HelloWorld/frontend/src/App.css +62 -37
  23. package/templates/HelloWorld/frontend/src/App.tsx +131 -111
  24. package/templates/HelloWorld/frontend/src/services/index.ts +11 -11
  25. package/templates/HelloWorld/tests/test.createInvoicePdf.json +18 -0
  26. package/templates/HelloWorld/tests/{test.getSecretWithoutGrant.json → test.createSimplePdf.json} +4 -2
  27. package/templates/HelloWorld/tests/test.createSpreadsheet.json +11 -0
  28. package/templates/HelloWorld/tests/test.echo.json +2 -2
  29. package/templates/HelloWorld/tests/test.fetchExternalApi.json +13 -0
  30. package/templates/HelloWorld/tests/test.getSecret.json +5 -1
  31. package/templates/HelloWorld/tests/test.info.json +3 -1
  32. package/templates/HelloWorld/tests/test.listFiles.json +13 -0
  33. package/templates/HelloWorld/tests/{test.echo2.json → test.queryUsers.json} +3 -3
  34. package/templates/HelloWorld/tests/{test.greet.json → test.readFile.json} +2 -2
  35. package/templates/HelloWorld/tests/{test.testWriteFileWithoutVolumeGrant.json → test.saveFile.json} +4 -2
  36. package/templates/HelloWorld/tests/test.sendNotification.json +14 -0
  37. package/templates/HelloWorld/backend/src/volume.ts +0 -55
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAgEnC"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAgEnC"}
package/dist/src/cli.js CHANGED
@@ -12,7 +12,7 @@ const build_1 = require("./commands/build");
12
12
  const deploy_1 = require("./commands/deploy");
13
13
  const validate_1 = require("./commands/validate");
14
14
  const run_1 = require("./commands/run");
15
- const VERSION = "0.1.1";
15
+ const version_1 = require("./version");
16
16
  /**
17
17
  * Create and configure CLI program
18
18
  */
@@ -21,7 +21,7 @@ function createCLI() {
21
21
  program
22
22
  .name("ketrics")
23
23
  .description("CLI tool for deploying applications to Ketrics platform")
24
- .version(VERSION, "-v, --version", "Show CLI version");
24
+ .version(version_1.VERSION, "-v, --version", "Show CLI version");
25
25
  // Create command
26
26
  program
27
27
  .command("create <app-name>")
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAcH,8BAgEC;AA5ED,yCAAoC;AACpC,8CAAkD;AAClD,4CAAgD;AAChD,8CAAkD;AAClD,kDAAsD;AACtD,wCAA4C;AAE5C,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB;;GAEG;AACH,SAAgB,SAAS;IACvB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,SAAS,CAAC;SACf,WAAW,CAAC,yDAAyD,CAAC;SACtE,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,kBAAkB,CAAC,CAAC;IAEzD,iBAAiB;IACjB,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,kDAAkD,CAAC;SAC/D,MAAM,CAAC,uBAAuB,EAAE,oDAAoD,CAAC;SACrF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QACjC,MAAM,IAAA,sBAAa,EAAC,OAAO,EAAE;YAC3B,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,gBAAgB;IAChB,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,IAAA,oBAAY,GAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEL,iBAAiB;IACjB,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;SAC/C,MAAM,CAAC,WAAW,EAAE,yDAAyD,CAAC;SAC9E,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,IAAA,sBAAa,EAAC;YAClB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,mBAAmB;IACnB,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;SAC5D,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;SAC/C,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,IAAA,0BAAe,EAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEL,cAAc;IACd,OAAO;SACJ,OAAO,CAAC,iBAAiB,CAAC;SAC1B,WAAW,CAAC,uDAAuD,CAAC;SACpE,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;SAC/C,MAAM,CAAC,eAAe,EAAE,4CAA4C,CAAC;SACrE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;QAClC,MAAM,IAAA,gBAAU,EAAC,QAAQ,EAAE;YACzB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAaH,8BAgEC;AA3ED,yCAAoC;AACpC,8CAAkD;AAClD,4CAAgD;AAChD,8CAAkD;AAClD,kDAAsD;AACtD,wCAA4C;AAC5C,uCAAoC;AAEpC;;GAEG;AACH,SAAgB,SAAS;IACvB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,SAAS,CAAC;SACf,WAAW,CAAC,yDAAyD,CAAC;SACtE,OAAO,CAAC,iBAAO,EAAE,eAAe,EAAE,kBAAkB,CAAC,CAAC;IAEzD,iBAAiB;IACjB,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,kDAAkD,CAAC;SAC/D,MAAM,CAAC,uBAAuB,EAAE,oDAAoD,CAAC;SACrF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QACjC,MAAM,IAAA,sBAAa,EAAC,OAAO,EAAE;YAC3B,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,gBAAgB;IAChB,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,IAAA,oBAAY,GAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEL,iBAAiB;IACjB,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;SAC/C,MAAM,CAAC,WAAW,EAAE,yDAAyD,CAAC;SAC9E,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,IAAA,sBAAa,EAAC;YAClB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,mBAAmB;IACnB,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;SAC5D,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;SAC/C,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,IAAA,0BAAe,EAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEL,cAAc;IACd,OAAO;SACJ,OAAO,CAAC,iBAAiB,CAAC;SAC1B,WAAW,CAAC,uDAAuD,CAAC;SACpE,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;SAC/C,MAAM,CAAC,eAAe,EAAE,4CAA4C,CAAC;SACrE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;QAClC,MAAM,IAAA,gBAAU,EAAC,QAAQ,EAAE;YACzB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const VERSION = "0.3.0";
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,OAAO,UAAU,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VERSION = void 0;
4
+ // Auto-generated - do not edit
5
+ exports.VERSION = "0.3.0";
6
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";;;AAAA,+BAA+B;AAClB,QAAA,OAAO,GAAG,OAAO,CAAC"}
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@ketrics/ketrics-cli",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "CLI tool for deploying applications to Ketrics platform",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
7
7
  "ketrics": "./dist/bin/ketrics.js"
8
8
  },
9
9
  "scripts": {
10
- "build": "tsc",
10
+ "prebuild": "node scripts/generate-version.js",
11
+ "build": "npm run prebuild && tsc",
11
12
  "dev": "ts-node bin/ketrics.ts",
12
13
  "clean": "rm -rf dist",
13
14
  "prepublishOnly": "npm run build"
@@ -1,134 +1,111 @@
1
- # Ketrics Test Application
1
+ # Ketrics Application Template
2
2
 
3
- Test applications for validating the Ketrics CLI deployment workflow.
3
+ A starter template for building applications on the Ketrics platform, demonstrating all SDK features.
4
4
 
5
5
  ## Structure
6
6
 
7
7
  ```
8
- test-application/
9
- ├── frontend/ # React + TypeScript + Vite frontend
10
- ├── src/
11
- ├── ketrics.config.json
12
- └── .env.example
13
- └── backend/ # TypeScript handlers for data-plane
14
- ├── src/
15
- ├── ketrics.config.json
16
- └── .env.example
8
+ ├── ketrics.config.json # Application configuration
9
+ ├── backend/ # TypeScript handlers for Runtime API
10
+ └── src/
11
+ ├── index.ts # Main exports (echo, info)
12
+ ├── volumes.ts # Volume storage examples
13
+ │ ├── database.ts # Database connection examples
14
+ ├── pdf.ts # PDF generation examples
15
+ ├── excel.ts # Excel workbook examples
16
+ │ ├── secrets.ts # Secret management examples
17
+ │ ├── messages.ts # User messaging examples
18
+ │ ├── jobs.ts # Background job examples
19
+ │ └── http.ts # HTTP client examples
20
+ ├── frontend/ # React + TypeScript + Vite frontend
21
+ │ └── src/
22
+ │ ├── App.tsx # Main UI with feature demos
23
+ │ └── services/ # API client (payload-wrapped requests)
24
+ └── tests/ # Test request definitions
17
25
  ```
18
26
 
19
- ## Frontend
27
+ ## Backend Functions
28
+
29
+ | Function | Description |
30
+ | --- | --- |
31
+ | `echo` | Returns payload with full context info |
32
+ | `info` | Returns runtime environment details |
33
+ | `saveFile` | Write JSON and text files to a volume |
34
+ | `readFile` | Read and parse files from a volume |
35
+ | `listFiles` | List files in a volume with prefix filtering |
36
+ | `generateDownloadUrl` | Generate a temporary download URL |
37
+ | `copyFile` | Copy a file within a volume |
38
+ | `queryUsers` | Query records from a database |
39
+ | `insertRecord` | Insert a record into a database |
40
+ | `transferFunds` | Database transaction example |
41
+ | `createSimplePdf` | Generate a simple PDF document |
42
+ | `createInvoicePdf` | Generate an invoice-style PDF |
43
+ | `createSpreadsheet` | Create an Excel workbook |
44
+ | `exportDataToExcel` | Export data to a multi-sheet Excel file |
45
+ | `getSecret` | Retrieve an encrypted secret |
46
+ | `sendNotification` | Send a notification to the current user |
47
+ | `sendBulkNotification` | Send notifications to multiple users |
48
+ | `scheduleBackgroundJob` | Schedule a background job |
49
+ | `getJobStatus` | Check background job status |
50
+ | `fetchExternalApi` | Make an external HTTP request |
51
+
52
+ ## Ketrics SDK (v0.8.0)
53
+
54
+ Backend handlers access the `ketrics` global object injected at runtime:
20
55
 
21
- A simple React application demonstrating:
56
+ ```typescript
57
+ // Context
58
+ ketrics.tenant // { id, code, name }
59
+ ketrics.application // { id, code, name, version, deploymentId }
60
+ ketrics.requestor // { type, userId, email, name, applicationPermissions }
61
+ ketrics.runtime // { nodeVersion, runtime, region }
62
+ ketrics.environment // key-value environment variables
63
+
64
+ // Utilities
65
+ ketrics.console // { log, error, warn, info, debug } → CloudWatch
66
+ ketrics.http // { get, post, put, delete } → external APIs
67
+
68
+ // Feature Modules
69
+ ketrics.Volume // .connect(code) → S3-backed file storage
70
+ ketrics.Database // .connect(code) → SQL databases (PostgreSQL, MySQL, etc.)
71
+ ketrics.Secret // .get(code) → encrypted secrets
72
+ ketrics.Excel // .create() / .read(buffer) → Excel workbooks
73
+ ketrics.Pdf // .create() / .read(buffer) → PDF documents
74
+ ketrics.Job // .runInBackground(params) → async job execution
75
+ ketrics.Messages // .send(params) → user notifications
76
+ ```
22
77
 
23
- - React + TypeScript + Vite setup
24
- - Zod schema validation
25
- - Deployment via Ketrics CLI
78
+ ## Setup
26
79
 
27
- ### Setup
80
+ ### Backend
28
81
 
29
82
  ```bash
30
- cd frontend
83
+ cd backend
31
84
  npm install
32
85
  npm run build
33
86
  ```
34
87
 
35
- ### Deploy
36
-
37
- 1. Copy `.env.example` to `.env` and fill in your credentials:
38
-
39
- ```bash
40
- cp .env.example .env
41
- ```
42
-
43
- 2. Deploy:
44
- ```bash
45
- ketrics deploy
46
- ```
47
-
48
- ## Backend
49
-
50
- TypeScript handlers compatible with Ketrics data-plane-api.
51
-
52
- ### Available Actions
53
-
54
- | Action | Description |
55
- | ----------- | ------------------------------- |
56
- | `echo` | Returns payload with context |
57
- | `greet` | Personalized greeting |
58
- | `calculate` | Simple math operations |
59
- | `fetch` | Test HTTP client |
60
- | `info` | Environment and context info |
61
-
62
- ### Example Payloads
88
+ ### Frontend
63
89
 
64
- **Echo:**
65
-
66
- ```json
67
- {
68
- "message": "Hello, World!"
69
- }
90
+ ```bash
91
+ cd frontend
92
+ npm install
93
+ npm run build
70
94
  ```
71
95
 
72
- **Greet:**
96
+ ## Deploy
73
97
 
74
- ```json
75
- {
76
- "name": "John"
77
- }
98
+ ```bash
99
+ ketrics deploy
78
100
  ```
79
101
 
80
- **Calculate:**
102
+ ## API Request Format
81
103
 
82
- ```json
83
- {
84
- "operation": "add",
85
- "a": 10,
86
- "b": 5
87
- }
88
- ```
89
-
90
- **Fetch:**
104
+ All function calls use the Runtime API with payload wrapped in a `payload` property:
91
105
 
92
106
  ```json
107
+ POST /tenants/{tenantId}/applications/{applicationId}/functions/{functionName}
93
108
  {
94
- "url": "https://api.example.com/data"
109
+ "payload": { "your": "data" }
95
110
  }
96
111
  ```
97
-
98
- ### Setup
99
-
100
- ```bash
101
- cd backend
102
- npm install
103
- npm run build
104
- ```
105
-
106
- ### Deploy
107
-
108
- 1. Copy `.env.example` to `.env` and fill in your credentials:
109
-
110
- ```bash
111
- cp .env.example .env
112
- ```
113
-
114
- 2. Deploy:
115
- ```bash
116
- ketrics deploy
117
- ```
118
-
119
- ## Ketrics SDK
120
-
121
- The backend handlers have access to the `ketrics` global object injected at runtime:
122
-
123
- ```typescript
124
- ketrics.tenant // { id, code, name }
125
- ketrics.application // { id, code, name, version, deploymentId }
126
- ketrics.user // { id, email, name, isAdmin }
127
- ketrics.env // { nodeVersion, runtime, region }
128
- ketrics.console // { log, error }
129
- ketrics.http // { get, post }
130
- ```
131
-
132
- ## License
133
-
134
- MIT
@@ -9,7 +9,7 @@
9
9
  "clean": "rm -rf dist"
10
10
  },
11
11
  "devDependencies": {
12
- "@ketrics/sdk-backend": "0.7.1",
12
+ "@ketrics/sdk-backend": "0.8.0",
13
13
  "@types/node": ">=24.0.0",
14
14
  "esbuild": "^0.27.2",
15
15
  "ts-node": "^1.7.1",
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Database Examples
3
+ *
4
+ * Demonstrates external SQL database operations using ketrics.Database.
5
+ * Data connections must be configured and granted to the application in the Ketrics portal.
6
+ *
7
+ * Supports PostgreSQL, MySQL, SQL Server, and Oracle databases.
8
+ */
9
+
10
+ /**
11
+ * Query records from a database.
12
+ */
13
+ const queryUsers = async (payload: { limit?: number }) => {
14
+ const db = await ketrics.Database.connect("my-database");
15
+
16
+ try {
17
+ const result = await db.query<{ id: number; name: string; email: string }>(
18
+ "SELECT id, name, email FROM users ORDER BY name LIMIT $1",
19
+ [payload?.limit || 10],
20
+ );
21
+
22
+ return {
23
+ users: result.rows,
24
+ rowCount: result.rowCount,
25
+ };
26
+ } finally {
27
+ await db.close();
28
+ }
29
+ };
30
+
31
+ /**
32
+ * Insert a record into a database.
33
+ */
34
+ const insertRecord = async (payload: { name: string; email: string }) => {
35
+ if (!payload?.name || !payload?.email) {
36
+ throw new Error("name and email are required");
37
+ }
38
+
39
+ const db = await ketrics.Database.connect("my-database");
40
+
41
+ try {
42
+ const result = await db.execute(
43
+ "INSERT INTO users (name, email, created_at) VALUES ($1, $2, NOW())",
44
+ [payload.name, payload.email],
45
+ );
46
+
47
+ return {
48
+ affectedRows: result.affectedRows,
49
+ insertId: result.insertId,
50
+ };
51
+ } finally {
52
+ await db.close();
53
+ }
54
+ };
55
+
56
+ /**
57
+ * Perform a database transaction - demonstrates atomic multi-step operations.
58
+ * Transactions automatically commit on success or rollback on error.
59
+ */
60
+ const transferFunds = async (payload: {
61
+ fromAccountId: number;
62
+ toAccountId: number;
63
+ amount: number;
64
+ }) => {
65
+ if (!payload?.fromAccountId || !payload?.toAccountId || !payload?.amount) {
66
+ throw new Error("fromAccountId, toAccountId, and amount are required");
67
+ }
68
+
69
+ if (payload.amount <= 0) {
70
+ throw new Error("Amount must be positive");
71
+ }
72
+
73
+ const db = await ketrics.Database.connect("my-database");
74
+
75
+ try {
76
+ const result = await db.transaction(async (tx) => {
77
+ // Debit source account
78
+ const debit = await tx.execute(
79
+ "UPDATE accounts SET balance = balance - $1 WHERE id = $2 AND balance >= $1",
80
+ [payload.amount, payload.fromAccountId],
81
+ );
82
+
83
+ if (debit.affectedRows === 0) {
84
+ throw new Error("Insufficient funds or account not found");
85
+ }
86
+
87
+ // Credit destination account
88
+ await tx.execute(
89
+ "UPDATE accounts SET balance = balance + $1 WHERE id = $2",
90
+ [payload.amount, payload.toAccountId],
91
+ );
92
+
93
+ // Log the transfer
94
+ await tx.execute(
95
+ "INSERT INTO transfers (from_account, to_account, amount, created_at) VALUES ($1, $2, $3, NOW())",
96
+ [payload.fromAccountId, payload.toAccountId, payload.amount],
97
+ );
98
+
99
+ return { transferred: payload.amount };
100
+ });
101
+
102
+ return result;
103
+ } finally {
104
+ await db.close();
105
+ }
106
+ };
107
+
108
+ export { queryUsers, insertRecord, transferFunds };
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Excel Examples
3
+ *
4
+ * Demonstrates Excel workbook creation using ketrics.Excel.
5
+ * Generated workbooks can be saved to a volume for download.
6
+ */
7
+
8
+ /**
9
+ * Create a spreadsheet with headers and sample data.
10
+ */
11
+ const createSpreadsheet = async () => {
12
+ const workbook = ketrics.Excel.create();
13
+
14
+ // Create a worksheet with column definitions
15
+ const sheet = workbook.addWorksheet("Employees", {
16
+ tabColor: "4472C4",
17
+ });
18
+
19
+ // Define columns
20
+ sheet.columns = [
21
+ { header: "ID", key: "id", width: 10 },
22
+ { header: "Name", key: "name", width: 25 },
23
+ { header: "Department", key: "department", width: 20 },
24
+ { header: "Start Date", key: "startDate", width: 15 },
25
+ { header: "Salary", key: "salary", width: 15 },
26
+ ];
27
+
28
+ // Add rows
29
+ const employees = [
30
+ { id: 1, name: "Alice Johnson", department: "Engineering", startDate: "2024-01-15", salary: 95000 },
31
+ { id: 2, name: "Bob Smith", department: "Marketing", startDate: "2023-06-01", salary: 78000 },
32
+ { id: 3, name: "Carol Williams", department: "Engineering", startDate: "2024-03-20", salary: 105000 },
33
+ { id: 4, name: "David Brown", department: "Sales", startDate: "2023-09-10", salary: 82000 },
34
+ { id: 5, name: "Eva Martinez", department: "Engineering", startDate: "2024-07-01", salary: 92000 },
35
+ ];
36
+
37
+ sheet.addRows(employees);
38
+
39
+ // Save to volume
40
+ const buffer = await workbook.toBuffer();
41
+ const volume = await ketrics.Volume.connect("test-volume");
42
+ const result = await volume.put("reports/employees.xlsx", buffer, {
43
+ contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
44
+ });
45
+
46
+ const downloadUrl = await volume.generateDownloadUrl("reports/employees.xlsx", {
47
+ expiresIn: 3600,
48
+ });
49
+
50
+ return {
51
+ file: { key: result.key, size: result.size },
52
+ downloadUrl: downloadUrl.url,
53
+ rowCount: employees.length,
54
+ };
55
+ };
56
+
57
+ /**
58
+ * Export dynamic data to Excel - demonstrates creating a multi-sheet
59
+ * workbook with a summary sheet and a data sheet.
60
+ */
61
+ const exportDataToExcel = async (payload: { title?: string }) => {
62
+ const title = payload?.title || "Data Export";
63
+
64
+ const workbook = ketrics.Excel.create();
65
+
66
+ // Summary sheet
67
+ const summarySheet = workbook.addWorksheet("Summary");
68
+ summarySheet.columns = [
69
+ { header: "Property", key: "property", width: 25 },
70
+ { header: "Value", key: "value", width: 40 },
71
+ ];
72
+
73
+ summarySheet.addRows([
74
+ { property: "Report Title", value: title },
75
+ { property: "Generated By", value: ketrics.application.name },
76
+ { property: "Tenant", value: ketrics.tenant.name },
77
+ { property: "Generated At", value: new Date().toISOString() },
78
+ { property: "Requestor", value: ketrics.requestor.name },
79
+ ]);
80
+
81
+ // Data sheet with sample data
82
+ const dataSheet = workbook.addWorksheet("Data");
83
+ dataSheet.columns = [
84
+ { header: "Category", key: "category", width: 20 },
85
+ { header: "Month", key: "month", width: 15 },
86
+ { header: "Revenue", key: "revenue", width: 15 },
87
+ { header: "Expenses", key: "expenses", width: 15 },
88
+ { header: "Profit", key: "profit", width: 15 },
89
+ ];
90
+
91
+ const sampleData = [
92
+ { category: "Product A", month: "January", revenue: 50000, expenses: 30000, profit: 20000 },
93
+ { category: "Product A", month: "February", revenue: 55000, expenses: 31000, profit: 24000 },
94
+ { category: "Product B", month: "January", revenue: 35000, expenses: 20000, profit: 15000 },
95
+ { category: "Product B", month: "February", revenue: 40000, expenses: 22000, profit: 18000 },
96
+ ];
97
+
98
+ dataSheet.addRows(sampleData);
99
+
100
+ // Save to volume
101
+ const buffer = await workbook.toBuffer();
102
+ const volume = await ketrics.Volume.connect("test-volume");
103
+ const fileName = `reports/export-${Date.now()}.xlsx`;
104
+ const result = await volume.put(fileName, buffer, {
105
+ contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
106
+ });
107
+
108
+ const downloadUrl = await volume.generateDownloadUrl(fileName, { expiresIn: 3600 });
109
+
110
+ return {
111
+ file: { key: result.key, size: result.size },
112
+ downloadUrl: downloadUrl.url,
113
+ sheets: ["Summary", "Data"],
114
+ dataRowCount: sampleData.length,
115
+ };
116
+ };
117
+
118
+ export { createSpreadsheet, exportDataToExcel };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * HTTP Client Examples
3
+ *
4
+ * Demonstrates making external HTTP requests using ketrics.http.
5
+ * The HTTP client supports GET, POST, PUT, and DELETE methods.
6
+ */
7
+
8
+ /**
9
+ * Fetch data from an external API.
10
+ */
11
+ const fetchExternalApi = async (payload: { url?: string }) => {
12
+ const url = payload?.url || "https://jsonplaceholder.typicode.com/posts/1";
13
+
14
+ const response = await ketrics.http.get<{ id: number; title: string; body: string }>(url);
15
+
16
+ return {
17
+ data: response,
18
+ fetchedAt: new Date().toISOString(),
19
+ };
20
+ };
21
+
22
+ export { fetchExternalApi };