unpackDetector.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.detectUnpackedDirs = exports.isLibOrExe = void 0;
  4. const bluebird_lst_1 = require("bluebird-lst");
  5. const builder_util_1 = require("builder-util");
  6. const fs_1 = require("builder-util/out/fs");
  7. const fs_extra_1 = require("fs-extra");
  8. const isbinaryfile_1 = require("isbinaryfile");
  9. const path = require("path");
  10. const fileTransformer_1 = require("../fileTransformer");
  11. const appFileCopier_1 = require("../util/appFileCopier");
  12. function addValue(map, key, value) {
  13. let list = map.get(key);
  14. if (list == null) {
  15. list = [value];
  16. map.set(key, list);
  17. }
  18. else {
  19. list.push(value);
  20. }
  21. }
  22. function isLibOrExe(file) {
  23. return file.endsWith(".dll") || file.endsWith(".exe") || file.endsWith(".dylib") || file.endsWith(".so");
  24. }
  25. exports.isLibOrExe = isLibOrExe;
  26. /** @internal */
  27. async function detectUnpackedDirs(fileSet, autoUnpackDirs, unpackedDest, rootForAppFilesWithoutAsar) {
  28. const dirToCreate = new Map();
  29. const metadata = fileSet.metadata;
  30. function addParents(child, root) {
  31. child = path.dirname(child);
  32. if (autoUnpackDirs.has(child)) {
  33. return;
  34. }
  35. do {
  36. autoUnpackDirs.add(child);
  37. const p = path.dirname(child);
  38. // create parent dir to be able to copy file later without directory existence check
  39. addValue(dirToCreate, p, path.basename(child));
  40. if (child === root || p === root || autoUnpackDirs.has(p)) {
  41. break;
  42. }
  43. child = p;
  44. } while (true);
  45. autoUnpackDirs.add(root);
  46. }
  47. for (let i = 0, n = fileSet.files.length; i < n; i++) {
  48. const file = fileSet.files[i];
  49. const index = file.lastIndexOf(fileTransformer_1.NODE_MODULES_PATTERN);
  50. if (index < 0) {
  51. continue;
  52. }
  53. let nextSlashIndex = file.indexOf(path.sep, index + fileTransformer_1.NODE_MODULES_PATTERN.length + 1);
  54. if (nextSlashIndex < 0) {
  55. continue;
  56. }
  57. if (file[index + fileTransformer_1.NODE_MODULES_PATTERN.length] === "@") {
  58. nextSlashIndex = file.indexOf(path.sep, nextSlashIndex + 1);
  59. }
  60. if (!metadata.get(file).isFile()) {
  61. continue;
  62. }
  63. const packageDir = file.substring(0, nextSlashIndex);
  64. const packageDirPathInArchive = path.relative(rootForAppFilesWithoutAsar, (0, appFileCopier_1.getDestinationPath)(packageDir, fileSet));
  65. const pathInArchive = path.relative(rootForAppFilesWithoutAsar, (0, appFileCopier_1.getDestinationPath)(file, fileSet));
  66. if (autoUnpackDirs.has(packageDirPathInArchive)) {
  67. // if package dir is unpacked, any file also unpacked
  68. addParents(pathInArchive, packageDirPathInArchive);
  69. continue;
  70. }
  71. // https://github.com/electron-userland/electron-builder/issues/2679
  72. let shouldUnpack = false;
  73. // ffprobe-static and ffmpeg-static are known packages to always unpack
  74. const moduleName = path.basename(packageDir);
  75. if (moduleName === "ffprobe-static" || moduleName === "ffmpeg-static" || isLibOrExe(file)) {
  76. shouldUnpack = true;
  77. }
  78. else if (!file.includes(".", nextSlashIndex)) {
  79. shouldUnpack = !!(0, isbinaryfile_1.isBinaryFileSync)(file);
  80. }
  81. if (!shouldUnpack) {
  82. continue;
  83. }
  84. if (builder_util_1.log.isDebugEnabled) {
  85. builder_util_1.log.debug({ file: pathInArchive, reason: "contains executable code" }, "not packed into asar archive");
  86. }
  87. addParents(pathInArchive, packageDirPathInArchive);
  88. }
  89. if (dirToCreate.size > 0) {
  90. await (0, fs_extra_1.mkdir)(`${unpackedDest + path.sep}node_modules`, { recursive: true });
  91. // child directories should be not created asynchronously - parent directories should be created first
  92. await bluebird_lst_1.default.map(dirToCreate.keys(), async (parentDir) => {
  93. const base = unpackedDest + path.sep + parentDir;
  94. await (0, fs_extra_1.mkdir)(base, { recursive: true });
  95. await bluebird_lst_1.default.each(dirToCreate.get(parentDir), (it) => {
  96. if (dirToCreate.has(parentDir + path.sep + it)) {
  97. // already created
  98. return null;
  99. }
  100. else {
  101. return (0, fs_extra_1.mkdir)(base + path.sep + it, { recursive: true });
  102. }
  103. });
  104. }, fs_1.CONCURRENCY);
  105. }
  106. }
  107. exports.detectUnpackedDirs = detectUnpackedDirs;
  108. //# sourceMappingURL=unpackDetector.js.map