@rdjperron/lint 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +146 -57
  2. package/dist/config.d.mts +113 -0
  3. package/dist/config.mjs +218 -0
  4. package/dist/config.mjs.map +1 -0
  5. package/dist/index.d.mts +5 -0
  6. package/dist/{anti-slop.mjs → index.mjs} +253 -94
  7. package/dist/index.mjs.map +1 -0
  8. package/dist/verify.d.mts +92 -0
  9. package/dist/verify.mjs +400 -0
  10. package/dist/verify.mjs.map +1 -0
  11. package/docs/rules/README.md +43 -0
  12. package/docs/rules/no-array-filter-map.md +60 -0
  13. package/docs/rules/no-chained-type-assertions.md +52 -0
  14. package/docs/rules/no-conditional-empty-object-spread.md +50 -0
  15. package/docs/rules/no-hardcoded-jsx-text.md +52 -0
  16. package/docs/rules/no-known-value-widening.md +62 -0
  17. package/docs/rules/no-module-mocking.md +53 -0
  18. package/docs/rules/no-object-parameters.md +55 -0
  19. package/docs/rules/no-reduce-accumulator-copy.md +57 -0
  20. package/docs/rules/no-reflect-apply.md +56 -0
  21. package/docs/rules/no-reflect-get.md +51 -0
  22. package/docs/rules/no-runtime-typeof.md +61 -0
  23. package/docs/rules/no-shape-in-symbol-names.md +53 -0
  24. package/docs/rules/no-unknown-parameters.md +55 -0
  25. package/docs/rules/no-unknown-returns.md +61 -0
  26. package/docs/rules/no-unknown-type-aliases.md +52 -0
  27. package/docs/rules/no-unsafe-dictionary-type.md +56 -0
  28. package/docs/rules/no-use-effect.md +55 -0
  29. package/docs/rules/no-widen-then-assert.md +53 -0
  30. package/docs/rules/require-safety-comment-for-type-assertion.md +59 -0
  31. package/docs/rules/static-public-env.md +55 -0
  32. package/fixtures/README.md +22 -23
  33. package/fixtures/{anti-slop/no-array-filter-map.fixture.ts → no-array-filter-map.fixture.ts} +1 -1
  34. package/fixtures/{anti-slop/no-chained-type-assertions.fixture.ts → no-chained-type-assertions.fixture.ts} +1 -1
  35. package/fixtures/{anti-slop/no-conditional-empty-object-spread.fixture.ts → no-conditional-empty-object-spread.fixture.ts} +1 -1
  36. package/fixtures/{i18n/no-hardcoded-jsx-text.fixture.tsx → no-hardcoded-jsx-text.fixture.tsx} +1 -1
  37. package/fixtures/{anti-slop/no-known-value-widening.fixture.ts → no-known-value-widening.fixture.ts} +1 -1
  38. package/fixtures/{anti-slop/no-module-mocking.fixture.ts → no-module-mocking.fixture.ts} +1 -1
  39. package/fixtures/{anti-slop/no-object-parameters.fixture.ts → no-object-parameters.fixture.ts} +1 -1
  40. package/fixtures/{anti-slop/no-reduce-accumulator-copy.fixture.ts → no-reduce-accumulator-copy.fixture.ts} +1 -1
  41. package/fixtures/{anti-slop/no-reflect-apply.fixture.ts → no-reflect-apply.fixture.ts} +1 -1
  42. package/fixtures/{anti-slop/no-reflect-get.fixture.ts → no-reflect-get.fixture.ts} +1 -1
  43. package/fixtures/{anti-slop/no-runtime-typeof.fixture.ts → no-runtime-typeof.fixture.ts} +1 -1
  44. package/fixtures/no-shape-in-symbol-names.fixture.ts +2 -0
  45. package/fixtures/{anti-slop/no-unknown-parameters.fixture.ts → no-unknown-parameters.fixture.ts} +1 -1
  46. package/fixtures/{anti-slop/no-unknown-returns.fixture.ts → no-unknown-returns.fixture.ts} +1 -1
  47. package/fixtures/no-unknown-type-aliases.fixture.ts +2 -0
  48. package/fixtures/no-unsafe-dictionary-type.fixture.ts +2 -0
  49. package/fixtures/{react/no-use-effect.fixture.tsx → no-use-effect.fixture.tsx} +1 -1
  50. package/fixtures/{anti-slop/no-widen-then-assert.fixture.ts → no-widen-then-assert.fixture.ts} +1 -1
  51. package/fixtures/{anti-slop/require-safety-comment-for-type-assertion.fixture.ts → require-safety-comment-for-type-assertion.fixture.ts} +1 -1
  52. package/fixtures/{expo/static-public-env.fixture.ts → static-public-env.fixture.ts} +1 -1
  53. package/package.json +27 -26
  54. package/dist/anti-slop.d.mts +0 -6
  55. package/dist/anti-slop.mjs.map +0 -1
  56. package/dist/expo.d.mts +0 -5
  57. package/dist/expo.mjs +0 -51
  58. package/dist/expo.mjs.map +0 -1
  59. package/dist/i18n.d.mts +0 -5
  60. package/dist/i18n.mjs +0 -50
  61. package/dist/i18n.mjs.map +0 -1
  62. package/dist/react.d.mts +0 -5
  63. package/dist/react.mjs +0 -73
  64. package/dist/react.mjs.map +0 -1
  65. package/dist/rule-options-DrAXz8BD.mjs +0 -18
  66. package/dist/rule-options-DrAXz8BD.mjs.map +0 -1
  67. package/fixtures/anti-slop/no-shape-in-symbol-names.fixture.ts +0 -2
  68. package/fixtures/anti-slop/no-unknown-type-aliases.fixture.ts +0 -2
  69. package/fixtures/anti-slop/no-unsafe-dictionary-type.fixture.ts +0 -2
