From 844e004f25ec4b89376b4d62aea735318393be9d Mon Sep 17 00:00:00 2001 From: Petri Lehtinen Date: Wed, 16 Mar 2022 22:09:00 +0200 Subject: [PATCH] Make it possible to move routes under a prefix again --- README.md | 5 +++++ docs/upgrading.md | 18 ++++++++++++++++-- src/generate.ts | 13 +++++++++++-- tests/__snapshots__/generate.spec.ts.snap | 2 +- tests/other-routes.ts | 1 + 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 28a4d6c4..3eb4165b 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,12 @@ const myRoute: Route | Response.BadRequest> = // ... +/** + * @prefix /api + */ export default router(myRoute, ...) + +// The optional @prefix JSDoc tag prepends the prefix to all route paths. ``` Run the `typera-openapi` tool giving paths to your route files as command line diff --git a/docs/upgrading.md b/docs/upgrading.md index ae96e048..53db4534 100644 --- a/docs/upgrading.md +++ b/docs/upgrading.md @@ -60,14 +60,28 @@ const openapiDoc: OpenAPIV3.Document = { version: '0.1.0', }, paths: { - ...routeDefs.paths, - ...otherDefs.paths + ...prefix('/api', routeDefs.paths), + ...prefix('/other', otherDefs.paths), } } ``` New: +Use the `@prefix` JSDoc tag to move routes to a different prefix: + +`routes.ts` + +``` +/** + * @prefix /api + */ +export default router(myRoute, ...) +``` + +The file that has the final OpenAPI document doesn't need to use the `prefix` +function anymore: + ``` import openapi from './openapi' diff --git a/src/generate.ts b/src/generate.ts index 60399bc0..9d619c37 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -70,6 +70,8 @@ const visitTopLevelNode = ( node: ts.Node ): OpenAPIV3.PathsObject | undefined => { if (ts.isExportAssignment(node) && !node.isExportEquals) { + const prefix = getRouterPrefix(node) + // 'export default' statement const argSymbols = getRouterCallArgSymbols(ctx, node.expression) if (!argSymbols) return @@ -96,9 +98,10 @@ const visitTopLevelNode = ( ) if (routeDeclaration) { const [path, method, operation] = routeDeclaration - const pathsItemObject = paths[path] + const prefixedPath = prefix + path + const pathsItemObject = paths[prefixedPath] if (!pathsItemObject) { - paths[path] = { [method]: operation } + paths[prefixedPath] = { [method]: operation } } else { pathsItemObject[method] = operation } @@ -213,6 +216,12 @@ const getRouteTags = (symbol: ts.Symbol): string[] | undefined => .flatMap((symbolDisplayPart) => symbolDisplayPart.text.split(',')) .map((tag) => tag.trim()) +const getRouterPrefix = (node: ts.Node): string => + ts + .getJSDocTags(node) + .filter((tag) => tag.tagName.escapedText === 'prefix') + .flatMap((tag) => (typeof tag.comment === 'string' ? [tag.comment] : []))[0] ?? '' + const operationRequestBody = ( contentSchema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined, contentType = 'application/json' diff --git a/tests/__snapshots__/generate.spec.ts.snap b/tests/__snapshots__/generate.spec.ts.snap index 75733dde..44688eff 100644 --- a/tests/__snapshots__/generate.spec.ts.snap +++ b/tests/__snapshots__/generate.spec.ts.snap @@ -399,7 +399,7 @@ Object { }, }, }, - "/other-route": Object { + "/other-stuff/other-route": Object { "get": Object { "responses": Object { "200": Object { diff --git a/tests/other-routes.ts b/tests/other-routes.ts index 0b6587bb..a61ffd3b 100644 --- a/tests/other-routes.ts +++ b/tests/other-routes.ts @@ -2,4 +2,5 @@ import { Response, route, Route, router } from 'typera-express' const otherRoute: Route> = route.get('/other-route').handler(() => Response.ok('hello')) +/** @prefix /other-stuff */ export default router(otherRoute)