@ttsc/lint 0.11.0 → 0.12.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 (57) hide show
  1. package/README.md +66 -140
  2. package/lib/{structures/defaultFormat.d.ts → defaultFormat.d.ts} +3 -3
  3. package/lib/{structures/defaultFormat.js → defaultFormat.js} +3 -3
  4. package/lib/defaultFormat.js.map +1 -0
  5. package/lib/index.d.ts +1 -38
  6. package/lib/index.js +7 -5
  7. package/lib/index.js.map +1 -1
  8. package/lib/structures/ITtscLintConfig.d.ts +27 -0
  9. package/lib/structures/{PluginRuleNames.js → ITtscLintConfig.js} +1 -1
  10. package/lib/structures/ITtscLintConfig.js.map +1 -0
  11. package/lib/structures/{TtscLintFormatConfig.d.ts → ITtscLintFormatConfig.d.ts} +17 -16
  12. package/lib/structures/{TtscLintConfig.js → ITtscLintFormatConfig.js} +1 -1
  13. package/lib/structures/ITtscLintFormatConfig.js.map +1 -0
  14. package/lib/structures/ITtscLintPluginConfig.d.ts +6 -6
  15. package/lib/structures/TtscLintRuleMap.d.ts +11 -9
  16. package/lib/structures/TtscLintRuleOptions.d.ts +118 -144
  17. package/lib/structures/index.d.ts +2 -7
  18. package/lib/structures/index.js +2 -7
  19. package/lib/structures/index.js.map +1 -1
  20. package/linthost/config.go +1 -6
  21. package/linthost/config_format.go +253 -298
  22. package/linthost/format.go +91 -1
  23. package/package.json +2 -2
  24. package/rule/rule.go +124 -124
  25. package/src/{structures/defaultFormat.ts → defaultFormat.ts} +5 -5
  26. package/src/index.ts +7 -5
  27. package/src/structures/ITtscLintConfig.ts +33 -0
  28. package/src/structures/{TtscLintFormatConfig.ts → ITtscLintFormatConfig.ts} +17 -16
  29. package/src/structures/ITtscLintPluginConfig.ts +6 -6
  30. package/src/structures/TtscLintRuleMap.ts +17 -13
  31. package/src/structures/TtscLintRuleOptions.ts +118 -144
  32. package/src/structures/index.ts +2 -7
  33. package/lib/defineConfig.d.ts +0 -55
  34. package/lib/defineConfig.js +0 -39
  35. package/lib/defineConfig.js.map +0 -1
  36. package/lib/structures/PluginRuleNames.d.ts +0 -14
  37. package/lib/structures/PluginRuleNames.js.map +0 -1
  38. package/lib/structures/TtscLintConfig.d.ts +0 -27
  39. package/lib/structures/TtscLintConfig.js.map +0 -1
  40. package/lib/structures/TtscLintConfigEntry.d.ts +0 -39
  41. package/lib/structures/TtscLintConfigEntry.js +0 -3
  42. package/lib/structures/TtscLintConfigEntry.js.map +0 -1
  43. package/lib/structures/TtscLintFormatConfig.js +0 -3
  44. package/lib/structures/TtscLintFormatConfig.js.map +0 -1
  45. package/lib/structures/TtscLintPlugins.d.ts +0 -9
  46. package/lib/structures/TtscLintPlugins.js +0 -3
  47. package/lib/structures/TtscLintPlugins.js.map +0 -1
  48. package/lib/structures/TtscLintRuleEntry.d.ts +0 -22
  49. package/lib/structures/TtscLintRuleEntry.js +0 -3
  50. package/lib/structures/TtscLintRuleEntry.js.map +0 -1
  51. package/lib/structures/defaultFormat.js.map +0 -1
  52. package/src/defineConfig.ts +0 -69
  53. package/src/structures/PluginRuleNames.ts +0 -19
  54. package/src/structures/TtscLintConfig.ts +0 -31
  55. package/src/structures/TtscLintConfigEntry.ts +0 -50
  56. package/src/structures/TtscLintPlugins.ts +0 -10
  57. package/src/structures/TtscLintRuleEntry.ts +0 -28
@@ -9,21 +9,24 @@ import type { TtscLintSeverity } from "./TtscLintSeverity";
9
9
  * verbatim. The block is opt-in by presence: a `lint.config.ts` with no
10
10
  * `format` field keeps every format rule off, exactly as before.
