@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.
- package/README.md +623 -607
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +2 -2
- package/dist/src/cli.js.map +1 -1
- package/dist/src/version.d.ts +2 -0
- package/dist/src/version.d.ts.map +1 -0
- package/dist/src/version.js +6 -0
- package/dist/src/version.js.map +1 -0
- package/package.json +3 -2
- package/templates/HelloWorld/README.md +83 -106
- package/templates/HelloWorld/backend/package.json +1 -1
- package/templates/HelloWorld/backend/src/database.ts +108 -0
- package/templates/HelloWorld/backend/src/excel.ts +118 -0
- package/templates/HelloWorld/backend/src/http.ts +22 -0
- package/templates/HelloWorld/backend/src/index.ts +105 -29
- package/templates/HelloWorld/backend/src/jobs.ts +47 -0
- package/templates/HelloWorld/backend/src/messages.ts +59 -0
- package/templates/HelloWorld/backend/src/pdf.ts +212 -0
- package/templates/HelloWorld/backend/src/secrets.ts +21 -14
- package/templates/HelloWorld/backend/src/volumes.ts +107 -0
- package/templates/HelloWorld/frontend/package.json +1 -3
- package/templates/HelloWorld/frontend/src/App.css +62 -37
- package/templates/HelloWorld/frontend/src/App.tsx +131 -111
- package/templates/HelloWorld/frontend/src/services/index.ts +11 -11
- package/templates/HelloWorld/tests/test.createInvoicePdf.json +18 -0
- package/templates/HelloWorld/tests/{test.getSecretWithoutGrant.json → test.createSimplePdf.json} +4 -2
- package/templates/HelloWorld/tests/test.createSpreadsheet.json +11 -0
- package/templates/HelloWorld/tests/test.echo.json +2 -2
- package/templates/HelloWorld/tests/test.fetchExternalApi.json +13 -0
- package/templates/HelloWorld/tests/test.getSecret.json +5 -1
- package/templates/HelloWorld/tests/test.info.json +3 -1
- package/templates/HelloWorld/tests/test.listFiles.json +13 -0
- package/templates/HelloWorld/tests/{test.echo2.json → test.queryUsers.json} +3 -3
- package/templates/HelloWorld/tests/{test.greet.json → test.readFile.json} +2 -2
- package/templates/HelloWorld/tests/{test.testWriteFileWithoutVolumeGrant.json → test.saveFile.json} +4 -2
- package/templates/HelloWorld/tests/test.sendNotification.json +14 -0
- package/templates/HelloWorld/backend/src/volume.ts +0 -55
package/dist/src/cli.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
|
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>")
|
package/dist/src/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
|
@@ -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.
|
|
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
|
-
"
|
|
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
|
|
1
|
+
# Ketrics Application Template
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
9
|
-
├──
|
|
10
|
-
│
|
|
11
|
-
│
|
|
12
|
-
│
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
24
|
-
- Zod schema validation
|
|
25
|
-
- Deployment via Ketrics CLI
|
|
78
|
+
## Setup
|
|
26
79
|
|
|
27
|
-
###
|
|
80
|
+
### Backend
|
|
28
81
|
|
|
29
82
|
```bash
|
|
30
|
-
cd
|
|
83
|
+
cd backend
|
|
31
84
|
npm install
|
|
32
85
|
npm run build
|
|
33
86
|
```
|
|
34
87
|
|
|
35
|
-
###
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
"message": "Hello, World!"
|
|
69
|
-
}
|
|
90
|
+
```bash
|
|
91
|
+
cd frontend
|
|
92
|
+
npm install
|
|
93
|
+
npm run build
|
|
70
94
|
```
|
|
71
95
|
|
|
72
|
-
|
|
96
|
+
## Deploy
|
|
73
97
|
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
"name": "John"
|
|
77
|
-
}
|
|
98
|
+
```bash
|
|
99
|
+
ketrics deploy
|
|
78
100
|
```
|
|
79
101
|
|
|
80
|
-
|
|
102
|
+
## API Request Format
|
|
81
103
|
|
|
82
|
-
|
|
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
|
-
"
|
|
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
|
|
@@ -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 };
|