isolate-package 1.21.0-1 → 1.23.0-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.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  // src/isolate.ts
2
2
  import fs16 from "fs-extra";
3
- import assert6 from "node:assert";
4
- import path20 from "node:path";
3
+ import assert7 from "node:assert";
4
+ import path21 from "node:path";
5
5
  import { unique as unique2 } from "remeda";
6
6
 
7
7
  // src/lib/config.ts
8
8
  import fs8 from "fs-extra";
9
- import assert2 from "node:assert";
9
+ import assert3 from "node:assert";
10
10
  import path6 from "node:path";
11
11
  import { isEmpty } from "remeda";
12
12
 
@@ -81,17 +81,6 @@ function toErrorWithMessage(maybeError) {
81
81
  }
82
82
  }
83
83
 
84
- // src/lib/utils/get-relative-path.ts
85
- import { join } from "node:path";
86
- function getRootRelativePath(path21, rootPath) {
87
- const strippedPath = path21.replace(rootPath, "");
88
- return join("(root)", strippedPath);
89
- }
90
- function getIsolateRelativePath(path21, isolatePath) {
91
- const strippedPath = path21.replace(isolatePath, "");
92
- return join("(isolate)", strippedPath);
93
- }
94
-
95
84
  // src/lib/utils/inspect-value.ts
96
85
  import { inspect } from "node:util";
97
86
  function inspectValue(value) {
@@ -135,7 +124,19 @@ async function readTypedJson(filePath) {
135
124
  }
136
125
  }
137
126
 
127
+ // src/lib/utils/log-paths.ts
128
+ import { join } from "node:path";
129
+ function getRootRelativeLogPath(path22, rootPath) {
130
+ const strippedPath = path22.replace(rootPath, "");
131
+ return join("(root)", strippedPath);
132
+ }
133
+ function getIsolateRelativeLogPath(path22, isolatePath) {
134
+ const strippedPath = path22.replace(isolatePath, "");
135
+ return join("(isolate)", strippedPath);
136
+ }
137
+
138
138
  // src/lib/utils/pack.ts
139
+ import assert2 from "node:assert";
139
140
  import { exec } from "node:child_process";
140
141
  import fs5 from "node:fs";
141
142
  import path5 from "node:path";
@@ -288,10 +289,9 @@ async function pack(srcDir, dstDir) {
288
289
  );
289
290
  });
290
291
  const lastLine = stdout.trim().split("\n").at(-1);
291
- if (!lastLine) {
292
- throw new Error(`Failed to parse last line from stdout: ${stdout.trim()}`);
293
- }
292
+ assert2(lastLine, `Failed to parse last line from stdout: ${stdout.trim()}`);
294
293
  const fileName = path5.basename(lastLine);
294
+ assert2(fileName, `Failed to parse file name from: ${lastLine}`);
295
295
  const filePath = path5.join(dstDir, fileName);
