Skip to content
Snippets Groups Projects
Select Git revision
  • c4ec53cac4b8f45a79d91795d42adc167fb335ec
  • master default protected
  • gh-pages
  • dependabot/npm_and_yarn/neostandard-0.12.2
  • dependabot/npm_and_yarn/eslint-plugin-import-2.32.0
  • dependabot/npm_and_yarn/typescript-eslint/parser-8.36.0
  • dependabot/npm_and_yarn/nock-14.0.5
  • dependabot/npm_and_yarn/react-19.1.0
  • dependabot/npm_and_yarn/react-dom-19.1.0
  • server-2025-02-01-6100669a
  • server-2024-11-01-87cba042
  • server-2024-10-01-6875b7c8
  • dependabot/npm_and_yarn/path-to-regexp-8.2.0
  • server-2024-09-01-3d52575c
  • daily-tests-gha2
  • daily-tests-gha
  • server-2023-12-01-92d8fb8e
  • server-2023-11-01-a80c93fd
  • server-2023-10-01-31096085
  • coc-v2
  • server-2023-09-01-8edc3810
  • server-2025-07-01
  • 5.0.2
  • 5.0.1
  • 5.0.0
  • server-2025-06-01
  • server-2025-05-01
  • server-2025-04-03
  • server-2025-03-02
  • server-2025-03-01
  • server-2025-02-02
  • server-2025-01-01
  • server-2024-12-01
  • server-2024-11-02
  • 4.1.0
  • server-2024-09-25
  • server-2024-09-02
  • server-2024-08-01
  • server-2024-07-01
  • 4.0.0
  • server-2024-06-01
41 results

server.js

Blame
  • validation.js 4.50 KiB
    const semver = require('semver');
    const options = require('./definitions').getOptions();
    const {
      hasValidSchedule,
      hasValidTimezone,
    } = require('../workers/branch/schedule');
    
    let optionTypes;
    
    module.exports = {
      validateConfig,
    };
    
    function validateConfig(config) {
      if (!optionTypes) {
        optionTypes = {};
        options.forEach(option => {
          optionTypes[option.name] = option.type;
        });
      }
      let errors = [];
      let warnings = [];
    
      function isIgnored(key) {
        const ignoredNodes = [
          'prBanner',
          'depType',
          'npmToken',
          'packageFile',
          'forkToken',
          'repository',
        ];
        return ignoredNodes.indexOf(key) !== -1;
      }
    
      function isAFunction(value) {
        const getType = {};
        return value && getType.toString.call(value) === '[object Function]';
      }
    
      function isObject(obj) {
        return Object.prototype.toString.call(obj) === '[object Object]';
      }
    
      function isString(val) {
        return typeof val === 'string' || val instanceof String;
      }
    
      for (const [key, val] of Object.entries(config)) {
        if (
          !isIgnored(key) && // We need to ignore some reserved keys
          !isAFunction(val) // Ignore all functions
        ) {
          if (!optionTypes[key]) {
            errors.push({
              depName: 'Configuration Error',
              message: `Invalid configuration option: \`${key}\``,
            });
          } else if (key === 'schedule') {
            const [validSchedule, errorMessage] = hasValidSchedule(val);
            if (!validSchedule) {
              errors.push({
                depName: 'Configuration Error',
                message: `Invalid schedule: \`${errorMessage}\``,
              });
            }
          } else if (key === 'timezone' && val !== null) {
            const [validTimezone, errorMessage] = hasValidTimezone(val);
            if (!validTimezone) {
              errors.push({
                depName: 'Configuration Error',
                message: errorMessage,
              });
            }
          } else if (key === 'allowedVersions' && val !== null) {
            if (!semver.validRange(val)) {
              errors.push({
                depName: 'Configuration Error',
                message: `Invalid semver range for allowedVersions: \`${val}\``,
              });
            }
          } else if (val != null) {
            const type = optionTypes[key];
            if (type === 'boolean') {
              if (val !== true && val !== false) {
                errors.push({
                  depName: 'Configuration Error',
                  message: `Configuration option \`${key}\` should be boolean. Found: ${JSON.stringify(
                    val
                  )} (${typeof val})`,
                });
              }
            } else if (type === 'list') {
              if (!Array.isArray(val)) {
                errors.push({
                  depName: 'Configuration Error',
                  message: `Configuration option \`${key}\` should be a list (Array)`,
                });
              } else if (key === 'extends') {
                for (const subval of val) {
                  if (isString(subval) && subval.match(/^:timezone(.+)$/)) {
                    const [, timezone] = subval.match(/^:timezone\((.+)\)$/);
                    const [validTimezone, errorMessage] = hasValidTimezone(
                      timezone
                    );
                    if (!validTimezone) {
                      errors.push({
                        depName: 'Configuration Error',
                        message: errorMessage,
                      });
                    }
                  }
                }
              } else {
                // eslint-disable-next-line no-loop-func
                val.forEach(subval => {
                  if (isObject(subval)) {
                    const subValidation = module.exports.validateConfig(subval);
                    warnings = warnings.concat(subValidation.warnings);
                    errors = errors.concat(subValidation.errors);
                  }
                });
              }
            } else if (type === 'string') {
              if (!isString(val)) {
                errors.push({
                  depName: 'Configuration Error',
                  message: `Configuration option \`${key}\` should be a string`,
                });
              }
            } else if (type === 'json') {
              if (isObject(val)) {
                const subValidation = module.exports.validateConfig(val);
                warnings = warnings.concat(subValidation.warnings);
                errors = errors.concat(subValidation.errors);
              } else {
                errors.push({
                  depName: 'Configuration Error',
                  message: `Configuration option \`${key}\` should be a json object`,
                });
              }
            }
          }
        }
      }
      return { errors, warnings };
    }