@sarj/eslint-plugin 1.0.0 → 1.0.1
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/package.json +2 -2
- package/dist/rules/no-enum.test.d.ts +0 -2
- package/dist/rules/no-enum.test.d.ts.map +0 -1
- package/dist/rules/no-enum.test.js +0 -44
- package/dist/rules/no-raw-env.test.d.ts +0 -2
- package/dist/rules/no-raw-env.test.d.ts.map +0 -1
- package/dist/rules/no-raw-env.test.js +0 -36
- package/dist/rules/prefer-shadcn.test.d.ts +0 -2
- package/dist/rules/prefer-shadcn.test.d.ts.map +0 -1
- package/dist/rules/prefer-shadcn.test.js +0 -58
- package/dist/rules/require-assert-never.test.d.ts +0 -2
- package/dist/rules/require-assert-never.test.d.ts.map +0 -1
- package/dist/rules/require-assert-never.test.js +0 -76
- package/dist/rules/zod-naming-convention.test.d.ts +0 -2
- package/dist/rules/zod-naming-convention.test.d.ts.map +0 -1
- package/dist/rules/zod-naming-convention.test.js +0 -38
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sarj/eslint-plugin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Custom ESLint rules collection for Sarj projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"access": "public"
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
|
-
"build": "tsc",
|
|
21
|
+
"build": "tsc -p tsconfig.build.json",
|
|
22
22
|
"test": "vitest run",
|
|
23
23
|
"test:watch": "vitest",
|
|
24
24
|
"lint": "eslint src",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"no-enum.test.d.ts","sourceRoot":"","sources":["../../src/rules/no-enum.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { RuleTester } from "eslint";
|
|
2
|
-
import { describe, it } from "vitest";
|
|
3
|
-
import { noEnum } from "./no-enum.js";
|
|
4
|
-
// Note: This test requires @typescript-eslint/parser to work properly
|
|
5
|
-
// For now, we'll skip the actual test execution and just verify the rule exports correctly
|
|
6
|
-
describe("no-enum", () => {
|
|
7
|
-
it("should export a valid rule module", () => {
|
|
8
|
-
if (!noEnum.meta || !noEnum.create) {
|
|
9
|
-
throw new Error("Rule is not properly exported");
|
|
10
|
-
}
|
|
11
|
-
if (noEnum.meta.type !== "suggestion") {
|
|
12
|
-
throw new Error("Expected rule type to be 'suggestion'");
|
|
13
|
-
}
|
|
14
|
-
if (!noEnum.meta.messages?.noEnum) {
|
|
15
|
-
throw new Error("Expected noEnum message to be defined");
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
// Full test requires TypeScript parser
|
|
19
|
-
it("should work with TypeScript parser", async () => {
|
|
20
|
-
const parser = await import("@typescript-eslint/parser");
|
|
21
|
-
const ruleTester = new RuleTester({
|
|
22
|
-
languageOptions: {
|
|
23
|
-
ecmaVersion: 2022,
|
|
24
|
-
sourceType: "module",
|
|
25
|
-
parser,
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
ruleTester.run("no-enum", noEnum, {
|
|
29
|
-
valid: [
|
|
30
|
-
// Union types are OK
|
|
31
|
-
{ code: 'type Status = "active" | "inactive";' },
|
|
32
|
-
// Const objects are OK
|
|
33
|
-
{ code: 'const Status = { ACTIVE: "active", INACTIVE: "inactive" } as const;' },
|
|
34
|
-
],
|
|
35
|
-
invalid: [
|
|
36
|
-
// Regular enum
|
|
37
|
-
{
|
|
38
|
-
code: "enum Status { Active, Inactive }",
|
|
39
|
-
errors: [{ messageId: "noEnum" }],
|
|
40
|
-
},
|
|
41
|
-
],
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"no-raw-env.test.d.ts","sourceRoot":"","sources":["../../src/rules/no-raw-env.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { RuleTester } from "eslint";
|
|
2
|
-
import { describe, it } from "vitest";
|
|
3
|
-
import { noRawEnv } from "./no-raw-env.js";
|
|
4
|
-
const ruleTester = new RuleTester({
|
|
5
|
-
languageOptions: {
|
|
6
|
-
ecmaVersion: 2022,
|
|
7
|
-
sourceType: "module",
|
|
8
|
-
},
|
|
9
|
-
});
|
|
10
|
-
describe("no-raw-env", () => {
|
|
11
|
-
it("should pass valid and fail invalid cases", () => {
|
|
12
|
-
ruleTester.run("no-raw-env", noRawEnv, {
|
|
13
|
-
valid: [
|
|
14
|
-
// Using validated env schema
|
|
15
|
-
{ code: 'const apiKey = env.API_KEY;' },
|
|
16
|
-
{ code: 'const dbUrl = config.databaseUrl;' },
|
|
17
|
-
{ code: 'const { NODE_ENV } = validatedEnv;' },
|
|
18
|
-
],
|
|
19
|
-
invalid: [
|
|
20
|
-
// Direct process.env access
|
|
21
|
-
{
|
|
22
|
-
code: 'const apiKey = process.env.API_KEY;',
|
|
23
|
-
errors: [{ messageId: "noRawEnv" }],
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
code: 'if (process.env.NODE_ENV === "production") {}',
|
|
27
|
-
errors: [{ messageId: "noRawEnv" }],
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
code: 'console.log(process.env.DEBUG);',
|
|
31
|
-
errors: [{ messageId: "noRawEnv" }],
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-shadcn.test.d.ts","sourceRoot":"","sources":["../../src/rules/prefer-shadcn.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { RuleTester } from "eslint";
|
|
2
|
-
import { describe, it } from "vitest";
|
|
3
|
-
import { preferShadcn } from "./prefer-shadcn.js";
|
|
4
|
-
const ruleTester = new RuleTester({
|
|
5
|
-
languageOptions: {
|
|
6
|
-
ecmaVersion: 2022,
|
|
7
|
-
sourceType: "module",
|
|
8
|
-
parserOptions: {
|
|
9
|
-
ecmaFeatures: {
|
|
10
|
-
jsx: true,
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
});
|
|
15
|
-
describe("prefer-shadcn", () => {
|
|
16
|
-
it("should pass valid and fail invalid cases", () => {
|
|
17
|
-
ruleTester.run("prefer-shadcn", preferShadcn, {
|
|
18
|
-
valid: [
|
|
19
|
-
// shadcn components are OK
|
|
20
|
-
{ code: '<Button onClick={handleClick}>Click me</Button>' },
|
|
21
|
-
{ code: '<Input type="text" placeholder="Enter name" />' },
|
|
22
|
-
{ code: '<Select value={value} onValueChange={setValue} />' },
|
|
23
|
-
{ code: '<Table><TableBody /></Table>' },
|
|
24
|
-
// Other elements are OK
|
|
25
|
-
{ code: '<div className="container">Content</div>' },
|
|
26
|
-
{ code: '<span>Text</span>' },
|
|
27
|
-
{ code: '<form onSubmit={handleSubmit}></form>' },
|
|
28
|
-
],
|
|
29
|
-
invalid: [
|
|
30
|
-
// Native button
|
|
31
|
-
{
|
|
32
|
-
code: '<button onClick={handleClick}>Click me</button>',
|
|
33
|
-
errors: [{ messageId: "preferShadcn" }],
|
|
34
|
-
},
|
|
35
|
-
// Native input
|
|
36
|
-
{
|
|
37
|
-
code: '<input type="text" placeholder="Enter name" />',
|
|
38
|
-
errors: [{ messageId: "preferShadcn" }],
|
|
39
|
-
},
|
|
40
|
-
// Native select
|
|
41
|
-
{
|
|
42
|
-
code: '<select value={value} onChange={handleChange}><option>A</option></select>',
|
|
43
|
-
errors: [{ messageId: "preferShadcn" }],
|
|
44
|
-
},
|
|
45
|
-
// Native textarea
|
|
46
|
-
{
|
|
47
|
-
code: '<textarea rows={5} />',
|
|
48
|
-
errors: [{ messageId: "preferShadcn" }],
|
|
49
|
-
},
|
|
50
|
-
// Native table
|
|
51
|
-
{
|
|
52
|
-
code: '<table><tbody /></table>',
|
|
53
|
-
errors: [{ messageId: "preferShadcn" }],
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"require-assert-never.test.d.ts","sourceRoot":"","sources":["../../src/rules/require-assert-never.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { RuleTester } from "eslint";
|
|
2
|
-
import { describe, it } from "vitest";
|
|
3
|
-
import { requireAssertNever } from "./require-assert-never.js";
|
|
4
|
-
const ruleTester = new RuleTester({
|
|
5
|
-
languageOptions: {
|
|
6
|
-
ecmaVersion: 2022,
|
|
7
|
-
sourceType: "module",
|
|
8
|
-
},
|
|
9
|
-
});
|
|
10
|
-
describe("require-assert-never", () => {
|
|
11
|
-
it("should pass valid and fail invalid cases", () => {
|
|
12
|
-
ruleTester.run("require-assert-never", requireAssertNever, {
|
|
13
|
-
valid: [
|
|
14
|
-
// Switch with assertNever in default case
|
|
15
|
-
{
|
|
16
|
-
code: `
|
|
17
|
-
switch (status) {
|
|
18
|
-
case "active":
|
|
19
|
-
return 1;
|
|
20
|
-
default:
|
|
21
|
-
assertNever(status);
|
|
22
|
-
}
|
|
23
|
-
`,
|
|
24
|
-
},
|
|
25
|
-
// Switch with throw assertNever
|
|
26
|
-
{
|
|
27
|
-
code: `
|
|
28
|
-
switch (type) {
|
|
29
|
-
case "a":
|
|
30
|
-
break;
|
|
31
|
-
default:
|
|
32
|
-
throw assertNever(type);
|
|
33
|
-
}
|
|
34
|
-
`,
|
|
35
|
-
},
|
|
36
|
-
// Switch without default case is OK
|
|
37
|
-
{
|
|
38
|
-
code: `
|
|
39
|
-
switch (value) {
|
|
40
|
-
case 1:
|
|
41
|
-
return "one";
|
|
42
|
-
case 2:
|
|
43
|
-
return "two";
|
|
44
|
-
}
|
|
45
|
-
`,
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
invalid: [
|
|
49
|
-
// Default case without assertNever
|
|
50
|
-
{
|
|
51
|
-
code: `
|
|
52
|
-
switch (status) {
|
|
53
|
-
case "active":
|
|
54
|
-
return 1;
|
|
55
|
-
default:
|
|
56
|
-
return 0;
|
|
57
|
-
}
|
|
58
|
-
`,
|
|
59
|
-
errors: [{ messageId: "missingAssertNever" }],
|
|
60
|
-
},
|
|
61
|
-
// Empty default case
|
|
62
|
-
{
|
|
63
|
-
code: `
|
|
64
|
-
switch (type) {
|
|
65
|
-
case "a":
|
|
66
|
-
break;
|
|
67
|
-
default:
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
`,
|
|
71
|
-
errors: [{ messageId: "missingAssertNever" }],
|
|
72
|
-
},
|
|
73
|
-
],
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"zod-naming-convention.test.d.ts","sourceRoot":"","sources":["../../src/rules/zod-naming-convention.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { RuleTester } from "eslint";
|
|
2
|
-
import { describe, it } from "vitest";
|
|
3
|
-
import { zodNamingConvention } from "./zod-naming-convention.js";
|
|
4
|
-
const ruleTester = new RuleTester({
|
|
5
|
-
languageOptions: {
|
|
6
|
-
ecmaVersion: 2022,
|
|
7
|
-
sourceType: "module",
|
|
8
|
-
},
|
|
9
|
-
});
|
|
10
|
-
describe("zod-naming-convention", () => {
|
|
11
|
-
it("should pass valid and fail invalid cases", () => {
|
|
12
|
-
ruleTester.run("zod-naming-convention", zodNamingConvention, {
|
|
13
|
-
valid: [
|
|
14
|
-
// Correct naming with Z prefix
|
|
15
|
-
{ code: 'const ZUserSchema = z.object({ name: z.string() });' },
|
|
16
|
-
{ code: 'const ZConfig = z.object({ port: z.number() });' },
|
|
17
|
-
{ code: 'const ZResponse = z.object({}).extend({});' },
|
|
18
|
-
// Non-Zod variables are fine
|
|
19
|
-
{ code: 'const userSchema = createSchema();' },
|
|
20
|
-
{ code: 'const config = { name: "test" };' },
|
|
21
|
-
],
|
|
22
|
-
invalid: [
|
|
23
|
-
{
|
|
24
|
-
code: 'const userSchema = z.object({ name: z.string() });',
|
|
25
|
-
errors: [{ messageId: "zodPrefix" }],
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
code: 'const schema = z.string();',
|
|
29
|
-
errors: [{ messageId: "zodPrefix" }],
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
code: 'const config = z.object({}).extend({ port: z.number() });',
|
|
33
|
-
errors: [{ messageId: "zodPrefix" }],
|
|
34
|
-
},
|
|
35
|
-
],
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
});
|