@typespec/events 0.60.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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/dist/generated-defs/TypeSpec.Events.d.ts +56 -0
  4. package/dist/generated-defs/TypeSpec.Events.d.ts.map +1 -0
  5. package/dist/generated-defs/TypeSpec.Events.js +2 -0
  6. package/dist/generated-defs/TypeSpec.Events.js.map +1 -0
  7. package/dist/generated-defs/TypeSpec.Events.ts-test.d.ts +2 -0
  8. package/dist/generated-defs/TypeSpec.Events.ts-test.d.ts.map +1 -0
  9. package/dist/generated-defs/TypeSpec.Events.ts-test.js +5 -0
  10. package/dist/generated-defs/TypeSpec.Events.ts-test.js.map +1 -0
  11. package/dist/src/decorators.d.ts +12 -0
  12. package/dist/src/decorators.d.ts.map +1 -0
  13. package/dist/src/decorators.js +19 -0
  14. package/dist/src/decorators.js.map +1 -0
  15. package/dist/src/experimental/get-event-definitions.d.ts +43 -0
  16. package/dist/src/experimental/get-event-definitions.d.ts.map +1 -0
  17. package/dist/src/experimental/get-event-definitions.js +165 -0
  18. package/dist/src/experimental/get-event-definitions.js.map +1 -0
  19. package/dist/src/experimental/index.d.ts +3 -0
  20. package/dist/src/experimental/index.d.ts.map +1 -0
  21. package/dist/src/experimental/index.js +2 -0
  22. package/dist/src/experimental/index.js.map +1 -0
  23. package/dist/src/index.d.ts +4 -0
  24. package/dist/src/index.d.ts.map +1 -0
  25. package/dist/src/index.js +4 -0
  26. package/dist/src/index.js.map +1 -0
  27. package/dist/src/lib.d.ts +43 -0
  28. package/dist/src/lib.d.ts.map +1 -0
  29. package/dist/src/lib.js +26 -0
  30. package/dist/src/lib.js.map +1 -0
  31. package/dist/src/testing/index.d.ts +2 -0
  32. package/dist/src/testing/index.d.ts.map +1 -0
  33. package/dist/src/testing/index.js +6 -0
  34. package/dist/src/testing/index.js.map +1 -0
  35. package/dist/src/tsp-index.d.ts +10 -0
  36. package/dist/src/tsp-index.d.ts.map +1 -0
  37. package/dist/src/tsp-index.js +11 -0
  38. package/dist/src/tsp-index.js.map +1 -0
  39. package/dist/src/validate.d.ts +3 -0
  40. package/dist/src/validate.d.ts.map +1 -0
  41. package/dist/src/validate.js +12 -0
  42. package/dist/src/validate.js.map +1 -0
  43. package/lib/decorators.tsp +59 -0
  44. package/lib/main.tsp +2 -0
  45. package/package.json +67 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Microsoft Corporation. All rights reserved.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE
