Openapi swagger启动导致nestjs找不到Connection元素

plupiseo  于 2023-06-29  发布在  其他
关注(0)|答案(1)|浏览(132)

我需要一些帮助,如果有人已经面临这一点,我不能处理为什么会发生!如果我做任何类型的启动(开发或生产),它正常工作,但当我需要更新openapi.yaml通过做node dist/openapi.js它不工作。
它抛出一个node nestjs错误:

2023-06-26T09:45:01+02:00 - OmsModule dependencies initialized
(node:10136) UnhandledPromiseRejectionWarning: Error: Nest could not find Connection element (this provider does not exist in the current context)
    at ContainerScanner.getWrapperCollectionPairByHost (C:\Users\ostorero-gu\Documents\projects\oms-api\node_modules\@nestjs\core\injector\container-sca
nner.js:34:19)
    at ContainerScanner.findInstanceByToken (C:\Users\ostorero-gu\Documents\projects\oms-api\node_modules\@nestjs\core\injector\container-scanner.js:20:
40)
    at Object.findInstanceByToken (C:\Users\ostorero-gu\Documents\projects\oms-api\node_modules\@nestjs\core\injector\module-ref.js:40:38)
    at Object.get (C:\Users\ostorero-gu\Documents\projects\oms-api\node_modules\@nestjs\core\injector\module.js:341:29)
    at TypeOrmCoreModule.<anonymous> (C:\Users\ostorero-gu\Documents\projects\oms-api\node_modules\@nestjs\typeorm\dist\typeorm-core.module.js:94:47)   
    at Generator.next (<anonymous>)
    at C:\Users\ostorero-gu\Documents\projects\oms-api\node_modules\@nestjs\typeorm\dist\typeorm-core.module.js:20:71
    at new Promise (<anonymous>)
    at __awaiter (C:\Users\ostorero-gu\Documents\projects\oms-api\node_modules\@nestjs\typeorm\dist\typeorm-core.module.js:16:12)
    at TypeOrmCoreModule.onApplicationShutdown (C:\Users\ostorero-gu\Documents\projects\oms-api\node_modules\@nestjs\typeorm\dist\typeorm-core.module.js
:90:16)
(node:10136) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without
 a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:10136) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will term
inate the Node.js process with a non-zero exit code.

所以我在app.module.ts中声明了两个与数据库的连接:

@Module({
  imports: [
    LoggerModule,
    ConfigurationModule,
    HealthcheckModule,
    TypeOrmModule.forRootAsync({
      imports: [ConfigurationModule],
      inject: [ConfigurationService],
      useFactory: async (configurationService: ConfigurationService) => {
        return ({
          type: 'oracle',
          extra: {
            connectString: configurationService.get(ConfigurationKeys.GOLDCONNECTSTRING),
          },
          username: configurationService.get(ConfigurationKeys.GOLDUSERNAME),
          password: configurationService.get(ConfigurationKeys.GOLDPASSWORD),
          database: '',
          entities: [__dirname + '/**/*.entity{.ts,.js}'],
          synchronize: false,
          logging: false,
        }) as TypeOrmModuleOptions;
      },
    }),
    HealthcheckTypeormModule.register({
      name: 'GOLD',
      type: 'oracle',
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigurationModule],
      name: 'reflex',
      inject: [ConfigurationService],
      useFactory: async (configurationService: ConfigurationService) => {
        return ({
          type: 'postgres',
          host: configurationService.get(ConfigurationKeys.REFLEXHOST),
          database: configurationService.get(ConfigurationKeys.REFLEXDB),
          username: configurationService.get(ConfigurationKeys.REFLEXUSERNAME),
          password: configurationService.get(ConfigurationKeys.REFLEXPASSWORD),
          synchronize: false,
          logging: false,
        }) as TypeOrmModuleOptions;
      },
    }),
    OmsModule,
  ],
  providers: []
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(HelmetMiddleware).forRoutes('*');
  }
}

“反射”连接用于两个存储库:

@Injectable()
export class ReflexRepository {

  private static readonly TAG = 'ReflexRepository';

  constructor(
    @InjectConnection('reflex') private readonly connection: Connection,
    private readonly logger: LoggerService,
  ) {
  }

  public async getOrderPreparation(orderPreparationNumber: string): Promise<Array<ReflexModelOrderPreparation>> {

    let queryResult;
    const query = ReflexRepository.getOrderPreparationSql(orderPreparationNumber);

    try {
      queryResult = await this.connection.query(query);
    } catch (e) {
      this.logger.error(ReflexRepository.TAG, e.message);
      throw e;
    }

    return queryResult;
  }

  private static getOrderPreparationSql(orderPreparationNumber: string): string {
    return `private query`;
  }

  async getTrackingByOrderNumber(orderNumber: string): Promise<TrackingCommandeEntity[]> {
    const result = this.connection.getRepository(TrackingCommandeEntity).find({ NUM_CDE_CLT: orderNumber });
    if ((await result).length <= 0) { throw new NotFoundError('Tracking pour la commande introuvable'); }
    return result;
  }
}

下面是我的OmsModule:

@Module({
  imports: [ProduitsModule],
  controllers: [OmsController],
  providers: [OmsService, GoldRepository, OmsMapper, ReflexRepository],
})

export class OmsModule {
}

最后,也许它会有用,这里是我的package.json:

