knip 6.40.0 → 6.42.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 (91) hide show
  1. package/README.md +1 -1
  2. package/dist/ConfigurationChief.d.ts +30 -0
  3. package/dist/DependencyDeputy.d.ts +1 -0
  4. package/dist/DependencyDeputy.js +28 -2
  5. package/dist/IssueCollector.js +13 -15
  6. package/dist/IssueFixer.js +1 -1
  7. package/dist/WorkspaceWorker.js +15 -8
  8. package/dist/binaries/bash-parser.js +16 -33
  9. package/dist/binaries/command.d.ts +1 -1
  10. package/dist/binaries/command.js +14 -8
  11. package/dist/binaries/resolvers/bun.js +1 -0
  12. package/dist/graph/build.js +18 -9
  13. package/dist/graph-explorer/operations/is-referenced.js +8 -2
  14. package/dist/manifest/index.d.ts +1 -0
  15. package/dist/manifest/index.js +7 -3
  16. package/dist/plugins/_component-style-urls/component-style-urls-visitor.d.ts +2 -0
  17. package/dist/plugins/_component-style-urls/component-style-urls-visitor.js +40 -0
  18. package/dist/plugins/angular/index.js +7 -1
  19. package/dist/plugins/biome/index.js +2 -2
  20. package/dist/plugins/commitlint/index.js +2 -2
  21. package/dist/plugins/eslint/helpers.js +1 -1
  22. package/dist/plugins/expo/helpers.js +1 -1
  23. package/dist/plugins/expo/index.js +4 -24
  24. package/dist/plugins/expo-router/index.d.ts +3 -0
  25. package/dist/plugins/expo-router/index.js +32 -0
  26. package/dist/plugins/filesystem-routing/index.d.ts +3 -0
  27. package/dist/plugins/filesystem-routing/index.js +57 -0
  28. package/dist/plugins/flue/index.d.ts +3 -0
  29. package/dist/plugins/flue/index.js +42 -0
  30. package/dist/plugins/github-actions/index.js +1 -1
  31. package/dist/plugins/index.d.ts +5 -0
  32. package/dist/plugins/index.js +10 -0
  33. package/dist/plugins/jest/index.js +5 -0
  34. package/dist/plugins/jest/visitors/mock.d.ts +2 -0
  35. package/dist/plugins/jest/visitors/mock.js +91 -0
  36. package/dist/plugins/mise/scripts.js +56 -76
  37. package/dist/plugins/moonrepo/index.js +2 -1
  38. package/dist/plugins/next/index.js +33 -1
  39. package/dist/plugins/nx/index.js +50 -8
  40. package/dist/plugins/nx/types.d.ts +8 -0
  41. package/dist/plugins/oxlint/index.js +1 -1
  42. package/dist/plugins/react-native/index.js +1 -1
  43. package/dist/plugins/react-router/index.d.ts +3 -0
  44. package/dist/plugins/react-router/index.js +3 -0
  45. package/dist/plugins/rsbuild/index.js +20 -6
  46. package/dist/plugins/rsbuild/types.d.ts +6 -0
  47. package/dist/plugins/rstest/index.js +1 -1
  48. package/dist/plugins/rstest/types.d.ts +1 -5
  49. package/dist/plugins/solidjs-vite-plugin/index.d.ts +6 -0
  50. package/dist/plugins/solidjs-vite-plugin/index.js +17 -0
  51. package/dist/plugins/solidjs-vite-plugin/resolveFromAST.d.ts +3 -0
  52. package/dist/plugins/solidjs-vite-plugin/resolveFromAST.js +76 -0
  53. package/dist/plugins/sst/resolveFromAST.js +1 -1
  54. package/dist/plugins/stencil/index.js +2 -39
  55. package/dist/plugins/storybook/index.js +2 -4
  56. package/dist/plugins/sveltejs-package/helpers.js +7 -44
  57. package/dist/plugins/taskfile/index.js +3 -6
  58. package/dist/plugins/tsrs/index.d.ts +3 -0
  59. package/dist/plugins/tsrs/index.js +15 -0
  60. package/dist/plugins/typescript/index.d.ts +12 -1
  61. package/dist/plugins/typescript/index.js +5 -7
  62. package/dist/plugins/vite/helpers.d.ts +1 -0
  63. package/dist/plugins/vite/helpers.js +15 -1
  64. package/dist/plugins/vitest/index.js +2 -2
  65. package/dist/run.js +2 -0
  66. package/dist/schema/configuration.d.ts +75 -0
  67. package/dist/schema/plugins.d.ts +25 -0
  68. package/dist/schema/plugins.js +5 -0
  69. package/dist/types/PluginNames.d.ts +2 -2
  70. package/dist/types/PluginNames.js +5 -0
  71. package/dist/types/config.d.ts +1 -0
  72. package/dist/types/workspace.d.ts +1 -0
  73. package/dist/typescript/visitors/imports.js +11 -0
  74. package/dist/typescript/visitors/jsdoc.js +27 -22
  75. package/dist/util/create-options.d.ts +50 -0
  76. package/dist/util/create-options.js +2 -3
  77. package/dist/util/glob-cache.d.ts +2 -2
  78. package/dist/util/glob-core.js +70 -47
  79. package/dist/util/glob.js +15 -10
  80. package/dist/util/load-tsconfig.d.ts +1 -1
  81. package/dist/util/load-tsconfig.js +21 -11
  82. package/dist/util/module-graph.js +9 -4
  83. package/dist/util/path.d.ts +1 -0
  84. package/dist/util/path.js +1 -0
  85. package/dist/util/scripts.d.ts +4 -2
  86. package/dist/util/scripts.js +33 -67
  87. package/dist/util/to-source-path.js +1 -1
  88. package/dist/version.d.ts +1 -1
  89. package/dist/version.js +1 -1
  90. package/package.json +10 -11
  91. package/schema.json +20 -0
