@nimbus-cqrs/core 2.0.0-beta.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/LICENSE +85 -0
- package/README.md +56 -0
- package/esm/_dnt.shims.d.ts +2 -0
- package/esm/_dnt.shims.d.ts.map +1 -0
- package/esm/_dnt.shims.js +57 -0
- package/esm/deps/jsr.io/@std/fmt/1.0.10/colors.d.ts +700 -0
- package/esm/deps/jsr.io/@std/fmt/1.0.10/colors.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/fmt/1.0.10/colors.js +903 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/_util.d.ts +14 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/_util.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/_util.js +65 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/decode_time.d.ts +20 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/decode_time.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/decode_time.js +43 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/mod.d.ts +44 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/mod.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/mod.js +47 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/monotonic_ulid.d.ts +44 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/monotonic_ulid.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/monotonic_ulid.js +51 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/ulid.d.ts +31 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/ulid.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/ulid/1.0.0/ulid.js +37 -0
- package/esm/index.d.ts +18 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +17 -0
- package/esm/lib/eventBus/eventBus.d.ts +329 -0
- package/esm/lib/eventBus/eventBus.d.ts.map +1 -0
- package/esm/lib/eventBus/eventBus.js +473 -0
- package/esm/lib/exception/exception.d.ts +10 -0
- package/esm/lib/exception/exception.d.ts.map +1 -0
- package/esm/lib/exception/exception.js +26 -0
- package/esm/lib/exception/forbiddenException.d.ts +8 -0
- package/esm/lib/exception/forbiddenException.d.ts.map +1 -0
- package/esm/lib/exception/forbiddenException.js +9 -0
- package/esm/lib/exception/genericException.d.ts +8 -0
- package/esm/lib/exception/genericException.d.ts.map +1 -0
- package/esm/lib/exception/genericException.js +9 -0
- package/esm/lib/exception/invalidInputException.d.ts +18 -0
- package/esm/lib/exception/invalidInputException.d.ts.map +1 -0
- package/esm/lib/exception/invalidInputException.js +28 -0
- package/esm/lib/exception/notFoundException.d.ts +8 -0
- package/esm/lib/exception/notFoundException.d.ts.map +1 -0
- package/esm/lib/exception/notFoundException.js +9 -0
- package/esm/lib/exception/unauthorizedException.d.ts +8 -0
- package/esm/lib/exception/unauthorizedException.d.ts.map +1 -0
- package/esm/lib/exception/unauthorizedException.js +9 -0
- package/esm/lib/log/logFormatter.d.ts +26 -0
- package/esm/lib/log/logFormatter.d.ts.map +1 -0
- package/esm/lib/log/logFormatter.js +59 -0
- package/esm/lib/log/logLevel.d.ts +24 -0
- package/esm/lib/log/logLevel.d.ts.map +1 -0
- package/esm/lib/log/logLevel.js +27 -0
- package/esm/lib/log/logger.d.ts +377 -0
- package/esm/lib/log/logger.d.ts.map +1 -0
- package/esm/lib/log/logger.js +394 -0
- package/esm/lib/log/options.d.ts +34 -0
- package/esm/lib/log/options.d.ts.map +1 -0
- package/esm/lib/log/options.js +9 -0
- package/esm/lib/message/command.d.ts +100 -0
- package/esm/lib/message/command.d.ts.map +1 -0
- package/esm/lib/message/command.js +47 -0
- package/esm/lib/message/event.d.ts +103 -0
- package/esm/lib/message/event.d.ts.map +1 -0
- package/esm/lib/message/event.js +47 -0
- package/esm/lib/message/message.d.ts +18 -0
- package/esm/lib/message/message.d.ts.map +1 -0
- package/esm/lib/message/message.js +1 -0
- package/esm/lib/message/query.d.ts +95 -0
- package/esm/lib/message/query.d.ts.map +1 -0
- package/esm/lib/message/query.js +45 -0
- package/esm/lib/message/router.d.ts +233 -0
- package/esm/lib/message/router.d.ts.map +1 -0
- package/esm/lib/message/router.js +304 -0
- package/esm/lib/tracing/withSpan.d.ts +67 -0
- package/esm/lib/tracing/withSpan.d.ts.map +1 -0
- package/esm/lib/tracing/withSpan.js +87 -0
- package/esm/package.json +3 -0
- package/package.json +33 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/lib/message/event.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,MAAM,KAAK,CAAC,KAAK,GAAG,OAAO,IAAI;IACjC,WAAW,EAAE,KAAK,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,KAAK,CAAC;IACZ,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;GAEG;AACH,KAAK,eAAe,GAAG,CAAC,CAAC,QAAQ,CAC7B;IACI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC;IACtC,CAAC,CAAC,SAAS;IACX,CAAC,CAAC,SAAS;IACX,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;IACxB,CAAC,CAAC,UAAU;CACf,CACJ,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,SAAS,CAAC;IACtC,WAAW,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC;IAChB,aAAa,EAAE,CAAC,CAAC,SAAS,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC,cAAc,CAAC;IACvB,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC;IAClB,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,IAAI,EAAE,eAAe,CAAC;IACtB,eAAe,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;CACvC,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,EAAE,eAiBxB,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,CAAC,MAAM,SAAS,KAAK,GAAG,KAAK,IACnD,OAAO,CACL,IAAI,CACA,MAAM,EACN,IAAI,GAAG,eAAe,GAAG,MAAM,GAAG,iBAAiB,GAAG,YAAY,CACrE,CACJ,GACC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC,CAAC;AAE3D;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,SAAS,KAAK,EAC5C,OAAO,gBAAgB,CAAC,MAAM,CAAC,KAChC,MAeF,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ulid } from '../../deps/jsr.io/@std/ulid/1.0.0/mod.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* The Zod schema matching the Event type.
|
|
5
|
+
*
|
|
6
|
+
* Zod is the default for validating incoming messages.
|
|
7
|
+
*
|
|
8
|
+
* We do not infer the Event type from this schema because of
|
|
9
|
+
* slow type issues see https://jsr.io/docs/about-slow-types for more details.
|
|
10
|
+
*/
|
|
11
|
+
export const eventSchema = z.object({
|
|
12
|
+
specversion: z.literal('1.0'),
|
|
13
|
+
id: z.string(),
|
|
14
|
+
correlationid: z.string(),
|
|
15
|
+
time: z.iso.datetime(),
|
|
16
|
+
source: z.string(),
|
|
17
|
+
type: z.string(),
|
|
18
|
+
subject: z.string(),
|
|
19
|
+
data: z.union([
|
|
20
|
+
z.record(z.string(), z.unknown()),
|
|
21
|
+
z.string(),
|
|
22
|
+
z.number(),
|
|
23
|
+
z.array(z.unknown()),
|
|
24
|
+
z.boolean(),
|
|
25
|
+
]),
|
|
26
|
+
datacontenttype: z.string().optional(),
|
|
27
|
+
dataschema: z.url().optional(),
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* Creates an event based on input data with the convenience
|
|
31
|
+
* to skip properties and use the defaults for the rest.
|
|
32
|
+
*/
|
|
33
|
+
export const createEvent = (input) => {
|
|
34
|
+
const event = {
|
|
35
|
+
specversion: '1.0',
|
|
36
|
+
id: input.id ?? ulid(),
|
|
37
|
+
correlationid: input.correlationid ?? ulid(),
|
|
38
|
+
time: input.time ?? new Date().toISOString(),
|
|
39
|
+
source: input.source,
|
|
40
|
+
type: input.type,
|
|
41
|
+
subject: input.subject,
|
|
42
|
+
data: input.data,
|
|
43
|
+
datacontenttype: input.datacontenttype ?? 'application/json',
|
|
44
|
+
...(input.dataschema && { dataschema: input.dataschema }),
|
|
45
|
+
};
|
|
46
|
+
return event;
|
|
47
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Command } from './command.js';
|
|
2
|
+
import type { Event } from './event.js';
|
|
3
|
+
import type { Query } from './query.js';
|
|
4
|
+
/**
|
|
5
|
+
* A message is a communication object that can be passed between
|
|
6
|
+
* systems, modules, functions etc.
|
|
7
|
+
*
|
|
8
|
+
* In the Nimbus ecosystem it is either a Command, Event or Query.
|
|
9
|
+
*
|
|
10
|
+
* Nimbus sticks to the CloudEvents specifications for all messages
|
|
11
|
+
* to make it easier to work with these messages across multiple systems.
|
|
12
|
+
*
|
|
13
|
+
* @see https://cloudevents.io/ for more information.
|
|
14
|
+
*
|
|
15
|
+
* @template TData - The type of the data.
|
|
16
|
+
*/
|
|
17
|
+
export type Message<TData = unknown> = Command<TData> | Event<TData> | Query<TData>;
|
|
18
|
+
//# sourceMappingURL=message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/lib/message/message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,OAAO,CAAC,KAAK,GAAG,OAAO,IAC7B,OAAO,CAAC,KAAK,CAAC,GACd,KAAK,CAAC,KAAK,CAAC,GACZ,KAAK,CAAC,KAAK,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* A query is a message that is sent to the system to request
|
|
4
|
+
* information.
|
|
5
|
+
*
|
|
6
|
+
* Nimbus sticks to the CloudEvents specifications for all messages
|
|
7
|
+
* to make it easier to work with these messages across multiple systems.
|
|
8
|
+
*
|
|
9
|
+
* @see https://cloudevents.io/ for more information.
|
|
10
|
+
*
|
|
11
|
+
* @property {string} specversion - The version of the CloudEvents specification which the query uses.
|
|
12
|
+
* @property {string} id - A globally unique identifier of the query.
|
|
13
|
+
* @property {string} correlationid - A globally unique identifier that indicates a correlation to previous and subsequent messages to this query.
|
|
14
|
+
* @property {string} time - The time when the query was created.
|
|
15
|
+
* @property {string} source - A URI reference that identifies the system that is constructing the query.
|
|
16
|
+
* @property {string} type - The type must follow the CloudEvents naming convention, which uses a reversed domain name as a namespace, followed by a domain-specific name.
|
|
17
|
+
* @property {TData} data - The actual data, containing the specific business payload.
|
|
18
|
+
* @property {string} datacontenttype - A MIME type that indicates the format that the data is in (optional).
|
|
19
|
+
* @property {string} dataschema - An absolute URL to the schema that the data adheres to (optional).
|
|
20
|
+
*
|
|
21
|
+
* @template TData - The type of the data.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* const getOrdersQuery: Query<GetOrdersParams> = {
|
|
25
|
+
* specversion: '1.0',
|
|
26
|
+
* id: '123',
|
|
27
|
+
* time: '2025-01-01T00:00:00Z',
|
|
28
|
+
* source: 'https://nimbus.overlap.at',
|
|
29
|
+
* type: 'at.overlap.nimbus.get-orders',
|
|
30
|
+
* data: {
|
|
31
|
+
* customerId: '666',
|
|
32
|
+
* status: 'fulfilled',
|
|
33
|
+
* },
|
|
34
|
+
* datacontenttype: 'application/json',
|
|
35
|
+
* };
|
|
36
|
+
*/
|
|
37
|
+
export type Query<TData = unknown> = {
|
|
38
|
+
specversion: '1.0';
|
|
39
|
+
id: string;
|
|
40
|
+
correlationid: string;
|
|
41
|
+
time: string;
|
|
42
|
+
source: string;
|
|
43
|
+
type: string;
|
|
44
|
+
data: TData;
|
|
45
|
+
datacontenttype?: string;
|
|
46
|
+
dataschema?: string;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Type alias for the query data field schema.
|
|
50
|
+
*/
|
|
51
|
+
type QueryDataSchema = z.ZodUnion<[
|
|
52
|
+
z.ZodRecord<z.ZodString, z.ZodUnknown>,
|
|
53
|
+
z.ZodString,
|
|
54
|
+
z.ZodNumber,
|
|
55
|
+
z.ZodArray<z.ZodUnknown>,
|
|
56
|
+
z.ZodBoolean
|
|
57
|
+
]>;
|
|
58
|
+
/**
|
|
59
|
+
* Type alias for the query schema shape.
|
|
60
|
+
*/
|
|
61
|
+
export type QuerySchemaType = z.ZodObject<{
|
|
62
|
+
specversion: z.ZodLiteral<'1.0'>;
|
|
63
|
+
id: z.ZodString;
|
|
64
|
+
correlationid: z.ZodString;
|
|
65
|
+
time: z.ZodISODateTime;
|
|
66
|
+
source: z.ZodString;
|
|
67
|
+
type: z.ZodString;
|
|
68
|
+
data: QueryDataSchema;
|
|
69
|
+
datacontenttype: z.ZodOptional<z.ZodString>;
|
|
70
|
+
dataschema: z.ZodOptional<z.ZodURL>;
|
|
71
|
+
}>;
|
|
72
|
+
/**
|
|
73
|
+
* The Zod schema matching the Query type.
|
|
74
|
+
*
|
|
75
|
+
* Zod is the default for validating incomming messages.
|
|
76
|
+
*
|
|
77
|
+
* We do not infer the Query type from this schema because of
|
|
78
|
+
* slow type issues see https://jsr.io/docs/about-slow-types for more details.
|
|
79
|
+
*/
|
|
80
|
+
export declare const querySchema: QuerySchemaType;
|
|
81
|
+
/**
|
|
82
|
+
* Input for creating a query.
|
|
83
|
+
*
|
|
84
|
+
* When a specific query type is provided via the generic parameter,
|
|
85
|
+
* the input is validated against that type. This means fields like
|
|
86
|
+
* `type` and `data` must match the narrower types of `TQuery`.
|
|
87
|
+
*/
|
|
88
|
+
export type CreateQueryInput<TQuery extends Query = Query> = Partial<Pick<TQuery, 'id' | 'correlationid' | 'time' | 'datacontenttype' | 'dataschema'>> & Pick<TQuery, 'type' | 'source' | 'data'>;
|
|
89
|
+
/**
|
|
90
|
+
* Creates a query based on input data with the convenience
|
|
91
|
+
* to skip properties and use the defaults for the rest.
|
|
92
|
+
*/
|
|
93
|
+
export declare const createQuery: <TQuery extends Query>(input: CreateQueryInput<TQuery>) => TQuery;
|
|
94
|
+
export {};
|
|
95
|
+
//# sourceMappingURL=query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/lib/message/query.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,MAAM,KAAK,CAAC,KAAK,GAAG,OAAO,IAAI;IACjC,WAAW,EAAE,KAAK,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,KAAK,CAAC;IACZ,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;GAEG;AACH,KAAK,eAAe,GAAG,CAAC,CAAC,QAAQ,CAC7B;IACI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC;IACtC,CAAC,CAAC,SAAS;IACX,CAAC,CAAC,SAAS;IACX,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC;IACxB,CAAC,CAAC,UAAU;CACf,CACJ,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,SAAS,CAAC;IACtC,WAAW,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC;IAChB,aAAa,EAAE,CAAC,CAAC,SAAS,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC,cAAc,CAAC;IACvB,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC;IAClB,IAAI,EAAE,eAAe,CAAC;IACtB,eAAe,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;CACvC,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,EAAE,eAgBxB,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,CAAC,MAAM,SAAS,KAAK,GAAG,KAAK,IACnD,OAAO,CACL,IAAI,CACA,MAAM,EACN,IAAI,GAAG,eAAe,GAAG,MAAM,GAAG,iBAAiB,GAAG,YAAY,CACrE,CACJ,GACC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC;AAE/C;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,SAAS,KAAK,EAC5C,OAAO,gBAAgB,CAAC,MAAM,CAAC,KAChC,MAcF,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ulid } from '../../deps/jsr.io/@std/ulid/1.0.0/mod.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* The Zod schema matching the Query type.
|
|
5
|
+
*
|
|
6
|
+
* Zod is the default for validating incomming messages.
|
|
7
|
+
*
|
|
8
|
+
* We do not infer the Query type from this schema because of
|
|
9
|
+
* slow type issues see https://jsr.io/docs/about-slow-types for more details.
|
|
10
|
+
*/
|
|
11
|
+
export const querySchema = z.object({
|
|
12
|
+
specversion: z.literal('1.0'),
|
|
13
|
+
id: z.string(),
|
|
14
|
+
correlationid: z.string(),
|
|
15
|
+
time: z.iso.datetime(),
|
|
16
|
+
source: z.string(),
|
|
17
|
+
type: z.string(),
|
|
18
|
+
data: z.union([
|
|
19
|
+
z.record(z.string(), z.unknown()),
|
|
20
|
+
z.string(),
|
|
21
|
+
z.number(),
|
|
22
|
+
z.array(z.unknown()),
|
|
23
|
+
z.boolean(),
|
|
24
|
+
]),
|
|
25
|
+
datacontenttype: z.string().optional(),
|
|
26
|
+
dataschema: z.url().optional(),
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Creates a query based on input data with the convenience
|
|
30
|
+
* to skip properties and use the defaults for the rest.
|
|
31
|
+
*/
|
|
32
|
+
export const createQuery = (input) => {
|
|
33
|
+
const query = {
|
|
34
|
+
specversion: '1.0',
|
|
35
|
+
id: input.id ?? ulid(),
|
|
36
|
+
correlationid: input.correlationid ?? ulid(),
|
|
37
|
+
time: input.time ?? new Date().toISOString(),
|
|
38
|
+
source: input.source,
|
|
39
|
+
type: input.type,
|
|
40
|
+
data: input.data,
|
|
41
|
+
datacontenttype: input.datacontenttype ?? 'application/json',
|
|
42
|
+
...(input.dataschema && { dataschema: input.dataschema }),
|
|
43
|
+
};
|
|
44
|
+
return query;
|
|
45
|
+
};
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type { Message } from './message.js';
|
|
3
|
+
/**
|
|
4
|
+
* The message handler type - transport-agnostic, just returns domain data.
|
|
5
|
+
*
|
|
6
|
+
* @template TInput - The type of the input message.
|
|
7
|
+
* @template TOutput - The type of the data returned by the handler.
|
|
8
|
+
*/
|
|
9
|
+
export type MessageHandler<TInput extends Message = Message, TOutput = unknown> = (input: TInput) => Promise<TOutput> | TOutput;
|
|
10
|
+
/**
|
|
11
|
+
* Options for creating a MessageRouter.
|
|
12
|
+
*/
|
|
13
|
+
export type MessageRouterOptions = {
|
|
14
|
+
/**
|
|
15
|
+
* The name of the router instance for metrics and traces.
|
|
16
|
+
* Defaults to 'default'.
|
|
17
|
+
*/
|
|
18
|
+
name?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Optional callback invoked when a message is received for routing.
|
|
21
|
+
* Useful for custom logging or debugging of incoming messages.
|
|
22
|
+
*
|
|
23
|
+
* @param input - The incoming message to be routed.
|
|
24
|
+
*/
|
|
25
|
+
logInput?: (input: any) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Optional callback invoked after a message has been successfully handled.
|
|
28
|
+
* Useful for custom logging or debugging of handler results.
|
|
29
|
+
*
|
|
30
|
+
* @param output - The result returned by the message handler.
|
|
31
|
+
*/
|
|
32
|
+
logOutput?: (output: any) => void;
|
|
33
|
+
};
|
|
34
|
+
type ZodSchema<T = any> = z.ZodType<T>;
|
|
35
|
+
/**
|
|
36
|
+
* The MessageRouter routes messages to their handlers based on the type value of the message.
|
|
37
|
+
*
|
|
38
|
+
* Messages are validated against their registered Zod schemas before being passed to handlers.
|
|
39
|
+
* All routing operations are instrumented with OpenTelemetry tracing and metrics for observability.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* import { createCommand, MessageRouter } from '@nimbus/core';
|
|
44
|
+
*
|
|
45
|
+
* const messageRouter = new MessageRouter({
|
|
46
|
+
* name: 'api',
|
|
47
|
+
* logInput: (input) => {
|
|
48
|
+
* console.log('Received message:', input.type);
|
|
49
|
+
* },
|
|
50
|
+
* logOutput: (output) => {
|
|
51
|
+
* console.log('Handler result:', output);
|
|
52
|
+
* },
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* // Register command handler
|
|
56
|
+
* messageRouter.register(
|
|
57
|
+
* 'at.overlap.nimbus.create-order',
|
|
58
|
+
* createOrderHandler,
|
|
59
|
+
* createOrderCommandSchema,
|
|
60
|
+
* );
|
|
61
|
+
*
|
|
62
|
+
* // Register query handler
|
|
63
|
+
* messageRouter.register(
|
|
64
|
+
* 'at.overlap.nimbus.get-order',
|
|
65
|
+
* getOrderHandler,
|
|
66
|
+
* getOrderQuerySchema,
|
|
67
|
+
* );
|
|
68
|
+
*
|
|
69
|
+
* // Route a command
|
|
70
|
+
* const command = createCommand({
|
|
71
|
+
* type: 'at.overlap.nimbus.create-order',
|
|
72
|
+
* source: 'https://api.example.com',
|
|
73
|
+
* data: { customerId: '123', items: ['item-1', 'item-2'] },
|
|
74
|
+
* });
|
|
75
|
+
*
|
|
76
|
+
* const result = await messageRouter.route(command);
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare class MessageRouter {
|
|
80
|
+
private readonly _handlers;
|
|
81
|
+
private readonly _name;
|
|
82
|
+
private readonly _logInput?;
|
|
83
|
+
private readonly _logOutput?;
|
|
84
|
+
constructor(options?: MessageRouterOptions);
|
|
85
|
+
/**
|
|
86
|
+
* Register a handler for a specific message type.
|
|
87
|
+
*
|
|
88
|
+
* @param messageType - The message type as defined in the CloudEvents specification
|
|
89
|
+
* (e.g., 'at.overlap.nimbus.create-order').
|
|
90
|
+
* @param handler - The async handler function that processes the message and returns a result.
|
|
91
|
+
* @param schema - The Zod schema to validate the incoming message before passing to the handler.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* import { commandSchema, type Command, getRouter } from '@nimbus/core';
|
|
96
|
+
* import { z } from 'zod';
|
|
97
|
+
*
|
|
98
|
+
* // Define the command type and schema
|
|
99
|
+
* const CREATE_ORDER_TYPE = 'at.overlap.nimbus.create-order';
|
|
100
|
+
*
|
|
101
|
+
* const createOrderSchema = commandSchema.extend({
|
|
102
|
+
* type: z.literal(CREATE_ORDER_TYPE),
|
|
103
|
+
* data: z.object({
|
|
104
|
+
* customerId: z.string(),
|
|
105
|
+
* items: z.array(z.string()),
|
|
106
|
+
* }),
|
|
107
|
+
* });
|
|
108
|
+
* type CreateOrderCommand = z.infer<typeof createOrderSchema>;
|
|
109
|
+
*
|
|
110
|
+
* // Define the handler
|
|
111
|
+
* const createOrderHandler = async (command: CreateOrderCommand) => {
|
|
112
|
+
* // Process the command and return the result
|
|
113
|
+
* return { orderId: '12345', status: 'created' };
|
|
114
|
+
* };
|
|
115
|
+
*
|
|
116
|
+
* // Register the handler
|
|
117
|
+
* const router = getRouter('default');
|
|
118
|
+
* router.register(CREATE_ORDER_TYPE, createOrderHandler, createOrderSchema);
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
register<TInput extends Message = Message, TOutput = unknown>(messageType: string, handler: MessageHandler<TInput, TOutput>, schema: ZodSchema): void;
|
|
122
|
+
/**
|
|
123
|
+
* Route a message to its handler.
|
|
124
|
+
*
|
|
125
|
+
* The message is validated against the registered schema before being passed to the handler.
|
|
126
|
+
* The routing operation is instrumented with OpenTelemetry tracing and metrics.
|
|
127
|
+
*
|
|
128
|
+
* @param input - The CloudEvents-compliant message to route (command, query, or event).
|
|
129
|
+
* @returns The result from the handler.
|
|
130
|
+
*
|
|
131
|
+
* @throws {NotFoundException} If no handler is registered for the message type.
|
|
132
|
+
* @throws {InvalidInputException} If the message has no type attribute or fails schema validation.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```ts
|
|
136
|
+
* import { createCommand, getRouter } from '@nimbus/core';
|
|
137
|
+
*
|
|
138
|
+
* const router = getRouter('default');
|
|
139
|
+
*
|
|
140
|
+
* // Create a command with all CloudEvents properties
|
|
141
|
+
* const command = createCommand({
|
|
142
|
+
* type: 'at.overlap.nimbus.create-order',
|
|
143
|
+
* source: 'https://api.example.com',
|
|
144
|
+
* correlationid: '550e8400-e29b-41d4-a716-446655440000',
|
|
145
|
+
* data: {
|
|
146
|
+
* customerId: '123',
|
|
147
|
+
* items: ['item-1', 'item-2'],
|
|
148
|
+
* },
|
|
149
|
+
* datacontenttype: 'application/json',
|
|
150
|
+
* });
|
|
151
|
+
*
|
|
152
|
+
* // Route the command to its registered handler
|
|
153
|
+
* const result = await router.route(command);
|
|
154
|
+
* console.log('Order created:', result);
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
route(input: any): Promise<unknown>;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Setup a named MessageRouter instance and register it for later retrieval.
|
|
161
|
+
*
|
|
162
|
+
* Use this function to configure a MessageRouter with specific options at application
|
|
163
|
+
* startup, then retrieve it later using {@link getRouter}.
|
|
164
|
+
*
|
|
165
|
+
* @param name - The unique name for this MessageRouter instance.
|
|
166
|
+
* @param options - Optional configuration options for the MessageRouter.
|
|
167
|
+
* @param options.logInput - Optional callback invoked when a message is received for routing.
|
|
168
|
+
* @param options.logOutput - Optional callback invoked after a message has been successfully handled.
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* import { getLogger, setupRouter } from '@nimbus/core';
|
|
173
|
+
*
|
|
174
|
+
* // At application startup, configure the router with all options
|
|
175
|
+
* setupRouter('default', {
|
|
176
|
+
* logInput: (input) => {
|
|
177
|
+
* getLogger().debug({
|
|
178
|
+
* category: 'Router',
|
|
179
|
+
* message: 'Received message',
|
|
180
|
+
* data: { type: input.type, correlationId: input.correlationid },
|
|
181
|
+
* correlationId: input.correlationid,
|
|
182
|
+
* });
|
|
183
|
+
* },
|
|
184
|
+
* logOutput: (output) => {
|
|
185
|
+
* getLogger().debug({
|
|
186
|
+
* category: 'Router',
|
|
187
|
+
* message: 'Handler completed',
|
|
188
|
+
* data: { output },
|
|
189
|
+
* });
|
|
190
|
+
* },
|
|
191
|
+
* });
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
export declare const setupRouter: (name: string, options?: Omit<MessageRouterOptions, "name">) => void;
|
|
195
|
+
/**
|
|
196
|
+
* Get a named MessageRouter instance.
|
|
197
|
+
*
|
|
198
|
+
* If a MessageRouter with the given name has been configured via {@link setupRouter},
|
|
199
|
+
* that instance is returned. Otherwise, a new MessageRouter with default options is created
|
|
200
|
+
* and registered.
|
|
201
|
+
*
|
|
202
|
+
* @param name - The name of the MessageRouter instance to retrieve. Defaults to 'default'.
|
|
203
|
+
* @returns The MessageRouter instance.
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* ```ts
|
|
207
|
+
* import { createCommand, getRouter } from '@nimbus/core';
|
|
208
|
+
*
|
|
209
|
+
* // Get the router configured earlier with setupRouter
|
|
210
|
+
* const router = getRouter('default');
|
|
211
|
+
*
|
|
212
|
+
* // Register handlers
|
|
213
|
+
* router.register(
|
|
214
|
+
* 'at.overlap.nimbus.create-order',
|
|
215
|
+
* createOrderHandler,
|
|
216
|
+
* createOrderSchema,
|
|
217
|
+
* );
|
|
218
|
+
*
|
|
219
|
+
* // Route a message
|
|
220
|
+
* const command = createCommand({
|
|
221
|
+
* type: 'at.overlap.nimbus.create-order',
|
|
222
|
+
* source: 'https://api.example.com',
|
|
223
|
+
* correlationid: '550e8400-e29b-41d4-a716-446655440000',
|
|
224
|
+
* data: { customerId: '123', items: ['item-1'] },
|
|
225
|
+
* datacontenttype: 'application/json',
|
|
226
|
+
* });
|
|
227
|
+
*
|
|
228
|
+
* const result = await router.route(command);
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
export declare const getRouter: (name?: string) => MessageRouter;
|
|
232
|
+
export {};
|
|
233
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/lib/message/router.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAI7B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAoB5C;;;;;GAKG;AACH,MAAM,MAAM,cAAc,CACtB,MAAM,SAAS,OAAO,GAAG,OAAO,EAChC,OAAO,GAAG,OAAO,IACjB,CACA,KAAK,EAAE,MAAM,KACZ,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;AAEhC;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IAC/B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAChC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,KAAK,SAAS,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAUvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmC;IAC7D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAuB;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAwB;gBAGhD,OAAO,CAAC,EAAE,oBAAoB;IAQlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACI,QAAQ,CAAC,MAAM,SAAS,OAAO,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAC/D,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,MAAM,EAAE,SAAS,GAClB,IAAI;IAYP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IACU,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;CAkGnD;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,eAAO,MAAM,WAAW,GACpB,MAAM,MAAM,EACZ,UAAU,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC,KAC7C,IAEF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,SAAS,GAAI,OAAM,MAAkB,KAAG,aASpD,CAAC"}
|