isolate-package 1.9.4 → 1.10.0-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 +18 -5
- package/dist/index.d.ts +2 -1
- package/dist/index.mjs +43 -22
- package/dist/index.mjs.map +1 -1
- package/dist/isolate-bin.mjs +43 -22
- package/dist/isolate-bin.mjs.map +1 -1
- package/docs/firebase.md +5 -5
- package/package.json +25 -26
package/README.md
CHANGED
|
@@ -60,6 +60,9 @@ integrated, check out [mono-ts](https://github.com/0x80/mono-ts)
|
|
|
60
60
|
- Compatible with the Firebase tools CLI, including 1st and 2nd generation
|
|
61
61
|
Firebase Functions. For more information see
|
|
62
62
|
[the Firebase instructions](./docs/firebase.md).
|
|
63
|
+
- Available in a
|
|
64
|
+
[forked version of firebase-tools](https://github.com/0x80/firebase-tools-with-isolate)
|
|
65
|
+
to preserve live code updates when running the emulators
|
|
63
66
|
|
|
64
67
|
## Installation
|
|
65
68
|
|
|
@@ -72,6 +75,11 @@ package manager should work.
|
|
|
72
75
|
|
|
73
76
|
## Usage
|
|
74
77
|
|
|
78
|
+
> !! If you plan use this for Firebase deployments, and you want to preserve
|
|
79
|
+
> live code updates when running the local emulators, you will want to use
|
|
80
|
+
> [firebase-tools-with-isolate](https://github.com/0x80/firebase-tools-with-isolate)
|
|
81
|
+
> instead.
|
|
82
|
+
|
|
75
83
|
This package exposes a binary called `isolate`.
|
|
76
84
|
|
|
77
85
|
Run `npx isolate` from the root of the package you want to isolate. Make sure
|
|
@@ -221,6 +229,11 @@ therefore should match the versions in your original lockfile.
|
|
|
221
229
|
This way you can enjoy using PNPM or Yarn for your monorepo, while your
|
|
222
230
|
deployment uses NPM with modules locked to the same versions.
|
|
223
231
|
|
|
232
|
+
> !! Warning: Generating an NPM lockfile currently requires moving the
|
|
233
|
+
> node_modules from the root of the monorepo temporarily into the isolate
|
|
234
|
+
> directory. This will not be compatible with setups that run multiple isolation
|
|
235
|
+
> processes in parallel.
|
|
236
|
+
|
|
224
237
|
### buildDirName
|
|
225
238
|
|
|
226
239
|
Type: `string | undefined`, default: `undefined`
|
|
@@ -338,18 +351,18 @@ configuration.
|
|
|
338
351
|
|
|
339
352
|
### NPM
|
|
340
353
|
|
|
341
|
-
For NPM we use a tool called Arborist which is an integral part of the NPM
|
|
354
|
+
For NPM we use a tool called Arborist, which is an integral part of the NPM
|
|
342
355
|
codebase. It is executed in the isolate output directory and requires the
|
|
343
356
|
adapted lockfile and the `node_modules` directory from the root of the
|
|
344
357
|
repository. As this directory is typically quite large, copying it over as part
|
|
345
358
|
of the isolate flow is not very desirable.
|
|
346
359
|
|
|
347
360
|
To work around this, we move it to the isolate output and then move it back
|
|
348
|
-
after Arborist has finished doing its thing.
|
|
349
|
-
hopefully this doesn't create any unwanted side effects for IDEs and other tools
|
|
350
|
-
that depend on the content of the directory.
|
|
361
|
+
after Arborist has finished doing its thing.
|
|
351
362
|
|
|
352
|
-
|
|
363
|
+
> !! Warning: This will not be compatible with setups that run multiple
|
|
364
|
+
> isolation processes in parallel. Hopefully a future update to NPM Arborist
|
|
365
|
+
> (the part the generates the lockfile) will solve this.
|
|
353
366
|
|
|
354
367
|
### PNPM
|
|
355
368
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
type IsolateConfigResolved = {
|
|
2
2
|
buildDirName?: string;
|
|
3
3
|
includeDevDependencies: boolean;
|
|
4
|
+
includePatchedDependencies: boolean;
|
|
4
5
|
isolateDirName: string;
|
|
5
6
|
logLevel: "info" | "debug" | "warn" | "error";
|
|
6
7
|
targetPackagePath?: string;
|
|
@@ -35,4 +36,4 @@ type IsolateExports = {
|
|
|
35
36
|
isolate: typeof isolate;
|
|
36
37
|
};
|
|
37
38
|
|
|
38
|
-
export { IsolateExports, Logger, isolate };
|
|
39
|
+
export { type IsolateExports, type Logger, isolate };
|
package/dist/index.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import path16 from "node:path";
|
|
|
7
7
|
import fs5 from "fs-extra";
|
|
8
8
|
import assert from "node:assert";
|
|
9
9
|
import path2 from "node:path";
|
|
10
|
-
import { isEmpty } from "
|
|
10
|
+
import { isEmpty } from "remeda";
|
|
11
11
|
|
|
12
12
|
// src/lib/logger.ts
|
|
13
13
|
import chalk from "chalk";
|
|
@@ -124,10 +124,10 @@ async function readTypedJson(filePath) {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
// src/lib/utils/pack.ts
|
|
127
|
-
import fs2 from "fs-extra";
|
|
128
127
|
import { exec } from "node:child_process";
|
|
128
|
+
import fs2 from "node:fs";
|
|
129
129
|
import path from "node:path";
|
|
130
|
-
async function pack(srcDir, dstDir, usePnpmPack
|
|
130
|
+
async function pack(srcDir, dstDir, usePnpmPack) {
|
|
131
131
|
const execOptions = {
|
|
132
132
|
maxBuffer: 10 * 1024 * 1024
|
|
133
133
|
};
|
|
@@ -138,9 +138,9 @@ async function pack(srcDir, dstDir, usePnpmPack = false) {
|
|
|
138
138
|
exec(
|
|
139
139
|
`pnpm pack --pack-destination "${dstDir}"`,
|
|
140
140
|
execOptions,
|
|
141
|
-
(err, stdout2
|
|
141
|
+
(err, stdout2) => {
|
|
142
142
|
if (err) {
|
|
143
|
-
log.error(
|
|
143
|
+
log.error(getErrorMessage(err));
|
|
144
144
|
return reject(err);
|
|
145
145
|
}
|
|
146
146
|
resolve(stdout2);
|
|
@@ -200,6 +200,7 @@ function readTypedYamlSync(filePath) {
|
|
|
200
200
|
var configDefaults = {
|
|
201
201
|
buildDirName: void 0,
|
|
202
202
|
includeDevDependencies: false,
|
|
203
|
+
includePatchedDependencies: false,
|
|
203
204
|
isolateDirName: "isolate",
|
|
204
205
|
logLevel: "info",
|
|
205
206
|
targetPackagePath: void 0,
|
|
@@ -257,7 +258,7 @@ function resolveConfig() {
|
|
|
257
258
|
}
|
|
258
259
|
|
|
259
260
|
// src/lib/lockfile/process-lockfile.ts
|
|
260
|
-
import {
|
|
261
|
+
import { mapValues } from "remeda";
|
|
261
262
|
|
|
262
263
|
// src/lib/package-manager/helpers/infer-from-files.ts
|
|
263
264
|
import fs6 from "fs-extra";
|
|
@@ -349,6 +350,7 @@ async function generateNpmLockfile({
|
|
|
349
350
|
const origRootNodeModulesPath = path5.join(workspaceRootDir, "node_modules");
|
|
350
351
|
const tempRootNodeModulesPath = path5.join(isolateDir, "node_modules");
|
|
351
352
|
let hasMovedNodeModules = false;
|
|
353
|
+
let hasError = false;
|
|
352
354
|
try {
|
|
353
355
|
if (!fs8.existsSync(origRootNodeModulesPath)) {
|
|
354
356
|
throw new Error(
|
|
@@ -359,7 +361,7 @@ async function generateNpmLockfile({
|
|
|
359
361
|
await fs8.move(origRootNodeModulesPath, tempRootNodeModulesPath);
|
|
360
362
|
hasMovedNodeModules = true;
|
|
361
363
|
const arborist = new Arborist({ path: isolateDir });
|
|
362
|
-
log.debug(`
|
|
364
|
+
log.debug(`Building tree...`);
|
|
363
365
|
const { meta } = await arborist.buildIdealTree();
|
|
364
366
|
meta?.commit();
|
|
365
367
|
const lockfilePath = path5.join(isolateDir, "package-lock.json");
|
|
@@ -368,12 +370,16 @@ async function generateNpmLockfile({
|
|
|
368
370
|
} catch (err) {
|
|
369
371
|
console.error(inspectValue(err));
|
|
370
372
|
log.error(`Failed to generate lockfile: ${getErrorMessage(err)}`);
|
|
373
|
+
hasError = true;
|
|
371
374
|
} finally {
|
|
372
375
|
if (hasMovedNodeModules) {
|
|
373
376
|
log.debug(`Restoring node_modules to the workspace root`);
|
|
374
377
|
await fs8.move(tempRootNodeModulesPath, origRootNodeModulesPath);
|
|
375
378
|
}
|
|
376
379
|
}
|
|
380
|
+
if (hasError) {
|
|
381
|
+
throw new Error("Failed to generate lockfile");
|
|
382
|
+
}
|
|
377
383
|
}
|
|
378
384
|
|
|
379
385
|
// src/lib/lockfile/helpers/generate-pnpm-lockfile.ts
|
|
@@ -384,7 +390,7 @@ import {
|
|
|
384
390
|
} from "@pnpm/lockfile-file";
|
|
385
391
|
import assert3 from "node:assert";
|
|
386
392
|
import path6 from "node:path";
|
|
387
|
-
import { pick } from "
|
|
393
|
+
import { pick } from "remeda";
|
|
388
394
|
async function generatePnpmLockfile({
|
|
389
395
|
workspaceRootDir,
|
|
390
396
|
targetPackageDir,
|
|
@@ -392,7 +398,7 @@ async function generatePnpmLockfile({
|
|
|
392
398
|
internalDepPackageNames,
|
|
393
399
|
packagesRegistry
|
|
394
400
|
}) {
|
|
395
|
-
const { includeDevDependencies } = useConfig();
|
|
401
|
+
const { includeDevDependencies, includePatchedDependencies } = useConfig();
|
|
396
402
|
const log = useLogger();
|
|
397
403
|
log.info("Generating PNPM lockfile...");
|
|
398
404
|
try {
|
|
@@ -421,7 +427,7 @@ async function generatePnpmLockfile({
|
|
|
421
427
|
];
|
|
422
428
|
log.debug("Relevant importer ids:", relevantImporterIds);
|
|
423
429
|
lockfile.importers = Object.fromEntries(
|
|
424
|
-
Object.entries(pick(
|
|
430
|
+
Object.entries(pick(lockfile.importers, relevantImporterIds)).map(
|
|
425
431
|
([importerId, importer]) => {
|
|
426
432
|
if (importerId === targetImporterId) {
|
|
427
433
|
log.debug("Setting target package importer on root");
|
|
@@ -429,6 +435,7 @@ async function generatePnpmLockfile({
|
|
|
429
435
|
".",
|
|
430
436
|
pnpmMapImporter(importer, {
|
|
431
437
|
includeDevDependencies,
|
|
438
|
+
includePatchedDependencies,
|
|
432
439
|
directoryByPackageName
|
|
433
440
|
})
|
|
434
441
|
];
|
|
@@ -438,6 +445,7 @@ async function generatePnpmLockfile({
|
|
|
438
445
|
importerId,
|
|
439
446
|
pnpmMapImporter(importer, {
|
|
440
447
|
includeDevDependencies,
|
|
448
|
+
includePatchedDependencies,
|
|
441
449
|
directoryByPackageName
|
|
442
450
|
})
|
|
443
451
|
];
|
|
@@ -447,7 +455,7 @@ async function generatePnpmLockfile({
|
|
|
447
455
|
await writeWantedLockfile(isolateDir, lockfile);
|
|
448
456
|
log.debug("Created lockfile at", path6.join(isolateDir, "pnpm-lock.yaml"));
|
|
449
457
|
} catch (err) {
|
|
450
|
-
|
|
458
|
+
throw new Error(`Failed to generate lockfile: ${getErrorMessage(err)}`);
|
|
451
459
|
}
|
|
452
460
|
}
|
|
453
461
|
|
|
@@ -473,25 +481,38 @@ async function generateYarnLockfile({
|
|
|
473
481
|
execSync2(`yarn install --cwd ${isolateDir}`);
|
|
474
482
|
log.debug("Generated lockfile at", newLockfilePath);
|
|
475
483
|
} catch (err) {
|
|
476
|
-
|
|
484
|
+
throw new Error(`Failed to generate lockfile: ${getErrorMessage(err)}`);
|
|
477
485
|
}
|
|
478
486
|
}
|
|
479
487
|
|
|
480
488
|
// src/lib/lockfile/process-lockfile.ts
|
|
481
|
-
function pnpmMapImporter({
|
|
489
|
+
function pnpmMapImporter({
|
|
490
|
+
dependencies,
|
|
491
|
+
devDependencies,
|
|
492
|
+
patchedDependencies,
|
|
493
|
+
...rest
|
|
494
|
+
}, {
|
|
482
495
|
includeDevDependencies,
|
|
496
|
+
includePatchedDependencies,
|
|
483
497
|
directoryByPackageName
|
|
484
498
|
}) {
|
|
485
499
|
return {
|
|
486
500
|
dependencies: dependencies ? pnpmMapDependenciesLinks(dependencies, directoryByPackageName) : void 0,
|
|
487
501
|
devDependencies: includeDevDependencies && devDependencies ? pnpmMapDependenciesLinks(devDependencies, directoryByPackageName) : void 0,
|
|
502
|
+
/**
|
|
503
|
+
* Don't know how to map the patched dependencies yet, so we just include
|
|
504
|
+
* them but I don't think it would work like this. The important thing for
|
|
505
|
+
* now is that they are omitted by default, because that is the most common
|
|
506
|
+
* use case.
|
|
507
|
+
*/
|
|
508
|
+
patchedDependencies: includePatchedDependencies ? patchedDependencies : void 0,
|
|
488
509
|
...rest
|
|
489
510
|
};
|
|
490
511
|
}
|
|
491
512
|
function pnpmMapDependenciesLinks(def, directoryByPackageName) {
|
|
492
|
-
return
|
|
493
|
-
|
|
494
|
-
|
|
513
|
+
return mapValues(
|
|
514
|
+
def,
|
|
515
|
+
(value, key) => value.startsWith("link:") ? `link:./${directoryByPackageName[key]}` : value
|
|
495
516
|
);
|
|
496
517
|
}
|
|
497
518
|
async function processLockfile({
|
|
@@ -562,11 +583,11 @@ async function processLockfile({
|
|
|
562
583
|
}
|
|
563
584
|
|
|
564
585
|
// src/lib/manifest/adapt-target-package-manifest.ts
|
|
565
|
-
import { omit as omit2, pick as pick2 } from "
|
|
586
|
+
import { omit as omit2, pick as pick2 } from "remeda";
|
|
566
587
|
|
|
567
588
|
// src/lib/manifest/helpers/adapt-internal-package-manifests.ts
|
|
568
589
|
import path10 from "node:path";
|
|
569
|
-
import { omit } from "
|
|
590
|
+
import { omit } from "remeda";
|
|
570
591
|
|
|
571
592
|
// src/lib/manifest/io.ts
|
|
572
593
|
import fs10 from "fs-extra";
|
|
@@ -630,7 +651,7 @@ async function adaptInternalPackageManifests(internalPackageNames, packagesRegis
|
|
|
630
651
|
await Promise.all(
|
|
631
652
|
internalPackageNames.map(async (packageName) => {
|
|
632
653
|
const { manifest, rootRelativeDir } = packagesRegistry[packageName];
|
|
633
|
-
const inputManifest = includeDevDependencies ? omit(["peerDependencies"]
|
|
654
|
+
const inputManifest = includeDevDependencies ? omit(manifest, ["peerDependencies"]) : omit(manifest, ["devDependencies", "peerDependencies"]);
|
|
634
655
|
const outputManifest = packageManager2.name === "pnpm" && !forceNpm ? (
|
|
635
656
|
/**
|
|
636
657
|
* For PNPM the output itself is a workspace so we can preserve the specifiers
|
|
@@ -654,7 +675,7 @@ async function adaptInternalPackageManifests(internalPackageNames, packagesRegis
|
|
|
654
675
|
async function adaptTargetPackageManifest(manifest, packagesRegistry, isolateDir) {
|
|
655
676
|
const packageManager2 = usePackageManager();
|
|
656
677
|
const { includeDevDependencies, forceNpm, pickFromScripts, omitFromScripts } = useConfig();
|
|
657
|
-
const inputManifest = includeDevDependencies ? manifest : omit2(["devDependencies"]
|
|
678
|
+
const inputManifest = includeDevDependencies ? manifest : omit2(manifest, ["devDependencies"]);
|
|
658
679
|
const adaptedManifest = packageManager2.name === "pnpm" && !forceNpm ? (
|
|
659
680
|
/**
|
|
660
681
|
* For PNPM the output itself is a workspace so we can preserve the specifiers
|
|
@@ -674,7 +695,7 @@ async function adaptTargetPackageManifest(manifest, packagesRegistry, isolateDir
|
|
|
674
695
|
* Scripts are removed by default if not explicitly picked or omitted via
|
|
675
696
|
* config.
|
|
676
697
|
*/
|
|
677
|
-
scripts: pickFromScripts ? pick2(
|
|
698
|
+
scripts: pickFromScripts ? pick2(manifest.scripts ?? {}, pickFromScripts) : omitFromScripts ? omit2(manifest.scripts ?? {}, omitFromScripts) : void 0
|
|
678
699
|
};
|
|
679
700
|
await writeManifest(isolateDir, outputManifest);
|
|
680
701
|
}
|
|
@@ -891,7 +912,7 @@ async function createPackagesRegistry(workspaceRootDir, workspacePackagesOverrid
|
|
|
891
912
|
}
|
|
892
913
|
|
|
893
914
|
// src/lib/registry/list-internal-packages.ts
|
|
894
|
-
import { uniq } from "
|
|
915
|
+
import { uniq } from "remeda";
|
|
895
916
|
function listInternalPackages(manifest, packagesRegistry, { includeDevDependencies = false } = {}) {
|
|
896
917
|
const allWorkspacePackageNames = Object.keys(packagesRegistry);
|
|
897
918
|
const internalPackageNames = (includeDevDependencies ? [
|