@mouse_484/oxc-config 0.8.11 → 0.8.12

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mouse_484/oxc-config",
3
3
  "type": "module",
4
- "version": "0.8.11",
4
+ "version": "0.8.12",
5
5
  "author": "mouse_484",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/mouse484/config/tree/main/packages/oxc",
@@ -77,12 +77,16 @@ dtsFile.addInterface({
77
77
  }
78
78
  return {
79
79
  name,
80
- type: options ? `boolean | ${options.getText()}` : 'boolean',
80
+ type: options
81
+ ? `boolean | ${options.getText()}`
82
+ : 'boolean',
81
83
  hasQuestionToken: true,
82
- docs: [{
83
- description: `\`${name}\` option`,
84
- tags,
85
- }],
84
+ docs: [
85
+ {
86
+ description: `\`${name}\` option`,
87
+ tags,
88
+ },
89
+ ],
86
90
  }
87
91
  }),
88
92
  })
@@ -8,13 +8,25 @@ export default createConfigs({
8
8
  plugins: ['eslint'],
9
9
  rules: {
10
10
  'id-length': 'off',
11
- 'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
12
- 'no-magic-numbers': ['error', { ignore: [0, 1, -1] }],
11
+ 'func-style': [
12
+ 'error',
13
+ 'declaration',
14
+ { allowArrowFunctions: true },
15
+ ],
16
+ 'no-magic-numbers': [
17
+ 'error',
18
+ {
19
+ ignore: [0, 1, -1],
20
+ },
21
+ ],
13
22
  'no-undefined': 'off',
14
23
  'no-ternary': 'off',
15
24
  'no-nested-ternary': 'error',
16
25
  'no-unneeded-ternary': 'error',
17
- 'no-void': ['error', { allowAsStatement: true }],
26
+ 'no-void': [
27
+ 'error',
28
+ { allowAsStatement: true },
29
+ ],
18
30
  'one-var': 'off',
19
31
  'no-warning-comments': 'off',
20
32
  'capitalized-comments': 'off',
@@ -5,16 +5,27 @@ export default createConfigs({
5
5
  enable: true,
6
6
  configs: [
7
7
  {
8
- jsPlugins: [{
9
- name: 'perfectionist',
10
- specifier: import.meta.resolve('eslint-plugin-perfectionist'),
11
- }],
8
+ jsPlugins: [
9
+ {
10
+ name: 'perfectionist',
11
+ specifier: import.meta.resolve('eslint-plugin-perfectionist'),
12
+ },
13
+ ],
12
14
  rules: {
13
15
  // `sort-imports` is handled by oxfmt (`sortImports`)
14
16
  'perfectionist/sort-imports': 'off',
15
- 'perfectionist/sort-named-imports': ['error', { type: 'natural', order: 'asc' }],
16
- 'perfectionist/sort-named-exports': ['error', { type: 'natural', order: 'asc' }],
17
- 'perfectionist/sort-exports': ['error', { type: 'natural', order: 'asc' }],
17
+ 'perfectionist/sort-named-imports': [
18
+ 'error',
19
+ { type: 'natural', order: 'asc' },
20
+ ],
21
+ 'perfectionist/sort-named-exports': [
22
+ 'error',
23
+ { type: 'natural', order: 'asc' },
24
+ ],
25
+ 'perfectionist/sort-exports': [
26
+ 'error',
27
+ { type: 'natural', order: 'asc' },
28
+ ],
18
29
  },
19
30
  },
20
31
  {
@@ -30,19 +30,26 @@ const CONFIGS = /** @type {const} */[
30
30
  @returns {import("oxlint").OxlintConfig[]} Generated configs for the enabled options
31
31
  */
32
32
  export default function buildConfigs(options) {
33
- const context = { isPackageExists: createPackageDetector(), options }
33
+ const context = {
34
+ isPackageExists: createPackageDetector(),
35
+ options,
36
+ }
34
37
  return CONFIGS.flatMap(({ name, build, enable = true }) => {
35
38
  const option = options[name]
36
39
  if (option === false) {
37
40
  return []
38
41
  }
39
42
  if (option === undefined) {
40
- const isEnabled = typeof enable === 'function' ? enable(context) : enable
43
+ const isEnabled = typeof enable === 'function'
44
+ ? enable(context)
45
+ : enable
41
46
  if (!isEnabled) {
42
47
  return []
43
48
  }
44
49
  }
45
50
  // @ts-expect-error - build configs with options
46
- return build(context, typeof option === 'object' ? option : undefined)
51
+ return build(context, typeof option === 'object'
52
+ ? option
53
+ : undefined)
47
54
  })
48
55
  }
@@ -5,14 +5,19 @@ export default createConfigs({
5
5
  enable: true,
6
6
  configs: [
7
7
  {
8
- jsPlugins: [{
9
- name: 'antfu',
10
- specifier: import.meta.resolve('eslint-plugin-antfu'),
11
- }],
8
+ jsPlugins: [
9
+ {
10
+ name: 'antfu',
11
+ specifier: import.meta.resolve('eslint-plugin-antfu'),
12
+ },
13
+ ],
12
14
  rules: {
13
15
  'antfu/top-level-function': 'error',
14
16
  'antfu/import-dedupe': 'error',
15
- 'antfu/indent-unindent': ['error', { indent: 2 }],
17
+ 'antfu/indent-unindent': [
18
+ 'error',
19
+ { indent: 2 },
20
+ ],
16
21
  'antfu/no-ts-export-equal': 'error',
17
22
  },
18
23
  },
@@ -9,10 +9,23 @@ export default createConfigs({
9
9
  rules: {
10
10
  'react/react-in-jsx-scope': 'off',
11
11
  'react/jsx-props-no-spreading': 'off',
12
- 'react/jsx-max-depth': ['error', { max: 5 }],
13
- 'react/jsx-filename-extension': ['error', { extensions: ['.jsx', '.tsx'] }],
12
+ 'react/jsx-max-depth': [
13
+ 'error',
14
+ { max: 5 },
15
+ ],
16
+ 'react/jsx-filename-extension': [
17
+ 'error',
18
+ {
19
+ extensions: ['.jsx', '.tsx'],
20
+ },
21
+ ],
14
22
  'react/jsx-no-literals': 'off',
15
- 'react/forbid-component-props': ['error', { forbid: ['style'] }],
23
+ 'react/forbid-component-props': [
24
+ 'error',
25
+ {
26
+ forbid: ['style'],
27
+ },
28
+ ],
16
29
  },
17
30
  },
18
31
  {
@@ -11,8 +11,16 @@ export default createConfigs({
11
11
  {
12
12
  files: ['src/routes/**/*.tsx'],
13
13
  rules: {
14
- 'no-use-before-define': ['error', { functions: false }],
15
- 'react/only-export-components': ['error', { customHOCs: ['createRootRoute', 'createFileRoute', 'createRootRouteWithContext'] }],
14
+ 'no-use-before-define': [
15
+ 'error',
16
+ { functions: false },
17
+ ],
18
+ 'react/only-export-components': [
19
+ 'error',
20
+ {
21
+ customHOCs: ['createRootRoute', 'createFileRoute', 'createRootRouteWithContext'],
22
+ },
23
+ ],
16
24
  },
17
25
  },
18
26
  ],
package/src/format.js CHANGED
@@ -13,5 +13,8 @@ const DEFAULT_FORMAT = /** @type {import('oxfmt').OxfmtConfig} */ ({
13
13
  * @param {import('oxfmt').OxfmtConfig} [config]
14
14
  */
15
15
  export function format(config = {}) {
16
- return { ...DEFAULT_FORMAT, ...config }
16
+ return {
17
+ ...DEFAULT_FORMAT,
18
+ ...config,
19
+ }
17
20
  }
@@ -7,10 +7,20 @@ export function createConfigs({ name, enable = true, options, configs }) {
7
7
  enable,
8
8
  options,
9
9
  build: (context, overriddenOptions) => {
10
- const local = { ...context, options: { ...options, ...overriddenOptions } }
10
+ const local = {
11
+ ...context,
12
+ options: {
13
+ ...options,
14
+ ...overriddenOptions,
15
+ },
16
+ }
11
17
  return configs.flatMap((item) => {
12
- const config = typeof item === 'function' ? item(local) : item
13
- return config ? [config] : []
18
+ const config = typeof item === 'function'
19
+ ? item(local)
20
+ : item
21
+ return config
22
+ ? [config]
23
+ : []
14
24
  })
15
25
  },
16
26
  }
@@ -13,11 +13,21 @@ void test('detects packages from the consumer, including import-only and types-o
13
13
  const project = path.join(root, 'project')
14
14
  mkdirSync(project)
15
15
  const fixtures = {
16
- 'import-only': { exports: { import: './index.js' }, type: 'module' },
16
+ 'import-only': {
17
+ exports: { import: './index.js' },
18
+ type: 'module',
19
+ },
17
20
  'hidden-manifest': { exports: './index.js', type: 'module' },
18
- 'types-only-export': { exports: { '.': { types: './index.d.ts' } } },
21
+ 'types-only-export': {
22
+ exports: {
23
+ '.': { types: './index.d.ts' },
24
+ },
25
+ },
19
26
  '@types/example': { types: './index.d.ts' },
20
- 'conditional': { exports: { import: './index.js', require: './missing.cjs' }, type: 'module' },
27
+ 'conditional': {
28
+ exports: { import: './index.js', require: './missing.cjs' },
29
+ type: 'module',
30
+ },
21
31
  }
22
32
  for (const [name, manifest] of Object.entries(fixtures)) {
23
33
  const directory = path.join(root, 'node_modules', name)
@@ -29,28 +39,28 @@ void test('detects packages from the consumer, including import-only and types-o
29
39
  writeFileSync(path.join(directory, 'index.d.ts'), 'export {}\n')
30
40
  }
31
41
 
32
- const detect = createPackageDetector(project)
42
+ const isPackageInstalled = createPackageDetector(project)
33
43
  for (const name of Object.keys(fixtures)) {
34
- assert.equal(detect(name), true, name)
44
+ assert.equal(isPackageInstalled(name), true, name)
35
45
  }
36
- assert.equal(detect('missing-package'), false)
46
+ assert.equal(isPackageInstalled('missing-package'), false)
37
47
  // Packages installed beside the config must not enable consumer presets.
38
- assert.equal(detect('eslint-plugin-antfu'), false)
48
+ assert.equal(isPackageInstalled('eslint-plugin-antfu'), false)
39
49
 
40
50
  symlinkSync(path.join(root, 'node_modules/import-only'), path.join(root, 'node_modules/linked-package'), 'junction')
41
- assert.equal(detect('linked-package'), true)
51
+ assert.equal(isPackageInstalled('linked-package'), true)
42
52
 
43
53
  const broken = path.join(root, 'node_modules/broken-export')
44
54
  mkdirSync(broken)
45
55
  writeFileSync(path.join(broken, 'package.json'), JSON.stringify({ exports: './missing.js' }))
46
- assert.equal(detect('broken-export'), false)
56
+ assert.equal(isPackageInstalled('broken-export'), false)
47
57
  })
48
58
 
49
59
  void test('a new detector observes the current project and newly installed packages', (context) => {
50
60
  const root = mkdtempSync(path.join(tmpdir(), 'oxc-package-detection-'))
51
61
  context.after(() => rmSync(root, { recursive: true, force: true }))
52
- const detect = createPackageDetector(root)
53
- assert.equal(detect('react'), false)
62
+ const isPackageInstalled = createPackageDetector(root)
63
+ assert.equal(isPackageInstalled('react'), false)
54
64
 
55
65
  const directory = path.join(root, 'node_modules/react')
56
66
  mkdirSync(directory, { recursive: true })
package/src/lint.js CHANGED
@@ -10,22 +10,41 @@ const DEFAULT_CATEGORIES = {
10
10
  nursery: 'warn',
11
11
  }
12
12
 
13
- const OBJECT_KEYS = ['settings', 'env', 'globals', 'options']
13
+ const OBJECT_KEYS = [
14
+ 'settings',
15
+ 'env',
16
+ 'globals',
17
+ 'options',
18
+ ]
14
19
  const ARRAY_KEYS = ['ignorePatterns']
15
- const HOISTED_KEYS = [...OBJECT_KEYS, ...ARRAY_KEYS, 'categories']
20
+ const HOISTED_KEYS = [
21
+ ...OBJECT_KEYS,
22
+ ...ARRAY_KEYS,
23
+ 'categories',
24
+ ]
16
25
 
17
26
  /**
18
27
  @type {import('.').lint}
19
28
  */
20
29
  export function lint(options, config = {}) {
21
- const all = [...buildConfigs(options), config]
30
+ const all = [
31
+ ...buildConfigs(options),
32
+ config,
33
+ ]
22
34
 
23
35
  /**
24
36
  @type {Record<string, any>}
25
37
  */
26
38
  const root = {
27
- categories: { ...DEFAULT_CATEGORIES, ...config.categories },
39
+ categories: {
40
+ ...DEFAULT_CATEGORIES,
41
+ ...config.categories,
42
+ },
28
43
  }
44
+ /**
45
+ @type {string[]}
46
+ */
47
+ let ignorePatterns = []
29
48
 
30
49
  for (const item of all) {
31
50
  for (const key of OBJECT_KEYS) {
@@ -34,18 +53,22 @@ export function lint(options, config = {}) {
34
53
  const value = item[key]
35
54
  if (value !== undefined) {
36
55
  // eslint-disable-next-line ts/no-unsafe-assignment
37
- root[key] = { ...root[key], ...value }
56
+ root[key] = {
57
+ ...root[key],
58
+ ...value,
59
+ }
38
60
  }
39
61
  }
40
- for (const key of ARRAY_KEYS) {
41
- // @ts-expect-error - hoisted keys are not part of the OxlintConfig index signature
42
- // eslint-disable-next-line ts/no-unsafe-assignment
43
- const value = item[key]
44
- if (value !== undefined) {
45
- // eslint-disable-next-line ts/no-unsafe-assignment
46
- root[key] = [...new Set([...(root[key] ?? []), ...value])]
47
- }
62
+ if (item.ignorePatterns === undefined) {
63
+ continue
48
64
  }
65
+ ignorePatterns = [
66
+ ...new Set([
67
+ ...ignorePatterns,
68
+ ...item.ignorePatterns,
69
+ ]),
70
+ ]
71
+ root.ignorePatterns = ignorePatterns
49
72
  }
50
73
 
51
74
  return {
@@ -0,0 +1,17 @@
1
+ import assert from 'node:assert/strict'
2
+ // eslint-disable-next-line test/no-import-node-test -- This package uses the built-in test runner.
3
+ import { test } from 'node:test'
4
+ import { lint } from './lint.js'
5
+
6
+ void test('merges and deduplicates ignore patterns in order', () => {
7
+ const config = lint({ tanstack: true }, {
8
+ ignorePatterns: ['**/src/routeTree.gen.ts', 'custom/**'],
9
+ })
10
+ assert.deepEqual(config.ignorePatterns, ['**/src/routeTree.gen.ts', 'custom/**'])
11
+ assert.equal(config.extends?.some(item => item.ignorePatterns !== undefined), false)
12
+ })
13
+
14
+ void test('preserves an explicitly empty ignore list', () => {
15
+ const config = lint({ tanstack: false }, { ignorePatterns: [] })
16
+ assert.deepEqual(config.ignorePatterns, [])
17
+ })