isolate-package 1.4.0 → 1.4.1-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,21 +1,980 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- isolate
4
- } from "./chunk-PXDYN4JI.mjs";
5
2
 
6
3
  // src/isolate-bin.ts
7
- import console from "node:console";
4
+ import console2 from "node:console";
8
5
  import sourceMaps from "source-map-support";
6
+
7
+ // src/isolate.ts
8
+ import fs15 from "fs-extra";
9
+ import assert6 from "node:assert";
10
+ import path15 from "node:path";
11
+
12
+ // src/utils/filter-object-undefined.ts
13
+ function filterObjectUndefined(object) {
14
+ return Object.fromEntries(
15
+ Object.entries(object).filter(([_, value]) => value !== void 0)
16
+ );
17
+ }
18
+
19
+ // src/utils/get-dirname.ts
20
+ import { fileURLToPath } from "url";
21
+ function getDirname(importMetaUrl) {
22
+ return fileURLToPath(new URL(".", importMetaUrl));
23
+ }
24
+
25
+ // src/utils/get-error-message.ts
26
+ function getErrorMessage(error) {
27
+ return toErrorWithMessage(error).message;
28
+ }
29
+ function isErrorWithMessage(error) {
30
+ return typeof error === "object" && error !== null && "message" in error;
31
+ }
32
+ function toErrorWithMessage(maybeError) {
33
+ if (isErrorWithMessage(maybeError))
34
+ return maybeError;
35
+ try {
36
+ return new Error(JSON.stringify(maybeError));
37
+ } catch {
38
+ return new Error(String(maybeError));
39
+ }
40
+ }
41
+
42
+ // src/utils/get-relative-path.ts
43
+ function getRootRelativePath(path16, rootPath) {
44
+ const strippedPath = path16.replace(rootPath, "");
45
+ return strippedPath.startsWith("/") ? `(root)${strippedPath}` : `(root)/${strippedPath}`;
46
+ }
47
+ function getIsolateRelativePath(path16, isolatePath) {
48
+ const strippedPath = path16.replace(isolatePath, "");
49
+ return strippedPath.startsWith("/") ? `(isolate)${strippedPath}` : `(isolate)/${strippedPath}`;
50
+ }
51
+
52
+ // src/utils/inspect-value.ts
53
+ import { inspect } from "node:util";
54
+ function inspectValue(value) {
55
+ return inspect(value, false, 4, true);
56
+ }
57
+
58
+ // src/utils/is-present.ts
59
+ function isDefined(t) {
60
+ return t !== void 0;
61
+ }
62
+
63
+ // src/utils/json.ts
64
+ import fs from "fs-extra";
65
+ import stripJsonComments from "strip-json-comments";
66
+ function readTypedJsonSync(filePath) {
67
+ try {
68
+ const rawContent = fs.readFileSync(filePath, "utf-8");
69
+ const data = JSON.parse(stripJsonComments(rawContent));
70
+ return data;
71
+ } catch (err) {
72
+ throw new Error(
73
+ `Failed to read JSON from ${filePath}: ${getErrorMessage(err)}`
74
+ );
75
+ }
76
+ }
77
+ async function readTypedJson(filePath) {
78
+ try {
79
+ const rawContent = await fs.readFile(filePath, "utf-8");
80
+ const data = JSON.parse(rawContent);
81
+ return data;
82
+ } catch (err) {
83
+ throw new Error(
84
+ `Failed to read JSON from ${filePath}: ${getErrorMessage(err)}`
85
+ );
86
+ }
87
+ }
88
+
89
+ // src/utils/logger.ts
90
+ import chalk from "chalk";
91
+ var _loggerHandlers = {
92
+ debug(...args) {
93
+ console.log(chalk.blue("debug"), ...args);
94
+ },
95
+ info(...args) {
96
+ console.log(chalk.green("info"), ...args);
97
+ },
98
+ warn(...args) {
99
+ console.log(chalk.yellow("warning"), ...args);
100
+ },
101
+ error(...args) {
102
+ console.log(chalk.red("error"), ...args);
103
+ }
104
+ };
105
+ var _logger = {
106
+ debug(...args) {
107
+ if (_logLevel === "debug") {
108
+ _loggerHandlers.debug(...args);
109
+ }
110
+ },
111
+ info(...args) {
112
+ if (_logLevel === "debug" || _logLevel === "info") {
113
+ _loggerHandlers.info(...args);
114
+ }
115
+ },
116
+ warn(...args) {
117
+ if (_logLevel === "debug" || _logLevel === "info" || _logLevel === "warn") {
118
+ _loggerHandlers.warn(...args);
119
+ }
120
+ },
121
+ error(...args) {
122
+ _loggerHandlers.error(...args);
123
+ }
124
+ };
125
+ var _logLevel = "info";
126
+ function setLogger(logger) {
127
+ _loggerHandlers = logger;
128
+ return _logger;
129
+ }
130
+ function setLogLevel(logLevel) {
131
+ _logLevel = logLevel;
132
+ return _logger;
133
+ }
134
+ function useLogger() {
135
+ return _logger;
136
+ }
137
+
138
+ // src/utils/pack.ts
139
+ import fs2 from "fs-extra";
140
+ import { exec } from "node:child_process";
141
+ import path from "node:path";
142
+ async function pack(srcDir, dstDir, usePnpmPack = false) {
143
+ const execOptions = {
144
+ maxBuffer: 10 * 1024 * 1024
145
+ };
146
+ const log = useLogger();
147
+ const previousCwd = process.cwd();
148
+ process.chdir(srcDir);
149
+ const stdout = usePnpmPack ? await new Promise((resolve, reject) => {
150
+ exec(
151
+ `pnpm pack --pack-destination ${dstDir}`,
152
+ execOptions,
153
+ (err, stdout2, stderr) => {
154
+ if (err) {
155
+ log.error(stderr);
156
+ return reject(err);
157
+ }
158
+ resolve(stdout2);
159
+ }
160
+ );
161
+ }) : await new Promise((resolve, reject) => {
162
+ exec(
163
+ `npm pack --pack-destination ${dstDir}`,
164
+ execOptions,
165
+ (err, stdout2) => {
166
+ if (err) {
167
+ return reject(err);
168
+ }
169
+ resolve(stdout2);
170
+ }
171
+ );
172
+ });
173
+ const fileName = path.basename(stdout.trim());
174
+ const filePath = path.join(dstDir, fileName);
175
+ if (!fs2.existsSync(filePath)) {
176
+ log.error(
177
+ `The response from pack could not be resolved to an existing file: ${filePath}`
178
+ );
179
+ } else {
180
+ log.debug(`Packed (temp)/${fileName}`);
181
+ }
182
+ process.chdir(previousCwd);
183
+ return filePath;
184
+ }
185
+
186
+ // src/utils/unpack.ts
187
+ import fs3 from "fs-extra";
188
+ import tar from "tar-fs";
189
+ import { createGunzip } from "zlib";
190
+ async function unpack(filePath, unpackDir) {
191
+ await new Promise((resolve, reject) => {
192
+ fs3.createReadStream(filePath).pipe(createGunzip()).pipe(tar.extract(unpackDir)).on("finish", () => resolve()).on("error", (err) => reject(err));
193
+ });
194
+ }
195
+
196
+ // src/utils/yaml.ts
197
+ import fs4 from "fs-extra";
198
+ import yaml from "yaml";
199
+ function readTypedYamlSync(filePath) {
200
+ try {
201
+ const rawContent = fs4.readFileSync(filePath, "utf-8");
202
+ const data = yaml.parse(rawContent);
203
+ return data;
204
+ } catch (err) {
205
+ throw new Error(
206
+ `Failed to read YAML from ${filePath}: ${getErrorMessage(err)}`
207
+ );
208
+ }
209
+ }
210
+
211
+ // src/helpers/adapt-internal-package-manifests.ts
212
+ import fs9 from "fs-extra";
213
+ import path8 from "node:path";
214
+ import { omit as omit2 } from "ramda";
215
+
216
+ // src/helpers/adapt-manifest-internal-deps.ts
217
+ import { omit } from "ramda";
218
+
219
+ // src/helpers/patch-internal-entries.ts
220
+ import path2 from "node:path";
221
+ function patchInternalEntries(dependencies, packagesRegistry, parentRootRelativeDir) {
222
+ const log = useLogger();
223
+ const allWorkspacePackageNames = Object.keys(packagesRegistry);
224
+ return Object.fromEntries(
225
+ Object.entries(dependencies).map(([key, value]) => {
226
+ if (allWorkspacePackageNames.includes(key)) {
227
+ const def = packagesRegistry[key];
228
+ const relativePath = parentRootRelativeDir ? path2.relative(parentRootRelativeDir, `./${def.rootRelativeDir}`) : `./${def.rootRelativeDir}`;
229
+ const linkPath = `file:${relativePath}`;
230
+ log.debug(`Linking dependency ${key} to ${linkPath}`);
231
+ return [key, linkPath];
232
+ } else {
233
+ return [key, value];
234
+ }
235
+ })
236
+ );
237
+ }
238
+
239
+ // src/helpers/adapt-manifest-internal-deps.ts
240
+ function adaptManifestInternalDeps({
241
+ manifest,
242
+ packagesRegistry,
243
+ parentRootRelativeDir
244
+ }, opts = {}) {
245
+ return Object.assign(
246
+ omit(["devDependencies"], manifest),
247
+ filterObjectUndefined({
248
+ dependencies: manifest.dependencies ? patchInternalEntries(
249
+ manifest.dependencies,
250
+ packagesRegistry,
251
+ parentRootRelativeDir
252
+ ) : void 0,
253
+ devDependencies: opts.includeDevDependencies && manifest.devDependencies ? patchInternalEntries(
254
+ manifest.devDependencies,
255
+ packagesRegistry,
256
+ parentRootRelativeDir
257
+ ) : void 0
258
+ })
259
+ );
260
+ }
261
+
262
+ // src/helpers/config.ts
263
+ import fs5 from "fs-extra";
264
+ import assert from "node:assert";
265
+ import path3 from "node:path";
266
+ import { isEmpty } from "ramda";
267
+ var configDefaults = {
268
+ buildDirName: void 0,
269
+ includeDevDependencies: false,
270
+ isolateDirName: "isolate",
271
+ logLevel: "info",
272
+ targetPackagePath: void 0,
273
+ tsconfigPath: "./tsconfig.json",
274
+ workspacePackages: void 0,
275
+ workspaceRoot: "../..",
276
+ excludeLockfile: false,
277
+ avoidPnpmPack: false
278
+ };
279
+ var _resolvedConfig;
280
+ var _user_defined_config;
281
+ var validConfigKeys = Object.keys(configDefaults);
282
+ var CONFIG_FILE_NAME = "isolate.config.json";
283
+ function setUserConfig(config) {
284
+ _user_defined_config = config;
285
+ if (config.logLevel) {
286
+ setLogLevel(config.logLevel);
287
+ }
288
+ }
289
+ function useConfig() {
290
+ if (_resolvedConfig) {
291
+ return _resolvedConfig;
292
+ } else {
293
+ throw new Error("Called useConfig before config was made available");
294
+ }
295
+ }
296
+ function resolveConfig() {
297
+ if (_resolvedConfig) {
298
+ return _resolvedConfig;
299
+ }
300
+ setLogLevel(process.env.DEBUG_ISOLATE_CONFIG ? "debug" : "info");
301
+ const log = useLogger();
302
+ const configFilePath = path3.join(process.cwd(), CONFIG_FILE_NAME);
303
+ if (_user_defined_config) {
304
+ log.debug(`Using user defined config:`, inspectValue(_user_defined_config));
305
+ } else {
306
+ log.debug(`Attempting to load config from ${configFilePath}`);
307
+ _user_defined_config = fs5.existsSync(configFilePath) ? readTypedJsonSync(configFilePath) : {};
308
+ }
309
+ const foreignKeys = Object.keys(_user_defined_config).filter(
310
+ (key) => !validConfigKeys.includes(key)
311
+ );
312
+ if (!isEmpty(foreignKeys)) {
313
+ log.warn(`Found invalid config settings:`, foreignKeys.join(", "));
314
+ }
315
+ const config = Object.assign(
316
+ {},
317
+ configDefaults,
318
+ _user_defined_config
319
+ );
320
+ log.debug("Using configuration:", inspectValue(config));
321
+ _resolvedConfig = config;
322
+ return config;
323
+ }
324
+ function getUserDefinedConfig() {
325
+ assert(
326
+ _user_defined_config,
327
+ "Called getUserDefinedConfig before user config was made available"
328
+ );
329
+ return _user_defined_config;
330
+ }
331
+
332
+ // src/helpers/detect-package-manager.ts
333
+ import fs8 from "fs-extra";
334
+ import assert3 from "node:assert";
335
+ import { execSync } from "node:child_process";
336
+ import path7 from "node:path";
337
+
338
+ // src/helpers/process-lockfile.ts
339
+ import fs7 from "fs-extra";
340
+ import path6 from "node:path";
341
+ import { mapObjIndexed } from "ramda";
342
+
343
+ // src/helpers/generate-npm-lockfile.ts
344
+ import Arborist from "@npmcli/arborist";
345
+ import fs6 from "node:fs/promises";
346
+ import path4 from "node:path";
347
+
348
+ // src/helpers/generate-pnpm-lockfile.ts
349
+ import {
350
+ getLockfileImporterId,
351
+ readWantedLockfile,
352
+ writeWantedLockfile
353
+ } from "@pnpm/lockfile-file";
354
+ import assert2 from "node:assert";
355
+ import path5 from "node:path";
356
+ import { pick } from "ramda";
357
+ async function generatePnpmLockfile({
358
+ workspaceRootDir,
359
+ targetPackageDir,
360
+ isolateDir,
361
+ internalDepPackageNames,
362
+ packagesRegistry
363
+ }) {
364
+ const { includeDevDependencies } = useConfig();
365
+ const log = useLogger();
366
+ log.debug("Generating PNPM lockfile");
367
+ const lockfile = await readWantedLockfile(workspaceRootDir, {
368
+ ignoreIncompatible: false
369
+ });
370
+ assert2(lockfile, "No lockfile found");
371
+ const targetImporterId = getLockfileImporterId(
372
+ workspaceRootDir,
373
+ targetPackageDir
374
+ );
375
+ const directoryByPackageName = Object.fromEntries(
376
+ internalDepPackageNames.map((name) => {
377
+ const pkg = packagesRegistry[name];
378
+ assert2(pkg, `Package ${name} not found in packages registry`);
379
+ return [name, pkg.rootRelativeDir];
380
+ })
381
+ );
382
+ const relevantImporterIds = [
383
+ targetImporterId,
384
+ /**
385
+ * The directory paths happen to correspond with what PNPM calls the
386
+ * importer ids in the context of a lockfile.
387
+ */
388
+ ...Object.values(directoryByPackageName)
389
+ ];
390
+ log.debug("Relevant importer ids:", relevantImporterIds);
391
+ lockfile.importers = Object.fromEntries(
392
+ Object.entries(pick(relevantImporterIds, lockfile.importers)).map(
393
+ ([importerId, importer]) => {
394
+ if (importerId === targetImporterId) {
395
+ log.debug("Setting target package importer on root");
396
+ return [
397
+ ".",
398
+ pnpmMapImporter(importer, {
399
+ includeDevDependencies,
400
+ directoryByPackageName
401
+ })
402
+ ];
403
+ }
404
+ log.debug("Setting internal package importer:", importerId);
405
+ return [
406
+ importerId,
407
+ pnpmMapImporter(importer, {
408
+ includeDevDependencies,
409
+ directoryByPackageName
410
+ })
411
+ ];
412
+ }
413
+ )
414
+ );
415
+ await writeWantedLockfile(isolateDir, lockfile);
416
+ log.debug("Created lockfile at", path5.join(isolateDir, "pnpm-lock.yaml"));
417
+ }
418
+
419
+ // src/helpers/process-lockfile.ts
420
+ function getLockfileFileName(name) {
421
+ switch (name) {
422
+ case "pnpm":
423
+ return "pnpm-lock.yaml";
424
+ case "yarn":
425
+ return "yarn.lock";
426
+ case "npm":
427
+ return "package-lock.json";
428
+ }
429
+ }
430
+ function pnpmMapImporter({ dependencies, devDependencies, ...rest }, {
431
+ includeDevDependencies,
432
+ directoryByPackageName
433
+ }) {
434
+ return {
435
+ dependencies: dependencies ? pnpmMapDependenciesLinks(dependencies, directoryByPackageName) : void 0,
436
+ devDependencies: includeDevDependencies && devDependencies ? pnpmMapDependenciesLinks(devDependencies, directoryByPackageName) : void 0,
437
+ ...rest
438
+ };
439
+ }
440
+ function pnpmMapDependenciesLinks(def, directoryByPackageName) {
441
+ return mapObjIndexed(
442
+ (version, name) => version.startsWith("link:") ? `link:./${directoryByPackageName[name]}` : version,
443
+ def
444
+ );
445
+ }
446
+ async function processLockfile({
447
+ workspaceRootDir,
448
+ packagesRegistry,
449
+ isolateDir,
450
+ internalDepPackageNames,
451
+ targetPackageDir,
452
+ targetPackageName
453
+ }) {
454
+ const log = useLogger();
455
+ const { name } = usePackageManager();
456
+ const fileName = getLockfileFileName(name);
457
+ const lockfileSrcPath = path6.join(workspaceRootDir, fileName);
458
+ const lockfileDstPath = path6.join(isolateDir, fileName);
459
+ switch (name) {
460
+ case "npm": {
461
+ const shrinkwrapSrcPath = path6.join(
462
+ workspaceRootDir,
463
+ "npm-shrinkwrap.json"
464
+ );
465
+ const shrinkwrapDstPath = path6.join(isolateDir, "npm-shrinkwrap.json");
466
+ if (fs7.existsSync(shrinkwrapSrcPath)) {
467
+ fs7.copyFileSync(shrinkwrapSrcPath, shrinkwrapDstPath);
468
+ log.debug("Copied shrinkwrap to", shrinkwrapDstPath);
469
+ } else {
470
+ fs7.copyFileSync(lockfileSrcPath, lockfileDstPath);
471
+ log.debug("Copied lockfile to", lockfileDstPath);
472
+ }
473
+ if (false) {
474
+ await generateNpmLockfile({
475
+ workspaceRootDir,
476
+ targetPackageName,
477
+ isolateDir,
478
+ packagesRegistry
479
+ });
480
+ }
481
+ break;
482
+ }
483
+ case "yarn": {
484
+ fs7.copyFileSync(lockfileSrcPath, lockfileDstPath);
485
+ log.debug("Copied lockfile to", lockfileDstPath);
486
+ break;
487
+ }
488
+ case "pnpm": {
489
+ await generatePnpmLockfile({
490
+ workspaceRootDir,
491
+ targetPackageDir,
492
+ isolateDir,
493
+ internalDepPackageNames,
494
+ packagesRegistry
495
+ });
496
+ break;
497
+ }
498
+ default:
499
+ log.warn(`Unexpected package manager ${name}`);
500
+ }
501
+ }
502
+
503
+ // src/helpers/detect-package-manager.ts
504
+ var supportedPackageManagerNames = ["pnpm", "yarn", "npm"];
505
+ var packageManager;
506
+ function detectPackageManager(workspaceRoot) {
507
+ packageManager = inferFromManifest(workspaceRoot) ?? inferFromFiles(workspaceRoot);
508
+ return packageManager;
509
+ }
510
+ function inferFromManifest(workspaceRoot) {
511
+ const log = useLogger();
512
+ const rootManifest = readTypedJsonSync(
513
+ path7.join(workspaceRoot, "package.json")
514
+ );
515
+ if (!rootManifest.packageManager) {
516
+ log.debug("No packageManager field found in root manifest");
517
+ return;
518
+ }
519
+ const [name, version = "*"] = rootManifest.packageManager.split("@");
520
+ assert3(
521
+ supportedPackageManagerNames.includes(name),
522
+ `Package manager "${name}" is not currently supported`
523
+ );
524
+ const lockfileName = getLockfileFileName(name);
525
+ assert3(
526
+ fs8.existsSync(path7.join(workspaceRoot, lockfileName)),
527
+ `Manifest declares ${name} to be the packageManager, but failed to find ${lockfileName} in workspace root`
528
+ );
529
+ return { name, version };
530
+ }
531
+ function inferFromFiles(workspaceRoot) {
532
+ for (const name of supportedPackageManagerNames) {
533
+ const lockfileName = getLockfileFileName(name);
534
+ if (fs8.existsSync(path7.join(workspaceRoot, lockfileName))) {
535
+ return { name, version: getVersion(name) };
536
+ }
537
+ }
538
+ if (fs8.existsSync(path7.join(workspaceRoot, "npm-shrinkwrap.json"))) {
539
+ return { name: "npm", version: getVersion("npm") };
540
+ }
541
+ throw new Error(`Failed to detect package manager`);
542
+ }
543
+ function getVersion(packageManagerName) {
544
+ const buffer = execSync(`${packageManagerName} --version`);
545
+ return buffer.toString().trim();
546
+ }
547
+ function usePackageManager() {
548
+ if (!packageManager) {
549
+ throw Error(
550
+ "No package manager detected. Make sure to call detectPackageManager() before usePackageManager()"
551
+ );
552
+ }
553
+ return packageManager;
554
+ }
555
+
556
+ // src/helpers/adapt-internal-package-manifests.ts
557
+ async function adaptInternalPackageManifests(internalPackageNames, packagesRegistry, isolateDir) {
558
+ const packageManager2 = usePackageManager();
559
+ const { includeDevDependencies } = useConfig();
560
+ await Promise.all(
561
+ internalPackageNames.map(async (packageName) => {
562
+ const { manifest, rootRelativeDir } = packagesRegistry[packageName];
563
+ const outputManifest = packageManager2.name === "pnpm" ? Object.assign(
564
+ /**
565
+ * For internal dependencies we want to omit the peerDependencies,
566
+ * because installing these is the responsibility of the consuming
567
+ * app / service, and otherwise the frozen lockfile install will
568
+ * error since the package file contains something that is not
569
+ * referenced in the lockfile.
570
+ */
571
+ omit2(["devDependencies", "peerDependencies"], manifest),
572
+ {
573
+ dependencies: manifest.dependencies,
574
+ devDependencies: includeDevDependencies ? manifest.devDependencies : void 0
575
+ }
576
+ ) : adaptManifestInternalDeps(
577
+ {
578
+ manifest,
579
+ packagesRegistry,
580
+ parentRootRelativeDir: rootRelativeDir
581
+ },
582
+ { includeDevDependencies }
583
+ );
584
+ await fs9.writeFile(
585
+ path8.join(isolateDir, rootRelativeDir, "package.json"),
586
+ JSON.stringify(outputManifest, null, 2)
587
+ );
588
+ })
589
+ );
590
+ }
591
+
592
+ // src/helpers/adapt-target-package-manifest.ts
593
+ import fs10 from "fs-extra";
594
+ import path9 from "node:path";
595
+ import { omit as omit3 } from "ramda";
596
+ async function adaptTargetPackageManifest(manifest, packagesRegistry, isolateDir) {
597
+ const packageManager2 = usePackageManager();
598
+ const { includeDevDependencies } = useConfig();
599
+ const outputManifest = packageManager2.name === "pnpm" ? Object.assign(omit3(["devDependencies", "scripts"], manifest), {
600
+ devDependencies: includeDevDependencies ? manifest.devDependencies : void 0
601
+ }) : adaptManifestInternalDeps(
602
+ {
603
+ manifest,
604
+ packagesRegistry
605
+ },
606
+ { includeDevDependencies }
607
+ );
608
+ await fs10.writeFile(
609
+ path9.join(isolateDir, "package.json"),
610
+ JSON.stringify(outputManifest, null, 2)
611
+ );
612
+ }
613
+
614
+ // src/helpers/create-packages-registry.ts
615
+ import fs11 from "fs-extra";
616
+ import { globSync } from "glob";
617
+ import path11 from "node:path";
618
+
619
+ // src/helpers/find-packages-globs.ts
620
+ import assert4 from "node:assert";
621
+ import path10 from "node:path";
622
+ function findPackagesGlobs(workspaceRootDir) {
623
+ const log = useLogger();
624
+ const packageManager2 = usePackageManager();
625
+ switch (packageManager2.name) {
626
+ case "pnpm": {
627
+ const { packages: globs } = readTypedYamlSync(
628
+ path10.join(workspaceRootDir, "pnpm-workspace.yaml")
629
+ );
630
+ log.debug("Detected pnpm packages globs:", inspectValue(globs));
631
+ return globs;
632
+ }
633
+ case "yarn":
634
+ case "npm": {
635
+ const workspaceRootManifestPath = path10.join(
636
+ workspaceRootDir,
637
+ "package.json"
638
+ );
639
+ const { workspaces } = readTypedJsonSync(
640
+ workspaceRootManifestPath
641
+ );
642
+ if (!workspaces) {
643
+ throw new Error(
644
+ `No workspaces field found in ${workspaceRootManifestPath}`
645
+ );
646
+ }
647
+ if (Array.isArray(workspaces)) {
648
+ return workspaces;
649
+ } else {
650
+ const workspacesObject = workspaces;
651
+ assert4(
652
+ workspacesObject.packages,
653
+ "workspaces.packages must be an array"
654
+ );
655
+ return workspacesObject.packages;
656
+ }
657
+ }
658
+ }
659
+ }
660
+
661
+ // src/helpers/create-packages-registry.ts
662
+ async function createPackagesRegistry(workspaceRootDir, workspacePackagesOverride) {
663
+ const log = useLogger();
664
+ if (workspacePackagesOverride) {
665
+ log.debug(
666
+ `Override workspace packages via config: ${workspacePackagesOverride}`
667
+ );
668
+ }
669
+ const packagesGlobs = workspacePackagesOverride ?? findPackagesGlobs(workspaceRootDir);
670
+ const cwd = process.cwd();
671
+ process.chdir(workspaceRootDir);
672
+ const allPackages = packagesGlobs.flatMap((glob) => globSync(glob)).filter((dir) => fs11.lstatSync(dir).isDirectory());
673
+ const registry = (await Promise.all(
674
+ allPackages.map(async (rootRelativeDir) => {
675
+ const manifestPath = path11.join(rootRelativeDir, "package.json");
676
+ if (!fs11.existsSync(manifestPath)) {
677
+ log.warn(
678
+ `Ignoring directory ./${rootRelativeDir} because it does not contain a package.json file`
679
+ );
680
+ return;
681
+ } else {
682
+ log.debug(`Registering package ./${rootRelativeDir}`);
683
+ const manifest = await readTypedJson(
684
+ path11.join(rootRelativeDir, "package.json")
685
+ );
686
+ return {
687
+ manifest,
688
+ rootRelativeDir,
689
+ absoluteDir: path11.join(workspaceRootDir, rootRelativeDir)
690
+ };
691
+ }
692
+ })
693
+ )).reduce((acc, info) => {
694
+ if (info) {
695
+ acc[info.manifest.name] = info;
696
+ }
697
+ return acc;
698
+ }, {});
699
+ process.chdir(cwd);
700
+ return registry;
701
+ }
702
+
703
+ // src/helpers/get-build-output-dir.ts
704
+ import fs12 from "fs-extra";
705
+ import path12 from "node:path";
706
+ import outdent from "outdent";
707
+ async function getBuildOutputDir(targetPackageDir) {
708
+ const config = useConfig();
709
+ const log = useLogger();
710
+ if (config.buildDirName) {
711
+ log.debug("Using buildDirName from config:", config.buildDirName);
712
+ return path12.join(targetPackageDir, config.buildDirName);
713
+ }
714
+ const tsconfigPath = path12.join(targetPackageDir, config.tsconfigPath);
715
+ if (fs12.existsSync(tsconfigPath)) {
716
+ log.debug("Found tsconfig at:", config.tsconfigPath);
717
+ const tsconfig = await readTypedJson(tsconfigPath);
718
+ const outDir = tsconfig.compilerOptions?.outDir;
719
+ if (outDir) {
720
+ return path12.join(targetPackageDir, outDir);
721
+ } else {
722
+ throw new Error(outdent`
723
+ Failed to find outDir in tsconfig. If you are executing isolate from the root of a monorepo you should specify the buildDirName in isolate.config.json.
724
+ `);
725
+ }
726
+ } else {
727
+ log.warn("Failed to find tsconfig at:", tsconfigPath);
728
+ throw new Error(outdent`
729
+ Failed to infer the build output directory from either the isolate config buildDirName or a Typescript config file. See the documentation on how to configure one of these options.
730
+ `);
731
+ }
732
+ }
733
+
734
+ // src/helpers/list-internal-packages.ts
735
+ import { uniq } from "ramda";
736
+ function listInternalPackages(manifest, packagesRegistry, { includeDevDependencies = false } = {}) {
737
+ const allWorkspacePackageNames = Object.keys(packagesRegistry);
738
+ const internalPackageNames = (includeDevDependencies ? [
739
+ ...Object.keys(manifest.dependencies ?? {}),
740
+ ...Object.keys(manifest.devDependencies ?? {})
741
+ ] : Object.keys(manifest.dependencies ?? {})).filter((name) => allWorkspacePackageNames.includes(name));
742
+ const nestedInternalPackageNames = internalPackageNames.flatMap(
743
+ (packageName) => listInternalPackages(
744
+ packagesRegistry[packageName].manifest,
745
+ packagesRegistry,
746
+ { includeDevDependencies }
747
+ )
748
+ );
749
+ return uniq(internalPackageNames.concat(nestedInternalPackageNames));
750
+ }
751
+
752
+ // src/helpers/pack-dependencies.ts
753
+ import assert5 from "node:assert";
754
+ async function packDependencies({
755
+ /** All packages found in the monorepo by workspaces declaration */
756
+ packagesRegistry,
757
+ /** The dependencies that appear to be internal packages */
758
+ internalPackageNames,
759
+ /**
760
+ * The directory where the isolated package and all its dependencies will end
761
+ * up. This is also the directory from where the package will be deployed. By
762
+ * default it is a subfolder in targetPackageDir called "isolate" but you can
763
+ * configure it.
764
+ */
765
+ packDestinationDir
766
+ }) {
767
+ const config = useConfig();
768
+ const log = useLogger();
769
+ const packedFileByName = {};
770
+ const { name, version } = usePackageManager();
771
+ const versionMajor = parseInt(version.split(".")[0], 10);
772
+ const usePnpmPack = !config.avoidPnpmPack && name === "pnpm" && versionMajor >= 8;
773
+ if (usePnpmPack) {
774
+ log.debug("Using PNPM pack instead of NPM pack");
775
+ }
776
+ for (const dependency of internalPackageNames) {
777
+ const def = packagesRegistry[dependency];
778
+ assert5(dependency, `Failed to find package definition for ${dependency}`);
779
+ const { name: name2 } = def.manifest;
780
+ if (packedFileByName[name2]) {
781
+ log.debug(`Skipping ${name2} because it has already been packed`);
782
+ continue;
783
+ }
784
+ packedFileByName[name2] = await pack(
785
+ def.absoluteDir,
786
+ packDestinationDir,
787
+ usePnpmPack
788
+ );
789
+ }
790
+ return packedFileByName;
791
+ }
792
+
793
+ // src/helpers/process-build-output-files.ts
794
+ import fs13 from "fs-extra";
795
+ import path13 from "node:path";
796
+ var TIMEOUT_MS = 5e3;
797
+ async function processBuildOutputFiles({
798
+ targetPackageDir,
799
+ tmpDir,
800
+ isolateDir
801
+ }) {
802
+ const log = useLogger();
803
+ const packedFilePath = await pack(targetPackageDir, tmpDir);
804
+ const unpackDir = path13.join(tmpDir, "target");
805
+ const now = Date.now();
806
+ let isWaitingYet = false;
807
+ while (!fs13.existsSync(packedFilePath) && Date.now() - now < TIMEOUT_MS) {
808
+ if (!isWaitingYet) {
809
+ log.debug(`Waiting for ${packedFilePath} to become available...`);
810
+ }
811
+ isWaitingYet = true;
812
+ await new Promise((resolve) => setTimeout(resolve, 100));
813
+ }
814
+ await unpack(packedFilePath, unpackDir);
815
+ await fs13.copy(path13.join(unpackDir, "package"), isolateDir);
816
+ }
817
+
818
+ // src/helpers/unpack-dependencies.ts
819
+ import fs14 from "fs-extra";
820
+ import path14, { join } from "node:path";
821
+ async function unpackDependencies(packedFilesByName, packagesRegistry, tmpDir, isolateDir) {
822
+ const log = useLogger();
823
+ await Promise.all(
824
+ Object.entries(packedFilesByName).map(async ([packageName, filePath]) => {
825
+ const dir = packagesRegistry[packageName].rootRelativeDir;
826
+ const unpackDir = join(tmpDir, dir);
827
+ log.debug("Unpacking", `(temp)/${path14.basename(filePath)}`);
828
+ await unpack(filePath, unpackDir);
829
+ const destinationDir = join(isolateDir, dir);
830
+ await fs14.ensureDir(destinationDir);
831
+ await fs14.move(join(unpackDir, "package"), destinationDir, {
832
+ overwrite: true
833
+ });
834
+ log.debug(
835
+ `Moved package files to ${getIsolateRelativePath(
836
+ destinationDir,
837
+ isolateDir
838
+ )}`
839
+ );
840
+ })
841
+ );
842
+ }
843
+
844
+ // src/isolate.ts
845
+ var __dirname2 = getDirname(import.meta.url);
846
+ async function isolate(options = {}) {
847
+ if (options.logger) {
848
+ setLogger(options.logger);
849
+ }
850
+ if (options.config) {
851
+ setUserConfig(options.config);
852
+ }
853
+ const config = resolveConfig();
854
+ setLogLevel(config.logLevel);
855
+ const log = useLogger();
856
+ const thisPackageManifest = await readTypedJson(
857
+ path15.join(path15.join(__dirname2, "..", "package.json"))
858
+ );
859
+ log.debug("Using isolate-package version", thisPackageManifest.version);
860
+ const targetPackageDir = config.targetPackagePath ? path15.join(process.cwd(), config.targetPackagePath) : process.cwd();
861
+ const workspaceRootDir = config.targetPackagePath ? process.cwd() : path15.join(targetPackageDir, config.workspaceRoot);
862
+ const buildOutputDir = await getBuildOutputDir(targetPackageDir);
863
+ assert6(
864
+ fs15.existsSync(buildOutputDir),
865
+ `Failed to find build output path at ${buildOutputDir}. Please make sure you build the source before isolating it.`
866
+ );
867
+ log.debug("Workspace root resolved to", workspaceRootDir);
868
+ log.debug(
869
+ "Isolate target package",
870
+ getRootRelativePath(targetPackageDir, workspaceRootDir)
871
+ );
872
+ const isolateDir = path15.join(targetPackageDir, config.isolateDirName);
873
+ log.debug(
874
+ "Isolate output directory",
875
+ getRootRelativePath(isolateDir, workspaceRootDir)
876
+ );
877
+ if (fs15.existsSync(isolateDir)) {
878
+ await fs15.remove(isolateDir);
879
+ log.debug("Cleaned the existing isolate output directory");
880
+ }
881
+ await fs15.ensureDir(isolateDir);
882
+ const tmpDir = path15.join(isolateDir, "__tmp");
883
+ await fs15.ensureDir(tmpDir);
884
+ const targetPackageManifest = await readTypedJson(
885
+ path15.join(targetPackageDir, "package.json")
886
+ );
887
+ const packageManager2 = detectPackageManager(workspaceRootDir);
888
+ log.debug(
889
+ "Detected package manager",
890
+ packageManager2.name,
891
+ packageManager2.version
892
+ );
893
+ const packagesRegistry = await createPackagesRegistry(
894
+ workspaceRootDir,
895
+ config.workspacePackages
896
+ );
897
+ const internalPackageNames = listInternalPackages(
898
+ targetPackageManifest,
899
+ packagesRegistry,
900
+ {
901
+ includeDevDependencies: config.includeDevDependencies
902
+ }
903
+ );
904
+ const packedFilesByName = await packDependencies({
905
+ internalPackageNames,
906
+ packagesRegistry,
907
+ packDestinationDir: tmpDir
908
+ });
909
+ await unpackDependencies(
910
+ packedFilesByName,
911
+ packagesRegistry,
912
+ tmpDir,
913
+ isolateDir
914
+ );
915
+ await adaptInternalPackageManifests(
916
+ internalPackageNames,
917
+ packagesRegistry,
918
+ isolateDir
919
+ );
920
+ await processBuildOutputFiles({
921
+ targetPackageDir,
922
+ tmpDir,
923
+ isolateDir
924
+ });
925
+ await adaptTargetPackageManifest(
926
+ targetPackageManifest,
927
+ packagesRegistry,
928
+ isolateDir
929
+ );
930
+ const userDefinedConfig = getUserDefinedConfig();
931
+ if (!isDefined(userDefinedConfig.excludeLockfile)) {
932
+ if (packageManager2.name === "npm" || packageManager2.name === "yarn") {
933
+ config.excludeLockfile = true;
934
+ }
935
+ }
936
+ if (config.excludeLockfile) {
937
+ log.warn("Excluding the lockfile from the isolate output");
938
+ } else {
939
+ await processLockfile({
940
+ workspaceRootDir,
941
+ isolateDir,
942
+ packagesRegistry,
943
+ internalDepPackageNames: internalPackageNames,
944
+ targetPackageDir,
945
+ targetPackageName: targetPackageManifest.name
946
+ });
947
+ }
948
+ if (packageManager2.name === "pnpm") {
949
+ fs15.copyFileSync(
950
+ path15.join(workspaceRootDir, "pnpm-workspace.yaml"),
951
+ path15.join(isolateDir, "pnpm-workspace.yaml")
952
+ );
953
+ }
954
+ const npmrcPath = path15.join(workspaceRootDir, ".npmrc");
955
+ if (fs15.existsSync(npmrcPath)) {
956
+ fs15.copyFileSync(npmrcPath, path15.join(isolateDir, ".npmrc"));
957
+ log.debug("Copied .npmrc file to the isolate output");
958
+ }
959
+ log.debug(
960
+ "Deleting temp directory",
961
+ getRootRelativePath(tmpDir, workspaceRootDir)
962
+ );
963
+ await fs15.remove(tmpDir);
964
+ log.info("Isolate completed at", isolateDir);
965
+ }
966
+
967
+ // src/isolate-bin.ts
9
968
  sourceMaps.install();
10
969
  async function run() {
11
970
  await isolate();
12
971
  }
13
972
  run().catch((err) => {
14
973
  if (err instanceof Error) {
15
- console.error(err.stack);
974
+ console2.error(err.stack);
16
975
  process.exit(1);
17
976
  } else {
18
- console.error(err);
977
+ console2.error(err);
19
978
  }
20
979
  });
21
- //# sourceMappingURL=isolate-bin.mjs.map
980
+ //# sourceMappingURL=isolate-bin.js.map