@eventcatalog/generator-openapi 0.0.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/README.md ADDED
@@ -0,0 +1,132 @@
1
+ <div align="center">
2
+
3
+ <h1>⚡️ OpenAPI generator for EventCatalog</h1>
4
+
5
+ [![PRs Welcome][prs-badge]][prs]
6
+ <img src="https://img.shields.io/github/actions/workflow/status/event-catalog/generator-asyncapi/verify-build.yml"/>
7
+ [![](https://dcbadge.limes.pink/api/server/https://discord.gg/3rjaZMmrAm?style=flat)](https://discord.gg/3rjaZMmrAm) [<img src="https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white" height="20px" />](https://www.linkedin.com/in/david-boyne/) [![blog](https://img.shields.io/badge/blog-EDA--Visuals-brightgreen)](https://eda-visuals.boyney.io/?utm_source=event-catalog-gihub)
8
+
9
+ <img alt="header" src="./images/openapi.png" />
10
+
11
+ <h4>Features: Generate EventCatalogs with your OpenAPI files, Auto versioning, schema downloads, map to domains, custom OpenAPI extensions and more... </h4>
12
+
13
+ [Read the Docs](https://eventcatalog.dev/) | [Edit the Docs](https://github.com/event-catalog/docs) | [View Demo](https://demo.eventcatalog.dev/docs)
14
+
15
+ </div>
16
+
17
+ <hr/>
18
+
19
+ # Core Features
20
+
21
+ - 📃 Document domains, services and messages from your OpenAPI files ([example](https://github.com/event-catalog/eventcatalog-openapi-example))
22
+ - 📊 Visualise your architecture ([demo](https://demo.eventcatalog.dev/visualiser))
23
+ - ⭐ Download your OpenAPI files from EventCatalog ([demo](https://demo.eventcatalog.dev/docs/events/InventoryAdjusted/0.0.4))
24
+ - 💅 Custom MDX components ([read more](https://eventcatalog.dev/docs/development/components/using-components))
25
+ - 🗄️ Auto versioning of your domains, services and messages
26
+ - ⭐ Discoverability feature (search, filter and more) ([demo](https://demo.eventcatalog.dev/discover/events))
27
+ - ⭐ And much more...
28
+
29
+ # How it works
30
+
31
+ [EventCatalog](https://www.eventcatalog.dev/) is technology agnostic, meaning it can integrate with any schemas, specs or brokers.
32
+
33
+ EventCatalog supports [generators](https://www.eventcatalog.dev/docs/development/plugins/generators).
34
+ Generators are scripts are run to pre build to generate content in your catalog. Generators can use the [EventCatalog SDK](https://www.eventcatalog.dev/docs/sdk).
35
+
36
+ With this OpenAPI plugin you can connect your OpenAPI files to your catalog. This is done by defining your generators in your `eventcatlaog.config.js` file.
37
+
38
+ ```js
39
+ ...
40
+ generators: [
41
+ [
42
+ '@eventcatalogtest/generator-openapi',
43
+ {
44
+ path: [path.join(__dirname, 'openapi-files', 'petstore.yml'),
45
+ domain: { id: 'orders', name: 'Orders', version: '0.0.1' },
46
+ },
47
+ ],
48
+ ],
49
+ ...
50
+ ```
51
+
52
+ In this example the generator will read the `petstore.yml` file and populate services and messages inside your catalog. It will add the service to the domain `Orders`.
53
+
54
+ You can see an example in the [eventcatalog-openapi-example](https://github.com/event-catalog/eventcatalog-openapi-example/blob/main/eventcatalog.config.js) repo
55
+
56
+ # Getting started
57
+
58
+ ## Installation and configuration
59
+
60
+ _Make sure you are on the latest version of EventCatalog_.
61
+
62
+ 1. Install the package
63
+
64
+ ```sh
65
+ @eventcatalog/generator-openapi
66
+ ```
67
+
68
+ 2. Configure your `eventcatalog.config.js` file [(see example)](https://github.com/event-catalog/eventcatalog-openapi-example/blob/main/eventcatalog.config.js)
69
+
70
+ 3. Run the generate command
71
+
72
+ ```sh
73
+ npm run generate
74
+ ```
75
+
76
+ 4. See your new domains, services and messages, run
77
+
78
+ ```sh
79
+ npm run dev
80
+ ```
81
+
82
+ ## Found a problem?
83
+
84
+ Raise a GitHub issue on this project, or contact us on [our Discord server](https://discord.gg/3rjaZMmrAm).
85
+
86
+ # Sponsors
87
+
88
+ Thank you to our EventCatalog project sponsors.
89
+
90
+ <hr />
91
+
92
+ <div align="center">
93
+ <img alt="hookdeck" src="./images/sponsors/hookdeck.svg" />
94
+ <p style="margin: 0; padding: 0;">Serverless infrastructure for event-driven architecture. </p>
95
+ <a href="https://hookdeck.com/?ref=eventcatalog-sponsor" target="_blank" >Learn more</a>
96
+ </div>
97
+
98
+ <hr />
99
+
100
+ _Sponsors help make EventCatalog sustainable, want to help the project? Get in touch! Or [visit our sponsor page](https://www.eventcatalog.dev/support)._
101
+
102
+ # Enterprise support
103
+
104
+ Interested in collaborating with us? Our offerings include dedicated support, priority assistance, feature development, custom integrations, and more.
105
+
106
+ Find more details on our [services page](https://eventcatalog.dev/services).
107
+
108
+ # Contributing
109
+
110
+ If you have any questions, features or issues please raise any issue or pull requests you like. We will try my best to get back to you.
111
+
112
+ You can find the [contributing guidelines here](https://eventcatalog.dev/docs/contributing/overview).
113
+
114
+ ## Running the project locally
115
+
116
+ 1. Clone the repo
117
+ 1. Install required dependencies `pnpm i`
118
+ 1. Run the examples `npx tsx examples/streelights-mqtt/index.ts
119
+ 1. Run tests `pnpm run tests`
120
+
121
+ [license-badge]: https://img.shields.io/github/license/event-catalog/eventcatalog.svg?color=yellow
122
+ [license]: https://github.com/event-catalog/eventcatalog/blob/main/LICENSE
123
+ [prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
124
+ [prs]: http://makeapullrequest.com
125
+ [github-watch-badge]: https://img.shields.io/github/watchers/event-catalog/eventcatalog.svg?style=social
126
+ [github-watch]: https://github.com/event-catalog/eventcatalog/watchers
127
+ [github-star-badge]: https://img.shields.io/github/stars/event-catalog/eventcatalog.svg?style=social
128
+ [github-star]: https://github.com/event-catalog/eventcatalog/stargazers
129
+
130
+ # Commercial Use
131
+
132
+ This project is governed by the [AGPL-3.0](/LICENSE.md) copyleft license. To ensure the sustainability of the project, you can freely make use of this software as long the outcome is distributed under the same license. Otherwise, you must obtain a [commercial license](./LICENSE-COMMERCIAL.md) that removes such restrictions.
@@ -0,0 +1,11 @@
1
+ import { Domain } from './types.mjs';
2
+ import 'openapi-types';
3
+
4
+ type Props = {
5
+ path: string | string[];
6
+ domain?: Domain;
7
+ debug?: boolean;
8
+ };
9
+ declare const _default: (_: any, options: Props) => Promise<void>;
10
+
11
+ export { _default as default };
@@ -0,0 +1,11 @@
1
+ import { Domain } from './types.js';
2
+ import 'openapi-types';
3
+
4
+ type Props = {
5
+ path: string | string[];
6
+ domain?: Domain;
7
+ debug?: boolean;
8
+ };
9
+ declare const _default: (_: any, options: Props) => Promise<void>;
10
+
11
+ export { _default as default };
package/dist/index.js ADDED
@@ -0,0 +1,427 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ default: () => src_default
34
+ });
35
+ module.exports = __toCommonJS(src_exports);
36
+ var import_sdk2 = __toESM(require("@eventcatalog/sdk"));
37
+ var import_promises = require("fs/promises");
38
+ var import_chalk = __toESM(require("chalk"));
39
+ var import_swagger_parser2 = __toESM(require("@apidevtools/swagger-parser"));
40
+
41
+ // src/utils/domains.ts
42
+ var defaultMarkdown = () => {
43
+ return `
44
+
45
+ ## Architecture diagram
46
+ <NodeGraph />
47
+
48
+ `;
49
+ };
50
+
51
+ // src/utils/services.ts
52
+ var import_slugify = __toESM(require("slugify"));
53
+ var defaultMarkdown2 = (document, fileName) => {
54
+ return `
55
+
56
+ ${document.info.description ? `${document.info.description}` : ""}
57
+
58
+ ## Architecture diagram
59
+ <NodeGraph />
60
+
61
+ ## OpenAPI Specification
62
+ <OpenAPI file="${fileName}"/>
63
+
64
+ ${document.externalDocs ? `
65
+ ## External documentation
66
+ - [${document.externalDocs.description}](${document.externalDocs.url})
67
+ ` : ""}
68
+
69
+ `;
70
+ };
71
+ var getSummary = (document) => {
72
+ const summary = document.info.description ? document.info.description : "";
73
+ return summary && summary.length < 150 ? summary : "";
74
+ };
75
+ var buildService = (pathToFile, document) => {
76
+ const schemaPath = pathToFile.split("/").pop() || "openapi.yml";
77
+ const documentTags = document.tags || [];
78
+ return {
79
+ id: (0, import_slugify.default)(document.info.title, { lower: true, strict: true }),
80
+ version: document.info.version,
81
+ name: document.info.title,
82
+ summary: getSummary(document),
83
+ schemaPath,
84
+ markdown: defaultMarkdown2(document, schemaPath),
85
+ badges: documentTags.map((tag) => ({ content: tag.name, textColor: "blue", backgroundColor: "blue" }))
86
+ };
87
+ };
88
+
89
+ // src/utils/openapi.ts
90
+ var import_swagger_parser = __toESM(require("@apidevtools/swagger-parser"));
91
+ var DEFAULT_MESSAGE_TYPE = "query";
92
+ async function getSchemasByOperationId(filePath, operationId) {
93
+ try {
94
+ const api = await import_swagger_parser.default.dereference(filePath);
95
+ const schemas = {
96
+ parameters: [],
97
+ requestBody: null,
98
+ responses: {}
99
+ };
100
+ for (const [path, pathItem] of Object.entries(api.paths)) {
101
+ for (const [method, operation] of Object.entries(pathItem)) {
102
+ const typedOperation = operation;
103
+ if (typedOperation.operationId === operationId) {
104
+ if (typedOperation.parameters) {
105
+ schemas.parameters = typedOperation.parameters;
106
+ }
107
+ if (typedOperation.requestBody && typedOperation.requestBody.content) {
108
+ const contentType = Object.keys(typedOperation.requestBody.content)[0];
109
+ schemas.requestBody = typedOperation.requestBody.content[contentType].schema;
110
+ }
111
+ if (typedOperation.responses) {
112
+ for (const [statusCode, response] of Object.entries(typedOperation.responses)) {
113
+ if (response.content) {
114
+ const contentType = Object.keys(response.content)[0];
115
+ schemas.responses[statusCode] = response.content[contentType].schema || response.content[contentType];
116
+ schemas.responses[statusCode].isSchema = !!response.content[contentType].schema;
117
+ }
118
+ }
119
+ }
120
+ return schemas;
121
+ }
122
+ }
123
+ }
124
+ throw new Error(`Operation with ID "${operationId}" not found.`);
125
+ } catch (error) {
126
+ console.error("Error parsing OpenAPI file or finding operation:", error);
127
+ return;
128
+ }
129
+ }
130
+ async function getOperationsByType(openApiPath) {
131
+ try {
132
+ const api = await import_swagger_parser.default.validate(openApiPath);
133
+ const operations = [];
134
+ for (const path in api.paths) {
135
+ const pathItem = api.paths[path];
136
+ for (const method in pathItem) {
137
+ const openAPIOperation = pathItem[method];
138
+ const messageType = openAPIOperation["x-eventcatalog-message-type"] || DEFAULT_MESSAGE_TYPE;
139
+ const operation = {
140
+ path,
141
+ method: method.toUpperCase(),
142
+ operationId: openAPIOperation.operationId,
143
+ externalDocs: openAPIOperation.externalDocs,
144
+ type: messageType,
145
+ description: openAPIOperation.description,
146
+ summary: openAPIOperation.summary,
147
+ tags: openAPIOperation.tags || []
148
+ };
149
+ operations.push(operation);
150
+ }
151
+ }
152
+ return operations;
153
+ } catch (err) {
154
+ console.error("Error parsing OpenAPI document:", err);
155
+ return [];
156
+ }
157
+ }
158
+
159
+ // src/utils/messages.ts
160
+ var markdownForParameters = (parameters) => {
161
+ let markdown = "### Parameters\n";
162
+ for (const parameter of parameters) {
163
+ markdown += `- **${parameter.name}** (${parameter.in})`;
164
+ if (parameter.required) {
165
+ markdown += " (required)";
166
+ }
167
+ if (parameter.description) {
168
+ markdown += `: ${parameter.description}`;
169
+ }
170
+ markdown += "\n";
171
+ }
172
+ return markdown;
173
+ };
174
+ var markdownForResponses = (openAPIOperation) => {
175
+ let markdown = "### Responses\n";
176
+ for (const [statusCode, content] of Object.entries(openAPIOperation.responses)) {
177
+ if (content.isSchema) {
178
+ markdown += `**${statusCode} Response**
179
+ <SchemaViewer file="response-${statusCode}.json" maxHeight="500" id="response-${statusCode}" />
180
+ `;
181
+ } else {
182
+ markdown += `**${statusCode} Response**
183
+ \`\`\`json
184
+ ${JSON.stringify(content, null, 2)}
185
+ \`\`\`
186
+ `;
187
+ }
188
+ }
189
+ return markdown;
190
+ };
191
+ var defaultMarkdown3 = (message, openAPIOperation = {}) => {
192
+ return `
193
+
194
+
195
+ ## Architecture
196
+ <NodeGraph />
197
+
198
+ ${message.externalDocs ? `
199
+ ## External documentation
200
+ - [${message.externalDocs.description}](${message.externalDocs.url})
201
+ ` : ""}
202
+
203
+ ## ${message.method.toUpperCase()} \`(${message.path})\`
204
+
205
+ ${openAPIOperation.parameters && openAPIOperation.parameters.length > 0 ? markdownForParameters(openAPIOperation.parameters) : ""}
206
+
207
+ ${openAPIOperation.requestBody ? `
208
+ ### Request Body
209
+ <SchemaViewer file="request-body.json" maxHeight="500" id="request-body" />
210
+ ` : ""}
211
+
212
+ ${markdownForResponses(openAPIOperation)}
213
+
214
+ `;
215
+ };
216
+ var getSummary2 = (message) => {
217
+ const messageSummary = message.summary ? message.summary : "";
218
+ const messageDescription = message.description ? message.description : "";
219
+ let eventCatalogMessageSummary = messageSummary;
220
+ if (!eventCatalogMessageSummary) {
221
+ eventCatalogMessageSummary = messageDescription && messageDescription.length < 150 ? messageDescription : "";
222
+ }
223
+ return eventCatalogMessageSummary;
224
+ };
225
+ var buildMessage = async (pathToFile, document, operation) => {
226
+ const requestBodiesAndResponses = await getSchemasByOperationId(pathToFile, operation.operationId);
227
+ const operationTags = operation.tags.map((badge) => ({
228
+ content: `tag:${badge}`,
229
+ textColor: "blue",
230
+ backgroundColor: "blue"
231
+ }));
232
+ const badges = [{ content: operation.method.toUpperCase(), textColor: "blue", backgroundColor: "blue" }, ...operationTags];
233
+ return {
234
+ id: operation.operationId,
235
+ version: document.info.version,
236
+ name: operation.operationId,
237
+ summary: getSummary2(operation),
238
+ markdown: defaultMarkdown3(operation, requestBodiesAndResponses),
239
+ schemaPath: requestBodiesAndResponses?.requestBody ? "request-body.json" : "",
240
+ badges,
241
+ requestBodiesAndResponses
242
+ };
243
+ };
244
+
245
+ // src/utils/catalog-shorthand.ts
246
+ var import_sdk = __toESM(require("@eventcatalog/sdk"));
247
+ var getMessageTypeUtils = (projectDirectory, messageType) => {
248
+ const {
249
+ writeEvent,
250
+ versionCommand,
251
+ getEvent,
252
+ getCommand,
253
+ rmCommandById,
254
+ rmEventById,
255
+ writeCommand,
256
+ addFileToCommand,
257
+ addFileToEvent,
258
+ versionEvent
259
+ } = (0, import_sdk.default)(projectDirectory);
260
+ if (messageType === "event") {
261
+ return {
262
+ versionMessage: versionEvent,
263
+ getMessage: getEvent,
264
+ rmMessageById: rmEventById,
265
+ writeMessage: writeEvent,
266
+ addFileToMessage: addFileToEvent
267
+ };
268
+ }
269
+ return {
270
+ versionMessage: versionCommand,
271
+ getMessage: getCommand,
272
+ rmMessageById: rmCommandById,
273
+ writeMessage: writeCommand,
274
+ addFileToMessage: addFileToCommand
275
+ };
276
+ };
277
+
278
+ // src/index.ts
279
+ var src_default = async (_, options) => {
280
+ if (!process.env.PROJECT_DIR) {
281
+ throw new Error("Please provide catalog url (env variable PROJECT_DIR)");
282
+ }
283
+ const {
284
+ getDomain,
285
+ versionDomain,
286
+ writeDomain,
287
+ addServiceToDomain,
288
+ getService,
289
+ versionService,
290
+ rmService,
291
+ writeService,
292
+ addFileToService
293
+ } = (0, import_sdk2.default)(process.env.PROJECT_DIR);
294
+ const openAPIFiles = Array.isArray(options.path) ? options.path : [options.path];
295
+ for (const path of openAPIFiles) {
296
+ console.log(import_chalk.default.green(`Processing ${path}`));
297
+ try {
298
+ await import_swagger_parser2.default.validate(path);
299
+ } catch (error) {
300
+ console.error(import_chalk.default.red(`Failed to parse OpenAPI file: ${path}`));
301
+ console.error(import_chalk.default.red(error));
302
+ continue;
303
+ }
304
+ const openAPIFile = await (0, import_promises.readFile)(path, "utf-8");
305
+ const document = await import_swagger_parser2.default.parse(path);
306
+ const version = document.info.version;
307
+ const service = buildService(path, document);
308
+ let serviceMarkdown = service.markdown;
309
+ if (options.domain) {
310
+ const { id: domainId, name: domainName, version: domainVersion } = options.domain;
311
+ const domain = await getDomain(options.domain.id, domainVersion || "latest");
312
+ const currentDomain = await getDomain(options.domain.id, "latest");
313
+ console.log(import_chalk.default.blue(`
314
+ Processing domain: ${domainName} (v${domainVersion})`));
315
+ if (currentDomain && currentDomain.version !== domainVersion) {
316
+ await versionDomain(domainId);
317
+ console.log(import_chalk.default.cyan(` - Versioned previous domain (v${currentDomain.version})`));
318
+ }
319
+ if (!domain || domain && domain.version !== domainVersion) {
320
+ await writeDomain({
321
+ id: domainId,
322
+ name: domainName,
323
+ version: domainVersion,
324
+ markdown: defaultMarkdown()
325
+ });
326
+ console.log(import_chalk.default.cyan(` - Domain (v${domainVersion}) created`));
327
+ }
328
+ if (currentDomain && currentDomain.version === domainVersion) {
329
+ console.log(import_chalk.default.yellow(` - Domain (v${domainVersion}) already exists, skipped creation...`));
330
+ }
331
+ await addServiceToDomain(domainId, { id: service.id, version: service.version }, domainVersion);
332
+ }
333
+ let { sends, receives } = await processMessagesForOpenAPISpec(path, document);
334
+ const latestServiceInCatalog = await getService(service.id, "latest");
335
+ console.log(import_chalk.default.blue(`Processing service: ${document.info.title} (v${version})`));
336
+ if (latestServiceInCatalog) {
337
+ serviceMarkdown = latestServiceInCatalog.markdown;
338
+ sends = latestServiceInCatalog.sends || [];
339
+ if (latestServiceInCatalog.version !== version) {
340
+ await versionService(service.id);
341
+ console.log(import_chalk.default.cyan(` - Versioned previous service (v${latestServiceInCatalog.version})`));
342
+ }
343
+ if (latestServiceInCatalog.version === version) {
344
+ await rmService(service.name);
345
+ }
346
+ }
347
+ await writeService(
348
+ {
349
+ ...service,
350
+ markdown: serviceMarkdown,
351
+ sends,
352
+ receives
353
+ },
354
+ { path: service.name }
355
+ );
356
+ await addFileToService(
357
+ service.id,
358
+ {
359
+ fileName: service.schemaPath,
360
+ content: openAPIFile
361
+ },
362
+ version
363
+ );
364
+ console.log(import_chalk.default.cyan(` - Service (v${version}) created`));
365
+ console.log(import_chalk.default.green(`
366
+ Finished generating event catalog for OpenAPI ${service.name} (v${version})`));
367
+ console.log(import_chalk.default.bgBlue(`
368
+ You are using a free version of this plugin`));
369
+ console.log(import_chalk.default.blueBright(`This plugin is governed and published under the AGPL-3.0 copy-left license.
370
+ If using for commercial purposes or proprietary software, please contact hello@eventcatalog.dev for a license to support the project.`));
371
+ }
372
+ };
373
+ var processMessagesForOpenAPISpec = async (pathToSpec, document) => {
374
+ const operations = await getOperationsByType(pathToSpec);
375
+ const version = document.info.version;
376
+ let receives = [];
377
+ for (const operation of operations) {
378
+ const { requestBodiesAndResponses, ...message } = await buildMessage(pathToSpec, document, operation);
379
+ let messageMarkdown = message.markdown;
380
+ const messageType = operation.type;
381
+ console.log(import_chalk.default.blue(`Processing message: ${message.name} (v${version})`));
382
+ const { addFileToMessage, writeMessage, rmMessageById, getMessage, versionMessage } = getMessageTypeUtils(
383
+ process.env.PROJECT_DIR,
384
+ messageType
385
+ );
386
+ const catalogedMessage = await getMessage(message.id, "latest");
387
+ if (catalogedMessage) {
388
+ messageMarkdown = catalogedMessage.markdown;
389
+ if (catalogedMessage.version === version) {
390
+ await rmMessageById(message.id, version);
391
+ } else {
392
+ await versionMessage(message.id);
393
+ console.log(import_chalk.default.cyan(` - Versioned previous message: (v${catalogedMessage.version})`));
394
+ }
395
+ }
396
+ await writeMessage({ ...message, markdown: messageMarkdown }, { path: message.name });
397
+ receives.push({
398
+ id: operation.operationId,
399
+ version: message.version
400
+ });
401
+ if (requestBodiesAndResponses?.requestBody) {
402
+ await addFileToMessage(
403
+ message.id,
404
+ {
405
+ fileName: "request-body.json",
406
+ content: JSON.stringify(requestBodiesAndResponses.requestBody, null, 2)
407
+ },
408
+ message.version
409
+ );
410
+ }
411
+ if (requestBodiesAndResponses?.responses) {
412
+ for (const [statusCode, schema] of Object.entries(requestBodiesAndResponses.responses)) {
413
+ await addFileToMessage(
414
+ message.id,
415
+ {
416
+ fileName: `response-${statusCode}.json`,
417
+ content: JSON.stringify(schema, null, 2)
418
+ },
419
+ message.version
420
+ );
421
+ }
422
+ }
423
+ console.log(import_chalk.default.cyan(` - Message (v${version}) created`));
424
+ }
425
+ return { receives, sends: [] };
426
+ };
427
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/domains.ts","../src/utils/services.ts","../src/utils/openapi.ts","../src/utils/messages.ts","../src/utils/catalog-shorthand.ts"],"sourcesContent":["import utils from '@eventcatalog/sdk';\nimport { readFile } from 'node:fs/promises';\nimport chalk from 'chalk';\nimport SwaggerParser from '@apidevtools/swagger-parser';\n\nimport { defaultMarkdown as generateMarkdownForDomain } from './utils/domains';\nimport { buildService } from './utils/services';\nimport { buildMessage } from './utils/messages';\nimport { getOperationsByType } from './utils/openapi';\nimport { Domain } from './types';\nimport { getMessageTypeUtils } from './utils/catalog-shorthand';\nimport { OpenAPI } from 'openapi-types';\n\ntype Props = {\n path: string | string[];\n domain?: Domain;\n debug?: boolean;\n};\n\nexport default async (_: any, options: Props) => {\n if (!process.env.PROJECT_DIR) {\n throw new Error('Please provide catalog url (env variable PROJECT_DIR)');\n }\n\n const {\n getDomain,\n versionDomain,\n writeDomain,\n addServiceToDomain,\n getService,\n versionService,\n rmService,\n writeService,\n addFileToService,\n } = utils(process.env.PROJECT_DIR);\n\n const openAPIFiles = Array.isArray(options.path) ? options.path : [options.path];\n\n for (const path of openAPIFiles) {\n console.log(chalk.green(`Processing ${path}`));\n\n try {\n await SwaggerParser.validate(path);\n } catch (error) {\n console.error(chalk.red(`Failed to parse OpenAPI file: ${path}`));\n console.error(chalk.red(error));\n continue;\n }\n\n const openAPIFile = await readFile(path, 'utf-8');\n const document = await SwaggerParser.parse(path);\n const version = document.info.version;\n\n const service = buildService(path, document);\n let serviceMarkdown = service.markdown;\n\n // Manage domain\n if (options.domain) {\n // Try and get the domain\n const { id: domainId, name: domainName, version: domainVersion } = options.domain;\n const domain = await getDomain(options.domain.id, domainVersion || 'latest');\n const currentDomain = await getDomain(options.domain.id, 'latest');\n\n console.log(chalk.blue(`\\nProcessing domain: ${domainName} (v${domainVersion})`));\n\n // Found a domain, but the versions do not match\n if (currentDomain && currentDomain.version !== domainVersion) {\n await versionDomain(domainId);\n console.log(chalk.cyan(` - Versioned previous domain (v${currentDomain.version})`));\n }\n\n // Do we need to create a new domain?\n if (!domain || (domain && domain.version !== domainVersion)) {\n await writeDomain({\n id: domainId,\n name: domainName,\n version: domainVersion,\n markdown: generateMarkdownForDomain(),\n });\n console.log(chalk.cyan(` - Domain (v${domainVersion}) created`));\n }\n\n if (currentDomain && currentDomain.version === domainVersion) {\n console.log(chalk.yellow(` - Domain (v${domainVersion}) already exists, skipped creation...`));\n }\n\n // Add the service to the domain\n await addServiceToDomain(domainId, { id: service.id, version: service.version }, domainVersion);\n }\n\n // Process all messages for the OpenAPI spec\n let { sends, receives } = await processMessagesForOpenAPISpec(path, document);\n\n // Check if service is already defined... if the versions do not match then create service.\n const latestServiceInCatalog = await getService(service.id, 'latest');\n console.log(chalk.blue(`Processing service: ${document.info.title} (v${version})`));\n\n if (latestServiceInCatalog) {\n serviceMarkdown = latestServiceInCatalog.markdown;\n sends = latestServiceInCatalog.sends || ([] as any);\n // Found a service, and versions do not match, we need to version the one already there\n if (latestServiceInCatalog.version !== version) {\n await versionService(service.id);\n console.log(chalk.cyan(` - Versioned previous service (v${latestServiceInCatalog.version})`));\n }\n\n // Match found, override it\n if (latestServiceInCatalog.version === version) {\n await rmService(service.name);\n }\n }\n\n await writeService(\n {\n ...service,\n markdown: serviceMarkdown,\n sends,\n receives,\n },\n { path: service.name }\n );\n\n await addFileToService(\n service.id,\n {\n fileName: service.schemaPath,\n content: openAPIFile,\n },\n version\n );\n\n console.log(chalk.cyan(` - Service (v${version}) created`));\n\n console.log(chalk.green(`\\nFinished generating event catalog for OpenAPI ${service.name} (v${version})`));\n\n console.log(chalk.bgBlue(`\\nYou are using a free version of this plugin`));\n console.log(chalk.blueBright(`This plugin is governed and published under the AGPL-3.0 copy-left license. \\nIf using for commercial purposes or proprietary software, please contact hello@eventcatalog.dev for a license to support the project.`));\n }\n};\n\nconst processMessagesForOpenAPISpec = async (pathToSpec: string, document: OpenAPI.Document) => {\n const operations = await getOperationsByType(pathToSpec);\n const version = document.info.version;\n let receives = [];\n\n // Go through all messages\n for (const operation of operations) {\n\n const { requestBodiesAndResponses, ...message } = await buildMessage(pathToSpec, document, operation);\n let messageMarkdown = message.markdown;\n const messageType = operation.type;\n\n console.log(chalk.blue(`Processing message: ${message.name} (v${version})`));\n\n const { addFileToMessage, writeMessage, rmMessageById, getMessage, versionMessage } = getMessageTypeUtils(\n process.env.PROJECT_DIR as string,\n messageType\n );\n\n // Check if the message already exists in the catalog\n const catalogedMessage = await getMessage(message.id, 'latest');\n\n if (catalogedMessage) {\n messageMarkdown = catalogedMessage.markdown;\n // if the version matches, we can override the message but keep markdown as it was\n if (catalogedMessage.version === version) {\n await rmMessageById(message.id, version);\n } else {\n // if the version does not match, we need to version the message\n await versionMessage(message.id);\n console.log(chalk.cyan(` - Versioned previous message: (v${catalogedMessage.version})`));\n }\n }\n\n // Write the message to the catalog\n await writeMessage({...message, markdown: messageMarkdown}, { path: message.name });\n\n // messages will always be messages the service receives\n receives.push({\n id: operation.operationId,\n version: message.version,\n });\n\n // Does the message have a request body or responses?\n if (requestBodiesAndResponses?.requestBody) {\n await addFileToMessage(\n message.id,\n {\n fileName: 'request-body.json',\n content: JSON.stringify(requestBodiesAndResponses.requestBody, null, 2),\n },\n message.version\n );\n }\n\n if (requestBodiesAndResponses?.responses) {\n for (const [statusCode, schema] of Object.entries(requestBodiesAndResponses.responses)) {\n await addFileToMessage(\n message.id,\n {\n fileName: `response-${statusCode}.json`,\n content: JSON.stringify(schema, null, 2),\n },\n message.version\n );\n }\n }\n\n console.log(chalk.cyan(` - Message (v${version}) created`));\n }\n return { receives, sends: [] };\n};\n","export const defaultMarkdown = () => {\n return `\n\n## Architecture diagram\n<NodeGraph />\n\n`;\n};\n","import { OpenAPI } from 'openapi-types';\nimport slugify from 'slugify';\n\nexport const defaultMarkdown = (document: OpenAPI.Document, fileName: string) => {\n return `\n\n${document.info.description ? `${document.info.description}` : ''} \n\n## Architecture diagram\n<NodeGraph />\n\n## OpenAPI Specification\n<OpenAPI file=\"${fileName}\"/>\n\n${\n document.externalDocs\n ? `\n## External documentation\n- [${document.externalDocs.description}](${document.externalDocs.url})\n`\n : ''\n}\n\n`;\n};\n\nexport const getSummary = (document: OpenAPI.Document) => {\n const summary = document.info.description ? document.info.description : '';\n return summary && summary.length < 150 ? summary : '';\n};\n\n\nexport const buildService = (pathToFile:string, document: OpenAPI.Document) => {\n const schemaPath = pathToFile.split('/').pop() || 'openapi.yml';\n const documentTags = document.tags || [];\n return {\n id: slugify(document.info.title, { lower: true, strict: true }),\n version: document.info.version,\n name: document.info.title,\n summary: getSummary(document),\n schemaPath,\n markdown: defaultMarkdown(document, schemaPath),\n badges: documentTags.map((tag) => ({ content: tag.name, textColor: 'blue', backgroundColor: 'blue' }))\n }\n};","import SwaggerParser from '@apidevtools/swagger-parser';\nimport { OpenAPIDocument, OpenAPIOperation, OpenAPIParameter, Operation } from '../types';\nimport { OpenAPIV3_1 } from \"openapi-types\";\n\nconst DEFAULT_MESSAGE_TYPE = 'query';\n\nexport async function getSchemasByOperationId(filePath: string, operationId: string): Promise<OpenAPIOperation | undefined> {\n try {\n // Parse and resolve all references in the OpenAPI document\n const api = (await SwaggerParser.dereference(filePath)) as OpenAPIDocument;\n const schemas: {\n parameters: OpenAPIParameter[];\n requestBody: any;\n responses: { [statusCode: string]: any };\n } = {\n parameters: [],\n requestBody: null,\n responses: {},\n };\n\n // Iterate through paths and operations\n for (const [path, pathItem] of Object.entries(api.paths)) {\n for (const [method, operation] of Object.entries(pathItem)) {\n // Cast operation to OpenAPIOperation type\n const typedOperation = operation as OpenAPIOperation;\n\n if (typedOperation.operationId === operationId) {\n // Extract query parameters\n if (typedOperation.parameters) {\n schemas.parameters = typedOperation.parameters;\n }\n\n // Extract request body schema\n if (typedOperation.requestBody && typedOperation.requestBody.content) {\n const contentType = Object.keys(typedOperation.requestBody.content)[0];\n schemas.requestBody = typedOperation.requestBody.content[contentType].schema;\n }\n\n // Extract response schemas\n if (typedOperation.responses) {\n for (const [statusCode, response] of Object.entries(typedOperation.responses)) {\n if (response.content) {\n const contentType = Object.keys(response.content)[0];\n schemas.responses[statusCode] = response.content[contentType].schema || response.content[contentType];\n schemas.responses[statusCode].isSchema = !!response.content[contentType].schema;\n }\n }\n }\n\n return schemas;\n }\n }\n }\n\n throw new Error(`Operation with ID \"${operationId}\" not found.`);\n } catch (error) {\n console.error('Error parsing OpenAPI file or finding operation:', error);\n return;\n }\n}\n\nexport async function getOperationsByType(openApiPath: string) {\n try {\n // Parse the OpenAPI document\n const api = await SwaggerParser.validate(openApiPath);\n\n const operations = [];\n\n // Iterate through paths\n for (const path in api.paths) {\n const pathItem = api.paths[path];\n\n // Iterate through each HTTP method in the path\n for (const method in pathItem) {\n // @ts-ignore\n const openAPIOperation = pathItem[method];\n\n // Check if the x-eventcatalog-message-type field is set\n const messageType = openAPIOperation['x-eventcatalog-message-type'] || DEFAULT_MESSAGE_TYPE;\n\n const operation = {\n path: path,\n method: method.toUpperCase(),\n operationId: openAPIOperation.operationId,\n externalDocs: openAPIOperation.externalDocs,\n type: messageType,\n description: openAPIOperation.description,\n summary: openAPIOperation.summary,\n tags: openAPIOperation.tags || [],\n } as Operation;\n\n operations.push(operation);\n }\n }\n\n return operations;\n } catch (err) {\n console.error('Error parsing OpenAPI document:', err);\n return [];\n }\n}\n","import { OpenAPI } from 'openapi-types';\nimport { getSchemasByOperationId } from './openapi';\nimport { OpenAPIOperation, OpenAPIParameter, Operation } from '../types';\n\nconst markdownForParameters = (parameters: OpenAPIParameter[]) => {\n let markdown = '### Parameters\\n';\n\n for (const parameter of parameters) {\n markdown += `- **${parameter.name}** (${parameter.in})`;\n if (parameter.required) {\n markdown += ' (required)';\n }\n if (parameter.description) {\n markdown += `: ${parameter.description}`;\n }\n markdown += '\\n';\n }\n\n return markdown;\n};\n\nexport const markdownForResponses = (openAPIOperation: OpenAPIOperation) => {\n let markdown = '### Responses\\n';\n\n for (const [statusCode, content] of Object.entries(openAPIOperation.responses as any)) {\n if (content.isSchema) {\n markdown += `**${statusCode} Response**\n<SchemaViewer file=\"response-${statusCode}.json\" maxHeight=\"500\" id=\"response-${statusCode}\" />\n `;\n } else {\n markdown += `**${statusCode} Response**\n \\`\\`\\`json\n${JSON.stringify(content, null, 2)}\n\\`\\`\\`\n `;\n }\n }\n\n return markdown;\n};\n\nexport const defaultMarkdown = (message: Operation, openAPIOperation: OpenAPIOperation = {}) => {\n return `\n\n\n## Architecture\n<NodeGraph />\n\n${\n message.externalDocs\n ? `\n## External documentation\n- [${message.externalDocs.description}](${message.externalDocs.url})\n`\n : ''\n}\n\n## ${message.method.toUpperCase()} \\`(${message.path})\\`\n\n${openAPIOperation.parameters && openAPIOperation.parameters.length > 0 ? markdownForParameters(openAPIOperation.parameters) : ''}\n\n${\n openAPIOperation.requestBody\n ? `\n### Request Body\n<SchemaViewer file=\"request-body.json\" maxHeight=\"500\" id=\"request-body\" />\n`\n : ''\n}\n\n${markdownForResponses(openAPIOperation)}\n\n`;\n};\n\nexport const getSummary = (message: Operation) => {\n const messageSummary = message.summary ? message.summary : '';\n const messageDescription = message.description ? message.description : '';\n\n let eventCatalogMessageSummary = messageSummary;\n\n if (!eventCatalogMessageSummary) {\n eventCatalogMessageSummary = messageDescription && messageDescription.length < 150 ? messageDescription : '';\n }\n\n return eventCatalogMessageSummary;\n};\n\nexport const buildMessage = async (pathToFile: string, document: OpenAPI.Document, operation: Operation) => {\n\n const requestBodiesAndResponses = await getSchemasByOperationId(pathToFile, operation.operationId);\n\n const operationTags = operation.tags.map((badge) => ({\n content: `tag:${badge}`,\n textColor: 'blue',\n backgroundColor: 'blue',\n }));\n\n const badges = [{ content: operation.method.toUpperCase(), textColor: 'blue', backgroundColor: 'blue' }, ...operationTags];\n\n return {\n id: operation.operationId,\n version: document.info.version,\n name: operation.operationId,\n summary: getSummary(operation),\n markdown: defaultMarkdown(operation, requestBodiesAndResponses),\n schemaPath: requestBodiesAndResponses?.requestBody ? 'request-body.json' : '',\n badges,\n requestBodiesAndResponses\n };\n};","/**\n * TODO: Move this into the SDK\n */\n\nimport utils from '@eventcatalog/sdk';\n\nexport const getMessageTypeUtils = (projectDirectory: string, messageType: string) => {\n const {\n writeEvent,\n versionCommand,\n getEvent,\n getCommand,\n rmCommandById,\n rmEventById,\n writeCommand,\n addFileToCommand,\n addFileToEvent,\n versionEvent,\n } = utils(projectDirectory);\n\n if (messageType === 'event') {\n return {\n versionMessage: versionEvent,\n getMessage: getEvent,\n rmMessageById: rmEventById,\n writeMessage: writeEvent,\n addFileToMessage: addFileToEvent,\n };\n }\n\n // default command\n return {\n versionMessage: versionCommand,\n getMessage: getCommand,\n rmMessageById: rmCommandById,\n writeMessage: writeCommand,\n addFileToMessage: addFileToCommand,\n };\n \n};\n"],"mappings":"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","names":["import_sdk","import_swagger_parser","defaultMarkdown","slugify","SwaggerParser","defaultMarkdown","getSummary","utils","utils","chalk","SwaggerParser"]}