knip 6.35.0 → 6.36.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/dist/ConfigurationChief.d.ts +12 -0
- package/dist/IssueCollector.d.ts +3 -0
- package/dist/IssueCollector.js +5 -0
- package/dist/WorkspaceWorker.d.ts +3 -1
- package/dist/WorkspaceWorker.js +10 -5
- package/dist/binaries/command.js +2 -2
- package/dist/cli.js +4 -0
- package/dist/compilers/compilers.js +1 -1
- package/dist/compilers/scss.js +2 -2
- package/dist/graph/build.js +1 -0
- package/dist/graph-explorer/cache.d.ts +3 -0
- package/dist/graph-explorer/cache.js +6 -0
- package/dist/graph-explorer/explorer.d.ts +1 -0
- package/dist/graph-explorer/explorer.js +2 -0
- package/dist/graph-explorer/operations/build-exports-tree.js +14 -2
- package/dist/graph-explorer/operations/get-ambiguous-star-export.d.ts +8 -0
- package/dist/graph-explorer/operations/get-ambiguous-star-export.js +11 -0
- package/dist/graph-explorer/operations/get-contention.js +265 -122
- package/dist/graph-explorer/operations/resolve-export-origins.d.ts +32 -0
- package/dist/graph-explorer/operations/resolve-export-origins.js +255 -0
- package/dist/graph-explorer/utils.js +8 -0
- package/dist/index.d.ts +1 -0
- package/dist/plugins/eslint/helpers.js +31 -6
- package/dist/plugins/eslint/resolveFromAST.js +17 -11
- package/dist/plugins/eslint/types.d.ts +3 -3
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.js +4 -0
- package/dist/plugins/next/index.js +39 -5
- package/dist/plugins/node/index.js +6 -0
- package/dist/plugins/tailwind/compiler.js +2 -2
- package/dist/plugins/tailwind/index.js +7 -1
- package/dist/plugins/textlint/helpers.d.ts +4 -0
- package/dist/plugins/textlint/helpers.js +39 -0
- package/dist/plugins/textlint/index.d.ts +3 -0
- package/dist/plugins/textlint/index.js +52 -0
- package/dist/plugins/textlint/types.d.ts +5 -0
- package/dist/plugins/textlint/types.js +1 -0
- package/dist/plugins/typedoc/index.js +3 -2
- package/dist/plugins/typedoc/types.d.ts +2 -2
- package/dist/plugins/varlock/index.d.ts +3 -0
- package/dist/plugins/varlock/index.js +31 -0
- package/dist/plugins/varlock/parse.d.ts +11 -0
- package/dist/plugins/varlock/parse.js +185 -0
- package/dist/plugins/varlock/scan.d.ts +2 -0
- package/dist/plugins/varlock/scan.js +78 -0
- package/dist/plugins/vitest/index.js +4 -2
- package/dist/reporters/trace.js +30 -1
- package/dist/reporters/util/configuration-hints.d.ts +1 -1
- package/dist/reporters/util/configuration-hints.js +11 -2
- package/dist/run.d.ts +2 -0
- package/dist/run.js +2 -1
- package/dist/schema/configuration.d.ts +30 -0
- package/dist/schema/plugins.d.ts +10 -0
- package/dist/schema/plugins.js +2 -0
- package/dist/session/build-maps.js +9 -1
- package/dist/session/file-descriptor.js +0 -2
- package/dist/session/index.d.ts +1 -1
- package/dist/session/types.d.ts +18 -0
- package/dist/types/PluginNames.d.ts +2 -2
- package/dist/types/PluginNames.js +2 -0
- package/dist/types/config.d.ts +1 -0
- package/dist/types/issues.d.ts +1 -0
- package/dist/types/module-graph.d.ts +3 -0
- package/dist/typescript/get-imports-and-exports.js +43 -9
- package/dist/typescript/resolve-module-names.js +7 -27
- package/dist/typescript/visitors/exports.js +9 -4
- package/dist/typescript/visitors/walk.d.ts +1 -1
- package/dist/typescript/visitors/walk.js +4 -1
- package/dist/util/array.d.ts +1 -1
- package/dist/util/array.js +5 -1
- package/dist/util/create-options.d.ts +20 -0
- package/dist/util/file-entry-cache.js +1 -1
- package/dist/util/glob-core.d.ts +1 -0
- package/dist/util/glob-core.js +11 -3
- package/dist/util/package-json.d.ts +2 -0
- package/dist/util/url.d.ts +1 -0
- package/dist/util/url.js +2 -0
- package/dist/util/watch.d.ts +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/schema.json +8 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { isBuiltin } from 'node:module';
|
|
2
|
+
import { IMPORT_FLAGS, IMPORT_STAR } from '../../constants.js';
|
|
3
|
+
import { getCachedExportTable, setCachedExportTable } from '../cache.js';
|
|
4
|
+
import { forEachAliasReExport, forEachNamespaceReExport, forEachPassThroughReExport, getStarReExportSources, } from '../visitors.js';
|
|
5
|
+
const originKey = (origin) => origin.filePath + '\0' + origin.identifier;
|
|
6
|
+
const isExplicit = (info, name) => info.node?.exports.has(name) || info.terminals.has(name);
|
|
7
|
+
export const createExportResolver = (graph) => {
|
|
8
|
+
const infos = new Map();
|
|
9
|
+
const getInfo = (filePath) => {
|
|
10
|
+
const cached = infos.get(filePath);
|
|
11
|
+
if (cached)
|
|
12
|
+
return cached;
|
|
13
|
+
const node = graph.get(filePath);
|
|
14
|
+
const info = { node, references: new Map(), terminals: new Map(), stars: [] };
|
|
15
|
+
infos.set(filePath, info);
|
|
16
|
+
if (!node)
|
|
17
|
+
return info;
|
|
18
|
+
const add = (map, name, origin) => {
|
|
19
|
+
const list = map.get(name);
|
|
20
|
+
if (list)
|
|
21
|
+
list.push(origin);
|
|
22
|
+
else
|
|
23
|
+
map.set(name, [origin]);
|
|
24
|
+
};
|
|
25
|
+
for (const [sourcePath, imports] of node.imports.internal) {
|
|
26
|
+
if (getStarReExportSources(imports))
|
|
27
|
+
info.stars.push(sourcePath);
|
|
28
|
+
forEachNamespaceReExport(imports, name => {
|
|
29
|
+
const exp = node.exports.get(name);
|
|
30
|
+
if (!exp || exp.isBindingReExport)
|
|
31
|
+
add(info.terminals, name, { filePath: sourcePath, identifier: IMPORT_STAR });
|
|
32
|
+
});
|
|
33
|
+
forEachPassThroughReExport(imports, name => {
|
|
34
|
+
if (node.exports.get(name)?.isBindingReExport)
|
|
35
|
+
add(info.references, name, { filePath: sourcePath, identifier: name });
|
|
36
|
+
});
|
|
37
|
+
forEachAliasReExport(imports, (identifier, alias) => {
|
|
38
|
+
if (node.exports.get(alias)?.isBindingReExport)
|
|
39
|
+
add(info.references, alias, { filePath: sourcePath, identifier });
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const addExternal = (record) => {
|
|
43
|
+
if (!(record.modifiers & IMPORT_FLAGS.RE_EXPORT) || !record.identifier)
|
|
44
|
+
return;
|
|
45
|
+
const name = record.alias ?? record.identifier;
|
|
46
|
+
const exp = node.exports.get(name);
|
|
47
|
+
if ((!exp && !(record.identifier === IMPORT_STAR && record.alias)) ||
|
|
48
|
+
(record.isTypeOnly && exp && !exp.isBindingReExport) ||
|
|
49
|
+
info.references.has(name))
|
|
50
|
+
return;
|
|
51
|
+
add(info.terminals, name, { filePath: record.specifier, identifier: record.identifier });
|
|
52
|
+
};
|
|
53
|
+
for (const record of node.imports.external)
|
|
54
|
+
addExternal(record);
|
|
55
|
+
for (const record of node.imports.imports)
|
|
56
|
+
if (isBuiltin(record.specifier))
|
|
57
|
+
addExternal(record);
|
|
58
|
+
return info;
|
|
59
|
+
};
|
|
60
|
+
const build = (filePath, identifier) => {
|
|
61
|
+
const states = new Map();
|
|
62
|
+
const discovery = [];
|
|
63
|
+
const updates = [];
|
|
64
|
+
const request = (path, name) => {
|
|
65
|
+
let state = states.get(path);
|
|
66
|
+
if (!state) {
|
|
67
|
+
state = {
|
|
68
|
+
filePath: path,
|
|
69
|
+
info: getInfo(path),
|
|
70
|
+
names: new Set(),
|
|
71
|
+
all: false,
|
|
72
|
+
entries: new Map(),
|
|
73
|
+
dependents: new Map(),
|
|
74
|
+
pending: new Set(),
|
|
75
|
+
};
|
|
76
|
+
states.set(path, state);
|
|
77
|
+
}
|
|
78
|
+
if (state.all || (name !== undefined && state.names.has(name)))
|
|
79
|
+
return state;
|
|
80
|
+
if (name === undefined)
|
|
81
|
+
state.all = true;
|
|
82
|
+
else
|
|
83
|
+
state.names.add(name);
|
|
84
|
+
discovery.push([state, name]);
|
|
85
|
+
return state;
|
|
86
|
+
};
|
|
87
|
+
const merge = (state, name, origins) => {
|
|
88
|
+
let entry = state.entries.get(name);
|
|
89
|
+
let changed = false;
|
|
90
|
+
if (!entry) {
|
|
91
|
+
entry = { origins, hasExplicitExport: !!isExplicit(state.info, name) };
|
|
92
|
+
state.entries.set(name, entry);
|
|
93
|
+
changed = origins.size > 0;
|
|
94
|
+
}
|
|
95
|
+
else if (entry.origins.size === 0) {
|
|
96
|
+
entry.origins = origins;
|
|
97
|
+
changed = origins.size > 0;
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
let merged;
|
|
101
|
+
for (const [key, origin] of origins) {
|
|
102
|
+
if (!entry.origins.has(key))
|
|
103
|
+
(merged ??= new Map(entry.origins)).set(key, origin);
|
|
104
|
+
}
|
|
105
|
+
if (merged) {
|
|
106
|
+
entry.origins = merged;
|
|
107
|
+
changed = true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (changed) {
|
|
111
|
+
if (state.pending.size === 0)
|
|
112
|
+
updates.push(state);
|
|
113
|
+
state.pending.add(name);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const connect = (source, target, sourceName, targetName) => {
|
|
117
|
+
let edge = source.dependents.get(target);
|
|
118
|
+
if (!edge)
|
|
119
|
+
source.dependents.set(target, (edge = { star: false, aliases: new Map() }));
|
|
120
|
+
if (sourceName === undefined || targetName === undefined)
|
|
121
|
+
edge.star = true;
|
|
122
|
+
else {
|
|
123
|
+
let aliases = edge.aliases.get(sourceName);
|
|
124
|
+
if (!aliases)
|
|
125
|
+
edge.aliases.set(sourceName, (aliases = new Set()));
|
|
126
|
+
aliases.add(targetName);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
request(filePath, identifier);
|
|
130
|
+
for (let index = 0; index < discovery.length; index++) {
|
|
131
|
+
const [state, name] = discovery[index];
|
|
132
|
+
const cached = getCachedExportTable(graph, state.filePath);
|
|
133
|
+
if (name === undefined && cached?.complete) {
|
|
134
|
+
for (const [id, entry] of cached.entries)
|
|
135
|
+
merge(state, id, entry.origins);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const seed = (id) => {
|
|
139
|
+
const entry = cached?.entries.get(id);
|
|
140
|
+
if (entry) {
|
|
141
|
+
merge(state, id, entry.origins);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const terminals = state.info.terminals.get(id);
|
|
145
|
+
const references = state.info.references.get(id);
|
|
146
|
+
const exp = state.info.node?.exports.get(id);
|
|
147
|
+
if (terminals || exp) {
|
|
148
|
+
const origins = new Map();
|
|
149
|
+
if (terminals)
|
|
150
|
+
for (const origin of terminals)
|
|
151
|
+
origins.set(originKey(origin), origin);
|
|
152
|
+
else if (exp && !exp.isBindingReExport) {
|
|
153
|
+
const origin = { filePath: state.filePath, identifier: exp.binding };
|
|
154
|
+
origins.set(originKey(origin), origin);
|
|
155
|
+
}
|
|
156
|
+
merge(state, id, origins);
|
|
157
|
+
}
|
|
158
|
+
if (references)
|
|
159
|
+
for (const source of references)
|
|
160
|
+
connect(request(source.filePath, source.identifier), state, source.identifier, id);
|
|
161
|
+
};
|
|
162
|
+
if (name === undefined) {
|
|
163
|
+
if (state.info.node)
|
|
164
|
+
for (const id of state.info.node.exports.keys())
|
|
165
|
+
seed(id);
|
|
166
|
+
for (const id of state.info.terminals.keys())
|
|
167
|
+
if (!state.info.node?.exports.has(id))
|
|
168
|
+
seed(id);
|
|
169
|
+
for (const source of state.info.stars)
|
|
170
|
+
connect(request(source), state);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
seed(name);
|
|
174
|
+
if (cached?.complete || cached?.entries.has(name) || isExplicit(state.info, name) || name === 'default')
|
|
175
|
+
continue;
|
|
176
|
+
for (const source of state.info.stars)
|
|
177
|
+
connect(request(source, name), state);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
for (let index = 0; index < updates.length; index++) {
|
|
181
|
+
const state = updates[index];
|
|
182
|
+
const names = state.pending;
|
|
183
|
+
state.pending = new Set();
|
|
184
|
+
for (const [target, edge] of state.dependents) {
|
|
185
|
+
for (const name of names) {
|
|
186
|
+
const entry = state.entries.get(name);
|
|
187
|
+
if (!entry)
|
|
188
|
+
continue;
|
|
189
|
+
if (edge.star &&
|
|
190
|
+
name !== 'default' &&
|
|
191
|
+
!isExplicit(target.info, name) &&
|
|
192
|
+
(target.all || target.names.has(name)))
|
|
193
|
+
merge(target, name, entry.origins);
|
|
194
|
+
const aliases = edge.aliases.get(name);
|
|
195
|
+
if (aliases)
|
|
196
|
+
for (const alias of aliases)
|
|
197
|
+
merge(target, alias, entry.origins);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
for (const state of states.values()) {
|
|
202
|
+
const cached = getCachedExportTable(graph, state.filePath);
|
|
203
|
+
if (cached && !state.all) {
|
|
204
|
+
for (const [name, entry] of state.entries)
|
|
205
|
+
cached.entries.set(name, entry);
|
|
206
|
+
}
|
|
207
|
+
else
|
|
208
|
+
setCachedExportTable(graph, state.filePath, { entries: state.entries, complete: state.all });
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
const getTable = (filePath) => {
|
|
212
|
+
if (!getCachedExportTable(graph, filePath)?.complete)
|
|
213
|
+
build(filePath);
|
|
214
|
+
return getCachedExportTable(graph, filePath)?.entries ?? new Map();
|
|
215
|
+
};
|
|
216
|
+
const resolve = (filePath, identifier) => {
|
|
217
|
+
const cached = getCachedExportTable(graph, filePath);
|
|
218
|
+
if (!cached?.complete && !cached?.entries.has(identifier))
|
|
219
|
+
build(filePath, identifier);
|
|
220
|
+
return getCachedExportTable(graph, filePath)?.entries.get(identifier);
|
|
221
|
+
};
|
|
222
|
+
const getSources = (filePath, identifier) => {
|
|
223
|
+
const info = getInfo(filePath);
|
|
224
|
+
if (isExplicit(info, identifier))
|
|
225
|
+
return info.references.get(identifier) ?? [];
|
|
226
|
+
return identifier === 'default' ? [] : info.stars.map(source => ({ filePath: source, identifier }));
|
|
227
|
+
};
|
|
228
|
+
const reachesOrigin = (source, origin, site) => {
|
|
229
|
+
const visited = new Set([originKey(site)]);
|
|
230
|
+
const queue = [source];
|
|
231
|
+
const key = originKey(origin);
|
|
232
|
+
for (let index = 0; index < queue.length; index++) {
|
|
233
|
+
const current = queue[index];
|
|
234
|
+
const currentKey = originKey(current);
|
|
235
|
+
if (visited.has(currentKey))
|
|
236
|
+
continue;
|
|
237
|
+
visited.add(currentKey);
|
|
238
|
+
if (current.identifier === IMPORT_STAR && currentKey === key)
|
|
239
|
+
return true;
|
|
240
|
+
const info = getInfo(current.filePath);
|
|
241
|
+
const exp = info.node?.exports.get(current.identifier);
|
|
242
|
+
if (info.terminals.get(current.identifier)?.some(value => originKey(value) === key))
|
|
243
|
+
return true;
|
|
244
|
+
if (exp && !exp.isBindingReExport && originKey({ filePath: current.filePath, identifier: exp.binding }) === key)
|
|
245
|
+
return true;
|
|
246
|
+
queue.push(...getSources(current.filePath, current.identifier));
|
|
247
|
+
}
|
|
248
|
+
return false;
|
|
249
|
+
};
|
|
250
|
+
return { getTable, resolve, getInfo, reachesOrigin };
|
|
251
|
+
};
|
|
252
|
+
export const resolveExportOrigins = (graph, filePath, identifier) => {
|
|
253
|
+
const entry = createExportResolver(graph).resolve(filePath, identifier);
|
|
254
|
+
return { origins: entry ? [...entry.origins.values()] : [], hasExplicitExport: entry?.hasExplicitExport ?? false };
|
|
255
|
+
};
|
|
@@ -27,6 +27,14 @@ export const getExportedIdentifiers = (graph, filePath, visited = new Set()) =>
|
|
|
27
27
|
continue;
|
|
28
28
|
addIdentifier(identifier);
|
|
29
29
|
}
|
|
30
|
+
for (const _import of node.imports.imports) {
|
|
31
|
+
if (!_import.filePath &&
|
|
32
|
+
_import.modifiers & IMPORT_FLAGS.RE_EXPORT &&
|
|
33
|
+
_import.identifier === IMPORT_STAR &&
|
|
34
|
+
_import.alias) {
|
|
35
|
+
addIdentifier(_import.alias, true);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
30
38
|
if (node.imports?.internal) {
|
|
31
39
|
for (const [importedPath, importDetails] of node.imports.internal) {
|
|
32
40
|
forEachPassThroughReExport(importDetails, (id, _sources) => {
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export declare const main: (options: MainOptions) => Promise<{
|
|
|
4
4
|
counters: import("./types/issues.ts").Counters;
|
|
5
5
|
tagHints: Set<import("./types/issues.ts").TagHint>;
|
|
6
6
|
configurationHints: import("./types/issues.ts").ConfigurationHint[];
|
|
7
|
+
hasConfigLoadErrors: boolean;
|
|
7
8
|
selectedWorkspaces: string[] | undefined;
|
|
8
9
|
includedWorkspaceDirs: string[];
|
|
9
10
|
enabledPlugins: {
|
|
@@ -16,20 +16,36 @@ export const getInputs = (config, options) => {
|
|
|
16
16
|
return compact(dependencies).map(id => toDeferResolve(id, { optional: true }));
|
|
17
17
|
};
|
|
18
18
|
const getInputsDeprecated = (config, options) => {
|
|
19
|
-
const
|
|
19
|
+
const extendsList = config.extends ? [config.extends].flat() : [];
|
|
20
|
+
const extendsSpecifiers = compact(extendsList.map(resolveExtendSpecifier));
|
|
20
21
|
if (extendsSpecifiers.some(specifier => specifier?.startsWith('eslint-plugin-prettier')))
|
|
21
22
|
extendsSpecifiers.push('eslint-config-prettier');
|
|
22
|
-
const extendConfigs = extendsSpecifiers.map(specifier => toConfig('eslint', specifier, { containingFilePath: options.configFilePath }));
|
|
23
|
+
const extendConfigs = [...extendsList.filter(isInternal), ...extendsSpecifiers].map(specifier => toConfig('eslint', specifier, { containingFilePath: options.configFilePath }));
|
|
23
24
|
const plugins = config.plugins ? config.plugins.map(resolvePluginSpecifier) : [];
|
|
24
|
-
const
|
|
25
|
+
const parsers = getParsers(config);
|
|
25
26
|
const babelDependencies = config.parserOptions?.babelOptions
|
|
26
27
|
? getDependenciesFromConfig(config.parserOptions.babelOptions)
|
|
27
28
|
: [];
|
|
28
29
|
const settings = config.settings ? getDependenciesFromSettings(config.settings) : [];
|
|
29
30
|
const rules = getDependenciesFromRules({});
|
|
30
31
|
const overrides = config.overrides ? [config.overrides].flat().flatMap(d => getInputsDeprecated(d, options)) : [];
|
|
31
|
-
const deferred = compact([...extendsSpecifiers, ...plugins,
|
|
32
|
-
return [...extendConfigs, ...deferred, ...babelDependencies, ...overrides];
|
|
32
|
+
const deferred = compact([...extendsSpecifiers, ...plugins, ...settings, ...rules]).map(id => toDeferResolve(id));
|
|
33
|
+
return [...extendConfigs, ...deferred, ...parsers, ...babelDependencies, ...overrides];
|
|
34
|
+
};
|
|
35
|
+
const isParserObject = (value) => typeof value.parseForESLint === 'function' || typeof value.parse === 'function';
|
|
36
|
+
const toParser = (name) => toDeferResolve(name, name === 'espree' ? { optional: true } : {});
|
|
37
|
+
const getParsers = ({ parser, parserOptions }) => {
|
|
38
|
+
const inputs = [];
|
|
39
|
+
for (const value of [parser, parserOptions?.parser]) {
|
|
40
|
+
if (typeof value === 'string')
|
|
41
|
+
inputs.push(toParser(value));
|
|
42
|
+
else if (value && typeof value === 'object' && !isParserObject(value)) {
|
|
43
|
+
for (const name of Object.values(value))
|
|
44
|
+
if (typeof name === 'string')
|
|
45
|
+
inputs.push(toParser(name));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return inputs;
|
|
33
49
|
};
|
|
34
50
|
const isQualifiedSpecifier = (specifier) => specifier === 'eslint' ||
|
|
35
51
|
/\/eslint-(config|plugin)$/.test(specifier) ||
|
|
@@ -58,10 +74,19 @@ const resolveExtendSpecifier = (specifier) => {
|
|
|
58
74
|
return resolveSpecifier(namespace, specifier);
|
|
59
75
|
};
|
|
60
76
|
const getDependenciesFromRules = (rules = {}) => Object.keys(rules).flatMap(ruleKey => ruleKey.includes('/') ? [resolveSpecifier('eslint-plugin', ruleKey.split('/').slice(0, -1).join('/'))] : []);
|
|
77
|
+
const getResolverNames = (value) => {
|
|
78
|
+
if (typeof value === 'string')
|
|
79
|
+
return [value];
|
|
80
|
+
if (Array.isArray(value))
|
|
81
|
+
return value.flatMap(getResolverNames);
|
|
82
|
+
if (value && typeof value === 'object')
|
|
83
|
+
return Object.keys(value);
|
|
84
|
+
return [];
|
|
85
|
+
};
|
|
61
86
|
const getDependenciesFromSettings = (settings = {}) => {
|
|
62
87
|
return Object.entries(settings).flatMap(([settingKey, settings]) => {
|
|
63
88
|
if (settingKey === 'import/resolver') {
|
|
64
|
-
return (
|
|
89
|
+
return getResolverNames(settings)
|
|
65
90
|
.filter(key => key !== 'node')
|
|
66
91
|
.map(key => {
|
|
67
92
|
if (isInternal(key))
|
|
@@ -11,6 +11,21 @@ export const getInputsFromSettingsAST = (program) => {
|
|
|
11
11
|
const dep = key === 'import/resolver' ? `eslint-import-resolver-${resolver}` : resolver;
|
|
12
12
|
inputs.push(toDeferResolve(dep, { optional: true }));
|
|
13
13
|
};
|
|
14
|
+
const addResolvers = (key, node) => {
|
|
15
|
+
if (node?.type === 'ArrayExpression') {
|
|
16
|
+
for (const element of node.elements)
|
|
17
|
+
addResolvers(key, element);
|
|
18
|
+
}
|
|
19
|
+
else if (node?.type === 'ObjectExpression') {
|
|
20
|
+
for (const prop of node.properties) {
|
|
21
|
+
if (prop.type === 'Property')
|
|
22
|
+
addResolver(key, getPropertyKey(prop));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
addResolver(key, getStringValue(node));
|
|
27
|
+
}
|
|
28
|
+
};
|
|
14
29
|
const visitor = new Visitor({
|
|
15
30
|
ObjectExpression(node) {
|
|
16
31
|
const settingsNode = findProperty(node, 'settings');
|
|
@@ -20,17 +35,8 @@ export const getInputsFromSettingsAST = (program) => {
|
|
|
20
35
|
if (prop.type !== 'Property')
|
|
21
36
|
continue;
|
|
22
37
|
const key = getPropertyKey(prop);
|
|
23
|
-
if (key
|
|
24
|
-
|
|
25
|
-
if (prop.value?.type === 'ObjectExpression') {
|
|
26
|
-
for (const p of prop.value.properties ?? []) {
|
|
27
|
-
if (p.type === 'Property')
|
|
28
|
-
addResolver(key, getPropertyKey(p));
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
addResolver(key, getStringValue(prop.value));
|
|
33
|
-
}
|
|
38
|
+
if (key === 'import/resolver' || key === 'import/parsers')
|
|
39
|
+
addResolvers(key, prop.value);
|
|
34
40
|
}
|
|
35
41
|
},
|
|
36
42
|
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
type ParserOptions = {
|
|
2
2
|
project?: string;
|
|
3
|
-
parser?: string
|
|
3
|
+
parser?: string | Record<string, unknown>;
|
|
4
4
|
babelOptions?: {
|
|
5
5
|
plugins: string[];
|
|
6
6
|
presets: string[];
|
|
7
7
|
};
|
|
8
8
|
};
|
|
9
|
-
export type Settings = Record<string, Record<string, unknown> | string>;
|
|
9
|
+
export type Settings = Record<string, Record<string, unknown> | string | unknown[]>;
|
|
10
10
|
type Rules = Record<string, string | number>;
|
|
11
|
-
type BaseConfig = {
|
|
11
|
+
export type BaseConfig = {
|
|
12
12
|
extends?: string | string[];
|
|
13
13
|
parser?: string;
|
|
14
14
|
parserOptions?: ParserOptions;
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -150,6 +150,7 @@ export declare const Plugins: {
|
|
|
150
150
|
taskfile: import("../types/config.ts").Plugin;
|
|
151
151
|
tauri: import("../types/config.ts").Plugin;
|
|
152
152
|
temporal: import("../types/config.ts").Plugin;
|
|
153
|
+
textlint: import("../types/config.ts").Plugin;
|
|
153
154
|
travis: import("../types/config.ts").Plugin;
|
|
154
155
|
'ts-node': import("../types/config.ts").Plugin;
|
|
155
156
|
tsd: import("../types/config.ts").Plugin;
|
|
@@ -166,6 +167,7 @@ export declare const Plugins: {
|
|
|
166
167
|
'unplugin-vue-i18n': import("../types/config.ts").Plugin;
|
|
167
168
|
'unplugin-vue-markdown': import("../types/config.ts").Plugin;
|
|
168
169
|
'unplugin-vue-router': import("../types/config.ts").Plugin;
|
|
170
|
+
varlock: import("../types/config.ts").Plugin;
|
|
169
171
|
vercel: import("../types/config.ts").Plugin;
|
|
170
172
|
'vercel-og': import("../types/config.ts").Plugin;
|
|
171
173
|
vike: import("../types/config.ts").Plugin;
|
package/dist/plugins/index.js
CHANGED
|
@@ -144,6 +144,7 @@ import { default as tanstackRouter } from './tanstack-router/index.js';
|
|
|
144
144
|
import { default as taskfile } from './taskfile/index.js';
|
|
145
145
|
import { default as tauri } from './tauri/index.js';
|
|
146
146
|
import { default as temporal } from './temporal/index.js';
|
|
147
|
+
import { default as textlint } from './textlint/index.js';
|
|
147
148
|
import { default as travis } from './travis/index.js';
|
|
148
149
|
import { default as tsNode } from './ts-node/index.js';
|
|
149
150
|
import { default as tsd } from './tsd/index.js';
|
|
@@ -160,6 +161,7 @@ import { default as unpluginVueComponents } from './unplugin-vue-components/inde
|
|
|
160
161
|
import { default as unpluginVueI18n } from './unplugin-vue-i18n/index.js';
|
|
161
162
|
import { default as unpluginVueMarkdown } from './unplugin-vue-markdown/index.js';
|
|
162
163
|
import { default as unpluginVueRouter } from './unplugin-vue-router/index.js';
|
|
164
|
+
import { default as varlock } from './varlock/index.js';
|
|
163
165
|
import { default as vercel } from './vercel/index.js';
|
|
164
166
|
import { default as vercelOg } from './vercel-og/index.js';
|
|
165
167
|
import { default as vike } from './vike/index.js';
|
|
@@ -328,6 +330,7 @@ export const Plugins = {
|
|
|
328
330
|
taskfile,
|
|
329
331
|
tauri,
|
|
330
332
|
temporal,
|
|
333
|
+
textlint,
|
|
331
334
|
travis,
|
|
332
335
|
'ts-node': tsNode,
|
|
333
336
|
tsd,
|
|
@@ -344,6 +347,7 @@ export const Plugins = {
|
|
|
344
347
|
'unplugin-vue-i18n': unpluginVueI18n,
|
|
345
348
|
'unplugin-vue-markdown': unpluginVueMarkdown,
|
|
346
349
|
'unplugin-vue-router': unpluginVueRouter,
|
|
350
|
+
varlock,
|
|
347
351
|
vercel,
|
|
348
352
|
'vercel-og': vercelOg,
|
|
349
353
|
vike,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Visitor } from 'oxc-parser';
|
|
2
|
+
import { findProperty, getPropertyValues } from '../../typescript/ast-helpers.js';
|
|
3
|
+
import { getStringValue } from '../../typescript/ast-nodes.js';
|
|
2
4
|
import { isDirectory } from '../../util/fs.js';
|
|
3
|
-
import { toConfig, toProductionEntry } from '../../util/input.js';
|
|
5
|
+
import { toConfig, toDeferResolve, toProductionEntry } from '../../util/input.js';
|
|
4
6
|
import { join } from '../../util/path.js';
|
|
5
7
|
import { hasDependency } from '../../util/plugin.js';
|
|
6
8
|
const title = 'Next.js';
|
|
@@ -38,10 +40,42 @@ const getEntryFilePatterns = (pageExtensions = defaultPageExtensions, cwd) => {
|
|
|
38
40
|
};
|
|
39
41
|
const production = getEntryFilePatterns();
|
|
40
42
|
const resolveFromAST = (program, { configFileDir }) => {
|
|
41
|
-
const pageExtensions =
|
|
42
|
-
const
|
|
43
|
+
const pageExtensions = new Set();
|
|
44
|
+
const loaders = new Set();
|
|
45
|
+
const collectLoaders = (node) => {
|
|
46
|
+
if (node?.type === 'ArrayExpression') {
|
|
47
|
+
for (const element of node.elements)
|
|
48
|
+
collectLoaders(element);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
const loader = getStringValue(node) ?? getStringValue(findProperty(node, 'loader'));
|
|
52
|
+
if (loader)
|
|
53
|
+
loaders.add(loader);
|
|
54
|
+
const nested = findProperty(node, 'loaders');
|
|
55
|
+
if (nested?.type === 'ArrayExpression')
|
|
56
|
+
collectLoaders(nested);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const visitor = new Visitor({
|
|
60
|
+
ObjectExpression(node) {
|
|
61
|
+
for (const extension of getPropertyValues(node, 'pageExtensions'))
|
|
62
|
+
pageExtensions.add(extension);
|
|
63
|
+
const rules = findProperty(findProperty(node, 'turbopack'), 'rules');
|
|
64
|
+
if (rules?.type !== 'ObjectExpression')
|
|
65
|
+
return;
|
|
66
|
+
for (const rule of rules.properties) {
|
|
67
|
+
if (rule.type === 'Property')
|
|
68
|
+
collectLoaders(rule.value);
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
visitor.visit(program);
|
|
73
|
+
const extensions = pageExtensions.size > 0 ? [...pageExtensions] : defaultPageExtensions;
|
|
43
74
|
const patterns = [...getEntryFilePatterns(extensions, configFileDir), 'next-env.d.ts'];
|
|
44
|
-
|
|
75
|
+
const inputs = patterns.map(id => toProductionEntry(join(configFileDir, id)));
|
|
76
|
+
for (const loader of loaders)
|
|
77
|
+
inputs.push(toDeferResolve(loader));
|
|
78
|
+
return inputs;
|
|
45
79
|
};
|
|
46
80
|
const commands = new Set(['dev', 'build', 'start']);
|
|
47
81
|
const args = {
|
|
@@ -38,12 +38,18 @@ const args = {
|
|
|
38
38
|
resolve: ['test-reporter'],
|
|
39
39
|
boolean: [
|
|
40
40
|
'deprecation',
|
|
41
|
+
'enable-source-maps',
|
|
42
|
+
'experimental-detect-module',
|
|
43
|
+
'experimental-json-modules',
|
|
41
44
|
'experimental-strip-types',
|
|
42
45
|
'experimental-transform-types',
|
|
46
|
+
'experimental-vm-modules',
|
|
47
|
+
'expose-gc',
|
|
43
48
|
'harmony',
|
|
44
49
|
'inspect-brk',
|
|
45
50
|
'inspect-wait',
|
|
46
51
|
'inspect',
|
|
52
|
+
'openssl-legacy-provider',
|
|
47
53
|
'test-only',
|
|
48
54
|
'test',
|
|
49
55
|
'warnings',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { hasUrlScheme } from '../../util/url.js';
|
|
1
2
|
const directiveMatcher = /"(?:\\(?:\r\n|[\s\S]|$)|[^"\\\r\n\f])*(?:"|[\r\n\f]|$)|'(?:\\(?:\r\n|[\s\S]|$)|[^'\\\r\n\f])*(?:'|[\r\n\f]|$)|\/\*[\s\S]*?(?:\*\/|$)|@(?:(?:import|config|plugin)\s+['"]([^'"]+)['"]|import\s+url\(\s*(?:['"]([^'"]+)['"]|([^'")\s]+))\s*\))[^;]*;/g;
|
|
2
|
-
const urlSchemeMatcher = /^[a-z][a-z\d+.-]*:/i;
|
|
3
3
|
const compiler = (text) => {
|
|
4
4
|
if (!text.includes('@import') && !text.includes('@config') && !text.includes('@plugin'))
|
|
5
5
|
return '';
|
|
@@ -10,7 +10,7 @@ const compiler = (text) => {
|
|
|
10
10
|
while ((match = directiveMatcher.exec(text))) {
|
|
11
11
|
const url = match[2] ?? match[3];
|
|
12
12
|
const specifier = match[1] ?? url;
|
|
13
|
-
if (!specifier || (url && (url.startsWith('//') ||
|
|
13
|
+
if (!specifier || (url && (url.startsWith('//') || hasUrlScheme(url))))
|
|
14
14
|
continue;
|
|
15
15
|
imports.push(`import _$${index++} from '${specifier}';`);
|
|
16
16
|
}
|
|
@@ -2,7 +2,13 @@ import { toProductionEntry } from '../../util/input.js';
|
|
|
2
2
|
import { hasDependency } from '../../util/plugin.js';
|
|
3
3
|
import compiler from './compiler.js';
|
|
4
4
|
const title = 'Tailwind';
|
|
5
|
-
const enablers = [
|
|
5
|
+
const enablers = [
|
|
6
|
+
'tailwindcss',
|
|
7
|
+
'@tailwindcss/vite',
|
|
8
|
+
'@tailwindcss/webpack',
|
|
9
|
+
'@tailwindcss/postcss',
|
|
10
|
+
'@tailwindcss/cli',
|
|
11
|
+
];
|
|
6
12
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
7
13
|
const entry = ['tailwind.config.{js,cjs,mjs,ts,cts,mts}'];
|
|
8
14
|
const registerCompilers = ({ registerCompiler, hasDependency }) => {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Manifest } from '../../util/package-json.ts';
|
|
2
|
+
export declare const toRuleDependency: (key: string, manifest: Manifest, cwd: string) => import("../../util/input.ts").Input;
|
|
3
|
+
export declare const toFilterRuleDependency: (key: string, manifest: Manifest, cwd: string) => import("../../util/input.ts").Input;
|
|
4
|
+
export declare const toPluginDependency: (key: string, manifest: Manifest, cwd: string) => import("../../util/input.ts").Input;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { toDependency, toDeferResolveEntry } from '../../util/input.js';
|
|
2
|
+
import { isInternal, toAbsolute } from '../../util/path.js';
|
|
3
|
+
const RULE_PREFIX = 'textlint-rule-';
|
|
4
|
+
const PRESET_PREFIX = 'textlint-rule-preset-';
|
|
5
|
+
const FILTER_RULE_PREFIX = 'textlint-filter-rule-';
|
|
6
|
+
const PLUGIN_PREFIX = 'textlint-plugin-';
|
|
7
|
+
const createFullPackageName = (prefix, name) => {
|
|
8
|
+
if (name.charAt(0) === '@') {
|
|
9
|
+
const scopedName = name.slice(name.indexOf('/') + 1);
|
|
10
|
+
if (scopedName !== prefix && !scopedName.startsWith(`${prefix}-`)) {
|
|
11
|
+
return name.replace(/^@([^/]+)\/(.*)$/, `@$1/${prefix}$2`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return `${prefix}${name}`;
|
|
15
|
+
};
|
|
16
|
+
const hasPrefix = (prefix, name) => (name.charAt(0) === '@' ? name.slice(name.indexOf('/') + 1) : name).startsWith(prefix);
|
|
17
|
+
const isDeclared = (manifest, name) => Boolean(manifest.dependencies?.[name] ??
|
|
18
|
+
manifest.devDependencies?.[name] ??
|
|
19
|
+
manifest.optionalDependencies?.[name] ??
|
|
20
|
+
manifest.peerDependencies?.[name]);
|
|
21
|
+
const toPackageDependency = (prefix, name, candidates, manifest) => toDependency(candidates.find(candidate => isDeclared(manifest, candidate)) ??
|
|
22
|
+
(hasPrefix(prefix, name) ? name : createFullPackageName(prefix, name)));
|
|
23
|
+
const isPresetRuleKey = (key) => key.startsWith('preset-') ||
|
|
24
|
+
key.startsWith(PRESET_PREFIX) ||
|
|
25
|
+
(key.charAt(0) === '@' && (key.includes('/preset-') || key.includes(`/${PRESET_PREFIX}`)));
|
|
26
|
+
const toPresetDependency = (key, manifest) => {
|
|
27
|
+
const name = key.replace(/^preset-/, '').replace(/^@([^/]+)\/preset-(.*)$/, '@$1/$2');
|
|
28
|
+
const candidates = [`${PRESET_PREFIX}${name}`, name, createFullPackageName(PRESET_PREFIX, name), key];
|
|
29
|
+
return toPackageDependency(PRESET_PREFIX, name, candidates, manifest);
|
|
30
|
+
};
|
|
31
|
+
const toModuleDependency = (prefix, key, manifest) => toPackageDependency(prefix, key, [createFullPackageName(prefix, key), key], manifest);
|
|
32
|
+
const toLocalEntry = (key, cwd) => toDeferResolveEntry(toAbsolute(key, cwd));
|
|
33
|
+
export const toRuleDependency = (key, manifest, cwd) => {
|
|
34
|
+
if (isInternal(key))
|
|
35
|
+
return toLocalEntry(key, cwd);
|
|
36
|
+
return isPresetRuleKey(key) ? toPresetDependency(key, manifest) : toModuleDependency(RULE_PREFIX, key, manifest);
|
|
37
|
+
};
|
|
38
|
+
export const toFilterRuleDependency = (key, manifest, cwd) => isInternal(key) ? toLocalEntry(key, cwd) : toModuleDependency(FILTER_RULE_PREFIX, key, manifest);
|
|
39
|
+
export const toPluginDependency = (key, manifest, cwd) => isInternal(key) ? toLocalEntry(key, cwd) : toModuleDependency(PLUGIN_PREFIX, key, manifest);
|