function initConfig(N) {
  // set application environment
  N.environment = process.env.NODECA_ENV || N.config.env_default || 'development';

  // do global expansion first
  // merge `^all` branch
  if (N.config['^all']) {
    mergeConfigs(N.config, N.config['^all']);
    delete N.config['^all'];
  }

  // expand environment-dependent configs
  for (let [ key, val ] of Object.entries(N.config)) {
    if (key[0] === '^') {
      delete N.config[key];

      if (N.environment === key.substr(1)) {
        mergeConfigs(N.config, val);
      }
    }
  }

  //
  // Post-process config.
  //
  N.config.options = N.config.options || {};
}
internal
 N.validate.process(apiPath, rawParams) -> Object|Null

 Validate `raw_params` against apiPath schema, any undeclared properties
 in `raw_params.$query` will be moved to `params.$query_extra`.

 Runs revalidate of apiPath for given params. Returns an object:
   - is_valid (Boolean) - true if validation succeeded
   - errors   (Array)   - list of errors, each error is { field, message, value }
   - params   (Object)  - filtered params you should be using instead of raw_params

 If apiPath has no schema, `Null` is returned instead.