11
11
  *
12
- * Once present, the block enables a curated set of format rules at
13
- * Prettier-aligned defaults. Individual rules can be overridden or
14
- * disabled through the `rules` map (the `rules` entry wins on conflict).
12
+ * Once present, the block configures a curated set of format rules at
13
+ * Prettier-aligned defaults. `ttsc format` uses these rules to rewrite source.
14
+ * `ttsc check` does not report format findings unless `severity` is set to a
15
+ * non-off value. Individual rules can be overridden or disabled through the
16
+ * `rules` map (the `rules` entry wins on conflict).
15
17
  *
16
18
  * @example
17
- * import type { TtscLintConfig } from "@ttsc/lint";
19
+ * import type { ITtscLintConfig } from "@ttsc/lint";
18
20
  *
19
21
  * export default {
20
22
  * rules: { "no-var": "error" },
21
23
  * format: {
24
+ * severity: "warning",
22
25
  * printWidth: 100,
23
26
  * singleQuote: true,
24
27
  * importOrder: ["<THIRD_PARTY_MODULES>", "^[./]"],
25
28
  * },
26
- * } satisfies TtscLintConfig;
29
+ * } satisfies ITtscLintConfig;
27
30
  *
28
31
  * Deviations from Prettier:
29
32
  * - `endOfLine` is restricted to `"lf"` and `"crlf"`. Prettier's
@@ -31,7 +34,6 @@ import type { TtscLintSeverity } from "./TtscLintSeverity";
31
34
  * printer does not auto-detect terminators.
32
35
  * - Many Prettier knobs (`bracketSpacing`, `arrowParens`,
33
36
  * `quoteProps`, JSX-specific switches) are not yet implemented.
34
- * See `docs/14-prettier-migration.md` for the full gap list.
35
37
  *
36
38
  * Rule enablement matrix (when the `format` block is present):
37
39
  *
@@ -46,19 +48,18 @@ import type { TtscLintSeverity } from "./TtscLintSeverity";
46
48
  * - `format/sort-imports` — opt-in. Setting `importOrder` enables it.
47
49
  * - `format/jsdoc` — opt-in. Setting `jsdoc` enables it.
48
50
  *
49
- * For per-rule severity overrides, drop a `rules` entry alongside:
50
- *
51
- * format: { semi: true, severity: "warning" },
52
- * rules: { "format/semi": "error" },
51
+ * Format findings produced from this block are off by default. Set `severity`
52
+ * only when a project intentionally wants check-time format diagnostics.
53
53
  */
