@flint.fyi/plugin-flint 0.5.0 → 0.5.2

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/lib/index.d.ts CHANGED
@@ -1,98 +1,98 @@
1
1
  import * as _flint_fyi_core0 from "@flint.fyi/core";
2
2
 
3
3
  //#region src/plugin.d.ts
4
- declare const flint: _flint_fyi_core0.Plugin<_flint_fyi_core0.RuleAbout, string | undefined, [_flint_fyi_core0.Rule<{
4
+ declare const flint: _flint_fyi_core0.Plugin<_flint_fyi_core0.RuleAbout<string>, string | undefined, [_flint_fyi_core0.Rule<{
5
5
  readonly description: "Requires passing `sourceFile` to `getStart()` for better performance.";
6
6
  readonly id: "getStartSourceFile";
7
- readonly presets: ["logical"];
7
+ readonly presets: readonly ["logical"];
8
8
  } & {
9
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
10
- url: string;
11
- }, object, object, "missingSourceFile", _flint_fyi_core0.AnyOptionalSchema>, _flint_fyi_core0.Rule<{
9
+ readonly pluginId: string;
10
+ readonly url: string;
11
+ }, "missingSourceFile", undefined>, _flint_fyi_core0.Rule<{
12
12
  readonly description: "Reports cases for invalid code that isn't formatted across lines.";
13
13
  readonly id: "invalidCodeLines";
14
- readonly presets: ["logical"];
14
+ readonly presets: readonly ["logical"];
15
15
  } & {
16
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
17
- url: string;
18
- }, object, object, "singleLineTest", _flint_fyi_core0.AnyOptionalSchema>, _flint_fyi_core0.Rule<{
16
+ readonly pluginId: string;
17
+ readonly url: string;
18
+ }, "singleLineTest", undefined>, _flint_fyi_core0.Rule<{
19
19
  readonly description: "Reports `context.report()` calls missing data for message placeholders.";
20
20
  readonly id: "missingPlaceholders";
21
- readonly presets: ["logical"];
21
+ readonly presets: readonly ["logical"];
22
22
  } & {
23
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
24
- url: string;
25
- }, object, object, "missingPlaceholders", _flint_fyi_core0.AnyOptionalSchema>, _flint_fyi_core0.Rule<{
23
+ readonly pluginId: string;
24
+ readonly url: string;
25
+ }, "missingPlaceholders", undefined>, _flint_fyi_core0.Rule<{
26
26
  readonly description: "Disallows using the `in` operator to check properties on TypeScript nodes.";
27
27
  readonly id: "nodePropertyInChecks";
28
- readonly presets: ["logical"];
28
+ readonly presets: readonly ["logical"];
29
29
  } & {
30
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
31
- url: string;
32
- }, object, object, "nodePropertyInChecks", _flint_fyi_core0.AnyOptionalSchema>, _flint_fyi_core0.Rule<{
30
+ readonly pluginId: string;
31
+ readonly url: string;
32
+ }, "nodePropertyInChecks", undefined>, _flint_fyi_core0.Rule<{
33
33
  readonly description: "Reports and auto-fixes message placeholders that are not formatted as `{{ placeholder }}`.";
34
34
  readonly id: "placeholderFormats";
35
- readonly presets: ["stylistic", "stylisticStrict"];
35
+ readonly presets: readonly ["stylistic", "stylisticStrict"];
36
36
  } & {
37
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
38
- url: string;
39
- }, object, object, "placeholderFormats", _flint_fyi_core0.AnyOptionalSchema>, _flint_fyi_core0.Rule<{
37
+ readonly pluginId: string;
38
+ readonly url: string;
39
+ }, "placeholderFormats", undefined>, _flint_fyi_core0.Rule<{
40
40
  readonly description: "Reports Flint plugin `rules` arrays that are not sorted alphabetically.";
41
41
  readonly id: "pluginRuleOrdering";
42
- readonly presets: ["stylisticStrict"];
42
+ readonly presets: readonly ["stylisticStrict"];
43
43
  } & {
44
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
45
- url: string;
46
- }, object, object, "pluginRuleOrdering", _flint_fyi_core0.AnyOptionalSchema>, _flint_fyi_core0.Rule<{
44
+ readonly pluginId: string;
45
+ readonly url: string;
46
+ }, "pluginRuleOrdering", undefined>, _flint_fyi_core0.Rule<{
47
47
  readonly description: "Reports plugin rules created directly with language instead of through RuleCreator.";
48
48
  readonly id: "ruleCreationMethods";
49
- readonly presets: ["logical"];
49
+ readonly presets: readonly ["logical"];
50
50
  } & {
51
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
52
- url: string;
53
- }, object, object, "ruleCreationMethods", _flint_fyi_core0.AnyOptionalSchema>, _flint_fyi_core0.Rule<{
51
+ readonly pluginId: string;
52
+ readonly url: string;
53
+ }, "ruleCreationMethods", undefined>, _flint_fyi_core0.Rule<{
54
54
  readonly description: "Reports test cases that are identical to previous test cases.";
55
55
  readonly id: "testCaseDuplicates";
56
- readonly presets: ["logical"];
56
+ readonly presets: readonly ["logical"];
57
57
  } & {
58
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
59
- url: string;
60
- }, object, object, "duplicateTest", _flint_fyi_core0.AnyOptionalSchema>, _flint_fyi_core0.Rule<{
58
+ readonly pluginId: string;
59
+ readonly url: string;
60
+ }, "duplicateTest", undefined>, _flint_fyi_core0.Rule<{
61
61
  readonly description: "Reports test cases that have the same name as a previous test case.";
62
62
  readonly id: "testCaseNameDuplicates";
63
- readonly presets: ["logical"];
63
+ readonly presets: readonly ["logical"];
64
64
  } & {
65
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
66
- url: string;
67
- }, object, object, "duplicateTestName", _flint_fyi_core0.AnyOptionalSchema>, _flint_fyi_core0.Rule<{
65
+ readonly pluginId: string;
66
+ readonly url: string;
67
+ }, "duplicateTestName", undefined>, _flint_fyi_core0.Rule<{
68
68
  readonly description: "Test case code should be a static string literal.";
69
69
  readonly id: "testCaseNonStaticCode";
70
- readonly presets: ["logical"];
70
+ readonly presets: readonly ["logical"];
71
71
  } & {
72
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
73
- url: string;
74
- }, object, object, "nonStaticTestCaseCode", _flint_fyi_core0.AnyOptionalSchema>, _flint_fyi_core0.Rule<{
72
+ readonly pluginId: string;
73
+ readonly url: string;
74
+ }, "nonStaticTestCaseCode", undefined>, _flint_fyi_core0.Rule<{
75
75
  readonly description: "Reports test cases that are marked `only: true`.";
76
76
  readonly id: "testCaseOnlyFlags";
77
- readonly presets: ["logical"];
77
+ readonly presets: readonly ["logical"];
78
78
  } & {
79
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
80
- url: string;
81
- }, object, object, "testCaseOnly", _flint_fyi_core0.AnyOptionalSchema>, _flint_fyi_core0.Rule<{
79
+ readonly pluginId: string;
80
+ readonly url: string;
81
+ }, "testCaseOnly", undefined>, _flint_fyi_core0.Rule<{
82
82
  readonly description: "Test cases with only a code property can use string shorthand syntax instead of object literal syntax.";
83
83
  readonly id: "testShorthands";
84
- readonly presets: ["logical"];
84
+ readonly presets: readonly ["logical"];
85
85
  } & {
86
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
87
- url: string;
88
- }, object, object, "testShorthands", _flint_fyi_core0.AnyOptionalSchema>, _flint_fyi_core0.Rule<{
86
+ readonly pluginId: string;
87
+ readonly url: string;
88
+ }, "testShorthands", undefined>, _flint_fyi_core0.Rule<{
89
89
  readonly description: "Reports message IDs defined in the messages object that are never used in recognized report calls.";
90
90
  readonly id: "unusedMessageIds";
91
- readonly presets: ["logical"];
91
+ readonly presets: readonly ["logical"];
92
92
  } & {
93
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
94
- url: string;
95
- }, object, object, "unusedMessageIds", _flint_fyi_core0.AnyOptionalSchema>]>;
93
+ readonly pluginId: string;
94
+ readonly url: string;
95
+ }, "unusedMessageIds", undefined>]>;
96
96
  //#endregion
