@reliverse/dler 2.3.3 → 2.3.4

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.
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,133 @@
1
+ import { logger } from "@reliverse/relinka";
2
+ import { defineCommand, option } from "@reliverse/rempts-core";
3
+ import { type } from "arktype";
4
+ import { removeDependency } from "./impl.js";
5
+ export default defineCommand({
6
+ description: "Remove dependencies from package.json files with catalog support",
7
+ options: {
8
+ // Target package selection
9
+ target: option(type("string | undefined"), {
10
+ short: "t",
11
+ description: "Target workspace package(s) (from workspaces.packages). Use '.' for current directory package. Supports multiple packages (space-separated) and glob patterns."
12
+ }),
13
+ package: option(type("string | undefined"), {
14
+ description: "Target workspace package(s) (alias for --target). Use '.' for current directory package. Supports multiple packages (space-separated) and glob patterns."
15
+ }),
16
+ pkg: option(type("string | undefined"), {
17
+ description: "Target workspace package(s) (alias for --target). Use '.' for current directory package. Supports multiple packages (space-separated) and glob patterns."
18
+ }),
19
+ w: option(type("boolean | undefined"), {
20
+ description: "Remove dependency from root package.json"
21
+ }),
22
+ // Catalog options
23
+ catalog: option(type("string | boolean | undefined"), {
24
+ short: "c",
25
+ description: "Use catalog mode. Can be 'true', 'false', or a catalog name (e.g., 'testing')",
26
+ default: true
27
+ }),
28
+ // Dependency scope/type
29
+ scope: option(type("'dev'|'prod'|'peer'|'optional' | undefined"), {
30
+ short: "s",
31
+ description: "Dependency scope: dev, prod, peer, optional"
32
+ }),
33
+ dev: option(type("boolean | undefined"), {
34
+ short: "D",
35
+ description: "Remove from devDependencies (shorthand for --scope dev)"
36
+ }),
37
+ prod: option(type("boolean | undefined"), {
38
+ short: "P",
39
+ description: "Remove from dependencies (shorthand for --scope prod)"
40
+ }),
41
+ peer: option(type("boolean | undefined"), {
42
+ short: "R",
43
+ description: "Remove from peerDependencies (shorthand for --scope peer)"
44
+ }),
45
+ optional: option(type("boolean | undefined"), {
46
+ short: "O",
47
+ description: "Remove from optionalDependencies (shorthand for --scope optional)"
48
+ }),
49
+ // Other options
50
+ install: option(type("boolean | undefined"), {
51
+ description: "Run install after removing dependencies (default: true)",
52
+ short: "i",
53
+ default: true
54
+ }),
55
+ cwd: option(type("string | undefined"), {
56
+ description: "Working directory (monorepo root)"
57
+ }),
58
+ dryRun: option(type("boolean | undefined"), {
59
+ short: "n",
60
+ description: "Show what would be done without making changes"
61
+ }),
62
+ verbose: option(type("boolean | undefined"), {
63
+ short: "v",
64
+ description: "Verbose output"
65
+ })
66
+ },
67
+ handler: async ({ flags, positional }) => {
68
+ try {
69
+ if (typeof process.versions.bun === "undefined") {
70
+ logger.error("\u274C This command requires Bun runtime.");
71
+ logger.error("Please run this command using Bun: bun dler rm <package>");
72
+ process.exit(1);
73
+ }
74
+ if (positional.length === 0) {
75
+ logger.error("\u274C No package names provided.");
76
+ logger.log("Usage: dler rm <package> [package2...] [options]");
77
+ logger.log("");
78
+ logger.log("Examples:");
79
+ logger.log(" dler rm lodash");
80
+ logger.log(" dler rm typescript --dev");
81
+ logger.log(" dler rm react react-dom --target @scope/ui");
82
+ process.exit(1);
83
+ }
84
+ const packageList = positional.join(", ");
85
+ logger.log(`\u{1F5D1}\uFE0F Removing dependencies: ${packageList}`);
86
+ if (flags.dryRun) {
87
+ logger.log("\u{1F50D} Running in dry-run mode (no changes will be made)");
88
+ }
89
+ const packageNames = positional;
90
+ let scope;
91
+ if (flags.scope) {
92
+ scope = flags.scope;
93
+ } else if (flags.dev) {
94
+ scope = "dev";
95
+ } else if (flags.prod) {
96
+ scope = "prod";
97
+ } else if (flags.peer) {
98
+ scope = "peer";
99
+ } else if (flags.optional) {
100
+ scope = "optional";
101
+ }
102
+ let catalogMode = flags.catalog ?? true;
103
+ if (typeof flags.catalog === "string") {
104
+ catalogMode = flags.catalog;
105
+ }
106
+ const options = {
107
+ target: flags.target || flags.package || flags.pkg,
108
+ w: flags.w,
109
+ catalog: catalogMode,
110
+ scope,
111
+ install: flags.install ?? true,
112
+ cwd: flags.cwd || void 0,
113
+ dryRun: flags.dryRun ?? false,
114
+ verbose: flags.verbose ?? false
115
+ };
116
+ await removeDependency(packageNames, options);
117
+ } catch (error) {
118
+ logger.error("\n\u274C Failed to remove dependencies:");
119
+ if (error instanceof Error) {
120
+ logger.error(error.message);
121
+ } else {
122
+ logger.error(String(error));
123
+ }
124
+ logger.log("");
125
+ logger.log("\u{1F4A1} Tips:");
126
+ logger.log(" \u2022 Check if the package names are spelled correctly");
127
+ logger.log(" \u2022 Ensure the packages are actually installed");
128
+ logger.log(" \u2022 Use --verbose flag for more detailed output");
129
+ logger.log(" \u2022 Use --dry-run flag to see what would be changed without making changes");
130
+ process.exit(1);
131
+ }
132
+ }
133
+ });
@@ -0,0 +1,17 @@
1
+ export interface RemoveOptions {
2
+ target?: string;
3
+ w?: boolean;
4
+ catalog: boolean | string;
5
+ scope?: "dev" | "prod" | "peer" | "optional";
6
+ install: boolean;
7
+ cwd?: string;
8
+ dryRun: boolean;
9
+ verbose: boolean;
10
+ }
11
+ export interface MonorepoInfo {
12
+ isMonorepo: boolean;
13
+ rootPath: string;
14
+ rootPackageJson: any;
15
+ workspacePackages?: string[];
16
+ }
17
+ export declare function removeDependency(packageNames: string | string[], options: RemoveOptions): Promise<boolean>;
@@ -0,0 +1,509 @@
1
+ import { existsSync } from "node:fs";
2
+ import { relative, resolve } from "node:path";
3
+ import { createIncludeFilter } from "@reliverse/matcha";
4
+ import path from "@reliverse/pathkit";
5
+ import { logger } from "@reliverse/relinka";
6
+ import { hasWorkspaces, readPackageJSON, writePackageJSON } from "@reliverse/typerso";
7
+ import { runInstallCommand } from "../update/utils.js";
8
+ const packageInfoCache = /* @__PURE__ */ new Map();
9
+ async function getWorkspacePackageInfos(monorepoInfo) {
10
+ if (packageInfoCache.has(monorepoInfo.rootPath)) {
11
+ return packageInfoCache.get(monorepoInfo.rootPath);
12
+ }
13
+ if (!monorepoInfo.workspacePackages) {
14
+ const empty = [];
15
+ packageInfoCache.set(monorepoInfo.rootPath, empty);
16
+ return empty;
17
+ }
18
+ const packageInfos = [];
19
+ const readPromises = monorepoInfo.workspacePackages.map(async (pkgPath) => {
20
+ const packageJson = await readPackageJSON(pkgPath);
21
+ if (packageJson?.name) {
22
+ return {
23
+ name: packageJson.name,
24
+ path: pkgPath,
25
+ json: packageJson
26
+ };
27
+ }
28
+ return null;
29
+ });
30
+ const results = await Promise.all(readPromises);
31
+ for (const result of results) {
32
+ if (result) {
33
+ packageInfos.push(result);
34
+ }
35
+ }
36
+ packageInfoCache.set(monorepoInfo.rootPath, packageInfos);
37
+ return packageInfos;
38
+ }
39
+ const monorepoCache = /* @__PURE__ */ new Map();
40
+ async function detectMonorepo(startDir) {
41
+ const cwd = resolve(startDir ?? process.cwd());
42
+ if (monorepoCache.has(cwd)) {
43
+ return monorepoCache.get(cwd);
44
+ }
45
+ let currentDir = cwd;
46
+ while (true) {
47
+ const packageJsonPath2 = path.join(currentDir, "package.json");
48
+ if (existsSync(packageJsonPath2)) {
49
+ const packageJson2 = await readPackageJSON(currentDir);
50
+ if (packageJson2 && hasWorkspaces(packageJson2)) {
51
+ const workspacePackages = await discoverWorkspacePackages(currentDir, packageJson2);
52
+ const result2 = {
53
+ isMonorepo: true,
54
+ rootPath: currentDir,
55
+ rootPackageJson: packageJson2,
56
+ workspacePackages
57
+ };
58
+ monorepoCache.set(cwd, result2);
59
+ return result2;
60
+ }
61
+ }
62
+ const parentDir = path.dirname(currentDir);
63
+ if (parentDir === currentDir) {
64
+ break;
65
+ }
66
+ currentDir = parentDir;
67
+ }
68
+ const packageJsonPath = path.join(cwd, "package.json");
69
+ if (!existsSync(packageJsonPath)) {
70
+ throw new Error("No package.json found in current directory or any parent directory");
71
+ }
72
+ const packageJson = await readPackageJSON(cwd);
73
+ if (!packageJson) {
74
+ throw new Error("Could not read package.json");
75
+ }
76
+ const result = {
77
+ isMonorepo: false,
78
+ rootPath: cwd,
79
+ rootPackageJson: packageJson
80
+ };
81
+ monorepoCache.set(cwd, result);
82
+ return result;
83
+ }
84
+ const workspaceCache = /* @__PURE__ */ new Map();
85
+ async function discoverWorkspacePackages(monorepoRoot, rootPackageJson) {
86
+ if (workspaceCache.has(monorepoRoot)) {
87
+ return workspaceCache.get(monorepoRoot);
88
+ }
89
+ const packages = [];
90
+ if (!rootPackageJson.workspaces?.packages) {
91
+ workspaceCache.set(monorepoRoot, packages);
92
+ return packages;
93
+ }
94
+ const patterns = Array.isArray(rootPackageJson.workspaces.packages) ? rootPackageJson.workspaces.packages : [];
95
+ const packagePaths = [];
96
+ const validationPromises = [];
97
+ for (const pattern of patterns) {
98
+ if (pattern.includes("*")) {
99
+ const glob = new Bun.Glob(pattern);
100
+ const matches = glob.scanSync({ cwd: monorepoRoot, onlyFiles: false });
101
+ for (const match of matches) {
102
+ const packagePath = resolve(monorepoRoot, match);
103
+ packagePaths.push(packagePath);
104
+ validationPromises.push(isValidWorkspacePackage(packagePath));
105
+ }
106
+ } else {
107
+ const packagePath = resolve(monorepoRoot, pattern);
108
+ packagePaths.push(packagePath);
109
+ validationPromises.push(isValidWorkspacePackage(packagePath));
110
+ }
111
+ }
112
+ const validationResults = await Promise.all(validationPromises);
113
+ for (let i = 0; i < packagePaths.length; i++) {
114
+ if (validationResults[i]) {
115
+ packages.push(packagePaths[i]);
116
+ }
117
+ }
118
+ workspaceCache.set(monorepoRoot, packages);
119
+ return packages;
120
+ }
121
+ async function isValidWorkspacePackage(packagePath) {
122
+ const packageJsonPath = path.join(packagePath, "package.json");
123
+ if (!existsSync(packageJsonPath)) {
124
+ return false;
125
+ }
126
+ const packageJson = await readPackageJSON(packagePath);
127
+ return !!packageJson?.name;
128
+ }
129
+ function resolveCatalog(monorepoInfo, catalogOption) {
130
+ if (!monorepoInfo.isMonorepo) {
131
+ return { catalogName: null, catalogPath: null };
132
+ }
133
+ const workspaces = monorepoInfo.rootPackageJson.workspaces;
134
+ if (catalogOption === false) {
135
+ return { catalogName: null, catalogPath: null };
136
+ }
137
+ let catalogName;
138
+ if (typeof catalogOption === "string") {
139
+ catalogName = catalogOption;
140
+ } else {
141
+ catalogName = "catalog";
142
+ }
143
+ const catalogExists = workspaces[catalogName];
144
+ if (!catalogExists) {
145
+ if (typeof catalogOption === "string") {
146
+ throw new Error(`Catalog '${catalogName}' not found in workspaces configuration`);
147
+ }
148
+ return { catalogName: null, catalogPath: null };
149
+ }
150
+ return {
151
+ catalogName,
152
+ catalogPath: catalogName
153
+ };
154
+ }
155
+ function containsGlobPattern(str) {
156
+ return str.includes("*") || str.includes("?") || str.includes("[") || str.includes("{");
157
+ }
158
+ function containsMultipleTargets(str) {
159
+ return str.includes(" ") && str.trim().split(/\s+/).length > 1;
160
+ }
161
+ async function resolveTargetPackage(monorepoInfo, options) {
162
+ const { target, w } = options;
163
+ if (w) {
164
+ return {
165
+ packagePath: monorepoInfo.rootPath,
166
+ packageJson: monorepoInfo.rootPackageJson
167
+ };
168
+ }
169
+ if (target) {
170
+ if (!monorepoInfo.isMonorepo) {
171
+ throw new Error("--target can only be used in monorepo environments");
172
+ }
173
+ if (target === ".") {
174
+ const cwd = resolve(options.cwd ?? process.cwd());
175
+ if (path.relative(monorepoInfo.rootPath, cwd) === "") {
176
+ return {
177
+ packagePath: monorepoInfo.rootPath,
178
+ packageJson: monorepoInfo.rootPackageJson
179
+ };
180
+ }
181
+ const workspacePackage = monorepoInfo.workspacePackages?.find(
182
+ (pkgPath) => path.relative(pkgPath, cwd) === "" || cwd === pkgPath || cwd.startsWith(pkgPath + path.sep)
183
+ );
184
+ if (workspacePackage) {
185
+ const packageInfos2 = await getWorkspacePackageInfos(monorepoInfo);
186
+ const cachedInfo = packageInfos2.find((info) => info.path === workspacePackage);
187
+ if (cachedInfo) {
188
+ return {
189
+ packagePath: workspacePackage,
190
+ packageJson: cachedInfo.json
191
+ };
192
+ }
193
+ const packageJson = await readPackageJSON(workspacePackage);
194
+ if (!packageJson) {
195
+ throw new Error(`Could not read package.json from ${workspacePackage}`);
196
+ }
197
+ return {
198
+ packagePath: workspacePackage,
199
+ packageJson
200
+ };
201
+ }
202
+ throw new Error(`Current directory is not a workspace package and not the monorepo root`);
203
+ }
204
+ if (containsMultipleTargets(target)) {
205
+ const targetNames = target.trim().split(/\s+/);
206
+ const packageInfos2 = await getWorkspacePackageInfos(monorepoInfo);
207
+ const targets = [];
208
+ for (const targetName of targetNames) {
209
+ if (targetName === "*") {
210
+ targets.push(
211
+ ...packageInfos2.map((pkg) => ({
212
+ packagePath: pkg.path,
213
+ packageJson: pkg.json
214
+ }))
215
+ );
216
+ } else if (containsGlobPattern(targetName)) {
217
+ const includeFilter = createIncludeFilter(targetName);
218
+ const matchingPackages = includeFilter(packageInfos2);
219
+ if (matchingPackages.length === 0) {
220
+ throw new Error(`No workspace packages match pattern '${targetName}'`);
221
+ }
222
+ targets.push(
223
+ ...matchingPackages.map((pkg) => ({
224
+ packagePath: pkg.path,
225
+ packageJson: pkg.json
226
+ }))
227
+ );
228
+ } else {
229
+ const matchingPackage2 = packageInfos2.find((info) => info.name === targetName);
230
+ if (!matchingPackage2) {
231
+ throw new Error(`Workspace package '${targetName}' not found`);
232
+ }
233
+ targets.push({
234
+ packagePath: matchingPackage2.path,
235
+ packageJson: matchingPackage2.json
236
+ });
237
+ }
238
+ }
239
+ const uniqueTargets = targets.filter(
240
+ (target2, index, self) => index === self.findIndex((t) => t.packagePath === target2.packagePath)
241
+ );
242
+ return {
243
+ targets: uniqueTargets,
244
+ isMultiple: true
245
+ };
246
+ }
247
+ if (target === "*") {
248
+ const packageInfos2 = await getWorkspacePackageInfos(monorepoInfo);
249
+ const targets = packageInfos2.map((pkg) => ({
250
+ packagePath: pkg.path,
251
+ packageJson: pkg.json
252
+ }));
253
+ return {
254
+ targets,
255
+ isMultiple: true
256
+ };
257
+ }
258
+ const packageInfos = await getWorkspacePackageInfos(monorepoInfo);
259
+ const matchingPackage = packageInfos.find((info) => info.name === target);
260
+ if (!matchingPackage) {
261
+ throw new Error(`Workspace package '${target}' not found`);
262
+ }
263
+ return {
264
+ packagePath: matchingPackage.path,
265
+ packageJson: matchingPackage.json
266
+ };
267
+ }
268
+ if (monorepoInfo.isMonorepo) {
269
+ return {
270
+ packagePath: monorepoInfo.rootPath,
271
+ packageJson: monorepoInfo.rootPackageJson
272
+ };
273
+ } else {
274
+ return {
275
+ packagePath: monorepoInfo.rootPath,
276
+ packageJson: monorepoInfo.rootPackageJson
277
+ };
278
+ }
279
+ }
280
+ async function removeDependencyFromPackage(packagePath, packageJson, packageName, scope, dryRun, verbose) {
281
+ const packageJsonPath = path.join(packagePath, "package.json");
282
+ const relativePath = relative(process.cwd(), packageJsonPath) || "package.json";
283
+ const allScopes = [
284
+ "prod",
285
+ "dev",
286
+ "peer",
287
+ "optional"
288
+ ];
289
+ let changesMade = false;
290
+ if (scope) {
291
+ const fieldName = getDependencyFieldName(scope);
292
+ if (!packageJson[fieldName]?.[packageName]) {
293
+ const foundInScopes = [];
294
+ for (const checkScope of allScopes) {
295
+ const checkFieldName = getDependencyFieldName(checkScope);
296
+ if (packageJson[checkFieldName]?.[packageName]) {
297
+ foundInScopes.push(checkScope);
298
+ }
299
+ }
300
+ if (foundInScopes.length > 0) {
301
+ logger.warn(
302
+ `\u26A0\uFE0F ${packageName} not found in ${fieldName} of ${relativePath}, but found in: ${foundInScopes.join(", ")}`
303
+ );
304
+ logger.warn(`\u{1F4A1} Try using --${foundInScopes[0]} flag`);
305
+ } else {
306
+ if (verbose) {
307
+ logger.info(`\u2139\uFE0F ${packageName} not found in ${fieldName} of ${relativePath}`);
308
+ }
309
+ }
310
+ return false;
311
+ }
312
+ delete packageJson[fieldName][packageName];
313
+ if (Object.keys(packageJson[fieldName]).length === 0) {
314
+ delete packageJson[fieldName];
315
+ }
316
+ if (dryRun) {
317
+ if (verbose) {
318
+ logger.log(`\u{1F4DD} Would remove ${packageName} from ${fieldName} in ${relativePath}`);
319
+ }
320
+ } else {
321
+ await writePackageJSON(packageJsonPath, packageJson);
322
+ }
323
+ return true;
324
+ }
325
+ for (const checkScope of allScopes) {
326
+ const fieldName = getDependencyFieldName(checkScope);
327
+ if (packageJson[fieldName]?.[packageName]) {
328
+ delete packageJson[fieldName][packageName];
329
+ if (Object.keys(packageJson[fieldName]).length === 0) {
330
+ delete packageJson[fieldName];
331
+ }
332
+ changesMade = true;
333
+ if (dryRun) {
334
+ if (verbose) {
335
+ logger.log(`\u{1F4DD} Would remove ${packageName} from ${fieldName} in ${relativePath}`);
336
+ }
337
+ }
338
+ }
339
+ }
340
+ if (changesMade && !dryRun) {
341
+ await writePackageJSON(packageJsonPath, packageJson);
342
+ }
343
+ if (!changesMade && verbose) {
344
+ logger.info(`\u2139\uFE0F ${packageName} not found in any dependency section of ${relativePath}`);
345
+ }
346
+ return changesMade;
347
+ }
348
+ async function removeDependencyFromCatalog(monorepoInfo, catalogInfo, packageName, dryRun, verbose) {
349
+ const workspaces = monorepoInfo.rootPackageJson.workspaces;
350
+ const catalogExists = workspaces[catalogInfo.catalogName];
351
+ if (!catalogExists) {
352
+ throw new Error(`Catalog '${catalogInfo.catalogName}' not found`);
353
+ }
354
+ if (!catalogExists[packageName]) {
355
+ if (verbose) {
356
+ logger.info(`\u2139\uFE0F ${packageName} not found in catalog '${catalogInfo.catalogName}'`);
357
+ }
358
+ return false;
359
+ }
360
+ if (dryRun) {
361
+ if (verbose) {
362
+ logger.log(`\u{1F4DD} Would remove ${packageName} from catalog '${catalogInfo.catalogName}'`);
363
+ }
364
+ } else {
365
+ delete catalogExists[packageName];
366
+ await writePackageJSON(
367
+ path.join(monorepoInfo.rootPath, "package.json"),
368
+ monorepoInfo.rootPackageJson
369
+ );
370
+ }
371
+ return true;
372
+ }
373
+ function getDependencyFieldName(scope) {
374
+ switch (scope) {
375
+ case "dev":
376
+ return "devDependencies";
377
+ case "prod":
378
+ return "dependencies";
379
+ case "peer":
380
+ return "peerDependencies";
381
+ case "optional":
382
+ return "optionalDependencies";
383
+ }
384
+ }
385
+ export async function removeDependency(packageNames, options) {
386
+ const packageNameArray = Array.isArray(packageNames) ? packageNames : [packageNames];
387
+ let totalChangesMade = false;
388
+ const removedPackages = [];
389
+ const monorepoInfo = await detectMonorepo(options.cwd);
390
+ logger.log(
391
+ `\u{1F4E6} Detected ${monorepoInfo.isMonorepo ? "monorepo" : "single package"} at ${monorepoInfo.rootPath}`
392
+ );
393
+ const catalogInfo = resolveCatalog(monorepoInfo, options.catalog);
394
+ if (catalogInfo.catalogName) {
395
+ logger.log(`\u{1F4DA} Using catalog '${catalogInfo.catalogName}'`);
396
+ }
397
+ const targetResult = await resolveTargetPackage(monorepoInfo, options);
398
+ if ("isMultiple" in targetResult && targetResult.isMultiple) {
399
+ if (options.verbose) {
400
+ logger.log(`\u{1F3AF} Target packages (${targetResult.targets.length}):`);
401
+ for (const target of targetResult.targets) {
402
+ const relativePath = relative(process.cwd(), target.packagePath) || "package.json";
403
+ logger.log(` \u2022 ${relativePath}`);
404
+ }
405
+ }
406
+ for (const packageName of packageNameArray) {
407
+ let changesMade = false;
408
+ if (catalogInfo.catalogName && monorepoInfo.isMonorepo) {
409
+ const catalogChanged = await removeDependencyFromCatalog(
410
+ monorepoInfo,
411
+ catalogInfo,
412
+ packageName,
413
+ options.dryRun,
414
+ options.verbose
415
+ );
416
+ changesMade = changesMade || catalogChanged;
417
+ for (const target of targetResult.targets) {
418
+ const packageChanged = await removeDependencyFromPackage(
419
+ target.packagePath,
420
+ target.packageJson,
421
+ packageName,
422
+ options.scope,
423
+ options.dryRun,
424
+ options.verbose
425
+ );
426
+ changesMade = changesMade || packageChanged;
427
+ }
428
+ } else {
429
+ for (const target of targetResult.targets) {
430
+ const packageChanged = await removeDependencyFromPackage(
431
+ target.packagePath,
432
+ target.packageJson,
433
+ packageName,
434
+ options.scope,
435
+ options.dryRun,
436
+ options.verbose
437
+ );
438
+ changesMade = changesMade || packageChanged;
439
+ }
440
+ }
441
+ if (changesMade) {
442
+ removedPackages.push(packageName);
443
+ }
444
+ totalChangesMade = totalChangesMade || changesMade;
445
+ }
446
+ } else {
447
+ const targetInfo = targetResult;
448
+ const relativePath = relative(process.cwd(), targetInfo.packagePath) || "package.json";
449
+ logger.log(`\u{1F3AF} Target package: ${relativePath}`);
450
+ for (const packageName of packageNameArray) {
451
+ let changesMade = false;
452
+ if (catalogInfo.catalogName && monorepoInfo.isMonorepo) {
453
+ const catalogChanged = await removeDependencyFromCatalog(
454
+ monorepoInfo,
455
+ catalogInfo,
456
+ packageName,
457
+ options.dryRun,
458
+ options.verbose
459
+ );
460
+ changesMade = changesMade || catalogChanged;
461
+ const packageChanged = await removeDependencyFromPackage(
462
+ targetInfo.packagePath,
463
+ targetInfo.packageJson,
464
+ packageName,
465
+ options.scope,
466
+ options.dryRun,
467
+ options.verbose
468
+ );
469
+ changesMade = changesMade || packageChanged;
470
+ } else {
471
+ const packageChanged = await removeDependencyFromPackage(
472
+ targetInfo.packagePath,
473
+ targetInfo.packageJson,
474
+ packageName,
475
+ options.scope,
476
+ options.dryRun,
477
+ options.verbose
478
+ );
479
+ changesMade = changesMade || packageChanged;
480
+ }
481
+ if (changesMade) {
482
+ removedPackages.push(packageName);
483
+ }
484
+ totalChangesMade = totalChangesMade || changesMade;
485
+ }
486
+ }
487
+ if (removedPackages.length > 0) {
488
+ if (options.dryRun) {
489
+ logger.log(`\u{1F4DD} Would remove dependencies: ${removedPackages.join(", ")}`);
490
+ } else {
491
+ logger.success(`\u2705 Removed dependencies: ${removedPackages.join(", ")}`);
492
+ }
493
+ } else {
494
+ logger.log("\u2139\uFE0F No dependencies to remove");
495
+ }
496
+ if (totalChangesMade && options.install && !options.dryRun) {
497
+ try {
498
+ logger.log("Applying changes (bun install)...");
499
+ await runInstallCommand(options.verbose);
500
+ logger.log("Package removal completed successfully");
501
+ } catch (error) {
502
+ logger.warn(`bun install failed: ${error instanceof Error ? error.message : String(error)}`);
503
+ logger.log("Run 'bun install' manually to apply the changes");
504
+ }
505
+ } else if (!(options.dryRun || options.install)) {
506
+ logger.log("Run 'bun install' to apply the changes");
507
+ }
508
+ return totalChangesMade;
509
+ }
@@ -3,7 +3,6 @@ import type { PackageCacheEntry, TscCacheOptions } from "./types.js";
3
3
  export declare class TscCache {
4
4
  private readonly options;
5
5
  private metadata;
6
- private readonly metadataPath;
7
6
  constructor(options?: Partial<TscCacheOptions>);
8
7
  initialize(): Promise<void>;
9
8
  private loadMetadata;