@loongdotjs/electron-winstaller 5.4.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.
Files changed (92) hide show
  1. package/.circleci/config.yml +95 -0
  2. package/.editorconfig +9 -0
  3. package/.eslintrc.json +30 -0
  4. package/.github/CODEOWNERS +1 -0
  5. package/.github/dependabot.yml +6 -0
  6. package/.github/workflows/add-to-project.yml +29 -0
  7. package/.github/workflows/semantic.yml +26 -0
  8. package/.gitignore +18 -0
  9. package/.releaserc.json +9 -0
  10. package/LICENSE +20 -0
  11. package/README.md +189 -0
  12. package/lib/index.d.ts +20 -0
  13. package/lib/index.js +350 -0
  14. package/lib/index.js.map +1 -0
  15. package/lib/options.d.ts +219 -0
  16. package/lib/options.js +6 -0
  17. package/lib/options.js.map +1 -0
  18. package/lib/sign.d.ts +15 -0
  19. package/lib/sign.js +189 -0
  20. package/lib/sign.js.map +1 -0
  21. package/lib/spawn-promise.d.ts +3 -0
  22. package/lib/spawn-promise.js +54 -0
  23. package/lib/spawn-promise.js.map +1 -0
  24. package/lib/temp-utils.d.ts +3 -0
  25. package/lib/temp-utils.js +32 -0
  26. package/lib/temp-utils.js.map +1 -0
  27. package/package.json +69 -0
  28. package/resources/install-spinner.gif +0 -0
  29. package/script/select-7z-arch.js +33 -0
  30. package/spec/convert-version-spec.ts +14 -0
  31. package/spec/fixtures/app/LICENSE +0 -0
  32. package/spec/fixtures/app/chromiumcontent.dll +0 -0
  33. package/spec/fixtures/app/d3dcompiler_47.dll +0 -0
  34. package/spec/fixtures/app/ffmpegsumo.dll +0 -0
  35. package/spec/fixtures/app/icudtl.dat +0 -0
  36. package/spec/fixtures/app/locales/en.pak +0 -0
  37. package/spec/fixtures/app/msvcp120.dll +0 -0
  38. package/spec/fixtures/app/msvcr120.dll +0 -0
  39. package/spec/fixtures/app/myapp.exe +0 -0
  40. package/spec/fixtures/app/natives_blob.bin +0 -0
  41. package/spec/fixtures/app/resources/app/package.json +7 -0
  42. package/spec/fixtures/app/snapshot_blob.bin +0 -0
  43. package/spec/fixtures/app/swiftshader/libEGL.dll +0 -0
  44. package/spec/fixtures/app/swiftshader/libGLESv2.dll +0 -0
  45. package/spec/fixtures/app/vccorlib120.dll +0 -0
  46. package/spec/fixtures/app/vk_swiftshader.dll +0 -0
  47. package/spec/fixtures/app/vk_swiftshader_icd.json +0 -0
  48. package/spec/fixtures/app/xinput1_3.dll +0 -0
  49. package/spec/helpers/helpers.ts +12 -0
  50. package/spec/helpers/windowsSignHook.js +8 -0
  51. package/spec/installer-spec.ts +70 -0
  52. package/spec/sign-spec.ts +48 -0
  53. package/src/index.ts +271 -0
  54. package/src/options.ts +228 -0
  55. package/src/sign.ts +89 -0
  56. package/src/spawn-promise.ts +55 -0
  57. package/src/temp-utils.ts +9 -0
  58. package/template.nuspectemplate +30 -0
  59. package/tsconfig.json +21 -0
  60. package/typedoc.json +4 -0
  61. package/vendor/7z-arm64.dll +0 -0
  62. package/vendor/7z-arm64.exe +0 -0
  63. package/vendor/7z-x64.dll +0 -0
  64. package/vendor/7z-x64.exe +0 -0
  65. package/vendor/Microsoft.Deployment.Resources.dll +0 -0
  66. package/vendor/Microsoft.Deployment.WindowsInstaller.dll +0 -0
  67. package/vendor/Setup.exe +0 -0
  68. package/vendor/Setup.pdb +0 -0
  69. package/vendor/Squirrel-Mono.exe +0 -0
  70. package/vendor/Squirrel-Mono.pdb +0 -0
  71. package/vendor/Squirrel.com +0 -0
  72. package/vendor/Squirrel.exe +0 -0
  73. package/vendor/Squirrel.pdb +0 -0
  74. package/vendor/StubExecutable.exe +0 -0
  75. package/vendor/SyncReleases.exe +0 -0
  76. package/vendor/SyncReleases.pdb +0 -0
  77. package/vendor/WixNetFxExtension.dll +0 -0
  78. package/vendor/WriteZipToSetup.exe +0 -0
  79. package/vendor/WriteZipToSetup.pdb +0 -0
  80. package/vendor/candle.exe +0 -0
  81. package/vendor/candle.exe.config +18 -0
  82. package/vendor/darice.cub +0 -0
  83. package/vendor/light.exe +0 -0
  84. package/vendor/light.exe.config +18 -0
  85. package/vendor/nuget.exe +0 -0
  86. package/vendor/rcedit.exe +0 -0
  87. package/vendor/signtool.exe +0 -0
  88. package/vendor/template.wxs +39 -0
  89. package/vendor/wconsole.dll +0 -0
  90. package/vendor/winterop.dll +0 -0
  91. package/vendor/wix.dll +0 -0
  92. package/yarn.lock +2008 -0