54
- export interface TtscLintFormatConfig {
54
+ export interface ITtscLintFormatConfig {
55
55
  /**
56
- * Severity for every format diagnostic emitted by `ttsc check`. The
57
- * same vocabulary as the `rules` map (`"off" | "warn" | "warning" |
58
- * "error"` plus numeric 0/1/2). `"off"` disables both the diagnostic
59
- * and the `ttsc format` / `ttsc fix` rewrite for every format rule.
56
+ * Check-time severity for format findings generated from this block.
57
+ *
58
+ * The default is `"off"` so formatting policy does not affect compilation
59
+ * unless the project opts into that behavior. `ttsc format` can still use the
60
+ * rest of this block to rewrite files.
60
61
  *
61
- * @default "warning"
62
+ * @default "off"
62
63
  */
63
64
  severity?: TtscLintSeverity;
64
65
 
@@ -1,4 +1,4 @@
1
- import type { TtscLintFormatConfig } from "./TtscLintFormatConfig";
1
+ import type { ITtscLintFormatConfig } from "./ITtscLintFormatConfig";
2
2
  import type { TtscLintRuleMap } from "./TtscLintRuleMap";
3
3
 
4
4
  /** `compilerOptions.plugins[]` entry shape consumed by `@ttsc/lint`. */
@@ -67,7 +67,7 @@ export interface ITtscLintPluginConfig {
67
67
 
68
68
  /**
69
69
  * Prettier-style flat configuration for the `format/*` rules. Sibling of
70
- * `rules`. See {@link TtscLintFormatConfig} for the full surface.
70
+ * `rules`. See {@link ITtscLintFormatConfig} for the full surface.
71
71
  *
72
72
  * ```jsonc
73
73
  * {
@@ -80,7 +80,7 @@ export interface ITtscLintPluginConfig {
80
80
  * combined with `extends` on the same plugin entry — put format options
81
81
  * inside the extends-target lint.config.ts instead.
82
82
  */
83
- format?: TtscLintFormatConfig;
83
+ format?: ITtscLintFormatConfig;
84
84
 
85
85
  /**
86
86
  * Inline rule map or path to a standalone lint config file.
@@ -92,9 +92,9 @@ export interface ITtscLintPluginConfig {
92
92
  *
93
93
  * The legacy shape is intentionally narrower than `rules`/`extends`: a string
94
94
  * (file path) or a flat rule-name → severity map. The Go-side parser only
95
- * accepts those two shapes; widening the TS type to the new
96
- * `TtscLintConfig` union would silently let `config: [{ rules: {...} }]`
97
- * pass type-checking and fail at runtime.
95
+ * accepts those two shapes; widening the TS type to the full config object
96
+ * would silently let unsupported nested shapes pass type-checking and fail
97
+ * at runtime.
98
98
  */
99
99
  config?: string | TtscLintRuleMap;
100
100
 
@@ -1,7 +1,5 @@
1
- import type { PluginRuleNames } from "./PluginRuleNames";
2
- import type { TtscLintPlugins } from "./TtscLintPlugins";
3
1
  import type { TtscLintRule } from "./TtscLintRule";
4
- import type { TtscLintRuleOptionsMap } from "./TtscLintRuleOptions";
2
+ import type { ITtscLintRuleOptionsMap } from "./TtscLintRuleOptions";
5
3
  import type { TtscLintSeverity } from "./TtscLintSeverity";
6
4
 
7
5
  /**
@@ -9,10 +7,12 @@ import type { TtscLintSeverity } from "./TtscLintSeverity";
9
7
  *
10
8
  * Built from two independent mapped types intersected together:
11
9
  *
12
- * - Rules listed in `TtscLintRuleOptionsMap` accept `severity`, `[severity]`, or
10
+ * - Rules listed in `ITtscLintRuleOptionsMap` accept `severity`, `[severity]`, or
13
11
  * `[severity, options]`, with the options type picked per rule key.
14
- * - Every other built-in rule plus any contributor plugin rule accepts `severity`
15
- * or `[severity]`.
12
+ * - Every other built-in rule accepts `severity` or `[severity]`.
13
+ * - Namespaced contributor plugin rules accept `severity`, `[severity]`, or
14
+ * `[severity, unknownOptions]` because the host type surface no longer
15
+ * knows contributor rule schemas.
16
16
  *
17
17
  * Splitting the two halves (instead of folding them into one mapped type with a
18
18
  * conditional value) keeps TypeScript's contextual typing intact inside the
@@ -38,15 +38,19 @@ import type { TtscLintSeverity } from "./TtscLintSeverity";
38
38
  * splits each negative case into its own const to keep every branch
39
39
  * load-bearing.
40
40
  */
41
- export type TtscLintRuleMap<P extends TtscLintPlugins = Record<string, never>> =
41
+ export type TtscLintRuleMap =
42
42
  {
43
- [K in keyof TtscLintRuleOptionsMap]?:
43
+ [K in keyof ITtscLintRuleOptionsMap]?:
44
44
  | TtscLintSeverity
45
45
  | readonly [TtscLintSeverity]
46
- | readonly [TtscLintSeverity, TtscLintRuleOptionsMap[K]];
46
+ | readonly [TtscLintSeverity, ITtscLintRuleOptionsMap[K]];
47
47
  } & {
48
- [K in Exclude<
49
- TtscLintRule | PluginRuleNames<P>,
50
- keyof TtscLintRuleOptionsMap
51
- >]?: TtscLintSeverity | readonly [TtscLintSeverity];
48
+ [K in Exclude<TtscLintRule, keyof ITtscLintRuleOptionsMap>]?:
49
+ | TtscLintSeverity
50
+ | readonly [TtscLintSeverity];
51
+ } & {
52
+ [K in `${string}/${string}`]?:
53
+ | TtscLintSeverity
54
+ | readonly [TtscLintSeverity]
55
+ | readonly [TtscLintSeverity, unknown];
52
56
  };
@@ -1,162 +1,136 @@
1
- /**
2
- * Per-rule option shapes used by `TtscLintRuleEntry` to type the second tuple
3
- * slot.
4
- *
5
- * Each entry here maps a rule name to its option struct. Rule names that do not
6
- * appear in this interface accept severity-only configuration (a `[severity]`
7
- * tuple is _also_ allowed for them, with an empty options blob).
8
- *
9
- * The shapes are designed to match the analogous prettier / ESLint options
10
- * where the rule absorbs an existing tool's behavior:
11
- *
12
- * - `format/semi` mirrors prettier `semi`.
13
- * - `format/quotes` mirrors prettier `singleQuote` (inverted).
14
- * - `format/trailing-comma` mirrors prettier `trailingComma`.
15
- * - `format/sort-imports` mirrors `@trivago/prettier-plugin-sort-imports`
16
- * (`importOrder`, `importOrderSeparation`, `importOrderSortSpecifiers`,
17
- * `importOrderCaseInsensitive`).
18
- * - `format/jsdoc` mirrors `prettier-plugin-jsdoc` (`tagSynonyms` layered onto
19
- * the built-in synonym table, `sortTags` reserved for a future pass).
20
- *
21
- * Future option additions go here so the TypeScript autocomplete updates in one
22
- * place. The Go side reads these as `json.RawMessage` and each rule decodes
23
- * into its own struct.
24
- */
25
- export namespace TtscLintRuleOptions {
26
- /** `format/semi` options. */
27
- export interface Semi {
28
- /**
29
- * Whether trailing semicolons must be present on ASI statements.
30
- *
31
- * @default "always"
32
- */
33
- prefer?: "always" | "never";
34
- }
1
+ /** `format/semi` rule options. */
2
+ export interface ITtscLintSemiRuleOptions {
3
+ /**
4
+ * Whether trailing semicolons must be present on ASI statements.
5
+ *
6
+ * @default "always"
7
+ */
8
+ prefer?: "always" | "never";
9
+ }
35
10
 
36
- /** `format/quotes` options. */
37
- export interface Quotes {
38
- /**
39
- * Quote style for string literals. Template literals are always preserved
40
- * regardless of this setting.
41
- *
42
- * @default "double"
43
- */
44
- prefer?: "double" | "single";
45
- }
11
+ /** `format/quotes` rule options. */
12
+ export interface ITtscLintQuotesRuleOptions {
13
+ /**
14
+ * Quote style for string literals. Template literals are always preserved
15
+ * regardless of this setting.
16
+ *
17
+ * @default "double"
18
+ */
19
+ prefer?: "double" | "single";
20
+ }
46
21
 
47
- /** `format/trailing-comma` options. */
48
- export interface TrailingComma {
49
- /**
50
- * Which multi-line lists receive a trailing comma. `"all"` matches
51
- * prettier's modern default; `"es5"` skips function calls and type
52
- * parameter lists; `"none"` disables the rule entirely.
53
- *
54
- * @default "all"
55
- */
56
- mode?: "all" | "es5" | "none";
57
- }
22
+ /** `format/trailing-comma` rule options. */
23
+ export interface ITtscLintTrailingCommaRuleOptions {
24
+ /**
25
+ * Which multi-line lists receive a trailing comma. `"all"` matches prettier's
26
+ * modern default; `"es5"` skips function calls and type parameter lists;
27
+ * `"none"` disables the rule entirely.
28
+ *
29
+ * @default "all"
30
+ */
31
+ mode?: "all" | "es5" | "none";
32
+ }
58
33
 
59
- /** `format/sort-imports` options. */
60
- export interface SortImports {
61
- /**
62
- * Ordered list of regex strings (or the `<THIRD_PARTY_MODULES>`
63
- * placeholder) defining the group order. Imports matching the first pattern
64
- * land in group 0, the second in group 1, and so on. The placeholder
65
- * absorbs any specifier that does not match another pattern. Mirrors
66
- * trivago's `importOrder` semantics.
67
- */
68
- importOrder?: readonly string[];
34
+ /** `format/sort-imports` rule options. */
35
+ export interface ITtscLintSortImportsRuleOptions {
36
+ /**
37
+ * Ordered list of regex strings (or the `<THIRD_PARTY_MODULES>` placeholder)
38
+ * defining the group order. Imports matching the first pattern land in group
39
+ * 0, the second in group 1, and so on. The placeholder absorbs any specifier
40
+ * that does not match another pattern. Mirrors trivago's `importOrder`
41
+ * semantics.
42
+ */
43
+ importOrder?: readonly string[];
69
44
 
70
- /**
71
- * Insert a blank line between groups.
72
- *
73
- * @default true
74
- */
75
- importOrderSeparation?: boolean;
45
+ /**
46
+ * Insert a blank line between groups.
47
+ *
48
+ * @default true
49
+ */
50
+ importOrderSeparation?: boolean;
76
51
 
77
- /**
78
- * Sort named import specifiers alphabetically within each declaration.
79
- *
80
- * @default true
81
- */
82
- importOrderSortSpecifiers?: boolean;
52
+ /**
53
+ * Sort named import specifiers alphabetically within each declaration.
54
+ *
55
+ * @default true
56
+ */
57
+ importOrderSortSpecifiers?: boolean;
83
58
 
84
- /**
85
- * Treat `A` and `a` as equivalent when comparing module specifiers and
86
- * specifier names. Mirrors trivago's `importOrderCaseInsensitive`.
87
- *
88
- * @default false
89
- */
90
- importOrderCaseInsensitive?: boolean;
91
- }
59
+ /**
60
+ * Treat `A` and `a` as equivalent when comparing module specifiers and
61
+ * specifier names. Mirrors trivago's `importOrderCaseInsensitive`.
62
+ *
63
+ * @default false
64
+ */
65
+ importOrderCaseInsensitive?: boolean;
66
+ }
92
67
 
93
- /** `format/print-width` options. */
94
- export interface PrintWidth {
95
- /**
96
- * Maximum column width before broken-form layout is chosen. Mirrors
97
- * prettier's `printWidth`.
98
- *
99
- * @default 80
100
- */
101
- printWidth?: number;
68
+ /** `format/print-width` rule options. */
69
+ export interface ITtscLintPrintWidthRuleOptions {
70
+ /**
71
+ * Maximum column width before broken-form layout is chosen. Mirrors
72
+ * prettier's `printWidth`.
73
+ *
74
+ * @default 80
75
+ */
76
+ printWidth?: number;
102
77
 
103
- /**
104
- * Indentation increment in columns. Mirrors prettier's `tabWidth`.
105
- *
106
- * @default 2
107
- */
108
- tabWidth?: number;
78
+ /**
79
+ * Indentation increment in columns. Mirrors prettier's `tabWidth`.
80
+ *
81
+ * @default 2
82
+ */
83
+ tabWidth?: number;
109
84
 
110
- /**
111
- * Emit indentation as tab characters rather than spaces. Mirrors
112
- * prettier's `useTabs`. Continuation alignment beyond the tab
113
- * boundary still falls back to spaces, matching dprint's
114
- * "indent with tabs, align with spaces" convention.
115
- *
116
- * @default false
117
- */
118
- useTabs?: boolean;
85
+ /**
86
+ * Emit indentation as tab characters rather than spaces. Mirrors prettier's
87
+ * `useTabs`. Continuation alignment beyond the tab boundary still falls back
88
+ * to spaces, matching dprint's "indent with tabs, align with spaces"
89
+ * convention.
90
+ *
91
+ * @default false
92
+ */
93
+ useTabs?: boolean;
119
94
 
120
- /**
121
- * Line-terminator emitted on every newline the printer inserts.
122
- * Mirrors prettier's `endOfLine` `"lf"` and `"crlf"` modes.
123
- *
124
- * @default "lf"
125
- */
126
- endOfLine?: "lf" | "crlf";
127
- }
95
+ /**
96
+ * Line-terminator emitted on every newline the printer inserts. Mirrors
97
+ * prettier's `endOfLine` `"lf"` and `"crlf"` modes.
98
+ *
99
+ * @default "lf"
100
+ */
101
+ endOfLine?: "lf" | "crlf";
102
+ }
128
103
 
129
- /** `format/jsdoc` options. */
130
- export interface JSDoc {
131
- /**
132
- * Extra `from to` tag rewrites layered on top of the built-in synonym
133
- * table (`@return @returns`, `@arg @param`, etc.). User-supplied
134
- * entries win on key collision, so a `{"return": "RETURN"}` entry overrides
135
- * the built-in default for `@return`.
136
- *
137
- * @default {} (use built-in table unchanged)
138
- */
139
- tagSynonyms?: Record<string, string>;
104
+ /** `format/jsdoc` rule options. */
105
+ export interface ITtscLintJsdocRuleOptions {
106
+ /**
107
+ * Extra `from -> to` tag rewrites layered on top of the built-in synonym
108
+ * table (`@return -> @returns`, `@arg -> @param`, etc.). User-supplied
109
+ * entries win on key collision, so a `{"return": "RETURN"}` entry overrides
110
+ * the built-in default for `@return`.
111
+ *
112
+ * @default {} (use built-in table unchanged)
113
+ */
114
+ tagSynonyms?: Record<string, string>;
140
115
 
141
- /**
142
- * Sort JSDoc tag blocks into the canonical order (`@description`, `@param`,
143
- * `@returns`, ).
144
- *
145
- * @default false (deferred; MVP only normalizes tag names)
146
- */
147
- sortTags?: boolean;
148
- }
116
+ /**
117
+ * Sort JSDoc tag blocks into the canonical order (`@description`, `@param`,
118
+ * `@returns`, ...).
119
+ *
120
+ * @default false (deferred; MVP only normalizes tag names)
121
+ */
122
+ sortTags?: boolean;
149
123
  }
150
124
 
151
125
  /**
152
- * Index from rule name to its option struct. Used by `TtscLintRuleEntry<R>` to
126
+ * Index from rule name to its option object. `TtscLintRuleMap` uses this to
153
127
  * produce precise tuple types per rule.
154
128
  */
155
- export interface TtscLintRuleOptionsMap {
156
- "format/semi": TtscLintRuleOptions.Semi;
157
- "format/quotes": TtscLintRuleOptions.Quotes;
158
- "format/trailing-comma": TtscLintRuleOptions.TrailingComma;
159
- "format/sort-imports": TtscLintRuleOptions.SortImports;
160
- "format/jsdoc": TtscLintRuleOptions.JSDoc;
161
- "format/print-width": TtscLintRuleOptions.PrintWidth;
129
+ export interface ITtscLintRuleOptionsMap {
130
+ "format/semi": ITtscLintSemiRuleOptions;
131
+ "format/quotes": ITtscLintQuotesRuleOptions;
132
+ "format/trailing-comma": ITtscLintTrailingCommaRuleOptions;
133
+ "format/sort-imports": ITtscLintSortImportsRuleOptions;
134
+ "format/jsdoc": ITtscLintJsdocRuleOptions;
135
+ "format/print-width": ITtscLintPrintWidthRuleOptions;
162
136
  }
@@ -1,14 +1,9 @@
1
- export * from "./defaultFormat";
1
+ export * from "./ITtscLintConfig";
2
+ export * from "./ITtscLintFormatConfig";
2
3
  export * from "./ITtscLintPlugin";
3
4
  export * from "./ITtscLintPluginConfig";
4
5
  export * from "./ITtscLintPluginMeta";
5
- export * from "./PluginRuleNames";
6
- export * from "./TtscLintConfig";
7
- export * from "./TtscLintConfigEntry";
8
- export * from "./TtscLintFormatConfig";
9
- export * from "./TtscLintPlugins";
10
6
  export * from "./TtscLintRule";
11
- export * from "./TtscLintRuleEntry";
12
7
  export * from "./TtscLintRuleMap";
13
8
  export * from "./TtscLintRuleOptions";
14
9
  export * from "./TtscLintSeverity";
@@ -1,55 +0,0 @@
1
- import type { TtscLintConfig } from "./structures/TtscLintConfig";
2
- import type { TtscLintPlugins } from "./structures/TtscLintPlugins";
3
- /**
4
- * Authoring helper that preserves the literal type of a lint config.
5
- *
6
- * ESLint's flat-config experience relies on `defineConfig` to capture the
7
- * const-narrowed type of the configuration array, which is what makes plugin
8
- * rule names autocomplete across entries. `@ttsc/lint` follows the same
9
- * pattern: pass your config through this helper and the contributor plugin
10
- * objects in `plugins` propagate their `rules` tuples into the rule-name
11
- * union.
12
- *
13
- * ```ts
14
- * import { defineConfig } from "@ttsc/lint";
15
- * import importPlugin from "@ttsc/lint-plugin-import";
16
- *
17
- * export default defineConfig([
18
- * {
19
- * plugins: { import: importPlugin },
20
- * rules: {
21
- * "no-var": "error",
22
- * "import/no-cycle": ["error", { maxDepth: 1 }],
23
- * },
24
- * },
25
- * ]);
26
- * ```
27
- *
28
- * The function is a pure pass-through at runtime. The generic gymnastics below
29
- * gather every `plugins` map across the array of config entries into one
30
- * intersected `TtscLintPlugins` shape that gets threaded back into the
31
- * `TtscLintConfig<P>` constraint. Without this, `TtscLintConfig`'s default `P =
32
- * Record<string, never>` rules out every namespaced rule name and `{
33
- * "import/no-cycle": "error" }` would be flagged as a typo.
34
- */
35
- export declare function defineConfig<const T extends TtscLintConfig<GatherPlugins<T>>>(config: T): T;
36
- /**
37
- * Walks the input type to collect every plugin map declared across entries.
38
- * Single entries yield the entry's `plugins`; arrays intersect every entry's
39
- * `plugins` so each entry's rule-name union remains valid for the whole array.
40
- * The intersection (vs. union) is load-bearing — TypeScript's `keyof (A | B)`
41
- * collapses to `never`, which would reject every namespaced rule name.
42
- *
43
- * Plugins declared exclusively inside an `extends` chain are NOT collected:
44
- * recursing into `T extends { extends?: infer E } ? GatherPlugins<E> : {}`
45
- * blows TypeScript's instantiation budget (`extends` is itself a
46
- * `TtscLintConfigEntry` tree). Authors should declare each plugin's `plugins`
47
- * map on the outermost entry where its rules are configured. The runtime
48
- * resolver still picks up plugins from `extends` entries; only the autocomplete
49
- * domain is bounded.
50
- */
51
- type GatherPlugins<T> = T extends {
52
- plugins?: infer P;
53
- } ? P extends TtscLintPlugins ? P : {} : T extends readonly (infer Item)[] ? UnionToIntersection<Item extends unknown ? GatherPlugins<Item> : never> : {};
54
- type UnionToIntersection<U> = (U extends unknown ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
55
- export {};
@@ -1,39 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defineConfig = defineConfig;
4
- /**
5
- * Authoring helper that preserves the literal type of a lint config.
6
- *
7
- * ESLint's flat-config experience relies on `defineConfig` to capture the
8
- * const-narrowed type of the configuration array, which is what makes plugin
9
- * rule names autocomplete across entries. `@ttsc/lint` follows the same
10
- * pattern: pass your config through this helper and the contributor plugin
11
- * objects in `plugins` propagate their `rules` tuples into the rule-name
12
- * union.
13
- *
14
- * ```ts
15
- * import { defineConfig } from "@ttsc/lint";
16
- * import importPlugin from "@ttsc/lint-plugin-import";
17
- *
18
- * export default defineConfig([
19
- * {
20
- * plugins: { import: importPlugin },
21
- * rules: {
22
- * "no-var": "error",
23
- * "import/no-cycle": ["error", { maxDepth: 1 }],
24
- * },
25
- * },
26
- * ]);
27
- * ```
28
- *
29
- * The function is a pure pass-through at runtime. The generic gymnastics below
30
- * gather every `plugins` map across the array of config entries into one
31
- * intersected `TtscLintPlugins` shape that gets threaded back into the
32
- * `TtscLintConfig<P>` constraint. Without this, `TtscLintConfig`'s default `P =
33
- * Record<string, never>` rules out every namespaced rule name and `{
34
- * "import/no-cycle": "error" }` would be flagged as a typo.
35
- */
36
- function defineConfig(config) {
37
- return config;
38
- }
39
- //# sourceMappingURL=defineConfig.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"defineConfig.js","sourceRoot":"","sources":["../src/defineConfig.ts"],"names":[],"mappings":";;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,sBACE,MAAS;IAET,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,14 +0,0 @@
1
- import type { TtscLintPlugins } from "./TtscLintPlugins";
2
- /**
3
- * Builds the union of `${namespace}/${rule}` strings from a plugins map.
4
- *
5
- * Each plugin's `rules` tuple is read literally: an `as const` tuple
6
- * (`["no-cycle", "order"] as const`) provides exact autocomplete, while a plain
7
- * `string[]` collapses to `${namespace}/${string}` and disables rule-level typo
8
- * detection for that namespace.
9
- */
10
- export type PluginRuleNames<P extends TtscLintPlugins> = {
11
- [Ns in keyof P]: P[Ns] extends {
12
- rules?: infer R;
13
- } ? R extends readonly (infer N)[] ? N extends string ? `${Ns & string}/${N}` : never : never : never;
14
- }[keyof P];
@@ -1 +0,0 @@
1
- {"version":3,"file":"PluginRuleNames.js","sourceRoot":"","sources":["../../src/structures/PluginRuleNames.ts"],"names":[],"mappings":""}
@@ -1,27 +0,0 @@
1
- import type { TtscLintConfigEntry } from "./TtscLintConfigEntry";
2
- import type { TtscLintPlugins } from "./TtscLintPlugins";
3
- import type { TtscLintRuleMap } from "./TtscLintRuleMap";
4
- /**
5
- * Top-level config accepted by `@ttsc/lint`.
6
- *
7
- * Three accepted forms, listed in expected order of preference:
8
- *
9
- * 1. **Flat-config array** — mirrors ESLint flat config exactly. Each entry can
10
- * scope by `files` / `ignores`, declare a `plugins` map of contributors,
11
- * configure `rules`, and configure formatting through the Prettier-style
12
- * {@link TtscLintFormatConfig | `format`} block. Multiple entries layer in
13
- * order.
14
- * 2. **Single config object** — same shape as one flat-config entry. Useful when
15
- * the project has no per-file scoping. Pass `format: { … }` here for the
16
- * smallest "describe my style" config.
17
- * 3. **Rules-only map** — historical shape kept for backward compat with
18
- * single-file projects. `{"no-var":"error"}` is interpreted as `[{rules:
19
- * {"no-var":"error"}}]`. The shorthand intentionally has no slot for the
20
- * `format` block — use form (1) or (2) to enable formatting.
21
- *
22
- * The generic parameter `P` lets `defineConfig` capture the literal plugin
23
- * object types declared in `plugins`. When non-empty, rule-name keys
24
- * autocomplete as `BuiltInRule | "<ns>/<rule>"` where the namespace-rule
25
- * combinations come from each plugin's `rules` tuple.
26
- */
27
- export type TtscLintConfig<P extends TtscLintPlugins = Record<string, never>> = TtscLintRuleMap<P> | TtscLintConfigEntry<P> | readonly TtscLintConfigEntry<P>[];
@@ -1 +0,0 @@
1
- {"version":3,"file":"TtscLintConfig.js","sourceRoot":"","sources":["../../src/structures/TtscLintConfig.ts"],"names":[],"mappings":""}
@@ -1,39 +0,0 @@
1
- import type { TtscLintFormatConfig } from "./TtscLintFormatConfig";
2
- import type { TtscLintPlugins } from "./TtscLintPlugins";
3
- import type { TtscLintRuleMap } from "./TtscLintRuleMap";
4
- /**
5
- * One flat-config entry. ESLint-style `files` / `ignores` glob scoping, a
6
- * `plugins` namespace map of contributor plugin objects, an `extends` list of
7
- * child entries to fold in first, and a severity-keyed `rules` map applied
8
- * after the extends chain.
9
- *
10
- * Prettier-style formatting opts in through a sibling `format` block — see
11
- * `TtscLintFormatConfig`. The block can scope per-entry (e.g. wider
12
- * `printWidth` for `legacy/**`) just like `rules` does.
13
- */
14
- export interface TtscLintConfigEntry<P extends TtscLintPlugins = Record<string, never>> {
15
- /** Globs that select the files this entry applies to. */
16
- files?: string | readonly string[];
17
- /** Globs that exclude files this entry would otherwise match. */
18
- ignores?: string | readonly string[];
19
- /**
20
- * Nested entries (or arrays of entries) folded in before this entry's own
21
- * rules apply. Mirrors ESLint flat config's `extends`: each child's rules
22
- * layer first, with `this.rules` taking precedence on key collisions.
23
- */
24
- extends?: TtscLintConfigEntry<P> | readonly TtscLintConfigEntry<P>[] | readonly (TtscLintConfigEntry<P> | readonly TtscLintConfigEntry<P>[])[];
25
- /**
26
- * Contributor plugin objects keyed by namespace. Each value is the default
27
- * export of a `@ttsc/lint` contributor package (an `ITtscLintPlugin`).
28
- */
29
- plugins?: P;
30
- /** Rule-name → severity map. Supports severity tuples with options. */
31
- rules?: TtscLintRuleMap<P>;
32
- /**
33
- * Prettier-style flat configuration for the `format/*` rules. Presence
34
- * (even an empty `format: {}`) enables format-class rules at Prettier
35
- * defaults; absence keeps them all off. Per-rule overrides go through
36
- * the `rules` map — the `rules` entry wins on conflict.
37
- */
38
- format?: TtscLintFormatConfig;
39
- }
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=TtscLintConfigEntry.js.map