44 */
55"use strict"
66
7+ let typeMatchesSpecifier =
8+ /** @type {import('ts-declaration-location').default | undefined } */
9+ ( undefined )
10+
11+ try {
12+ typeMatchesSpecifier =
13+ /** @type {import('ts-declaration-location').default } */ (
14+ /** @type {unknown } */ ( require ( "ts-declaration-location" ) )
15+ )
16+
17+ // eslint-disable-next-line no-empty -- Deliberately left empty.
18+ } catch { }
19+ const getTypeOfNode = require ( "../util/get-type-of-node" )
20+ const getParserServices = require ( "../util/get-parser-services" )
21+ const getFullTypeName = require ( "../util/get-full-type-name" )
22+
723const selectors = [
824 // fs.readFileSync()
925 // readFileSync.call(null, 'path')
@@ -16,7 +32,7 @@ const selectors = [
1632 * @typedef {[
1733 * {
1834 * allowAtRootLevel?: boolean
19- * ignores?: string[]
35+ * ignores?: ( string | { from: "file"; path?: string; name?: string[]; } | { from: "package"; package?: string; name?: string[]; } | { from: "lib"; name?: string[]; }) []
2036 * }?
2137 * ]} RuleOptions
2238 */
@@ -40,7 +56,56 @@ module.exports = {
4056 } ,
4157 ignores : {
4258 type : "array" ,
43- items : { type : "string" } ,
59+ items : {
60+ oneOf : [
61+ { type : "string" } ,
62+ {
63+ type : "object" ,
64+ properties : {
65+ from : { const : "file" } ,
66+ path : {
67+ type : "string" ,
68+ } ,
69+ name : {
70+ type : "array" ,
71+ items : {
72+ type : "string" ,
73+ } ,
74+ } ,
75+ } ,
76+ additionalProperties : false ,
77+ } ,
78+ {
79+ type : "object" ,
80+ properties : {
81+ from : { const : "lib" } ,
82+ name : {
83+ type : "array" ,
84+ items : {
85+ type : "string" ,
86+ } ,
87+ } ,
88+ } ,
89+ additionalProperties : false ,
90+ } ,
91+ {
92+ type : "object" ,
93+ properties : {
94+ from : { const : "package" } ,
95+ package : {
96+ type : "string" ,
97+ } ,
98+ name : {
99+ type : "array" ,
100+ items : {
101+ type : "string" ,
102+ } ,
103+ } ,
104+ } ,
105+ additionalProperties : false ,
106+ } ,
107+ ] ,
108+ } ,
44109 default : [ ] ,
45110 } ,
46111 } ,
@@ -65,15 +130,70 @@ module.exports = {
65130 * @returns {void }
66131 */
67132 [ selector . join ( "," ) ] ( node ) {
68- if ( ignores . includes ( node . name ) ) {
69- return
133+ const parserServices = getParserServices ( context )
134+
135+ /**
136+ * @type {import('typescript').Type | undefined | null }
137+ */
138+ let type = undefined
139+
140+ /**
141+ * @type {string | undefined | null }
142+ */
143+ let fullName = undefined
144+
145+ for ( const ignore of ignores ) {
146+ if ( typeof ignore === "string" ) {
147+ if ( ignore === node . name ) {
148+ return
149+ }
150+
151+ continue
152+ }
153+
154+ if (
155+ parserServices === null ||
156+ parserServices . program === null
157+ ) {
158+ throw new Error (
159+ 'TypeScript parser services not available. Rule "n/no-sync" is configured to use "ignores" option with a non-string value. This requires TypeScript parser services to be available.'
160+ )
161+ }
162+
163+ if ( typeMatchesSpecifier === undefined ) {
164+ throw new Error (
165+ 'ts-declaration-location not available. Rule "n/no-sync" is configured to use "ignores" option with a non-string value. This requires ts-declaration-location to be available.'
166+ )
167+ }
168+
169+ type =
170+ type === undefined
171+ ? getTypeOfNode ( node , parserServices )
172+ : type
173+
174+ fullName =
175+ fullName === undefined
176+ ? getFullTypeName ( type )
177+ : fullName
178+
179+ if (
180+ typeMatchesSpecifier (
181+ parserServices . program ,
182+ ignore ,
183+ type
184+ ) &&
185+ ( ignore . name === undefined ||
186+ ignore . name . includes ( fullName ?? node . name ) )
187+ ) {
188+ return
189+ }
70190 }
71191
72192 context . report ( {
73193 node : node . parent ,
74194 messageId : "noSync" ,
75195 data : {
76- propertyName : node . name ,
196+ propertyName : fullName ?? node . name ,
77197 } ,
78198 } )
79199 } ,
0 commit comments