@ketrics/sdk-backend 0.2.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 +329 -0
- package/dist/console.d.ts +34 -0
- package/dist/console.d.ts.map +1 -0
- package/dist/console.js +9 -0
- package/dist/console.js.map +1 -0
- package/dist/context.d.ts +65 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +9 -0
- package/dist/context.js.map +1 -0
- package/dist/database-errors.d.ts +197 -0
- package/dist/database-errors.d.ts.map +1 -0
- package/dist/database-errors.js +258 -0
- package/dist/database-errors.js.map +1 -0
- package/dist/databases.d.ts +165 -0
- package/dist/databases.d.ts.map +1 -0
- package/dist/databases.js +31 -0
- package/dist/databases.js.map +1 -0
- package/dist/errors.d.ts +244 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +316 -0
- package/dist/errors.js.map +1 -0
- package/dist/http.d.ts +57 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +9 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +377 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +99 -0
- package/dist/index.js.map +1 -0
- package/dist/secret-errors.d.ts +128 -0
- package/dist/secret-errors.d.ts.map +1 -0
- package/dist/secret-errors.js +172 -0
- package/dist/secret-errors.js.map +1 -0
- package/dist/secrets.d.ts +50 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +27 -0
- package/dist/secrets.js.map +1 -0
- package/dist/volumes.d.ts +276 -0
- package/dist/volumes.d.ts.map +1 -0
- package/dist/volumes.js +9 -0
- package/dist/volumes.js.map +1 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# @ketrics/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript type definitions for building tenant applications on the Ketrics platform.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @ketrics/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
The SDK provides TypeScript types for the global `ketrics` object that is automatically injected into your tenant application code at runtime. Everything is accessible via the `ketrics` object:
|
|
14
|
+
|
|
15
|
+
- **Context**: `ketrics.tenant`, `ketrics.application`, `ketrics.user`, `ketrics.env`
|
|
16
|
+
- **Utilities**: `ketrics.console`, `ketrics.http`, `ketrics.databases`
|
|
17
|
+
- **Volume**: `ketrics.Volume.connect()` for S3-backed storage
|
|
18
|
+
- **Error classes**: `ketrics.VolumeNotFoundError`, etc. for `instanceof` checks
|
|
19
|
+
|
|
20
|
+
### Basic Example
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// Import types only if needed for type annotations
|
|
24
|
+
import type { FileContent, IVolume } from '@ketrics/sdk';
|
|
25
|
+
|
|
26
|
+
export async function handler() {
|
|
27
|
+
// The global `ketrics` object is automatically typed
|
|
28
|
+
console.log('Tenant:', ketrics.tenant.name);
|
|
29
|
+
console.log('User:', ketrics.user.email);
|
|
30
|
+
console.log('App:', ketrics.application.code);
|
|
31
|
+
|
|
32
|
+
// Use ketrics.Volume.connect() for S3 storage
|
|
33
|
+
try {
|
|
34
|
+
const volume = await ketrics.Volume.connect('uploads');
|
|
35
|
+
|
|
36
|
+
// Get a file
|
|
37
|
+
const file = await volume.get('documents/report.pdf');
|
|
38
|
+
console.log('Content-Type:', file.contentType);
|
|
39
|
+
console.log('Size:', file.contentLength);
|
|
40
|
+
|
|
41
|
+
return { success: true, size: file.contentLength };
|
|
42
|
+
} catch (error) {
|
|
43
|
+
// Error classes are on the ketrics object
|
|
44
|
+
if (error instanceof ketrics.VolumeNotFoundError) {
|
|
45
|
+
return { error: `Volume '${error.volumeCode}' not found` };
|
|
46
|
+
}
|
|
47
|
+
if (error instanceof ketrics.FileNotFoundError) {
|
|
48
|
+
return { error: `File '${error.key}' not found` };
|
|
49
|
+
}
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Available APIs
|
|
56
|
+
|
|
57
|
+
### Context (Read-only)
|
|
58
|
+
|
|
59
|
+
Access information about the current tenant, application, user, and environment:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
// Tenant context
|
|
63
|
+
ketrics.tenant.id // Tenant UUID
|
|
64
|
+
ketrics.tenant.code // e.g., "acme-corp"
|
|
65
|
+
ketrics.tenant.name // e.g., "ACME Corporation"
|
|
66
|
+
|
|
67
|
+
// Application context
|
|
68
|
+
ketrics.application.id // Application UUID
|
|
69
|
+
ketrics.application.code // e.g., "inventory"
|
|
70
|
+
ketrics.application.name // e.g., "Inventory Manager"
|
|
71
|
+
ketrics.application.deploymentId // Current deployment ID
|
|
72
|
+
|
|
73
|
+
// User context
|
|
74
|
+
ketrics.user.id // User UUID
|
|
75
|
+
ketrics.user.email // e.g., "user@example.com"
|
|
76
|
+
ketrics.user.name // e.g., "John Doe"
|
|
77
|
+
ketrics.user.isAdmin // boolean
|
|
78
|
+
|
|
79
|
+
// Environment context
|
|
80
|
+
ketrics.env.nodeVersion // e.g., "18.x"
|
|
81
|
+
ketrics.env.runtime // "ecs-fargate"
|
|
82
|
+
ketrics.env.region // e.g., "us-east-1"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Console Logging
|
|
86
|
+
|
|
87
|
+
Logs are forwarded to CloudWatch with proper context:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
ketrics.console.log('Info message');
|
|
91
|
+
ketrics.console.error('Error message');
|
|
92
|
+
ketrics.console.warn('Warning message');
|
|
93
|
+
ketrics.console.info('Info message');
|
|
94
|
+
ketrics.console.debug('Debug message');
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### HTTP Client
|
|
98
|
+
|
|
99
|
+
Make external API requests:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
// GET request
|
|
103
|
+
const response = await ketrics.http.get<MyData>('https://api.example.com/data');
|
|
104
|
+
console.log(response.data, response.status);
|
|
105
|
+
|
|
106
|
+
// POST request
|
|
107
|
+
const result = await ketrics.http.post('https://api.example.com/submit', {
|
|
108
|
+
name: 'Test',
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// With options
|
|
112
|
+
const configured = await ketrics.http.get('https://api.example.com/data', {
|
|
113
|
+
headers: { 'Authorization': 'Bearer token' },
|
|
114
|
+
timeout: 5000,
|
|
115
|
+
params: { page: 1, limit: 10 },
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Volume Storage
|
|
120
|
+
|
|
121
|
+
S3-backed file storage with granular permissions. Access via `ketrics.Volume`:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// Import types only if needed for type annotations
|
|
125
|
+
import type { FileContent, PutResult, ListResult, IVolume } from '@ketrics/sdk';
|
|
126
|
+
|
|
127
|
+
// Connect to a volume via ketrics.Volume
|
|
128
|
+
const volume = await ketrics.Volume.connect('uploads');
|
|
129
|
+
|
|
130
|
+
// Check permissions
|
|
131
|
+
console.log(volume.code); // 'uploads'
|
|
132
|
+
console.log(volume.permissions); // Set { 'ReadObject', 'CreateObject', ... }
|
|
133
|
+
|
|
134
|
+
// Read a file
|
|
135
|
+
const file: FileContent = await volume.get('documents/report.pdf');
|
|
136
|
+
console.log(file.content); // Buffer
|
|
137
|
+
console.log(file.contentType); // 'application/pdf'
|
|
138
|
+
console.log(file.contentLength); // 12345
|
|
139
|
+
console.log(file.lastModified); // Date
|
|
140
|
+
console.log(file.etag); // 'abc123'
|
|
141
|
+
|
|
142
|
+
// Write a file
|
|
143
|
+
const result: PutResult = await volume.put('output/data.json', JSON.stringify(data), {
|
|
144
|
+
contentType: 'application/json',
|
|
145
|
+
metadata: { author: ketrics.user.email },
|
|
146
|
+
});
|
|
147
|
+
console.log(result.key, result.etag, result.size);
|
|
148
|
+
|
|
149
|
+
// Check if file exists
|
|
150
|
+
const exists = await volume.exists('config.json');
|
|
151
|
+
|
|
152
|
+
// Get file metadata (without downloading content)
|
|
153
|
+
const meta = await volume.getMetadata('large-file.zip');
|
|
154
|
+
console.log(meta.size, meta.contentType);
|
|
155
|
+
|
|
156
|
+
// List files
|
|
157
|
+
const list: ListResult = await volume.list({ prefix: 'documents/', maxResults: 100 });
|
|
158
|
+
for (const file of list.files) {
|
|
159
|
+
console.log(file.key, file.size, file.lastModified);
|
|
160
|
+
}
|
|
161
|
+
if (list.isTruncated) {
|
|
162
|
+
// Fetch next page
|
|
163
|
+
const nextPage = await volume.list({
|
|
164
|
+
prefix: 'documents/',
|
|
165
|
+
continuationToken: list.continuationToken,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Delete a file
|
|
170
|
+
await volume.delete('temp/file.txt');
|
|
171
|
+
|
|
172
|
+
// Delete by prefix (batch delete)
|
|
173
|
+
const deleteResult = await volume.deleteByPrefix('temp/');
|
|
174
|
+
console.log(`Deleted ${deleteResult.deletedCount} files`);
|
|
175
|
+
|
|
176
|
+
// Copy a file
|
|
177
|
+
await volume.copy('source.pdf', 'backup/source.pdf');
|
|
178
|
+
|
|
179
|
+
// Move a file
|
|
180
|
+
await volume.move('temp/upload.pdf', 'documents/final.pdf');
|
|
181
|
+
|
|
182
|
+
// Generate presigned URLs
|
|
183
|
+
const downloadUrl = await volume.generateDownloadUrl('report.pdf', {
|
|
184
|
+
expiresIn: 3600, // 1 hour
|
|
185
|
+
responseContentDisposition: 'attachment; filename="report.pdf"',
|
|
186
|
+
});
|
|
187
|
+
console.log(downloadUrl.url, downloadUrl.expiresAt);
|
|
188
|
+
|
|
189
|
+
const uploadUrl = await volume.generateUploadUrl('uploads/new-file.pdf', {
|
|
190
|
+
expiresIn: 3600,
|
|
191
|
+
contentType: 'application/pdf',
|
|
192
|
+
});
|
|
193
|
+
// Client can PUT directly to uploadUrl.url
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Database Connections
|
|
197
|
+
|
|
198
|
+
Access external databases:
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
const db = await ketrics.databases.connect('main-db');
|
|
202
|
+
if (db) {
|
|
203
|
+
// SELECT query
|
|
204
|
+
const result = await db.query<User>('SELECT * FROM users WHERE id = ?', [userId]);
|
|
205
|
+
console.log(result.rows, result.rowCount);
|
|
206
|
+
|
|
207
|
+
// INSERT/UPDATE/DELETE
|
|
208
|
+
const execResult = await db.execute(
|
|
209
|
+
'INSERT INTO logs (message) VALUES (?)',
|
|
210
|
+
['User logged in']
|
|
211
|
+
);
|
|
212
|
+
console.log(execResult.affectedRows, execResult.insertId);
|
|
213
|
+
|
|
214
|
+
// Transaction
|
|
215
|
+
const transactionResult = await db.transaction(async (tx) => {
|
|
216
|
+
await tx.execute('UPDATE accounts SET balance = balance - ? WHERE id = ?', [100, fromId]);
|
|
217
|
+
await tx.execute('UPDATE accounts SET balance = balance + ? WHERE id = ?', [100, toId]);
|
|
218
|
+
return { success: true };
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// Always close when done
|
|
222
|
+
await db.close();
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Error Handling
|
|
227
|
+
|
|
228
|
+
Error classes are available on the `ketrics` object for `instanceof` checks:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
try {
|
|
232
|
+
const volume = await ketrics.Volume.connect('uploads');
|
|
233
|
+
const file = await volume.get('missing.txt');
|
|
234
|
+
} catch (error) {
|
|
235
|
+
// Error classes are on the ketrics object
|
|
236
|
+
if (error instanceof ketrics.VolumeNotFoundError) {
|
|
237
|
+
console.log(`Volume '${error.volumeCode}' not found`);
|
|
238
|
+
} else if (error instanceof ketrics.VolumeAccessDeniedError) {
|
|
239
|
+
console.log(`No access to volume '${error.volumeCode}'`);
|
|
240
|
+
} else if (error instanceof ketrics.VolumePermissionDeniedError) {
|
|
241
|
+
console.log(`Missing permission: ${error.requiredPermission}`);
|
|
242
|
+
} else if (error instanceof ketrics.FileNotFoundError) {
|
|
243
|
+
console.log(`File '${error.key}' not found`);
|
|
244
|
+
} else if (error instanceof ketrics.FileAlreadyExistsError) {
|
|
245
|
+
console.log(`File '${error.key}' already exists`);
|
|
246
|
+
} else if (error instanceof ketrics.FileSizeLimitError) {
|
|
247
|
+
console.log(`File too large: ${error.size} > ${error.maxSize}`);
|
|
248
|
+
} else if (error instanceof ketrics.ContentTypeNotAllowedError) {
|
|
249
|
+
console.log(`Type '${error.contentType}' not allowed. Use: ${error.allowedTypes.join(', ')}`);
|
|
250
|
+
} else if (error instanceof ketrics.InvalidPathError) {
|
|
251
|
+
console.log(`Invalid path '${error.path}': ${error.reason}`);
|
|
252
|
+
} else if (error instanceof ketrics.VolumeError) {
|
|
253
|
+
// Base class catches all volume errors
|
|
254
|
+
console.log(`Volume error: ${error.message}`);
|
|
255
|
+
console.log(error.toJSON());
|
|
256
|
+
} else {
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Available Error Classes (on `ketrics` object)
|
|
263
|
+
|
|
264
|
+
| Error Class | When Thrown |
|
|
265
|
+
|-------------|-------------|
|
|
266
|
+
| `ketrics.VolumeError` | Base class for all volume errors |
|
|
267
|
+
| `ketrics.VolumeNotFoundError` | Volume doesn't exist |
|
|
268
|
+
| `ketrics.VolumeAccessDeniedError` | Application has no access grant |
|
|
269
|
+
| `ketrics.VolumePermissionDeniedError` | Missing required permission |
|
|
270
|
+
| `ketrics.FileNotFoundError` | File doesn't exist |
|
|
271
|
+
| `ketrics.FileAlreadyExistsError` | File exists (with `ifNotExists` option) |
|
|
272
|
+
| `ketrics.InvalidPathError` | Invalid file path |
|
|
273
|
+
| `ketrics.FileSizeLimitError` | File exceeds size limit |
|
|
274
|
+
| `ketrics.ContentTypeNotAllowedError` | Content type not allowed |
|
|
275
|
+
|
|
276
|
+
## Type Exports
|
|
277
|
+
|
|
278
|
+
All types are exported for use in your application:
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
import type {
|
|
282
|
+
// Context
|
|
283
|
+
TenantContext,
|
|
284
|
+
ApplicationContext,
|
|
285
|
+
UserContext,
|
|
286
|
+
EnvironmentContext,
|
|
287
|
+
|
|
288
|
+
// Console
|
|
289
|
+
ConsoleLogger,
|
|
290
|
+
|
|
291
|
+
// HTTP
|
|
292
|
+
HttpRequestConfig,
|
|
293
|
+
HttpResponse,
|
|
294
|
+
HttpClient,
|
|
295
|
+
|
|
296
|
+
// Volumes
|
|
297
|
+
IVolume,
|
|
298
|
+
PutContent,
|
|
299
|
+
FileContent,
|
|
300
|
+
FileMetadata,
|
|
301
|
+
FileInfo,
|
|
302
|
+
PutOptions,
|
|
303
|
+
PutResult,
|
|
304
|
+
DeleteResult,
|
|
305
|
+
DeleteByPrefixResult,
|
|
306
|
+
ListOptions,
|
|
307
|
+
ListResult,
|
|
308
|
+
CopyOptions,
|
|
309
|
+
CopyResult,
|
|
310
|
+
MoveOptions,
|
|
311
|
+
MoveResult,
|
|
312
|
+
DownloadUrlOptions,
|
|
313
|
+
UploadUrlOptions,
|
|
314
|
+
PresignedUrl,
|
|
315
|
+
|
|
316
|
+
// Databases
|
|
317
|
+
DatabaseManager,
|
|
318
|
+
DatabaseConnection,
|
|
319
|
+
DatabaseQueryResult,
|
|
320
|
+
DatabaseExecuteResult,
|
|
321
|
+
|
|
322
|
+
// Main SDK
|
|
323
|
+
KetricsSdkV1,
|
|
324
|
+
} from '@ketrics/sdk';
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## License
|
|
328
|
+
|
|
329
|
+
MIT
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ketrics SDK - Console Logger Interface
|
|
3
|
+
*
|
|
4
|
+
* Provides type definitions for the console logging functionality
|
|
5
|
+
* that forwards tenant code logs to CloudWatch with proper context.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Console Logger Interface
|
|
9
|
+
*
|
|
10
|
+
* Forwards tenant code logs to CloudWatch with proper context.
|
|
11
|
+
*/
|
|
12
|
+
export interface ConsoleLogger {
|
|
13
|
+
/**
|
|
14
|
+
* Log informational message
|
|
15
|
+
*/
|
|
16
|
+
log(...args: unknown[]): void;
|
|
17
|
+
/**
|
|
18
|
+
* Log error message
|
|
19
|
+
*/
|
|
20
|
+
error(...args: unknown[]): void;
|
|
21
|
+
/**
|
|
22
|
+
* Log warning message
|
|
23
|
+
*/
|
|
24
|
+
warn(...args: unknown[]): void;
|
|
25
|
+
/**
|
|
26
|
+
* Log info message (alias for log)
|
|
27
|
+
*/
|
|
28
|
+
info(...args: unknown[]): void;
|
|
29
|
+
/**
|
|
30
|
+
* Log debug message
|
|
31
|
+
*/
|
|
32
|
+
debug(...args: unknown[]): void;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=console.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAE9B;;OAEG;IACH,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAEhC;;OAEG;IACH,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAE/B;;OAEG;IACH,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAE/B;;OAEG;IACH,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CACjC"}
|
package/dist/console.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Ketrics SDK - Console Logger Interface
|
|
4
|
+
*
|
|
5
|
+
* Provides type definitions for the console logging functionality
|
|
6
|
+
* that forwards tenant code logs to CloudWatch with proper context.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
//# sourceMappingURL=console.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console.js","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ketrics SDK - Context Interfaces
|
|
3
|
+
*
|
|
4
|
+
* Provides type definitions for the execution context available
|
|
5
|
+
* in tenant applications via the global `ketrics` object.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Tenant Context
|
|
9
|
+
*
|
|
10
|
+
* Information about the current tenant.
|
|
11
|
+
*/
|
|
12
|
+
export interface TenantContext {
|
|
13
|
+
/** Tenant UUID */
|
|
14
|
+
id: string;
|
|
15
|
+
/** Tenant code (e.g., "acme-corp") */
|
|
16
|
+
code: string;
|
|
17
|
+
/** Tenant display name */
|
|
18
|
+
name: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Application Context
|
|
22
|
+
*
|
|
23
|
+
* Information about the current application.
|
|
24
|
+
*/
|
|
25
|
+
export interface ApplicationContext {
|
|
26
|
+
/** Application UUID */
|
|
27
|
+
id: string;
|
|
28
|
+
/** Application code (e.g., "inventory", "crm") */
|
|
29
|
+
code: string;
|
|
30
|
+
/** Application display name */
|
|
31
|
+
name: string;
|
|
32
|
+
/** Application version (optional) */
|
|
33
|
+
version?: string;
|
|
34
|
+
/** Current deployment ID */
|
|
35
|
+
deploymentId: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* User Context
|
|
39
|
+
*
|
|
40
|
+
* Information about the user making the request.
|
|
41
|
+
*/
|
|
42
|
+
export interface UserContext {
|
|
43
|
+
/** User UUID */
|
|
44
|
+
id: string;
|
|
45
|
+
/** User email address */
|
|
46
|
+
email: string;
|
|
47
|
+
/** User full name */
|
|
48
|
+
name: string;
|
|
49
|
+
/** Whether user is tenant admin */
|
|
50
|
+
isAdmin: boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Environment Context
|
|
54
|
+
*
|
|
55
|
+
* Information about the runtime environment.
|
|
56
|
+
*/
|
|
57
|
+
export interface EnvironmentContext {
|
|
58
|
+
/** Node.js version (e.g., "18.x") */
|
|
59
|
+
nodeVersion: string;
|
|
60
|
+
/** Runtime platform */
|
|
61
|
+
runtime: 'ecs-fargate';
|
|
62
|
+
/** AWS region (e.g., "us-east-1") */
|
|
63
|
+
region: string;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,gBAAgB;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;CAChB"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Ketrics SDK - Context Interfaces
|
|
4
|
+
*
|
|
5
|
+
* Provides type definitions for the execution context available
|
|
6
|
+
* in tenant applications via the global `ketrics` object.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ketrics SDK - Database Error Classes
|
|
3
|
+
*
|
|
4
|
+
* Provides typed errors for database operations in tenant applications.
|
|
5
|
+
*
|
|
6
|
+
* Error Hierarchy:
|
|
7
|
+
* - DatabaseError (base)
|
|
8
|
+
* - DatabaseNotFoundError
|
|
9
|
+
* - DatabaseAccessDeniedError
|
|
10
|
+
* - DatabaseConnectionError
|
|
11
|
+
* - DatabaseQueryError
|
|
12
|
+
* - DatabaseTransactionError
|
|
13
|
+
*
|
|
14
|
+
* Security Note: Error messages MUST NOT expose internal details like:
|
|
15
|
+
* - Connection strings or credentials
|
|
16
|
+
* - Tenant IDs
|
|
17
|
+
* - Internal database names
|
|
18
|
+
* - AWS account information
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Base error class for all Database errors
|
|
22
|
+
*
|
|
23
|
+
* All Database errors extend this class and include:
|
|
24
|
+
* - databaseCode: The database code that caused the error
|
|
25
|
+
* - operation: The operation that failed
|
|
26
|
+
* - timestamp: When the error occurred
|
|
27
|
+
*/
|
|
28
|
+
export declare abstract class DatabaseError extends Error {
|
|
29
|
+
/** Database code that caused the error */
|
|
30
|
+
readonly databaseCode: string;
|
|
31
|
+
/** Operation that failed */
|
|
32
|
+
readonly operation: string;
|
|
33
|
+
/** When the error occurred */
|
|
34
|
+
readonly timestamp: Date;
|
|
35
|
+
constructor(databaseCode: string, operation: string, message: string);
|
|
36
|
+
/**
|
|
37
|
+
* Serialize error for logging
|
|
38
|
+
*/
|
|
39
|
+
toJSON(): Record<string, unknown>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Error thrown when a database is not found
|
|
43
|
+
*
|
|
44
|
+
* Thrown when DatabaseConnection.connect() is called with a database code
|
|
45
|
+
* that doesn't exist in the tenant's namespace.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* try {
|
|
50
|
+
* const db = await ketrics.DatabaseConnection.connect('unknown-db');
|
|
51
|
+
* } catch (error) {
|
|
52
|
+
* if (error instanceof ketrics.DatabaseNotFoundError) {
|
|
53
|
+
* console.log(`Database '${error.databaseCode}' not found`);
|
|
54
|
+
* }
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare class DatabaseNotFoundError extends DatabaseError {
|
|
59
|
+
constructor(databaseCode: string);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Error thrown when application does not have access to a database
|
|
63
|
+
*
|
|
64
|
+
* Thrown when DatabaseConnection.connect() is called for a database that exists
|
|
65
|
+
* but the executing application has not been granted access.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* try {
|
|
70
|
+
* const db = await ketrics.DatabaseConnection.connect('restricted-db');
|
|
71
|
+
* } catch (error) {
|
|
72
|
+
* if (error instanceof ketrics.DatabaseAccessDeniedError) {
|
|
73
|
+
* console.log(`No access to database '${error.databaseCode}'`);
|
|
74
|
+
* }
|
|
75
|
+
* }
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export declare class DatabaseAccessDeniedError extends DatabaseError {
|
|
79
|
+
constructor(databaseCode: string);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Error thrown when a database connection cannot be established
|
|
83
|
+
*
|
|
84
|
+
* Thrown when the database connection cannot be established due to
|
|
85
|
+
* network issues, authentication failures, or server unavailability.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* try {
|
|
90
|
+
* const db = await ketrics.DatabaseConnection.connect('main-db');
|
|
91
|
+
* } catch (error) {
|
|
92
|
+
* if (error instanceof ketrics.DatabaseConnectionError) {
|
|
93
|
+
* console.log(`Connection failed: ${error.reason}`);
|
|
94
|
+
* }
|
|
95
|
+
* }
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export declare class DatabaseConnectionError extends DatabaseError {
|
|
99
|
+
/** Reason for connection failure */
|
|
100
|
+
readonly reason: string;
|
|
101
|
+
constructor(databaseCode: string, reason: string);
|
|
102
|
+
toJSON(): Record<string, unknown>;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Error thrown when a database query fails
|
|
106
|
+
*
|
|
107
|
+
* Thrown when a SQL query fails to execute due to syntax errors,
|
|
108
|
+
* constraint violations, or other database-level errors.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* try {
|
|
113
|
+
* await db.query('SELECT * FROM nonexistent_table');
|
|
114
|
+
* } catch (error) {
|
|
115
|
+
* if (error instanceof ketrics.DatabaseQueryError) {
|
|
116
|
+
* console.log(`Query failed: ${error.reason}`);
|
|
117
|
+
* }
|
|
118
|
+
* }
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
export declare class DatabaseQueryError extends DatabaseError {
|
|
122
|
+
/** Reason for query failure */
|
|
123
|
+
readonly reason: string;
|
|
124
|
+
/** The SQL that failed (sanitized, max 200 chars) */
|
|
125
|
+
readonly sql?: string;
|
|
126
|
+
constructor(databaseCode: string, reason: string, sql?: string);
|
|
127
|
+
toJSON(): Record<string, unknown>;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Error thrown when a database transaction fails
|
|
131
|
+
*
|
|
132
|
+
* Thrown when a transaction fails to commit or encounters an error
|
|
133
|
+
* during execution that requires rollback.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* try {
|
|
138
|
+
* await db.transaction(async (tx) => {
|
|
139
|
+
* await tx.execute('INSERT INTO users VALUES (...)');
|
|
140
|
+
* throw new Error('Simulated failure');
|
|
141
|
+
* });
|
|
142
|
+
* } catch (error) {
|
|
143
|
+
* if (error instanceof ketrics.DatabaseTransactionError) {
|
|
144
|
+
* console.log(`Transaction failed: ${error.reason}`);
|
|
145
|
+
* console.log(`Rolled back: ${error.rolledBack}`);
|
|
146
|
+
* }
|
|
147
|
+
* }
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
export declare class DatabaseTransactionError extends DatabaseError {
|
|
151
|
+
/** Reason for transaction failure */
|
|
152
|
+
readonly reason: string;
|
|
153
|
+
/** Whether the transaction was rolled back */
|
|
154
|
+
readonly rolledBack: boolean;
|
|
155
|
+
constructor(databaseCode: string, reason: string, rolledBack?: boolean);
|
|
156
|
+
toJSON(): Record<string, unknown>;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Type guard to check if an error is a DatabaseError
|
|
160
|
+
*
|
|
161
|
+
* @param error - The error to check
|
|
162
|
+
* @returns True if the error is a DatabaseError
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```typescript
|
|
166
|
+
* try {
|
|
167
|
+
* const db = await ketrics.DatabaseConnection.connect('main-db');
|
|
168
|
+
* } catch (error) {
|
|
169
|
+
* if (isDatabaseError(error)) {
|
|
170
|
+
* console.log(`Database error: ${error.databaseCode}`);
|
|
171
|
+
* }
|
|
172
|
+
* }
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
export declare function isDatabaseError(error: unknown): error is DatabaseError;
|
|
176
|
+
/**
|
|
177
|
+
* Type guard to check if an error is a specific DatabaseError type
|
|
178
|
+
*
|
|
179
|
+
* @param error - The error to check
|
|
180
|
+
* @param errorClass - The error class to check against
|
|
181
|
+
* @returns True if the error is an instance of the specified class
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```typescript
|
|
185
|
+
* try {
|
|
186
|
+
* const db = await ketrics.DatabaseConnection.connect('main-db');
|
|
187
|
+
* } catch (error) {
|
|
188
|
+
* if (isDatabaseErrorType(error, DatabaseNotFoundError)) {
|
|
189
|
+
* console.log('Database not found');
|
|
190
|
+
* } else if (isDatabaseErrorType(error, DatabaseAccessDeniedError)) {
|
|
191
|
+
* console.log('Access denied');
|
|
192
|
+
* }
|
|
193
|
+
* }
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
export declare function isDatabaseErrorType<T extends DatabaseError>(error: unknown, errorClass: new (...args: never[]) => T): error is T;
|
|
197
|
+
//# sourceMappingURL=database-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-errors.d.ts","sourceRoot":"","sources":["../src/database-errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAMH;;;;;;;GAOG;AACH,8BAAsB,aAAc,SAAQ,KAAK;IAC/C,0CAA0C;IAC1C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B,4BAA4B;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,8BAA8B;IAC9B,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;gBAEb,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAapE;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CASlC;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,qBAAsB,SAAQ,aAAa;gBAC1C,YAAY,EAAE,MAAM;CAGjC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,yBAA0B,SAAQ,aAAa;gBAC9C,YAAY,EAAE,MAAM;CAOjC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,uBAAwB,SAAQ,aAAa;IACxD,oCAAoC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAShD,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAMlC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,kBAAmB,SAAQ,aAAa;IACnD,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,qDAAqD;IACrD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;gBAEV,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM;IAS9D,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAOlC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,wBAAyB,SAAQ,aAAa;IACzD,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,8CAA8C;IAC9C,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;gBAEjB,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAE,OAAc;IAU5E,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAOlC;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAEtE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,aAAa,EACzD,KAAK,EAAE,OAAO,EACd,UAAU,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,GACtC,KAAK,IAAI,CAAC,CAEZ"}
|