create-turbo-kit 1.3.1 → 1.3.2

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
@@ -28,4 +28,7 @@ To run the script (manually):
28
28
  **Do not run in this directory!**
29
29
  ```bash
30
30
  node <path-to-cli>/dist/cli.js
31
- ```
31
+ ```
32
+
33
+ ## Package manager support
34
+ Currently turbo-kit works with only pnpm. There is an issue with the template repo that breaks the conversion to other package managers that is typically handled by create-turbo.
@@ -39,6 +39,19 @@ var DOCKER_CONTAINERS = {
39
39
  dependsOn: []
40
40
  }
41
41
  };
42
+ function sortPackageJsonDependencies(pkg) {
43
+ const depTypes = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
44
+ for (const depType of depTypes) {
45
+ const deps = pkg[depType];
46
+ if (deps && typeof deps === "object") {
47
+ const sorted = Object.keys(deps).sort().reduce((acc, key) => {
48
+ acc[key] = deps[key];
49
+ return acc;
50
+ }, {});
51
+ pkg[depType] = sorted;
52
+ }
53
+ }
54
+ }
42
55
  async function replaceScope(projectDir, newScope) {
43
56
  const s = spinner();
44
57
  s.start(`Replacing scope with ${color.cyan(newScope)}...`);
@@ -70,7 +83,23 @@ async function replaceScope(projectDir, newScope) {
70
83
  }
71
84
  })
72
85
  );
73
- s.stop(`Replaced scope with ${color.cyan(newScope)}`);
86
+ s.message("Sorting dependencies alphabetically...");
87
+ const packageJsonFiles = await fg("**/package.json", {
88
+ cwd: projectDir,
89
+ ignore: ["**/node_modules/**"],
90
+ absolute: true
91
+ });
92
+ await Promise.all(
93
+ packageJsonFiles.map(async (file) => {
94
+ try {
95
+ const pkg = await fs.readJson(file);
96
+ sortPackageJsonDependencies(pkg);
97
+ await fs.writeJson(file, pkg, { spaces: 2 });
98
+ } catch (e) {
99
+ }
100
+ })
101
+ );
102
+ s.stop(`Replaced scope with ${color.cyan(newScope)} and sorted dependencies`);
74
103
  } catch (error) {
75
104
  s.stop("Failed to replace scope");
76
105
  throw error;
@@ -310,4 +339,4 @@ export {
310
339
  removeReactEmail,
311
340
  resolveCatalogVersions
312
341
  };
313
- //# sourceMappingURL=chunk-6ZFG4OIY.js.map
342
+ //# sourceMappingURL=chunk-Q43WSJ4J.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/helpers/transform.ts"],"sourcesContent":["import fg from 'fast-glob';\r\nimport fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { spinner } from '@clack/prompts';\r\nimport color from 'picocolors';\r\nimport YAML from 'yaml';\r\nimport type { PackageManager } from '../utils/package-manager.js';\r\n\r\nconst DOCKER_CONTAINERS = {\r\n postgres: {\r\n label: 'PostgreSQL 16 (Database)',\r\n services: ['postgres'],\r\n volumes: ['postgres_data'],\r\n dependsOn: [], \r\n },\r\n pgadmin: {\r\n label: `pgAdmin 4.9 (Database management) [Depends on PostgreSQL]`,\r\n services: ['pgadmin'],\r\n volumes: [],\r\n dependsOn: ['postgres'],\r\n },\r\n redis: {\r\n label: 'Redis (Caching)',\r\n services: ['redis'],\r\n volumes: [],\r\n dependsOn: [],\r\n },\r\n mailpit: {\r\n label: 'Mailpit (Email testing)',\r\n services: ['mailpit'],\r\n volumes: [],\r\n dependsOn: [],\r\n },\r\n minio: {\r\n label: 'MinIO (S3-compatible storage)',\r\n services: ['minio', 'minio-create-bucket'],\r\n volumes: ['minio_data'],\r\n dependsOn: [],\r\n },\r\n} as const;\r\n\r\nexport type DockerContainer = keyof typeof DOCKER_CONTAINERS;\r\n\r\n/**\r\n * Sort dependencies alphabetically in a package.json object\r\n */\r\nfunction sortPackageJsonDependencies(pkg: PackageJson): void {\r\n const depTypes = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'] as const;\r\n \r\n for (const depType of depTypes) {\r\n const deps = pkg[depType];\r\n if (deps && typeof deps === 'object') {\r\n const sorted = Object.keys(deps)\r\n .sort()\r\n .reduce((acc, key) => {\r\n acc[key] = deps[key]!;\r\n return acc;\r\n }, {} as Record<string, string>);\r\n pkg[depType] = sorted;\r\n }\r\n }\r\n}\r\n\r\nexport async function replaceScope(projectDir: string, newScope: string) {\r\n const s = spinner();\r\n s.start(`Replacing scope with ${color.cyan(newScope)}...`);\r\n\r\n try {\r\n const files = await fg('**/*', {\r\n cwd: projectDir,\r\n ignore: [\r\n '**/.git/**',\r\n '**/node_modules/**',\r\n '**/.turbo/**',\r\n '**/dist/**',\r\n '**/.next/**',\r\n '**/pnpm-lock.yaml',\r\n '**/yarn.lock',\r\n '**/package-lock.json',\r\n '**/bun.lockb',\r\n ],\r\n absolute: true,\r\n });\r\n\r\n await Promise.all(\r\n files.map(async (file) => {\r\n try {\r\n const content = await fs.readFile(file, 'utf8');\r\n if (content.includes('@acme')) {\r\n const newContent = content.replace(/@acme/g, newScope);\r\n await fs.writeFile(file, newContent);\r\n }\r\n } catch (e) {\r\n }\r\n })\r\n );\r\n \r\n // Sort dependencies in all package.json files after replacing scope\r\n s.message('Sorting dependencies alphabetically...');\r\n const packageJsonFiles = await fg('**/package.json', {\r\n cwd: projectDir,\r\n ignore: ['**/node_modules/**'],\r\n absolute: true,\r\n });\r\n\r\n await Promise.all(\r\n packageJsonFiles.map(async (file) => {\r\n try {\r\n const pkg: PackageJson = await fs.readJson(file);\r\n sortPackageJsonDependencies(pkg);\r\n await fs.writeJson(file, pkg, { spaces: 2 });\r\n } catch (e) {\r\n // Ignore errors for malformed package.json files\r\n }\r\n })\r\n );\r\n \r\n s.stop(`Replaced scope with ${color.cyan(newScope)} and sorted dependencies`);\r\n } catch (error) {\r\n s.stop('Failed to replace scope');\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function setupEnv(projectDir: string) {\r\n const envExample = path.join(projectDir, '.env.example');\r\n const envDest = path.join(projectDir, '.env');\r\n\r\n if (await fs.pathExists(envExample)) {\r\n await fs.copy(envExample, envDest);\r\n }\r\n}\r\n\r\nexport function getDockerContainers() {\r\n return Object.entries(DOCKER_CONTAINERS).map(([value, config]) => ({\r\n value,\r\n label: config.label,\r\n }));\r\n}\r\n\r\nexport async function deleteDockerCompose(projectDir: string) {\r\n const s = spinner();\r\n s.start('Removing Docker Compose setup...');\r\n\r\n try {\r\n const dockerComposePath = path.join(projectDir, 'docker-compose.yml');\r\n if (await fs.pathExists(dockerComposePath)) {\r\n await fs.remove(dockerComposePath);\r\n s.message(`Removed ${color.cyan(dockerComposePath)}`);\r\n }\r\n const dockerDir = path.join(projectDir, 'docker');\r\n if (await fs.pathExists(dockerDir)) {\r\n await fs.remove(dockerDir);\r\n s.message(`Removed ${color.cyan(dockerDir)}`);\r\n }\r\n s.stop('Removed Docker Compose setup');\r\n } catch (error) {\r\n s.stop('Failed to remove Docker Compose setup');\r\n throw error;\r\n }\r\n}\r\n\r\nfunction resolveContainerDependencies(selectedContainers: string[]): string[] {\r\n const resolved = new Set<string>(selectedContainers);\r\n const queue = [...selectedContainers];\r\n\r\n while (queue.length > 0) {\r\n const current = queue.shift()!;\r\n const config = DOCKER_CONTAINERS[current as DockerContainer];\r\n \r\n if (config && config.dependsOn) {\r\n for (const dep of config.dependsOn) {\r\n if (!resolved.has(dep)) {\r\n resolved.add(dep);\r\n queue.push(dep);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return Array.from(resolved);\r\n}\r\n\r\nexport async function configureDockerCompose(projectDir: string, selectedContainers: string[]) {\r\n const s = spinner();\r\n s.start('Configuring Docker Compose...');\r\n\r\n try {\r\n const dockerComposePath = path.join(projectDir, 'docker-compose.yml');\r\n \r\n if (!(await fs.pathExists(dockerComposePath))) {\r\n s.stop('Docker Compose file not found');\r\n return;\r\n }\r\n\r\n const resolvedContainers = resolveContainerDependencies(selectedContainers);\r\n const addedDependencies = resolvedContainers.filter(c => !selectedContainers.includes(c));\r\n \r\n if (addedDependencies.length > 0) {\r\n s.message(`Auto-including dependencies: ${color.cyan(addedDependencies.join(', '))}`);\r\n }\r\n\r\n let content = await fs.readFile(dockerComposePath, 'utf8');\r\n\r\n const allContainers = Object.keys(DOCKER_CONTAINERS) as DockerContainer[];\r\n const containersToRemove = allContainers.filter(c => !resolvedContainers.includes(c));\r\n\r\n for (const container of containersToRemove) {\r\n const containerRegex = new RegExp(\r\n ` # -- ${container} --\\\\n[\\\\s\\\\S]*? # // ${container} //\\\\n`,\r\n 'g'\r\n );\r\n content = content.replace(containerRegex, '');\r\n\r\n // delete `./docker/<container>/`\r\n const dockerDirPath = path.join(projectDir, 'docker', container);\r\n if (await fs.pathExists(dockerDirPath)) {\r\n await fs.remove(dockerDirPath);\r\n s.message(`Removed ${color.cyan(dockerDirPath)}`);\r\n }\r\n }\r\n\r\n content = content.replace(/ # -- \\w+ --\\n/g, '');\r\n content = content.replace(/ # \\/\\/ \\w+ \\/\\/\\n/g, '');\r\n\r\n await fs.writeFile(dockerComposePath, content);\r\n\r\n // check if `./docker/` is empty\r\n const dockerDir = path.join(projectDir, 'docker');\r\n if (await fs.pathExists(dockerDir) && (await fs.readdir(dockerDir)).length === 0) {\r\n await fs.remove(dockerDir);\r\n s.message(`Removed ${color.cyan(dockerDir)} ${color.gray('(because it was empty)')}`);\r\n }\r\n \r\n s.stop(`Configured Docker Compose with ${color.cyan(resolvedContainers.length)} container(s)`);\r\n } catch (error) {\r\n s.stop('Failed to configure Docker Compose');\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function removePackages(\r\n packages: string[],\r\n packagePath: string,\r\n projectDir: string,\r\n s?: ReturnType<typeof spinner>\r\n) {\r\n const packageJsonPath = path.join(projectDir, packagePath, 'package.json');\r\n if (await fs.pathExists(packageJsonPath)) {\r\n const packageJson = await fs.readJson(packageJsonPath);\r\n let hasChanges = false;\r\n\r\n for (const dep of packages) {\r\n if (packageJson.dependencies && packageJson.dependencies[dep]) {\r\n delete packageJson.dependencies[dep];\r\n hasChanges = true;\r\n if (s) {\r\n s.message(`Removed ${color.cyan(dep)} from ${packagePath}/package.json`);\r\n }\r\n }\r\n }\r\n\r\n if (hasChanges) {\r\n await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });\r\n }\r\n }\r\n}\r\n\r\nexport async function removeReactEmail(projectDir: string) {\r\n const s = spinner();\r\n s.start('Removing react-email...');\r\n\r\n try {\r\n // remove email package\r\n const emailPackagePath = path.join(projectDir, 'packages', 'email');\r\n if (await fs.pathExists(emailPackagePath)) {\r\n await fs.remove(emailPackagePath);\r\n s.message(`Removed ${color.cyan(emailPackagePath)}`);\r\n }\r\n\r\n // remove @react-email/components from packages/api/package.json\r\n await removePackages(['@react-email/components', '@acme/email'], 'packages/api', projectDir, s);\r\n\r\n s.stop('Removed react-email');\r\n } catch (error) {\r\n s.stop('Failed to remove react-email');\r\n throw error;\r\n }\r\n}\r\n\r\ninterface PnpmWorkspace {\r\n packages?: string[];\r\n catalog?: Record<string, string>;\r\n catalogs?: Record<string, Record<string, string>>;\r\n overrides?: Record<string, string>;\r\n}\r\n\r\ninterface PackageJson {\r\n name?: string;\r\n packageManager?: string;\r\n dependencies?: Record<string, string>;\r\n devDependencies?: Record<string, string>;\r\n peerDependencies?: Record<string, string>;\r\n optionalDependencies?: Record<string, string>;\r\n pnpm?: {\r\n overrides?: Record<string, string>;\r\n [key: string]: unknown;\r\n };\r\n overrides?: Record<string, string>;\r\n resolutions?: Record<string, string>;\r\n [key: string]: unknown;\r\n}\r\n\r\n/**\r\n * Resolves a version string that may contain catalog: or workspace: protocols\r\n */\r\nfunction resolveVersion(\r\n packageName: string,\r\n version: string,\r\n defaultCatalog: Record<string, string>,\r\n namedCatalogs: Record<string, Record<string, string>>\r\n): string {\r\n // Handle catalog: (default catalog)\r\n if (version === 'catalog:') {\r\n const resolved = defaultCatalog[packageName];\r\n if (resolved) {\r\n return resolved;\r\n }\r\n // If not found in catalog, keep original (will likely fail at install)\r\n return version;\r\n }\r\n\r\n // Handle catalog:catalogName (named catalog)\r\n if (version.startsWith('catalog:')) {\r\n const catalogName = version.slice('catalog:'.length);\r\n const catalog = namedCatalogs[catalogName];\r\n if (catalog && catalog[packageName]) {\r\n return catalog[packageName];\r\n }\r\n // If not found in named catalog, keep original\r\n return version;\r\n }\r\n\r\n // Handle workspace:* or workspace:^ etc.\r\n if (version.startsWith('workspace:')) {\r\n return '*';\r\n }\r\n\r\n return version;\r\n}\r\n\r\n/**\r\n * Resolves catalog versions in an overrides/resolutions object\r\n */\r\nfunction resolveOverrides(\r\n overrides: Record<string, string>,\r\n defaultCatalog: Record<string, string>,\r\n namedCatalogs: Record<string, Record<string, string>>\r\n): Record<string, string> {\r\n const resolved: Record<string, string> = {};\r\n \r\n for (const [pkg, version] of Object.entries(overrides)) {\r\n resolved[pkg] = resolveVersion(pkg, version, defaultCatalog, namedCatalogs);\r\n }\r\n \r\n return resolved;\r\n}\r\n\r\n/**\r\n * Resolves pnpm catalog versions in all package.json files when using a non-pnpm package manager.\r\n * \r\n * This transform:\r\n * 1. Parses pnpm-workspace.yaml to extract catalog version mappings\r\n * 2. Replaces catalog: and catalog:name versions with actual versions in all package.json files\r\n * 3. Replaces workspace:* references with *\r\n * 4. Converts pnpm.overrides to overrides (npm/bun) or resolutions (yarn)\r\n * 5. Removes the packageManager field from root package.json\r\n * 6. Deletes pnpm-workspace.yaml\r\n */\r\nexport async function resolveCatalogVersions(\r\n projectDir: string,\r\n packageManager: PackageManager\r\n) {\r\n const s = spinner();\r\n s.start('Resolving pnpm catalog versions...');\r\n\r\n try {\r\n // 1. Parse pnpm-workspace.yaml\r\n const workspaceYamlPath = path.join(projectDir, 'pnpm-workspace.yaml');\r\n \r\n if (!(await fs.pathExists(workspaceYamlPath))) {\r\n s.stop('No pnpm-workspace.yaml found, skipping catalog resolution');\r\n return;\r\n }\r\n\r\n const workspaceContent = await fs.readFile(workspaceYamlPath, 'utf8');\r\n const workspace: PnpmWorkspace = YAML.parse(workspaceContent);\r\n\r\n const defaultCatalog = workspace.catalog ?? {};\r\n const namedCatalogs = workspace.catalogs ?? {};\r\n\r\n // 2. Find all package.json files\r\n const packageJsonFiles = await fg('**/package.json', {\r\n cwd: projectDir,\r\n ignore: ['**/node_modules/**'],\r\n absolute: true,\r\n });\r\n\r\n let totalResolved = 0;\r\n\r\n // 3. Process each package.json\r\n for (const filePath of packageJsonFiles) {\r\n const pkg: PackageJson = await fs.readJson(filePath);\r\n let modified = false;\r\n const relativePath = path.relative(projectDir, filePath);\r\n\r\n // Process all dependency types\r\n const depTypes = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'] as const;\r\n \r\n for (const depType of depTypes) {\r\n const deps = pkg[depType];\r\n if (deps) {\r\n for (const [name, version] of Object.entries(deps)) {\r\n const resolved = resolveVersion(name, version, defaultCatalog, namedCatalogs);\r\n if (resolved !== version) {\r\n deps[name] = resolved;\r\n modified = true;\r\n totalResolved++;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // 4. Handle pnpm.overrides\r\n if (pkg.pnpm?.overrides) {\r\n const resolvedOverrides = resolveOverrides(\r\n pkg.pnpm.overrides,\r\n defaultCatalog,\r\n namedCatalogs\r\n );\r\n\r\n if (packageManager === 'yarn') {\r\n // Yarn uses 'resolutions'\r\n pkg.resolutions = { ...(pkg.resolutions ?? {}), ...resolvedOverrides };\r\n } else {\r\n // npm and bun use 'overrides'\r\n pkg.overrides = { ...(pkg.overrides ?? {}), ...resolvedOverrides };\r\n }\r\n\r\n // Remove pnpm-specific field\r\n delete pkg.pnpm;\r\n modified = true;\r\n s.message(`Converted pnpm.overrides in ${color.cyan(relativePath)}`);\r\n }\r\n\r\n // 5. Remove packageManager field from root package.json\r\n if (relativePath === 'package.json' && pkg.packageManager) {\r\n delete pkg.packageManager;\r\n modified = true;\r\n }\r\n\r\n if (modified) {\r\n await fs.writeJson(filePath, pkg, { spaces: 2 });\r\n }\r\n }\r\n\r\n // 6. Delete pnpm-workspace.yaml\r\n await fs.remove(workspaceYamlPath);\r\n\r\n s.stop(`Resolved ${color.cyan(totalResolved.toString())} catalog versions`);\r\n } catch (error) {\r\n s.stop('Failed to resolve catalog versions');\r\n throw error;\r\n }\r\n}\r\n\r\n"],"mappings":"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","names":[]}
package/dist/cli.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  replaceScope,
15
15
  resolveCatalogVersions,
