@event-driven-io/emmett-fastify 0.43.0-rc.1 → 0.43.0-rc.3

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/dist/index.cjs CHANGED
@@ -38,6 +38,12 @@ let fastify = require("fastify");
38
38
  fastify = __toESM(fastify, 1);
39
39
  let _opentelemetry_api = require("@opentelemetry/api");
40
40
 
41
+ // src/problemDetailsErrorHandler.ts
42
+ const problemDetailsErrorHandler = (mapError) => (error, request, reply) => {
43
+ const problemDetails = mapError?.(error, request) ?? (0, _event_driven_io_emmett.defaultErrorToProblemDetailsMapping)(error);
44
+ return reply.status(problemDetails.status).header("Content-Type", "application/problem+json").send(problemDetails);
45
+ };
46
+
41
47
  // src/traceIdHook.ts
42
48
  const traceIdHook = (_request, reply, done) => {
43
49
  const traceId = _opentelemetry_api.trace.getSpan(_opentelemetry_api.context.active())?.spanContext().traceId;
@@ -61,12 +67,13 @@ const defaultPlugins = [
61
67
  }
62
68
  ];
63
69
  const getApplication = async (options) => {
64
- const { registerRoutes, activeDefaultPlugins = defaultPlugins, serverOptions, observability, disableTraceIdHeader } = options;
70
+ const { registerRoutes, activeDefaultPlugins = defaultPlugins, serverOptions, observability, disableTraceIdHeader, mapError } = options;
65
71
  const app = (0, fastify.default)(serverOptions);
66
72
  if ((observability !== void 0 || (0, _event_driven_io_emmett.currentDefaultObservability)() !== void 0) && disableTraceIdHeader !== true) app.addHook("onRequest", traceIdHook);
67
73
  await Promise.all(activeDefaultPlugins.map(async ({ plugin, options }) => {
68
74
  await app.register(plugin, options);
69
75
  }));
76
+ if (mapError) app.setErrorHandler(problemDetailsErrorHandler(mapError));
70
77
  if (registerRoutes) registerRoutes(app);
71
78
  const closeListeners = (0, close_with_grace.default)({ delay: 500 }, async (opts) => {
72
79
  if (opts.err) app.log.error(opts.err);
@@ -89,6 +96,7 @@ const startAPI = async (app, options = { port: 5e3 }) => {
89
96
  };
90
97
 
91
98
  exports.getApplication = getApplication;
99
+ exports.problemDetailsErrorHandler = problemDetailsErrorHandler;
92
100
  exports.startAPI = startAPI;
93
101
  exports.traceIdHook = traceIdHook;
94
102
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["trace","context","Etag","Compress","Form","Fastify","currentDefaultObservability","closeWithGrace"],"sources":["../src/traceIdHook.ts","../src/index.ts"],"sourcesContent":["import { context, trace } from '@opentelemetry/api';\nimport type { onRequestHookHandler } from 'fastify';\n\nexport const traceIdHook: onRequestHookHandler = (_request, reply, done) => {\n const traceId = trace.getSpan(context.active())?.spanContext().traceId;\n if (traceId) void reply.header('x-trace-id', traceId);\n done();\n};\n","import Compress from '@fastify/compress';\nimport Etag from '@fastify/etag';\nimport Form from '@fastify/formbody';\nimport {\n currentDefaultObservability,\n type Observability,\n} from '@event-driven-io/emmett';\nimport closeWithGrace from 'close-with-grace';\nimport Fastify, {\n type FastifyInstance,\n type FastifyPluginAsync,\n type FastifyPluginCallback,\n type FastifyPluginOptions,\n type FastifyServerOptions,\n} from 'fastify';\nimport { traceIdHook } from './traceIdHook';\n\nexport * from './traceIdHook';\n\n// TODO: THIS WILL NEED TO BE BETTER TYPED\ntype Plugin = {\n plugin: FastifyPluginAsync | FastifyPluginCallback;\n options: FastifyPluginOptions;\n};\n\nconst defaultPlugins: Plugin[] = [\n { plugin: Etag, options: {} },\n { plugin: Compress, options: { global: false } },\n { plugin: Form, options: {} },\n];\n\nexport interface ApplicationOptions {\n serverOptions?: FastifyServerOptions;\n registerRoutes?: (app: FastifyInstance) => void;\n activeDefaultPlugins?: Plugin[];\n observability?: Partial<Observability<string>>;\n disableTraceIdHeader?: boolean;\n}\n\nexport const getApplication = async (options: ApplicationOptions) => {\n const {\n registerRoutes,\n activeDefaultPlugins = defaultPlugins,\n serverOptions,\n observability,\n disableTraceIdHeader,\n } = options;\n\n const app: FastifyInstance = Fastify(serverOptions);\n\n const isObservabilityRegistered =\n observability !== undefined || currentDefaultObservability() !== undefined;\n\n if (isObservabilityRegistered && disableTraceIdHeader !== true)\n app.addHook('onRequest', traceIdHook);\n\n await Promise.all(\n activeDefaultPlugins.map(async ({ plugin, options }) => {\n await app.register(plugin, options);\n }),\n );\n\n if (registerRoutes) {\n registerRoutes(app);\n }\n\n const closeListeners = closeWithGrace({ delay: 500 }, async (opts) => {\n if (opts.err) {\n app.log.error(opts.err);\n }\n\n await app.close();\n });\n\n app.addHook('onClose', (instance, done) => {\n closeListeners.uninstall();\n done();\n });\n\n return app;\n};\n\nexport type StartApiOptions = {\n port?: number;\n};\n\nexport const startAPI = async (\n app: FastifyInstance,\n options: StartApiOptions = { port: 5000 },\n) => {\n const { port } = options;\n try {\n await app.listen({ port });\n } catch (err) {\n app.log.error(err);\n process.exit(1);\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,MAAa,eAAqC,UAAU,OAAO,SAAS;CAC1E,MAAM,UAAUA,yBAAM,QAAQC,2BAAQ,OAAO,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;CAC/D,IAAI,SAAS,AAAK,MAAM,OAAO,cAAc,OAAO;CACpD,KAAK;AACP;;;ACkBA,MAAM,iBAA2B;CAC/B;EAAE,QAAQC;EAAM,SAAS,CAAC;CAAE;CAC5B;EAAE,QAAQC;EAAU,SAAS,EAAE,QAAQ,MAAM;CAAE;CAC/C;EAAE,QAAQC;EAAM,SAAS,CAAC;CAAE;AAC9B;AAUA,MAAa,iBAAiB,OAAO,YAAgC;CACnE,MAAM,EACJ,gBACA,uBAAuB,gBACvB,eACA,eACA,yBACE;CAEJ,MAAM,UAAuBC,iBAAQ,aAAa;CAKlD,KAFE,kBAAkB,cAAaC,qDAA4B,MAAM,WAElC,yBAAyB,MACxD,IAAI,QAAQ,aAAa,WAAW;CAEtC,MAAM,QAAQ,IACZ,qBAAqB,IAAI,OAAO,EAAE,QAAQ,cAAc;EACtD,MAAM,IAAI,SAAS,QAAQ,OAAO;CACpC,CAAC,CACH;CAEA,IAAI,gBACF,eAAe,GAAG;CAGpB,MAAM,qBAAiBC,0BAAe,EAAE,OAAO,IAAI,GAAG,OAAO,SAAS;EACpE,IAAI,KAAK,KACP,IAAI,IAAI,MAAM,KAAK,GAAG;EAGxB,MAAM,IAAI,MAAM;CAClB,CAAC;CAED,IAAI,QAAQ,YAAY,UAAU,SAAS;EACzC,eAAe,UAAU;EACzB,KAAK;CACP,CAAC;CAED,OAAO;AACT;AAMA,MAAa,WAAW,OACtB,KACA,UAA2B,EAAE,MAAM,IAAK,MACrC;CACH,MAAM,EAAE,SAAS;CACjB,IAAI;EACF,MAAM,IAAI,OAAO,EAAE,KAAK,CAAC;CAC3B,SAAS,KAAK;EACZ,IAAI,IAAI,MAAM,GAAG;EACjB,QAAQ,KAAK,CAAC;CAChB;AACF"}
1
+ {"version":3,"file":"index.cjs","names":["defaultErrorToProblemDetailsMapping","trace","context","Etag","Compress","Form","Fastify","currentDefaultObservability","closeWithGrace"],"sources":["../src/problemDetailsErrorHandler.ts","../src/traceIdHook.ts","../src/index.ts"],"sourcesContent":["import {\n defaultErrorToProblemDetailsMapping,\n type ProblemDocument,\n} from '@event-driven-io/emmett';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\n\nexport type ErrorToProblemDetailsMapping = (\n error: unknown,\n request: FastifyRequest,\n) => ProblemDocument | undefined;\n\nexport const problemDetailsErrorHandler =\n (mapError?: ErrorToProblemDetailsMapping) =>\n (error: unknown, request: FastifyRequest, reply: FastifyReply) => {\n const problemDetails =\n mapError?.(error, request) ?? defaultErrorToProblemDetailsMapping(error);\n\n return reply\n .status(problemDetails.status)\n .header('Content-Type', 'application/problem+json')\n .send(problemDetails);\n };\n","import { context, trace } from '@opentelemetry/api';\nimport type { onRequestHookHandler } from 'fastify';\n\nexport const traceIdHook: onRequestHookHandler = (_request, reply, done) => {\n const traceId = trace.getSpan(context.active())?.spanContext().traceId;\n if (traceId) void reply.header('x-trace-id', traceId);\n done();\n};\n","import Compress from '@fastify/compress';\nimport Etag from '@fastify/etag';\nimport Form from '@fastify/formbody';\nimport {\n currentDefaultObservability,\n type Observability,\n} from '@event-driven-io/emmett';\nimport closeWithGrace from 'close-with-grace';\nimport Fastify, {\n type FastifyInstance,\n type FastifyPluginAsync,\n type FastifyPluginCallback,\n type FastifyPluginOptions,\n type FastifyServerOptions,\n} from 'fastify';\nimport {\n problemDetailsErrorHandler,\n type ErrorToProblemDetailsMapping,\n} from './problemDetailsErrorHandler';\nimport { traceIdHook } from './traceIdHook';\n\nexport * from './problemDetailsErrorHandler';\nexport * from './traceIdHook';\n\n// TODO: THIS WILL NEED TO BE BETTER TYPED\ntype Plugin = {\n plugin: FastifyPluginAsync | FastifyPluginCallback;\n options: FastifyPluginOptions;\n};\n\nconst defaultPlugins: Plugin[] = [\n { plugin: Etag, options: {} },\n { plugin: Compress, options: { global: false } },\n { plugin: Form, options: {} },\n];\n\nexport interface ApplicationOptions {\n serverOptions?: FastifyServerOptions;\n registerRoutes?: (app: FastifyInstance) => void;\n activeDefaultPlugins?: Plugin[];\n observability?: Partial<Observability<string>>;\n disableTraceIdHeader?: boolean;\n mapError?: ErrorToProblemDetailsMapping;\n}\n\nexport const getApplication = async (options: ApplicationOptions) => {\n const {\n registerRoutes,\n activeDefaultPlugins = defaultPlugins,\n serverOptions,\n observability,\n disableTraceIdHeader,\n mapError,\n } = options;\n\n const app: FastifyInstance = Fastify(serverOptions);\n\n const isObservabilityRegistered =\n observability !== undefined || currentDefaultObservability() !== undefined;\n\n if (isObservabilityRegistered && disableTraceIdHeader !== true)\n app.addHook('onRequest', traceIdHook);\n\n await Promise.all(\n activeDefaultPlugins.map(async ({ plugin, options }) => {\n await app.register(plugin, options);\n }),\n );\n\n if (mapError) app.setErrorHandler(problemDetailsErrorHandler(mapError));\n\n if (registerRoutes) {\n registerRoutes(app);\n }\n\n const closeListeners = closeWithGrace({ delay: 500 }, async (opts) => {\n if (opts.err) {\n app.log.error(opts.err);\n }\n\n await app.close();\n });\n\n app.addHook('onClose', (instance, done) => {\n closeListeners.uninstall();\n done();\n });\n\n return app;\n};\n\nexport type StartApiOptions = {\n port?: number;\n};\n\nexport const startAPI = async (\n app: FastifyInstance,\n options: StartApiOptions = { port: 5000 },\n) => {\n const { port } = options;\n try {\n await app.listen({ port });\n } catch (err) {\n app.log.error(err);\n process.exit(1);\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,MAAa,8BACV,cACA,OAAgB,SAAyB,UAAwB;CAChE,MAAM,iBACJ,WAAW,OAAO,OAAO,SAAKA,6DAAoC,KAAK;CAEzE,OAAO,MACJ,OAAO,eAAe,MAAM,CAAC,CAC7B,OAAO,gBAAgB,0BAA0B,CAAC,CAClD,KAAK,cAAc;AACxB;;;AClBF,MAAa,eAAqC,UAAU,OAAO,SAAS;CAC1E,MAAM,UAAUC,yBAAM,QAAQC,2BAAQ,OAAO,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;CAC/D,IAAI,SAAS,AAAK,MAAM,OAAO,cAAc,OAAO;CACpD,KAAK;AACP;;;ACuBA,MAAM,iBAA2B;CAC/B;EAAE,QAAQC;EAAM,SAAS,CAAC;CAAE;CAC5B;EAAE,QAAQC;EAAU,SAAS,EAAE,QAAQ,MAAM;CAAE;CAC/C;EAAE,QAAQC;EAAM,SAAS,CAAC;CAAE;AAC9B;AAWA,MAAa,iBAAiB,OAAO,YAAgC;CACnE,MAAM,EACJ,gBACA,uBAAuB,gBACvB,eACA,eACA,sBACA,aACE;CAEJ,MAAM,UAAuBC,iBAAQ,aAAa;CAKlD,KAFE,kBAAkB,cAAaC,qDAA4B,MAAM,WAElC,yBAAyB,MACxD,IAAI,QAAQ,aAAa,WAAW;CAEtC,MAAM,QAAQ,IACZ,qBAAqB,IAAI,OAAO,EAAE,QAAQ,cAAc;EACtD,MAAM,IAAI,SAAS,QAAQ,OAAO;CACpC,CAAC,CACH;CAEA,IAAI,UAAU,IAAI,gBAAgB,2BAA2B,QAAQ,CAAC;CAEtE,IAAI,gBACF,eAAe,GAAG;CAGpB,MAAM,qBAAiBC,0BAAe,EAAE,OAAO,IAAI,GAAG,OAAO,SAAS;EACpE,IAAI,KAAK,KACP,IAAI,IAAI,MAAM,KAAK,GAAG;EAGxB,MAAM,IAAI,MAAM;CAClB,CAAC;CAED,IAAI,QAAQ,YAAY,UAAU,SAAS;EACzC,eAAe,UAAU;EACzB,KAAK;CACP,CAAC;CAED,OAAO;AACT;AAMA,MAAa,WAAW,OACtB,KACA,UAA2B,EAAE,MAAM,IAAK,MACrC;CACH,MAAM,EAAE,SAAS;CACjB,IAAI;EACF,MAAM,IAAI,OAAO,EAAE,KAAK,CAAC;CAC3B,SAAS,KAAK;EACZ,IAAI,IAAI,MAAM,GAAG;EACjB,QAAQ,KAAK,CAAC;CAChB;AACF"}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,7 @@
1
- import { Observability } from "@event-driven-io/emmett";
2
- import { FastifyInstance, FastifyPluginAsync, FastifyPluginCallback, FastifyPluginOptions, FastifyServerOptions, onRequestHookHandler } from "fastify";
1
+ import { Observability, ProblemDocument } from "@event-driven-io/emmett";
2
+ import { FastifyInstance, FastifyPluginAsync, FastifyPluginCallback, FastifyPluginOptions, FastifyReply, FastifyRequest, FastifyServerOptions, onRequestHookHandler } from "fastify";
3
+ export type ErrorToProblemDetailsMapping = (error: unknown, request: FastifyRequest) => ProblemDocument | undefined;
4
+ export declare const problemDetailsErrorHandler: (mapError?: ErrorToProblemDetailsMapping) => (error: unknown, request: FastifyRequest, reply: FastifyReply) => FastifyReply<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, unknown, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown>;
3
5
  export declare const traceIdHook: onRequestHookHandler;
4
6
  type Plugin = {
5
7
  plugin: FastifyPluginAsync | FastifyPluginCallback;
@@ -11,6 +13,7 @@ export interface ApplicationOptions {
11
13
  activeDefaultPlugins?: Plugin[];
12
14
  observability?: Partial<Observability<string>>;
13
15
  disableTraceIdHeader?: boolean;
16
+ mapError?: ErrorToProblemDetailsMapping;
14
17
  }
15
18
  export declare const getApplication: (options: ApplicationOptions) => Promise<FastifyInstance<import("fastify").RawServerDefault, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault>>;
16
19
  export type StartApiOptions = {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { Observability } from "@event-driven-io/emmett";
2
- import { FastifyInstance, FastifyPluginAsync, FastifyPluginCallback, FastifyPluginOptions, FastifyServerOptions, onRequestHookHandler } from "fastify";
1
+ import { Observability, ProblemDocument } from "@event-driven-io/emmett";
2
+ import { FastifyInstance, FastifyPluginAsync, FastifyPluginCallback, FastifyPluginOptions, FastifyReply, FastifyRequest, FastifyServerOptions, onRequestHookHandler } from "fastify";
3
+ export type ErrorToProblemDetailsMapping = (error: unknown, request: FastifyRequest) => ProblemDocument | undefined;
4
+ export declare const problemDetailsErrorHandler: (mapError?: ErrorToProblemDetailsMapping) => (error: unknown, request: FastifyRequest, reply: FastifyReply) => FastifyReply<import("fastify").RouteGenericInterface, import("fastify").RawServerDefault, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, unknown, import("fastify").FastifySchema, import("fastify").FastifyTypeProviderDefault, unknown>;
3
5
  export declare const traceIdHook: onRequestHookHandler;
4
6
  type Plugin = {
5
7
  plugin: FastifyPluginAsync | FastifyPluginCallback;
@@ -11,6 +13,7 @@ export interface ApplicationOptions {
11
13
  activeDefaultPlugins?: Plugin[];
12
14
  observability?: Partial<Observability<string>>;
13
15
  disableTraceIdHeader?: boolean;
16
+ mapError?: ErrorToProblemDetailsMapping;
14
17
  }
15
18
  export declare const getApplication: (options: ApplicationOptions) => Promise<FastifyInstance<import("fastify").RawServerDefault, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault>>;
16
19
  export type StartApiOptions = {
package/dist/index.js CHANGED
@@ -1,11 +1,17 @@
1
1
  import Compress from "@fastify/compress";
2
2
  import Etag from "@fastify/etag";
3
3
  import Form from "@fastify/formbody";
4
- import { currentDefaultObservability } from "@event-driven-io/emmett";
4
+ import { currentDefaultObservability, defaultErrorToProblemDetailsMapping } from "@event-driven-io/emmett";
5
5
  import closeWithGrace from "close-with-grace";
6
6
  import Fastify from "fastify";
7
7
  import { context, trace } from "@opentelemetry/api";
8
8
 
9
+ // src/problemDetailsErrorHandler.ts
10
+ const problemDetailsErrorHandler = (mapError) => (error, request, reply) => {
11
+ const problemDetails = mapError?.(error, request) ?? defaultErrorToProblemDetailsMapping(error);
12
+ return reply.status(problemDetails.status).header("Content-Type", "application/problem+json").send(problemDetails);
13
+ };
14
+
9
15
  // src/traceIdHook.ts
10
16
  const traceIdHook = (_request, reply, done) => {
11
17
  const traceId = trace.getSpan(context.active())?.spanContext().traceId;
@@ -29,12 +35,13 @@ const defaultPlugins = [
29
35
  }
30
36
  ];
31
37
  const getApplication = async (options) => {
32
- const { registerRoutes, activeDefaultPlugins = defaultPlugins, serverOptions, observability, disableTraceIdHeader } = options;
38
+ const { registerRoutes, activeDefaultPlugins = defaultPlugins, serverOptions, observability, disableTraceIdHeader, mapError } = options;
33
39
  const app = Fastify(serverOptions);
34
40
  if ((observability !== void 0 || currentDefaultObservability() !== void 0) && disableTraceIdHeader !== true) app.addHook("onRequest", traceIdHook);
35
41
  await Promise.all(activeDefaultPlugins.map(async ({ plugin, options }) => {
36
42
  await app.register(plugin, options);
37
43
  }));
44
+ if (mapError) app.setErrorHandler(problemDetailsErrorHandler(mapError));
38
45
  if (registerRoutes) registerRoutes(app);
39
46
  const closeListeners = closeWithGrace({ delay: 500 }, async (opts) => {
40
47
  if (opts.err) app.log.error(opts.err);
@@ -56,5 +63,5 @@ const startAPI = async (app, options = { port: 5e3 }) => {
56
63
  }
57
64
  };
58
65
 
59
- export { getApplication, startAPI, traceIdHook };
66
+ export { getApplication, problemDetailsErrorHandler, startAPI, traceIdHook };
60
67
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/traceIdHook.ts","../src/index.ts"],"sourcesContent":["import { context, trace } from '@opentelemetry/api';\nimport type { onRequestHookHandler } from 'fastify';\n\nexport const traceIdHook: onRequestHookHandler = (_request, reply, done) => {\n const traceId = trace.getSpan(context.active())?.spanContext().traceId;\n if (traceId) void reply.header('x-trace-id', traceId);\n done();\n};\n","import Compress from '@fastify/compress';\nimport Etag from '@fastify/etag';\nimport Form from '@fastify/formbody';\nimport {\n currentDefaultObservability,\n type Observability,\n} from '@event-driven-io/emmett';\nimport closeWithGrace from 'close-with-grace';\nimport Fastify, {\n type FastifyInstance,\n type FastifyPluginAsync,\n type FastifyPluginCallback,\n type FastifyPluginOptions,\n type FastifyServerOptions,\n} from 'fastify';\nimport { traceIdHook } from './traceIdHook';\n\nexport * from './traceIdHook';\n\n// TODO: THIS WILL NEED TO BE BETTER TYPED\ntype Plugin = {\n plugin: FastifyPluginAsync | FastifyPluginCallback;\n options: FastifyPluginOptions;\n};\n\nconst defaultPlugins: Plugin[] = [\n { plugin: Etag, options: {} },\n { plugin: Compress, options: { global: false } },\n { plugin: Form, options: {} },\n];\n\nexport interface ApplicationOptions {\n serverOptions?: FastifyServerOptions;\n registerRoutes?: (app: FastifyInstance) => void;\n activeDefaultPlugins?: Plugin[];\n observability?: Partial<Observability<string>>;\n disableTraceIdHeader?: boolean;\n}\n\nexport const getApplication = async (options: ApplicationOptions) => {\n const {\n registerRoutes,\n activeDefaultPlugins = defaultPlugins,\n serverOptions,\n observability,\n disableTraceIdHeader,\n } = options;\n\n const app: FastifyInstance = Fastify(serverOptions);\n\n const isObservabilityRegistered =\n observability !== undefined || currentDefaultObservability() !== undefined;\n\n if (isObservabilityRegistered && disableTraceIdHeader !== true)\n app.addHook('onRequest', traceIdHook);\n\n await Promise.all(\n activeDefaultPlugins.map(async ({ plugin, options }) => {\n await app.register(plugin, options);\n }),\n );\n\n if (registerRoutes) {\n registerRoutes(app);\n }\n\n const closeListeners = closeWithGrace({ delay: 500 }, async (opts) => {\n if (opts.err) {\n app.log.error(opts.err);\n }\n\n await app.close();\n });\n\n app.addHook('onClose', (instance, done) => {\n closeListeners.uninstall();\n done();\n });\n\n return app;\n};\n\nexport type StartApiOptions = {\n port?: number;\n};\n\nexport const startAPI = async (\n app: FastifyInstance,\n options: StartApiOptions = { port: 5000 },\n) => {\n const { port } = options;\n try {\n await app.listen({ port });\n } catch (err) {\n app.log.error(err);\n process.exit(1);\n }\n};\n"],"mappings":";;;;;;;;;AAGA,MAAa,eAAqC,UAAU,OAAO,SAAS;CAC1E,MAAM,UAAU,MAAM,QAAQ,QAAQ,OAAO,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;CAC/D,IAAI,SAAS,AAAK,MAAM,OAAO,cAAc,OAAO;CACpD,KAAK;AACP;;;ACkBA,MAAM,iBAA2B;CAC/B;EAAE,QAAQ;EAAM,SAAS,CAAC;CAAE;CAC5B;EAAE,QAAQ;EAAU,SAAS,EAAE,QAAQ,MAAM;CAAE;CAC/C;EAAE,QAAQ;EAAM,SAAS,CAAC;CAAE;AAC9B;AAUA,MAAa,iBAAiB,OAAO,YAAgC;CACnE,MAAM,EACJ,gBACA,uBAAuB,gBACvB,eACA,eACA,yBACE;CAEJ,MAAM,MAAuB,QAAQ,aAAa;CAKlD,KAFE,kBAAkB,UAAa,4BAA4B,MAAM,WAElC,yBAAyB,MACxD,IAAI,QAAQ,aAAa,WAAW;CAEtC,MAAM,QAAQ,IACZ,qBAAqB,IAAI,OAAO,EAAE,QAAQ,cAAc;EACtD,MAAM,IAAI,SAAS,QAAQ,OAAO;CACpC,CAAC,CACH;CAEA,IAAI,gBACF,eAAe,GAAG;CAGpB,MAAM,iBAAiB,eAAe,EAAE,OAAO,IAAI,GAAG,OAAO,SAAS;EACpE,IAAI,KAAK,KACP,IAAI,IAAI,MAAM,KAAK,GAAG;EAGxB,MAAM,IAAI,MAAM;CAClB,CAAC;CAED,IAAI,QAAQ,YAAY,UAAU,SAAS;EACzC,eAAe,UAAU;EACzB,KAAK;CACP,CAAC;CAED,OAAO;AACT;AAMA,MAAa,WAAW,OACtB,KACA,UAA2B,EAAE,MAAM,IAAK,MACrC;CACH,MAAM,EAAE,SAAS;CACjB,IAAI;EACF,MAAM,IAAI,OAAO,EAAE,KAAK,CAAC;CAC3B,SAAS,KAAK;EACZ,IAAI,IAAI,MAAM,GAAG;EACjB,QAAQ,KAAK,CAAC;CAChB;AACF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/problemDetailsErrorHandler.ts","../src/traceIdHook.ts","../src/index.ts"],"sourcesContent":["import {\n defaultErrorToProblemDetailsMapping,\n type ProblemDocument,\n} from '@event-driven-io/emmett';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\n\nexport type ErrorToProblemDetailsMapping = (\n error: unknown,\n request: FastifyRequest,\n) => ProblemDocument | undefined;\n\nexport const problemDetailsErrorHandler =\n (mapError?: ErrorToProblemDetailsMapping) =>\n (error: unknown, request: FastifyRequest, reply: FastifyReply) => {\n const problemDetails =\n mapError?.(error, request) ?? defaultErrorToProblemDetailsMapping(error);\n\n return reply\n .status(problemDetails.status)\n .header('Content-Type', 'application/problem+json')\n .send(problemDetails);\n };\n","import { context, trace } from '@opentelemetry/api';\nimport type { onRequestHookHandler } from 'fastify';\n\nexport const traceIdHook: onRequestHookHandler = (_request, reply, done) => {\n const traceId = trace.getSpan(context.active())?.spanContext().traceId;\n if (traceId) void reply.header('x-trace-id', traceId);\n done();\n};\n","import Compress from '@fastify/compress';\nimport Etag from '@fastify/etag';\nimport Form from '@fastify/formbody';\nimport {\n currentDefaultObservability,\n type Observability,\n} from '@event-driven-io/emmett';\nimport closeWithGrace from 'close-with-grace';\nimport Fastify, {\n type FastifyInstance,\n type FastifyPluginAsync,\n type FastifyPluginCallback,\n type FastifyPluginOptions,\n type FastifyServerOptions,\n} from 'fastify';\nimport {\n problemDetailsErrorHandler,\n type ErrorToProblemDetailsMapping,\n} from './problemDetailsErrorHandler';\nimport { traceIdHook } from './traceIdHook';\n\nexport * from './problemDetailsErrorHandler';\nexport * from './traceIdHook';\n\n// TODO: THIS WILL NEED TO BE BETTER TYPED\ntype Plugin = {\n plugin: FastifyPluginAsync | FastifyPluginCallback;\n options: FastifyPluginOptions;\n};\n\nconst defaultPlugins: Plugin[] = [\n { plugin: Etag, options: {} },\n { plugin: Compress, options: { global: false } },\n { plugin: Form, options: {} },\n];\n\nexport interface ApplicationOptions {\n serverOptions?: FastifyServerOptions;\n registerRoutes?: (app: FastifyInstance) => void;\n activeDefaultPlugins?: Plugin[];\n observability?: Partial<Observability<string>>;\n disableTraceIdHeader?: boolean;\n mapError?: ErrorToProblemDetailsMapping;\n}\n\nexport const getApplication = async (options: ApplicationOptions) => {\n const {\n registerRoutes,\n activeDefaultPlugins = defaultPlugins,\n serverOptions,\n observability,\n disableTraceIdHeader,\n mapError,\n } = options;\n\n const app: FastifyInstance = Fastify(serverOptions);\n\n const isObservabilityRegistered =\n observability !== undefined || currentDefaultObservability() !== undefined;\n\n if (isObservabilityRegistered && disableTraceIdHeader !== true)\n app.addHook('onRequest', traceIdHook);\n\n await Promise.all(\n activeDefaultPlugins.map(async ({ plugin, options }) => {\n await app.register(plugin, options);\n }),\n );\n\n if (mapError) app.setErrorHandler(problemDetailsErrorHandler(mapError));\n\n if (registerRoutes) {\n registerRoutes(app);\n }\n\n const closeListeners = closeWithGrace({ delay: 500 }, async (opts) => {\n if (opts.err) {\n app.log.error(opts.err);\n }\n\n await app.close();\n });\n\n app.addHook('onClose', (instance, done) => {\n closeListeners.uninstall();\n done();\n });\n\n return app;\n};\n\nexport type StartApiOptions = {\n port?: number;\n};\n\nexport const startAPI = async (\n app: FastifyInstance,\n options: StartApiOptions = { port: 5000 },\n) => {\n const { port } = options;\n try {\n await app.listen({ port });\n } catch (err) {\n app.log.error(err);\n process.exit(1);\n }\n};\n"],"mappings":";;;;;;;;;AAWA,MAAa,8BACV,cACA,OAAgB,SAAyB,UAAwB;CAChE,MAAM,iBACJ,WAAW,OAAO,OAAO,KAAK,oCAAoC,KAAK;CAEzE,OAAO,MACJ,OAAO,eAAe,MAAM,CAAC,CAC7B,OAAO,gBAAgB,0BAA0B,CAAC,CAClD,KAAK,cAAc;AACxB;;;AClBF,MAAa,eAAqC,UAAU,OAAO,SAAS;CAC1E,MAAM,UAAU,MAAM,QAAQ,QAAQ,OAAO,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;CAC/D,IAAI,SAAS,AAAK,MAAM,OAAO,cAAc,OAAO;CACpD,KAAK;AACP;;;ACuBA,MAAM,iBAA2B;CAC/B;EAAE,QAAQ;EAAM,SAAS,CAAC;CAAE;CAC5B;EAAE,QAAQ;EAAU,SAAS,EAAE,QAAQ,MAAM;CAAE;CAC/C;EAAE,QAAQ;EAAM,SAAS,CAAC;CAAE;AAC9B;AAWA,MAAa,iBAAiB,OAAO,YAAgC;CACnE,MAAM,EACJ,gBACA,uBAAuB,gBACvB,eACA,eACA,sBACA,aACE;CAEJ,MAAM,MAAuB,QAAQ,aAAa;CAKlD,KAFE,kBAAkB,UAAa,4BAA4B,MAAM,WAElC,yBAAyB,MACxD,IAAI,QAAQ,aAAa,WAAW;CAEtC,MAAM,QAAQ,IACZ,qBAAqB,IAAI,OAAO,EAAE,QAAQ,cAAc;EACtD,MAAM,IAAI,SAAS,QAAQ,OAAO;CACpC,CAAC,CACH;CAEA,IAAI,UAAU,IAAI,gBAAgB,2BAA2B,QAAQ,CAAC;CAEtE,IAAI,gBACF,eAAe,GAAG;CAGpB,MAAM,iBAAiB,eAAe,EAAE,OAAO,IAAI,GAAG,OAAO,SAAS;EACpE,IAAI,KAAK,KACP,IAAI,IAAI,MAAM,KAAK,GAAG;EAGxB,MAAM,IAAI,MAAM;CAClB,CAAC;CAED,IAAI,QAAQ,YAAY,UAAU,SAAS;EACzC,eAAe,UAAU;EACzB,KAAK;CACP,CAAC;CAED,OAAO;AACT;AAMA,MAAa,WAAW,OACtB,KACA,UAA2B,EAAE,MAAM,IAAK,MACrC;CACH,MAAM,EAAE,SAAS;CACjB,IAAI;EACF,MAAM,IAAI,OAAO,EAAE,KAAK,CAAC;CAC3B,SAAS,KAAK;EACZ,IAAI,IAAI,MAAM,GAAG;EACjB,QAAQ,KAAK,CAAC;CAChB;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event-driven-io/emmett-fastify",
3
- "version": "0.43.0-rc.1",
3
+ "version": "0.43.0-rc.3",
4
4
  "type": "module",
5
5
  "description": "Emmett - Event Sourcing development made simple",
6
6
  "scripts": {
@@ -58,7 +58,7 @@
58
58
  },
59
59
  "devDependencies": {},
60
60
  "peerDependencies": {
61
- "@event-driven-io/emmett": "0.43.0-rc.1",
61
+ "@event-driven-io/emmett": "0.43.0-rc.3",
62
62
  "fastify": "^5.12.7",
63
63
  "@opentelemetry/api": ">=1.10.0 <1.11.0"
64
64
  }