@nimbus-cqrs/core 2.1.2 → 2.2.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/esm/lib/exception/exception.d.ts +1 -1
- package/esm/lib/exception/exception.d.ts.map +1 -1
- package/esm/lib/exception/invalidInputException.d.ts +1 -1
- package/esm/lib/exception/invalidInputException.d.ts.map +1 -1
- package/esm/lib/message/command.d.ts +11 -1
- package/esm/lib/message/command.d.ts.map +1 -1
- package/esm/lib/message/command.js +17 -10
- package/esm/lib/message/event.d.ts +11 -1
- package/esm/lib/message/event.d.ts.map +1 -1
- package/esm/lib/message/event.js +17 -10
- package/esm/lib/message/message.d.ts +14 -0
- package/esm/lib/message/message.d.ts.map +1 -1
- package/esm/lib/message/message.js +47 -1
- package/esm/lib/message/query.d.ts +11 -1
- package/esm/lib/message/query.d.ts.map +1 -1
- package/esm/lib/message/query.js +16 -9
- package/package.json +2 -2
|
@@ -5,6 +5,6 @@ export declare class Exception extends Error {
|
|
|
5
5
|
details?: Record<string, unknown>;
|
|
6
6
|
statusCode?: number;
|
|
7
7
|
constructor(name: string, message: string, details?: Record<string, unknown>, statusCode?: number);
|
|
8
|
-
fromError(error: Error):
|
|
8
|
+
fromError(error: Error): this;
|
|
9
9
|
}
|
|
10
10
|
//# sourceMappingURL=exception.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exception.d.ts","sourceRoot":"","sources":["../../../src/lib/exception/exception.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,SAAU,SAAQ,KAAK;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAGvB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,UAAU,CAAC,EAAE,MAAM;IAmBhB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,
|
|
1
|
+
{"version":3,"file":"exception.d.ts","sourceRoot":"","sources":["../../../src/lib/exception/exception.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,SAAU,SAAQ,KAAK;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAGvB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,UAAU,CAAC,EAAE,MAAM;IAmBhB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;CAMvC"}
|
|
@@ -13,6 +13,6 @@ export declare class InvalidInputException extends Exception {
|
|
|
13
13
|
*
|
|
14
14
|
* @returns {InvalidInputException} The InvalidInputException.
|
|
15
15
|
*/
|
|
16
|
-
fromZodError(error: ZodError):
|
|
16
|
+
fromZodError(error: ZodError): this;
|
|
17
17
|
}
|
|
18
18
|
//# sourceMappingURL=invalidInputException.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invalidInputException.d.ts","sourceRoot":"","sources":["../../../src/lib/exception/invalidInputException.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,SAAS;gBACpC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAS/D;;;;;;;OAOG;IACI,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,
|
|
1
|
+
{"version":3,"file":"invalidInputException.d.ts","sourceRoot":"","sources":["../../../src/lib/exception/invalidInputException.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,SAAS;gBACpC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAS/D;;;;;;;OAOG;IACI,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;CAa7C"}
|
|
@@ -20,6 +20,12 @@ import { z } from 'zod';
|
|
|
20
20
|
* @property {string} datacontenttype - A MIME type that indicates the format that the data is in (optional).
|
|
21
21
|
* @property {string} dataschema - An absolute URL to the schema that the data adheres to (optional).
|
|
22
22
|
*
|
|
23
|
+
* Commands may include additional CloudEvents extension attributes such as
|
|
24
|
+
* `metadata` or `authcontext`. Define them on a command-specific schema via
|
|
25
|
+
* {@link commandSchema.extend} or as an intersection type.
|
|
26
|
+
*
|
|
27
|
+
* @see https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md#extension-context-attributes
|
|
28
|
+
*
|
|
23
29
|
* @template TData - The type of the data.
|
|
24
30
|
*
|
|
25
31
|
* @example
|
|
@@ -49,6 +55,10 @@ export type Command<TData = unknown> = {
|
|
|
49
55
|
datacontenttype?: string;
|
|
50
56
|
dataschema?: string;
|
|
51
57
|
};
|
|
58
|
+
/**
|
|
59
|
+
* Known command properties handled by {@link createCommand}.
|
|
60
|
+
*/
|
|
61
|
+
type CommandKnownProperty = 'specversion' | 'id' | 'correlationid' | 'time' | 'source' | 'type' | 'subject' | 'data' | 'datacontenttype' | 'dataschema';
|
|
52
62
|
/**
|
|
53
63
|
* Type alias for the command data field schema.
|
|
54
64
|
*/
|
|
@@ -90,7 +100,7 @@ export declare const commandSchema: CommandSchemaType;
|
|
|
90
100
|
* the input is validated against that type. This means fields like
|
|
91
101
|
* `type` and `data` must match the narrower types of `TCommand`.
|
|
92
102
|
*/
|
|
93
|
-
export type CreateCommandInput<TCommand extends Command = Command> = Partial<Pick<TCommand, 'id' | 'correlationid' | 'time' | 'subject' | 'datacontenttype' | 'dataschema'>> & Pick<TCommand, 'type' | 'source' | 'data'
|
|
103
|
+
export type CreateCommandInput<TCommand extends Command = Command> = Partial<Pick<TCommand, 'id' | 'correlationid' | 'time' | 'subject' | 'datacontenttype' | 'dataschema'>> & Pick<TCommand, 'type' | 'source' | 'data'> & Partial<Omit<TCommand, CommandKnownProperty>>;
|
|
94
104
|
/**
|
|
95
105
|
* Creates a command based on input data with the convenience
|
|
96
106
|
* to skip properties and use the defaults for the rest.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/lib/message/command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/lib/message/command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,MAAM,OAAO,CAAC,KAAK,GAAG,OAAO,IAAI;IACnC,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,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,KAAK,CAAC;IACZ,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;GAEG;AACH,KAAK,oBAAoB,GACnB,aAAa,GACb,IAAI,GACJ,eAAe,GACf,MAAM,GACN,QAAQ,GACR,MAAM,GACN,SAAS,GACT,MAAM,GACN,iBAAiB,GACjB,YAAY,CAAC;AAEnB;;GAEG;AACH,KAAK,iBAAiB,GAAG,CAAC,CAAC,QAAQ,CAC/B;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,iBAAiB,GAAG,CAAC,CAAC,SAAS,CAAC;IACxC,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,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACpC,IAAI,EAAE,iBAAiB,CAAC;IACxB,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,aAAa,EAAE,iBAiBL,CAAC;AAExB;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,CAAC,QAAQ,SAAS,OAAO,GAAG,OAAO,IAC3D,OAAO,CACL,IAAI,CACA,QAAQ,EACN,IAAI,GACJ,eAAe,GACf,MAAM,GACN,SAAS,GACT,iBAAiB,GACjB,YAAY,CACjB,CACJ,GACC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC,GAC1C,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,SAAS,OAAO,EAClD,OAAO,kBAAkB,CAAC,QAAQ,CAAC,KACpC,QAuCF,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ulid } from '../../deps/jsr.io/@std/ulid/1.0.0/mod.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
+
import { warnOnInvalidExtensionAttributeNames } from './message.js';
|
|
3
4
|
/**
|
|
4
5
|
* The Zod schema matching the Command type.
|
|
5
6
|
*
|
|
@@ -8,7 +9,7 @@ import { z } from 'zod';
|
|
|
8
9
|
* We do not infer the Command type from this schema because of
|
|
9
10
|
* slow type issues see https://jsr.io/docs/about-slow-types for more details.
|
|
10
11
|
*/
|
|
11
|
-
export const commandSchema = z.
|
|
12
|
+
export const commandSchema = z.looseObject({
|
|
12
13
|
specversion: z.literal('1.0'),
|
|
13
14
|
id: z.string(),
|
|
14
15
|
correlationid: z.string(),
|
|
@@ -31,17 +32,23 @@ export const commandSchema = z.object({
|
|
|
31
32
|
* to skip properties and use the defaults for the rest.
|
|
32
33
|
*/
|
|
33
34
|
export const createCommand = (input) => {
|
|
35
|
+
const { id, correlationid, time, source, type, subject, data, datacontenttype, dataschema, ...extensions } = input;
|
|
36
|
+
const correlationIdWithFallback = correlationid ?? ulid();
|
|
37
|
+
if (Object.keys(extensions).length > 0) {
|
|
38
|
+
warnOnInvalidExtensionAttributeNames(extensions, correlationIdWithFallback, createCommand);
|
|
39
|
+
}
|
|
34
40
|
const command = {
|
|
35
41
|
specversion: '1.0',
|
|
36
|
-
id:
|
|
37
|
-
correlationid:
|
|
38
|
-
time:
|
|
39
|
-
source
|
|
40
|
-
type
|
|
41
|
-
...(
|
|
42
|
-
data
|
|
43
|
-
datacontenttype:
|
|
44
|
-
...(
|
|
42
|
+
id: id ?? ulid(),
|
|
43
|
+
correlationid: correlationIdWithFallback,
|
|
44
|
+
time: time ?? new Date().toISOString(),
|
|
45
|
+
source,
|
|
46
|
+
type,
|
|
47
|
+
...(subject && { subject }),
|
|
48
|
+
data,
|
|
49
|
+
datacontenttype: datacontenttype ?? 'application/json',
|
|
50
|
+
...(dataschema && { dataschema }),
|
|
51
|
+
...extensions,
|
|
45
52
|
};
|
|
46
53
|
return command;
|
|
47
54
|
};
|
|
@@ -20,6 +20,12 @@ import { z } from 'zod';
|
|
|
20
20
|
* @property {string} datacontenttype - A MIME type that indicates the format that the data is in (optional).
|
|
21
21
|
* @property {string} dataschema - An absolute URL to the schema that the data adheres to (optional).
|
|
22
22
|
*
|
|
23
|
+
* Events may include additional CloudEvents extension attributes such as
|
|
24
|
+
* `metadata` or `authcontext`. Define them on an event-specific schema via
|
|
25
|
+
* {@link eventSchema.extend} or as an intersection type.
|
|
26
|
+
*
|
|
27
|
+
* @see https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md#extension-context-attributes
|
|
28
|
+
*
|
|
23
29
|
* @template TData - The type of the data.
|
|
24
30
|
*
|
|
25
31
|
* @example
|
|
@@ -52,6 +58,10 @@ export type Event<TData = unknown> = {
|
|
|
52
58
|
datacontenttype?: string;
|
|
53
59
|
dataschema?: string;
|
|
54
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* Known event properties handled by {@link createEvent}.
|
|
63
|
+
*/
|
|
64
|
+
type EventKnownProperty = 'specversion' | 'id' | 'correlationid' | 'time' | 'source' | 'type' | 'subject' | 'data' | 'datacontenttype' | 'dataschema';
|
|
55
65
|
/**
|
|
56
66
|
* Type alias for the event data field schema.
|
|
57
67
|
*/
|
|
@@ -93,7 +103,7 @@ export declare const eventSchema: EventSchemaType;
|
|
|
93
103
|
* the input is validated against that type. This means fields like
|
|
94
104
|
* `type` and `data` must match the narrower types of `TEvent`.
|
|
95
105
|
*/
|
|
96
|
-
export type CreateEventInput<TEvent extends Event = Event> = Partial<Pick<TEvent, 'id' | 'correlationid' | 'time' | 'datacontenttype' | 'dataschema'>> & Pick<TEvent, 'type' | 'source' | 'subject' | 'data'
|
|
106
|
+
export type CreateEventInput<TEvent extends Event = Event> = Partial<Pick<TEvent, 'id' | 'correlationid' | 'time' | 'datacontenttype' | 'dataschema'>> & Pick<TEvent, 'type' | 'source' | 'subject' | 'data'> & Partial<Omit<TEvent, EventKnownProperty>>;
|
|
97
107
|
/**
|
|
98
108
|
* Creates an event based on input data with the convenience
|
|
99
109
|
* to skip properties and use the defaults for the rest.
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/lib/message/event.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;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,kBAAkB,GACjB,aAAa,GACb,IAAI,GACJ,eAAe,GACf,MAAM,GACN,QAAQ,GACR,MAAM,GACN,SAAS,GACT,MAAM,GACN,iBAAiB,GACjB,YAAY,CAAC;AAEnB;;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,eAiBL,CAAC;AAEtB;;;;;;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,GACpD,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,SAAS,KAAK,EAC5C,OAAO,gBAAgB,CAAC,MAAM,CAAC,KAChC,MAuCF,CAAC"}
|
package/esm/lib/message/event.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ulid } from '../../deps/jsr.io/@std/ulid/1.0.0/mod.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
+
import { warnOnInvalidExtensionAttributeNames } from './message.js';
|
|
3
4
|
/**
|
|
4
5
|
* The Zod schema matching the Event type.
|
|
5
6
|
*
|
|
@@ -8,7 +9,7 @@ import { z } from 'zod';
|
|
|
8
9
|
* We do not infer the Event type from this schema because of
|
|
9
10
|
* slow type issues see https://jsr.io/docs/about-slow-types for more details.
|
|
10
11
|
*/
|
|
11
|
-
export const eventSchema = z.
|
|
12
|
+
export const eventSchema = z.looseObject({
|
|
12
13
|
specversion: z.literal('1.0'),
|
|
13
14
|
id: z.string(),
|
|
14
15
|
correlationid: z.string(),
|
|
@@ -31,17 +32,23 @@ export const eventSchema = z.object({
|
|
|
31
32
|
* to skip properties and use the defaults for the rest.
|
|
32
33
|
*/
|
|
33
34
|
export const createEvent = (input) => {
|
|
35
|
+
const { id, correlationid, time, source, type, subject, data, datacontenttype, dataschema, ...extensions } = input;
|
|
36
|
+
const correlationIdWithFallback = correlationid ?? ulid();
|
|
37
|
+
if (Object.keys(extensions).length > 0) {
|
|
38
|
+
warnOnInvalidExtensionAttributeNames(extensions, correlationIdWithFallback, createEvent);
|
|
39
|
+
}
|
|
34
40
|
const event = {
|
|
35
41
|
specversion: '1.0',
|
|
36
|
-
id:
|
|
37
|
-
correlationid:
|
|
38
|
-
time:
|
|
39
|
-
source
|
|
40
|
-
type
|
|
41
|
-
subject
|
|
42
|
-
data
|
|
43
|
-
datacontenttype:
|
|
44
|
-
...(
|
|
42
|
+
id: id ?? ulid(),
|
|
43
|
+
correlationid: correlationIdWithFallback,
|
|
44
|
+
time: time ?? new Date().toISOString(),
|
|
45
|
+
source,
|
|
46
|
+
type,
|
|
47
|
+
subject,
|
|
48
|
+
data,
|
|
49
|
+
datacontenttype: datacontenttype ?? 'application/json',
|
|
50
|
+
...(dataschema && { dataschema }),
|
|
51
|
+
...extensions,
|
|
45
52
|
};
|
|
46
53
|
return event;
|
|
47
54
|
};
|
|
@@ -15,4 +15,18 @@ import type { Query } from './query.js';
|
|
|
15
15
|
* @template TData - The type of the data.
|
|
16
16
|
*/
|
|
17
17
|
export type Message<TData = unknown> = Command<TData> | Event<TData> | Query<TData>;
|
|
18
|
+
/**
|
|
19
|
+
* Validates CloudEvents extension attribute names and logs a warning when invalid.
|
|
20
|
+
*
|
|
21
|
+
* Called by {@link createCommand}, {@link createEvent}, and {@link createQuery}
|
|
22
|
+
* to check extension attributes against the CloudEvents naming rules. Invalid
|
|
23
|
+
* names are logged with a stack trace anchored at the caller function.
|
|
24
|
+
*
|
|
25
|
+
* @see https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md#extension-context-attributes
|
|
26
|
+
*
|
|
27
|
+
* @param {Record<string, unknown>} extensions - Extension attributes to validate, excluding known CloudEvents context attributes.
|
|
28
|
+
* @param {string | undefined} correlationId - Optional correlation ID included in the warning log for tracing.
|
|
29
|
+
* @param {(...args: never[]) => unknown} stackTraceAnchor - Function used to anchor the warning stack trace at the message factory caller (for example {@link createCommand}).
|
|
30
|
+
*/
|
|
31
|
+
export declare const warnOnInvalidExtensionAttributeNames: (extensions: Record<string, unknown>, correlationId: string | undefined, stackTraceAnchor: (...args: never[]) => unknown) => void;
|
|
18
32
|
//# sourceMappingURL=message.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/lib/message/message.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/lib/message/message.ts"],"names":[],"mappings":"AACA,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;AAsCnB;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oCAAoC,GAC7C,YAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,eAAe,MAAM,GAAG,SAAS,EACjC,kBAAkB,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,KAChD,IAkBF,CAAC"}
|
|
@@ -1 +1,47 @@
|
|
|
1
|
-
|
|
1
|
+
import { getLogger } from '../log/logger.js';
|
|
2
|
+
/**
|
|
3
|
+
* CloudEvents extension context attribute names must consist of lowercase
|
|
4
|
+
* ASCII letters or digits.
|
|
5
|
+
*
|
|
6
|
+
* @see https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md#extension-context-attributes
|
|
7
|
+
*/
|
|
8
|
+
const getInvalidExtensionAttributeNames = (extensions) => {
|
|
9
|
+
const EXTENSION_ATTRIBUTE_NAME_PATTERN = /^[a-z0-9]+$/;
|
|
10
|
+
return Object.keys(extensions).filter((name) => !EXTENSION_ATTRIBUTE_NAME_PATTERN.test(name));
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Create an error object to capture the stack trace for better debugging.
|
|
14
|
+
*/
|
|
15
|
+
const createInvalidExtensionAttributeNamesError = (invalidNames, stackTraceAnchor) => {
|
|
16
|
+
const error = new Error(`Invalid CloudEvents extension attribute names: ${invalidNames.join(', ')}`);
|
|
17
|
+
if (typeof Error.captureStackTrace === 'function') {
|
|
18
|
+
Error.captureStackTrace(error, stackTraceAnchor);
|
|
19
|
+
}
|
|
20
|
+
return error;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Validates CloudEvents extension attribute names and logs a warning when invalid.
|
|
24
|
+
*
|
|
25
|
+
* Called by {@link createCommand}, {@link createEvent}, and {@link createQuery}
|
|
26
|
+
* to check extension attributes against the CloudEvents naming rules. Invalid
|
|
27
|
+
* names are logged with a stack trace anchored at the caller function.
|
|
28
|
+
*
|
|
29
|
+
* @see https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md#extension-context-attributes
|
|
30
|
+
*
|
|
31
|
+
* @param {Record<string, unknown>} extensions - Extension attributes to validate, excluding known CloudEvents context attributes.
|
|
32
|
+
* @param {string | undefined} correlationId - Optional correlation ID included in the warning log for tracing.
|
|
33
|
+
* @param {(...args: never[]) => unknown} stackTraceAnchor - Function used to anchor the warning stack trace at the message factory caller (for example {@link createCommand}).
|
|
34
|
+
*/
|
|
35
|
+
export const warnOnInvalidExtensionAttributeNames = (extensions, correlationId, stackTraceAnchor) => {
|
|
36
|
+
const invalidNames = getInvalidExtensionAttributeNames(extensions);
|
|
37
|
+
if (invalidNames.length === 0) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
getLogger().warn({
|
|
41
|
+
category: 'Nimbus',
|
|
42
|
+
message: 'Extension attribute names must use lowercase ASCII letters or digits only per CloudEvents specification.',
|
|
43
|
+
data: { invalidAttributeNames: invalidNames },
|
|
44
|
+
error: createInvalidExtensionAttributeNamesError(invalidNames, stackTraceAnchor),
|
|
45
|
+
...(correlationId && { correlationId }),
|
|
46
|
+
});
|
|
47
|
+
};
|
|
@@ -18,6 +18,12 @@ import { z } from 'zod';
|
|
|
18
18
|
* @property {string} datacontenttype - A MIME type that indicates the format that the data is in (optional).
|
|
19
19
|
* @property {string} dataschema - An absolute URL to the schema that the data adheres to (optional).
|
|
20
20
|
*
|
|
21
|
+
* Queries may include additional CloudEvents extension attributes such as
|
|
22
|
+
* `metadata` or `authcontext`. Define them on a query-specific schema via
|
|
23
|
+
* {@link querySchema.extend} or as an intersection type.
|
|
24
|
+
*
|
|
25
|
+
* @see https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md#extension-context-attributes
|
|
26
|
+
*
|
|
21
27
|
* @template TData - The type of the data.
|
|
22
28
|
*
|
|
23
29
|
* @example
|
|
@@ -45,6 +51,10 @@ export type Query<TData = unknown> = {
|
|
|
45
51
|
datacontenttype?: string;
|
|
46
52
|
dataschema?: string;
|
|
47
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* Known query properties handled by {@link createQuery}.
|
|
56
|
+
*/
|
|
57
|
+
type QueryKnownProperty = 'specversion' | 'id' | 'correlationid' | 'time' | 'source' | 'type' | 'data' | 'datacontenttype' | 'dataschema';
|
|
48
58
|
/**
|
|
49
59
|
* Type alias for the query data field schema.
|
|
50
60
|
*/
|
|
@@ -85,7 +95,7 @@ export declare const querySchema: QuerySchemaType;
|
|
|
85
95
|
* the input is validated against that type. This means fields like
|
|
86
96
|
* `type` and `data` must match the narrower types of `TQuery`.
|
|
87
97
|
*/
|
|
88
|
-
export type CreateQueryInput<TQuery extends Query = Query> = Partial<Pick<TQuery, 'id' | 'correlationid' | 'time' | 'datacontenttype' | 'dataschema'>> & Pick<TQuery, 'type' | 'source' | 'data'
|
|
98
|
+
export type CreateQueryInput<TQuery extends Query = Query> = Partial<Pick<TQuery, 'id' | 'correlationid' | 'time' | 'datacontenttype' | 'dataschema'>> & Pick<TQuery, 'type' | 'source' | 'data'> & Partial<Omit<TQuery, QueryKnownProperty>>;
|
|
89
99
|
/**
|
|
90
100
|
* Creates a query based on input data with the convenience
|
|
91
101
|
* to skip properties and use the defaults for the rest.
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/lib/message/query.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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,IAAI,EAAE,KAAK,CAAC;IACZ,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;GAEG;AACH,KAAK,kBAAkB,GACjB,aAAa,GACb,IAAI,GACJ,eAAe,GACf,MAAM,GACN,QAAQ,GACR,MAAM,GACN,MAAM,GACN,iBAAiB,GACjB,YAAY,CAAC;AAEnB;;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,eAgBL,CAAC;AAEtB;;;;;;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,GACxC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,SAAS,KAAK,EAC5C,OAAO,gBAAgB,CAAC,MAAM,CAAC,KAChC,MAqCF,CAAC"}
|
package/esm/lib/message/query.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ulid } from '../../deps/jsr.io/@std/ulid/1.0.0/mod.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
+
import { warnOnInvalidExtensionAttributeNames } from './message.js';
|
|
3
4
|
/**
|
|
4
5
|
* The Zod schema matching the Query type.
|
|
5
6
|
*
|
|
@@ -8,7 +9,7 @@ import { z } from 'zod';
|
|
|
8
9
|
* We do not infer the Query type from this schema because of
|
|
9
10
|
* slow type issues see https://jsr.io/docs/about-slow-types for more details.
|
|
10
11
|
*/
|
|
11
|
-
export const querySchema = z.
|
|
12
|
+
export const querySchema = z.looseObject({
|
|
12
13
|
specversion: z.literal('1.0'),
|
|
13
14
|
id: z.string(),
|
|
14
15
|
correlationid: z.string(),
|
|
@@ -30,16 +31,22 @@ export const querySchema = z.object({
|
|
|
30
31
|
* to skip properties and use the defaults for the rest.
|
|
31
32
|
*/
|
|
32
33
|
export const createQuery = (input) => {
|
|
34
|
+
const { id, correlationid, time, source, type, data, datacontenttype, dataschema, ...extensions } = input;
|
|
35
|
+
const correlationIdWithFallback = correlationid ?? ulid();
|
|
36
|
+
if (Object.keys(extensions).length > 0) {
|
|
37
|
+
warnOnInvalidExtensionAttributeNames(extensions, correlationIdWithFallback, createQuery);
|
|
38
|
+
}
|
|
33
39
|
const query = {
|
|
34
40
|
specversion: '1.0',
|
|
35
|
-
id:
|
|
36
|
-
correlationid:
|
|
37
|
-
time:
|
|
38
|
-
source
|
|
39
|
-
type
|
|
40
|
-
data
|
|
41
|
-
datacontenttype:
|
|
42
|
-
...(
|
|
41
|
+
id: id ?? ulid(),
|
|
42
|
+
correlationid: correlationIdWithFallback,
|
|
43
|
+
time: time ?? new Date().toISOString(),
|
|
44
|
+
source,
|
|
45
|
+
type,
|
|
46
|
+
data,
|
|
47
|
+
datacontenttype: datacontenttype ?? 'application/json',
|
|
48
|
+
...(dataschema && { dataschema }),
|
|
49
|
+
...extensions,
|
|
43
50
|
};
|
|
44
51
|
return query;
|
|
45
52
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nimbus-cqrs/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Simplify Event-Driven Applications - Core building blocks of the Nimbus framework.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nimbus",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@opentelemetry/api": "^1.9.1",
|
|
37
|
-
"zod": "^4.3
|
|
37
|
+
"zod": "^4.4.3"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^22.0.0"
|