From ff3a604dae3157b26f2b618411d8d860554d583e Mon Sep 17 00:00:00 2001 From: Aramis Date: Thu, 18 Jan 2024 18:00:01 -0500 Subject: [PATCH] feat(repo-tools): Update OpenAPI command naming. fixes: https://github.com/backstage/backstage/issues/21790 Signed-off-by: Aramis --- docs/openapi/01-getting-started.md | 6 +- packages/repo-tools/src/commands/index.ts | 99 +++++++++++++------ .../schema/openapi/generate/client.ts} | 35 ++++--- .../schema/openapi/generate/server.ts} | 57 +++-------- .../test => package/schema/openapi}/init.ts | 10 +- .../{ => repo/schema}/openapi/lint.ts | 25 ++--- .../index.ts => repo/schema/openapi/test.ts} | 16 +-- .../schema => repo/schema/openapi}/verify.ts | 20 ++-- .../{commands => lib}/openapi/constants.ts | 0 .../repo-tools/src/lib/openapi/helpers.ts | 32 ++++++ .../src/{commands/openapi => lib}/runner.ts | 4 +- plugins/catalog-backend/package.json | 5 +- plugins/search-backend/package.json | 3 +- plugins/todo-backend/package.json | 4 +- yarn.lock | 4 +- 15 files changed, 195 insertions(+), 125 deletions(-) rename packages/repo-tools/src/commands/{openapi/client/generate.ts => package/schema/openapi/generate/client.ts} (73%) rename packages/repo-tools/src/commands/{openapi/schema/generate.ts => package/schema/openapi/generate/server.ts} (60%) rename packages/repo-tools/src/commands/{openapi/test => package/schema/openapi}/init.ts (90%) rename packages/repo-tools/src/commands/{ => repo/schema}/openapi/lint.ts (83%) rename packages/repo-tools/src/commands/{openapi/test/index.ts => repo/schema/openapi/test.ts} (86%) rename packages/repo-tools/src/commands/{openapi/schema => repo/schema/openapi}/verify.ts (79%) rename packages/repo-tools/src/{commands => lib}/openapi/constants.ts (100%) create mode 100644 packages/repo-tools/src/lib/openapi/helpers.ts rename packages/repo-tools/src/{commands/openapi => lib}/runner.ts (94%) diff --git a/docs/openapi/01-getting-started.md b/docs/openapi/01-getting-started.md index eb3b1c1209..ce04e75107 100644 --- a/docs/openapi/01-getting-started.md +++ b/docs/openapi/01-getting-started.md @@ -45,7 +45,7 @@ You should create a new folder, `src/schema` in your backend plugin to store you ## Generating a typed express router from a spec -Run `yarn backstage-repo-tools schema openapi generate `. This will create an `openapi.generated.ts` file in the `src/schema` directory that contains the OpenAPI schema as well as a generated express router with types. +Run `yarn backstage-repo-tools package schema openapi generate server `. This will create an `openapi.generated.ts` file in the `src/schema` directory that contains the OpenAPI schema as well as a generated express router with types. You should add this command to your `package.json` for future use. Use it like so, update your `router.ts` or `createRouter.ts` file with the following content, @@ -63,7 +63,7 @@ export async function createRouter( ## Generating a typed client from a spec -Run `yarn backstage-repo-tools schema openapi generate-client --input-spec /src/schema/openapi.yaml --output-directory `. `` should match the same backend plugin we've been using so far. `` is a new directory and npm package that you should create. The general pattern is `plugins/-client`. +From your current backend plugin directory, run `yarn backstage-repo-tools package schema openapi generate client --output-package `. `` is a new directory and npm package that you should create. The general pattern is `plugins/-client` or if you want to co-locate this with your other shared types, use `plugins/-common`. You should add this command to your `package.json` for future use. The generated client will have a directory `src/generated` that exports a `DefaultApiClient` class and all generated types. You can use the client like so, @@ -108,7 +108,7 @@ describe('createRouter', () => { + app = wrapInOpenApiTestServer(express().use(router)); ``` -This adds a wrapper around the express server that allows it to reroute traffic for `supertest`. Run `yarn backstage-repo-tools schema openapi init` to create some required config files. Now, when you run `yarn backstage-repo-tools schema openapi test` your schema will now be tested against your test data. Any errors will be reported. +This adds a wrapper around the express server that allows it to reroute traffic for `supertest`. Run `yarn backstage-repo-tools package schema openapi init` to create some required files. Now, when you run `yarn backstage-repo-tools repo schema openapi test` your schema will now be tested against your test data. Any errors will be reported. Our command is a small wrapper over [`Optic`](https://github.com/opticdev/optic) which does all of the heavy lifting. diff --git a/packages/repo-tools/src/commands/index.ts b/packages/repo-tools/src/commands/index.ts index d9c6d892f5..06ea2fa95c 100644 --- a/packages/repo-tools/src/commands/index.ts +++ b/packages/repo-tools/src/commands/index.ts @@ -18,12 +18,71 @@ import { assertError } from '@backstage/errors'; import { Command } from 'commander'; import { exitWithError } from '../lib/errors'; -function registerSchemaCommand(program: Command) { +function registerPackageCommand(program: Command) { const command = program + .command('package [command]') + .description('Various tools for working with specific packages.'); + + const schemaCommand = command + .command('schema [command]') + .description( + "Various tools for working with specific packages' API schema", + ); + + const openApiCommand = schemaCommand + .command('openapi [command]') + .description('Tooling for OpenAPI schema'); + + openApiCommand + .command('init') + .description('Initialize any required files to use the OpenAPI tooling.') + .action( + lazy(() => import('./package/schema/openapi/init').then(m => m.default)), + ); + + const generateCommand = openApiCommand + .command('generate [command]') + .description( + 'Commands for generating various things from an OpenAPI spec.', + ); + + generateCommand + .command('server') + .description( + 'Generates an express server stub using the OpenAPI schema for typings.', + ) + .action( + lazy(() => + import('./package/schema/openapi/generate/server').then(m => m.command), + ), + ); + + generateCommand + .command('client') + .description( + 'Generates a client that can interact with your backend plugin using types from your OpenAPI schema.', + ) + .requiredOption( + '--output-package ', + 'Top-level path to where the client should be generated, ie packages/catalog-client.', + ) + .action( + lazy(() => + import('./package/schema/openapi/generate/client').then(m => m.command), + ), + ); +} + +function registerRepoCommand(program: Command) { + const command = program + .command('repo [command]') + .description('Tools for working across your entire repository.'); + + const schemaCommand = command .command('schema [command]') .description('Various tools for working with API schema'); - const openApiCommand = command + const openApiCommand = schemaCommand .command('openapi [command]') .description('Tooling for OpenApi schema'); @@ -33,16 +92,9 @@ function registerSchemaCommand(program: Command) { 'Verify that all OpenAPI schemas are valid and have a matching `schemas/openapi.generated.ts` file.', ) .action( - lazy(() => import('./openapi/schema/verify').then(m => m.bulkCommand)), - ); - - openApiCommand - .command('generate [paths...]') - .description( - 'Generates a Typescript file from an OpenAPI yaml spec. For use with the `@backstage/backend-openapi-utils` ApiRouter type.', - ) - .action( - lazy(() => import('./openapi/schema/generate').then(m => m.bulkCommand)), + lazy(() => + import('./repo/schema/openapi/verify').then(m => m.bulkCommand), + ), ); openApiCommand @@ -52,27 +104,16 @@ function registerSchemaCommand(program: Command) { '--strict', 'Fail on any linting severity messages, not just errors.', ) - .action(lazy(() => import('./openapi/lint').then(m => m.bulkCommand))); + .action( + lazy(() => import('./repo/schema/openapi/lint').then(m => m.bulkCommand)), + ); openApiCommand .command('test [paths...]') .description('Test OpenAPI schemas against written tests') .option('--update', 'Update the spec on failure.') - .action(lazy(() => import('./openapi/test').then(m => m.bulkCommand))); - - openApiCommand - .command('init ') - .description('Creates any config needed for the test command.') - .action(lazy(() => import('./openapi/test/init').then(m => m.default))); - - openApiCommand - .command('generate-client') - .requiredOption('--input-spec ') - .requiredOption('--output-directory ') .action( - lazy(() => - import('./openapi/client/generate').then(m => m.singleCommand), - ), + lazy(() => import('./repo/schema/openapi/test').then(m => m.bulkCommand)), ); } @@ -139,8 +180,8 @@ export function registerCommands(program: Command) { ), ), ); - - registerSchemaCommand(program); + registerPackageCommand(program); + registerRepoCommand(program); } // Wraps an action function so that it always exits and handles errors diff --git a/packages/repo-tools/src/commands/openapi/client/generate.ts b/packages/repo-tools/src/commands/package/schema/openapi/generate/client.ts similarity index 73% rename from packages/repo-tools/src/commands/openapi/client/generate.ts rename to packages/repo-tools/src/commands/package/schema/openapi/generate/client.ts index f827f1005f..101c2c918b 100644 --- a/packages/repo-tools/src/commands/openapi/client/generate.ts +++ b/packages/repo-tools/src/commands/package/schema/openapi/generate/client.ts @@ -16,16 +16,23 @@ import chalk from 'chalk'; import { resolve } from 'path'; -import { OPENAPI_IGNORE_FILES, OUTPUT_PATH } from '../constants'; -import { paths as cliPaths } from '../../../lib/paths'; +import { + OPENAPI_IGNORE_FILES, + OUTPUT_PATH, +} from '../../../../../lib/openapi/constants'; +import { paths as cliPaths } from '../../../../../lib/paths'; import { mkdirpSync } from 'fs-extra'; import fs from 'fs-extra'; -import { exec } from '../../../lib/exec'; +import { exec } from '../../../../../lib/exec'; import { resolvePackagePath } from '@backstage/backend-common'; +import { getPathToCurrentOpenApiSpec } from '../../../../../lib/openapi/helpers'; -async function generate(spec: string, outputDirectory: string) { - const resolvedOpenapiPath = resolve(spec); - const resolvedOutputDirectory = resolve(outputDirectory, OUTPUT_PATH); +async function generate(outputDirectory: string) { + const resolvedOpenapiPath = await getPathToCurrentOpenApiSpec(); + const resolvedOutputDirectory = cliPaths.resolveTargetRoot( + outputDirectory, + OUTPUT_PATH, + ); mkdirpSync(resolvedOutputDirectory); await fs.mkdirp(resolvedOutputDirectory); @@ -80,19 +87,19 @@ async function generate(spec: string, outputDirectory: string) { }); } -export async function singleCommand({ - inputSpec, - outputDirectory, +export async function command({ + outputPackage, }: { - inputSpec: string; - outputDirectory: string; + outputPackage: string; }): Promise { try { - await generate(inputSpec, outputDirectory); - console.log(chalk.green(`Generated client for ${inputSpec}`)); + await generate(outputPackage); + console.log( + chalk.green(`Generated client in ${outputPackage}/${OUTPUT_PATH}`), + ); } catch (err) { console.log(); - console.log(chalk.red(`Client generation failed in ${outputDirectory}:`)); + console.log(chalk.red(`Client generation failed:`)); console.log(err); process.exit(1); diff --git a/packages/repo-tools/src/commands/openapi/schema/generate.ts b/packages/repo-tools/src/commands/package/schema/openapi/generate/server.ts similarity index 60% rename from packages/repo-tools/src/commands/openapi/schema/generate.ts rename to packages/repo-tools/src/commands/package/schema/openapi/generate/server.ts index cd9f572f2d..e6c56c3122 100644 --- a/packages/repo-tools/src/commands/openapi/schema/generate.ts +++ b/packages/repo-tools/src/commands/package/schema/openapi/generate/server.ts @@ -17,30 +17,19 @@ import fs from 'fs-extra'; import YAML from 'js-yaml'; import chalk from 'chalk'; -import { resolve } from 'path'; -import { paths as cliPaths } from '../../../lib/paths'; -import { runner } from '../runner'; -import { TS_SCHEMA_PATH, YAML_SCHEMA_PATH } from '../constants'; +import { paths as cliPaths } from '../../../../../lib/paths'; +import { TS_SCHEMA_PATH } from '../../../../../lib/openapi/constants'; import { promisify } from 'util'; import { exec as execCb } from 'child_process'; +import { getPathToCurrentOpenApiSpec } from '../../../../../lib/openapi/helpers'; const exec = promisify(execCb); -async function generate( - directoryPath: string, - config?: { skipMissingYamlFile: boolean }, -) { - const { skipMissingYamlFile } = config ?? {}; - const openapiPath = resolve(directoryPath, YAML_SCHEMA_PATH); - if (!(await fs.pathExists(openapiPath))) { - if (skipMissingYamlFile) { - return; - } - throw new Error(`Could not find ${YAML_SCHEMA_PATH} in root of directory.`); - } +async function generate() { + const openapiPath = await getPathToCurrentOpenApiSpec(); const yaml = YAML.load(await fs.readFile(openapiPath, 'utf8')); - const tsPath = resolve(directoryPath, TS_SCHEMA_PATH); + const tsPath = cliPaths.resolveTarget(TS_SCHEMA_PATH); // The first set of comment slashes allow for the eslint notice plugin to run // with onNonMatchingHeader: 'replace', as is the case in the open source @@ -63,33 +52,19 @@ export const createOpenApiRouter = async ( await exec(`yarn backstage-cli package lint --fix ${tsPath}`); if (await cliPaths.resolveTargetRoot('node_modules/.bin/prettier')) { - await exec(`yarn prettier --write ${tsPath}`); + await exec(`yarn prettier --write ${tsPath}`, { + cwd: cliPaths.targetRoot, + }); } } -export async function bulkCommand(paths: string[] = []): Promise { - const resultsList = await runner(paths, (dir: string) => - generate(dir, { skipMissingYamlFile: true }), - ); - - let failed = false; - for (const { relativeDir, resultText } of resultsList) { - if (resultText) { - console.log(); - console.log( - chalk.red( - `OpenAPI yaml to Typescript generation failed in ${relativeDir}:`, - ), - ); - console.log(resultText.trimStart()); - - failed = true; - } - } - - if (failed) { - process.exit(1); - } else { +export async function command(): Promise { + try { + await generate(); console.log(chalk.green('Generated all files.')); + } catch (err) { + console.log(chalk.red(`OpenAPI server stub generation failed.`)); + console.log(err.message); + process.exit(1); } } diff --git a/packages/repo-tools/src/commands/openapi/test/init.ts b/packages/repo-tools/src/commands/package/schema/openapi/init.ts similarity index 90% rename from packages/repo-tools/src/commands/openapi/test/init.ts rename to packages/repo-tools/src/commands/package/schema/openapi/init.ts index a38416aabb..56136f8882 100644 --- a/packages/repo-tools/src/commands/openapi/test/init.ts +++ b/packages/repo-tools/src/commands/package/schema/openapi/init.ts @@ -15,12 +15,12 @@ */ import fs from 'fs-extra'; import { join } from 'path'; -import { YAML_SCHEMA_PATH } from './../constants'; +import { YAML_SCHEMA_PATH } from '../../../../lib/openapi/constants'; -import { paths as cliPaths } from '../../../lib/paths'; -import { runner } from '../runner'; +import { paths as cliPaths } from '../../../../lib/paths'; +import { runner } from '../../../../lib/runner'; import chalk from 'chalk'; -import { exec } from '../../../lib/exec'; +import { exec } from '../../../../lib/exec'; const ROUTER_TEST_PATHS = [ 'src/service/router.test.ts', @@ -31,7 +31,7 @@ async function init(directoryPath: string) { const openapiPath = join(directoryPath, YAML_SCHEMA_PATH); if (!(await fs.pathExists(openapiPath))) { throw new Error( - `You do not have an OpenAPI YAML file at ${openapiPath}. Please create one and retry this command. If you already have existing test cases for your router, see 'backstage-repo-tools schema openapi test --update'`, + `You do not have an OpenAPI YAML file at ${openapiPath}. Please create one and retry this command. If you already have existing test cases for your router, see 'backstage-repo-tools package schema openapi test --update'`, ); } const opticConfigFilePath = join(directoryPath, 'optic.yml'); diff --git a/packages/repo-tools/src/commands/openapi/lint.ts b/packages/repo-tools/src/commands/repo/schema/openapi/lint.ts similarity index 83% rename from packages/repo-tools/src/commands/openapi/lint.ts rename to packages/repo-tools/src/commands/repo/schema/openapi/lint.ts index 8aac0189b1..eacb3ac50d 100644 --- a/packages/repo-tools/src/commands/openapi/lint.ts +++ b/packages/repo-tools/src/commands/repo/schema/openapi/lint.ts @@ -24,24 +24,19 @@ import { Yaml } from '@stoplight/spectral-parsers'; import ruleset from '@apisyouwonthate/style-guide'; import fs from 'fs-extra'; import chalk from 'chalk'; -import { resolve } from 'path'; -import { runner } from './runner'; -import { YAML_SCHEMA_PATH } from './constants'; +import { runner } from '../../../../lib/runner'; import { oas } from '@stoplight/spectral-rulesets'; import { DiagnosticSeverity } from '@stoplight/types'; import { pretty } from '@stoplight/spectral-formatters'; +import { getPathToOpenApiSpec } from '../../../../lib/openapi/helpers'; -async function lint( - directoryPath: string, - config?: { skipMissingYamlFile: boolean; strict: boolean }, -) { - const { skipMissingYamlFile, strict } = config ?? {}; - const openapiPath = resolve(directoryPath, YAML_SCHEMA_PATH); - if (!(await fs.pathExists(openapiPath))) { - if (skipMissingYamlFile) { - return; - } - throw new Error(`Could not find a file at ${openapiPath}.`); +async function lint(directoryPath: string, config?: { strict: boolean }) { + const { strict } = config ?? {}; + let openapiPath = ''; + try { + openapiPath = await getPathToOpenApiSpec(directoryPath); + } catch { + return; } const openapiFileContent = await fs.readFile(openapiPath, 'utf8'); @@ -90,7 +85,7 @@ export async function bulkCommand( options: { strict?: boolean }, ): Promise { const resultsList = await runner(paths, (dir: string) => - lint(dir, { skipMissingYamlFile: true, strict: !!options.strict }), + lint(dir, { strict: !!options.strict }), ); let failed = false; diff --git a/packages/repo-tools/src/commands/openapi/test/index.ts b/packages/repo-tools/src/commands/repo/schema/openapi/test.ts similarity index 86% rename from packages/repo-tools/src/commands/openapi/test/index.ts rename to packages/repo-tools/src/commands/repo/schema/openapi/test.ts index 47b553aaef..833de181e3 100644 --- a/packages/repo-tools/src/commands/openapi/test/index.ts +++ b/packages/repo-tools/src/commands/repo/schema/openapi/test.ts @@ -17,18 +17,22 @@ import fs from 'fs-extra'; import { join } from 'path'; import chalk from 'chalk'; -import { runner } from '../runner'; -import { YAML_SCHEMA_PATH } from '../constants'; -import { paths as cliPaths } from '../../../lib/paths'; -import { exec } from '../../../lib/exec'; +import { runner } from '../../../../lib/runner'; +import { YAML_SCHEMA_PATH } from '../../../../lib/openapi/constants'; +import { paths as cliPaths } from '../../../../lib/paths'; +import { exec } from '../../../../lib/exec'; +import { getPathToOpenApiSpec } from '../../../../lib/openapi/helpers'; async function test( directoryPath: string, { port }: { port: number }, options?: { update?: boolean }, ) { - const openapiPath = join(directoryPath, YAML_SCHEMA_PATH); - if (!(await fs.pathExists(openapiPath))) { + let openapiPath = join(directoryPath, YAML_SCHEMA_PATH); + try { + openapiPath = await getPathToOpenApiSpec(directoryPath); + } catch { + // OpenAPI schema doesn't exist. return; } const opticConfigFilePath = join(directoryPath, 'optic.yml'); diff --git a/packages/repo-tools/src/commands/openapi/schema/verify.ts b/packages/repo-tools/src/commands/repo/schema/openapi/verify.ts similarity index 79% rename from packages/repo-tools/src/commands/openapi/schema/verify.ts rename to packages/repo-tools/src/commands/repo/schema/openapi/verify.ts index 7120dd67ad..442494610c 100644 --- a/packages/repo-tools/src/commands/openapi/schema/verify.ts +++ b/packages/repo-tools/src/commands/repo/schema/openapi/verify.ts @@ -21,13 +21,21 @@ import { join } from 'path'; import chalk from 'chalk'; import { relative as relativePath, resolve as resolvePath } from 'path'; import Parser from '@apidevtools/swagger-parser'; -import { runner } from '../runner'; -import { paths as cliPaths } from '../../../lib/paths'; -import { TS_MODULE, TS_SCHEMA_PATH, YAML_SCHEMA_PATH } from '../constants'; +import { runner } from '../../../../lib/runner'; +import { paths as cliPaths } from '../../../../lib/paths'; +import { + TS_MODULE, + TS_SCHEMA_PATH, + YAML_SCHEMA_PATH, +} from '../../../../lib/openapi/constants'; +import { getPathToOpenApiSpec } from '../../../../lib/openapi/helpers'; async function verify(directoryPath: string) { - const openapiPath = join(directoryPath, YAML_SCHEMA_PATH); - if (!(await fs.pathExists(openapiPath))) { + let openapiPath = ''; + try { + openapiPath = await getPathToOpenApiSpec(directoryPath); + } catch { + // Unable to find spec at path. return; } @@ -47,7 +55,7 @@ async function verify(directoryPath: string) { if (!isEqual(schema.spec, yaml)) { const path = relativePath(cliPaths.targetRoot, directoryPath); throw new Error( - `\`${YAML_SCHEMA_PATH}\` and \`${TS_SCHEMA_PATH}\` do not match. Please run \`yarn backstage-repo-tools schema openapi generate ${path}\` to regenerate \`${TS_SCHEMA_PATH}\`.`, + `\`${YAML_SCHEMA_PATH}\` and \`${TS_SCHEMA_PATH}\` do not match. Please run \`yarn backstage-repo-tools package schema openapi generate\` from '${path}' to regenerate \`${TS_SCHEMA_PATH}\`.`, ); } } diff --git a/packages/repo-tools/src/commands/openapi/constants.ts b/packages/repo-tools/src/lib/openapi/constants.ts similarity index 100% rename from packages/repo-tools/src/commands/openapi/constants.ts rename to packages/repo-tools/src/lib/openapi/constants.ts diff --git a/packages/repo-tools/src/lib/openapi/helpers.ts b/packages/repo-tools/src/lib/openapi/helpers.ts new file mode 100644 index 0000000000..5a5932c802 --- /dev/null +++ b/packages/repo-tools/src/lib/openapi/helpers.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { pathExists } from 'fs-extra'; +import { paths } from '../paths'; +import { YAML_SCHEMA_PATH } from './constants'; +import { resolve } from 'path'; + +export const getPathToOpenApiSpec = async (directory: string) => { + const openapiPath = resolve(directory, YAML_SCHEMA_PATH); + if (!(await pathExists(openapiPath))) { + throw new Error(`Could not find ${YAML_SCHEMA_PATH}.`); + } + return openapiPath; +}; + +export const getPathToCurrentOpenApiSpec = async () => { + return await getPathToOpenApiSpec(paths.targetDir); +}; diff --git a/packages/repo-tools/src/commands/openapi/runner.ts b/packages/repo-tools/src/lib/runner.ts similarity index 94% rename from packages/repo-tools/src/commands/openapi/runner.ts rename to packages/repo-tools/src/lib/runner.ts index cc354daaaa..b9700cd09b 100644 --- a/packages/repo-tools/src/commands/openapi/runner.ts +++ b/packages/repo-tools/src/lib/runner.ts @@ -14,10 +14,10 @@ * limitations under the License. */ -import { resolvePackagePaths } from '../../lib/paths'; +import { resolvePackagePaths } from './paths'; import pLimit from 'p-limit'; import { relative as relativePath } from 'path'; -import { paths as cliPaths } from '../../lib/paths'; +import { paths as cliPaths } from './paths'; import portFinder from 'portfinder'; export async function runner( diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 42f40cccd2..eee268736a 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -42,7 +42,9 @@ "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "clean": "backstage-cli package clean", + "generate-server": "backstage-repo-tools package schema openapi generate server", + "generate-client": "backstage-repo-tools package schema openapi generate client --output-package packages/catalog-client" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -61,6 +63,7 @@ "@backstage/plugin-permission-common": "workspace:^", "@backstage/plugin-permission-node": "workspace:^", "@backstage/plugin-search-backend-module-catalog": "workspace:^", + "@backstage/repo-tools": "workspace:^", "@backstage/types": "workspace:^", "@opentelemetry/api": "^1.3.0", "@types/express": "^4.17.6", diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index bea288f6b2..b328083246 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -39,7 +39,8 @@ "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", - "clean": "backstage-cli package clean" + "clean": "backstage-cli package clean", + "generate-server": "backstage-repo-tools package schema openapi generate server" }, "dependencies": { "@backstage/backend-common": "workspace:^", diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index ddf3baac3d..75a070e284 100644 --- a/plugins/todo-backend/package.json +++ b/plugins/todo-backend/package.json @@ -26,7 +26,8 @@ "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack", "clean": "backstage-cli package clean", - "start": "backstage-cli package start" + "start": "backstage-cli package start", + "generate-server": "backstage-repo-tools package schema openapi generate server" }, "dependencies": { "@backstage/backend-common": "workspace:^", @@ -38,6 +39,7 @@ "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", + "@backstage/repo-tools": "workspace:^", "@types/express": "^4.17.6", "express": "^4.17.1", "leasot": "^12.0.0", diff --git a/yarn.lock b/yarn.lock index 33ac9d7aab..ef01464078 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5560,6 +5560,7 @@ __metadata: "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" "@backstage/plugin-search-backend-module-catalog": "workspace:^" + "@backstage/repo-tools": "workspace:^" "@backstage/types": "workspace:^" "@opentelemetry/api": ^1.3.0 "@types/core-js": ^2.5.4 @@ -9350,6 +9351,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" + "@backstage/repo-tools": "workspace:^" "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 express: ^4.17.1 @@ -9550,7 +9552,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/repo-tools@workspace:*, @backstage/repo-tools@workspace:packages/repo-tools": +"@backstage/repo-tools@workspace:*, @backstage/repo-tools@workspace:^, @backstage/repo-tools@workspace:packages/repo-tools": version: 0.0.0-use.local resolution: "@backstage/repo-tools@workspace:packages/repo-tools" dependencies: