knip 6.35.1 → 6.37.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 +20 -2
- package/dist/ConfigurationChief.js +15 -1
- package/dist/DependencyDeputy.d.ts +0 -2
- package/dist/DependencyDeputy.js +1 -17
- package/dist/WorkspaceWorker.js +7 -6
- package/dist/binaries/bash-parser.js +1 -1
- package/dist/binaries/command.js +21 -10
- package/dist/binaries/fallback.js +5 -4
- package/dist/binaries/plugins.js +4 -4
- package/dist/binaries/resolvers/bun.js +2 -2
- package/dist/binaries/resolvers/find.js +5 -4
- package/dist/binaries/resolvers/index.d.ts +2 -1
- package/dist/binaries/resolvers/index.js +3 -2
- package/dist/binaries/resolvers/npm.js +46 -4
- package/dist/binaries/resolvers/npx.js +8 -4
- package/dist/binaries/resolvers/nub.js +3 -2
- package/dist/binaries/resolvers/pnpm.js +17 -10
- package/dist/binaries/resolvers/yarn.js +1 -1
- package/dist/binaries/util.d.ts +4 -1
- package/dist/binaries/util.js +2 -0
- package/dist/compilers/compilers.js +1 -1
- package/dist/compilers/scss.js +2 -2
- 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/manifest/index.js +1 -3
- package/dist/plugins/ava/index.js +1 -1
- package/dist/plugins/eslint/helpers.d.ts +2 -1
- package/dist/plugins/eslint/helpers.js +59 -14
- package/dist/plugins/eslint/index.js +2 -2
- package/dist/plugins/eslint/resolveFromAST.js +17 -11
- package/dist/plugins/eslint/types.d.ts +3 -3
- package/dist/plugins/github-actions/index.js +1 -1
- package/dist/plugins/graphql-codegen/index.js +15 -4
- package/dist/plugins/graphql-codegen/types.d.ts +11 -1
- package/dist/plugins/graphql-codegen/types.js +6 -0
- package/dist/plugins/husky/index.js +1 -1
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.js +4 -0
- package/dist/plugins/lefthook/index.js +1 -1
- package/dist/plugins/mise/scripts.js +5 -5
- 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/taskfile/index.js +1 -1
- package/dist/plugins/tauri/index.js +1 -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/travis/index.js +1 -1
- 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/vite-plus/resolveFromAST.js +1 -1
- package/dist/plugins/vitest/index.js +4 -2
- package/dist/reporters/trace.js +30 -1
- package/dist/schema/configuration.d.ts +33 -0
- package/dist/schema/configuration.js +2 -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 +5 -1
- package/dist/types/module-graph.d.ts +3 -0
- package/dist/types/package-json.d.ts +1 -1
- package/dist/typescript/get-imports-and-exports.js +43 -9
- 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-input-handler.js +3 -3
- package/dist/util/create-options.d.ts +28 -2
- 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/jiti.js +1 -0
- package/dist/util/modules.d.ts +2 -0
- package/dist/util/modules.js +3 -1
- package/dist/util/package-json.d.ts +185 -183
- package/dist/util/parse-args.d.ts +2 -0
- package/dist/util/parse-args.js +6 -1
- package/dist/util/url.d.ts +1 -0
- package/dist/util/url.js +2 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -5
- package/schema.json +20 -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/manifest/index.js
CHANGED
|
@@ -17,10 +17,8 @@ const getMetaDataFromPackageJson = ({ dir, packageNames }) => {
|
|
|
17
17
|
if (manifest) {
|
|
18
18
|
const defaultBinaryName = packageName.replace(/^@[^/]+\//, '');
|
|
19
19
|
const binaries = typeof manifest.bin === 'string' ? [defaultBinaryName] : Object.keys(manifest.bin ?? {});
|
|
20
|
-
for (const binaryName of binaries)
|
|
20
|
+
for (const binaryName of binaries)
|
|
21
21
|
addBinary(binaryName, packageName);
|
|
22
|
-
addBinary(packageName, binaryName);
|
|
23
|
-
}
|
|
24
22
|
const packagePeerDependencies = Object.keys(manifest.peerDependencies ?? {});
|
|
25
23
|
for (const packagePeerDependency of packagePeerDependencies) {
|
|
26
24
|
const hostDependency = {
|
|
@@ -23,7 +23,7 @@ const resolveConfig = async (localConfig, options) => {
|
|
|
23
23
|
const nodeArgs = localConfig.nodeArguments ?? [];
|
|
24
24
|
const requireArgs = (localConfig.require ?? []).map(require => `--require ${require}`);
|
|
25
25
|
const fakeCommand = `node ${nodeArgs.join(' ')} ${requireArgs.join(' ')}`;
|
|
26
|
-
return files.concat(options.getInputsFromScripts(fakeCommand, {
|
|
26
|
+
return files.concat(options.getInputsFromScripts(fakeCommand, { optionalBinaries: true }));
|
|
27
27
|
};
|
|
28
28
|
const plugin = {
|
|
29
29
|
title,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { PluginOptions } from '../../types/config.ts';
|
|
2
|
+
import type { Manifest } from '../../util/package-json.ts';
|
|
2
3
|
import { type ConfigInput, type Input } from '../../util/input.ts';
|
|
3
4
|
import type { ESLintConfig, ESLintConfigDeprecated, OverrideConfigDeprecated, Settings } from './types.ts';
|
|
4
5
|
export declare const isFlatConfig: (fileName: string) => boolean;
|
|
5
6
|
export declare const getInputs: (config: ESLintConfigDeprecated | OverrideConfigDeprecated | ESLintConfig, options: PluginOptions) => (Input | ConfigInput)[];
|
|
6
7
|
export declare const getInputsFromSettings: (settings?: Settings) => Input[];
|
|
7
|
-
export declare const resolveFormatters: (formatters: string | string[]) => Set<Input>;
|
|
8
|
+
export declare const resolveFormatters: (formatters: string | string[], manifest: Manifest) => Set<Input>;
|
|
@@ -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))
|
|
@@ -82,15 +107,35 @@ const getDependenciesFromSettings = (settings = {}) => {
|
|
|
82
107
|
};
|
|
83
108
|
export const getInputsFromSettings = (settings) => compact(getDependenciesFromSettings(settings)).map(id => toDeferResolve(id, { optional: true }));
|
|
84
109
|
const builtinFormatters = new Set(['html', 'json-with-metadata', 'json', 'stylish']);
|
|
85
|
-
|
|
110
|
+
const builtinFormattersUntilV8 = new Set([
|
|
111
|
+
'checkstyle',
|
|
112
|
+
'compact',
|
|
113
|
+
'jslint-xml',
|
|
114
|
+
'junit',
|
|
115
|
+
'tap',
|
|
116
|
+
'unix',
|
|
117
|
+
'visualstudio',
|
|
118
|
+
]);
|
|
119
|
+
const normalizeFormatterName = (name) => {
|
|
120
|
+
if (!name.startsWith('@'))
|
|
121
|
+
return name.startsWith('eslint-formatter-') ? name : `eslint-formatter-${name}`;
|
|
122
|
+
const [scope, id] = name.split('/');
|
|
123
|
+
if (!id)
|
|
124
|
+
return `${scope}/eslint-formatter`;
|
|
125
|
+
return /^eslint-formatter(-|$)/.test(id) ? name : name.replace('/', '/eslint-formatter-');
|
|
126
|
+
};
|
|
127
|
+
export const resolveFormatters = (formatters, manifest) => {
|
|
86
128
|
const inputs = new Set();
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
inputs.add(toDeferResolve(formatter));
|
|
92
|
-
|
|
93
|
-
|
|
129
|
+
const isBeforeV9 = (manifest.getMajor('eslint') ?? 9) < 9;
|
|
130
|
+
for (const rawFormatter of [formatters].flat()) {
|
|
131
|
+
const formatter = rawFormatter.replace(/\\/g, '/');
|
|
132
|
+
if (!formatter.startsWith('@') && formatter.includes('/')) {
|
|
133
|
+
inputs.add(toDeferResolve(isInternal(formatter) ? formatter : `./${formatter}`));
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
const isBuiltin = builtinFormatters.has(formatter) || (isBeforeV9 && builtinFormattersUntilV8.has(formatter));
|
|
137
|
+
inputs.add(toDependency(normalizeFormatterName(formatter), isBuiltin ? { optional: true } : {}));
|
|
138
|
+
}
|
|
94
139
|
}
|
|
95
140
|
return inputs;
|
|
96
141
|
};
|
|
@@ -49,12 +49,12 @@ const args = {
|
|
|
49
49
|
config: true,
|
|
50
50
|
alias: { format: ['f'] },
|
|
51
51
|
boolean: ['inspect-config'],
|
|
52
|
-
resolveInputs: (parsed) => {
|
|
52
|
+
resolveInputs: (parsed, { manifest }) => {
|
|
53
53
|
const inputs = [];
|
|
54
54
|
if (parsed['inspect-config'])
|
|
55
55
|
inputs.push(toDependency('@eslint/config-inspector', { optional: true }));
|
|
56
56
|
if (parsed['format'])
|
|
57
|
-
for (const input of resolveFormatters(parsed['format']))
|
|
57
|
+
for (const input of resolveFormatters(parsed['format'], manifest))
|
|
58
58
|
inputs.push(input);
|
|
59
59
|
return inputs;
|
|
60
60
|
},
|
|
@@ -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;
|
|
@@ -34,7 +34,7 @@ const resolveConfig = async (config, options) => {
|
|
|
34
34
|
const manifest = getManifest(dir) ?? options.manifest;
|
|
35
35
|
const actionPath = relative(dir, configFileDir);
|
|
36
36
|
const run = step.run.replace(ACTION_PATH_VAR, actionPath ? `./${actionPath}` : '.');
|
|
37
|
-
for (const input of getInputsFromScripts([run], {
|
|
37
|
+
for (const input of getInputsFromScripts([run], { optionalBinaries: true, manifest })) {
|
|
38
38
|
if (isDeferResolveEntry(input) && path && !workingDir) {
|
|
39
39
|
input.specifier = relative(join(dir, path), join(rootCwd, input.specifier));
|
|
40
40
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { toDependency, toEntry, toProductionEntry } from '../../util/input.js';
|
|
2
2
|
import { get } from '../../util/object.js';
|
|
3
|
-
import { isInternal, join } from '../../util/path.js';
|
|
3
|
+
import { isInternal, join, normalize } from '../../util/path.js';
|
|
4
4
|
import { hasDependency } from '../../util/plugin.js';
|
|
5
|
-
import { isConfigurationOutput, isGraphqlConfigTypes, isGraphqlProjectsConfigTypes } from './types.js';
|
|
5
|
+
import { isConfigurationOutput, isGraphqlConfigTypes, isGraphqlProjectsConfigTypes, isNearOperationFilePreset, } from './types.js';
|
|
6
6
|
const title = 'GraphQL Codegen';
|
|
7
7
|
const enablers = [/^@graphql-codegen\//, 'graphql-config'];
|
|
8
8
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
@@ -24,6 +24,17 @@ const getPluginPackageName = (name) => {
|
|
|
24
24
|
return name;
|
|
25
25
|
return `@graphql-codegen/${name}`;
|
|
26
26
|
};
|
|
27
|
+
const getOutputPattern = (output, outputConfig) => {
|
|
28
|
+
if (isConfigurationOutput(outputConfig) && isNearOperationFilePreset(outputConfig.preset)) {
|
|
29
|
+
const presetConfig = outputConfig.presetConfig ?? {};
|
|
30
|
+
const { folder = '', extension = '.generated.ts', fileName = '*', filePerOperation = false } = presetConfig;
|
|
31
|
+
const subfolder = normalize(folder)
|
|
32
|
+
.split('/')
|
|
33
|
+
.filter(segment => segment !== '' && segment !== '.' && segment !== '..');
|
|
34
|
+
return join(output, '**', ...subfolder, `${filePerOperation ? '*' : fileName}${extension}`);
|
|
35
|
+
}
|
|
36
|
+
return output.endsWith('/') ? `${output}**` : output;
|
|
37
|
+
};
|
|
27
38
|
const resolveConfig = (config, options) => {
|
|
28
39
|
const codegenConfigs = isGraphqlProjectsConfigTypes(config)
|
|
29
40
|
? Object.values(config.projects).flatMap(project => project.extensions?.codegen ?? [])
|
|
@@ -33,8 +44,8 @@ const resolveConfig = (config, options) => {
|
|
|
33
44
|
const generateConfigs = codegenConfigs.filter((config) => Boolean(config?.generates));
|
|
34
45
|
const generateSet = generateConfigs.flatMap(config => Object.values(config.generates));
|
|
35
46
|
const outputs = generateConfigs
|
|
36
|
-
.flatMap(config => Object.
|
|
37
|
-
.map(output => toProductionEntry(join(options.configFileDir,
|
|
47
|
+
.flatMap(config => Object.entries(config.generates))
|
|
48
|
+
.map(([output, outputConfig]) => toProductionEntry(join(options.configFileDir, getOutputPattern(output, outputConfig))));
|
|
38
49
|
const configurationOutput = generateSet.filter(isConfigurationOutput);
|
|
39
50
|
const presets = configurationOutput
|
|
40
51
|
.map(configOutput => (configOutput.preset ? configOutput.preset : undefined))
|
|
@@ -12,10 +12,20 @@ type OutputPreset = {
|
|
|
12
12
|
buildGeneratesSection: (options: unknown) => Promise<unknown>;
|
|
13
13
|
prepareDocuments?: (outputFilePath: string, outputSpecificDocuments: unknown) => Promise<unknown>;
|
|
14
14
|
};
|
|
15
|
+
export interface NearOperationFilePresetConfig {
|
|
16
|
+
baseTypesPath?: string;
|
|
17
|
+
extension?: string;
|
|
18
|
+
fileName?: string;
|
|
19
|
+
filePerOperation?: boolean;
|
|
20
|
+
folder?: string;
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
export declare const isNearOperationFilePreset: (preset: ConfiguredOutput['preset']) => preset is PresetNames;
|
|
15
24
|
export declare function isConfigurationOutput(config: ConfiguredOutput | ConfiguredPlugin[]): config is ConfiguredOutput;
|
|
16
|
-
interface ConfiguredOutput {
|
|
25
|
+
export interface ConfiguredOutput {
|
|
17
26
|
plugins?: OutputConfig[];
|
|
18
27
|
preset?: PresetNames | OutputPreset;
|
|
28
|
+
presetConfig?: NearOperationFilePresetConfig;
|
|
19
29
|
}
|
|
20
30
|
export interface GraphqlCodegenTypes {
|
|
21
31
|
generates: {
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
const nearOperationFilePresetNames = new Set([
|
|
2
|
+
'near-operation-file',
|
|
3
|
+
'near-operation-file-preset',
|
|
4
|
+
'@graphql-codegen/near-operation-file-preset',
|
|
5
|
+
]);
|
|
6
|
+
export const isNearOperationFilePreset = (preset) => typeof preset === 'string' && nearOperationFilePresetNames.has(preset);
|
|
1
7
|
export function isConfigurationOutput(config) {
|
|
2
8
|
return 'preset' in config || 'plugins' in config;
|
|
3
9
|
}
|
|
@@ -17,7 +17,7 @@ const resolveConfig = (script, options) => {
|
|
|
17
17
|
return [toDependency('husky'), ...options.getInputsFromScripts(scripts, { ...options })];
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
return options.getInputsFromScripts(String(script), {
|
|
20
|
+
return options.getInputsFromScripts(String(script), { optionalBinaries: true });
|
|
21
21
|
};
|
|
22
22
|
const plugin = {
|
|
23
23
|
title,
|
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,
|
|
@@ -21,7 +21,7 @@ const resolveConfig = async (localConfig, options) => {
|
|
|
21
21
|
const inputs = manifest.devDependencies ? Object.keys(manifest.devDependencies).map(id => toDependency(id)) : [];
|
|
22
22
|
if (extname(configFileName) !== '') {
|
|
23
23
|
const scripts = findByKeyDeep(localConfig, 'run').flatMap(command => {
|
|
24
|
-
const deps = getInputsFromScripts([command.run], { ...options,
|
|
24
|
+
const deps = getInputsFromScripts([command.run], { ...options, optionalBinaries: true });
|
|
25
25
|
const dir = command.root ?? cwd;
|
|
26
26
|
return deps.flatMap(dependency => ({ ...dependency, dir }));
|
|
27
27
|
});
|