committed by
Fredrik Adelöw
parent
62fe726fdc
commit
be5aca5011
@@ -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.
|
||||
@@ -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)`.
|
||||
|
||||
@@ -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<void> {
|
||||
packages.map(async pkg => {
|
||||
let resultText = '';
|
||||
try {
|
||||
await verify(pkg.dir);
|
||||
await verify(pkg.dir, { checkRole: false });
|
||||
} catch (err) {
|
||||
resultText = err.message;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user