@prairielearn/eslint-plugin 4.1.0 → 4.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/index.d.ts +15 -10
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +20 -21
  5. package/dist/index.js.map +1 -1
  6. package/dist/rules/aws-client-mandatory-config.d.ts.map +1 -1
  7. package/dist/rules/aws-client-mandatory-config.js +4 -6
  8. package/dist/rules/aws-client-mandatory-config.js.map +1 -1
  9. package/dist/rules/aws-client-shared-config.d.ts.map +1 -1
  10. package/dist/rules/aws-client-shared-config.js +4 -6
  11. package/dist/rules/aws-client-shared-config.js.map +1 -1
  12. package/dist/rules/html-no-duplicate-id.d.ts +10 -0
  13. package/dist/rules/html-no-duplicate-id.d.ts.map +1 -0
  14. package/dist/rules/html-no-duplicate-id.js +54 -0
  15. package/dist/rules/html-no-duplicate-id.js.map +1 -0
  16. package/dist/rules/jsx-no-dollar-interpolation.d.ts.map +1 -1
  17. package/dist/rules/jsx-no-dollar-interpolation.js +2 -4
  18. package/dist/rules/jsx-no-dollar-interpolation.js.map +1 -1
  19. package/dist/rules/no-current-target-in-callback.d.ts.map +1 -1
  20. package/dist/rules/no-current-target-in-callback.js +2 -4
  21. package/dist/rules/no-current-target-in-callback.js.map +1 -1
  22. package/dist/rules/no-hydrate-reslocals.d.ts.map +1 -1
  23. package/dist/rules/no-hydrate-reslocals.js +2 -4
  24. package/dist/rules/no-hydrate-reslocals.js.map +1 -1
  25. package/dist/rules/no-unused-sql-blocks.d.ts.map +1 -1
  26. package/dist/rules/no-unused-sql-blocks.js +4 -39
  27. package/dist/rules/no-unused-sql-blocks.js.map +1 -1
  28. package/dist/rules/require-trpc-permission-middleware.d.ts +4 -0
  29. package/dist/rules/require-trpc-permission-middleware.d.ts.map +1 -0
  30. package/dist/rules/require-trpc-permission-middleware.js +133 -0
  31. package/dist/rules/require-trpc-permission-middleware.js.map +1 -0
  32. package/dist/rules/safe-db-types.d.ts +1 -1
  33. package/dist/rules/safe-db-types.d.ts.map +1 -1
  34. package/dist/rules/safe-db-types.js +6 -40
  35. package/dist/rules/safe-db-types.js.map +1 -1
  36. package/dist/tests/aws-client-mandatory-config.test.d.ts.map +1 -1
  37. package/dist/tests/aws-client-mandatory-config.test.js +8 -13
  38. package/dist/tests/aws-client-mandatory-config.test.js.map +1 -1
  39. package/dist/tests/aws-client-shared-config.test.d.ts.map +1 -1
  40. package/dist/tests/aws-client-shared-config.test.js +8 -13
  41. package/dist/tests/aws-client-shared-config.test.js.map +1 -1
  42. package/dist/tests/html-no-duplicate-id.test.d.ts +2 -0
  43. package/dist/tests/html-no-duplicate-id.test.d.ts.map +1 -0
  44. package/dist/tests/html-no-duplicate-id.test.js +54 -0
  45. package/dist/tests/html-no-duplicate-id.test.js.map +1 -0
  46. package/dist/tests/jsx-no-dollar-interpolation.test.d.ts.map +1 -1
  47. package/dist/tests/jsx-no-dollar-interpolation.test.js +8 -13
  48. package/dist/tests/jsx-no-dollar-interpolation.test.js.map +1 -1
  49. package/dist/tests/no-current-target-in-callback.test.js +8 -13
  50. package/dist/tests/no-current-target-in-callback.test.js.map +1 -1
  51. package/dist/tests/no-hydrate-reslocals.test.d.ts.map +1 -1
  52. package/dist/tests/no-hydrate-reslocals.test.js +8 -13
  53. package/dist/tests/no-hydrate-reslocals.test.js.map +1 -1
  54. package/dist/tests/require-trpc-permission-middleware.test.d.ts +2 -0
  55. package/dist/tests/require-trpc-permission-middleware.test.d.ts.map +1 -0
  56. package/dist/tests/require-trpc-permission-middleware.test.js +106 -0
  57. package/dist/tests/require-trpc-permission-middleware.test.js.map +1 -0
  58. package/dist/utils.js +1 -4
  59. package/dist/utils.js.map +1 -1
  60. package/package.json +11 -10
  61. package/src/index.ts +7 -1
  62. package/src/rules/html-no-duplicate-id.ts +76 -0
  63. package/src/rules/require-trpc-permission-middleware.ts +168 -0
  64. package/src/tests/aws-client-mandatory-config.test.ts +1 -1
  65. package/src/tests/aws-client-shared-config.test.ts +1 -1
  66. package/src/tests/html-no-duplicate-id.test.ts +57 -0
  67. package/src/tests/jsx-no-dollar-interpolation.test.ts +1 -1
  68. package/src/tests/no-hydrate-reslocals.test.ts +1 -1
  69. package/src/tests/require-trpc-permission-middleware.test.ts +109 -0
  70. package/tsconfig.json +1 -7
