eslint 5.12.0 → 5.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/README.md +76 -143
  3. package/conf/eslint-all.js +3 -5
  4. package/conf/eslint-recommended.js +4 -268
  5. package/lib/built-in-rules-index.js +277 -0
  6. package/lib/cli-engine.js +6 -2
  7. package/lib/config/config-file.js +25 -2
  8. package/lib/config/config-initializer.js +150 -143
  9. package/lib/config/config-ops.js +30 -0
  10. package/lib/config/config-rule.js +2 -4
  11. package/lib/config/plugins.js +12 -4
  12. package/lib/config.js +1 -1
  13. package/lib/formatters/table.js +13 -4
  14. package/lib/formatters/tap.js +7 -4
  15. package/lib/linter.js +31 -31
  16. package/lib/load-rules.js +2 -5
  17. package/lib/rules/accessor-pairs.js +4 -2
  18. package/lib/rules/array-bracket-newline.js +4 -2
  19. package/lib/rules/array-callback-return.js +2 -1
  20. package/lib/rules/array-element-newline.js +4 -2
  21. package/lib/rules/arrow-body-style.js +1 -1
  22. package/lib/rules/arrow-parens.js +2 -1
  23. package/lib/rules/arrow-spacing.js +7 -6
  24. package/lib/rules/brace-style.js +2 -1
  25. package/lib/rules/camelcase.js +3 -2
  26. package/lib/rules/capitalized-comments.js +15 -14
  27. package/lib/rules/class-methods-use-this.js +1 -1
  28. package/lib/rules/comma-spacing.js +10 -4
  29. package/lib/rules/complexity.js +7 -9
  30. package/lib/rules/consistent-return.js +2 -1
  31. package/lib/rules/dot-notation.js +5 -3
  32. package/lib/rules/eqeqeq.js +2 -1
  33. package/lib/rules/for-direction.js +30 -17
  34. package/lib/rules/func-call-spacing.js +2 -1
  35. package/lib/rules/func-style.js +3 -2
  36. package/lib/rules/getter-return.js +2 -1
  37. package/lib/rules/global-require.js +5 -2
  38. package/lib/rules/guard-for-in.js +5 -2
  39. package/lib/rules/handle-callback-err.js +5 -2
  40. package/lib/rules/id-blacklist.js +4 -1
  41. package/lib/rules/id-length.js +9 -6
  42. package/lib/rules/id-match.js +11 -5
  43. package/lib/rules/implicit-arrow-linebreak.js +7 -3
  44. package/lib/rules/indent-legacy.js +11 -5
  45. package/lib/rules/indent.js +18 -9
  46. package/lib/rules/init-declarations.js +13 -13
  47. package/lib/rules/jsx-quotes.js +5 -2
  48. package/lib/rules/key-spacing.js +70 -35
  49. package/lib/rules/keyword-spacing.js +18 -12
  50. package/lib/rules/line-comment-position.js +15 -8
  51. package/lib/rules/linebreak-style.js +6 -6
  52. package/lib/rules/lines-around-comment.js +20 -16
  53. package/lib/rules/lines-around-directive.js +5 -2
  54. package/lib/rules/lines-between-class-members.js +8 -6
  55. package/lib/rules/max-depth.js +11 -9
  56. package/lib/rules/max-len.js +24 -13
  57. package/lib/rules/max-lines-per-function.js +17 -18
  58. package/lib/rules/max-lines.js +14 -10
  59. package/lib/rules/max-nested-callbacks.js +12 -11
  60. package/lib/rules/max-params.js +11 -9
  61. package/lib/rules/max-statements-per-line.js +8 -5
  62. package/lib/rules/max-statements.js +12 -11
  63. package/lib/rules/multiline-comment-style.js +18 -17
  64. package/lib/rules/multiline-ternary.js +8 -6
  65. package/lib/rules/new-cap.js +18 -11
  66. package/lib/rules/new-parens.js +5 -2
  67. package/lib/rules/newline-after-var.js +6 -8
  68. package/lib/rules/newline-before-return.js +5 -1
  69. package/lib/rules/newline-per-chained-call.js +7 -3
  70. package/lib/rules/no-async-promise-executor.js +5 -2
  71. package/lib/rules/no-bitwise.js +2 -1
  72. package/lib/rules/no-confusing-arrow.js +1 -1
  73. package/lib/rules/no-constant-condition.js +24 -2
  74. package/lib/rules/no-duplicate-imports.js +17 -11
  75. package/lib/rules/no-else-return.js +2 -1
  76. package/lib/rules/no-empty.js +2 -1
  77. package/lib/rules/no-eval.js +1 -1
  78. package/lib/rules/no-extra-parens.js +4 -4
  79. package/lib/rules/no-fallthrough.js +8 -4
  80. package/lib/rules/no-floating-decimal.js +7 -3
  81. package/lib/rules/no-implicit-coercion.js +9 -6
  82. package/lib/rules/no-irregular-whitespace.js +8 -4
  83. package/lib/rules/no-labels.js +6 -4
  84. package/lib/rules/no-magic-numbers.js +6 -3
  85. package/lib/rules/no-mixed-operators.js +5 -4
  86. package/lib/rules/no-mixed-requires.js +4 -2
  87. package/lib/rules/no-multi-spaces.js +2 -1
  88. package/lib/rules/no-param-reassign.js +1 -1
  89. package/lib/rules/no-plusplus.js +2 -1
  90. package/lib/rules/no-redeclare.js +2 -2
  91. package/lib/rules/no-self-assign.js +2 -1
  92. package/lib/rules/no-shadow-restricted-names.js +16 -2
  93. package/lib/rules/no-shadow.js +3 -3
  94. package/lib/rules/no-sync.js +2 -1
  95. package/lib/rules/no-tabs.js +2 -1
  96. package/lib/rules/no-trailing-spaces.js +5 -3
  97. package/lib/rules/no-undef.js +7 -3
  98. package/lib/rules/no-underscore-dangle.js +6 -3
  99. package/lib/rules/no-unexpected-multiline.js +14 -13
  100. package/lib/rules/no-unneeded-ternary.js +2 -1
  101. package/lib/rules/no-unsafe-negation.js +6 -3
  102. package/lib/rules/no-unused-expressions.js +6 -3
  103. package/lib/rules/no-unused-labels.js +7 -2
  104. package/lib/rules/no-unused-vars.js +8 -4
  105. package/lib/rules/no-use-before-define.js +3 -3
  106. package/lib/rules/no-useless-rename.js +3 -3
  107. package/lib/rules/object-curly-newline.js +6 -4
  108. package/lib/rules/object-property-newline.js +5 -3
  109. package/lib/rules/object-shorthand.js +9 -5
  110. package/lib/rules/one-var.js +24 -38
  111. package/lib/rules/operator-assignment.js +8 -4
  112. package/lib/rules/padded-blocks.js +32 -9
  113. package/lib/rules/prefer-arrow-callback.js +4 -2
  114. package/lib/rules/prefer-const.js +7 -4
  115. package/lib/rules/prefer-destructuring.js +70 -12
  116. package/lib/rules/prefer-promise-reject-errors.js +1 -1
  117. package/lib/rules/prefer-spread.js +2 -13
  118. package/lib/rules/quote-props.js +10 -5
  119. package/lib/rules/quotes.js +4 -2
  120. package/lib/rules/require-jsdoc.js +13 -7
  121. package/lib/rules/semi-spacing.js +6 -8
  122. package/lib/rules/semi.js +5 -4
  123. package/lib/rules/sort-imports.js +6 -3
  124. package/lib/rules/sort-keys.js +13 -5
  125. package/lib/rules/sort-vars.js +2 -1
  126. package/lib/rules/space-before-function-paren.js +6 -3
  127. package/lib/rules/space-infix-ops.js +2 -1
  128. package/lib/rules/space-unary-ops.js +20 -10
  129. package/lib/rules/spaced-comment.js +2 -1
  130. package/lib/rules/strict.js +34 -35
  131. package/lib/rules/switch-colon-spacing.js +11 -8
  132. package/lib/rules/symbol-description.js +6 -3
  133. package/lib/rules/template-curly-spacing.js +10 -10
  134. package/lib/rules/template-tag-spacing.js +7 -3
  135. package/lib/rules/unicode-bom.js +7 -3
  136. package/lib/rules/use-isnan.js +5 -2
  137. package/lib/rules/valid-jsdoc.js +40 -19
  138. package/lib/rules/valid-typeof.js +9 -4
  139. package/lib/rules/vars-on-top.js +6 -4
  140. package/lib/rules/wrap-iife.js +12 -6
  141. package/lib/rules/yield-star-spacing.js +17 -10
  142. package/lib/rules/yoda.js +9 -4
  143. package/lib/rules.js +4 -34
  144. package/lib/util/ajv.js +1 -0
  145. package/lib/util/config-comment-parser.js +7 -10
  146. package/package.json +20 -20