16
16
  setupEnv
17
- } from "./chunk-6ZFG4OIY.js";
17
+ } from "./chunk-Q43WSJ4J.js";
18
18
  import "./chunk-WQABKQSK.js";
19
19
 
20
20
  // src/cli.ts
@@ -8,7 +8,7 @@ import {
8
8
  replaceScope,
9
9
  resolveCatalogVersions,
10
10
  setupEnv
11
- } from "../chunk-6ZFG4OIY.js";
11
+ } from "../chunk-Q43WSJ4J.js";
12
12
  export {
13
13
  configureDockerCompose,
14
14
  deleteDockerCompose,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-turbo-kit",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "main": "dist/cli.js",
@@ -1,10 +1,10 @@
1
- import fg from 'fast-glob';
2
- import fs from 'fs-extra';
3
- import path from 'path';
4
- import { spinner } from '@clack/prompts';
5
- import color from 'picocolors';
6
- import YAML from 'yaml';
7
- import type { PackageManager } from '../utils/package-manager.js';
1
+ import fg from 'fast-glob';
2
+ import fs from 'fs-extra';
3
+ import path from 'path';
4
+ import { spinner } from '@clack/prompts';
5
+ import color from 'picocolors';
6
+ import YAML from 'yaml';
7
+ import type { PackageManager } from '../utils/package-manager.js';
8
8
 
9
9
  const DOCKER_CONTAINERS = {
10
10
  postgres: {
@@ -41,6 +41,26 @@ const DOCKER_CONTAINERS = {
41
41
 
42
42
  export type DockerContainer = keyof typeof DOCKER_CONTAINERS;
43
43
 
44
+ /**
45
+ * Sort dependencies alphabetically in a package.json object
46
+ */
47
+ function sortPackageJsonDependencies(pkg: PackageJson): void {
48
+ const depTypes = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'] as const;
49
+
50
+ for (const depType of depTypes) {
51
+ const deps = pkg[depType];
52
+ if (deps && typeof deps === 'object') {
53
+ const sorted = Object.keys(deps)
54
+ .sort()
55
+ .reduce((acc, key) => {
56
+ acc[key] = deps[key]!;
57
+ return acc;
58
+ }, {} as Record<string, string>);
59
+ pkg[depType] = sorted;
60
+ }
61
+ }
62
+ }
63
+
44
64
  export async function replaceScope(projectDir: string, newScope: string) {
45
65
  const s = spinner();
46
66
  s.start(`Replacing scope with ${color.cyan(newScope)}...`);
@@ -75,7 +95,27 @@ export async function replaceScope(projectDir: string, newScope: string) {
75
95
  })
76
96
  );
77
97
 
78
- s.stop(`Replaced scope with ${color.cyan(newScope)}`);
98
+ // Sort dependencies in all package.json files after replacing scope
99
+ s.message('Sorting dependencies alphabetically...');
100
+ const packageJsonFiles = await fg('**/package.json', {
101
+ cwd: projectDir,
102
+ ignore: ['**/node_modules/**'],
103
+ absolute: true,
104
+ });
105
+
106
+ await Promise.all(
107
+ packageJsonFiles.map(async (file) => {
108
+ try {
109
+ const pkg: PackageJson = await fs.readJson(file);
110
+ sortPackageJsonDependencies(pkg);
111
+ await fs.writeJson(file, pkg, { spaces: 2 });
112
+ } catch (e) {
113
+ // Ignore errors for malformed package.json files
114
+ }
115
+ })
116
+ );
117
+
118
+ s.stop(`Replaced scope with ${color.cyan(newScope)} and sorted dependencies`);
79
119
  } catch (error) {
80
120
  s.stop('Failed to replace scope');
81
121
  throw error;
@@ -226,211 +266,211 @@ export async function removePackages(
226
266
  }
227
267
  }
228
268
 
229
- export async function removeReactEmail(projectDir: string) {
230
- const s = spinner();
231
- s.start('Removing react-email...');
232
-
233
- try {
234
- // remove email package
235
- const emailPackagePath = path.join(projectDir, 'packages', 'email');
236
- if (await fs.pathExists(emailPackagePath)) {
237
- await fs.remove(emailPackagePath);
238
- s.message(`Removed ${color.cyan(emailPackagePath)}`);
239
- }
240
-
241
- // remove @react-email/components from packages/api/package.json
242
- await removePackages(['@react-email/components', '@acme/email'], 'packages/api', projectDir, s);
243
-
244
- s.stop('Removed react-email');
245
- } catch (error) {
246
- s.stop('Failed to remove react-email');
247
- throw error;
248
- }
249
- }
250
-
251
- interface PnpmWorkspace {
252
- packages?: string[];
253
- catalog?: Record<string, string>;
254
- catalogs?: Record<string, Record<string, string>>;
255
- overrides?: Record<string, string>;
256
- }
257
-
258
- interface PackageJson {
259
- name?: string;
260
- packageManager?: string;
261
- dependencies?: Record<string, string>;
262
- devDependencies?: Record<string, string>;
263
- peerDependencies?: Record<string, string>;
264
- optionalDependencies?: Record<string, string>;
265
- pnpm?: {
266
- overrides?: Record<string, string>;
267
- [key: string]: unknown;
268
- };
269
- overrides?: Record<string, string>;
270
- resolutions?: Record<string, string>;
271
- [key: string]: unknown;
272
- }
273
-
274
- /**
275
- * Resolves a version string that may contain catalog: or workspace: protocols
276
- */
277
- function resolveVersion(
278
- packageName: string,
279
- version: string,
280
- defaultCatalog: Record<string, string>,
281
- namedCatalogs: Record<string, Record<string, string>>
282
- ): string {
283
- // Handle catalog: (default catalog)
284
- if (version === 'catalog:') {
285
- const resolved = defaultCatalog[packageName];
286
- if (resolved) {
287
- return resolved;
288
- }
289
- // If not found in catalog, keep original (will likely fail at install)
290
- return version;
291
- }
292
-
293
- // Handle catalog:catalogName (named catalog)
294
- if (version.startsWith('catalog:')) {
295
- const catalogName = version.slice('catalog:'.length);
296
- const catalog = namedCatalogs[catalogName];
297
- if (catalog && catalog[packageName]) {
298
- return catalog[packageName];
299
- }
300
- // If not found in named catalog, keep original
301
- return version;
302
- }
303
-
304
- // Handle workspace:* or workspace:^ etc.
305
- if (version.startsWith('workspace:')) {
306
- return '*';
307
- }
308
-
309
- return version;
310
- }
311
-
312
- /**
313
- * Resolves catalog versions in an overrides/resolutions object
314
- */
315
- function resolveOverrides(
316
- overrides: Record<string, string>,
317
- defaultCatalog: Record<string, string>,
318
- namedCatalogs: Record<string, Record<string, string>>
319
- ): Record<string, string> {
320
- const resolved: Record<string, string> = {};
321
-
322
- for (const [pkg, version] of Object.entries(overrides)) {
323
- resolved[pkg] = resolveVersion(pkg, version, defaultCatalog, namedCatalogs);
324
- }
325
-
326
- return resolved;
327
- }
328
-
329
- /**
330
- * Resolves pnpm catalog versions in all package.json files when using a non-pnpm package manager.
331
- *
332
- * This transform:
333
- * 1. Parses pnpm-workspace.yaml to extract catalog version mappings
334
- * 2. Replaces catalog: and catalog:name versions with actual versions in all package.json files
335
- * 3. Replaces workspace:* references with *
336
- * 4. Converts pnpm.overrides to overrides (npm/bun) or resolutions (yarn)
337
- * 5. Removes the packageManager field from root package.json
338
- * 6. Deletes pnpm-workspace.yaml
339
- */
340
- export async function resolveCatalogVersions(
341
- projectDir: string,
342
- packageManager: PackageManager
343
- ) {
344
- const s = spinner();
345
- s.start('Resolving pnpm catalog versions...');
346
-
347
- try {
348
- // 1. Parse pnpm-workspace.yaml
349
- const workspaceYamlPath = path.join(projectDir, 'pnpm-workspace.yaml');
350
-
351
- if (!(await fs.pathExists(workspaceYamlPath))) {
352
- s.stop('No pnpm-workspace.yaml found, skipping catalog resolution');
353
- return;
354
- }
355
-
356
- const workspaceContent = await fs.readFile(workspaceYamlPath, 'utf8');
357
- const workspace: PnpmWorkspace = YAML.parse(workspaceContent);
358
-
359
- const defaultCatalog = workspace.catalog ?? {};
360
- const namedCatalogs = workspace.catalogs ?? {};
361
-
362
- // 2. Find all package.json files
363
- const packageJsonFiles = await fg('**/package.json', {
364
- cwd: projectDir,
365
- ignore: ['**/node_modules/**'],
366
- absolute: true,
367
- });
368
-
369
- let totalResolved = 0;
370
-
371
- // 3. Process each package.json
372
- for (const filePath of packageJsonFiles) {
373
- const pkg: PackageJson = await fs.readJson(filePath);
374
- let modified = false;
375
- const relativePath = path.relative(projectDir, filePath);
376
-
377
- // Process all dependency types
378
- const depTypes = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'] as const;
379
-
380
- for (const depType of depTypes) {
381
- const deps = pkg[depType];
382
- if (deps) {
383
- for (const [name, version] of Object.entries(deps)) {
384
- const resolved = resolveVersion(name, version, defaultCatalog, namedCatalogs);
385
- if (resolved !== version) {
386
- deps[name] = resolved;
387
- modified = true;
388
- totalResolved++;
389
- }
390
- }
391
- }
392
- }
393
-
394
- // 4. Handle pnpm.overrides
395
- if (pkg.pnpm?.overrides) {
396
- const resolvedOverrides = resolveOverrides(
397
- pkg.pnpm.overrides,
398
- defaultCatalog,
399
- namedCatalogs
400
- );
401
-
402
- if (packageManager === 'yarn') {
403
- // Yarn uses 'resolutions'
404
- pkg.resolutions = { ...(pkg.resolutions ?? {}), ...resolvedOverrides };
405
- } else {
406
- // npm and bun use 'overrides'
407
- pkg.overrides = { ...(pkg.overrides ?? {}), ...resolvedOverrides };
408
- }
409
-
410
- // Remove pnpm-specific field
411
- delete pkg.pnpm;
412
- modified = true;
413
- s.message(`Converted pnpm.overrides in ${color.cyan(relativePath)}`);
414
- }
415
-
416
- // 5. Remove packageManager field from root package.json
417
- if (relativePath === 'package.json' && pkg.packageManager) {
418
- delete pkg.packageManager;
419
- modified = true;
420
- }
421
-
422
- if (modified) {
423
- await fs.writeJson(filePath, pkg, { spaces: 2 });
424
- }
425
- }
426
-
427
- // 6. Delete pnpm-workspace.yaml
428
- await fs.remove(workspaceYamlPath);
429
-
430
- s.stop(`Resolved ${color.cyan(totalResolved.toString())} catalog versions`);
431
- } catch (error) {
432
- s.stop('Failed to resolve catalog versions');
433
- throw error;
434
- }
435
- }
269
+ export async function removeReactEmail(projectDir: string) {
270
+ const s = spinner();
271
+ s.start('Removing react-email...');
272
+
273
+ try {
274
+ // remove email package
275
+ const emailPackagePath = path.join(projectDir, 'packages', 'email');
276
+ if (await fs.pathExists(emailPackagePath)) {
277
+ await fs.remove(emailPackagePath);
278
+ s.message(`Removed ${color.cyan(emailPackagePath)}`);
279
+ }
280
+
281
+ // remove @react-email/components from packages/api/package.json
282
+ await removePackages(['@react-email/components', '@acme/email'], 'packages/api', projectDir, s);
283
+
284
+ s.stop('Removed react-email');
285
+ } catch (error) {
286
+ s.stop('Failed to remove react-email');
287
+ throw error;
288
+ }
289
+ }
290
+
291
+ interface PnpmWorkspace {
292
+ packages?: string[];
293
+ catalog?: Record<string, string>;
294
+ catalogs?: Record<string, Record<string, string>>;
295
+ overrides?: Record<string, string>;
296
+ }
297
+
298
+ interface PackageJson {
299
+ name?: string;
300
+ packageManager?: string;
301
+ dependencies?: Record<string, string>;
302
+ devDependencies?: Record<string, string>;
303
+ peerDependencies?: Record<string, string>;
304
+ optionalDependencies?: Record<string, string>;
305
+ pnpm?: {
306
+ overrides?: Record<string, string>;
307
+ [key: string]: unknown;
308
+ };
309
+ overrides?: Record<string, string>;
310
+ resolutions?: Record<string, string>;
311
+ [key: string]: unknown;
312
+ }
313
+
314
+ /**
315
+ * Resolves a version string that may contain catalog: or workspace: protocols
316
+ */
317
+ function resolveVersion(
318
+ packageName: string,
319
+ version: string,
320
+ defaultCatalog: Record<string, string>,
321
+ namedCatalogs: Record<string, Record<string, string>>
322
+ ): string {
323
+ // Handle catalog: (default catalog)
324
+ if (version === 'catalog:') {
325
+ const resolved = defaultCatalog[packageName];
326
+ if (resolved) {
327
+ return resolved;
328
+ }
329
+ // If not found in catalog, keep original (will likely fail at install)
330
+ return version;
331
+ }
332
+
333
+ // Handle catalog:catalogName (named catalog)
334
+ if (version.startsWith('catalog:')) {
335
+ const catalogName = version.slice('catalog:'.length);
336
+ const catalog = namedCatalogs[catalogName];
337
+ if (catalog && catalog[packageName]) {
338
+ return catalog[packageName];
339
+ }
340
+ // If not found in named catalog, keep original
341
+ return version;
342
+ }
343
+
344
+ // Handle workspace:* or workspace:^ etc.
345
+ if (version.startsWith('workspace:')) {
346
+ return '*';
347
+ }
348
+
349
+ return version;
350
+ }
351
+
352
+ /**
353
+ * Resolves catalog versions in an overrides/resolutions object
354
+ */
355
+ function resolveOverrides(
356
+ overrides: Record<string, string>,
357
+ defaultCatalog: Record<string, string>,
358
+ namedCatalogs: Record<string, Record<string, string>>
359
+ ): Record<string, string> {
360
+ const resolved: Record<string, string> = {};
361
+
362
+ for (const [pkg, version] of Object.entries(overrides)) {
363
+ resolved[pkg] = resolveVersion(pkg, version, defaultCatalog, namedCatalogs);
364
+ }
365
+
366
+ return resolved;
367
+ }
368
+
369
+ /**
370
+ * Resolves pnpm catalog versions in all package.json files when using a non-pnpm package manager.
371
+ *
372
+ * This transform:
373
+ * 1. Parses pnpm-workspace.yaml to extract catalog version mappings
374
+ * 2. Replaces catalog: and catalog:name versions with actual versions in all package.json files
375
+ * 3. Replaces workspace:* references with *
376
+ * 4. Converts pnpm.overrides to overrides (npm/bun) or resolutions (yarn)
377
+ * 5. Removes the packageManager field from root package.json
378
+ * 6. Deletes pnpm-workspace.yaml
379
+ */
380
+ export async function resolveCatalogVersions(
381
+ projectDir: string,
382
+ packageManager: PackageManager
383
+ ) {
384
+ const s = spinner();
385
+ s.start('Resolving pnpm catalog versions...');
386
+
387
+ try {
388
+ // 1. Parse pnpm-workspace.yaml
389
+ const workspaceYamlPath = path.join(projectDir, 'pnpm-workspace.yaml');
390
+
391
+ if (!(await fs.pathExists(workspaceYamlPath))) {
392
+ s.stop('No pnpm-workspace.yaml found, skipping catalog resolution');
393
+ return;
394
+ }
395
+
396
+ const workspaceContent = await fs.readFile(workspaceYamlPath, 'utf8');
397
+ const workspace: PnpmWorkspace = YAML.parse(workspaceContent);
398
+
399
+ const defaultCatalog = workspace.catalog ?? {};
400
+ const namedCatalogs = workspace.catalogs ?? {};
401
+
402
+ // 2. Find all package.json files
403
+ const packageJsonFiles = await fg('**/package.json', {
404
+ cwd: projectDir,
405
+ ignore: ['**/node_modules/**'],
406
+ absolute: true,
407
+ });
408
+
409
+ let totalResolved = 0;
410
+
411
+ // 3. Process each package.json
412
+ for (const filePath of packageJsonFiles) {
413
+ const pkg: PackageJson = await fs.readJson(filePath);
414
+ let modified = false;
415
+ const relativePath = path.relative(projectDir, filePath);
416
+
417
+ // Process all dependency types
418
+ const depTypes = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'] as const;
419
+
420
+ for (const depType of depTypes) {
421
+ const deps = pkg[depType];
422
+ if (deps) {
423
+ for (const [name, version] of Object.entries(deps)) {
424
+ const resolved = resolveVersion(name, version, defaultCatalog, namedCatalogs);
425
+ if (resolved !== version) {
426
+ deps[name] = resolved;
427
+ modified = true;
428
+ totalResolved++;
429
+ }
430
+ }
431
+ }
432
+ }
433
+
434
+ // 4. Handle pnpm.overrides
435
+ if (pkg.pnpm?.overrides) {
436
+ const resolvedOverrides = resolveOverrides(
437
+ pkg.pnpm.overrides,
438
+ defaultCatalog,
439
+ namedCatalogs
440
+ );
441
+
442
+ if (packageManager === 'yarn') {
443
+ // Yarn uses 'resolutions'
444
+ pkg.resolutions = { ...(pkg.resolutions ?? {}), ...resolvedOverrides };
445
+ } else {
446
+ // npm and bun use 'overrides'
447
+ pkg.overrides = { ...(pkg.overrides ?? {}), ...resolvedOverrides };
448
+ }
449
+
450
+ // Remove pnpm-specific field
451
+ delete pkg.pnpm;
452
+ modified = true;
453
+ s.message(`Converted pnpm.overrides in ${color.cyan(relativePath)}`);
454
+ }
455
+
456
+ // 5. Remove packageManager field from root package.json
457
+ if (relativePath === 'package.json' && pkg.packageManager) {
458
+ delete pkg.packageManager;
459
+ modified = true;
460
+ }
461
+
462
+ if (modified) {
463
+ await fs.writeJson(filePath, pkg, { spaces: 2 });
464
+ }
465
+ }
466
+
467
+ // 6. Delete pnpm-workspace.yaml
468
+ await fs.remove(workspaceYamlPath);
469
+
470
+ s.stop(`Resolved ${color.cyan(totalResolved.toString())} catalog versions`);
471
+ } catch (error) {
472
+ s.stop('Failed to resolve catalog versions');
473
+ throw error;
474
+ }
475
+ }
436
476
 
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/helpers/transform.ts"],"sourcesContent":["import fg from 'fast-glob';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { spinner } from '@clack/prompts';\nimport color from 'picocolors';\nimport YAML from 'yaml';\nimport type { PackageManager } from '../utils/package-manager.js';\n\r\nconst DOCKER_CONTAINERS = {\r\n postgres: {\r\n label: 'PostgreSQL 16 (Database)',\r\n services: ['postgres'],\r\n volumes: ['postgres_data'],\r\n dependsOn: [], \r\n },\r\n pgadmin: {\r\n label: `pgAdmin 4.9 (Database management) [Depends on PostgreSQL]`,\r\n services: ['pgadmin'],\r\n volumes: [],\r\n dependsOn: ['postgres'],\r\n },\r\n redis: {\r\n label: 'Redis (Caching)',\r\n services: ['redis'],\r\n volumes: [],\r\n dependsOn: [],\r\n },\r\n mailpit: {\r\n label: 'Mailpit (Email testing)',\r\n services: ['mailpit'],\r\n volumes: [],\r\n dependsOn: [],\r\n },\r\n minio: {\r\n label: 'MinIO (S3-compatible storage)',\r\n services: ['minio', 'minio-create-bucket'],\r\n volumes: ['minio_data'],\r\n dependsOn: [],\r\n },\r\n} as const;\r\n\r\nexport type DockerContainer = keyof typeof DOCKER_CONTAINERS;\r\n\r\nexport async function replaceScope(projectDir: string, newScope: string) {\r\n const s = spinner();\r\n s.start(`Replacing scope with ${color.cyan(newScope)}...`);\r\n\r\n try {\r\n const files = await fg('**/*', {\r\n cwd: projectDir,\r\n ignore: [\r\n '**/.git/**',\r\n '**/node_modules/**',\r\n '**/.turbo/**',\r\n '**/dist/**',\r\n '**/.next/**',\r\n '**/pnpm-lock.yaml',\r\n '**/yarn.lock',\r\n '**/package-lock.json',\r\n '**/bun.lockb',\r\n ],\r\n absolute: true,\r\n });\r\n\r\n await Promise.all(\r\n files.map(async (file) => {\r\n try {\r\n const content = await fs.readFile(file, 'utf8');\r\n if (content.includes('@acme')) {\r\n const newContent = content.replace(/@acme/g, newScope);\r\n await fs.writeFile(file, newContent);\r\n }\r\n } catch (e) {\r\n }\r\n })\r\n );\r\n \r\n s.stop(`Replaced scope with ${color.cyan(newScope)}`);\r\n } catch (error) {\r\n s.stop('Failed to replace scope');\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function setupEnv(projectDir: string) {\r\n const envExample = path.join(projectDir, '.env.example');\r\n const envDest = path.join(projectDir, '.env');\r\n\r\n if (await fs.pathExists(envExample)) {\r\n await fs.copy(envExample, envDest);\r\n }\r\n}\r\n\r\nexport function getDockerContainers() {\r\n return Object.entries(DOCKER_CONTAINERS).map(([value, config]) => ({\r\n value,\r\n label: config.label,\r\n }));\r\n}\r\n\r\nexport async function deleteDockerCompose(projectDir: string) {\r\n const s = spinner();\r\n s.start('Removing Docker Compose setup...');\r\n\r\n try {\r\n const dockerComposePath = path.join(projectDir, 'docker-compose.yml');\r\n if (await fs.pathExists(dockerComposePath)) {\r\n await fs.remove(dockerComposePath);\r\n s.message(`Removed ${color.cyan(dockerComposePath)}`);\r\n }\r\n const dockerDir = path.join(projectDir, 'docker');\r\n if (await fs.pathExists(dockerDir)) {\r\n await fs.remove(dockerDir);\r\n s.message(`Removed ${color.cyan(dockerDir)}`);\r\n }\r\n s.stop('Removed Docker Compose setup');\r\n } catch (error) {\r\n s.stop('Failed to remove Docker Compose setup');\r\n throw error;\r\n }\r\n}\r\n\r\nfunction resolveContainerDependencies(selectedContainers: string[]): string[] {\r\n const resolved = new Set<string>(selectedContainers);\r\n const queue = [...selectedContainers];\r\n\r\n while (queue.length > 0) {\r\n const current = queue.shift()!;\r\n const config = DOCKER_CONTAINERS[current as DockerContainer];\r\n \r\n if (config && config.dependsOn) {\r\n for (const dep of config.dependsOn) {\r\n if (!resolved.has(dep)) {\r\n resolved.add(dep);\r\n queue.push(dep);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return Array.from(resolved);\r\n}\r\n\r\nexport async function configureDockerCompose(projectDir: string, selectedContainers: string[]) {\r\n const s = spinner();\r\n s.start('Configuring Docker Compose...');\r\n\r\n try {\r\n const dockerComposePath = path.join(projectDir, 'docker-compose.yml');\r\n \r\n if (!(await fs.pathExists(dockerComposePath))) {\r\n s.stop('Docker Compose file not found');\r\n return;\r\n }\r\n\r\n const resolvedContainers = resolveContainerDependencies(selectedContainers);\r\n const addedDependencies = resolvedContainers.filter(c => !selectedContainers.includes(c));\r\n \r\n if (addedDependencies.length > 0) {\r\n s.message(`Auto-including dependencies: ${color.cyan(addedDependencies.join(', '))}`);\r\n }\r\n\r\n let content = await fs.readFile(dockerComposePath, 'utf8');\r\n\r\n const allContainers = Object.keys(DOCKER_CONTAINERS) as DockerContainer[];\r\n const containersToRemove = allContainers.filter(c => !resolvedContainers.includes(c));\r\n\r\n for (const container of containersToRemove) {\r\n const containerRegex = new RegExp(\r\n ` # -- ${container} --\\\\n[\\\\s\\\\S]*? # // ${container} //\\\\n`,\r\n 'g'\r\n );\r\n content = content.replace(containerRegex, '');\r\n\r\n // delete `./docker/<container>/`\r\n const dockerDirPath = path.join(projectDir, 'docker', container);\r\n if (await fs.pathExists(dockerDirPath)) {\r\n await fs.remove(dockerDirPath);\r\n s.message(`Removed ${color.cyan(dockerDirPath)}`);\r\n }\r\n }\r\n\r\n content = content.replace(/ # -- \\w+ --\\n/g, '');\r\n content = content.replace(/ # \\/\\/ \\w+ \\/\\/\\n/g, '');\r\n\r\n await fs.writeFile(dockerComposePath, content);\r\n\r\n // check if `./docker/` is empty\r\n const dockerDir = path.join(projectDir, 'docker');\r\n if (await fs.pathExists(dockerDir) && (await fs.readdir(dockerDir)).length === 0) {\r\n await fs.remove(dockerDir);\r\n s.message(`Removed ${color.cyan(dockerDir)} ${color.gray('(because it was empty)')}`);\r\n }\r\n \r\n s.stop(`Configured Docker Compose with ${color.cyan(resolvedContainers.length)} container(s)`);\r\n } catch (error) {\r\n s.stop('Failed to configure Docker Compose');\r\n throw error;\r\n }\r\n}\r\n\r\nexport async function removePackages(\r\n packages: string[],\r\n packagePath: string,\r\n projectDir: string,\r\n s?: ReturnType<typeof spinner>\r\n) {\r\n const packageJsonPath = path.join(projectDir, packagePath, 'package.json');\r\n if (await fs.pathExists(packageJsonPath)) {\r\n const packageJson = await fs.readJson(packageJsonPath);\r\n let hasChanges = false;\r\n\r\n for (const dep of packages) {\r\n if (packageJson.dependencies && packageJson.dependencies[dep]) {\r\n delete packageJson.dependencies[dep];\r\n hasChanges = true;\r\n if (s) {\r\n s.message(`Removed ${color.cyan(dep)} from ${packagePath}/package.json`);\r\n }\r\n }\r\n }\r\n\r\n if (hasChanges) {\r\n await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });\r\n }\r\n }\r\n}\r\n\r\nexport async function removeReactEmail(projectDir: string) {\n const s = spinner();\n s.start('Removing react-email...');\n\n try {\n // remove email package\n const emailPackagePath = path.join(projectDir, 'packages', 'email');\n if (await fs.pathExists(emailPackagePath)) {\n await fs.remove(emailPackagePath);\n s.message(`Removed ${color.cyan(emailPackagePath)}`);\n }\n\n // remove @react-email/components from packages/api/package.json\n await removePackages(['@react-email/components', '@acme/email'], 'packages/api', projectDir, s);\n\n s.stop('Removed react-email');\n } catch (error) {\n s.stop('Failed to remove react-email');\n throw error;\n }\n}\n\ninterface PnpmWorkspace {\n packages?: string[];\n catalog?: Record<string, string>;\n catalogs?: Record<string, Record<string, string>>;\n overrides?: Record<string, string>;\n}\n\ninterface PackageJson {\n name?: string;\n packageManager?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n pnpm?: {\n overrides?: Record<string, string>;\n [key: string]: unknown;\n };\n overrides?: Record<string, string>;\n resolutions?: Record<string, string>;\n [key: string]: unknown;\n}\n\n/**\n * Resolves a version string that may contain catalog: or workspace: protocols\n */\nfunction resolveVersion(\n packageName: string,\n version: string,\n defaultCatalog: Record<string, string>,\n namedCatalogs: Record<string, Record<string, string>>\n): string {\n // Handle catalog: (default catalog)\n if (version === 'catalog:') {\n const resolved = defaultCatalog[packageName];\n if (resolved) {\n return resolved;\n }\n // If not found in catalog, keep original (will likely fail at install)\n return version;\n }\n\n // Handle catalog:catalogName (named catalog)\n if (version.startsWith('catalog:')) {\n const catalogName = version.slice('catalog:'.length);\n const catalog = namedCatalogs[catalogName];\n if (catalog && catalog[packageName]) {\n return catalog[packageName];\n }\n // If not found in named catalog, keep original\n return version;\n }\n\n // Handle workspace:* or workspace:^ etc.\n if (version.startsWith('workspace:')) {\n return '*';\n }\n\n return version;\n}\n\n/**\n * Resolves catalog versions in an overrides/resolutions object\n */\nfunction resolveOverrides(\n overrides: Record<string, string>,\n defaultCatalog: Record<string, string>,\n namedCatalogs: Record<string, Record<string, string>>\n): Record<string, string> {\n const resolved: Record<string, string> = {};\n \n for (const [pkg, version] of Object.entries(overrides)) {\n resolved[pkg] = resolveVersion(pkg, version, defaultCatalog, namedCatalogs);\n }\n \n return resolved;\n}\n\n/**\n * Resolves pnpm catalog versions in all package.json files when using a non-pnpm package manager.\n * \n * This transform:\n * 1. Parses pnpm-workspace.yaml to extract catalog version mappings\n * 2. Replaces catalog: and catalog:name versions with actual versions in all package.json files\n * 3. Replaces workspace:* references with *\n * 4. Converts pnpm.overrides to overrides (npm/bun) or resolutions (yarn)\n * 5. Removes the packageManager field from root package.json\n * 6. Deletes pnpm-workspace.yaml\n */\nexport async function resolveCatalogVersions(\n projectDir: string,\n packageManager: PackageManager\n) {\n const s = spinner();\n s.start('Resolving pnpm catalog versions...');\n\n try {\n // 1. Parse pnpm-workspace.yaml\n const workspaceYamlPath = path.join(projectDir, 'pnpm-workspace.yaml');\n \n if (!(await fs.pathExists(workspaceYamlPath))) {\n s.stop('No pnpm-workspace.yaml found, skipping catalog resolution');\n return;\n }\n\n const workspaceContent = await fs.readFile(workspaceYamlPath, 'utf8');\n const workspace: PnpmWorkspace = YAML.parse(workspaceContent);\n\n const defaultCatalog = workspace.catalog ?? {};\n const namedCatalogs = workspace.catalogs ?? {};\n\n // 2. Find all package.json files\n const packageJsonFiles = await fg('**/package.json', {\n cwd: projectDir,\n ignore: ['**/node_modules/**'],\n absolute: true,\n });\n\n let totalResolved = 0;\n\n // 3. Process each package.json\n for (const filePath of packageJsonFiles) {\n const pkg: PackageJson = await fs.readJson(filePath);\n let modified = false;\n const relativePath = path.relative(projectDir, filePath);\n\n // Process all dependency types\n const depTypes = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'] as const;\n \n for (const depType of depTypes) {\n const deps = pkg[depType];\n if (deps) {\n for (const [name, version] of Object.entries(deps)) {\n const resolved = resolveVersion(name, version, defaultCatalog, namedCatalogs);\n if (resolved !== version) {\n deps[name] = resolved;\n modified = true;\n totalResolved++;\n }\n }\n }\n }\n\n // 4. Handle pnpm.overrides\n if (pkg.pnpm?.overrides) {\n const resolvedOverrides = resolveOverrides(\n pkg.pnpm.overrides,\n defaultCatalog,\n namedCatalogs\n );\n\n if (packageManager === 'yarn') {\n // Yarn uses 'resolutions'\n pkg.resolutions = { ...(pkg.resolutions ?? {}), ...resolvedOverrides };\n } else {\n // npm and bun use 'overrides'\n pkg.overrides = { ...(pkg.overrides ?? {}), ...resolvedOverrides };\n }\n\n // Remove pnpm-specific field\n delete pkg.pnpm;\n modified = true;\n s.message(`Converted pnpm.overrides in ${color.cyan(relativePath)}`);\n }\n\n // 5. Remove packageManager field from root package.json\n if (relativePath === 'package.json' && pkg.packageManager) {\n delete pkg.packageManager;\n modified = true;\n }\n\n if (modified) {\n await fs.writeJson(filePath, pkg, { spaces: 2 });\n }\n }\n\n // 6. Delete pnpm-workspace.yaml\n await fs.remove(workspaceYamlPath);\n\n s.stop(`Resolved ${color.cyan(totalResolved.toString())} catalog versions`);\n } catch (error) {\n s.stop('Failed to resolve catalog versions');\n throw error;\n }\n}\n\r\n"],"mappings":"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","names":[]}