@lokalise/fastify-extras 30.5.0 → 30.6.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 +117 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/plugins/amplitude/FakeAmplitude.d.ts +7 -0
- package/dist/plugins/amplitude/FakeAmplitude.js +12 -0
- package/dist/plugins/amplitude/FakeAmplitude.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -402,9 +402,11 @@ The plugin decorates your Fastify instance with a `Amplitude`, which you can inj
|
|
|
402
402
|
> "@amplitude/analytics-types": "*"
|
|
403
403
|
> ```
|
|
404
404
|
|
|
405
|
-
|
|
405
|
+
**Related utilities:**
|
|
406
406
|
|
|
407
|
-
|
|
407
|
+
- `AmplitudeAdapter` - A type-safe wrapper that validates events using Zod schemas before sending them to Amplitude
|
|
408
|
+
- `FakeAmplitude` - A utility class for testing environments that doesn't send events to Amplitude
|
|
409
|
+
See the [Amplitude utilities section](#amplitude) for detailed documentation and examples.
|
|
408
410
|
|
|
409
411
|
### Strip Trailing Slash Plugin
|
|
410
412
|
|
|
@@ -487,6 +489,119 @@ When an uncaught exception occurs, the plugin:
|
|
|
487
489
|
|
|
488
490
|
## Utilities
|
|
489
491
|
|
|
492
|
+
### amplitude
|
|
493
|
+
|
|
494
|
+
#### FakeAmplitude
|
|
495
|
+
|
|
496
|
+
`FakeAmplitude` is a utility class that extends `Amplitude` but doesn't send any events to Amplitude. This is useful for
|
|
497
|
+
testing environments or when you want to disable event tracking without changing your application code.
|
|
498
|
+
|
|
499
|
+
Example usage:
|
|
500
|
+
|
|
501
|
+
```typescript
|
|
502
|
+
import { FakeAmplitude } from '@lokalise/fastify-extras'
|
|
503
|
+
|
|
504
|
+
// In your test or development environment
|
|
505
|
+
const amplitude = new FakeAmplitude()
|
|
506
|
+
|
|
507
|
+
// track() will not send any events
|
|
508
|
+
amplitude.track({
|
|
509
|
+
event_type: 'button_clicked',
|
|
510
|
+
user_id: 'user-123',
|
|
511
|
+
})
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
The `track()` method returns a promise that resolves to `null` immediately, maintaining the same interface as the real
|
|
515
|
+
`Amplitude` class without actually sending data.
|
|
516
|
+
|
|
517
|
+
#### AmplitudeAdapter
|
|
518
|
+
|
|
519
|
+
`AmplitudeAdapter` is a type-safe wrapper around `Amplitude` that uses Zod schemas to validate events before sending them.
|
|
520
|
+
This ensures that all events sent to Amplitude conform to predefined schemas, catching errors at compile-time and runtime.
|
|
521
|
+
|
|
522
|
+
**Key features:**
|
|
523
|
+
|
|
524
|
+
- Type-safe event tracking with TypeScript
|
|
525
|
+
- Automatic validation using Zod schemas
|
|
526
|
+
- Prevents sending malformed events to Amplitude
|
|
527
|
+
|
|
528
|
+
**Example usage:**
|
|
529
|
+
|
|
530
|
+
```typescript
|
|
531
|
+
import { z } from 'zod'
|
|
532
|
+
import { AmplitudeAdapter, AMPLITUDE_BASE_MESSAGE_SCHEMA, Amplitude } from '@lokalise/fastify-extras'
|
|
533
|
+
import type { AmplitudeMessage } from '@lokalise/fastify-extras'
|
|
534
|
+
|
|
535
|
+
// Define your event schemas
|
|
536
|
+
const eventSchemas = {
|
|
537
|
+
buttonClicked: {
|
|
538
|
+
schema: AMPLITUDE_BASE_MESSAGE_SCHEMA.extend({
|
|
539
|
+
event_type: z.literal('button_clicked'),
|
|
540
|
+
event_properties: z.object({
|
|
541
|
+
button_id: z.string(),
|
|
542
|
+
page: z.string(),
|
|
543
|
+
}),
|
|
544
|
+
}),
|
|
545
|
+
},
|
|
546
|
+
userSignedUp: {
|
|
547
|
+
schema: AMPLITUDE_BASE_MESSAGE_SCHEMA.extend({
|
|
548
|
+
event_type: z.literal('user_signed_up'),
|
|
549
|
+
event_properties: z.object({
|
|
550
|
+
plan: z.enum(['free', 'premium']),
|
|
551
|
+
}),
|
|
552
|
+
}),
|
|
553
|
+
},
|
|
554
|
+
} as const satisfies Record<string, AmplitudeMessage>
|
|
555
|
+
|
|
556
|
+
const eventSchemaValues = Object.values(eventSchemas)
|
|
557
|
+
type SupportedEvents = typeof eventSchemaValues
|
|
558
|
+
|
|
559
|
+
// Create the adapter
|
|
560
|
+
const amplitude = new Amplitude(true)
|
|
561
|
+
const amplitudeAdapter = new AmplitudeAdapter<SupportedEvents>({ amplitude })
|
|
562
|
+
|
|
563
|
+
// Track events with type safety
|
|
564
|
+
amplitudeAdapter.track(eventSchemas.buttonClicked, {
|
|
565
|
+
user_id: 'user-123',
|
|
566
|
+
event_properties: {
|
|
567
|
+
button_id: 'submit-btn',
|
|
568
|
+
page: '/checkout',
|
|
569
|
+
},
|
|
570
|
+
})
|
|
571
|
+
|
|
572
|
+
// With groups
|
|
573
|
+
amplitudeAdapter.track(eventSchemas.userSignedUp, {
|
|
574
|
+
user_id: 'user-456',
|
|
575
|
+
groups: { company: 'acme-corp' },
|
|
576
|
+
event_properties: {
|
|
577
|
+
plan: 'premium',
|
|
578
|
+
},
|
|
579
|
+
})
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
**Schema validation:**
|
|
583
|
+
|
|
584
|
+
The `AMPLITUDE_BASE_MESSAGE_SCHEMA` provides the base schema that all events must extend. It requires:
|
|
585
|
+
|
|
586
|
+
- `event_type`: A literal string identifying the event
|
|
587
|
+
- `user_id`: A non-empty string or the literal `'SYSTEM'`
|
|
588
|
+
- `groups` (optional): A record of group names to values
|
|
589
|
+
|
|
590
|
+
When defining custom events, extend this base schema with your specific `event_type` and `event_properties`:
|
|
591
|
+
|
|
592
|
+
```typescript
|
|
593
|
+
const myEventSchema = AMPLITUDE_BASE_MESSAGE_SCHEMA.extend({
|
|
594
|
+
event_type: z.literal('my_custom_event'),
|
|
595
|
+
event_properties: z.object({
|
|
596
|
+
// Your custom properties with validation
|
|
597
|
+
count: z.number().int().positive(),
|
|
598
|
+
status: z.enum(['active', 'inactive']),
|
|
599
|
+
}),
|
|
600
|
+
})
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
If validation fails, a `ZodError` will be thrown, preventing invalid data from being sent to Amplitude.
|
|
604
|
+
|
|
490
605
|
### route-utilities
|
|
491
606
|
|
|
492
607
|
#### authPreHandlers
|
package/dist/index.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export { commonSyncHealthcheckPlugin } from './plugins/healthcheck/commonSyncHea
|
|
|
29
29
|
export type { CommonSyncHealthcheckPluginOptions } from './plugins/healthcheck/commonSyncHealthcheckPlugin.ts';
|
|
30
30
|
export { amplitudePlugin, type AmplitudeConfig, type CreateApiTrackingEventFn, } from './plugins/amplitude/amplitudePlugin.js';
|
|
31
31
|
export { Amplitude } from './plugins/amplitude/Amplitude.js';
|
|
32
|
+
export { FakeAmplitude } from './plugins/amplitude/FakeAmplitude.js';
|
|
32
33
|
export { AmplitudeAdapter, AMPLITUDE_BASE_MESSAGE_SCHEMA, type AmplitudeMessage, type AmplitudeAdapterDependencies, } from './plugins/amplitude/AmplitudeAdapter.js';
|
|
33
34
|
export type { FastifyReplyWithPayload } from './types.js';
|
|
34
35
|
export { stripTrailingSlashPlugin } from './plugins/stripTrailingSlashPlugin.js';
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ export { startupHealthcheckPlugin } from './plugins/healthcheck/startupHealthche
|
|
|
15
15
|
export { commonSyncHealthcheckPlugin } from "./plugins/healthcheck/commonSyncHealthcheckPlugin.js";
|
|
16
16
|
export { amplitudePlugin, } from './plugins/amplitude/amplitudePlugin.js';
|
|
17
17
|
export { Amplitude } from './plugins/amplitude/Amplitude.js';
|
|
18
|
+
export { FakeAmplitude } from './plugins/amplitude/FakeAmplitude.js';
|
|
18
19
|
export { AmplitudeAdapter, AMPLITUDE_BASE_MESSAGE_SCHEMA, } from './plugins/amplitude/AmplitudeAdapter.js';
|
|
19
20
|
export { stripTrailingSlashPlugin } from './plugins/stripTrailingSlashPlugin.js';
|
|
20
21
|
export { unhandledExceptionPlugin, commonErrorObjectResolver, } from './plugins/unhandledExceptionPlugin.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,GACf,MAAM,4BAA4B,CAAA;AAGnC,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,2CAA2C,CAAA;AAGlD,OAAO,EACL,gCAAgC,EAChC,0BAA0B,GAC3B,MAAM,+CAA+C,CAAA;AAGtD,OAAO,EACL,qCAAqC,EACrC,+BAA+B,GAChC,MAAM,oDAAoD,CAAA;AAG3D,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,GACtB,MAAM,0CAA0C,CAAA;AAGjD,OAAO,EACL,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,mDAAmD,CAAA;AAO1D,OAAO,EAAE,mCAAmC,EAAE,MAAM,6DAA6D,CAAA;AAEjH,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAEtE,OAAO,EACL,yBAAyB,EACzB,kCAAkC,GACnC,MAAM,+CAA+C,CAAA;AAGtD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAM1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAA;AAO1F,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAA;AAG7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAA;AAG1F,OAAO,EAAE,wBAAwB,EAAE,MAAM,mDAAmD,CAAA;AAG5F,OAAO,EAAE,2BAA2B,EAAE,MAAM,sDAAsD,CAAA;AAGlG,OAAO,EACL,eAAe,GAGhB,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAC5D,OAAO,EACL,gBAAgB,EAChB,6BAA6B,GAG9B,MAAM,yCAAyC,CAAA;AAIhD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAA;AAEhF,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,uCAAuC,CAAA;AAG9C,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAA4B,MAAM,0BAA0B,CAAA;AAGnG,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAE5E,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAA;AAClF,OAAO,EACL,0BAA0B,GAG3B,MAAM,4BAA4B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,GACf,MAAM,4BAA4B,CAAA;AAGnC,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,2CAA2C,CAAA;AAGlD,OAAO,EACL,gCAAgC,EAChC,0BAA0B,GAC3B,MAAM,+CAA+C,CAAA;AAGtD,OAAO,EACL,qCAAqC,EACrC,+BAA+B,GAChC,MAAM,oDAAoD,CAAA;AAG3D,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,GACtB,MAAM,0CAA0C,CAAA;AAGjD,OAAO,EACL,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,mDAAmD,CAAA;AAO1D,OAAO,EAAE,mCAAmC,EAAE,MAAM,6DAA6D,CAAA;AAEjH,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAEtE,OAAO,EACL,yBAAyB,EACzB,kCAAkC,GACnC,MAAM,+CAA+C,CAAA;AAGtD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAM1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAA;AAO1F,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAA;AAG7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAA;AAG1F,OAAO,EAAE,wBAAwB,EAAE,MAAM,mDAAmD,CAAA;AAG5F,OAAO,EAAE,2BAA2B,EAAE,MAAM,sDAAsD,CAAA;AAGlG,OAAO,EACL,eAAe,GAGhB,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACpE,OAAO,EACL,gBAAgB,EAChB,6BAA6B,GAG9B,MAAM,yCAAyC,CAAA;AAIhD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAA;AAEhF,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,uCAAuC,CAAA;AAG9C,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAA4B,MAAM,0BAA0B,CAAA;AAGnG,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAE5E,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAA;AAClF,OAAO,EACL,0BAA0B,GAG3B,MAAM,4BAA4B,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AmplitudeReturn, Result } from '@amplitude/analytics-types';
|
|
2
|
+
import type { BaseEvent } from '@amplitude/analytics-types/lib/esm/base-event.d.ts';
|
|
3
|
+
import { Amplitude } from './Amplitude.ts';
|
|
4
|
+
export declare class FakeAmplitude extends Amplitude {
|
|
5
|
+
constructor();
|
|
6
|
+
track(_: BaseEvent): AmplitudeReturn<Result | null>;
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FakeAmplitude.js","sourceRoot":"","sources":["../../../lib/plugins/amplitude/FakeAmplitude.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,MAAM,OAAO,aAAc,SAAQ,SAAS;IAC1C;QACE,KAAK,CAAC,KAAK,CAAC,CAAA;IACd,CAAC;IAEQ,KAAK,CAAC,CAAY;QACzB,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;SAC/B,CAAA;IACH,CAAC;CACF"}
|