97
97
  export { flint };
98
98
  //# sourceMappingURL=index.d.ts.map
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { RuleCreator, createPlugin } from "@flint.fyi/core";
2
- import { getTSNodeRange, typescriptLanguage } from "@flint.fyi/typescript-language";
3
2
  import ts, { SyntaxKind } from "typescript";
3
+ import { getTSNodeRange, isStaticString, isStringRawNoSubstitution, typescriptLanguage } from "@flint.fyi/typescript-language";
4
4
  import { isTruthy } from "@flint.fyi/utils";
5
5
  //#region src/utils/isTypeFromTS.ts
6
6
  function isTypeFromTS(node, typeChecker, typeName) {
@@ -95,22 +95,22 @@ function tsAstToLiteral(node) {
95
95
  //#endregion
96
96
  //#region src/utils/parseTestCases.ts
97
97
  function parseTestCase(node) {
98
- if (node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NoSubstitutionTemplateLiteral) return {
99
- code: node.text,
98
+ if (isTestCaseCode(node)) return {
99
+ code: getTestCaseCode(node),
100
100
  nodes: {
101
101
  case: node,
102
102
  code: node
103
103
  }
104
104
  };
105
105
  if (node.kind !== SyntaxKind.ObjectLiteralExpression) return;
106
- const code = findProperty(node.properties, "code", (node) => node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NoSubstitutionTemplateLiteral);
106
+ const code = findProperty(node.properties, "code", isTestCaseCode);
107
107
  if (!code) return;
108
- const fileName = findProperty(node.properties, "fileName", (node) => node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NoSubstitutionTemplateLiteral);
108
+ const fileName = findProperty(node.properties, "fileName", isStaticString);
109
109
  const files = findProperty(node.properties, "files", (node) => node.kind === SyntaxKind.ObjectLiteralExpression);
110
- const name = findProperty(node.properties, "name", (node) => node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NoSubstitutionTemplateLiteral);
110
+ const name = findProperty(node.properties, "name", isStaticString);
111
111
  const options = findProperty(node.properties, "options", (node) => node.kind === SyntaxKind.ObjectLiteralExpression);
112
112
  return {
113
- code: code.text,
113
+ code: getTestCaseCode(code),
114
114
  fileName: fileName?.text,
115
115
  files: files && tsAstToLiteral(files),
116
116
  name: name?.text,
@@ -127,16 +127,16 @@ function parseTestCase(node) {
127
127
  }
128
128
  function parseTestCaseInvalid(node) {
129
129
  if (node.kind !== SyntaxKind.ObjectLiteralExpression) return;
130
- const code = findProperty(node.properties, "code", (node) => node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NoSubstitutionTemplateLiteral);
130
+ const code = findProperty(node.properties, "code", isTestCaseCode);
131
131
  if (!code) return;
132
- const fileName = findProperty(node.properties, "fileName", (node) => node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NoSubstitutionTemplateLiteral);
132
+ const fileName = findProperty(node.properties, "fileName", isStaticString);
133
133
  const files = findProperty(node.properties, "files", (node) => node.kind === SyntaxKind.ObjectLiteralExpression);
134
- const name = findProperty(node.properties, "name", (node) => node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NoSubstitutionTemplateLiteral);
134
+ const name = findProperty(node.properties, "name", isStaticString);
135
135
  const options = findProperty(node.properties, "options", (node) => node.kind === SyntaxKind.ObjectLiteralExpression);
136
- const snapshot = findProperty(node.properties, "snapshot", (node) => node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NoSubstitutionTemplateLiteral);
136
+ const snapshot = findProperty(node.properties, "snapshot", isStaticString);
137
137
  if (!snapshot) return;
138
138
  return {
139
- code: code.text,
139
+ code: getTestCaseCode(code),
140
140
  fileName: fileName?.text,
141
141
  files: files && tsAstToLiteral(files),
142
142
  name: name?.text,
@@ -153,6 +153,13 @@ function parseTestCaseInvalid(node) {
153
153
  snapshot: snapshot.text
154
154
  };
155
155
  }
156
+ function getTestCaseCode(node) {
157
+ if (isStringRawNoSubstitution(node)) return node.template.rawText ?? node.template.text;
158
+ return node.text;
159
+ }
160
+ function isTestCaseCode(node) {
161
+ return isStaticString(node) || isStringRawNoSubstitution(node);
162
+ }
156
163
  //#endregion
157
164
  //#region src/utils/getRuleTesterDescribedCases.ts
158
165
  function getRuleTesterDescribedCases(node) {
@@ -190,18 +197,19 @@ var invalidCodeLines_default = ruleCreator.createRule(typescriptLanguage, {
190
197
  range: getTSNodeRange(node, sourceFile),
191
198
  text: `\`\n${code}\n\``
192
199
  }];
200
+ const template = node.kind === ts.SyntaxKind.TaggedTemplateExpression ? node.template : node;
193
201
  const changes = [];
194
202
  if (!code.startsWith("\n")) changes.push({
195
203
  range: {
196
- begin: node.getStart(sourceFile) + 1,
197
- end: node.getStart(sourceFile) + 1
204
+ begin: template.getStart(sourceFile) + 1,
205
+ end: template.getStart(sourceFile) + 1
198
206
  },
199
207
  text: "\n"
200
208
  });
201
209
  if (!code.endsWith("\n")) changes.push({
202
210
  range: {
203
- begin: node.getEnd() - 1,
204
- end: node.getEnd() - 1
211
+ begin: template.getEnd() - 1,
212
+ end: template.getEnd() - 1
205
213
  },
206
214
  text: "\n"
207
215
  });
@@ -593,10 +601,10 @@ function getCodeProperty(node) {
593
601
  return property.kind === SyntaxKind.ShorthandPropertyAssignment && property.name.text === "code";
594
602
  });
595
603
  }
596
- function isStaticString(node) {
604
+ function isStaticString$1(node) {
597
605
  return node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NoSubstitutionTemplateLiteral;
598
606
  }
599
- function isStringRawNoSubstitution(node) {
607
+ function isStringRawNoSubstitution$1(node) {
600
608
  if (node.kind !== SyntaxKind.TaggedTemplateExpression) return false;
601
609
  const tag = node.tag;
602
610
  return tag.kind === SyntaxKind.PropertyAccessExpression && tag.expression.kind === SyntaxKind.Identifier && tag.expression.text === "String" && tag.name.kind === SyntaxKind.Identifier && tag.name.text === "raw" && node.template.kind === SyntaxKind.NoSubstitutionTemplateLiteral;
@@ -614,7 +622,7 @@ var testCaseNonStaticCode_default = ruleCreator.createRule(typescriptLanguage, {
614
622
  } },
615
623
  setup(context) {
616
624
  function checkTestCase(testCase, sourceFile) {
617
- if (testCase.kind === SyntaxKind.OmittedExpression || isStaticString(testCase) || isStringRawNoSubstitution(testCase)) return;
625
+ if (testCase.kind === SyntaxKind.OmittedExpression || isStaticString$1(testCase) || isStringRawNoSubstitution$1(testCase)) return;
618
626
  if (testCase.kind !== SyntaxKind.ObjectLiteralExpression) {
619
627
  const range = getTSNodeRange(testCase, sourceFile);
620
628
  context.report({
@@ -635,7 +643,7 @@ var testCaseNonStaticCode_default = ruleCreator.createRule(typescriptLanguage, {
635
643
  return;
636
644
  }
637
645
  if (codeProperty.kind === SyntaxKind.PropertyAssignment) {
638
- if (isStaticString(codeProperty.initializer) || isStringRawNoSubstitution(codeProperty.initializer)) return;
646
+ if (isStaticString$1(codeProperty.initializer) || isStringRawNoSubstitution$1(codeProperty.initializer)) return;
639
647
  const range = getTSNodeRange(codeProperty.initializer, sourceFile);
640
648
  context.report({
641
649
  message: "nonStaticTestCaseCode",
package/lib/plugin.d.ts CHANGED
@@ -1,93 +1,93 @@
1
- export declare const flint: import("@flint.fyi/core").Plugin<import("@flint.fyi/core").RuleAbout, string | undefined, [import("@flint.fyi/core").Rule<{
1
+ export declare const flint: import("@flint.fyi/core").Plugin<import("@flint.fyi/core").RuleAbout<string>, string | undefined, [import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Requires passing `sourceFile` to `getStart()` for better performance.";
3
3
  readonly id: "getStartSourceFile";
4
- readonly presets: ["logical"];
4
+ readonly presets: readonly ["logical"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "missingSourceFile", import("@flint.fyi/core").AnyOptionalSchema>, import("@flint.fyi/core").Rule<{
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "missingSourceFile", undefined>, import("@flint.fyi/core").Rule<{
9
9
  readonly description: "Reports cases for invalid code that isn't formatted across lines.";
10
10
  readonly id: "invalidCodeLines";
11
- readonly presets: ["logical"];
11
+ readonly presets: readonly ["logical"];
12
12
  } & {
13
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
14
- url: string;
15
- }, object, object, "singleLineTest", import("@flint.fyi/core").AnyOptionalSchema>, import("@flint.fyi/core").Rule<{
13
+ readonly pluginId: string;
14
+ readonly url: string;
15
+ }, "singleLineTest", undefined>, import("@flint.fyi/core").Rule<{
16
16
  readonly description: "Reports `context.report()` calls missing data for message placeholders.";
17
17
  readonly id: "missingPlaceholders";
18
- readonly presets: ["logical"];
18
+ readonly presets: readonly ["logical"];
19
19
  } & {
20
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
21
- url: string;
22
- }, object, object, "missingPlaceholders", import("@flint.fyi/core").AnyOptionalSchema>, import("@flint.fyi/core").Rule<{
20
+ readonly pluginId: string;
21
+ readonly url: string;
22
+ }, "missingPlaceholders", undefined>, import("@flint.fyi/core").Rule<{
23
23
  readonly description: "Disallows using the `in` operator to check properties on TypeScript nodes.";
24
24
  readonly id: "nodePropertyInChecks";
25
- readonly presets: ["logical"];
25
+ readonly presets: readonly ["logical"];
26
26
  } & {
27
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
28
- url: string;
29
- }, object, object, "nodePropertyInChecks", import("@flint.fyi/core").AnyOptionalSchema>, import("@flint.fyi/core").Rule<{
27
+ readonly pluginId: string;
28
+ readonly url: string;
29
+ }, "nodePropertyInChecks", undefined>, import("@flint.fyi/core").Rule<{
30
30
  readonly description: "Reports and auto-fixes message placeholders that are not formatted as `{{ placeholder }}`.";
31
31
  readonly id: "placeholderFormats";
32
- readonly presets: ["stylistic", "stylisticStrict"];
32
+ readonly presets: readonly ["stylistic", "stylisticStrict"];
33
33
  } & {
34
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
35
- url: string;
36
- }, object, object, "placeholderFormats", import("@flint.fyi/core").AnyOptionalSchema>, import("@flint.fyi/core").Rule<{
34
+ readonly pluginId: string;
35
+ readonly url: string;
36
+ }, "placeholderFormats", undefined>, import("@flint.fyi/core").Rule<{
37
37
  readonly description: "Reports Flint plugin `rules` arrays that are not sorted alphabetically.";
38
38
  readonly id: "pluginRuleOrdering";
39
- readonly presets: ["stylisticStrict"];
39
+ readonly presets: readonly ["stylisticStrict"];
40
40
  } & {
41
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
42
- url: string;
43
- }, object, object, "pluginRuleOrdering", import("@flint.fyi/core").AnyOptionalSchema>, import("@flint.fyi/core").Rule<{
41
+ readonly pluginId: string;
42
+ readonly url: string;
43
+ }, "pluginRuleOrdering", undefined>, import("@flint.fyi/core").Rule<{
44
44
  readonly description: "Reports plugin rules created directly with language instead of through RuleCreator.";
45
45
  readonly id: "ruleCreationMethods";
46
- readonly presets: ["logical"];
46
+ readonly presets: readonly ["logical"];
47
47
  } & {
48
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
49
- url: string;
50
- }, object, object, "ruleCreationMethods", import("@flint.fyi/core").AnyOptionalSchema>, import("@flint.fyi/core").Rule<{
48
+ readonly pluginId: string;
49
+ readonly url: string;
50
+ }, "ruleCreationMethods", undefined>, import("@flint.fyi/core").Rule<{
51
51
  readonly description: "Reports test cases that are identical to previous test cases.";
52
52
  readonly id: "testCaseDuplicates";
53
- readonly presets: ["logical"];
53
+ readonly presets: readonly ["logical"];
54
54
  } & {
55
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
56
- url: string;
57
- }, object, object, "duplicateTest", import("@flint.fyi/core").AnyOptionalSchema>, import("@flint.fyi/core").Rule<{
55
+ readonly pluginId: string;
56
+ readonly url: string;
57
+ }, "duplicateTest", undefined>, import("@flint.fyi/core").Rule<{
58
58
  readonly description: "Reports test cases that have the same name as a previous test case.";
59
59
  readonly id: "testCaseNameDuplicates";
60
- readonly presets: ["logical"];
60
+ readonly presets: readonly ["logical"];
61
61
  } & {
62
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
63
- url: string;
64
- }, object, object, "duplicateTestName", import("@flint.fyi/core").AnyOptionalSchema>, import("@flint.fyi/core").Rule<{
62
+ readonly pluginId: string;
63
+ readonly url: string;
64
+ }, "duplicateTestName", undefined>, import("@flint.fyi/core").Rule<{
65
65
  readonly description: "Test case code should be a static string literal.";
66
66
  readonly id: "testCaseNonStaticCode";
67
- readonly presets: ["logical"];
67
+ readonly presets: readonly ["logical"];
68
68
  } & {
69
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
70
- url: string;
71
- }, object, object, "nonStaticTestCaseCode", import("@flint.fyi/core").AnyOptionalSchema>, import("@flint.fyi/core").Rule<{
69
+ readonly pluginId: string;
70
+ readonly url: string;
71
+ }, "nonStaticTestCaseCode", undefined>, import("@flint.fyi/core").Rule<{
72
72
  readonly description: "Reports test cases that are marked `only: true`.";
73
73
  readonly id: "testCaseOnlyFlags";
74
- readonly presets: ["logical"];
74
+ readonly presets: readonly ["logical"];
75
75
  } & {
76
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
77
- url: string;
78
- }, object, object, "testCaseOnly", import("@flint.fyi/core").AnyOptionalSchema>, import("@flint.fyi/core").Rule<{
76
+ readonly pluginId: string;
77
+ readonly url: string;
78
+ }, "testCaseOnly", undefined>, import("@flint.fyi/core").Rule<{
79
79
  readonly description: "Test cases with only a code property can use string shorthand syntax instead of object literal syntax.";
80
80
  readonly id: "testShorthands";
81
- readonly presets: ["logical"];
81
+ readonly presets: readonly ["logical"];
82
82
  } & {
83
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
84
- url: string;
85
- }, object, object, "testShorthands", import("@flint.fyi/core").AnyOptionalSchema>, import("@flint.fyi/core").Rule<{
83
+ readonly pluginId: string;
84
+ readonly url: string;
85
+ }, "testShorthands", undefined>, import("@flint.fyi/core").Rule<{
86
86
  readonly description: "Reports message IDs defined in the messages object that are never used in recognized report calls.";
87
87
  readonly id: "unusedMessageIds";
88
- readonly presets: ["logical"];
88
+ readonly presets: readonly ["logical"];
89
89
  } & {
90
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
91
- url: string;
92
- }, object, object, "unusedMessageIds", import("@flint.fyi/core").AnyOptionalSchema>]>;
90
+ readonly pluginId: string;
91
+ readonly url: string;
92
+ }, "unusedMessageIds", undefined>]>;
93
93
  //# sourceMappingURL=plugin.d.ts.map
@@ -1,10 +1,10 @@
1
1
  declare const _default: import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Requires passing `sourceFile` to `getStart()` for better performance.";
3
3
  readonly id: "getStartSourceFile";
4
- readonly presets: ["logical"];
4
+ readonly presets: readonly ["logical"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "missingSourceFile", import("@flint.fyi/core").AnyOptionalSchema>;
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "missingSourceFile", undefined>;
9
9
  export default _default;
10
10
  //# sourceMappingURL=getStartSourceFile.d.ts.map
@@ -1,10 +1,10 @@
1
1
  declare const _default: import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Reports cases for invalid code that isn't formatted across lines.";
3
3
  readonly id: "invalidCodeLines";
4
- readonly presets: ["logical"];
4
+ readonly presets: readonly ["logical"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "singleLineTest", import("@flint.fyi/core").AnyOptionalSchema>;
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "singleLineTest", undefined>;
9
9
  export default _default;
10
10
  //# sourceMappingURL=invalidCodeLines.d.ts.map
@@ -1,10 +1,10 @@
1
1
  declare const _default: import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Reports `context.report()` calls missing data for message placeholders.";
3
3
  readonly id: "missingPlaceholders";
4
- readonly presets: ["logical"];
4
+ readonly presets: readonly ["logical"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "missingPlaceholders", import("@flint.fyi/core").AnyOptionalSchema>;
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "missingPlaceholders", undefined>;
9
9
  export default _default;
10
10
  //# sourceMappingURL=missingPlaceholders.d.ts.map
@@ -1,10 +1,10 @@
1
1
  declare const _default: import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Disallows using the `in` operator to check properties on TypeScript nodes.";
3
3
  readonly id: "nodePropertyInChecks";
4
- readonly presets: ["logical"];
4
+ readonly presets: readonly ["logical"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "nodePropertyInChecks", import("@flint.fyi/core").AnyOptionalSchema>;
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "nodePropertyInChecks", undefined>;
9
9
  export default _default;
10
10
  //# sourceMappingURL=nodePropertyInChecks.d.ts.map
@@ -1,10 +1,10 @@
1
1
  declare const _default: import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Reports and auto-fixes message placeholders that are not formatted as `{{ placeholder }}`.";
3
3
  readonly id: "placeholderFormats";
4
- readonly presets: ["stylistic", "stylisticStrict"];
4
+ readonly presets: readonly ["stylistic", "stylisticStrict"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "placeholderFormats", import("@flint.fyi/core").AnyOptionalSchema>;
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "placeholderFormats", undefined>;
9
9
  export default _default;
10
10
  //# sourceMappingURL=placeholderFormats.d.ts.map
@@ -1,10 +1,10 @@
1
1
  declare const _default: import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Reports Flint plugin `rules` arrays that are not sorted alphabetically.";
3
3
  readonly id: "pluginRuleOrdering";
4
- readonly presets: ["stylisticStrict"];
4
+ readonly presets: readonly ["stylisticStrict"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "pluginRuleOrdering", import("@flint.fyi/core").AnyOptionalSchema>;
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "pluginRuleOrdering", undefined>;
9
9
  export default _default;
10
10
  //# sourceMappingURL=pluginRuleOrdering.d.ts.map
@@ -1,10 +1,10 @@
1
1
  declare const _default: import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Reports plugin rules created directly with language instead of through RuleCreator.";
3
3
  readonly id: "ruleCreationMethods";
4
- readonly presets: ["logical"];
4
+ readonly presets: readonly ["logical"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "ruleCreationMethods", import("@flint.fyi/core").AnyOptionalSchema>;
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "ruleCreationMethods", undefined>;
9
9
  export default _default;
10
10
  //# sourceMappingURL=ruleCreationMethods.d.ts.map
@@ -1,3 +1,3 @@
1
1
  import { RuleCreator } from "@flint.fyi/core";
2
- export declare const ruleCreator: RuleCreator<"logical" | "logicalStrict" | "stylistic" | "stylisticStrict">;
2
+ export declare const ruleCreator: RuleCreator<"logical" | "logicalStrict" | "stylistic" | "stylisticStrict", import("@flint.fyi/core").RuleAbout<"logical" | "logicalStrict" | "stylistic" | "stylisticStrict">>;
3
3
  //# sourceMappingURL=ruleCreator.d.ts.map
@@ -1,10 +1,10 @@
1
1
  declare const _default: import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Reports test cases that are identical to previous test cases.";
3
3
  readonly id: "testCaseDuplicates";
4
- readonly presets: ["logical"];
4
+ readonly presets: readonly ["logical"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "duplicateTest", import("@flint.fyi/core").AnyOptionalSchema>;
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "duplicateTest", undefined>;
9
9
  export default _default;
10
10
  //# sourceMappingURL=testCaseDuplicates.d.ts.map
@@ -1,10 +1,10 @@
1
1
  declare const _default: import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Reports test cases that have the same name as a previous test case.";
3
3
  readonly id: "testCaseNameDuplicates";
4
- readonly presets: ["logical"];
4
+ readonly presets: readonly ["logical"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "duplicateTestName", import("@flint.fyi/core").AnyOptionalSchema>;
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "duplicateTestName", undefined>;
9
9
  export default _default;
10
10
  //# sourceMappingURL=testCaseNameDuplicates.d.ts.map
@@ -1,10 +1,10 @@
1
1
  declare const _default: import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Test case code should be a static string literal.";
3
3
  readonly id: "testCaseNonStaticCode";
4
- readonly presets: ["logical"];
4
+ readonly presets: readonly ["logical"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "nonStaticTestCaseCode", import("@flint.fyi/core").AnyOptionalSchema>;
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "nonStaticTestCaseCode", undefined>;
9
9
  export default _default;
10
10
  //# sourceMappingURL=testCaseNonStaticCode.d.ts.map
@@ -1,10 +1,10 @@
1
1
  declare const _default: import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Reports test cases that are marked `only: true`.";
3
3
  readonly id: "testCaseOnlyFlags";
4
- readonly presets: ["logical"];
4
+ readonly presets: readonly ["logical"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "testCaseOnly", import("@flint.fyi/core").AnyOptionalSchema>;
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "testCaseOnly", undefined>;
9
9
  export default _default;
10
10
  //# sourceMappingURL=testCaseOnlyFlags.d.ts.map
@@ -1,10 +1,10 @@
1
1
  declare const _default: import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Test cases with only a code property can use string shorthand syntax instead of object literal syntax.";
3
3
  readonly id: "testShorthands";
4
- readonly presets: ["logical"];
4
+ readonly presets: readonly ["logical"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "testShorthands", import("@flint.fyi/core").AnyOptionalSchema>;
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "testShorthands", undefined>;
9
9
  export default _default;
10
10
  //# sourceMappingURL=testShorthands.d.ts.map
@@ -1,10 +1,10 @@
1
1
  declare const _default: import("@flint.fyi/core").Rule<{
2
2
  readonly description: "Reports message IDs defined in the messages object that are never used in recognized report calls.";
3
3
  readonly id: "unusedMessageIds";
4
- readonly presets: ["logical"];
4
+ readonly presets: readonly ["logical"];
5
5
  } & {
6
- presets?: ("logical" | "logicalStrict" | "stylistic" | "stylisticStrict")[];
7
- url: string;
8
- }, object, object, "unusedMessageIds", import("@flint.fyi/core").AnyOptionalSchema>;
6
+ readonly pluginId: string;
7
+ readonly url: string;
8
+ }, "unusedMessageIds", undefined>;
9
9
  export default _default;
10
10
  //# sourceMappingURL=unusedMessageIds.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { AST } from "@flint.fyi/typescript-language";
2
1
  import type ts from "typescript";
2
+ import type { AST } from "@flint.fyi/typescript-language";
3
3
  export declare function findProperty<Node extends AST.Expression>(properties: ts.NodeArray<AST.ObjectLiteralElementLike>, name: string, predicate: (node: AST.Expression) => node is Node): (AST.Expression & Node) | undefined;
4
4
  //# sourceMappingURL=findProperty.d.ts.map
@@ -1,6 +1,40 @@
1
1
  import type { AST } from "@flint.fyi/typescript-language";
2
2
  export declare function getRuleTesterDescribedCases(node: AST.CallExpression): {
3
3
  invalid: import("./types.ts").ParsedTestCaseInvalid[];
4
- valid: import("./types.ts").ParsedTestCase[];
4
+ valid: ({
5
+ code: string;
6
+ nodes: {
7
+ case: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral | (AST.TaggedTemplateExpression & {
8
+ template: AST.NoSubstitutionTemplateLiteral;
9
+ });
10
+ code: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral | (AST.TaggedTemplateExpression & {
11
+ template: AST.NoSubstitutionTemplateLiteral;
12
+ });
13
+ fileName?: never;
14
+ files?: never;
15
+ name?: never;
16
+ options?: never;
17
+ };
18
+ fileName?: never;
19
+ files?: never;
20
+ name?: never;
21
+ options?: never;
22
+ } | {
23
+ code: string;
24
+ fileName: string | undefined;
25
+ files: Record<string, string> | undefined;
26
+ name: string | undefined;
27
+ nodes: {
28
+ case: AST.ObjectLiteralExpression;
29
+ code: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral | (AST.TaggedTemplateExpression & {
30
+ template: AST.NoSubstitutionTemplateLiteral;
31
+ });
32
+ fileName: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral | undefined;
33
+ files: AST.ObjectLiteralExpression | undefined;
34
+ name: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral | undefined;
35
+ options: AST.ObjectLiteralExpression | undefined;
36
+ };
37
+ options: object | undefined;
38
+ })[];
5
39
  } | undefined;
6
40
  //# sourceMappingURL=getRuleTesterDescribedCases.d.ts.map
@@ -1,5 +1,5 @@
1
- import type { AST } from "@flint.fyi/typescript-language";
2
1
  import { type Node } from "typescript";
2
+ import type { AST } from "@flint.fyi/typescript-language";
3
3
  export declare function isImportedBindingFromModule(declaration: Node, moduleName: string): declaration is AST.ImportSpecifier | AST.NamespaceImport;
4
4
  export declare function isImportedSpecifierFromModule(declaration: Node, moduleName: string, importedName: string): declaration is AST.ImportSpecifier;
5
5
  //# sourceMappingURL=importHelpers.d.ts.map
@@ -1,5 +1,39 @@
1
- import type { AST } from "@flint.fyi/typescript-language";
2
- import type { ParsedTestCase, ParsedTestCaseInvalid } from "./types.ts";
3
- export declare function parseTestCase(node: AST.Expression): ParsedTestCase | undefined;
1
+ import { type AST } from "@flint.fyi/typescript-language";
2
+ import type { ParsedTestCaseInvalid } from "./types.ts";
3
+ export declare function parseTestCase(node: AST.Expression): {
4
+ code: string;
5
+ nodes: {
6
+ case: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral | (AST.TaggedTemplateExpression & {
7
+ template: AST.NoSubstitutionTemplateLiteral;
8
+ });
9
+ code: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral | (AST.TaggedTemplateExpression & {
10
+ template: AST.NoSubstitutionTemplateLiteral;
11
+ });
12
+ fileName?: never;
13
+ files?: never;
14
+ name?: never;
15
+ options?: never;
16
+ };
17
+ fileName?: never;
18
+ files?: never;
19
+ name?: never;
20
+ options?: never;
21
+ } | {
22
+ code: string;
23
+ fileName: string | undefined;
24
+ files: Record<string, string> | undefined;
25
+ name: string | undefined;
26
+ nodes: {
27
+ case: AST.ObjectLiteralExpression;
28
+ code: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral | (AST.TaggedTemplateExpression & {
29
+ template: AST.NoSubstitutionTemplateLiteral;
30
+ });
31
+ fileName: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral | undefined;
32
+ files: AST.ObjectLiteralExpression | undefined;
33
+ name: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral | undefined;
34
+ options: AST.ObjectLiteralExpression | undefined;
35
+ };
36
+ options: object | undefined;
37
+ } | undefined;
4
38
  export declare function parseTestCaseInvalid(node: AST.Expression): ParsedTestCaseInvalid | undefined;
5
39
  //# sourceMappingURL=parseTestCases.d.ts.map
@@ -1,5 +1,5 @@
1
- import type { AST } from "@flint.fyi/typescript-language";
2
1
  import ts from "typescript";
2
+ import type { AST } from "@flint.fyi/typescript-language";
3
3
  export declare function tsAstToLiteral(node: AST.ArrayLiteralExpression): unknown[];
4
4
  export declare function tsAstToLiteral(node: AST.ObjectLiteralExpression): object;
5
5
  export declare function tsAstToLiteral(node: ts.Node): unknown;
@@ -1,21 +1,25 @@
1
+ import type * as ts from "typescript";
1
2
  import type { InvalidTestCase, TestCase } from "@flint.fyi/rule-tester";
2
3
  import type { AST } from "@flint.fyi/typescript-language";
3
- import type * as ts from "typescript";
4
4
  export interface ParsedTestCase extends TestCase {
5
5
  nodes: ParsedTestCaseNodes;
6
6
  }
7
+ export type ParsedTestCaseCodeNode = AST.NoSubstitutionTemplateLiteral | AST.StringLiteral | (AST.TaggedTemplateExpression & {
8
+ template: AST.NoSubstitutionTemplateLiteral;
9
+ });
7
10
  export interface ParsedTestCaseInvalid extends InvalidTestCase {
8
11
  nodes: ParsedTestCaseNodesInvalid;
9
12
  }
10
13
  export interface ParsedTestCaseNodes {
11
14
  case: ts.Node;
12
- code: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral;
13
- fileName?: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral | undefined;
15
+ code: ParsedTestCaseCodeNode;
16
+ fileName?: ParsedTestCaseStaticStringNode | undefined;
14
17
  files?: AST.ObjectLiteralExpression | undefined;
15
- name?: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral | undefined;
18
+ name?: ParsedTestCaseStaticStringNode | undefined;
16
19
  options?: AST.ObjectLiteralExpression | undefined;
17
20
  }
18
21
  export interface ParsedTestCaseNodesInvalid extends ParsedTestCaseNodes {
19
- snapshot: AST.NoSubstitutionTemplateLiteral | AST.StringLiteral;
22
+ snapshot: ParsedTestCaseStaticStringNode;
20
23
  }
24
+ export type ParsedTestCaseStaticStringNode = AST.NoSubstitutionTemplateLiteral | AST.StringLiteral;
21
25
  //# sourceMappingURL=types.d.ts.map
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@flint.fyi/plugin-flint",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "[Experimental] A Flint plugin for linting Flint plugins.",
5
- "homepage": "https://www.flint.fyi/rules/flint",
5
+ "homepage": "https://flint.fyi/rules/flint",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/flint-fyi/flint.git",
@@ -10,8 +10,8 @@
10
10
  },
11
11
  "license": "MIT",
12
12
  "author": {
13
- "name": "JoshuaKGoldberg",
14
- "email": "npm@joshuakgoldberg.com"
13
+ "name": "Flint Team",
14
+ "url": "https://flint.fyi/team"
15
15
  },
16
16
  "sideEffects": false,
17
17
  "type": "module",
@@ -24,14 +24,14 @@
24
24
  ],
25
25
  "dependencies": {
26
26
  "typescript": "^5.9.3 || ^6.0.0",
27
- "@flint.fyi/typescript-language": "^0.18.0",
28
- "@flint.fyi/core": "^0.21.0",
29
- "@flint.fyi/utils": "^0.14.1"
27
+ "@flint.fyi/typescript-language": "^0.18.3",
28
+ "@flint.fyi/utils": "^0.14.1",
29
+ "@flint.fyi/core": "^0.23.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "tsdown": "0.21.0",
33
33
  "vitest": "4.1.0",
34
- "@flint.fyi/rule-tester": "^0.16.1"
34
+ "@flint.fyi/rule-tester": "^0.16.4"
35
35
  },
36
36
  "engines": {
37
37
  "node": ">=24.0.0"