@donkeylabs/server 0.1.3 → 0.1.4

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 (55) hide show
  1. package/examples/starter/node_modules/@donkeylabs/server/README.md +15 -0
  2. package/examples/starter/node_modules/@donkeylabs/server/cli/commands/generate.ts +461 -0
  3. package/examples/starter/node_modules/@donkeylabs/server/cli/commands/init.ts +476 -0
  4. package/examples/starter/node_modules/@donkeylabs/server/cli/commands/interactive.ts +223 -0
  5. package/examples/starter/node_modules/@donkeylabs/server/cli/commands/plugin.ts +192 -0
  6. package/examples/starter/node_modules/@donkeylabs/server/cli/donkeylabs +106 -0
  7. package/examples/starter/node_modules/@donkeylabs/server/cli/index.ts +100 -0
  8. package/examples/starter/node_modules/@donkeylabs/server/context.d.ts +17 -0
  9. package/examples/starter/node_modules/@donkeylabs/server/docs/api-client.md +520 -0
  10. package/examples/starter/node_modules/@donkeylabs/server/docs/cache.md +437 -0
  11. package/examples/starter/node_modules/@donkeylabs/server/docs/cli.md +353 -0
  12. package/examples/starter/node_modules/@donkeylabs/server/docs/core-services.md +338 -0
  13. package/examples/starter/node_modules/@donkeylabs/server/docs/cron.md +465 -0
  14. package/examples/starter/node_modules/@donkeylabs/server/docs/errors.md +303 -0
  15. package/examples/starter/node_modules/@donkeylabs/server/docs/events.md +460 -0
  16. package/examples/starter/node_modules/@donkeylabs/server/docs/handlers.md +549 -0
  17. package/examples/starter/node_modules/@donkeylabs/server/docs/jobs.md +556 -0
  18. package/examples/starter/node_modules/@donkeylabs/server/docs/logger.md +316 -0
  19. package/examples/starter/node_modules/@donkeylabs/server/docs/middleware.md +682 -0
  20. package/examples/starter/node_modules/@donkeylabs/server/docs/plugins.md +524 -0
  21. package/examples/starter/node_modules/@donkeylabs/server/docs/project-structure.md +493 -0
  22. package/examples/starter/node_modules/@donkeylabs/server/docs/rate-limiter.md +525 -0
  23. package/examples/starter/node_modules/@donkeylabs/server/docs/router.md +566 -0
  24. package/examples/starter/node_modules/@donkeylabs/server/docs/sse.md +542 -0
  25. package/examples/starter/node_modules/@donkeylabs/server/docs/svelte-frontend.md +324 -0
  26. package/examples/starter/node_modules/@donkeylabs/server/mcp/donkeylabs-mcp +3238 -0
  27. package/examples/starter/node_modules/@donkeylabs/server/mcp/server.ts +3238 -0
  28. package/examples/starter/node_modules/@donkeylabs/server/package.json +77 -0
  29. package/examples/starter/node_modules/@donkeylabs/server/registry.d.ts +11 -0
  30. package/examples/starter/node_modules/@donkeylabs/server/src/client/base.ts +481 -0
  31. package/examples/starter/node_modules/@donkeylabs/server/src/client/index.ts +150 -0
  32. package/examples/starter/node_modules/@donkeylabs/server/src/core/cache.ts +183 -0
  33. package/examples/starter/node_modules/@donkeylabs/server/src/core/cron.ts +255 -0
  34. package/examples/starter/node_modules/@donkeylabs/server/src/core/errors.ts +320 -0
  35. package/examples/starter/node_modules/@donkeylabs/server/src/core/events.ts +163 -0
  36. package/examples/starter/node_modules/@donkeylabs/server/src/core/index.ts +94 -0
  37. package/examples/starter/node_modules/@donkeylabs/server/src/core/jobs.ts +334 -0
  38. package/examples/starter/node_modules/@donkeylabs/server/src/core/logger.ts +131 -0
  39. package/examples/starter/node_modules/@donkeylabs/server/src/core/rate-limiter.ts +193 -0
  40. package/examples/starter/node_modules/@donkeylabs/server/src/core/sse.ts +210 -0
  41. package/examples/starter/node_modules/@donkeylabs/server/src/core.ts +428 -0
  42. package/examples/starter/node_modules/@donkeylabs/server/src/handlers.ts +87 -0
  43. package/examples/starter/node_modules/@donkeylabs/server/src/harness.ts +70 -0
  44. package/examples/starter/node_modules/@donkeylabs/server/src/index.ts +38 -0
  45. package/examples/starter/node_modules/@donkeylabs/server/src/middleware.ts +34 -0
  46. package/examples/starter/node_modules/@donkeylabs/server/src/registry.ts +13 -0
  47. package/examples/starter/node_modules/@donkeylabs/server/src/router.ts +155 -0
  48. package/examples/starter/node_modules/@donkeylabs/server/src/server.ts +234 -0
  49. package/examples/starter/node_modules/@donkeylabs/server/templates/init/donkeylabs.config.ts.template +14 -0
  50. package/examples/starter/node_modules/@donkeylabs/server/templates/init/index.ts.template +41 -0
  51. package/examples/starter/node_modules/@donkeylabs/server/templates/plugin/index.ts.template +25 -0
  52. package/examples/starter/src/routes/health/ping/models/model.ts +11 -7
  53. package/package.json +3 -3
  54. package/examples/starter/node_modules/.svelte2tsx-language-server-files/svelte-native-jsx.d.ts +0 -32
  55. package/examples/starter/node_modules/.svelte2tsx-language-server-files/svelte-shims-v4.d.ts +0 -290
