Skip to content

Commit

Permalink
Merge pull request #30 from XaaXaaX/feat/add-save-parsed-spec-flag
Browse files Browse the repository at this point in the history
feat([openapi]): persisting parsed or original and resolving refs
  • Loading branch information
boyney123 authored Oct 21, 2024
2 parents df9490b + cade528 commit c7b7cee
Show file tree
Hide file tree
Showing 10 changed files with 485 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/slimy-chefs-hide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@eventcatalog/generator-openapi": patch
---

feat(plugin): added ability to resolve $ref values when saving OpenAPI files to the catalog
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"license": "ISC",
"devDependencies": {
"@types/fs-extra": "^11.0.4",
"@types/js-yaml": "^4.0.9",
"@types/lodash": "^4.17.7",
"@types/node": "^20.16.1",
"prettier": "^3.3.3",
Expand All @@ -37,6 +38,7 @@
"@changesets/cli": "^2.27.7",
"@eventcatalog/sdk": "^0.1.4",
"chalk": "^4",
"js-yaml": "^4.1.0",
"openapi-types": "^12.1.3",
"slugify": "^1.6.6"
}
Expand Down
24 changes: 24 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 12 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import { Domain, Service } from './types';
import { getMessageTypeUtils } from './utils/catalog-shorthand';
import { OpenAPI } from 'openapi-types';
import checkLicense from './utils/checkLicense';
import yaml from 'js-yaml';

type Props = {
services: Service[];
domain?: Domain;
debug?: boolean;
saveParsedSpecFile?: boolean;
};

export default async (_: any, options: Props) => {
Expand All @@ -36,7 +38,7 @@ export default async (_: any, options: Props) => {
getSpecificationFilesForService,
} = utils(process.env.PROJECT_DIR);

const services = options.services ?? [];
const { services = [], saveParsedSpecFile = false } = options;
for (const serviceSpec of services) {
console.log(chalk.green(`Processing ${serviceSpec.path}`));

Expand All @@ -48,8 +50,7 @@ export default async (_: any, options: Props) => {
continue;
}

const openAPIFile = await readFile(serviceSpec.path, 'utf-8');
const document = await SwaggerParser.parse(serviceSpec.path);
const document = await SwaggerParser.dereference(serviceSpec.path);
const version = document.info.version;

const service = buildService(serviceSpec, document);
Expand Down Expand Up @@ -138,7 +139,7 @@ export default async (_: any, options: Props) => {
// add any previous spec files to the list
...serviceSpecificationsFiles,
{
content: openAPIFile,
content: saveParsedSpecFile ? getParsedSpecFile(serviceSpec, document) : await getRawSpecFile(serviceSpec),
fileName: service.schemaPath,
},
];
Expand Down Expand Up @@ -235,3 +236,10 @@ const processMessagesForOpenAPISpec = async (pathToSpec: string, document: OpenA
}
return { receives, sends: [] };
};

const getParsedSpecFile = (service: Service, document: OpenAPI.Document) => {
const isSpecFileJSON = service.path.endsWith('.json');
return isSpecFileJSON ? JSON.stringify(document, null, 2) : yaml.dump(document, { noRefs: true });
};

const getRawSpecFile = async (service: Service) => await readFile(service.path, 'utf8');
20 changes: 20 additions & 0 deletions src/test/openapi-files/ref-example-signup-message.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
type: object
properties:
id:
type: string
name:
type: string
description:
type: string
price:
type: number
format: float
category:
type: string
imageUrl:
type: string
required:
- id
- name
- price
- category
123 changes: 123 additions & 0 deletions src/test/openapi-files/ref-example-with-resolved-refs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
{
"openapi": "3.0.0",
"info": {
"title": "Test Service",
"version": "1.1.0"
},
"paths": {
"/signup": {
"post": {
"operationId": "usersignup",
"summary": "List all users",
"description": "Returns a list of all users.\nThis operation is **deprecated**.\n",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"price": {
"type": "number",
"format": "float"
},
"category": {
"type": "string"
},
"imageUrl": {
"type": "string"
}
},
"required": ["id", "name", "price", "category"]
}
}
}
},
"responses": {
"200": {
"description": "A list of users",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"price": {
"type": "number",
"format": "float"
},
"category": {
"type": "string"
},
"imageUrl": {
"type": "string"
}
},
"required": ["id", "name", "price", "category"]
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"UserSignup": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"price": {
"type": "number",
"format": "float"
},
"category": {
"type": "string"
},
"imageUrl": {
"type": "string"
}
},
"required": ["id", "name", "price", "category"]
},
"Date": {
"type": "string",
"format": "date"
},
"DateWithExample": {
"description": "Date schema extended with a `default` value... Or not?",
"default": "2000-01-01T00:00:00.000Z",
"type": "string",
"format": "date"
}
}
}
}
95 changes: 95 additions & 0 deletions src/test/openapi-files/ref-example-with-resolved-refs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
openapi: 3.0.0
info:
title: Test Service
version: 1.1.0
paths:
/signup:
post:
operationId: usersignup
summary: List all users
description: |
Returns a list of all users.
This operation is **deprecated**.
requestBody:
content:
application/json:
schema:
type: object
properties:
id:
type: string
name:
type: string
description:
type: string
price:
type: number
format: float
category:
type: string
imageUrl:
type: string
required:
- id
- name
- price
- category
responses:
'200':
description: A list of users
content:
application/json:
schema:
type: array
items:
type: object
properties:
id:
type: string
name:
type: string
description:
type: string
price:
type: number
format: float
category:
type: string
imageUrl:
type: string
required:
- id
- name
- price
- category
components:
schemas:
UserSignup:
type: object
properties:
id:
type: string
name:
type: string
description:
type: string
price:
type: number
format: float
category:
type: string
imageUrl:
type: string
required:
- id
- name
- price
- category
Date:
type: string
format: date
DateWithExample:
description: Date schema extended with a `default` value... Or not?
default: 2000-01-01T00:00:00.000Z
type: string
format: date
Loading

0 comments on commit c7b7cee

Please sign in to comment.