From 6248b2844796f93e22404ddea85ee77c1a5b7d50 Mon Sep 17 00:00:00 2001 From: Daniil Poletaev <44584010+danpoletaev@users.noreply.github.com> Date: Mon, 27 Jan 2025 10:23:28 +0100 Subject: [PATCH] feat: added getOpenApiSpecification() to BuildClient (#626) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recently we've introduced new endpoint: - `/v2/actor-builds/:buildId/openapi-specification` **This PR adds this endpoint to BuildClient** P.S. The link to the documentation is correct, but docs are not yet merged into production. I'll merge this PR after the docs are merged. --------- Co-authored-by: Martin Adámek --- src/resource_clients/build.ts | 68 +++++++++++++++++++++++++++++++ test/builds.test.js | 12 ++++++ test/mock_server/routes/builds.js | 1 + 3 files changed, 81 insertions(+) diff --git a/src/resource_clients/build.ts b/src/resource_clients/build.ts index 2782b161..fafca3ed 100644 --- a/src/resource_clients/build.ts +++ b/src/resource_clients/build.ts @@ -53,6 +53,19 @@ export class BuildClient extends ResourceClient { return this._delete(); } + /** + * https://docs.apify.com/api/v2/actor-build-openapi-specification-get + */ + async getOpenApiSpecification(): Promise { + const response = await this.httpClient.call({ + url: this._url('openapi-specification'), + method: 'GET', + params: this._params(), + }); + + return response.data; + } + /** * Returns a promise that resolves with the finished Build object when the provided actor build finishes * or with the unfinished Build object when the `waitSecs` timeout lapses. The promise is NOT rejected @@ -142,3 +155,58 @@ export interface BuildOptions { memoryMbytes?: number; diskMbytes?: number; } + +export interface OpenApiSpecification { + openapi: string; + info: { + title: string + description?: string; + version?: string + 'x-build-id': string + }; + servers: { url: string }[] + paths: { [key: string]: { post: OpenApiOperation } }; + components: { + schemas: { + [key: string]: object + } + } +} + +interface OpenApiOperation { + operationId: string + 'x-openai-isConsequential': boolean + summary: string + tags: string[] + requestBody: { + required: boolean; + content: { + 'application/json': { + schema: { + '$ref': string + } + } + } + } + parameters: { + name: string + in: string + required: boolean + schema: { + type: string; + } + description: string + }[] + responses: { + '200': { + description: string + content?: { + 'application/json': { + schema: { + '$ref': string + } + } + } + } + } +} diff --git a/test/builds.test.js b/test/builds.test.js index 839b90a3..ef34d2f9 100644 --- a/test/builds.test.js +++ b/test/builds.test.js @@ -89,6 +89,18 @@ describe('Build methods', () => { validateRequest({}, { buildId }); }); + test('getOpenApiSpecification() works', async () => { + const buildId = 'some-build-id'; + + const res = await client.build(buildId).getOpenApiSpecification(); + expect(res.data.id).toEqual('build-openapi-specification'); + validateRequest({}, { buildId }); + + const browserRes = await page.evaluate((bId) => client.build(bId).getOpenApiSpecification(), buildId); + expect(browserRes).toEqual(res); + validateRequest({}, { buildId }); + }); + test('waitForFinish() works', async () => { const buildId = 'some-build-id'; const waitSecs = 0.1; diff --git a/test/mock_server/routes/builds.js b/test/mock_server/routes/builds.js index 3545ed7b..e596953c 100644 --- a/test/mock_server/routes/builds.js +++ b/test/mock_server/routes/builds.js @@ -9,6 +9,7 @@ const ROUTES = [ { id: 'get-build', method: 'GET', path: '/:buildId', type: 'responseJsonMock' }, { id: 'abort-build', method: 'POST', path: '/:buildId/abort' }, { id: 'build-log', method: 'GET', path: '/:buildId/log', type: 'text' }, + { id: 'build-openapi-specification', method: 'GET', path: '/:buildId/openapi-specification', type: 'responseJsonMock' }, ]; addRoutes(builds, ROUTES);