@@ -0,0 +1,316 @@
1
+ # Logger Service
2
+
3
+ Structured logging with configurable levels, custom transports, and child loggers for contextual logging.
4
+
5
+ ## Quick Start
6
+
7
+ ```ts
8
+ // Access via ctx.core.logger
9
+ ctx.core.logger.info("User logged in", { userId: 123 });
10
+ ctx.core.logger.error("Payment failed", { orderId: 456, error: "Insufficient funds" });
11
+ ```
12
+
13
+ ---
14
+
15
+ ## API Reference
16
+
17
+ ### Interface
18
+
19
+ ```ts
20
+ interface Logger {
21
+ debug(message: string, data?: Record<string, any>): void;
22
+ info(message: string, data?: Record<string, any>): void;
23
+ warn(message: string, data?: Record<string, any>): void;
24
+ error(message: string, data?: Record<string, any>): void;
25
+ child(context: Record<string, any>): Logger;
26
+ }
27
+ ```
28
+
29
+ ### Log Levels
30
+
31
+ | Level | Priority | Use Case |
32
+ |-------|----------|----------|
33
+ | `debug` | 0 | Detailed debugging information |
34
+ | `info` | 1 | General operational messages |
35
+ | `warn` | 2 | Warning conditions |
36
+ | `error` | 3 | Error conditions |
37
+
38
+ Only messages at or above the configured level are logged.
39
+
40
+ ---
41
+
42
+ ## Configuration
43
+
44
+ ```ts
45
+ const server = new AppServer({
46
+ db,
47
+ logger: {
48
+ level: "info", // Minimum level to log (default: "info")
49
+ format: "pretty", // "pretty" or "json" (default: "pretty")
50
+ transports: [], // Custom transports (optional)
51
+ },
52
+ });
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Usage Examples
58
+
59
+ ### Basic Logging
60
+
61
+ ```ts
62
+ router.route("checkout").typed({
63
+ handle: async (input, ctx) => {
64
+ ctx.core.logger.info("Checkout started", {
65
+ userId: ctx.user.id,
66
+ cartTotal: input.total,
67
+ });
68
+
69
+ try {
70
+ const order = await processPayment(input);
71
+ ctx.core.logger.info("Payment successful", { orderId: order.id });
72
+ return order;
73
+ } catch (error) {
74
+ ctx.core.logger.error("Payment failed", {
75
+ userId: ctx.user.id,
76
+ error: error.message,
77
+ });
78
+ throw error;
79
+ }
80
+ },
81
+ });
82
+ ```
83
+
84
+ ### Child Loggers
85
+
86
+ Child loggers inherit parent settings and add persistent context:
87
+
88
+ ```ts
89
+ // In plugin initialization
90
+ service: async (ctx) => {
91
+ // Create logger with plugin context
92
+ const log = ctx.core.logger.child({ plugin: "payments" });
93
+
94
+ return {
95
+ async processPayment(orderId: string) {
96
+ // Create request-specific logger
97
+ const requestLog = log.child({ orderId });
98
+
99
+ requestLog.info("Processing payment");
100
+ // Logs: { plugin: "payments", orderId: "123", ... }
101
+
102
+ requestLog.debug("Validating card");
103
+ requestLog.info("Payment complete");
104
+ },
105
+ };
106
+ };
107
+ ```
108
+
109
+ ### Request Logging Middleware
110
+
111
+ ```ts
112
+ const requestLogger = createMiddleware(async (req, ctx, next) => {
113
+ const start = Date.now();
114
+ const requestId = ctx.requestId;
115
+
116
+ // Create request-scoped logger
117
+ const log = ctx.core.logger.child({
118
+ requestId,
119
+ method: req.method,
120
+ path: new URL(req.url).pathname,
121
+ ip: ctx.ip,
122
+ });
123
+
124
+ log.info("Request started");
125
+
126
+ try {
127
+ const response = await next();
128
+ log.info("Request completed", {
129
+ status: response.status,
130
+ duration: Date.now() - start,
131
+ });
132
+ return response;
133
+ } catch (error) {
134
+ log.error("Request failed", {
135
+ error: error.message,
136
+ duration: Date.now() - start,
137
+ });
138
+ throw error;
139
+ }
140
+ });
141
+ ```
142
+
143
+ ---
144
+
145
+ ## Output Formats
146
+
147
+ ### Pretty Format (Default)
148
+
149
+ Human-readable colored output for development:
150
+
151
+ ```
152
+ [12:34:56.789] INFO User logged in {"userId":123}
153
+ [12:34:56.790] ERROR Payment failed {"orderId":456,"error":"Insufficient funds"}
154
+ ```
155
+
156
+ ### JSON Format
157
+
158
+ Structured JSON for production log aggregation:
159
+
160
+ ```json
161
+ {"timestamp":"2024-01-15T12:34:56.789Z","level":"info","message":"User logged in","userId":123}
162
+ {"timestamp":"2024-01-15T12:34:56.790Z","level":"error","message":"Payment failed","orderId":456,"error":"Insufficient funds"}
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Custom Transports
168
+
169
+ Create custom transports to send logs to external services:
170
+
171
+ ```ts
172
+ import { createLogger, type LogTransport, type LogEntry } from "./core/logger";
173
+
174
+ // Custom transport for external service
175
+ class DatadogTransport implements LogTransport {
176
+ constructor(private apiKey: string) {}
177
+
178
+ log(entry: LogEntry): void {
179
+ fetch("https://http-intake.logs.datadoghq.com/v1/input", {
180
+ method: "POST",
181
+ headers: {
182
+ "Content-Type": "application/json",
183
+ "DD-API-KEY": this.apiKey,
184
+ },
185
+ body: JSON.stringify({
186
+ timestamp: entry.timestamp.toISOString(),
187
+ level: entry.level,
188
+ message: entry.message,
189
+ ...entry.data,
190
+ ...entry.context,
191
+ }),
192
+ });
193
+ }
194
+ }
195
+
196
+ // File transport
197
+ class FileTransport implements LogTransport {
198
+ constructor(private filePath: string) {}
199
+
200
+ log(entry: LogEntry): void {
201
+ const line = JSON.stringify({
202
+ timestamp: entry.timestamp.toISOString(),
203
+ level: entry.level,
204
+ message: entry.message,
205
+ ...entry.data,
206
+ ...entry.context,
207
+ }) + "\n";
208
+
209
+ Bun.write(this.filePath, line, { append: true });
210
+ }
211
+ }
212
+
213
+ // Use custom transports
214
+ const logger = createLogger({
215
+ level: "info",
216
+ transports: [
217
+ new ConsoleTransport("pretty"),
218
+ new DatadogTransport(process.env.DD_API_KEY!),
219
+ new FileTransport("./logs/app.log"),
220
+ ],
221
+ });
222
+ ```
223
+
224
+ ---
225
+
226
+ ## Best Practices
227
+
228
+ ### 1. Use Appropriate Levels
229
+
230
+ ```ts
231
+ // Debug - detailed technical info (disabled in production)
232
+ log.debug("Cache lookup", { key, hit: !!cached });
233
+
234
+ // Info - notable events
235
+ log.info("Order created", { orderId, total });
236
+
237
+ // Warn - unexpected but handled conditions
238
+ log.warn("Retry attempt", { attempt: 3, maxAttempts: 5 });
239
+
240
+ // Error - failures requiring attention
241
+ log.error("Database connection lost", { error: err.message });
242
+ ```
243
+
244
+ ### 2. Include Relevant Context
245
+
246
+ ```ts
247
+ // Bad - missing context
248
+ log.error("Failed");
249
+
250
+ // Good - actionable information
251
+ log.error("Payment processing failed", {
252
+ userId: user.id,
253
+ orderId: order.id,
254
+ amount: order.total,
255
+ provider: "stripe",
256
+ error: err.message,
257
+ errorCode: err.code,
258
+ });
259
+ ```
260
+
261
+ ### 3. Use Child Loggers for Scopes
262
+
263
+ ```ts
264
+ // Create scoped loggers for different concerns
265
+ const dbLog = logger.child({ component: "database" });
266
+ const authLog = logger.child({ component: "auth" });
267
+ const apiLog = logger.child({ component: "api" });
268
+
269
+ // Each log includes its scope
270
+ dbLog.info("Query executed"); // includes component: "database"
271
+ authLog.info("Token validated"); // includes component: "auth"
272
+ ```
273
+
274
+ ### 4. Don't Log Sensitive Data
275
+
276
+ ```ts
277
+ // Bad - exposes password
278
+ log.info("Login attempt", { email, password });
279
+
280
+ // Good - redact sensitive fields
281
+ log.info("Login attempt", { email, passwordProvided: !!password });
282
+
283
+ // Bad - exposes token
284
+ log.debug("Auth header", { authorization: req.headers.get("authorization") });
285
+
286
+ // Good - mask token
287
+ log.debug("Auth header present", { hasAuth: !!req.headers.get("authorization") });
288
+ ```
289
+
290
+ ---
291
+
292
+ ## LogEntry Structure
293
+
294
+ ```ts
295
+ interface LogEntry {
296
+ timestamp: Date;
297
+ level: "debug" | "info" | "warn" | "error";
298
+ message: string;
299
+ data?: Record<string, any>; // Per-call data
300
+ context?: Record<string, any>; // From child logger
301
+ }
302
+ ```
303
+
304
+ ---
305
+
306
+ ## Environment-Based Configuration
307
+
308
+ ```ts
309
+ const server = new AppServer({
310
+ db,
311
+ logger: {
312
+ level: process.env.NODE_ENV === "production" ? "info" : "debug",
313
+ format: process.env.NODE_ENV === "production" ? "json" : "pretty",
314
+ },
315
+ });
316
+ ```