@imranbarbhuiya/oxc-config 0.2.2 → 0.3.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.
@@ -0,0 +1,247 @@
1
+ import { matchesFileGlob } from "../config.js";
2
+ import { definePlugin, defineRule } from "@oxlint/plugins";
3
+
4
+ //#region src/plugins/effect.ts
5
+ const DEFAULT_EDGE_FILES = [
6
+ "**/main.ts",
7
+ "**/*.test.ts",
8
+ "**/scripts/**"
9
+ ];
10
+ const RUN_METHODS = /* @__PURE__ */ new Set([
11
+ "runCallback",
12
+ "runFork",
13
+ "runPromise",
14
+ "runPromiseExit",
15
+ "runSync",
16
+ "runSyncExit"
17
+ ]);
18
+ const FAIL_METHODS = /* @__PURE__ */ new Set([
19
+ "die",
20
+ "dieMessage",
21
+ "dieSync",
22
+ "fail",
23
+ "failCause",
24
+ "failCauseSync",
25
+ "failSync"
26
+ ]);
27
+ const FN_METHODS = /* @__PURE__ */ new Set(["fn", "fnUntraced"]);
28
+ const FN_NAMED = /* @__PURE__ */ new Set(["fn"]);
29
+ const GEN = /* @__PURE__ */ new Set(["gen"]);
30
+ const GEN_OR_FN = /* @__PURE__ */ new Set(["gen", ...FN_METHODS]);
31
+ function isEffectMember(node, methods) {
32
+ return node.type === "MemberExpression" && !node.computed && node.object.type === "Identifier" && node.object.name === "Effect" && node.property.type === "Identifier" && methods.has(node.property.name);
33
+ }
34
+ function isEffectCall(node, methods) {
35
+ return node?.type === "CallExpression" && isEffectMember(node.callee, methods);
36
+ }
37
+ function staticString(node) {
38
+ if (node?.type === "Literal" && typeof node.value === "string") return node.value;
39
+ if (node?.type !== "TemplateLiteral" || node.expressions.length > 0) return void 0;
40
+ return node.quasis[0]?.value.cooked ?? void 0;
41
+ }
42
+ function isNamedFnFactory(node) {
43
+ return isEffectCall(node, FN_NAMED) && staticString(node.arguments[0]) !== void 0;
44
+ }
45
+ function isEffectGeneratorBody(fn) {
46
+ if (fn.type !== "FunctionExpression" || !fn.generator) return false;
47
+ const call = fn.parent;
48
+ if (call.type !== "CallExpression" || !call.arguments.includes(fn)) return false;
49
+ if (isEffectMember(call.callee, GEN_OR_FN)) return true;
50
+ return isNamedFnFactory(call.callee);
51
+ }
52
+ function isEffectFnCall(node) {
53
+ if (node.type !== "CallExpression") return false;
54
+ if (isNamedFnFactory(node.callee)) return true;
55
+ return isEffectCall(node, FN_METHODS) && node.arguments[0]?.type === "FunctionExpression";
56
+ }
57
+ function isGenOrPipedGen(node) {
58
+ if (node?.type !== "CallExpression") return false;
59
+ const { callee } = node;
60
+ if (callee.type === "MemberExpression" && !callee.computed && callee.property.type === "Identifier" && callee.property.name === "pipe") return isEffectCall(callee.object, GEN);
61
+ return isEffectMember(callee, GEN);
62
+ }
63
+ function returnedExpression(fn) {
64
+ const { body } = fn;
65
+ if (!body) return void 0;
66
+ if (body.type !== "BlockStatement") return body;
67
+ if (body.body.length !== 1) return void 0;
68
+ const [statement] = body.body;
69
+ return statement.type === "ReturnStatement" ? statement.argument : void 0;
70
+ }
71
+ function isReusableFunction(fn) {
72
+ if (fn.type === "FunctionDeclaration") return true;
73
+ const { parent } = fn;
74
+ if (parent.type === "VariableDeclarator") return parent.init === fn;
75
+ if (parent.type === "Property" || parent.type === "PropertyDefinition") return parent.value === fn;
76
+ return parent.type === "MethodDefinition" || parent.type === "ExportDefaultDeclaration";
77
+ }
78
+ function bindingName(node) {
79
+ const { parent } = node;
80
+ if (!parent) return void 0;
81
+ if (parent.type === "VariableDeclarator" && parent.init === node && parent.id.type === "Identifier") return parent.id.name;
82
+ if ((parent.type === "Property" || parent.type === "PropertyDefinition") && parent.value === node && !parent.computed) {
83
+ if (parent.key.type === "Identifier") return parent.key.name;
84
+ return staticString(parent.key);
85
+ }
86
+ }
87
+ const noGenWrapper = defineRule({
88
+ meta: {
89
+ type: "suggestion",
90
+ docs: { description: "Disallow functions that only wrap and return `Effect.gen`" },
91
+ messages: { noGenWrapper: "Avoid functions that only wrap and return `Effect.gen`. Use `Effect.fn(\"name\")(function* (...) {...})` or `Effect.fnUntraced` instead." }
92
+ },
93
+ createOnce(context) {
94
+ function check(fn) {
95
+ if (fn.generator || !isReusableFunction(fn)) return;
96
+ if (isGenOrPipedGen(returnedExpression(fn))) context.report({
97
+ node: fn,
98
+ messageId: "noGenWrapper"
99
+ });
100
+ }
101
+ return {
102
+ ArrowFunctionExpression: check,
103
+ FunctionDeclaration: check,
104
+ FunctionExpression: check
105
+ };
106
+ }
107
+ });
108
+ const fnNameMatches = defineRule({
109
+ meta: {
110
+ type: "suggestion",
111
+ docs: { description: "Require the `Effect.fn` span name to match the binding it is assigned to" },
112
+ fixable: "code",
113
+ messages: { mismatch: "`Effect.fn(\"{{name}}\")` is assigned to `{{binding}}`. Use \"{{binding}}\" or \"<Service>.{{binding}}\"." }
114
+ },
115
+ createOnce(context) {
116
+ return { CallExpression(node) {
117
+ if (!isNamedFnFactory(node.callee)) return;
118
+ const binding = bindingName(node);
119
+ const nameNode = node.callee.arguments[0];
120
+ const name = staticString(nameNode);
121
+ if (!binding || name === void 0) return;
122
+ if (name === binding || name.endsWith(`.${binding}`)) return;
123
+ context.report({
124
+ node: nameNode,
125
+ messageId: "mismatch",
126
+ data: {
127
+ name,
128
+ binding
129
+ },
130
+ fix(fixer) {
131
+ const quote = context.sourceCode.getText(nameNode).at(0) ?? "'";
132
+ const prefix = name.includes(".") ? name.slice(0, name.lastIndexOf(".") + 1) : "";
133
+ return fixer.replaceText(nameNode, `${quote}${prefix}${binding}${quote}`);
134
+ }
135
+ });
136
+ } };
137
+ }
138
+ });
139
+ const returnYieldError = defineRule({
140
+ meta: {
141
+ type: "problem",
142
+ docs: { description: "Require `return yield*` when yielding an error so TypeScript knows execution stops" },
143
+ fixable: "code",
144
+ messages: { missingReturn: "Use `return yield* ...` when raising an error so TypeScript knows the generator stops here." }
145
+ },
146
+ createOnce(context) {
147
+ return { YieldExpression(node) {
148
+ if (!node.delegate || !node.argument || node.parent.type !== "ExpressionStatement") return;
149
+ if (node.argument.type !== "NewExpression" && !isEffectCall(node.argument, FAIL_METHODS)) return;
150
+ context.report({
151
+ node,
152
+ messageId: "missingReturn",
153
+ fix: (fixer) => fixer.insertTextBefore(node, "return ")
154
+ });
155
+ } };
156
+ }
157
+ });
158
+ const noPipeOnFn = defineRule({
159
+ meta: {
160
+ type: "suggestion",
161
+ docs: { description: "Disallow `.pipe` on `Effect.fn` / `Effect.fnUntraced`; pass combinators as extra arguments" },
162
+ messages: { noPipe: "Do not use `.pipe` with `Effect.fn`. Pass the combinators as extra arguments: `Effect.fn(\"name\")(function* () {...}, Effect.withSpan(...))`." }
163
+ },
164
+ createOnce(context) {
165
+ return { MemberExpression(node) {
166
+ if (node.computed || node.property.type !== "Identifier" || node.property.name !== "pipe") return;
167
+ if (!isEffectFnCall(node.object)) return;
168
+ context.report({
169
+ node: node.property,
170
+ messageId: "noPipe"
171
+ });
172
+ } };
173
+ }
174
+ });
175
+ const noThrowInGen = defineRule({
176
+ meta: {
177
+ type: "problem",
178
+ docs: { description: "Disallow `throw` inside `Effect.gen` / `Effect.fn` generators" },
179
+ messages: { noThrow: "Do not throw inside an Effect generator; a throw becomes a defect. Use `return yield* new SomeError(...)` instead." }
180
+ },
181
+ createOnce(context) {
182
+ return { ThrowStatement(node) {
183
+ let current = node.parent;
184
+ while (current.type !== "FunctionExpression" && current.type !== "FunctionDeclaration" && current.type !== "ArrowFunctionExpression" && current.type !== "Program") current = current.parent;
185
+ if (isEffectGeneratorBody(current)) context.report({
186
+ node,
187
+ messageId: "noThrow"
188
+ });
189
+ } };
190
+ }
191
+ });
192
+ const noRunOutsideEdge = defineRule({
193
+ meta: {
194
+ type: "problem",
195
+ docs: { description: "Restrict `Effect.run*` to entrypoints, tests and scripts" },
196
+ schema: [{
197
+ type: "object",
198
+ additionalProperties: false,
199
+ properties: { allow: {
200
+ type: "array",
201
+ items: {
202
+ type: "string",
203
+ minLength: 1
204
+ },
205
+ uniqueItems: true
206
+ } }
207
+ }],
208
+ messages: { noRun: "`Effect.{{method}}` belongs at the edge (`NodeRuntime.runMain`, `ManagedRuntime`). Allowed files: {{allow}}." },
209
+ defaultOptions: [{ allow: [...DEFAULT_EDGE_FILES] }]
210
+ },
211
+ createOnce(context) {
212
+ let allow = DEFAULT_EDGE_FILES;
213
+ return {
214
+ before() {
215
+ allow = context.options[0]?.allow ?? DEFAULT_EDGE_FILES;
216
+ return !matchesFileGlob(context, allow);
217
+ },
218
+ CallExpression(node) {
219
+ if (!isEffectMember(node.callee, RUN_METHODS)) return;
220
+ const method = node.callee.property.type === "Identifier" ? node.callee.property.name : "";
221
+ context.report({
222
+ node,
223
+ messageId: "noRun",
224
+ data: {
225
+ method,
226
+ allow: allow.join(", ")
227
+ }
228
+ });
229
+ }
230
+ };
231
+ }
232
+ });
233
+ var effect_default = definePlugin({
234
+ meta: { name: "eslint-plugin-mahir-effect" },
235
+ rules: {
236
+ "fn-name-matches": fnNameMatches,
237
+ "no-gen-wrapper": noGenWrapper,
238
+ "no-pipe-on-fn": noPipeOnFn,
239
+ "no-run-outside-edge": noRunOutsideEdge,
240
+ "no-throw-in-gen": noThrowInGen,
241
+ "return-yield-error": returnYieldError
242
+ }
243
+ });
244
+
245
+ //#endregion
246
+ export { effect_default as default };
247
+ //# sourceMappingURL=effect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effect.js","names":[],"sources":["../../src/plugins/effect.ts"],"sourcesContent":["import { definePlugin, defineRule } from '@oxlint/plugins';\n\nimport { matchesFileGlob } from '../config.js';\n\nimport type { ESTree } from '@oxlint/plugins';\n\nconst DEFAULT_EDGE_FILES = ['**/main.ts', '**/*.test.ts', '**/scripts/**'];\nconst RUN_METHODS = new Set(['runCallback', 'runFork', 'runPromise', 'runPromiseExit', 'runSync', 'runSyncExit']);\nconst FAIL_METHODS = new Set(['die', 'dieMessage', 'dieSync', 'fail', 'failCause', 'failCauseSync', 'failSync']);\nconst FN_METHODS = new Set(['fn', 'fnUntraced']);\nconst FN_NAMED = new Set(['fn']);\nconst GEN = new Set(['gen']);\nconst GEN_OR_FN = new Set(['gen', ...FN_METHODS]);\n\nfunction isEffectMember(node: ESTree.Node, methods: Set<string>): node is ESTree.MemberExpression {\n\treturn (\n\t\tnode.type === 'MemberExpression' &&\n\t\t!node.computed &&\n\t\tnode.object.type === 'Identifier' &&\n\t\tnode.object.name === 'Effect' &&\n\t\tnode.property.type === 'Identifier' &&\n\t\tmethods.has(node.property.name)\n\t);\n}\n\nfunction isEffectCall(node: ESTree.Node | null | undefined, methods: Set<string>): node is ESTree.CallExpression {\n\treturn node?.type === 'CallExpression' && isEffectMember(node.callee, methods);\n}\n\nfunction staticString(node: ESTree.Node | undefined) {\n\tif (node?.type === 'Literal' && typeof node.value === 'string') return node.value;\n\tif (node?.type !== 'TemplateLiteral' || node.expressions.length > 0) return undefined;\n\treturn node.quasis[0]?.value.cooked ?? undefined;\n}\n\nfunction isNamedFnFactory(node: ESTree.Node): node is ESTree.CallExpression {\n\treturn isEffectCall(node, FN_NAMED) && staticString(node.arguments[0]) !== undefined;\n}\n\nfunction isEffectGeneratorBody(fn: ESTree.Node) {\n\tif (fn.type !== 'FunctionExpression' || !fn.generator) return false;\n\tconst call = fn.parent;\n\tif (call.type !== 'CallExpression' || !call.arguments.includes(fn)) return false;\n\tif (isEffectMember(call.callee, GEN_OR_FN)) return true;\n\treturn isNamedFnFactory(call.callee);\n}\n\nfunction isEffectFnCall(node: ESTree.Node) {\n\tif (node.type !== 'CallExpression') return false;\n\tif (isNamedFnFactory(node.callee)) return true;\n\treturn isEffectCall(node, FN_METHODS) && node.arguments[0]?.type === 'FunctionExpression';\n}\n\nfunction isGenOrPipedGen(node: ESTree.Node | null | undefined) {\n\tif (node?.type !== 'CallExpression') return false;\n\tconst { callee } = node;\n\tif (\n\t\tcallee.type === 'MemberExpression' &&\n\t\t!callee.computed &&\n\t\tcallee.property.type === 'Identifier' &&\n\t\tcallee.property.name === 'pipe'\n\t) {\n\t\treturn isEffectCall(callee.object, GEN);\n\t}\n\treturn isEffectMember(callee, GEN);\n}\n\nfunction returnedExpression(fn: ESTree.Function | ESTree.ArrowFunctionExpression) {\n\tconst { body } = fn;\n\tif (!body) return undefined;\n\tif (body.type !== 'BlockStatement') return body;\n\tif (body.body.length !== 1) return undefined;\n\tconst [statement] = body.body;\n\treturn statement.type === 'ReturnStatement' ? statement.argument : undefined;\n}\n\nfunction isReusableFunction(fn: ESTree.Function | ESTree.ArrowFunctionExpression) {\n\tif (fn.type === 'FunctionDeclaration') return true;\n\tconst { parent } = fn;\n\tif (parent.type === 'VariableDeclarator') return parent.init === fn;\n\tif (parent.type === 'Property' || parent.type === 'PropertyDefinition') return parent.value === fn;\n\treturn parent.type === 'MethodDefinition' || parent.type === 'ExportDefaultDeclaration';\n}\n\nfunction bindingName(node: ESTree.Node) {\n\tconst { parent } = node;\n\tif (!parent) return undefined;\n\tif (parent.type === 'VariableDeclarator' && parent.init === node && parent.id.type === 'Identifier') {\n\t\treturn parent.id.name;\n\t}\n\tif (\n\t\t(parent.type === 'Property' || parent.type === 'PropertyDefinition') &&\n\t\tparent.value === node &&\n\t\t!parent.computed\n\t) {\n\t\tif (parent.key.type === 'Identifier') return parent.key.name;\n\t\treturn staticString(parent.key);\n\t}\n\treturn undefined;\n}\n\nconst noGenWrapper = defineRule({\n\tmeta: {\n\t\ttype: 'suggestion',\n\t\tdocs: {\n\t\t\tdescription: 'Disallow functions that only wrap and return `Effect.gen`',\n\t\t},\n\t\tmessages: {\n\t\t\tnoGenWrapper:\n\t\t\t\t'Avoid functions that only wrap and return `Effect.gen`. Use `Effect.fn(\"name\")(function* (...) {...})` or `Effect.fnUntraced` instead.',\n\t\t},\n\t},\n\tcreateOnce(context) {\n\t\tfunction check(fn: ESTree.Function | ESTree.ArrowFunctionExpression) {\n\t\t\tif (fn.generator || !isReusableFunction(fn)) return;\n\t\t\tif (isGenOrPipedGen(returnedExpression(fn))) context.report({ node: fn, messageId: 'noGenWrapper' });\n\t\t}\n\t\treturn {\n\t\t\tArrowFunctionExpression: check,\n\t\t\tFunctionDeclaration: check,\n\t\t\tFunctionExpression: check,\n\t\t};\n\t},\n});\n\nconst fnNameMatches = defineRule({\n\tmeta: {\n\t\ttype: 'suggestion',\n\t\tdocs: {\n\t\t\tdescription: 'Require the `Effect.fn` span name to match the binding it is assigned to',\n\t\t},\n\t\tfixable: 'code',\n\t\tmessages: {\n\t\t\tmismatch: '`Effect.fn(\"{{name}}\")` is assigned to `{{binding}}`. Use \"{{binding}}\" or \"<Service>.{{binding}}\".',\n\t\t},\n\t},\n\tcreateOnce(context) {\n\t\treturn {\n\t\t\tCallExpression(node) {\n\t\t\t\tif (!isNamedFnFactory(node.callee)) return;\n\t\t\t\tconst binding = bindingName(node);\n\t\t\t\tconst nameNode = node.callee.arguments[0];\n\t\t\t\tconst name = staticString(nameNode);\n\t\t\t\tif (!binding || name === undefined) return;\n\t\t\t\tif (name === binding || name.endsWith(`.${binding}`)) return;\n\t\t\t\tcontext.report({\n\t\t\t\t\tnode: nameNode,\n\t\t\t\t\tmessageId: 'mismatch',\n\t\t\t\t\tdata: { name, binding },\n\t\t\t\t\tfix(fixer) {\n\t\t\t\t\t\tconst quote = context.sourceCode.getText(nameNode).at(0) ?? \"'\";\n\t\t\t\t\t\tconst prefix = name.includes('.') ? name.slice(0, name.lastIndexOf('.') + 1) : '';\n\t\t\t\t\t\treturn fixer.replaceText(nameNode, `${quote}${prefix}${binding}${quote}`);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t},\n});\n\nconst returnYieldError = defineRule({\n\tmeta: {\n\t\ttype: 'problem',\n\t\tdocs: {\n\t\t\tdescription: 'Require `return yield*` when yielding an error so TypeScript knows execution stops',\n\t\t},\n\t\tfixable: 'code',\n\t\tmessages: {\n\t\t\tmissingReturn: 'Use `return yield* ...` when raising an error so TypeScript knows the generator stops here.',\n\t\t},\n\t},\n\tcreateOnce(context) {\n\t\treturn {\n\t\t\tYieldExpression(node) {\n\t\t\t\tif (!node.delegate || !node.argument || node.parent.type !== 'ExpressionStatement') return;\n\t\t\t\tif (node.argument.type !== 'NewExpression' && !isEffectCall(node.argument, FAIL_METHODS)) return;\n\t\t\t\tcontext.report({\n\t\t\t\t\tnode,\n\t\t\t\t\tmessageId: 'missingReturn',\n\t\t\t\t\tfix: (fixer) => fixer.insertTextBefore(node, 'return '),\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t},\n});\n\nconst noPipeOnFn = defineRule({\n\tmeta: {\n\t\ttype: 'suggestion',\n\t\tdocs: {\n\t\t\tdescription: 'Disallow `.pipe` on `Effect.fn` / `Effect.fnUntraced`; pass combinators as extra arguments',\n\t\t},\n\t\tmessages: {\n\t\t\tnoPipe:\n\t\t\t\t'Do not use `.pipe` with `Effect.fn`. Pass the combinators as extra arguments: `Effect.fn(\"name\")(function* () {...}, Effect.withSpan(...))`.',\n\t\t},\n\t},\n\tcreateOnce(context) {\n\t\treturn {\n\t\t\tMemberExpression(node) {\n\t\t\t\tif (node.computed || node.property.type !== 'Identifier' || node.property.name !== 'pipe') return;\n\t\t\t\tif (!isEffectFnCall(node.object)) return;\n\t\t\t\tcontext.report({ node: node.property, messageId: 'noPipe' });\n\t\t\t},\n\t\t};\n\t},\n});\n\nconst noThrowInGen = defineRule({\n\tmeta: {\n\t\ttype: 'problem',\n\t\tdocs: {\n\t\t\tdescription: 'Disallow `throw` inside `Effect.gen` / `Effect.fn` generators',\n\t\t},\n\t\tmessages: {\n\t\t\tnoThrow:\n\t\t\t\t'Do not throw inside an Effect generator; a throw becomes a defect. Use `return yield* new SomeError(...)` instead.',\n\t\t},\n\t},\n\tcreateOnce(context) {\n\t\treturn {\n\t\t\tThrowStatement(node) {\n\t\t\t\tlet current: ESTree.Node = node.parent;\n\t\t\t\twhile (\n\t\t\t\t\tcurrent.type !== 'FunctionExpression' &&\n\t\t\t\t\tcurrent.type !== 'FunctionDeclaration' &&\n\t\t\t\t\tcurrent.type !== 'ArrowFunctionExpression' &&\n\t\t\t\t\tcurrent.type !== 'Program'\n\t\t\t\t) {\n\t\t\t\t\tcurrent = current.parent;\n\t\t\t\t}\n\t\t\t\tif (isEffectGeneratorBody(current)) context.report({ node, messageId: 'noThrow' });\n\t\t\t},\n\t\t};\n\t},\n});\n\nconst noRunOutsideEdge = defineRule({\n\tmeta: {\n\t\ttype: 'problem',\n\t\tdocs: {\n\t\t\tdescription: 'Restrict `Effect.run*` to entrypoints, tests and scripts',\n\t\t},\n\t\tschema: [\n\t\t\t{\n\t\t\t\ttype: 'object',\n\t\t\t\tadditionalProperties: false,\n\t\t\t\tproperties: {\n\t\t\t\t\tallow: {\n\t\t\t\t\t\ttype: 'array',\n\t\t\t\t\t\titems: { type: 'string', minLength: 1 },\n\t\t\t\t\t\tuniqueItems: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tmessages: {\n\t\t\tnoRun:\n\t\t\t\t'`Effect.{{method}}` belongs at the edge (`NodeRuntime.runMain`, `ManagedRuntime`). Allowed files: {{allow}}.',\n\t\t},\n\t\tdefaultOptions: [{ allow: [...DEFAULT_EDGE_FILES] }],\n\t},\n\tcreateOnce(context) {\n\t\tlet allow = DEFAULT_EDGE_FILES;\n\t\treturn {\n\t\t\tbefore() {\n\t\t\t\tconst options = context.options[0] as { allow?: string[] } | undefined;\n\t\t\t\tallow = options?.allow ?? DEFAULT_EDGE_FILES;\n\t\t\t\treturn !matchesFileGlob(context, allow);\n\t\t\t},\n\t\t\tCallExpression(node) {\n\t\t\t\tif (!isEffectMember(node.callee, RUN_METHODS)) return;\n\t\t\t\tconst method = node.callee.property.type === 'Identifier' ? node.callee.property.name : '';\n\t\t\t\tcontext.report({ node, messageId: 'noRun', data: { method, allow: allow.join(', ') } });\n\t\t\t},\n\t\t};\n\t},\n});\n\nexport default definePlugin({\n\tmeta: {\n\t\tname: 'eslint-plugin-mahir-effect',\n\t},\n\trules: {\n\t\t'fn-name-matches': fnNameMatches,\n\t\t'no-gen-wrapper': noGenWrapper,\n\t\t'no-pipe-on-fn': noPipeOnFn,\n\t\t'no-run-outside-edge': noRunOutsideEdge,\n\t\t'no-throw-in-gen': noThrowInGen,\n\t\t'return-yield-error': returnYieldError,\n\t},\n});\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ //#region src/plugins/unistyles.d.ts
2
+ declare const _default: import("@oxlint/plugins").Plugin;
3
+ //#endregion
4
+ export { _default as default };
5
+ //# sourceMappingURL=unistyles.d.ts.map
@@ -0,0 +1,204 @@
1
+ import { matchesFileGlob } from "../config.js";
2
+ import { definePlugin, defineRule } from "@oxlint/plugins";
3
+
4
+ //#region src/plugins/unistyles.ts
5
+ const UNISTYLES = "react-native-unistyles";
6
+ const DEFAULT_THEME_FILES = ["**/theme/**", "**/tokens/**"];
7
+ const COLOR_FUNCTION = /^\s*(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch)\(/i;
8
+ const HEX_COLOR = /^#(?:[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/i;
9
+ const COLOR_KEY = /colou?r$/i;
10
+ const THEME_SOURCE = /(?:^|[/@-])(?:theme|themes|tokens)(?:[/.-]|$)/i;
11
+ const NAMED_COLORS = new Set("aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkslategrey darkturquoise darkviolet deeppink deepskyblue dimgray dimgrey dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow grey honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrodyellow lightgray lightgreen lightgrey lightpink lightsalmon lightseagreen lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime limegreen linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple rebeccapurple red rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray slategrey snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white whitesmoke yellow yellowgreen".split(" "));
12
+ function isStyleSheetCreate(node) {
13
+ return node.type === "CallExpression" && node.callee.type === "MemberExpression" && !node.callee.computed && node.callee.object.type === "Identifier" && node.callee.object.name === "StyleSheet" && node.callee.property.type === "Identifier" && node.callee.property.name === "create";
14
+ }
15
+ function isStyleAttribute(node) {
16
+ if (node.type !== "JSXAttribute" || node.name.type !== "JSXIdentifier") return false;
17
+ return node.name.name === "style" || node.name.name.endsWith("Style");
18
+ }
19
+ function stringValue(node) {
20
+ if (node.type === "Literal" && typeof node.value === "string") return node.value;
21
+ if (node.type !== "TemplateLiteral" || node.expressions.length > 0) return void 0;
22
+ return node.quasis[0]?.value.cooked ?? void 0;
23
+ }
24
+ function propertyKey(node) {
25
+ const { parent } = node;
26
+ if (parent?.type !== "Property" || parent.value !== node || parent.computed) return void 0;
27
+ if (parent.key.type === "Identifier") return parent.key.name;
28
+ return parent.key.type === "Literal" && typeof parent.key.value === "string" ? parent.key.value : void 0;
29
+ }
30
+ function isRawColor(node) {
31
+ const value = stringValue(node)?.trim();
32
+ if (!value) return false;
33
+ if (HEX_COLOR.test(value) || COLOR_FUNCTION.test(value)) return true;
34
+ const key = propertyKey(node);
35
+ return key !== void 0 && COLOR_KEY.test(key) && NAMED_COLORS.has(value.toLowerCase());
36
+ }
37
+ function isInsideStyle(node) {
38
+ let current = node.parent;
39
+ while (current && current.type !== "Program") {
40
+ if (isStyleSheetCreate(current) || isStyleAttribute(current)) return true;
41
+ current = current.parent;
42
+ }
43
+ return false;
44
+ }
45
+ function isVariableOrThemeAccess(node) {
46
+ if (node.type === "Identifier") return true;
47
+ if (node.type === "MemberExpression") return isVariableOrThemeAccess(node.object);
48
+ return node.type === "ChainExpression" && isVariableOrThemeAccess(node.expression);
49
+ }
50
+ function inlineObjects(node) {
51
+ if (node.type === "ObjectExpression") return [node];
52
+ if (node.type === "ArrayExpression") return node.elements.flatMap((element) => element && element.type !== "SpreadElement" ? inlineObjects(element) : []);
53
+ if (node.type === "ConditionalExpression") return [...inlineObjects(node.consequent), ...inlineObjects(node.alternate)];
54
+ if (node.type === "LogicalExpression") return inlineObjects(node.right);
55
+ return [];
56
+ }
57
+ function unistylesImport(program) {
58
+ return program.body.find((statement) => statement.type === "ImportDeclaration" && statement.source.value === UNISTYLES && statement.importKind !== "type" && statement.specifiers.some((specifier) => specifier.type === "ImportSpecifier"));
59
+ }
60
+ const stylesheetImport = defineRule({
61
+ meta: {
62
+ type: "problem",
63
+ docs: { description: "Require `StyleSheet` to be imported from `react-native-unistyles`" },
64
+ fixable: "code",
65
+ messages: { useUnistyles: "Import `StyleSheet` from `react-native-unistyles`; the `react-native` one has no theme or runtime-aware styles." }
66
+ },
67
+ createOnce(context) {
68
+ return { ImportDeclaration(node) {
69
+ if (node.source.value !== "react-native" || node.importKind === "type") return;
70
+ const specifier = node.specifiers.find((item) => item.type === "ImportSpecifier" && item.importKind !== "type" && item.imported.type === "Identifier" && item.imported.name === "StyleSheet");
71
+ if (!specifier) return;
72
+ context.report({
73
+ node: specifier,
74
+ messageId: "useUnistyles",
75
+ fix(fixer) {
76
+ const { sourceCode } = context;
77
+ const quote = node.source.raw?.at(0) ?? "'";
78
+ const moved = sourceCode.getText(specifier);
79
+ const others = node.specifiers.filter((item) => item !== specifier);
80
+ const program = sourceCode.ast;
81
+ const existing = unistylesImport(program);
82
+ const fixes = [];
83
+ if (others.length === 0) {
84
+ if (existing) {
85
+ const end = sourceCode.text[node.range[1]] === "\n" ? node.range[1] + 1 : node.range[1];
86
+ fixes.push(fixer.removeRange([node.range[0], end]));
87
+ } else fixes.push(fixer.replaceText(node.source, `${quote}${UNISTYLES}${quote}`));
88
+ } else {
89
+ const defaults = others.filter((item) => item.type !== "ImportSpecifier").map((item) => sourceCode.getText(item));
90
+ const named = others.filter((item) => item.type === "ImportSpecifier").map((item) => sourceCode.getText(item));
91
+ const replacement = `import ${[...defaults, ...named.length > 0 ? [`{ ${named.join(", ")} }`] : []].join(", ")} from ${node.source.raw ?? `'react-native'`};`;
92
+ fixes.push(fixer.replaceText(node, existing ? replacement : `${replacement}\nimport { ${moved} } from ${quote}${UNISTYLES}${quote};`));
93
+ }
94
+ if (existing) {
95
+ const last = existing.specifiers.findLast((item) => item.type === "ImportSpecifier");
96
+ if (last) fixes.push(fixer.insertTextAfter(last, `, ${moved}`));
97
+ }
98
+ return fixes;
99
+ }
100
+ });
101
+ } };
102
+ }
103
+ });
104
+ const noRawColors = defineRule({
105
+ meta: {
106
+ type: "problem",
107
+ docs: { description: "Disallow raw colour literals in `StyleSheet.create` and `style` props outside theme files" },
108
+ schema: [{
109
+ type: "object",
110
+ additionalProperties: false,
111
+ properties: { allow: {
112
+ type: "array",
113
+ items: {
114
+ type: "string",
115
+ minLength: 1
116
+ },
117
+ uniqueItems: true
118
+ } }
119
+ }],
120
+ messages: { rawColor: "Raw colour `{{value}}`. Read colours from the theme instead." },
121
+ defaultOptions: [{ allow: [...DEFAULT_THEME_FILES] }]
122
+ },
123
+ createOnce(context) {
124
+ function check(node) {
125
+ if (!isRawColor(node) || !isInsideStyle(node)) return;
126
+ context.report({
127
+ node,
128
+ messageId: "rawColor",
129
+ data: { value: stringValue(node) ?? "" }
130
+ });
131
+ }
132
+ return {
133
+ before() {
134
+ const options = context.options[0];
135
+ return !matchesFileGlob(context, options?.allow ?? DEFAULT_THEME_FILES);
136
+ },
137
+ Literal: check,
138
+ TemplateLiteral: check
139
+ };
140
+ }
141
+ });
142
+ const noInlineStyleObjects = defineRule({
143
+ meta: {
144
+ type: "suggestion",
145
+ docs: { description: "Disallow inline style object literals in JSX unless every value is a variable or theme access" },
146
+ messages: { inlineStyle: "Move this inline style into `StyleSheet.create` so Unistyles can update it natively." }
147
+ },
148
+ createOnce(context) {
149
+ return { JSXAttribute(node) {
150
+ if (!isStyleAttribute(node) || node.value?.type !== "JSXExpressionContainer") return;
151
+ const { expression } = node.value;
152
+ if (expression.type === "JSXEmptyExpression") return;
153
+ for (const object of inlineObjects(expression)) if (!object.properties.every((property) => property.type === "SpreadElement" ? isVariableOrThemeAccess(property.argument) : isVariableOrThemeAccess(property.value))) context.report({
154
+ node: object,
155
+ messageId: "inlineStyle"
156
+ });
157
+ } };
158
+ }
159
+ });
160
+ const createUsesTheme = defineRule({
161
+ meta: {
162
+ type: "suggestion",
163
+ docs: { description: "Prefer the theme callback form of `StyleSheet.create` in files that import the theme" },
164
+ messages: { useThemeCallback: "This file imports the theme. Use `StyleSheet.create((theme, rt) => ({ ... }))` so styles follow theme and runtime changes." }
165
+ },
166
+ createOnce(context) {
167
+ let importsTheme = false;
168
+ return {
169
+ before() {
170
+ importsTheme = false;
171
+ },
172
+ ImportDeclaration(node) {
173
+ if (node.importKind === "type") return;
174
+ const source = String(node.source.value);
175
+ if (THEME_SOURCE.test(source)) importsTheme = true;
176
+ for (const specifier of node.specifiers) {
177
+ if (specifier.type === "ImportSpecifier" && specifier.importKind === "type") continue;
178
+ const name = specifier.local.name;
179
+ if (/theme/i.test(name) || source === UNISTYLES && name === "useUnistyles") importsTheme = true;
180
+ }
181
+ },
182
+ "CallExpression:exit"(node) {
183
+ if (!importsTheme || !isStyleSheetCreate(node)) return;
184
+ if (node.arguments[0]?.type === "ObjectExpression") context.report({
185
+ node,
186
+ messageId: "useThemeCallback"
187
+ });
188
+ }
189
+ };
190
+ }
191
+ });
192
+ var unistyles_default = definePlugin({
193
+ meta: { name: "eslint-plugin-mahir-unistyles" },
194
+ rules: {
195
+ "create-uses-theme": createUsesTheme,
196
+ "no-inline-style-objects": noInlineStyleObjects,
197
+ "no-raw-colors": noRawColors,
198
+ "stylesheet-import": stylesheetImport
199
+ }
200
+ });
201
+
202
+ //#endregion
203
+ export { unistyles_default as default };
204
+ //# sourceMappingURL=unistyles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unistyles.js","names":[],"sources":["../../src/plugins/unistyles.ts"],"sourcesContent":["import { definePlugin, defineRule } from '@oxlint/plugins';\n\nimport { matchesFileGlob } from '../config.js';\n\nimport type { ESTree } from '@oxlint/plugins';\n\nconst UNISTYLES = 'react-native-unistyles';\nconst DEFAULT_THEME_FILES = ['**/theme/**', '**/tokens/**'];\nconst COLOR_FUNCTION = /^\\s*(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch)\\(/i;\nconst HEX_COLOR = /^#(?:[\\da-f]{3,4}|[\\da-f]{6}|[\\da-f]{8})$/i;\nconst COLOR_KEY = /colou?r$/i;\nconst THEME_SOURCE = /(?:^|[/@-])(?:theme|themes|tokens)(?:[/.-]|$)/i;\nconst NAMED_COLORS = new Set(\n\t'aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkslategrey darkturquoise darkviolet deeppink deepskyblue dimgray dimgrey dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow grey honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrodyellow lightgray lightgreen lightgrey lightpink lightsalmon lightseagreen lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime limegreen linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple rebeccapurple red rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray slategrey snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white whitesmoke yellow yellowgreen'.split(\n\t\t' ',\n\t),\n);\n\nfunction isStyleSheetCreate(node: ESTree.Node): node is ESTree.CallExpression {\n\treturn (\n\t\tnode.type === 'CallExpression' &&\n\t\tnode.callee.type === 'MemberExpression' &&\n\t\t!node.callee.computed &&\n\t\tnode.callee.object.type === 'Identifier' &&\n\t\tnode.callee.object.name === 'StyleSheet' &&\n\t\tnode.callee.property.type === 'Identifier' &&\n\t\tnode.callee.property.name === 'create'\n\t);\n}\n\nfunction isStyleAttribute(node: ESTree.Node): node is ESTree.JSXAttribute {\n\tif (node.type !== 'JSXAttribute' || node.name.type !== 'JSXIdentifier') return false;\n\treturn node.name.name === 'style' || node.name.name.endsWith('Style');\n}\n\nfunction stringValue(node: ESTree.Node) {\n\tif (node.type === 'Literal' && typeof node.value === 'string') return node.value;\n\tif (node.type !== 'TemplateLiteral' || node.expressions.length > 0) return undefined;\n\treturn node.quasis[0]?.value.cooked ?? undefined;\n}\n\nfunction propertyKey(node: ESTree.Node) {\n\tconst { parent } = node;\n\tif (parent?.type !== 'Property' || parent.value !== node || parent.computed) return undefined;\n\tif (parent.key.type === 'Identifier') return parent.key.name;\n\treturn parent.key.type === 'Literal' && typeof parent.key.value === 'string' ? parent.key.value : undefined;\n}\n\nfunction isRawColor(node: ESTree.Node) {\n\tconst value = stringValue(node)?.trim();\n\tif (!value) return false;\n\tif (HEX_COLOR.test(value) || COLOR_FUNCTION.test(value)) return true;\n\tconst key = propertyKey(node);\n\treturn key !== undefined && COLOR_KEY.test(key) && NAMED_COLORS.has(value.toLowerCase());\n}\n\nfunction isInsideStyle(node: ESTree.Node) {\n\tlet current: ESTree.Node | null = node.parent;\n\twhile (current && current.type !== 'Program') {\n\t\tif (isStyleSheetCreate(current) || isStyleAttribute(current)) return true;\n\t\tcurrent = current.parent;\n\t}\n\treturn false;\n}\n\nfunction isVariableOrThemeAccess(node: ESTree.Node): boolean {\n\tif (node.type === 'Identifier') return true;\n\tif (node.type === 'MemberExpression') return isVariableOrThemeAccess(node.object);\n\treturn node.type === 'ChainExpression' && isVariableOrThemeAccess(node.expression);\n}\n\nfunction inlineObjects(node: ESTree.Node): ESTree.ObjectExpression[] {\n\tif (node.type === 'ObjectExpression') return [node];\n\tif (node.type === 'ArrayExpression') {\n\t\treturn node.elements.flatMap((element) =>\n\t\t\telement && element.type !== 'SpreadElement' ? inlineObjects(element) : [],\n\t\t);\n\t}\n\tif (node.type === 'ConditionalExpression') {\n\t\treturn [...inlineObjects(node.consequent), ...inlineObjects(node.alternate)];\n\t}\n\tif (node.type === 'LogicalExpression') return inlineObjects(node.right);\n\treturn [];\n}\n\nfunction unistylesImport(program: ESTree.Program) {\n\treturn program.body.find(\n\t\t(statement): statement is ESTree.ImportDeclaration =>\n\t\t\tstatement.type === 'ImportDeclaration' &&\n\t\t\tstatement.source.value === UNISTYLES &&\n\t\t\tstatement.importKind !== 'type' &&\n\t\t\tstatement.specifiers.some((specifier) => specifier.type === 'ImportSpecifier'),\n\t);\n}\n\nconst stylesheetImport = defineRule({\n\tmeta: {\n\t\ttype: 'problem',\n\t\tdocs: {\n\t\t\tdescription: 'Require `StyleSheet` to be imported from `react-native-unistyles`',\n\t\t},\n\t\tfixable: 'code',\n\t\tmessages: {\n\t\t\tuseUnistyles:\n\t\t\t\t'Import `StyleSheet` from `react-native-unistyles`; the `react-native` one has no theme or runtime-aware styles.',\n\t\t},\n\t},\n\tcreateOnce(context) {\n\t\treturn {\n\t\t\tImportDeclaration(node) {\n\t\t\t\tif (node.source.value !== 'react-native' || node.importKind === 'type') return;\n\t\t\t\tconst specifier = node.specifiers.find(\n\t\t\t\t\t(item): item is ESTree.ImportSpecifier =>\n\t\t\t\t\t\titem.type === 'ImportSpecifier' &&\n\t\t\t\t\t\titem.importKind !== 'type' &&\n\t\t\t\t\t\titem.imported.type === 'Identifier' &&\n\t\t\t\t\t\titem.imported.name === 'StyleSheet',\n\t\t\t\t);\n\t\t\t\tif (!specifier) return;\n\t\t\t\tcontext.report({\n\t\t\t\t\tnode: specifier,\n\t\t\t\t\tmessageId: 'useUnistyles',\n\t\t\t\t\tfix(fixer) {\n\t\t\t\t\t\tconst { sourceCode } = context;\n\t\t\t\t\t\tconst quote = node.source.raw?.at(0) ?? \"'\";\n\t\t\t\t\t\tconst moved = sourceCode.getText(specifier);\n\t\t\t\t\t\tconst others = node.specifiers.filter((item) => item !== specifier);\n\t\t\t\t\t\tconst program = sourceCode.ast;\n\t\t\t\t\t\tconst existing = unistylesImport(program);\n\t\t\t\t\t\tconst fixes = [];\n\n\t\t\t\t\t\tif (others.length === 0) {\n\t\t\t\t\t\t\tif (existing) {\n\t\t\t\t\t\t\t\tconst end = sourceCode.text[node.range[1]] === '\\n' ? node.range[1] + 1 : node.range[1];\n\t\t\t\t\t\t\t\tfixes.push(fixer.removeRange([node.range[0], end]));\n\t\t\t\t\t\t\t} else fixes.push(fixer.replaceText(node.source, `${quote}${UNISTYLES}${quote}`));\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst defaults = others\n\t\t\t\t\t\t\t\t.filter((item) => item.type !== 'ImportSpecifier')\n\t\t\t\t\t\t\t\t.map((item) => sourceCode.getText(item));\n\t\t\t\t\t\t\tconst named = others\n\t\t\t\t\t\t\t\t.filter((item) => item.type === 'ImportSpecifier')\n\t\t\t\t\t\t\t\t.map((item) => sourceCode.getText(item));\n\t\t\t\t\t\t\tconst clause = [...defaults, ...(named.length > 0 ? [`{ ${named.join(', ')} }`] : [])].join(', ');\n\t\t\t\t\t\t\tconst replacement = `import ${clause} from ${node.source.raw ?? `'react-native'`};`;\n\t\t\t\t\t\t\tfixes.push(\n\t\t\t\t\t\t\t\tfixer.replaceText(\n\t\t\t\t\t\t\t\t\tnode,\n\t\t\t\t\t\t\t\t\texisting ? replacement : `${replacement}\\nimport { ${moved} } from ${quote}${UNISTYLES}${quote};`,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (existing) {\n\t\t\t\t\t\t\tconst last = existing.specifiers.findLast((item) => item.type === 'ImportSpecifier');\n\t\t\t\t\t\t\tif (last) fixes.push(fixer.insertTextAfter(last, `, ${moved}`));\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn fixes;\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t},\n});\n\nconst noRawColors = defineRule({\n\tmeta: {\n\t\ttype: 'problem',\n\t\tdocs: {\n\t\t\tdescription: 'Disallow raw colour literals in `StyleSheet.create` and `style` props outside theme files',\n\t\t},\n\t\tschema: [\n\t\t\t{\n\t\t\t\ttype: 'object',\n\t\t\t\tadditionalProperties: false,\n\t\t\t\tproperties: {\n\t\t\t\t\tallow: {\n\t\t\t\t\t\ttype: 'array',\n\t\t\t\t\t\titems: { type: 'string', minLength: 1 },\n\t\t\t\t\t\tuniqueItems: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tmessages: {\n\t\t\trawColor: 'Raw colour `{{value}}`. Read colours from the theme instead.',\n\t\t},\n\t\tdefaultOptions: [{ allow: [...DEFAULT_THEME_FILES] }],\n\t},\n\tcreateOnce(context) {\n\t\tfunction check(node: ESTree.Node) {\n\t\t\tif (!isRawColor(node) || !isInsideStyle(node)) return;\n\t\t\tcontext.report({ node, messageId: 'rawColor', data: { value: stringValue(node) ?? '' } });\n\t\t}\n\t\treturn {\n\t\t\tbefore() {\n\t\t\t\tconst options = context.options[0] as { allow?: string[] } | undefined;\n\t\t\t\treturn !matchesFileGlob(context, options?.allow ?? DEFAULT_THEME_FILES);\n\t\t\t},\n\t\t\tLiteral: check,\n\t\t\tTemplateLiteral: check,\n\t\t};\n\t},\n});\n\nconst noInlineStyleObjects = defineRule({\n\tmeta: {\n\t\ttype: 'suggestion',\n\t\tdocs: {\n\t\t\tdescription: 'Disallow inline style object literals in JSX unless every value is a variable or theme access',\n\t\t},\n\t\tmessages: {\n\t\t\tinlineStyle: 'Move this inline style into `StyleSheet.create` so Unistyles can update it natively.',\n\t\t},\n\t},\n\tcreateOnce(context) {\n\t\treturn {\n\t\t\tJSXAttribute(node) {\n\t\t\t\tif (!isStyleAttribute(node) || node.value?.type !== 'JSXExpressionContainer') return;\n\t\t\t\tconst { expression } = node.value;\n\t\t\t\tif (expression.type === 'JSXEmptyExpression') return;\n\t\t\t\tfor (const object of inlineObjects(expression)) {\n\t\t\t\t\tconst dynamicOnly = object.properties.every((property) =>\n\t\t\t\t\t\tproperty.type === 'SpreadElement'\n\t\t\t\t\t\t\t? isVariableOrThemeAccess(property.argument)\n\t\t\t\t\t\t\t: isVariableOrThemeAccess(property.value),\n\t\t\t\t\t);\n\t\t\t\t\tif (!dynamicOnly) context.report({ node: object, messageId: 'inlineStyle' });\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t},\n});\n\nconst createUsesTheme = defineRule({\n\tmeta: {\n\t\ttype: 'suggestion',\n\t\tdocs: {\n\t\t\tdescription: 'Prefer the theme callback form of `StyleSheet.create` in files that import the theme',\n\t\t},\n\t\tmessages: {\n\t\t\tuseThemeCallback:\n\t\t\t\t'This file imports the theme. Use `StyleSheet.create((theme, rt) => ({ ... }))` so styles follow theme and runtime changes.',\n\t\t},\n\t},\n\tcreateOnce(context) {\n\t\tlet importsTheme = false;\n\t\treturn {\n\t\t\tbefore() {\n\t\t\t\timportsTheme = false;\n\t\t\t},\n\t\t\tImportDeclaration(node) {\n\t\t\t\tif (node.importKind === 'type') return;\n\t\t\t\tconst source = String(node.source.value);\n\t\t\t\tif (THEME_SOURCE.test(source)) importsTheme = true;\n\t\t\t\tfor (const specifier of node.specifiers) {\n\t\t\t\t\tif (specifier.type === 'ImportSpecifier' && specifier.importKind === 'type') continue;\n\t\t\t\t\tconst name = specifier.local.name;\n\t\t\t\t\tif (/theme/i.test(name) || (source === UNISTYLES && name === 'useUnistyles')) importsTheme = true;\n\t\t\t\t}\n\t\t\t},\n\t\t\t'CallExpression:exit'(node) {\n\t\t\t\tif (!importsTheme || !isStyleSheetCreate(node)) return;\n\t\t\t\tif (node.arguments[0]?.type === 'ObjectExpression') context.report({ node, messageId: 'useThemeCallback' });\n\t\t\t},\n\t\t};\n\t},\n});\n\nexport default definePlugin({\n\tmeta: {\n\t\tname: 'eslint-plugin-mahir-unistyles',\n\t},\n\trules: {\n\t\t'create-uses-theme': createUsesTheme,\n\t\t'no-inline-style-objects': noInlineStyleObjects,\n\t\t'no-raw-colors': noRawColors,\n\t\t'stylesheet-import': stylesheetImport,\n\t},\n});\n"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ //#region src/unistyles.d.ts
2
+ declare const config: {
3
+ plugins: ("eslint" | "react" | "unicorn" | "typescript" | "oxc" | "import" | "jsdoc" | "jest" | "vitest" | "jsx-a11y" | "nextjs" | "react-perf" | "promise" | "node" | "vue")[];
4
+ jsPlugins: import("oxlint").ExternalPluginEntry[];
5
+ rules: import("oxlint").DummyRuleMap;
6
+ };
7
+ //#endregion
8
+ export { config as default };
9
+ //# sourceMappingURL=unistyles.d.ts.map
@@ -0,0 +1,18 @@
1
+ import { localPlugin, nativePlugins } from "./config.js";
2
+ import { defineConfig } from "oxlint";
3
+
4
+ //#region src/unistyles.ts
5
+ const config = defineConfig({
6
+ plugins: nativePlugins,
7
+ jsPlugins: [localPlugin("mahir-unistyles", "./plugins/unistyles.js")],
8
+ rules: {
9
+ "mahir-unistyles/create-uses-theme": 1,
10
+ "mahir-unistyles/no-inline-style-objects": 2,
11
+ "mahir-unistyles/no-raw-colors": 2,
12
+ "mahir-unistyles/stylesheet-import": 2
13
+ }
14
+ });
15
+
16
+ //#endregion
17
+ export { config as default };
18
+ //# sourceMappingURL=unistyles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unistyles.js","names":[],"sources":["../src/unistyles.ts"],"sourcesContent":["import { defineConfig } from 'oxlint';\n\nimport { localPlugin, nativePlugins } from './config.js';\n\nimport type { OxlintConfig } from 'oxlint';\n\nconst rules: NonNullable<OxlintConfig['rules']> = {\n\t'mahir-unistyles/create-uses-theme': 1,\n\t'mahir-unistyles/no-inline-style-objects': 2,\n\t'mahir-unistyles/no-raw-colors': 2,\n\t'mahir-unistyles/stylesheet-import': 2,\n};\n\nconst config = defineConfig({\n\tplugins: nativePlugins,\n\tjsPlugins: [localPlugin('mahir-unistyles', './plugins/unistyles.js')],\n\trules,\n});\n\nexport default config;\n"],"mappings":";;;;AAaA,MAAM,SAAS,aAAa;CAC3B,SAAS;CACT,WAAW,CAAC,YAAY,mBAAmB,wBAAwB,CAAC;CACpE;EATA,qCAAqC;EACrC,2CAA2C;EAC3C,iCAAiC;EACjC,qCAAqC;CAMjC;AACL,CAAC"}