@lokalise/fastify-extras 10.0.0 → 11.0.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 +19 -1
- 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 +67 -0
- package/dist/plugins/amplitudePlugin.js +70 -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/package.json +4 -2
package/README.md
CHANGED
|
@@ -142,4 +142,22 @@ Add the plugin to your Fastify instance by registering it with the following opt
|
|
|
142
142
|
The plugin decorates your Fastify instance with a `NewRelicTransactionManager`, which you can inject and use to leverage the following methods:
|
|
143
143
|
* `start()`, which takes a `jobName`, and starts a background transaction with the provided name;
|
|
144
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.
|
|
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).
|
|
157
|
+
|
|
158
|
+
The plugin decorates your Fastify instance with a `Amplitude`, which you can inject and use the `track` method on it to send events whenever you need
|
|
159
|
+
|
|
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, Amplitude, 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.Amplitude = 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, "Amplitude", { enumerable: true, get: function () { return amplitudePlugin_1.Amplitude; } });
|
|
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,4GAAA,SAAS,OAAA"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { AmplitudeReturn, BaseEvent, NodeOptions, Plugin, Result } from '@amplitude/analytics-types';
|
|
2
|
+
import type { FastifyReply, FastifyRequest } from 'fastify';
|
|
3
|
+
declare module 'fastify' {
|
|
4
|
+
interface FastifyInstance {
|
|
5
|
+
amplitude: Amplitude;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Callback used to create the events that will be used to automatically
|
|
10
|
+
* track the API usage
|
|
11
|
+
*/
|
|
12
|
+
export type CreateApiTrackingEventFn = (req: FastifyRequest, res: FastifyReply) => BaseEvent | null;
|
|
13
|
+
/**
|
|
14
|
+
* Configuration to set up the Amplitude Plugin.
|
|
15
|
+
*
|
|
16
|
+
* @property {boolean} isEnabled Flag to enable or disable the plugin.
|
|
17
|
+
*
|
|
18
|
+
* @property {string} apiKey Amplitude api key, please get it from your
|
|
19
|
+
* Amplitude project
|
|
20
|
+
*
|
|
21
|
+
* @property {NodeOptions} Amplitude configuration, please check
|
|
22
|
+
* [this](https://amplitude.github.io/Amplitude-TypeScript/modules/_amplitude_analytics_node.Types.html#NodeOptions)
|
|
23
|
+
* to learn more.
|
|
24
|
+
*
|
|
25
|
+
* @property {CreateApiTrackingEventFn} apiUsageTracking Callback used to create
|
|
26
|
+
* the event that will be sent automatically to track the API usage. If not
|
|
27
|
+
* specified the API usage track will be disabled.
|
|
28
|
+
*
|
|
29
|
+
* @property {Plugin[]} plugins Allow to extend plugin behavior by, for example,
|
|
30
|
+
* modifying event properties. Please check
|
|
31
|
+
* [this](https://www.docs.developers.amplitude.com/data/sdks/typescript-node/#plugins)
|
|
32
|
+
* to see how it works
|
|
33
|
+
*/
|
|
34
|
+
export interface AmplitudeConfig {
|
|
35
|
+
isEnabled: boolean;
|
|
36
|
+
apiKey?: string;
|
|
37
|
+
options?: NodeOptions;
|
|
38
|
+
apiUsageTracking?: CreateApiTrackingEventFn;
|
|
39
|
+
plugins?: Plugin[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Use this method to register the amplitude plugin on your fastify instance.
|
|
43
|
+
*
|
|
44
|
+
* Example of usage:
|
|
45
|
+
* ```ts
|
|
46
|
+
* await app.register(amplitudePlugin, {
|
|
47
|
+
* isEnabled: true,
|
|
48
|
+
* apiKey: 'dummy-api-key',
|
|
49
|
+
* options: {
|
|
50
|
+
* serverZone: 'EU',
|
|
51
|
+
* },
|
|
52
|
+
* })
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare const amplitudePlugin: import("fastify").FastifyPluginCallback<AmplitudeConfig, import("fastify").RawServerDefault, import("fastify").FastifyTypeProviderDefault>;
|
|
56
|
+
export declare class Amplitude {
|
|
57
|
+
private readonly isEnabled;
|
|
58
|
+
constructor(isEnabled: boolean);
|
|
59
|
+
/**
|
|
60
|
+
* Sends the given event to Amplitude
|
|
61
|
+
*
|
|
62
|
+
* @param event Event to send to amplitude. Please check
|
|
63
|
+
* [this](https://amplitude.github.io/Amplitude-TypeScript/interfaces/_amplitude_analytics_node.Types.BaseEvent.html)
|
|
64
|
+
* to get more info about the BaseEvent type
|
|
65
|
+
*/
|
|
66
|
+
track(event: BaseEvent): AmplitudeReturn<Result | null>;
|
|
67
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Amplitude = 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
|
+
async function plugin(fastify, config, next) {
|
|
8
|
+
const amplitudeInstance = new Amplitude(config.isEnabled);
|
|
9
|
+
fastify.decorate('amplitude', amplitudeInstance);
|
|
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, amplitudeInstance, 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, amplitude, eventCreationFn) {
|
|
27
|
+
fastify.addHook('onResponse', (req, res, done) => {
|
|
28
|
+
const event = eventCreationFn(req, res);
|
|
29
|
+
if (event) {
|
|
30
|
+
amplitude.track(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
|
+
class Amplitude {
|
|
54
|
+
isEnabled;
|
|
55
|
+
constructor(isEnabled) {
|
|
56
|
+
this.isEnabled = isEnabled;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Sends the given event to Amplitude
|
|
60
|
+
*
|
|
61
|
+
* @param event Event to send to amplitude. Please check
|
|
62
|
+
* [this](https://amplitude.github.io/Amplitude-TypeScript/interfaces/_amplitude_analytics_node.Types.BaseEvent.html)
|
|
63
|
+
* to get more info about the BaseEvent type
|
|
64
|
+
*/
|
|
65
|
+
track(event) {
|
|
66
|
+
return this.isEnabled ? (0, analytics_node_1.track)(event) : { promise: Promise.resolve(null) };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.Amplitude = Amplitude;
|
|
70
|
+
//# 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;AAQ/B,KAAK,UAAU,MAAM,CACnB,OAAwB,EACxB,MAAuB,EACvB,IAA2B;IAE3B,MAAM,iBAAiB,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IACzD,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAA;IAEhD,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,iBAAiB,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAA;KAC5E;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,SAAoB,EACpB,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,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;SACvB;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,MAAa,SAAS;IACH,SAAS,CAAS;IAEnC,YAAY,SAAkB;QAC5B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,KAAgB;QAC3B,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAA,sBAAK,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAA;IAC3E,CAAC;CACF;AAjBD,8BAiBC"}
|
|
@@ -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 app.amplitude.track({ 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 app.amplitude.track(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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lokalise/fastify-extras",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.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",
|