@@ -42,6 +42,28 @@ const production = getEntryFilePatterns();
42
42
  const resolveFromAST = (program, { configFileDir }) => {
43
43
  const pageExtensions = new Set();
44
44
  const loaders = new Set();
45
+ const aliasTargets = new Set();
46
+ const collectAliasTargets = (node) => {
47
+ const target = getStringValue(node);
48
+ if (target)
49
+ aliasTargets.add(target);
50
+ else if (node?.type === 'ArrayExpression') {
51
+ for (const element of node.elements)
52
+ collectAliasTargets(element);
53
+ }
54
+ else if (node?.type === 'ObjectExpression') {
55
+ collectAliasTargets(findProperty(node, 'browser'));
56
+ }
57
+ };
58
+ const collectTurbopackAliases = (node) => {
59
+ const aliases = findProperty(node, 'resolveAlias');
60
+ if (aliases?.type !== 'ObjectExpression')
61
+ return;
62
+ for (const alias of aliases.properties) {
63
+ if (alias.type === 'Property')
64
+ collectAliasTargets(alias.value);
65
+ }
66
+ };
45
67
  const collectLoaders = (node) => {
46
68
  if (node?.type === 'ArrayExpression') {
47
69
  for (const element of node.elements)
@@ -60,7 +82,15 @@ const resolveFromAST = (program, { configFileDir }) => {
60
82
  ObjectExpression(node) {
61
83
  for (const extension of getPropertyValues(node, 'pageExtensions'))
62
84
  pageExtensions.add(extension);
63
- const rules = findProperty(findProperty(node, 'turbopack'), 'rules');
85
+ const turbopack = findProperty(node, 'turbopack');
86
+ if (turbopack?.type === 'ConditionalExpression') {
87
+ collectTurbopackAliases(turbopack.consequent);
88
+ collectTurbopackAliases(turbopack.alternate);
89
+ }
90
+ else {
91
+ collectTurbopackAliases(turbopack);
92
+ }
93
+ const rules = findProperty(turbopack, 'rules');
64
94
  if (rules?.type !== 'ObjectExpression')
65
95
  return;
66
96
  for (const rule of rules.properties) {
@@ -75,6 +105,8 @@ const resolveFromAST = (program, { configFileDir }) => {
75
105
  const inputs = patterns.map(id => toProductionEntry(join(configFileDir, id)));
76
106
  for (const loader of loaders)
77
107
  inputs.push(toDeferResolve(loader));
108
+ for (const target of aliasTargets)
109
+ inputs.push({ ...toDeferResolve(target, { dir: configFileDir }), production: true });
78
110
  return inputs;
79
111
  };
80
112
  const commands = new Set(['dev', 'build', 'start']);
@@ -1,6 +1,8 @@
1
1
  import { compact } from '../../util/array.js';
2
- import { toConfig, toDependency } from '../../util/input.js';
3
- import { join } from '../../util/path.js';
2
+ import { isFile, loadJSON } from '../../util/fs.js';
3
+ import { toConfig, toDeferResolveEntry, toDependency } from '../../util/input.js';
4
+ import { get } from '../../util/object.js';
5
+ import { dirname, join, relative } from '../../util/path.js';
4
6
  import { hasDependency } from '../../util/plugin.js';
5
7
  import { substringBefore } from '../../util/string.js';
6
8
  const title = 'Nx';
@@ -53,32 +55,71 @@ const resolveConfig = async (localConfig, options) => {
53
55
  commands = [target.options.command];
54
56
  else if (target.options?.commands)
55
57
  commands = target.options.commands.map(commandConfig => typeof commandConfig === 'string' ? commandConfig : commandConfig.command);
56
- return options.getInputsFromScripts(commands.map(expand), { cwd: resolveTargetCwd(target.options?.cwd) });
58
+ const cwd = resolveTargetCwd(target.options?.cwd);
59
+ const expandRelative = (command) => command
60
+ .replaceAll('{projectRoot}', relative(cwd, options.configFileDir))
61
+ .replaceAll('{workspaceRoot}', relative(cwd, options.rootCwd));
62
+ const scriptInputs = options.getInputsFromScripts(commands.map(expandRelative), { cwd });
63
+ for (const input of scriptInputs)
64
+ input.dir ??= cwd;
65
+ return scriptInputs;
57
66
  });
67
+ const toTargetConfig = (pluginName, specifier) => toConfig(pluginName, expand(specifier), { dir: options.rootCwd });
58
68
  const configInputs = targets.flatMap(target => {
59
69
  const opts = target.options;
60
70
  if (!opts)
61
71
  return [];
62
72
  const configs = [];
63
73
  if ('eslintConfig' in opts && typeof opts.eslintConfig === 'string') {
64
- configs.push(toConfig('eslint', opts.eslintConfig));
74
+ configs.push(toTargetConfig('eslint', opts.eslintConfig));
65
75
  }
66
76
  if ('jestConfig' in opts && typeof opts.jestConfig === 'string') {
67
- configs.push(toConfig('jest', opts.jestConfig));
77
+ configs.push(toTargetConfig('jest', opts.jestConfig));
78
+ }
79
+ if ('karmaConfig' in opts && typeof opts.karmaConfig === 'string') {
80
+ configs.push(toTargetConfig('karma', opts.karmaConfig));
68
81
  }
69
82
  if ('tsConfig' in opts && typeof opts.tsConfig === 'string') {
70
- configs.push(toConfig('typescript', opts.tsConfig));
83
+ configs.push(toTargetConfig('typescript', opts.tsConfig));
71
84
  }
72
85
  if ('vitestConfig' in opts && typeof opts.vitestConfig === 'string') {
73
- configs.push(toConfig('vitest', opts.vitestConfig));
86
+ configs.push(toTargetConfig('vitest', opts.vitestConfig));
74
87
  }
75
88
  if ('webpackConfig' in opts && typeof opts.webpackConfig === 'string') {
76
- configs.push(toConfig('webpack', opts.webpackConfig));
89
+ configs.push(toTargetConfig('webpack', opts.webpackConfig));
77
90
  }
78
91
  return configs;
79
92
  });
80
93
  return compact([...executors, ...inputs, ...configInputs]).map(id => typeof id === 'string' ? toDependency(id) : id);
81
94
  };
95
+ const collections = [
96
+ ['generators', 'schematics'],
97
+ ['executors', 'builders'],
98
+ ];
99
+ const resolve = async (options) => {
100
+ const inputs = [];
101
+ for (const [key, alias] of collections) {
102
+ const file = get(options.manifest, key) ?? get(options.manifest, alias);
103
+ if (typeof file !== 'string')
104
+ continue;
105
+ const filePath = join(options.cwd, file);
106
+ if (!isFile(filePath))
107
+ continue;
108
+ const collection = await loadJSON(filePath);
109
+ for (const entries of [collection[key], collection[alias]]) {
110
+ for (const entry of Object.values(entries ?? {})) {
111
+ if (!entry || typeof entry !== 'object')
112
+ continue;
113
+ for (const id of [entry.implementation || entry.factory, entry.batchImplementation]) {
114
+ if (typeof id === 'string' && id.length > 0) {
115
+ inputs.push(toDeferResolveEntry(join(dirname(filePath), substringBefore(id, '#'))));
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+ return inputs;
122
+ };
82
123
  const args = {
83
124
  fromArgs: (parsed) => (parsed._[0] === 'exec' ? [...parsed._.slice(1), ...(parsed['--'] ?? [])] : []),
84
125
  };
@@ -91,6 +132,7 @@ const plugin = {
91
132
  isEnabled,
92
133
  config,
93
134
  resolveConfig,
135
+ resolve,
94
136
  args,
95
137
  };
96
138
  export default plugin;
@@ -11,6 +11,7 @@ export interface NxProjectConfiguration {
11
11
  cwd?: string;
12
12
  eslintConfig?: string;
13
13
  jestConfig?: string;
14
+ karmaConfig?: string;
14
15
  tsConfig?: string;
15
16
  vitestConfig?: string;
16
17
  webpackConfig?: string;
@@ -18,6 +19,12 @@ export interface NxProjectConfiguration {
18
19
  };
19
20
  };
20
21
  }
22
+ type NxCollectionEntry = string | {
23
+ factory?: string;
24
+ implementation?: string;
25
+ batchImplementation?: string;
26
+ };
27
+ export type NxCollection = Record<string, Record<string, NxCollectionEntry> | undefined>;
21
28
  export interface NxConfigRoot {
22
29
  plugins?: Array<string | {
23
30
  plugin: string;
@@ -25,3 +32,4 @@ export interface NxConfigRoot {
25
32
  generators?: Record<string, unknown>;
26
33
  targetDefaults?: Record<string, unknown>;
27
34
  }
35
+ export {};
@@ -26,7 +26,7 @@ export const resolveExtendedConfig = (config, configFilePath) => {
26
26
  for (const entry of config.extends ?? []) {
27
27
  if (typeof entry === 'string') {
28
28
  const filePath = toAbsolute(entry, dirname(configFilePath));
29
- inputs.push(toConfig('oxlint', filePath, { containingFilePath: configFilePath }));
29
+ inputs.push(toConfig('oxlint', filePath));
30
30
  }
31
31
  else {
32
32
  for (const input of resolveExtendedConfig(entry, configFilePath))
@@ -3,7 +3,7 @@ import { hasDependency } from '../../util/plugin.js';
3
3
  const title = 'React Native';
4
4
  const enablers = ['react-native'];
5
5
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
6
- const config = ['react-native.config.js'];
6
+ const config = ['react-native.config.{js,cjs,mjs,ts}'];
7
7
  const RN_CLI_PACKAGES = [
8
8
  '@react-native-community/cli',
9
9
  '@react-native-community/cli-platform-android',
@@ -1,3 +1,6 @@
1
1
  import type { Plugin } from '../../types/config.ts';
2
+ export declare const docs: {
3
+ note: string;
4
+ };
2
5
  declare const plugin: Plugin;
3
6
  export default plugin;
@@ -43,6 +43,9 @@ const resolveConfig = async (localConfig, options) => {
43
43
  }
44
44
  return resolved;
45
45
  };
46
+ const note = `Route modules import their types from \`./+types/<route>\`, which \`react-router typegen\` generates.
47
+ Run \`react-router typegen\` before Knip (e.g. in CI or a fresh checkout), or these imports are reported as unresolved.`;
48
+ export const docs = { note };
46
49
  const plugin = {
47
50
  title,
48
51
  enablers,
@@ -5,7 +5,19 @@ const title = 'Rsbuild';
5
5
  const enablers = ['@rsbuild/core'];
6
6
  const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
7
7
  const config = ['rsbuild*.config.{mjs,ts,js,cjs,mts,cts}'];
8
- const resolveConfig = async (config, options) => {
8
+ const configParams = [
9
+ { env: 'development', command: 'dev', envMode: 'development' },
10
+ { env: 'production', command: 'build', envMode: 'production' },
11
+ ];
12
+ const getConfigs = async (configOrFn) => {
13
+ if (typeof configOrFn !== 'function')
14
+ return [configOrFn];
15
+ const configs = [];
16
+ for (const params of configParams)
17
+ configs.push(await configOrFn(params));
18
+ return configs;
19
+ };
20
+ const resolveConfig = async (configOrFn, options) => {
9
21
  const entries = new Set();
10
22
  const inputs = [];
11
23
  const checkSource = (source) => {
@@ -34,7 +46,7 @@ const resolveConfig = async (config, options) => {
34
46
  entries.add(e);
35
47
  }
36
48
  };
37
- const checkConfig = async (localConfig) => {
49
+ const checkConfig = async (localConfig, config) => {
38
50
  checkSource(localConfig.source);
39
51
  if (!localConfig.tools?.rspack)
40
52
  return;
@@ -68,10 +80,12 @@ const resolveConfig = async (config, options) => {
68
80
  }
69
81
  }
70
82
  };
71
- await checkConfig(config);
72
- if (config.environments) {
73
- for (const environment of Object.values(config.environments)) {
74
- await checkConfig(environment);
83
+ for (const config of await getConfigs(configOrFn)) {
84
+ await checkConfig(config, config);
85
+ if (config.environments) {
86
+ for (const environment of Object.values(config.environments)) {
87
+ await checkConfig(environment, config);
88
+ }
75
89
  }
76
90
  }
77
91
  for (const entry of entries)
@@ -29,4 +29,10 @@ export type RsbuildConfig = {
29
29
  [k: string]: Omit<RsbuildConfig, 'environments'>;
30
30
  };
31
31
  };
32
+ export type ConfigParams = {
33
+ env: string;
34
+ command: string;
35
+ envMode: string;
36
+ };
37
+ export type RsbuildConfigOrFn = RsbuildConfig | ((params: ConfigParams) => RsbuildConfig | Promise<RsbuildConfig>);
32
38
  export {};
@@ -91,7 +91,7 @@ const resolveConfig = async (localConfig, options) => {
91
91
  .catch(() => undefined)
92
92
  : undefined;
93
93
  if (!project) {
94
- inputs.push(toConfig('rstest', filePath, { containingFilePath: configFilePath }));
94
+ inputs.push(toConfig('rstest', filePath));
95
95
  continue;
96
96
  }
97
97
  inputs.push(toEntry(filePath));
@@ -1,3 +1,4 @@
1
+ import type { ConfigParams } from '../rsbuild/types.ts';
1
2
  type TestEnvironment = 'node' | 'jsdom' | 'happy-dom';
2
3
  export type RstestProjectConfig = {
3
4
  root?: string;
@@ -23,10 +24,5 @@ type RstestConfig = RstestProjectConfig & {
23
24
  provider?: 'istanbul' | 'v8';
24
25
  };
25
26
  };
26
- type ConfigParams = {
27
- env: string;
28
- command: string;
29
- envMode: string;
30
- };
31
27
  export type RstestConfigOrFn = RstestConfig | ((params: ConfigParams) => RstestConfig | Promise<RstestConfig>);
32
28
  export {};
@@ -0,0 +1,6 @@
1
+ import type { Plugin } from '../../types/config.ts';
2
+ export declare const docs: {
3
+ note: string;
4
+ };
5
+ declare const plugin: Plugin;
6
+ export default plugin;
@@ -0,0 +1,17 @@
1
+ import { hasDependency } from '../../util/plugin.js';
2
+ import { config } from '../vite/index.js';
3
+ import { production, resolveFromAST } from './resolveFromAST.js';
4
+ const title = '@solidjs/vite-plugin';
5
+ const enablers = ['@solidjs/vite-plugin'];
6
+ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
7
+ const note = `Without a Vite config, the default entry patterns are used. With a config, start entries are only added when \`start\` is enabled. Paths like \`start.app\` replace the matching default, and the \`ssr\` option decides which files Solid loads. \`serverFunctions.configure\` is added with or without \`start\`.`;
8
+ export const docs = { note };
9
+ const plugin = {
10
+ title,
11
+ enablers,
12
+ isEnabled,
13
+ config,
14
+ production,
15
+ resolveFromAST,
16
+ };
17
+ export default plugin;
@@ -0,0 +1,3 @@
1
+ import type { ResolveFromAST } from '../../types/config.ts';
2
+ export declare const production: string[];
3
+ export declare const resolveFromAST: ResolveFromAST;
@@ -0,0 +1,76 @@
1
+ import { findImportedCalls, findProperty } from '../../typescript/ast-helpers.js';
2
+ import { getStringValue } from '../../typescript/ast-nodes.js';
3
+ import { isFile } from '../../util/fs.js';
4
+ import { toProductionEntry } from '../../util/input.js';
5
+ import { join, toAbsolute } from '../../util/path.js';
6
+ import { getViteRoot } from '../vite/helpers.js';
7
+ const entryExtensions = ['tsx', 'jsx', 'ts', 'js', 'mjs', 'tsrx'];
8
+ const entryStems = {
9
+ entryServer: 'src/entry-server',
10
+ entryClient: 'src/entry-client',
11
+ };
12
+ const conventions = {
13
+ entryServer: `src/entry-server.{${entryExtensions.join(',')}}`,
14
+ entryClient: `src/entry-client.{${entryExtensions.join(',')}}`,
15
+ app: 'src/{App,app}.{tsx,jsx,ts,js,tsrx}',
16
+ document: 'src/Document.{tsx,jsx,tsrx}',
17
+ env: 'env.{ts,js}',
18
+ };
19
+ export const production = Object.values(conventions);
20
+ const startOptions = ['app', 'document', 'entryServer', 'entryClient', 'middleware', 'instrument', 'setup', 'env'];
21
+ const isBoolean = (node, value) => node?.type === 'Literal' && node.value === value;
22
+ const hasEntryFile = (root, stem) => {
23
+ for (const extension of entryExtensions)
24
+ if (isFile(root, `${stem}.${extension}`))
25
+ return true;
26
+ return false;
27
+ };
28
+ export const resolveFromAST = (program, options) => {
29
+ const root = getViteRoot(program, options.cwd);
30
+ const patterns = new Set();
31
+ const paths = new Set();
32
+ for (const call of findImportedCalls(program, '@solidjs/vite-plugin')) {
33
+ const arg = call.arguments[0];
34
+ if (arg?.type !== 'ObjectExpression')
35
+ continue;
36
+ const configure = getStringValue(findProperty(findProperty(arg, 'serverFunctions'), 'configure'));
37
+ if (configure)
38
+ paths.add(configure);
39
+ const start = findProperty(arg, 'start');
40
+ if (!start || isBoolean(start, false))
41
+ continue;
42
+ const values = {};
43
+ for (const name of startOptions) {
44
+ values[name] = start.type === 'ObjectExpression' ? findProperty(start, name) : undefined;
45
+ }
46
+ const isAuthored = (name) => Boolean(getStringValue(values[name])) || hasEntryFile(root, entryStems[name]);
47
+ const ssr = findProperty(arg, 'ssr');
48
+ const skip = new Set();
49
+ if (!ssr || isBoolean(ssr, false)) {
50
+ skip.add('entryServer');
51
+ skip.add('setup');
52
+ if (isAuthored('entryClient'))
53
+ skip.add('app');
54
+ }
55
+ else if (isBoolean(ssr, true) && isAuthored('entryServer') && isAuthored('entryClient')) {
56
+ skip.add('app');
57
+ skip.add('document');
58
+ }
59
+ for (const name of startOptions) {
60
+ if (skip.has(name))
61
+ continue;
62
+ const value = values[name];
63
+ const path = getStringValue(value);
64
+ if (path)
65
+ paths.add(path);
66
+ else if (name in conventions && !(name === 'env' && isBoolean(value, false)))
67
+ patterns.add(conventions[name]);
68
+ }
69
+ }
70
+ const inputs = [];
71
+ for (const pattern of patterns)
72
+ inputs.push(toProductionEntry(join(root, pattern)));
73
+ for (const id of paths)
74
+ inputs.push(toProductionEntry(toAbsolute(id, root)));
75
+ return inputs;
76
+ };
@@ -44,5 +44,5 @@ export const resolveFromAST = (program, options) => {
44
44
  visitor.visit(program);
45
45
  }
46
46
  catch { }
47
- return Array.from(entries).map(specifier => toDeferResolveProductionEntry(specifier, { containingFilePath: options.configFilePath }));
47
+ return Array.from(entries).map(specifier => toDeferResolveProductionEntry(specifier));
48
48
  };
@@ -1,8 +1,6 @@
1
1
  import scss from '../../compilers/scss.js';
2
- import { IMPORT_FLAGS } from '../../constants.js';
3
- import { getPropertyValues } from '../../typescript/ast-helpers.js';
4
- import { dirname, join } from '../../util/path.js';
5
2
  import { hasDependency } from '../../util/plugin.js';
3
+ import { createComponentStyleUrlsVisitor } from '../_component-style-urls/component-style-urls-visitor.js';
6
4
  import { createCustomElementVisitor } from '../_custom-elements/custom-element-visitor.js';
7
5
  import { entry, resolveFromAST } from './resolveFromAST.js';
8
6
  const title = 'Stencil';
@@ -18,42 +16,7 @@ const registerCompilers = ({ hasDependency, registerCompiler }) => {
18
16
  };
19
17
  const registerVisitors = ({ ctx, registerVisitor }) => {
20
18
  registerVisitor(createCustomElementVisitor(ctx, isStencilSpecifier, { decoratorName: 'Component' }));
21
- const componentNames = new Set();
22
- registerVisitor({
23
- Program() {
24
- componentNames.clear();
25
- },
26
- ImportDeclaration(node) {
27
- if (!isStencilSpecifier(node.source?.value))
28
- return;
29
- for (const spec of node.specifiers ?? []) {
30
- if (spec.type === 'ImportSpecifier' &&
31
- spec.imported.type === 'Identifier' &&
32
- spec.imported.name === 'Component')
33
- componentNames.add(spec.local.name);
34
- }
35
- },
36
- ClassDeclaration(node) {
37
- resolveStyleUrls(node);
38
- },
39
- });
40
- function resolveStyleUrls(node) {
41
- const dir = dirname(ctx.filePath);
42
- for (const decorator of node.decorators ?? []) {
43
- const expr = decorator.expression;
44
- if (expr?.type !== 'CallExpression')
45
- continue;
46
- if (expr.callee?.type !== 'Identifier' || !componentNames.has(expr.callee.name))
47
- continue;
48
- const arg = expr.arguments?.[0];
49
- if (arg?.type !== 'ObjectExpression')
50
- continue;
51
- for (const url of getPropertyValues(arg, 'styleUrl'))
52
- ctx.addImport(join(dir, url), arg.start, IMPORT_FLAGS.NONE);
53
- for (const url of getPropertyValues(arg, 'styleUrls'))
54
- ctx.addImport(join(dir, url), arg.start, IMPORT_FLAGS.NONE);
55
- }
56
- }
19
+ registerVisitor(createComponentStyleUrlsVisitor(ctx, isStencilSpecifier));
57
20
  };
58
21
  const plugin = {
59
22
  title,
@@ -12,7 +12,7 @@ const restEntry = ['.{storybook,rnstorybook}/{manager,preview,index,vitest.setup
12
12
  const entry = [...restEntry, ...stories];
13
13
  const project = ['.{storybook,rnstorybook}/**/*.{js,jsx,ts,tsx,mts}'];
14
14
  const resolveConfig = async (localConfig, options) => {
15
- const { cwd, configFileDir, configFilePath } = options;
15
+ const { cwd, configFileDir } = options;
16
16
  const strs = typeof localConfig?.stories === 'function' ? await localConfig.stories(stories) : localConfig?.stories;
17
17
  const relativePatterns = strs?.map(pattern => {
18
18
  if (typeof pattern === 'string')
@@ -37,9 +37,7 @@ const resolveConfig = async (localConfig, options) => {
37
37
  const viteConfigPath = typeof framework === 'object' &&
38
38
  framework?.name === '@storybook/react-vite' &&
39
39
  framework?.options?.builder?.viteConfigPath;
40
- const configs = viteConfigPath
41
- ? [toConfig('vite', viteConfigPath, { dir: cwd, containingFilePath: configFilePath })]
42
- : [];
40
+ const configs = viteConfigPath ? [toConfig('vite', viteConfigPath, { dir: cwd })] : [];
43
41
  const hasVitestAddon = addons.some(addon => addon === '@storybook/addon-vitest');
44
42
  const coverageDeps = hasVitestAddon
45
43
  ? [
@@ -1,5 +1,6 @@
1
1
  import parseArgs from '../../util/parse-args.js';
2
2
  import { parse } from 'unbash';
3
+ import { getCommandWords, collectCommands } from '../../util/scripts.js';
3
4
  const BIN = 'svelte-package';
4
5
  export const DEFAULT_INPUT = 'src/lib';
5
6
  export const DEFAULT_OUTPUT = 'dist';
@@ -7,48 +8,6 @@ const parseCommandIO = (args) => {
7
8
  const parsed = parseArgs(args, { string: ['i', 'o', 'input', 'output'], alias: { input: ['i'], output: ['o'] } });
8
9
  return { input: parsed.input ?? DEFAULT_INPUT, output: parsed.output ?? DEFAULT_OUTPUT };
9
10
  };
10
- const collectFromCommands = (statements, out) => {
11
- for (const stmt of statements)
12
- visit(stmt.command, out);
13
- };
14
- const visit = (node, out) => {
15
- switch (node.type) {
16
- case 'Command':
17
- if (node.name?.value === BIN)
18
- out.push(parseCommandIO(node.suffix.map(w => w.value)));
19
- return;
20
- case 'AndOr':
21
- case 'Pipeline':
22
- for (const n of node.commands)
23
- visit(n, out);
24
- return;
25
- case 'If':
26
- collectFromCommands(node.clause.commands, out);
27
- collectFromCommands(node.then.commands, out);
28
- if (node.else)
29
- visit(node.else, out);
30
- return;
31
- case 'While':
32
- collectFromCommands(node.clause.commands, out);
33
- collectFromCommands(node.body.commands, out);
34
- return;
35
- case 'For':
36
- case 'Select':
37
- case 'Subshell':
38
- case 'BraceGroup':
39
- collectFromCommands(node.body.commands, out);
40
- return;
41
- case 'CompoundList':
42
- collectFromCommands(node.commands, out);
43
- return;
44
- case 'Function':
45
- case 'Coproc':
46
- visit(node.body, out);
47
- return;
48
- case 'Statement':
49
- visit(node.command, out);
50
- }
51
- };
52
11
  export const parseScripts = (scripts) => {
53
12
  const out = [];
54
13
  for (const script of Object.values(scripts ?? {})) {
@@ -56,8 +15,12 @@ export const parseScripts = (scripts) => {
56
15
  continue;
57
16
  try {
58
17
  const parsed = parse(script);
59
- if (parsed.commands)
60
- collectFromCommands(parsed.commands, out);
18
+ for (const statement of parsed.commands) {
19
+ for (const node of collectCommands(statement.command)) {
20
+ if (node.name?.value === BIN)
21
+ out.push(parseCommandIO(getCommandWords(node).map(word => word.value)));
22
+ }
23
+ }
61
24
  }
62
25
  catch { }
63
26
  }
@@ -78,7 +78,7 @@ const extractScriptsFromTask = (task) => {
78
78
  const resolveConfig = async (localConfig, options) => {
79
79
  if (!localConfig || !options.configFilePath)
80
80
  return [];
81
- const { configFilePath, getInputsFromScripts, isProduction, configFileDir } = options;
81
+ const { getInputsFromScripts, isProduction, configFileDir } = options;
82
82
  const inputs = [];
83
83
  if (localConfig.includes && typeof localConfig.includes === 'object') {
84
84
  for (const includeValue of Object.values(localConfig.includes)) {
@@ -89,17 +89,14 @@ const resolveConfig = async (localConfig, options) => {
89
89
  : undefined;
90
90
  if (includePath) {
91
91
  const resolvedPath = join(configFileDir, includePath);
92
- inputs.push(toConfig('taskfile', relative(configFileDir, resolvedPath), { containingFilePath: configFilePath }));
92
+ inputs.push(toConfig('taskfile', relative(configFileDir, resolvedPath)));
93
93
  }
94
94
  }
95
95
  }
96
96
  if (localConfig.tasks && typeof localConfig.tasks === 'object') {
97
97
  for (const task of Object.values(localConfig.tasks)) {
98
98
  for (const script of extractScriptsFromTask(task)) {
99
- for (const input of getInputsFromScripts([script], {
100
- optionalBinaries: true,
101
- containingFilePath: configFilePath,
102
- })) {
99
+ for (const input of getInputsFromScripts([script], { optionalBinaries: true })) {
103
100
  if (isProduction)
104
101
  Object.assign(input, { optional: true });
105
102
  inputs.push({ ...input, dir: configFileDir });
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from '../../types/config.ts';
2
+ declare const plugin: Plugin;
3
+ export default plugin;
@@ -0,0 +1,15 @@
1
+ import { hasDependency } from '../../util/plugin.js';
2
+ import { args as typescriptArgs, config, resolveConfig } from '../typescript/index.js';
3
+ const title = 'tsrs';
4
+ const enablers = ['tsrs'];
5
+ const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
6
+ const args = { ...typescriptArgs, binaries: ['tsrs'] };
7
+ const plugin = {
8
+ title,
9
+ enablers,
10
+ isEnabled,
11
+ config,
12
+ resolveConfig,
13
+ args,
14
+ };
15
+ export default plugin;
@@ -1,4 +1,15 @@
1
- import type { Plugin } from '../../types/config.ts';
1
+ import type { Plugin, ResolveConfig } from '../../types/config.ts';
2
+ import type { TsConfigJson } from '../../types/tsconfig-json.ts';
3
+ export declare const config: string[];
4
+ export declare const resolveConfig: ResolveConfig<TsConfigJson>;
5
+ export declare const args: {
6
+ binaries: string[];
7
+ string: string[];
8
+ alias: {
9
+ project: string[];
10
+ };
11
+ config: [string, (p: string) => string][];
12
+ };
2
13
  export declare const docs: {
3
14
  note: string;
4
15
  };