{
  "name": "oms-api",
  "version": "5.6.1",
  "description": "blablalbla",
  "author": "test",
  "license": "MIT",
  "scripts": {
    "build": "tsc",
    "format": "prettier --write \"src/**/*.ts\"",
    "start": "ts-node -r tsconfig-paths/register src/main.ts",
    "start:dev": "nodemon",
    "start:debug": "nodemon --config nodemon-debug.json",
    "prestart:prod": "rimraf dist && tsc --p tsconfig.prod.json",
    "start:prod": "node dist/main.js",
    "prestart:openapi": "rimraf dist && tsc",
    "start:openapi": "node dist/openapi.js",
    "lint": "tslint -p tsconfig.json -c tslint.json",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:e2e": "jest --config ./test/jest-e2e.json",
    "sonar-scanner": "sonar-scanner"
  },
  "repository": {
    "type": "git",
    "url": "xxxxPrivateURLxxxxxx"
  },
  "dependencies": {
    "@nest-middlewares/helmet": "^6.0.0",
    "@nestjs/common": "^6.11.0",
    "@nestjs/core": "^6.11.0",
    "@nestjs/platform-express": "^6.10.14",
    "@nestjs/swagger": "^3.1.0",
    "@nestjs/typeorm": "^6.2.0",
    "class-transformer": "^0.4.0",
    "class-validator": "^0.11.0",
    "moment": "^2.27.0",
    "oracledb": "^4.2.0",
    "pg": "^8.2.1",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.1",
    "rxjs": "^6.6.0",
    "typeorm": "^0.2.25",
    "typescript": "^4.0.0",
    "@types/express-serve-static-core": "4.17.21",
    "@types/babel__traverse": "7.0.6"
  },
  "devDependencies": {
    "@nestjs/testing": "^6.11.11",
    "@types/jest": "^24.9.0",
    "@types/js-yaml": "^3.12.2",
    "@types/supertest": "^2.0.8",
    "@types/express": "^4.17.2",
    "@types/node": "14.18.51",
    "jest": "^24.9.0",
    "js-yaml": "^4.0.0",
    "nodemon": "^2.0.2",
    "prettier": "^1.19.1",
    "sonar-scanner": "^3.1.0",
    "supertest": "^4.0.2",
    "swagger-ui-express": "^4.1.2",
    "ts-jest": "^24.3.0",
    "ts-loader": "^4.4.2",
    "ts-node": "^8.6.2",
    "tsconfig-paths": "^3.9.0",
    "tslint": "^5.20.1",
    "tslint-sonarts": "^1.9.0"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".spec.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "coverageDirectory": "../test/coverage",
    "testEnvironment": "node"
  }
}

提前感谢,任何帮助赞赏!
我尝试了很多奇怪的东西,因为我不明白问题来自哪里,为什么openapi不工作。
下面是我的openapi.builder.ts:

export function createDocument(app: INestApplication, versionPrefix = false, enableBearerAuth = false): SwaggerDocument {
  const title = process.env.npm_package_name;
  const version = process.env.npm_package_version;
  const description = process.env.npm_package_description;

  const options = new DocumentBuilder()
    .setTitle(title)
    .setDescription(description)
    .setVersion(version);

  if (enableBearerAuth) {
    options.addBearerAuth();
  }

  const configuration = options.build();
  return SwaggerModule.createDocument(app, configuration);
}

openapi.ts:

async function run() {
  const logger = new LoggerService();
  const app = await NestFactory.create(AppModule, { logger });
  const outputPath = path.resolve(process.cwd(), 'openapi.yaml');

  const document = createDocument(app, true);

  if (!document.definitions) document.definitions = {};

  try {
    writeFileSync(outputPath, toYaml(document, { schema: JSON_SCHEMA }), { encoding: 'utf8' });
  } catch (e) {
    logger.error(`Error while creation yaml openapi : ${e.message}`);
  }

  await app.close();
}

run();

在这里使用main.ts:

async function run() {
  const environment = process.env.NODE_ENV;
  const apiDocsPath = '/api-docs';

  const app = await NestFactory.create(AppModule, { logger: new LoggerService() });

  //Uncomment if needed
  //app.enableShutdownHooks();

  app.enableCors();

  const document = createDocument(app);

  if (environment !== 'prod' && environment !== 'preprod') {
    SwaggerModule.setup('swagger', app, document);
  }

  app.use(apiDocsPath, (req, res) => res.send(document));
  await app.listen(3000);
}

run();
uelo1irk

uelo1irk1#

回复:我发现这篇文章:Nest could not find Sequelize element when calling app.close()
答案是,我们必须对第二个数据库连接进行双重命名,以便getConnectionToken可以从连接的选项中获取名称。第一个连接有默认名称,您不需要明确地命名它。
示例:

TypeOrmModule.forRootAsync({
  imports: [ConfigurationModule],
  inject: [ConfigurationService],
  useFactory: async (configurationService: ConfigurationService) => {
    return ({
      type: 'oracle',
      blabla: 'blabla'
    }) as TypeOrmModuleOptions;
  },
}),
TypeOrmModule.forRootAsync({
  imports: [ConfigurationModule],
  // REQUIRED NAME
  name: 'reflex',
  inject: [ConfigurationService],
  useFactory: async (configurationService: ConfigurationService) => {
    return ({
      // HERE NAME REQUIRED ALSO
      name: 'reflex',
      type: 'postgres',
      blabla: 'blabla'
    }) as TypeOrmModuleOptions;
  },
}),

相关问题