diff --git a/README.md b/README.md index 03adf36..996383a 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,10 @@ CLI to help you set up a Node.js TypeScript project. The setup includes: ## Usage -Run directly from GitHub repo via npx: +Run directly from npm via npx: ``` -Usage: npm exec --ignore-scripts -- github:AckeeCZ/create-node-app [OPTIONS] +Usage: npx @ackee/create-node-app [OPTIONS] Options: -d, --dir Destination directory [string] [default: "./node-app"] diff --git a/src/Bootstrap.ts b/src/Bootstrap.ts index d4ea29c..469c598 100644 --- a/src/Bootstrap.ts +++ b/src/Bootstrap.ts @@ -87,7 +87,7 @@ export class Bootstrap { } cli = cli - .version('1.0.0') + .version() .help() .check(argv => { for (const [key, val] of Object.entries(argv)) { diff --git a/starter/api/rest/src/view/cli/openapi/generate.ts b/starter/api/rest/src/view/cli/openapi/generate.ts index d59bbaf..d67fbb0 100644 --- a/starter/api/rest/src/view/cli/openapi/generate.ts +++ b/starter/api/rest/src/view/cli/openapi/generate.ts @@ -33,9 +33,16 @@ export const run = async (argv: any): Promise => { const pathSpec = spec.paths[path] Object.keys(pathSpec).forEach(method => { if (pathSpec[method]?.operationId) { + const operationResponses = pathSpec[method].responses ?? {} + const responseCodes = Object.keys(operationResponses) + const successStatus = responseCodes.find(s => s.startsWith('2')) + ?? responseCodes.find(s => s.startsWith('3')) + ?? '200'; + acc[pathSpec[method].operationId] = { method, path, + successStatus: parseInt(successStatus, 10), } } }) diff --git a/starter/api/rest/src/view/rest/util/openapi.util.ts b/starter/api/rest/src/view/rest/util/openapi.util.ts index f8efc7e..d45b93b 100644 --- a/starter/api/rest/src/view/rest/util/openapi.util.ts +++ b/starter/api/rest/src/view/rest/util/openapi.util.ts @@ -126,11 +126,25 @@ export type ApiHandler = ( ) => TRes | Promise const asyncHandler = - (fn: ApiHandler): express.Handler => + (fn: ApiHandler, operationId?: OperationIds): express.Handler => async (req, res, next) => { try { + if (operationId) { + const metadata = operationPaths[operationId] + if (metadata?.successStatus) { + res.status(metadata.successStatus) + } + } + const result = await fn(req.context, req, res) - res.json(result) + + if (!res.headersSent) { + if (result != undefined) { + res.json(result) + } else { + res.end() + } + } } catch (error: unknown) { next(error) } @@ -158,7 +172,7 @@ type MimeContentValue< type OpenApiContentTypes> = { [K in keyof OpenApiContent]: OpenApiContent[K] extends Content ? MimeContentValue - : never + : void }[keyof OpenApiContent] export type OperationParams = @@ -200,8 +214,9 @@ export type RestApiController< } const handleOperationAsync = ( - fn: OperationHandler -): OpenApiHandler => asyncHandler(fn as any) as any + fn: OperationHandler, + operationId: OperationId +): OpenApiHandler => asyncHandler(fn as any, operationId) as any const createRestController = ( def: RouteHandlers @@ -211,7 +226,8 @@ const createRestController = ( return ctrl } ctrl[operationId as SubsetOperationIds] = handleOperationAsync( - handler as any + handler as any, + operationId as SubsetOperationIds ) as any return ctrl }, {} as RestApiController) @@ -245,6 +261,9 @@ export const openApiRouter = ( case 'post': router.post(route, handler) break + case 'PUT': + router.put(route, handler) + break case 'patch': router.patch(route, handler) break