@dereekb/util 13.11.2 → 13.11.4
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.
- package/eslint/index.cjs.default.js +1 -0
- package/eslint/index.cjs.js +687 -0
- package/eslint/index.cjs.mjs +2 -0
- package/eslint/index.d.ts +1 -0
- package/eslint/index.esm.js +683 -0
- package/eslint/package.json +23 -0
- package/eslint/src/index.d.ts +1 -0
- package/eslint/src/lib/comments.d.ts +101 -0
- package/eslint/src/lib/index.d.ts +3 -0
- package/eslint/src/lib/plugin.d.ts +18 -0
- package/eslint/src/lib/prefer-no-side-effects-in-jsdoc.rule.d.ts +50 -0
- package/eslint/src/lib/require-no-side-effects.rule.d.ts +67 -0
- package/fetch/package.json +2 -2
- package/index.cjs.js +1421 -23
- package/index.esm.js +1421 -24
- package/package.json +7 -1
- package/src/lib/array/array.factory.d.ts +2 -0
- package/src/lib/array/array.filter.d.ts +50 -17
- package/src/lib/array/array.find.d.ts +1 -0
- package/src/lib/array/array.index.d.ts +7 -0
- package/src/lib/array/array.indexed.d.ts +21 -0
- package/src/lib/array/array.make.d.ts +7 -0
- package/src/lib/array/array.random.d.ts +1 -0
- package/src/lib/array/array.unique.d.ts +3 -0
- package/src/lib/array/array.value.d.ts +7 -0
- package/src/lib/auth/auth.role.claims.d.ts +7 -0
- package/src/lib/boolean.d.ts +1 -0
- package/src/lib/contact/random.d.ts +14 -0
- package/src/lib/date/date.d.ts +229 -0
- package/src/lib/date/time.d.ts +7 -0
- package/src/lib/date/week.d.ts +7 -0
- package/src/lib/error/error.d.ts +7 -0
- package/src/lib/filter/filter.d.ts +7 -0
- package/src/lib/function/function.boolean.d.ts +7 -0
- package/src/lib/function/function.forward.d.ts +14 -0
- package/src/lib/getter/getter.cache.d.ts +7 -0
- package/src/lib/getter/getter.d.ts +34 -0
- package/src/lib/getter/getter.map.d.ts +7 -0
- package/src/lib/getter/getter.util.d.ts +7 -0
- package/src/lib/grouping.d.ts +8 -0
- package/src/lib/hash.d.ts +1 -0
- package/src/lib/key.d.ts +16 -0
- package/src/lib/map/map.key.d.ts +14 -0
- package/src/lib/model/id.batch.d.ts +7 -0
- package/src/lib/model/id.factory.d.ts +7 -0
- package/src/lib/model/model.conversion.d.ts +35 -0
- package/src/lib/model/model.copy.d.ts +7 -0
- package/src/lib/model/model.d.ts +19 -0
- package/src/lib/model/model.modify.d.ts +14 -0
- package/src/lib/nodejs/stream.d.ts +7 -0
- package/src/lib/number/bound.d.ts +3 -0
- package/src/lib/number/dollar.d.ts +7 -0
- package/src/lib/number/factory.d.ts +7 -0
- package/src/lib/number/random.d.ts +1 -0
- package/src/lib/number/round.d.ts +22 -0
- package/src/lib/number/sort.d.ts +7 -0
- package/src/lib/number/transform.d.ts +7 -0
- package/src/lib/object/object.array.delta.d.ts +7 -0
- package/src/lib/object/object.equal.d.ts +7 -0
- package/src/lib/object/object.filter.pojo.d.ts +87 -0
- package/src/lib/object/object.filter.tuple.d.ts +16 -0
- package/src/lib/object/object.key.d.ts +14 -0
- package/src/lib/object/object.map.d.ts +14 -0
- package/src/lib/path/path.d.ts +9 -0
- package/src/lib/promise/promise.d.ts +21 -0
- package/src/lib/promise/promise.factory.d.ts +7 -0
- package/src/lib/promise/promise.task.d.ts +7 -0
- package/src/lib/service/handler.config.d.ts +28 -0
- package/src/lib/service/handler.d.ts +14 -0
- package/src/lib/set/set.d.ts +21 -0
- package/src/lib/set/set.decision.d.ts +7 -0
- package/src/lib/set/set.delta.d.ts +7 -0
- package/src/lib/set/set.selection.d.ts +7 -0
- package/src/lib/sort.d.ts +8 -0
- package/src/lib/string/char.d.ts +7 -0
- package/src/lib/string/dencoder.d.ts +35 -0
- package/src/lib/string/factory.d.ts +22 -1
- package/src/lib/string/replace.d.ts +78 -0
- package/src/lib/string/search.d.ts +7 -0
- package/src/lib/string/sort.d.ts +7 -0
- package/src/lib/string/string.d.ts +1 -0
- package/src/lib/string/transform.d.ts +53 -0
- package/src/lib/string/tree.d.ts +7 -0
- package/src/lib/string/url.d.ts +7 -0
- package/src/lib/tree/tree.array.d.ts +1 -0
- package/src/lib/tree/tree.explore.d.ts +3 -0
- package/src/lib/type.d.ts +3 -2
- package/src/lib/value/bound.d.ts +28 -0
- package/src/lib/value/comparator.d.ts +16 -0
- package/src/lib/value/decision.d.ts +5 -0
- package/src/lib/value/equal.d.ts +2 -0
- package/src/lib/value/indexed.d.ts +127 -0
- package/src/lib/value/map.d.ts +22 -0
- package/src/lib/value/maybe.type.d.ts +2 -2
- package/src/lib/value/modifier.d.ts +13 -0
- package/src/lib/value/point.d.ts +56 -0
- package/src/lib/value/use.d.ts +37 -0
- package/src/lib/value/vector.d.ts +7 -0
- package/test/index.cjs.js +17 -4
- package/test/index.esm.js +17 -4
- package/test/package.json +2 -2
- package/test/src/lib/shared/shared.fail.d.ts +24 -5
|
@@ -0,0 +1,687 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The bundler hint string that marks a function call as side-effect-free.
|
|
5
|
+
*/ var NO_SIDE_EFFECTS_TAG = '@__NO_SIDE_EFFECTS__';
|
|
6
|
+
/**
|
|
7
|
+
* Returns true if the given comment text contains the @__NO_SIDE_EFFECTS__ marker.
|
|
8
|
+
*
|
|
9
|
+
* @param text - The comment body text (without the `/*` and `*\/` delimiters).
|
|
10
|
+
* @returns True when the marker substring is present.
|
|
11
|
+
*/ function commentContainsNoSideEffects(text) {
|
|
12
|
+
return text.includes(NO_SIDE_EFFECTS_TAG);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Returns the leading whitespace (column indent) of the line containing the given offset.
|
|
16
|
+
*
|
|
17
|
+
* @param sourceText - The full source text being inspected.
|
|
18
|
+
* @param offset - A character offset into `sourceText` indicating the line of interest.
|
|
19
|
+
* @returns The whitespace prefix (spaces/tabs) of that line.
|
|
20
|
+
*/ function getLineIndent(sourceText, offset) {
|
|
21
|
+
var lineStart = offset;
|
|
22
|
+
while(lineStart > 0 && sourceText.charAt(lineStart - 1) !== '\n'){
|
|
23
|
+
lineStart -= 1;
|
|
24
|
+
}
|
|
25
|
+
var cursor = lineStart;
|
|
26
|
+
while(cursor < sourceText.length && (sourceText.charAt(cursor) === ' ' || sourceText.charAt(cursor) === '\t')){
|
|
27
|
+
cursor += 1;
|
|
28
|
+
}
|
|
29
|
+
return sourceText.slice(lineStart, cursor);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Returns the outermost statement node for a FunctionDeclaration — its `ExportNamedDeclaration`
|
|
33
|
+
* or `ExportDefaultDeclaration` parent if exported, otherwise the declaration itself. This is the
|
|
34
|
+
* node ESLint attaches leading comments to.
|
|
35
|
+
*
|
|
36
|
+
* @param node - The FunctionDeclaration AST node.
|
|
37
|
+
* @returns The statement node ESLint attaches leading comments to.
|
|
38
|
+
*/ function getStatementAnchor(node) {
|
|
39
|
+
return node.parent && (node.parent.type === 'ExportNamedDeclaration' || node.parent.type === 'ExportDefaultDeclaration') ? node.parent : node;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Returns true if the statement is an overload signature (TSDeclareFunction) sharing the given name.
|
|
43
|
+
*
|
|
44
|
+
* @param stmt - The statement node to check (may be an export wrapper).
|
|
45
|
+
* @param name - The function identifier name to match.
|
|
46
|
+
* @returns True when `stmt` is an overload signature for `name`.
|
|
47
|
+
*/ function isOverloadSignature(stmt, name) {
|
|
48
|
+
var _inner_id;
|
|
49
|
+
var inner = stmt.type === 'ExportNamedDeclaration' || stmt.type === 'ExportDefaultDeclaration' ? stmt.declaration : stmt;
|
|
50
|
+
return (inner === null || inner === void 0 ? void 0 : inner.type) === 'TSDeclareFunction' && ((_inner_id = inner.id) === null || _inner_id === void 0 ? void 0 : _inner_id.type) === 'Identifier' && inner.id.name === name;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Walks backward from the implementation FunctionDeclaration through any overload signatures
|
|
54
|
+
* with the same name, collecting:
|
|
55
|
+
*
|
|
56
|
+
* - The leading JSDoc block (preferring the one attached to the **first** overload, since that's
|
|
57
|
+
* where the function's documentation conventionally lives).
|
|
58
|
+
* - All orphan `@__NO_SIDE_EFFECTS__` line/block comments encountered between overloads or
|
|
59
|
+
* between the last overload and the implementation.
|
|
60
|
+
*
|
|
61
|
+
* This handles the common pattern:
|
|
62
|
+
*
|
|
63
|
+
* ```ts
|
|
64
|
+
* \/\*\* doc \*\/
|
|
65
|
+
* export function foo(a: number): number;
|
|
66
|
+
* export function foo(a: string): string;
|
|
67
|
+
* \/\/ \@__NO_SIDE_EFFECTS__
|
|
68
|
+
* export function foo(a: any) { ... }
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @param sourceCode - The ESLint `SourceCode` object used to read leading comments.
|
|
72
|
+
* @param implNode - The implementation FunctionDeclaration node.
|
|
73
|
+
* @returns The leading JSDoc (if any) and any orphan side-effect annotation comments.
|
|
74
|
+
*/ function findFunctionLeadingContext(sourceCode, implNode) {
|
|
75
|
+
var _implNode_id;
|
|
76
|
+
if (((_implNode_id = implNode.id) === null || _implNode_id === void 0 ? void 0 : _implNode_id.type) !== 'Identifier') {
|
|
77
|
+
return {
|
|
78
|
+
jsdoc: null,
|
|
79
|
+
orphanLineComments: [],
|
|
80
|
+
hasOverloads: false,
|
|
81
|
+
implLineComment: null,
|
|
82
|
+
implHasSurvivingAnnotation: false,
|
|
83
|
+
chainStartStatement: getStatementAnchor(implNode)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
var name = implNode.id.name;
|
|
87
|
+
var implStmt = getStatementAnchor(implNode);
|
|
88
|
+
var container = implStmt.parent;
|
|
89
|
+
var chainStartIdx = -1;
|
|
90
|
+
var implIdx = -1;
|
|
91
|
+
if (container && Array.isArray(container.body)) {
|
|
92
|
+
implIdx = container.body.indexOf(implStmt);
|
|
93
|
+
if (implIdx >= 0) {
|
|
94
|
+
chainStartIdx = implIdx;
|
|
95
|
+
for(var i = implIdx - 1; i >= 0; i -= 1){
|
|
96
|
+
if (isOverloadSignature(container.body[i], name)) {
|
|
97
|
+
chainStartIdx = i;
|
|
98
|
+
} else {
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
var hasOverloads = chainStartIdx >= 0 && implIdx >= 0 && chainStartIdx < implIdx;
|
|
105
|
+
var firstJsdoc = null;
|
|
106
|
+
var anyJsdocHasNoSideEffects = false;
|
|
107
|
+
var implJsdocHasNoSideEffects = false;
|
|
108
|
+
var orphanLineComments = [];
|
|
109
|
+
|
|
110
|
+
// declaration is required (TS erases overload signatures, so only this annotation survives).
|
|
111
|
+
// Track it separately so callers don't accidentally remove it.
|
|
112
|
+
var implLineComment = null;
|
|
113
|
+
function processCommentsForStatement(stmt, isImplStatement) {
|
|
114
|
+
var comments = sourceCode.getCommentsBefore(stmt) || [];
|
|
115
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
116
|
+
try {
|
|
117
|
+
for(var _iterator = comments[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
118
|
+
var comment = _step.value;
|
|
119
|
+
if (comment.type === 'Block' && comment.value.startsWith('*')) {
|
|
120
|
+
var hasMarker = commentContainsNoSideEffects(comment.value);
|
|
121
|
+
if (hasMarker) {
|
|
122
|
+
anyJsdocHasNoSideEffects = true;
|
|
123
|
+
if (isImplStatement) {
|
|
124
|
+
implJsdocHasNoSideEffects = true;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Auto-fix target: the first JSDoc in the chain (where the function's docs conventionally live).
|
|
128
|
+
if (!firstJsdoc) {
|
|
129
|
+
firstJsdoc = {
|
|
130
|
+
node: comment,
|
|
131
|
+
text: comment.value,
|
|
132
|
+
hasNoSideEffects: hasMarker
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
} else if (commentContainsNoSideEffects(comment.value)) {
|
|
136
|
+
// Only the impl-leading annotation on an overloaded function is "required"; others are orphans.
|
|
137
|
+
// When multiple line/block comments stack above the impl, keep the closest one (last in source
|
|
138
|
+
// order) as the canonical impl annotation and treat the rest as orphans to consolidate.
|
|
139
|
+
if (isImplStatement && hasOverloads) {
|
|
140
|
+
if (implLineComment) {
|
|
141
|
+
orphanLineComments.push(implLineComment);
|
|
142
|
+
}
|
|
143
|
+
implLineComment = comment;
|
|
144
|
+
} else {
|
|
145
|
+
orphanLineComments.push(comment);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
} catch (err) {
|
|
150
|
+
_didIteratorError = true;
|
|
151
|
+
_iteratorError = err;
|
|
152
|
+
} finally{
|
|
153
|
+
try {
|
|
154
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
155
|
+
_iterator.return();
|
|
156
|
+
}
|
|
157
|
+
} finally{
|
|
158
|
+
if (_didIteratorError) {
|
|
159
|
+
throw _iteratorError;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (chainStartIdx >= 0 && implIdx >= 0) {
|
|
165
|
+
for(var i1 = chainStartIdx; i1 <= implIdx; i1 += 1){
|
|
166
|
+
processCommentsForStatement(container.body[i1], i1 === implIdx);
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
// Fallback: no container body found; just look at comments before the implementation.
|
|
170
|
+
processCommentsForStatement(implStmt, false);
|
|
171
|
+
}
|
|
172
|
+
// Report the first JSDoc as the canonical jsdoc, but reflect any-in-chain satisfaction
|
|
173
|
+
// so callers don't re-annotate when the marker is already present elsewhere in the chain.
|
|
174
|
+
var resolved = null;
|
|
175
|
+
var captured = firstJsdoc;
|
|
176
|
+
if (captured) {
|
|
177
|
+
resolved = {
|
|
178
|
+
node: captured.node,
|
|
179
|
+
text: captured.text,
|
|
180
|
+
hasNoSideEffects: anyJsdocHasNoSideEffects
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
// The implementation's emitted JS carries the marker when:
|
|
184
|
+
// - non-overloaded: the function's (only) JSDoc has the tag (it's directly attached to the impl), OR
|
|
185
|
+
// - overloaded: a line/block comment sits above the impl, OR the impl has its own tagged JSDoc.
|
|
186
|
+
var implHasSurvivingAnnotation = hasOverloads ? implLineComment !== null || implJsdocHasNoSideEffects : anyJsdocHasNoSideEffects;
|
|
187
|
+
var chainStartStatement = chainStartIdx >= 0 && container && Array.isArray(container.body) ? container.body[chainStartIdx] : implStmt;
|
|
188
|
+
return {
|
|
189
|
+
jsdoc: resolved,
|
|
190
|
+
orphanLineComments: orphanLineComments,
|
|
191
|
+
hasOverloads: hasOverloads,
|
|
192
|
+
implLineComment: implLineComment,
|
|
193
|
+
implHasSurvivingAnnotation: implHasSurvivingAnnotation,
|
|
194
|
+
chainStartStatement: chainStartStatement
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function _array_like_to_array$1(arr, len) {
|
|
199
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
200
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
201
|
+
return arr2;
|
|
202
|
+
}
|
|
203
|
+
function _array_with_holes$1(arr) {
|
|
204
|
+
if (Array.isArray(arr)) return arr;
|
|
205
|
+
}
|
|
206
|
+
function _array_without_holes(arr) {
|
|
207
|
+
if (Array.isArray(arr)) return _array_like_to_array$1(arr);
|
|
208
|
+
}
|
|
209
|
+
function _iterable_to_array(iter) {
|
|
210
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
211
|
+
}
|
|
212
|
+
function _iterable_to_array_limit$1(arr, i) {
|
|
213
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
214
|
+
if (_i == null) return;
|
|
215
|
+
var _arr = [];
|
|
216
|
+
var _n = true;
|
|
217
|
+
var _d = false;
|
|
218
|
+
var _s, _e;
|
|
219
|
+
try {
|
|
220
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
221
|
+
_arr.push(_s.value);
|
|
222
|
+
if (i && _arr.length === i) break;
|
|
223
|
+
}
|
|
224
|
+
} catch (err) {
|
|
225
|
+
_d = true;
|
|
226
|
+
_e = err;
|
|
227
|
+
} finally{
|
|
228
|
+
try {
|
|
229
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
230
|
+
} finally{
|
|
231
|
+
if (_d) throw _e;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return _arr;
|
|
235
|
+
}
|
|
236
|
+
function _non_iterable_rest$1() {
|
|
237
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
238
|
+
}
|
|
239
|
+
function _non_iterable_spread() {
|
|
240
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
241
|
+
}
|
|
242
|
+
function _sliced_to_array$1(arr, i) {
|
|
243
|
+
return _array_with_holes$1(arr) || _iterable_to_array_limit$1(arr, i) || _unsupported_iterable_to_array$1(arr, i) || _non_iterable_rest$1();
|
|
244
|
+
}
|
|
245
|
+
function _to_consumable_array(arr) {
|
|
246
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array$1(arr) || _non_iterable_spread();
|
|
247
|
+
}
|
|
248
|
+
function _unsupported_iterable_to_array$1(o, minLen) {
|
|
249
|
+
if (!o) return;
|
|
250
|
+
if (typeof o === "string") return _array_like_to_array$1(o, minLen);
|
|
251
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
252
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
253
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
254
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$1(o, minLen);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* The JSDoc tag identifying a function as a factory in the @dereekb conventions.
|
|
258
|
+
*/ var FACTORY_JSDOC_TAG = '@dbxUtilKind factory';
|
|
259
|
+
/**
|
|
260
|
+
* Default suffix patterns considered factory-like by name when `checkNamePatterns` is enabled.
|
|
261
|
+
*/ var DEFAULT_NAME_PATTERNS = [
|
|
262
|
+
/(?:Factory|Factories|Service|Services|Function|Functions)$/,
|
|
263
|
+
/^(?:make|build|create)[A-Z]/,
|
|
264
|
+
/^(?:firestore|optionalFirestore)[A-Z]/
|
|
265
|
+
];
|
|
266
|
+
/**
|
|
267
|
+
* Returns the function's identifier name, or null if anonymous.
|
|
268
|
+
*
|
|
269
|
+
* @param node - The FunctionDeclaration AST node.
|
|
270
|
+
* @returns The function's identifier name, or `null` for anonymous functions.
|
|
271
|
+
*/ function getFunctionName(node) {
|
|
272
|
+
var _node_id;
|
|
273
|
+
if (((_node_id = node.id) === null || _node_id === void 0 ? void 0 : _node_id.type) === 'Identifier') {
|
|
274
|
+
return node.id.name;
|
|
275
|
+
}
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Builds the merged set of name patterns based on rule options.
|
|
280
|
+
*
|
|
281
|
+
* @param options - The resolved rule options.
|
|
282
|
+
* @returns The combined default + additional regex patterns, or an empty list when name-pattern matching is disabled.
|
|
283
|
+
*/ function buildNamePatterns(options) {
|
|
284
|
+
var _options_additionalNamePatterns;
|
|
285
|
+
if (!options.checkNamePatterns) {
|
|
286
|
+
return [];
|
|
287
|
+
}
|
|
288
|
+
var additional = ((_options_additionalNamePatterns = options.additionalNamePatterns) !== null && _options_additionalNamePatterns !== void 0 ? _options_additionalNamePatterns : []).map(function(source) {
|
|
289
|
+
return new RegExp(source);
|
|
290
|
+
});
|
|
291
|
+
return _to_consumable_array(DEFAULT_NAME_PATTERNS).concat(_to_consumable_array(additional));
|
|
292
|
+
}
|
|
293
|
+
var utilRequireNoSideEffectsRule = {
|
|
294
|
+
meta: {
|
|
295
|
+
type: 'suggestion',
|
|
296
|
+
fixable: 'code',
|
|
297
|
+
docs: {
|
|
298
|
+
description: 'Require @__NO_SIDE_EFFECTS__ inside the JSDoc block of factory functions so esbuild can drop unused calls during tree-shaking.',
|
|
299
|
+
recommended: true
|
|
300
|
+
},
|
|
301
|
+
messages: {
|
|
302
|
+
missingNoSideEffectsJsdoc: 'Factory function "{{name}}" is missing the `@__NO_SIDE_EFFECTS__` annotation in its JSDoc. Add it as the last tag inside the JSDoc block so esbuild can drop unused calls during tree-shaking.',
|
|
303
|
+
missingJsdocForFactory: 'Factory-named function "{{name}}" has no JSDoc block. Add a JSDoc block containing `@__NO_SIDE_EFFECTS__` so esbuild can drop unused calls during tree-shaking.',
|
|
304
|
+
missingImplAnnotationOverloaded: 'Overloaded factory function "{{name}}" needs `@__NO_SIDE_EFFECTS__` directly on its implementation — TypeScript erases overload signatures during emit, so the JSDoc tag on the first overload is dropped from the bundled JavaScript. Add a `// @__NO_SIDE_EFFECTS__` line comment immediately above the implementation declaration.'
|
|
305
|
+
},
|
|
306
|
+
schema: [
|
|
307
|
+
{
|
|
308
|
+
type: 'object',
|
|
309
|
+
properties: {
|
|
310
|
+
checkNamePatterns: {
|
|
311
|
+
type: 'boolean',
|
|
312
|
+
description: 'Also flag functions whose names match factory naming patterns, in addition to JSDoc-tag detection.'
|
|
313
|
+
},
|
|
314
|
+
additionalNamePatterns: {
|
|
315
|
+
type: 'array',
|
|
316
|
+
items: {
|
|
317
|
+
type: 'string'
|
|
318
|
+
},
|
|
319
|
+
description: 'Additional name pattern source strings to treat as factory signals when checkNamePatterns is true.'
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
additionalProperties: false
|
|
323
|
+
}
|
|
324
|
+
]
|
|
325
|
+
},
|
|
326
|
+
create: function create(context) {
|
|
327
|
+
var _context_options_;
|
|
328
|
+
var options = (_context_options_ = context.options[0]) !== null && _context_options_ !== void 0 ? _context_options_ : {};
|
|
329
|
+
var namePatterns = buildNamePatterns(options);
|
|
330
|
+
var sourceCode = context.sourceCode;
|
|
331
|
+
var sourceText = sourceCode.getText();
|
|
332
|
+
function nameMatchesFactoryPattern(name) {
|
|
333
|
+
return namePatterns.some(function(pattern) {
|
|
334
|
+
return pattern.test(name);
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
function checkFunction(node) {
|
|
338
|
+
var _jsdoc_text;
|
|
339
|
+
// Skip overload signatures (TSDeclareFunction) and bodyless declarations.
|
|
340
|
+
if (node.type !== 'FunctionDeclaration' || !node.body) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
var name = getFunctionName(node);
|
|
344
|
+
if (!name) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
// Walks the overload chain (if any) so we read the JSDoc on the first overload,
|
|
348
|
+
// any orphan annotations placed between overloads, and the (preserved) impl-leading annotation.
|
|
349
|
+
var _findFunctionLeadingContext = findFunctionLeadingContext(sourceCode, node), jsdoc = _findFunctionLeadingContext.jsdoc, redundantLineComments = _findFunctionLeadingContext.orphanLineComments, hasOverloads = _findFunctionLeadingContext.hasOverloads, implLineComment = _findFunctionLeadingContext.implLineComment, implHasSurvivingAnnotation = _findFunctionLeadingContext.implHasSurvivingAnnotation, chainStartStatement = _findFunctionLeadingContext.chainStartStatement;
|
|
350
|
+
var taggedAsFactory = (jsdoc === null || jsdoc === void 0 ? void 0 : (_jsdoc_text = jsdoc.text) === null || _jsdoc_text === void 0 ? void 0 : _jsdoc_text.includes(FACTORY_JSDOC_TAG)) === true;
|
|
351
|
+
var matchedByName = !taggedAsFactory && namePatterns.length > 0 && nameMatchesFactoryPattern(name);
|
|
352
|
+
if (!taggedAsFactory && !matchedByName) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
// The bundled implementation already carries the marker — passing. This covers:
|
|
356
|
+
// - non-overloaded with the tag in the (only) JSDoc, AND
|
|
357
|
+
|
|
358
|
+
if (implHasSurvivingAnnotation) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
// Choose the most specific message:
|
|
362
|
+
// - overloaded + JSDoc with the tag on first overload but no impl annotation → impl-specific.
|
|
363
|
+
// - has any JSDoc → JSDoc tag missing.
|
|
364
|
+
// - no JSDoc → JSDoc must be created.
|
|
365
|
+
var messageId;
|
|
366
|
+
if (hasOverloads && (jsdoc === null || jsdoc === void 0 ? void 0 : jsdoc.hasNoSideEffects)) {
|
|
367
|
+
messageId = 'missingImplAnnotationOverloaded';
|
|
368
|
+
} else if (jsdoc) {
|
|
369
|
+
messageId = 'missingNoSideEffectsJsdoc';
|
|
370
|
+
} else {
|
|
371
|
+
messageId = 'missingJsdocForFactory';
|
|
372
|
+
}
|
|
373
|
+
context.report({
|
|
374
|
+
node: node.id,
|
|
375
|
+
messageId: messageId,
|
|
376
|
+
data: {
|
|
377
|
+
name: name
|
|
378
|
+
},
|
|
379
|
+
fix: function fix(fixer) {
|
|
380
|
+
var fixes = [];
|
|
381
|
+
// Add the JSDoc tag (or create the JSDoc) so consumer-facing docs reflect the marker.
|
|
382
|
+
// Skipped when the existing JSDoc already carries the tag — only the impl-line comment
|
|
383
|
+
// would be missing in that case (handled below).
|
|
384
|
+
if (jsdoc && !jsdoc.hasNoSideEffects) {
|
|
385
|
+
var jsdocText = jsdoc.text; // text excludes /* and */
|
|
386
|
+
var jsdocStart = jsdoc.node.range[0];
|
|
387
|
+
var jsdocEnd = jsdoc.node.range[1];
|
|
388
|
+
// Determine the column the JSDoc starts at to align the new line.
|
|
389
|
+
var jsdocIndent = getLineIndent(sourceText, jsdocStart);
|
|
390
|
+
// If the JSDoc is single-line (e.g. `/** @dbxUtilKind factory */`),
|
|
391
|
+
// expand it to multi-line. Detect by absence of newline in the body.
|
|
392
|
+
if (!jsdocText.includes('\n')) {
|
|
393
|
+
var bodyTrimmed = jsdocText.replace(/^\*\s*/, '').replace(/\s*$/, '');
|
|
394
|
+
var newBody = "/**\n".concat(jsdocIndent, " * ").concat(bodyTrimmed, "\n").concat(jsdocIndent, " * ").concat(NO_SIDE_EFFECTS_TAG, "\n").concat(jsdocIndent, " */");
|
|
395
|
+
fixes.push(fixer.replaceTextRange([
|
|
396
|
+
jsdocStart,
|
|
397
|
+
jsdocEnd
|
|
398
|
+
], newBody));
|
|
399
|
+
} else {
|
|
400
|
+
|
|
401
|
+
// immediately before the line containing the closing `*/`, so the closing line
|
|
402
|
+
// and existing body lines remain untouched.
|
|
403
|
+
var closingMarkerStart = jsdocEnd - 2; // start of `*/`
|
|
404
|
+
var closingLineStart = closingMarkerStart;
|
|
405
|
+
while(closingLineStart > 0 && sourceText.charAt(closingLineStart - 1) !== '\n'){
|
|
406
|
+
closingLineStart -= 1;
|
|
407
|
+
}
|
|
408
|
+
var insertion = "".concat(jsdocIndent, " * ").concat(NO_SIDE_EFFECTS_TAG, "\n");
|
|
409
|
+
fixes.push(fixer.insertTextBeforeRange([
|
|
410
|
+
closingLineStart,
|
|
411
|
+
closingLineStart
|
|
412
|
+
], insertion));
|
|
413
|
+
}
|
|
414
|
+
} else if (!jsdoc) {
|
|
415
|
+
// No JSDoc anywhere — create one above the FIRST statement in the chain. For overloaded
|
|
416
|
+
// functions the canonical doc placement is on the first overload, not the implementation.
|
|
417
|
+
var nodeStart = chainStartStatement.range[0];
|
|
418
|
+
var indent = getLineIndent(sourceText, nodeStart);
|
|
419
|
+
var newJsdoc = "/**\n".concat(indent, " * @dbxUtilKind factory\n").concat(indent, " * ").concat(NO_SIDE_EFFECTS_TAG, "\n").concat(indent, " */\n").concat(indent);
|
|
420
|
+
fixes.push(fixer.insertTextBeforeRange([
|
|
421
|
+
nodeStart,
|
|
422
|
+
nodeStart
|
|
423
|
+
], newJsdoc));
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// implementation so the marker survives TypeScript's overload-signature erasure and reaches
|
|
427
|
+
// the bundled JavaScript. Skipped when one is already in place.
|
|
428
|
+
if (hasOverloads && !implLineComment) {
|
|
429
|
+
var implAnchor = getStatementAnchor(node);
|
|
430
|
+
var implStart = implAnchor.range[0];
|
|
431
|
+
var indent1 = getLineIndent(sourceText, implStart);
|
|
432
|
+
fixes.push(fixer.insertTextBeforeRange([
|
|
433
|
+
implStart,
|
|
434
|
+
implStart
|
|
435
|
+
], "// ".concat(NO_SIDE_EFFECTS_TAG, "\n").concat(indent1)));
|
|
436
|
+
}
|
|
437
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
438
|
+
try {
|
|
439
|
+
// Remove any redundant adjacent annotation comments now that JSDoc carries the tag.
|
|
440
|
+
for(var _iterator = redundantLineComments[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
441
|
+
var redundant = _step.value;
|
|
442
|
+
var _redundant_range = _sliced_to_array$1(redundant.range, 2), start = _redundant_range[0], end = _redundant_range[1];
|
|
443
|
+
// Extend the removal to include the trailing newline + indent so we don't leave a blank line.
|
|
444
|
+
var removeEnd = end;
|
|
445
|
+
while(removeEnd < sourceText.length && (sourceText.charAt(removeEnd) === ' ' || sourceText.charAt(removeEnd) === '\t')){
|
|
446
|
+
removeEnd += 1;
|
|
447
|
+
}
|
|
448
|
+
if (sourceText.charAt(removeEnd) === '\n') {
|
|
449
|
+
removeEnd += 1;
|
|
450
|
+
}
|
|
451
|
+
// Also drop leading indent on the comment's line.
|
|
452
|
+
var removeStart = start;
|
|
453
|
+
while(removeStart > 0 && (sourceText.charAt(removeStart - 1) === ' ' || sourceText.charAt(removeStart - 1) === '\t')){
|
|
454
|
+
removeStart -= 1;
|
|
455
|
+
}
|
|
456
|
+
fixes.push(fixer.removeRange([
|
|
457
|
+
removeStart,
|
|
458
|
+
removeEnd
|
|
459
|
+
]));
|
|
460
|
+
}
|
|
461
|
+
} catch (err) {
|
|
462
|
+
_didIteratorError = true;
|
|
463
|
+
_iteratorError = err;
|
|
464
|
+
} finally{
|
|
465
|
+
try {
|
|
466
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
467
|
+
_iterator.return();
|
|
468
|
+
}
|
|
469
|
+
} finally{
|
|
470
|
+
if (_didIteratorError) {
|
|
471
|
+
throw _iteratorError;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return fixes;
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
return {
|
|
480
|
+
FunctionDeclaration: checkFunction
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
function _array_like_to_array(arr, len) {
|
|
486
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
487
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
488
|
+
return arr2;
|
|
489
|
+
}
|
|
490
|
+
function _array_with_holes(arr) {
|
|
491
|
+
if (Array.isArray(arr)) return arr;
|
|
492
|
+
}
|
|
493
|
+
function _iterable_to_array_limit(arr, i) {
|
|
494
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
495
|
+
if (_i == null) return;
|
|
496
|
+
var _arr = [];
|
|
497
|
+
var _n = true;
|
|
498
|
+
var _d = false;
|
|
499
|
+
var _s, _e;
|
|
500
|
+
try {
|
|
501
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
502
|
+
_arr.push(_s.value);
|
|
503
|
+
if (i && _arr.length === i) break;
|
|
504
|
+
}
|
|
505
|
+
} catch (err) {
|
|
506
|
+
_d = true;
|
|
507
|
+
_e = err;
|
|
508
|
+
} finally{
|
|
509
|
+
try {
|
|
510
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
511
|
+
} finally{
|
|
512
|
+
if (_d) throw _e;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return _arr;
|
|
516
|
+
}
|
|
517
|
+
function _non_iterable_rest() {
|
|
518
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
519
|
+
}
|
|
520
|
+
function _sliced_to_array(arr, i) {
|
|
521
|
+
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
522
|
+
}
|
|
523
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
524
|
+
if (!o) return;
|
|
525
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
526
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
527
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
528
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
529
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
530
|
+
}
|
|
531
|
+
var utilPreferNoSideEffectsInJsdocRule = {
|
|
532
|
+
meta: {
|
|
533
|
+
type: 'suggestion',
|
|
534
|
+
fixable: 'code',
|
|
535
|
+
docs: {
|
|
536
|
+
description: "Prefer the @__NO_SIDE_EFFECTS__ annotation inside a function's JSDoc instead of a separate line comment between the JSDoc and the declaration.",
|
|
537
|
+
recommended: true
|
|
538
|
+
},
|
|
539
|
+
messages: {
|
|
540
|
+
preferJsdocPlacement: 'Move the `@__NO_SIDE_EFFECTS__` annotation into the JSDoc block of "{{name}}" (as the last tag before the closing) instead of a separate line comment.',
|
|
541
|
+
missingImplAnnotationOverloaded: '"{{name}}" carries `@__NO_SIDE_EFFECTS__` in its first-overload JSDoc but is overloaded — TypeScript erases overload signatures during emit, so the JSDoc tag is dropped from the bundled JavaScript. Add a `// @__NO_SIDE_EFFECTS__` line comment immediately above the implementation declaration.'
|
|
542
|
+
},
|
|
543
|
+
schema: []
|
|
544
|
+
},
|
|
545
|
+
create: function create(context) {
|
|
546
|
+
var sourceCode = context.sourceCode;
|
|
547
|
+
var sourceText = sourceCode.getText();
|
|
548
|
+
function checkFunction(node) {
|
|
549
|
+
var _node_id;
|
|
550
|
+
if (node.type !== 'FunctionDeclaration' || !node.body) {
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
if (((_node_id = node.id) === null || _node_id === void 0 ? void 0 : _node_id.type) !== 'Identifier') {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
var name = node.id.name;
|
|
557
|
+
// Walks the overload chain (if any) so we find the JSDoc on the first overload,
|
|
558
|
+
// any orphan annotations between overloads, and the (preserved) impl-leading annotation.
|
|
559
|
+
var _findFunctionLeadingContext = findFunctionLeadingContext(sourceCode, node), jsdoc = _findFunctionLeadingContext.jsdoc, orphanLineComments = _findFunctionLeadingContext.orphanLineComments, implLineComment = _findFunctionLeadingContext.implLineComment, hasOverloads = _findFunctionLeadingContext.hasOverloads, implHasSurvivingAnnotation = _findFunctionLeadingContext.implHasSurvivingAnnotation;
|
|
560
|
+
if (!jsdoc) {
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
// Three reasons to fire:
|
|
564
|
+
// 1. There's an annotation form (orphan OR overload-impl line comment) and the JSDoc
|
|
565
|
+
// doesn't yet carry the tag — the JSDoc needs the tag added (for docs/tooling).
|
|
566
|
+
// 2. There are orphan annotations to consolidate, regardless of JSDoc tag state.
|
|
567
|
+
// 3. Function is overloaded, JSDoc carries the tag, but the implementation lacks any
|
|
568
|
+
// surviving annotation — TS erases overload signatures during emit, so the JSDoc tag
|
|
569
|
+
|
|
570
|
+
// above the impl so the bundler still sees the hint.
|
|
571
|
+
// The impl line comment on overloaded functions is REQUIRED for tree-shaking and is never
|
|
572
|
+
// removed — it is only counted as a signal that the JSDoc should also carry the tag.
|
|
573
|
+
var hasAnyAnnotationSource = orphanLineComments.length > 0 || implLineComment !== null;
|
|
574
|
+
var needsJsdocTag = !jsdoc.hasNoSideEffects && hasAnyAnnotationSource;
|
|
575
|
+
var needsOrphanRemoval = orphanLineComments.length > 0;
|
|
576
|
+
var needsImplLineCommentForOverload = jsdoc.hasNoSideEffects && hasOverloads && !implHasSurvivingAnnotation;
|
|
577
|
+
if (!needsJsdocTag && !needsOrphanRemoval && !needsImplLineCommentForOverload) {
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
context.report({
|
|
581
|
+
node: node.id,
|
|
582
|
+
messageId: needsImplLineCommentForOverload && !needsJsdocTag && !needsOrphanRemoval ? 'missingImplAnnotationOverloaded' : 'preferJsdocPlacement',
|
|
583
|
+
data: {
|
|
584
|
+
name: name
|
|
585
|
+
},
|
|
586
|
+
fix: function fix(fixer) {
|
|
587
|
+
var fixes = [];
|
|
588
|
+
var jsdocText = jsdoc.text;
|
|
589
|
+
var jsdocStart = jsdoc.node.range[0];
|
|
590
|
+
var jsdocEnd = jsdoc.node.range[1];
|
|
591
|
+
var jsdocIndent = getLineIndent(sourceText, jsdocStart);
|
|
592
|
+
// Insert into JSDoc only if needed (preserve idempotency and skip when only orphans need removal).
|
|
593
|
+
if (needsJsdocTag) {
|
|
594
|
+
if (!jsdocText.includes('\n')) {
|
|
595
|
+
// Single-line JSDoc — expand to multi-line so the new tag has its own line.
|
|
596
|
+
var bodyTrimmed = jsdocText.replace(/^\*\s*/, '').replace(/\s*$/, '');
|
|
597
|
+
var newBody = "/**\n".concat(jsdocIndent, " * ").concat(bodyTrimmed, "\n").concat(jsdocIndent, " * ").concat(NO_SIDE_EFFECTS_TAG, "\n").concat(jsdocIndent, " */");
|
|
598
|
+
fixes.push(fixer.replaceTextRange([
|
|
599
|
+
jsdocStart,
|
|
600
|
+
jsdocEnd
|
|
601
|
+
], newBody));
|
|
602
|
+
} else {
|
|
603
|
+
// Multi-line JSDoc — insert a new tag line immediately before the closing `*/` line.
|
|
604
|
+
var closingMarkerStart = jsdocEnd - 2;
|
|
605
|
+
var closingLineStart = closingMarkerStart;
|
|
606
|
+
while(closingLineStart > 0 && sourceText.charAt(closingLineStart - 1) !== '\n'){
|
|
607
|
+
closingLineStart -= 1;
|
|
608
|
+
}
|
|
609
|
+
var insertion = "".concat(jsdocIndent, " * ").concat(NO_SIDE_EFFECTS_TAG, "\n");
|
|
610
|
+
fixes.push(fixer.insertTextBeforeRange([
|
|
611
|
+
closingLineStart,
|
|
612
|
+
closingLineStart
|
|
613
|
+
], insertion));
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
// Overloaded function with no surviving impl annotation — insert the bundler-required
|
|
617
|
+
// line comment directly above the implementation declaration.
|
|
618
|
+
if (needsImplLineCommentForOverload) {
|
|
619
|
+
var implAnchor = getStatementAnchor(node);
|
|
620
|
+
var implStart = implAnchor.range[0];
|
|
621
|
+
var indent = getLineIndent(sourceText, implStart);
|
|
622
|
+
fixes.push(fixer.insertTextBeforeRange([
|
|
623
|
+
implStart,
|
|
624
|
+
implStart
|
|
625
|
+
], "// ".concat(NO_SIDE_EFFECTS_TAG, "\n").concat(indent)));
|
|
626
|
+
}
|
|
627
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
628
|
+
try {
|
|
629
|
+
// Remove the orphan line/block comment annotations.
|
|
630
|
+
for(var _iterator = orphanLineComments[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
631
|
+
var orphan = _step.value;
|
|
632
|
+
var _orphan_range = _sliced_to_array(orphan.range, 2), start = _orphan_range[0], end = _orphan_range[1];
|
|
633
|
+
var removeEnd = end;
|
|
634
|
+
while(removeEnd < sourceText.length && (sourceText.charAt(removeEnd) === ' ' || sourceText.charAt(removeEnd) === '\t')){
|
|
635
|
+
removeEnd += 1;
|
|
636
|
+
}
|
|
637
|
+
if (sourceText.charAt(removeEnd) === '\n') {
|
|
638
|
+
removeEnd += 1;
|
|
639
|
+
}
|
|
640
|
+
var removeStart = start;
|
|
641
|
+
while(removeStart > 0 && (sourceText.charAt(removeStart - 1) === ' ' || sourceText.charAt(removeStart - 1) === '\t')){
|
|
642
|
+
removeStart -= 1;
|
|
643
|
+
}
|
|
644
|
+
fixes.push(fixer.removeRange([
|
|
645
|
+
removeStart,
|
|
646
|
+
removeEnd
|
|
647
|
+
]));
|
|
648
|
+
}
|
|
649
|
+
} catch (err) {
|
|
650
|
+
_didIteratorError = true;
|
|
651
|
+
_iteratorError = err;
|
|
652
|
+
} finally{
|
|
653
|
+
try {
|
|
654
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
655
|
+
_iterator.return();
|
|
656
|
+
}
|
|
657
|
+
} finally{
|
|
658
|
+
if (_didIteratorError) {
|
|
659
|
+
throw _iteratorError;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
return fixes;
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
return {
|
|
668
|
+
FunctionDeclaration: checkFunction
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* ESLint plugin for @dereekb/util rules.
|
|
675
|
+
*
|
|
676
|
+
* Register as a plugin in your flat ESLint config, then enable individual rules
|
|
677
|
+
* under the chosen plugin prefix (e.g. 'dereekb-util/require-no-side-effects').
|
|
678
|
+
*/ var utilEslintPlugin = {
|
|
679
|
+
rules: {
|
|
680
|
+
'require-no-side-effects': utilRequireNoSideEffectsRule,
|
|
681
|
+
'prefer-no-side-effects-in-jsdoc': utilPreferNoSideEffectsInJsdocRule
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
exports.utilEslintPlugin = utilEslintPlugin;
|
|
686
|
+
exports.utilPreferNoSideEffectsInJsdocRule = utilPreferNoSideEffectsInJsdocRule;
|
|
687
|
+
exports.utilRequireNoSideEffectsRule = utilRequireNoSideEffectsRule;
|