@@ -97,89 +97,6 @@ const noArrayFilterMapRule = defineRule({
97
97
  }
98
98
  });
99
99
  //#endregion
100
- //#region src/anti-slop/rules/no-reduce-accumulator-copy.ts
101
- function enclosingReducer(node) {
102
- let parent = node.parent;
103
- while (parent !== null) {
104
- if (parent.type === "FunctionDeclaration") return null;
105
- if (parent.type === "ArrowFunctionExpression" || parent.type === "FunctionExpression") {
106
- const callback = parent;
107
- let owner = callback.parent;
108
- while (owner !== null && unwrapArrayExpression(owner) === callback) owner = owner.parent;
109
- if (owner?.type !== "CallExpression") return null;
110
- const method = arrayMethodTarget(owner.callee);
111
- const firstArgument = owner.arguments[0];
112
- if (method === null || method.name !== "reduce" && method.name !== "reduceRight" || owner.arguments.length > 2 || firstArgument === void 0 || unwrapArrayExpression(firstArgument) !== callback) return null;
113
- const firstParameter = callback.params[0];
114
- const accumulator = firstParameter?.type === "AssignmentPattern" ? firstParameter.left : firstParameter;
115
- if (accumulator?.type !== "Identifier") return null;
116
- return {
117
- callback,
118
- accumulator,
119
- initialValue: owner.arguments[1]
120
- };
121
- }
122
- parent = parent.parent;
123
- }
124
- return null;
125
- }
126
- function referencesAccumulator(sourceCode, node, accumulator, visited = /* @__PURE__ */ new Set()) {
127
- const variable = resolveArrayBinding(sourceCode, node);
128
- if (variable === null || visited.has(variable)) return false;
129
- if (variable === accumulator) return true;
130
- visited.add(variable);
131
- if (variable.references.some((reference) => reference.isWrite() && !reference.init)) return false;
132
- for (const definition of variable.defs) if (definition.type === "Variable" && definition.node.type === "VariableDeclarator" && definition.node.id.type === "Identifier" && definition.node.init !== null && definition.node.parent.type === "VariableDeclaration" && definition.node.parent.kind === "const") return referencesAccumulator(sourceCode, definition.node.init, accumulator, visited);
133
- return false;
134
- }
135
- function isGlobalCopyOwner(sourceCode, node, name) {
136
- node = unwrapArrayExpression(node);
137
- if (node.type !== "Identifier" || node.name !== name) return false;
138
- const variable = resolveArrayBinding(sourceCode, node);
139
- return variable === null || variable.defs.length === 0;
140
- }
141
- /** Reject non-spread copies of reducer accumulators; pair with oxc/no-accumulating-spread. */
142
- const noReduceAccumulatorCopyRule = defineRule({
143
- meta: {
144
- type: "problem",
145
- docs: { description: "Disallow copying growing reducer accumulators with Object.assign, Array.from, or array copy methods." },
146
- messages: { accumulatorCopy: "Do not copy the reducer accumulator on every iteration; growing copies can cause quadratic work. Mutate a fresh, locally owned accumulator and return it, or use an iterator pipeline/flatMap." }
147
- },
148
- createOnce(context) {
149
- return { CallExpression(node) {
150
- const method = arrayMethodTarget(node.callee);
151
- if (method === null) return;
152
- const reducer = enclosingReducer(node);
153
- if (reducer === null) return;
154
- const accumulator = context.sourceCode.getDeclaredVariables(reducer.callback).find((variable) => variable.identifiers.some((identifier) => identifier.start === reducer.accumulator.start));
155
- if (accumulator === void 0) return;
156
- const isAccumulator = (expression) => referencesAccumulator(context.sourceCode, expression, accumulator);
157
- let copiesAccumulator = false;
158
- if (method.name === "assign" && isGlobalCopyOwner(context.sourceCode, method.object, "Object")) {
159
- const target = node.arguments[0];
160
- copiesAccumulator = target !== void 0 && unwrapArrayExpression(target).type === "ObjectExpression" && node.arguments.slice(1).some(isAccumulator);
161
- } else if (method.name === "from" && isGlobalCopyOwner(context.sourceCode, method.object, "Array")) {
162
- const source = node.arguments[0];
163
- copiesAccumulator = source !== void 0 && isAccumulator(source);
164
- } else if ([
165
- "concat",
166
- "slice",
167
- "toSpliced",
168
- "toSorted",
169
- "toReversed",
170
- "with"
171
- ].includes(method.name)) {
172
- const initialValue = reducer.initialValue;
173
- copiesAccumulator = initialValue !== void 0 && isKnownArrayExpression(context.sourceCode, initialValue) && isAccumulator(method.object);
174
- }
175
- if (copiesAccumulator) context.report({
176
- node,
177
- messageId: "accumulatorCopy"
178
- });
179
- } };
180
- }
181
- });
182
- //#endregion
183
100
  //#region src/anti-slop/rules/no-chained-type-assertions.ts
