@nimbus-cqrs/hono 2.0.0-beta.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/LICENSE +85 -0
  2. package/README.md +26 -0
  3. package/esm/_dnt.shims.d.ts +2 -0
  4. package/esm/_dnt.shims.d.ts.map +1 -0
  5. package/esm/_dnt.shims.js +57 -0
  6. package/esm/deps/jsr.io/@std/fmt/1.0.10/colors.d.ts +700 -0
  7. package/esm/deps/jsr.io/@std/fmt/1.0.10/colors.d.ts.map +1 -0
  8. package/esm/deps/jsr.io/@std/fmt/1.0.10/colors.js +903 -0
  9. package/esm/deps/jsr.io/@std/ulid/1.0.0/_util.d.ts +14 -0
  10. package/esm/deps/jsr.io/@std/ulid/1.0.0/_util.d.ts.map +1 -0
  11. package/esm/deps/jsr.io/@std/ulid/1.0.0/_util.js +65 -0
  12. package/esm/deps/jsr.io/@std/ulid/1.0.0/decode_time.d.ts +20 -0
  13. package/esm/deps/jsr.io/@std/ulid/1.0.0/decode_time.d.ts.map +1 -0
  14. package/esm/deps/jsr.io/@std/ulid/1.0.0/decode_time.js +43 -0
  15. package/esm/deps/jsr.io/@std/ulid/1.0.0/mod.d.ts +44 -0
  16. package/esm/deps/jsr.io/@std/ulid/1.0.0/mod.d.ts.map +1 -0
  17. package/esm/deps/jsr.io/@std/ulid/1.0.0/mod.js +47 -0
  18. package/esm/deps/jsr.io/@std/ulid/1.0.0/monotonic_ulid.d.ts +44 -0
  19. package/esm/deps/jsr.io/@std/ulid/1.0.0/monotonic_ulid.d.ts.map +1 -0
  20. package/esm/deps/jsr.io/@std/ulid/1.0.0/monotonic_ulid.js +51 -0
  21. package/esm/deps/jsr.io/@std/ulid/1.0.0/ulid.d.ts +31 -0
  22. package/esm/deps/jsr.io/@std/ulid/1.0.0/ulid.d.ts.map +1 -0
  23. package/esm/deps/jsr.io/@std/ulid/1.0.0/ulid.js +37 -0
  24. package/esm/index.d.ts +4 -0
  25. package/esm/index.d.ts.map +1 -0
  26. package/esm/index.js +3 -0
  27. package/esm/lib/middleware/correlationId.d.ts +57 -0
  28. package/esm/lib/middleware/correlationId.d.ts.map +1 -0
  29. package/esm/lib/middleware/correlationId.js +76 -0
  30. package/esm/lib/middleware/logger.d.ts +37 -0
  31. package/esm/lib/middleware/logger.d.ts.map +1 -0
  32. package/esm/lib/middleware/logger.js +94 -0
  33. package/esm/lib/onError.d.ts +20 -0
  34. package/esm/lib/onError.d.ts.map +1 -0
  35. package/esm/lib/onError.js +54 -0
  36. package/esm/package.json +3 -0
  37. package/package.json +35 -0
