@eslint-config-snapshot/api 0.3.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @eslint-config-snapshot/api
2
2
 
3
+ ## 0.3.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix deterministic aggregation when same-severity ESLint rule options differ across sampled files, preventing update crashes.
8
+
9
+ ## 0.3.1
10
+
11
+ ### Patch Changes
12
+
13
+ - Release patch bump after init UX clarity improvements for default catch-all group messaging.
14
+
3
15
  ## 0.3.0
4
16
 
5
17
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -398,8 +398,20 @@ function aggregateRules(ruleMaps) {
398
398
  }
399
399
  const currentOptions = currentEntry.length > 1 ? canonicalizeJson(currentEntry[1]) : void 0;
400
400
  const nextOptions = nextEntry.length > 1 ? canonicalizeJson(nextEntry[1]) : void 0;
401
- if (JSON.stringify(currentOptions) !== JSON.stringify(nextOptions)) {
402
- throw new Error(`Conflicting rule options for ${ruleName} at severity ${currentEntry[0]}`);
401
+ if (currentOptions === void 0 && nextOptions !== void 0) {
402
+ aggregated.set(ruleName, canonicalizeJson(nextEntry));
403
+ continue;
404
+ }
405
+ if (currentOptions !== void 0 && nextOptions === void 0) {
406
+ continue;
407
+ }
408
+ if (currentOptions === void 0 && nextOptions === void 0) {
409
+ continue;
410
+ }
411
+ const currentJson = JSON.stringify(currentOptions);
412
+ const nextJson = JSON.stringify(nextOptions);
413
+ if (nextJson < currentJson) {
414
+ aggregated.set(ruleName, canonicalizeJson(nextEntry));
403
415
  }
404
416
  }
405
417
  }
package/dist/index.js CHANGED
@@ -343,8 +343,20 @@ function aggregateRules(ruleMaps) {
343
343
  }
344
344
  const currentOptions = currentEntry.length > 1 ? canonicalizeJson(currentEntry[1]) : void 0;
345
345
  const nextOptions = nextEntry.length > 1 ? canonicalizeJson(nextEntry[1]) : void 0;
346
- if (JSON.stringify(currentOptions) !== JSON.stringify(nextOptions)) {
347
- throw new Error(`Conflicting rule options for ${ruleName} at severity ${currentEntry[0]}`);
346
+ if (currentOptions === void 0 && nextOptions !== void 0) {
347
+ aggregated.set(ruleName, canonicalizeJson(nextEntry));
348
+ continue;
349
+ }
350
+ if (currentOptions !== void 0 && nextOptions === void 0) {
351
+ continue;
352
+ }
353
+ if (currentOptions === void 0 && nextOptions === void 0) {
354
+ continue;
355
+ }
356
+ const currentJson = JSON.stringify(currentOptions);
357
+ const nextJson = JSON.stringify(nextOptions);
358
+ if (nextJson < currentJson) {
359
+ aggregated.set(ruleName, canonicalizeJson(nextEntry));
348
360
  }
349
361
  }
350
362
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint-config-snapshot/api",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
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 (JSON.stringify(currentOptions) !== JSON.stringify(nextOptions)) {
40
- throw new Error(`Conflicting rule options for ${ruleName} at severity ${currentEntry[0]}`)
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
  }
@@ -53,12 +53,25 @@ describe('snapshot', () => {
53
53
  })
54
54
  })
55
55
 
56
- it('throws on conflicting options at same severity', () => {
57
- expect(() =>
58
- aggregateRules([
59
- new Map([['no-restricted-imports', ['error', { paths: ['a'] }] as const]]),
60
- new Map([['no-restricted-imports', ['error', { paths: ['b'] }] as const]])
61
- ])
62
- ).toThrow('Conflicting rule options for no-restricted-imports at severity error')
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
  })