184
101
  function isTypeAssertionExpression(node) {
185
102
  return node.type === "TSAsExpression" || node.type === "TSTypeAssertion";
@@ -934,7 +851,7 @@ const moduleMockMethods = /* @__PURE__ */ new Set([
934
851
  "mock",
935
852
  "unstable_mockModule"
936
853
  ]);
937
- function importedName(node) {
854
+ function importedName$1(node) {
938
855
  if (node.type !== "ImportSpecifier") return null;
939
856
  return node.imported.type === "Identifier" ? node.imported.name : node.imported.value;
940
857
  }
@@ -946,7 +863,7 @@ function isTestFrameworkObject(sourceCode, expression) {
946
863
  return variable.defs.some((definition) => {
947
864
  if (definition.type !== "ImportBinding" || definition.parent?.type !== "ImportDeclaration") return false;
948
865
  const source = definition.parent.source.value;
949
- const name = importedName(definition.node);
866
+ const name = importedName$1(definition.node);
950
867
  return source === "vitest" && name === "vi" || source === "@jest/globals" && name === "jest";
951
868
  });
952
869
  }
@@ -1020,6 +937,89 @@ const noObjectParametersRule = defineRule({
1020
937
  }
1021
938
  });
1022
939
  //#endregion
940
+ //#region src/anti-slop/rules/no-reduce-accumulator-copy.ts
941
+ function enclosingReducer(node) {
942
+ let parent = node.parent;
943
+ while (parent !== null) {
944
+ if (parent.type === "FunctionDeclaration") return null;
945
+ if (parent.type === "ArrowFunctionExpression" || parent.type === "FunctionExpression") {
946
+ const callback = parent;
947
+ let owner = callback.parent;
948
+ while (owner !== null && unwrapArrayExpression(owner) === callback) owner = owner.parent;
949
+ if (owner?.type !== "CallExpression") return null;
950
+ const method = arrayMethodTarget(owner.callee);
951
+ const firstArgument = owner.arguments[0];
952
+ if (method === null || method.name !== "reduce" && method.name !== "reduceRight" || owner.arguments.length > 2 || firstArgument === void 0 || unwrapArrayExpression(firstArgument) !== callback) return null;
953
+ const firstParameter = callback.params[0];
954
+ const accumulator = firstParameter?.type === "AssignmentPattern" ? firstParameter.left : firstParameter;
955
+ if (accumulator?.type !== "Identifier") return null;
956
+ return {
957
+ callback,
958
+ accumulator,
959
+ initialValue: owner.arguments[1]
960
+ };
961
+ }
962
+ parent = parent.parent;
963
+ }
964
+ return null;
965
+ }
966
+ function referencesAccumulator(sourceCode, node, accumulator, visited = /* @__PURE__ */ new Set()) {
967
+ const variable = resolveArrayBinding(sourceCode, node);
968
+ if (variable === null || visited.has(variable)) return false;
969
+ if (variable === accumulator) return true;
970
+ visited.add(variable);
971
+ if (variable.references.some((reference) => reference.isWrite() && !reference.init)) return false;
972
+ for (const definition of variable.defs) if (definition.type === "Variable" && definition.node.type === "VariableDeclarator" && definition.node.id.type === "Identifier" && definition.node.init !== null && definition.node.parent.type === "VariableDeclaration" && definition.node.parent.kind === "const") return referencesAccumulator(sourceCode, definition.node.init, accumulator, visited);
973
+ return false;
974
+ }
975
+ function isGlobalCopyOwner(sourceCode, node, name) {
976
+ node = unwrapArrayExpression(node);
977
+ if (node.type !== "Identifier" || node.name !== name) return false;
978
+ const variable = resolveArrayBinding(sourceCode, node);
979
+ return variable === null || variable.defs.length === 0;
980
+ }
981
+ /** Reject non-spread copies of reducer accumulators; pair with oxc/no-accumulating-spread. */
982
+ const noReduceAccumulatorCopyRule = defineRule({
983
+ meta: {
984
+ type: "problem",
985
+ docs: { description: "Disallow copying growing reducer accumulators with Object.assign, Array.from, or array copy methods." },
986
+ messages: { accumulatorCopy: "Do not copy the reducer accumulator on every iteration; growing copies can cause quadratic work. Mutate a fresh, locally owned accumulator and return it, or use an iterator pipeline/flatMap." }
987
+ },
988
+ createOnce(context) {
989
+ return { CallExpression(node) {
990
+ const method = arrayMethodTarget(node.callee);
991
+ if (method === null) return;
992
+ const reducer = enclosingReducer(node);
993
+ if (reducer === null) return;
994
+ const accumulator = context.sourceCode.getDeclaredVariables(reducer.callback).find((variable) => variable.identifiers.some((identifier) => identifier.start === reducer.accumulator.start));
995
+ if (accumulator === void 0) return;
996
+ const isAccumulator = (expression) => referencesAccumulator(context.sourceCode, expression, accumulator);
997
+ let copiesAccumulator = false;
998
+ if (method.name === "assign" && isGlobalCopyOwner(context.sourceCode, method.object, "Object")) {
999
+ const target = node.arguments[0];
1000
+ copiesAccumulator = target !== void 0 && unwrapArrayExpression(target).type === "ObjectExpression" && node.arguments.slice(1).some(isAccumulator);
1001
+ } else if (method.name === "from" && isGlobalCopyOwner(context.sourceCode, method.object, "Array")) {
1002
+ const source = node.arguments[0];
1003
+ copiesAccumulator = source !== void 0 && isAccumulator(source);
1004
+ } else if ([
1005
+ "concat",
1006
+ "slice",
1007
+ "toSpliced",
1008
+ "toSorted",
1009
+ "toReversed",
1010
+ "with"
1011
+ ].includes(method.name)) {
1012
+ const initialValue = reducer.initialValue;
1013
+ copiesAccumulator = initialValue !== void 0 && isKnownArrayExpression(context.sourceCode, initialValue) && isAccumulator(method.object);
1014
+ }
1015
+ if (copiesAccumulator) context.report({
1016
+ node,
1017
+ messageId: "accumulatorCopy"
1018
+ });
1019
+ } };
1020
+ }
1021
+ });
1022
+ //#endregion
1023
1023
  //#region src/anti-slop/shared/reflect-method.ts
1024
1024
  function isGlobalReflect(sourceCode, expression) {
1025
1025
  if (expression.type !== "Identifier" || expression.name !== "Reflect") return false;
@@ -1664,31 +1664,190 @@ const requireSafetyCommentForTypeAssertionRule = defineRule({
1664
1664
  }
1665
1665
  });
1666
1666
  //#endregion
1667
- //#region src/anti-slop/index.ts
1668
- /** Generic Oxlint rules that reject low-evidence and low-signal implementation patterns. */
1669
- const antiSlopPlugin = eslintCompatPlugin({
1670
- meta: { name: "anti-slop" },
1667
+ //#region src/shared/rule-options.ts
1668
+ /**
1669
+ * Rule options arrive as parsed JSON from the linter config, so this is the one
1670
+ * place their shape is checked. Returns the first option when it is an object.
1671
+ */
1672
+ function firstOptionObject(options) {
1673
+ const first = options[0];
1674
+ return typeof first === "object" && first !== null && !Array.isArray(first) ? first : {};
1675
+ }
1676
+ /** A string-valued key of the first option object, or undefined when absent or not a string. */
1677
+ function stringOption(options, key) {
1678
+ const value = firstOptionObject(options)[key];
1679
+ return typeof value === "string" ? value : void 0;
1680
+ }
1681
+ //#endregion
1682
+ //#region src/rules/no-hardcoded-jsx-text.ts
1683
+ const defaultWordPattern = String.raw`\p{L}{3,}`;
1684
+ /** A string literal that is the whole expression of `{...}` placed among an element's children. */
1685
+ function isChildStringLiteral(node) {
1686
+ const { expression, parent } = node;
1687
+ if (expression.type !== "Literal" || typeof expression.value !== "string") return false;
1688
+ return parent.type === "JSXElement" || parent.type === "JSXFragment";
1689
+ }
1690
+ /** Reject words written straight into JSX instead of coming from the translation dictionary. */
1691
+ const noHardcodedJsxTextRule = defineRule({
1692
+ meta: {
1693
+ type: "problem",
1694
+ docs: { description: "Disallow literal words in JSX children; every string on screen comes from the translation dictionary." },
1695
+ messages: { hardcodedText: "Do not write words straight into JSX. Every string on screen comes from the translation dictionary." },
1696
+ schema: [{
1697
+ type: "object",
1698
+ properties: { pattern: { type: "string" } },
1699
+ additionalProperties: false
1700
+ }]
1701
+ },
1702
+ create(context) {
1703
+ const word = new RegExp(stringOption(context.options, "pattern") ?? defaultWordPattern, "u");
1704
+ return {
1705
+ JSXText(node) {
1706
+ if (word.test(node.value)) context.report({
1707
+ node,
1708
+ messageId: "hardcodedText"
1709
+ });
1710
+ },
1711
+ JSXExpressionContainer(node) {
1712
+ if (isChildStringLiteral(node) && word.test(node.expression.value)) context.report({
1713
+ node: node.expression,
1714
+ messageId: "hardcodedText"
1715
+ });
1716
+ }
1717
+ };
1718
+ }
1719
+ });
1720
+ //#endregion
1721
+ //#region src/rules/no-use-effect.ts
1722
+ const effectHooks = /* @__PURE__ */ new Set(["useEffect", "useLayoutEffect"]);
1723
+ /** The effect hook a call reaches, whether called bare (`useEffect(...)`) or through a member (`React.useEffect(...)`). */
1724
+ function calledEffectHook(callee) {
1725
+ if (callee.type === "Identifier") return effectHooks.has(callee.name) ? callee.name : null;
1726
+ if (callee.type !== "MemberExpression" || callee.computed) return null;
1727
+ const { property } = callee;
1728
+ return property.type === "Identifier" && effectHooks.has(property.name) ? property.name : null;
1729
+ }
1730
+ function importedName(specifier) {
1731
+ return specifier.imported.type === "Identifier" ? specifier.imported.name : specifier.imported.value;
1732
+ }
1733
+ function isTypeOnly(specifier) {
1734
+ const declaration = specifier.parent;
1735
+ return specifier.importKind === "type" || declaration.type === "ImportDeclaration" && declaration.importKind === "type";
1736
+ }
1737
+ /** Reject `useEffect` and `useLayoutEffect`, called or imported. */
1738
+ const noUseEffectRule = defineRule({
1739
+ meta: {
1740
+ type: "problem",
1741
+ docs: { description: "Disallow useEffect and useLayoutEffect; derive during render, act in the event handler, or subscribe through a reactive query." },
1742
+ messages: {
1743
+ noEffect: "Do not call {{name}}. Derive the value during render, do the work in the event handler, or subscribe through a reactive query.",
1744
+ noEffectWithHint: "Do not call {{name}}. Derive the value during render, do the work in the event handler, or subscribe through a reactive query. {{hint}}"
1745
+ },
1746
+ schema: [{
1747
+ type: "object",
1748
+ properties: { hint: { type: "string" } },
1749
+ additionalProperties: false
1750
+ }]
1751
+ },
1752
+ create(context) {
1753
+ const hint = stringOption(context.options, "hint");
1754
+ const report = (node, name) => {
1755
+ if (hint === void 0) context.report({
1756
+ node,
1757
+ messageId: "noEffect",
1758
+ data: { name }
1759
+ });
1760
+ else context.report({
1761
+ node,
1762
+ messageId: "noEffectWithHint",
1763
+ data: {
1764
+ name,
1765
+ hint
1766
+ }
1767
+ });
1768
+ };
1769
+ return {
1770
+ CallExpression(node) {
1771
+ const name = calledEffectHook(node.callee);
1772
+ if (name !== null) report(node, name);
1773
+ },
1774
+ ImportSpecifier(node) {
1775
+ if (isTypeOnly(node)) return;
1776
+ const name = importedName(node);
1777
+ if (effectHooks.has(name)) report(node, name);
1778
+ }
1779
+ };
1780
+ }
1781
+ });
1782
+ //#endregion
1783
+ //#region src/rules/static-public-env.ts
1784
+ function isProcessEnv(node) {
1785
+ return node.type === "MemberExpression" && !node.computed && node.object.type === "Identifier" && node.object.name === "process" && node.property.type === "Identifier" && node.property.name === "env";
1786
+ }
1787
+ /** Reject every use of `process.env` that Expo's textual inlining cannot see. */
1788
+ const staticPublicEnvRule = defineRule({
1789
+ meta: {
1790
+ type: "problem",
1791
+ docs: { description: "Allow only static `process.env.NAME` reads; Expo replaces each one textually at bundle time and everything else is undefined on the device." },
1792
+ messages: {
1793
+ destructured: "Expo replaces each `process.env.EXPO_PUBLIC_*` read textually at bundle time, so there is no `process.env` object to destructure on the device. Read each variable as `process.env.NAME`.",
1794
+ computed: "Expo replaces each `process.env.EXPO_PUBLIC_*` read textually at bundle time, so a computed key is undefined on the device. Read the variable as `process.env.NAME` with the name spelled out.",
1795
+ bareValue: "Expo replaces each `process.env.EXPO_PUBLIC_*` read textually at bundle time, so `process.env` passed around as a value is empty on the device. Read each variable as `process.env.NAME`."
1796
+ }
1797
+ },
1798
+ create(context) {
1799
+ return { MemberExpression(node) {
1800
+ if (!isProcessEnv(node)) return;
1801
+ const { parent } = node;
1802
+ if (parent.type === "MemberExpression" && parent.object === node) {
1803
+ if (parent.computed) context.report({
1804
+ node: parent,
1805
+ messageId: "computed"
1806
+ });
1807
+ return;
1808
+ }
1809
+ if (parent.type === "VariableDeclarator" && parent.id.type === "ObjectPattern") {
1810
+ context.report({
1811
+ node: parent,
1812
+ messageId: "destructured"
1813
+ });
1814
+ return;
1815
+ }
1816
+ context.report({
1817
+ node,
1818
+ messageId: "bareValue"
1819
+ });
1820
+ } };
1821
+ }
1822
+ });
1823
+ //#endregion
1824
+ //#region src/index.ts
1825
+ const rdjPlugin = eslintCompatPlugin({
1826
+ meta: { name: "rdj" },
1671
1827
  rules: {
1672
1828
  "no-array-filter-map": noArrayFilterMapRule,
1673
- "no-reduce-accumulator-copy": noReduceAccumulatorCopyRule,
1674
1829
  "no-chained-type-assertions": noChainedTypeAssertionsRule,
1675
1830
  "no-conditional-empty-object-spread": noConditionalEmptyObjectSpreadRule,
1831
+ "no-hardcoded-jsx-text": noHardcodedJsxTextRule,
1676
1832
  "no-known-value-widening": noKnownValueWideningRule,
1677
1833
  "no-module-mocking": noModuleMockingRule,
1678
1834
  "no-object-parameters": noObjectParametersRule,
1835
+ "no-reduce-accumulator-copy": noReduceAccumulatorCopyRule,
1679
1836
  "no-reflect-apply": noReflectApplyRule,
1680
1837
  "no-reflect-get": noReflectGetRule,
1681
1838
  "no-runtime-typeof": noRuntimeTypeofRule,
1682
- "no-unsafe-dictionary-type": noUnsafeDictionaryTypeRule,
1683
1839
  "no-shape-in-symbol-names": noForbiddenTermInSymbolNamesRule,
1684
1840
  "no-unknown-parameters": noUnknownParametersRule,
1685
1841
  "no-unknown-returns": noUnknownReturnsRule,
1686
1842
  "no-unknown-type-aliases": noUnknownTypeAliasesRule,
1843
+ "no-unsafe-dictionary-type": noUnsafeDictionaryTypeRule,
1844
+ "no-use-effect": noUseEffectRule,
1687
1845
  "no-widen-then-assert": noWidenThenAssertRule,
1688
- "require-safety-comment-for-type-assertion": requireSafetyCommentForTypeAssertionRule
1846
+ "require-safety-comment-for-type-assertion": requireSafetyCommentForTypeAssertionRule,
1847
+ "static-public-env": staticPublicEnvRule
1689
1848
  }
1690
1849
  });
1691
1850
  //#endregion
1692
- export { antiSlopPlugin as default };
1851
+ export { rdjPlugin as default };
1693
1852
 
1694
- //# sourceMappingURL=anti-slop.mjs.map
1853
+ //# sourceMappingURL=index.mjs.map