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.
Files changed (82) hide show
  1. package/dist/ConfigurationChief.d.ts +12 -0
  2. package/dist/IssueCollector.d.ts +3 -0
  3. package/dist/IssueCollector.js +5 -0
  4. package/dist/WorkspaceWorker.d.ts +3 -1
  5. package/dist/WorkspaceWorker.js +10 -5
  6. package/dist/binaries/command.js +2 -2
  7. package/dist/cli.js +4 -0
  8. package/dist/compilers/compilers.js +1 -1
  9. package/dist/compilers/scss.js +2 -2
  10. package/dist/graph/build.js +1 -0
  11. package/dist/graph-explorer/cache.d.ts +3 -0
  12. package/dist/graph-explorer/cache.js +6 -0
  13. package/dist/graph-explorer/explorer.d.ts +1 -0
  14. package/dist/graph-explorer/explorer.js +2 -0
  15. package/dist/graph-explorer/operations/build-exports-tree.js +14 -2
  16. package/dist/graph-explorer/operations/get-ambiguous-star-export.d.ts +8 -0
  17. package/dist/graph-explorer/operations/get-ambiguous-star-export.js +11 -0
  18. package/dist/graph-explorer/operations/get-contention.js +265 -122
  19. package/dist/graph-explorer/operations/resolve-export-origins.d.ts +32 -0
  20. package/dist/graph-explorer/operations/resolve-export-origins.js +255 -0
  21. package/dist/graph-explorer/utils.js +8 -0
  22. package/dist/index.d.ts +1 -0
  23. package/dist/plugins/eslint/helpers.js +31 -6
  24. package/dist/plugins/eslint/resolveFromAST.js +17 -11
  25. package/dist/plugins/eslint/types.d.ts +3 -3
  26. package/dist/plugins/index.d.ts +2 -0
  27. package/dist/plugins/index.js +4 -0
  28. package/dist/plugins/next/index.js +39 -5
  29. package/dist/plugins/node/index.js +6 -0
  30. package/dist/plugins/tailwind/compiler.js +2 -2
  31. package/dist/plugins/tailwind/index.js +7 -1
  32. package/dist/plugins/textlint/helpers.d.ts +4 -0
  33. package/dist/plugins/textlint/helpers.js +39 -0
  34. package/dist/plugins/textlint/index.d.ts +3 -0
  35. package/dist/plugins/textlint/index.js +52 -0
  36. package/dist/plugins/textlint/types.d.ts +5 -0
  37. package/dist/plugins/textlint/types.js +1 -0
  38. package/dist/plugins/typedoc/index.js +3 -2
  39. package/dist/plugins/typedoc/types.d.ts +2 -2
  40. package/dist/plugins/varlock/index.d.ts +3 -0
  41. package/dist/plugins/varlock/index.js +31 -0
  42. package/dist/plugins/varlock/parse.d.ts +11 -0
  43. package/dist/plugins/varlock/parse.js +185 -0
  44. package/dist/plugins/varlock/scan.d.ts +2 -0
  45. package/dist/plugins/varlock/scan.js +78 -0
  46. package/dist/plugins/vitest/index.js +4 -2
  47. package/dist/reporters/trace.js +30 -1
  48. package/dist/reporters/util/configuration-hints.d.ts +1 -1
  49. package/dist/reporters/util/configuration-hints.js +11 -2
  50. package/dist/run.d.ts +2 -0
  51. package/dist/run.js +2 -1
  52. package/dist/schema/configuration.d.ts +30 -0
  53. package/dist/schema/plugins.d.ts +10 -0
  54. package/dist/schema/plugins.js +2 -0
  55. package/dist/session/build-maps.js +9 -1
  56. package/dist/session/file-descriptor.js +0 -2
  57. package/dist/session/index.d.ts +1 -1
  58. package/dist/session/types.d.ts +18 -0
  59. package/dist/types/PluginNames.d.ts +2 -2
  60. package/dist/types/PluginNames.js +2 -0
  61. package/dist/types/config.d.ts +1 -0
  62. package/dist/types/issues.d.ts +1 -0
  63. package/dist/types/module-graph.d.ts +3 -0
  64. package/dist/typescript/get-imports-and-exports.js +43 -9
  65. package/dist/typescript/resolve-module-names.js +7 -27
  66. package/dist/typescript/visitors/exports.js +9 -4
  67. package/dist/typescript/visitors/walk.d.ts +1 -1
  68. package/dist/typescript/visitors/walk.js +4 -1
  69. package/dist/util/array.d.ts +1 -1
  70. package/dist/util/array.js +5 -1
  71. package/dist/util/create-options.d.ts +20 -0
  72. package/dist/util/file-entry-cache.js +1 -1
  73. package/dist/util/glob-core.d.ts +1 -0
  74. package/dist/util/glob-core.js +11 -3
  75. package/dist/util/package-json.d.ts +2 -0
  76. package/dist/util/url.d.ts +1 -0
  77. package/dist/util/url.js +2 -0
  78. package/dist/util/watch.d.ts +1 -0
  79. package/dist/version.d.ts +1 -1
  80. package/dist/version.js +1 -1
  81. package/package.json +1 -1
  82. 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 extendsSpecifiers = config.extends ? compact([config.extends].flat().map(resolveExtendSpecifier)) : [];
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 parser = config.parser ?? config.parserOptions?.parser;
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, parser, ...settings, ...rules]).map(id => toDeferResolve(id));
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 (typeof settings === 'string' ? [settings] : Object.keys(settings))
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 !== 'import/resolver' && key !== 'import/parsers')
24
- continue;
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;
@@ -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;
@@ -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 { collectPropertyValues } from '../../typescript/ast-helpers.js';
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 = [...collectPropertyValues(program, 'pageExtensions')];
42
- const extensions = pageExtensions.length > 0 ? pageExtensions : defaultPageExtensions;
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
- return patterns.map(id => toProductionEntry(join(configFileDir, id)));
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('//') || urlSchemeMatcher.test(url))))
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 = ['tailwindcss', '@tailwindcss/vite', '@tailwindcss/postcss', '@tailwindcss/cli'];
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);
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from '../../types/config.ts';
2
+ declare const plugin: Plugin;
3
+ export default plugin;