diff --git a/examples/lb3-application/src/__tests__/acceptance/lb3app.acceptance.ts b/examples/lb3-application/src/__tests__/acceptance/lb3app.acceptance.ts index 447d7353326f..784629bfad08 100644 --- a/examples/lb3-application/src/__tests__/acceptance/lb3app.acceptance.ts +++ b/examples/lb3-application/src/__tests__/acceptance/lb3app.acceptance.ts @@ -138,7 +138,7 @@ describe('CoffeeShopApplication', () => { let apiSpec: OpenApiSpec; before(async () => { - apiSpec = app.lbApp.restServer.getApiSpec(); + apiSpec = await app.lbApp.restServer.getApiSpec(); }); it('has the same properties in both the LB3 and LB4 specs', () => { diff --git a/packages/booter-lb3app/src/__tests__/acceptance/booter-lb3app.acceptance.ts b/packages/booter-lb3app/src/__tests__/acceptance/booter-lb3app.acceptance.ts index d632a1141f4f..7ad9bf303e6d 100644 --- a/packages/booter-lb3app/src/__tests__/acceptance/booter-lb3app.acceptance.ts +++ b/packages/booter-lb3app/src/__tests__/acceptance/booter-lb3app.acceptance.ts @@ -41,8 +41,8 @@ describe('booter-lb3app', () => { }); context('generated OpenAPI spec', () => { - it('uses different request-body schema for "create" operation', () => { - const spec = app.restServer.getApiSpec(); + it('uses different request-body schema for "create" operation', async () => { + const spec = await app.restServer.getApiSpec(); const createOp: OperationObject = spec.paths['/api/CoffeeShops'].post; expect(createOp.requestBody).to.containDeep({ content: { @@ -66,8 +66,8 @@ describe('booter-lb3app', () => { }); }); - it('includes the target model as a property of the source model in a relation', () => { - const spec = app.restServer.getApiSpec(); + it('includes the target model as a property of the source model in a relation', async () => { + const spec = await app.restServer.getApiSpec(); const schemas = (spec.components ?? {}).schemas ?? {}; expect(schemas.CoffeeShop) @@ -118,8 +118,8 @@ describe('booter-lb3app', () => { } }); - it('includes LoopBack 3 endpoints with `/api` base in OpenApiSpec', () => { - const apiSpec = app.restServer.getApiSpec(); + it('includes LoopBack 3 endpoints with `/api` base in OpenApiSpec', async () => { + const apiSpec = await app.restServer.getApiSpec(); const paths = Object.keys(apiSpec.paths); expect(paths).to.containDeep([ '/api/CoffeeShops/{id}', @@ -219,8 +219,8 @@ describe('booter-lb3app', () => { })); }); - it('does apply the spec modification', () => { - const spec = app.restServer.getApiSpec(); + it('does apply the spec modification', async () => { + const spec = await app.restServer.getApiSpec(); const createOp: OperationObject = spec.paths['/api/CoffeeShops'].post; expect(createOp.summary).to.eql('just a very simple modification'); }); diff --git a/packages/rest-crud/src/__tests__/acceptance/default-model-crud-rest.acceptance.ts b/packages/rest-crud/src/__tests__/acceptance/default-model-crud-rest.acceptance.ts index 6e6caa438f63..c10b4f92bbbb 100644 --- a/packages/rest-crud/src/__tests__/acceptance/default-model-crud-rest.acceptance.ts +++ b/packages/rest-crud/src/__tests__/acceptance/default-model-crud-rest.acceptance.ts @@ -126,7 +126,7 @@ describe('CrudRestController for a simple Product model', () => { // a new test suite that will configure a PK with a different name // and type, e.g. `pk: string` instead of `id: number`. it('uses correct schema for the id parameter', async () => { - const spec = app.restServer.getApiSpec(); + const spec = await app.restServer.getApiSpec(); const findByIdOp = spec.paths['/products/{id}'].get; expect(findByIdOp).to.containDeep({ parameters: [ @@ -210,7 +210,7 @@ describe('CrudRestController for a simple Product model', () => { // a new test suite that will configure a PK with a different name // and type, e.g. `pk: string` instead of `id: number`. it('uses correct schema for the id parameter', async () => { - const spec = app.restServer.getApiSpec(); + const spec = await app.restServer.getApiSpec(); const findByIdOp = spec.paths['/products/{id}'].patch; expect(findByIdOp).to.containDeep({ parameters: [ @@ -245,7 +245,7 @@ describe('CrudRestController for a simple Product model', () => { // a new test suite that will configure a PK with a different name // and type, e.g. `pk: string` instead of `id: number`. it('uses correct schema for the id parameter', async () => { - const spec = app.restServer.getApiSpec(); + const spec = await app.restServer.getApiSpec(); const findByIdOp = spec.paths['/products/{id}']['patch']; expect(findByIdOp).to.containDeep({ parameters: [ @@ -278,7 +278,7 @@ describe('CrudRestController for a simple Product model', () => { // a new test suite that will configure a PK with a different name // and type, e.g. `pk: string` instead of `id: number`. it('uses correct schema for the id parameter', async () => { - const spec = app.restServer.getApiSpec(); + const spec = await app.restServer.getApiSpec(); const findByIdOp = spec.paths['/products/{id}']['delete']; expect(findByIdOp).to.containDeep({ parameters: [ diff --git a/packages/rest/src/__tests__/integration/rest.application.integration.ts b/packages/rest/src/__tests__/integration/rest.application.integration.ts index 79d67b9a22d7..808f50afe958 100644 --- a/packages/rest/src/__tests__/integration/rest.application.integration.ts +++ b/packages/rest/src/__tests__/integration/rest.application.integration.ts @@ -139,7 +139,7 @@ describe('RestApplication (integration)', () => { 'x-foo': 'bar', }); - const spec = restApp.restServer.getApiSpec(); + const spec = await restApp.restServer.getApiSpec(); expect(spec).to.deepEqual({ openapi: '3.0.0', info: { @@ -231,7 +231,7 @@ describe('RestApplication (integration)', () => { restApp.mountExpressRouter('/dogs', router, spec); await client.get('/dogs/hello').expect(200, 'Hello dogs!'); - const openApiSpec = restApp.restServer.getApiSpec(); + const openApiSpec = await restApp.restServer.getApiSpec(); expect(openApiSpec.paths).to.deepEqual({ '/dogs/hello': { get: { diff --git a/packages/rest/src/__tests__/unit/rest.server/rest.server.open-api-spec.unit.ts b/packages/rest/src/__tests__/unit/rest.server/rest.server.open-api-spec.unit.ts index 43dea9dd4a92..8bbbd1cd178f 100644 --- a/packages/rest/src/__tests__/unit/rest.server/rest.server.open-api-spec.unit.ts +++ b/packages/rest/src/__tests__/unit/rest.server/rest.server.open-api-spec.unit.ts @@ -20,10 +20,10 @@ describe('RestServer.getApiSpec()', () => { beforeEach(givenApplication); it('comes with a valid default spec', async () => { - await validateApiSpec(server.getApiSpec()); + await validateApiSpec(await server.getApiSpec()); }); - it('honours API defined via app.api()', () => { + it('honours API defined via app.api()', async () => { server.api({ openapi: '3.0.0', info: { @@ -35,7 +35,7 @@ describe('RestServer.getApiSpec()', () => { 'x-foo': 'bar', }); - const spec = server.getApiSpec(); + const spec = await server.getApiSpec(); expect(spec).to.deepEqual({ openapi: '3.0.0', info: { @@ -72,11 +72,11 @@ describe('RestServer.getApiSpec()', () => { expect(binding.tagNames).containEql('route'); }); - it('returns routes registered via app.route(route)', () => { + it('returns routes registered via app.route(route)', async () => { function greet() {} server.route('get', '/greet', {responses: {}}, greet); - const spec = server.getApiSpec(); + const spec = await server.getApiSpec(); expect(spec.paths).to.eql({ '/greet': { get: { @@ -86,7 +86,7 @@ describe('RestServer.getApiSpec()', () => { }); }); - it('ignores routes marked as "x-visibility" via app.route(route)', () => { + it('ignores routes marked as "x-visibility" via app.route(route)', async () => { function greet() {} function meet() {} server.route( @@ -96,7 +96,7 @@ describe('RestServer.getApiSpec()', () => { greet, ); server.route('get', '/meet', {responses: {}, spec: {}}, meet); - const spec = server.getApiSpec(); + const spec = await server.getApiSpec(); expect(spec.paths).to.eql({ '/meet': { get: { @@ -107,7 +107,7 @@ describe('RestServer.getApiSpec()', () => { }); }); - it('returns routes registered via app.route(..., Controller, method)', () => { + it('returns routes registered via app.route(..., Controller, method)', async () => { class MyController { greet() {} } @@ -121,7 +121,7 @@ describe('RestServer.getApiSpec()', () => { 'greet', ); - const spec = server.getApiSpec(); + const spec = await server.getApiSpec(); expect(spec.paths).to.eql({ '/greet': { get: { @@ -134,7 +134,7 @@ describe('RestServer.getApiSpec()', () => { }); }); - it('ignores routes marked as "x-visibility" via app.route(..., Controller, method)', () => { + it('ignores routes marked as "x-visibility" via app.route(..., Controller, method)', async () => { class GreetController { greet() {} } @@ -161,7 +161,7 @@ describe('RestServer.getApiSpec()', () => { 'meet', ); - const spec = server.getApiSpec(); + const spec = await server.getApiSpec(); expect(spec.paths).to.eql({ '/meet': { get: { @@ -174,14 +174,14 @@ describe('RestServer.getApiSpec()', () => { }); }); - it('honors tags in the operation spec', () => { + it('honors tags in the operation spec', async () => { class MyController { @get('/greet', {responses: {'200': {description: ''}}, tags: ['MyTag']}) greet() {} } app.controller(MyController); - const spec = server.getApiSpec(); + const spec = await server.getApiSpec(); expect(spec.paths).to.eql({ '/greet': { get: { @@ -195,7 +195,7 @@ describe('RestServer.getApiSpec()', () => { }); }); - it('emits all media types for request body', () => { + it('emits all media types for request body', async () => { const expectedOpSpec = anOperationSpec() .withRequestBody({ description: 'Any object value.', @@ -229,18 +229,18 @@ describe('RestServer.getApiSpec()', () => { } app.controller(MyController); - const spec = server.getApiSpec(); + const spec = await server.getApiSpec(); expect(spec.paths['/show-body'].post).to.containDeep(expectedOpSpec); }); - it('returns routes registered via app.controller()', () => { + it('returns routes registered via app.controller()', async () => { class MyController { @get('/greet') greet() {} } app.controller(MyController); - const spec = server.getApiSpec(); + const spec = await server.getApiSpec(); expect(spec.paths).to.eql({ '/greet': { get: { @@ -256,7 +256,7 @@ describe('RestServer.getApiSpec()', () => { }); }); - it('returns definitions inferred via app.controller()', () => { + it('returns definitions inferred via app.controller()', async () => { @model() class MyModel { @property() @@ -268,7 +268,7 @@ describe('RestServer.getApiSpec()', () => { } app.controller(MyController); - const spec = server.getApiSpec(); + const spec = await server.getApiSpec(); expect(spec.components && spec.components.schemas).to.deepEqual({ MyModel: { title: 'MyModel', @@ -282,7 +282,7 @@ describe('RestServer.getApiSpec()', () => { }); }); - it('preserves routes specified in app.api()', () => { + it('preserves routes specified in app.api()', async () => { function status() {} server.api( anOpenApiSpec() @@ -296,7 +296,7 @@ describe('RestServer.getApiSpec()', () => { function greet() {} server.route('get', '/greet', {responses: {}}, greet); - const spec = server.getApiSpec(); + const spec = await server.getApiSpec(); expect(spec.paths).to.eql({ '/greet': { get: { diff --git a/packages/rest/src/rest.server.ts b/packages/rest/src/rest.server.ts index 24f5dde5d5a4..bb6e2387aedc 100644 --- a/packages/rest/src/rest.server.ts +++ b/packages/rest/src/rest.server.ts @@ -458,7 +458,7 @@ export class RestServer extends Context implements Server, HttpServerLike { ); specForm = specForm ?? {version: '3.0.0', format: 'json'}; - const specObj = this.getApiSpec(requestContext); + const specObj = await this.getApiSpec(requestContext); if (specForm.format === 'json') { const spec = JSON.stringify(specObj, null, 2); @@ -736,8 +736,8 @@ export class RestServer extends Context implements Server, HttpServerLike { * @param requestContext - Optional context to update the `servers` list * in the returned spec */ - getApiSpec(requestContext?: RequestContext): OpenApiSpec { - let spec = this.getSync(RestBindings.API_SPEC); + async getApiSpec(requestContext?: RequestContext): Promise { + let spec = await this.get(RestBindings.API_SPEC); const defs = this.httpHandler.getApiDefinitions(); // Apply deep clone to prevent getApiSpec() callers from