diff --git a/packages/openapi-generator/src/cli.ts b/packages/openapi-generator/src/cli.ts index 4e33e51e..cf5fe22d 100644 --- a/packages/openapi-generator/src/cli.ts +++ b/packages/openapi-generator/src/cli.ts @@ -60,6 +60,13 @@ const app = command({ short: 'i', defaultValue: () => false, }), + includeUnstable: flag({ + type: boolean, + description: 'include routes marked unstable', + long: 'unstable', + short: 'u', + defaultValue: () => false, + }), codecFile: option({ type: optional(string), description: 'Custom codec definition file', diff --git a/packages/openapi-generator/src/openapi.ts b/packages/openapi-generator/src/openapi.ts index e95638d2..6fc04216 100644 --- a/packages/openapi-generator/src/openapi.ts +++ b/packages/openapi-generator/src/openapi.ts @@ -116,6 +116,7 @@ function routeToOpenAPI(route: Route): [string, string, OpenAPIV3.OperationObjec const operationId = jsdoc.tags?.operationId; const tag = jsdoc.tags?.tag ?? ''; const isInternal = jsdoc.tags?.private !== undefined; + const isUnstable = jsdoc.tags?.unstable !== undefined; const requestBody = route.body === undefined @@ -137,6 +138,7 @@ function routeToOpenAPI(route: Route): [string, string, OpenAPIV3.OperationObjec ...(operationId !== undefined ? { operationId } : {}), ...(tag !== '' ? { tags: [tag] } : {}), ...(isInternal ? { 'x-internal': true } : {}), + ...(isUnstable ? { 'x-unstable': true } : {}), parameters: route.parameters.map((p) => { // Array types not allowed here const schema = schemaToOpenAPI(p.schema); diff --git a/packages/openapi-generator/test/openapi.test.ts b/packages/openapi-generator/test/openapi.test.ts index dad2e9a7..a2e9c862 100644 --- a/packages/openapi-generator/test/openapi.test.ts +++ b/packages/openapi-generator/test/openapi.test.ts @@ -16,7 +16,7 @@ import { async function testCase( description: string, src: string, - expected: OpenAPIV3_1.Document<{ 'x-internal'?: boolean }>, + expected: OpenAPIV3_1.Document<{ 'x-internal'?: boolean; 'x-unstable'?: boolean }>, expectedErrors: string[] = [], ) { test(description, async () => { @@ -106,6 +106,26 @@ export const internalRoute = h.httpRoute({ 200: t.string }, }); + +/** + * An unstable route + * + * @unstable + * @operationId api.v1.unstable + * @tag Unstable Routes + */ +export const unstableRoute = h.httpRoute({ + path: '/unstable/foo', + method: 'GET', + request: h.httpRequest({ + query: { + foo: t.string, + }, + }), + response: { + 200: t.string + }, +}); `; testCase('simple route', SIMPLE, { @@ -181,6 +201,36 @@ testCase('simple route', SIMPLE, { }, }, }, + '/unstable/foo': { + get: { + summary: 'An unstable route', + operationId: 'api.v1.unstable', + tags: ['Unstable Routes'], + 'x-unstable': true, + parameters: [ + { + in: 'query', + name: 'foo', + required: true, + schema: { + type: 'string', + }, + }, + ], + responses: { + 200: { + description: 'OK', + content: { + 'application/json': { + schema: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, }, components: { schemas: {},