@amqp-contract/asyncapi 0.1.4 → 0.2.1

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/dist/index.d.mts CHANGED
@@ -1,136 +1,143 @@
1
+ import { ConditionalSchemaConverter } from "@orpc/openapi";
2
+ import { AsyncAPIObject } from "@asyncapi/parser/esm/spec-types/v3";
1
3
  import { ContractDefinition } from "@amqp-contract/contract";
2
- import { StandardSchemaV1 } from "@standard-schema/spec";
3
4
 
4
- //#region src/generator.d.ts
5
- /**
6
- * AsyncAPI 3.0.0 Specification
7
- */
8
- interface AsyncAPIDocument {
9
- asyncapi: "3.0.0";
10
- info: AsyncAPIInfo;
11
- servers?: Record<string, AsyncAPIServer>;
12
- channels?: Record<string, AsyncAPIChannel>;
13
- operations?: Record<string, AsyncAPIOperation>;
14
- components?: AsyncAPIComponents;
15
- }
16
- interface AsyncAPIInfo {
17
- title: string;
18
- version: string;
19
- description?: string;
20
- termsOfService?: string;
21
- contact?: {
22
- name?: string;
23
- url?: string;
24
- email?: string;
25
- };
26
- license?: {
27
- name: string;
28
- url?: string;
29
- };
30
- }
31
- interface AsyncAPIServer {
32
- host: string;
33
- protocol: string;
34
- description?: string;
35
- variables?: Record<string, {
36
- default: string;
37
- description?: string;
38
- }>;
39
- }
40
- interface AsyncAPIChannel {
41
- address: string;
42
- messages?: Record<string, AsyncAPIMessageRef>;
43
- description?: string;
44
- bindings?: {
45
- amqp?: {
46
- is: "queue" | "routingKey";
47
- queue?: {
48
- name: string;
49
- durable?: boolean;
50
- exclusive?: boolean;
51
- autoDelete?: boolean;
52
- };
53
- exchange?: {
54
- name: string;
55
- type: "topic" | "direct" | "fanout" | "headers";
56
- durable?: boolean;
57
- autoDelete?: boolean;
58
- };
59
- };
60
- };
61
- }
62
- interface AsyncAPIOperation {
63
- action: "send" | "receive";
64
- channel: AsyncAPIRef;
65
- messages?: AsyncAPIMessageRef[];
66
- description?: string;
67
- }
68
- interface AsyncAPIMessageRef {
69
- $ref?: string;
70
- payload?: AsyncAPISchema;
71
- contentType?: string;
72
- name?: string;
73
- title?: string;
74
- summary?: string;
75
- description?: string;
76
- }
77
- interface AsyncAPISchema {
78
- type?: string;
79
- properties?: Record<string, AsyncAPISchema>;
80
- required?: string[];
81
- items?: AsyncAPISchema;
82
- $ref?: string;
83
- description?: string;
84
- format?: string;
85
- minimum?: number;
86
- maximum?: number;
87
- minLength?: number;
88
- maxLength?: number;
89
- pattern?: string;
90
- enum?: unknown[];
91
- }
92
- interface AsyncAPIRef {
93
- $ref: string;
94
- }
95
- interface AsyncAPIComponents {
96
- messages?: Record<string, AsyncAPIMessageRef>;
97
- schemas?: Record<string, AsyncAPISchema>;
98
- }
5
+ //#region src/index.d.ts
6
+
99
7
  /**
100
- * Options for generating AsyncAPI specification
8
+ * Options for configuring the AsyncAPI generator.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { AsyncAPIGenerator } from '@amqp-contract/asyncapi';
13
+ * import { zodToJsonSchema } from '@orpc/zod';
14
+ *
15
+ * const generator = new AsyncAPIGenerator({
16
+ * schemaConverters: [zodToJsonSchema]
17
+ * });
18
+ * ```
101
19
  */
