@@ -11,11 +11,27 @@ import type {
1111 CheckPackageOptions ,
1212 CheckResult ,
1313 Problem ,
14+ ProblemKind ,
1415} from '@arethetypeswrong/core'
1516
1617const debug = createDebug ( 'tsdown:attw' )
1718const label = dim `[attw]`
1819
20+ const problemFlags : Record < ProblemKind , string > = {
21+ NoResolution : 'no-resolution' ,
22+ UntypedResolution : 'untyped-resolution' ,
23+ FalseCJS : 'false-cjs' ,
24+ FalseESM : 'false-esm' ,
25+ CJSResolvesToESM : 'cjs-resolves-to-esm' ,
26+ FallbackCondition : 'fallback-condition' ,
27+ CJSOnlyExportsDefault : 'cjs-only-exports-default' ,
28+ NamedExports : 'named-exports' ,
29+ FalseExportDefault : 'false-export-default' ,
30+ MissingExportEquals : 'missing-export-equals' ,
31+ UnexpectedModuleSyntax : 'unexpected-module-syntax' ,
32+ InternalResolutionError : 'internal-resolution-error' ,
33+ }
34+
1935export interface AttwOptions extends CheckPackageOptions {
2036 /**
2137 * Profiles select a set of resolution modes to require/ignore. All are evaluated but failures outside
@@ -39,6 +55,33 @@ export interface AttwOptions extends CheckPackageOptions {
3955 * @default 'warn'
4056 */
4157 level ?: 'error' | 'warn'
58+
59+ /**
60+ * List of problem types to ignore by rule name.
61+ *
62+ * These rule names correspond to the string values in the {@link problemFlags} mapping above.
63+ * The available values are:
64+ * - `no-resolution`
65+ * - `untyped-resolution`
66+ * - `false-cjs`
67+ * - `false-esm`
68+ * - `cjs-resolves-to-esm`
69+ * - `fallback-condition`
70+ * - `cjs-only-exports-default`
71+ * - `named-exports`
72+ * - `false-export-default`
73+ * - `missing-export-equals`
74+ * - `unexpected-module-syntax`
75+ * - `internal-resolution-error`
76+ *
77+ * Example:
78+ * ```ts
79+ * ignoreRules: ['no-resolution', 'false-cjs']
80+ * ```
81+ *
82+ * @see {@link problemFlags }
83+ */
84+ ignoreRules ?: ( typeof problemFlags ) [ keyof typeof problemFlags ] [ ]
4285}
4386
4487/**
@@ -59,7 +102,21 @@ export async function attw(options: ResolvedConfig): Promise<void> {
59102 options . logger . warn ( 'attw is enabled but package.json is not found' )
60103 return
61104 }
62- const { profile = 'strict' , level = 'warn' , ...attwOptions } = options . attw
105+ const {
106+ profile = 'strict' ,
107+ level = 'warn' ,
108+ ignoreRules = [ ] ,
109+ ...attwOptions
110+ } = options . attw
111+
112+ const invalidRules = ignoreRules . filter (
113+ ( rule ) => ! Object . values ( problemFlags ) . includes ( rule ) ,
114+ )
115+ if ( invalidRules . length ) {
116+ options . logger . warn (
117+ `attw config option 'ignoreRules' contains invalid value '${ invalidRules . join ( ', ' ) } '.` ,
118+ )
119+ }
63120
64121 const t = performance . now ( )
65122 debug ( 'Running attw check' )
@@ -96,6 +153,11 @@ export async function attw(options: ResolvedConfig): Promise<void> {
96153 let errorMessage : string | undefined
97154 if ( checkResult . types ) {
98155 const problems = checkResult . problems . filter ( ( problem ) => {
156+ // Exclude ignored problem kinds
157+ if ( ignoreRules . includes ( problemFlags [ problem . kind ] ) ) {
158+ return false
159+ }
160+
99161 // Only apply profile filter to problems that have resolutionKind
100162 if ( 'resolutionKind' in problem ) {
101163 return ! profiles [ profile ] ?. includes ( problem . resolutionKind )
0 commit comments