knip 6.42.0 → 6.42.1

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.
@@ -1,26 +1,6 @@
1
- import { ensureRelative, isScopedPackage, isTildePackage, splitSpec } from './shared.js';
2
- import { hasUrlScheme } from '../util/url.js';
1
+ import { getUrlSpecifier, isScopedPackage, isTildePackage, splitSpec } from './shared.js';
3
2
  const dependencies = ['sass', 'sass-embedded', 'node-sass'];
4
- const dependencyMatcher = /"(?:\\(?:\r\n|[\s\S]|$)|[^"\\\r\n\f])*(?:"|[\r\n\f]|$)|'(?:\\(?:\r\n|[\s\S]|$)|[^'\\\r\n\f])*(?:'|[\r\n\f]|$)|\/\*[\s\S]*?(?:\*\/|$)|\/\/[^\r\n]*(?:[\r\n]|$)|@(?:use|import|forward)\s+['"](pkg:)?([^'"]+)['"]|url\(\s*(?:["']([^"']*)["']|([^'")\s]+))\s*\)/g;
5
- const getUrlSpecifier = (url) => {
6
- if (!url ||
7
- url.startsWith('//') ||
8
- url.startsWith('/') ||
9
- url.startsWith('#') ||
10
- hasUrlScheme(url) ||
11
- url.includes('$') ||
12
- url.includes('#{'))
13
- return;
14
- let end = url.length;
15
- const queryIndex = url.indexOf('?');
16
- if (queryIndex !== -1)
17
- end = queryIndex;
18
- const fragmentIndex = url.indexOf('#');
19
- if (fragmentIndex !== -1 && fragmentIndex < end)
20
- end = fragmentIndex;
21
- const path = url.slice(0, end);
22
- return path ? ensureRelative(path) : undefined;
23
- };
3
+ const dependencyMatcher = /"(?:\\(?:\r\n|[\s\S]|$)|[^"\\\r\n\f])*(?:"|[\r\n\f]|$)|'(?:\\(?:\r\n|[\s\S]|$)|[^'\\\r\n\f])*(?:'|[\r\n\f]|$)|\/\*[\s\S]*?(?:\*\/|$)|\/\/[^\r\n]*(?:[\r\n]|$)|@(?:use|import|forward)\s+['"](pkg:)?([^'"]+)['"]|url\(\s*(?:["']([^"'\r\n]*)["']|([^'")\s]+))\s*\)/g;
24
4
  const candidates = (specifier) => {
25
5
  const { dir, name } = splitSpec(specifier);
26
6
  const hasExt = name.endsWith('.scss') || name.endsWith('.sass');
@@ -1,6 +1,6 @@
1
1
  export declare const isScopedPackage: (s: string) => boolean;
2
2
  export declare const isTildePackage: (s: string) => boolean;
3
- export declare const ensureRelative: (spec: string) => string;
3
+ export declare const getUrlSpecifier: (url: string) => string | undefined;
4
4
  export declare const splitSpec: (specifier: string) => {
5
5
  dir: string;
6
6
  name: string;
@@ -1,8 +1,31 @@
1
1
  import { basename, dirname } from '../util/path.js';
2
+ import { hasUrlScheme } from '../util/url.js';
2
3
  const isAlias = (s) => (s.charCodeAt(0) === 64 && s.charCodeAt(1) === 47) || s.charCodeAt(0) === 126 || s.charCodeAt(0) === 35;
3
4
  export const isScopedPackage = (s) => s.charCodeAt(0) === 64 && s.charCodeAt(1) !== 47;
4
5
  export const isTildePackage = (s) => s.charCodeAt(0) === 126 && s.charCodeAt(1) !== 47;
5
- export const ensureRelative = (spec) => (spec.startsWith('.') || isAlias(spec) ? spec : `./${spec}`);
6
+ export const getUrlSpecifier = (url) => {
7
+ if (!url ||
8
+ url.startsWith('//') ||
9
+ url.startsWith('/') ||
10
+ url.startsWith('#') ||
11
+ hasUrlScheme(url) ||
12
+ url.includes('$') ||
13
+ url.includes('#{') ||
14
+ url.includes('('))
15
+ return;
16
+ let end = url.length;
17
+ const queryIndex = url.indexOf('?');
18
+ if (queryIndex !== -1)
19
+ end = queryIndex;
20
+ const fragmentIndex = url.indexOf('#');
21
+ if (fragmentIndex !== -1 && fragmentIndex < end)
22
+ end = fragmentIndex;
23
+ const path = url.slice(0, end);
24
+ if (!path)
25
+ return;
26
+ return isScopedPackage(path) ? path : ensureRelative(path);
27
+ };
28
+ const ensureRelative = (spec) => (spec.startsWith('.') || isAlias(spec) ? spec : `./${spec}`);
6
29
  export const splitSpec = (specifier) => {
7
30
  const spec = ensureRelative(specifier);
8
31
  return { dir: dirname(spec), name: basename(spec) };
package/dist/constants.js CHANGED
@@ -186,6 +186,7 @@ export const FOREIGN_FILE_EXTENSIONS = new Set([
186
186
  '.jpg',
187
187
  '.less',
188
188
  '.mp3',
189
+ '.otf',
189
190
  '.png',
190
191
  '.sass',
191
192
  '.scss',
@@ -21,9 +21,22 @@ const resolveConfig = localConfig => {
21
21
  const preload = localConfig.test?.preload ?? [];
22
22
  return preload.map(specifier => toDeferResolve(specifier));
23
23
  };
24
+ const isPath = (arg) => /^\.{0,2}\//.test(arg);
25
+ const toFilterPatterns = (filter) => {
26
+ if (filter === '.')
27
+ return patterns;
28
+ if (/\.[cm]?[jt]sx?$/.test(filter))
29
+ return [`**/*${filter}`];
30
+ return [
31
+ ...patterns.map(pattern => `**/*${filter}*/${pattern}`),
32
+ ...patterns.map(pattern => pattern.replace('**/*', `**/*${filter}*`)),
33
+ ];
34
+ };
24
35
  const toPatterns = (arg) => {
25
36
  if (/[*{?]/.test(arg))
26
37
  return [arg];
38
+ if (!isPath(arg))
39
+ return toFilterPatterns(arg);
27
40
  if (/\.\w+$/.test(arg))
28
41
  return [arg];
29
42
  const dir = arg.replace(/\/+$/, '');
@@ -1,7 +1,7 @@
1
1
  import { arrayify } from '../../util/array.js';
2
- import { _glob, _dirGlob } from '../../util/glob.js';
2
+ import { _glob } from '../../util/glob.js';
3
3
  import { toConfig, toDeferResolve, toDependency, toEntry } from '../../util/input.js';
4
- import { isInternal, join, normalize, toAbsolute } from '../../util/path.js';
4
+ import { extname, isInternal, join, normalize, toAbsolute } from '../../util/path.js';
5
5
  import { hasDependency } from '../../util/plugin.js';
6
6
  import { getDependenciesFromConfig } from '../babel/index.js';
7
7
  import { getReportersDependencies, resolveExtensibleConfig, resolveWithPrefix } from './helpers.js';
@@ -9,7 +9,9 @@ import { createJestMockVisitor } from './visitors/mock.js';
9
9
  const title = 'Jest';
10
10
  const enablers = ['jest'];
11
11
  const isEnabled = ({ dependencies, manifest }) => hasDependency(dependencies, enablers) || Boolean(manifest.name?.startsWith('jest-presets'));
12
- const config = ['jest.config.{js,ts,mjs,cjs,mts,cts,json}', 'package.json'];
12
+ const configExtensions = ['js', 'ts', 'mjs', 'mts', 'cjs', 'cts', 'json'];
13
+ const configPattern = `jest.config.{${configExtensions.join(',')}}`;
14
+ const config = [configPattern, 'package.json'];
13
15
  const mocks = ['**/__mocks__/**/*.[jt]s?(x)'];
14
16
  const entry = ['**/__tests__/**/*.?(c|m)[jt]s?(x)', '**/?(*.)+(spec|test).?(c|m)[jt]s?(x)', ...mocks];
15
17
  const rootDirRe = /<rootDir>/;
@@ -28,10 +30,12 @@ const resolveDependencies = async (config, rootDir, options) => {
28
30
  const projects = [];
29
31
  for (const project of config.projects ?? []) {
30
32
  if (typeof project === 'string') {
31
- const patterns = [project.replace(rootDirRe, rootDir)];
32
- const files = await _glob({ patterns, cwd: options.cwd });
33
- const dirs = await _dirGlob({ patterns, cwd: options.cwd });
34
- projects.push(...files, ...dirs);
33
+ const pattern = project.replace(rootDirRe, rootDir);
34
+ const files = await _glob({ patterns: [pattern, join(pattern, configPattern)], cwd: options.cwd });
35
+ for (const file of files) {
36
+ if (configExtensions.includes(extname(file).slice(1)))
37
+ projects.push(toConfig('jest', file));
38
+ }
35
39
  }
36
40
  else {
37
41
  const dependencies = await resolveDependencies(project, rootDir, options);
@@ -1,4 +1,5 @@
1
- import { toDeferResolve } from '../../util/input.js';
1
+ import { toConfig, toDeferResolve } from '../../util/input.js';
2
+ import { isInternal } from '../../util/path.js';
2
3
  import { hasDependency } from '../../util/plugin.js';
3
4
  import { toCosmiconfig } from '../../util/plugin-config.js';
4
5
  const title = 'Semantic Release';
@@ -13,9 +14,36 @@ const excludePackages = [
13
14
  '@semantic-release/npm',
14
15
  '@semantic-release/release-notes-generator',
15
16
  ];
16
- const resolveConfig = config => {
17
+ const resolveConfig = (config, options) => {
18
+ const inputs = [];
19
+ for (const id of [config?.extends ?? []].flat()) {
20
+ if (isInternal(id))
21
+ inputs.push(toConfig('semantic-release', id, { containingFilePath: options.configFilePath }));
22
+ else
23
+ inputs.push(toDeferResolve(id));
24
+ }
17
25
  const plugins = (config?.plugins ?? []).map(plugin => (Array.isArray(plugin) ? plugin[0] : plugin));
18
- return plugins.filter(plugin => !excludePackages.includes(plugin)).map(id => toDeferResolve(id));
26
+ for (const id of plugins.filter(plugin => !excludePackages.includes(plugin)))
27
+ inputs.push(toDeferResolve(id));
28
+ return inputs;
29
+ };
30
+ const args = {
31
+ alias: { extends: ['e'] },
32
+ resolveInputs: (parsed, { cwd }) => {
33
+ if (parsed.extends === 'false')
34
+ return [];
35
+ const inputs = [];
36
+ for (const value of [parsed.extends ?? []].flat()) {
37
+ for (const part of String(value).split(',')) {
38
+ const id = part.trim();
39
+ if (isInternal(id))
40
+ inputs.push(toConfig('semantic-release', id, { dir: cwd }));
41
+ else
42
+ inputs.push(toDeferResolve(id));
43
+ }
44
+ }
45
+ return inputs;
46
+ },
19
47
  };
20
48
  const plugin = {
21
49
  title,
@@ -25,5 +53,6 @@ const plugin = {
25
53
  packageJsonPath,
26
54
  config,
27
55
  resolveConfig,
56
+ args,
28
57
  };
29
58
  export default plugin;
@@ -1,3 +1,4 @@
1
1
  export type SemanticReleaseConfig = {
2
+ extends?: string | string[];
2
3
  plugins?: (string | [string, Record<string, unknown>])[];
3
4
  };
@@ -1,13 +1,21 @@
1
+ import { getUrlSpecifier } from '../../compilers/shared.js';
1
2
  import { hasUrlScheme } from '../../util/url.js';
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;
3
+ 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*\))[^;]*;|url\(\s*(?:["']([^"'\r\n]*)["']|([^'")\s]+))\s*\)/g;
3
4
  const compiler = (text) => {
4
- if (!text.includes('@import') && !text.includes('@config') && !text.includes('@plugin'))
5
+ if (!text.includes('@import') && !text.includes('@config') && !text.includes('@plugin') && !text.includes('url('))
5
6
  return '';
6
7
  const imports = [];
7
8
  let match;
8
9
  let index = 0;
9
10
  directiveMatcher.lastIndex = 0;
10
11
  while ((match = directiveMatcher.exec(text))) {
12
+ const asset = match[4] ?? match[5];
13
+ if (asset !== undefined) {
14
+ const specifier = getUrlSpecifier(asset);
15
+ if (specifier)
16
+ imports.push(`import _$${index++} from '${specifier}';`);
17
+ continue;
18
+ }
11
19
  const url = match[2] ?? match[3];
12
20
  const specifier = match[1] ?? url;
13
21
  if (!specifier || (url && (url.startsWith('//') || hasUrlScheme(url))))
@@ -156,7 +156,7 @@ export const resolveConfig = async (localConfig, options) => {
156
156
  : toAbsolute('.', options.configFileDir);
157
157
  const vitestRoot = !cfg.test?.root && cfg.root && !options.isResolvedConfigFile ? toAbsolute(cfg.root, options.cwd) : testRoot;
158
158
  const dir = cfg.test?.dir ? toAbsolute(cfg.test.dir, testRoot) : vitestRoot;
159
- if (cfg.test) {
159
+ if (cfg.test || options.pluginName === 'vitest') {
160
160
  if (cfg.test?.include) {
161
161
  for (const dependency of cfg.test.include)
162
162
  dependency[0] !== '!' && inputs.add(toEntry(join(dir, dependency)));
@@ -171,7 +171,7 @@ export const resolveConfig = async (localConfig, options) => {
171
171
  if (!options.config.entry)
172
172
  for (const dependency of mocks)
173
173
  inputs.add(toEntry(join(vitestRoot, dependency)));
174
- if (cfg.test.alias)
174
+ if (cfg.test?.alias)
175
175
  addAliases(cfg.test.alias);
176
176
  }
177
177
  if (cfg.resolve?.alias)
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "6.42.0";
1
+ export declare const version = "6.42.1";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '6.42.0';
1
+ export const version = '6.42.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "6.42.0",
3
+ "version": "6.42.1",
4
4
  "description": "Find and fix unused dependencies, exports and files in your TypeScript and JavaScript projects",
5
5
  "keywords": [
6
6
  "analysis",