eslint-plugin-jest 28.0.0-next.1 → 28.0.0-next.3
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/lib/index.js +0 -2
- package/lib/rules/consistent-test-it.js +3 -3
- package/lib/rules/expect-expect.js +1 -3
- package/lib/rules/max-expects.js +3 -7
- package/lib/rules/max-nested-describe.js +1 -3
- package/lib/rules/no-alias-methods.js +2 -4
- package/lib/rules/no-commented-out-tests.js +1 -3
- package/lib/rules/no-conditional-expect.js +1 -3
- package/lib/rules/no-conditional-in-test.js +1 -3
- package/lib/rules/no-confusing-set-timeout.js +1 -3
- package/lib/rules/no-deprecated-functions.js +2 -5
- package/lib/rules/no-disabled-tests.js +1 -3
- package/lib/rules/no-done-callback.js +5 -9
- package/lib/rules/no-duplicate-hooks.js +4 -7
- package/lib/rules/no-export.js +1 -3
- package/lib/rules/no-focused-tests.js +2 -4
- package/lib/rules/no-hooks.js +3 -4
- package/lib/rules/no-identical-title.js +1 -3
- package/lib/rules/no-interpolation-in-snapshots.js +2 -4
- package/lib/rules/no-jasmine-globals.js +1 -3
- package/lib/rules/no-large-snapshots.js +2 -4
- package/lib/rules/no-mocks-import.js +1 -3
- package/lib/rules/no-restricted-jest-methods.js +2 -4
- package/lib/rules/no-restricted-matchers.js +2 -4
- package/lib/rules/no-standalone-expect.js +6 -9
- package/lib/rules/no-test-prefixes.js +2 -4
- package/lib/rules/no-test-return-statement.js +1 -3
- package/lib/rules/no-untyped-mock-factory.js +10 -7
- package/lib/rules/prefer-called-with.js +2 -4
- package/lib/rules/prefer-comparison-matcher.js +4 -6
- package/lib/rules/prefer-each.js +1 -3
- package/lib/rules/prefer-equality-matcher.js +4 -6
- package/lib/rules/prefer-expect-assertions.js +6 -10
- package/lib/rules/prefer-expect-resolves.js +4 -6
- package/lib/rules/prefer-hooks-in-order.js +2 -4
- package/lib/rules/prefer-hooks-on-top.js +1 -3
- package/lib/rules/prefer-lowercase-title.js +4 -3
- package/lib/rules/prefer-mock-promise-shorthand.js +3 -6
- package/lib/rules/prefer-snapshot-hint.js +3 -5
- package/lib/rules/prefer-spy-on.js +2 -5
- package/lib/rules/prefer-strict-equal.js +2 -4
- package/lib/rules/prefer-to-be.js +3 -6
- package/lib/rules/prefer-to-contain.js +3 -5
- package/lib/rules/prefer-to-have-length.js +4 -6
- package/lib/rules/prefer-todo.js +2 -4
- package/lib/rules/require-hook.js +2 -5
- package/lib/rules/require-to-throw-message.js +2 -4
- package/lib/rules/require-top-level-describe.js +1 -3
- package/lib/rules/unbound-method.js +8 -9
- package/lib/rules/utils/misc.js +6 -18
- package/lib/rules/utils/parseJestFnCall.js +12 -16
- package/lib/rules/valid-describe-callback.js +2 -4
- package/lib/rules/valid-expect-in-promise.js +7 -11
- package/lib/rules/valid-expect.js +7 -14
- package/lib/rules/valid-title.js +3 -4
- package/package.json +4 -4
|
@@ -50,9 +50,12 @@ const determineJestFnType = name => {
|
|
|
50
50
|
return 'unknown';
|
|
51
51
|
};
|
|
52
52
|
const ValidJestFnCallChains = ['afterAll', 'afterEach', 'beforeAll', 'beforeEach', 'describe', 'describe.each', 'describe.only', 'describe.only.each', 'describe.skip', 'describe.skip.each', 'fdescribe', 'fdescribe.each', 'xdescribe', 'xdescribe.each', 'it', 'it.concurrent', 'it.concurrent.failing', 'it.concurrent.each', 'it.concurrent.failing.each', 'it.concurrent.failing.only.each', 'it.concurrent.failing.skip.each', 'it.concurrent.only.each', 'it.concurrent.skip.each', 'it.each', 'it.failing', 'it.failing.each', 'it.only', 'it.only.each', 'it.only.failing', 'it.only.failing.each', 'it.skip', 'it.skip.each', 'it.skip.failing', 'it.skip.failing.each', 'it.todo', 'fit', 'fit.each', 'fit.failing', 'fit.failing.each', 'xit', 'xit.each', 'xit.failing', 'xit.failing.each', 'test', 'test.concurrent', 'test.concurrent.failing', 'test.concurrent.each', 'test.concurrent.failing.each', 'test.concurrent.failing.only.each', 'test.concurrent.failing.skip.each', 'test.concurrent.only.each', 'test.concurrent.skip.each', 'test.each', 'test.failing', 'test.failing.each', 'test.only', 'test.only.each', 'test.only.failing', 'test.only.failing.each', 'test.skip', 'test.skip.each', 'test.skip.failing', 'test.skip.failing.each', 'test.todo', 'xtest', 'xtest.each', 'xtest.failing', 'xtest.failing.each'];
|
|
53
|
+
|
|
54
|
+
// todo: switch back to using declaration merging once https://github.com/typescript-eslint/typescript-eslint/pull/8485
|
|
55
|
+
// is landed
|
|
56
|
+
|
|
53
57
|
const resolvePossibleAliasedGlobal = (global, context) => {
|
|
54
|
-
|
|
55
|
-
const globalAliases = ((_context$settings$jes = context.settings.jest) === null || _context$settings$jes === void 0 ? void 0 : _context$settings$jes.globalAliases) ?? {};
|
|
58
|
+
const globalAliases = context.settings.jest?.globalAliases ?? {};
|
|
56
59
|
const alias = Object.entries(globalAliases).find(([, aliases]) => aliases.includes(global));
|
|
57
60
|
if (alias) {
|
|
58
61
|
return alias[0];
|
|
@@ -79,9 +82,8 @@ const parseJestFnCallWithReason = (node, context) => {
|
|
|
79
82
|
};
|
|
80
83
|
exports.parseJestFnCallWithReason = parseJestFnCallWithReason;
|
|
81
84
|
const parseJestFnCallWithReasonInner = (node, context) => {
|
|
82
|
-
var _node$parent2, _node$parent3;
|
|
83
85
|
const chain = getNodeChain(node);
|
|
84
|
-
if (!
|
|
86
|
+
if (!chain?.length) {
|
|
85
87
|
return null;
|
|
86
88
|
}
|
|
87
89
|
const [first, ...rest] = chain;
|
|
@@ -127,8 +129,7 @@ const parseJestFnCallWithReasonInner = (node, context) => {
|
|
|
127
129
|
return null;
|
|
128
130
|
}
|
|
129
131
|
if (result === 'matcher-not-found') {
|
|
130
|
-
|
|
131
|
-
if (((_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.type) === _utils.AST_NODE_TYPES.MemberExpression) {
|
|
132
|
+
if (node.parent?.type === _utils.AST_NODE_TYPES.MemberExpression) {
|
|
132
133
|
return 'matcher-not-called';
|
|
133
134
|
}
|
|
134
135
|
}
|
|
@@ -136,17 +137,14 @@ const parseJestFnCallWithReasonInner = (node, context) => {
|
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
// check that every link in the chain except the last is a member expression
|
|
139
|
-
if (chain.slice(0, chain.length - 1).some(nod => {
|
|
140
|
-
var _nod$parent;
|
|
141
|
-
return ((_nod$parent = nod.parent) === null || _nod$parent === void 0 ? void 0 : _nod$parent.type) !== _utils.AST_NODE_TYPES.MemberExpression;
|
|
142
|
-
})) {
|
|
140
|
+
if (chain.slice(0, chain.length - 1).some(nod => nod.parent?.type !== _utils.AST_NODE_TYPES.MemberExpression)) {
|
|
143
141
|
return null;
|
|
144
142
|
}
|
|
145
143
|
|
|
146
144
|
// ensure that we're at the "top" of the function call chain otherwise when
|
|
147
145
|
// parsing e.g. x().y.z(), we'll incorrectly find & parse "x()" even though
|
|
148
146
|
// the full chain is not a valid jest function call chain
|
|
149
|
-
if (
|
|
147
|
+
if (node.parent?.type === _utils.AST_NODE_TYPES.CallExpression || node.parent?.type === _utils.AST_NODE_TYPES.MemberExpression) {
|
|
150
148
|
return null;
|
|
151
149
|
}
|
|
152
150
|
return {
|
|
@@ -157,10 +155,9 @@ const parseJestFnCallWithReasonInner = (node, context) => {
|
|
|
157
155
|
const findModifiersAndMatcher = members => {
|
|
158
156
|
const modifiers = [];
|
|
159
157
|
for (const member of members) {
|
|
160
|
-
var _member$parent, _member$parent$parent;
|
|
161
158
|
// check if the member is being called, which means it is the matcher
|
|
162
159
|
// (and also the end of the entire "expect" call chain)
|
|
163
|
-
if (
|
|
160
|
+
if (member.parent?.type === _utils.AST_NODE_TYPES.MemberExpression && member.parent.parent?.type === _utils.AST_NODE_TYPES.CallExpression) {
|
|
164
161
|
return {
|
|
165
162
|
matcher: member,
|
|
166
163
|
args: member.parent.parent.arguments,
|
|
@@ -245,7 +242,6 @@ const findImportSourceNode = node => {
|
|
|
245
242
|
return null;
|
|
246
243
|
};
|
|
247
244
|
const describeVariableDefAsImport = def => {
|
|
248
|
-
var _def$name$parent;
|
|
249
245
|
// make sure that we've actually being assigned a value
|
|
250
246
|
if (!def.node.init) {
|
|
251
247
|
return null;
|
|
@@ -254,7 +250,7 @@ const describeVariableDefAsImport = def => {
|
|
|
254
250
|
if (!sourceNode || !(0, _utils2.isStringNode)(sourceNode)) {
|
|
255
251
|
return null;
|
|
256
252
|
}
|
|
257
|
-
if (
|
|
253
|
+
if (def.name.parent?.type !== _utils.AST_NODE_TYPES.Property) {
|
|
258
254
|
return null;
|
|
259
255
|
}
|
|
260
256
|
if (!(0, _utils2.isSupportedAccessor)(def.name.parent.key)) {
|
|
@@ -293,7 +289,7 @@ const resolveScope = (scope, identifier) => {
|
|
|
293
289
|
if (ref && ref.defs.length > 0) {
|
|
294
290
|
const def = ref.defs[ref.defs.length - 1];
|
|
295
291
|
const importDetails = describePossibleImportDef(def);
|
|
296
|
-
if (
|
|
292
|
+
if (importDetails?.local === identifier) {
|
|
297
293
|
return importDetails;
|
|
298
294
|
}
|
|
299
295
|
return 'local';
|
|
@@ -19,9 +19,7 @@ var _default = exports.default = (0, _utils2.createRule)({
|
|
|
19
19
|
meta: {
|
|
20
20
|
type: 'problem',
|
|
21
21
|
docs: {
|
|
22
|
-
|
|
23
|
-
description: 'Enforce valid `describe()` callback',
|
|
24
|
-
recommended: 'error'
|
|
22
|
+
description: 'Enforce valid `describe()` callback'
|
|
25
23
|
},
|
|
26
24
|
messages: {
|
|
27
25
|
nameAndCallback: 'Describe requires name and callback arguments',
|
|
@@ -37,7 +35,7 @@ var _default = exports.default = (0, _utils2.createRule)({
|
|
|
37
35
|
return {
|
|
38
36
|
CallExpression(node) {
|
|
39
37
|
const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
|
|
40
|
-
if (
|
|
38
|
+
if (jestFnCall?.type !== 'describe') {
|
|
41
39
|
return;
|
|
42
40
|
}
|
|
43
41
|
if (node.arguments.length < 1) {
|
|
@@ -24,7 +24,7 @@ const isPromiseChainCall = node => {
|
|
|
24
24
|
};
|
|
25
25
|
const isTestCaseCallWithCallbackArg = (node, context) => {
|
|
26
26
|
const jestCallFn = (0, _utils2.parseJestFnCall)(node, context);
|
|
27
|
-
if (
|
|
27
|
+
if (jestCallFn?.type !== 'test') {
|
|
28
28
|
return false;
|
|
29
29
|
}
|
|
30
30
|
const isJestEach = jestCallFn.members.some(s => (0, _utils2.getAccessorValue)(s) === 'each');
|
|
@@ -67,10 +67,10 @@ const isPromiseMethodThatUsesValue = (node, identifier) => {
|
|
|
67
67
|
*/
|
|
68
68
|
const isValueAwaitedInElements = (name, elements) => {
|
|
69
69
|
for (const element of elements) {
|
|
70
|
-
if (
|
|
70
|
+
if (element?.type === _utils.AST_NODE_TYPES.AwaitExpression && (0, _utils2.isIdentifier)(element.argument, name)) {
|
|
71
71
|
return true;
|
|
72
72
|
}
|
|
73
|
-
if (
|
|
73
|
+
if (element?.type === _utils.AST_NODE_TYPES.ArrayExpression && isValueAwaitedInElements(name, element.elements)) {
|
|
74
74
|
return true;
|
|
75
75
|
}
|
|
76
76
|
}
|
|
@@ -138,7 +138,7 @@ const isValueAwaitedOrReturned = (identifier, body, context) => {
|
|
|
138
138
|
}
|
|
139
139
|
const leftMostCall = getLeftMostCallExpression(node.expression);
|
|
140
140
|
const jestFnCall = (0, _utils2.parseJestFnCall)(node.expression, context);
|
|
141
|
-
if (
|
|
141
|
+
if (jestFnCall?.type === 'expect' && leftMostCall.arguments.length > 0 && (0, _utils2.isIdentifier)(leftMostCall.arguments[0], name)) {
|
|
142
142
|
if (jestFnCall.members.some(m => {
|
|
143
143
|
const v = (0, _utils2.getAccessorValue)(m);
|
|
144
144
|
return v === _utils2.ModifierName.resolves || v === _utils2.ModifierName.rejects;
|
|
@@ -154,10 +154,9 @@ const isValueAwaitedOrReturned = (identifier, body, context) => {
|
|
|
154
154
|
// (re)assignment changes the runtime value, so if we've not found an
|
|
155
155
|
// await or return already we act as if we've reached the end of the body
|
|
156
156
|
if (node.expression.type === _utils.AST_NODE_TYPES.AssignmentExpression) {
|
|
157
|
-
var _getNodeName;
|
|
158
157
|
// unless we're assigning to the same identifier, in which case
|
|
159
158
|
// we might be chaining off the existing promise value
|
|
160
|
-
if ((0, _utils2.isIdentifier)(node.expression.left, name) && (
|
|
159
|
+
if ((0, _utils2.isIdentifier)(node.expression.left, name) && (0, _utils2.getNodeName)(node.expression.right)?.startsWith(`${name}.`) && isPromiseChainCall(node.expression.right)) {
|
|
161
160
|
continue;
|
|
162
161
|
}
|
|
163
162
|
break;
|
|
@@ -185,9 +184,8 @@ const isDirectlyWithinTestCaseCall = (node, context) => {
|
|
|
185
184
|
let parent = node;
|
|
186
185
|
while (parent) {
|
|
187
186
|
if ((0, _utils2.isFunction)(parent)) {
|
|
188
|
-
var _parent;
|
|
189
187
|
parent = parent.parent;
|
|
190
|
-
return
|
|
188
|
+
return parent?.type === _utils.AST_NODE_TYPES.CallExpression && (0, _utils2.isTypeOfJestFnCall)(parent, context, ['test']);
|
|
191
189
|
}
|
|
192
190
|
parent = parent.parent;
|
|
193
191
|
}
|
|
@@ -207,9 +205,7 @@ var _default = exports.default = (0, _utils2.createRule)({
|
|
|
207
205
|
name: __filename,
|
|
208
206
|
meta: {
|
|
209
207
|
docs: {
|
|
210
|
-
|
|
211
|
-
description: 'Require promises that have expectations in their chain to be valid',
|
|
212
|
-
recommended: 'error'
|
|
208
|
+
description: 'Require promises that have expectations in their chain to be valid'
|
|
213
209
|
},
|
|
214
210
|
messages: {
|
|
215
211
|
expectInFloatingPromise: 'This promise should either be returned or awaited to ensure the expects in its chain are called'
|
|
@@ -27,13 +27,9 @@ const getPromiseCallExpressionNode = node => {
|
|
|
27
27
|
}
|
|
28
28
|
return null;
|
|
29
29
|
};
|
|
30
|
-
const findPromiseCallExpressionNode = node =>
|
|
31
|
-
var _node$parent;
|
|
32
|
-
return (_node$parent = node.parent) !== null && _node$parent !== void 0 && _node$parent.parent && [_utils.AST_NODE_TYPES.CallExpression, _utils.AST_NODE_TYPES.ArrayExpression].includes(node.parent.type) ? getPromiseCallExpressionNode(node.parent) : null;
|
|
33
|
-
};
|
|
30
|
+
const findPromiseCallExpressionNode = node => node.parent?.parent && [_utils.AST_NODE_TYPES.CallExpression, _utils.AST_NODE_TYPES.ArrayExpression].includes(node.parent.type) ? getPromiseCallExpressionNode(node.parent) : null;
|
|
34
31
|
const getParentIfThenified = node => {
|
|
35
|
-
|
|
36
|
-
const grandParentNode = (_node$parent2 = node.parent) === null || _node$parent2 === void 0 ? void 0 : _node$parent2.parent;
|
|
32
|
+
const grandParentNode = node.parent?.parent;
|
|
37
33
|
if (grandParentNode && grandParentNode.type === _utils.AST_NODE_TYPES.CallExpression && grandParentNode.callee.type === _utils.AST_NODE_TYPES.MemberExpression && (0, _utils2.isSupportedAccessor)(grandParentNode.callee.property) && ['then', 'catch'].includes((0, _utils2.getAccessorValue)(grandParentNode.callee.property)) && grandParentNode.parent) {
|
|
38
34
|
// Just in case `then`s are chained look one above.
|
|
39
35
|
return getParentIfThenified(grandParentNode);
|
|
@@ -58,9 +54,7 @@ var _default = exports.default = (0, _utils2.createRule)({
|
|
|
58
54
|
name: __filename,
|
|
59
55
|
meta: {
|
|
60
56
|
docs: {
|
|
61
|
-
|
|
62
|
-
description: 'Enforce valid `expect()` usage',
|
|
63
|
-
recommended: 'error'
|
|
57
|
+
description: 'Enforce valid `expect()` usage'
|
|
64
58
|
},
|
|
65
59
|
messages: {
|
|
66
60
|
tooManyArgs: 'Expect takes at most {{ amount }} argument{{ s }}',
|
|
@@ -139,8 +133,7 @@ var _default = exports.default = (0, _utils2.createRule)({
|
|
|
139
133
|
CallExpression(node) {
|
|
140
134
|
const jestFnCall = (0, _utils2.parseJestFnCallWithReason)(node, context);
|
|
141
135
|
if (typeof jestFnCall === 'string') {
|
|
142
|
-
|
|
143
|
-
const reportingNode = ((_node$parent3 = node.parent) === null || _node$parent3 === void 0 ? void 0 : _node$parent3.type) === _utils.AST_NODE_TYPES.MemberExpression ? findTopMostMemberExpression(node.parent).property : node;
|
|
136
|
+
const reportingNode = node.parent?.type === _utils.AST_NODE_TYPES.MemberExpression ? findTopMostMemberExpression(node.parent).property : node;
|
|
144
137
|
if (jestFnCall === 'matcher-not-found') {
|
|
145
138
|
context.report({
|
|
146
139
|
messageId: 'matcherNotFound',
|
|
@@ -162,13 +155,13 @@ var _default = exports.default = (0, _utils2.createRule)({
|
|
|
162
155
|
return;
|
|
163
156
|
}
|
|
164
157
|
return;
|
|
165
|
-
} else if (
|
|
158
|
+
} else if (jestFnCall?.type !== 'expect') {
|
|
166
159
|
return;
|
|
167
160
|
}
|
|
168
161
|
const {
|
|
169
162
|
parent: expect
|
|
170
163
|
} = jestFnCall.head.node;
|
|
171
|
-
if (
|
|
164
|
+
if (expect?.type !== _utils.AST_NODE_TYPES.CallExpression) {
|
|
172
165
|
return;
|
|
173
166
|
}
|
|
174
167
|
if (expect.arguments.length < minArgs) {
|
|
@@ -222,7 +215,7 @@ var _default = exports.default = (0, _utils2.createRule)({
|
|
|
222
215
|
} = jestFnCall;
|
|
223
216
|
const parentNode = matcher.parent.parent;
|
|
224
217
|
const shouldBeAwaited = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) !== 'not') || asyncMatchers.includes((0, _utils2.getAccessorValue)(matcher));
|
|
225
|
-
if (!
|
|
218
|
+
if (!parentNode?.parent || !shouldBeAwaited) {
|
|
226
219
|
return;
|
|
227
220
|
}
|
|
228
221
|
/**
|
package/lib/rules/valid-title.js
CHANGED
|
@@ -49,9 +49,7 @@ var _default = exports.default = (0, _utils2.createRule)({
|
|
|
49
49
|
name: __filename,
|
|
50
50
|
meta: {
|
|
51
51
|
docs: {
|
|
52
|
-
|
|
53
|
-
description: 'Enforce valid titles',
|
|
54
|
-
recommended: 'error'
|
|
52
|
+
description: 'Enforce valid titles'
|
|
55
53
|
},
|
|
56
54
|
messages: {
|
|
57
55
|
titleMustBeString: 'Title must be a string',
|
|
@@ -93,6 +91,7 @@ var _default = exports.default = (0, _utils2.createRule)({
|
|
|
93
91
|
type: 'string'
|
|
94
92
|
}, MatcherAndMessageSchema, {
|
|
95
93
|
type: 'object',
|
|
94
|
+
// @ts-expect-error https://github.com/eslint/eslint/discussions/17573
|
|
96
95
|
propertyNames: {
|
|
97
96
|
enum: ['describe', 'test', 'it']
|
|
98
97
|
},
|
|
@@ -128,7 +127,7 @@ var _default = exports.default = (0, _utils2.createRule)({
|
|
|
128
127
|
return {
|
|
129
128
|
CallExpression(node) {
|
|
130
129
|
const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
|
|
131
|
-
if (
|
|
130
|
+
if (jestFnCall?.type !== 'describe' && jestFnCall?.type !== 'test') {
|
|
132
131
|
return;
|
|
133
132
|
}
|
|
134
133
|
const [argument] = node.arguments;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-jest",
|
|
3
|
-
"version": "28.0.0-next.
|
|
3
|
+
"version": "28.0.0-next.3",
|
|
4
4
|
"description": "ESLint rules for Jest",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
]
|
|
96
96
|
},
|
|
97
97
|
"dependencies": {
|
|
98
|
-
"@typescript-eslint/utils": "^
|
|
98
|
+
"@typescript-eslint/utils": "^6.0.0"
|
|
99
99
|
},
|
|
100
100
|
"devDependencies": {
|
|
101
101
|
"@babel/cli": "^7.4.4",
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
"@schemastore/package": "^0.0.10",
|
|
108
108
|
"@semantic-release/changelog": "^6.0.0",
|
|
109
109
|
"@semantic-release/git": "^10.0.0",
|
|
110
|
-
"@tsconfig/
|
|
110
|
+
"@tsconfig/node16": "^16.0.0",
|
|
111
111
|
"@types/eslint": "^8.4.6",
|
|
112
112
|
"@types/jest": "^29.0.0",
|
|
113
113
|
"@types/node": "^14.18.26",
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
},
|
|
157
157
|
"packageManager": "yarn@3.8.1",
|
|
158
158
|
"engines": {
|
|
159
|
-
"node": "^
|
|
159
|
+
"node": "^16.10.0 || >=18.0.0"
|
|
160
160
|
},
|
|
161
161
|
"publishConfig": {
|
|
162
162
|
"provenance": true
|