@valbuild/eslint-plugin 0.47.0 → 0.48.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.
@@ -46,8 +46,7 @@ var noIllegalModuleIds = {
46
46
  meta: {
47
47
  type: "problem",
48
48
  docs: {
49
- description: "Check that the first argument of export default declaration matches the string from val.config.ts file.",
50
- category: "Best Practices",
49
+ description: "Check that the first argument of export default declaration matches the string from val.config.{j,t}s file.",
51
50
  recommended: true
52
51
  },
53
52
  fixable: "code",
@@ -130,10 +129,8 @@ var noIllegalImports = {
130
129
  type: "problem",
131
130
  docs: {
132
131
  description: "Check that val files only has valid imports.",
133
- category: "Best Practices",
134
132
  recommended: true
135
133
  },
136
- fixable: "code",
137
134
  schema: []
138
135
  },
139
136
  create: function create(context) {
@@ -144,11 +141,49 @@ var noIllegalImports = {
144
141
  var isValFile = filename.endsWith(".val.ts") || filename.endsWith(".val.js");
145
142
  // only allow: .val files, @valbuild packages, and val config
146
143
  if (isValFile && typeof importSource === "string" && !importSource.match(/\.val(\.ts|\.js|)$/) && !importSource.match(/^@valbuild/) && !importSource.match(/val\.config(\.ts|\.js|)$/)) {
147
- var message = "Val: import source should be a .val.ts file, a @valbuild package, or val.config.ts. Found: '".concat(importSource, "'");
148
- context.report({
149
- node: node.source,
150
- message: message
151
- });
144
+ if ("importKind" in node && node["importKind"] !== "type" && !node.specifiers.every(function (s) {
145
+ return "importKind" in s && s["importKind"] === "type";
146
+ })) {
147
+ var message = "Val: can only 'import type' or import from source that is either: a .val.{j,t}s file, a @valbuild package, or val.config.{j,t}s.";
148
+ context.report({
149
+ node: node.source,
150
+ message: message
151
+ });
152
+ }
153
+ }
154
+ }
155
+ };
156
+ }
157
+ };
158
+
159
+ // @ts-check
160
+
161
+ /**
162
+ * @type {import('eslint').Rule.RuleModule}
163
+ */
164
+ var exportContentMustBeValid = {
165
+ meta: {
166
+ type: "problem",
167
+ docs: {
168
+ description: "Export val.content should only happen in .val files.",
169
+ recommended: true
170
+ },
171
+ messages: {
172
+ "val/export-content-must-be-valid": "Val: val.content should only be exported from .val files"
173
+ },
174
+ schema: []
175
+ },
176
+ create: function create(context) {
177
+ return {
178
+ ExportDefaultDeclaration: function ExportDefaultDeclaration(node) {
179
+ if (node.declaration && node.declaration.type === "CallExpression" && node.declaration.callee.type === "MemberExpression" && node.declaration.callee.object.type === "Identifier" && node.declaration.callee.object.name === "val" && node.declaration.callee.property.type === "Identifier" && node.declaration.callee.property.name === "content") {
180
+ var filename = context.filename || context.getFilename();
181
+ if (!(filename !== null && filename !== void 0 && filename.endsWith(".val.ts") || filename !== null && filename !== void 0 && filename.endsWith(".val.js"))) {
182
+ context.report({
183
+ node: node.declaration.callee,
184
+ messageId: "val/export-content-must-be-valid"
185
+ });
186
+ }
152
187
  }
153
188
  }
154
189
  };
@@ -162,7 +197,8 @@ var noIllegalImports = {
162
197
  */
163
198
  var rules = {
164
199
  "no-illegal-module-ids": noIllegalModuleIds,
165
- "no-illegal-imports": noIllegalImports
200
+ "no-illegal-imports": noIllegalImports,
201
+ "export-content-must-be-valid": exportContentMustBeValid
166
202
  };
167
203
 
168
204
  /**
@@ -46,8 +46,7 @@ var noIllegalModuleIds = {
46
46
  meta: {
47
47
  type: "problem",
48
48
  docs: {
49
- description: "Check that the first argument of export default declaration matches the string from val.config.ts file.",
50
- category: "Best Practices",
49
+ description: "Check that the first argument of export default declaration matches the string from val.config.{j,t}s file.",
51
50
  recommended: true
52
51
  },
53
52
  fixable: "code",
@@ -130,10 +129,8 @@ var noIllegalImports = {
130
129
  type: "problem",
131
130
  docs: {
132
131
  description: "Check that val files only has valid imports.",
133
- category: "Best Practices",
134
132
  recommended: true
135
133
  },
136
- fixable: "code",
137
134
  schema: []
138
135
  },
139
136
  create: function create(context) {
@@ -144,11 +141,49 @@ var noIllegalImports = {
144
141
  var isValFile = filename.endsWith(".val.ts") || filename.endsWith(".val.js");
145
142
  // only allow: .val files, @valbuild packages, and val config
146
143
  if (isValFile && typeof importSource === "string" && !importSource.match(/\.val(\.ts|\.js|)$/) && !importSource.match(/^@valbuild/) && !importSource.match(/val\.config(\.ts|\.js|)$/)) {
147
- var message = "Val: import source should be a .val.ts file, a @valbuild package, or val.config.ts. Found: '".concat(importSource, "'");
148
- context.report({
149
- node: node.source,
150
- message: message
151
- });
144
+ if ("importKind" in node && node["importKind"] !== "type" && !node.specifiers.every(function (s) {
145
+ return "importKind" in s && s["importKind"] === "type";
146
+ })) {
147
+ var message = "Val: can only 'import type' or import from source that is either: a .val.{j,t}s file, a @valbuild package, or val.config.{j,t}s.";
148
+ context.report({
149
+ node: node.source,
150
+ message: message
151
+ });
152
+ }
153
+ }
154
+ }
155
+ };
156
+ }
157
+ };
158
+
159
+ // @ts-check
160
+
161
+ /**
162
+ * @type {import('eslint').Rule.RuleModule}
163
+ */
164
+ var exportContentMustBeValid = {
165
+ meta: {
166
+ type: "problem",
167
+ docs: {
168
+ description: "Export val.content should only happen in .val files.",
169
+ recommended: true
170
+ },
171
+ messages: {
172
+ "val/export-content-must-be-valid": "Val: val.content should only be exported from .val files"
173
+ },
174
+ schema: []
175
+ },
176
+ create: function create(context) {
177
+ return {
178
+ ExportDefaultDeclaration: function ExportDefaultDeclaration(node) {
179
+ if (node.declaration && node.declaration.type === "CallExpression" && node.declaration.callee.type === "MemberExpression" && node.declaration.callee.object.type === "Identifier" && node.declaration.callee.object.name === "val" && node.declaration.callee.property.type === "Identifier" && node.declaration.callee.property.name === "content") {
180
+ var filename = context.filename || context.getFilename();
181
+ if (!(filename !== null && filename !== void 0 && filename.endsWith(".val.ts") || filename !== null && filename !== void 0 && filename.endsWith(".val.js"))) {
182
+ context.report({
183
+ node: node.declaration.callee,
184
+ messageId: "val/export-content-must-be-valid"
185
+ });
186
+ }
152
187
  }
153
188
  }
154
189
  };
@@ -162,7 +197,8 @@ var noIllegalImports = {
162
197
  */
163
198
  var rules = {
164
199
  "no-illegal-module-ids": noIllegalModuleIds,
165
- "no-illegal-imports": noIllegalImports
200
+ "no-illegal-imports": noIllegalImports,
201
+ "export-content-must-be-valid": exportContentMustBeValid
166
202
  };
167
203
 
168
204
  /**
@@ -38,8 +38,7 @@ var noIllegalModuleIds = {
38
38
  meta: {
39
39
  type: "problem",
40
40
  docs: {
41
- description: "Check that the first argument of export default declaration matches the string from val.config.ts file.",
42
- category: "Best Practices",
41
+ description: "Check that the first argument of export default declaration matches the string from val.config.{j,t}s file.",
43
42
  recommended: true
44
43
  },
45
44
  fixable: "code",
@@ -122,10 +121,8 @@ var noIllegalImports = {
122
121
  type: "problem",
123
122
  docs: {
124
123
  description: "Check that val files only has valid imports.",
125
- category: "Best Practices",
126
124
  recommended: true
127
125
  },
128
- fixable: "code",
129
126
  schema: []
130
127
  },
131
128
  create: function create(context) {
@@ -136,11 +133,49 @@ var noIllegalImports = {
136
133
  var isValFile = filename.endsWith(".val.ts") || filename.endsWith(".val.js");
137
134
  // only allow: .val files, @valbuild packages, and val config
138
135
  if (isValFile && typeof importSource === "string" && !importSource.match(/\.val(\.ts|\.js|)$/) && !importSource.match(/^@valbuild/) && !importSource.match(/val\.config(\.ts|\.js|)$/)) {
139
- var message = "Val: import source should be a .val.ts file, a @valbuild package, or val.config.ts. Found: '".concat(importSource, "'");
140
- context.report({
141
- node: node.source,
142
- message: message
143
- });
136
+ if ("importKind" in node && node["importKind"] !== "type" && !node.specifiers.every(function (s) {
137
+ return "importKind" in s && s["importKind"] === "type";
138
+ })) {
139
+ var message = "Val: can only 'import type' or import from source that is either: a .val.{j,t}s file, a @valbuild package, or val.config.{j,t}s.";
140
+ context.report({
141
+ node: node.source,
142
+ message: message
143
+ });
144
+ }
145
+ }
146
+ }
147
+ };
148
+ }
149
+ };
150
+
151
+ // @ts-check
152
+
153
+ /**
154
+ * @type {import('eslint').Rule.RuleModule}
155
+ */
156
+ var exportContentMustBeValid = {
157
+ meta: {
158
+ type: "problem",
159
+ docs: {
160
+ description: "Export val.content should only happen in .val files.",
161
+ recommended: true
162
+ },
163
+ messages: {
164
+ "val/export-content-must-be-valid": "Val: val.content should only be exported from .val files"
165
+ },
166
+ schema: []
167
+ },
168
+ create: function create(context) {
169
+ return {
170
+ ExportDefaultDeclaration: function ExportDefaultDeclaration(node) {
171
+ if (node.declaration && node.declaration.type === "CallExpression" && node.declaration.callee.type === "MemberExpression" && node.declaration.callee.object.type === "Identifier" && node.declaration.callee.object.name === "val" && node.declaration.callee.property.type === "Identifier" && node.declaration.callee.property.name === "content") {
172
+ var filename = context.filename || context.getFilename();
173
+ if (!(filename !== null && filename !== void 0 && filename.endsWith(".val.ts") || filename !== null && filename !== void 0 && filename.endsWith(".val.js"))) {
174
+ context.report({
175
+ node: node.declaration.callee,
176
+ messageId: "val/export-content-must-be-valid"
177
+ });
178
+ }
144
179
  }
145
180
  }
146
181
  };
@@ -154,7 +189,8 @@ var noIllegalImports = {
154
189
  */
155
190
  var rules = {
156
191
  "no-illegal-module-ids": noIllegalModuleIds,
157
- "no-illegal-imports": noIllegalImports
192
+ "no-illegal-imports": noIllegalImports,
193
+ "export-content-must-be-valid": exportContentMustBeValid
158
194
  };
159
195
 
160
196
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valbuild/eslint-plugin",
3
- "version": "0.47.0",
3
+ "version": "0.48.0",
4
4
  "description": "ESLint rules for val",
5
5
  "keywords": [
6
6
  "eslint",
@@ -27,7 +27,8 @@
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/jest": "^29.5.11",
30
- "eslint": "^7.10.0",
30
+ "@typescript-eslint/rule-tester": "^6.15.0",
31
+ "eslint": "^8.56.0",
31
32
  "jest": "^29.6"
32
33
  },
33
34
  "scripts": {
package/src/index.js CHANGED
@@ -8,6 +8,7 @@
8
8
 
9
9
  import noIllegalModuleIds from "./rules/noIllegalModuleIds";
10
10
  import noIllegalImports from "./rules/noIllegalImports";
11
+ import exportContentMustBeValid from "./rules/exportContentMustBeValid";
11
12
 
12
13
  /**
13
14
  * @type {Plugin["rules"]}
@@ -15,6 +16,7 @@ import noIllegalImports from "./rules/noIllegalImports";
15
16
  export let rules = {
16
17
  "no-illegal-module-ids": noIllegalModuleIds,
17
18
  "no-illegal-imports": noIllegalImports,
19
+ "export-content-must-be-valid": exportContentMustBeValid,
18
20
  };
19
21
 
20
22
  /**
@@ -0,0 +1,44 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @type {import('eslint').Rule.RuleModule}
5
+ */
6
+ export default {
7
+ meta: {
8
+ type: "problem",
9
+ docs: {
10
+ description: "Export val.content should only happen in .val files.",
11
+ recommended: true,
12
+ },
13
+ messages: {
14
+ "val/export-content-must-be-valid":
15
+ "Val: val.content should only be exported from .val files",
16
+ },
17
+ schema: [],
18
+ },
19
+ create: function (context) {
20
+ return {
21
+ ExportDefaultDeclaration(node) {
22
+ if (
23
+ node.declaration &&
24
+ node.declaration.type === "CallExpression" &&
25
+ node.declaration.callee.type === "MemberExpression" &&
26
+ node.declaration.callee.object.type === "Identifier" &&
27
+ node.declaration.callee.object.name === "val" &&
28
+ node.declaration.callee.property.type === "Identifier" &&
29
+ node.declaration.callee.property.name === "content"
30
+ ) {
31
+ const filename = context.filename || context.getFilename();
32
+ if (
33
+ !(filename?.endsWith(".val.ts") || filename?.endsWith(".val.js"))
34
+ ) {
35
+ context.report({
36
+ node: node.declaration.callee,
37
+ messageId: "val/export-content-must-be-valid",
38
+ });
39
+ }
40
+ }
41
+ },
42
+ };
43
+ },
44
+ };
@@ -8,10 +8,8 @@ export default {
8
8
  type: "problem",
9
9
  docs: {
10
10
  description: "Check that val files only has valid imports.",
11
- category: "Best Practices",
12
11
  recommended: true,
13
12
  },
14
- fixable: "code",
15
13
  schema: [],
16
14
  },
17
15
  create: function (context) {
@@ -30,11 +28,19 @@ export default {
30
28
  !importSource.match(/^@valbuild/) &&
31
29
  !importSource.match(/val\.config(\.ts|\.js|)$/)
32
30
  ) {
33
- const message = `Val: import source should be a .val.ts file, a @valbuild package, or val.config.ts. Found: '${importSource}'`;
34
- context.report({
35
- node: node.source,
36
- message,
37
- });
31
+ if (
32
+ "importKind" in node &&
33
+ node["importKind"] !== "type" &&
34
+ !node.specifiers.every(
35
+ (s) => "importKind" in s && s["importKind"] === "type"
36
+ )
37
+ ) {
38
+ const message = `Val: can only 'import type' or import from source that is either: a .val.{j,t}s file, a @valbuild package, or val.config.{j,t}s.`;
39
+ context.report({
40
+ node: node.source,
41
+ message,
42
+ });
43
+ }
38
44
  }
39
45
  },
40
46
  };
@@ -9,8 +9,7 @@ export default {
9
9
  type: "problem",
10
10
  docs: {
11
11
  description:
12
- "Check that the first argument of export default declaration matches the string from val.config.ts file.",
13
- category: "Best Practices",
12
+ "Check that the first argument of export default declaration matches the string from val.config.{j,t}s file.",
14
13
  recommended: true,
15
14
  },
16
15
  fixable: "code",
@@ -0,0 +1,56 @@
1
+ import { RuleTester } from "@typescript-eslint/rule-tester";
2
+ import { rules as valRules } from "@valbuild/eslint-plugin";
3
+ import path from "path";
4
+
5
+ const rule = valRules["export-content-must-be-valid"];
6
+
7
+ RuleTester.setDefaultConfig({
8
+ parserOptions: {
9
+ ecmaVersion: 2018,
10
+ sourceType: "module",
11
+ ecmaFeatures: {},
12
+ },
13
+ });
14
+
15
+ const ruleTester = new RuleTester();
16
+
17
+ ruleTester.run("export-content-must-be-valid", rule, {
18
+ valid: [
19
+ {
20
+ filename: path.join(process.cwd(), "./foo/test.val.ts"),
21
+ code: `
22
+ import { val, s } from '../val.config';
23
+
24
+ export const schema = s.string();
25
+ export default val.content('/foo/test', schema, '')`,
26
+ },
27
+ ],
28
+ invalid: [
29
+ {
30
+ filename: path.join(process.cwd(), "./foo/test.ts"),
31
+ code: `
32
+ import { val, s } from '../val.config';
33
+
34
+ export const schema = s.string();
35
+ export default val.content('/foo/test', schema, '')`,
36
+ errors: [
37
+ {
38
+ message: "Val: val.content should only be exported from .val files",
39
+ },
40
+ ],
41
+ },
42
+ {
43
+ filename: path.join(process.cwd(), "./foo/test.js"),
44
+ code: `
45
+ import { val, s } from '../val.config';
46
+
47
+ export const schema = s.string();
48
+ export default val.content('/foo/test', schema, '')`,
49
+ errors: [
50
+ {
51
+ message: "Val: val.content should only be exported from .val files",
52
+ },
53
+ ],
54
+ },
55
+ ],
56
+ });
@@ -1,4 +1,4 @@
1
- import { RuleTester } from "eslint";
1
+ import { RuleTester } from "@typescript-eslint/rule-tester";
2
2
  import { rules as valRules } from "@valbuild/eslint-plugin";
3
3
  import path from "path";
4
4
 
@@ -8,9 +8,8 @@ RuleTester.setDefaultConfig({
8
8
  parserOptions: {
9
9
  ecmaVersion: 2018,
10
10
  sourceType: "module",
11
- ecmaFeatures: {
12
- jsx: true,
13
- },
11
+
12
+ ecmaFeatures: {},
14
13
  },
15
14
  });
16
15
 
@@ -40,6 +39,26 @@ export default val.content('/foo/test', schema, [])`,
40
39
  filename: path.join(process.cwd(), "./foo/test.val.ts"),
41
40
  code: `
42
41
  import { val, s } from '../val.config.ts';
42
+ import type { Event } from './eventSchema';
43
+
44
+ export const schema = s.array(s.string());
45
+ type Test = Event;
46
+ export default val.content('/foo/test', schema, [])`,
47
+ },
48
+ {
49
+ filename: path.join(process.cwd(), "./foo/test.val.ts"),
50
+ code: `
51
+ import { val, s } from '../val.config.ts';
52
+ import { type Event } from './eventSchema';
53
+
54
+ export const schema = s.array(s.string());
55
+ type Test = Event;
56
+ export default val.content('/foo/test', schema, [])`,
57
+ },
58
+ {
59
+ filename: path.join(process.cwd(), "./foo/test.val.ts"),
60
+ code: `
61
+ import { val, s } from '../val.config.ts';
43
62
 
44
63
  export const schema = s.string();
45
64
  export default val.content('/foo/test', schema, 'String')`,
@@ -57,7 +76,23 @@ export default val.content('/foo/test', schema, [])`,
57
76
  errors: [
58
77
  {
59
78
  message:
60
- "Val: import source should be a .val.ts file, a @valbuild package, or val.config.ts. Found: './event'",
79
+ "Val: can only 'import type' or import from source that is either: a .val.{j,t}s file, a @valbuild package, or val.config.{j,t}s.",
80
+ },
81
+ ],
82
+ },
83
+ {
84
+ filename: path.join(process.cwd(), "./foo/test.val.ts"),
85
+ code: `
86
+ import { val, s } from '../val.config';
87
+ import { eventSchema, type Unused } from './event';
88
+
89
+ export const schema = s.array(eventSchema);
90
+ type Event = Unused;
91
+ export default val.content('/foo/test', schema, [])`,
92
+ errors: [
93
+ {
94
+ message:
95
+ "Val: can only 'import type' or import from source that is either: a .val.{j,t}s file, a @valbuild package, or val.config.{j,t}s.",
61
96
  },
62
97
  ],
63
98
  },