@lokalise/fastify-extras 9.0.0 → 10.1.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 +153 -9
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/plugins/amplitudePlugin.d.ts +58 -0
- package/dist/plugins/amplitudePlugin.js +62 -0
- package/dist/plugins/amplitudePlugin.js.map +1 -0
- package/dist/plugins/amplitudePlugin.spec.d.ts +1 -0
- package/dist/plugins/amplitudePlugin.spec.js +156 -0
- package/dist/plugins/amplitudePlugin.spec.js.map +1 -0
- package/dist/plugins/newrelicTransactionManagerPlugin.d.ts +1 -1
- package/dist/plugins/newrelicTransactionManagerPlugin.js +1 -1
- package/dist/plugins/newrelicTransactionManagerPlugin.js.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,19 +1,163 @@
|
|
|
1
|
-
# fastify-extras
|
|
1
|
+
# fastify-extras 🧩
|
|
2
2
|
|
|
3
|
-
Reusable plugins for
|
|
3
|
+
Reusable plugins for Fastify.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
* [Dependency Management](#dependency-management)
|
|
6
|
+
* [Plugins](#plugins)
|
|
7
|
+
|
|
8
|
+
* [RequestContext Provider Plugin](#requestcontext-provider-plugin)
|
|
9
|
+
* [Public Healthcheck Plugin](#public-healthcheck-plugin)
|
|
10
|
+
* [Split IO Plugin](#split-io-plugin)
|
|
11
|
+
* [BugSnag Plugin](#bugsnag-plugin)
|
|
12
|
+
* [Metrics Plugin](#metrics-plugin)
|
|
13
|
+
* [NewRelic Transaction Manager Plugin](#newrelic-transaction-manager-plugin)
|
|
14
|
+
|
|
15
|
+
## Dependency Management
|
|
6
16
|
|
|
7
17
|
The following needs to be taken into consideration when adding new runtime dependency for the `fastify-extras` package:
|
|
8
18
|
|
|
9
19
|
* If dependency is an implementation detail, and end consumer is not expected to import and use the dependency directly, it should be a `dependency`;
|
|
10
20
|
* If dependency needs to be imported and used by consumer directly for it to function properly, it should be a `peerDependency`.
|
|
11
21
|
|
|
12
|
-
###
|
|
22
|
+
### Dependencies
|
|
23
|
+
|
|
24
|
+
* `@bugsnag/js`;
|
|
25
|
+
* `@opentelemetry/api`;
|
|
26
|
+
* `@opentelemetry/exporter-trace-otlp-grpc`;
|
|
27
|
+
* `@opentelemetry/instrumentation`;
|
|
28
|
+
* `@opentelemetry/resources`;
|
|
29
|
+
* `@opentelemetry/sdk-trace-base`;
|
|
30
|
+
* `@opentelemetry/sdk-trace-node`;
|
|
31
|
+
* `@opentelemetry/semantic-conventions`;
|
|
32
|
+
* `@prisma/instrumentation`;
|
|
33
|
+
* `@splitsoftware/splitio`;
|
|
34
|
+
* `fastify-metrics`;
|
|
35
|
+
* `fastify-plugin`;
|
|
36
|
+
* `tslib`.
|
|
37
|
+
|
|
38
|
+
### Peer Dependencies
|
|
39
|
+
|
|
40
|
+
* `@fastify/request-context`;
|
|
41
|
+
* `fastify`;
|
|
42
|
+
* `newrelic`;
|
|
43
|
+
* `pino`.
|
|
44
|
+
|
|
45
|
+
## Plugins
|
|
46
|
+
|
|
47
|
+
### RequestContext Provider Plugin
|
|
48
|
+
|
|
49
|
+
Plugin to:
|
|
50
|
+
* extend existing `FastifyRequest` with request context by setting the following:
|
|
51
|
+
* `logger`, an instance of `FastifyBaseLogger`;
|
|
52
|
+
* `reqId`, the request-id;
|
|
53
|
+
* store the request-id in Asynchronous Local Storage to be picked up by instrumentation tooling (e. g. OpenTelemetry).
|
|
54
|
+
|
|
55
|
+
No options are required to register the plugin.
|
|
56
|
+
|
|
57
|
+
The `getRequestIdFastifyAppConfig()` method is exported and returns:
|
|
58
|
+
* `genReqId`, a function for generating the request-id;
|
|
59
|
+
* `requestIdHeader`, the header name used to set the request-id.
|
|
60
|
+
|
|
61
|
+
Which can be passed to Fastify during instantiation.
|
|
62
|
+
|
|
63
|
+
### Public Healthcheck Plugin
|
|
64
|
+
|
|
65
|
+
Plugin to monitor app status through public healthcheck.
|
|
66
|
+
|
|
67
|
+
Add the plugin to your Fastify instance by registering it with the following options:
|
|
68
|
+
* `healthChecks`, a list of promises with healthcheck in the callback;
|
|
69
|
+
* `responsePayload` (optional), the response payload that the public healthcheck should return. If no response payload is provided, the default response is:
|
|
70
|
+
```json
|
|
71
|
+
{"heartbeat": "HEALTHY"}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Your Fastify app will reply with the status of the app when hitting the `GET /` route.
|
|
75
|
+
|
|
76
|
+
### Split IO Plugin
|
|
77
|
+
|
|
78
|
+
Plugin to handle feature flags in Split IO.
|
|
79
|
+
|
|
80
|
+
Add the plugin to your Fastify instance by registering it with the following options:
|
|
81
|
+
* `isEnabled`, if `true` the plugin will connect to [Split IO](https://split.io) using the provided `apiKey` and store data in memory with background syncing;
|
|
82
|
+
* `apiKey`, your SDK key;
|
|
83
|
+
* `debugMode`;
|
|
84
|
+
* `localhostFilePath` (optional), used to utilize the SDK in [localhost mode](https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#localhost-mode). It corresponds to the full path to a file with the mapping of feature flag name to treatment. `apiKey` will be automatically replaced with `localhost` if `localhostFilePath` is provided.
|
|
85
|
+
|
|
86
|
+
The plugin decorates your Fastify instance with a `SplitIOFeatureManager`, which you can inject and use to leverage the following methods:
|
|
87
|
+
|
|
88
|
+
* `init()`, returns a promise that resolves once the SDK has finished loading. It's called automatically when registering the plugin;
|
|
89
|
+
* `getTreatment()`, returns the proper treatment based on the feature flag name and the key in input. Expected parameters are:
|
|
90
|
+
* `key`, the ID of the user/account/etc. you're trying to evaluate a treatment for;
|
|
91
|
+
* `splitName`, the Split IO feature flag name;
|
|
92
|
+
* `attributes` (optional), a set of [Attributes](https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#attribute-syntax) used in evaluation to further decide whether to show the on or off treatment;
|
|
93
|
+
|
|
94
|
+
> **_NOTE:_** If `isEnabled` is false, `getTreatement()` will return `control` to signal disabled treatment.
|
|
95
|
+
* `getTreatmentWithConfig()`, used to leverage [dynamic configurations with your treatment](https://help.split.io/hc/en-us/articles/360026943552). It accepts the same parameters as `getTreatment()`, but the response structure is as follows:
|
|
96
|
+
```ts
|
|
97
|
+
type TreatmentResult = {
|
|
98
|
+
treatment: string,
|
|
99
|
+
config: string | null
|
|
100
|
+
};
|
|
101
|
+
```
|
|
102
|
+
> **_NOTE:_** If `isEnabled` is false, `getTreatementWithConfig()` will return `control` as `treatment` and `null` as `config` to signal disabled treatment.
|
|
103
|
+
* `track()`, used to record any actions your customers perform. Returns a boolean to indicate whether or not the SDK was able to successfully queue the event. Expected parameters are:
|
|
104
|
+
* `key`, the ID of the user/account/etc. you're trying to evaluate a treatment for;
|
|
105
|
+
* `trafficType`, the [traffic type](https://help.split.io/hc/en-us/articles/360019916311-Traffic-type) of the key;
|
|
106
|
+
* `eventType`, the event type that this event should correspond to;
|
|
107
|
+
* `value` (optional), the value to be used in creating the metric;
|
|
108
|
+
* `properties`(optional), an object of key value pairs that represent the [properties](https://help.split.io/hc/en-us/articles/360027333612-Event-property-capture-) to be used to filter your metrics;
|
|
109
|
+
* `shutdown()`, gracefully shuts down the client.
|
|
110
|
+
|
|
111
|
+
More info about Split IO can be checked [here](https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK).
|
|
112
|
+
|
|
113
|
+
### BugSnag Plugin
|
|
114
|
+
|
|
115
|
+
Plugin to report errors to BugSnag.
|
|
116
|
+
|
|
117
|
+
Add the plugin to your Fastify instance by registering it with the following options:
|
|
118
|
+
* `isEnabled`;
|
|
119
|
+
* `bugsnag`, a set of customizable [xonfiguration options](https://docs.bugsnag.com/platforms/javascript/configuration-options/).
|
|
120
|
+
|
|
121
|
+
Once the plugin has been added to your Fastify instance and loaded, errors will be reported to BugSnag.
|
|
122
|
+
|
|
123
|
+
### Metrics Plugin
|
|
124
|
+
|
|
125
|
+
Plugin to expose Prometheus metrics.
|
|
126
|
+
|
|
127
|
+
Add the plugin to your Fastify instance by registering it with the following options:
|
|
128
|
+
* `loggerOptions`, used to configure the internal logger instance. It can be a boolean or a set of [Pino options](https://getpino.io/#/docs/api?id=options). By default it is set to `false` and the logger is disabled;
|
|
129
|
+
* `disablePrometheusRequestLogging` (optional). By default Fastify will issue an `info` level log message when a request is received and when the response for that request has been sent. By setting this option to `true`, these log messages will be disabled. Defaults to `true`;
|
|
130
|
+
* `bindAddress` (optional). By default, the server will listen on the address(es) resolved by localhost when no specific host is provided. See the possible values for host when targeting localhost [here](https://fastify.dev/docs/latest/Reference/Server#listen);
|
|
131
|
+
* `errorObjectResolver`, a resolver method that, given an `err` and optionally a `correlationID`, it will log the error if something goes wrong.
|
|
132
|
+
|
|
133
|
+
The plugin exposes a `GET /metrics` route in your Fastify app to retrieve Prometheus metrics. If something goes wrong while starting the Prometheus metrics server, an `Error` is thrown. Otherwise, a success message is displayed when the plugin has been loaded.
|
|
134
|
+
|
|
135
|
+
### NewRelic Transaction Manager Plugin
|
|
136
|
+
|
|
137
|
+
Plugin to create custom NewRelic spans for background jobs.
|
|
138
|
+
|
|
139
|
+
Add the plugin to your Fastify instance by registering it with the following options:
|
|
140
|
+
* `isEnabled`.
|
|
141
|
+
|
|
142
|
+
The plugin decorates your Fastify instance with a `NewRelicTransactionManager`, which you can inject and use to leverage the following methods:
|
|
143
|
+
* `start()`, which takes a `jobName`, and starts a background transaction with the provided name;
|
|
144
|
+
* `stop()`, which takes a `jobId`, and ends the background transaction referenced by the ID;
|
|
145
|
+
* `addCustomAttribute()`, which takes `attrName` and `attrValue` and records the custom attribute as such defined. `attrValue` can be a string, a number, or a boolean.
|
|
146
|
+
|
|
147
|
+
### Amplitude Plugin
|
|
148
|
+
|
|
149
|
+
This plugin facilitates the transmission of events to Amplitude.
|
|
150
|
+
|
|
151
|
+
To add this plugin to your Fastify instance, register it with the following configurations:
|
|
152
|
+
* `isEnabled`: A flag utilized to activate or de-activate the plugin.
|
|
153
|
+
* `apiKey` (optional): This refers to the Amplitude API key which can be procured from your respective Amplitude project.
|
|
154
|
+
* `options` (optional): To configure Amplitude, please refer to [this documentation](https://amplitude.github.io/Amplitude-TypeScript/modules/_amplitude_analytics_node.Types.html#NodeOptions).
|
|
155
|
+
* `apiUsageTracking` (optional): You can use this callback to generate an event that will automatically be sent for tracking API usage. Non-specification of this feature will lead to disabling of API tracking.
|
|
156
|
+
* `plugins` (optional): This feature allows you to expand the plugin's functionality, from altering event properties to relaying to third-party APIs. To learn more, visit [this link](https://www.docs.developers.amplitude.com/data/sdks/typescript-node/#plugins).
|
|
13
157
|
|
|
14
|
-
|
|
15
|
-
- `enabled` - will connect to [](https://split.io) using provided `apiKey` and store data in memory with background sync
|
|
16
|
-
- `localhost` - will use `localhost` mode with features provided in a file via param `localhostFilePath`
|
|
17
|
-
- `disabled` - on any request to `SplitIOFeatureManager` it will return `control` treatment
|
|
158
|
+
While `apiUsageTracking` can be configured for automatic tracking of API usage, the `amplitudeTrack` method allows you to send events to Amplitude whenever necessary.
|
|
18
159
|
|
|
19
|
-
|
|
160
|
+
> 📘 To ensure optimal functionality with this plugin, you may need to incorporate Amplitude types into your development dependencies.
|
|
161
|
+
> ```
|
|
162
|
+
> "@amplitude/analytics-types": "*"
|
|
163
|
+
> ```
|
package/dist/index.d.ts
CHANGED
|
@@ -12,3 +12,4 @@ export { prismaOtelTracingPlugin } from './plugins/opentelemetry/prismaOtelTraci
|
|
|
12
12
|
export type { PrismaOtelTracingPluginConfig } from './plugins/opentelemetry/prismaOtelTracingPlugin';
|
|
13
13
|
export { publicHealthcheckPlugin } from './plugins/publicHealthcheckPlugin';
|
|
14
14
|
export type { PublicHealthcheckPluginOptions, HealthCheck } from './plugins/publicHealthcheckPlugin';
|
|
15
|
+
export { amplitudePlugin, amplitudeTrack, type AmplitudeConfig, type CreateApiTrackingEventFn, } from './plugins/amplitudePlugin';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.publicHealthcheckPlugin = exports.prismaOtelTracingPlugin = exports.metricsPlugin = exports.SplitIOFeatureManager = exports.splitIOFeatureManagerPlugin = exports.NewRelicTransactionManager = exports.newrelicTransactionManagerPlugin = exports.REQUEST_ID_STORE_KEY = exports.getRequestIdFastifyAppConfig = exports.requestContextProviderPlugin = exports.reportErrorToBugsnag = exports.bugsnagPlugin = void 0;
|
|
3
|
+
exports.amplitudeTrack = exports.amplitudePlugin = exports.publicHealthcheckPlugin = exports.prismaOtelTracingPlugin = exports.metricsPlugin = exports.SplitIOFeatureManager = exports.splitIOFeatureManagerPlugin = exports.NewRelicTransactionManager = exports.newrelicTransactionManagerPlugin = exports.REQUEST_ID_STORE_KEY = exports.getRequestIdFastifyAppConfig = exports.requestContextProviderPlugin = exports.reportErrorToBugsnag = exports.bugsnagPlugin = void 0;
|
|
4
4
|
var bugsnagPlugin_1 = require("./plugins/bugsnagPlugin");
|
|
5
5
|
Object.defineProperty(exports, "bugsnagPlugin", { enumerable: true, get: function () { return bugsnagPlugin_1.bugsnagPlugin; } });
|
|
6
6
|
Object.defineProperty(exports, "reportErrorToBugsnag", { enumerable: true, get: function () { return bugsnagPlugin_1.reportErrorToBugsnag; } });
|
|
@@ -20,4 +20,7 @@ var prismaOtelTracingPlugin_1 = require("./plugins/opentelemetry/prismaOtelTraci
|
|
|
20
20
|
Object.defineProperty(exports, "prismaOtelTracingPlugin", { enumerable: true, get: function () { return prismaOtelTracingPlugin_1.prismaOtelTracingPlugin; } });
|
|
21
21
|
var publicHealthcheckPlugin_1 = require("./plugins/publicHealthcheckPlugin");
|
|
22
22
|
Object.defineProperty(exports, "publicHealthcheckPlugin", { enumerable: true, get: function () { return publicHealthcheckPlugin_1.publicHealthcheckPlugin; } });
|
|
23
|
+
var amplitudePlugin_1 = require("./plugins/amplitudePlugin");
|
|
24
|
+
Object.defineProperty(exports, "amplitudePlugin", { enumerable: true, get: function () { return amplitudePlugin_1.amplitudePlugin; } });
|
|
25
|
+
Object.defineProperty(exports, "amplitudeTrack", { enumerable: true, get: function () { return amplitudePlugin_1.amplitudeTrack; } });
|
|
23
26
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;AAAA,yDAA6E;AAApE,8GAAA,aAAa,OAAA;AAAE,qHAAA,oBAAoB,OAAA;AAG5C,uFAI+C;AAH7C,4IAAA,4BAA4B,OAAA;AAC5B,4IAAA,4BAA4B,OAAA;AAC5B,oIAAA,oBAAoB,OAAA;AAItB,+FAGmD;AAFjD,oJAAA,gCAAgC,OAAA;AAChC,8IAAA,0BAA0B,OAAA;AAI5B,qFAG8C;AAF5C,0IAAA,2BAA2B,OAAA;AAC3B,oIAAA,qBAAqB,OAAA;AAIvB,yDAAuD;AAA9C,8GAAA,aAAa,OAAA;AAGtB,2FAAyF;AAAhF,kIAAA,uBAAuB,OAAA;AAGhC,6EAA2E;AAAlE,kIAAA,uBAAuB,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;AAAA,yDAA6E;AAApE,8GAAA,aAAa,OAAA;AAAE,qHAAA,oBAAoB,OAAA;AAG5C,uFAI+C;AAH7C,4IAAA,4BAA4B,OAAA;AAC5B,4IAAA,4BAA4B,OAAA;AAC5B,oIAAA,oBAAoB,OAAA;AAItB,+FAGmD;AAFjD,oJAAA,gCAAgC,OAAA;AAChC,8IAAA,0BAA0B,OAAA;AAI5B,qFAG8C;AAF5C,0IAAA,2BAA2B,OAAA;AAC3B,oIAAA,qBAAqB,OAAA;AAIvB,yDAAuD;AAA9C,8GAAA,aAAa,OAAA;AAGtB,2FAAyF;AAAhF,kIAAA,uBAAuB,OAAA;AAGhC,6EAA2E;AAAlE,kIAAA,uBAAuB,OAAA;AAGhC,6DAKkC;AAJhC,kHAAA,eAAe,OAAA;AACf,iHAAA,cAAc,OAAA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { AmplitudeReturn, BaseEvent, NodeOptions, Plugin, Result } from '@amplitude/analytics-types';
|
|
2
|
+
import type { FastifyReply, FastifyRequest } from 'fastify';
|
|
3
|
+
/**
|
|
4
|
+
* Callback used to create the events that will be used to automatically
|
|
5
|
+
* track the API usage
|
|
6
|
+
*/
|
|
7
|
+
export type CreateApiTrackingEventFn = (req: FastifyRequest, res: FastifyReply) => BaseEvent | null;
|
|
8
|
+
/**
|
|
9
|
+
* Configuration to set up the Amplitude Plugin.
|
|
10
|
+
*
|
|
11
|
+
* @property {boolean} isEnabled Flag to enable or disable the plugin.
|
|
12
|
+
*
|
|
13
|
+
* @property {string} apiKey Amplitude api key, please get it from your
|
|
14
|
+
* Amplitude project
|
|
15
|
+
*
|
|
16
|
+
* @property {NodeOptions} Amplitude configuration, please check
|
|
17
|
+
* [this](https://amplitude.github.io/Amplitude-TypeScript/modules/_amplitude_analytics_node.Types.html#NodeOptions)
|
|
18
|
+
* to learn more.
|
|
19
|
+
*
|
|
20
|
+
* @property {CreateApiTrackingEventFn} apiUsageTracking Callback used to create
|
|
21
|
+
* the event that will be sent automatically to track the API usage. If not
|
|
22
|
+
* specified the API usage track will be disabled.
|
|
23
|
+
*
|
|
24
|
+
* @property {Plugin[]} plugins Allow to extend plugin behavior by, for example,
|
|
25
|
+
* modifying event properties. Please check
|
|
26
|
+
* [this](https://www.docs.developers.amplitude.com/data/sdks/typescript-node/#plugins)
|
|
27
|
+
* to see how it works
|
|
28
|
+
*/
|
|
29
|
+
export interface AmplitudeConfig {
|
|
30
|
+
isEnabled: boolean;
|
|
31
|
+
apiKey?: string;
|
|
32
|
+
options?: NodeOptions;
|
|
33
|
+
apiUsageTracking?: CreateApiTrackingEventFn;
|
|
34
|
+
plugins?: Plugin[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Use this method to register the amplitude plugin on your fastify instance.
|
|
38
|
+
*
|
|
39
|
+
* Example of usage:
|
|
40
|
+
* ```ts
|
|
41
|
+
* await app.register(amplitudePlugin, {
|
|
42
|
+
* isEnabled: true,
|
|
43
|
+
* apiKey: 'dummy-api-key',
|
|
44
|
+
* options: {
|
|
45
|
+
* serverZone: 'EU',
|
|
46
|
+
* },
|
|
47
|
+
* })
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare const amplitudePlugin: import("fastify").FastifyPluginCallback<AmplitudeConfig, import("fastify").RawServerDefault, import("fastify").FastifyTypeProviderDefault>;
|
|
51
|
+
/**
|
|
52
|
+
* Sends the given event to Amplitude
|
|
53
|
+
*
|
|
54
|
+
* @param event Event to send to amplitude. Please check
|
|
55
|
+
* [this](https://amplitude.github.io/Amplitude-TypeScript/interfaces/_amplitude_analytics_node.Types.BaseEvent.html)
|
|
56
|
+
* to get more info about the BaseEvent type
|
|
57
|
+
*/
|
|
58
|
+
export declare const amplitudeTrack: (event: BaseEvent) => AmplitudeReturn<Result | null>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.amplitudeTrack = exports.amplitudePlugin = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const analytics_node_1 = require("@amplitude/analytics-node");
|
|
6
|
+
const fastify_plugin_1 = tslib_1.__importDefault(require("fastify-plugin"));
|
|
7
|
+
let pluginConfig = null;
|
|
8
|
+
async function plugin(fastify, config, next) {
|
|
9
|
+
pluginConfig = config;
|
|
10
|
+
if (!config.isEnabled) {
|
|
11
|
+
return next();
|
|
12
|
+
}
|
|
13
|
+
if (!config.apiKey) {
|
|
14
|
+
return next(Error('Amplitude key not defined'));
|
|
15
|
+
}
|
|
16
|
+
await (0, analytics_node_1.init)(config.apiKey, config.options).promise;
|
|
17
|
+
if (config.apiUsageTracking) {
|
|
18
|
+
enableApiUsageTracking(fastify, config.apiUsageTracking);
|
|
19
|
+
}
|
|
20
|
+
if (config.plugins) {
|
|
21
|
+
// @ts-expect-error
|
|
22
|
+
config.plugins.forEach((e) => (0, analytics_node_1.add)(e));
|
|
23
|
+
}
|
|
24
|
+
return next();
|
|
25
|
+
}
|
|
26
|
+
function enableApiUsageTracking(fastify, eventCreationFn) {
|
|
27
|
+
fastify.addHook('onResponse', (req, res, done) => {
|
|
28
|
+
const event = eventCreationFn(req, res);
|
|
29
|
+
if (event) {
|
|
30
|
+
(0, exports.amplitudeTrack)(event);
|
|
31
|
+
}
|
|
32
|
+
return done();
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Use this method to register the amplitude plugin on your fastify instance.
|
|
37
|
+
*
|
|
38
|
+
* Example of usage:
|
|
39
|
+
* ```ts
|
|
40
|
+
* await app.register(amplitudePlugin, {
|
|
41
|
+
* isEnabled: true,
|
|
42
|
+
* apiKey: 'dummy-api-key',
|
|
43
|
+
* options: {
|
|
44
|
+
* serverZone: 'EU',
|
|
45
|
+
* },
|
|
46
|
+
* })
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
exports.amplitudePlugin = (0, fastify_plugin_1.default)(plugin, {
|
|
50
|
+
fastify: '4.x',
|
|
51
|
+
name: 'amplitude-plugin',
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* Sends the given event to Amplitude
|
|
55
|
+
*
|
|
56
|
+
* @param event Event to send to amplitude. Please check
|
|
57
|
+
* [this](https://amplitude.github.io/Amplitude-TypeScript/interfaces/_amplitude_analytics_node.Types.BaseEvent.html)
|
|
58
|
+
* to get more info about the BaseEvent type
|
|
59
|
+
*/
|
|
60
|
+
const amplitudeTrack = (event) => pluginConfig?.isEnabled ? (0, analytics_node_1.track)(event) : { promise: Promise.resolve(null) };
|
|
61
|
+
exports.amplitudeTrack = amplitudeTrack;
|
|
62
|
+
//# sourceMappingURL=amplitudePlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amplitudePlugin.js","sourceRoot":"","sources":["../../lib/plugins/amplitudePlugin.ts"],"names":[],"mappings":";;;;AAAA,8DAA4D;AAc5D,4EAA+B;AAE/B,IAAI,YAAY,GAA2B,IAAI,CAAA;AAE/C,KAAK,UAAU,MAAM,CACnB,OAAwB,EACxB,MAAuB,EACvB,IAA2B;IAE3B,YAAY,GAAG,MAAM,CAAA;IAErB,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;QACrB,OAAO,IAAI,EAAE,CAAA;KACd;IAED,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAA;KAChD;IAED,MAAM,IAAA,qBAAI,EAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAA;IAEjD,IAAI,MAAM,CAAC,gBAAgB,EAAE;QAC3B,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAA;KACzD;IACD,IAAI,MAAM,CAAC,OAAO,EAAE;QAClB,mBAAmB;QACnB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,oBAAG,EAAC,CAAC,CAAC,CAAC,CAAA;KACtC;IAED,OAAO,IAAI,EAAE,CAAA;AACf,CAAC;AAED,SAAS,sBAAsB,CAC7B,OAAwB,EACxB,eAAyC;IAEzC,OAAO,CAAC,OAAO,CACb,YAAY,EACZ,CAAC,GAAmB,EAAE,GAAiB,EAAE,IAA6B,EAAE,EAAE;QACxE,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QACvC,IAAI,KAAK,EAAE;YACT,IAAA,sBAAc,EAAC,KAAK,CAAC,CAAA;SACtB;QACD,OAAO,IAAI,EAAE,CAAA;IACf,CAAC,CACF,CAAA;AACH,CAAC;AAqCD;;;;;;;;;;;;;GAaG;AACU,QAAA,eAAe,GAAG,IAAA,wBAAE,EAAkB,MAAM,EAAE;IACzD,OAAO,EAAE,KAAK;IACd,IAAI,EAAE,kBAAkB;CACzB,CAAC,CAAA;AAEF;;;;;;GAMG;AACI,MAAM,cAAc,GAAG,CAAC,KAAgB,EAAkC,EAAE,CACjF,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC,IAAA,sBAAK,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAA;AADhE,QAAA,cAAc,kBACkD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const amplitude = tslib_1.__importStar(require("@amplitude/analytics-node"));
|
|
5
|
+
const fastify_1 = tslib_1.__importDefault(require("fastify"));
|
|
6
|
+
const amplitudePlugin_1 = require("./amplitudePlugin");
|
|
7
|
+
describe('amplitudePlugin', () => {
|
|
8
|
+
let app;
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
app = (0, fastify_1.default)();
|
|
11
|
+
});
|
|
12
|
+
afterEach(async () => {
|
|
13
|
+
jest.clearAllMocks();
|
|
14
|
+
await app.close();
|
|
15
|
+
});
|
|
16
|
+
it('skips initialization if isEnabled is false', async () => {
|
|
17
|
+
// Given
|
|
18
|
+
const initSpy = jest.spyOn(amplitude, 'init');
|
|
19
|
+
// When
|
|
20
|
+
await app.register(amplitudePlugin_1.amplitudePlugin, {
|
|
21
|
+
isEnabled: false,
|
|
22
|
+
});
|
|
23
|
+
// Then
|
|
24
|
+
expect(initSpy).not.toHaveBeenCalled();
|
|
25
|
+
});
|
|
26
|
+
it('throws error if is enabled and api key is not defined', async () => {
|
|
27
|
+
// Given
|
|
28
|
+
const initSpy = jest.spyOn(amplitude, 'init');
|
|
29
|
+
// When
|
|
30
|
+
let error = null;
|
|
31
|
+
try {
|
|
32
|
+
await app.register(amplitudePlugin_1.amplitudePlugin, {
|
|
33
|
+
isEnabled: true,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
error = e;
|
|
38
|
+
}
|
|
39
|
+
// Then
|
|
40
|
+
expect(initSpy).not.toHaveBeenCalled();
|
|
41
|
+
expect(error).not.toBeNull();
|
|
42
|
+
});
|
|
43
|
+
it('amplitudeTrack avoids track if plugin is not enabled', async () => {
|
|
44
|
+
// Given
|
|
45
|
+
const trackSpy = jest.spyOn(amplitude, 'track');
|
|
46
|
+
await app.register(amplitudePlugin_1.amplitudePlugin, {
|
|
47
|
+
isEnabled: false,
|
|
48
|
+
});
|
|
49
|
+
// When
|
|
50
|
+
const result = await (0, amplitudePlugin_1.amplitudeTrack)({ event_type: 'event not tracked' }).promise;
|
|
51
|
+
// Then
|
|
52
|
+
expect(result).toBeNull();
|
|
53
|
+
expect(trackSpy).not.toHaveBeenCalled();
|
|
54
|
+
});
|
|
55
|
+
it('amplitudeTrack calls track if the plugin is enabled', async () => {
|
|
56
|
+
// Given
|
|
57
|
+
const trackResponse = {
|
|
58
|
+
event: { event_type: 'test' },
|
|
59
|
+
code: 1,
|
|
60
|
+
message: 'message',
|
|
61
|
+
};
|
|
62
|
+
const trackSpy = jest.spyOn(amplitude, 'track').mockImplementation(() => ({
|
|
63
|
+
promise: Promise.resolve(trackResponse),
|
|
64
|
+
}));
|
|
65
|
+
await app.register(amplitudePlugin_1.amplitudePlugin, {
|
|
66
|
+
isEnabled: true,
|
|
67
|
+
apiKey: 'This is an api key',
|
|
68
|
+
});
|
|
69
|
+
// When
|
|
70
|
+
const event = { event_type: 'event tracked' };
|
|
71
|
+
const response = await (0, amplitudePlugin_1.amplitudeTrack)(event).promise;
|
|
72
|
+
// Then
|
|
73
|
+
expect(response).toBe(trackResponse);
|
|
74
|
+
expect(trackSpy).toHaveBeenCalledWith(event);
|
|
75
|
+
});
|
|
76
|
+
it('tracks api usage if apiUsageTracking callback returns an event', async () => {
|
|
77
|
+
// Given
|
|
78
|
+
const trackSpy = jest.spyOn(amplitude, 'track').mockImplementation(() => ({
|
|
79
|
+
promise: Promise.resolve({
|
|
80
|
+
event: { event_type: 'test' },
|
|
81
|
+
code: 1,
|
|
82
|
+
message: 'message',
|
|
83
|
+
}),
|
|
84
|
+
}));
|
|
85
|
+
const event = { event_type: 'My api event' };
|
|
86
|
+
await app.register(amplitudePlugin_1.amplitudePlugin, {
|
|
87
|
+
isEnabled: true,
|
|
88
|
+
apiKey: 'This is an api key',
|
|
89
|
+
apiUsageTracking: () => event,
|
|
90
|
+
});
|
|
91
|
+
// When
|
|
92
|
+
const response = await app
|
|
93
|
+
.route({
|
|
94
|
+
url: '/test',
|
|
95
|
+
method: 'GET',
|
|
96
|
+
handler: async (_, reply) => {
|
|
97
|
+
return reply.send('Testing');
|
|
98
|
+
},
|
|
99
|
+
})
|
|
100
|
+
.inject({
|
|
101
|
+
method: 'GET',
|
|
102
|
+
url: '/test',
|
|
103
|
+
});
|
|
104
|
+
// Then
|
|
105
|
+
expect(response.statusCode).toBe(200);
|
|
106
|
+
expect(response.body).toBe('Testing');
|
|
107
|
+
expect(trackSpy).toHaveBeenCalledWith(event);
|
|
108
|
+
});
|
|
109
|
+
it('does not track api usage if apiUsageTracking returns null', async () => {
|
|
110
|
+
// Given
|
|
111
|
+
const trackSpy = jest.spyOn(amplitude, 'track');
|
|
112
|
+
await app.register(amplitudePlugin_1.amplitudePlugin, {
|
|
113
|
+
isEnabled: true,
|
|
114
|
+
apiKey: 'This is an api key',
|
|
115
|
+
apiUsageTracking: () => null,
|
|
116
|
+
});
|
|
117
|
+
// When
|
|
118
|
+
const response = await app
|
|
119
|
+
.route({
|
|
120
|
+
url: '/test',
|
|
121
|
+
method: 'GET',
|
|
122
|
+
handler: async (_, reply) => {
|
|
123
|
+
return reply.send('Testing');
|
|
124
|
+
},
|
|
125
|
+
})
|
|
126
|
+
.inject({
|
|
127
|
+
method: 'GET',
|
|
128
|
+
url: '/test',
|
|
129
|
+
});
|
|
130
|
+
// Then
|
|
131
|
+
expect(response.statusCode).toBe(200);
|
|
132
|
+
expect(response.body).toBe('Testing');
|
|
133
|
+
expect(trackSpy).not.toHaveBeenCalled();
|
|
134
|
+
});
|
|
135
|
+
it('defined amplitude plugins are set up', async () => {
|
|
136
|
+
// Given
|
|
137
|
+
const addSpy = jest.spyOn(amplitude, 'add');
|
|
138
|
+
const plugin = new FakePlugin();
|
|
139
|
+
const pluginSetUpSpy = jest.spyOn(plugin, 'setup');
|
|
140
|
+
// When
|
|
141
|
+
await app.register(amplitudePlugin_1.amplitudePlugin, {
|
|
142
|
+
isEnabled: true,
|
|
143
|
+
apiKey: 'This is an api key',
|
|
144
|
+
plugins: [plugin],
|
|
145
|
+
});
|
|
146
|
+
// Then
|
|
147
|
+
expect(addSpy).toHaveBeenCalledWith(plugin);
|
|
148
|
+
expect(pluginSetUpSpy).toHaveBeenCalled();
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
class FakePlugin {
|
|
152
|
+
type = 'enrichment';
|
|
153
|
+
setup = () => Promise.resolve(undefined);
|
|
154
|
+
execute = (event) => Promise.resolve(event);
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=amplitudePlugin.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amplitudePlugin.spec.js","sourceRoot":"","sources":["../../lib/plugins/amplitudePlugin.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ export declare class NewRelicTransactionManager {
|
|
|
10
10
|
private readonly isEnabled;
|
|
11
11
|
private readonly transactionMap;
|
|
12
12
|
constructor(isNewRelicEnabled: boolean);
|
|
13
|
-
|
|
13
|
+
addCustomAttribute(attrName: string, attrValue: string | number | boolean): void;
|
|
14
14
|
start(jobName: string): void;
|
|
15
15
|
stop(jobId: string): void;
|
|
16
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"newrelicTransactionManagerPlugin.js","sourceRoot":"","sources":["../../lib/plugins/newrelicTransactionManagerPlugin.ts"],"names":[],"mappings":";;;;AACA,4EAA+B;AAe/B,IAAI,QAAkB,CAAA;AAYtB,MAAa,0BAA0B;IACpB,SAAS,CAAS;IAClB,cAAc,CAAgC;IAE/D,YAAY,iBAA0B;QACpC,IAAI,iBAAiB,EAAE;YACrB,mEAAmE;YACnE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;SAC/B;QAED,IAAI,CAAC,SAAS,GAAG,iBAAiB,CAAA;QAClC,IAAI,CAAC,cAAc,GAAG,IAAI,GAAG,EAAE,CAAA;IACjC,CAAC;IAEM,
|
|
1
|
+
{"version":3,"file":"newrelicTransactionManagerPlugin.js","sourceRoot":"","sources":["../../lib/plugins/newrelicTransactionManagerPlugin.ts"],"names":[],"mappings":";;;;AACA,4EAA+B;AAe/B,IAAI,QAAkB,CAAA;AAYtB,MAAa,0BAA0B;IACpB,SAAS,CAAS;IAClB,cAAc,CAAgC;IAE/D,YAAY,iBAA0B;QACpC,IAAI,iBAAiB,EAAE;YACrB,mEAAmE;YACnE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;SAC/B;QAED,IAAI,CAAC,SAAS,GAAG,iBAAiB,CAAA;QAClC,IAAI,CAAC,cAAc,GAAG,IAAI,GAAG,EAAE,CAAA;IACjC,CAAC;IAEM,kBAAkB,CAAC,QAAgB,EAAE,SAAoC;QAC9E,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAM;SACP;QAED,QAAQ,CAAC,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;IAClD,CAAC;IAEM,KAAK,CAAC,OAAe;QAC1B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAM;SACP;QAED,QAAQ,CAAC,0BAA0B,CAAC,OAAO,EAAE,GAAG,EAAE;YAChD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAA;QAC7D,CAAC,CAAC,CAAA;IACJ,CAAC;IAEM,IAAI,CAAC,KAAa;QACvB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,OAAM;SACP;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAA;QAC1D,IAAI,IAAI,KAAK,WAAW,EAAE;YACxB,OAAM;SACP;QACD,WAAW,CAAC,GAAG,EAAE,CAAA;QACjB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACnC,CAAC;CACF;AA5CD,gEA4CC;AAED,SAAS,MAAM,CACb,OAAwB,EACxB,IAAuC,EACvC,IAAgB;IAEhB,MAAM,OAAO,GAAG,IAAI,0BAA0B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAE9D,OAAO,CAAC,QAAQ,CAAC,4BAA4B,EAAE,OAAO,CAAC,CAAA;IAEvD,IAAI,IAAI,CAAC,SAAS,EAAE;QAClB,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;YACpC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,QAAQ,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC1B,IAAI,KAAK,EAAE;wBACT,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;qBACrB;oBACD,OAAO,EAAE,CAAA;gBACX,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;KACH;IAED,IAAI,EAAE,CAAA;AACR,CAAC;AAEY,QAAA,gCAAgC,GAAG,IAAA,wBAAE,EAAC,MAAM,EAAE;IACzD,OAAO,EAAE,KAAK;IACd,IAAI,EAAE,qCAAqC;CAC5C,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lokalise/fastify-extras",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.1.0",
|
|
4
4
|
"description": "Opinionated set of fastify plugins, commonly used in Lokalise",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Lokalise",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"@opentelemetry/semantic-conventions": "^1.14.0",
|
|
54
54
|
"@prisma/instrumentation": "^4.16.0",
|
|
55
55
|
"@splitsoftware/splitio": "^10.22.5",
|
|
56
|
+
"@amplitude/analytics-node": "^1.3.0",
|
|
56
57
|
"fastify-metrics": "^10.3.0",
|
|
57
58
|
"fastify-plugin": "^4.5.0",
|
|
58
59
|
"tslib": "^2.5.3"
|
|
@@ -69,6 +70,7 @@
|
|
|
69
70
|
"@types/jest": "^29.5.2",
|
|
70
71
|
"@types/newrelic": "^9.14.0",
|
|
71
72
|
"@types/node": "^18.16.18",
|
|
73
|
+
"@amplitude/analytics-types": "^2.1.1",
|
|
72
74
|
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
|
73
75
|
"@typescript-eslint/parser": "^5.60.0",
|
|
74
76
|
"auto-changelog": "^2.4.0",
|
|
@@ -79,7 +81,7 @@
|
|
|
79
81
|
"eslint-plugin-prettier": "^4.2.1",
|
|
80
82
|
"fastify": "^4.18.0",
|
|
81
83
|
"jest": "^29.5.0",
|
|
82
|
-
"newrelic": "10.
|
|
84
|
+
"newrelic": "10.4.0",
|
|
83
85
|
"pino": "^8.14.1",
|
|
84
86
|
"prettier": "^2.8.8",
|
|
85
87
|
"shx": "^0.3.4",
|