@@ -0,0 +1,109 @@
1
+ import { RuleTester } from '@typescript-eslint/rule-tester';
2
+ import { afterAll, describe, it } from 'vitest';
3
+
4
+ import rule from '../rules/require-trpc-permission-middleware.js';
5
+
6
+ RuleTester.afterAll = afterAll;
7
+ RuleTester.describe = describe;
8
+ RuleTester.it = it;
9
+
10
+ const ruleTester = new RuleTester();
11
+
12
+ ruleTester.run('require-trpc-permission-middleware', rule, {
13
+ valid: [
14
+ {
15
+ code: 'const list = t.procedure.use(requireCoursePermissionEdit).query(async () => {});',
16
+ },
17
+ {
18
+ code: 'const m = t.procedure.use(requireCoursePermissionPreview).mutation(async () => {});',
19
+ },
20
+ {
21
+ code: `const m = t.procedure
22
+ .use(requireEnhancedAccessControl)
23
+ .use(requireCourseInstancePermissionView)
24
+ .query(async () => {});`,
25
+ },
26
+ {
27
+ code: 'const m = t.procedure.use(requireAdministrator).mutation(async () => {});',
28
+ },
29
+ {
30
+ code: `const m = t.procedure
31
+ .use(requireCourseInstancePermissionEdit)
32
+ .input(z.object({}))
33
+ .mutation(async () => {});`,
34
+ },
35
+ {
36
+ code: 'const list = t.procedure.use(requireCoursePermissionOwn).query(async () => {});',
37
+ },
38
+ // Not a t.procedure chain — should be ignored
39
+ {
40
+ code: 'const fn = somethingElse.query(async () => {});',
41
+ },
42
+ {
43
+ code: 'const fn = otherRouter.procedure.query(async () => {});',
44
+ },
45
+ // Intermediate procedure-base variable: permission middleware on the base
46
+ {
47
+ code: `
48
+ const protectedProcedure = t.procedure.use(requireCoursePermissionOwn);
49
+ const m = protectedProcedure.query(async () => {});
50
+ `,
51
+ },
52
+ // Intermediate procedure-base variable: permission added downstream
53
+ {
54
+ code: `
55
+ const featureProcedure = t.procedure.use(requireAiGradingFeature);
56
+ const m = featureProcedure.use(requireAdministrator).mutation(async () => {});
57
+ `,
58
+ },
59
+ // Imported procedure base — we can't follow across files, so don't fire
60
+ {
61
+ code: `
62
+ import { protectedProcedure } from './foo.js';
63
+ const m = protectedProcedure.query(async () => {});
64
+ `,
65
+ languageOptions: { parserOptions: { sourceType: 'module' } },
66
+ },
67
+ ],
68
+ invalid: [
69
+ {
70
+ code: 'const list = t.procedure.query(async () => {});',
71
+ errors: [{ messageId: 'missingPermissionMiddleware' }],
72
+ },
73
+ {
74
+ code: 'const m = t.procedure.input(z.object({})).mutation(async () => {});',
75
+ errors: [{ messageId: 'missingPermissionMiddleware' }],
76
+ },
77
+ // Feature gate alone is not a permission gate
78
+ {
79
+ code: 'const m = t.procedure.use(requireEnhancedAccessControl).mutation(async () => {});',
80
+ errors: [{ messageId: 'missingPermissionMiddleware' }],
81
+ },
82
+ {
83
+ code: 'const m = t.procedure.use(requireAiGradingFeature).mutation(async () => {});',
84
+ errors: [{ messageId: 'missingPermissionMiddleware' }],
85
+ },
86
+ {
87
+ code: `const m = t.procedure
88
+ .input(z.object({}))
89
+ .output(z.object({}))
90
+ .subscription(async () => {});`,
91
+ errors: [{ messageId: 'missingPermissionMiddleware' }],
92
+ },
93
+ // Intermediate procedure-base variable with only a feature gate is still a miss
94
+ {
95
+ code: `
96
+ const featureProcedure = t.procedure.use(requireAiGradingFeature);
97
+ const m = featureProcedure.query(async () => {});
98
+ `,
99
+ errors: [{ messageId: 'missingPermissionMiddleware' }],
100
+ },
101
+ {
102
+ code: `
103
+ const featureProcedure = t.procedure.use(requireAiGradingFeature);
104
+ const m = featureProcedure.input(z.object({})).mutation(async () => {});
105
+ `,
106
+ errors: [{ messageId: 'missingPermissionMiddleware' }],
107
+ },
108
+ ],
109
+ });
package/tsconfig.json CHANGED
@@ -1,9 +1,3 @@
1
1
  {
2
- // This must be a CJS package because ESLint doesn't support ESM plugins.
3
- "extends": "@prairielearn/tsconfig/tsconfig.package-cjs.json",
4
- "compilerOptions": {
5
- "outDir": "./dist",
6
- "rootDir": "./src",
7
- "types": ["node"]
8
- }
2
+ "extends": "@prairielearn/tsconfig/tsconfig.package-node.json"
9
3
  }