@myunisoft/events
v5.0.10
Published
MyUnisoft Events validation
Downloads
652
Readme
🚧 Requirements
- Node.js version 18 or higher
- Docker (for running tests).
🚀 Getting Started
This package is available in the Node Package Repository and can be easily installed with npm or yarn
$ npm i @myunisoft/events
# or
$ yarn add @myunisoft/events
| variable | description | default |
| --- | --- | --- |
| MYUNISOFT_EVENTS_LOGGER_MODE
| Set log level for the default logger | info
|
| Dispatcher |
| MYUNISOFT_DISPATCHER_IDLE_TIME
| Interval threshold when Dispatcher become idle | 600_000
|
| MYUNISOFT_DISPATCHER_CHECK_LAST_ACTIVITY_INTERVAL
| Dispatcher checking last activity interval | 120_000
|
| MYUNISOFT_DISPATCHER_BACKUP_TRANSACTION_STORE_NAME
| Default name for backup transaction store | backup
|
| MYUNISOFT_DISPATCHER_INIT_TIMEOUT
| Dispatcher initialisation timeout | 3_500
|
| MYUNISOFT_DISPATCHER_PING_INTERVAL
| Dispatcher ping interval | 3_500
|
| Incomer |
| MYUNISOFT_INCOMER_INIT_TIMEOUT
| Incomer initialisation timeout | 3_500
|
| MYUNISOFT_EVENTS_INIT_EXTERNAL
| Whenever Incomer should initialize an external Dispatcher | false
|
| MYUNISOFT_INCOMER_MAX_PING_INTERVAL
| Maximum ping interval | 60_000
|
| MYUNISOFT_INCOMER_PUBLISH_INTERVAL
| Publish interval | 60_000
|
| MYUNISOFT_INCOMER_IS_DISPATCHER
| Weither Incomer is a Dispatcher | false
|
Some options takes the lead over environment variables.
For instance with: new Incomer({ dispatcherInactivityOptions: { maxPingInterval: 900_000 }})
the max ping interval will be 900_000
even if MYUNISOFT_INCOMER_MAX_PING_INTERVAL
variable is set.
📚 Usage example
import * as Events, { type EventOptions } from "@myunisoft/events";
const event: EventOptions<"connector"> = {
name: "connector",
operation: "CREATE",
scope: {
schemaId: 1
},
metadata: {
agent: "Node",
origin: {
endpoint: "http://localhost:12080/api/v1/my-custom-feature",
method: "POST",
requestId: crypto.randomUUID();
},
createdAt: Date.now()
},
data: {
id: 1,
code: "JFAC"
}
};
Events.validate(event);
You can also use additional APIs to validate and narrow the data type depending on the operation:
if (Events.isCreateOperation(event.operation)) {
// Do some code
}
else if (Events.isUpdateOperation(event.operation)) {
// Do some code
}
else if (Events.isDeleteOperation(event.operation)) {
// Do some code
}
[!NOTE] 👀 See here for the exhaustive list of Events.
💡 What is an Event?
A fully constituted event is composed of a name
, an operation
, and multiple objects such as data
, scope
and metadata
.
- The
name
identifies the event. - The
operation
defines if it is a creation, update, or deletion. - Based on the name, we know the data and the different
metadata.origin.method
related to it. - The
metadata
object is used to determine various pieces of information, such as the entry point. - The
scope
defines the who.
export interface Scope {
schemaId: number;
firmId?: number | null;
firmSIRET?: number | null;
accountingFolderId?: number | null;
accountingFolderSIRET?: number | null;
accountingFolderRef?: string | null;
persPhysiqueId?: number | null;
}
export interface Metadata {
agent: string;
origin?: {
endpoint: string;
method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | (string & {});
requestId?: string;
};
createdAt: number;
}
API
validate< T extends keyof Events >(options: EventOptions): void
Throw an error if a given event is not recognized internally.
isCreateOperation< T extends keyof Events >(operation: EventOptions["operation"]): operation is Operation["create"]
isUpdateOperation< T extends keyof Events >(operation: EventOptions["operation"]): operation is Operation["update"]
isDeleteOperation< T extends keyof Events >(operation: EventOptions["operation"]): operation is Operation["delete"]
EventOptions is described by the following type:
export type EventOptions<K extends keyof EventsDefinition.Events> = {
scope: Scope;
metadata: Metadata;
} & EventsDefinition.Events[K];
Exploiting Webhooks
👀 See the root example/fastify for an example of utilizing webhooks with an HTTP server.
In TypeScript, webhooks can be described using the WebhookResponse
type:
import type { WebhookResponse } from "@myunisoft/events";
const response: WebhooksResponse<["connector", "accountingFolder"]> = [
{
name: "connector",
operation: "CREATE",
scope: {
schemaId: 1
},
data: {
id: 1,
code: "JFAC"
},
webhookId: "1",
createdAt: Date.now()
},
{
name: "accountingFolder",
operation: "CREATE",
scope: {
schemaId: 1
},
data: {
id: 1
},
webhookId: "2",
createdAt: Date.now()
},
];
{
"description": "Webhook",
"type": "array",
"items": {
"type": "object",
"properties": {
"scope": {
"$ref": "Scope"
},
"webhookId": {
"type": "string"
},
"createdAt": {
"type": "number"
},
"name": {
"type": "string",
"description": "event related name"
},
"operation": {
"type": "string",
"description": "event related operation",
"enum": ["CREATE", "UPDATE", "DELETE", "VOID"]
},
"data": {
"type": "object",
"description": "event related data",
"properties": {
"id": {
"type": "string"
},
"required": ["id"],
"additionalProperties": true
}
}
},
"required": ["scope", "webhookId", "createdAt", "name", "operation", "data"],
"additionalProperties": false
}
}
Contributors ✨
Thanks goes to these wonderful people (emoji key):
License
MIT