package/lib/sign.js ADDED
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __generator = (this && this.__generator) || function (thisArg, body) {
35
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
36
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
37
+ function verb(n) { return function (v) { return step([n, v]); }; }
38
+ function step(op) {
39
+ if (f) throw new TypeError("Generator is already executing.");
40
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
41
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
42
+ if (y = 0, t) op = [op[0] & 2, t.value];
43
+ switch (op[0]) {
44
+ case 0: case 1: t = op; break;
45
+ case 4: _.label++; return { value: op[1], done: false };
46
+ case 5: _.label++; y = op[1]; op = [0]; continue;
47
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
48
+ default:
49
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
50
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
51
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
52
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
53
+ if (t[2]) _.ops.pop();
54
+ _.trys.pop(); continue;
55
+ }
56
+ op = body.call(thisArg, _);
57
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
58
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
59
+ }
60
+ };
61
+ var __importDefault = (this && this.__importDefault) || function (mod) {
62
+ return (mod && mod.__esModule) ? mod : { "default": mod };
63
+ };
64
+ Object.defineProperty(exports, "__esModule", { value: true });
65
+ exports.resetSignTool = exports.createSignTool = void 0;
66
+ var path_1 = __importDefault(require("path"));
67
+ var semver_1 = __importDefault(require("semver"));
68
+ var fs_extra_1 = __importDefault(require("fs-extra"));
69
+ var VENDOR_PATH;
70
+ var ORIGINAL_SIGN_TOOL_PATH;
71
+ var BACKUP_SIGN_TOOL_PATH;
72
+ var SIGN_LOG_PATH;
73
+ /**
74
+ * This method uses @electron/windows-sign to create a fake signtool.exe
75
+ * that can be called by Squirrel - but then just calls @electron/windows-sign
76
+ * to actually perform the signing.
77
+ *
78
+ * That's useful for users who need a high degree of customization of the signing
79
+ * process but still want to use @electron/windows-installer.
80
+ */
81
+ function createSignTool(options) {
82
+ return __awaiter(this, void 0, void 0, function () {
83
+ var createSeaSignTool;
84
+ return __generator(this, function (_a) {
85
+ switch (_a.label) {
86
+ case 0:
87
+ if (!options.windowsSign) {
88
+ throw new Error('Signtool should only be created if windowsSign options are set');
89
+ }
90
+ VENDOR_PATH = options.vendorDirectory || path_1.default.join(__dirname, '..', 'vendor');
91
+ ORIGINAL_SIGN_TOOL_PATH = path_1.default.join(VENDOR_PATH, 'signtool.exe');
92
+ BACKUP_SIGN_TOOL_PATH = path_1.default.join(VENDOR_PATH, 'signtool-original.exe');
93
+ SIGN_LOG_PATH = path_1.default.join(VENDOR_PATH, 'electron-windows-sign.log');
94
+ return [4 /*yield*/, getCreateSeaSignTool()];
95
+ case 1:
96
+ createSeaSignTool = _a.sent();
97
+ return [4 /*yield*/, resetSignTool()];
98
+ case 2:
99
+ _a.sent();
100
+ return [4 /*yield*/, fs_extra_1.default.remove(SIGN_LOG_PATH)];
101
+ case 3:
102
+ _a.sent();
103
+ // Make a backup of signtool.exe
104
+ return [4 /*yield*/, fs_extra_1.default.copy(ORIGINAL_SIGN_TOOL_PATH, BACKUP_SIGN_TOOL_PATH, { overwrite: true })];
105
+ case 4:
106
+ // Make a backup of signtool.exe
107
+ _a.sent();
108
+ // Create a new signtool.exe using @electron/windows-sign
109
+ return [4 /*yield*/, createSeaSignTool({
110
+ path: ORIGINAL_SIGN_TOOL_PATH,
111
+ windowsSign: options.windowsSign
112
+ })];
113
+ case 5:
114
+ // Create a new signtool.exe using @electron/windows-sign
115
+ _a.sent();
116
+ return [2 /*return*/];
117
+ }
118
+ });
119
+ });
120
+ }
121
+ exports.createSignTool = createSignTool;
122
+ /**
123
+ * Ensure that signtool.exe is actually the "real" signtool.exe, not our
124
+ * fake substitute.
125
+ */
126
+ function resetSignTool() {
127
+ return __awaiter(this, void 0, void 0, function () {
128
+ return __generator(this, function (_a) {
129
+ switch (_a.label) {
130
+ case 0:
131
+ if (!fs_extra_1.default.existsSync(BACKUP_SIGN_TOOL_PATH)) return [3 /*break*/, 3];
132
+ // Reset the backup of signtool.exe
133
+ return [4 /*yield*/, fs_extra_1.default.copy(BACKUP_SIGN_TOOL_PATH, ORIGINAL_SIGN_TOOL_PATH, { overwrite: true })];
134
+ case 1:
135
+ // Reset the backup of signtool.exe
136
+ _a.sent();
137
+ return [4 /*yield*/, fs_extra_1.default.remove(BACKUP_SIGN_TOOL_PATH)];
138
+ case 2:
139
+ _a.sent();
140
+ _a.label = 3;
141
+ case 3: return [2 /*return*/];
142
+ }
143
+ });
144
+ });
145
+ }
146
+ exports.resetSignTool = resetSignTool;
147
+ /**
148
+ * @electron/windows-installer only requires Node.js >= 8.0.0.
149
+ * @electron/windows-sign requires Node.js >= 16.0.0.
150
+ * @electron/windows-sign's "fake signtool.exe" feature requires
151
+ * Node.js >= 20.0.0, the first version to contain the "single
152
+ * executable" feature with proper support.
153
+ *
154
+ * Since this is overall a very niche feature and only benefits
155
+ * consumers with rather advanced codesigning needs, we did not
156
+ * want to make Node.js v18 a hard requirement for @electron/windows-installer.
157
+ *
158
+ * Instead, @electron/windows-sign is an optional dependency - and
159
+ * if it didn't install, we'll throw a useful error here.
160
+ *
161
+ * @returns
162
+ */
163
+ function getCreateSeaSignTool() {
164
+ return __awaiter(this, void 0, void 0, function () {
165
+ var createSeaSignTool, error_1, message;
166
+ return __generator(this, function (_a) {
167
+ switch (_a.label) {
168
+ case 0:
169
+ _a.trys.push([0, 2, , 3]);
170
+ return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require('@electron/windows-sign')); })];
171
+ case 1:
172
+ createSeaSignTool = (_a.sent()).createSeaSignTool;
173
+ return [2 /*return*/, createSeaSignTool];
174
+ case 2:
175
+ error_1 = _a.sent();
176
+ message = 'In order to use windowsSign options, @electron/windows-sign must be installed as a dependency.';
177
+ if (semver_1.default.lte(process.version, '20.0.0')) {
178
+ message += " You are currently using Node.js ".concat(process.version, ". Please upgrade to Node.js 19 or later and reinstall all dependencies to ensure that @electron/windows-sign is available.");
179
+ }
180
+ else {
181
+ message += " ".concat(error_1);
182
+ }
183
+ throw new Error(message);
184
+ case 3: return [2 /*return*/];
185
+ }
186
+ });
187
+ });
188
+ }
189
+ //# sourceMappingURL=sign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign.js","sourceRoot":"","sources":["../src/sign.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,8CAAwB;AACxB,kDAA4B;AAC5B,sDAA0B;AAI1B,IAAI,WAAmB,CAAC;AACxB,IAAI,uBAA+B,CAAC;AACpC,IAAI,qBAA6B,CAAC;AAClC,IAAI,aAAqB,CAAC;AAE1B;;;;;;;GAOG;AACH,SAAsB,cAAc,CAAC,OAA+B;;;;;;oBAClE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;wBACxB,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;qBACnF;oBAED,WAAW,GAAG,OAAO,CAAC,eAAe,IAAI,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;oBAC9E,uBAAuB,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;oBACjE,qBAAqB,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC;oBACxE,aAAa,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,2BAA2B,CAAC,CAAC;oBAE1C,qBAAM,oBAAoB,EAAE,EAAA;;oBAAhD,iBAAiB,GAAG,SAA4B;oBAEtD,qBAAM,aAAa,EAAE,EAAA;;oBAArB,SAAqB,CAAC;oBACtB,qBAAM,kBAAE,CAAC,MAAM,CAAC,aAAa,CAAC,EAAA;;oBAA9B,SAA8B,CAAC;oBAE/B,gCAAgC;oBAChC,qBAAM,kBAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,qBAAqB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAA;;oBADlF,gCAAgC;oBAChC,SAAkF,CAAC;oBAEnF,yDAAyD;oBACzD,qBAAM,iBAAiB,CAAC;4BACtB,IAAI,EAAE,uBAAuB;4BAC7B,WAAW,EAAE,OAAO,CAAC,WAAW;yBACjC,CAAC,EAAA;;oBAJF,yDAAyD;oBACzD,SAGE,CAAC;;;;;CACJ;AAvBD,wCAuBC;AAED;;;GAGG;AACH,SAAsB,aAAa;;;;;yBAC7B,kBAAE,CAAC,UAAU,CAAC,qBAAqB,CAAC,EAApC,wBAAoC;oBACtC,mCAAmC;oBACnC,qBAAM,kBAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,uBAAuB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAA;;oBADlF,mCAAmC;oBACnC,SAAkF,CAAC;oBACnF,qBAAM,kBAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,EAAA;;oBAAtC,SAAsC,CAAC;;;;;;CAE1C;AAND,sCAMC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAe,oBAAoB;;;;;;;oBAED,sFAAa,wBAAwB,QAAC;;oBAA5D,iBAAiB,GAAK,CAAA,SAAsC,CAAA,kBAA3C;oBACzB,sBAAO,iBAAiB,EAAC;;;oBAErB,OAAO,GAAI,gGAAgG,CAAC;oBAEhH,IAAI,gBAAM,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE;wBACzC,OAAO,IAAI,2CAAoC,OAAO,CAAC,OAAO,+HAA4H,CAAC;qBAC5L;yBAAM;wBACL,OAAO,IAAI,WAAI,OAAK,CAAE,CAAC;qBACxB;oBAED,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;;;;;CAE5B"}
@@ -0,0 +1,3 @@
1
+ /// <reference types="node" />
2
+ import { SpawnOptionsWithoutStdio } from 'child_process';
3
+ export default function spawn(exe: string, params: string[], opts?: SpawnOptionsWithoutStdio): Promise<string>;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var child_process_1 = require("child_process");
4
+ var d = require('debug')('electron-windows-installer:spawn');
5
+ // Public: Maps a process's output into an {Observable}
6
+ //
7
+ // exe - The program to execute
8
+ // params - Arguments passed to the process
9
+ // opts - Options that will be passed to child_process.spawn
10
+ //
11
+ // Returns an {Observable} with a single value, that is the output of the
12
+ // spawned process
13
+ function spawn(exe, params, opts) {
14
+ return new Promise(function (resolve, reject) {
15
+ var proc = null;
16
+ d("Spawning ".concat(exe, " ").concat(params.join(' ')));
17
+ if (!opts) {
18
+ proc = (0, child_process_1.spawn)(exe, params);
19
+ }
20
+ else {
21
+ proc = (0, child_process_1.spawn)(exe, params, opts);
22
+ }
23
+ // We need to wait until all three events have happened:
24
+ // * stdout's pipe is closed
25
+ // * stderr's pipe is closed
26
+ // * We've got an exit code
27
+ var rejected = false;
28
+ var refCount = 3;
29
+ var stdout = '';
30
+ var release = function () {
31
+ if (--refCount <= 0 && !rejected)
32
+ resolve(stdout);
33
+ };
34
+ var bufHandler = function (chunk) {
35
+ stdout += chunk;
36
+ };
37
+ proc.stdout.setEncoding('utf8').on('data', bufHandler);
38
+ proc.stdout.once('close', release);
39
+ proc.stderr.setEncoding('utf8').on('data', bufHandler);
40
+ proc.stderr.once('close', release);
41
+ proc.on('error', function (e) { return reject(e); });
42
+ proc.on('close', function (code) {
43
+ if (code === 0) {
44
+ release();
45
+ }
46
+ else {
47
+ rejected = true;
48
+ reject(new Error("Failed with exit code: ".concat(code, "\nOutput:\n").concat(stdout)));
49
+ }
50
+ });
51
+ });
52
+ }
53
+ exports.default = spawn;
54
+ //# sourceMappingURL=spawn-promise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-promise.js","sourceRoot":"","sources":["../src/spawn-promise.ts"],"names":[],"mappings":";;AAAA,+CAA2E;AAE3E,IAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,kCAAkC,CAAC,CAAC;AAE/D,uDAAuD;AACvD,EAAE;AACF,+BAA+B;AAC/B,2CAA2C;AAC3C,4DAA4D;AAC5D,EAAE;AACF,yEAAyE;AACzE,kBAAkB;AAClB,SAAwB,KAAK,CAAC,GAAW,EAAE,MAAgB,EAAE,IAA+B;IAC1F,OAAO,IAAI,OAAO,CAAC,UAAC,OAAO,EAAE,MAAM;QACjC,IAAI,IAAI,GAAG,IAAI,CAAC;QAEhB,CAAC,CAAC,mBAAY,GAAG,cAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,EAAE;YACT,IAAI,GAAG,IAAA,qBAAO,EAAC,GAAG,EAAE,MAAM,CAAC,CAAC;SAC7B;aAAM;YACL,IAAI,GAAG,IAAA,qBAAO,EAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;SACnC;QAED,wDAAwD;QACxD,4BAA4B;QAC5B,4BAA4B;QAC5B,2BAA2B;QAC3B,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,IAAM,OAAO,GAAG;YACd,IAAI,EAAE,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACpD,CAAC,CAAC;QAEF,IAAM,UAAU,GAAG,UAAC,KAAa;YAC/B,MAAM,IAAI,KAAK,CAAC;QAClB,CAAC,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACnC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,UAAC,CAAQ,IAAW,OAAA,MAAM,CAAC,CAAC,CAAC,EAAT,CAAS,CAAC,CAAC;QAEhD,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,UAAC,IAAY;YAC5B,IAAI,IAAI,KAAK,CAAC,EAAE;gBACd,OAAO,EAAE,CAAC;aACX;iBAAM;gBACL,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM,CAAC,IAAI,KAAK,CAAC,iCAA0B,IAAI,wBAAc,MAAM,CAAE,CAAC,CAAC,CAAC;aACzE;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AA1CD,wBA0CC"}
@@ -0,0 +1,3 @@
1
+ import * as temp from 'temp';
2
+ declare const createTempDir: (arg1: string | temp.AffixOptions | undefined) => Promise<string>;
3
+ export { createTempDir };
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.createTempDir = void 0;
27
+ var temp = __importStar(require("temp"));
28
+ var util_1 = require("util");
29
+ temp.track();
30
+ var createTempDir = (0, util_1.promisify)(temp.mkdir);
31
+ exports.createTempDir = createTempDir;
32
+ //# sourceMappingURL=temp-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temp-utils.js","sourceRoot":"","sources":["../src/temp-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yCAA6B;AAC7B,6BAAiC;AACjC,IAAI,CAAC,KAAK,EAAE,CAAC;AAEb,IAAM,aAAa,GAAG,IAAA,gBAAS,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAG1C,sCAAa"}
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@loongdotjs/electron-winstaller",
3
+ "version": "5.4.0",
4
+ "description": "Module to generate Windows installers for Electron apps",
5
+ "main": "lib/index.js",
6
+ "types": "lib/index.d.ts",
7
+ "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/electron/windows-installer"
11
+ },
12
+ "files": [
13
+ "lib",
14
+ "resources",
15
+ "script",
16
+ "template.nuspectemplate",
17
+ "vendor",
18
+ "!vendor/7z.dll",
19
+ "!vendor/7z.exe"
20
+ ],
21
+ "scripts": {
22
+ "install": "node ./script/select-7z-arch.js",
23
+ "build": "tsc",
24
+ "docs": "npx typedoc",
25
+ "prepublish": "npm run build",
26
+ "lint": "eslint --ext .ts src spec",
27
+ "ava": "ava --timeout=60s",
28
+ "test": "npm run lint && npm run ava",
29
+ "tdd": "ava --watch"
30
+ },
31
+ "dependencies": {
32
+ "@electron/asar": "^3.2.1",
33
+ "debug": "^4.1.1",
34
+ "fs-extra": "^7.0.1",
35
+ "lodash": "^4.17.21",
36
+ "temp": "^0.9.0"
37
+ },
38
+ "devDependencies": {
39
+ "@types/fs-extra": "^5.0.5",
40
+ "@types/lodash": "^4.17.0",
41
+ "@types/node": "^20.6.0",
42
+ "@types/temp": "^0.8.34",
43
+ "@typescript-eslint/eslint-plugin": "^5.62.0",
44
+ "@typescript-eslint/parser": "^5.62.0",
45
+ "ava": "^5.1.1",
46
+ "eslint": "^8.49.0",
47
+ "eslint-plugin-ava": "^14.0.0",
48
+ "ts-node": "^10.9.1",
49
+ "typedoc": "0.25.13",
50
+ "typescript": "^4.9.3"
51
+ },
52
+ "optionalDependencies": {
53
+ "@electron/windows-sign": "^1.1.2"
54
+ },
55
+ "engines": {
56
+ "node": ">=8.0.0"
57
+ },
58
+ "ava": {
59
+ "extensions": [
60
+ "ts"
61
+ ],
62
+ "files": [
63
+ "spec/*.ts"
64
+ ],
65
+ "require": [
66
+ "ts-node/register/transpile-only"
67
+ ]
68
+ }
69
+ }
Binary file
@@ -0,0 +1,33 @@
1
+ const fs = require('fs');
2
+ const os = require('os');
3
+
4
+ /**
5
+ * Even if we're cross-compiling for a different arch like arm64,
6
+ * we still need to use the 7-Zip executable for the host arch
7
+ */
8
+ const arch = os.arch;
9
+ const platform = process.platform;
10
+
11
+ console.log('Selecting 7-Zip for arch ' + arch + ' on platform ' + platform);
12
+
13
+ // Only copy 7-Zip on Windows platform and for supported architectures
14
+ if (platform === 'win32') {
15
+ try {
16
+ fs.copyFileSync('vendor/7z-' + arch + '.exe', 'vendor/7z.exe');
17
+ console.log(`Successfully copied 7z-${arch}.exe to vendor/7z.exe`);
18
+ } catch (err) {
19
+ console.error(`Failed to copy 7z-${arch}.exe:`, err.message);
20
+ throw err;
21
+ }
22
+
23
+ try {
24
+ fs.copyFileSync('vendor/7z-' + arch + '.dll', 'vendor/7z.dll');
25
+ console.log(`Successfully copied 7z-${arch}.dll to vendor/7z.dll`);
26
+ } catch (err) {
27
+ console.error(`Failed to copy 7z-${arch}.dll:`, err.message);
28
+ throw err;
29
+ }
30
+ } else {
31
+ console.log(`Skipping 7-Zip selection on non-Windows platform (${platform}). 7-Zip is only required on Windows.`);
32
+ process.exit(0);
33
+ }
@@ -0,0 +1,14 @@
1
+ import test from 'ava';
2
+ import { convertVersion } from '../src/index';
3
+
4
+ test('makes semver versions into valid NuGet versions', (t): void => {
5
+ t.is(convertVersion('1'), '1');
6
+ t.is(convertVersion('1.2'), '1.2');
7
+ t.is(convertVersion('1.2.3'), '1.2.3');
8
+ t.is(convertVersion('1.2.3-alpha'), '1.2.3-alpha');
9
+ t.is(convertVersion('1.2.3-alpha.1'), '1.2.3-alpha1');
10
+ t.is(convertVersion('1.2.3-alpha.1.2'), '1.2.3-alpha12');
11
+ t.is(convertVersion('1.2.3-alpha-1-2'), '1.2.3-alpha-1-2');
12
+ t.is(convertVersion('1.2.3-alpha.1.2+build-meta.1.2'), '1.2.3-alpha12');
13
+ t.is(convertVersion('1.2.3-alpha-1-2+build-meta.1.2'), '1.2.3-alpha-1-2');
14
+ });
File without changes
Binary file
File without changes
File without changes
Binary file
Binary file
Binary file
File without changes
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "myapp",
3
+ "productName": "MyApp",
4
+ "version": "1.0.0",
5
+ "description": "An app",
6
+ "authors": "Cyril Figgis"
7
+ }
File without changes
File without changes
File without changes
File without changes
File without changes
Binary file
@@ -0,0 +1,12 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+
4
+ import { createTempDir } from '../../src/temp-utils';
5
+
6
+ export const FIXTURE_APP_DIR = path.join(__dirname, '../fixtures/app');
7
+
8
+ export async function createTempAppDirectory(): Promise<string> {
9
+ const appDirectory = await createTempDir('electron-winstaller-ad-');
10
+ await fs.copy(FIXTURE_APP_DIR, appDirectory);
11
+ return appDirectory;
12
+ }
@@ -0,0 +1,8 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+
4
+ module.exports = function(args) {
5
+ console.log(...args);
6
+
7
+ fs.appendFileSync(path.join(__dirname, 'hook.log'), `${JSON.stringify(args)}\n`);
8
+ };
@@ -0,0 +1,70 @@
1
+ import test from 'ava';
2
+ import path from 'path';
3
+ import { createTempDir } from '../src/temp-utils';
4
+ import fs from 'fs-extra';
5
+ import { createWindowsInstaller } from '../src';
6
+ import spawn from '../src/spawn-promise';
7
+ import { createTempAppDirectory } from './helpers/helpers';
8
+
9
+ const log = require('debug')('electron-windows-installer:spec');
10
+
11
+ function spawn7z(args: string[]): Promise<string> {
12
+ const sevenZipPath = path.join(__dirname, '..', 'vendor', '7z.exe');
13
+ const wineExe = ['arm64', 'x64'].includes(process.arch) ? 'wine64' : 'wine';
14
+ return process.platform !== 'win32'
15
+ ? spawn(wineExe, [sevenZipPath, ...args])
16
+ : spawn(sevenZipPath, args);
17
+ }
18
+
19
+
20
+ test.serial('creates a nuget package and installer', async (t): Promise<void> => {
21
+ const outputDirectory = await createTempDir('ei-');
22
+ const appDirectory = await createTempAppDirectory();
23
+ const options = { appDirectory, outputDirectory };
24
+
25
+ await createWindowsInstaller(options);
26
+
27
+ log(`Verifying assertions on ${outputDirectory}`);
28
+ log(JSON.stringify(await fs.readdir(outputDirectory)));
29
+
30
+ const nupkgPath = path.join(outputDirectory, 'myapp-1.0.0-full.nupkg');
31
+
32
+ t.true(await fs.pathExists(nupkgPath));
33
+ t.true(await fs.pathExists(path.join(outputDirectory, 'MyAppSetup.exe')));
34
+
35
+ if (process.platform === 'win32') {
36
+ t.true(await fs.pathExists(path.join(outputDirectory, 'MyAppSetup.msi')));
37
+ }
38
+
39
+ log('Verifying Update.exe');
40
+ t.true(await fs.pathExists(path.join(appDirectory, 'Squirrel.exe')));
41
+
42
+ log('Verifying contents of .nupkg');
43
+
44
+ const packageContents = await spawn7z(['l', nupkgPath]);
45
+
46
+ t.true(packageContents.includes('lib\\net45\\vk_swiftshader_icd.json'));
47
+ t.true(packageContents.includes('lib\\net45\\swiftshader\\libEGL.dll'));
48
+ });
49
+
50
+ test.serial('creates an installer when swiftshader files are missing', async (t): Promise<void> => {
51
+ const appDirectory = await createTempAppDirectory();
52
+ const outputDirectory = await createTempDir('electron-winstaller-test-');
53
+ const options = { appDirectory, outputDirectory };
54
+
55
+ // Remove swiftshader folder and swiftshader json file, simulating Electron < 10.0
56
+ await fs.remove(path.join(appDirectory, 'swiftshader', 'libEGL.dll'));
57
+ await fs.remove(path.join(appDirectory, 'swiftshader', 'libGLESv2.dll'));
58
+ await fs.rmdir(path.join(appDirectory, 'swiftshader'));
59
+ await fs.remove(path.join(appDirectory, 'vk_swiftshader_icd.json'));
60
+
61
+ await createWindowsInstaller(options);
62
+
63
+ const nupkgPath = path.join(outputDirectory, 'myapp-1.0.0-full.nupkg');
64
+
65
+ log('Verifying contents of .nupkg');
66
+
67
+ const packageContents = await spawn7z(['l', nupkgPath]);
68
+ t.false(packageContents.includes('vk_swiftshader_icd.json'));
69
+ t.false(packageContents.includes('swiftshader\\'));
70
+ });
@@ -0,0 +1,48 @@
1
+ import test from 'ava';
2
+ import path from 'path';
3
+ import { createTempDir } from '../src/temp-utils';
4
+ import fs from 'fs-extra';
5
+ import { createWindowsInstaller } from '../src';
6
+ import { createTempAppDirectory } from './helpers/helpers';
7
+ import { SignToolOptions } from '@electron/windows-sign';
8
+ import semver from 'semver';
9
+
10
+ const log = require('debug')('electron-windows-installer:spec');
11
+
12
+ if (process.platform === 'win32' && semver.gte(process.version, '20.0.0')) {
13
+ test.serial('creates a signtool.exe and uses it to sign', async (t): Promise<void> => {
14
+
15
+ const outputDirectory = await createTempDir('ei-');
16
+ const appDirectory = await createTempAppDirectory();
17
+ const hookLogPath = path.join(__dirname, './helpers/hook.log');
18
+ const hookModulePath = path.join(__dirname, './helpers/windowsSignHook.js');
19
+ const windowsSign: SignToolOptions = { hookModulePath };
20
+ const options = { appDirectory, outputDirectory, windowsSign };
21
+
22
+ // Reset
23
+ await fs.remove(hookLogPath);
24
+
25
+ // Test
26
+ await createWindowsInstaller(options);
27
+
28
+ log(`Verifying assertions on ${outputDirectory}`);
29
+ log(JSON.stringify(await fs.readdir(outputDirectory)));
30
+
31
+ const nupkgPath = path.join(outputDirectory, 'myapp-1.0.0-full.nupkg');
32
+
33
+ t.true(await fs.pathExists(nupkgPath));
34
+ t.true(await fs.pathExists(path.join(outputDirectory, 'MyAppSetup.exe')));
35
+
36
+ if (process.platform === 'win32') {
37
+ t.true(await fs.pathExists(path.join(outputDirectory, 'MyAppSetup.msi')));
38
+ }
39
+
40
+ log('Verifying Update.exe');
41
+ t.true(await fs.pathExists(path.join(appDirectory, 'Squirrel.exe')));
42
+
43
+ log('Verifying that our hook got to "sign" all files');
44
+ const hookLog = await fs.readFile(hookLogPath, { encoding: 'utf8' });
45
+ const filesLogged = hookLog.split('\n').filter(v => !!v.trim()).length;
46
+ t.is(filesLogged, 8);
47
+ });
48
+ }