@deslop/coding-standards 0.1.1241 → 0.1.1243
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/README.md +1 -1
- package/dist/install.js +1 -1
- package/dist/lint.js +135 -122
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ export default defineConfig({lint: {extends: [lint]}})
|
|
|
21
21
|
{
|
|
22
22
|
"scripts": {
|
|
23
23
|
"prepare": "effect-tsgo patch --no-typescript --tsrs",
|
|
24
|
-
"typecheck": "tsrs --
|
|
24
|
+
"typecheck": "tsrs --checkerAssignment go --pretty false",
|
|
25
25
|
"check": "vp check && vp run typecheck"
|
|
26
26
|
}
|
|
27
27
|
}
|
package/dist/install.js
CHANGED
|
@@ -27604,7 +27604,7 @@ const runWith = (command, config) => {
|
|
|
27604
27604
|
}, ({ error, userMessage }) => andThen(showUserError(error, userMessage), fail$3(error))), catchFilter((e) => isQuitError(e) ? succeed$6(e) : fail$8(e), (_) => interrupt$1));
|
|
27605
27605
|
};
|
|
27606
27606
|
// package.json
|
|
27607
|
-
var version = "0.1.
|
|
27607
|
+
var version = "0.1.1243";
|
|
27608
27608
|
// src/install.ts
|
|
27609
27609
|
const cli = pipe(make("deslop-coding-standards", {}, fnUntraced(function* () {
|
|
27610
27610
|
const fs = yield* FileSystem;
|
package/dist/lint.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as join, A as dedupe, At as all, B as findFirstIndex, Br as isRegExp, Bt as getOrElse, C as TaggedError, D as contains, E as appendAll, Er as hasProperty, F as ensure, Fr as isNullish, Ft as firstSomeOf, Gr as constFalse, Gt as liftThrowable, H as flatMap, Ht as isNone, I as every, Ir as isNumber$1, It as flatMap$1, J as head, Jr as constVoid, Jt as none, K as get$3, Kt as map
|
|
1
|
+
import { $ as join, A as dedupe, At as all, B as findFirstIndex, Br as isRegExp, Bt as getOrElse, C as TaggedError, D as contains, E as appendAll, Er as hasProperty, F as ensure, Fr as isNullish, Ft as firstSomeOf, Gr as constFalse, Gt as liftThrowable, H as flatMap, Ht as isNone, I as every, Ir as isNumber$1, It as flatMap$1, J as head, Jr as constVoid, Jt as none, K as get$3, Kt as map, L as filter$1, Lt as flatten$1, M as drop, Mr as isNotNull, Mt as contains$1, N as dropRight, Nr as isNotNullish, Nt as exists, O as containsWith, Or as isBoolean, P as empty$2, Pt as filter, Q as isReadonlyArrayNonEmpty, Qt as zipWith, R as filterMap, Rt as fromNullishOr, Sr as string, St as fromOption, T as append, Tr as symbol$1, U as flatten, Ut as isSome, Vr as isString, Vt as getOrUndefined, W as forEach, Wt as liftPredicate, X as isArrayNonEmpty, Xr as dual, Xt as some, Y as isArrayEmpty, Yt as orElse, Zt as toArray$1, _ as toUpperCase, ar as format, at as of, b as parse, br as number, c as Order, ct as some$1, d as match$1, dt as takeWhile, ei as pipe, et as last, f as matchAll, ft as zip, g as startsWith, gr as symbol, h as split, hr as equals, ht as has$2, i as make$2, it as matchRight, j as dedupeWith, jt as as, k as countBy, l as includes, lt as sort, m as slice, mr as byReferenceUnsafe, mt as get$2, n as append$1, nr as NodeInspectSymbol, nt as map$1, ot as prepend, p as replaceAll, pt as fromEntries, q as getSomes, qt as match, ri as pipeArguments, rr as toJson, s as toArray, t as match$2, u as isNonEmpty, un as strictEqual, ut as take, v as trim, vr as combine, vt as mapEntries, xr as optimize, yr as hash, z as findFirst, zt as fromUndefinedOr } from "./Boolean-C8Zb2yak.mjs";
|
|
2
2
|
import { definePlugin, defineRule } from "vite-plus/lint/plugins";
|
|
3
3
|
// ../../node_modules/.pnpm/effect@4.1.2/node_modules/effect/dist/MutableHashMap.js
|
|
4
4
|
const TypeId$2 = "~effect/MutableHashMap";
|
|
@@ -962,6 +962,12 @@ function variableFromScope(input) {
|
|
|
962
962
|
function boundVariable(input) {
|
|
963
963
|
return filter(variableFromScope(input), (variable) => isArrayNonEmpty(variable.defs) || isArrayNonEmpty(variable.references));
|
|
964
964
|
}
|
|
965
|
+
function readsOf(input) {
|
|
966
|
+
return pipe(variableFromScope({
|
|
967
|
+
name: input.name,
|
|
968
|
+
scope: input.context.sourceCode.getScope(input.node)
|
|
969
|
+
}), map((variable) => filter$1(variable.references, (reference) => reference.isRead())));
|
|
970
|
+
}
|
|
965
971
|
function variableFor(context, node) {
|
|
966
972
|
return variableFromScope({
|
|
967
973
|
name: node.name,
|
|
@@ -971,7 +977,7 @@ function variableFor(context, node) {
|
|
|
971
977
|
const importedNames = /* @__PURE__ */ new WeakMap();
|
|
972
978
|
function importNames(statements) {
|
|
973
979
|
return flatMap(statements, (statement) => {
|
|
974
|
-
if (statement.type === "ImportDeclaration") return map(statement.specifiers, (specifier) => specifier.local.name);
|
|
980
|
+
if (statement.type === "ImportDeclaration") return map$1(statement.specifiers, (specifier) => specifier.local.name);
|
|
975
981
|
if (statement.type === "TSModuleDeclaration" && statement.body?.type === "TSModuleBlock") return importNames(statement.body.body);
|
|
976
982
|
return [];
|
|
977
983
|
});
|
|
@@ -1004,8 +1010,8 @@ function effectImport(input) {
|
|
|
1004
1010
|
}), filter((variable) => isArrayNonEmpty(variable.defs)), match({
|
|
1005
1011
|
onNone: () => pipe(input.context.sourceCode.ast.body, findFirst((statement) => statement.type === "ImportDeclaration" && statement.source.value === "effect" && statement.importKind !== "type" && every(statement.specifiers, (specifier) => specifier.type === "ImportSpecifier")), flatMap$1((statement) => {
|
|
1006
1012
|
if (statement.type !== "ImportDeclaration") return none();
|
|
1007
|
-
return pipe(findFirst(statement.specifiers, (specifier) => Order(importedName(specifier), input.name) > 0), map
|
|
1008
|
-
}), orElse(() => map
|
|
1013
|
+
return pipe(findFirst(statement.specifiers, (specifier) => Order(importedName(specifier), input.name) > 0), map((specifier) => input.fixer.insertTextBefore(specifier, `${input.name}, `)), orElse(() => map(last(statement.specifiers), (specifier) => input.fixer.insertTextAfter(specifier, `, ${input.name}`))));
|
|
1014
|
+
}), orElse(() => map(findFirst(input.context.sourceCode.ast.body, (statement) => statement.type !== "ExpressionStatement" || isNullish(statement.directive)), (statement) => input.fixer.insertTextBefore(statement, `import {${input.name}} from 'effect'\n`))), map(of)),
|
|
1009
1015
|
onSome: (variable) => liftPredicate(empty$2(), () => some$1(variable.defs, (definition) => definition.type === "ImportBinding" && definition.parent?.type === "ImportDeclaration" && definition.parent.source.value === "effect" && definition.parent.importKind !== "type" && definition.node.type === "ImportSpecifier" && definition.node.importKind !== "type" && definition.node.imported.type === "Identifier" && definition.node.imported.name === input.name))
|
|
1010
1016
|
}));
|
|
1011
1017
|
}
|
|
@@ -1066,11 +1072,11 @@ function chainOf(node) {
|
|
|
1066
1072
|
members: [],
|
|
1067
1073
|
root: node
|
|
1068
1074
|
});
|
|
1069
|
-
if (node.type === "MemberExpression") return flatMap$1(memberName(node), (name) => map
|
|
1075
|
+
if (node.type === "MemberExpression") return flatMap$1(memberName(node), (name) => map(chainOf(node.object), (chain) => ({
|
|
1070
1076
|
...chain,
|
|
1071
1077
|
members: append(chain.members, name)
|
|
1072
1078
|
})));
|
|
1073
|
-
if (node.type === "CallExpression") return map
|
|
1079
|
+
if (node.type === "CallExpression") return map(chainOf(node.callee), (chain) => ({
|
|
1074
1080
|
...chain,
|
|
1075
1081
|
calls: append(chain.calls, node)
|
|
1076
1082
|
}));
|
|
@@ -1133,7 +1139,7 @@ function propertyKey(property) {
|
|
|
1133
1139
|
}
|
|
1134
1140
|
function optionKeys(node) {
|
|
1135
1141
|
if (node.type !== "ObjectExpression") return empty$2();
|
|
1136
|
-
return getSomes(map(node.properties, propertyKey));
|
|
1142
|
+
return getSomes(map$1(node.properties, propertyKey));
|
|
1137
1143
|
}
|
|
1138
1144
|
function isTestClockMember(context, node, propertyName) {
|
|
1139
1145
|
return node.type === "MemberExpression" && node.object.type === "Identifier" && contains$1(memberName(node), propertyName) && isImportBinding({
|
|
@@ -1165,6 +1171,14 @@ function importedMember(input) {
|
|
|
1165
1171
|
source: "effect"
|
|
1166
1172
|
});
|
|
1167
1173
|
}
|
|
1174
|
+
function effectMethod(input) {
|
|
1175
|
+
if (input.node.callee.type !== "MemberExpression" || !importedMember({
|
|
1176
|
+
context: input.context,
|
|
1177
|
+
importedName: "Effect",
|
|
1178
|
+
node: input.node.callee
|
|
1179
|
+
})) return none();
|
|
1180
|
+
return memberName(input.node.callee);
|
|
1181
|
+
}
|
|
1168
1182
|
function isWriteTarget(node) {
|
|
1169
1183
|
if (node.parent === null) return false;
|
|
1170
1184
|
return (node.parent.type === "AssignmentExpression" || node.parent.type === "AssignmentPattern") && node.parent.left === node || node.parent.type === "ArrayPattern" || node.parent.type === "RestElement" || node.parent.type === "Property" && node.parent.value === node && node.parent.parent.type === "ObjectPattern" || (node.parent.type === "ForInStatement" || node.parent.type === "ForOfStatement") && node.parent.left === node || node.parent.type === "UpdateExpression" || node.parent.type === "UnaryExpression" && node.parent.operator === "delete";
|
|
@@ -1266,12 +1280,12 @@ function suspendedTypeName(input) {
|
|
|
1266
1280
|
}
|
|
1267
1281
|
function memberType(member) {
|
|
1268
1282
|
if (member.type === "TSIndexSignature") return some(member.typeAnnotation.typeAnnotation);
|
|
1269
|
-
if (member.type === "TSPropertySignature") return map
|
|
1270
|
-
return map
|
|
1283
|
+
if (member.type === "TSPropertySignature") return map(fromNullishOr(member.typeAnnotation), (annotation) => annotation.typeAnnotation);
|
|
1284
|
+
return map(fromNullishOr(member.returnType), (annotation) => annotation.typeAnnotation);
|
|
1271
1285
|
}
|
|
1272
1286
|
function referencedTypeNames(node) {
|
|
1273
1287
|
if (node.type === "TSTypeReference") {
|
|
1274
|
-
const argumentNames = pipe(fromNullishOr(node.typeArguments), map
|
|
1288
|
+
const argumentNames = pipe(fromNullishOr(node.typeArguments), map((typeArguments) => pipe(typeArguments.params, flatMap(referencedTypeNames))), getOrElse(() => empty$2()));
|
|
1275
1289
|
if (node.typeName.type !== "Identifier") return argumentNames;
|
|
1276
1290
|
return prepend(argumentNames, node.typeName.name);
|
|
1277
1291
|
}
|
|
@@ -1293,8 +1307,8 @@ function referencedTypeNames(node) {
|
|
|
1293
1307
|
node.constraint,
|
|
1294
1308
|
node.nameType,
|
|
1295
1309
|
node.typeAnnotation
|
|
1296
|
-
], map((child) => fromNullishOr(child)), getSomes, flatMap(referencedTypeNames));
|
|
1297
|
-
if (node.type === "TSTypeLiteral") return pipe(node.members, map(memberType), getSomes, flatMap(referencedTypeNames));
|
|
1310
|
+
], map$1((child) => fromNullishOr(child)), getSomes, flatMap(referencedTypeNames));
|
|
1311
|
+
if (node.type === "TSTypeLiteral") return pipe(node.members, map$1(memberType), getSomes, flatMap(referencedTypeNames));
|
|
1298
1312
|
return empty$2();
|
|
1299
1313
|
}
|
|
1300
1314
|
function isNode(value) {
|
|
@@ -1379,12 +1393,12 @@ function schemaEdges(context, statement) {
|
|
|
1379
1393
|
function schemaCycleNames(input) {
|
|
1380
1394
|
if (isArrayEmpty(input.seeds) || !some$1(input.program.body, (statement) => statement.type === "ImportDeclaration" && statement.source.value === "effect" && some$1(statement.specifiers, (specifier) => specifier.type === "ImportSpecifier" && specifier.imported.type === "Identifier" && specifier.imported.name === "Schema"))) return empty$2();
|
|
1381
1395
|
const edges = pipe(input.program.body, flatMap((statement) => schemaEdges(input.context, statement)));
|
|
1382
|
-
const names = pipe(edges, map((edge) => edge.name), dedupe);
|
|
1396
|
+
const names = pipe(edges, map$1((edge) => edge.name), dedupe);
|
|
1383
1397
|
const graph = directed((mutable) => {
|
|
1384
|
-
const indices = fromEntries(map(names, (name) => [name, addNode(mutable, name)]));
|
|
1398
|
+
const indices = fromEntries(map$1(names, (name) => [name, addNode(mutable, name)]));
|
|
1385
1399
|
for (const edge of edges) for (const target of edge.targets) zipWith(get$2(indices, edge.name), get$2(indices, target), (source, sink) => addEdge(mutable, source, sink, "reads"));
|
|
1386
1400
|
});
|
|
1387
|
-
return pipe(stronglyConnectedComponents(graph), map((component) => getSomes(map(component, (index) => getNode(graph, index)))), filter$1((component) => (component.length > 1 || some$1(edges, (edge) => contains(component, edge.name) && contains(edge.targets, edge.name))) && some$1(component, (name) => contains(input.seeds, name))), flatten);
|
|
1401
|
+
return pipe(stronglyConnectedComponents(graph), map$1((component) => getSomes(map$1(component, (index) => getNode(graph, index)))), filter$1((component) => (component.length > 1 || some$1(edges, (edge) => contains(component, edge.name) && contains(edge.targets, edge.name))) && some$1(component, (name) => contains(input.seeds, name))), flatten);
|
|
1388
1402
|
}
|
|
1389
1403
|
function suspends(context, node) {
|
|
1390
1404
|
if (node.type === "YieldExpression" || node.type === "AwaitExpression") return true;
|
|
@@ -1432,12 +1446,16 @@ function bindingName(node) {
|
|
|
1432
1446
|
if (node.parent.type === "VariableDeclarator" && node.parent.id.type === "Identifier") return some(node.parent.id.name);
|
|
1433
1447
|
return none();
|
|
1434
1448
|
}
|
|
1449
|
+
function boundReads(input) {
|
|
1450
|
+
return pipe(bindingName(input.node), flatMap$1((name) => readsOf({
|
|
1451
|
+
context: input.context,
|
|
1452
|
+
name,
|
|
1453
|
+
node: input.node
|
|
1454
|
+
})));
|
|
1455
|
+
}
|
|
1435
1456
|
function singleUseThunk(input) {
|
|
1436
1457
|
if (isReadonlyArrayNonEmpty(input.node.params) || input.node.typeParameters !== null || !hasSingleStatementExpression(input.node)) return false;
|
|
1437
|
-
return
|
|
1438
|
-
name,
|
|
1439
|
-
scope: input.context.sourceCode.getScope(input.node)
|
|
1440
|
-
})), exists((variable) => countBy(variable.references, (reference) => reference.isRead()) === 1));
|
|
1458
|
+
return exists(boundReads(input), (reads) => reads.length === 1);
|
|
1441
1459
|
}
|
|
1442
1460
|
// src/rules/explicit-effect-concurrency.ts
|
|
1443
1461
|
function statesConcurrency(node) {
|
|
@@ -1477,13 +1495,11 @@ function isFunction(context, node) {
|
|
|
1477
1495
|
}
|
|
1478
1496
|
const explicitEffectConcurrency = defineRule({
|
|
1479
1497
|
create: (context) => ({ CallExpression: (node) => {
|
|
1480
|
-
|
|
1481
|
-
const name = memberName(node.callee);
|
|
1482
|
-
if (!exists(name, (method) => method === "all" || method === "forEach") || !importedMember({
|
|
1498
|
+
const name = effectMethod({
|
|
1483
1499
|
context,
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1500
|
+
node
|
|
1501
|
+
});
|
|
1502
|
+
if (!exists(name, (method) => method === "all" || method === "forEach")) return;
|
|
1487
1503
|
const index = match$2(contains$1(name, "all") || isFunction(context, node.arguments[0]) || node.arguments[1]?.type === "ObjectExpression", {
|
|
1488
1504
|
onFalse: () => 2,
|
|
1489
1505
|
onTrue: () => 1
|
|
@@ -1622,14 +1638,14 @@ function check$3(input) {
|
|
|
1622
1638
|
}
|
|
1623
1639
|
if (!isConstantName(input.found.id.name)) {
|
|
1624
1640
|
const name = pipe(input.found.id.name, replaceAll(/(?<=[a-z0-9])(?=[A-Z])/gu, "_"), toUpperCase);
|
|
1625
|
-
const taken = some$1([input.found.id, ...map(input.variable.references, (reference) => reference.identifier)], (node) => isSome(variableFromScope({
|
|
1641
|
+
const taken = some$1([input.found.id, ...map$1(input.variable.references, (reference) => reference.identifier)], (node) => isSome(variableFromScope({
|
|
1626
1642
|
name,
|
|
1627
1643
|
scope: input.context.sourceCode.getScope(node)
|
|
1628
1644
|
})));
|
|
1629
1645
|
input.context.report({
|
|
1630
1646
|
fix: (fixer) => {
|
|
1631
1647
|
if (taken) return [];
|
|
1632
|
-
return [fixer.replaceTextRange([input.found.id.range[0], input.found.id.range[0] + input.found.id.name.length], name), ...pipe(input.variable.references, filter$1((reference) => reference.identifier !== input.found.id), map((reference) => renamed({
|
|
1648
|
+
return [fixer.replaceTextRange([input.found.id.range[0], input.found.id.range[0] + input.found.id.name.length], name), ...pipe(input.variable.references, filter$1((reference) => reference.identifier !== input.found.id), map$1((reference) => renamed({
|
|
1633
1649
|
fixer,
|
|
1634
1650
|
name,
|
|
1635
1651
|
reference
|
|
@@ -1646,11 +1662,11 @@ function check$3(input) {
|
|
|
1646
1662
|
}
|
|
1647
1663
|
const moduleConstant = defineRule({
|
|
1648
1664
|
create: (context) => ({ Program: (program) => {
|
|
1649
|
-
const leadingEnd = pipe(program.body, takeWhile((statement) => statement.type === "ImportDeclaration" || isSome(literalConstant(statement))), last, map
|
|
1665
|
+
const leadingEnd = pipe(program.body, takeWhile((statement) => statement.type === "ImportDeclaration" || isSome(literalConstant(statement))), last, map((statement) => statement.range[1]), getOrElse(() => 0));
|
|
1650
1666
|
for (const statement of program.body) pipe(literalConstant(statement), flatMap$1((found) => pipe(variableFromScope({
|
|
1651
1667
|
name: found.id.name,
|
|
1652
1668
|
scope: context.sourceCode.getScope(found.node)
|
|
1653
|
-
}), filter((variable) => !some$1(variable.references, (reference) => reference.identifier.parent.type === "ExportSpecifier")), map
|
|
1669
|
+
}), filter((variable) => !some$1(variable.references, (reference) => reference.identifier.parent.type === "ExportSpecifier")), map((variable) => ({
|
|
1654
1670
|
found,
|
|
1655
1671
|
variable
|
|
1656
1672
|
})))), match({
|
|
@@ -1670,7 +1686,7 @@ const moduleConstant = defineRule({
|
|
|
1670
1686
|
// src/rules/motion-limits.ts
|
|
1671
1687
|
const MOTION_UTILITY = /duration-|zoom-|scale-/u;
|
|
1672
1688
|
function amount(token, pattern) {
|
|
1673
|
-
return pipe(token, match$1(pattern), flatMap$1((match) => fromNullishOr(match[1])), map
|
|
1689
|
+
return pipe(token, match$1(pattern), flatMap$1((match) => fromNullishOr(match[1])), map((value) => pipe(parse(value), getOrElse(() => 0))));
|
|
1674
1690
|
}
|
|
1675
1691
|
function violation(token) {
|
|
1676
1692
|
const name = pipe(token, split(":"), last, getOrElse(() => token), replaceAll(/^!|!$/gu, ""));
|
|
@@ -1681,7 +1697,7 @@ function violation(token) {
|
|
|
1681
1697
|
}
|
|
1682
1698
|
function check$2(context, node, text) {
|
|
1683
1699
|
if (!MOTION_UTILITY.test(text)) return;
|
|
1684
|
-
pipe(split(text, /\s+/u), findFirst(violation), map
|
|
1700
|
+
pipe(split(text, /\s+/u), findFirst(violation), map((message) => context.report({
|
|
1685
1701
|
message,
|
|
1686
1702
|
node
|
|
1687
1703
|
})));
|
|
@@ -1776,8 +1792,8 @@ const noAccumulatingCopy = defineRule({
|
|
|
1776
1792
|
pipe(variableFromScope({
|
|
1777
1793
|
name: parameter.name,
|
|
1778
1794
|
scope: context.sourceCode.getScope(callback)
|
|
1779
|
-
}), map
|
|
1780
|
-
for (const reference of variable.references) pipe(copySite(context, reference.identifier), filter((copy) => !has(reported, copy.range[0])), map
|
|
1795
|
+
}), map((variable) => {
|
|
1796
|
+
for (const reference of variable.references) pipe(copySite(context, reference.identifier), filter((copy) => !has(reported, copy.range[0])), map((copy) => {
|
|
1781
1797
|
add(reported, copy.range[0]);
|
|
1782
1798
|
context.report({
|
|
1783
1799
|
message: "Copying the accumulator in a fold can make collection building quadratic. Prefer Array.map/filterMap/flatMap/groupBy, Record.fromEntries, Array.mapAccum, or a local MutableList/MutableHashMap collector.",
|
|
@@ -1850,10 +1866,7 @@ const noComponentAtomAllocation = defineRule({
|
|
|
1850
1866
|
function isConstantFunction(input) {
|
|
1851
1867
|
if (input.node.async || input.node.generator || isArrayNonEmpty(input.node.params) || isNotNullish(input.node.typeParameters)) return false;
|
|
1852
1868
|
const returned = returnedExpression(input.node);
|
|
1853
|
-
return isNotNullish(returned) && (returned.type === "Literal" && !hasProperty(returned, "regex") || returned.type === "TemplateLiteral" && isArrayEmpty(returned.expressions)) &&
|
|
1854
|
-
name,
|
|
1855
|
-
scope: input.context.sourceCode.getScope(input.node)
|
|
1856
|
-
})), exists((variable) => every(filter$1(variable.references, (reference) => reference.isRead()), (reference) => reference.identifier.parent.type === "CallExpression" && reference.identifier.parent.callee === reference.identifier)));
|
|
1869
|
+
return isNotNullish(returned) && (returned.type === "Literal" && !hasProperty(returned, "regex") || returned.type === "TemplateLiteral" && isArrayEmpty(returned.expressions)) && exists(boundReads(input), (reads) => every(reads, (reference) => reference.identifier.parent.type === "CallExpression" && reference.identifier.parent.callee === reference.identifier));
|
|
1857
1870
|
}
|
|
1858
1871
|
function isConstBound(node) {
|
|
1859
1872
|
return node.parent.type === "VariableDeclarator" && node.parent.parent.type === "VariableDeclaration" && node.parent.parent.kind === "const";
|
|
@@ -2041,7 +2054,7 @@ function operands(input) {
|
|
|
2041
2054
|
function comparedNullish(input) {
|
|
2042
2055
|
if (input.node.type !== "BinaryExpression" || input.node.operator !== input.operator) return none();
|
|
2043
2056
|
const subject = input.node.left;
|
|
2044
|
-
return map
|
|
2057
|
+
return map(nullishOperand({
|
|
2045
2058
|
context: input.context,
|
|
2046
2059
|
node: input.node.right
|
|
2047
2060
|
}), (nullish) => ({
|
|
@@ -2059,7 +2072,7 @@ function guardCall(input) {
|
|
|
2059
2072
|
first: input.checks[0],
|
|
2060
2073
|
second: input.checks[1]
|
|
2061
2074
|
}) || input.context.sourceCode.getTokensBetween(input.checks[0].node, input.checks[1].node).length !== 1) return none();
|
|
2062
|
-
return map
|
|
2075
|
+
return map(effectImport({
|
|
2063
2076
|
context: input.context,
|
|
2064
2077
|
fixer: input.fixer,
|
|
2065
2078
|
name: "Predicate",
|
|
@@ -2071,7 +2084,7 @@ const noDoubleNullishCheck = defineRule({
|
|
|
2071
2084
|
if (node.operator === "??") return;
|
|
2072
2085
|
if (node.parent.type === "LogicalExpression" && node.parent.operator === node.operator) return;
|
|
2073
2086
|
const variant = VARIANTS[node.operator];
|
|
2074
|
-
const checks = map(operands({
|
|
2087
|
+
const checks = map$1(operands({
|
|
2075
2088
|
node,
|
|
2076
2089
|
operator: node.operator
|
|
2077
2090
|
}), (operand) => comparedNullish({
|
|
@@ -2114,7 +2127,7 @@ function generator(context, node) {
|
|
|
2114
2127
|
propertyName: "gen"
|
|
2115
2128
|
}) || node.arguments.length !== 1) return none();
|
|
2116
2129
|
const effect = node.callee.object;
|
|
2117
|
-
return pipe(head(node.arguments), filter((argument) => argument.type === "FunctionExpression" && argument.generator && !argument.async && argument.id === null && isArrayEmpty(argument.params) && argument.body !== null && isNone(match$1(/\b(?:arguments|this)\b/u)(context.sourceCode.getText(argument.body)))), map
|
|
2130
|
+
return pipe(head(node.arguments), filter((argument) => argument.type === "FunctionExpression" && argument.generator && !argument.async && argument.id === null && isArrayEmpty(argument.params) && argument.body !== null && isNone(match$1(/\b(?:arguments|this)\b/u)(context.sourceCode.getText(argument.body)))), map((body) => ({
|
|
2118
2131
|
body,
|
|
2119
2132
|
effect
|
|
2120
2133
|
})));
|
|
@@ -2227,12 +2240,10 @@ function recoversEmpty(context, name, node) {
|
|
|
2227
2240
|
}
|
|
2228
2241
|
const noEmptyRecovery = defineRule({
|
|
2229
2242
|
create: (context) => ({ CallExpression: (node) => {
|
|
2230
|
-
|
|
2243
|
+
const name = pipe(effectMethod({
|
|
2231
2244
|
context,
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
})) return;
|
|
2235
|
-
const name = pipe(memberName(node.callee), getOrElse(() => ""));
|
|
2245
|
+
node
|
|
2246
|
+
}), getOrElse(() => ""));
|
|
2236
2247
|
if (!pipe(name, startsWith("catch")) && !pipe(name, startsWith("orElse"))) return;
|
|
2237
2248
|
for (const argument of node.arguments) {
|
|
2238
2249
|
const callback = resolveBinding(context, argument);
|
|
@@ -2329,17 +2340,16 @@ function inspectPredicate(context, node) {
|
|
|
2329
2340
|
}
|
|
2330
2341
|
const noErrorMessageControlFlow = defineRule({
|
|
2331
2342
|
create: (context) => ({ CallExpression: (node) => {
|
|
2332
|
-
|
|
2343
|
+
const method = effectMethod({
|
|
2333
2344
|
context,
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
if (contains$1(memberName(node.callee), "catchIf")) {
|
|
2345
|
+
node
|
|
2346
|
+
});
|
|
2347
|
+
if (contains$1(method, "catchIf")) {
|
|
2338
2348
|
if (node.arguments.length === 3) inspectPredicate(context, node.arguments[1]);
|
|
2339
2349
|
if (node.arguments.length === 2) inspectPredicate(context, node.arguments[0]);
|
|
2340
2350
|
return;
|
|
2341
2351
|
}
|
|
2342
|
-
if (!contains$1(
|
|
2352
|
+
if (!contains$1(method, "retry")) return;
|
|
2343
2353
|
for (const property of flatMap(node.arguments, (argument) => {
|
|
2344
2354
|
if (argument.type === "ObjectExpression") return argument.properties;
|
|
2345
2355
|
return [];
|
|
@@ -2504,7 +2514,7 @@ function check(input) {
|
|
|
2504
2514
|
}), check({
|
|
2505
2515
|
name: input.name,
|
|
2506
2516
|
node: input.node.right
|
|
2507
|
-
})]), map
|
|
2517
|
+
})]), map(flatten));
|
|
2508
2518
|
if (input.node.type === "UnaryExpression" && input.node.operator === "!" && input.node.argument.type === "CallExpression" && input.node.argument.callee.type === "MemberExpression" && isSubject({
|
|
2509
2519
|
name: "Array",
|
|
2510
2520
|
node: input.node.argument.callee.object
|
|
@@ -2530,7 +2540,7 @@ function check(input) {
|
|
|
2530
2540
|
operator: input.node.operator,
|
|
2531
2541
|
other: input.node.left,
|
|
2532
2542
|
subject: input.node.right
|
|
2533
|
-
})]), map
|
|
2543
|
+
})]), map(of));
|
|
2534
2544
|
}
|
|
2535
2545
|
function replaceableGuard(node) {
|
|
2536
2546
|
const predicate = node.returnType?.typeAnnotation;
|
|
@@ -2539,7 +2549,7 @@ function replaceableGuard(node) {
|
|
|
2539
2549
|
return pipe(check({
|
|
2540
2550
|
name: predicate.parameterName.name,
|
|
2541
2551
|
node: returned
|
|
2542
|
-
}), map
|
|
2552
|
+
}), map((checks) => pipe(checks, sort(Order), join(" && "))), flatMap$1((key) => get$2({
|
|
2543
2553
|
"!= null": "isNotNullish",
|
|
2544
2554
|
"!== null": "isNotNull",
|
|
2545
2555
|
"!== null && !Array.isArray && typeof === object": "isObject",
|
|
@@ -2564,7 +2574,7 @@ function replaceableGuard(node) {
|
|
|
2564
2574
|
}, key)));
|
|
2565
2575
|
}
|
|
2566
2576
|
function report$4(input) {
|
|
2567
|
-
map
|
|
2577
|
+
map(replaceableGuard(input.node), (guard) => input.context.report({
|
|
2568
2578
|
message: `Use Predicate.${guard} instead of this hand-written type guard.`,
|
|
2569
2579
|
node: input.node
|
|
2570
2580
|
}));
|
|
@@ -2637,7 +2647,7 @@ const PRIMITIVES = {
|
|
|
2637
2647
|
const CONTROL_STYLE = /(?:^|:)(?:hover|focus|focus-visible|active):|(?:^|:)(?:rounded|shadow|ring)(?:-|$)|(?:^|:)p[blrtxy]?-(?!0$)|(?:^|:)bg-(?!transparent$)|(?:^|:)border(?:-[blrtxy])?$|(?:^|:)border-(?!0$|[blrtxy]-0$)/u;
|
|
2638
2648
|
function classStrings(node) {
|
|
2639
2649
|
if (node.type === "Literal") return filter$1([node.value], isString);
|
|
2640
|
-
if (node.type === "TemplateLiteral") return map(node.quasis, (quasi) => quasi.value.raw);
|
|
2650
|
+
if (node.type === "TemplateLiteral") return map$1(node.quasis, (quasi) => quasi.value.raw);
|
|
2641
2651
|
if (node.type === "JSXExpressionContainer") return classStrings(node.expression);
|
|
2642
2652
|
if (node.type === "CallExpression") return flatMap(node.arguments, classStrings);
|
|
2643
2653
|
if (node.type === "ConditionalExpression") return flatMap([node.consequent, node.alternate], classStrings);
|
|
@@ -2649,8 +2659,8 @@ const noNativeControl = defineRule({
|
|
|
2649
2659
|
create: (context) => ({ JSXOpeningElement: (node) => {
|
|
2650
2660
|
if (node.name.type !== "JSXIdentifier") return;
|
|
2651
2661
|
const name = node.name.name;
|
|
2652
|
-
map
|
|
2653
|
-
const styled = pipe(node.attributes, findFirst((attribute) => attribute.type === "JSXAttribute" && attribute.name.type === "JSXIdentifier" && attribute.name.name === "className"), map
|
|
2662
|
+
map(get$2(PRIMITIVES, name), (primitive) => {
|
|
2663
|
+
const styled = pipe(node.attributes, findFirst((attribute) => attribute.type === "JSXAttribute" && attribute.name.type === "JSXIdentifier" && attribute.name.name === "className"), map((attribute) => {
|
|
2654
2664
|
if (attribute.type !== "JSXAttribute" || attribute.value === null) return empty$2();
|
|
2655
2665
|
return classStrings(attribute.value);
|
|
2656
2666
|
}), exists((values) => some$1(values, (value) => some$1(split(value, /\s+/u), matches(CONTROL_STYLE)))));
|
|
@@ -2674,7 +2684,7 @@ const noNativeEmptinessCheck = defineRule({
|
|
|
2674
2684
|
context,
|
|
2675
2685
|
node: node.left
|
|
2676
2686
|
})) return;
|
|
2677
|
-
map
|
|
2687
|
+
map(lengthTest(node), (test) => {
|
|
2678
2688
|
context.report({
|
|
2679
2689
|
message: `Use ${PREDICATES[test]}.`,
|
|
2680
2690
|
node
|
|
@@ -2770,10 +2780,10 @@ const noNativeMethodCall = defineRule({
|
|
|
2770
2780
|
"entries",
|
|
2771
2781
|
"keys",
|
|
2772
2782
|
"values"
|
|
2773
|
-
], name) || isArrayEmpty(node.arguments)), flatMap$1((name) => pipe(get$2(REPLACEMENTS, name), map
|
|
2783
|
+
], name) || isArrayEmpty(node.arguments)), flatMap$1((name) => pipe(get$2(REPLACEMENTS, name), map((replacement) => ({
|
|
2774
2784
|
name,
|
|
2775
2785
|
replacement
|
|
2776
|
-
})))), map
|
|
2786
|
+
})))), map((method) => context.report({
|
|
2777
2787
|
message: `Use ${method.replacement} instead of the native .${method.name}(); a third-party object's own method stays, with an inline disable naming it.`,
|
|
2778
2788
|
node: node.callee
|
|
2779
2789
|
})));
|
|
@@ -2900,8 +2910,8 @@ function receiverText(context, node) {
|
|
|
2900
2910
|
function fix$5(input) {
|
|
2901
2911
|
const calls = chain(input.node);
|
|
2902
2912
|
if (!rewritable(input.context, calls)) return [];
|
|
2903
|
-
const steps = filter$1(map(calls, (call) => argumentsText(input.context, call)), (text) => isNonEmpty(text));
|
|
2904
|
-
return getOrElse(flatMap$1(head(calls), (innermost) => map
|
|
2913
|
+
const steps = filter$1(map$1(calls, (call) => argumentsText(input.context, call)), (text) => isNonEmpty(text));
|
|
2914
|
+
return getOrElse(flatMap$1(head(calls), (innermost) => map(effectImport({
|
|
2905
2915
|
context: input.context,
|
|
2906
2916
|
fixer: input.fixer,
|
|
2907
2917
|
name: "pipe",
|
|
@@ -3043,31 +3053,23 @@ const noPollingTest = defineRule({
|
|
|
3043
3053
|
}
|
|
3044
3054
|
return {
|
|
3045
3055
|
CallExpression: (node) => {
|
|
3046
|
-
|
|
3047
|
-
const callee = node.callee;
|
|
3048
|
-
if (importedMember({
|
|
3056
|
+
const method = effectMethod({
|
|
3049
3057
|
context,
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
})) {
|
|
3058
|
+
node
|
|
3059
|
+
});
|
|
3060
|
+
if (contains$1(method, "eventually")) {
|
|
3054
3061
|
context.report({
|
|
3055
3062
|
message: MESSAGE$4,
|
|
3056
3063
|
node
|
|
3057
3064
|
});
|
|
3058
3065
|
return;
|
|
3059
3066
|
}
|
|
3060
|
-
if (
|
|
3067
|
+
if (exists(method, (name) => contains([
|
|
3061
3068
|
"repeat",
|
|
3062
3069
|
"repeatOrElse",
|
|
3063
3070
|
"retry",
|
|
3064
3071
|
"retryOrElse"
|
|
3065
|
-
],
|
|
3066
|
-
context,
|
|
3067
|
-
importedName: "Effect",
|
|
3068
|
-
node: callee,
|
|
3069
|
-
propertyName
|
|
3070
|
-
})) && (containsNode({
|
|
3072
|
+
], name)) && (containsNode({
|
|
3071
3073
|
context,
|
|
3072
3074
|
matches: (child) => isWait(context, child),
|
|
3073
3075
|
node: pipedFrom(node),
|
|
@@ -3150,7 +3152,7 @@ function enclosed(input) {
|
|
|
3150
3152
|
function needsAlias(input) {
|
|
3151
3153
|
if (input.declaration.parent.type !== "BlockStatement" || !contains(FUNCTIONS, input.declaration.parent.parent.type) || !pipe(input.declaration.parent.body, takeWhile((statement) => statement !== input.declaration), every((statement) => statement.type === "VariableDeclaration"))) return true;
|
|
3152
3154
|
const block = input.declaration.parent;
|
|
3153
|
-
const paths = map(input.reads, (read) => ({
|
|
3155
|
+
const paths = map$1(input.reads, (read) => ({
|
|
3154
3156
|
callback: enclosed({
|
|
3155
3157
|
block,
|
|
3156
3158
|
node: read,
|
|
@@ -3181,7 +3183,7 @@ function replacement(input) {
|
|
|
3181
3183
|
return input.text;
|
|
3182
3184
|
}
|
|
3183
3185
|
function report$3(input) {
|
|
3184
|
-
const reads = pipe(input.variable.references, filter$1((reference) => reference.isRead()), map((reference) => reference.identifier));
|
|
3186
|
+
const reads = pipe(input.variable.references, filter$1((reference) => reference.isRead()), map$1((reference) => reference.identifier));
|
|
3185
3187
|
const text = input.context.sourceCode.getText(input.init);
|
|
3186
3188
|
const aliasRequired = needsAlias({
|
|
3187
3189
|
context: input.context,
|
|
@@ -3232,7 +3234,7 @@ function report$3(input) {
|
|
|
3232
3234
|
node,
|
|
3233
3235
|
read
|
|
3234
3236
|
})) || !every(input.context.sourceCode.getTokensBetween(input.declaration, read), inert$1))) return [];
|
|
3235
|
-
return [fixer.remove(input.declaration), ...map(reads, (read) => fixer.replaceText(read, replacement({
|
|
3237
|
+
return [fixer.remove(input.declaration), ...map$1(reads, (read) => fixer.replaceText(read, replacement({
|
|
3236
3238
|
name: input.name,
|
|
3237
3239
|
read,
|
|
3238
3240
|
text
|
|
@@ -3320,7 +3322,7 @@ const noRedundantStateType = defineRule({
|
|
|
3320
3322
|
propertyName: "make"
|
|
3321
3323
|
})))) return;
|
|
3322
3324
|
if (isString(argument.value) && type?.type === "TSStringKeyword" || isNumber$1(argument.value) && type?.type === "TSNumberKeyword" || isBoolean(argument.value) && type?.type === "TSBooleanKeyword") context.report({
|
|
3323
|
-
fix: (fixer) => toArray$1(map
|
|
3325
|
+
fix: (fixer) => toArray$1(map(fromNullishOr(node.typeArguments), (typeArguments) => fixer.remove(typeArguments))),
|
|
3324
3326
|
message: "Drop this state type; the initializer infers the same primitive type.",
|
|
3325
3327
|
node: type
|
|
3326
3328
|
});
|
|
@@ -3352,7 +3354,7 @@ function nullableType(input) {
|
|
|
3352
3354
|
function removeNull(input) {
|
|
3353
3355
|
const before = input.context.sourceCode.getTokenBefore(input.member);
|
|
3354
3356
|
if (before?.value === "|" && before.range[0] >= input.type.range[0]) return some(input.fixer.removeRange([before.range[0], input.member.range[1]]));
|
|
3355
|
-
return pipe(fromNullishOr(input.context.sourceCode.getTokenAfter(input.member)), filter((token) => token.value === "|"), map
|
|
3357
|
+
return pipe(fromNullishOr(input.context.sourceCode.getTokenAfter(input.member)), filter((token) => token.value === "|"), map((token) => input.fixer.removeRange([input.member.range[0], token.range[1]])));
|
|
3356
3358
|
}
|
|
3357
3359
|
const noRedundantUseRefNullType = defineRule({
|
|
3358
3360
|
create: (context) => ({ CallExpression: (node) => {
|
|
@@ -3389,7 +3391,7 @@ function fix$4(input) {
|
|
|
3389
3391
|
name: "Array",
|
|
3390
3392
|
scope: input.context.sourceCode.getScope(input.init)
|
|
3391
3393
|
}), (variable) => some$1(variable.defs, (definition) => definition.type === "ImportBinding" && definition.parent?.type === "ImportDeclaration" && definition.parent.source.value === "effect"))) return [];
|
|
3392
|
-
return getOrElse(flatMap$1(elementType(input.annotation.typeAnnotation), (element) => map
|
|
3394
|
+
return getOrElse(flatMap$1(elementType(input.annotation.typeAnnotation), (element) => map(effectImport({
|
|
3393
3395
|
context: input.context,
|
|
3394
3396
|
fixer: input.fixer,
|
|
3395
3397
|
name: "Array",
|
|
@@ -3477,7 +3479,7 @@ function shippedSchema(input) {
|
|
|
3477
3479
|
return pipe(shipped, findFirst((entry) => contains$1(base, entry.base) && contains$1(check, entry.check) && isArrayEmpty(rest) && match(fromUndefinedOr(entry.only), {
|
|
3478
3480
|
onNone: () => value === void 0,
|
|
3479
3481
|
onSome: (only) => value?.type === "Literal" && value.value === only
|
|
3480
|
-
})), map
|
|
3482
|
+
})), map((entry) => entry.schema));
|
|
3481
3483
|
}
|
|
3482
3484
|
function pipedBase(node) {
|
|
3483
3485
|
if (node.parent.type !== "CallExpression") return none();
|
|
@@ -3511,7 +3513,7 @@ function reinventedSchema(input) {
|
|
|
3511
3513
|
}
|
|
3512
3514
|
const noReinventedSchema = defineRule({
|
|
3513
3515
|
create: (context) => ({ CallExpression: (node) => {
|
|
3514
|
-
map
|
|
3516
|
+
map(reinventedSchema({
|
|
3515
3517
|
context,
|
|
3516
3518
|
node
|
|
3517
3519
|
}), (schema) => {
|
|
@@ -3548,7 +3550,7 @@ function fix$3(input) {
|
|
|
3548
3550
|
...input,
|
|
3549
3551
|
reference
|
|
3550
3552
|
}))) return none();
|
|
3551
|
-
return some([input.fixer.removeRange([input.node.imported.range[1], input.node.local.range[1]]), ...map(variable.references, (reference) => {
|
|
3553
|
+
return some([input.fixer.removeRange([input.node.imported.range[1], input.node.local.range[1]]), ...map$1(variable.references, (reference) => {
|
|
3552
3554
|
if (reference.identifier.parent.type === "Property" && reference.identifier.parent.shorthand) return input.fixer.replaceText(reference.identifier.parent, `${input.node.local.name}: ${input.imported}`);
|
|
3553
3555
|
return input.fixer.replaceText(reference.identifier, input.imported);
|
|
3554
3556
|
})]);
|
|
@@ -3615,7 +3617,7 @@ function reaches(input) {
|
|
|
3615
3617
|
if (isArrayEmpty(next)) return false;
|
|
3616
3618
|
return reaches({
|
|
3617
3619
|
...input,
|
|
3618
|
-
nodes: pipe(next, flatMap((variable) => variable.defs), filter$1((definition) => definition.type === "FunctionName" || definition.type === "Variable"), map((definition) => definition.node)),
|
|
3620
|
+
nodes: pipe(next, flatMap((variable) => variable.defs), filter$1((definition) => definition.type === "FunctionName" || definition.type === "Variable"), map$1((definition) => definition.node)),
|
|
3619
3621
|
visited: appendAll(input.visited, next)
|
|
3620
3622
|
});
|
|
3621
3623
|
}
|
|
@@ -3718,7 +3720,7 @@ function forwardedChain(input) {
|
|
|
3718
3720
|
});
|
|
3719
3721
|
}
|
|
3720
3722
|
function exactForwardingFunction(input) {
|
|
3721
|
-
const names = pipe(input.node.params, map(parameterName), getSomes);
|
|
3723
|
+
const names = pipe(input.node.params, map$1(parameterName), getSomes);
|
|
3722
3724
|
const returned = returnedExpression(input.node);
|
|
3723
3725
|
if (input.node.async || input.node.generator || isArrayEmpty(names) || names.length !== input.node.params.length || isNullish(returned)) return false;
|
|
3724
3726
|
if (returned.type === "Identifier") return names.length === 1 && returned.name === names[0];
|
|
@@ -3760,14 +3762,15 @@ function copiesSafely(input) {
|
|
|
3760
3762
|
});
|
|
3761
3763
|
}
|
|
3762
3764
|
function singleUseFunction(input) {
|
|
3763
|
-
const names = pipe(input.node.params, map(parameterName), getSomes);
|
|
3765
|
+
const names = pipe(input.node.params, map$1(parameterName), getSomes);
|
|
3764
3766
|
const returned = returnedExpression(input.node);
|
|
3765
3767
|
if (input.node.async || input.node.generator || input.node.typeParameters !== null || input.node.returnType?.typeAnnotation.type === "TSTypePredicate" || isArrayEmpty(names) || names.length !== input.node.params.length || isNullish(returned)) return false;
|
|
3766
3768
|
const oneLine = !pipe(input.context.sourceCode.getText(returned), includes("\n"));
|
|
3767
|
-
return pipe(unexportedBindingName(input.node), flatMap$1((name) =>
|
|
3769
|
+
return pipe(unexportedBindingName(input.node), flatMap$1((name) => readsOf({
|
|
3770
|
+
context: input.context,
|
|
3768
3771
|
name,
|
|
3769
|
-
|
|
3770
|
-
})),
|
|
3772
|
+
node: input.node
|
|
3773
|
+
})), filter((reads) => reads.length === 1), flatMap$1(head), map((reference) => reference.identifier), filter((read) => read.range[0] < input.node.range[0] || read.range[0] > input.node.range[1]), exists((read) => {
|
|
3771
3774
|
if (read.parent.type !== "CallExpression") return false;
|
|
3772
3775
|
if (read.parent.callee !== read) return oneLine && some$1(read.parent.arguments, (argument) => argument === read);
|
|
3773
3776
|
if (!copiesSafely({
|
|
@@ -3791,20 +3794,22 @@ function redundantConstAlias(input) {
|
|
|
3791
3794
|
return definition.node.type === "VariableDeclarator" && definition.node.parent.type === "VariableDeclaration" && definition.node.parent.kind === "const";
|
|
3792
3795
|
});
|
|
3793
3796
|
}))) return false;
|
|
3794
|
-
return pipe(
|
|
3797
|
+
return pipe(readsOf({
|
|
3798
|
+
context: input.context,
|
|
3795
3799
|
name: input.node.id.name,
|
|
3796
|
-
|
|
3797
|
-
}), exists((
|
|
3800
|
+
node: input.node
|
|
3801
|
+
}), exists((reads) => reads.length === 1));
|
|
3798
3802
|
}
|
|
3799
3803
|
function exportedAlias(input) {
|
|
3800
3804
|
return input.node.parent.type === "VariableDeclaration" && input.node.parent.kind === "const" && input.node.parent.parent.type === "ExportNamedDeclaration" && input.node.id.type === "Identifier" && input.node.init?.type === "Identifier" && pipe(variableFor(input.context, input.node.init), exists((variable) => some$1(variable.defs, (definition) => definition.type === "ImportBinding" || definition.type === "FunctionName" || definition.type === "ClassName" || definition.node.type === "VariableDeclarator" && definition.node.parent.type === "VariableDeclaration" && definition.node.parent.kind === "const")));
|
|
3801
3805
|
}
|
|
3802
3806
|
function singleUseLiteral(input) {
|
|
3803
3807
|
if (input.node.parent.type !== "VariableDeclaration" || input.node.parent.kind !== "const" || isExport(input.node.parent.parent) || input.node.parent.parent.type === "Program" || input.node.id.type !== "Identifier" || input.node.id.typeAnnotation !== null || !(input.node.init?.type === "Literal" && !hasProperty(input.node.init, "regex") || input.node.init?.type === "TemplateLiteral" && isArrayEmpty(input.node.init.expressions))) return false;
|
|
3804
|
-
return pipe(
|
|
3808
|
+
return pipe(readsOf({
|
|
3809
|
+
context: input.context,
|
|
3805
3810
|
name: input.node.id.name,
|
|
3806
|
-
|
|
3807
|
-
}),
|
|
3811
|
+
node: input.node
|
|
3812
|
+
}), exists((reads) => reads.length === 1 && reads[0]?.identifier.parent.type !== "ExportSpecifier"));
|
|
3808
3813
|
}
|
|
3809
3814
|
function singleUseLayerPart(input) {
|
|
3810
3815
|
const init = input.node.init;
|
|
@@ -3814,10 +3819,11 @@ function singleUseLayerPart(input) {
|
|
|
3814
3819
|
node: init.callee,
|
|
3815
3820
|
propertyName: "gen"
|
|
3816
3821
|
}))) return false;
|
|
3817
|
-
return pipe(
|
|
3822
|
+
return pipe(readsOf({
|
|
3823
|
+
context: input.context,
|
|
3818
3824
|
name: input.node.id.name,
|
|
3819
|
-
|
|
3820
|
-
}),
|
|
3825
|
+
node: input.node
|
|
3826
|
+
}), exists((reads) => {
|
|
3821
3827
|
const consumer = reads[0]?.identifier.parent;
|
|
3822
3828
|
if (reads.length !== 1 || consumer?.type !== "CallExpression") return false;
|
|
3823
3829
|
if (init.type === "MemberExpression") return importedMember({
|
|
@@ -4057,10 +4063,11 @@ function report$2(input) {
|
|
|
4057
4063
|
if (declaration.type !== "VariableDeclaration" || declaration.parent.type !== "BlockStatement" || input.node.id.type !== "Identifier" || init === null) return;
|
|
4058
4064
|
const statements = declaration.parent.body;
|
|
4059
4065
|
const name = input.node.id.name;
|
|
4060
|
-
pipe(findFirstIndex(statements, (statement) => statement === declaration), flatMap$1((index) => get$3(statements, index + 1)), flatMap$1((next) => pipe(
|
|
4066
|
+
pipe(findFirstIndex(statements, (statement) => statement === declaration), flatMap$1((index) => get$3(statements, index + 1)), flatMap$1((next) => pipe(readsOf({
|
|
4067
|
+
context: input.context,
|
|
4061
4068
|
name,
|
|
4062
|
-
|
|
4063
|
-
}),
|
|
4069
|
+
node: input.node
|
|
4070
|
+
}), filter((reads) => reads.length === 1), flatMap$1(head), map((reference) => reference.identifier), filter((read) => read.range[0] >= next.range[0] && read.range[1] <= next.range[1] && climb({
|
|
4064
4071
|
node: read,
|
|
4065
4072
|
statement: next
|
|
4066
4073
|
}) && readable({
|
|
@@ -4070,7 +4077,7 @@ function report$2(input) {
|
|
|
4070
4077
|
}) && !(init.type === "ConditionalExpression" && insideConditional({
|
|
4071
4078
|
node: read,
|
|
4072
4079
|
statement: next
|
|
4073
|
-
})) && !(suspends(input.context, init) && receiver(outermost(read))) && !some$1(input.effects, (effect) => effect.range[0] >= next.range[0] && effect.range[1] <= read.range[0])), map
|
|
4080
|
+
})) && !(suspends(input.context, init) && receiver(outermost(read))) && !some$1(input.effects, (effect) => effect.range[0] >= next.range[0] && effect.range[1] <= read.range[0])), map((read) => ({
|
|
4074
4081
|
next,
|
|
4075
4082
|
read
|
|
4076
4083
|
})))), match({
|
|
@@ -4283,7 +4290,7 @@ function branches(node) {
|
|
|
4283
4290
|
function returns(context, node) {
|
|
4284
4291
|
const chain = branches(node);
|
|
4285
4292
|
if (some$1(chain.tests, (test) => test.consequent.type === "ConditionalExpression")) return [];
|
|
4286
|
-
return [...map(chain.tests, (test) => `if (${context.sourceCode.getText(test.test)}) return ${context.sourceCode.getText(test.consequent)}`), `return ${context.sourceCode.getText(chain.last)}`];
|
|
4293
|
+
return [...map$1(chain.tests, (test) => `if (${context.sourceCode.getText(test.test)}) return ${context.sourceCode.getText(test.consequent)}`), `return ${context.sourceCode.getText(chain.last)}`];
|
|
4287
4294
|
}
|
|
4288
4295
|
function inStatementList(node) {
|
|
4289
4296
|
return node.parent?.type === "BlockStatement" || node.parent?.type === "StaticBlock" || node.parent?.type === "SwitchCase";
|
|
@@ -4483,7 +4490,7 @@ function fix$1(input) {
|
|
|
4483
4490
|
const guard = GUARDS[input.node.parent.right.value];
|
|
4484
4491
|
if (guard === void 0) return [];
|
|
4485
4492
|
const replacement = input.fixer.replaceTextRange(input.node.parent.range, `${NEGATIONS[input.node.parent.operator]}Predicate.${guard}(${input.node.argument.name})`);
|
|
4486
|
-
return getOrElse(map
|
|
4493
|
+
return getOrElse(map(effectImport({
|
|
4487
4494
|
context: input.context,
|
|
4488
4495
|
fixer: input.fixer,
|
|
4489
4496
|
name: "Predicate",
|
|
@@ -4621,7 +4628,7 @@ const WALL_CLOCKS = [
|
|
|
4621
4628
|
function globalPath(context, node) {
|
|
4622
4629
|
if (node.type === "Identifier") return liftPredicate(node.name, () => !exists(variableFor(context, node), (variable) => isArrayNonEmpty(variable.defs)));
|
|
4623
4630
|
if (node.type !== "MemberExpression") return none();
|
|
4624
|
-
return flatMap$1(memberName(node), (name) => map
|
|
4631
|
+
return flatMap$1(memberName(node), (name) => map(globalPath(context, node.object), (path) => `${path}.${name}`));
|
|
4625
4632
|
}
|
|
4626
4633
|
function readsRealTime(context, node) {
|
|
4627
4634
|
if (importedMember({
|
|
@@ -4798,12 +4805,10 @@ function reportOption(context, key, bare, options) {
|
|
|
4798
4805
|
}
|
|
4799
4806
|
const preserveErrorCause = defineRule({
|
|
4800
4807
|
create: (context) => ({ CallExpression: (node) => {
|
|
4801
|
-
|
|
4808
|
+
const name = effectMethod({
|
|
4802
4809
|
context,
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
})) return;
|
|
4806
|
-
const name = memberName(node.callee);
|
|
4810
|
+
node
|
|
4811
|
+
});
|
|
4807
4812
|
if (contains$1(name, "mapError")) {
|
|
4808
4813
|
const bare = detailedFailure(context, node);
|
|
4809
4814
|
forEach(filter$1(node.arguments, (argument) => dropsCause(context, argument, bare)), (callback) => report$1(context, callback));
|
|
@@ -4997,7 +5002,7 @@ function reportSchemaVariable(input) {
|
|
|
4997
5002
|
name
|
|
4998
5003
|
})) return [];
|
|
4999
5004
|
const start = pipe(input.context.sourceCode.getCommentsBefore(input.statement), head, getOrElse(() => input.statement)).range[0];
|
|
5000
|
-
return [fixer.insertTextBeforeRange([start, start], `${EXPORT_PREFIXES[input.statement.type] ?? ""}type ${name} = typeof ${name}.Type\n`), ...pipe(input.queries, filter$1((query) => contains$1(queriedSchema(query), name) && readsModuleBinding(input.context, query, name)), map((query) => fixer.replaceText(query, name)))];
|
|
5005
|
+
return [fixer.insertTextBeforeRange([start, start], `${EXPORT_PREFIXES[input.statement.type] ?? ""}type ${name} = typeof ${name}.Type\n`), ...pipe(input.queries, filter$1((query) => contains$1(queriedSchema(query), name) && readsModuleBinding(input.context, query, name)), map$1((query) => fixer.replaceText(query, name)))];
|
|
5001
5006
|
},
|
|
5002
5007
|
message: `Place \`type ${name} = typeof ${name}.Type\` immediately before this Schema.`,
|
|
5003
5008
|
node: input.variable
|
|
@@ -5023,7 +5028,7 @@ const schemaTypePair = defineRule({
|
|
|
5023
5028
|
const seeds = make$2();
|
|
5024
5029
|
return {
|
|
5025
5030
|
CallExpression: (node) => {
|
|
5026
|
-
map
|
|
5031
|
+
map(suspendedTypeName({
|
|
5027
5032
|
context,
|
|
5028
5033
|
node
|
|
5029
5034
|
}), (name) => append$1(seeds, name));
|
|
@@ -5098,7 +5103,7 @@ const swiftuiThemeValues = defineRule({
|
|
|
5098
5103
|
const name = calleeName(node);
|
|
5099
5104
|
if (contains(["listRowInsets", "padding"], name) && some$1(properties(node.arguments[0]), (property) => isNumber(property.value)) || name === "lineSpacing" && isNumber(node.arguments[0])) report(context, node, "Space with the theme’s spacing steps, such as padding({all: space[4]}).");
|
|
5100
5105
|
if (name === "font" && some$1(properties(node.arguments[0]), (property) => keyOf(property) === "size")) report(context, node, "Set type with a text token or a Dynamic Type textStyle, not a point size.");
|
|
5101
|
-
if (contains(PAINTS, name) && some$1(flatMap(node.arguments, (argument) => [argument, ...map(properties(argument), (property) => property.value)]), (value) => value.type === "Literal" && isString(value.value) && isSome(match$1(/^#[\da-f]{3,8}$/iu)(value.value)))) report(context, node, "Paint with the theme’s colors, which follow light and dark, not a hex string.");
|
|
5106
|
+
if (contains(PAINTS, name) && some$1(flatMap(node.arguments, (argument) => [argument, ...map$1(properties(argument), (property) => property.value)]), (value) => value.type === "Literal" && isString(value.value) && isSome(match$1(/^#[\da-f]{3,8}$/iu)(value.value)))) report(context, node, "Paint with the theme’s colors, which follow light and dark, not a hex string.");
|
|
5102
5107
|
},
|
|
5103
5108
|
ImportDeclaration: (node) => {
|
|
5104
5109
|
if (startsWith("@expo/ui/swift-ui")(node.source.value)) file.swiftui = true;
|
|
@@ -5377,10 +5382,18 @@ const lint = {
|
|
|
5377
5382
|
message: "Import Array from 'effect'.",
|
|
5378
5383
|
name: "Array"
|
|
5379
5384
|
},
|
|
5385
|
+
{
|
|
5386
|
+
message: "Use Base64 or Base64Url from effect/encoding.",
|
|
5387
|
+
name: "atob"
|
|
5388
|
+
},
|
|
5380
5389
|
{
|
|
5381
5390
|
message: "Import Boolean from 'effect'.",
|
|
5382
5391
|
name: "Boolean"
|
|
5383
5392
|
},
|
|
5393
|
+
{
|
|
5394
|
+
message: "Use Base64 or Base64Url from effect/encoding.",
|
|
5395
|
+
name: "btoa"
|
|
5396
|
+
},
|
|
5384
5397
|
{
|
|
5385
5398
|
message: "Use the effect/crypto services: SecureRandom, Digest, Signature.",
|
|
5386
5399
|
name: "crypto"
|
|
@@ -5552,7 +5565,7 @@ const lint = {
|
|
|
5552
5565
|
message: "Use Record or Struct from 'effect'.",
|
|
5553
5566
|
object: "Object"
|
|
5554
5567
|
},
|
|
5555
|
-
...map(RUNNERS, (property) => ({
|
|
5568
|
+
...map$1(RUNNERS, (property) => ({
|
|
5556
5569
|
message: RUN_MESSAGE,
|
|
5557
5570
|
object: "Effect",
|
|
5558
5571
|
property
|
|
@@ -5582,12 +5595,12 @@ const lint = {
|
|
|
5582
5595
|
object: "Math",
|
|
5583
5596
|
property: "round"
|
|
5584
5597
|
},
|
|
5585
|
-
...map(REACT_LEGACY_APIS, (property) => ({
|
|
5598
|
+
...map$1(REACT_LEGACY_APIS, (property) => ({
|
|
5586
5599
|
message: REACT_LEGACY_MESSAGE,
|
|
5587
5600
|
object: "React",
|
|
5588
5601
|
property
|
|
5589
5602
|
})),
|
|
5590
|
-
...map(REACT_HOOKS, (property) => ({
|
|
5603
|
+
...map$1(REACT_HOOKS, (property) => ({
|
|
5591
5604
|
message: `Import ${property} by name from react.`,
|
|
5592
5605
|
object: "React",
|
|
5593
5606
|
property
|
|
@@ -5627,7 +5640,7 @@ const lint = {
|
|
|
5627
5640
|
object: "Data",
|
|
5628
5641
|
property: "TaggedError"
|
|
5629
5642
|
},
|
|
5630
|
-
...map([
|
|
5643
|
+
...map$1([
|
|
5631
5644
|
"addEventListener",
|
|
5632
5645
|
"atob",
|
|
5633
5646
|
"btoa",
|
|
@@ -5647,7 +5660,7 @@ const lint = {
|
|
|
5647
5660
|
object: "window",
|
|
5648
5661
|
property
|
|
5649
5662
|
})),
|
|
5650
|
-
...map([
|
|
5663
|
+
...map$1([
|
|
5651
5664
|
"clearInterval",
|
|
5652
5665
|
"clearTimeout",
|
|
5653
5666
|
"setInterval",
|