296
296
  if (!fs5.existsSync(filePath)) {
297
297
  log.error(
@@ -442,7 +442,7 @@ async function generateNpmLockfile({
442
442
  }
443
443
 
444
444
  // src/lib/lockfile/helpers/generate-pnpm-lockfile.ts
445
- import assert3 from "node:assert";
445
+ import assert4 from "node:assert";
446
446
  import path9 from "node:path";
447
447
  import {
448
448
  getLockfileImporterId as getLockfileImporterId_v8,
@@ -484,10 +484,7 @@ function pnpmMapDependenciesLinks(importerPath, def, directoryByPackageName) {
484
484
  if (!value.startsWith("link:")) {
485
485
  return value;
486
486
  }
487
- const relativePath = path8.relative(
488
- importerPath,
489
- directoryByPackageName[key]
490
- );
487
+ const relativePath = path8.relative(importerPath, directoryByPackageName[key]).replace(path8.sep, path8.posix.sep);
491
488
  return relativePath.startsWith(".") ? `link:${relativePath}` : `link:./${relativePath}`;
492
489
  });
493
490
  }
@@ -519,12 +516,12 @@ async function generatePnpmLockfile({
519
516
  ignoreIncompatible: false
520
517
  }
521
518
  );
522
- assert3(lockfile, `No input lockfile found at ${workspaceRootDir}`);
519
+ assert4(lockfile, `No input lockfile found at ${workspaceRootDir}`);
523
520
  const targetImporterId = useVersion9 ? getLockfileImporterId_v9(workspaceRootDir, targetPackageDir) : getLockfileImporterId_v8(workspaceRootDir, targetPackageDir);
524
521
  const directoryByPackageName = Object.fromEntries(
525
522
  internalDepPackageNames.map((name) => {
526
523
  const pkg = packagesRegistry[name];
527
- assert3(pkg, `Package ${name} not found in packages registry`);
524
+ assert4(pkg, `Package ${name} not found in packages registry`);
528
525
  return [name, pkg.rootRelativeDir];
529
526
  })
530
527
  );
@@ -535,7 +532,17 @@ async function generatePnpmLockfile({
535
532
  * importer ids in the context of a lockfile.
536
533
  */
537
534
  ...Object.values(directoryByPackageName)
538
- ];
535
+ /**
536
+ * Split the path by the OS separator and join it back with the POSIX
537
+ * separator.
538
+ *
539
+ * The importerIds are built from directory names, so Windows Git Bash
540
+ * environments will have double backslashes in their ids:
541
+ * "packages\common" vs. "packages/common". Without this split & join, any
542
+ * packages not on the top-level will have ill-formatted importerIds and
543
+ * their entries will be missing from the lockfile.importers list.
544
+ */
545
+ ].map((x) => x.split(path9.sep).join(path9.posix.sep));
539
546
  log.debug("Relevant importer ids:", relevantImporterIds);
540
547
  const relevantImporterIdsWithPrefix = relevantImporterIds.map(
541
548
  (x) => isRush ? `../../${x}` : x
@@ -854,7 +861,7 @@ async function adaptTargetPackageManifest({
854
861
  }
855
862
 
856
863
  // src/lib/output/get-build-output-dir.ts
857
- import fs12 from "fs-extra";
864
+ import { getTsconfig } from "get-tsconfig";
858
865
  import path15 from "node:path";
859
866
  import outdent from "outdent";
860
867
  async function getBuildOutputDir(targetPackageDir) {
@@ -865,10 +872,10 @@ async function getBuildOutputDir(targetPackageDir) {
865
872
  return path15.join(targetPackageDir, config.buildDirName);
866
873
  }
867
874
  const tsconfigPath = path15.join(targetPackageDir, config.tsconfigPath);
868
- if (fs12.existsSync(tsconfigPath)) {
869
- log.debug("Found tsconfig at:", config.tsconfigPath);
870
- const tsconfig = await readTypedJson(tsconfigPath);
871
- const outDir = tsconfig.compilerOptions?.outDir;
875
+ const tsconfig = getTsconfig(tsconfigPath);
876
+ if (tsconfig) {
877
+ log.debug("Found tsconfig at:", tsconfig.path);
878
+ const outDir = tsconfig.config.compilerOptions?.outDir;
872
879
  if (outDir) {
873
880
  return path15.join(targetPackageDir, outDir);
874
881
  } else {
@@ -884,8 +891,62 @@ async function getBuildOutputDir(targetPackageDir) {
884
891
  }
885
892
  }
886
893
 
894
+ // src/lib/output/handle-firebase-config.ts
895
+ import fs12 from "fs-extra";
896
+ import path16 from "node:path";
897
+ import { omit as omit3 } from "remeda";
898
+ async function handleFirebaseConfig({
899
+ targetPackageDir,
900
+ workspaceRootDir,
901
+ isolateDir
902
+ }) {
903
+ const log = useLogger();
904
+ const targetHasFirebaseConfig = fs12.existsSync(
905
+ path16.join(targetPackageDir, "firebase.json")
906
+ );
907
+ if (targetHasFirebaseConfig) {
908
+ const firebaseConfig = await readTypedJson(path16.join(targetPackageDir, "firebase.json"));
909
+ if (firebaseConfig.functions.predeploy) {
910
+ log.warn(
911
+ "The firebase predeploy phase is not supported by isolate-package and will be ignored. Please execute the predeploy commands before executing isolate."
912
+ );
913
+ }
914
+ fs12.writeJsonSync(path16.join(isolateDir, "firebase.json"), {
915
+ ...firebaseConfig,
916
+ functions: omit3(firebaseConfig.functions, ["predeploy"])
917
+ });
918
+ log.info("Included firebase config from the target package");
919
+ }
920
+ if (!targetHasFirebaseConfig) {
921
+ const rootHasFirebaseConfig = fs12.existsSync(
922
+ path16.join(workspaceRootDir, "firebase.json")
923
+ );
924
+ if (rootHasFirebaseConfig) {
925
+ log.debug("Attempting to extract firebase config from the root");
926
+ const firebaseConfig = await readTypedJson(path16.join(workspaceRootDir, "firebase.json"));
927
+ const targetFolderName = path16.basename(targetPackageDir);
928
+ const extractedFunctionsConfig = firebaseConfig.functions.find(
929
+ (x) => x.source.includes(targetFolderName)
930
+ );
931
+ if (extractedFunctionsConfig) {
932
+ fs12.writeJsonSync(path16.join(isolateDir, "firebase.json"), {
933
+ functions: {
934
+ ...extractedFunctionsConfig,
935
+ source: "."
936
+ }
937
+ });
938
+ log.info("Included firebase config extracted from the root");
939
+ } else {
940
+ log.debug(
941
+ `No functions config found for ${targetFolderName} in the root firebase.json`
942
+ );
943
+ }
944
+ }
945
+ }
946
+ }
947
+
887
948
  // src/lib/output/pack-dependencies.ts
888
- import assert4 from "node:assert";
949
+ import assert5 from "node:assert";
889
950
  async function packDependencies({
890
951
  /** All packages found in the monorepo by workspaces declaration */
891
952
  packagesRegistry,
@@ -903,7 +964,7 @@ async function packDependencies({
903
964
  const packedFileByName = {};
904
965
  for (const dependency of internalPackageNames) {
905
966
  const def = packagesRegistry[dependency];
906
- assert4(dependency, `Failed to find package definition for ${dependency}`);
967
+ assert5(dependency, `Failed to find package definition for ${dependency}`);
907
968
  const { name } = def.manifest;
908
969
  if (packedFileByName[name]) {
909
970
  log.debug(`Skipping ${name} because it has already been packed`);
@@ -916,7 +977,7 @@ async function packDependencies({
916
977
 
917
978
  // src/lib/output/process-build-output-files.ts
918
979
  import fs13 from "fs-extra";
919
- import path16 from "node:path";
980
+ import path17 from "node:path";
920
981
  var TIMEOUT_MS = 5e3;
921
982
  async function processBuildOutputFiles({
922
983
  targetPackageDir,
@@ -925,7 +986,7 @@ async function processBuildOutputFiles({
925
986
  }) {
926
987
  const log = useLogger();
927
988
  const packedFilePath = await pack(targetPackageDir, tmpDir);
928
- const unpackDir = path16.join(tmpDir, "target");
989
+ const unpackDir = path17.join(tmpDir, "target");
929
990
  const now = Date.now();
930
991
  let isWaitingYet = false;
931
992
  while (!fs13.existsSync(packedFilePath) && Date.now() - now < TIMEOUT_MS) {
@@ -936,19 +997,19 @@ async function processBuildOutputFiles({
936
997
  await new Promise((resolve) => setTimeout(resolve, 100));
937
998
  }
938
999
  await unpack(packedFilePath, unpackDir);
939
- await fs13.copy(path16.join(unpackDir, "package"), isolateDir);
1000
+ await fs13.copy(path17.join(unpackDir, "package"), isolateDir);
940
1001
  }
941
1002
 
942
1003
  // src/lib/output/unpack-dependencies.ts
943
1004
  import fs14 from "fs-extra";
944
- import path17, { join as join2 } from "node:path";
1005
+ import path18, { join as join2 } from "node:path";
945
1006
  async function unpackDependencies(packedFilesByName, packagesRegistry, tmpDir, isolateDir) {
946
1007
  const log = useLogger();
947
1008
  await Promise.all(
948
1009
  Object.entries(packedFilesByName).map(async ([packageName, filePath]) => {
949
1010
  const dir = packagesRegistry[packageName].rootRelativeDir;
950
1011
  const unpackDir = join2(tmpDir, dir);
951
- log.debug("Unpacking", `(temp)/${path17.basename(filePath)}`);
1012
+ log.debug("Unpacking", `(temp)/${path18.basename(filePath)}`);
952
1013
  await unpack(filePath, unpackDir);
953
1014
  const destinationDir = join2(isolateDir, dir);
954
1015
  await fs14.ensureDir(destinationDir);
@@ -956,7 +1017,7 @@ async function unpackDependencies(packedFilesByName, packagesRegistry, tmpDir, i
956
1017
  overwrite: true
957
1018
  });
958
1019
  log.debug(
959
- `Moved package files to ${getIsolateRelativePath(
1020
+ `Moved package files to ${getIsolateRelativeLogPath(
960
1021
  destinationDir,
961
1022
  isolateDir
962
1023
  )}`
@@ -968,18 +1029,18 @@ async function unpackDependencies(packedFilesByName, packagesRegistry, tmpDir, i
968
1029
  // src/lib/registry/create-packages-registry.ts
969
1030
  import fs15 from "fs-extra";
970
1031
  import { globSync } from "glob";
971
- import path19 from "node:path";
1032
+ import path20 from "node:path";
972
1033
 
973
1034
  // src/lib/registry/helpers/find-packages-globs.ts
974
- import assert5 from "node:assert";
975
- import path18 from "node:path";
1035
+ import assert6 from "node:assert";
1036
+ import path19 from "node:path";
976
1037
  function findPackagesGlobs(workspaceRootDir) {
977
1038
  const log = useLogger();
978
1039
  const packageManager2 = usePackageManager();
979
1040
  switch (packageManager2.name) {
980
1041
  case "pnpm": {
981
1042
  const { packages: globs } = readTypedYamlSync(
982
- path18.join(workspaceRootDir, "pnpm-workspace.yaml")
1043
+ path19.join(workspaceRootDir, "pnpm-workspace.yaml")
983
1044
  );
984
1045
  log.debug("Detected pnpm packages globs:", inspectValue(globs));
985
1046
  return globs;
@@ -987,7 +1048,7 @@ function findPackagesGlobs(workspaceRootDir) {
987
1048
  case "bun":
988
1049
  case "yarn":
989
1050
  case "npm": {
990
- const workspaceRootManifestPath = path18.join(
1051
+ const workspaceRootManifestPath = path19.join(
991
1052
  workspaceRootDir,
992
1053
  "package.json"
993
1054
  );
@@ -1003,7 +1064,7 @@ function findPackagesGlobs(workspaceRootDir) {
1003
1064
  return workspaces;
1004
1065
  } else {
1005
1066
  const workspacesObject = workspaces;
1006
- assert5(
1067
+ assert6(
1007
1068
  workspacesObject.packages,
1008
1069
  "workspaces.packages must be an array"
1009
1070
  );
@@ -1027,8 +1088,8 @@ async function createPackagesRegistry(workspaceRootDir, workspacePackagesOverrid
1027
1088
  );
1028
1089
  const registry = (await Promise.all(
1029
1090
  allPackages.map(async (rootRelativeDir) => {
1030
- const absoluteDir = path19.join(workspaceRootDir, rootRelativeDir);
1031
- const manifestPath = path19.join(absoluteDir, "package.json");
1091
+ const absoluteDir = path20.join(workspaceRootDir, rootRelativeDir);
1092
+ const manifestPath = path20.join(absoluteDir, "package.json");
1032
1093
  if (!fs15.existsSync(manifestPath)) {
1033
1094
  log.warn(
1034
1095
  `Ignoring directory ${rootRelativeDir} because it does not contain a package.json file`
@@ -1037,7 +1098,7 @@ async function createPackagesRegistry(workspaceRootDir, workspacePackagesOverrid
1037
1098
  } else {
1038
1099
  log.debug(`Registering package ${rootRelativeDir}`);
1039
1100
  const manifest = await readTypedJson(
1040
- path19.join(absoluteDir, "package.json")
1101
+ path20.join(absoluteDir, "package.json")
1041
1102
  );
1042
1103
  return {
1043
1104
  manifest,
@@ -1057,7 +1118,7 @@ async function createPackagesRegistry(workspaceRootDir, workspacePackagesOverrid
1057
1118
  function listWorkspacePackages(workspacePackagesOverride, workspaceRootDir) {
1058
1119
  if (isRushWorkspace(workspaceRootDir)) {
1059
1120
  const rushConfig = readTypedJsonSync(
1060
- path19.join(workspaceRootDir, "rush.json")
1121
+ path20.join(workspaceRootDir, "rush.json")
1061
1122
  );
1062
1123
  return rushConfig.projects.map(({ projectFolder }) => projectFolder);
1063
1124
  } else {
@@ -1101,35 +1162,35 @@ async function isolate(options = {}) {
1101
1162
  setLogLevel(config.logLevel);
1102
1163
  const log = useLogger();
1103
1164
  const { version: libraryVersion } = await readTypedJson(
1104
- path20.join(path20.join(__dirname, "..", "package.json"))
1165
+ path21.join(path21.join(__dirname, "..", "package.json"))
1105
1166
  );
1106
1167
  log.info("Using isolate-package version", libraryVersion);
1107
- const targetPackageDir = config.targetPackagePath ? path20.join(process.cwd(), config.targetPackagePath) : process.cwd();
1108
- const workspaceRootDir = config.targetPackagePath ? process.cwd() : path20.join(targetPackageDir, config.workspaceRoot);
1168
+ const targetPackageDir = config.targetPackagePath ? path21.join(process.cwd(), config.targetPackagePath) : process.cwd();
1169
+ const workspaceRootDir = config.targetPackagePath ? process.cwd() : path21.join(targetPackageDir, config.workspaceRoot);
1109
1170
  const buildOutputDir = await getBuildOutputDir(targetPackageDir);
1110
- assert6(
1171
+ assert7(
1111
1172
  fs16.existsSync(buildOutputDir),
1112
1173
  `Failed to find build output path at ${buildOutputDir}. Please make sure you build the source before isolating it.`
1113
1174
  );
1114
1175
  log.debug("Workspace root resolved to", workspaceRootDir);
1115
1176
  log.debug(
1116
1177
  "Isolate target package",
1117
- getRootRelativePath(targetPackageDir, workspaceRootDir)
1178
+ getRootRelativeLogPath(targetPackageDir, workspaceRootDir)
1118
1179
  );
1119
- const isolateDir = path20.join(targetPackageDir, config.isolateDirName);
1180
+ const isolateDir = path21.join(targetPackageDir, config.isolateDirName);
1120
1181
  log.debug(
1121
1182
  "Isolate output directory",
1122
- getRootRelativePath(isolateDir, workspaceRootDir)
1183
+ getRootRelativeLogPath(isolateDir, workspaceRootDir)
1123
1184
  );
1124
1185
  if (fs16.existsSync(isolateDir)) {
1125
1186
  await fs16.remove(isolateDir);
1126
1187
  log.debug("Cleaned the existing isolate output directory");
1127
1188
  }
1128
1189
  await fs16.ensureDir(isolateDir);
1129
- const tmpDir = path20.join(isolateDir, "__tmp");
1190
+ const tmpDir = path21.join(isolateDir, "__tmp");
1130
1191
  await fs16.ensureDir(tmpDir);
1131
1192
  const targetPackageManifest = await readTypedJson(
1132
- path20.join(targetPackageDir, "package.json")
1193
+ path21.join(targetPackageDir, "package.json")
1133
1194
  );
1134
1195
  const packageManager2 = detectPackageManager(workspaceRootDir);
1135
1196
  log.debug(
@@ -1197,30 +1258,35 @@ async function isolate(options = {}) {
1197
1258
  if (isRushWorkspace(workspaceRootDir)) {
1198
1259
  const packagesFolderNames = unique2(
1199
1260
  internalPackageNames.map(
1200
- (name) => path20.parse(packagesRegistry[name].rootRelativeDir).dir
1261
+ (name) => path21.parse(packagesRegistry[name].rootRelativeDir).dir
1201
1262
  )
1202
1263
  );
1203
1264
  log.debug("Generating pnpm-workspace.yaml for Rush workspace");
1204
1265
  log.debug("Packages folder names:", packagesFolderNames);
1205
- const packages = packagesFolderNames.map((x) => path20.join(x, "/*"));
1206
- await writeTypedYamlSync(path20.join(isolateDir, "pnpm-workspace.yaml"), {
1266
+ const packages = packagesFolderNames.map((x) => path21.join(x, "/*"));
1267
+ await writeTypedYamlSync(path21.join(isolateDir, "pnpm-workspace.yaml"), {
1207
1268
  packages
1208
1269
  });
1209
1270
  } else {
1210
1271
  fs16.copyFileSync(
1211
- path20.join(workspaceRootDir, "pnpm-workspace.yaml"),
1212
- path20.join(isolateDir, "pnpm-workspace.yaml")
1272
+ path21.join(workspaceRootDir, "pnpm-workspace.yaml"),
1273
+ path21.join(isolateDir, "pnpm-workspace.yaml")
1213
1274
  );
1214
1275
  }
1215
1276
  }
1216
- const npmrcPath = path20.join(workspaceRootDir, ".npmrc");
1277
+ const npmrcPath = path21.join(workspaceRootDir, ".npmrc");
1217
1278
  if (fs16.existsSync(npmrcPath)) {
1218
- fs16.copyFileSync(npmrcPath, path20.join(isolateDir, ".npmrc"));
1279
+ fs16.copyFileSync(npmrcPath, path21.join(isolateDir, ".npmrc"));
1219
1280
  log.debug("Copied .npmrc file to the isolate output");
1220
1281
  }
1282
+ await handleFirebaseConfig({
1283
+ targetPackageDir,
1284
+ workspaceRootDir,
1285
+ isolateDir
1286
+ });
1221
1287
  log.debug(
1222
1288
  "Deleting temp directory",
1223
- getRootRelativePath(tmpDir, workspaceRootDir)
1289
+ getRootRelativeLogPath(tmpDir, workspaceRootDir)
1224
1290
  );
1225
1291
  await fs16.remove(tmpDir);
1226
1292
  log.info("Isolate completed at", isolateDir);