102
- interface GenerateAsyncAPIOptions {
103
- info: Omit<AsyncAPIInfo, "title" | "version"> & {
104
- title?: string;
105
- version?: string;
106
- };
107
- servers?: Record<string, AsyncAPIServer>;
20
+ interface AsyncAPIGeneratorOptions {
21
+ /**
22
+ * Schema converters for transforming validation schemas to JSON Schema.
23
+ * Supports Zod, Valibot, ArkType, and other Standard Schema v1 compatible libraries.
24
+ */
25
+ schemaConverters?: ConditionalSchemaConverter[];
108
26
  }
109
27
  /**
110
- * Generate AsyncAPI 3.0.0 specification from AMQP contract
28
+ * Options for generating an AsyncAPI document.
29
+ * These correspond to the top-level AsyncAPI document fields.
111
30
  */
112
- declare function generateAsyncAPI(contract: ContractDefinition, options: GenerateAsyncAPIOptions): AsyncAPIDocument;
113
- //#endregion
114
- //#region src/schema-converter.d.ts
31
+ type AsyncAPIGeneratorGenerateOptions = Pick<AsyncAPIObject, "id" | "info" | "servers">;
115
32
  /**
116
- * Convert a Standard Schema to JSON Schema (AsyncAPI format)
117
- *
118
- * This is a basic converter that returns a generic object schema.
119
- * Users should provide their own schema-to-JSON-Schema converter function
120
- * specific to their schema library.
33
+ * Generator for creating AsyncAPI 3.0 documentation from AMQP contracts.
121
34
  *
122
- * For Zod users, import and use zodToJsonSchema from @amqp-contract/zod
35
+ * This class converts contract definitions into AsyncAPI 3.0 specification documents,
36
+ * which can be used for API documentation, code generation, and tooling integration.
123
37
  *
124
38
  * @example
125
- * ```ts
126
- * import { zodToJsonSchema } from '@amqp-contract/zod';
127
- * import { generateAsyncAPI } from '@amqp-contract/asyncapi';
39
+ * ```typescript
40
+ * import { AsyncAPIGenerator } from '@amqp-contract/asyncapi';
41
+ * import { zodToJsonSchema } from '@orpc/zod';
42
+ * import { z } from 'zod';
43
+ *
44
+ * const contract = defineContract({
45
+ * exchanges: {
46
+ * orders: defineExchange('orders', 'topic', { durable: true })
47
+ * },
48
+ * publishers: {
49
+ * orderCreated: definePublisher('orders', z.object({
50
+ * orderId: z.string(),
51
+ * amount: z.number()
52
+ * }), {
53
+ * routingKey: 'order.created'
54
+ * })
55
+ * }
56
+ * });
128
57
  *
129
- * // Use zodToJsonSchema for converting Zod schemas
130
- * const jsonSchema = zodToJsonSchema(zodSchema);
58
+ * const generator = new AsyncAPIGenerator({
59
+ * schemaConverters: [zodToJsonSchema]
60
+ * });
61
+ *
62
+ * const asyncapi = await generator.generate(contract, {
63
+ * id: 'urn:com:example:order-service',
64
+ * info: {
65
+ * title: 'Order Service API',
66
+ * version: '1.0.0',
67
+ * description: 'Async API for order processing'
68
+ * },
69
+ * servers: {
70
+ * production: {
71
+ * host: 'rabbitmq.example.com',
72
+ * protocol: 'amqp',
73
+ * protocolVersion: '0.9.1'
74
+ * }
75
+ * }
76
+ * });
131
77
  * ```
132
78
  */
133
- declare function standardSchemaToJsonSchema(_schema: StandardSchemaV1): AsyncAPISchema;
79
+ declare class AsyncAPIGenerator {
80
+ private readonly converters;
81
+ /**
82
+ * Create a new AsyncAPI generator instance.
83
+ *
84
+ * @param options - Configuration options including schema converters
85
+ */
86
+ constructor(options?: AsyncAPIGeneratorOptions);
87
+ /**
88
+ * Generate an AsyncAPI 3.0 document from a contract definition.
89
+ *
90
+ * Converts AMQP exchanges, queues, publishers, and consumers into
91
+ * AsyncAPI channels, operations, and messages with proper JSON Schema
92
+ * validation definitions.
93
+ *
94
+ * @param contract - The AMQP contract definition to convert
95
+ * @param options - AsyncAPI document metadata (id, info, servers)
96
+ * @returns Promise resolving to a complete AsyncAPI 3.0 document
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * const asyncapi = await generator.generate(contract, {
101
+ * id: 'urn:com:example:api',
102
+ * info: {
103
+ * title: 'My API',
104
+ * version: '1.0.0'
105
+ * },
106
+ * servers: {
107
+ * dev: {
108
+ * host: 'localhost:5672',
109
+ * protocol: 'amqp'
110
+ * }
111
+ * }
112
+ * });
113
+ * ```
114
+ */
115
+ generate(contract: ContractDefinition, options: AsyncAPIGeneratorGenerateOptions): Promise<AsyncAPIObject>;
116
+ /**
117
+ * Convert a message definition to AsyncAPI MessageObject
118
+ */
119
+ private convertMessage;
120
+ /**
121
+ * Convert a queue definition to AsyncAPI ChannelObject
122
+ */
123
+ private queueToChannel;
124
+ /**
125
+ * Convert an exchange definition to AsyncAPI ChannelObject
126
+ */
127
+ private exchangeToChannel;
128
+ /**
129
+ * Get the name/key of an exchange from the contract
130
+ */
131
+ private getExchangeName;
132
+ /**
133
+ * Get the name/key of a queue from the contract
134
+ */
135
+ private getQueueName;
136
+ /**
137
+ * Convert a Standard Schema to JSON Schema using oRPC converters
138
+ */
139
+ private convertSchema;
140
+ }
134
141
  //#endregion
135
- export { type AsyncAPIChannel, type AsyncAPIComponents, type AsyncAPIDocument, type AsyncAPIInfo, type AsyncAPIMessageRef, type AsyncAPIOperation, type AsyncAPISchema, type AsyncAPIServer, type GenerateAsyncAPIOptions, generateAsyncAPI, standardSchemaToJsonSchema };
142
+ export { AsyncAPIGenerator, AsyncAPIGeneratorGenerateOptions, AsyncAPIGeneratorOptions };
136
143
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/generator.ts","../src/schema-converter.ts"],"sourcesContent":[],"mappings":";;;;;;;AAMiB,UAAA,gBAAA,CAAgB;EAEzB,QAAA,EAAA,OAAA;EACmB,IAAA,EADnB,YACmB;EAAf,OAAA,CAAA,EAAA,MAAA,CAAA,MAAA,EAAe,cAAf,CAAA;EACgB,QAAA,CAAA,EAAf,MAAe,CAAA,MAAA,EAAA,eAAA,CAAA;EAAf,UAAA,CAAA,EACE,MADF,CAAA,MAAA,EACiB,iBADjB,CAAA;EACiB,UAAA,CAAA,EACf,kBADe;;AACf,UAGE,YAAA,CAHF;EAAkB,KAAA,EAAA,MAAA;EAGhB,OAAA,EAAA,MAAY;EAgBZ,WAAA,CAAA,EAAA,MAAc;EAOd,cAAA,CAAA,EAAA,MAAe;EAuBf,OAAA,CAAA,EAAA;IAOA,IAAA,CAAA,EAAA,MAAA;IAUA,GAAA,CAAA,EAAA,MAAA;IAEa,KAAA,CAAA,EAAA,MAAA;EAAf,CAAA;EAEL,OAAA,CAAA,EAAA;IAAc,IAAA,EAAA,MAAA;IAYd,GAAA,CAAA,EAAA,MAAW;EAIJ,CAAA;;AACJ,UApEI,cAAA,CAoEJ;EACc,IAAA,EAAA,MAAA;EAAf,QAAA,EAAA,MAAA;EAAM,WAAA,CAAA,EAAA,MAAA;EAMD,SAAA,CAAA,EAvEH,MAuEG,CAAA,MAAA,EAAuB;IAC3B,OAAA,EAAA,MAAA;IAAL,WAAA,CAAA,EAAA,MAAA;EAImB,CAAA,CAAA;;AAAT,UAzED,eAAA,CAyEC;EAMF,OAAA,EAAA,MAAA;EACJ,QAAA,CAAA,EA9EC,MA8ED,CAAA,MAAA,EA9EgB,kBA8EhB,CAAA;EACD,WAAA,CAAA,EAAA,MAAA;EACR,QAAA,CAAA,EAAA;IAAgB,IAAA,CAAA,EAAA;;;;QCnGH,OAAA,CAAA,EAAA,OAA0B;;;;;;;;;;;;;UDwCzB,iBAAA;;WAEN;aACE;;;UAII,kBAAA;;YAEL;;;;;;;UAQK,cAAA;;eAEF,eAAe;;UAEpB;;;;;;;;;;;UAYA,WAAA;;;UAIO,kBAAA;aACJ,eAAe;YAChB,eAAe;;;;;UAMV,uBAAA;QACT,KAAK;;;;YAID,eAAe;;;;;iBAMX,gBAAA,WACJ,6BACD,0BACR;;;;;AAlHH;;;;;;;;;;AASA;AAgBA;AAOA;AAuBA;AAOA;AAUA;AAE8B,iBC3Dd,0BAAA,CD2Dc,OAAA,EC3DsB,gBD2DtB,CAAA,EC3DyC,cD2DzC"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;AA8BA;AAYA;AAiDA;;;;;;;;;UA7DiB,wBAAA;;;;;qBAKI;;;;;;KAOT,gCAAA,GAAmC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiDvC,iBAAA;;;;;;;wBAQU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAiCT,6BACD,mCACR,QAAQ"}
package/dist/index.mjs CHANGED
@@ -1,110 +1,247 @@
1
- //#region src/schema-converter.ts
1
+ //#region src/index.ts
2
2
  /**
3
- * Convert a Standard Schema to JSON Schema (AsyncAPI format)
3
+ * Generator for creating AsyncAPI 3.0 documentation from AMQP contracts.
4
4
  *
5
- * This is a basic converter that returns a generic object schema.
6
- * Users should provide their own schema-to-JSON-Schema converter function
7
- * specific to their schema library.
8
- *
9
- * For Zod users, import and use zodToJsonSchema from @amqp-contract/zod
5
+ * This class converts contract definitions into AsyncAPI 3.0 specification documents,
6
+ * which can be used for API documentation, code generation, and tooling integration.
10
7
  *
11
8
  * @example
12
- * ```ts
13
- * import { zodToJsonSchema } from '@amqp-contract/zod';
14
- * import { generateAsyncAPI } from '@amqp-contract/asyncapi';
9
+ * ```typescript
10
+ * import { AsyncAPIGenerator } from '@amqp-contract/asyncapi';
11
+ * import { zodToJsonSchema } from '@orpc/zod';
12
+ * import { z } from 'zod';
13
+ *
14
+ * const contract = defineContract({
15
+ * exchanges: {
16
+ * orders: defineExchange('orders', 'topic', { durable: true })
17
+ * },
18
+ * publishers: {
19
+ * orderCreated: definePublisher('orders', z.object({
20
+ * orderId: z.string(),
21
+ * amount: z.number()
22
+ * }), {
23
+ * routingKey: 'order.created'
24
+ * })
25
+ * }
26
+ * });
27
+ *
28
+ * const generator = new AsyncAPIGenerator({
29
+ * schemaConverters: [zodToJsonSchema]
30
+ * });
15
31
  *
16
- * // Use zodToJsonSchema for converting Zod schemas
17
- * const jsonSchema = zodToJsonSchema(zodSchema);
32
+ * const asyncapi = await generator.generate(contract, {
33
+ * id: 'urn:com:example:order-service',
34
+ * info: {
35
+ * title: 'Order Service API',
36
+ * version: '1.0.0',
37
+ * description: 'Async API for order processing'
38
+ * },
39
+ * servers: {
40
+ * production: {
41
+ * host: 'rabbitmq.example.com',
42
+ * protocol: 'amqp',
43
+ * protocolVersion: '0.9.1'
44
+ * }
45
+ * }
46
+ * });
18
47
  * ```
19
48
  */
