export default async function initialize()

in middleware/initialize.ts [265:403]


export default async function initialize(app: IReposApplication, express, rootdir: string, config: any, exception: Error): Promise<IReposApplication> {
  if (!config) {
    throw new Error('No configuration resolved');
  }
  const applicationProfile = config?.web?.app && config.web.app !== 'repos' ? await alternateRoutes(config, app, config.web.app) : DefaultApplicationProfile;
  const web = !(config?.skipModules && config.skipModules.has('web'));
  if (applicationProfile.webServer && !web) {
    applicationProfile.webServer = false;
  }
  const containerPurpose = config && config.isJobInternal ? 'Job' : (applicationProfile.webServer ? 'Web Application' : 'Application');
  debug(`${containerPurpose} name: ${applicationProfile.applicationName}`);
  debug(`Environment: ${config?.debug?.environmentName || 'Unknown'}`);
  if (!exception && applicationProfile.validate) {
    try {
      await applicationProfile.validate();
    } catch (error) {
      exception = error;
    }
  }
  app.set('started', new Date());
  app.config = config;
  if (exception) {
    // Once app insights is available, will try to log this exception; display for now.
    console.dir(exception);
  }
  app.set('basedir', rootdir);
  const providers: IProviders = {
    app,
    basedir: rootdir,
    applicationProfile,
  };
  app.set('providers', providers);
  app.providers = providers;
  app.set('runtimeConfig', config);
  providers.healthCheck = healthCheck(app, config);
  if (applicationProfile.webServer) {
    if (!app.startServer) {
      throw new Error(`app.startServer is required for web applications`);
    }
    await app.startServer();
  }
  app.use(RouteCorrelationId);
  providers.insights = appInsights(app, config);
  app.set('appInsightsClient', providers.insights);
  if (!exception && (!config || !config.activeDirectory)) {
    exception = new Error(`config.activeDirectory.clientId and config.activeDirectory.clientSecret are required to initialize KeyVault`);
  }
  app.use('*', (req, res, next) => {
    if (providers.healthCheck.ready) {
      return next();
    }
    return res.send('Service not ready.');
  });
  if (config.containers && config.containers.deployment) {
    debug('Container deployment: HTTP: listening, HSTS: on');
    app.use(RouteHsts);
  } else if (config.containers && config.containers.docker) {
    debug('Docker image: HTTP: listening, HSTS: off');
  } else if (config.webServer.allowHttp) {
    debug('WARNING: Development mode (DEBUG_ALLOW_HTTP): HTTP: listening, HSTS: off');
  } else {
    app.use(RouteSslify);
    app.use(RouteHsts);
  }
  if (!exception) {
    const kvConfig = {
      clientId: config?.activeDirectory?.clientId,
      clientSecret: config?.activeDirectory?.clientSecret,
      tenantId: config?.activeDirectory?.tenantId,
    };
    providers.config = config;
    let keyEncryptionKeyResolver: IKeyVaultSecretResolver = null;
    try {
      const keyVaultClient = keyVault(kvConfig);
      keyEncryptionKeyResolver = keyVaultResolver(keyVaultClient);
      app.set('keyEncryptionKeyResolver', keyEncryptionKeyResolver);
      providers.keyEncryptionKeyResolver = keyEncryptionKeyResolver;
      debug('configuration secrets resolved');
    } catch (noKeyVault) {
      if (!kvConfig.clientId && !kvConfig.clientSecret) {
        debug('configuration resolved, no key vault client configured');
      } else {
        console.warn(noKeyVault);
        throw noKeyVault;
      }
    }
    try {
      await initializeAsync(app, express, rootdir, config);
    } catch (initializeError) {
      console.dir(initializeError);
      debug(`Initialization failure: ${initializeError}`);
      exception = initializeError;
    }
  }
  try {
    MiddlewareIndex(app, express, config, rootdir, exception);
  } catch (middlewareError) {
    exception = middlewareError;
  }
  // ROUTES:
  if (!exception) {
    if (applicationProfile.customRoutes) {
      await applicationProfile.customRoutes();
    } else {
      app.use('/', expressRoutes);
    }
  } else {
    console.error(exception);
    const appInsightsClient = providers.insights;
    const crash = (error) => {
      return () => {
        debug('App crashed because of an initialization error.');
        console.log(error.message);
        if (error.stack) {
          console.log(error.stack);
        }
        process.exit(1);
      };
    };
    if (appInsightsClient) {
      appInsightsClient.trackException({
        exception,
        properties: {
          info: 'App crashed while initializing',
        },
      });
      try {
        appInsightsClient.flush({ isAppCrashing: true, callback: crash(exception) });
      } catch (sendError) {
        console.dir(sendError);
        crash(exception)();
      }
    } else {
      crash(exception)();
    }
  }
  await ErrorRoutes(app, exception);
  return app;
}