@myunisoft/events
v4.3.1
Published
MyUnisoft Events validation
Downloads
450
Readme
🚧 Requirements
- Node.js version 16 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
Publishing Events
Events
An Event fully constituted is composed by a name
, an operation
and multiple objects such as data
, scope
and metadata
.
- The
name
identify the event. - The
operation
will define if it is a creation, update or deletion. - According to the name, we know the
data
and the differentmetadata.origin.method
related. - The
metadata
object is used to determine different information as the ecosystem, the entry point etc. - The
scope
will define 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 type Method = "POST" | "PATCH" | "PUT" | "DELETE";
export interface Metadata {
agent: string;
origin?: {
endpoint: string;
method: Method;
requestId?: string;
};
createdAt: number;
}
📚 Usage
Define and validate an event.
import * as MyEvents, { 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"
}
};
MyEvents.validate<"connector">(event);
Define which operation the event has.
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"
}
};
if (isCreateOperation(event.operation)) {
// Do some code
}
if (isUpdateOperation(event.operation)) {
// Do some code
}
if (isDeleteOperation(event.operation)) {
// Do some code
}
Environment Variables
[!IMPORTANT] Some options takes the lead over environment variables. For instance with:
new Incomer({ dispatcherInactivityOptions: { maxPingInterval: 900_000 }})
the max ping interval will be900_000
even ifMYUNISOFT_INCOMER_MAX_PING_INTERVAL
variable is set.
| variable | description | default |
| --- | --- | --- |
| MYUNISOFT_INCOMER_INIT_TIMEOUT
| Incomer initialisation timeout | 3_500
|
| MYUNISOFT_EVENTS_INIT_EXTERNAL
| Weither Incomer should initialise an external Dispatcher | false
|
| MYUNISOFT_EVENTS_LOGGER_MODE
| Set log level for the default logger | info
|
| 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
|
| 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
|
API
Dispatcher & Incomer class
There is the documentation of Dispatcher, and Incomer classes.
validate< T extends keyof Events >(options: EventOptions): void
Throw an error if a given event is not internaly known.
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"]
Types
EventOptions
export type EventOptions<K extends keyof EventsDefinition.Events> = {
scope: Scope;
metadata: Metadata;
} & EventsDefinition.Events[K];
const event: EventOptions<"connector"> = {
name: "connector",
operation: "CREATE",
scope: {
schemaId: 1
},
metadata: {
agent: "Node",
createdAt: Date.now(),
requestId: crypto.randomUUID();
},
data: {
id: 1,
code: "JFAC"
}
}
EventsOptions
type TupleToObject<T extends readonly any[],
M extends Record<Exclude<keyof T, keyof any[]>, PropertyKey>> =
{ [K in Exclude<keyof T, keyof any[]> as M[K]]: T[K] };
export type EventsOptions<T extends (keyof EventsDefinition.Events)[] = (keyof EventsDefinition.Events)[]> = TupleToObject<[
...(EventOptions<T[number]>)[]
], []>;
const events: EventsOptions<["connector", "accountingFolder"]> = [
{
name: "connector",
operation: "CREATE",
scope: {
schemaId: 1
},
metadata: {
agent: "Node",
createdAt: Date.now(),
requestId: crypto.randomUUID();
},
data: {
id: 1,
code: "JFAC"
}
},
{
name: "accountingFolder",
operation: "CREATE",
scope: {
schemaId: 1
},
metadata: {
agent: "Windev",
createdAt: Date.now(),
requestId: crypto.randomUUID();
},
data: {
id: 1
}
}
];
const event: EventsOptions<["connector", "accountingFolder"]> = {
name: "connector",
operation: "CREATE",
scope: {
schemaId: 1
},
metadata: {
agent: "Node",
createdAt: Date.now(),
requestId: 0
},
data: {
id: 1,
code: "JFAC"
}
}
Exploiting Webhooks
📚 Usage
👀 See here for an example of exploiting webhooks with an http server.
👀 See here for an exhaustive list of MyUnisoft Events you can subscribe to.
⚠️ A Webhook can send multiple Events on a single HTTP POST request.
Types
WebhooksResponse
type WebhookResponse<K extends keyof EventTypes.Events> = {
scope: Scope;
webhookId: string;
createdAt: number;
} & EventTypes.Events[K];
export type WebhooksResponse<T extends (keyof EventTypes.Events)[] = (keyof EventTypes.Events)[]> = [
...(WebhookResponse<T[number]>)[]
];
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()
},
];
Contributors ✨
Thanks goes to these wonderful people (emoji key):
License
MIT