@eslint-config-snapshot/api 0.3.0 → 0.4.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.
- package/CHANGELOG.md +18 -0
- package/dist/index.cjs +55 -2
- package/dist/index.js +54 -2
- package/package.json +1 -1
- package/src/extract.ts +57 -0
- package/src/index.ts +2 -2
- package/src/snapshot.ts +17 -2
- package/test/extract.test.ts +26 -1
- package/test/snapshot.test.ts +20 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @eslint-config-snapshot/api
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Minor release with improved CLI output consistency and faster workspace extraction using ESLint API fallback strategy.
|
|
8
|
+
|
|
9
|
+
## 0.3.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Fix deterministic aggregation when same-severity ESLint rule options differ across sampled files, preventing update crashes.
|
|
14
|
+
|
|
15
|
+
## 0.3.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Release patch bump after init UX clarity improvements for default catch-all group messaging.
|
|
20
|
+
|
|
3
21
|
## 0.3.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
package/dist/index.cjs
CHANGED
|
@@ -38,6 +38,7 @@ __export(index_exports, {
|
|
|
38
38
|
compareSeverity: () => compareSeverity,
|
|
39
39
|
diffSnapshots: () => diffSnapshots,
|
|
40
40
|
discoverWorkspaces: () => discoverWorkspaces,
|
|
41
|
+
extractRulesForWorkspaceSamples: () => extractRulesForWorkspaceSamples,
|
|
41
42
|
extractRulesFromPrintConfig: () => extractRulesFromPrintConfig,
|
|
42
43
|
findConfigPath: () => findConfigPath,
|
|
43
44
|
getConfigScaffold: () => getConfigScaffold,
|
|
@@ -288,6 +289,7 @@ var import_node_child_process = require("child_process");
|
|
|
288
289
|
var import_node_fs = require("fs");
|
|
289
290
|
var import_node_module = require("module");
|
|
290
291
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
292
|
+
var import_node_url = require("url");
|
|
291
293
|
function resolveEslintBinForWorkspace(workspaceAbs) {
|
|
292
294
|
const anchor = import_node_path2.default.join(workspaceAbs, "__snapshot_anchor__.cjs");
|
|
293
295
|
const req = (0, import_node_module.createRequire)(anchor);
|
|
@@ -352,6 +354,44 @@ function extractRulesFromPrintConfig(workspaceAbs, fileAbs) {
|
|
|
352
354
|
throw new Error(`Invalid JSON from eslint --print-config for ${fileAbs}`);
|
|
353
355
|
}
|
|
354
356
|
const rules = parsed.rules ?? {};
|
|
357
|
+
return normalizeRules(rules);
|
|
358
|
+
}
|
|
359
|
+
async function extractRulesForWorkspaceSamples(workspaceAbs, fileAbsList) {
|
|
360
|
+
const evaluate = await createWorkspaceEvaluator(workspaceAbs);
|
|
361
|
+
const results = [];
|
|
362
|
+
for (const fileAbs of fileAbsList) {
|
|
363
|
+
try {
|
|
364
|
+
const rules = await evaluate(fileAbs);
|
|
365
|
+
results.push({ fileAbs, rules });
|
|
366
|
+
} catch (error) {
|
|
367
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
368
|
+
results.push({ fileAbs, error: normalizedError });
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return results;
|
|
372
|
+
}
|
|
373
|
+
async function createWorkspaceEvaluator(workspaceAbs) {
|
|
374
|
+
try {
|
|
375
|
+
const anchor = import_node_path2.default.join(workspaceAbs, "__snapshot_anchor__.cjs");
|
|
376
|
+
const req = (0, import_node_module.createRequire)(anchor);
|
|
377
|
+
const eslintModuleEntry = req.resolve("eslint");
|
|
378
|
+
const eslintModule = await import((0, import_node_url.pathToFileURL)(eslintModuleEntry).href);
|
|
379
|
+
const ESLintClass = eslintModule.ESLint ?? eslintModule.default?.ESLint;
|
|
380
|
+
if (ESLintClass) {
|
|
381
|
+
const eslint = new ESLintClass({ cwd: workspaceAbs });
|
|
382
|
+
return async (fileAbs) => {
|
|
383
|
+
const config = await eslint.calculateConfigForFile(fileAbs);
|
|
384
|
+
if (!config || typeof config !== "object") {
|
|
385
|
+
throw new Error(`Empty ESLint print-config output for ${fileAbs}`);
|
|
386
|
+
}
|
|
387
|
+
return normalizeRules(config.rules ?? {});
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
} catch {
|
|
391
|
+
}
|
|
392
|
+
return (fileAbs) => Promise.resolve(extractRulesFromPrintConfig(workspaceAbs, fileAbs));
|
|
393
|
+
}
|
|
394
|
+
function normalizeRules(rules) {
|
|
355
395
|
const normalized = /* @__PURE__ */ new Map();
|
|
356
396
|
for (const [ruleName, ruleConfig] of Object.entries(rules)) {
|
|
357
397
|
normalized.set(ruleName, normalizeRuleEntry(ruleConfig));
|
|
@@ -398,8 +438,20 @@ function aggregateRules(ruleMaps) {
|
|
|
398
438
|
}
|
|
399
439
|
const currentOptions = currentEntry.length > 1 ? canonicalizeJson(currentEntry[1]) : void 0;
|
|
400
440
|
const nextOptions = nextEntry.length > 1 ? canonicalizeJson(nextEntry[1]) : void 0;
|
|
401
|
-
if (
|
|
402
|
-
|
|
441
|
+
if (currentOptions === void 0 && nextOptions !== void 0) {
|
|
442
|
+
aggregated.set(ruleName, canonicalizeJson(nextEntry));
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
if (currentOptions !== void 0 && nextOptions === void 0) {
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
if (currentOptions === void 0 && nextOptions === void 0) {
|
|
449
|
+
continue;
|
|
450
|
+
}
|
|
451
|
+
const currentJson = JSON.stringify(currentOptions);
|
|
452
|
+
const nextJson = JSON.stringify(nextOptions);
|
|
453
|
+
if (nextJson < currentJson) {
|
|
454
|
+
aggregated.set(ruleName, canonicalizeJson(nextEntry));
|
|
403
455
|
}
|
|
404
456
|
}
|
|
405
457
|
}
|
|
@@ -595,6 +647,7 @@ function getConfigScaffold(preset = "minimal") {
|
|
|
595
647
|
compareSeverity,
|
|
596
648
|
diffSnapshots,
|
|
597
649
|
discoverWorkspaces,
|
|
650
|
+
extractRulesForWorkspaceSamples,
|
|
598
651
|
extractRulesFromPrintConfig,
|
|
599
652
|
findConfigPath,
|
|
600
653
|
getConfigScaffold,
|
package/dist/index.js
CHANGED
|
@@ -233,6 +233,7 @@ import { spawnSync } from "child_process";
|
|
|
233
233
|
import { existsSync, readFileSync } from "fs";
|
|
234
234
|
import { createRequire } from "module";
|
|
235
235
|
import path2 from "path";
|
|
236
|
+
import { pathToFileURL } from "url";
|
|
236
237
|
function resolveEslintBinForWorkspace(workspaceAbs) {
|
|
237
238
|
const anchor = path2.join(workspaceAbs, "__snapshot_anchor__.cjs");
|
|
238
239
|
const req = createRequire(anchor);
|
|
@@ -297,6 +298,44 @@ function extractRulesFromPrintConfig(workspaceAbs, fileAbs) {
|
|
|
297
298
|
throw new Error(`Invalid JSON from eslint --print-config for ${fileAbs}`);
|
|
298
299
|
}
|
|
299
300
|
const rules = parsed.rules ?? {};
|
|
301
|
+
return normalizeRules(rules);
|
|
302
|
+
}
|
|
303
|
+
async function extractRulesForWorkspaceSamples(workspaceAbs, fileAbsList) {
|
|
304
|
+
const evaluate = await createWorkspaceEvaluator(workspaceAbs);
|
|
305
|
+
const results = [];
|
|
306
|
+
for (const fileAbs of fileAbsList) {
|
|
307
|
+
try {
|
|
308
|
+
const rules = await evaluate(fileAbs);
|
|
309
|
+
results.push({ fileAbs, rules });
|
|
310
|
+
} catch (error) {
|
|
311
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
312
|
+
results.push({ fileAbs, error: normalizedError });
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return results;
|
|
316
|
+
}
|
|
317
|
+
async function createWorkspaceEvaluator(workspaceAbs) {
|
|
318
|
+
try {
|
|
319
|
+
const anchor = path2.join(workspaceAbs, "__snapshot_anchor__.cjs");
|
|
320
|
+
const req = createRequire(anchor);
|
|
321
|
+
const eslintModuleEntry = req.resolve("eslint");
|
|
322
|
+
const eslintModule = await import(pathToFileURL(eslintModuleEntry).href);
|
|
323
|
+
const ESLintClass = eslintModule.ESLint ?? eslintModule.default?.ESLint;
|
|
324
|
+
if (ESLintClass) {
|
|
325
|
+
const eslint = new ESLintClass({ cwd: workspaceAbs });
|
|
326
|
+
return async (fileAbs) => {
|
|
327
|
+
const config = await eslint.calculateConfigForFile(fileAbs);
|
|
328
|
+
if (!config || typeof config !== "object") {
|
|
329
|
+
throw new Error(`Empty ESLint print-config output for ${fileAbs}`);
|
|
330
|
+
}
|
|
331
|
+
return normalizeRules(config.rules ?? {});
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
} catch {
|
|
335
|
+
}
|
|
336
|
+
return (fileAbs) => Promise.resolve(extractRulesFromPrintConfig(workspaceAbs, fileAbs));
|
|
337
|
+
}
|
|
338
|
+
function normalizeRules(rules) {
|
|
300
339
|
const normalized = /* @__PURE__ */ new Map();
|
|
301
340
|
for (const [ruleName, ruleConfig] of Object.entries(rules)) {
|
|
302
341
|
normalized.set(ruleName, normalizeRuleEntry(ruleConfig));
|
|
@@ -343,8 +382,20 @@ function aggregateRules(ruleMaps) {
|
|
|
343
382
|
}
|
|
344
383
|
const currentOptions = currentEntry.length > 1 ? canonicalizeJson(currentEntry[1]) : void 0;
|
|
345
384
|
const nextOptions = nextEntry.length > 1 ? canonicalizeJson(nextEntry[1]) : void 0;
|
|
346
|
-
if (
|
|
347
|
-
|
|
385
|
+
if (currentOptions === void 0 && nextOptions !== void 0) {
|
|
386
|
+
aggregated.set(ruleName, canonicalizeJson(nextEntry));
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
if (currentOptions !== void 0 && nextOptions === void 0) {
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
if (currentOptions === void 0 && nextOptions === void 0) {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
const currentJson = JSON.stringify(currentOptions);
|
|
396
|
+
const nextJson = JSON.stringify(nextOptions);
|
|
397
|
+
if (nextJson < currentJson) {
|
|
398
|
+
aggregated.set(ruleName, canonicalizeJson(nextEntry));
|
|
348
399
|
}
|
|
349
400
|
}
|
|
350
401
|
}
|
|
@@ -539,6 +590,7 @@ export {
|
|
|
539
590
|
compareSeverity,
|
|
540
591
|
diffSnapshots,
|
|
541
592
|
discoverWorkspaces,
|
|
593
|
+
extractRulesForWorkspaceSamples,
|
|
542
594
|
extractRulesFromPrintConfig,
|
|
543
595
|
findConfigPath,
|
|
544
596
|
getConfigScaffold,
|
package/package.json
CHANGED
package/src/extract.ts
CHANGED
|
@@ -2,12 +2,14 @@ import { spawnSync } from 'node:child_process'
|
|
|
2
2
|
import { existsSync, readFileSync } from 'node:fs'
|
|
3
3
|
import { createRequire } from 'node:module'
|
|
4
4
|
import path from 'node:path'
|
|
5
|
+
import { pathToFileURL } from 'node:url'
|
|
5
6
|
|
|
6
7
|
import { canonicalizeJson, normalizeSeverity } from './core.js'
|
|
7
8
|
|
|
8
9
|
export type NormalizedRuleEntry = [severity: 'off' | 'warn' | 'error'] | [severity: 'off' | 'warn' | 'error', options: unknown]
|
|
9
10
|
|
|
10
11
|
export type ExtractedWorkspaceRules = Map<string, NormalizedRuleEntry>
|
|
12
|
+
export type WorkspaceExtractionResult = { fileAbs: string; rules?: ExtractedWorkspaceRules; error?: Error }
|
|
11
13
|
|
|
12
14
|
export function resolveEslintBinForWorkspace(workspaceAbs: string): string {
|
|
13
15
|
const anchor = path.join(workspaceAbs, '__snapshot_anchor__.cjs')
|
|
@@ -86,6 +88,61 @@ export function extractRulesFromPrintConfig(workspaceAbs: string, fileAbs: strin
|
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
const rules = (parsed as { rules?: Record<string, unknown> }).rules ?? {}
|
|
91
|
+
return normalizeRules(rules)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export async function extractRulesForWorkspaceSamples(
|
|
95
|
+
workspaceAbs: string,
|
|
96
|
+
fileAbsList: string[]
|
|
97
|
+
): Promise<WorkspaceExtractionResult[]> {
|
|
98
|
+
const evaluate = await createWorkspaceEvaluator(workspaceAbs)
|
|
99
|
+
const results: WorkspaceExtractionResult[] = []
|
|
100
|
+
|
|
101
|
+
for (const fileAbs of fileAbsList) {
|
|
102
|
+
try {
|
|
103
|
+
const rules = await evaluate(fileAbs)
|
|
104
|
+
results.push({ fileAbs, rules })
|
|
105
|
+
} catch (error: unknown) {
|
|
106
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error))
|
|
107
|
+
results.push({ fileAbs, error: normalizedError })
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return results
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function createWorkspaceEvaluator(
|
|
115
|
+
workspaceAbs: string
|
|
116
|
+
): Promise<(fileAbs: string) => Promise<ExtractedWorkspaceRules>> {
|
|
117
|
+
try {
|
|
118
|
+
const anchor = path.join(workspaceAbs, '__snapshot_anchor__.cjs')
|
|
119
|
+
const req = createRequire(anchor)
|
|
120
|
+
const eslintModuleEntry = req.resolve('eslint')
|
|
121
|
+
const eslintModule = (await import(pathToFileURL(eslintModuleEntry).href)) as {
|
|
122
|
+
ESLint?: new (options: { cwd: string }) => { calculateConfigForFile: (fileAbs: string) => Promise<{ rules?: Record<string, unknown> } | undefined> }
|
|
123
|
+
default?: { ESLint?: new (options: { cwd: string }) => { calculateConfigForFile: (fileAbs: string) => Promise<{ rules?: Record<string, unknown> } | undefined> } }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const ESLintClass = eslintModule.ESLint ?? eslintModule.default?.ESLint
|
|
127
|
+
if (ESLintClass) {
|
|
128
|
+
const eslint = new ESLintClass({ cwd: workspaceAbs })
|
|
129
|
+
return async (fileAbs: string) => {
|
|
130
|
+
const config = await eslint.calculateConfigForFile(fileAbs)
|
|
131
|
+
if (!config || typeof config !== 'object') {
|
|
132
|
+
throw new Error(`Empty ESLint print-config output for ${fileAbs}`)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return normalizeRules(config.rules ?? {})
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
} catch {
|
|
139
|
+
// fall through to subprocess-based extractor
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return (fileAbs: string) => Promise.resolve(extractRulesFromPrintConfig(workspaceAbs, fileAbs))
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function normalizeRules(rules: Record<string, unknown>): ExtractedWorkspaceRules {
|
|
89
146
|
const normalized = new Map<string, NormalizedRuleEntry>()
|
|
90
147
|
|
|
91
148
|
for (const [ruleName, ruleConfig] of Object.entries(rules)) {
|
package/src/index.ts
CHANGED
|
@@ -7,8 +7,8 @@ export type { GroupAssignment, GroupDefinition, WorkspaceDiscovery, WorkspaceInp
|
|
|
7
7
|
export { sampleWorkspaceFiles } from './sampling.js'
|
|
8
8
|
export type { SamplingConfig } from './sampling.js'
|
|
9
9
|
|
|
10
|
-
export { extractRulesFromPrintConfig, resolveEslintBinForWorkspace } from './extract.js'
|
|
11
|
-
export type { ExtractedWorkspaceRules, NormalizedRuleEntry } from './extract.js'
|
|
10
|
+
export { extractRulesForWorkspaceSamples, extractRulesFromPrintConfig, resolveEslintBinForWorkspace } from './extract.js'
|
|
11
|
+
export type { ExtractedWorkspaceRules, NormalizedRuleEntry, WorkspaceExtractionResult } from './extract.js'
|
|
12
12
|
|
|
13
13
|
export { aggregateRules, buildSnapshot, readSnapshotFile, writeSnapshotFile } from './snapshot.js'
|
|
14
14
|
export type { SnapshotFile } from './snapshot.js'
|
package/src/snapshot.ts
CHANGED
|
@@ -36,8 +36,23 @@ export function aggregateRules(ruleMaps: readonly Map<string, NormalizedRuleEntr
|
|
|
36
36
|
const currentOptions = currentEntry.length > 1 ? canonicalizeJson(currentEntry[1]) : undefined
|
|
37
37
|
const nextOptions = nextEntry.length > 1 ? canonicalizeJson(nextEntry[1]) : undefined
|
|
38
38
|
|
|
39
|
-
if (
|
|
40
|
-
|
|
39
|
+
if (currentOptions === undefined && nextOptions !== undefined) {
|
|
40
|
+
aggregated.set(ruleName, canonicalizeJson(nextEntry))
|
|
41
|
+
continue
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (currentOptions !== undefined && nextOptions === undefined) {
|
|
45
|
+
continue
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (currentOptions === undefined && nextOptions === undefined) {
|
|
49
|
+
continue
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const currentJson = JSON.stringify(currentOptions)
|
|
53
|
+
const nextJson = JSON.stringify(nextOptions)
|
|
54
|
+
if (nextJson < currentJson) {
|
|
55
|
+
aggregated.set(ruleName, canonicalizeJson(nextEntry))
|
|
41
56
|
}
|
|
42
57
|
}
|
|
43
58
|
}
|
package/test/extract.test.ts
CHANGED
|
@@ -3,7 +3,7 @@ import os from 'node:os'
|
|
|
3
3
|
import path from 'node:path'
|
|
4
4
|
import { afterAll, describe, expect, it } from 'vitest'
|
|
5
5
|
|
|
6
|
-
import { extractRulesFromPrintConfig, resolveEslintBinForWorkspace } from '../src/index.js'
|
|
6
|
+
import { extractRulesForWorkspaceSamples, extractRulesFromPrintConfig, resolveEslintBinForWorkspace } from '../src/index.js'
|
|
7
7
|
|
|
8
8
|
const workspace = path.join(os.tmpdir(), `snapshot-extract-${Date.now()}`)
|
|
9
9
|
|
|
@@ -137,4 +137,29 @@ describe('extract', () => {
|
|
|
137
137
|
`Failed to run eslint --print-config for ${fileAbs}`
|
|
138
138
|
)
|
|
139
139
|
})
|
|
140
|
+
|
|
141
|
+
it('extracts multiple sampled files in one workspace call', async () => {
|
|
142
|
+
const multiWorkspace = `${workspace}-multi`
|
|
143
|
+
await mkdir(path.join(multiWorkspace, 'node_modules/eslint/bin'), { recursive: true })
|
|
144
|
+
await mkdir(path.join(multiWorkspace, 'src'), { recursive: true })
|
|
145
|
+
await writeFile(path.join(multiWorkspace, 'node_modules/eslint/package.json'), JSON.stringify({ name: 'eslint', version: '0.0.0' }, null, 2))
|
|
146
|
+
await writeFile(
|
|
147
|
+
path.join(multiWorkspace, 'node_modules/eslint/bin/eslint.js'),
|
|
148
|
+
"console.log(JSON.stringify({ rules: { 'no-console': 1 } }))\n"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
const fileA = path.join(multiWorkspace, 'src/a.ts')
|
|
152
|
+
const fileB = path.join(multiWorkspace, 'src/b.ts')
|
|
153
|
+
await writeFile(fileA, 'export const a = 1\n')
|
|
154
|
+
await writeFile(fileB, 'export const b = 1\n')
|
|
155
|
+
|
|
156
|
+
const extracted = await extractRulesForWorkspaceSamples(multiWorkspace, [fileA, fileB])
|
|
157
|
+
expect(extracted).toHaveLength(2)
|
|
158
|
+
for (const entry of extracted) {
|
|
159
|
+
expect(entry.error).toBeUndefined()
|
|
160
|
+
expect(entry.rules ? Object.fromEntries(entry.rules.entries()) : {}).toEqual({
|
|
161
|
+
'no-console': ['warn']
|
|
162
|
+
})
|
|
163
|
+
}
|
|
164
|
+
})
|
|
140
165
|
})
|
package/test/snapshot.test.ts
CHANGED
|
@@ -53,12 +53,25 @@ describe('snapshot', () => {
|
|
|
53
53
|
})
|
|
54
54
|
})
|
|
55
55
|
|
|
56
|
-
it('
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
).
|
|
56
|
+
it('resolves conflicting options at same severity deterministically', () => {
|
|
57
|
+
const result = aggregateRules([
|
|
58
|
+
new Map([['no-restricted-imports', ['error', { paths: ['b'] }] as const]]),
|
|
59
|
+
new Map([['no-restricted-imports', ['error', { paths: ['a'] }] as const]])
|
|
60
|
+
])
|
|
61
|
+
|
|
62
|
+
expect(Object.fromEntries(result.entries())).toEqual({
|
|
63
|
+
'no-restricted-imports': ['error', { paths: ['a'] }]
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('prefers configured options over bare severity at same level', () => {
|
|
68
|
+
const result = aggregateRules([
|
|
69
|
+
new Map([['@typescript-eslint/consistent-type-imports', ['warn'] as const]]),
|
|
70
|
+
new Map([['@typescript-eslint/consistent-type-imports', ['warn', { fixStyle: 'inline-type-imports' }] as const]])
|
|
71
|
+
])
|
|
72
|
+
|
|
73
|
+
expect(Object.fromEntries(result.entries())).toEqual({
|
|
74
|
+
'@typescript-eslint/consistent-type-imports': ['warn', { fixStyle: 'inline-type-imports' }]
|
|
75
|
+
})
|
|
63
76
|
})
|
|
64
77
|
})
|