Skip to content

Commit

Permalink
Merge pull request #797 from BitGo/DX-478-example-parsing
Browse files Browse the repository at this point in the history
feat: parse comment into jsdoc comment block and parse all fields
  • Loading branch information
bitgopatmcl authored Jun 12, 2024
2 parents c676efb + 285b6f4 commit 72a27e9
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 39 deletions.
60 changes: 27 additions & 33 deletions packages/openapi-generator/src/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { parseCommentBlock } from './jsdoc';
import { optimize } from './optimize';
import type { Route } from './route';
import type { Schema } from './ir';
import { Block } from 'comment-parser';

function schemaToOpenAPI(
schema: Schema,
Expand Down Expand Up @@ -158,33 +159,39 @@ function schemaToOpenAPI(
return fieldValue === 'true';
} else if (schema.type === 'null') {
return null;
} else if (schema.type === 'string') {
// Remove extraneous double quotes around the fieldValue
return fieldValue?.replace(/^"(.*)"$/, '$1');
} else {
return fieldValue;
}
};

function buildDefaultOpenAPIObject(schema: Schema): OpenAPIV3.SchemaObject {
const defaultValue = getTagName(schema, 'default');
const example = getTagName(schema, 'example');
const maxLength = getTagName(schema, 'maxLength');
const minLength = getTagName(schema, 'minLength');
const pattern = getTagName(schema, 'pattern');
const minimum = getTagName(schema, 'minimum');
const maximum = getTagName(schema, 'maximum');
const minItems = getTagName(schema, 'minItems');
const maxItems = getTagName(schema, 'maxItems');
const minProperties = getTagName(schema, 'minProperties');
const maxProperties = getTagName(schema, 'maxProperties');
const exclusiveMinimum = getTagName(schema, 'exclusiveMinimum');
const exclusiveMaximum = getTagName(schema, 'exclusiveMaximum');
const multipleOf = getTagName(schema, 'multipleOf');
const uniqueItems = getTagName(schema, 'uniqueItems');
const readOnly = getTagName(schema, 'readOnly');
const writeOnly = getTagName(schema, 'writeOnly');
const format = getTagName(schema, 'format');
const title = getTagContent(schema, 'title');
const emptyBlock: Block = { description: '', tags: [], source: [], problems: [] };
const jsdoc = parseCommentBlock(schema.comment ?? emptyBlock);

const deprecated = schema.comment?.tags.find((t) => t.tag === 'deprecated');
const defaultValue = jsdoc?.tags?.default;
const example = jsdoc?.tags?.example;
const maxLength = jsdoc?.tags?.maxLength;
const minLength = jsdoc?.tags?.minLength;
const pattern = jsdoc?.tags?.pattern;
const minimum = jsdoc?.tags?.minimum;
const maximum = jsdoc?.tags?.maximum;
const minItems = jsdoc?.tags?.minItems;
const maxItems = jsdoc?.tags?.maxItems;
const minProperties = jsdoc?.tags?.minProperties;
const maxProperties = jsdoc?.tags?.maxProperties;
const exclusiveMinimum = jsdoc?.tags?.exclusiveMinimum;
const exclusiveMaximum = jsdoc?.tags?.exclusiveMaximum;
const multipleOf = jsdoc?.tags?.multipleOf;
const uniqueItems = jsdoc?.tags?.uniqueItems;
const readOnly = jsdoc?.tags?.readOnly;
const writeOnly = jsdoc?.tags?.writeOnly;
const format = jsdoc?.tags?.format;
const title = jsdoc?.tags?.title;

const deprecated = Object.keys(jsdoc?.tags || {}).includes('deprecated');
const description = schema.comment?.description;

const defaultOpenAPIObject = {
Expand Down Expand Up @@ -218,19 +225,6 @@ function schemaToOpenAPI(
return openAPIObject;
}

function getTagName(schema: Schema, tagName: String): string | undefined {
return schema.comment?.tags.find((t) => t.tag === tagName)?.name;
}

function getTagContent(schema: Schema, tagName: String): string | undefined {
if (schema.comment === undefined) return undefined;

const tag = schema.comment.tags.find((t) => t.tag === tagName);
if (tag === undefined) return undefined;

return `${tag.name} ${tag.description}`.trim();
}

function routeToOpenAPI(route: Route): [string, string, OpenAPIV3.OperationObject] {
const jsdoc = route.comment !== undefined ? parseCommentBlock(route.comment) : {};
const operationId = jsdoc.tags?.operationId;
Expand Down
14 changes: 8 additions & 6 deletions packages/openapi-generator/test/openapi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2054,7 +2054,7 @@ export const route = h.httpRoute({
query: {
/**
* This is a bar param.
* @example "{ 'foo': 'bar' }"
* @example { "foo": "bar" }
*/
bar: t.record(t.string, t.string),
},
Expand Down Expand Up @@ -2103,7 +2103,9 @@ testCase('route with descriptions, patterns, and examples', ROUTE_WITH_DESCRIPTI
required: true,
schema: {
type: 'object',
example: "{ 'foo': 'bar' }",
example: {
foo: 'bar'
},
additionalProperties: {
type: 'string'
}
Expand Down Expand Up @@ -2204,7 +2206,7 @@ export const route = h.httpRoute({
body: {
/**
* This is a foo description.
* @example "BitGo Inc"
* @example BitGo Inc
*/
foo: Foo,
bar: Bar,
Expand Down Expand Up @@ -2349,8 +2351,8 @@ export const route = h.httpRoute({
* This is a foo description.
* @minLength 5
* @maxLength 10
* @example "SomeInc"
* @default "BitgoInc"
* @example SomeInc
* @default BitgoInc
*/
foo: t.string()
},
Expand Down Expand Up @@ -2663,7 +2665,7 @@ export const route = h.httpRoute({
query: {
/**
* This is a foo description.
* @example "abc"
* @example abc
* @pattern ^[a-z]+$
*/
foo: h.optional(t.array(t.string))
Expand Down

0 comments on commit 72a27e9

Please sign in to comment.