isolate-package 1.30.0-0 → 1.31.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.
- package/dist/index.d.mts +14 -2
- package/dist/index.mjs +2 -3
- package/dist/index.mjs.map +1 -1
- package/dist/{isolate-BZjQHi0U.mjs → isolate-DtNAHzfa.mjs} +122 -71
- package/dist/isolate-DtNAHzfa.mjs.map +1 -0
- package/dist/isolate-bin.mjs +5 -7
- package/dist/isolate-bin.mjs.map +1 -1
- package/package.json +31 -21
- package/src/index.ts +6 -0
- package/src/isolate-bin.ts +2 -2
- package/src/isolate.ts +42 -5
- package/src/lib/config.ts +31 -6
- package/src/lib/lockfile/helpers/generate-bun-lockfile.ts +17 -3
- package/src/lib/manifest/adapt-target-package-manifest.ts +2 -1
- package/src/lib/manifest/helpers/adapt-internal-package-manifests.test.ts +181 -0
- package/src/lib/manifest/helpers/adapt-internal-package-manifests.ts +17 -5
- package/src/lib/manifest/helpers/adopt-pnpm-fields-from-root.test.ts +61 -0
- package/src/lib/manifest/helpers/adopt-pnpm-fields-from-root.ts +42 -3
- package/src/lib/manifest/validate-manifest.test.ts +19 -10
- package/src/lib/manifest/validate-manifest.ts +13 -1
- package/src/lib/patches/copy-patches.test.ts +316 -243
- package/src/lib/patches/copy-patches.ts +54 -15
- package/src/lib/types.ts +6 -0
- package/src/lib/utils/is-rush-workspace.ts +6 -0
- package/dist/isolate-BZjQHi0U.mjs.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -20,7 +20,13 @@ type IsolateConfigResolved = {
|
|
|
20
20
|
targetPackagePath?: string;
|
|
21
21
|
tsconfigPath: string;
|
|
22
22
|
workspacePackages?: string[];
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Path to the workspace root, relative to the target package directory.
|
|
25
|
+
* When omitted, the workspace root is auto-detected by walking upward from
|
|
26
|
+
* the target package directory looking for a pnpm-workspace.yaml, a
|
|
27
|
+
* package.json with a `workspaces` field, or a rush.json.
|
|
28
|
+
*/
|
|
29
|
+
workspaceRoot?: string;
|
|
24
30
|
forceNpm: boolean;
|
|
25
31
|
pickFromScripts?: string[];
|
|
26
32
|
omitFromScripts?: string[];
|
|
@@ -45,5 +51,11 @@ declare function isolate(config?: IsolateConfig): Promise<string>;
|
|
|
45
51
|
*/
|
|
46
52
|
declare function getInternalPackageNames(config?: IsolateConfig): Promise<string[]>;
|
|
47
53
|
//#endregion
|
|
48
|
-
|
|
54
|
+
//#region src/index.d.ts
|
|
55
|
+
/** Used by firebase-tools-with-isolate to type the dynamic import */
|
|
56
|
+
type IsolateExports = {
|
|
57
|
+
isolate: typeof isolate;
|
|
58
|
+
};
|
|
59
|
+
//#endregion
|
|
60
|
+
export { type IsolateConfig, IsolateExports, type Logger, defineConfig, getInternalPackageNames, isolate };
|
|
49
61
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { c as detectPackageManager, i as defineConfig, l as readTypedJson, n as listInternalPackages, o as resolveConfig, r as createPackagesRegistry, s as resolveWorkspacePaths, t as isolate } from "./isolate-
|
|
1
|
+
import { c as detectPackageManager, i as defineConfig, l as readTypedJson, n as listInternalPackages, o as resolveConfig, r as createPackagesRegistry, s as resolveWorkspacePaths, t as isolate } from "./isolate-DtNAHzfa.mjs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
|
|
4
3
|
//#region src/get-internal-package-names.ts
|
|
5
4
|
/**
|
|
6
5
|
* Get the names of all internal workspace packages that the target package
|
|
@@ -16,7 +15,7 @@ async function getInternalPackageNames(config) {
|
|
|
16
15
|
detectPackageManager(workspaceRootDir);
|
|
17
16
|
return listInternalPackages(await readTypedJson(path.join(targetPackageDir, "package.json")), await createPackagesRegistry(workspaceRootDir, resolvedConfig.workspacePackages), { includeDevDependencies: resolvedConfig.includeDevDependencies });
|
|
18
17
|
}
|
|
19
|
-
|
|
20
18
|
//#endregion
|
|
21
19
|
export { defineConfig, getInternalPackageNames, isolate };
|
|
20
|
+
|
|
22
21
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/get-internal-package-names.ts"],"sourcesContent":["import path from \"node:path\";\nimport type { IsolateConfig } from \"./lib/config\";\nimport { resolveConfig, resolveWorkspacePaths } from \"./lib/config\";\nimport { detectPackageManager } from \"./lib/package-manager\";\nimport { createPackagesRegistry, listInternalPackages } from \"./lib/registry\";\nimport type { PackageManifest } from \"./lib/types\";\nimport { readTypedJson } from \"./lib/utils\";\n\n/**\n * Get the names of all internal workspace packages that the target package\n * depends on. This is useful for tools like tsup that need a list of internal\n * packages to include in `noExternal`.\n *\n * If no config is passed, it reads from `isolate.config.{ts,js,json}` in the\n * current working directory.\n */\nexport async function getInternalPackageNames(\n config?: IsolateConfig,\n): Promise<string[]> {\n const resolvedConfig = resolveConfig(config);\n const { targetPackageDir, workspaceRootDir } =\n resolveWorkspacePaths(resolvedConfig);\n\n detectPackageManager(workspaceRootDir);\n\n const targetPackageManifest = await readTypedJson<PackageManifest>(\n path.join(targetPackageDir, \"package.json\"),\n );\n\n const packagesRegistry = await createPackagesRegistry(\n workspaceRootDir,\n resolvedConfig.workspacePackages,\n );\n\n return listInternalPackages(targetPackageManifest, packagesRegistry, {\n includeDevDependencies: resolvedConfig.includeDevDependencies,\n });\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/get-internal-package-names.ts"],"sourcesContent":["import path from \"node:path\";\nimport type { IsolateConfig } from \"./lib/config\";\nimport { resolveConfig, resolveWorkspacePaths } from \"./lib/config\";\nimport { detectPackageManager } from \"./lib/package-manager\";\nimport { createPackagesRegistry, listInternalPackages } from \"./lib/registry\";\nimport type { PackageManifest } from \"./lib/types\";\nimport { readTypedJson } from \"./lib/utils\";\n\n/**\n * Get the names of all internal workspace packages that the target package\n * depends on. This is useful for tools like tsup that need a list of internal\n * packages to include in `noExternal`.\n *\n * If no config is passed, it reads from `isolate.config.{ts,js,json}` in the\n * current working directory.\n */\nexport async function getInternalPackageNames(\n config?: IsolateConfig,\n): Promise<string[]> {\n const resolvedConfig = resolveConfig(config);\n const { targetPackageDir, workspaceRootDir } =\n resolveWorkspacePaths(resolvedConfig);\n\n detectPackageManager(workspaceRootDir);\n\n const targetPackageManifest = await readTypedJson<PackageManifest>(\n path.join(targetPackageDir, \"package.json\"),\n );\n\n const packagesRegistry = await createPackagesRegistry(\n workspaceRootDir,\n resolvedConfig.workspacePackages,\n );\n\n return listInternalPackages(targetPackageManifest, packagesRegistry, {\n includeDevDependencies: resolvedConfig.includeDevDependencies,\n });\n}\n"],"mappings":";;;;;;;;;;;AAgBA,eAAsB,wBACpB,QACmB;CACnB,MAAM,iBAAiB,cAAc,OAAO;CAC5C,MAAM,EAAE,kBAAkB,qBACxB,sBAAsB,eAAe;AAEvC,sBAAqB,iBAAiB;AAWtC,QAAO,qBATuB,MAAM,cAClC,KAAK,KAAK,kBAAkB,eAAe,CAC5C,EAEwB,MAAM,uBAC7B,kBACA,eAAe,kBAChB,EAEoE,EACnE,wBAAwB,eAAe,wBACxC,CAAC"}
|
|
@@ -4,6 +4,7 @@ import assert from "node:assert";
|
|
|
4
4
|
import path, { join } from "node:path";
|
|
5
5
|
import { isEmpty, omit, pick, unique } from "remeda";
|
|
6
6
|
import { exec, execFileSync, execSync } from "node:child_process";
|
|
7
|
+
import { detectMonorepo } from "detect-monorepo";
|
|
7
8
|
import { pathToFileURL } from "node:url";
|
|
8
9
|
import { createConsola } from "consola";
|
|
9
10
|
import { fileURLToPath } from "url";
|
|
@@ -24,7 +25,6 @@ import path$1 from "path";
|
|
|
24
25
|
import { getTsconfig } from "get-tsconfig";
|
|
25
26
|
import outdent$1 from "outdent";
|
|
26
27
|
import { globSync } from "glob";
|
|
27
|
-
|
|
28
28
|
//#region src/lib/logger.ts
|
|
29
29
|
/**
|
|
30
30
|
* Map our log levels to consola's numeric levels. Consola levels:
|
|
@@ -56,13 +56,11 @@ function setLogLevel(logLevel) {
|
|
|
56
56
|
function useLogger() {
|
|
57
57
|
return _logger;
|
|
58
58
|
}
|
|
59
|
-
|
|
60
59
|
//#endregion
|
|
61
60
|
//#region src/lib/utils/filter-object-undefined.ts
|
|
62
61
|
function filterObjectUndefined(object) {
|
|
63
62
|
return Object.fromEntries(Object.entries(object).filter(([_, value]) => value !== void 0));
|
|
64
63
|
}
|
|
65
|
-
|
|
66
64
|
//#endregion
|
|
67
65
|
//#region src/lib/utils/get-package-name.ts
|
|
68
66
|
/**
|
|
@@ -74,7 +72,6 @@ function getPackageName(packageSpec) {
|
|
|
74
72
|
/** Regular packages: package@version -> package */
|
|
75
73
|
return packageSpec.split("@")[0] ?? "";
|
|
76
74
|
}
|
|
77
|
-
|
|
78
75
|
//#endregion
|
|
79
76
|
//#region src/lib/utils/filter-patched-dependencies.ts
|
|
80
77
|
/**
|
|
@@ -115,7 +112,6 @@ function filterPatchedDependencies({ patchedDependencies, targetPackageManifest,
|
|
|
115
112
|
log.debug(`Filtered patches: ${includedCount} included, ${excludedCount} excluded`);
|
|
116
113
|
return Object.keys(filteredPatches).length > 0 ? filteredPatches : void 0;
|
|
117
114
|
}
|
|
118
|
-
|
|
119
115
|
//#endregion
|
|
120
116
|
//#region src/lib/utils/get-dirname.ts
|
|
121
117
|
/**
|
|
@@ -125,7 +121,6 @@ function filterPatchedDependencies({ patchedDependencies, targetPackageManifest,
|
|
|
125
121
|
function getDirname(importMetaUrl) {
|
|
126
122
|
return fileURLToPath(new URL(".", importMetaUrl));
|
|
127
123
|
}
|
|
128
|
-
|
|
129
124
|
//#endregion
|
|
130
125
|
//#region src/lib/utils/get-error-message.ts
|
|
131
126
|
function getErrorMessage(error) {
|
|
@@ -146,23 +141,26 @@ function toErrorWithMessage(maybeError) {
|
|
|
146
141
|
return new Error(String(maybeError));
|
|
147
142
|
}
|
|
148
143
|
}
|
|
149
|
-
|
|
150
144
|
//#endregion
|
|
151
145
|
//#region src/lib/utils/inspect-value.ts
|
|
152
146
|
function inspectValue(value) {
|
|
153
147
|
return inspect(value, false, 16, true);
|
|
154
148
|
}
|
|
155
|
-
|
|
156
149
|
//#endregion
|
|
157
150
|
//#region src/lib/utils/is-rush-workspace.ts
|
|
158
151
|
/**
|
|
159
152
|
* Detect if this is a Rush monorepo. They use a very different structure so
|
|
160
153
|
* there are multiple places where we need to make exceptions based on this.
|
|
154
|
+
*
|
|
155
|
+
* This intentionally only checks the passed-in directory. Using the upward
|
|
156
|
+
* walk of `detectMonorepo` here would break callers that pass a subdirectory
|
|
157
|
+
* of the actual Rush root, because downstream code builds paths (like
|
|
158
|
+
* `common/config/rush`) and lockfile importer ids relative to the same
|
|
159
|
+
* directory it gets.
|
|
161
160
|
*/
|
|
162
161
|
function isRushWorkspace(workspaceRootDir) {
|
|
163
162
|
return fs$1.existsSync(path.join(workspaceRootDir, "rush.json"));
|
|
164
163
|
}
|
|
165
|
-
|
|
166
164
|
//#endregion
|
|
167
165
|
//#region src/lib/utils/json.ts
|
|
168
166
|
/** @todo Pass in zod schema and validate */
|
|
@@ -182,7 +180,6 @@ async function readTypedJson(filePath) {
|
|
|
182
180
|
throw new Error(`Failed to read JSON from ${filePath}: ${getErrorMessage(err)}`, { cause: err });
|
|
183
181
|
}
|
|
184
182
|
}
|
|
185
|
-
|
|
186
183
|
//#endregion
|
|
187
184
|
//#region src/lib/utils/log-paths.ts
|
|
188
185
|
function getRootRelativeLogPath(path, rootPath) {
|
|
@@ -191,13 +188,11 @@ function getRootRelativeLogPath(path, rootPath) {
|
|
|
191
188
|
function getIsolateRelativeLogPath(path, isolatePath) {
|
|
192
189
|
return join("(isolate)", path.replace(isolatePath, ""));
|
|
193
190
|
}
|
|
194
|
-
|
|
195
191
|
//#endregion
|
|
196
192
|
//#region src/lib/utils/get-major-version.ts
|
|
197
193
|
function getMajorVersion(version) {
|
|
198
194
|
return parseInt(version.split(".").at(0) ?? "0", 10);
|
|
199
195
|
}
|
|
200
|
-
|
|
201
196
|
//#endregion
|
|
202
197
|
//#region src/lib/package-manager/names.ts
|
|
203
198
|
const supportedPackageManagerNames = [
|
|
@@ -214,7 +209,6 @@ function getLockfileFileName(name) {
|
|
|
214
209
|
case "npm": return "package-lock.json";
|
|
215
210
|
}
|
|
216
211
|
}
|
|
217
|
-
|
|
218
212
|
//#endregion
|
|
219
213
|
//#region src/lib/package-manager/helpers/infer-from-files.ts
|
|
220
214
|
function inferFromFiles(workspaceRoot) {
|
|
@@ -245,7 +239,6 @@ function inferFromFiles(workspaceRoot) {
|
|
|
245
239
|
function getVersion(packageManagerName) {
|
|
246
240
|
return execSync(`${packageManagerName} --version`).toString().trim();
|
|
247
241
|
}
|
|
248
|
-
|
|
249
242
|
//#endregion
|
|
250
243
|
//#region src/lib/package-manager/helpers/infer-from-manifest.ts
|
|
251
244
|
function inferFromManifest(workspaceRoot) {
|
|
@@ -266,7 +259,6 @@ function inferFromManifest(workspaceRoot) {
|
|
|
266
259
|
packageManagerString
|
|
267
260
|
};
|
|
268
261
|
}
|
|
269
|
-
|
|
270
262
|
//#endregion
|
|
271
263
|
//#region src/lib/package-manager/index.ts
|
|
272
264
|
let packageManager;
|
|
@@ -293,7 +285,6 @@ function shouldUsePnpmPack() {
|
|
|
293
285
|
const { name, majorVersion } = usePackageManager();
|
|
294
286
|
return name === "pnpm" && majorVersion >= 8;
|
|
295
287
|
}
|
|
296
|
-
|
|
297
288
|
//#endregion
|
|
298
289
|
//#region src/lib/utils/pack.ts
|
|
299
290
|
async function pack(srcDir, dstDir) {
|
|
@@ -334,7 +325,6 @@ async function pack(srcDir, dstDir) {
|
|
|
334
325
|
*/
|
|
335
326
|
return filePath;
|
|
336
327
|
}
|
|
337
|
-
|
|
338
328
|
//#endregion
|
|
339
329
|
//#region src/lib/utils/unpack.ts
|
|
340
330
|
async function unpack(filePath, unpackDir) {
|
|
@@ -342,7 +332,6 @@ async function unpack(filePath, unpackDir) {
|
|
|
342
332
|
fs.createReadStream(filePath).pipe(createGunzip()).pipe(tar.extract(unpackDir)).on("finish", () => resolve()).on("error", (err) => reject(err));
|
|
343
333
|
});
|
|
344
334
|
}
|
|
345
|
-
|
|
346
335
|
//#endregion
|
|
347
336
|
//#region src/lib/utils/yaml.ts
|
|
348
337
|
function readTypedYamlSync(filePath) {
|
|
@@ -358,7 +347,6 @@ function writeTypedYamlSync(filePath, content) {
|
|
|
358
347
|
/** @todo Add some zod validation maybe */
|
|
359
348
|
fs.writeFileSync(filePath, yaml.stringify(content), "utf-8");
|
|
360
349
|
}
|
|
361
|
-
|
|
362
350
|
//#endregion
|
|
363
351
|
//#region src/lib/config.ts
|
|
364
352
|
const configDefaults = {
|
|
@@ -369,7 +357,7 @@ const configDefaults = {
|
|
|
369
357
|
targetPackagePath: void 0,
|
|
370
358
|
tsconfigPath: "./tsconfig.json",
|
|
371
359
|
workspacePackages: void 0,
|
|
372
|
-
workspaceRoot:
|
|
360
|
+
workspaceRoot: void 0,
|
|
373
361
|
forceNpm: false,
|
|
374
362
|
pickFromScripts: void 0,
|
|
375
363
|
omitFromScripts: void 0,
|
|
@@ -451,12 +439,25 @@ function validateConfig(config) {
|
|
|
451
439
|
* Resolve the target package directory and workspace root directory from the
|
|
452
440
|
* configuration. When targetPackagePath is set, the config is assumed to live
|
|
453
441
|
* at the workspace root. Otherwise it lives in the target package directory.
|
|
442
|
+
*
|
|
443
|
+
* When `workspaceRoot` is not explicitly set, auto-detect the monorepo root by
|
|
444
|
+
* walking upward from the target package directory.
|
|
454
445
|
*/
|
|
455
446
|
function resolveWorkspacePaths(config) {
|
|
456
447
|
const targetPackageDir = config.targetPackagePath ? path.join(process.cwd(), config.targetPackagePath) : process.cwd();
|
|
448
|
+
if (config.targetPackagePath) return {
|
|
449
|
+
targetPackageDir,
|
|
450
|
+
workspaceRootDir: process.cwd()
|
|
451
|
+
};
|
|
452
|
+
if (config.workspaceRoot !== void 0) return {
|
|
453
|
+
targetPackageDir,
|
|
454
|
+
workspaceRootDir: path.join(targetPackageDir, config.workspaceRoot)
|
|
455
|
+
};
|
|
456
|
+
const detected = detectMonorepo(targetPackageDir);
|
|
457
|
+
if (!detected) throw new Error(`Failed to auto-detect monorepo workspace root from ${targetPackageDir}. Set the 'workspaceRoot' config option explicitly.`);
|
|
457
458
|
return {
|
|
458
459
|
targetPackageDir,
|
|
459
|
-
workspaceRootDir:
|
|
460
|
+
workspaceRootDir: detected.rootDir
|
|
460
461
|
};
|
|
461
462
|
}
|
|
462
463
|
function resolveConfig(initialConfig) {
|
|
@@ -474,7 +475,6 @@ function resolveConfig(initialConfig) {
|
|
|
474
475
|
log.debug("Using configuration:", inspectValue(config));
|
|
475
476
|
return config;
|
|
476
477
|
}
|
|
477
|
-
|
|
478
478
|
//#endregion
|
|
479
479
|
//#region src/lib/lockfile/helpers/generate-bun-lockfile.ts
|
|
480
480
|
/**
|
|
@@ -578,14 +578,16 @@ async function generateBunLockfile({ workspaceRootDir, targetPackageDir, isolate
|
|
|
578
578
|
const targetWorkspaceKey = path.relative(workspaceRootDir, targetPackageDir).split(path.sep).join(path.posix.sep);
|
|
579
579
|
const internalDepWorkspaceKeys = /* @__PURE__ */ new Map();
|
|
580
580
|
for (const name of internalDepPackageNames) {
|
|
581
|
-
|
|
582
|
-
|
|
581
|
+
/** Normalize to POSIX separators for matching bun.lock workspace keys */
|
|
582
|
+
const workspaceKey = got(packagesRegistry, name).rootRelativeDir.split(path.sep).join(path.posix.sep);
|
|
583
|
+
internalDepWorkspaceKeys.set(name, workspaceKey);
|
|
583
584
|
}
|
|
584
585
|
/** Build the filtered workspaces object */
|
|
585
586
|
const filteredWorkspaces = {};
|
|
586
587
|
/** Remap the target workspace to root ("") */
|
|
587
588
|
const targetEntry = lockfile.workspaces[targetWorkspaceKey];
|
|
588
|
-
if (targetEntry) {
|
|
589
|
+
if (!targetEntry) throw new Error(`Target workspace "${targetWorkspaceKey}" not found in bun.lock. Available workspaces: ${Object.keys(lockfile.workspaces).join(", ")}`);
|
|
590
|
+
{
|
|
589
591
|
const entry = { ...targetEntry };
|
|
590
592
|
if (!includeDevDependencies) delete entry.devDependencies;
|
|
591
593
|
filteredWorkspaces[""] = entry;
|
|
@@ -645,14 +647,14 @@ async function generateBunLockfile({ workspaceRootDir, targetPackageDir, isolate
|
|
|
645
647
|
if (Object.keys(outputPatches).length > 0) outputLockfile.patchedDependencies = outputPatches;
|
|
646
648
|
}
|
|
647
649
|
const outputPath = path.join(isolateDir, "bun.lock");
|
|
648
|
-
|
|
650
|
+
/** Append trailing newline to match Bun's native output format */
|
|
651
|
+
await fs.writeFile(outputPath, serializeWithTrailingCommas(outputLockfile) + "\n");
|
|
649
652
|
log.debug("Created lockfile at", outputPath);
|
|
650
653
|
} catch (err) {
|
|
651
654
|
log.error(`Failed to generate lockfile: ${getErrorMessage(err)}`);
|
|
652
655
|
throw err;
|
|
653
656
|
}
|
|
654
657
|
}
|
|
655
|
-
|
|
656
658
|
//#endregion
|
|
657
659
|
//#region src/lib/lockfile/helpers/load-npm-config.ts
|
|
658
660
|
async function loadNpmConfig({ npmPath }) {
|
|
@@ -665,7 +667,6 @@ async function loadNpmConfig({ npmPath }) {
|
|
|
665
667
|
await config.load();
|
|
666
668
|
return config;
|
|
667
669
|
}
|
|
668
|
-
|
|
669
670
|
//#endregion
|
|
670
671
|
//#region src/lib/lockfile/helpers/generate-npm-lockfile.ts
|
|
671
672
|
/**
|
|
@@ -692,7 +693,6 @@ async function generateNpmLockfile({ workspaceRootDir, isolateDir }) {
|
|
|
692
693
|
throw err;
|
|
693
694
|
}
|
|
694
695
|
}
|
|
695
|
-
|
|
696
696
|
//#endregion
|
|
697
697
|
//#region src/lib/lockfile/helpers/pnpm-map-importer.ts
|
|
698
698
|
/** Convert dependency links */
|
|
@@ -723,7 +723,6 @@ function pnpmMapDependenciesLinks(importerPath, def, directoryByPackageName) {
|
|
|
723
723
|
return [[key, relativePath.startsWith(".") ? `link:${relativePath}` : `link:./${relativePath}`]];
|
|
724
724
|
}));
|
|
725
725
|
}
|
|
726
|
-
|
|
727
726
|
//#endregion
|
|
728
727
|
//#region src/lib/lockfile/helpers/generate-pnpm-lockfile.ts
|
|
729
728
|
async function generatePnpmLockfile({ workspaceRootDir, targetPackageDir, isolateDir, internalDepPackageNames, packagesRegistry, targetPackageManifest, majorVersion, includeDevDependencies, patchedDependencies }) {
|
|
@@ -794,7 +793,6 @@ async function generatePnpmLockfile({ workspaceRootDir, targetPackageDir, isolat
|
|
|
794
793
|
throw err;
|
|
795
794
|
}
|
|
796
795
|
}
|
|
797
|
-
|
|
798
796
|
//#endregion
|
|
799
797
|
//#region src/lib/lockfile/helpers/generate-yarn-lockfile.ts
|
|
800
798
|
/**
|
|
@@ -823,7 +821,6 @@ async function generateYarnLockfile({ workspaceRootDir, isolateDir }) {
|
|
|
823
821
|
throw err;
|
|
824
822
|
}
|
|
825
823
|
}
|
|
826
|
-
|
|
827
824
|
//#endregion
|
|
828
825
|
//#region src/lib/lockfile/process-lockfile.ts
|
|
829
826
|
/**
|
|
@@ -899,7 +896,6 @@ async function processLockfile({ workspaceRootDir, packagesRegistry, isolateDir,
|
|
|
899
896
|
}
|
|
900
897
|
return usedFallbackToNpm;
|
|
901
898
|
}
|
|
902
|
-
|
|
903
899
|
//#endregion
|
|
904
900
|
//#region src/lib/manifest/io.ts
|
|
905
901
|
async function readManifest(packageDir) {
|
|
@@ -908,7 +904,6 @@ async function readManifest(packageDir) {
|
|
|
908
904
|
async function writeManifest(outputDir, manifest) {
|
|
909
905
|
await fs.writeFile(path.join(outputDir, "package.json"), JSON.stringify(manifest, null, 2));
|
|
910
906
|
}
|
|
911
|
-
|
|
912
907
|
//#endregion
|
|
913
908
|
//#region src/lib/manifest/helpers/patch-internal-entries.ts
|
|
914
909
|
function patchInternalEntries(dependencies, packagesRegistry, parentRootRelativeDir) {
|
|
@@ -923,7 +918,6 @@ function patchInternalEntries(dependencies, packagesRegistry, parentRootRelative
|
|
|
923
918
|
} else return [key, value];
|
|
924
919
|
}));
|
|
925
920
|
}
|
|
926
|
-
|
|
927
921
|
//#endregion
|
|
928
922
|
//#region src/lib/manifest/helpers/adapt-manifest-internal-deps.ts
|
|
929
923
|
/**
|
|
@@ -939,7 +933,6 @@ function adaptManifestInternalDeps({ manifest, packagesRegistry, parentRootRelat
|
|
|
939
933
|
devDependencies: devDependencies ? patchInternalEntries(devDependencies, packagesRegistry, parentRootRelativeDir) : void 0
|
|
940
934
|
};
|
|
941
935
|
}
|
|
942
|
-
|
|
943
936
|
//#endregion
|
|
944
937
|
//#region src/lib/manifest/helpers/resolve-catalog-dependencies.ts
|
|
945
938
|
/**
|
|
@@ -973,7 +966,6 @@ async function resolveCatalogDependencies(dependencies, workspaceRootDir) {
|
|
|
973
966
|
}
|
|
974
967
|
return resolved;
|
|
975
968
|
}
|
|
976
|
-
|
|
977
969
|
//#endregion
|
|
978
970
|
//#region src/lib/manifest/helpers/adapt-internal-package-manifests.ts
|
|
979
971
|
/**
|
|
@@ -985,14 +977,22 @@ async function adaptInternalPackageManifests({ internalPackageNames, packagesReg
|
|
|
985
977
|
const packageManager = usePackageManager();
|
|
986
978
|
await Promise.all(internalPackageNames.map(async (packageName) => {
|
|
987
979
|
const { manifest, rootRelativeDir } = got(packagesRegistry, packageName);
|
|
988
|
-
/** Dev dependencies
|
|
989
|
-
const strippedManifest = omit(manifest, ["
|
|
980
|
+
/** Dev dependencies are never included for internal deps */
|
|
981
|
+
const strippedManifest = omit(manifest, ["devDependencies"]);
|
|
982
|
+
/**
|
|
983
|
+
* Strip the `prepare` script because it runs during `pnpm install` and
|
|
984
|
+
* typically depends on devDependency binaries (e.g. tsdown, del-cli)
|
|
985
|
+
* which are not available in the isolated output. Other lifecycle
|
|
986
|
+
* scripts like `postinstall` are preserved because they handle runtime
|
|
987
|
+
* setup (e.g. Prisma client generation).
|
|
988
|
+
*/
|
|
989
|
+
if (strippedManifest.scripts) strippedManifest.scripts = omit(strippedManifest.scripts, ["prepare"]);
|
|
990
990
|
/** Resolve catalog dependencies before adapting internal deps */
|
|
991
991
|
const manifestWithResolvedCatalogs = {
|
|
992
992
|
...strippedManifest,
|
|
993
993
|
dependencies: await resolveCatalogDependencies(strippedManifest.dependencies, workspaceRootDir)
|
|
994
994
|
};
|
|
995
|
-
const outputManifest = packageManager.name === "pnpm" && !forceNpm ? manifestWithResolvedCatalogs : adaptManifestInternalDeps({
|
|
995
|
+
const outputManifest = (packageManager.name === "pnpm" || packageManager.name === "bun") && !forceNpm ? manifestWithResolvedCatalogs : adaptManifestInternalDeps({
|
|
996
996
|
manifest: manifestWithResolvedCatalogs,
|
|
997
997
|
packagesRegistry,
|
|
998
998
|
parentRootRelativeDir: rootRelativeDir
|
|
@@ -1000,17 +1000,36 @@ async function adaptInternalPackageManifests({ internalPackageNames, packagesReg
|
|
|
1000
1000
|
await writeManifest(path.join(isolateDir, rootRelativeDir), outputManifest);
|
|
1001
1001
|
}));
|
|
1002
1002
|
}
|
|
1003
|
-
|
|
1004
1003
|
//#endregion
|
|
1005
1004
|
//#region src/lib/manifest/helpers/adopt-pnpm-fields-from-root.ts
|
|
1006
1005
|
/**
|
|
1007
|
-
* Adopts
|
|
1008
|
-
* overrides, onlyBuiltDependencies, and ignoredBuiltDependencies
|
|
1009
|
-
*
|
|
1006
|
+
* Adopts workspace-level fields from the root package manifest. For pnpm this
|
|
1007
|
+
* reads overrides, onlyBuiltDependencies, and ignoredBuiltDependencies from the
|
|
1008
|
+
* `pnpm` key. For Bun it reads `overrides` from the top level.
|
|
1010
1009
|
*/
|
|
1011
1010
|
async function adoptPnpmFieldsFromRoot(targetPackageManifest, workspaceRootDir) {
|
|
1012
1011
|
if (isRushWorkspace(workspaceRootDir)) return targetPackageManifest;
|
|
1013
|
-
const
|
|
1012
|
+
const rootPackageManifest = await readTypedJson(path$1.join(workspaceRootDir, "package.json"));
|
|
1013
|
+
if (usePackageManager().name === "bun") return adoptBunFieldsFromRoot(targetPackageManifest, rootPackageManifest);
|
|
1014
|
+
return adoptPnpmFieldsOnly(targetPackageManifest, rootPackageManifest);
|
|
1015
|
+
}
|
|
1016
|
+
/** Adopt Bun's top-level overrides from the root manifest */
|
|
1017
|
+
function adoptBunFieldsFromRoot(targetPackageManifest, rootPackageManifest) {
|
|
1018
|
+
/**
|
|
1019
|
+
* Bun supports `overrides` at the top level of package.json (same as npm).
|
|
1020
|
+
* Read from the root manifest and set them on the output manifest so that
|
|
1021
|
+
* `bun install --frozen-lockfile` succeeds.
|
|
1022
|
+
*/
|
|
1023
|
+
const overrides = rootPackageManifest["overrides"];
|
|
1024
|
+
if (!overrides) return targetPackageManifest;
|
|
1025
|
+
return {
|
|
1026
|
+
...targetPackageManifest,
|
|
1027
|
+
overrides
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
/** Adopt pnpm-specific fields from the root manifest */
|
|
1031
|
+
function adoptPnpmFieldsOnly(targetPackageManifest, rootPackageManifest) {
|
|
1032
|
+
const { overrides, onlyBuiltDependencies, ignoredBuiltDependencies } = rootPackageManifest.pnpm || {};
|
|
1014
1033
|
/** If no pnpm fields are present, return the original manifest */
|
|
1015
1034
|
if (!overrides && !onlyBuiltDependencies && !ignoredBuiltDependencies) return targetPackageManifest;
|
|
1016
1035
|
const pnpmConfig = {};
|
|
@@ -1022,7 +1041,6 @@ async function adoptPnpmFieldsFromRoot(targetPackageManifest, workspaceRootDir)
|
|
|
1022
1041
|
pnpm: pnpmConfig
|
|
1023
1042
|
};
|
|
1024
1043
|
}
|
|
1025
|
-
|
|
1026
1044
|
//#endregion
|
|
1027
1045
|
//#region src/lib/manifest/adapt-target-package-manifest.ts
|
|
1028
1046
|
/**
|
|
@@ -1051,9 +1069,13 @@ async function adaptTargetPackageManifest({ manifest, packagesRegistry, workspac
|
|
|
1051
1069
|
scripts: pickFromScripts ? pick(manifest.scripts ?? {}, pickFromScripts) : omitFromScripts ? omit(manifest.scripts ?? {}, omitFromScripts) : {}
|
|
1052
1070
|
};
|
|
1053
1071
|
}
|
|
1054
|
-
|
|
1055
1072
|
//#endregion
|
|
1056
1073
|
//#region src/lib/manifest/validate-manifest.ts
|
|
1074
|
+
/** Maps field names to their documentation URLs */
|
|
1075
|
+
const fieldDocUrls = {
|
|
1076
|
+
version: "https://isolate-package.codecompose.dev/getting-started#define-version-field-in-each-package-manifest",
|
|
1077
|
+
files: "https://isolate-package.codecompose.dev/getting-started#define-files-field-in-each-package-manifest"
|
|
1078
|
+
};
|
|
1057
1079
|
/**
|
|
1058
1080
|
* Validate that mandatory fields are present in the package manifest. These
|
|
1059
1081
|
* fields are required for the isolate process to work properly.
|
|
@@ -1075,13 +1097,13 @@ function validateManifestMandatoryFields(manifest, packagePath, requireFilesFiel
|
|
|
1075
1097
|
*/
|
|
1076
1098
|
if (requireFilesField && (!manifest.files || !Array.isArray(manifest.files) || manifest.files.length === 0)) missingFields.push("files");
|
|
1077
1099
|
if (missingFields.length > 0) {
|
|
1078
|
-
const
|
|
1100
|
+
const field = missingFields[0];
|
|
1101
|
+
const errorMessage = missingFields.length === 1 ? `Package at ${packagePath} is missing the "${field}" field in its package.json. See ${fieldDocUrls[field] ?? "https://isolate-package.codecompose.dev/getting-started#prerequisites"}` : `Package at ${packagePath} is missing mandatory fields in its package.json: ${missingFields.join(", ")}. See https://isolate-package.codecompose.dev/getting-started#prerequisites`;
|
|
1079
1102
|
log.error(errorMessage);
|
|
1080
1103
|
throw new Error(errorMessage);
|
|
1081
1104
|
}
|
|
1082
1105
|
log.debug(`Validated mandatory fields for package at ${packagePath}`);
|
|
1083
1106
|
}
|
|
1084
|
-
|
|
1085
1107
|
//#endregion
|
|
1086
1108
|
//#region src/lib/output/get-build-output-dir.ts
|
|
1087
1109
|
async function getBuildOutputDir({ targetPackageDir, buildDirName, tsconfigPath }) {
|
|
@@ -1106,7 +1128,6 @@ async function getBuildOutputDir({ targetPackageDir, buildDirName, tsconfigPath
|
|
|
1106
1128
|
`);
|
|
1107
1129
|
}
|
|
1108
1130
|
}
|
|
1109
|
-
|
|
1110
1131
|
//#endregion
|
|
1111
1132
|
//#region src/lib/output/pack-dependencies.ts
|
|
1112
1133
|
/**
|
|
@@ -1134,7 +1155,6 @@ async function packDependencies({ packagesRegistry, internalPackageNames, packDe
|
|
|
1134
1155
|
}
|
|
1135
1156
|
return packedFileByName;
|
|
1136
1157
|
}
|
|
1137
|
-
|
|
1138
1158
|
//#endregion
|
|
1139
1159
|
//#region src/lib/output/process-build-output-files.ts
|
|
1140
1160
|
const TIMEOUT_MS = 5e3;
|
|
@@ -1152,7 +1172,6 @@ async function processBuildOutputFiles({ targetPackageDir, tmpDir, isolateDir })
|
|
|
1152
1172
|
await unpack(packedFilePath, unpackDir);
|
|
1153
1173
|
await fs.copy(path.join(unpackDir, "package"), isolateDir);
|
|
1154
1174
|
}
|
|
1155
|
-
|
|
1156
1175
|
//#endregion
|
|
1157
1176
|
//#region src/lib/output/unpack-dependencies.ts
|
|
1158
1177
|
async function unpackDependencies(packedFilesByName, packagesRegistry, tmpDir, isolateDir) {
|
|
@@ -1168,19 +1187,32 @@ async function unpackDependencies(packedFilesByName, packagesRegistry, tmpDir, i
|
|
|
1168
1187
|
log.debug(`Moved package files to ${getIsolateRelativeLogPath(destinationDir, isolateDir)}`);
|
|
1169
1188
|
}));
|
|
1170
1189
|
}
|
|
1171
|
-
|
|
1172
1190
|
//#endregion
|
|
1173
1191
|
//#region src/lib/patches/copy-patches.ts
|
|
1174
1192
|
async function copyPatches({ workspaceRootDir, targetPackageManifest, isolateDir, includeDevDependencies }) {
|
|
1175
1193
|
const log = useLogger();
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1194
|
+
const { name: packageManagerName } = usePackageManager();
|
|
1195
|
+
let patchedDependencies;
|
|
1196
|
+
/**
|
|
1197
|
+
* Only try reading pnpm-workspace.yaml for pnpm workspaces. Bun workspaces
|
|
1198
|
+
* don't have this file and the warning would be noisy.
|
|
1199
|
+
*/
|
|
1200
|
+
if (packageManagerName === "pnpm") try {
|
|
1201
|
+
patchedDependencies = readTypedYamlSync(path.join(workspaceRootDir, "pnpm-workspace.yaml"))?.patchedDependencies;
|
|
1179
1202
|
} catch (error) {
|
|
1180
|
-
log.warn(`Could not read workspace
|
|
1181
|
-
|
|
1203
|
+
log.warn(`Could not read pnpm-workspace.yaml: ${error instanceof Error ? error.message : String(error)}`);
|
|
1204
|
+
}
|
|
1205
|
+
if (!patchedDependencies || Object.keys(patchedDependencies).length === 0) {
|
|
1206
|
+
if (packageManagerName === "pnpm") log.debug("No patched dependencies found in pnpm-workspace.yaml; Falling back to workspace root package.json");
|
|
1207
|
+
else log.debug("Reading patched dependencies from workspace root package.json");
|
|
1208
|
+
try {
|
|
1209
|
+
const workspaceRootManifest = await readTypedJson(path.join(workspaceRootDir, "package.json"));
|
|
1210
|
+
/** PNPM stores patches under pnpm.patchedDependencies, Bun at the top level */
|
|
1211
|
+
patchedDependencies = workspaceRootManifest?.pnpm?.patchedDependencies ?? workspaceRootManifest?.patchedDependencies;
|
|
1212
|
+
} catch (error) {
|
|
1213
|
+
log.warn(`Could not read workspace root package.json: ${error instanceof Error ? error.message : String(error)}`);
|
|
1214
|
+
}
|
|
1182
1215
|
}
|
|
1183
|
-
const patchedDependencies = workspaceRootManifest.pnpm?.patchedDependencies;
|
|
1184
1216
|
if (!patchedDependencies || Object.keys(patchedDependencies).length === 0) {
|
|
1185
1217
|
log.debug("No patched dependencies found in workspace root package.json");
|
|
1186
1218
|
return {};
|
|
@@ -1192,8 +1224,11 @@ async function copyPatches({ workspaceRootDir, targetPackageManifest, isolateDir
|
|
|
1192
1224
|
includeDevDependencies
|
|
1193
1225
|
});
|
|
1194
1226
|
if (!filteredPatches) return {};
|
|
1195
|
-
/**
|
|
1196
|
-
|
|
1227
|
+
/**
|
|
1228
|
+
* Read the pnpm lockfile to get patch hashes. Bun doesn't store hashes in
|
|
1229
|
+
* its lockfile so we skip this for Bun.
|
|
1230
|
+
*/
|
|
1231
|
+
const lockfilePatchedDependencies = packageManagerName === "pnpm" ? await readLockfilePatchedDependencies(workspaceRootDir) : void 0;
|
|
1197
1232
|
const copiedPatches = {};
|
|
1198
1233
|
for (const [packageSpec, patchPath] of Object.entries(filteredPatches)) {
|
|
1199
1234
|
const sourcePatchPath = path.resolve(workspaceRootDir, patchPath);
|
|
@@ -1207,7 +1242,7 @@ async function copyPatches({ workspaceRootDir, targetPackageManifest, isolateDir
|
|
|
1207
1242
|
await fs.copy(sourcePatchPath, targetPatchPath);
|
|
1208
1243
|
log.debug(`Copied patch for ${packageSpec}: ${patchPath}`);
|
|
1209
1244
|
const hash = (lockfilePatchedDependencies?.[packageSpec])?.hash ?? "";
|
|
1210
|
-
if (!hash) log.warn(`No hash found for patch ${packageSpec} in lockfile`);
|
|
1245
|
+
if (packageManagerName === "pnpm" && !hash) log.warn(`No hash found for patch ${packageSpec} in lockfile`);
|
|
1211
1246
|
copiedPatches[packageSpec] = {
|
|
1212
1247
|
path: patchPath,
|
|
1213
1248
|
hash
|
|
@@ -1231,7 +1266,6 @@ async function readLockfilePatchedDependencies(workspaceRootDir) {
|
|
|
1231
1266
|
return;
|
|
1232
1267
|
}
|
|
1233
1268
|
}
|
|
1234
|
-
|
|
1235
1269
|
//#endregion
|
|
1236
1270
|
//#region src/lib/registry/helpers/find-packages-globs.ts
|
|
1237
1271
|
/**
|
|
@@ -1270,7 +1304,6 @@ function findPackagesGlobs(workspaceRootDir) {
|
|
|
1270
1304
|
}
|
|
1271
1305
|
}
|
|
1272
1306
|
}
|
|
1273
|
-
|
|
1274
1307
|
//#endregion
|
|
1275
1308
|
//#region src/lib/registry/create-packages-registry.ts
|
|
1276
1309
|
/**
|
|
@@ -1305,7 +1338,6 @@ function listWorkspacePackages(workspacePackagesOverride, workspaceRootDir) {
|
|
|
1305
1338
|
if (isRushWorkspace(workspaceRootDir)) return readTypedJsonSync(path.join(workspaceRootDir, "rush.json")).projects.map(({ projectFolder }) => projectFolder);
|
|
1306
1339
|
else return (workspacePackagesOverride ?? findPackagesGlobs(workspaceRootDir)).flatMap((glob) => globSync(glob, { cwd: workspaceRootDir })).filter((dir) => fs.lstatSync(path.join(workspaceRootDir, dir)).isDirectory());
|
|
1307
1340
|
}
|
|
1308
|
-
|
|
1309
1341
|
//#endregion
|
|
1310
1342
|
//#region src/lib/registry/list-internal-packages.ts
|
|
1311
1343
|
/**
|
|
@@ -1350,7 +1382,6 @@ function listInternalPackages(manifest, packagesRegistry, { includeDevDependenci
|
|
|
1350
1382
|
const result = collectInternalPackages(manifest, packagesRegistry, includeDevDependencies, /* @__PURE__ */ new Set(), new Set(manifest.name ? [manifest.name] : []));
|
|
1351
1383
|
return [...new Set(result)];
|
|
1352
1384
|
}
|
|
1353
|
-
|
|
1354
1385
|
//#endregion
|
|
1355
1386
|
//#region src/isolate.ts
|
|
1356
1387
|
const __dirname = getDirname(import.meta.url);
|
|
@@ -1403,6 +1434,21 @@ function createIsolator(config) {
|
|
|
1403
1434
|
const isProductionDependency = productionInternalPackageNames.includes(packageName);
|
|
1404
1435
|
validateManifestMandatoryFields(packageDef.manifest, getRootRelativeLogPath(packageDef.absoluteDir, workspaceRootDir), isProductionDependency);
|
|
1405
1436
|
}
|
|
1437
|
+
/**
|
|
1438
|
+
* Validate that workspace dev dependencies of all packages being packed
|
|
1439
|
+
* have a version field. Even when dev dependencies are not included in the
|
|
1440
|
+
* isolation output, pnpm pack resolves workspace:* specifiers and requires
|
|
1441
|
+
* the version field to be present.
|
|
1442
|
+
*/
|
|
1443
|
+
const validatedPackageNames = new Set(internalPackageNames);
|
|
1444
|
+
const manifestsToPack = [targetPackageManifest, ...internalPackageNames.map((name) => got(packagesRegistry, name).manifest)];
|
|
1445
|
+
for (const manifest of manifestsToPack) for (const depName of Object.keys(manifest.devDependencies ?? {})) {
|
|
1446
|
+
if (validatedPackageNames.has(depName)) continue;
|
|
1447
|
+
const packageDef = packagesRegistry[depName];
|
|
1448
|
+
if (!packageDef) continue;
|
|
1449
|
+
validateManifestMandatoryFields(packageDef.manifest, getRootRelativeLogPath(packageDef.absoluteDir, workspaceRootDir), false);
|
|
1450
|
+
validatedPackageNames.add(depName);
|
|
1451
|
+
}
|
|
1406
1452
|
await unpackDependencies(await packDependencies({
|
|
1407
1453
|
internalPackageNames,
|
|
1408
1454
|
packagesRegistry,
|
|
@@ -1456,12 +1502,17 @@ function createIsolator(config) {
|
|
|
1456
1502
|
if (hasCopiedPatches || usedFallbackToNpm) {
|
|
1457
1503
|
const manifest = await readManifest(isolateDir);
|
|
1458
1504
|
if (hasCopiedPatches) {
|
|
1459
|
-
if (!manifest.pnpm) manifest.pnpm = {};
|
|
1460
1505
|
/**
|
|
1461
1506
|
* Extract just the paths for the manifest (lockfile needs full
|
|
1462
|
-
* PatchFile)
|
|
1507
|
+
* PatchFile). PNPM stores patches under pnpm.patchedDependencies, Bun
|
|
1508
|
+
* at the top level.
|
|
1463
1509
|
*/
|
|
1464
|
-
|
|
1510
|
+
const patchEntries = Object.fromEntries(Object.entries(copiedPatches).map(([spec, patchFile]) => [spec, patchFile.path]));
|
|
1511
|
+
if (packageManager.name === "bun") manifest.patchedDependencies = patchEntries;
|
|
1512
|
+
else {
|
|
1513
|
+
if (!manifest.pnpm) manifest.pnpm = {};
|
|
1514
|
+
manifest.pnpm.patchedDependencies = patchEntries;
|
|
1515
|
+
}
|
|
1465
1516
|
log.debug(`Added ${Object.keys(copiedPatches).length} patches to isolated package.json`);
|
|
1466
1517
|
}
|
|
1467
1518
|
if (usedFallbackToNpm) manifest.packageManager = `npm@${getVersion("npm")}`;
|
|
@@ -1521,7 +1572,7 @@ function createIsolator(config) {
|
|
|
1521
1572
|
async function isolate(config) {
|
|
1522
1573
|
return createIsolator(config)();
|
|
1523
1574
|
}
|
|
1524
|
-
|
|
1525
1575
|
//#endregion
|
|
1526
1576
|
export { loadConfigFromFile as a, detectPackageManager as c, defineConfig as i, readTypedJson as l, listInternalPackages as n, resolveConfig as o, createPackagesRegistry as r, resolveWorkspacePaths as s, isolate as t, filterObjectUndefined as u };
|
|
1527
|
-
|
|
1577
|
+
|
|
1578
|
+
//# sourceMappingURL=isolate-DtNAHzfa.mjs.map
|