UNPKG

@loopback/booter-lb3app

Version:

A booter component for LoopBack 3 applications to expose their REST API via LoopBack 4

124 lines 5.36 kB
"use strict"; // Copyright IBM Corp. and LoopBack contributors 2019,2020. All Rights Reserved. // Node module: @loopback/booter-lb3app // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT Object.defineProperty(exports, "__esModule", { value: true }); exports.Lb3AppBooter = void 0; const tslib_1 = require("tslib"); const boot_1 = require("@loopback/boot"); const core_1 = require("@loopback/core"); const rest_1 = require("@loopback/rest"); const debug_1 = tslib_1.__importDefault(require("debug")); const events_1 = require("events"); const path_1 = tslib_1.__importDefault(require("path")); const { generateSwaggerSpec } = require('loopback-swagger'); const swagger2openapi = require('swagger2openapi'); const debug = (0, debug_1.default)('loopback:boot:lb3app'); const DefaultOptions = { // from "/dist/application.ts" to "/lb3app" path: '../lb3app/server/server', mode: 'fullApp', restApiRoot: '/api', }; let Lb3AppBooter = class Lb3AppBooter { constructor(app, projectRoot, options = {}) { this.app = app; this.projectRoot = projectRoot; this.options = Object.assign({}, DefaultOptions, options); if (typeof app.mountExpressRouter !== 'function') { throw new Error('Lb3AppBooter requires RestApplication with mountExpressRouter API'); } } async configure() { this.appPath = path_1.default.join(this.projectRoot, this.options.path); } async load() { const lb3App = await this.loadAndBootTheApp(); const spec = await this.buildOpenApiSpec(lb3App); if (this.options.mode === 'fullApp') { this.mountFullApp(lb3App, spec); } else { this.mountRoutesOnly(lb3App, spec); } const dataSources = lb3App.dataSources; if (dataSources) { const visitedDs = new Set(); for (const k in dataSources) { const ds = dataSources[k]; if (visitedDs.has(ds)) continue; this.app.bind(`lb3-datasources.${k}`).to(ds).tag('lb3-datasource'); visitedDs.add(ds); } } const models = lb3App.models; if (models) { const visitedModels = new Set(); for (const k in models) { const model = models[k]; if (visitedModels.has(model)) continue; this.app.bind(`lb3-models.${k}`).to(model).tag('lb3-model'); visitedModels.add(model); } } // TODO(bajtos) Listen for the following events to update the OpenAPI spec: // - modelRemoted // - modelDeleted // - remoteMethodAdded // - remoteMethodDisabled // Note: LB4 does not support live spec updates yet. See // https://github.com/loopbackio/loopback-next/issues/2394 for details. } async loadAndBootTheApp() { debug('Loading LB3 app from', this.appPath); const lb3App = require(this.appPath); debug('If your LB3 app does not boot correctly then make sure it is using loopback-boot version 3.2.1 or higher.'); if (lb3App.booting) { debug(' waiting for boot process to finish'); // Wait until the legacy LB3 app boots await (0, events_1.once)(lb3App, 'booted'); } return lb3App; } async buildOpenApiSpec(lb3App) { const swaggerSpec = generateSwaggerSpec(lb3App, { generateOperationScopedModels: true, }); // remove any properties that have values that are functions before // converting, as `convertObj` can't handle function values const fixedSwaggerSpec = JSON.parse(JSON.stringify(swaggerSpec)); const result = await swagger2openapi.convertObj(fixedSwaggerSpec, { // swagger2openapi options }); let spec = result.openapi; if (typeof this.options.specTransformer === 'function') { spec = this.options.specTransformer(spec); } return spec; } mountFullApp(lb3App, spec) { const restApiRoot = lb3App.get('restApiRoot') || '/'; debug('Mounting the entire LB3 app at %s', restApiRoot); const specInRoot = (0, rest_1.rebaseOpenApiSpec)(spec, restApiRoot); this.app.mountExpressRouter('/', lb3App, specInRoot); } mountRoutesOnly(lb3App, spec) { const restApiRoot = this.options.restApiRoot; debug('Mounting LB3 REST router at %s', restApiRoot); this.app.mountExpressRouter(restApiRoot, // TODO(bajtos) reload the handler when a model/method was added/removed // See https://github.com/loopbackio/loopback-next/issues/2394 for details. lb3App.handler('rest'), spec); } }; exports.Lb3AppBooter = Lb3AppBooter; exports.Lb3AppBooter = Lb3AppBooter = tslib_1.__decorate([ tslib_1.__param(0, (0, core_1.inject)(core_1.CoreBindings.APPLICATION_INSTANCE)), tslib_1.__param(1, (0, core_1.inject)(boot_1.BootBindings.PROJECT_ROOT)), tslib_1.__param(2, (0, core_1.inject)(`${boot_1.BootBindings.BOOT_OPTIONS}#lb3app`)), tslib_1.__metadata("design:paramtypes", [rest_1.RestApplication, String, Object]) ], Lb3AppBooter); //# sourceMappingURL=lb3app.booter.js.map