From be5aca50114921f2b054bac0d9eadd960cda300b Mon Sep 17 00:00:00 2001 From: Aramis Sennyey Date: Tue, 7 Mar 2023 17:57:29 -0500 Subject: [PATCH] Add role checks. Signed-off-by: Aramis Sennyey --- .changeset/cold-seahorses-greet.md | 5 +++ .changeset/tricky-beans-knock.md | 5 ++- packages/cli/src/commands/openapi/verify.ts | 36 +++++++++++++++++---- 3 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 .changeset/cold-seahorses-greet.md diff --git a/.changeset/cold-seahorses-greet.md b/.changeset/cold-seahorses-greet.md new file mode 100644 index 0000000000..e50cdfd673 --- /dev/null +++ b/.changeset/cold-seahorses-greet.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Update `openapi.yaml` and use `ApiRouter` type from `@backstage/backend-openapi-utils` to handle automatic types from the OpenAPI spec file. diff --git a/.changeset/tricky-beans-knock.md b/.changeset/tricky-beans-knock.md index 32357d896c..1bdd95a365 100644 --- a/.changeset/tricky-beans-knock.md +++ b/.changeset/tricky-beans-knock.md @@ -1,6 +1,5 @@ --- -'@backstage/plugin-catalog-backend': minor -'@backstage/backend-openapi-utils': minor +'@backstage/backend-openapi-utils': patch --- -Adding support for typings based on an `openapi.yaml` file. +New plugin! Primary focus is to support types on `Router`s in backend packages. Developers can use the `ApiRouter` from this package in their packages to support a typed experience based on their OpenAPI specs. The `ApiRouter` supports request bodies, response bodies, query parameters and path parameters, as well as full path-based context of the above. This means no more guessing on an endpoint like `req.post('/not-my-route', (req, res)=>{res.send(req.body.badparam)})`. Typescript would catch `/not-my-route`, `req.body.badparam`, `res.send(req.body.badparam)`. diff --git a/packages/cli/src/commands/openapi/verify.ts b/packages/cli/src/commands/openapi/verify.ts index 923114128c..f93672aca9 100644 --- a/packages/cli/src/commands/openapi/verify.ts +++ b/packages/cli/src/commands/openapi/verify.ts @@ -18,20 +18,43 @@ import fs from 'fs-extra'; import { paths } from '../../lib/paths'; import YAML from 'js-yaml'; import { isEqual } from 'lodash'; -import { join } from 'path'; +import { join, resolve } from 'path'; import chalk from 'chalk'; import { relative as relativePath } from 'path'; import { PackageGraph } from '../../lib/monorepo'; import { cloneDeep } from 'lodash'; -import { validate as validateSpec } from '@apidevtools/swagger-parser'; +import Parser from '@apidevtools/swagger-parser'; +import { detectRoleFromPackage } from '../../lib/role'; + +const SUPPORTED_ROLES = [ + 'backend', + 'backend-plugin', + 'backend-plugin-module', + 'node-library', +]; + +async function verify( + directoryPath: string, + { checkRole }: { checkRole: boolean }, +) { + if (checkRole) { + const role = detectRoleFromPackage( + await fs.readJson(resolve(directoryPath, 'package.json')), + ); + + if (!SUPPORTED_ROLES.some(r => r === role)) { + console.log(chalk.red(`Unsupported role ${role}`)); + process.exit(1); + } + } -async function verify(directoryPath: string) { const openapiPath = join(directoryPath, 'openapi.yaml'); if (!(await fs.pathExists(openapiPath))) { return; } + const yaml = YAML.load(await fs.readFile(openapiPath, 'utf8')); - await validateSpec(cloneDeep(yaml) as any); + await Parser.validate(cloneDeep(yaml) as any); const schemaPath = join(directoryPath, 'schema/openapi.ts'); if (!(await fs.pathExists(schemaPath))) { @@ -51,7 +74,8 @@ async function verify(directoryPath: string) { export async function command() { try { - await verify(paths.resolveTarget('.')); + await verify(paths.resolveTarget('.'), { checkRole: true }); + console.log(chalk.green('OpenAPI files are valid.')); } catch (err) { console.error(chalk.red(err.message)); process.exit(1); @@ -65,7 +89,7 @@ export async function bulkCommand(): Promise { packages.map(async pkg => { let resultText = ''; try { - await verify(pkg.dir); + await verify(pkg.dir, { checkRole: false }); } catch (err) { resultText = err.message; }