From bcb909fe3f8b09549148a856cde20507fbe48548 Mon Sep 17 00:00:00 2001
From: David Boyne <boyneyy123@gmail.com>
Date: Tue, 26 Nov 2024 10:53:29 +0000
Subject: [PATCH 1/2] feat(core): added new extensions for name and id in
 openapi

---
 src/index.ts                        |  2 +-
 src/test/openapi-files/petstore.yml |  2 ++
 src/test/plugin.test.ts             | 47 +++++++++++++++++++++++------
 src/types.ts                        |  3 ++
 src/utils/messages.ts               |  5 +--
 src/utils/openapi.ts                |  7 +++++
 6 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/src/index.ts b/src/index.ts
index ef4d9e0..90bda1e 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -193,7 +193,7 @@ const processMessagesForOpenAPISpec = async (pathToSpec: string, document: OpenA
     }
 
     // Write the message to the catalog
-    await writeMessage({ ...message, markdown: messageMarkdown }, { path: message.name, override: true });
+    await writeMessage({ ...message, markdown: messageMarkdown }, { path: message.id, override: true });
 
     // If the message send or recieved by the service?
     if (messageAction === 'sends') {
diff --git a/src/test/openapi-files/petstore.yml b/src/test/openapi-files/petstore.yml
index ec9f2e6..c8987eb 100644
--- a/src/test/openapi-files/petstore.yml
+++ b/src/test/openapi-files/petstore.yml
@@ -24,6 +24,8 @@ paths:
       tags:
         - pets
       x-eventcatalog-message-type: query # This is a query operation
+      x-eventcatalog-message-name: List Pets # Name used in EventCatalog
+      x-eventcatalog-message-id: list-pets # ID value used in EventCatalog
       parameters:
         - name: limit
           in: query
diff --git a/src/test/plugin.test.ts b/src/test/plugin.test.ts
index 2c01698..ff0008f 100644
--- a/src/test/plugin.test.ts
+++ b/src/test/plugin.test.ts
@@ -473,7 +473,7 @@ describe('OpenAPI EventCatalog Plugin', () => {
 
         expect(service.receives).toHaveLength(4);
         expect(service.receives).toEqual([
-          { id: 'listPets', version: '1.0.0' },
+          { id: 'list-pets', version: '1.0.0' },
           { id: 'createPets', version: '1.0.0' },
           { id: 'showPetById', version: '1.0.0' },
           { id: 'petAdopted', version: '1.0.0' },
@@ -501,7 +501,7 @@ describe('OpenAPI EventCatalog Plugin', () => {
         expect(service.receives).toHaveLength(5);
         expect(service.receives).toEqual([
           { id: 'userloggedin', version: '1.0.0' },
-          { id: 'listPets', version: '1.0.0' },
+          { id: 'list-pets', version: '1.0.0' },
           { id: 'createPets', version: '1.0.0' },
           { id: 'showPetById', version: '1.0.0' },
           { id: 'petAdopted', version: '1.0.0' },
@@ -519,7 +519,7 @@ describe('OpenAPI EventCatalog Plugin', () => {
             name: 'Random Name',
             markdown: 'Here is my original markdown, please do not override this!',
             receives: [
-              { id: 'listPets', version: '1.0.0' },
+              { id: 'list-pets', version: '1.0.0' },
               { id: 'createPets', version: '1.0.0' },
             ],
           },
@@ -532,7 +532,7 @@ describe('OpenAPI EventCatalog Plugin', () => {
         expect(service.receives).toHaveLength(4);
 
         expect(service.receives).toEqual([
-          { id: 'listPets', version: '1.0.0' },
+          { id: 'list-pets', version: '1.0.0' },
           { id: 'createPets', version: '1.0.0' },
           { id: 'showPetById', version: '1.0.0' },
           { id: 'petAdopted', version: '1.0.0' },
@@ -562,16 +562,20 @@ describe('OpenAPI EventCatalog Plugin', () => {
 
         await plugin(config, { services: [{ path: join(openAPIExamples, 'petstore.yml'), id: 'swagger-petstore' }] });
 
-        const command = await getQuery('listPets');
+        const command = await getQuery('list-pets');
 
-        const file = await fs.readFile(join(catalogDir, 'queries', 'listPets', 'index.md'));
+        const dir = await fs.readdir(join(catalogDir, 'queries'));
+
+        console.log(dir);
+
+        const file = await fs.readFile(join(catalogDir, 'queries', 'list-pets', 'index.md'));
         expect(file).toBeDefined();
 
         expect(command).toEqual(
           expect.objectContaining({
-            id: 'listPets',
+            id: 'list-pets',
             version: '1.0.0',
-            name: 'listPets',
+            name: 'List Pets',
             summary: 'List all pets',
             badges: [
               { content: 'GET', textColor: 'blue', backgroundColor: 'blue' },
@@ -643,6 +647,31 @@ describe('OpenAPI EventCatalog Plugin', () => {
           expect(service.sends).toHaveLength(1);
           expect(service.sends).toEqual([{ id: 'petVaccinated', version: '1.0.0' }]);
         });
+
+        it('when messages have the `x-eventcatalog-message-name` extension defined, this value is used for the message name', async () => {
+          const { getQuery } = utils(catalogDir);
+
+          await plugin(config, { services: [{ path: join(openAPIExamples, 'petstore.yml'), id: 'swagger-petstore' }] });
+
+          const event = await getQuery('list-pets');
+
+          expect(event).toEqual(
+            expect.objectContaining({
+              id: 'list-pets',
+              name: 'List Pets',
+              version: '1.0.0',
+              summary: 'List all pets',
+            })
+          );
+        });
+        it('when messages have the `x-eventcatalog-message-id` extension defined, this value is used for the message id', async () => {
+          const { getQuery } = utils(catalogDir);
+
+          await plugin(config, { services: [{ path: join(openAPIExamples, 'petstore.yml'), id: 'swagger-petstore' }] });
+
+          const event = await getQuery('list-pets');
+          expect(event.id).toEqual('list-pets');
+        });
       });
 
       it('when the message already exists in EventCatalog but the versions do not match, the existing message is versioned', async () => {
@@ -766,7 +795,7 @@ describe('OpenAPI EventCatalog Plugin', () => {
 
           await plugin(config, { services: [{ path: join(openAPIExamples, 'petstore.yml'), id: 'swagger-petstore' }] });
 
-          const command = await getCommand('listPets');
+          const command = await getCommand('list-pets');
 
           expect(command.markdown).toContain(`### Parameters
 - **limit** (query): How many items to return at one time (max 100)`);
diff --git a/src/types.ts b/src/types.ts
index 3bf9280..d637f5b 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -21,6 +21,9 @@ export type Operation = {
   action: string;
   externalDocs?: OpenAPIV3_1.ExternalDocumentationObject;
   tags: string[];
+  extensions?: {
+    [key: string]: any;
+  };
 };
 
 export interface OpenAPIParameter {
diff --git a/src/utils/messages.ts b/src/utils/messages.ts
index 80f7265..1847f80 100644
--- a/src/utils/messages.ts
+++ b/src/utils/messages.ts
@@ -98,6 +98,7 @@ export const getSummary = (message: Operation) => {
 
 export const buildMessage = async (pathToFile: string, document: OpenAPI.Document, operation: Operation) => {
   const requestBodiesAndResponses = await getSchemasByOperationId(pathToFile, operation.operationId);
+  const extensions = operation.extensions || {};
 
   const operationTags = operation.tags.map((badge) => ({
     content: `tag:${badge}`,
@@ -116,9 +117,9 @@ export const buildMessage = async (pathToFile: string, document: OpenAPI.Documen
   }
 
   return {
-    id: uniqueIdentifier,
+    id: extensions['x-eventcatalog-message-id'] || uniqueIdentifier,
     version: document.info.version,
-    name: uniqueIdentifier,
+    name: extensions['x-eventcatalog-message-name'] || uniqueIdentifier,
     summary: getSummary(operation),
     markdown: defaultMarkdown(operation, requestBodiesAndResponses),
     schemaPath: requestBodiesAndResponses?.requestBody ? 'request-body.json' : '',
diff --git a/src/utils/openapi.ts b/src/utils/openapi.ts
index 7f2c71c..c49893a 100644
--- a/src/utils/openapi.ts
+++ b/src/utils/openapi.ts
@@ -77,6 +77,12 @@ export async function getOperationsByType(openApiPath: string) {
         // Check if the x-eventcatalog-message-type field is set
         const messageType = openAPIOperation['x-eventcatalog-message-type'] || DEFAULT_MESSAGE_TYPE;
         const messageAction = openAPIOperation['x-eventcatalog-message-action'] === 'sends' ? 'sends' : 'receives';
+        const extensions = Object.keys(openAPIOperation).reduce((acc: { [key: string]: any }, key) => {
+          if (key.startsWith('x-eventcatalog-')) {
+            acc[key] = openAPIOperation[key];
+          }
+          return acc;
+        }, {});
 
         const operation = {
           path: path,
@@ -88,6 +94,7 @@ export async function getOperationsByType(openApiPath: string) {
           description: openAPIOperation.description,
           summary: openAPIOperation.summary,
           tags: openAPIOperation.tags || [],
+          extensions,
         } as Operation;
 
         operations.push(operation);

From 73edb5e83c3052e2d52a54e9b854a818cc0bc77c Mon Sep 17 00:00:00 2001
From: David Boyne <boyneyy123@gmail.com>
Date: Tue, 26 Nov 2024 10:53:57 +0000
Subject: [PATCH 2/2] Create sharp-bees-look.md

---
 .changeset/sharp-bees-look.md | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 .changeset/sharp-bees-look.md

diff --git a/.changeset/sharp-bees-look.md b/.changeset/sharp-bees-look.md
new file mode 100644
index 0000000..0cd6bad
--- /dev/null
+++ b/.changeset/sharp-bees-look.md
@@ -0,0 +1,5 @@
+---
+"@eventcatalog/generator-openapi": major
+---
+
+feat(core): added new extensions for name and id in openapi