From eb573dbc10e2e4b96d2ac0b9c27323b21353b6ee Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Fri, 29 Nov 2024 16:17:22 +0000 Subject: [PATCH 1/8] yarn-plugin: use yarn's httpUtils to fetch release manifests This allows us to leverage yarn's built in proxy configuration when making the request. The yarn HTTP utilities handle caching of GET requests, so we can remove our memoization of the request, too. Signed-off-by: MT Lewis Signed-off-by: kevspl --- .changeset/beige-chicken-type.md | 5 ++ packages/yarn-plugin/package.json | 1 - .../handlers/beforeWorkspacePacking.test.ts | 49 ++++++----- .../src/handlers/beforeWorkspacePacking.ts | 1 + .../src/resolver/BackstageResolver.test.ts | 82 +++++++++---------- .../src/resolver/BackstageResolver.ts | 18 +++- packages/yarn-plugin/src/util.ts | 51 ++++++++++-- yarn.lock | 1 - 8 files changed, 130 insertions(+), 78 deletions(-) create mode 100644 .changeset/beige-chicken-type.md diff --git a/.changeset/beige-chicken-type.md b/.changeset/beige-chicken-type.md new file mode 100644 index 0000000000..d73500a7f9 --- /dev/null +++ b/.changeset/beige-chicken-type.md @@ -0,0 +1,5 @@ +--- +'yarn-plugin-backstage': patch +--- + +Use yarn's built-in http utilities for fetching release manifests diff --git a/packages/yarn-plugin/package.json b/packages/yarn-plugin/package.json index 0cc923a993..48af10b9da 100644 --- a/packages/yarn-plugin/package.json +++ b/packages/yarn-plugin/package.json @@ -35,7 +35,6 @@ "@yarnpkg/core": "^4.0.3", "@yarnpkg/fslib": "^3.0.2", "@yarnpkg/plugin-pack": "^4.0.0", - "lodash": "^4.17.21", "semver": "^7.6.0" }, "devDependencies": { diff --git a/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.test.ts b/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.test.ts index d156182923..ee4af2c4f6 100644 --- a/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.test.ts +++ b/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.test.ts @@ -14,35 +14,24 @@ * limitations under the License. */ -import { Manifest, Workspace } from '@yarnpkg/core'; +import { + Configuration, + Manifest, + Project, + Workspace, + httpUtils, +} from '@yarnpkg/core'; import { npath, ppath } from '@yarnpkg/fslib'; import { createMockDirectory } from '@backstage/backend-test-utils'; import { beforeWorkspacePacking } from './beforeWorkspacePacking'; -jest.mock('@backstage/release-manifests', () => ({ - getManifestByVersion: jest.fn().mockResolvedValue({ - releaseVersion: '1.23.45', - packages: [ - { - name: '@backstage/core', - version: '3.2.1', - }, - { - name: '@backstage/plugin-1', - version: '6.5.4', - }, - { - name: '@backstage/plugin-2', - version: '9.8.7', - }, - ], - }), -})); - const makeWorkspace = (manifest: object) => { return { manifest: Manifest.fromText(JSON.stringify(manifest)), + project: new Project(ppath.cwd(), { + configuration: Configuration.create(ppath.cwd()), + }), } as Workspace; }; @@ -58,6 +47,24 @@ describe('beforeWorkspacePacking', () => { .spyOn(process, 'cwd') .mockReturnValue(npath.toPortablePath(mockDir.path)); + jest.spyOn(httpUtils, 'get').mockResolvedValue({ + releaseVersion: '1.23.45', + packages: [ + { + name: '@backstage/core', + version: '3.2.1', + }, + { + name: '@backstage/plugin-1', + version: '6.5.4', + }, + { + name: '@backstage/plugin-2', + version: '9.8.7', + }, + ], + }); + mockDir.setContent({ 'backstage.json': JSON.stringify({ version: '1.23.45', diff --git a/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.ts b/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.ts index fbdea3fa34..e5823607e3 100644 --- a/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.ts +++ b/packages/yarn-plugin/src/handlers/beforeWorkspacePacking.ts @@ -70,6 +70,7 @@ export const beforeWorkspacePacking = async ( rawManifest[finalDependencyType][ident] = `^${await getPackageVersion( bindBackstageVersion(descriptor, backstageVersion), + workspace.project.configuration, )}`; } } diff --git a/packages/yarn-plugin/src/resolver/BackstageResolver.test.ts b/packages/yarn-plugin/src/resolver/BackstageResolver.test.ts index f6369b6cdf..8cba189cb8 100644 --- a/packages/yarn-plugin/src/resolver/BackstageResolver.test.ts +++ b/packages/yarn-plugin/src/resolver/BackstageResolver.test.ts @@ -14,31 +14,22 @@ * limitations under the License. */ -import { structUtils } from '@yarnpkg/core'; +import { + Configuration, + Project, + ResolveOptions, + structUtils, + ThrowReport, + httpUtils, +} from '@yarnpkg/core'; import { npath, ppath } from '@yarnpkg/fslib'; -import { getManifestByVersion } from '@backstage/release-manifests'; import { BackstageResolver } from './BackstageResolver'; import { createMockDirectory } from '@backstage/backend-test-utils'; -jest.mock('@backstage/release-manifests', () => ({ - getManifestByVersion: jest.fn().mockResolvedValue({ - releaseVersion: '1.23.45', - packages: [ - { - name: '@backstage/core', - version: '6.7.8', - }, - ], - }), -})); - -const getManifestByVersionMock = getManifestByVersion as jest.MockedFunction< - typeof getManifestByVersion ->; - describe('BackstageResolver', () => { const mockDir = createMockDirectory(); let backstageResolver: BackstageResolver; + let resolveOptions: ResolveOptions; beforeEach(() => { jest @@ -49,6 +40,16 @@ describe('BackstageResolver', () => { .spyOn(process, 'cwd') .mockReturnValue(npath.toPortablePath(mockDir.path)); + jest.spyOn(httpUtils, 'get').mockResolvedValue({ + releaseVersion: '1.23.45', + packages: [ + { + name: '@backstage/core', + version: '6.7.8', + }, + ], + }); + mockDir.setContent({ 'backstage.json': JSON.stringify({ version: '1.23.45', @@ -71,6 +72,14 @@ describe('BackstageResolver', () => { }); backstageResolver = new BackstageResolver(); + + resolveOptions = { + resolver: backstageResolver, + project: new Project(ppath.cwd(), { + configuration: Configuration.create(ppath.cwd()), + }), + report: new ThrowReport(), + }; }); afterEach(() => { @@ -140,7 +149,7 @@ describe('BackstageResolver', () => { ); await expect( - backstageResolver.getCandidates(descriptor), + backstageResolver.getCandidates(descriptor, {}, resolveOptions), ).resolves.toEqual([structUtils.makeLocator(descriptor, 'npm:6.7.8')]); }); @@ -151,6 +160,8 @@ describe('BackstageResolver', () => { structUtils.makeIdent('backstage', 'core'), 'npm:1.2.3', ), + {}, + resolveOptions, ), ).rejects.toThrow(/unsupported version protocol/i); }); @@ -162,6 +173,8 @@ describe('BackstageResolver', () => { structUtils.makeIdent('backstage', 'core'), 'backstage:^', ), + {}, + resolveOptions, ), ).rejects.toThrow(/missing Backstage version/i); }); @@ -173,6 +186,8 @@ describe('BackstageResolver', () => { structUtils.makeIdent('backstage', 'core'), 'backstage:^::v=1&v=2', ), + {}, + resolveOptions, ), ).rejects.toThrow(/multiple Backstage versions/i); }); @@ -190,34 +205,12 @@ describe('BackstageResolver', () => { structUtils.makeIdent('backstage', 'core'), `backstage:${selector}`, ), + {}, + resolveOptions, ), ).rejects.toThrow(/unexpected version selector/i); }, ); - - it('memoizes manifest retrieval', async () => { - const descriptor1 = structUtils.makeDescriptor( - structUtils.makeIdent('backstage', 'core'), - 'backstage:^::v=1.23.45', - ); - - for (let i = 0; i < 5; i++) { - await backstageResolver.getCandidates(descriptor1); - } - - expect(getManifestByVersionMock).toHaveBeenCalledTimes(1); - - const descriptor2 = structUtils.makeDescriptor( - structUtils.makeIdent('backstage', 'core'), - 'backstage:^::v=6.78.90', - ); - - for (let i = 0; i < 5; i++) { - await backstageResolver.getCandidates(descriptor2); - } - - expect(getManifestByVersionMock).toHaveBeenCalledTimes(2); - }); }); describe('getSatisfying', () => { @@ -243,6 +236,7 @@ describe('BackstageResolver', () => { 'npm:1.2.3', ), ], + resolveOptions, ), ).resolves.toEqual({ locators: [ @@ -277,6 +271,7 @@ describe('BackstageResolver', () => { 'npm:7.8.9', ), ], + resolveOptions, ), ).resolves.toEqual({ locators: [ @@ -298,6 +293,7 @@ describe('BackstageResolver', () => { ), {}, [], + resolveOptions, ), ).rejects.toThrow(/unsupported version protocol/i); }); diff --git a/packages/yarn-plugin/src/resolver/BackstageResolver.ts b/packages/yarn-plugin/src/resolver/BackstageResolver.ts index 0e575cc687..d2d0c98d1e 100644 --- a/packages/yarn-plugin/src/resolver/BackstageResolver.ts +++ b/packages/yarn-plugin/src/resolver/BackstageResolver.ts @@ -20,6 +20,7 @@ import { Locator, Package, Resolver, + ResolveOptions, } from '@yarnpkg/core'; import { PROTOCOL } from '../constants'; import { @@ -60,11 +61,18 @@ export class BackstageResolver implements Resolver { * concrete version into the appropriate concrete npm version for that * backstage release. */ - async getCandidates(descriptor: Descriptor): Promise { + async getCandidates( + descriptor: Descriptor, + _dependencies: Record, + opts: ResolveOptions, + ): Promise { return [ structUtils.makeLocator( descriptor, - `npm:${await getPackageVersion(descriptor)}`, + `npm:${await getPackageVersion( + descriptor, + opts.project.configuration, + )}`, ), ]; } @@ -79,8 +87,12 @@ export class BackstageResolver implements Resolver { descriptor: Descriptor, _dependencies: Record, locators: Array, + opts: ResolveOptions, ): Promise<{ locators: Locator[]; sorted: boolean }> { - const packageVersion = await getPackageVersion(descriptor); + const packageVersion = await getPackageVersion( + descriptor, + opts.project.configuration, + ); return { locators: locators.filter( diff --git a/packages/yarn-plugin/src/util.ts b/packages/yarn-plugin/src/util.ts index 5fd0091b2b..ee89a647e3 100644 --- a/packages/yarn-plugin/src/util.ts +++ b/packages/yarn-plugin/src/util.ts @@ -14,18 +14,18 @@ * limitations under the License. */ +import { + Configuration, + Descriptor, + httpUtils, + structUtils, +} from '@yarnpkg/core'; import { ppath, xfs } from '@yarnpkg/fslib'; import { valid as semverValid } from 'semver'; -import memoize from 'lodash/memoize'; -import { getManifestByVersion as getManifestByVersionBase } from '@backstage/release-manifests'; import { BACKSTAGE_JSON, findPaths } from '@backstage/cli-common'; -import { Descriptor, structUtils } from '@yarnpkg/core'; -import { PROTOCOL } from './constants'; +import { getManifestByVersion } from '@backstage/release-manifests'; -const getManifestByVersion = memoize( - getManifestByVersionBase, - ({ version }) => version, -); +import { PROTOCOL } from './constants'; export const getCurrentBackstageVersion = () => { const workspaceRoot = ppath.resolve(findPaths(ppath.cwd()).targetRoot); @@ -50,7 +50,10 @@ export const bindBackstageVersion = ( return structUtils.bindDescriptor(descriptor, { v: backstageVersion }); }; -export const getPackageVersion = async (descriptor: Descriptor) => { +export const getPackageVersion = async ( + descriptor: Descriptor, + configuration: Configuration, +) => { const ident = structUtils.stringifyIdent(descriptor); const range = structUtils.parseRange(descriptor.range); @@ -80,6 +83,36 @@ export const getPackageVersion = async (descriptor: Descriptor) => { const manifest = await getManifestByVersion({ version: range.params.v, + // We override the fetch function used inside getManifestByVersion with a + // custom implementation that calls yarn's built-in `httpUtils` method + // instead. This has a couple of benefits: + // + // 1. This means that the fetch should leverage yarn's built-in cache, so we + // don't need to explicitly memoize the fetch. + // 2. The request should automatically take account of any proxy settings + // configured in yarn. + fetch: async (url: string) => { + const response = await httpUtils.get(url, { + configuration, + jsonResponse: true, + }); + + // The release-manifests package expects fetchFn to resolve with a subset + // of the native HTTP Response object, but yarn's httpUtils implementation + // keeps most of the details hidden. This means we need to construct an + // object which quacks like a Response in the appropriate ways. + return { + // The function has some custom handling for non-200 errors. Yarn + // doesn't provide the status code, but if we've got to this point + // without throwing, we can assume the request has been successful. + status: 200, + // The requested URL, used to correctly report errors + url, + // Yarn automatically parses the response as JSON, so our implementation + // can simply return it. + json: () => response, + }; + }, }); const manifestEntry = manifest.packages.find( diff --git a/yarn.lock b/yarn.lock index ffc3c2dfde..80cc9458c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -47630,7 +47630,6 @@ __metadata: "@yarnpkg/core": ^4.0.3 "@yarnpkg/fslib": ^3.0.2 "@yarnpkg/plugin-pack": ^4.0.0 - lodash: ^4.17.21 nodemon: ^3.0.1 semver: ^7.6.0 languageName: unknown From 98d34fd5b27acec35bae208fd4f156d028c1a359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 2 Dec 2024 14:12:45 +0100 Subject: [PATCH 2/8] fix nulls in by-query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw Signed-off-by: kevspl --- .changeset/gold-stingrays-cross.md | 5 +++ .../service/DefaultEntitiesCatalog.test.ts | 45 +++++++++++++++++++ .../src/service/DefaultEntitiesCatalog.ts | 12 ++--- 3 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 .changeset/gold-stingrays-cross.md diff --git a/.changeset/gold-stingrays-cross.md b/.changeset/gold-stingrays-cross.md new file mode 100644 index 0000000000..f2a8da99b3 --- /dev/null +++ b/.changeset/gold-stingrays-cross.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Fix a bug where sometimes the `by-query` endpoint could return nulls for entities that were not yet stitched. diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts index 08ba11c59d..418f503739 100644 --- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts +++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts @@ -1797,6 +1797,51 @@ describe('DefaultEntitiesCatalog', () => { ).resolves.toEqual(['BB', 'CC', 'AA']); // 'AA' has no title, ends up last }, ); + + it.each(databases.eachSupportedId())( + 'should silently skip over entities that are not yet stitched, %p', + async databaseId => { + await createDatabase(databaseId); + + const entity1 = entityFrom('AA', { uid: 'id1' }); + const entity2 = entityFrom('BB', { uid: 'id2' }); + await Promise.all([ + addEntityToSearch(entity1), + addEntityToSearch(entity2), + ]); + + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: mockServices.logger.mock(), + stitcher, + }); + + await expect( + catalog + .queryEntities({ + orderFields: [{ field: 'metadata.uid', order: 'asc' }], + limit: 10, + credentials: mockCredentials.none(), + }) + .then(r => r.items.map(e => e.metadata.name)), + ).resolves.toEqual(['AA', 'BB']); + + // simulate a situation where stitching is not yet complete + await knex('final_entities') + .update({ final_entity: null }) + .where({ entity_ref: stringifyEntityRef(entity1) }); + + await expect( + catalog + .queryEntities({ + orderFields: [{ field: 'metadata.uid', order: 'asc' }], + limit: 10, + credentials: mockCredentials.none(), + }) + .then(r => r.items.map(e => e.metadata.name)), + ).resolves.toEqual(['BB']); + }, + ); }); describe('removeEntityByUid', () => { diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts index 74d08d3ad7..c8afe8124f 100644 --- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts +++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts @@ -379,11 +379,13 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog { const [prevItemOrderFieldValue, prevItemUid] = cursor.orderFieldValues || []; - const dbQuery = db('final_entities').leftOuterJoin('search', qb => - qb - .on('search.entity_id', 'final_entities.entity_id') - .andOnVal('search.key', sortField.field), - ); + const dbQuery = db('final_entities') + .leftOuterJoin('search', qb => + qb + .on('search.entity_id', 'final_entities.entity_id') + .andOnVal('search.key', sortField.field), + ) + .whereNotNull('final_entities.final_entity'); if (cursor.filter) { parseFilter( From 6c4ad9ee809e16b71cf827121327e77ded77120a Mon Sep 17 00:00:00 2001 From: Kevin Kantesaria Date: Mon, 2 Dec 2024 16:23:32 -0500 Subject: [PATCH 3/8] fix: typed router export Signed-off-by: kevspl --- packages/backend-openapi-utils/src/index.ts | 2 +- packages/backend-openapi-utils/src/router.ts | 18 +++++++++++++++++- .../src/types/generated.ts | 12 ------------ 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/packages/backend-openapi-utils/src/index.ts b/packages/backend-openapi-utils/src/index.ts index a66894d473..9389fe3be6 100644 --- a/packages/backend-openapi-utils/src/index.ts +++ b/packages/backend-openapi-utils/src/index.ts @@ -30,7 +30,7 @@ export type { CookieParameters, PathParameters, } from './utility'; -export type { ApiRouter } from './router'; +export type { ApiRouter, TypedRouter } from './router'; export type { PathTemplate } from './types/common'; export { wrapInOpenApiTestServer, wrapServer } from './testUtils'; export { diff --git a/packages/backend-openapi-utils/src/router.ts b/packages/backend-openapi-utils/src/router.ts index 253fc1596e..48d89054ba 100644 --- a/packages/backend-openapi-utils/src/router.ts +++ b/packages/backend-openapi-utils/src/router.ts @@ -14,7 +14,12 @@ * limitations under the License. */ import { Router } from 'express'; -import { DocRequestMatcher, RequiredDoc } from './types'; +import { + DocRequestMatcher, + EndpointMap, + EndpointMapRequestMatcher, + RequiredDoc, +} from './types'; /** * Typed Express router based on an OpenAPI 3.1 spec. @@ -37,3 +42,14 @@ export interface ApiRouter extends Router { head: DocRequestMatcher; } + +/** + * @public + */ +export interface TypedRouter + extends Router { + get: EndpointMapRequestMatcher; + post: EndpointMapRequestMatcher; + put: EndpointMapRequestMatcher; + delete: EndpointMapRequestMatcher; +} diff --git a/packages/backend-openapi-utils/src/types/generated.ts b/packages/backend-openapi-utils/src/types/generated.ts index b0b80f45fb..e4d5dada72 100644 --- a/packages/backend-openapi-utils/src/types/generated.ts +++ b/packages/backend-openapi-utils/src/types/generated.ts @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Router } from 'express'; import type core from 'express-serve-static-core'; import { PathTemplate, ValueOf } from './common'; @@ -209,14 +208,3 @@ export interface EndpointMapRequestMatcher< > ): T; } - -/** - * @public - */ -export interface TypedRouter - extends Router { - get: EndpointMapRequestMatcher; - post: EndpointMapRequestMatcher; - put: EndpointMapRequestMatcher; - delete: EndpointMapRequestMatcher; -} From 71ffeafd690be0717f1366e5034963602e6bffc4 Mon Sep 17 00:00:00 2001 From: Kevin Kantesaria Date: Mon, 2 Dec 2024 16:31:54 -0500 Subject: [PATCH 4/8] changeset Signed-off-by: kevspl --- .changeset/rich-suns-drive.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/rich-suns-drive.md diff --git a/.changeset/rich-suns-drive.md b/.changeset/rich-suns-drive.md new file mode 100644 index 0000000000..c5c91d2829 --- /dev/null +++ b/.changeset/rich-suns-drive.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-openapi-utils': minor +--- + +fix typedrouter export not being properly imported in generated code in openapi-utils From 69b075b6cd3e9f6afa5de93cb298afbb198a9322 Mon Sep 17 00:00:00 2001 From: kevspl <130582010+kevspl@users.noreply.github.com> Date: Mon, 2 Dec 2024 16:37:53 -0500 Subject: [PATCH 5/8] Update .changeset/rich-suns-drive.md Co-authored-by: Aramis Sennyey <159921952+aramissennyeydd@users.noreply.github.com> Signed-off-by: kevspl <130582010+kevspl@users.noreply.github.com> Signed-off-by: kevspl --- .changeset/rich-suns-drive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/rich-suns-drive.md b/.changeset/rich-suns-drive.md index c5c91d2829..0b2eb85a5b 100644 --- a/.changeset/rich-suns-drive.md +++ b/.changeset/rich-suns-drive.md @@ -2,4 +2,4 @@ '@backstage/backend-openapi-utils': minor --- -fix typedrouter export not being properly imported in generated code in openapi-utils +Fixed a Typescript error when trying to use the new OpenAPI server-side generated code. From afcebeacf4c23f5a23592de982f9f2959f3c40b7 Mon Sep 17 00:00:00 2001 From: kevspl Date: Mon, 2 Dec 2024 17:20:51 -0500 Subject: [PATCH 6/8] reset Signed-off-by: kevspl --- .changeset/rich-suns-drive.md | 5 +++++ packages/backend-openapi-utils/src/index.ts | 2 +- packages/backend-openapi-utils/src/router.ts | 18 +++++++++++++++++- .../src/types/generated.ts | 12 ------------ 4 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 .changeset/rich-suns-drive.md diff --git a/.changeset/rich-suns-drive.md b/.changeset/rich-suns-drive.md new file mode 100644 index 0000000000..0b2eb85a5b --- /dev/null +++ b/.changeset/rich-suns-drive.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-openapi-utils': minor +--- + +Fixed a Typescript error when trying to use the new OpenAPI server-side generated code. diff --git a/packages/backend-openapi-utils/src/index.ts b/packages/backend-openapi-utils/src/index.ts index a66894d473..9389fe3be6 100644 --- a/packages/backend-openapi-utils/src/index.ts +++ b/packages/backend-openapi-utils/src/index.ts @@ -30,7 +30,7 @@ export type { CookieParameters, PathParameters, } from './utility'; -export type { ApiRouter } from './router'; +export type { ApiRouter, TypedRouter } from './router'; export type { PathTemplate } from './types/common'; export { wrapInOpenApiTestServer, wrapServer } from './testUtils'; export { diff --git a/packages/backend-openapi-utils/src/router.ts b/packages/backend-openapi-utils/src/router.ts index 253fc1596e..48d89054ba 100644 --- a/packages/backend-openapi-utils/src/router.ts +++ b/packages/backend-openapi-utils/src/router.ts @@ -14,7 +14,12 @@ * limitations under the License. */ import { Router } from 'express'; -import { DocRequestMatcher, RequiredDoc } from './types'; +import { + DocRequestMatcher, + EndpointMap, + EndpointMapRequestMatcher, + RequiredDoc, +} from './types'; /** * Typed Express router based on an OpenAPI 3.1 spec. @@ -37,3 +42,14 @@ export interface ApiRouter extends Router { head: DocRequestMatcher; } + +/** + * @public + */ +export interface TypedRouter + extends Router { + get: EndpointMapRequestMatcher; + post: EndpointMapRequestMatcher; + put: EndpointMapRequestMatcher; + delete: EndpointMapRequestMatcher; +} diff --git a/packages/backend-openapi-utils/src/types/generated.ts b/packages/backend-openapi-utils/src/types/generated.ts index b0b80f45fb..e4d5dada72 100644 --- a/packages/backend-openapi-utils/src/types/generated.ts +++ b/packages/backend-openapi-utils/src/types/generated.ts @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Router } from 'express'; import type core from 'express-serve-static-core'; import { PathTemplate, ValueOf } from './common'; @@ -209,14 +208,3 @@ export interface EndpointMapRequestMatcher< > ): T; } - -/** - * @public - */ -export interface TypedRouter - extends Router { - get: EndpointMapRequestMatcher; - post: EndpointMapRequestMatcher; - put: EndpointMapRequestMatcher; - delete: EndpointMapRequestMatcher; -} From 327dcb45d79a6ae9788b2d16aa9ad42740949836 Mon Sep 17 00:00:00 2001 From: kevspl Date: Tue, 3 Dec 2024 11:08:00 -0500 Subject: [PATCH 7/8] fix stub.ts import Signed-off-by: kevspl --- packages/backend-openapi-utils/src/stub.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend-openapi-utils/src/stub.ts b/packages/backend-openapi-utils/src/stub.ts index 615c32cb31..8ab00c4df4 100644 --- a/packages/backend-openapi-utils/src/stub.ts +++ b/packages/backend-openapi-utils/src/stub.ts @@ -15,8 +15,8 @@ */ import PromiseRouter from 'express-promise-router'; -import { ApiRouter } from './router'; -import { EndpointMap, RequiredDoc, TypedRouter } from './types'; +import { ApiRouter, TypedRouter } from './router'; +import { EndpointMap, RequiredDoc } from './types'; import { ErrorRequestHandler, RequestHandler, From 0b3edcb55ebe73ce1aca63340151effc9372fa09 Mon Sep 17 00:00:00 2001 From: kevspl Date: Tue, 3 Dec 2024 13:22:46 -0500 Subject: [PATCH 8/8] build api report Signed-off-by: kevspl --- packages/backend-openapi-utils/report.api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend-openapi-utils/report.api.md b/packages/backend-openapi-utils/report.api.md index 399705a9e4..22913eb321 100644 --- a/packages/backend-openapi-utils/report.api.md +++ b/packages/backend-openapi-utils/report.api.md @@ -530,7 +530,6 @@ declare namespace internal { DocEndpointTemplate, TemplateToDocEndpoint, EndpointMapRequestMatcher, - TypedRouter, }; } export { internal }; @@ -902,7 +901,8 @@ type TuplifyUnion< > = true extends N ? [] : Push>, L>; // @public (undocumented) -interface TypedRouter extends Router { +export interface TypedRouter + extends Router { // (undocumented) delete: EndpointMapRequestMatcher; // (undocumented)