@@ -4,8 +4,6 @@ import path from 'node:path'
4
4
import { pathToFileURL } from 'node:url'
5
5
6
6
import type { Token , TokenType , tokTypes as _tokTypes } from 'acorn'
7
- import { cosmiconfig } from 'cosmiconfig'
8
- import type { CosmiconfigResult } from 'cosmiconfig/dist/types'
9
7
import type { AST } from 'eslint'
10
8
import type { EsprimaToken } from 'espree/lib/token-translator'
11
9
import type {
@@ -26,27 +24,22 @@ import type {
26
24
import type { Options } from 'micromark-extension-mdx-expression'
27
25
import type { Root } from 'remark-mdx'
28
26
import { extractProperties , runAsWorker } from 'synckit'
29
- import type { FrozenProcessor , Plugin } from 'unified'
27
+ import type { FrozenProcessor } from 'unified'
28
+ import type { Config , Configuration } from 'unified-engine/lib/configuration'
30
29
import type { Node } from 'unist'
31
30
import { ok as assert } from 'uvu/assert'
32
31
import type { VFileMessage } from 'vfile-message'
33
32
34
33
import {
35
- arrayify ,
36
34
loadEsmModule ,
37
35
nextCharOffsetFactory ,
38
36
normalizePosition ,
39
37
prevCharOffsetFactory ,
40
- requirePkg ,
41
38
} from './helpers'
42
39
import { restoreTokens } from './tokens'
43
- import type {
44
- NormalPosition ,
45
- RemarkConfig ,
46
- RemarkPlugin ,
47
- WorkerOptions ,
48
- WorkerResult ,
49
- } from './types'
40
+ import type { NormalPosition , WorkerOptions , WorkerResult } from './types'
41
+
42
+ let config : Configuration
50
43
51
44
let acorn : typeof import ( 'acorn' )
52
45
let acornJsx : {
@@ -60,12 +53,29 @@ let tt: Record<string, TokenType> & typeof _tokTypes
60
53
61
54
let TokenTranslator : typeof import ( 'espree/lib/token-translator' ) [ 'default' ]
62
55
63
- const explorer = cosmiconfig ( 'remark' , {
64
- packageProp : 'remarkConfig' ,
65
- } )
66
-
67
56
export const processorCache = new Map < string , FrozenProcessor > ( )
68
57
58
+ const getRemarkConfig = async ( searchFrom : string ) => {
59
+ if ( ! config ) {
60
+ const { Configuration } = await loadEsmModule <
61
+ typeof import ( 'unified-engine/lib/configuration' )
62
+ > ( 'unified-engine/lib/configuration.js' )
63
+ config = new Configuration ( {
64
+ cwd : process . cwd ( ) ,
65
+ packageField : 'remarkConfig' ,
66
+ pluginPrefix : 'remark' ,
67
+ rcName : '.remarkrc' ,
68
+ detectConfig : true ,
69
+ } )
70
+ }
71
+
72
+ return new Promise < Config > ( ( resolve , reject ) =>
73
+ config . load ( searchFrom , ( error , result ) =>
74
+ error ? reject ( error ) : resolve ( result ) ,
75
+ ) ,
76
+ )
77
+ }
78
+
69
79
const getRemarkMdxOptions = ( tokens : Token [ ] ) : Options => ( {
70
80
acorn : acornParser ,
71
81
acornOptions : {
@@ -83,7 +93,6 @@ export const getRemarkProcessor = async (
83
93
searchFrom : string ,
84
94
isMdx : boolean ,
85
95
ignoreRemarkConfig ?: boolean ,
86
- // eslint-disable-next-line sonarjs/cognitive-complexity
87
96
) => {
88
97
const initCacheKey = `${ String ( isMdx ) } -${ searchFrom } `
89
98
@@ -93,12 +102,10 @@ export const getRemarkProcessor = async (
93
102
return cachedProcessor
94
103
}
95
104
96
- const result : CosmiconfigResult = ignoreRemarkConfig
97
- ? null
98
- : await explorer . search ( searchFrom )
105
+ const result = ignoreRemarkConfig ? null : await getRemarkConfig ( searchFrom )
99
106
100
- const cacheKey = result
101
- ? `${ String ( isMdx ) } -${ result . filepath } `
107
+ const cacheKey = result ?. filePath
108
+ ? `${ String ( isMdx ) } -${ result . filePath } `
102
109
: String ( isMdx )
103
110
104
111
cachedProcessor = processorCache . get ( cacheKey )
@@ -120,19 +127,23 @@ export const getRemarkProcessor = async (
120
127
121
128
const remarkProcessor = unified ( ) . use ( remarkParse ) . freeze ( )
122
129
123
- if ( result ) {
124
- /* istanbul ignore next */
125
- const { plugins = [ ] , settings } =
126
- // type-coverage:ignore-next-line -- cosmiconfig's typings issue
127
- ( result . config || { } ) as Partial < RemarkConfig >
130
+ if ( result ?. filePath ) {
131
+ const { plugins, settings } = result
128
132
129
133
// disable this rule automatically since we already have a parser option `extensions`
130
134
// only disable this plugin if there are at least one plugin enabled
131
135
// otherwise it is redundant
132
136
/* istanbul ignore else */
133
137
if ( plugins . length > 0 ) {
134
138
try {
135
- plugins . push ( [ await requirePkg ( 'lint-file-extension' , 'remark' ) , false ] )
139
+ plugins . push ( [
140
+ (
141
+ await loadEsmModule < typeof import ( 'remark-lint-file-extension' ) > (
142
+ 'remark-lint-file-extension' ,
143
+ )
144
+ ) . default ,
145
+ false ,
146
+ ] )
136
147
} catch {
137
148
// just ignore if the package does not exist
138
149
}
@@ -146,21 +157,9 @@ export const getRemarkProcessor = async (
146
157
initProcessor . use ( remarkMdx , getRemarkMdxOptions ( sharedTokens ) )
147
158
}
148
159
149
- cachedProcessor = (
150
- await plugins . reduce ( async ( processor , pluginWithSettings ) => {
151
- const [ plugin , ...pluginSettings ] = arrayify ( pluginWithSettings ) as [
152
- RemarkPlugin ,
153
- ...unknown [ ] ,
154
- ]
155
- return ( await processor ) . use (
156
- /* istanbul ignore next */
157
- typeof plugin === 'string'
158
- ? await requirePkg < Plugin > ( plugin , 'remark' , result . filepath )
159
- : plugin ,
160
- ...pluginSettings ,
161
- )
162
- } , Promise . resolve ( initProcessor ) )
163
- ) . freeze ( )
160
+ cachedProcessor = plugins
161
+ . reduce ( ( processor , plugin ) => processor . use ( ...plugin ) , initProcessor )
162
+ . freeze ( )
164
163
} else {
165
164
const initProcessor = remarkProcessor ( ) . use ( remarkStringify )
166
165
0 commit comments