20
- function standardSchemaToJsonSchema(_schema) {
21
- return { type: "object" };
22
- }
23
-
24
- //#endregion
25
- //#region src/generator.ts
26
- /**
27
- * Generate AsyncAPI 3.0.0 specification from AMQP contract
28
- */
29
- function generateAsyncAPI(contract, options) {
30
- const channels = {};
31
- const operations = {};
32
- const messages = {};
33
- if (contract.queues) for (const [queueName, queue] of Object.entries(contract.queues)) {
34
- const binding = { amqp: {
35
- is: "queue",
36
- queue: { name: queue.name }
37
- } };
38
- if (queue.durable !== void 0) binding.amqp.queue.durable = queue.durable;
39
- if (queue.exclusive !== void 0) binding.amqp.queue.exclusive = queue.exclusive;
40
- if (queue.autoDelete !== void 0) binding.amqp.queue.autoDelete = queue.autoDelete;
41
- channels[queueName] = {
42
- address: queue.name,
43
- description: `Queue: ${queue.name}`,
44
- bindings: binding
45
- };
49
+ var AsyncAPIGenerator = class {
50
+ converters;
51
+ /**
52
+ * Create a new AsyncAPI generator instance.
53
+ *
54
+ * @param options - Configuration options including schema converters
55
+ */
56
+ constructor(options = {}) {
57
+ this.converters = options.schemaConverters ?? [];
46
58
  }
47
- if (contract.exchanges) for (const [exchangeName, exchange] of Object.entries(contract.exchanges)) {
48
- const binding = { amqp: {
49
- is: "routingKey",
50
- exchange: {
51
- name: exchange.name,
52
- type: exchange.type
59
+ /**
60
+ * Generate an AsyncAPI 3.0 document from a contract definition.
61
+ *
62
+ * Converts AMQP exchanges, queues, publishers, and consumers into
63
+ * AsyncAPI channels, operations, and messages with proper JSON Schema
64
+ * validation definitions.
65
+ *
66
+ * @param contract - The AMQP contract definition to convert
67
+ * @param options - AsyncAPI document metadata (id, info, servers)
68
+ * @returns Promise resolving to a complete AsyncAPI 3.0 document
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * const asyncapi = await generator.generate(contract, {
73
+ * id: 'urn:com:example:api',
74
+ * info: {
75
+ * title: 'My API',
76
+ * version: '1.0.0'
77
+ * },
78
+ * servers: {
79
+ * dev: {
80
+ * host: 'localhost:5672',
81
+ * protocol: 'amqp'
82
+ * }
83
+ * }
84
+ * });
85
+ * ```
86
+ */
87
+ async generate(contract, options) {
88
+ const convertedChannels = {};
89
+ const convertedOperations = {};
90
+ const convertedMessages = {};
91
+ const publisherMessages = /* @__PURE__ */ new Map();
92
+ const consumerMessages = /* @__PURE__ */ new Map();
93
+ if (contract.publishers) for (const [publisherName, publisher] of Object.entries(contract.publishers)) {
94
+ const channelKey = this.getExchangeName(publisher.exchange, contract);
95
+ publisherMessages.set(publisherName, {
96
+ message: publisher.message,
97
+ channelKey
98
+ });
99
+ }
100
+ if (contract.consumers) for (const [consumerName, consumer] of Object.entries(contract.consumers)) {
101
+ const channelKey = this.getQueueName(consumer.queue, contract);
102
+ consumerMessages.set(consumerName, {
103
+ message: consumer.message,
104
+ channelKey
105
+ });
106
+ }
107
+ if (contract.queues) for (const [queueName, queue] of Object.entries(contract.queues)) {
108
+ const channelMessages = {};
109
+ for (const [consumerName, { message, channelKey }] of consumerMessages) if (channelKey === queueName) {
110
+ const messageName = `${consumerName}Message`;
111
+ channelMessages[messageName] = await this.convertMessage(message);
112
+ convertedMessages[messageName] = await this.convertMessage(message);
53
113
  }
54
- } };
55
- if (exchange.durable !== void 0) binding.amqp.exchange.durable = exchange.durable;
56
- if (exchange.autoDelete !== void 0) binding.amqp.exchange.autoDelete = exchange.autoDelete;
57
- channels[exchangeName] = {
58
- address: exchange.name,
59
- description: `Exchange: ${exchange.name} (${exchange.type})`,
60
- bindings: binding
114
+ const channel = { ...this.queueToChannel(queue) };
115
+ if (Object.keys(channelMessages).length > 0) channel.messages = channelMessages;
116
+ convertedChannels[queueName] = channel;
117
+ }
118
+ if (contract.exchanges) for (const [exchangeName, exchange] of Object.entries(contract.exchanges)) {
119
+ const channelMessages = {};
120
+ for (const [publisherName, { message, channelKey }] of publisherMessages) if (channelKey === exchangeName) {
121
+ const messageName = `${publisherName}Message`;
122
+ channelMessages[messageName] = await this.convertMessage(message);
123
+ convertedMessages[messageName] = await this.convertMessage(message);
124
+ }
125
+ const channel = { ...this.exchangeToChannel(exchange) };
126
+ if (Object.keys(channelMessages).length > 0) channel.messages = channelMessages;
127
+ convertedChannels[exchangeName] = channel;
128
+ }
129
+ if (contract.publishers) for (const [publisherName, publisher] of Object.entries(contract.publishers)) {
130
+ const exchangeName = this.getExchangeName(publisher.exchange, contract);
131
+ const messageName = `${publisherName}Message`;
132
+ convertedOperations[publisherName] = {
133
+ action: "send",
134
+ channel: { $ref: `#/channels/${exchangeName}` },
135
+ messages: [{ $ref: `#/channels/${exchangeName}/messages/${messageName}` }],
136
+ summary: `Publish to ${publisher.exchange.name}`,
137
+ ...publisher.routingKey && { description: `Routing key: ${publisher.routingKey}` }
138
+ };
139
+ }
140
+ if (contract.consumers) for (const [consumerName, consumer] of Object.entries(contract.consumers)) {
141
+ const queueName = this.getQueueName(consumer.queue, contract);
142
+ const messageName = `${consumerName}Message`;
143
+ convertedOperations[consumerName] = {
144
+ action: "receive",
145
+ channel: { $ref: `#/channels/${queueName}` },
146
+ messages: [{ $ref: `#/channels/${queueName}/messages/${messageName}` }],
147
+ summary: `Consume from ${consumer.queue.name}`
148
+ };
149
+ }
150
+ return {
151
+ ...options,
152
+ asyncapi: "3.0.0",
153
+ channels: convertedChannels,
154
+ operations: convertedOperations,
155
+ components: { messages: convertedMessages }
61
156
  };
62
157
  }
63
- if (contract.publishers) for (const [publisherName, publisher] of Object.entries(contract.publishers)) {
64
- const messageName = `${publisherName}Message`;
65
- messages[messageName] = {
66
- name: messageName,
67
- title: `${publisherName} message`,
68
- contentType: "application/json",
69
- payload: standardSchemaToJsonSchema(publisher.message)
70
- };
71
- operations[publisherName] = {
72
- action: "send",
73
- channel: { $ref: `#/channels/${publisher.exchange}` },
74
- messages: [{ $ref: `#/components/messages/${messageName}` }],
75
- description: `Publish message to ${publisher.exchange}`
158
+ /**
159
+ * Convert a message definition to AsyncAPI MessageObject
160
+ */
161
+ async convertMessage(message) {
162
+ const payload = message.payload;
163
+ const result = {
164
+ payload: await this.convertSchema(payload, "input"),
165
+ contentType: "application/json"
76
166
  };
167
+ if (message.headers) {
168
+ const headersJsonSchema = await this.convertSchema(message.headers, "input");
169
+ if (headersJsonSchema) result["headers"] = headersJsonSchema;
170
+ }
171
+ if (message.summary) result["summary"] = message.summary;
172
+ if (message.description) result["description"] = message.description;
173
+ return result;
77
174
  }
78
- if (contract.consumers) for (const [consumerName, consumer] of Object.entries(contract.consumers)) {
79
- const messageName = `${consumerName}Message`;
80
- messages[messageName] = {
81
- name: messageName,
82
- title: `${consumerName} message`,
83
- contentType: "application/json",
84
- payload: standardSchemaToJsonSchema(consumer.message)
175
+ /**
176
+ * Convert a queue definition to AsyncAPI ChannelObject
177
+ */
178
+ queueToChannel(queue) {
179
+ return {
180
+ address: queue.name,
181
+ title: queue.name,
182
+ description: `AMQP Queue: ${queue.name}`,
183
+ bindings: { amqp: {
184
+ is: "queue",
185
+ queue: {
186
+ name: queue.name,
187
+ durable: queue.durable ?? false,
188
+ exclusive: queue.exclusive ?? false,
189
+ autoDelete: queue.autoDelete ?? false,
190
+ ...queue.arguments && { vhost: "/" }
191
+ }
192
+ } }
85
193
  };
86
- operations[consumerName] = {
87
- action: "receive",
88
- channel: { $ref: `#/channels/${consumer.queue}` },
89
- messages: [{ $ref: `#/components/messages/${messageName}` }],
90
- description: `Consume message from ${consumer.queue}`
194
+ }
195
+ /**
196
+ * Convert an exchange definition to AsyncAPI ChannelObject
197
+ */
198
+ exchangeToChannel(exchange) {
199
+ return {
200
+ address: exchange.name,
201
+ title: exchange.name,
202
+ description: `AMQP Exchange: ${exchange.name} (${exchange.type})`,
203
+ bindings: { amqp: {
204
+ is: "routingKey",
205
+ exchange: {
206
+ name: exchange.name,
207
+ type: exchange.type,
208
+ durable: exchange.durable ?? false,
209
+ autoDelete: exchange.autoDelete ?? false,
210
+ ...exchange.arguments && { vhost: "/" }
211
+ }
212
+ } }
91
213
  };
92
214
  }
93
- const result = {
94
- asyncapi: "3.0.0",
95
- info: {
96
- title: options.info.title ?? "AMQP Contract API",
97
- version: options.info.version ?? "1.0.0",
98
- ...options.info
99
- },
100
- channels,
101
- operations,
102
- components: { messages }
103
- };
104
- if (options.servers) result.servers = options.servers;
105
- return result;
106
- }
215
+ /**
216
+ * Get the name/key of an exchange from the contract
217
+ */
218
+ getExchangeName(exchange, contract) {
219
+ if (contract.exchanges) {
220
+ for (const [name, ex] of Object.entries(contract.exchanges)) if (ex === exchange || ex.name === exchange.name) return name;
221
+ }
222
+ return exchange.name;
223
+ }
224
+ /**
225
+ * Get the name/key of a queue from the contract
226
+ */
227
+ getQueueName(queue, contract) {
228
+ if (contract.queues) {
229
+ for (const [name, q] of Object.entries(contract.queues)) if (q === queue || q.name === queue.name) return name;
230
+ }
231
+ return queue.name;
232
+ }
233
+ /**
234
+ * Convert a Standard Schema to JSON Schema using oRPC converters
235
+ */
236
+ async convertSchema(schema, strategy) {
237
+ for (const converter of this.converters) if (await converter.condition(schema, { strategy })) {
238
+ const [_required, jsonSchema] = await converter.convert(schema, { strategy });
239
+ return jsonSchema;
240
+ }
241
+ return { type: "object" };
242
+ }
243
+ };
107
244
 
108
245
  //#endregion
109
- export { generateAsyncAPI, standardSchemaToJsonSchema };
246
+ export { AsyncAPIGenerator };
110
247
  //# sourceMappingURL=index.mjs.map