@turbo/workspaces 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -0
- package/README.md +49 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1038 -0
- package/dist/index.d.ts +123 -0
- package/dist/index.js +840 -0
- package/package.json +65 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,840 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
|
|
23
|
+
// src/index.ts
|
|
24
|
+
var src_exports = {};
|
|
25
|
+
__export(src_exports, {
|
|
26
|
+
MANAGERS: () => managers_default,
|
|
27
|
+
convertMonorepo: () => convertMonorepo,
|
|
28
|
+
getWorkspaceDetails: () => getWorkspaceDetails,
|
|
29
|
+
install: () => install_default
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(src_exports);
|
|
32
|
+
var import_turbo_utils = require("turbo-utils");
|
|
33
|
+
|
|
34
|
+
// src/errors.ts
|
|
35
|
+
var ConvertError = class extends Error {
|
|
36
|
+
constructor(message) {
|
|
37
|
+
super(message);
|
|
38
|
+
this.name = "ConvertError";
|
|
39
|
+
Error.captureStackTrace(this, ConvertError);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// src/managers/pnpm.ts
|
|
44
|
+
var import_fs_extra3 = __toESM(require("fs-extra"));
|
|
45
|
+
var import_path3 = __toESM(require("path"));
|
|
46
|
+
var import_execa = __toESM(require("execa"));
|
|
47
|
+
|
|
48
|
+
// src/updateDependencies.ts
|
|
49
|
+
var import_fs_extra2 = __toESM(require("fs-extra"));
|
|
50
|
+
var import_chalk = __toESM(require("chalk"));
|
|
51
|
+
var import_path2 = __toESM(require("path"));
|
|
52
|
+
|
|
53
|
+
// src/utils.ts
|
|
54
|
+
var import_fs_extra = __toESM(require("fs-extra"));
|
|
55
|
+
var import_path = __toESM(require("path"));
|
|
56
|
+
var import_fast_glob = __toESM(require("fast-glob"));
|
|
57
|
+
var import_js_yaml = __toESM(require("js-yaml"));
|
|
58
|
+
var PACKAGE_MANAGER_REGEX = /^(?!_)(.+)@(.+)$/;
|
|
59
|
+
function getPackageJson({
|
|
60
|
+
workspaceRoot
|
|
61
|
+
}) {
|
|
62
|
+
const packageJsonPath = import_path.default.join(workspaceRoot, "package.json");
|
|
63
|
+
try {
|
|
64
|
+
return import_fs_extra.default.readJsonSync(packageJsonPath, "utf8");
|
|
65
|
+
} catch (err) {
|
|
66
|
+
if (err && typeof err === "object" && "code" in err) {
|
|
67
|
+
if (err.code === "ENOENT") {
|
|
68
|
+
throw new ConvertError(`no "package.json" found at ${workspaceRoot}`);
|
|
69
|
+
}
|
|
70
|
+
if (err.code === "EJSONPARSE") {
|
|
71
|
+
throw new ConvertError(`failed to parse "package.json" at ${workspaceRoot}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
throw new Error(`unexpected error reading "package.json" at ${workspaceRoot}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function getWorkspacePackageManager({
|
|
78
|
+
workspaceRoot
|
|
79
|
+
}) {
|
|
80
|
+
const { packageManager } = getPackageJson({ workspaceRoot });
|
|
81
|
+
if (packageManager) {
|
|
82
|
+
try {
|
|
83
|
+
const match = packageManager.match(PACKAGE_MANAGER_REGEX);
|
|
84
|
+
if (match) {
|
|
85
|
+
const [_, manager] = match;
|
|
86
|
+
return manager;
|
|
87
|
+
}
|
|
88
|
+
} catch (err) {
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return void 0;
|
|
92
|
+
}
|
|
93
|
+
function getWorkspaceName({
|
|
94
|
+
workspaceRoot
|
|
95
|
+
}) {
|
|
96
|
+
const packageJson = getPackageJson({ workspaceRoot });
|
|
97
|
+
if (packageJson.name) {
|
|
98
|
+
return packageJson.name;
|
|
99
|
+
}
|
|
100
|
+
const workspaceDirectory = import_path.default.basename(workspaceRoot);
|
|
101
|
+
return workspaceDirectory;
|
|
102
|
+
}
|
|
103
|
+
function getPnpmWorkspaces({
|
|
104
|
+
workspaceRoot
|
|
105
|
+
}) {
|
|
106
|
+
const workspaceFile = import_path.default.join(workspaceRoot, "pnpm-workspace.yaml");
|
|
107
|
+
if (import_fs_extra.default.existsSync(workspaceFile)) {
|
|
108
|
+
try {
|
|
109
|
+
const workspaceConfig = import_js_yaml.default.load(import_fs_extra.default.readFileSync(workspaceFile, "utf8"));
|
|
110
|
+
if (workspaceConfig instanceof Object && "packages" in workspaceConfig && Array.isArray(workspaceConfig.packages)) {
|
|
111
|
+
return workspaceConfig.packages;
|
|
112
|
+
}
|
|
113
|
+
} catch (err) {
|
|
114
|
+
throw new ConvertError(`failed to parse ${workspaceFile}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
function expandPaths({
|
|
120
|
+
root,
|
|
121
|
+
lockFile,
|
|
122
|
+
workspaceConfig
|
|
123
|
+
}) {
|
|
124
|
+
const fromRoot = (p) => import_path.default.join(root, p);
|
|
125
|
+
const paths = {
|
|
126
|
+
root,
|
|
127
|
+
lockfile: fromRoot(lockFile),
|
|
128
|
+
packageJson: fromRoot("package.json"),
|
|
129
|
+
nodeModules: fromRoot("node_modules")
|
|
130
|
+
};
|
|
131
|
+
if (workspaceConfig) {
|
|
132
|
+
paths.workspaceConfig = fromRoot(workspaceConfig);
|
|
133
|
+
}
|
|
134
|
+
return paths;
|
|
135
|
+
}
|
|
136
|
+
function expandWorkspaces({
|
|
137
|
+
workspaceRoot,
|
|
138
|
+
workspaceGlobs
|
|
139
|
+
}) {
|
|
140
|
+
if (!workspaceGlobs) {
|
|
141
|
+
return [];
|
|
142
|
+
}
|
|
143
|
+
return workspaceGlobs.flatMap((workspaceGlob) => {
|
|
144
|
+
const workspacePackageJsonGlob = `${workspaceGlob}/package.json`;
|
|
145
|
+
return import_fast_glob.default.sync(workspacePackageJsonGlob, {
|
|
146
|
+
onlyFiles: true,
|
|
147
|
+
absolute: true,
|
|
148
|
+
cwd: workspaceRoot
|
|
149
|
+
});
|
|
150
|
+
}).map((workspacePackageJson) => {
|
|
151
|
+
const workspaceRoot2 = import_path.default.dirname(workspacePackageJson);
|
|
152
|
+
const name = getWorkspaceName({ workspaceRoot: workspaceRoot2 });
|
|
153
|
+
return {
|
|
154
|
+
name,
|
|
155
|
+
paths: {
|
|
156
|
+
root: workspaceRoot2,
|
|
157
|
+
packageJson: workspacePackageJson,
|
|
158
|
+
nodeModules: import_path.default.join(workspaceRoot2, "node_modules")
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
function directoryInfo({ directory }) {
|
|
164
|
+
const dir = import_path.default.resolve(process.cwd(), directory);
|
|
165
|
+
return { exists: import_fs_extra.default.existsSync(dir), absolute: dir };
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// src/updateDependencies.ts
|
|
169
|
+
function updateDependencyList({
|
|
170
|
+
dependencyList,
|
|
171
|
+
project,
|
|
172
|
+
to
|
|
173
|
+
}) {
|
|
174
|
+
const updated = [];
|
|
175
|
+
project.workspaceData.workspaces.forEach((workspace) => {
|
|
176
|
+
const { name } = workspace;
|
|
177
|
+
if (dependencyList[name]) {
|
|
178
|
+
const workspaceVersion = dependencyList[name];
|
|
179
|
+
const version = workspaceVersion.startsWith("workspace:") ? workspaceVersion.slice("workspace:".length) : workspaceVersion;
|
|
180
|
+
dependencyList[name] = to.name === "pnpm" ? `workspace:${version}` : version;
|
|
181
|
+
updated.push(name);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
return { dependencyList, updated };
|
|
185
|
+
}
|
|
186
|
+
function updateDependencies({
|
|
187
|
+
project,
|
|
188
|
+
workspace,
|
|
189
|
+
to,
|
|
190
|
+
logger,
|
|
191
|
+
options
|
|
192
|
+
}) {
|
|
193
|
+
if (["yarn", "npm"].includes(to.name) && ["yarn", "npm"].includes(project.packageManager)) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const workspacePackageJson = getPackageJson({
|
|
197
|
+
workspaceRoot: workspace.paths.root
|
|
198
|
+
});
|
|
199
|
+
const stats = {
|
|
200
|
+
dependencies: [],
|
|
201
|
+
devDependencies: [],
|
|
202
|
+
peerDependencies: [],
|
|
203
|
+
optionalDependencies: []
|
|
204
|
+
};
|
|
205
|
+
const allDependencyKeys = [
|
|
206
|
+
"dependencies",
|
|
207
|
+
"devDependencies",
|
|
208
|
+
"peerDependencies",
|
|
209
|
+
"optionalDependencies"
|
|
210
|
+
];
|
|
211
|
+
allDependencyKeys.forEach((depKey) => {
|
|
212
|
+
const depList = workspacePackageJson[depKey];
|
|
213
|
+
if (depList) {
|
|
214
|
+
const { updated, dependencyList } = updateDependencyList({
|
|
215
|
+
dependencyList: depList,
|
|
216
|
+
project,
|
|
217
|
+
to
|
|
218
|
+
});
|
|
219
|
+
workspacePackageJson[depKey] = dependencyList;
|
|
220
|
+
stats[depKey] = updated;
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
const toLog = (key) => {
|
|
224
|
+
const total = stats[key].length;
|
|
225
|
+
if (total > 0) {
|
|
226
|
+
return `${import_chalk.default.green(total.toString())} ${key}`;
|
|
227
|
+
}
|
|
228
|
+
return void 0;
|
|
229
|
+
};
|
|
230
|
+
const allChanges = allDependencyKeys.map(toLog).filter(Boolean);
|
|
231
|
+
const workspaceLocation = `./${import_path2.default.relative(project.paths.root, workspace.paths.packageJson)}`;
|
|
232
|
+
if (allChanges.length >= 1) {
|
|
233
|
+
let logLine = "updating";
|
|
234
|
+
allChanges.forEach((stat, idx) => {
|
|
235
|
+
if (allChanges.length === 1) {
|
|
236
|
+
logLine += ` ${stat} in ${workspaceLocation}`;
|
|
237
|
+
} else {
|
|
238
|
+
if (idx === allChanges.length - 1) {
|
|
239
|
+
logLine += `and ${stat} in ${workspaceLocation}`;
|
|
240
|
+
} else {
|
|
241
|
+
logLine += ` ${stat}, `;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
logger.workspaceStep(logLine);
|
|
246
|
+
} else {
|
|
247
|
+
logger.workspaceStep(`no workspace dependencies found in ${workspaceLocation}`);
|
|
248
|
+
}
|
|
249
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
250
|
+
import_fs_extra2.default.writeJSONSync(workspace.paths.packageJson, workspacePackageJson, {
|
|
251
|
+
spaces: 2
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// src/managers/pnpm.ts
|
|
257
|
+
async function detect(args) {
|
|
258
|
+
const lockFile = import_path3.default.join(args.workspaceRoot, "pnpm-lock.yaml");
|
|
259
|
+
const workspaceFile = import_path3.default.join(args.workspaceRoot, "pnpm-workspace.yaml");
|
|
260
|
+
const packageManager = getWorkspacePackageManager({
|
|
261
|
+
workspaceRoot: args.workspaceRoot
|
|
262
|
+
});
|
|
263
|
+
return import_fs_extra3.default.existsSync(lockFile) || import_fs_extra3.default.existsSync(workspaceFile) || packageManager === "pnpm";
|
|
264
|
+
}
|
|
265
|
+
async function read(args) {
|
|
266
|
+
const isPnpm = await detect(args);
|
|
267
|
+
if (!isPnpm) {
|
|
268
|
+
throw new ConvertError("Not a pnpm project");
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
name: getWorkspaceName(args),
|
|
272
|
+
packageManager: "pnpm",
|
|
273
|
+
paths: expandPaths({
|
|
274
|
+
root: args.workspaceRoot,
|
|
275
|
+
lockFile: "pnpm-lock.yaml",
|
|
276
|
+
workspaceConfig: "pnpm-workspace.yaml"
|
|
277
|
+
}),
|
|
278
|
+
workspaceData: {
|
|
279
|
+
globs: getPnpmWorkspaces(args),
|
|
280
|
+
workspaces: expandWorkspaces({
|
|
281
|
+
workspaceGlobs: getPnpmWorkspaces(args),
|
|
282
|
+
...args
|
|
283
|
+
})
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
async function create(args) {
|
|
288
|
+
const { project, to, logger, options } = args;
|
|
289
|
+
const hasWorkspaces = project.workspaceData.globs.length > 0;
|
|
290
|
+
logger.mainStep(`Creating ${project.packageManager}${hasWorkspaces ? "workspaces" : ""}`);
|
|
291
|
+
const packageJson = getPackageJson({ workspaceRoot: project.paths.root });
|
|
292
|
+
logger.rootHeader();
|
|
293
|
+
packageJson.packageManager = `${to.name}@${to.version}`;
|
|
294
|
+
logger.rootStep(`adding "packageManager" field to ${project.name} root "package.json"`);
|
|
295
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
296
|
+
import_fs_extra3.default.writeJSONSync(project.paths.packageJson, packageJson, { spaces: 2 });
|
|
297
|
+
if (hasWorkspaces) {
|
|
298
|
+
logger.rootStep(`adding "pnpm-workspace.yaml"`);
|
|
299
|
+
import_fs_extra3.default.writeFileSync(import_path3.default.join(project.paths.root, "pnpm-workspace.yaml"), `packages:
|
|
300
|
+
${project.workspaceData.globs.map((w) => ` - "${w}"`).join("\n")}`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (hasWorkspaces) {
|
|
304
|
+
updateDependencies({
|
|
305
|
+
workspace: { name: "root", paths: project.paths },
|
|
306
|
+
project,
|
|
307
|
+
to,
|
|
308
|
+
logger,
|
|
309
|
+
options
|
|
310
|
+
});
|
|
311
|
+
logger.workspaceHeader();
|
|
312
|
+
project.workspaceData.workspaces.forEach((workspace) => updateDependencies({ workspace, project, to, logger, options }));
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
async function remove(args) {
|
|
316
|
+
const { project, logger, options } = args;
|
|
317
|
+
const hasWorkspaces = project.workspaceData.globs.length > 0;
|
|
318
|
+
logger.mainStep(`Removing ${project.packageManager}${hasWorkspaces ? "workspaces" : ""}`);
|
|
319
|
+
const packageJson = getPackageJson({ workspaceRoot: project.paths.root });
|
|
320
|
+
if (project.paths.workspaceConfig && hasWorkspaces) {
|
|
321
|
+
logger.subStep(`removing "pnpm-workspace.yaml"`);
|
|
322
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
323
|
+
import_fs_extra3.default.rmSync(project.paths.workspaceConfig, { force: true });
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
logger.subStep(`removing "packageManager" field in ${project.name} root "package.json"`);
|
|
327
|
+
delete packageJson.packageManager;
|
|
328
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
329
|
+
import_fs_extra3.default.writeJSONSync(project.paths.packageJson, packageJson, { spaces: 2 });
|
|
330
|
+
const allModulesDirs = [
|
|
331
|
+
project.paths.nodeModules,
|
|
332
|
+
...project.workspaceData.workspaces.map((w) => w.paths.nodeModules)
|
|
333
|
+
];
|
|
334
|
+
try {
|
|
335
|
+
logger.subStep(`removing "node_modules"`);
|
|
336
|
+
await Promise.all(allModulesDirs.map((dir) => import_fs_extra3.default.rm(dir, { recursive: true, force: true })));
|
|
337
|
+
} catch (err) {
|
|
338
|
+
throw new ConvertError("Failed to remove node_modules");
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
async function clean(args) {
|
|
343
|
+
const { project, logger, options } = args;
|
|
344
|
+
logger.subStep(`removing ${import_path3.default.relative(project.paths.root, project.paths.lockfile)}`);
|
|
345
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
346
|
+
import_fs_extra3.default.rmSync(project.paths.lockfile, { force: true });
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
async function convertLock(args) {
|
|
350
|
+
const { project, logger, options } = args;
|
|
351
|
+
if (project.packageManager !== "pnpm") {
|
|
352
|
+
logger.subStep(`converting ${import_path3.default.relative(project.paths.root, project.paths.lockfile)} to pnpm-lock.yaml`);
|
|
353
|
+
if (!(options == null ? void 0 : options.dry) && import_fs_extra3.default.existsSync(project.paths.lockfile)) {
|
|
354
|
+
try {
|
|
355
|
+
await (0, import_execa.default)("pnpm", ["import"], {
|
|
356
|
+
stdio: "ignore",
|
|
357
|
+
cwd: project.paths.root
|
|
358
|
+
});
|
|
359
|
+
} finally {
|
|
360
|
+
import_fs_extra3.default.rmSync(project.paths.lockfile, { force: true });
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
var pnpm = {
|
|
366
|
+
detect,
|
|
367
|
+
read,
|
|
368
|
+
create,
|
|
369
|
+
remove,
|
|
370
|
+
clean,
|
|
371
|
+
convertLock
|
|
372
|
+
};
|
|
373
|
+
var pnpm_default = pnpm;
|
|
374
|
+
|
|
375
|
+
// src/managers/npm.ts
|
|
376
|
+
var import_fs_extra4 = __toESM(require("fs-extra"));
|
|
377
|
+
var import_path4 = __toESM(require("path"));
|
|
378
|
+
async function detect2(args) {
|
|
379
|
+
const lockFile = import_path4.default.join(args.workspaceRoot, "package-lock.json");
|
|
380
|
+
const packageManager = getWorkspacePackageManager({
|
|
381
|
+
workspaceRoot: args.workspaceRoot
|
|
382
|
+
});
|
|
383
|
+
return import_fs_extra4.default.existsSync(lockFile) || packageManager === "npm";
|
|
384
|
+
}
|
|
385
|
+
async function read2(args) {
|
|
386
|
+
const isNpm = await detect2(args);
|
|
387
|
+
if (!isNpm) {
|
|
388
|
+
throw new ConvertError("Not an npm project");
|
|
389
|
+
}
|
|
390
|
+
const packageJson = getPackageJson(args);
|
|
391
|
+
return {
|
|
392
|
+
name: getWorkspaceName(args),
|
|
393
|
+
packageManager: "npm",
|
|
394
|
+
paths: expandPaths({
|
|
395
|
+
root: args.workspaceRoot,
|
|
396
|
+
lockFile: "package-lock.json"
|
|
397
|
+
}),
|
|
398
|
+
workspaceData: {
|
|
399
|
+
globs: packageJson.workspaces || [],
|
|
400
|
+
workspaces: expandWorkspaces({
|
|
401
|
+
workspaceGlobs: packageJson.workspaces,
|
|
402
|
+
...args
|
|
403
|
+
})
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
async function create2(args) {
|
|
408
|
+
const { project, options, to, logger } = args;
|
|
409
|
+
const hasWorkspaces = project.workspaceData.globs.length > 0;
|
|
410
|
+
logger.mainStep(`Creating ${project.packageManager}${hasWorkspaces ? "workspaces" : ""}`);
|
|
411
|
+
const packageJson = getPackageJson({ workspaceRoot: project.paths.root });
|
|
412
|
+
logger.rootHeader();
|
|
413
|
+
logger.rootStep(`adding "packageManager" field to ${project.name} root "package.json"`);
|
|
414
|
+
packageJson.packageManager = `${to.name}@${to.version}`;
|
|
415
|
+
if (hasWorkspaces) {
|
|
416
|
+
logger.rootStep(`adding "workspaces" field to ${project.name} root "package.json"`);
|
|
417
|
+
packageJson.workspaces = project.workspaceData.globs;
|
|
418
|
+
updateDependencies({
|
|
419
|
+
workspace: { name: "root", paths: project.paths },
|
|
420
|
+
project,
|
|
421
|
+
to,
|
|
422
|
+
logger,
|
|
423
|
+
options
|
|
424
|
+
});
|
|
425
|
+
logger.workspaceHeader();
|
|
426
|
+
project.workspaceData.workspaces.forEach((workspace) => updateDependencies({ workspace, project, to, logger, options }));
|
|
427
|
+
}
|
|
428
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
429
|
+
import_fs_extra4.default.writeJSONSync(project.paths.packageJson, packageJson, { spaces: 2 });
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
async function remove2(args) {
|
|
433
|
+
const { project, logger, options } = args;
|
|
434
|
+
const hasWorkspaces = project.workspaceData.globs.length > 0;
|
|
435
|
+
logger.mainStep(`Creating ${project.packageManager}${hasWorkspaces ? "workspaces" : ""}`);
|
|
436
|
+
const packageJson = getPackageJson({ workspaceRoot: project.paths.root });
|
|
437
|
+
if (hasWorkspaces) {
|
|
438
|
+
logger.subStep(`removing "workspaces" field in ${project.name} root "package.json"`);
|
|
439
|
+
delete packageJson.workspaces;
|
|
440
|
+
}
|
|
441
|
+
logger.subStep(`removing "packageManager" field in ${project.name} root "package.json"`);
|
|
442
|
+
delete packageJson.packageManager;
|
|
443
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
444
|
+
import_fs_extra4.default.writeJSONSync(project.paths.packageJson, packageJson, { spaces: 2 });
|
|
445
|
+
const allModulesDirs = [
|
|
446
|
+
project.paths.nodeModules,
|
|
447
|
+
...project.workspaceData.workspaces.map((w) => w.paths.nodeModules)
|
|
448
|
+
];
|
|
449
|
+
try {
|
|
450
|
+
logger.subStep(`removing "node_modules"`);
|
|
451
|
+
await Promise.all(allModulesDirs.map((dir) => import_fs_extra4.default.rm(dir, { recursive: true, force: true })));
|
|
452
|
+
} catch (err) {
|
|
453
|
+
throw new ConvertError("Failed to remove node_modules");
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
async function clean2(args) {
|
|
458
|
+
const { project, logger, options } = args;
|
|
459
|
+
logger.subStep(`removing ${import_path4.default.relative(project.paths.root, project.paths.lockfile)}`);
|
|
460
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
461
|
+
import_fs_extra4.default.rmSync(project.paths.lockfile, { force: true });
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
async function convertLock2(args) {
|
|
465
|
+
const { project, options } = args;
|
|
466
|
+
if (project.packageManager !== "npm") {
|
|
467
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
468
|
+
import_fs_extra4.default.rmSync(project.paths.lockfile, { force: true });
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
var npm = {
|
|
473
|
+
detect: detect2,
|
|
474
|
+
read: read2,
|
|
475
|
+
create: create2,
|
|
476
|
+
remove: remove2,
|
|
477
|
+
clean: clean2,
|
|
478
|
+
convertLock: convertLock2
|
|
479
|
+
};
|
|
480
|
+
var npm_default = npm;
|
|
481
|
+
|
|
482
|
+
// src/managers/yarn.ts
|
|
483
|
+
var import_fs_extra5 = __toESM(require("fs-extra"));
|
|
484
|
+
var import_path5 = __toESM(require("path"));
|
|
485
|
+
async function detect3(args) {
|
|
486
|
+
const lockFile = import_path5.default.join(args.workspaceRoot, "yarn.lock");
|
|
487
|
+
const packageManager = getWorkspacePackageManager({
|
|
488
|
+
workspaceRoot: args.workspaceRoot
|
|
489
|
+
});
|
|
490
|
+
return import_fs_extra5.default.existsSync(lockFile) || packageManager === "yarn";
|
|
491
|
+
}
|
|
492
|
+
async function read3(args) {
|
|
493
|
+
const isYarn = await detect3(args);
|
|
494
|
+
if (!isYarn) {
|
|
495
|
+
throw new ConvertError("Not a yarn project");
|
|
496
|
+
}
|
|
497
|
+
const packageJson = getPackageJson(args);
|
|
498
|
+
return {
|
|
499
|
+
name: getWorkspaceName(args),
|
|
500
|
+
packageManager: "yarn",
|
|
501
|
+
paths: expandPaths({
|
|
502
|
+
root: args.workspaceRoot,
|
|
503
|
+
lockFile: "yarn.lock"
|
|
504
|
+
}),
|
|
505
|
+
workspaceData: {
|
|
506
|
+
globs: packageJson.workspaces || [],
|
|
507
|
+
workspaces: expandWorkspaces({
|
|
508
|
+
workspaceGlobs: packageJson.workspaces,
|
|
509
|
+
...args
|
|
510
|
+
})
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
async function create3(args) {
|
|
515
|
+
const { project, to, logger, options } = args;
|
|
516
|
+
const hasWorkspaces = project.workspaceData.globs.length > 0;
|
|
517
|
+
logger.mainStep(`Creating ${project.packageManager}${hasWorkspaces ? "workspaces" : ""}`);
|
|
518
|
+
const packageJson = getPackageJson({ workspaceRoot: project.paths.root });
|
|
519
|
+
logger.rootHeader();
|
|
520
|
+
logger.rootStep(`adding "packageManager" field to ${import_path5.default.relative(project.paths.root, project.paths.packageJson)}`);
|
|
521
|
+
packageJson.packageManager = `${to.name}@${to.version}`;
|
|
522
|
+
if (hasWorkspaces) {
|
|
523
|
+
logger.rootStep(`adding "workspaces" field to ${import_path5.default.relative(project.paths.root, project.paths.packageJson)}`);
|
|
524
|
+
packageJson.workspaces = project.workspaceData.globs;
|
|
525
|
+
updateDependencies({
|
|
526
|
+
workspace: { name: "root", paths: project.paths },
|
|
527
|
+
project,
|
|
528
|
+
to,
|
|
529
|
+
logger,
|
|
530
|
+
options
|
|
531
|
+
});
|
|
532
|
+
logger.workspaceHeader();
|
|
533
|
+
project.workspaceData.workspaces.forEach((workspace) => updateDependencies({ workspace, project, to, logger, options }));
|
|
534
|
+
}
|
|
535
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
536
|
+
import_fs_extra5.default.writeJSONSync(project.paths.packageJson, packageJson, { spaces: 2 });
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
async function remove3(args) {
|
|
540
|
+
const { project, logger, options } = args;
|
|
541
|
+
const hasWorkspaces = project.workspaceData.globs.length > 0;
|
|
542
|
+
logger.mainStep(`Removing ${project.packageManager}${hasWorkspaces ? "workspaces" : ""}`);
|
|
543
|
+
const packageJson = getPackageJson({ workspaceRoot: project.paths.root });
|
|
544
|
+
if (hasWorkspaces) {
|
|
545
|
+
logger.subStep(`removing "workspaces" field in ${project.name} root "package.json"`);
|
|
546
|
+
delete packageJson.workspaces;
|
|
547
|
+
}
|
|
548
|
+
logger.subStep(`removing "packageManager" field in ${project.name} root "package.json"`);
|
|
549
|
+
delete packageJson.packageManager;
|
|
550
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
551
|
+
import_fs_extra5.default.writeJSONSync(project.paths.packageJson, packageJson, { spaces: 2 });
|
|
552
|
+
const allModulesDirs = [
|
|
553
|
+
project.paths.nodeModules,
|
|
554
|
+
...project.workspaceData.workspaces.map((w) => w.paths.nodeModules)
|
|
555
|
+
];
|
|
556
|
+
try {
|
|
557
|
+
logger.subStep(`removing "node_modules"`);
|
|
558
|
+
await Promise.all(allModulesDirs.map((dir) => import_fs_extra5.default.rm(dir, { recursive: true, force: true })));
|
|
559
|
+
} catch (err) {
|
|
560
|
+
throw new ConvertError("Failed to remove node_modules");
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
async function clean3(args) {
|
|
565
|
+
const { project, logger, options } = args;
|
|
566
|
+
logger.subStep(`removing ${import_path5.default.relative(project.paths.root, project.paths.lockfile)}`);
|
|
567
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
568
|
+
import_fs_extra5.default.rmSync(project.paths.lockfile, { force: true });
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
async function convertLock3(args) {
|
|
572
|
+
const { project, options } = args;
|
|
573
|
+
if (project.packageManager !== "yarn") {
|
|
574
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
575
|
+
import_fs_extra5.default.rmSync(project.paths.lockfile, { force: true });
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
var yarn = {
|
|
580
|
+
detect: detect3,
|
|
581
|
+
read: read3,
|
|
582
|
+
create: create3,
|
|
583
|
+
remove: remove3,
|
|
584
|
+
clean: clean3,
|
|
585
|
+
convertLock: convertLock3
|
|
586
|
+
};
|
|
587
|
+
var yarn_default = yarn;
|
|
588
|
+
|
|
589
|
+
// src/managers/index.ts
|
|
590
|
+
var MANAGERS = {
|
|
591
|
+
pnpm: pnpm_default,
|
|
592
|
+
yarn: yarn_default,
|
|
593
|
+
npm: npm_default
|
|
594
|
+
};
|
|
595
|
+
var managers_default = MANAGERS;
|
|
596
|
+
|
|
597
|
+
// src/getWorkspaceDetails.ts
|
|
598
|
+
async function getWorkspaceDetails({
|
|
599
|
+
root
|
|
600
|
+
}) {
|
|
601
|
+
const { exists, absolute: workspaceRoot } = directoryInfo({
|
|
602
|
+
directory: root
|
|
603
|
+
});
|
|
604
|
+
if (!exists) {
|
|
605
|
+
throw new ConvertError(`Could not find directory at ${workspaceRoot}. Ensure the directory exists.`);
|
|
606
|
+
}
|
|
607
|
+
for (const { detect: detect4, read: read4 } of Object.values(managers_default)) {
|
|
608
|
+
if (await detect4({ workspaceRoot })) {
|
|
609
|
+
return read4({ workspaceRoot });
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
throw new ConvertError("Could not determine workspace manager. Add `packageManager` to `package.json` or ensure a lockfile is present.");
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// src/convert.ts
|
|
616
|
+
var import_chalk2 = __toESM(require("chalk"));
|
|
617
|
+
|
|
618
|
+
// src/install.ts
|
|
619
|
+
var import_execa2 = __toESM(require("execa"));
|
|
620
|
+
var import_ora = __toESM(require("ora"));
|
|
621
|
+
var import_semver = require("semver");
|
|
622
|
+
var PACKAGE_MANAGERS = {
|
|
623
|
+
npm: [
|
|
624
|
+
{
|
|
625
|
+
name: "npm",
|
|
626
|
+
template: "npm",
|
|
627
|
+
command: "npm",
|
|
628
|
+
installArgs: ["install"],
|
|
629
|
+
version: "latest",
|
|
630
|
+
executable: "npx",
|
|
631
|
+
semver: "*"
|
|
632
|
+
}
|
|
633
|
+
],
|
|
634
|
+
pnpm: [
|
|
635
|
+
{
|
|
636
|
+
name: "pnpm6",
|
|
637
|
+
template: "pnpm",
|
|
638
|
+
command: "pnpm",
|
|
639
|
+
installArgs: ["install"],
|
|
640
|
+
version: "latest-6",
|
|
641
|
+
executable: "pnpx",
|
|
642
|
+
semver: "6.x"
|
|
643
|
+
},
|
|
644
|
+
{
|
|
645
|
+
name: "pnpm",
|
|
646
|
+
template: "pnpm",
|
|
647
|
+
command: "pnpm",
|
|
648
|
+
installArgs: ["install"],
|
|
649
|
+
version: "latest",
|
|
650
|
+
executable: "pnpm dlx",
|
|
651
|
+
semver: ">=7"
|
|
652
|
+
}
|
|
653
|
+
],
|
|
654
|
+
yarn: [
|
|
655
|
+
{
|
|
656
|
+
name: "yarn",
|
|
657
|
+
template: "yarn",
|
|
658
|
+
command: "yarn",
|
|
659
|
+
installArgs: ["install"],
|
|
660
|
+
version: "1.x",
|
|
661
|
+
executable: "npx",
|
|
662
|
+
semver: "<2"
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
name: "berry",
|
|
666
|
+
template: "berry",
|
|
667
|
+
command: "yarn",
|
|
668
|
+
installArgs: ["install", "--no-immutable"],
|
|
669
|
+
version: "stable",
|
|
670
|
+
executable: "yarn dlx",
|
|
671
|
+
semver: ">=2"
|
|
672
|
+
}
|
|
673
|
+
]
|
|
674
|
+
};
|
|
675
|
+
async function install(args) {
|
|
676
|
+
const { to, logger, options } = args;
|
|
677
|
+
let packageManager = PACKAGE_MANAGERS[to.name].find((manager) => (0, import_semver.satisfies)(to.version, manager.semver));
|
|
678
|
+
if (!packageManager) {
|
|
679
|
+
throw new ConvertError("Unsupported package manager version.");
|
|
680
|
+
}
|
|
681
|
+
logger.subStep(`running "${packageManager.command} ${packageManager.installArgs}"`);
|
|
682
|
+
if (!(options == null ? void 0 : options.dry)) {
|
|
683
|
+
let spinner;
|
|
684
|
+
if (options == null ? void 0 : options.interactive) {
|
|
685
|
+
spinner = (0, import_ora.default)({
|
|
686
|
+
text: "Installing dependencies...",
|
|
687
|
+
spinner: {
|
|
688
|
+
frames: logger.installerFrames()
|
|
689
|
+
}
|
|
690
|
+
}).start();
|
|
691
|
+
}
|
|
692
|
+
try {
|
|
693
|
+
await (0, import_execa2.default)(packageManager.command, packageManager.installArgs, {
|
|
694
|
+
cwd: args.project.paths.root
|
|
695
|
+
});
|
|
696
|
+
logger.subStep(`dependencies installed`);
|
|
697
|
+
} catch (err) {
|
|
698
|
+
logger.subStepFailure(`failed to install dependencies`);
|
|
699
|
+
throw err;
|
|
700
|
+
} finally {
|
|
701
|
+
if (spinner) {
|
|
702
|
+
spinner.stop();
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
var install_default = install;
|
|
708
|
+
|
|
709
|
+
// src/convert.ts
|
|
710
|
+
async function convert({
|
|
711
|
+
project,
|
|
712
|
+
to,
|
|
713
|
+
logger,
|
|
714
|
+
options
|
|
715
|
+
}) {
|
|
716
|
+
logger.header(`Converting project from ${project.packageManager} to ${to.name}.`);
|
|
717
|
+
if (project.packageManager == to.name) {
|
|
718
|
+
throw new ConvertError("You are already using this package manager");
|
|
719
|
+
}
|
|
720
|
+
await managers_default[project.packageManager].remove({
|
|
721
|
+
project,
|
|
722
|
+
to,
|
|
723
|
+
logger,
|
|
724
|
+
options
|
|
725
|
+
});
|
|
726
|
+
await managers_default[to.name].create({ project, to, logger, options });
|
|
727
|
+
logger.mainStep("Installing dependencies");
|
|
728
|
+
if (!(options == null ? void 0 : options.skipInstall)) {
|
|
729
|
+
await managers_default[to.name].convertLock({ project, logger, options });
|
|
730
|
+
await install_default({ project, to, logger, options });
|
|
731
|
+
} else {
|
|
732
|
+
logger.subStep(import_chalk2.default.yellow("Skipping install"));
|
|
733
|
+
}
|
|
734
|
+
logger.mainStep(`Cleaning up ${project.packageManager} workspaces`);
|
|
735
|
+
await managers_default[project.packageManager].clean({ project, logger });
|
|
736
|
+
}
|
|
737
|
+
var convert_default = convert;
|
|
738
|
+
|
|
739
|
+
// src/logger.ts
|
|
740
|
+
var import_chalk3 = __toESM(require("chalk"));
|
|
741
|
+
var import_gradient_string = __toESM(require("gradient-string"));
|
|
742
|
+
var INDENTATION = 2;
|
|
743
|
+
var Logger = class {
|
|
744
|
+
constructor({
|
|
745
|
+
interactive,
|
|
746
|
+
dry
|
|
747
|
+
} = {}) {
|
|
748
|
+
this.interactive = interactive != null ? interactive : true;
|
|
749
|
+
this.dry = dry != null ? dry : false;
|
|
750
|
+
this.step = 1;
|
|
751
|
+
}
|
|
752
|
+
logger(...args) {
|
|
753
|
+
if (this.interactive) {
|
|
754
|
+
console.log(...args);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
indented(level, ...args) {
|
|
758
|
+
this.logger(" ".repeat(INDENTATION * level), ...args);
|
|
759
|
+
}
|
|
760
|
+
header(title) {
|
|
761
|
+
this.blankLine();
|
|
762
|
+
this.logger(import_chalk3.default.bold(title));
|
|
763
|
+
}
|
|
764
|
+
installerFrames() {
|
|
765
|
+
const prefix = `${" ".repeat(INDENTATION)} - ${this.dry ? import_chalk3.default.yellow("SKIPPED | ") : import_chalk3.default.green("OK | ")}`;
|
|
766
|
+
return [`${prefix} `, `${prefix}> `, `${prefix}>> `, `${prefix}>>>`];
|
|
767
|
+
}
|
|
768
|
+
gradient(text) {
|
|
769
|
+
const turboGradient = (0, import_gradient_string.default)("#0099F7", "#F11712");
|
|
770
|
+
return turboGradient(text.toString());
|
|
771
|
+
}
|
|
772
|
+
hero() {
|
|
773
|
+
this.logger(import_chalk3.default.bold(this.gradient(`
|
|
774
|
+
>>> TURBOREPO
|
|
775
|
+
`)));
|
|
776
|
+
}
|
|
777
|
+
info(...args) {
|
|
778
|
+
this.logger(...args);
|
|
779
|
+
}
|
|
780
|
+
mainStep(title) {
|
|
781
|
+
this.blankLine();
|
|
782
|
+
this.logger(`${this.step}. ${import_chalk3.default.underline(title)}`);
|
|
783
|
+
this.step += 1;
|
|
784
|
+
}
|
|
785
|
+
subStep(...args) {
|
|
786
|
+
this.logger(" ".repeat(INDENTATION), `-`, this.dry ? import_chalk3.default.yellow("SKIPPED |") : import_chalk3.default.green("OK |"), ...args);
|
|
787
|
+
}
|
|
788
|
+
subStepFailure(...args) {
|
|
789
|
+
this.logger(" ".repeat(INDENTATION), `-`, import_chalk3.default.red("ERROR |"), ...args);
|
|
790
|
+
}
|
|
791
|
+
rootHeader() {
|
|
792
|
+
this.blankLine();
|
|
793
|
+
this.indented(2, "Root:");
|
|
794
|
+
}
|
|
795
|
+
rootStep(...args) {
|
|
796
|
+
this.logger(" ".repeat(INDENTATION * 3), `-`, this.dry ? import_chalk3.default.yellow("SKIPPED |") : import_chalk3.default.green("OK |"), ...args);
|
|
797
|
+
}
|
|
798
|
+
workspaceHeader() {
|
|
799
|
+
this.blankLine();
|
|
800
|
+
this.indented(2, "Workspaces:");
|
|
801
|
+
}
|
|
802
|
+
workspaceStep(...args) {
|
|
803
|
+
this.logger(" ".repeat(INDENTATION * 3), `-`, this.dry ? import_chalk3.default.yellow("SKIPPED |") : import_chalk3.default.green("OK |"), ...args);
|
|
804
|
+
}
|
|
805
|
+
blankLine() {
|
|
806
|
+
this.logger();
|
|
807
|
+
}
|
|
808
|
+
error(...args) {
|
|
809
|
+
console.error(...args);
|
|
810
|
+
}
|
|
811
|
+
};
|
|
812
|
+
|
|
813
|
+
// src/index.ts
|
|
814
|
+
async function convertMonorepo({
|
|
815
|
+
root,
|
|
816
|
+
to,
|
|
817
|
+
options
|
|
818
|
+
}) {
|
|
819
|
+
const logger = new Logger({ ...options, interactive: false });
|
|
820
|
+
const [project, availablePackageManagers] = await Promise.all([
|
|
821
|
+
getWorkspaceDetails({ root }),
|
|
822
|
+
(0, import_turbo_utils.getAvailablePackageManagers)()
|
|
823
|
+
]);
|
|
824
|
+
await convert_default({
|
|
825
|
+
project,
|
|
826
|
+
to: {
|
|
827
|
+
name: to,
|
|
828
|
+
version: availablePackageManagers[to].version
|
|
829
|
+
},
|
|
830
|
+
logger,
|
|
831
|
+
options
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
835
|
+
0 && (module.exports = {
|
|
836
|
+
MANAGERS,
|
|
837
|
+
convertMonorepo,
|
|
838
|
+
getWorkspaceDetails,
|
|
839
|
+
install
|
|
840
|
+
});
|