Skip to content

Commit 285b6f4

Browse files
committed
feat: parse comment into jsdoc comment block and parse all fields
DX-478
1 parent c676efb commit 285b6f4

File tree

2 files changed

+35
-39
lines changed

2 files changed

+35
-39
lines changed

packages/openapi-generator/src/openapi.ts

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { parseCommentBlock } from './jsdoc';
55
import { optimize } from './optimize';
66
import type { Route } from './route';
77
import type { Schema } from './ir';
8+
import { Block } from 'comment-parser';
89

910
function schemaToOpenAPI(
1011
schema: Schema,
@@ -158,33 +159,39 @@ function schemaToOpenAPI(
158159
return fieldValue === 'true';
159160
} else if (schema.type === 'null') {
160161
return null;
162+
} else if (schema.type === 'string') {
163+
// Remove extraneous double quotes around the fieldValue
164+
return fieldValue?.replace(/^"(.*)"$/, '$1');
161165
} else {
162166
return fieldValue;
163167
}
164168
};
165169

166170
function buildDefaultOpenAPIObject(schema: Schema): OpenAPIV3.SchemaObject {
167-
const defaultValue = getTagName(schema, 'default');
168-
const example = getTagName(schema, 'example');
169-
const maxLength = getTagName(schema, 'maxLength');
170-
const minLength = getTagName(schema, 'minLength');
171-
const pattern = getTagName(schema, 'pattern');
172-
const minimum = getTagName(schema, 'minimum');
173-
const maximum = getTagName(schema, 'maximum');
174-
const minItems = getTagName(schema, 'minItems');
175-
const maxItems = getTagName(schema, 'maxItems');
176-
const minProperties = getTagName(schema, 'minProperties');
177-
const maxProperties = getTagName(schema, 'maxProperties');
178-
const exclusiveMinimum = getTagName(schema, 'exclusiveMinimum');
179-
const exclusiveMaximum = getTagName(schema, 'exclusiveMaximum');
180-
const multipleOf = getTagName(schema, 'multipleOf');
181-
const uniqueItems = getTagName(schema, 'uniqueItems');
182-
const readOnly = getTagName(schema, 'readOnly');
183-
const writeOnly = getTagName(schema, 'writeOnly');
184-
const format = getTagName(schema, 'format');
185-
const title = getTagContent(schema, 'title');
171+
const emptyBlock: Block = { description: '', tags: [], source: [], problems: [] };
172+
const jsdoc = parseCommentBlock(schema.comment ?? emptyBlock);
186173

187-
const deprecated = schema.comment?.tags.find((t) => t.tag === 'deprecated');
174+
const defaultValue = jsdoc?.tags?.default;
175+
const example = jsdoc?.tags?.example;
176+
const maxLength = jsdoc?.tags?.maxLength;
177+
const minLength = jsdoc?.tags?.minLength;
178+
const pattern = jsdoc?.tags?.pattern;
179+
const minimum = jsdoc?.tags?.minimum;
180+
const maximum = jsdoc?.tags?.maximum;
181+
const minItems = jsdoc?.tags?.minItems;
182+
const maxItems = jsdoc?.tags?.maxItems;
183+
const minProperties = jsdoc?.tags?.minProperties;
184+
const maxProperties = jsdoc?.tags?.maxProperties;
185+
const exclusiveMinimum = jsdoc?.tags?.exclusiveMinimum;
186+
const exclusiveMaximum = jsdoc?.tags?.exclusiveMaximum;
187+
const multipleOf = jsdoc?.tags?.multipleOf;
188+
const uniqueItems = jsdoc?.tags?.uniqueItems;
189+
const readOnly = jsdoc?.tags?.readOnly;
190+
const writeOnly = jsdoc?.tags?.writeOnly;
191+
const format = jsdoc?.tags?.format;
192+
const title = jsdoc?.tags?.title;
193+
194+
const deprecated = Object.keys(jsdoc?.tags || {}).includes('deprecated');
188195
const description = schema.comment?.description;
189196

190197
const defaultOpenAPIObject = {
@@ -218,19 +225,6 @@ function schemaToOpenAPI(
218225
return openAPIObject;
219226
}
220227

221-
function getTagName(schema: Schema, tagName: String): string | undefined {
222-
return schema.comment?.tags.find((t) => t.tag === tagName)?.name;
223-
}
224-
225-
function getTagContent(schema: Schema, tagName: String): string | undefined {
226-
if (schema.comment === undefined) return undefined;
227-
228-
const tag = schema.comment.tags.find((t) => t.tag === tagName);
229-
if (tag === undefined) return undefined;
230-
231-
return `${tag.name} ${tag.description}`.trim();
232-
}
233-
234228
function routeToOpenAPI(route: Route): [string, string, OpenAPIV3.OperationObject] {
235229
const jsdoc = route.comment !== undefined ? parseCommentBlock(route.comment) : {};
236230
const operationId = jsdoc.tags?.operationId;

packages/openapi-generator/test/openapi.test.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,7 +2054,7 @@ export const route = h.httpRoute({
20542054
query: {
20552055
/**
20562056
* This is a bar param.
2057-
* @example "{ 'foo': 'bar' }"
2057+
* @example { "foo": "bar" }
20582058
*/
20592059
bar: t.record(t.string, t.string),
20602060
},
@@ -2103,7 +2103,9 @@ testCase('route with descriptions, patterns, and examples', ROUTE_WITH_DESCRIPTI
21032103
required: true,
21042104
schema: {
21052105
type: 'object',
2106-
example: "{ 'foo': 'bar' }",
2106+
example: {
2107+
foo: 'bar'
2108+
},
21072109
additionalProperties: {
21082110
type: 'string'
21092111
}
@@ -2204,7 +2206,7 @@ export const route = h.httpRoute({
22042206
body: {
22052207
/**
22062208
* This is a foo description.
2207-
* @example "BitGo Inc"
2209+
* @example BitGo Inc
22082210
*/
22092211
foo: Foo,
22102212
bar: Bar,
@@ -2349,8 +2351,8 @@ export const route = h.httpRoute({
23492351
* This is a foo description.
23502352
* @minLength 5
23512353
* @maxLength 10
2352-
* @example "SomeInc"
2353-
* @default "BitgoInc"
2354+
* @example SomeInc
2355+
* @default BitgoInc
23542356
*/
23552357
foo: t.string()
23562358
},
@@ -2663,7 +2665,7 @@ export const route = h.httpRoute({
26632665
query: {
26642666
/**
26652667
* This is a foo description.
2666-
* @example "abc"
2668+
* @example abc
26672669
* @pattern ^[a-z]+$
26682670
*/
26692671
foo: h.optional(t.array(t.string))

0 commit comments

Comments
 (0)