@@ -0,0 +1,94 @@
1
+ import { getLogger } from '../../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
2
+ import { context, propagation, SpanKind, SpanStatusCode, trace, } from '@opentelemetry/api';
3
+ import { getCorrelationId } from './correlationId.js';
4
+ const humanize = (times) => {
5
+ const [delimiter, separator] = [',', '.'];
6
+ const orderTimes = times.map((v) => v.replaceAll(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + delimiter));
7
+ return orderTimes.join(separator);
8
+ };
9
+ const time = (start) => {
10
+ const delta = Date.now() - start;
11
+ return humanize([
12
+ delta < 1000 ? delta + 'ms' : Math.round(delta / 1000) + 's',
13
+ ]);
14
+ };
15
+ /**
16
+ * Logger middleware for Hono with optional OpenTelemetry tracing.
17
+ *
18
+ * When tracing is enabled, the middleware:
19
+ * - Extracts trace context from incoming request headers (traceparent/tracestate)
20
+ * - Creates a server span for the HTTP request
21
+ * - Makes the span active so child spans can be created in handlers
22
+ * - Records HTTP method, path, and status code as span attributes
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * import { Hono } from 'hono';
27
+ * import { logger } from '@nimbus/hono';
28
+ *
29
+ * const app = new Hono();
30
+ * app.use(logger({ enableTracing: true }));
31
+ * ```
32
+ */
33
+ export const logger = (options) => {
34
+ const enableTracing = options?.enableTracing ?? true;
35
+ const tracerName = options?.tracerName ?? 'nimbus';
36
+ const tracer = trace.getTracer(tracerName);
37
+ return async (c, next) => {
38
+ const startTime = Date.now();
39
+ const correlationId = getCorrelationId(c);
40
+ getLogger().info({
41
+ category: 'API',
42
+ message: `REQ: [${c.req.method}] ${c.req.path}`,
43
+ correlationId,
44
+ });
45
+ if (enableTracing) {
46
+ // Extract trace context from incoming headers (traceparent, tracestate)
47
+ const parentContext = propagation.extract(context.active(), c.req.raw.headers, {
48
+ get: (headers, key) => headers.get(key) ?? undefined,
49
+ keys: (headers) => [...headers.keys()],
50
+ });
51
+ // Run the request within the extracted context
52
+ await context.with(parentContext, async () => {
53
+ await tracer.startActiveSpan(`HTTP ${c.req.method} ${c.req.path}`, {
54
+ kind: SpanKind.SERVER,
55
+ attributes: {
56
+ 'http.method': c.req.method,
57
+ 'url.path': c.req.path,
58
+ 'http.target': c.req.url,
59
+ ...(correlationId && {
60
+ correlation_id: correlationId,
61
+ }),
62
+ },
63
+ }, async (span) => {
64
+ try {
65
+ await next();
66
+ span.setAttribute('http.status_code', c.res.status);
67
+ if (c.res.status >= 400) {
68
+ span.setStatus({ code: SpanStatusCode.ERROR });
69
+ }
70
+ }
71
+ catch (err) {
72
+ span.setStatus({
73
+ code: SpanStatusCode.ERROR,
74
+ message: err.message,
75
+ });
76
+ span.recordException(err);
77
+ throw err;
78
+ }
79
+ finally {
80
+ span.end();
81
+ }
82
+ });
83
+ });
84
+ }
85
+ else {
86
+ await next();
87
+ }
88
+ getLogger().info({
89
+ category: 'API',
90
+ message: `RES: [${c.req.method}] ${c.req.path} - ${time(startTime)}`,
91
+ correlationId,
92
+ });
93
+ };
94
+ };
@@ -0,0 +1,20 @@
1
+ import type { Context } from 'hono';
2
+ import type { HTTPResponseError } from 'hono/types';
3
+ /**
4
+ * An error handler for Hono applications that maps
5
+ * Nimbus exceptions to HTTP responses and handles
6
+ * other unhandled errors.
7
+ *
8
+ * @param error - The error to handle.
9
+ * @param c - The Hono context.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import { handleError } from '@nimbus/hono';
14
+ *
15
+ * const app = new Hono();
16
+ * app.onError(handleError);
17
+ * ```
18
+ */
19
+ export declare const handleError: (error: Error | HTTPResponseError, c: Context) => Response;
20
+ //# sourceMappingURL=onError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onError.d.ts","sourceRoot":"","sources":["../../src/lib/onError.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,WAAW,GACpB,OAAO,KAAK,GAAG,iBAAiB,EAChC,GAAG,OAAO,KACX,QAsCF,CAAC"}
@@ -0,0 +1,54 @@
1
+ import { Exception, getLogger } from '../deps/jsr.io/@nimbus/core/2.0.0/src/index.js';
2
+ /**
3
+ * An error handler for Hono applications that maps
4
+ * Nimbus exceptions to HTTP responses and handles
5
+ * other unhandled errors.
6
+ *
7
+ * @param error - The error to handle.
8
+ * @param c - The Hono context.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { handleError } from '@nimbus/hono';
13
+ *
14
+ * const app = new Hono();
15
+ * app.onError(handleError);
16
+ * ```
17
+ */
18
+ export const handleError = (error, c) => {
19
+ let statusCode = 500;
20
+ let response = {
21
+ error: 'INTERNAL_SERVER_ERROR',
22
+ };
23
+ const isNimbusException = error instanceof Exception;
24
+ if (isNimbusException) {
25
+ statusCode = error.statusCode ?? 500;
26
+ response = {
27
+ error: error.name,
28
+ message: error.message,
29
+ ...(error.details && { details: error.details }),
30
+ };
31
+ if (statusCode >= 500) {
32
+ getLogger().error({
33
+ category: 'Nimbus',
34
+ message: error.message,
35
+ error,
36
+ });
37
+ }
38
+ else {
39
+ getLogger().debug({
40
+ category: 'Nimbus',
41
+ message: error.message,
42
+ error,
43
+ });
44
+ }
45
+ }
46
+ else {
47
+ getLogger().critical({
48
+ category: 'Nimbus',
49
+ message: 'An unhandled error occurred',
50
+ error,
51
+ });
52
+ }
53
+ return c.json(response, statusCode);
54
+ };
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@nimbus-cqrs/hono",
3
+ "version": "2.0.0-beta.0",
4
+ "description": "Hono integration for the Nimbus CQRS framework.",
5
+ "author": "Daniel Gördes <d.goerdes@overlap.at> (https://overlap.at)",
6
+ "homepage": "https://nimbus.overlap.at",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/overlap-dev/Nimbus"
10
+ },
11
+ "license": "Apache-2.0",
12
+ "bugs": {
13
+ "url": "https://github.com/overlap-dev/Nimbus/issues"
14
+ },
15
+ "module": "./esm/index.js",
16
+ "exports": {
17
+ ".": {
18
+ "import": "./esm/index.js"
19
+ }
20
+ },
21
+ "scripts": {},
22
+ "engines": {
23
+ "node": ">=20"
24
+ },
25
+ "dependencies": {
26
+ "@opentelemetry/api": "^1.9.1",
27
+ "hono": "^4.12.14",
28
+ "zod": "^4.3.6",
29
+ "@nimbus-cqrs/core": "^2.0.0-beta.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.0.0"
33
+ },
34
+ "_generatedBy": "dnt@dev"
35
+ }