f385a680699e443f20e9fb8091d4dbd1ac4f251cd3c52441ae2d7df585585fcc61c1644d4463d7e499a1196131a4d97607a9c3f6c0837ec11863e664fc028d 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /* eslint no-prototype-builtins: 0 */
  2. 'use strict'
  3. const chalk = require('chalk')
  4. const format = require('stringify-object')
  5. const debug = require('debug')('lint-staged:cfg')
  6. const TEST_DEPRECATED_KEYS = new Map([
  7. ['concurrent', (key) => typeof key === 'boolean'],
  8. ['chunkSize', (key) => typeof key === 'number'],
  9. ['globOptions', (key) => typeof key === 'object'],
  10. ['linters', (key) => typeof key === 'object'],
  11. ['ignore', (key) => Array.isArray(key)],
  12. ['subTaskConcurrency', (key) => typeof key === 'number'],
  13. ['renderer', (key) => typeof key === 'string'],
  14. ['relative', (key) => typeof key === 'boolean'],
  15. ])
  16. const formatError = (helpMsg) => `● Validation Error:
  17. ${helpMsg}
  18. Please refer to https://github.com/okonet/lint-staged#configuration for more information...`
  19. const createError = (opt, helpMsg, value) =>
  20. formatError(`Invalid value for '${chalk.bold(opt)}'.
  21. ${helpMsg}.
  22. Configured value is: ${chalk.bold(
  23. format(value, { inlineCharacterLimit: Number.POSITIVE_INFINITY })
  24. )}`)
  25. /**
  26. * Runs config validation. Throws error if the config is not valid.
  27. * @param config {Object}
  28. * @returns config {Object}
  29. */
  30. module.exports = function validateConfig(config) {
  31. debug('Validating config')
  32. const errors = []
  33. if (!config || typeof config !== 'object') {
  34. errors.push('Configuration should be an object!')
  35. } else {
  36. const entries = Object.entries(config)
  37. if (entries.length === 0) {
  38. errors.push('Configuration should not be empty!')
  39. }
  40. entries.forEach(([pattern, task]) => {
  41. if (TEST_DEPRECATED_KEYS.has(pattern)) {
  42. const testFn = TEST_DEPRECATED_KEYS.get(pattern)
  43. if (testFn(task)) {
  44. errors.push(
  45. createError(
  46. pattern,
  47. 'Advanced configuration has been deprecated. For more info, please visit: https://github.com/okonet/lint-staged',
  48. task
  49. )
  50. )
  51. }
  52. }
  53. if (
  54. (!Array.isArray(task) ||
  55. task.some((item) => typeof item !== 'string' && typeof item !== 'function')) &&
  56. typeof task !== 'string' &&
  57. typeof task !== 'function'
  58. ) {
  59. errors.push(
  60. createError(
  61. pattern,
  62. 'Should be a string, a function, or an array of strings and functions',
  63. task
  64. )
  65. )
  66. }
  67. })
  68. }
  69. if (errors.length) {
  70. throw new Error(errors.join('\n'))
  71. }
  72. return config
  73. }
  74. module.exports.createError = createError