@reliverse/dler 1.5.5 → 1.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -127,7 +127,7 @@ if you run just `dler` — it will display a list of plugins which you can launc
127
127
 
128
128
  ## **available plugins**
129
129
 
130
- [agg](#1-agg), [build](#2-build), [conv](#3-conv), [deps](#4-deps), [inject](#5-inject), [libs](#6-libs), [merge](#7-merge), [mono](#8-mono), [pub](#9-pub), [relifso](#10-relifso), [relinka](#11-relinka), [rempts](#12-rempts), [spell](#13-spell), [split](#14-split).
130
+ [agg](#1-agg), [build](#2-build), [conv](#3-conv), [deps](#4-deps), [inject](#5-inject), [libs](#6-libs), [merge](#7-merge), [migrate](#8-migrate), [mono](#9-mono), [pub](#10-pub), [relifso](#11-relifso), [relinka](#12-relinka), [rempts](#13-rempts), [spell](#14-spell), [split](#15-split).
131
131
 
132
132
  ### 1. `agg`
133
133
 
@@ -253,11 +253,61 @@ libslist: {
253
253
 
254
254
  not yet documented.
255
255
 
256
- ### 8. `mono`
256
+ ### 8. `migrate`
257
+
258
+ helps migrate between different libraries and module resolution strategies. currently supports:
259
+
260
+ - `pathe-to-pathkit`: migrate from pathe to pathkit library
261
+ - `pathkit-to-pathe`: migrate from pathkit to pathe library
262
+ - `module-resolution`: migrate between module resolution strategies
263
+
264
+ **module resolution targets:**
265
+
266
+ - `nodenext`: adds `.js` extensions to imports and updates tsconfig
267
+ - `bundler`: removes extensions from imports and updates tsconfig
268
+
269
+ **usage examples:**
270
+
271
+ ```bash
272
+ # Migrate from pathe to pathkit
273
+ dler migrate --lib pathe-to-pathkit
274
+
275
+ # Migrate to nodenext module resolution
276
+ dler migrate --lib module-resolution --target nodenext
277
+
278
+ # Migrate to bundler module resolution
279
+ dler migrate --lib module-resolution --target bundler
280
+
281
+ # Preview changes without applying them
282
+ dler migrate --lib module-resolution --target nodenext --dryRun
283
+ ```
284
+
285
+ **what it does:**
286
+
287
+ - updates import statements in your code
288
+ - modifies tsconfig.json settings
289
+ - updates package.json type field
290
+ - provides a dry run option to preview changes
291
+ - handles both relative and alias imports
292
+ - supports both .ts and .tsx files
293
+
294
+ **next steps after migration:**
295
+
296
+ - for pathe-to-pathkit:
297
+ 1. run 'bun install' to install @reliverse/pathkit
298
+ 2. test your application
299
+ 3. consider using advanced pathkit features
300
+
301
+ - for module-resolution:
302
+ 1. test your application
303
+ 2. ensure your build tools support the new module resolution
304
+ 3. review any warnings in the migration output
305
+
306
+ ### 9. `mono`
257
307
 
258
308
  not yet documented.
259
309
 
260
- ### 9. `pub`
310
+ ### 10. `pub`
261
311
 
262
312
  pub command is separated for its own build-in plugin as well.
263
313
 
@@ -267,13 +317,13 @@ it already calls build command by itself, so you don't need to run `dler build`
267
317
  dler pub ...
268
318
  ```
269
319
 
270
- ### 10. `relifso`
320
+ ### 11. `relifso`
271
321
 
272
322
  ```bash
273
323
  dler relifso init ...
274
324
  ```
275
325
 
276
- ### 11. `relinka`
326
+ ### 12. `relinka`
277
327
 
278
328
  @reliverse/relinka's best friend. learn more in its [docs](https://github.com/reliverse/relinka).
279
329
 
@@ -281,7 +331,7 @@ dler relifso init ...
281
331
  dler relinka --console-to-relinka
282
332
  ```
283
333
 
284
- ### 12. `rempts`
334
+ ### 13. `rempts`
285
335
 
286
336
  @reliverse/rempts's best friend. learn more in its [docs](https://github.com/reliverse/rempts).
287
337
 
@@ -290,47 +340,58 @@ dler rempts init --cmd my-cmd-1
290
340
  dler rempts init --cmds
291
341
  ```
292
342
 
293
- ### 13. `spell`
343
+ ### 14. `spell`
294
344
 
295
345
  **available spell types:**
296
346
 
297
347
  - `replace-line` — injects contents from one file into another
348
+ - `replace-range` — replaces a range of lines with content from another file
298
349
  - `rename-file` — renames the current file
299
350
  - `remove-comment` — removes a specific comment from code
300
351
  - `remove-line` — removes a specific line from code
301
352
  - `remove-file` — deletes the current file
302
353
  - `transform-content` — applies a transformation to the file content
354
+ - `transform-line` — applies a transformation to a specific line
303
355
  - `copy-file` — copies the current file to a new location
304
356
  - `move-file` — moves the current file to a new location
305
357
  - `insert-at` — inserts content at a specific position in the file
358
+ - `insert-before` — inserts content before a specific line
359
+ - `insert-after` — inserts content after a specific line
360
+ - `conditional-execute` — executes spells conditionally
306
361
 
307
362
  **params:**
308
363
 
309
364
  params are optional and comma-separated.
310
365
 
311
- currently, only the first param is supported:
312
-
313
- - `hooked` (boolean, default: `false`)
314
- - `false`: dler handles the spell automatically at postbuild
366
+ - `hooked` (boolean, default: `true`)
315
367
  - `true`: disables default behavior, so you can trigger the spell yourself (e.g. from your own cli function)
316
-
317
- more params coming soon...
368
+ - `false`: dler handles the spell automatically at postbuild
369
+ - `startLine` (number) — line number to start the operation (for range operations)
370
+ - `endLine` (number) — line number to end the operation (for range operations)
371
+ - `condition` (string) — condition to check before executing the spell
372
+ - `skipIfMissing` (boolean) — whether to skip the spell if the target file doesn't exist
373
+ - `createDir` (boolean) — whether to create the target directory if it doesn't exist
318
374
 
319
375
  **usage examples:**
320
376
 
321
- - `export * from "../../types.js"; // <dler-replace-line-{hooked=false}>` — injects file contents at this line
322
- - `// @ts-expect-error <dler-remove-comment-{hooked=false}>` — removes just this comment
323
- - `// <dler-remove-line-{hooked=false}>` — removes this line
324
- - `// <dler-remove-file-{hooked=false}>` — deletes this file
325
- - `// <dler-rename-file-"tsconfig.json"-{hooked=false}>` — renames this file (runs at postbuild because `hooked=false`)
377
+ - `export * from "../../types.js"; // dler-replace-line` — injects file contents at this line (hooked=true by default)
378
+ - `// @ts-expect-error dler-remove-comment` — removes just this comment (hooked=true by default)
379
+ - `// dler-remove-line` — removes this line (hooked=true by default)
380
+ - `// dler-remove-file` — deletes this file (hooked=true by default)
381
+ - `// dler-rename-file-"tsconfig.json"-{hooked=false}` — renames this file (runs at postbuild because `hooked=false`)
382
+ - `// dler-replace-range-"../../types.js"-{startLine=1,endLine=5}` — replaces lines 1-5 with content from types.js
383
+ - `// dler-transform-line-"return line.toUpperCase()"` — transforms the line to uppercase
384
+ - `// dler-insert-before-"import { x } from 'y';"` — inserts import statement before this line
385
+ - `// dler-insert-after-"export { x };"` — inserts export statement after this line
386
+ - `// dler-conditional-execute-{condition="content.includes('TODO')"}` — executes spells only if file contains TODO
326
387
 
327
- **using `hooked=true`:**
388
+ **using `hooked=false`:**
328
389
 
329
- - `// <dler-rename-file-"tsconfig.json"-{hooked=true}>` — renames the file, but only when you trigger it yourself (hooked from your side)
390
+ - `// dler-rename-file-"tsconfig.json"-{hooked=false}` — renames the file immediately at postbuild (not hooked)
330
391
 
331
392
  **triggering spells:**
332
393
 
333
- from dlers cli:
394
+ from dler's cli:
334
395
 
335
396
  - `dler spell --trigger rename-file,... --files tsconfig.json,...`
336
397
  - `dler spell --trigger all`
@@ -340,15 +401,15 @@ from your own code:
340
401
 
341
402
  ```ts
342
403
  await dler.spell({ spells: ["rename-file"], files: [] });
343
- // await dler.spell({}) // means all spells and all files
344
- // spell: ["all"] // means all spells
345
- // spell: [] // means all spells
346
- // files: [] // means all files
404
+ await dler.spell({}) // all spells, all files
405
+ spells: ["all"] // means all spells
406
+ spells: [] // also means all spells
407
+ files: [] // means all files
347
408
  ```
348
409
 
349
410
  p.s. [see how rse cli uses hooked=true](https://github.com/reliverse/rse/blob/main/src/postbuild.ts)
350
411
 
351
- ### 14. `split`
412
+ ### 15. `split`
352
413
 
353
414
  splits your code/text file into multiple files.
354
415
 
package/bin/app/cmds.d.ts CHANGED
@@ -195,3 +195,19 @@ export declare function cmdRelifsoRename(): Promise<import("@reliverse/rempts").
195
195
  default: false;
196
196
  };
197
197
  }>>;
198
+ export declare function cmdMigrate(): Promise<import("@reliverse/rempts").Command<{
199
+ lib: {
200
+ type: "string";
201
+ description: string;
202
+ };
203
+ target: {
204
+ type: "string";
205
+ description: string;
206
+ default: string;
207
+ };
208
+ dryRun: {
209
+ type: "boolean";
210
+ description: string;
211
+ default: false;
212
+ };
213
+ }>>;
package/bin/app/cmds.js CHANGED
@@ -16,3 +16,6 @@ export async function cmdPub() {
16
16
  export async function cmdRelifsoRename() {
17
17
  return (await import("./relifso/rename/cmd.js")).default;
18
18
  }
19
+ export async function cmdMigrate() {
20
+ return (await import("./migrate/cmd.js")).default;
21
+ }
@@ -1,2 +1,2 @@
1
- import type { DependencyResult, FinderOptions } from "./deps-types.js";
1
+ import type { DependencyResult, FinderOptions } from "./deps-types";
2
2
  export declare const analyzeDependencies: (options: FinderOptions) => Promise<DependencyResult>;
@@ -1,4 +1,4 @@
1
- import type { PackageJson } from "./deps-types.js";
1
+ import type { PackageJson } from "./deps-types";
2
2
  export declare const findSourceFiles: (directory: string, ignorePatterns: string[]) => Promise<string[]>;
3
3
  export declare const readFile: (filePath: string) => Promise<string>;
4
4
  export declare const readPackageJson: (directory: string) => Promise<PackageJson>;
@@ -1,2 +1,2 @@
1
- import type { DependencyResult, FinderOptions } from "./deps-types.js";
1
+ import type { DependencyResult, FinderOptions } from "./deps-types";
2
2
  export declare const formatOutput: (result: DependencyResult, options: FinderOptions) => string;
@@ -1,4 +1,4 @@
1
- import type { PackageJson } from "./deps-types.js";
1
+ import type { PackageJson } from "./deps-types";
2
2
  export declare const extractPackageNames: (fileContent: string) => Set<string>;
3
3
  export declare const normalizePackageName: (importPath: string) => string | null;
4
4
  export declare const getListedDependencies: (packageJson: PackageJson) => Set<string>;
@@ -0,0 +1,17 @@
1
+ declare const _default: import("@reliverse/rempts").Command<{
2
+ lib: {
3
+ type: "string";
4
+ description: string;
5
+ };
6
+ target: {
7
+ type: "string";
8
+ description: string;
9
+ default: string;
10
+ };
11
+ dryRun: {
12
+ type: "boolean";
13
+ description: string;
14
+ default: false;
15
+ };
16
+ }>;
17
+ export default _default;
@@ -0,0 +1,121 @@
1
+ import { defineArgs, defineCommand } from "@reliverse/rempts";
2
+ import {
3
+ migratePatheToPathkit,
4
+ migratePathkitToPathe
5
+ } from "./codemods/lib-pathe-pathkit.js";
6
+ import { migrateModuleResolution } from "./codemods/ts-module-resolution.js";
7
+ export default defineCommand({
8
+ meta: {
9
+ name: "migrate",
10
+ version: "1.0.0",
11
+ description: "Migrate between different libraries and usages"
12
+ },
13
+ args: defineArgs({
14
+ lib: {
15
+ type: "string",
16
+ description: "The migration to perform (pathe-to-pathkit | pathkit-to-pathe | module-resolution)"
17
+ },
18
+ target: {
19
+ type: "string",
20
+ description: "Target for module resolution migration (nodenext | bundler)",
21
+ default: "nodenext"
22
+ },
23
+ dryRun: {
24
+ type: "boolean",
25
+ description: "Preview changes without applying them",
26
+ default: false
27
+ }
28
+ }),
29
+ async run({ args }) {
30
+ let results = [];
31
+ if (args.lib === "pathe-to-pathkit") {
32
+ console.log("Migrating from pathe to pathkit...");
33
+ results = await migratePatheToPathkit(args.dryRun);
34
+ } else if (args.lib === "pathkit-to-pathe") {
35
+ console.log("Migrating from pathkit to pathe...");
36
+ results = await migratePathkitToPathe(args.dryRun);
37
+ } else if (args.lib === "module-resolution") {
38
+ if (!["nodenext", "bundler"].includes(args.target)) {
39
+ console.error(`Invalid target: ${args.target}`);
40
+ console.log("Available targets:");
41
+ console.log(" - nodenext");
42
+ console.log(" - bundler");
43
+ return;
44
+ }
45
+ console.log(`Migrating to ${args.target} module resolution...`);
46
+ results = await migrateModuleResolution(
47
+ args.target,
48
+ args.dryRun
49
+ );
50
+ } else {
51
+ console.error(`Unknown migration: ${args.lib}`);
52
+ console.log("Available migrations:");
53
+ console.log(" - pathe-to-pathkit");
54
+ console.log(" - pathkit-to-pathe");
55
+ console.log(" - module-resolution");
56
+ return;
57
+ }
58
+ console.log("\nMigration Results:");
59
+ let successCount = 0;
60
+ let errorCount = 0;
61
+ let warningCount = 0;
62
+ for (const result of results) {
63
+ const status = result.success ? "\u2713" : "\u2717";
64
+ console.log(`${status} ${result.file}: ${result.message}`);
65
+ if (result.changes && result.changes.length > 0) {
66
+ for (const change of result.changes) {
67
+ if (change.startsWith("\u26A0\uFE0F")) {
68
+ console.log(` ${change}`);
69
+ warningCount++;
70
+ } else {
71
+ console.log(` - ${change}`);
72
+ }
73
+ }
74
+ }
75
+ if (result.success) successCount++;
76
+ else errorCount++;
77
+ }
78
+ console.log(
79
+ `
80
+ Summary: ${successCount} files updated, ${errorCount} errors, ${warningCount} warnings`
81
+ );
82
+ if (args.dryRun) {
83
+ console.log("\nThis was a dry run. No changes were made.");
84
+ console.log("Run without --dryRun to apply the changes.");
85
+ } else {
86
+ console.log("\nMigration completed!");
87
+ if (args.lib === "pathe-to-pathkit") {
88
+ console.log("Next steps:");
89
+ console.log("1. Run 'bun install' to install @reliverse/pathkit");
90
+ console.log("2. Test your application");
91
+ console.log(
92
+ "3. Consider using advanced pathkit features like alias resolution"
93
+ );
94
+ } else if (args.lib === "pathkit-to-pathe") {
95
+ console.log("Next steps:");
96
+ console.log("1. Run 'bun install' to install pathe");
97
+ console.log("2. Test your application");
98
+ if (warningCount > 0) {
99
+ console.log(
100
+ "3. \u26A0\uFE0F Review files with warnings - they may need manual updates"
101
+ );
102
+ }
103
+ } else if (args.lib === "module-resolution") {
104
+ console.log("Next steps:");
105
+ console.log("1. Test your application");
106
+ if (args.target === "nodenext") {
107
+ console.log(
108
+ "2. Ensure your build tools support .js extensions in imports"
109
+ );
110
+ } else if (args.target === "bundler") {
111
+ console.log("2. Ensure your bundler is configured correctly");
112
+ }
113
+ if (warningCount > 0) {
114
+ console.log(
115
+ "3. \u26A0\uFE0F Review files with warnings - they may need manual updates"
116
+ );
117
+ }
118
+ }
119
+ }
120
+ }
121
+ });
@@ -0,0 +1,9 @@
1
+ type MigrationResult = {
2
+ file: string;
3
+ success: boolean;
4
+ message: string;
5
+ changes?: string[];
6
+ };
7
+ export declare function migratePatheToPathkit(dryRun?: boolean): Promise<MigrationResult[]>;
8
+ export declare function migratePathkitToPathe(dryRun?: boolean): Promise<MigrationResult[]>;
9
+ export {};
@@ -0,0 +1,258 @@
1
+ import { existsSync } from "node:fs";
2
+ import { readFile, writeFile, readdir, stat } from "node:fs/promises";
3
+ import { join, extname } from "node:path";
4
+ async function getAllTsFiles(dir) {
5
+ const files = [];
6
+ try {
7
+ const entries = await readdir(dir);
8
+ for (const entry of entries) {
9
+ const fullPath = join(dir, entry);
10
+ const stats = await stat(fullPath);
11
+ if (stats.isDirectory() && !entry.startsWith(".") && entry !== "node_modules") {
12
+ const subFiles = await getAllTsFiles(fullPath);
13
+ files.push(...subFiles);
14
+ } else if (stats.isFile()) {
15
+ const ext = extname(entry);
16
+ if ([".ts", ".tsx", ".js", ".jsx", ".vue", ".svelte"].includes(ext)) {
17
+ files.push(fullPath);
18
+ }
19
+ }
20
+ }
21
+ } catch {
22
+ }
23
+ return files;
24
+ }
25
+ export async function migratePatheToPathkit(dryRun = false) {
26
+ const results = [];
27
+ const files = await getAllTsFiles(".");
28
+ for (const file of files) {
29
+ try {
30
+ const content = await readFile(file, "utf-8");
31
+ let modified = content;
32
+ const changes = [];
33
+ const patheImportRegex = /from\s+["']pathe["']/g;
34
+ if (patheImportRegex.test(content)) {
35
+ modified = modified.replace(
36
+ patheImportRegex,
37
+ 'from "@reliverse/pathkit"'
38
+ );
39
+ changes.push("Updated pathe imports to @reliverse/pathkit");
40
+ }
41
+ const patheUtilsRegex = /from\s+["']pathe\/utils["']/g;
42
+ if (patheUtilsRegex.test(content)) {
43
+ modified = modified.replace(
44
+ patheUtilsRegex,
45
+ 'from "@reliverse/pathkit"'
46
+ );
47
+ changes.push("Updated pathe/utils imports to @reliverse/pathkit");
48
+ }
49
+ const patheRequireRegex = /require\s*\(\s*["']pathe["']\s*\)/g;
50
+ if (patheRequireRegex.test(content)) {
51
+ modified = modified.replace(
52
+ patheRequireRegex,
53
+ 'require("@reliverse/pathkit")'
54
+ );
55
+ changes.push("Updated pathe require to @reliverse/pathkit");
56
+ }
57
+ const patheUtilsRequireRegex = /require\s*\(\s*["']pathe\/utils["']\s*\)/g;
58
+ if (patheUtilsRequireRegex.test(content)) {
59
+ modified = modified.replace(
60
+ patheUtilsRequireRegex,
61
+ 'require("@reliverse/pathkit")'
62
+ );
63
+ changes.push("Updated pathe/utils require to @reliverse/pathkit");
64
+ }
65
+ if (changes.length > 0) {
66
+ if (!dryRun) {
67
+ await writeFile(file, modified, "utf-8");
68
+ }
69
+ results.push({
70
+ file,
71
+ success: true,
72
+ message: `${changes.length} change(s) made`,
73
+ changes
74
+ });
75
+ }
76
+ } catch (error) {
77
+ results.push({
78
+ file,
79
+ success: false,
80
+ message: `Failed to process: ${error instanceof Error ? error.message : String(error)}`
81
+ });
82
+ }
83
+ }
84
+ await updatePackageJson(results, dryRun, {
85
+ remove: ["pathe"],
86
+ add: { "@reliverse/pathkit": "^latest" }
87
+ });
88
+ return results;
89
+ }
90
+ export async function migratePathkitToPathe(dryRun = false) {
91
+ const results = [];
92
+ const files = await getAllTsFiles(".");
93
+ for (const file of files) {
94
+ try {
95
+ const content = await readFile(file, "utf-8");
96
+ let modified = content;
97
+ const changes = [];
98
+ const pathkitImportRegex = /from\s+["']@reliverse\/pathkit["']/g;
99
+ if (pathkitImportRegex.test(content)) {
100
+ const advancedFeatures = [
101
+ "getFileImportsExports",
102
+ "convertImportPaths",
103
+ "convertImportExtensionsJsToTs",
104
+ "normalizeAliases",
105
+ "resolveAlias",
106
+ "reverseResolveAlias",
107
+ "normalizeQuotes"
108
+ ];
109
+ const usesAdvancedFeatures = advancedFeatures.some(
110
+ (feature) => content.includes(feature)
111
+ );
112
+ if (usesAdvancedFeatures) {
113
+ changes.push(
114
+ "\u26A0\uFE0F File uses advanced pathkit features - manual review needed"
115
+ );
116
+ results.push({
117
+ file,
118
+ success: false,
119
+ message: "Contains advanced pathkit features not available in pathe",
120
+ changes
121
+ });
122
+ continue;
123
+ }
124
+ const utilsPattern = /import\s*\{([^}]+)\}\s*from\s*["']@reliverse\/pathkit["']/g;
125
+ const utilsMatch = utilsPattern.exec(content);
126
+ if (utilsMatch?.[1]) {
127
+ const imports = utilsMatch[1].split(",").map((s) => s.trim());
128
+ const coreImports = imports.filter(
129
+ (imp) => ![
130
+ "filename",
131
+ "normalizeAliases",
132
+ "resolveAlias",
133
+ "reverseResolveAlias"
134
+ ].includes(imp.replace(/\s+as\s+\w+/, ""))
135
+ );
136
+ const utilImports = imports.filter(
137
+ (imp) => [
138
+ "filename",
139
+ "normalizeAliases",
140
+ "resolveAlias",
141
+ "reverseResolveAlias"
142
+ ].includes(imp.replace(/\s+as\s+\w+/, ""))
143
+ );
144
+ if (coreImports.length > 0 && utilImports.length > 0) {
145
+ const coreImportStatement = `import { ${coreImports.join(", ")} } from "pathe";`;
146
+ const utilImportStatement = `import { ${utilImports.join(", ")} } from "pathe/utils";`;
147
+ modified = modified.replace(
148
+ utilsMatch[0],
149
+ `${coreImportStatement}
150
+ ${utilImportStatement}`
151
+ );
152
+ changes.push(
153
+ "Split pathkit imports into pathe core and pathe/utils"
154
+ );
155
+ } else if (utilImports.length > 0) {
156
+ modified = modified.replace(
157
+ pathkitImportRegex,
158
+ 'from "pathe/utils"'
159
+ );
160
+ changes.push("Updated pathkit utils imports to pathe/utils");
161
+ } else {
162
+ modified = modified.replace(pathkitImportRegex, 'from "pathe"');
163
+ changes.push("Updated pathkit imports to pathe");
164
+ }
165
+ } else {
166
+ modified = modified.replace(pathkitImportRegex, 'from "pathe"');
167
+ changes.push("Updated pathkit imports to pathe");
168
+ }
169
+ }
170
+ const pathkitRequireRegex = /require\s*\(\s*["']@reliverse\/pathkit["']\s*\)/g;
171
+ if (pathkitRequireRegex.test(content)) {
172
+ modified = modified.replace(pathkitRequireRegex, 'require("pathe")');
173
+ changes.push("Updated pathkit require to pathe");
174
+ }
175
+ if (changes.length > 0) {
176
+ if (!dryRun) {
177
+ await writeFile(file, modified, "utf-8");
178
+ }
179
+ results.push({
180
+ file,
181
+ success: true,
182
+ message: `${changes.length} change(s) made`,
183
+ changes
184
+ });
185
+ }
186
+ } catch (error) {
187
+ results.push({
188
+ file,
189
+ success: false,
190
+ message: `Failed to process: ${error instanceof Error ? error.message : String(error)}`
191
+ });
192
+ }
193
+ }
194
+ await updatePackageJson(results, dryRun, {
195
+ remove: ["@reliverse/pathkit"],
196
+ add: { pathe: "^latest" }
197
+ });
198
+ return results;
199
+ }
200
+ async function updatePackageJson(results, dryRun, config) {
201
+ try {
202
+ const packageJsonPath = "./package.json";
203
+ if (existsSync(packageJsonPath)) {
204
+ const packageContent = await readFile(packageJsonPath, "utf-8");
205
+ const packageJson = JSON.parse(packageContent);
206
+ let packageChanged = false;
207
+ const packageChanges = [];
208
+ for (const pkg of config.remove) {
209
+ if (packageJson.dependencies?.[pkg]) {
210
+ packageJson.dependencies = Object.fromEntries(
211
+ Object.entries(packageJson.dependencies).filter(
212
+ ([key]) => key !== pkg
213
+ )
214
+ );
215
+ packageChanged = true;
216
+ packageChanges.push(`Removed ${pkg} from dependencies`);
217
+ }
218
+ if (packageJson.devDependencies?.[pkg]) {
219
+ packageJson.devDependencies = Object.fromEntries(
220
+ Object.entries(packageJson.devDependencies).filter(
221
+ ([key]) => key !== pkg
222
+ )
223
+ );
224
+ packageChanged = true;
225
+ packageChanges.push(`Removed ${pkg} from devDependencies`);
226
+ }
227
+ }
228
+ for (const [pkg, version] of Object.entries(config.add)) {
229
+ if (packageChanged && !packageJson.dependencies?.[pkg]) {
230
+ if (!packageJson.dependencies) packageJson.dependencies = {};
231
+ packageJson.dependencies[pkg] = version;
232
+ packageChanges.push(`Added ${pkg} to dependencies`);
233
+ }
234
+ }
235
+ if (packageChanged) {
236
+ if (!dryRun) {
237
+ await writeFile(
238
+ packageJsonPath,
239
+ JSON.stringify(packageJson, null, 2) + "\n",
240
+ "utf-8"
241
+ );
242
+ }
243
+ results.push({
244
+ file: packageJsonPath,
245
+ success: true,
246
+ message: `${packageChanges.length} change(s) made`,
247
+ changes: packageChanges
248
+ });
249
+ }
250
+ }
251
+ } catch (error) {
252
+ results.push({
253
+ file: "./package.json",
254
+ success: false,
255
+ message: `Failed to update package.json: ${error instanceof Error ? error.message : String(error)}`
256
+ });
257
+ }
258
+ }
@@ -0,0 +1,10 @@
1
+ type MigrationResult = {
2
+ file: string;
3
+ success: boolean;
4
+ message: string;
5
+ changes?: string[];
6
+ };
7
+ export declare function migrateToNodeNext(dryRun?: boolean): Promise<MigrationResult[]>;
8
+ export declare function migrateToBundler(dryRun?: boolean): Promise<MigrationResult[]>;
9
+ export declare function migrateModuleResolution(target: "nodenext" | "bundler", dryRun?: boolean): Promise<MigrationResult[]>;
10
+ export {};