package/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # @typespec/events
2
+
3
+ TypeSpec library providing events bindings
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @typespec/events
9
+ ```
10
+
11
+ ## Decorators
12
+
13
+ ### TypeSpec.Events
14
+
15
+ - [`@contentType`](#@contenttype)
16
+ - [`@data`](#@data)
17
+ - [`@events`](#@events)
18
+
19
+ #### `@contentType`
20
+
21
+ Specifies the content type of the event envelope, event body, or event payload.
22
+ When applied to an event payload, that field must also have a corresponding `@data`
23
+ decorator.
24
+
25
+ ```typespec
26
+ @TypeSpec.Events.contentType(contentType: valueof string)
27
+ ```
28
+
29
+ ##### Target
30
+
31
+ `UnionVariant | ModelProperty`
32
+
33
+ ##### Parameters
34
+
35
+ | Name | Type | Description |
36
+ | ----------- | ---------------- | ----------- |
37
+ | contentType | `valueof string` | |
38
+
39
+ ##### Examples
40
+
41
+ ```typespec
42
+ @events
43
+ union MixedEvents {
44
+ @contentType("application/json")
45
+ message: {
46
+ id: string,
47
+ text: string,
48
+ },
49
+ }
50
+ ```
51
+
52
+ ###### Specify the content type of the event payload.
53
+
54
+ ```typespec
55
+ @events
56
+ union MixedEvents {
57
+ {
58
+ done: true,
59
+ },
60
+ {
61
+ done: false,
62
+ @data @contentType("text/plain") value: string,
63
+ },
64
+ }
65
+ ```
66
+
67
+ #### `@data`
68
+
69
+ Identifies the payload of an event.
70
+ Only one field in an event can be marked as the payload.
71
+
72
+ ```typespec
73
+ @TypeSpec.Events.data
74
+ ```
75
+
76
+ ##### Target
77
+
78
+ `ModelProperty`
79
+
80
+ ##### Parameters
81
+
82
+ None
83
+
84
+ ##### Examples
85
+
86
+ ```typespec
87
+ @events
88
+ union MixedEvents {
89
+ {
90
+ metadata: Record<string>,
91
+ @data payload: string,
92
+ },
93
+ }
94
+ ```
95
+
96
+ #### `@events`
97
+
98
+ Specify that this union describes a set of events.
99
+
100
+ ```typespec
101
+ @TypeSpec.Events.events
102
+ ```
103
+
104
+ ##### Target
105
+
106
+ `Union`
107
+
108
+ ##### Parameters
109
+
110
+ None
111
+
112
+ ##### Examples
113
+
114
+ ```typespec
115
+ @events
116
+ union MixedEvents {
117
+ pingEvent: string,
118
+ doneEvent: "done",
119
+ }
120
+ ```
@@ -0,0 +1,56 @@
1
+ import type { DecoratorContext, ModelProperty, Union, UnionVariant } from "@typespec/compiler";
2
+ /**
3
+ * Specify that this union describes a set of events.
4
+ *
5
+ * @example
6
+ * ```typespec
7
+ * @events
8
+ * union MixedEvents {
9
+ * pingEvent: string;
10
+ *
11
+ * doneEvent: "done";
12
+ * }
13
+ * ```
14
+ */
15
+ export type EventsDecorator = (context: DecoratorContext, target: Union) => void;
16
+ /**
17
+ * Specifies the content type of the event envelope, event body, or event payload.
18
+ * When applied to an event payload, that field must also have a corresponding `@data`
19
+ * decorator.
20
+ *
21
+ * @example
22
+ * ```typespec
23
+ * @events union MixedEvents {
24
+ * @contentType("application/json")
25
+ * message: { id: string, text: string, }
26
+ * }
27
+ * ```
28
+ * @example Specify the content type of the event payload.
29
+ *
30
+ * ```typespec
31
+ * @events union MixedEvents {
32
+ * { done: true },
33
+ *
34
+ * { done: false, @data @contentType("text/plain") value: string,}
35
+ * }
36
+ * ```
37
+ */
38
+ export type ContentTypeDecorator = (context: DecoratorContext, target: UnionVariant | ModelProperty, contentType: string) => void;
39
+ /**
40
+ * Identifies the payload of an event.
41
+ * Only one field in an event can be marked as the payload.
42
+ *
43
+ * @example
44
+ * ```typespec
45
+ * @events union MixedEvents {
46
+ * { metadata: Record<string>, @data payload: string,}
47
+ * }
48
+ * ```
49
+ */
50
+ export type DataDecorator = (context: DecoratorContext, target: ModelProperty) => void;
51
+ export type TypeSpecEventsDecorators = {
52
+ events: EventsDecorator;
53
+ contentType: ContentTypeDecorator;
54
+ data: DataDecorator;
55
+ };
56
+ //# sourceMappingURL=TypeSpec.Events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypeSpec.Events.d.ts","sourceRoot":"","sources":["../../generated-defs/TypeSpec.Events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE/F;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,KAAK,KAAK,IAAI,CAAC;AAEjF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,oBAAoB,GAAG,CACjC,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,YAAY,GAAG,aAAa,EACpC,WAAW,EAAE,MAAM,KAChB,IAAI,CAAC;AAEV;;;;;;;;;;GAUG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;AAEvF,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,EAAE,eAAe,CAAC;IACxB,WAAW,EAAE,oBAAoB,CAAC;IAClC,IAAI,EAAE,aAAa,CAAC;CACrB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=TypeSpec.Events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypeSpec.Events.js","sourceRoot":"","sources":["../../generated-defs/TypeSpec.Events.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=TypeSpec.Events.ts-test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypeSpec.Events.ts-test.d.ts","sourceRoot":"","sources":["../../generated-defs/TypeSpec.Events.ts-test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ /** An error here would mean that the decorator is not exported or doesn't have the right name. */
2
+ import { $decorators } from "@typespec/events";
3
+ /** An error here would mean that the exported decorator is not using the same signature. Make sure to have export const $decName: DecNameDecorator = (...) => ... */
4
+ const _ = $decorators["TypeSpec.Events"];
5
+ //# sourceMappingURL=TypeSpec.Events.ts-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypeSpec.Events.ts-test.js","sourceRoot":"","sources":["../../generated-defs/TypeSpec.Events.ts-test.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,qKAAqK;AACrK,MAAM,CAAC,GAA6B,WAAW,CAAC,iBAAiB,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type ModelProperty, type Union, type UnionVariant } from "@typespec/compiler";
2
+ import type { ContentTypeDecorator, DataDecorator, EventsDecorator } from "../generated-defs/TypeSpec.Events.js";
3
+ declare const isEvents: (program: import("@typespec/compiler").Program, type: Union) => boolean;
4
+ export declare const $eventsDecorator: EventsDecorator;
5
+ export { isEvents };
6
+ declare const getContentType: (program: import("@typespec/compiler").Program, type: ModelProperty | UnionVariant) => string | undefined;
7
+ export declare const $contentTypeDecorator: ContentTypeDecorator;
8
+ export { getContentType };
9
+ declare const isEventData: (program: import("@typespec/compiler").Program, type: ModelProperty) => boolean;
10
+ export declare const $dataDecorator: DataDecorator;
11
+ export { isEventData };
12
+ //# sourceMappingURL=decorators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,KAAK,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvF,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,eAAe,EAChB,MAAM,sCAAsC,CAAC;AAG9C,QAAA,MAAO,QAAQ,yEAAgE,CAAC;AAEhF,eAAO,MAAM,gBAAgB,EAAE,eAE9B,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AAEpB,QAAA,MAAO,cAAc,2GAEpB,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,oBAEnC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B,QAAA,MAAO,WAAW,iFAAyE,CAAC;AAE5F,eAAO,MAAM,cAAc,EAAE,aAE5B,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,19 @@
1
+ import {} from "@typespec/compiler";
2
+ import { unsafe_useStateMap, unsafe_useStateSet } from "@typespec/compiler/experimental";
3
+ import { EventsStateKeys } from "./lib.js";
4
+ const [isEvents, setEvents] = unsafe_useStateSet(EventsStateKeys.events);
5
+ export const $eventsDecorator = (context, target) => {
6
+ setEvents(context.program, target);
7
+ };
8
+ export { isEvents };
9
+ const [getContentType, setContentType] = unsafe_useStateMap(EventsStateKeys.contentType);
10
+ export const $contentTypeDecorator = (context, target, contentType) => {
11
+ setContentType(context.program, target, contentType);
12
+ };
13
+ export { getContentType };
14
+ const [isEventData, setEventData] = unsafe_useStateSet(EventsStateKeys.data);
15
+ export const $dataDecorator = (context, target) => {
16
+ setEventData(context.program, target);
17
+ };
18
+ export { isEventData };
19
+ //# sourceMappingURL=decorators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAMzF,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,kBAAkB,CAAQ,eAAe,CAAC,MAAM,CAAC,CAAC;AAEhF,MAAM,CAAC,MAAM,gBAAgB,GAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IACnE,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AAEpB,MAAM,CAAC,cAAc,EAAE,cAAc,CAAC,GAAG,kBAAkB,CACzD,eAAe,CAAC,WAAW,CAC5B,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE;IAC1F,cAAc,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,GAAG,kBAAkB,CAAgB,eAAe,CAAC,IAAI,CAAC,CAAC;AAE5F,MAAM,CAAC,MAAM,cAAc,GAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IAC/D,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { type DiagnosticResult, type Program, type Type, type Union, type UnionVariant } from "@typespec/compiler";
2
+ export declare function getEventDefinitions(program: Program, target: Union): DiagnosticResult<EventDefinition[]>;
3
+ /**
4
+ * Represents the definition of an event.
5
+ */
6
+ export interface EventDefinition {
7
+ /**
8
+ * The name of the event type.
9
+ * This may be used when the underlying event protocol supports event types
10
+ * out-of-band from the event evelope or event payload.
11
+ */
12
+ readonly eventType?: string;
13
+ /**
14
+ * The root variant of the union that represents the event.
15
+ */
16
+ readonly root: UnionVariant;
17
+ /**
18
+ * Indicates whether the `type` describes an event envelope
19
+ * with a separate event payload.
20
+ */
21
+ readonly isEventEnvelope: boolean;
22
+ /**
23
+ * The type of the event.
24
+ * This represents an event envelope if `isEventEnvelope` is `true`.
25
+ */
26
+ readonly type: Type;
27
+ /**
28
+ * The content type of the event.
29
+ * This represents the content type of the event envelope if `isEventEnvelope` is `true`.
30
+ */
31
+ readonly contentType?: string;
32
+ /**
33
+ * The type of the event payload.
34
+ * This matches `type` if `isEventEnvelope` is `false`.
35
+ */
36
+ readonly payloadType: Type;
37
+ /**
38
+ * The content type of the event payload.
39
+ * This matches `contentType` if `isEventEnvelope` is `false`.
40
+ */
41
+ readonly payloadContentType?: string;
42
+ }
43
+ //# sourceMappingURL=get-event-definitions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-event-definitions.d.ts","sourceRoot":"","sources":["../../../src/experimental/get-event-definitions.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EAGrB,KAAK,OAAO,EAEZ,KAAK,IAAI,EACT,KAAK,KAAK,EACV,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AA0L5B,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,KAAK,GACZ,gBAAgB,CAAC,eAAe,EAAE,CAAC,CAUrC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC"}
@@ -0,0 +1,165 @@
1
+ import { createDiagnosticCollector, navigateType, } from "@typespec/compiler";
2
+ import { getContentType, isEventData } from "../decorators.js";
3
+ import { createDiagnostic } from "../lib.js";
4
+ function validateContentType(program, target) {
5
+ const contentType = getContentType(program, target);
6
+ if (!contentType || isEventData(program, target))
7
+ return;
8
+ return createDiagnostic({
9
+ code: "invalid-content-type-target",
10
+ target,
11
+ });
12
+ }
13
+ function stringifyPropertyPath(path) {
14
+ return path
15
+ .map((p) => {
16
+ switch (p.kind) {
17
+ case "ModelProperty":
18
+ return p.name;
19
+ case "Tuple":
20
+ return "[]";
21
+ case "Model":
22
+ return;
23
+ }
24
+ })
25
+ .filter(Boolean)
26
+ .join(".");
27
+ }
28
+ function getEventDefinition(program, target) {
29
+ const diagnostics = createDiagnosticCollector();
30
+ // If the variant has a name, that may be used for out-of-band event types.
31
+ const eventType = typeof target.name === "string" ? target.name : undefined;
32
+ const envelopeContentType = getContentType(program, target);
33
+ let payloadType;
34
+ let payloadContentType;
35
+ let pathToPayload = "";
36
+ // Keeps track of if we're in a Record or Array.
37
+ let indexerDepth = 0;
38
+ // Keeps track of the path from the target to the current model property.
39
+ const currentPropertyPath = [];
40
+ // Keeps track of the types that have a descendant that leads to the event payload.
41
+ const typesThatChainToPayload = new Set();
42
+ // Look for a model property that is decorated with `@data`.
43
+ // This property will be used as the event payload.
44
+ // It can only be applied once within an event, and if it is not found,
45
+ // the target type is the payload.
46
+ navigateType(target.type, {
47
+ modelProperty(prop) {
48
+ currentPropertyPath.push(prop);
49
+ const contentTypeDiagnostic = validateContentType(program, prop);
50
+ if (contentTypeDiagnostic) {
51
+ diagnostics.add(contentTypeDiagnostic);
52
+ }
53
+ // This detects the scenario where a model that contains a `@data` property
54
+ // is referenced multiple times directly or indirectly by the target event.
55
+ if (typesThatChainToPayload.has(prop.type)) {
56
+ diagnostics.add(createDiagnostic({
57
+ code: "multiple-event-payloads",
58
+ format: {
59
+ dataPath: pathToPayload,
60
+ currentPath: stringifyPropertyPath(currentPropertyPath),
61
+ },
62
+ target,
63
+ }));
64
+ return;
65
+ }
66
+ // Haven't found a payload property yet, move on.
67
+ if (!isEventData(program, prop))
68
+ return;
69
+ // Mark all the types in the current path as having a descendant that leads to the payload.
70
+ currentPropertyPath.forEach((p) => {
71
+ if (p.kind === "ModelProperty") {
72
+ typesThatChainToPayload.add(p.type);
73
+ }
74
+ else if (p.kind === "Model" || p.kind === "Tuple") {
75
+ typesThatChainToPayload.add(p);
76
+ }
77
+ });
78
+ // Found the payload property but it's referenced indirectly by
79
+ // a Record or Array, which implies there would be more than 1 payload.
80
+ if (indexerDepth > 0) {
81
+ diagnostics.add(createDiagnostic({
82
+ code: "multiple-event-payloads",
83
+ messageId: "payloadInIndexedModel",
84
+ format: {
85
+ dataPath: stringifyPropertyPath(currentPropertyPath.slice(0, -1)),
86
+ },
87
+ target,
88
+ }));
89
+ return;
90
+ }
91
+ // A payload type was previously found, but only one is allowed.
92
+ if (payloadType) {
93
+ diagnostics.add(createDiagnostic({
94
+ code: "multiple-event-payloads",
95
+ format: {
96
+ dataPath: pathToPayload,
97
+ currentPath: stringifyPropertyPath(currentPropertyPath),
98
+ },
99
+ target,
100
+ }));
101
+ return;
102
+ }
103
+ // A payload property was found.
104
+ payloadType = prop.type;
105
+ payloadContentType = getContentType(program, prop);
106
+ pathToPayload = stringifyPropertyPath(currentPropertyPath);
107
+ },
108
+ exitModelProperty() {
109
+ currentPropertyPath.pop();
110
+ },
111
+ tuple(tuple) {
112
+ currentPropertyPath.push(tuple);
113
+ // Check if any of the tuple values have already been marked as a payload/payload ancestor.
114
+ // They won't be visited again, so need to create diagnostic here.
115
+ tuple.values.forEach((value) => {
116
+ if (typesThatChainToPayload.has(value)) {
117
+ diagnostics.add(createDiagnostic({
118
+ code: "multiple-event-payloads",
119
+ format: {
120
+ dataPath: pathToPayload,
121
+ currentPath: stringifyPropertyPath(currentPropertyPath),
122
+ },
123
+ target,
124
+ }));
125
+ return;
126
+ }
127
+ });
128
+ },
129
+ exitTuple() {
130
+ currentPropertyPath.pop();
131
+ },
132
+ model(model) {
133
+ if (model.indexer) {
134
+ indexerDepth++;
135
+ }
136
+ currentPropertyPath.push(model);
137
+ },
138
+ exitModel(model) {
139
+ if (model.indexer) {
140
+ indexerDepth--;
141
+ }
142
+ currentPropertyPath.pop();
143
+ },
144
+ }, {});
145
+ const eventDefinition = {
146
+ eventType,
147
+ root: target,
148
+ isEventEnvelope: !!payloadType,
149
+ type: target.type,
150
+ contentType: envelopeContentType,
151
+ payloadType: payloadType ?? target.type,
152
+ payloadContentType: payloadType ? payloadContentType : envelopeContentType,
153
+ };
154
+ return diagnostics.wrap(eventDefinition);
155
+ }
156
+ export function getEventDefinitions(program, target) {
157
+ const diagnostics = createDiagnosticCollector();
158
+ // 1. Iterate over each variant of the action
159
+ const events = [];
160
+ target.variants.forEach((variant) => {
161
+ events.push(diagnostics.pipe(getEventDefinition(program, variant)));
162
+ });
163
+ return diagnostics.wrap(events);
164
+ }
165
+ //# sourceMappingURL=get-event-definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-event-definitions.js","sourceRoot":"","sources":["../../../src/experimental/get-event-definitions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { getEventDefinitions as unsafe_getEventDefinitions } from "./get-event-definitions.js";
2
+ export type { EventDefinition as unsafe_EventDefinition } from "./get-event-definitions.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/experimental/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC/F,YAAY,EAAE,eAAe,IAAI,sBAAsB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { getEventDefinitions as unsafe_getEventDefinitions } from "./get-event-definitions.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/experimental/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,IAAI,0BAA0B,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { $lib } from "./lib.js";
2
+ export { $decorators, $onValidate } from "./tsp-index.js";
3
+ export { getContentType, isEventData, isEvents } from "./decorators.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { $lib } from "./lib.js";
2
+ export { $decorators, $onValidate } from "./tsp-index.js";
3
+ export { getContentType, isEventData, isEvents } from "./decorators.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,43 @@
1
+ export declare const $lib: import("@typespec/compiler").TypeSpecLibrary<{
2
+ "invalid-content-type-target": {
3
+ readonly default: "@contentType can only be specified on the top-level event envelope, or the event payload marked with @data";
4
+ };
5
+ "multiple-event-payloads": {
6
+ readonly default: import("@typespec/compiler").CallableMessage<["dataPath", "currentPath"]>;
7
+ readonly payloadInIndexedModel: import("@typespec/compiler").CallableMessage<["dataPath"]>;
8
+ };
9
+ }, Record<string, any>, "data" | "events" | "contentType">;
10
+ export declare const reportDiagnostic: <C extends "invalid-content-type-target" | "multiple-event-payloads", M extends keyof {
11
+ "invalid-content-type-target": {
12
+ readonly default: "@contentType can only be specified on the top-level event envelope, or the event payload marked with @data";
13
+ };
14
+ "multiple-event-payloads": {
15
+ readonly default: import("@typespec/compiler").CallableMessage<["dataPath", "currentPath"]>;
16
+ readonly payloadInIndexedModel: import("@typespec/compiler").CallableMessage<["dataPath"]>;
17
+ };
18
+ }[C]>(program: import("@typespec/compiler").Program, diag: import("@typespec/compiler").DiagnosticReport<{
19
+ "invalid-content-type-target": {
20
+ readonly default: "@contentType can only be specified on the top-level event envelope, or the event payload marked with @data";
21
+ };
22
+ "multiple-event-payloads": {
23
+ readonly default: import("@typespec/compiler").CallableMessage<["dataPath", "currentPath"]>;
24
+ readonly payloadInIndexedModel: import("@typespec/compiler").CallableMessage<["dataPath"]>;
25
+ };
26
+ }, C, M>) => void, createDiagnostic: <C extends "invalid-content-type-target" | "multiple-event-payloads", M extends keyof {
27
+ "invalid-content-type-target": {
28
+ readonly default: "@contentType can only be specified on the top-level event envelope, or the event payload marked with @data";
29
+ };
30
+ "multiple-event-payloads": {
31
+ readonly default: import("@typespec/compiler").CallableMessage<["dataPath", "currentPath"]>;
32
+ readonly payloadInIndexedModel: import("@typespec/compiler").CallableMessage<["dataPath"]>;
33
+ };
34
+ }[C]>(diag: import("@typespec/compiler").DiagnosticReport<{
35
+ "invalid-content-type-target": {
36
+ readonly default: "@contentType can only be specified on the top-level event envelope, or the event payload marked with @data";
37
+ };
38
+ "multiple-event-payloads": {
39
+ readonly default: import("@typespec/compiler").CallableMessage<["dataPath", "currentPath"]>;
40
+ readonly payloadInIndexedModel: import("@typespec/compiler").CallableMessage<["dataPath"]>;
41
+ };
42
+ }, C, M>) => import("@typespec/compiler").Diagnostic, EventsStateKeys: Record<"data" | "events" | "contentType", symbol>;
43
+ //# sourceMappingURL=lib.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/lib.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,IAAI;;;;;;;;0DAuBf,CAAC;AAEH,eAAO,MAAQ,gBAAgB;;;;;;;;;;;;;;;;mBAAE,gBAAgB;;;;;;;;;;;;;;;;sDAAa,eAAe,mDAAS,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { createTypeSpecLibrary, paramMessage } from "@typespec/compiler";
2
+ export const $lib = createTypeSpecLibrary({
3
+ name: "@typespec/events",
4
+ diagnostics: {
5
+ "invalid-content-type-target": {
6
+ severity: "error",
7
+ messages: {
8
+ default: `@contentType can only be specified on the top-level event envelope, or the event payload marked with @data`,
9
+ },
10
+ },
11
+ "multiple-event-payloads": {
12
+ severity: "error",
13
+ messages: {
14
+ default: paramMessage `Event payload already applied to ${"dataPath"} but also exists under ${"currentPath"}`,
15
+ payloadInIndexedModel: paramMessage `Event payload applied from inside a Record or Array at ${"dataPath"}`,
16
+ },
17
+ },
18
+ },
19
+ state: {
20
+ events: { description: "State for the @events decorator." },
21
+ contentType: { description: "State for the @contentType decorator." },
22
+ data: { description: "State for the @data decorator." },
23
+ },
24
+ });
25
+ export const { reportDiagnostic, createDiagnostic, stateKeys: EventsStateKeys } = $lib;
26
+ //# sourceMappingURL=lib.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEzE,MAAM,CAAC,MAAM,IAAI,GAAG,qBAAqB,CAAC;IACxC,IAAI,EAAE,kBAAkB;IACxB,WAAW,EAAE;QACX,6BAA6B,EAAE;YAC7B,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE;gBACR,OAAO,EAAE,4GAA4G;aACtH;SACF;QACD,yBAAyB,EAAE;YACzB,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE;gBACR,OAAO,EAAE,YAAY,CAAA,oCAAoC,UAAU,0BAA0B,aAAa,EAAE;gBAE5G,qBAAqB,EAAE,YAAY,CAAA,0DAA0D,UAAU,EAAE;aAC1G;SACF;KACF;IACD,KAAK,EAAE;QACL,MAAM,EAAE,EAAE,WAAW,EAAE,kCAAkC,EAAE;QAC3D,WAAW,EAAE,EAAE,WAAW,EAAE,uCAAuC,EAAE;QACrE,IAAI,EAAE,EAAE,WAAW,EAAE,gCAAgC,EAAE;KACxD;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const EventsTestLibrary: import("@typespec/compiler/testing").TypeSpecTestLibrary;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB,0DAG5B,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { createTestLibrary, findTestPackageRoot } from "@typespec/compiler/testing";
2
+ export const EventsTestLibrary = createTestLibrary({
3
+ name: "@typespec/events",
4
+ packageRoot: await findTestPackageRoot(import.meta.url),
5
+ });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEpF,MAAM,CAAC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;IACjD,IAAI,EAAE,kBAAkB;IACxB,WAAW,EAAE,MAAM,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;CACxD,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ export { $lib } from "./lib.js";
2
+ export { $onValidate } from "./validate.js";
3
+ export declare const $decorators: {
4
+ "TypeSpec.Events": {
5
+ contentType: import("../generated-defs/TypeSpec.Events.js").ContentTypeDecorator;
6
+ data: import("../generated-defs/TypeSpec.Events.js").DataDecorator;
7
+ events: import("../generated-defs/TypeSpec.Events.js").EventsDecorator;
8
+ };
9
+ };
10
+ //# sourceMappingURL=tsp-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsp-index.d.ts","sourceRoot":"","sources":["../../src/tsp-index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,eAAO,MAAM,WAAW;;;;;;CAMvB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { $contentTypeDecorator, $dataDecorator, $eventsDecorator } from "./decorators.js";
2
+ export { $lib } from "./lib.js";
3
+ export { $onValidate } from "./validate.js";
4
+ export const $decorators = {
5
+ "TypeSpec.Events": {
6
+ contentType: $contentTypeDecorator,
7
+ data: $dataDecorator,
8
+ events: $eventsDecorator,
9
+ },
10
+ };
11
+ //# sourceMappingURL=tsp-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsp-index.js","sourceRoot":"","sources":["../../src/tsp-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE1F,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,iBAAiB,EAAE;QACjB,WAAW,EAAE,qBAAqB;QAClC,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,gBAAgB;KACzB;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Program } from "@typespec/compiler";
2
+ export declare function $onValidate(program: Program): void;
3
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAS,MAAM,oBAAoB,CAAC;AAGzD,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,QAE3C"}
@@ -0,0 +1,12 @@
1
+ import { unsafe_getEventDefinitions } from "./experimental/index.js";
2
+ import { EventsStateKeys } from "./lib.js";
3
+ export function $onValidate(program) {
4
+ checkForInvalidEvents(program);
5
+ }
6
+ function checkForInvalidEvents(program) {
7
+ program.stateSet(EventsStateKeys.events).forEach((events) => {
8
+ const [, diagnostics] = unsafe_getEventDefinitions(program, events);
9
+ program.reportDiagnostics(diagnostics);
10
+ });
11
+ }
12
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,qBAAqB,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QAC1D,MAAM,CAAC,EAAE,WAAW,CAAC,GAAG,0BAA0B,CAAC,OAAO,EAAE,MAAe,CAAC,CAAC;QAC7E,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,59 @@
1
+ using TypeSpec.Reflection;
2
+
3
+ namespace TypeSpec.Events;
4
+
5
+ /**
6
+ * Specify that this union describes a set of events.
7
+ *
8
+ * @example
9
+ *
10
+ * ```typespec
11
+ * @events
12
+ * union MixedEvents {
13
+ * pingEvent: string;
14
+ *
15
+ * doneEvent: "done";
16
+ * }
17
+ * ```
18
+ */
19
+ extern dec events(target: Union);
20
+
21
+ /**
22
+ * Specifies the content type of the event envelope, event body, or event payload.
23
+ * When applied to an event payload, that field must also have a corresponding `@data`
24
+ * decorator.
25
+ *
26
+ * @example
27
+ *
28
+ * ```typespec
29
+ * @events union MixedEvents {
30
+ * @contentType("application/json")
31
+ * message: { id: string, text: string, }
32
+ * }
33
+ * ```
34
+ *
35
+ * @example Specify the content type of the event payload.
36
+ *
37
+ * ```typespec
38
+ * @events union MixedEvents {
39
+ * { done: true },
40
+ *
41
+ * { done: false, @data @contentType("text/plain") value: string,}
42
+ * }
43
+ * ```
44
+ */
45
+ extern dec contentType(target: UnionVariant | ModelProperty, contentType: valueof string);
46
+
47
+ /**
48
+ * Identifies the payload of an event.
49
+ * Only one field in an event can be marked as the payload.
50
+ *
51
+ * @example
52
+ *
53
+ * ```typespec
54
+ * @events union MixedEvents {
55
+ * { metadata: Record<string>, @data payload: string,}
56
+ * }
57
+ * ```
58
+ */
59
+ extern dec data(target: ModelProperty);
package/lib/main.tsp ADDED
@@ -0,0 +1,2 @@
1
+ import "../dist/src/tsp-index.js";
2
+ import "./decorators.tsp";
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@typespec/events",
3
+ "version": "0.60.0",
4
+ "author": "Microsoft Corporation",
5
+ "description": "TypeSpec library providing events bindings",
6
+ "homepage": "https://typespec.io",
7
+ "readme": "https://github.com/microsoft/typespec/blob/main/README.md",
8
+ "license": "MIT",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/microsoft/typespec.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/microsoft/typespec/issues"
15
+ },
16
+ "keywords": [
17
+ "typespec"
18
+ ],
19
+ "type": "module",
20
+ "main": "dist/src/index.js",
21
+ "tspMain": "lib/main.tsp",
22
+ "exports": {
23
+ ".": "./dist/src/index.js",
24
+ "./testing": "./dist/src/testing/index.js",
25
+ "./experimental": {
26
+ "types": "./dist/src/experimental/index.d.ts",
27
+ "default": "./dist/src/experimental/index.js"
28
+ }
29
+ },
30
+ "engines": {
31
+ "node": ">=18.0.0"
32
+ },
33
+ "files": [
34
+ "lib/*.tsp",
35
+ "dist/**",
36
+ "!dist/test/**"
37
+ ],
38
+ "peerDependencies": {
39
+ "@typespec/compiler": "~0.60.1"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "~22.7.1",
43
+ "@vitest/coverage-v8": "^2.1.1",
44
+ "@vitest/ui": "^2.1.1",
45
+ "c8": "^10.1.2",
46
+ "rimraf": "~6.0.1",
47
+ "typescript": "~5.6.2",
48
+ "vitest": "^2.1.1",
49
+ "@typespec/library-linter": "~0.60.0",
50
+ "@typespec/compiler": "~0.60.1",
51
+ "@typespec/tspd": "~0.46.0"
52
+ },
53
+ "scripts": {
54
+ "clean": "rimraf ./dist ./temp",
55
+ "build": "npm run gen-extern-signature && tsc -p . && npm run lint-typespec-library",
56
+ "watch": "tsc -p . --watch",
57
+ "gen-extern-signature": "tspd --enable-experimental gen-extern-signature .",
58
+ "lint-typespec-library": "tsp compile . --warn-as-error --import @typespec/library-linter --no-emit",
59
+ "test": "vitest run",
60
+ "test:watch": "vitest -w",
61
+ "test:ui": "vitest --ui",
62
+ "test-official": "vitest run --coverage --reporter=junit --reporter=default --no-file-parallelism",
63
+ "lint": "eslint . --ext .ts --max-warnings=0",
64
+ "lint:fix": "eslint . --fix --ext .ts",
65
+ "regen-docs": "tspd doc . --enable-experimental --output-dir ../../docs/libraries/events/reference"
66
+ }
67
+ }