@ashstack/lint 0.1.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.
- package/LICENSE +21 -0
- package/README.md +60 -0
- package/RULES.md +2881 -0
- package/dist/core/index.d.ts +15 -0
- package/dist/core/index.js +222 -0
- package/dist/core/rules/core/components-tsx-only.d.ts +2 -0
- package/dist/core/rules/core/components-tsx-only.js +37 -0
- package/dist/core/rules/core/hoist-intl.d.ts +2 -0
- package/dist/core/rules/core/hoist-intl.js +32 -0
- package/dist/core/rules/core/index.d.ts +2 -0
- package/dist/core/rules/core/index.js +18 -0
- package/dist/core/rules/core/no-comments.d.ts +2 -0
- package/dist/core/rules/core/no-comments.js +194 -0
- package/dist/core/rules/core/no-naming-convention.d.ts +2 -0
- package/dist/core/rules/core/no-naming-convention.js +143 -0
- package/dist/core/rules/core/use-design-system.d.ts +2 -0
- package/dist/core/rules/core/use-design-system.js +147 -0
- package/dist/core/rules/zod/index.d.ts +2 -0
- package/dist/core/rules/zod/index.js +12 -0
- package/dist/core/rules/zod/prefer-enum.d.ts +2 -0
- package/dist/core/rules/zod/prefer-enum.js +44 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/lib/ast.d.ts +44 -0
- package/dist/lib/ast.js +162 -0
- package/dist/lib/detect.d.ts +9 -0
- package/dist/lib/detect.js +42 -0
- package/dist/lib/merge.d.ts +9 -0
- package/dist/lib/merge.js +18 -0
- package/dist/lib/module.d.ts +19 -0
- package/dist/lib/module.js +49 -0
- package/dist/lib/types.d.ts +114 -0
- package/dist/lib/types.js +1 -0
- package/dist/react/index.d.ts +9 -0
- package/dist/react/index.js +126 -0
- package/dist/react/rules/i18n/index.d.ts +2 -0
- package/dist/react/rules/i18n/index.js +16 -0
- package/dist/react/rules/i18n/no-bare-attrs.d.ts +2 -0
- package/dist/react/rules/i18n/no-bare-attrs.js +38 -0
- package/dist/react/rules/i18n/no-bare-text.d.ts +2 -0
- package/dist/react/rules/i18n/no-bare-text.js +26 -0
- package/dist/react/rules/i18n/no-bare-toast.d.ts +2 -0
- package/dist/react/rules/i18n/no-bare-toast.js +38 -0
- package/dist/react/rules/query/index.d.ts +2 -0
- package/dist/react/rules/query/index.js +20 -0
- package/dist/react/rules/query/next-page-param-undefined.d.ts +2 -0
- package/dist/react/rules/query/next-page-param-undefined.js +26 -0
- package/dist/react/rules/query/no-deprecated-filters.d.ts +2 -0
- package/dist/react/rules/query/no-deprecated-filters.js +63 -0
- package/dist/react/rules/query/no-fetch-in-query-fn.d.ts +2 -0
- package/dist/react/rules/query/no-fetch-in-query-fn.js +22 -0
- package/dist/react/rules/query/no-inline-keys.d.ts +2 -0
- package/dist/react/rules/query/no-inline-keys.js +107 -0
- package/dist/react/rules/query/require-destructured-hooks.d.ts +2 -0
- package/dist/react/rules/query/require-destructured-hooks.js +41 -0
- package/dist/react/rules/query/shared.d.ts +2 -0
- package/dist/react/rules/query/shared.js +10 -0
- package/dist/react/rules/zustand/index.d.ts +2 -0
- package/dist/react/rules/zustand/index.js +12 -0
- package/dist/react/rules/zustand/require-selector.d.ts +2 -0
- package/dist/react/rules/zustand/require-selector.js +62 -0
- package/dist/react-native/index.d.ts +11 -0
- package/dist/react-native/index.js +113 -0
- package/dist/react-native/rules/keyboard/index.d.ts +2 -0
- package/dist/react-native/rules/keyboard/index.js +18 -0
- package/dist/react-native/rules/legend-list/index.d.ts +2 -0
- package/dist/react-native/rules/legend-list/index.js +51 -0
- package/dist/react-native/rules/legend-list/no-flex-in-content-container.d.ts +2 -0
- package/dist/react-native/rules/legend-list/no-flex-in-content-container.js +77 -0
- package/dist/react-native/rules/legend-list/no-index-key-extractor.d.ts +2 -0
- package/dist/react-native/rules/legend-list/no-index-key-extractor.js +26 -0
- package/dist/react-native/rules/legend-list/no-inline-data.d.ts +2 -0
- package/dist/react-native/rules/legend-list/no-inline-data.js +25 -0
- package/dist/react-native/rules/legend-list/no-inline-extra-data.d.ts +2 -0
- package/dist/react-native/rules/legend-list/no-inline-extra-data.js +21 -0
- package/dist/react-native/rules/legend-list/no-inline-render-item-props.d.ts +2 -0
- package/dist/react-native/rules/legend-list/no-inline-render-item-props.js +35 -0
- package/dist/react-native/rules/legend-list/no-mixed-children.d.ts +2 -0
- package/dist/react-native/rules/legend-list/no-mixed-children.js +24 -0
- package/dist/react-native/rules/legend-list/no-remount-key.d.ts +2 -0
- package/dist/react-native/rules/legend-list/no-remount-key.js +18 -0
- package/dist/react-native/rules/legend-list/no-scrollview-map.d.ts +2 -0
- package/dist/react-native/rules/legend-list/no-scrollview-map.js +27 -0
- package/dist/react-native/rules/legend-list/no-unsupported-props.d.ts +2 -0
- package/dist/react-native/rules/legend-list/no-unsupported-props.js +29 -0
- package/dist/react-native/rules/legend-list/required-props.d.ts +2 -0
- package/dist/react-native/rules/legend-list/required-props.js +23 -0
- package/dist/react-native/rules/legend-list/shared.d.ts +19 -0
- package/dist/react-native/rules/legend-list/shared.js +25 -0
- package/dist/react-native/rules/legend-list/typed-items-need-item-type.d.ts +2 -0
- package/dist/react-native/rules/legend-list/typed-items-need-item-type.js +49 -0
- package/dist/react-native/rules/legend-state/index.d.ts +2 -0
- package/dist/react-native/rules/legend-state/index.js +35 -0
- package/dist/react-native/rules/legend-state/naming.d.ts +2 -0
- package/dist/react-native/rules/legend-state/naming.js +26 -0
- package/dist/react-native/rules/legend-state/no-assignment.d.ts +2 -0
- package/dist/react-native/rules/legend-state/no-assignment.js +31 -0
- package/dist/react-native/rules/legend-state/no-nested-observable.d.ts +2 -0
- package/dist/react-native/rules/legend-state/no-nested-observable.js +23 -0
- package/dist/react-native/rules/legend-state/no-object-selector.d.ts +2 -0
- package/dist/react-native/rules/legend-state/no-object-selector.js +47 -0
- package/dist/react-native/rules/legend-state/no-observable-in-component.d.ts +2 -0
- package/dist/react-native/rules/legend-state/no-observable-in-component.js +46 -0
- package/dist/react-native/rules/legend-state/no-peek-in-selector.d.ts +2 -0
- package/dist/react-native/rules/legend-state/no-peek-in-selector.js +67 -0
- package/dist/react-native/rules/legend-state/no-react-mirror.d.ts +2 -0
- package/dist/react-native/rules/legend-state/no-react-mirror.js +33 -0
- package/dist/react-native/rules/legend-state/no-untracked-get-in-jsx.d.ts +2 -0
- package/dist/react-native/rules/legend-state/no-untracked-get-in-jsx.js +52 -0
- package/dist/react-native/rules/legend-state/shared.d.ts +9 -0
- package/dist/react-native/rules/legend-state/shared.js +23 -0
- package/dist/react-native/rules/react-native/hoist-stateless-function.d.ts +2 -0
- package/dist/react-native/rules/react-native/hoist-stateless-function.js +59 -0
- package/dist/react-native/rules/react-native/index.d.ts +2 -0
- package/dist/react-native/rules/react-native/index.js +50 -0
- package/dist/react-native/rules/react-native/no-conditional-style-array.d.ts +2 -0
- package/dist/react-native/rules/react-native/no-conditional-style-array.js +23 -0
- package/dist/react-native/rules/react-native/no-dynamic-import.d.ts +2 -0
- package/dist/react-native/rules/react-native/no-dynamic-import.js +18 -0
- package/dist/react-native/rules/react-native/no-keyboard-will-events.d.ts +2 -0
- package/dist/react-native/rules/react-native/no-keyboard-will-events.js +18 -0
- package/dist/react-native/rules/react-native/no-leaked-render.d.ts +2 -0
- package/dist/react-native/rules/react-native/no-leaked-render.js +43 -0
- package/dist/react-native/rules/react-native/no-manual-memo.d.ts +2 -0
- package/dist/react-native/rules/react-native/no-manual-memo.js +87 -0
- package/dist/react-native/rules/react-native/no-redundant-view-nesting.d.ts +2 -0
- package/dist/react-native/rules/react-native/no-redundant-view-nesting.js +36 -0
- package/dist/react-native/rules/react-native/no-rn-image-network-source.d.ts +2 -0
- package/dist/react-native/rules/react-native/no-rn-image-network-source.js +58 -0
- package/dist/react-native/rules/react-native/no-rn-namespace-import.d.ts +2 -0
- package/dist/react-native/rules/react-native/no-rn-namespace-import.js +38 -0
- package/dist/react-native/rules/react-native/no-scroll-position-state.d.ts +2 -0
- package/dist/react-native/rules/react-native/no-scroll-position-state.js +26 -0
- package/dist/react-native/rules/react-native/no-unlabeled-icon-pressable.d.ts +2 -0
- package/dist/react-native/rules/react-native/no-unlabeled-icon-pressable.js +62 -0
- package/dist/react-native/rules/reanimated/animated-reaction-safety.d.ts +2 -0
- package/dist/react-native/rules/reanimated/animated-reaction-safety.js +110 -0
- package/dist/react-native/rules/reanimated/animated-style-needs-animated-component.d.ts +2 -0
- package/dist/react-native/rules/reanimated/animated-style-needs-animated-component.js +72 -0
- package/dist/react-native/rules/reanimated/animated-updater-purity.d.ts +2 -0
- package/dist/react-native/rules/reanimated/animated-updater-purity.js +38 -0
- package/dist/react-native/rules/reanimated/gpu-properties-only.d.ts +2 -0
- package/dist/react-native/rules/reanimated/gpu-properties-only.js +80 -0
- package/dist/react-native/rules/reanimated/hoist-layout-animation-builder.d.ts +2 -0
- package/dist/react-native/rules/reanimated/hoist-layout-animation-builder.js +43 -0
- package/dist/react-native/rules/reanimated/index.d.ts +2 -0
- package/dist/react-native/rules/reanimated/index.js +51 -0
- package/dist/react-native/rules/reanimated/interpolate-needs-clamp.d.ts +2 -0
- package/dist/react-native/rules/reanimated/interpolate-needs-clamp.js +41 -0
- package/dist/react-native/rules/reanimated/no-react-state-from-continuous-worklet.d.ts +2 -0
- package/dist/react-native/rules/reanimated/no-react-state-from-continuous-worklet.js +86 -0
- package/dist/react-native/rules/reanimated/no-shared-value-dot-value.d.ts +2 -0
- package/dist/react-native/rules/reanimated/no-shared-value-dot-value.js +112 -0
- package/dist/react-native/rules/reanimated/prefer-lazy-shared-value-initializer.d.ts +2 -0
- package/dist/react-native/rules/reanimated/prefer-lazy-shared-value-initializer.js +24 -0
- package/dist/react-native/rules/reanimated/schedule-on-rn-scope.d.ts +2 -0
- package/dist/react-native/rules/reanimated/schedule-on-rn-scope.js +21 -0
- package/dist/react-native/rules/reanimated/shared-value-usage.d.ts +2 -0
- package/dist/react-native/rules/reanimated/shared-value-usage.js +105 -0
- package/dist/react-native/rules/reanimated/shared.d.ts +5 -0
- package/dist/react-native/rules/reanimated/shared.js +13 -0
- package/dist/react-native/rules/skia/canvas-opaque.d.ts +2 -0
- package/dist/react-native/rules/skia/canvas-opaque.js +49 -0
- package/dist/react-native/rules/skia/index.d.ts +2 -0
- package/dist/react-native/rules/skia/index.js +21 -0
- package/dist/react-native/rules/turbo-image/index.d.ts +2 -0
- package/dist/react-native/rules/turbo-image/index.js +14 -0
- package/dist/react-native/rules/turbo-image/require-cache-policy.d.ts +2 -0
- package/dist/react-native/rules/turbo-image/require-cache-policy.js +21 -0
- package/dist/react-native/rules/turbo-image/require-resize.d.ts +2 -0
- package/dist/react-native/rules/turbo-image/require-resize.js +22 -0
- package/dist/react-native/rules/unistyles/animated-theme.d.ts +2 -0
- package/dist/react-native/rules/unistyles/animated-theme.js +37 -0
- package/dist/react-native/rules/unistyles/content-container.d.ts +2 -0
- package/dist/react-native/rules/unistyles/content-container.js +73 -0
- package/dist/react-native/rules/unistyles/in-sheet.d.ts +2 -0
- package/dist/react-native/rules/unistyles/in-sheet.js +116 -0
- package/dist/react-native/rules/unistyles/index.d.ts +2 -0
- package/dist/react-native/rules/unistyles/index.js +58 -0
- package/dist/react-native/rules/unistyles/insets.d.ts +2 -0
- package/dist/react-native/rules/unistyles/insets.js +92 -0
- package/dist/react-native/rules/unistyles/no-hardcoded-color.d.ts +2 -0
- package/dist/react-native/rules/unistyles/no-hardcoded-color.js +30 -0
- package/dist/react-native/rules/unistyles/no-hardcoded-spacing.d.ts +2 -0
- package/dist/react-native/rules/unistyles/no-hardcoded-spacing.js +78 -0
- package/dist/react-native/rules/unistyles/no-margin.d.ts +2 -0
- package/dist/react-native/rules/unistyles/no-margin.js +19 -0
- package/dist/react-native/rules/unistyles/no-style-spread.d.ts +2 -0
- package/dist/react-native/rules/unistyles/no-style-spread.js +41 -0
- package/dist/react-native/rules/unistyles/no-unused-styles.d.ts +2 -0
- package/dist/react-native/rules/unistyles/no-unused-styles.js +99 -0
- package/dist/react-native/rules/unistyles/rtl-style-call.d.ts +2 -0
- package/dist/react-native/rules/unistyles/rtl-style-call.js +42 -0
- package/dist/react-native/rules/unistyles/shared.d.ts +16 -0
- package/dist/react-native/rules/unistyles/shared.js +70 -0
- package/dist/react-native/rules/unistyles/theme-screen-component.d.ts +2 -0
- package/dist/react-native/rules/unistyles/theme-screen-component.js +22 -0
- package/dist/react-native/rules/unistyles/theme-style-attr.d.ts +2 -0
- package/dist/react-native/rules/unistyles/theme-style-attr.js +18 -0
- package/dist/react-native/stylesheet.d.ts +11 -0
- package/dist/react-native/stylesheet.js +44 -0
- package/package.json +70 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { ancestors, calleeName, gate, isFunction, problem, subtreeHas } from "../../../lib/ast.js";
|
|
2
|
+
import { CREATE_MARKER, isStyleSheetCreate } from "../../stylesheet.js";
|
|
3
|
+
export { CREATE_MARKER, isStyleSheetCreate, propertyName, stylesObjectOf, } from "../../stylesheet.js";
|
|
4
|
+
export const memberPath = (node) => {
|
|
5
|
+
const parts = [];
|
|
6
|
+
let current = node;
|
|
7
|
+
while (current?.type === "MemberExpression") {
|
|
8
|
+
const { property } = current;
|
|
9
|
+
if (property.type === "Identifier")
|
|
10
|
+
parts.unshift(property.name);
|
|
11
|
+
else if (property.type === "Literal")
|
|
12
|
+
parts.unshift(String(property.value));
|
|
13
|
+
else
|
|
14
|
+
parts.unshift("*");
|
|
15
|
+
current = current.object;
|
|
16
|
+
}
|
|
17
|
+
if (current?.type === "Identifier")
|
|
18
|
+
parts.unshift(current.name);
|
|
19
|
+
return parts.join(".");
|
|
20
|
+
};
|
|
21
|
+
export const declaresUseUnistylesTheme = (scope) => subtreeHas(scope, current => {
|
|
22
|
+
if (current.type !== "VariableDeclarator")
|
|
23
|
+
return false;
|
|
24
|
+
const { id, init } = current;
|
|
25
|
+
return (id.type === "ObjectPattern" &&
|
|
26
|
+
calleeName(init) === "useUnistyles" &&
|
|
27
|
+
id.properties.some(property => property.type === "Property" && property.key.type === "Identifier" && property.key.name === "theme"));
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* The enclosing function that destructures a `useUnistyles()` theme, innermost first. Walking past the
|
|
31
|
+
* innermost function matters: the read is often inside a callback the component passes down.
|
|
32
|
+
*/
|
|
33
|
+
export const themeConsumingComponent = (node) => {
|
|
34
|
+
for (const current of ancestors(node)) {
|
|
35
|
+
if (isFunction(current) && declaresUseUnistylesTheme(current))
|
|
36
|
+
return current;
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
};
|
|
40
|
+
export const readsTheme = (node) => subtreeHas(node, current => current.type === "MemberExpression" && memberPath(current).startsWith("theme."));
|
|
41
|
+
/**
|
|
42
|
+
* Builds a rule whose visitors only fire inside `StyleSheet.create(...)`, by tracking how deeply
|
|
43
|
+
* nested the traversal currently is in such a call. The depth resets per file in `before()`, which
|
|
44
|
+
* also runs the text gate.
|
|
45
|
+
*/
|
|
46
|
+
export const inCreate = (description, visit) => problem(description, {
|
|
47
|
+
createOnce(context) {
|
|
48
|
+
let createDepth = 0;
|
|
49
|
+
const inside = () => createDepth > 0;
|
|
50
|
+
const visitors = visit(context, inside);
|
|
51
|
+
const { CallExpression: enter, "CallExpression:exit": exit } = visitors;
|
|
52
|
+
return {
|
|
53
|
+
...visitors,
|
|
54
|
+
before() {
|
|
55
|
+
createDepth = 0;
|
|
56
|
+
return gate(context, CREATE_MARKER);
|
|
57
|
+
},
|
|
58
|
+
CallExpression(node) {
|
|
59
|
+
if (isStyleSheetCreate(node))
|
|
60
|
+
createDepth += 1;
|
|
61
|
+
enter?.(node);
|
|
62
|
+
},
|
|
63
|
+
"CallExpression:exit"(node) {
|
|
64
|
+
exit?.(node);
|
|
65
|
+
if (isStyleSheetCreate(node))
|
|
66
|
+
createDepth -= 1;
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { hasAncestor, problem } from "../../../lib/ast.js";
|
|
2
|
+
import { isStyleSheetCreate, memberPath, themeConsumingComponent } from "./shared.js";
|
|
3
|
+
const THEME_SCREEN_PREFIX = "theme.screen.";
|
|
4
|
+
const MESSAGE = "Read current screen values from `useUnistyles().rt.screen` or `useWindowDimensions()` instead of the theme's module-initialization snapshot.";
|
|
5
|
+
export const themeScreenComponent = problem("`theme.screen.*` is a snapshot taken at module initialization, so a component that reads it never sees the current size. `useUnistyles().rt.screen` and `useWindowDimensions` do.", {
|
|
6
|
+
createOnce(context) {
|
|
7
|
+
return {
|
|
8
|
+
MemberExpression(node) {
|
|
9
|
+
if (!memberPath(node).startsWith(THEME_SCREEN_PREFIX))
|
|
10
|
+
return;
|
|
11
|
+
const { parent } = node;
|
|
12
|
+
if (parent.type === "MemberExpression" && parent.object === node)
|
|
13
|
+
return;
|
|
14
|
+
if (hasAncestor(node, isStyleSheetCreate))
|
|
15
|
+
return;
|
|
16
|
+
if (!themeConsumingComponent(node))
|
|
17
|
+
return;
|
|
18
|
+
context.report({ node, message: MESSAGE });
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { problem } from "../../../lib/ast.js";
|
|
2
|
+
import { readsTheme, themeConsumingComponent } from "./shared.js";
|
|
3
|
+
const MESSAGE = "Resolve theme-dependent style values inside `StyleSheet.create` instead of reading `theme` in a JSX `style` prop or passing it into a dynamic style function.";
|
|
4
|
+
export const themeStyleAttr = problem("Theme-dependent values belong in `StyleSheet.create`, not in a JSX `style` prop that reads a `useUnistyles()` theme.", {
|
|
5
|
+
createOnce(context) {
|
|
6
|
+
return {
|
|
7
|
+
JSXAttribute(node) {
|
|
8
|
+
if (node.name.type !== "JSXIdentifier" || node.name.name !== "style")
|
|
9
|
+
return;
|
|
10
|
+
if (!readsTheme(node))
|
|
11
|
+
return;
|
|
12
|
+
if (!themeConsumingComponent(node))
|
|
13
|
+
return;
|
|
14
|
+
context.report({ node, message: MESSAGE });
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
},
|
|
18
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AstNode } from "../lib/types.js";
|
|
2
|
+
/** The object literal a stylesheet is built from. */
|
|
3
|
+
export type StylesObject = Extract<AstNode, {
|
|
4
|
+
type: "ObjectExpression";
|
|
5
|
+
}>;
|
|
6
|
+
/** Source-text gate for the stylesheet rules. Just the object, so `StyleSheet\n .create(...)` still counts. */
|
|
7
|
+
export declare const CREATE_MARKER = "StyleSheet";
|
|
8
|
+
export declare const isStyleSheetCreate: (node: AstNode | null | undefined) => boolean;
|
|
9
|
+
export declare const propertyName: (node: AstNode) => string;
|
|
10
|
+
/** The styles object a `StyleSheet.create` argument holds: a literal, or the one its theme function returns. */
|
|
11
|
+
export declare const stylesObjectOf: (factory: AstNode | null | undefined) => StylesObject | null;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { findInSubtree } from "../lib/ast.js";
|
|
2
|
+
/** Source-text gate for the stylesheet rules. Just the object, so `StyleSheet\n .create(...)` still counts. */
|
|
3
|
+
export const CREATE_MARKER = "StyleSheet";
|
|
4
|
+
export const isStyleSheetCreate = (node) => {
|
|
5
|
+
if (node?.type !== "CallExpression")
|
|
6
|
+
return false;
|
|
7
|
+
const { callee } = node;
|
|
8
|
+
if (callee.type !== "MemberExpression")
|
|
9
|
+
return false;
|
|
10
|
+
const { object, property } = callee;
|
|
11
|
+
return (object.type === "Identifier" &&
|
|
12
|
+
object.name === "StyleSheet" &&
|
|
13
|
+
property.type === "Identifier" &&
|
|
14
|
+
property.name === "create");
|
|
15
|
+
};
|
|
16
|
+
export const propertyName = (node) => {
|
|
17
|
+
if (node.type !== "Property" || node.computed)
|
|
18
|
+
return "";
|
|
19
|
+
const { key } = node;
|
|
20
|
+
if (key.type === "Identifier")
|
|
21
|
+
return key.name;
|
|
22
|
+
if (key.type === "Literal")
|
|
23
|
+
return String(key.value);
|
|
24
|
+
return "";
|
|
25
|
+
};
|
|
26
|
+
const themeFunctionBody = (factory) => factory.type === "ArrowFunctionExpression" || factory.type === "FunctionExpression" ? factory.body : null;
|
|
27
|
+
const returnsAnObject = (node) => node.type === "ReturnStatement" && node.argument?.type === "ObjectExpression";
|
|
28
|
+
const objectReturnedFrom = (body) => {
|
|
29
|
+
if (body.type === "ObjectExpression")
|
|
30
|
+
return body;
|
|
31
|
+
const found = findInSubtree(body, returnsAnObject);
|
|
32
|
+
if (found?.type !== "ReturnStatement" || found.argument?.type !== "ObjectExpression")
|
|
33
|
+
return null;
|
|
34
|
+
return found.argument;
|
|
35
|
+
};
|
|
36
|
+
/** The styles object a `StyleSheet.create` argument holds: a literal, or the one its theme function returns. */
|
|
37
|
+
export const stylesObjectOf = (factory) => {
|
|
38
|
+
if (!factory)
|
|
39
|
+
return null;
|
|
40
|
+
if (factory.type === "ObjectExpression")
|
|
41
|
+
return factory;
|
|
42
|
+
const body = themeFunctionBody(factory);
|
|
43
|
+
return body === null ? null : objectReturnedFrom(body);
|
|
44
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ashstack/lint",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "ashStack shared oxlint configuration and custom rules. Entries: core, react, react-native, with per-library rule groups auto-detected from your dependencies. Consume from oxlint.config.mts.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Ali Alshehri (https://github.com/AlshehriAli0)",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/AlshehriAli0/ashStack.git",
|
|
11
|
+
"directory": "packages/lint"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/AlshehriAli0/ashStack/tree/main/packages/lint#readme",
|
|
14
|
+
"bugs": "https://github.com/AlshehriAli0/ashStack/issues",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"oxlint",
|
|
17
|
+
"oxc",
|
|
18
|
+
"lint",
|
|
19
|
+
"linter",
|
|
20
|
+
"eslint-config",
|
|
21
|
+
"typescript",
|
|
22
|
+
"react",
|
|
23
|
+
"react-native",
|
|
24
|
+
"expo"
|
|
25
|
+
],
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"default": "./dist/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./core": {
|
|
32
|
+
"types": "./dist/core/index.d.ts",
|
|
33
|
+
"default": "./dist/core/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./react": {
|
|
36
|
+
"types": "./dist/react/index.d.ts",
|
|
37
|
+
"default": "./dist/react/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./react-native": {
|
|
40
|
+
"types": "./dist/react-native/index.d.ts",
|
|
41
|
+
"default": "./dist/react-native/index.js"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist",
|
|
46
|
+
"RULES.md"
|
|
47
|
+
],
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"eslint-plugin-react-you-might-not-need-an-effect": "^1.0.1"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"oxlint": ">=1.79.0",
|
|
56
|
+
"oxlint-tsgolint": ">=7.0.0"
|
|
57
|
+
},
|
|
58
|
+
"peerDependenciesMeta": {
|
|
59
|
+
"oxlint-tsgolint": {
|
|
60
|
+
"optional": true
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"prepack": "rm -rf dist && tsc"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@types/node": "^22.10.0",
|
|
68
|
+
"typescript": "^7.0.2"
|
|
69
|
+
}
|
|
70
|
+
}
|