eslint-plugin-jsdoc 55.3.0 → 55.4.0

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.
@@ -20,10 +20,13 @@ var _default = exports.default = (0, _iterateJsdoc.default)(({
20
20
  genericDot = false,
21
21
  objectFieldIndent = '',
22
22
  objectFieldQuote = null,
23
- objectFieldSeparator = null,
23
+ objectFieldSeparator = 'comma',
24
+ objectFieldSeparatorTrailingPunctuation = false,
24
25
  propertyQuotes = null,
25
26
  separatorForSingleObjectField = false,
26
- stringQuotes = 'single'
27
+ stringQuotes = 'single',
28
+ typeBracketSpacing = '',
29
+ unionSpacing = ' '
27
30
  } = context.options[0] || {};
28
31
  const {
29
32
  mode
@@ -49,7 +52,7 @@ var _default = exports.default = (0, _iterateJsdoc.default)(({
49
52
  }) => {
50
53
  return tokens.name || tokens.description;
51
54
  });
52
- const nameAndDesc = tag.source.slice(beginNameOrDescIdx);
55
+ const nameAndDesc = beginNameOrDescIdx === -1 ? null : tag.source.slice(beginNameOrDescIdx);
53
56
  const initialNumber = tag.source[0].number;
54
57
  const src = [
55
58
  // Get inevitably present tag from first `tag.source`
@@ -64,7 +67,7 @@ var _default = exports.default = (0, _iterateJsdoc.default)(({
64
67
  postName: '',
65
68
  postType: ''
66
69
  } : {}),
67
- type: '{' + firstTypeLine + (!typeLines.length && lastTypeLine === undefined ? '}' : '')
70
+ type: '{' + typeBracketSpacing + firstTypeLine + (!typeLines.length && lastTypeLine === undefined ? typeBracketSpacing + '}' : '')
68
71
  }
69
72
  },
70
73
  // Get any intervening type lines
@@ -91,13 +94,13 @@ var _default = exports.default = (0, _iterateJsdoc.default)(({
91
94
  // Merge any final type line and name and description
92
95
  if (
93
96
  // Name and description may be already included if present with the tag
94
- beginNameOrDescIdx > 0) {
97
+ nameAndDesc && beginNameOrDescIdx > 0) {
95
98
  src.push({
96
99
  number: src.length + 1,
97
100
  source: '',
98
101
  tokens: {
99
102
  ...nameAndDesc[0].tokens,
100
- type: lastTypeLine + '}'
103
+ type: lastTypeLine + typeBracketSpacing + '}'
101
104
  }
102
105
  });
103
106
  if (
@@ -114,7 +117,7 @@ var _default = exports.default = (0, _iterateJsdoc.default)(({
114
117
  };
115
118
  }));
116
119
  }
117
- } else {
120
+ } else if (nameAndDesc) {
118
121
  if (lastTypeLine) {
119
122
  src.push({
120
123
  number: src.length + 1,
@@ -125,7 +128,7 @@ var _default = exports.default = (0, _iterateJsdoc.default)(({
125
128
  postTag: '',
126
129
  start: indent + ' ',
127
130
  tag: '',
128
- type: lastTypeLine + '}'
131
+ type: lastTypeLine + typeBracketSpacing + '}'
129
132
  }
130
133
  });
131
134
  }
@@ -154,28 +157,44 @@ var _default = exports.default = (0, _iterateJsdoc.default)(({
154
157
  }) => {
155
158
  return tg;
156
159
  });
160
+ const initialEndSource = jsdoc.source.find(({
161
+ tokens: {
162
+ end
163
+ }
164
+ }) => {
165
+ return end;
166
+ });
157
167
  jsdoc.source = [...jsdoc.source.slice(0, firstTagIdx), ...jsdoc.tags.flatMap(({
158
168
  source
159
169
  }) => {
160
170
  return source;
161
171
  })];
172
+ if (initialEndSource && !jsdoc.source.at(-1)?.tokens?.end) {
173
+ jsdoc.source.push(initialEndSource);
174
+ }
162
175
  };
163
176
 
164
177
  /** @type {string[]} */
165
178
  const errorMessages = [];
166
- let needToReport = false;
179
+ if (typeBracketSpacing && (!tag.type.startsWith(typeBracketSpacing) || !tag.type.endsWith(typeBracketSpacing))) {
180
+ errorMessages.push(`Must have initial and final "${typeBracketSpacing}" spacing`);
181
+ } else if (!typeBracketSpacing && (/^\s/v.test(tag.type) || /\s$/v.test(tag.type))) {
182
+ errorMessages.push('Must have no initial spacing');
183
+ }
184
+
185
+ // eslint-disable-next-line complexity -- Todo
167
186
  (0, _jsdoccomment.traverse)(parsedType, nde => {
168
- let typeFound = true;
169
187
  let errorMessage = '';
170
- const initialType = (0, _jsdoccomment.stringify)(/** @type {import('jsdoc-type-pratt-parser').RootResult} */nde);
171
188
  switch (nde.type) {
172
189
  case 'JsdocTypeGeneric':
173
190
  {
174
191
  const typeNode = /** @type {import('jsdoc-type-pratt-parser').GenericResult} */nde;
175
192
  if ('value' in typeNode.left && typeNode.left.value === 'Array') {
176
- typeNode.meta.brackets = arrayBrackets;
177
- errorMessage = `Array bracket style should be ${arrayBrackets}`;
178
- } else {
193
+ if (typeNode.meta.brackets !== arrayBrackets) {
194
+ typeNode.meta.brackets = arrayBrackets;
195
+ errorMessage = `Array bracket style should be ${arrayBrackets}`;
196
+ }
197
+ } else if (typeNode.meta.dot !== genericDot) {
179
198
  typeNode.meta.dot = genericDot;
180
199
  errorMessage = `Dot usage should be ${genericDot}`;
181
200
  }
@@ -184,62 +203,78 @@ var _default = exports.default = (0, _iterateJsdoc.default)(({
184
203
  case 'JsdocTypeObject':
185
204
  {
186
205
  const typeNode = /** @type {import('jsdoc-type-pratt-parser').ObjectResult} */nde;
187
- typeNode.meta.separator = objectFieldSeparator ?? undefined;
188
- typeNode.meta.separatorForSingleObjectField = separatorForSingleObjectField;
189
- typeNode.meta.propertyIndent = objectFieldIndent;
190
- errorMessage = `Inconsistent ${objectFieldSeparator} usage`;
206
+ if (/* c8 ignore next -- Guard */
207
+ (typeNode.meta.separator ?? 'comma') !== objectFieldSeparator || (typeNode.meta.separatorForSingleObjectField ?? false) !== separatorForSingleObjectField || (typeNode.meta.propertyIndent ?? '') !== objectFieldIndent || (typeNode.meta.trailingPunctuation ?? false) !== objectFieldSeparatorTrailingPunctuation) {
208
+ typeNode.meta.separator = objectFieldSeparator;
209
+ typeNode.meta.separatorForSingleObjectField = separatorForSingleObjectField;
210
+ typeNode.meta.propertyIndent = objectFieldIndent;
211
+ typeNode.meta.trailingPunctuation = objectFieldSeparatorTrailingPunctuation;
212
+ errorMessage = `Inconsistent ${objectFieldSeparator} separator usage`;
213
+ }
191
214
  break;
192
215
  }
193
216
  case 'JsdocTypeObjectField':
194
217
  {
195
218
  const typeNode = /** @type {import('jsdoc-type-pratt-parser').ObjectFieldResult} */nde;
196
- if (objectFieldQuote || typeof typeNode.key === 'string' && !/\s/v.test(typeNode.key)) {
219
+ if ((objectFieldQuote || typeof typeNode.key === 'string' && !/\s/v.test(typeNode.key)) && typeNode.meta.quote !== (objectFieldQuote ?? undefined)) {
197
220
  typeNode.meta.quote = objectFieldQuote ?? undefined;
198
221
  errorMessage = `Inconsistent object field quotes ${objectFieldQuote}`;
199
- } else {
200
- typeFound = false;
201
222
  }
202
223
  break;
203
224
  }
204
225
  case 'JsdocTypeProperty':
205
226
  {
206
227
  const typeNode = /** @type {import('jsdoc-type-pratt-parser').PropertyResult} */nde;
207
- if (propertyQuotes || typeof typeNode.value === 'string' && !/\s/v.test(typeNode.value)) {
228
+ if ((propertyQuotes || typeof typeNode.value === 'string' && !/\s/v.test(typeNode.value)) && typeNode.meta.quote !== (propertyQuotes ?? undefined)) {
208
229
  typeNode.meta.quote = propertyQuotes ?? undefined;
209
230
  errorMessage = `Inconsistent ${propertyQuotes} property quotes usage`;
210
- } else {
211
- typeFound = false;
212
231
  }
213
232
  break;
214
233
  }
215
234
  case 'JsdocTypeStringValue':
216
235
  {
217
236
  const typeNode = /** @type {import('jsdoc-type-pratt-parser').StringValueResult} */nde;
218
- typeNode.meta.quote = stringQuotes;
219
- errorMessage = `Inconsistent ${stringQuotes} string quotes usage`;
237
+ if (typeNode.meta.quote !== stringQuotes) {
238
+ typeNode.meta.quote = stringQuotes;
239
+ errorMessage = `Inconsistent ${stringQuotes} string quotes usage`;
240
+ }
241
+ break;
242
+ }
243
+ case 'JsdocTypeUnion':
244
+ {
245
+ const typeNode = /** @type {import('jsdoc-type-pratt-parser').UnionResult} */nde;
246
+ /* c8 ignore next -- Guard */
247
+ if ((typeNode.meta?.spacing ?? ' ') !== unionSpacing) {
248
+ typeNode.meta = {
249
+ spacing: unionSpacing
250
+ };
251
+ errorMessage = `Inconsistent "${unionSpacing}" union spacing usage`;
252
+ }
220
253
  break;
221
254
  }
222
255
  default:
223
- typeFound = false;
224
256
  break;
225
257
  }
226
- if (typeFound) {
227
- const convertedType = (0, _jsdoccomment.stringify)(/** @type {import('jsdoc-type-pratt-parser').RootResult} */nde);
228
- if (initialType !== convertedType) {
229
- needToReport = true;
230
- errorMessages.push(errorMessage);
231
- }
258
+ if (errorMessage) {
259
+ errorMessages.push(errorMessage);
232
260
  }
233
261
  });
234
- if (needToReport) {
262
+ const differentResult = tag.type !== typeBracketSpacing + (0, _jsdoccomment.stringify)(parsedType) + typeBracketSpacing;
263
+ if (errorMessages.length && differentResult) {
235
264
  for (const errorMessage of errorMessages) {
236
- utils.reportJSDoc(errorMessage, tag, enableFixer ? fix : null, true);
265
+ utils.reportJSDoc(errorMessage, tag, enableFixer ? fix : null);
237
266
  }
267
+ // Stringification may have been equal previously (and thus no error reported)
268
+ // because the stringification doesn't preserve everything
269
+ } else if (differentResult) {
270
+ utils.reportJSDoc('There was an error with type formatting', tag, enableFixer ? fix : null);
238
271
  }
239
272
  };
240
- const tags = utils.getPresentTags(['param', 'returns']);
273
+ const tags = utils.getPresentTags(['param', 'returns', 'type', 'typedef']);
241
274
  for (const tag of tags) {
242
- checkTypeFormats(tag);
275
+ if (tag.type) {
276
+ checkTypeFormats(tag);
277
+ }
243
278
  }
244
279
  }, {
245
280
  iterateAllJsdocs: true,
@@ -268,7 +303,10 @@ var _default = exports.default = (0, _iterateJsdoc.default)(({
268
303
  enum: ['double', 'single', null]
269
304
  },
270
305
  objectFieldSeparator: {
271
- enum: ['comma', 'comma-and-linebreak', 'linebreak', 'semicolon', 'semicolon-and-linebreak', null]
306
+ enum: ['comma', 'comma-and-linebreak', 'linebreak', 'semicolon', 'semicolon-and-linebreak']
307
+ },
308
+ objectFieldSeparatorTrailingPunctuation: {
309
+ type: 'boolean'
272
310
  },
273
311
  propertyQuotes: {
274
312
  enum: ['double', 'single', null]
@@ -278,6 +316,12 @@ var _default = exports.default = (0, _iterateJsdoc.default)(({
278
316
  },
279
317
  stringQuotes: {
280
318
  enum: ['double', 'single']
319
+ },
320
+ typeBracketSpacing: {
321
+ type: 'string'
322
+ },
323
+ unionSpacing: {
324
+ type: 'string'
281
325
  }
282
326
  },
283
327
  type: 'object'
@@ -1 +1 @@
1
- {"version":3,"file":"typeFormatting.cjs","names":["_iterateJsdoc","_interopRequireDefault","require","_jsdoccomment","e","__esModule","default","_default","exports","iterateJsdoc","context","indent","jsdoc","settings","utils","arrayBrackets","enableFixer","genericDot","objectFieldIndent","objectFieldQuote","objectFieldSeparator","propertyQuotes","separatorForSingleObjectField","stringQuotes","options","mode","checkTypeFormats","tag","potentialType","type","parsedType","tryParseType","parseType","fix","typeLines","stringify","split","firstTypeLine","shift","lastTypeLine","pop","beginNameOrDescIdx","source","findIndex","tokens","name","description","nameAndDesc","slice","initialNumber","number","src","length","end","postName","postType","undefined","map","typeLine","idx","delimiter","postTag","start","push","firstTagIdx","tg","tags","flatMap","errorMessages","needToReport","traverse","nde","typeFound","errorMessage","initialType","typeNode","left","value","meta","brackets","dot","separator","propertyIndent","key","test","quote","convertedType","reportJSDoc","getPresentTags","iterateAllJsdocs","docs","url","fixable","schema","additionalProperties","properties","enum","module"],"sources":["../../src/rules/typeFormatting.js"],"sourcesContent":["import iterateJsdoc from '../iterateJsdoc.js';\nimport {\n parse as parseType,\n stringify,\n traverse,\n tryParse as tryParseType,\n} from '@es-joy/jsdoccomment';\n\nexport default iterateJsdoc(({\n context,\n indent,\n jsdoc,\n settings,\n utils,\n}) => {\n const {\n arrayBrackets = 'square',\n enableFixer = true,\n genericDot = false,\n objectFieldIndent = '',\n objectFieldQuote = null,\n objectFieldSeparator = null,\n propertyQuotes = null,\n separatorForSingleObjectField = false,\n stringQuotes = 'single',\n } = context.options[0] || {};\n\n const {\n mode,\n } = settings;\n\n /**\n * @param {import('@es-joy/jsdoccomment').JsdocTagWithInline} tag\n */\n const checkTypeFormats = (tag) => {\n const potentialType = tag.type;\n let parsedType;\n try {\n parsedType = mode === 'permissive' ?\n tryParseType(/** @type {string} */ (potentialType)) :\n parseType(/** @type {string} */ (potentialType), mode);\n } catch {\n return;\n }\n\n const fix = () => {\n const typeLines = stringify(parsedType).split('\\n');\n const firstTypeLine = typeLines.shift();\n const lastTypeLine = typeLines.pop();\n\n const beginNameOrDescIdx = tag.source.findIndex(({\n tokens,\n }) => {\n return tokens.name || tokens.description;\n });\n\n const nameAndDesc = tag.source.slice(beginNameOrDescIdx);\n const initialNumber = tag.source[0].number;\n const src = [\n // Get inevitably present tag from first `tag.source`\n {\n number: initialNumber,\n source: '',\n tokens: {\n ...tag.source[0].tokens,\n ...(typeLines.length || lastTypeLine ? {\n end: '',\n name: '',\n postName: '',\n postType: '',\n } : {}),\n type: '{' + firstTypeLine + (!typeLines.length && lastTypeLine === undefined ? '}' : ''),\n },\n },\n // Get any intervening type lines\n ...(typeLines.length ? typeLines.map((typeLine, idx) => {\n return {\n number: initialNumber + idx + 1,\n source: '',\n tokens: {\n // Grab any delimiter info from first item\n ...tag.source[0].tokens,\n delimiter: tag.source[0].tokens.delimiter === '/**' ? '*' : tag.source[0].tokens.delimiter,\n end: '',\n name: '',\n postName: '',\n postTag: '',\n postType: '',\n start: indent + ' ',\n tag: '',\n type: typeLine,\n },\n };\n }) : []),\n ];\n\n // Merge any final type line and name and description\n if (\n // Name and description may be already included if present with the tag\n beginNameOrDescIdx > 0\n ) {\n src.push({\n number: src.length + 1,\n source: '',\n tokens: {\n ...nameAndDesc[0].tokens,\n type: lastTypeLine + '}',\n },\n });\n\n if (\n // Get any remaining description lines\n nameAndDesc.length > 1\n ) {\n src.push(\n ...nameAndDesc.slice(1).map(({\n source,\n tokens,\n }, idx) => {\n return {\n number: src.length + idx + 2,\n source,\n tokens,\n };\n }),\n );\n }\n } else {\n if (lastTypeLine) {\n src.push({\n number: src.length + 1,\n source: '',\n tokens: {\n ...nameAndDesc[0].tokens,\n delimiter: nameAndDesc[0].tokens.delimiter === '/**' ? '*' : nameAndDesc[0].tokens.delimiter,\n postTag: '',\n start: indent + ' ',\n tag: '',\n type: lastTypeLine + '}',\n },\n });\n }\n\n if (\n // Get any remaining description lines\n nameAndDesc.length > 1\n ) {\n src.push(\n ...nameAndDesc.slice(1).map(({\n source,\n tokens,\n }, idx) => {\n return {\n number: src.length + idx + 2,\n source,\n tokens,\n };\n }),\n );\n }\n }\n\n tag.source = src;\n\n // Properly rewire `jsdoc.source`\n const firstTagIdx = jsdoc.source.findIndex(({\n tokens: {\n tag: tg,\n },\n }) => {\n return tg;\n });\n\n jsdoc.source = [\n ...jsdoc.source.slice(0, firstTagIdx),\n ...jsdoc.tags.flatMap(({\n source,\n }) => {\n return source;\n }),\n ];\n };\n\n /** @type {string[]} */\n const errorMessages = [];\n let needToReport = false;\n traverse(parsedType, (nde) => {\n let typeFound = true;\n let errorMessage = '';\n const initialType = stringify(\n /** @type {import('jsdoc-type-pratt-parser').RootResult} */ (nde),\n );\n switch (nde.type) {\n case 'JsdocTypeGeneric': {\n const typeNode = /** @type {import('jsdoc-type-pratt-parser').GenericResult} */ (nde);\n if ('value' in typeNode.left && typeNode.left.value === 'Array') {\n typeNode.meta.brackets = arrayBrackets;\n errorMessage = `Array bracket style should be ${arrayBrackets}`;\n } else {\n typeNode.meta.dot = genericDot;\n errorMessage = `Dot usage should be ${genericDot}`;\n }\n\n break;\n }\n\n case 'JsdocTypeObject': {\n const typeNode = /** @type {import('jsdoc-type-pratt-parser').ObjectResult} */ (nde);\n typeNode.meta.separator = objectFieldSeparator ?? undefined;\n typeNode.meta.separatorForSingleObjectField = separatorForSingleObjectField;\n typeNode.meta.propertyIndent = objectFieldIndent;\n errorMessage = `Inconsistent ${objectFieldSeparator} usage`;\n break;\n }\n\n case 'JsdocTypeObjectField': {\n const typeNode = /** @type {import('jsdoc-type-pratt-parser').ObjectFieldResult} */ (nde);\n if (objectFieldQuote ||\n (typeof typeNode.key === 'string' && !(/\\s/v).test(typeNode.key))\n ) {\n typeNode.meta.quote = objectFieldQuote ?? undefined;\n errorMessage = `Inconsistent object field quotes ${objectFieldQuote}`;\n } else {\n typeFound = false;\n }\n\n break;\n }\n\n case 'JsdocTypeProperty': {\n const typeNode = /** @type {import('jsdoc-type-pratt-parser').PropertyResult} */ (nde);\n\n if (propertyQuotes ||\n (typeof typeNode.value === 'string' && !(/\\s/v).test(typeNode.value))\n ) {\n typeNode.meta.quote = propertyQuotes ?? undefined;\n errorMessage = `Inconsistent ${propertyQuotes} property quotes usage`;\n } else {\n typeFound = false;\n }\n\n break;\n }\n\n case 'JsdocTypeStringValue': {\n const typeNode = /** @type {import('jsdoc-type-pratt-parser').StringValueResult} */ (nde);\n typeNode.meta.quote = stringQuotes;\n errorMessage = `Inconsistent ${stringQuotes} string quotes usage`;\n break;\n }\n\n default:\n typeFound = false;\n break;\n }\n\n if (typeFound) {\n const convertedType = stringify(/** @type {import('jsdoc-type-pratt-parser').RootResult} */ (nde));\n if (initialType !== convertedType) {\n needToReport = true;\n errorMessages.push(errorMessage);\n }\n }\n });\n\n if (needToReport) {\n for (const errorMessage of errorMessages) {\n utils.reportJSDoc(\n errorMessage, tag, enableFixer ? fix : null, true,\n );\n }\n }\n };\n\n const tags = utils.getPresentTags([\n 'param',\n 'returns',\n ]);\n for (const tag of tags) {\n checkTypeFormats(tag);\n }\n}, {\n iterateAllJsdocs: true,\n meta: {\n docs: {\n description: 'Formats JSDoc type values.',\n url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/type-formatting.md#repos-sticky-header',\n },\n fixable: 'code',\n schema: [\n {\n additionalProperties: false,\n properties: {\n arrayBrackets: {\n enum: [\n 'angle',\n 'square',\n ],\n },\n enableFixer: {\n type: 'boolean',\n },\n genericDot: {\n type: 'boolean',\n },\n objectFieldIndent: {\n type: 'string',\n },\n objectFieldQuote: {\n enum: [\n 'double',\n 'single',\n null,\n ],\n },\n objectFieldSeparator: {\n enum: [\n 'comma',\n 'comma-and-linebreak',\n 'linebreak',\n 'semicolon',\n 'semicolon-and-linebreak',\n null,\n ],\n },\n propertyQuotes: {\n enum: [\n 'double',\n 'single',\n null,\n ],\n },\n separatorForSingleObjectField: {\n type: 'boolean',\n },\n stringQuotes: {\n enum: [\n 'double',\n 'single',\n ],\n },\n },\n type: 'object',\n },\n ],\n type: 'suggestion',\n },\n});\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"typeFormatting.cjs","names":["_iterateJsdoc","_interopRequireDefault","require","_jsdoccomment","e","__esModule","default","_default","exports","iterateJsdoc","context","indent","jsdoc","settings","utils","arrayBrackets","enableFixer","genericDot","objectFieldIndent","objectFieldQuote","objectFieldSeparator","objectFieldSeparatorTrailingPunctuation","propertyQuotes","separatorForSingleObjectField","stringQuotes","typeBracketSpacing","unionSpacing","options","mode","checkTypeFormats","tag","potentialType","type","parsedType","tryParseType","parseType","fix","typeLines","stringify","split","firstTypeLine","shift","lastTypeLine","pop","beginNameOrDescIdx","source","findIndex","tokens","name","description","nameAndDesc","slice","initialNumber","number","src","length","end","postName","postType","undefined","map","typeLine","idx","delimiter","postTag","start","push","firstTagIdx","tg","initialEndSource","find","tags","flatMap","at","errorMessages","startsWith","endsWith","test","traverse","nde","errorMessage","typeNode","left","value","meta","brackets","dot","separator","propertyIndent","trailingPunctuation","key","quote","spacing","differentResult","reportJSDoc","getPresentTags","iterateAllJsdocs","docs","url","fixable","schema","additionalProperties","properties","enum","module"],"sources":["../../src/rules/typeFormatting.js"],"sourcesContent":["import iterateJsdoc from '../iterateJsdoc.js';\nimport {\n parse as parseType,\n stringify,\n traverse,\n tryParse as tryParseType,\n} from '@es-joy/jsdoccomment';\n\nexport default iterateJsdoc(({\n context,\n indent,\n jsdoc,\n settings,\n utils,\n}) => {\n const {\n arrayBrackets = 'square',\n enableFixer = true,\n genericDot = false,\n objectFieldIndent = '',\n objectFieldQuote = null,\n objectFieldSeparator = 'comma',\n objectFieldSeparatorTrailingPunctuation = false,\n propertyQuotes = null,\n separatorForSingleObjectField = false,\n stringQuotes = 'single',\n typeBracketSpacing = '',\n unionSpacing = ' ',\n } = context.options[0] || {};\n\n const {\n mode,\n } = settings;\n\n /**\n * @param {import('@es-joy/jsdoccomment').JsdocTagWithInline} tag\n */\n const checkTypeFormats = (tag) => {\n const potentialType = tag.type;\n let parsedType;\n try {\n parsedType = mode === 'permissive' ?\n tryParseType(/** @type {string} */ (potentialType)) :\n parseType(/** @type {string} */ (potentialType), mode);\n } catch {\n return;\n }\n\n const fix = () => {\n const typeLines = stringify(parsedType).split('\\n');\n const firstTypeLine = typeLines.shift();\n const lastTypeLine = typeLines.pop();\n\n const beginNameOrDescIdx = tag.source.findIndex(({\n tokens,\n }) => {\n return tokens.name || tokens.description;\n });\n\n const nameAndDesc = beginNameOrDescIdx === -1 ?\n null :\n tag.source.slice(beginNameOrDescIdx);\n\n const initialNumber = tag.source[0].number;\n const src = [\n // Get inevitably present tag from first `tag.source`\n {\n number: initialNumber,\n source: '',\n tokens: {\n ...tag.source[0].tokens,\n ...(typeLines.length || lastTypeLine ? {\n end: '',\n name: '',\n postName: '',\n postType: '',\n } : {}),\n type: '{' + typeBracketSpacing + firstTypeLine + (!typeLines.length && lastTypeLine === undefined ? typeBracketSpacing + '}' : ''),\n },\n },\n // Get any intervening type lines\n ...(typeLines.length ? typeLines.map((typeLine, idx) => {\n return {\n number: initialNumber + idx + 1,\n source: '',\n tokens: {\n // Grab any delimiter info from first item\n ...tag.source[0].tokens,\n delimiter: tag.source[0].tokens.delimiter === '/**' ? '*' : tag.source[0].tokens.delimiter,\n end: '',\n name: '',\n postName: '',\n postTag: '',\n postType: '',\n start: indent + ' ',\n tag: '',\n type: typeLine,\n },\n };\n }) : []),\n ];\n\n // Merge any final type line and name and description\n if (\n // Name and description may be already included if present with the tag\n nameAndDesc && beginNameOrDescIdx > 0\n ) {\n src.push({\n number: src.length + 1,\n source: '',\n tokens: {\n ...nameAndDesc[0].tokens,\n type: lastTypeLine + typeBracketSpacing + '}',\n },\n });\n\n if (\n // Get any remaining description lines\n nameAndDesc.length > 1\n ) {\n src.push(\n ...nameAndDesc.slice(1).map(({\n source,\n tokens,\n }, idx) => {\n return {\n number: src.length + idx + 2,\n source,\n tokens,\n };\n }),\n );\n }\n } else if (nameAndDesc) {\n if (lastTypeLine) {\n src.push({\n number: src.length + 1,\n source: '',\n tokens: {\n ...nameAndDesc[0].tokens,\n delimiter: nameAndDesc[0].tokens.delimiter === '/**' ? '*' : nameAndDesc[0].tokens.delimiter,\n postTag: '',\n start: indent + ' ',\n tag: '',\n type: lastTypeLine + typeBracketSpacing + '}',\n },\n });\n }\n\n if (\n // Get any remaining description lines\n nameAndDesc.length > 1\n ) {\n src.push(\n ...nameAndDesc.slice(1).map(({\n source,\n tokens,\n }, idx) => {\n return {\n number: src.length + idx + 2,\n source,\n tokens,\n };\n }),\n );\n }\n }\n\n tag.source = src;\n\n // Properly rewire `jsdoc.source`\n const firstTagIdx = jsdoc.source.findIndex(({\n tokens: {\n tag: tg,\n },\n }) => {\n return tg;\n });\n\n const initialEndSource = jsdoc.source.find(({\n tokens: {\n end,\n },\n }) => {\n return end;\n });\n\n jsdoc.source = [\n ...jsdoc.source.slice(0, firstTagIdx),\n ...jsdoc.tags.flatMap(({\n source,\n }) => {\n return source;\n }),\n ];\n\n if (initialEndSource && !jsdoc.source.at(-1)?.tokens?.end) {\n jsdoc.source.push(initialEndSource);\n }\n };\n\n /** @type {string[]} */\n const errorMessages = [];\n\n if (typeBracketSpacing && (!tag.type.startsWith(typeBracketSpacing) || !tag.type.endsWith(typeBracketSpacing))) {\n errorMessages.push(`Must have initial and final \"${typeBracketSpacing}\" spacing`);\n } else if (!typeBracketSpacing && ((/^\\s/v).test(tag.type) || (/\\s$/v).test(tag.type))) {\n errorMessages.push('Must have no initial spacing');\n }\n\n // eslint-disable-next-line complexity -- Todo\n traverse(parsedType, (nde) => {\n let errorMessage = '';\n\n switch (nde.type) {\n case 'JsdocTypeGeneric': {\n const typeNode = /** @type {import('jsdoc-type-pratt-parser').GenericResult} */ (nde);\n if ('value' in typeNode.left && typeNode.left.value === 'Array') {\n if (typeNode.meta.brackets !== arrayBrackets) {\n typeNode.meta.brackets = arrayBrackets;\n errorMessage = `Array bracket style should be ${arrayBrackets}`;\n }\n } else if (typeNode.meta.dot !== genericDot) {\n typeNode.meta.dot = genericDot;\n errorMessage = `Dot usage should be ${genericDot}`;\n }\n\n break;\n }\n\n case 'JsdocTypeObject': {\n const typeNode = /** @type {import('jsdoc-type-pratt-parser').ObjectResult} */ (nde);\n if (\n /* c8 ignore next -- Guard */\n (typeNode.meta.separator ?? 'comma') !== objectFieldSeparator ||\n (typeNode.meta.separatorForSingleObjectField ?? false) !== separatorForSingleObjectField ||\n (typeNode.meta.propertyIndent ?? '') !== objectFieldIndent ||\n (typeNode.meta.trailingPunctuation ?? false) !== objectFieldSeparatorTrailingPunctuation\n ) {\n typeNode.meta.separator = objectFieldSeparator;\n typeNode.meta.separatorForSingleObjectField = separatorForSingleObjectField;\n typeNode.meta.propertyIndent = objectFieldIndent;\n typeNode.meta.trailingPunctuation = objectFieldSeparatorTrailingPunctuation;\n errorMessage = `Inconsistent ${objectFieldSeparator} separator usage`;\n }\n\n break;\n }\n\n case 'JsdocTypeObjectField': {\n const typeNode = /** @type {import('jsdoc-type-pratt-parser').ObjectFieldResult} */ (nde);\n if ((objectFieldQuote ||\n (typeof typeNode.key === 'string' && !(/\\s/v).test(typeNode.key))) &&\n typeNode.meta.quote !== (objectFieldQuote ?? undefined)\n ) {\n typeNode.meta.quote = objectFieldQuote ?? undefined;\n errorMessage = `Inconsistent object field quotes ${objectFieldQuote}`;\n }\n\n break;\n }\n\n case 'JsdocTypeProperty': {\n const typeNode = /** @type {import('jsdoc-type-pratt-parser').PropertyResult} */ (nde);\n\n if ((propertyQuotes ||\n (typeof typeNode.value === 'string' && !(/\\s/v).test(typeNode.value))) &&\n typeNode.meta.quote !== (propertyQuotes ?? undefined)\n ) {\n typeNode.meta.quote = propertyQuotes ?? undefined;\n errorMessage = `Inconsistent ${propertyQuotes} property quotes usage`;\n }\n\n break;\n }\n\n case 'JsdocTypeStringValue': {\n const typeNode = /** @type {import('jsdoc-type-pratt-parser').StringValueResult} */ (nde);\n if (typeNode.meta.quote !== stringQuotes) {\n typeNode.meta.quote = stringQuotes;\n errorMessage = `Inconsistent ${stringQuotes} string quotes usage`;\n }\n\n break;\n }\n\n case 'JsdocTypeUnion': {\n const typeNode = /** @type {import('jsdoc-type-pratt-parser').UnionResult} */ (nde);\n /* c8 ignore next -- Guard */\n if ((typeNode.meta?.spacing ?? ' ') !== unionSpacing) {\n typeNode.meta = {\n spacing: unionSpacing,\n };\n errorMessage = `Inconsistent \"${unionSpacing}\" union spacing usage`;\n }\n\n break;\n }\n\n default:\n break;\n }\n\n if (errorMessage) {\n errorMessages.push(errorMessage);\n }\n });\n\n const differentResult = tag.type !==\n typeBracketSpacing + stringify(parsedType) + typeBracketSpacing;\n\n if (errorMessages.length && differentResult) {\n for (const errorMessage of errorMessages) {\n utils.reportJSDoc(\n errorMessage, tag, enableFixer ? fix : null,\n );\n }\n // Stringification may have been equal previously (and thus no error reported)\n // because the stringification doesn't preserve everything\n } else if (differentResult) {\n utils.reportJSDoc(\n 'There was an error with type formatting', tag, enableFixer ? fix : null,\n );\n }\n };\n\n const tags = utils.getPresentTags([\n 'param',\n 'returns',\n 'type',\n 'typedef',\n ]);\n for (const tag of tags) {\n if (tag.type) {\n checkTypeFormats(tag);\n }\n }\n}, {\n iterateAllJsdocs: true,\n meta: {\n docs: {\n description: 'Formats JSDoc type values.',\n url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/type-formatting.md#repos-sticky-header',\n },\n fixable: 'code',\n schema: [\n {\n additionalProperties: false,\n properties: {\n arrayBrackets: {\n enum: [\n 'angle',\n 'square',\n ],\n },\n enableFixer: {\n type: 'boolean',\n },\n genericDot: {\n type: 'boolean',\n },\n objectFieldIndent: {\n type: 'string',\n },\n objectFieldQuote: {\n enum: [\n 'double',\n 'single',\n null,\n ],\n },\n objectFieldSeparator: {\n enum: [\n 'comma',\n 'comma-and-linebreak',\n 'linebreak',\n 'semicolon',\n 'semicolon-and-linebreak',\n ],\n },\n objectFieldSeparatorTrailingPunctuation: {\n type: 'boolean',\n },\n propertyQuotes: {\n enum: [\n 'double',\n 'single',\n null,\n ],\n },\n separatorForSingleObjectField: {\n type: 'boolean',\n },\n stringQuotes: {\n enum: [\n 'double',\n 'single',\n ],\n },\n typeBracketSpacing: {\n type: 'string',\n },\n unionSpacing: {\n type: 'string',\n },\n },\n type: 'object',\n },\n ],\n type: 'suggestion',\n },\n});\n"],"mappings":"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","ignoreList":[]}
package/dist/rules.d.ts CHANGED
@@ -765,16 +765,13 @@ export interface Rules {
765
765
  genericDot?: boolean;
766
766
  objectFieldIndent?: string;
767
767
  objectFieldQuote?: "double" | "single" | null;
768
- objectFieldSeparator?:
769
- | "comma"
770
- | "comma-and-linebreak"
771
- | "linebreak"
772
- | "semicolon"
773
- | "semicolon-and-linebreak"
774
- | null;
768
+ objectFieldSeparator?: "comma" | "comma-and-linebreak" | "linebreak" | "semicolon" | "semicolon-and-linebreak";
769
+ objectFieldSeparatorTrailingPunctuation?: boolean;
775
770
  propertyQuotes?: "double" | "single" | null;
776
771
  separatorForSingleObjectField?: boolean;
777
772
  stringQuotes?: "double" | "single";
773
+ typeBracketSpacing?: string;
774
+ unionSpacing?: string;
778
775
  }
779
776
  ];
780
777
 
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "http://gajus.com"
6
6
  },
7
7
  "dependencies": {
8
- "@es-joy/jsdoccomment": "~0.57.0",
8
+ "@es-joy/jsdoccomment": "~0.58.0",
9
9
  "are-docs-informative": "^0.0.2",
10
10
  "comment-parser": "1.4.1",
11
11
  "debug": "^4.4.1",
@@ -56,7 +56,7 @@
56
56
  "glob": "^11.0.3",
57
57
  "globals": "^16.4.0",
58
58
  "husky": "^9.1.7",
59
- "jsdoc-type-pratt-parser": "^5.2.0",
59
+ "jsdoc-type-pratt-parser": "^5.4.0",
60
60
  "json-schema": "^0.4.0",
61
61
  "json-schema-to-typescript": "^15.0.4",
62
62
  "lint-staged": "^16.1.6",
@@ -64,7 +64,7 @@
64
64
  "open-editor": "^5.1.0",
65
65
  "replace": "^1.2.2",
66
66
  "rimraf": "^6.0.1",
67
- "semantic-release": "^24.2.7",
67
+ "semantic-release": "^24.2.8",
68
68
  "typescript": "5.9.2",
69
69
  "typescript-eslint": "^8.43.0"
70
70
  },
@@ -160,5 +160,5 @@
160
160
  "test-cov": "TIMING=1 c8 --reporter text pnpm run test-no-cov",
161
161
  "test-index": "pnpm run test-no-cov test/rules/index.js"
162
162
  },
163
- "version": "55.3.0"
163
+ "version": "55.4.0"
164
164
  }
@@ -19,10 +19,13 @@ export default iterateJsdoc(({
19
19
  genericDot = false,
20
20
  objectFieldIndent = '',
21
21
  objectFieldQuote = null,
22
- objectFieldSeparator = null,
22
+ objectFieldSeparator = 'comma',
23
+ objectFieldSeparatorTrailingPunctuation = false,
23
24
  propertyQuotes = null,
24
25
  separatorForSingleObjectField = false,
25
26
  stringQuotes = 'single',
27
+ typeBracketSpacing = '',
28
+ unionSpacing = ' ',
26
29
  } = context.options[0] || {};
27
30
 
28
31
  const {
@@ -54,7 +57,10 @@ export default iterateJsdoc(({
54
57
  return tokens.name || tokens.description;
55
58
  });
56
59
 
57
- const nameAndDesc = tag.source.slice(beginNameOrDescIdx);
60
+ const nameAndDesc = beginNameOrDescIdx === -1 ?
61
+ null :
62
+ tag.source.slice(beginNameOrDescIdx);
63
+
58
64
  const initialNumber = tag.source[0].number;
59
65
  const src = [
60
66
  // Get inevitably present tag from first `tag.source`
@@ -69,7 +75,7 @@ export default iterateJsdoc(({
69
75
  postName: '',
70
76
  postType: '',
71
77
  } : {}),
72
- type: '{' + firstTypeLine + (!typeLines.length && lastTypeLine === undefined ? '}' : ''),
78
+ type: '{' + typeBracketSpacing + firstTypeLine + (!typeLines.length && lastTypeLine === undefined ? typeBracketSpacing + '}' : ''),
73
79
  },
74
80
  },
75
81
  // Get any intervening type lines
@@ -97,14 +103,14 @@ export default iterateJsdoc(({
97
103
  // Merge any final type line and name and description
98
104
  if (
99
105
  // Name and description may be already included if present with the tag
100
- beginNameOrDescIdx > 0
106
+ nameAndDesc && beginNameOrDescIdx > 0
101
107
  ) {
102
108
  src.push({
103
109
  number: src.length + 1,
104
110
  source: '',
105
111
  tokens: {
106
112
  ...nameAndDesc[0].tokens,
107
- type: lastTypeLine + '}',
113
+ type: lastTypeLine + typeBracketSpacing + '}',
108
114
  },
109
115
  });
110
116
 
@@ -125,7 +131,7 @@ export default iterateJsdoc(({
125
131
  }),
126
132
  );
127
133
  }
128
- } else {
134
+ } else if (nameAndDesc) {
129
135
  if (lastTypeLine) {
130
136
  src.push({
131
137
  number: src.length + 1,
@@ -136,7 +142,7 @@ export default iterateJsdoc(({
136
142
  postTag: '',
137
143
  start: indent + ' ',
138
144
  tag: '',
139
- type: lastTypeLine + '}',
145
+ type: lastTypeLine + typeBracketSpacing + '}',
140
146
  },
141
147
  });
142
148
  }
@@ -171,6 +177,14 @@ export default iterateJsdoc(({
171
177
  return tg;
172
178
  });
173
179
 
180
+ const initialEndSource = jsdoc.source.find(({
181
+ tokens: {
182
+ end,
183
+ },
184
+ }) => {
185
+ return end;
186
+ });
187
+
174
188
  jsdoc.source = [
175
189
  ...jsdoc.source.slice(0, firstTagIdx),
176
190
  ...jsdoc.tags.flatMap(({
@@ -179,24 +193,34 @@ export default iterateJsdoc(({
179
193
  return source;
180
194
  }),
181
195
  ];
196
+
197
+ if (initialEndSource && !jsdoc.source.at(-1)?.tokens?.end) {
198
+ jsdoc.source.push(initialEndSource);
199
+ }
182
200
  };
183
201
 
184
202
  /** @type {string[]} */
185
203
  const errorMessages = [];
186
- let needToReport = false;
204
+
205
+ if (typeBracketSpacing && (!tag.type.startsWith(typeBracketSpacing) || !tag.type.endsWith(typeBracketSpacing))) {
206
+ errorMessages.push(`Must have initial and final "${typeBracketSpacing}" spacing`);
207
+ } else if (!typeBracketSpacing && ((/^\s/v).test(tag.type) || (/\s$/v).test(tag.type))) {
208
+ errorMessages.push('Must have no initial spacing');
209
+ }
210
+
211
+ // eslint-disable-next-line complexity -- Todo
187
212
  traverse(parsedType, (nde) => {
188
- let typeFound = true;
189
213
  let errorMessage = '';
190
- const initialType = stringify(
191
- /** @type {import('jsdoc-type-pratt-parser').RootResult} */ (nde),
192
- );
214
+
193
215
  switch (nde.type) {
194
216
  case 'JsdocTypeGeneric': {
195
217
  const typeNode = /** @type {import('jsdoc-type-pratt-parser').GenericResult} */ (nde);
196
218
  if ('value' in typeNode.left && typeNode.left.value === 'Array') {
197
- typeNode.meta.brackets = arrayBrackets;
198
- errorMessage = `Array bracket style should be ${arrayBrackets}`;
199
- } else {
219
+ if (typeNode.meta.brackets !== arrayBrackets) {
220
+ typeNode.meta.brackets = arrayBrackets;
221
+ errorMessage = `Array bracket style should be ${arrayBrackets}`;
222
+ }
223
+ } else if (typeNode.meta.dot !== genericDot) {
200
224
  typeNode.meta.dot = genericDot;
201
225
  errorMessage = `Dot usage should be ${genericDot}`;
202
226
  }
@@ -206,22 +230,31 @@ export default iterateJsdoc(({
206
230
 
207
231
  case 'JsdocTypeObject': {
208
232
  const typeNode = /** @type {import('jsdoc-type-pratt-parser').ObjectResult} */ (nde);
209
- typeNode.meta.separator = objectFieldSeparator ?? undefined;
210
- typeNode.meta.separatorForSingleObjectField = separatorForSingleObjectField;
211
- typeNode.meta.propertyIndent = objectFieldIndent;
212
- errorMessage = `Inconsistent ${objectFieldSeparator} usage`;
233
+ if (
234
+ /* c8 ignore next -- Guard */
235
+ (typeNode.meta.separator ?? 'comma') !== objectFieldSeparator ||
236
+ (typeNode.meta.separatorForSingleObjectField ?? false) !== separatorForSingleObjectField ||
237
+ (typeNode.meta.propertyIndent ?? '') !== objectFieldIndent ||
238
+ (typeNode.meta.trailingPunctuation ?? false) !== objectFieldSeparatorTrailingPunctuation
239
+ ) {
240
+ typeNode.meta.separator = objectFieldSeparator;
241
+ typeNode.meta.separatorForSingleObjectField = separatorForSingleObjectField;
242
+ typeNode.meta.propertyIndent = objectFieldIndent;
243
+ typeNode.meta.trailingPunctuation = objectFieldSeparatorTrailingPunctuation;
244
+ errorMessage = `Inconsistent ${objectFieldSeparator} separator usage`;
245
+ }
246
+
213
247
  break;
214
248
  }
215
249
 
216
250
  case 'JsdocTypeObjectField': {
217
251
  const typeNode = /** @type {import('jsdoc-type-pratt-parser').ObjectFieldResult} */ (nde);
218
- if (objectFieldQuote ||
219
- (typeof typeNode.key === 'string' && !(/\s/v).test(typeNode.key))
252
+ if ((objectFieldQuote ||
253
+ (typeof typeNode.key === 'string' && !(/\s/v).test(typeNode.key))) &&
254
+ typeNode.meta.quote !== (objectFieldQuote ?? undefined)
220
255
  ) {
221
256
  typeNode.meta.quote = objectFieldQuote ?? undefined;
222
257
  errorMessage = `Inconsistent object field quotes ${objectFieldQuote}`;
223
- } else {
224
- typeFound = false;
225
258
  }
226
259
 
227
260
  break;
@@ -230,13 +263,12 @@ export default iterateJsdoc(({
230
263
  case 'JsdocTypeProperty': {
231
264
  const typeNode = /** @type {import('jsdoc-type-pratt-parser').PropertyResult} */ (nde);
232
265
 
233
- if (propertyQuotes ||
234
- (typeof typeNode.value === 'string' && !(/\s/v).test(typeNode.value))
266
+ if ((propertyQuotes ||
267
+ (typeof typeNode.value === 'string' && !(/\s/v).test(typeNode.value))) &&
268
+ typeNode.meta.quote !== (propertyQuotes ?? undefined)
235
269
  ) {
236
270
  typeNode.meta.quote = propertyQuotes ?? undefined;
237
271
  errorMessage = `Inconsistent ${propertyQuotes} property quotes usage`;
238
- } else {
239
- typeFound = false;
240
272
  }
241
273
 
242
274
  break;
@@ -244,40 +276,64 @@ export default iterateJsdoc(({
244
276
 
245
277
  case 'JsdocTypeStringValue': {
246
278
  const typeNode = /** @type {import('jsdoc-type-pratt-parser').StringValueResult} */ (nde);
247
- typeNode.meta.quote = stringQuotes;
248
- errorMessage = `Inconsistent ${stringQuotes} string quotes usage`;
279
+ if (typeNode.meta.quote !== stringQuotes) {
280
+ typeNode.meta.quote = stringQuotes;
281
+ errorMessage = `Inconsistent ${stringQuotes} string quotes usage`;
282
+ }
283
+
284
+ break;
285
+ }
286
+
287
+ case 'JsdocTypeUnion': {
288
+ const typeNode = /** @type {import('jsdoc-type-pratt-parser').UnionResult} */ (nde);
289
+ /* c8 ignore next -- Guard */
290
+ if ((typeNode.meta?.spacing ?? ' ') !== unionSpacing) {
291
+ typeNode.meta = {
292
+ spacing: unionSpacing,
293
+ };
294
+ errorMessage = `Inconsistent "${unionSpacing}" union spacing usage`;
295
+ }
296
+
249
297
  break;
250
298
  }
251
299
 
252
300
  default:
253
- typeFound = false;
254
301
  break;
255
302
  }
256
303
 
257
- if (typeFound) {
258
- const convertedType = stringify(/** @type {import('jsdoc-type-pratt-parser').RootResult} */ (nde));
259
- if (initialType !== convertedType) {
260
- needToReport = true;
261
- errorMessages.push(errorMessage);
262
- }
304
+ if (errorMessage) {
305
+ errorMessages.push(errorMessage);
263
306
  }
264
307
  });
265
308
 
266
- if (needToReport) {
309
+ const differentResult = tag.type !==
310
+ typeBracketSpacing + stringify(parsedType) + typeBracketSpacing;
311
+
312
+ if (errorMessages.length && differentResult) {
267
313
  for (const errorMessage of errorMessages) {
268
314
  utils.reportJSDoc(
269
- errorMessage, tag, enableFixer ? fix : null, true,
315
+ errorMessage, tag, enableFixer ? fix : null,
270
316
  );
271
317
  }
318
+ // Stringification may have been equal previously (and thus no error reported)
319
+ // because the stringification doesn't preserve everything
320
+ } else if (differentResult) {
321
+ utils.reportJSDoc(
322
+ 'There was an error with type formatting', tag, enableFixer ? fix : null,
323
+ );
272
324
  }
273
325
  };
274
326
 
275
327
  const tags = utils.getPresentTags([
276
328
  'param',
277
329
  'returns',
330
+ 'type',
331
+ 'typedef',
278
332
  ]);
279
333
  for (const tag of tags) {
280
- checkTypeFormats(tag);
334
+ if (tag.type) {
335
+ checkTypeFormats(tag);
336
+ }
281
337
  }
282
338
  }, {
283
339
  iterateAllJsdocs: true,
@@ -320,9 +376,11 @@ export default iterateJsdoc(({
320
376
  'linebreak',
321
377
  'semicolon',
322
378
  'semicolon-and-linebreak',
323
- null,
324
379
  ],
325
380
  },
381
+ objectFieldSeparatorTrailingPunctuation: {
382
+ type: 'boolean',
383
+ },
326
384
  propertyQuotes: {
327
385
  enum: [
328
386
  'double',
@@ -339,6 +397,12 @@ export default iterateJsdoc(({
339
397
  'single',
340
398
  ],
341
399
  },
400
+ typeBracketSpacing: {
401
+ type: 'string',
402
+ },
403
+ unionSpacing: {
404
+ type: 'string',
405
+ },
342
406
  },
343
407
  type: 'object',
344
408
  },
package/src/rules.d.ts CHANGED
@@ -765,16 +765,13 @@ export interface Rules {
765
765
  genericDot?: boolean;
766
766
  objectFieldIndent?: string;
767
767
  objectFieldQuote?: "double" | "single" | null;
768
- objectFieldSeparator?:
769
- | "comma"
770
- | "comma-and-linebreak"
771
- | "linebreak"
772
- | "semicolon"
773
- | "semicolon-and-linebreak"
774
- | null;
768
+ objectFieldSeparator?: "comma" | "comma-and-linebreak" | "linebreak" | "semicolon" | "semicolon-and-linebreak";
769
+ objectFieldSeparatorTrailingPunctuation?: boolean;
775
770
  propertyQuotes?: "double" | "single" | null;
776
771
  separatorForSingleObjectField?: boolean;
777
772
  stringQuotes?: "double" | "single";
773
+ typeBracketSpacing?: string;
774
+ unionSpacing?: string;
778
775
  }
779
776
  ];
780
777