@@ -27,6 +27,9 @@ module.exports = {
27
27
  type: "string"
28
28
  },
29
29
  uniqueItems: true
30
+ },
31
+ messages: {
32
+ blacklisted: "Identifier '{{name}}' is blacklisted."
30
33
  }
31
34
  },
32
35
 
@@ -72,7 +75,7 @@ module.exports = {
72
75
  function report(node) {
73
76
  context.report({
74
77
  node,
75
- message: "Identifier '{{name}}' is blacklisted.",
78
+ messageId: "blacklisted",
76
79
  data: {
77
80
  name: node.name
78
81
  }
@@ -26,10 +26,11 @@ module.exports = {
26
26
  type: "object",
27
27
  properties: {
28
28
  min: {
29
- type: "number"
29
+ type: "integer",
30
+ default: 2
30
31
  },
31
32
  max: {
32
- type: "number"
33
+ type: "integer"
33
34
  },
34
35
  exceptions: {
35
36
  type: "array",
@@ -44,7 +45,11 @@ module.exports = {
44
45
  },
45
46
  additionalProperties: false
46
47
  }
47
- ]
48
+ ],
49
+ messages: {
50
+ tooShort: "Identifier name '{{name}}' is too short (< {{min}}).",
51
+ tooLong: "Identifier name '{{name}}' is too long (> {{max}})."
52
+ }
48
53
  },
49
54
 
50
55
  create(context) {
@@ -107,9 +112,7 @@ module.exports = {
107
112
  if (isValidExpression && (isValidExpression === true || isValidExpression(parent, node))) {
108
113
  context.report({
109
114
  node,
110
- message: isShort
111
- ? "Identifier name '{{name}}' is too short (< {{min}})."
112
- : "Identifier name '{{name}}' is too long (> {{max}}).",
115
+ messageId: isShort ? "tooShort" : "tooLong",
113
116
  data: { name, min: minLength, max: maxLength }
114
117
  });
115
118
  }
@@ -28,17 +28,23 @@ module.exports = {
28
28
  type: "object",
29
29
  properties: {
30
30
  properties: {
31
- type: "boolean"
31
+ type: "boolean",
32
+ default: false
32
33
  },
33
34
  onlyDeclarations: {
34
- type: "boolean"
35
+ type: "boolean",
36
+ default: false
35
37
  },
36
38
  ignoreDestructuring: {
37
- type: "boolean"
39
+ type: "boolean",
40
+ default: false
38
41
  }
39
42
  }
40
43
  }
41
- ]
44
+ ],
45
+ messages: {
46
+ notMatch: "Identifier '{{name}}' does not match the pattern '{{pattern}}'."
47
+ }
42
48
  },
43
49
 
44
50
  create(context) {
@@ -116,7 +122,7 @@ module.exports = {
116
122
  if (!reported.has(node)) {
117
123
  context.report({
118
124
  node,
119
- message: "Identifier '{{name}}' does not match the pattern '{{pattern}}'.",
125
+ messageId: "notMatch",
120
126
  data: {
121
127
  name: node.name,
122
128
  pattern
@@ -30,7 +30,11 @@ module.exports = {
30
30
  {
31
31
  enum: ["beside", "below"]
32
32
  }
33
- ]
33
+ ],
34
+ messages: {
35
+ expected: "Expected a linebreak before this expression.",
36
+ unexpected: "Expected no linebreak before this expression."
37
+ }
34
38
  },
35
39
 
36
40
  create(context) {
@@ -210,13 +214,13 @@ module.exports = {
210
214
  if (tokenBefore.loc.end.line === fixerTarget.loc.start.line && option === "below") {
211
215
  context.report({
212
216
  node: fixerTarget,
213
- message: "Expected a linebreak before this expression.",
217
+ messageId: "expected",
214
218
  fix: fixer => fixer.insertTextBefore(fixerTarget, "\n")
215
219
  });
216
220
  } else if (tokenBefore.loc.end.line !== fixerTarget.loc.start.line && option === "beside") {
217
221
  context.report({
218
222
  node: fixerTarget,
219
- message: "Expected no linebreak before this expression.",
223
+ messageId: "unexpected",
220
224
  fix: autoFixBesides(tokenBefore, fixerTarget, node)
221
225
  });
222
226
  }
@@ -169,7 +169,10 @@ module.exports = {
169
169
  },
170
170
  additionalProperties: false
171
171
  }
172
- ]
172
+ ],
173
+ messages: {
174
+ expected: "Expected indentation of {{expected}} but found {{actual}}."
175
+ }
173
176
  },
174
177
 
175
178
  create(context) {
@@ -268,7 +271,7 @@ module.exports = {
268
271
  * @param {int} actualTabs The actual number of indentation tabs that were found on this line
269
272
  * @returns {string} An error message for this line
270
273
  */
271
- function createErrorMessage(expectedAmount, actualSpaces, actualTabs) {
274
+ function createErrorMessageData(expectedAmount, actualSpaces, actualTabs) {
272
275
  const expectedStatement = `${expectedAmount} ${indentType}${expectedAmount === 1 ? "" : "s"}`; // e.g. "2 tabs"
273
276
  const foundSpacesWord = `space${actualSpaces === 1 ? "" : "s"}`; // e.g. "space"
274
277
  const foundTabsWord = `tab${actualTabs === 1 ? "" : "s"}`; // e.g. "tabs"
@@ -288,8 +291,10 @@ module.exports = {
288
291
  } else {
289
292
  foundStatement = "0";
290
293
  }
291
-
292
- return `Expected indentation of ${expectedStatement} but found ${foundStatement}.`;
294
+ return {
295
+ expected: expectedStatement,
296
+ actual: foundStatement
297
+ };
293
298
  }
294
299
 
295
300
  /**
@@ -318,7 +323,8 @@ module.exports = {
318
323
  context.report({
319
324
  node,
320
325
  loc,
321
- message: createErrorMessage(needed, gottenSpaces, gottenTabs),
326
+ messageId: "expected",
327
+ data: createErrorMessageData(needed, gottenSpaces, gottenTabs),
322
328
  fix: fixer => fixer.replaceTextRange(textRange, desiredIndent)
323
329
  });
324
330
  }
@@ -518,7 +518,8 @@ module.exports = {
518
518
  properties: {
519
519
  SwitchCase: {
520
520
  type: "integer",
521
- minimum: 0
521
+ minimum: 0,
522
+ default: 0
522
523
  },
523
524
  VariableDeclarator: {
524
525
  oneOf: [
@@ -582,7 +583,8 @@ module.exports = {
582
583
  ObjectExpression: ELEMENT_LIST_SCHEMA,
583
584
  ImportDeclaration: ELEMENT_LIST_SCHEMA,
584
585
  flatTernaryExpressions: {
585
- type: "boolean"
586
+ type: "boolean",
587
+ default: false
586
588
  },
587
589
  ignoredNodes: {
588
590
  type: "array",
@@ -594,12 +596,16 @@ module.exports = {
594
596
  }
595
597
  },
596
598
  ignoreComments: {
597
- type: "boolean"
599
+ type: "boolean",
600
+ default: false
598
601
  }
599
602
  },
600
603
  additionalProperties: false
601
604
  }
602
- ]
605
+ ],
606
+ messages: {
607
+ wrongIndentation: "Expected indentation of {{expected}} but found {{actual}}."
608
+ }
603
609
  },
604
610
 
605
611
  create(context) {
@@ -647,7 +653,7 @@ module.exports = {
647
653
  }
648
654
 
649
655
  if (context.options[1]) {
650
- lodash.merge(options, context.options[1]);
656
+ Object.assign(options, context.options[1]);
651
657
 
652
658
  if (typeof options.VariableDeclarator === "number" || options.VariableDeclarator === "first") {
653
659
  options.VariableDeclarator = {
@@ -671,7 +677,7 @@ module.exports = {
671
677
  * @param {int} actualTabs The actual number of indentation tabs that were found on this line
672
678
  * @returns {string} An error message for this line
673
679
  */
674
- function createErrorMessage(expectedAmount, actualSpaces, actualTabs) {
680
+ function createErrorMessageData(expectedAmount, actualSpaces, actualTabs) {
675
681
  const expectedStatement = `${expectedAmount} ${indentType}${expectedAmount === 1 ? "" : "s"}`; // e.g. "2 tabs"
676
682
  const foundSpacesWord = `space${actualSpaces === 1 ? "" : "s"}`; // e.g. "space"
677
683
  const foundTabsWord = `tab${actualTabs === 1 ? "" : "s"}`; // e.g. "tabs"
@@ -689,8 +695,10 @@ module.exports = {
689
695
  } else {
690
696
  foundStatement = "0";
691
697
  }
692
-
693
- return `Expected indentation of ${expectedStatement} but found ${foundStatement}.`;
698
+ return {
699
+ expected: expectedStatement,
700
+ actual: foundStatement
701
+ };
694
702
  }
695
703
 
696
704
  /**
@@ -706,7 +714,8 @@ module.exports = {
706
714
 
707
715
  context.report({
708
716
  node: token,
709
- message: createErrorMessage(neededIndent.length, numSpaces, numTabs),
717
+ messageId: "wrongIndentation",
718
+ data: createErrorMessageData(neededIndent.length, numSpaces, numTabs),
710
719
  loc: {
711
720
  start: { line: token.loc.start.line, column: 0 },
712
721
  end: { line: token.loc.start.line, column: token.loc.start.column }
@@ -75,7 +75,8 @@ module.exports = {
75
75
  type: "object",
76
76
  properties: {
77
77
  ignoreForLoopInit: {
78
- type: "boolean"
78
+ type: "boolean",
79
+ default: false
79
80
  }
80
81
  },
81
82
  additionalProperties: false
@@ -85,6 +86,10 @@ module.exports = {
85
86
  maxItems: 2
86
87
  }
87
88
  ]
89
+ },
90
+ messages: {
91
+ initialized: "Variable '{{idName}}' should be initialized on declaration.",
92
+ notInitialized: "Variable '{{idName}}' should not be initialized on declaration."
88
93
  }
89
94
  },
90
95
 
@@ -111,23 +116,18 @@ module.exports = {
111
116
  id = declaration.id,
112
117
  initialized = isInitialized(declaration),
113
118
  isIgnoredForLoop = params.ignoreForLoopInit && isForLoop(node.parent);
114
-
115
- if (id.type !== "Identifier") {
116
- continue;
117
- }
119
+ let messageId = "";
118
120
 
119
121
  if (mode === MODE_ALWAYS && !initialized) {
120
- context.report({
121
- node: declaration,
122
- message: "Variable '{{idName}}' should be initialized on declaration.",
123
- data: {
124
- idName: id.name
125
- }
126
- });
122
+ messageId = "initialized";
127
123
  } else if (mode === MODE_NEVER && kind !== "const" && initialized && !isIgnoredForLoop) {
124
+ messageId = "notInitialized";
125
+ }
126
+
127
+ if (id.type === "Identifier" && messageId) {
128
128
  context.report({
129
129
  node: declaration,
130
- message: "Variable '{{idName}}' should not be initialized on declaration.",
130
+ messageId,
131
131
  data: {
132
132
  idName: id.name
133
133
  }
@@ -53,7 +53,10 @@ module.exports = {
53
53
  {
54
54
  enum: ["prefer-single", "prefer-double"]
55
55
  }
56
- ]
56
+ ],
57
+ messages: {
58
+ unexpected: "Unexpected usage of {{description}}."
59
+ }
57
60
  },
58
61
 
59
62
  create(context) {
@@ -77,7 +80,7 @@ module.exports = {
77
80
  if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) {
78
81
  context.report({
79
82
  node: attributeValue,
80
- message: "Unexpected usage of {{description}}.",
83
+ messageId: "unexpected",
81
84
  data: {
82
85
  description: setting.description
83
86
  },
@@ -121,11 +121,6 @@ function initOptions(toOptions, fromOptions) {
121
121
  // Rule Definition
122
122
  //------------------------------------------------------------------------------
123
123
 
124
- const messages = {
125
- key: "{{error}} space after {{computed}}key '{{key}}'.",
126
- value: "{{error}} space before value for {{computed}}key '{{key}}'."
127
- };
128
-
129
124
  module.exports = {
130
125
  meta: {
131
126
  type: "layout",
@@ -153,16 +148,20 @@ module.exports = {
153
148
  type: "object",
154
149
  properties: {
155
150
  mode: {
156
- enum: ["strict", "minimum"]
151
+ enum: ["strict", "minimum"],
152
+ default: "strict"
157
153
  },
158
154
  on: {
159
- enum: ["colon", "value"]
155
+ enum: ["colon", "value"],
156
+ default: "colon"
160
157
  },
161
158
  beforeColon: {
162
- type: "boolean"
159
+ type: "boolean",
160
+ default: false
163
161
  },
164
162
  afterColon: {
165
- type: "boolean"
163
+ type: "boolean",
164
+ default: true
166
165
  }
167
166
  },
168
167
  additionalProperties: false
@@ -170,13 +169,16 @@ module.exports = {
170
169
  ]
171
170
  },
172
171
  mode: {
173
- enum: ["strict", "minimum"]
172
+ enum: ["strict", "minimum"],
173
+ default: "strict"
174
174
  },
175
175
  beforeColon: {
176
- type: "boolean"
176
+ type: "boolean",
177
+ default: false
177
178
  },
178
179
  afterColon: {
179
- type: "boolean"
180
+ type: "boolean",
181
+ default: true
180
182
  }
181
183
  },
182
184
  additionalProperties: false
@@ -188,13 +190,16 @@ module.exports = {
188
190
  type: "object",
189
191
  properties: {
190
192
  mode: {
191
- enum: ["strict", "minimum"]
193
+ enum: ["strict", "minimum"],
194
+ default: "strict"
192
195
  },
193
196
  beforeColon: {
194
- type: "boolean"
197
+ type: "boolean",
198
+ default: false
195
199
  },
196
200
  afterColon: {
197
- type: "boolean"
201
+ type: "boolean",
202
+ default: true
198
203
  }
199
204
  },
200
205
  additionalProperties: false
@@ -211,16 +216,20 @@ module.exports = {
211
216
  type: "object",
212
217
  properties: {
213
218
  mode: {
214
- enum: ["strict", "minimum"]
219
+ enum: ["strict", "minimum"],
220
+ default: "strict"
215
221
  },
216
222
  on: {
217
- enum: ["colon", "value"]
223
+ enum: ["colon", "value"],
224
+ default: "colon"
218
225
  },
219
226
  beforeColon: {
220
- type: "boolean"
227
+ type: "boolean",
228
+ default: false
221
229
  },
222
230
  afterColon: {
223
- type: "boolean"
231
+ type: "boolean",
232
+ default: true
224
233
  }
225
234
  },
226
235
  additionalProperties: false
@@ -228,13 +237,16 @@ module.exports = {
228
237
  ]
229
238
  },
230
239
  mode: {
231
- enum: ["strict", "minimum"]
240
+ enum: ["strict", "minimum"],
241
+ default: "strict"
232
242
  },
233
243
  beforeColon: {
234
- type: "boolean"
244
+ type: "boolean",
245
+ default: false
235
246
  },
236
247
  afterColon: {
237
- type: "boolean"
248
+ type: "boolean",
249
+ default: true
238
250
  }
239
251
  },
240
252
  additionalProperties: false
@@ -249,13 +261,16 @@ module.exports = {
249
261
  type: "object",
250
262
  properties: {
251
263
  mode: {
252
- enum: ["strict", "minimum"]
264
+ enum: ["strict", "minimum"],
265
+ default: "strict"
253
266
  },
254
267
  beforeColon: {
255
- type: "boolean"
268
+ type: "boolean",
269
+ default: false
256
270
  },
257
271
  afterColon: {
258
- type: "boolean"
272
+ type: "boolean",
273
+ default: true
259
274
  }
260
275
  },
261
276
  additionalProperties: false
@@ -264,13 +279,16 @@ module.exports = {
264
279
  type: "object",
265
280
  properties: {
266
281
  mode: {
267
- enum: ["strict", "minimum"]
282
+ enum: ["strict", "minimum"],
283
+ default: "strict"
268
284
  },
269
285
  beforeColon: {
270
- type: "boolean"
286
+ type: "boolean",
287
+ default: false
271
288
  },
272
289
  afterColon: {
273
- type: "boolean"
290
+ type: "boolean",
291
+ default: true
274
292
  }
275
293
  },
276
294
  additionalProperties: false
@@ -279,16 +297,20 @@ module.exports = {
279
297
  type: "object",
280
298
  properties: {
281
299
  mode: {
282
- enum: ["strict", "minimum"]
300
+ enum: ["strict", "minimum"],
301
+ default: "strict"
283
302
  },
284
303
  on: {
285
- enum: ["colon", "value"]
304
+ enum: ["colon", "value"],
305
+ default: "colon"
286
306
  },
287
307
  beforeColon: {
288
- type: "boolean"
308
+ type: "boolean",
309
+ default: false
289
310
  },
290
311
  afterColon: {
291
- type: "boolean"
312
+ type: "boolean",
313
+ default: true
292
314
  }
293
315
  },
294
316
  additionalProperties: false
@@ -297,7 +319,13 @@ module.exports = {
297
319
  additionalProperties: false
298
320
  }
299
321
  ]
300
- }]
322
+ }],
323
+ messages: {
324
+ extraKey: "Extra space after {{computed}}key '{{key}}'.",
325
+ extraValue: "Extra space before value for {{computed}}key '{{key}}'.",
326
+ missingKey: "Missing space after {{computed}}key '{{key}}'.",
327
+ missingValue: "Missing space before value for {{computed}}key '{{key}}'."
328
+ }
301
329
  },
302
330
 
303
331
  create(context) {
@@ -460,12 +488,19 @@ module.exports = {
460
488
  }
461
489
  }
462
490
 
491
+ let messageId = "";
492
+
493
+ if (isExtra) {
494
+ messageId = side === "key" ? "extraKey" : "extraValue";
495
+ } else {
496
+ messageId = side === "key" ? "missingKey" : "missingValue";
497
+ }
498
+
463
499
  context.report({
464
500
  node: property[side],
465
501
  loc: locStart,
466
- message: messages[side],
502
+ messageId,
467
503
  data: {
468
- error: isExtra ? "Extra" : "Missing",
469
504
  computed: property.computed ? "computed " : "",
470
505
  key: getKey(property)
471
506
  },
@@ -80,16 +80,16 @@ module.exports = {
80
80
  {
81
81
  type: "object",
82
82
  properties: {
83
- before: { type: "boolean" },
84
- after: { type: "boolean" },
83
+ before: { type: "boolean", default: true },
84
+ after: { type: "boolean", default: true },
85
85
  overrides: {
86
86
  type: "object",
87
87
  properties: KEYS.reduce((retv, key) => {
88
88
  retv[key] = {
89
89
  type: "object",
90
90
  properties: {
91
- before: { type: "boolean" },
92
- after: { type: "boolean" }
91
+ before: { type: "boolean", default: true },
92
+ after: { type: "boolean", default: true }
93
93
  },
94
94
  additionalProperties: false
95
95
  };
@@ -100,7 +100,13 @@ module.exports = {
100
100
  },
101
101
  additionalProperties: false
102
102
  }
103
- ]
103
+ ],
104
+ messages: {
105
+ expectedBefore: "Expected space(s) before \"{{value}}\".",
106
+ expectedAfter: "Expected space(s) after \"{{value}}\".",
107
+ unexpectedBefore: "Unexpected space(s) before \"{{value}}\".",
108
+ unexpectedAfter: "Unexpected space(s) after \"{{value}}\"."
109
+ }
104
110
  },
105
111
 
106
112
  create(context) {
@@ -124,7 +130,7 @@ module.exports = {
124
130
  ) {
125
131
  context.report({
126
132
  loc: token.loc.start,
127
- message: "Expected space(s) before \"{{value}}\".",
133
+ messageId: "expectedBefore",
128
134
  data: token,
129
135
  fix(fixer) {
130
136
  return fixer.insertTextBefore(token, " ");
@@ -151,7 +157,7 @@ module.exports = {
151
157
  ) {
152
158
  context.report({
153
159
  loc: token.loc.start,
154
- message: "Unexpected space(s) before \"{{value}}\".",
160
+ messageId: "unexpectedBefore",
155
161
  data: token,
156
162
  fix(fixer) {
157
163
  return fixer.removeRange([prevToken.range[1], token.range[0]]);
@@ -178,7 +184,7 @@ module.exports = {
178
184
  ) {
179
185
  context.report({
180
186
  loc: token.loc.start,
181
- message: "Expected space(s) after \"{{value}}\".",
187
+ messageId: "expectedAfter",
182
188
  data: token,
183
189
  fix(fixer) {
184
190
  return fixer.insertTextAfter(token, " ");
@@ -205,7 +211,7 @@ module.exports = {
205
211
  ) {
206
212
  context.report({
207
213
  loc: token.loc.start,
208
- message: "Unexpected space(s) after \"{{value}}\".",
214
+ messageId: "unexpectedAfter",
209
215
  data: token,
210
216
  fix(fixer) {
211
217
  return fixer.removeRange([token.range[1], nextToken.range[0]]);
@@ -222,9 +228,9 @@ module.exports = {
222
228
  * Keys are keywords (there are for every keyword).
223
229
  * Values are instances of `{"before": function, "after": function}`.
224
230
  */
225
- function parseOptions(options) {
226
- const before = !options || options.before !== false;
227
- const after = !options || options.after !== false;
231
+ function parseOptions(options = {}) {
232
+ const before = options.before !== false;
233
+ const after = options.after !== false;
228
234
  const defaultValue = {
229
235
  before: before ? expectSpaceBefore : unexpectSpaceBefore,
230
236
  after: after ? expectSpaceAfter : unexpectSpaceAfter