@alwaysmeticulous/remote-replay-launcher 2.248.13 → 2.248.15

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.
@@ -23,4 +23,3 @@ export declare const uploadAssetsFromZip: ({ apiToken: apiToken_, zipPath, commi
23
23
  zipPath: string;
24
24
  deleteAfterUpload?: boolean;
25
25
  }) => Promise<UploadAssetsResult>;
26
- export declare const createZipFromFolder: (folderPath: string, archivePath: string) => Promise<void>;
@@ -22,21 +22,17 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
25
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.createZipFromFolder = exports.uploadAssetsFromZip = exports.uploadAssets = void 0;
26
+ exports.uploadAssetsFromZip = exports.uploadAssets = void 0;
30
27
  const fs_1 = require("fs");
31
28
  const promises_1 = require("fs/promises");
32
29
  const https_1 = require("https");
33
- const os_1 = require("os");
34
30
  const path_1 = require("path");
35
31
  const client_1 = require("@alwaysmeticulous/client");
36
32
  const project_deployments_api_1 = require("@alwaysmeticulous/client/dist/api/project-deployments.api");
37
33
  const common_1 = require("@alwaysmeticulous/common");
38
34
  const Sentry = __importStar(require("@sentry/node"));
39
- const archiver_1 = __importDefault(require("archiver"));
35
+ const multipart_zip_uploader_1 = require("./upload-utils/multipart-zip-uploader");
40
36
  const POLL_FOR_BASE_TEST_RUN_INTERVAL_MS = 10000;
41
37
  const POLL_FOR_BASE_TEST_RUN_MAX_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
42
38
  /**
@@ -44,7 +40,7 @@ const POLL_FOR_BASE_TEST_RUN_MAX_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
44
40
  */
45
41
  const uploadAssets = async (opts) => {
46
42
  const logger = (0, common_1.initLogger)();
47
- const { appDirectory, warnIfNoIndexHtml } = opts;
43
+ const { appDirectory, warnIfNoIndexHtml, apiToken: apiToken_ } = opts;
48
44
  const resolvedAppDirectory = (0, path_1.resolve)(appDirectory);
49
45
  if (!(0, fs_1.existsSync)(resolvedAppDirectory)) {
50
46
  throw new Error(`Directory does not exist: ${resolvedAppDirectory}`);
@@ -58,13 +54,143 @@ const uploadAssets = async (opts) => {
58
54
  `you should use the \`cloud-compute\` GitHub Action or the \`run-all-tests-in-cloud\` command instead.`);
59
55
  }
60
56
  }
61
- const zipPath = (0, path_1.join)((0, os_1.tmpdir)(), `assets-${Date.now()}.zip`);
62
- await (0, exports.createZipFromFolder)(resolvedAppDirectory, zipPath);
63
- return (0, exports.uploadAssetsFromZip)({ ...opts, zipPath, deleteAfterUpload: true });
57
+ const apiToken = (0, client_1.getApiToken)(apiToken_);
58
+ if (!apiToken) {
59
+ logger.error("You must provide an API token by using the --apiToken parameter");
60
+ process.exit(1);
61
+ }
62
+ const client = (0, client_1.createClient)({ apiToken });
63
+ return uploadAssetsStreaming({
64
+ ...opts,
65
+ client,
66
+ folderPath: resolvedAppDirectory,
67
+ });
64
68
  };
65
69
  exports.uploadAssets = uploadAssets;
66
- const uploadAssetsFromZip = async ({ apiToken: apiToken_, zipPath, commitSha, waitForBase = false, rewrites = [], createDeployment = true, deleteAfterUpload = false, }) => {
70
+ const completeUploadAndWaitForBase = async ({ client, uploadId, commitSha, waitForBase, rewrites, createDeployment, multipartUploadInfo, }) => {
67
71
  var _a, _b, _c;
72
+ const logger = (0, common_1.initLogger)();
73
+ let testRun = null;
74
+ let message = undefined;
75
+ const completeAssetUploadArgs = {
76
+ client,
77
+ uploadId,
78
+ commitSha,
79
+ mustHaveBase: waitForBase,
80
+ rewrites,
81
+ createDeployment,
82
+ ...(multipartUploadInfo ? { multipartUploadInfo } : {}),
83
+ };
84
+ const startTime = Date.now();
85
+ let result = await (0, client_1.completeAssetUpload)(completeAssetUploadArgs);
86
+ testRun = (_a = result === null || result === void 0 ? void 0 : result.testRun) !== null && _a !== void 0 ? _a : null;
87
+ let baseNotFound = result === null || result === void 0 ? void 0 : result.baseNotFound;
88
+ let lastTimeElapsed = 0;
89
+ while (!testRun && baseNotFound) {
90
+ const timeElapsed = Date.now() - startTime;
91
+ if (timeElapsed > POLL_FOR_BASE_TEST_RUN_MAX_TIMEOUT_MS) {
92
+ logger.warn(`Timed out after ${POLL_FOR_BASE_TEST_RUN_MAX_TIMEOUT_MS / 1000} seconds waiting for test run`);
93
+ break;
94
+ }
95
+ if (lastTimeElapsed == 0 || timeElapsed - lastTimeElapsed >= 30000) {
96
+ logger.info(`Waiting for base test run to be created. Time elapsed: ${timeElapsed}ms`);
97
+ lastTimeElapsed = timeElapsed;
98
+ }
99
+ await new Promise((resolve) => setTimeout(resolve, POLL_FOR_BASE_TEST_RUN_INTERVAL_MS));
100
+ result = await (0, project_deployments_api_1.triggerRunOnDeployment)(completeAssetUploadArgs);
101
+ testRun = (_b = result === null || result === void 0 ? void 0 : result.testRun) !== null && _b !== void 0 ? _b : null;
102
+ baseNotFound = result === null || result === void 0 ? void 0 : result.baseNotFound;
103
+ }
104
+ if (baseNotFound) {
105
+ logger.info(`Base test run not found, proceeding without it.`);
106
+ testRun =
107
+ (_c = (await (0, project_deployments_api_1.triggerRunOnDeployment)({
108
+ ...completeAssetUploadArgs,
109
+ mustHaveBase: false,
110
+ })).testRun) !== null && _c !== void 0 ? _c : null;
111
+ }
112
+ Sentry.captureMessage("Deployment assets marked as uploaded", {
113
+ level: "debug",
114
+ extra: {
115
+ uploadId: uploadId,
116
+ commitSha: commitSha,
117
+ testRunId: testRun === null || testRun === void 0 ? void 0 : testRun.id,
118
+ baseNotFound: baseNotFound,
119
+ },
120
+ });
121
+ message = result === null || result === void 0 ? void 0 : result.message;
122
+ logger.info(`Deployment assets ${uploadId} marked as uploaded`);
123
+ return {
124
+ testRun,
125
+ ...(message ? { message } : {}),
126
+ };
127
+ };
128
+ const uploadAssetsStreaming = async ({ client, folderPath, commitSha, waitForBase = false, rewrites = [], createDeployment = true, }) => {
129
+ const logger = (0, common_1.initLogger)();
130
+ const { uploadId, awsUploadId, uploadPartUrls, uploadChunkSize } = await (0, client_1.requestMultipartAssetUpload)({ client });
131
+ logger.info(`Starting streaming upload for deployment ${uploadId}`);
132
+ const uploader = new multipart_zip_uploader_1.MultipartZipUploader({
133
+ folderPath,
134
+ uploadPartUrls,
135
+ uploadChunkSize,
136
+ awsUploadId,
137
+ uploadId,
138
+ client,
139
+ uploadBufferToSignedUrl,
140
+ });
141
+ const multipartUploadInfo = await uploader.execute();
142
+ logger.info(`Deployment assets ${uploadId} uploaded successfully`);
143
+ const { testRun, message } = await completeUploadAndWaitForBase({
144
+ client,
145
+ uploadId,
146
+ commitSha,
147
+ waitForBase,
148
+ rewrites,
149
+ createDeployment,
150
+ multipartUploadInfo,
151
+ });
152
+ return {
153
+ uploadId,
154
+ testRun,
155
+ ...(message ? { message } : {}),
156
+ };
157
+ };
158
+ const uploadBufferToSignedUrl = async (signedUrl, buffer) => {
159
+ return new Promise((resolve, reject) => {
160
+ const req = (0, https_1.request)(signedUrl, {
161
+ agent: (0, client_1.getProxyAgent)(),
162
+ method: "PUT",
163
+ headers: {
164
+ "Content-Length": buffer.length,
165
+ },
166
+ }, (response) => {
167
+ let responseData = "";
168
+ response.on("data", (chunk) => {
169
+ responseData += chunk;
170
+ });
171
+ response.on("end", () => {
172
+ if (response.statusCode === 200) {
173
+ const eTag = response.headers["etag"];
174
+ if (!eTag) {
175
+ reject(new Error("No ETag returned from S3"));
176
+ return;
177
+ }
178
+ resolve(eTag);
179
+ }
180
+ else {
181
+ const errorMessage = `Failed to upload part!\nStatus ${response.statusCode}.\nResponse:\n${responseData}`;
182
+ reject(new Error(errorMessage));
183
+ }
184
+ });
185
+ });
186
+ req.on("error", (error) => {
187
+ reject(error);
188
+ });
189
+ req.write(buffer);
190
+ req.end();
191
+ });
192
+ };
193
+ const uploadAssetsFromZip = async ({ apiToken: apiToken_, zipPath, commitSha, waitForBase = false, rewrites = [], createDeployment = true, deleteAfterUpload = false, }) => {
68
194
  const logger = (0, common_1.initLogger)();
69
195
  const apiToken = (0, client_1.getApiToken)(apiToken_);
70
196
  if (!apiToken) {
@@ -81,56 +207,14 @@ const uploadAssetsFromZip = async ({ apiToken: apiToken_, zipPath, commitSha, wa
81
207
  });
82
208
  await uploadFileToSignedUrl(zipPath, uploadUrl, fileSize);
83
209
  logger.info(`Deployment assets ${uploadId} uploaded successfully`);
84
- let testRun = null;
85
- let message = undefined;
86
- const completeAssetUploadArgs = {
210
+ const { testRun, message } = await completeUploadAndWaitForBase({
87
211
  client,
88
212
  uploadId,
89
213
  commitSha,
90
- mustHaveBase: waitForBase,
214
+ waitForBase,
91
215
  rewrites,
92
216
  createDeployment,
93
- };
94
- const startTime = Date.now();
95
- let result = await (0, client_1.completeAssetUpload)(completeAssetUploadArgs);
96
- testRun = (_a = result === null || result === void 0 ? void 0 : result.testRun) !== null && _a !== void 0 ? _a : null;
97
- let baseNotFound = result === null || result === void 0 ? void 0 : result.baseNotFound;
98
- let lastTimeElapsed = 0;
99
- while (!testRun && baseNotFound) {
100
- const timeElapsed = Date.now() - startTime;
101
- if (timeElapsed > POLL_FOR_BASE_TEST_RUN_MAX_TIMEOUT_MS) {
102
- logger.warn(`Timed out after ${POLL_FOR_BASE_TEST_RUN_MAX_TIMEOUT_MS / 1000} seconds waiting for test run`);
103
- break;
104
- }
105
- if (lastTimeElapsed == 0 || timeElapsed - lastTimeElapsed >= 30000) {
106
- // Log at most once every 30 seconds
107
- logger.info(`Waiting for base test run to be created. Time elapsed: ${timeElapsed}ms`);
108
- lastTimeElapsed = timeElapsed;
109
- }
110
- await new Promise((resolve) => setTimeout(resolve, POLL_FOR_BASE_TEST_RUN_INTERVAL_MS));
111
- result = await (0, project_deployments_api_1.triggerRunOnDeployment)(completeAssetUploadArgs);
112
- testRun = (_b = result === null || result === void 0 ? void 0 : result.testRun) !== null && _b !== void 0 ? _b : null;
113
- baseNotFound = result === null || result === void 0 ? void 0 : result.baseNotFound;
114
- }
115
- if (baseNotFound) {
116
- logger.info(`Base test run not found, proceeding without it.`);
117
- testRun =
118
- (_c = (await (0, project_deployments_api_1.triggerRunOnDeployment)({
119
- ...completeAssetUploadArgs,
120
- mustHaveBase: false,
121
- })).testRun) !== null && _c !== void 0 ? _c : null;
122
- }
123
- Sentry.captureMessage("Deployment assets marked as uploaded", {
124
- level: "debug",
125
- extra: {
126
- uploadId: uploadId,
127
- commitSha: commitSha,
128
- testRunId: testRun === null || testRun === void 0 ? void 0 : testRun.id,
129
- baseNotFound: baseNotFound,
130
- },
131
217
  });
132
- message = result === null || result === void 0 ? void 0 : result.message;
133
- logger.info(`Deployment assets ${uploadId} marked as uploaded`);
134
218
  return {
135
219
  uploadId,
136
220
  testRun,
@@ -149,118 +233,6 @@ const uploadAssetsFromZip = async ({ apiToken: apiToken_, zipPath, commitSha, wa
149
233
  }
150
234
  };
151
235
  exports.uploadAssetsFromZip = uploadAssetsFromZip;
152
- const walkDirectoryAndAddToArchive = async (folderPath, archive) => {
153
- const stack = [
154
- {
155
- absolutePath: await (0, promises_1.realpath)(folderPath),
156
- pathInArchive: "",
157
- ancestors: new Set(),
158
- },
159
- ];
160
- while (stack.length > 0) {
161
- const { absolutePath, pathInArchive, ancestors } = stack.pop();
162
- if (ancestors.has(absolutePath)) {
163
- continue;
164
- }
165
- const newAncestors = new Set([...ancestors, absolutePath]);
166
- const entries = await (0, promises_1.readdir)(absolutePath);
167
- for (const entry of entries) {
168
- const entryAbsolutePath = (0, path_1.join)(absolutePath, entry);
169
- const entryPathInArchive = (0, path_1.join)(pathInArchive, entry);
170
- const entryStats = await (0, promises_1.lstat)(entryAbsolutePath);
171
- if (entryStats.isSymbolicLink()) {
172
- const targetAbsolutePath = await (0, promises_1.realpath)(entryAbsolutePath);
173
- const targetStats = await (0, promises_1.stat)(targetAbsolutePath);
174
- if (targetStats.isFile()) {
175
- archive.file(targetAbsolutePath, { name: entryPathInArchive });
176
- }
177
- else if (targetStats.isDirectory() &&
178
- !newAncestors.has(targetAbsolutePath)) {
179
- stack.push({
180
- absolutePath: entryAbsolutePath,
181
- pathInArchive: entryPathInArchive,
182
- ancestors: newAncestors,
183
- });
184
- }
185
- }
186
- else if (entryStats.isFile()) {
187
- archive.file(entryAbsolutePath, { name: entryPathInArchive });
188
- }
189
- else if (entryStats.isDirectory()) {
190
- stack.push({
191
- absolutePath: entryAbsolutePath,
192
- pathInArchive: entryPathInArchive,
193
- ancestors: newAncestors,
194
- });
195
- }
196
- }
197
- }
198
- };
199
- const createZipFromFolder = async (folderPath, archivePath) => {
200
- // autoClose: false is required to prevent the file descriptor from being
201
- // closed before we can fsync it
202
- const fileStream = (0, fs_1.createWriteStream)(archivePath, { autoClose: false });
203
- const archive = (0, archiver_1.default)("zip");
204
- await new Promise((resolve, reject) => {
205
- let fd = null;
206
- let rejected = false;
207
- // Helper to close fd and reject, ensuring we only reject once
208
- const closeAndReject = (err) => {
209
- if (rejected)
210
- return;
211
- rejected = true;
212
- if (fd !== null) {
213
- (0, fs_1.close)(fd, () => reject(err));
214
- }
215
- else {
216
- reject(err);
217
- }
218
- };
219
- archive.on("error", (err) => closeAndReject(err));
220
- fileStream.on("error", (err) => closeAndReject(err));
221
- fileStream.on("open", (descriptor) => {
222
- fd = descriptor;
223
- });
224
- fileStream.on("finish", async () => {
225
- if (rejected)
226
- return;
227
- try {
228
- await new Promise((fsyncResolve, fsyncReject) => {
229
- if (fd !== null) {
230
- (0, fs_1.fsync)(fd, (err) => {
231
- if (err)
232
- fsyncReject(err);
233
- else
234
- fsyncResolve();
235
- });
236
- }
237
- else {
238
- fsyncReject(new Error("File descriptor not found"));
239
- }
240
- });
241
- // Manually close the fd since autoClose is disabled
242
- // Note: We use fs.close(fd) instead of fileStream.close() because
243
- // WriteStream.close() doesn't invoke its callback when autoClose is false
244
- (0, fs_1.close)(fd, (closeErr) => {
245
- if (closeErr)
246
- reject(closeErr);
247
- else
248
- resolve();
249
- });
250
- }
251
- catch (fsyncError) {
252
- if (fd !== null)
253
- (0, fs_1.close)(fd, () => { });
254
- reject(fsyncError);
255
- }
256
- });
257
- archive.pipe(fileStream);
258
- walkDirectoryAndAddToArchive(folderPath, archive)
259
- .then(() => archive.finalize())
260
- .catch(closeAndReject);
261
- });
262
- };
263
- exports.createZipFromFolder = createZipFromFolder;
264
236
  const uploadFileToSignedUrl = async (filePath, signedUrl, expectedFileSize) => {
265
237
  const fileStream = (0, fs_1.createReadStream)(filePath);
266
238
  const logger = (0, common_1.initLogger)();
@@ -1 +1 @@
1
- {"version":3,"file":"asset-upload-utils.js","sourceRoot":"","sources":["../src/asset-upload-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"asset-upload-utils.js","sourceRoot":"","sources":["../src/asset-upload-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const multipart_buffer_manager_1 = require("../multipart-buffer-manager");
5
+ (0, vitest_1.describe)("MultipartBufferManager", () => {
6
+ const CHUNK_SIZE = 1024;
7
+ const createManager = (maxConcurrentUploads = 4) => {
8
+ const uploadPart = async (_buffer, partNumber) => {
9
+ return `etag-${partNumber}`;
10
+ };
11
+ return new multipart_buffer_manager_1.MultipartBufferManager({
12
+ uploadChunkSize: CHUNK_SIZE,
13
+ uploadPart,
14
+ maxConcurrentUploads,
15
+ });
16
+ };
17
+ (0, vitest_1.describe)("addChunk", () => {
18
+ (0, vitest_1.it)("should accumulate chunks in the buffer", () => {
19
+ const manager = createManager();
20
+ const chunk1 = Buffer.alloc(100);
21
+ const chunk2 = Buffer.alloc(200);
22
+ manager.addChunk(chunk1);
23
+ (0, vitest_1.expect)(manager.getBufferSize()).toBe(100);
24
+ manager.addChunk(chunk2);
25
+ (0, vitest_1.expect)(manager.getBufferSize()).toBe(300);
26
+ });
27
+ });
28
+ (0, vitest_1.describe)("flush", () => {
29
+ (0, vitest_1.it)("should not upload if buffer is below chunk size and not last part", async () => {
30
+ const manager = createManager();
31
+ const smallChunk = Buffer.alloc(CHUNK_SIZE - 100);
32
+ manager.addChunk(smallChunk);
33
+ await manager.flush(false);
34
+ (0, vitest_1.expect)(manager.getBufferSize()).toBe(CHUNK_SIZE - 100);
35
+ });
36
+ (0, vitest_1.it)("should clear buffer after upload if buffer reaches chunk size", async () => {
37
+ const manager = createManager();
38
+ const chunk = Buffer.alloc(CHUNK_SIZE);
39
+ manager.addChunk(chunk);
40
+ await manager.flush(false);
41
+ (0, vitest_1.expect)(manager.getBufferSize()).toBe(0);
42
+ });
43
+ (0, vitest_1.it)("should clear buffer after upload if it is the last part", async () => {
44
+ const manager = createManager();
45
+ const smallChunk = Buffer.alloc(100);
46
+ manager.addChunk(smallChunk);
47
+ await manager.flush(true);
48
+ (0, vitest_1.expect)(manager.getBufferSize()).toBe(0);
49
+ });
50
+ (0, vitest_1.it)("should split buffer if it exceeds chunk size", async () => {
51
+ const manager = createManager();
52
+ const oversizedChunk = Buffer.alloc(CHUNK_SIZE + 500);
53
+ manager.addChunk(oversizedChunk);
54
+ await manager.flush(false);
55
+ (0, vitest_1.expect)(manager.getBufferSize()).toBe(500);
56
+ });
57
+ (0, vitest_1.it)("should combine multiple small chunks before uploading", async () => {
58
+ const manager = createManager();
59
+ const chunk1 = Buffer.alloc(300);
60
+ const chunk2 = Buffer.alloc(300);
61
+ const chunk3 = Buffer.alloc(424);
62
+ manager.addChunk(chunk1);
63
+ manager.addChunk(chunk2);
64
+ manager.addChunk(chunk3);
65
+ await manager.flush(false);
66
+ (0, vitest_1.expect)(manager.getBufferSize()).toBe(0);
67
+ });
68
+ });
69
+ (0, vitest_1.describe)("finalize", () => {
70
+ (0, vitest_1.it)("should return empty array if no uploads were made", async () => {
71
+ const manager = createManager();
72
+ const eTags = await manager.finalize();
73
+ (0, vitest_1.expect)(eTags).toEqual([]);
74
+ });
75
+ (0, vitest_1.it)("should return eTags in order of part numbers", async () => {
76
+ const manager = createManager();
77
+ const chunk1 = Buffer.alloc(CHUNK_SIZE);
78
+ const chunk2 = Buffer.alloc(CHUNK_SIZE);
79
+ const chunk3 = Buffer.alloc(CHUNK_SIZE);
80
+ manager.addChunk(chunk1);
81
+ await manager.flush(false);
82
+ manager.addChunk(chunk2);
83
+ await manager.flush(false);
84
+ manager.addChunk(chunk3);
85
+ await manager.flush(true);
86
+ const eTags = await manager.finalize();
87
+ (0, vitest_1.expect)(eTags).toEqual(["etag-1", "etag-2", "etag-3"]);
88
+ });
89
+ (0, vitest_1.it)("should wait for all pending uploads to complete", async () => {
90
+ let resolveUpload1;
91
+ let resolveUpload2;
92
+ const promise1 = new Promise((resolve) => {
93
+ resolveUpload1 = resolve;
94
+ });
95
+ const promise2 = new Promise((resolve) => {
96
+ resolveUpload2 = resolve;
97
+ });
98
+ let callCount = 0;
99
+ const uploadPart = async () => {
100
+ callCount++;
101
+ return callCount === 1 ? promise1 : promise2;
102
+ };
103
+ const manager = new multipart_buffer_manager_1.MultipartBufferManager({
104
+ uploadChunkSize: CHUNK_SIZE,
105
+ uploadPart,
106
+ maxConcurrentUploads: 4,
107
+ });
108
+ manager.addChunk(Buffer.alloc(CHUNK_SIZE));
109
+ await manager.flush(false);
110
+ manager.addChunk(Buffer.alloc(CHUNK_SIZE));
111
+ await manager.flush(false);
112
+ (0, vitest_1.expect)(manager.getPendingUploadCount()).toBe(2);
113
+ const finalizePromise = manager.finalize();
114
+ resolveUpload1("etag-1");
115
+ resolveUpload2("etag-2");
116
+ const eTags = await finalizePromise;
117
+ (0, vitest_1.expect)(eTags).toEqual(["etag-1", "etag-2"]);
118
+ });
119
+ (0, vitest_1.it)("should sort eTags by part number even if uploads complete out of order", async () => {
120
+ let resolveUpload1;
121
+ let resolveUpload2;
122
+ let resolveUpload3;
123
+ const promise1 = new Promise((resolve) => {
124
+ resolveUpload1 = resolve;
125
+ });
126
+ const promise2 = new Promise((resolve) => {
127
+ resolveUpload2 = resolve;
128
+ });
129
+ const promise3 = new Promise((resolve) => {
130
+ resolveUpload3 = resolve;
131
+ });
132
+ let callCount = 0;
133
+ const uploadPart = async () => {
134
+ callCount++;
135
+ if (callCount === 1)
136
+ return promise1;
137
+ if (callCount === 2)
138
+ return promise2;
139
+ return promise3;
140
+ };
141
+ const manager = new multipart_buffer_manager_1.MultipartBufferManager({
142
+ uploadChunkSize: CHUNK_SIZE,
143
+ uploadPart,
144
+ maxConcurrentUploads: 4,
145
+ });
146
+ manager.addChunk(Buffer.alloc(CHUNK_SIZE));
147
+ await manager.flush(false);
148
+ manager.addChunk(Buffer.alloc(CHUNK_SIZE));
149
+ await manager.flush(false);
150
+ manager.addChunk(Buffer.alloc(CHUNK_SIZE));
151
+ await manager.flush(true);
152
+ const finalizePromise = manager.finalize();
153
+ resolveUpload3("etag-3");
154
+ resolveUpload1("etag-1");
155
+ resolveUpload2("etag-2");
156
+ const eTags = await finalizePromise;
157
+ (0, vitest_1.expect)(eTags).toEqual(["etag-1", "etag-2", "etag-3"]);
158
+ });
159
+ });
160
+ (0, vitest_1.describe)("concurrent upload limiting", () => {
161
+ (0, vitest_1.it)("should respect max concurrent uploads limit", async () => {
162
+ const MAX_CONCURRENT = 2;
163
+ let activeUploads = 0;
164
+ let maxActiveUploads = 0;
165
+ const uploadPart = async (_buffer, partNumber) => new Promise((resolve) => {
166
+ activeUploads++;
167
+ maxActiveUploads = Math.max(maxActiveUploads, activeUploads);
168
+ setTimeout(() => {
169
+ activeUploads--;
170
+ resolve(`etag-${partNumber}`);
171
+ }, 10);
172
+ });
173
+ const manager = new multipart_buffer_manager_1.MultipartBufferManager({
174
+ uploadChunkSize: CHUNK_SIZE,
175
+ uploadPart,
176
+ maxConcurrentUploads: MAX_CONCURRENT,
177
+ });
178
+ const uploads = [];
179
+ for (let i = 0; i < 5; i++) {
180
+ manager.addChunk(Buffer.alloc(CHUNK_SIZE));
181
+ uploads.push(manager.flush(false));
182
+ }
183
+ await Promise.all(uploads);
184
+ await manager.finalize();
185
+ (0, vitest_1.expect)(maxActiveUploads).toBeLessThanOrEqual(MAX_CONCURRENT);
186
+ });
187
+ });
188
+ (0, vitest_1.describe)("error handling", () => {
189
+ (0, vitest_1.it)("should not throw during flush but propagate errors during finalize", async () => {
190
+ const uploadError = new Error("Upload failed");
191
+ const uploadPart = async () => {
192
+ throw uploadError;
193
+ };
194
+ const manager = new multipart_buffer_manager_1.MultipartBufferManager({
195
+ uploadChunkSize: CHUNK_SIZE,
196
+ uploadPart,
197
+ maxConcurrentUploads: 4,
198
+ });
199
+ manager.addChunk(Buffer.alloc(CHUNK_SIZE));
200
+ await (0, vitest_1.expect)(manager.flush(false)).resolves.toBeUndefined();
201
+ await (0, vitest_1.expect)(manager.finalize()).rejects.toThrow("Upload failed");
202
+ });
203
+ (0, vitest_1.it)("should propagate upload errors during finalize", async () => {
204
+ const uploadError = new Error("Upload failed");
205
+ let rejectUpload;
206
+ const uploadPromise = new Promise((_resolve, reject) => {
207
+ rejectUpload = reject;
208
+ });
209
+ const uploadPart = async () => uploadPromise;
210
+ const manager = new multipart_buffer_manager_1.MultipartBufferManager({
211
+ uploadChunkSize: CHUNK_SIZE,
212
+ uploadPart,
213
+ maxConcurrentUploads: 4,
214
+ });
215
+ manager.addChunk(Buffer.alloc(CHUNK_SIZE));
216
+ await manager.flush(false);
217
+ const finalizePromise = manager.finalize();
218
+ rejectUpload(uploadError);
219
+ await (0, vitest_1.expect)(finalizePromise).rejects.toThrow("Upload failed");
220
+ });
221
+ });
222
+ });
223
+ //# sourceMappingURL=multipart-buffer-manager.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart-buffer-manager.spec.js","sourceRoot":"","sources":["../../../src/upload-utils/__tests__/multipart-buffer-manager.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const promises_1 = require("fs/promises");
4
+ const os_1 = require("os");
5
+ const path_1 = require("path");
6
+ const vitest_1 = require("vitest");
7
+ const multipart_zip_uploader_1 = require("../multipart-zip-uploader");
8
+ vitest_1.vi.mock("@alwaysmeticulous/client", async () => {
9
+ const actual = await vitest_1.vi.importActual("@alwaysmeticulous/client");
10
+ return {
11
+ ...actual,
12
+ requestUploadPart: vitest_1.vi
13
+ .fn()
14
+ .mockResolvedValue({ uploadPartUrl: "https://example.com/extra-part" }),
15
+ };
16
+ });
17
+ (0, vitest_1.describe)("MultipartZipUploader", () => {
18
+ let testDir;
19
+ const uploadedParts = [];
20
+ (0, vitest_1.beforeEach)(async () => {
21
+ testDir = (0, path_1.join)((0, os_1.tmpdir)(), `test-multipart-zip-${Date.now()}`);
22
+ await (0, promises_1.mkdir)(testDir, { recursive: true });
23
+ uploadedParts.length = 0;
24
+ });
25
+ (0, vitest_1.afterEach)(async () => {
26
+ try {
27
+ await (0, promises_1.rm)(testDir, { recursive: true, force: true });
28
+ }
29
+ catch {
30
+ // Ignore cleanup errors
31
+ }
32
+ });
33
+ const createUploader = (overrides = {}) => {
34
+ const args = {
35
+ folderPath: testDir,
36
+ uploadPartUrls: [
37
+ "https://example.com/part1",
38
+ "https://example.com/part2",
39
+ "https://example.com/part3",
40
+ ],
41
+ uploadChunkSize: 10 * 1024 * 1024,
42
+ awsUploadId: "upload-123",
43
+ uploadId: "id-123",
44
+ client: {},
45
+ uploadBufferToSignedUrl: async (url, buffer) => {
46
+ uploadedParts.push({ url, size: buffer.length });
47
+ return `etag-${uploadedParts.length}`;
48
+ },
49
+ ...overrides,
50
+ };
51
+ return new multipart_zip_uploader_1.MultipartZipUploader(args);
52
+ };
53
+ (0, vitest_1.it)("should create an instance with valid args", () => {
54
+ const uploader = createUploader();
55
+ (0, vitest_1.expect)(uploader).toBeInstanceOf(multipart_zip_uploader_1.MultipartZipUploader);
56
+ });
57
+ (0, vitest_1.it)("should zip and upload a single file", async () => {
58
+ await (0, promises_1.writeFile)((0, path_1.join)(testDir, "test.txt"), "Hello World");
59
+ const uploader = createUploader();
60
+ const result = await uploader.execute();
61
+ (0, vitest_1.expect)(result.awsUploadId).toBe("upload-123");
62
+ (0, vitest_1.expect)(result.eTags.length).toBeGreaterThan(0);
63
+ (0, vitest_1.expect)(uploadedParts.length).toBeGreaterThan(0);
64
+ });
65
+ (0, vitest_1.it)("should zip and upload multiple files", async () => {
66
+ await (0, promises_1.writeFile)((0, path_1.join)(testDir, "file1.txt"), "Content 1");
67
+ await (0, promises_1.writeFile)((0, path_1.join)(testDir, "file2.txt"), "Content 2");
68
+ await (0, promises_1.writeFile)((0, path_1.join)(testDir, "file3.txt"), "Content 3");
69
+ const uploader = createUploader();
70
+ const result = await uploader.execute();
71
+ (0, vitest_1.expect)(result.awsUploadId).toBe("upload-123");
72
+ (0, vitest_1.expect)(uploadedParts.length).toBeGreaterThan(0);
73
+ });
74
+ (0, vitest_1.it)("should handle nested directories", async () => {
75
+ await (0, promises_1.mkdir)((0, path_1.join)(testDir, "subdir"), { recursive: true });
76
+ await (0, promises_1.writeFile)((0, path_1.join)(testDir, "root.txt"), "Root content");
77
+ await (0, promises_1.writeFile)((0, path_1.join)(testDir, "subdir", "nested.txt"), "Nested content");
78
+ const uploader = createUploader();
79
+ const result = await uploader.execute();
80
+ (0, vitest_1.expect)(result.awsUploadId).toBe("upload-123");
81
+ (0, vitest_1.expect)(result.eTags.length).toBeGreaterThan(0);
82
+ });
83
+ (0, vitest_1.it)("should handle empty directory", async () => {
84
+ const uploader = createUploader();
85
+ const result = await uploader.execute();
86
+ (0, vitest_1.expect)(result.awsUploadId).toBe("upload-123");
87
+ (0, vitest_1.expect)(result.eTags).toBeDefined();
88
+ });
89
+ });
90
+ //# sourceMappingURL=multipart-zip-uploader.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart-zip-uploader.spec.js","sourceRoot":"","sources":["../../../src/upload-utils/__tests__/multipart-zip-uploader.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ export interface BufferManagerOptions {
4
+ uploadChunkSize: number;
5
+ uploadPart: (buffer: Buffer, partNumber: number, isLastPart: boolean) => Promise<string>;
6
+ maxConcurrentUploads: number;
7
+ }
8
+ /**
9
+ * Manages buffering and flushing of data chunks for multipart uploads.
10
+ * Accumulates data in a buffer and uploads it in chunks of the specified size.
11
+ */
12
+ export declare class MultipartBufferManager {
13
+ private currentBuffer;
14
+ private currentBufferSize;
15
+ private currentPartNumber;
16
+ private pendingUploads;
17
+ private readonly uploadLimiter;
18
+ private readonly uploadChunkSize;
19
+ private readonly uploadPart;
20
+ constructor(options: BufferManagerOptions);
21
+ /**
22
+ * Adds a chunk of data to the buffer. If the buffer size exceeds the chunk size,
23
+ * it will be flushed automatically.
24
+ */
25
+ addChunk(chunk: Buffer): void;
26
+ /**
27
+ * Returns the current size of the accumulated buffer.
28
+ */
29
+ getBufferSize(): number;
30
+ /**
31
+ * Flushes the current buffer to upload. Handles splitting the buffer if it exceeds
32
+ * the chunk size, and keeps any remainder for the next flush.
33
+ *
34
+ * @param isLastPart - Whether this is the last part to be uploaded
35
+ */
36
+ flush(isLastPart: boolean): Promise<void>;
37
+ /**
38
+ * Waits for all pending uploads to complete and returns the ETags in order
39
+ * of part number.
40
+ */
41
+ finalize(): Promise<string[]>;
42
+ /**
43
+ * Returns the number of pending uploads that haven't completed yet.
44
+ */
45
+ getPendingUploadCount(): number;
46
+ }
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MultipartBufferManager = void 0;
7
+ const p_limit_1 = __importDefault(require("p-limit"));
8
+ /**
9
+ * Manages buffering and flushing of data chunks for multipart uploads.
10
+ * Accumulates data in a buffer and uploads it in chunks of the specified size.
11
+ */
12
+ class MultipartBufferManager {
13
+ constructor(options) {
14
+ this.currentBuffer = [];
15
+ this.currentBufferSize = 0;
16
+ this.currentPartNumber = 1;
17
+ this.pendingUploads = [];
18
+ this.uploadChunkSize = options.uploadChunkSize;
19
+ this.uploadPart = options.uploadPart;
20
+ this.uploadLimiter = (0, p_limit_1.default)(options.maxConcurrentUploads);
21
+ }
22
+ /**
23
+ * Adds a chunk of data to the buffer. If the buffer size exceeds the chunk size,
24
+ * it will be flushed automatically.
25
+ */
26
+ addChunk(chunk) {
27
+ this.currentBuffer.push(chunk);
28
+ this.currentBufferSize += chunk.length;
29
+ }
30
+ /**
31
+ * Returns the current size of the accumulated buffer.
32
+ */
33
+ getBufferSize() {
34
+ return this.currentBufferSize;
35
+ }
36
+ /**
37
+ * Flushes the current buffer to upload. Handles splitting the buffer if it exceeds
38
+ * the chunk size, and keeps any remainder for the next flush.
39
+ *
40
+ * @param isLastPart - Whether this is the last part to be uploaded
41
+ */
42
+ async flush(isLastPart) {
43
+ if (this.currentBuffer.length === 0) {
44
+ return;
45
+ }
46
+ const combinedBuffer = Buffer.concat(this.currentBuffer);
47
+ if (!isLastPart && combinedBuffer.length < this.uploadChunkSize) {
48
+ return;
49
+ }
50
+ let bufferToUpload;
51
+ let remainingBuffer = null;
52
+ if (!isLastPart && combinedBuffer.length > this.uploadChunkSize) {
53
+ bufferToUpload = combinedBuffer.subarray(0, this.uploadChunkSize);
54
+ remainingBuffer = combinedBuffer.subarray(this.uploadChunkSize);
55
+ }
56
+ else {
57
+ bufferToUpload = combinedBuffer;
58
+ }
59
+ const partNumber = this.currentPartNumber++;
60
+ const uploadPromise = this.uploadLimiter(() => this.uploadPart(bufferToUpload, partNumber, isLastPart)).then((eTag) => ({ partNumber, eTag }));
61
+ this.pendingUploads.push(uploadPromise);
62
+ if (remainingBuffer) {
63
+ this.currentBuffer = [remainingBuffer];
64
+ this.currentBufferSize = remainingBuffer.length;
65
+ }
66
+ else {
67
+ this.currentBuffer = [];
68
+ this.currentBufferSize = 0;
69
+ }
70
+ }
71
+ /**
72
+ * Waits for all pending uploads to complete and returns the ETags in order
73
+ * of part number.
74
+ */
75
+ async finalize() {
76
+ const results = await Promise.all(this.pendingUploads);
77
+ results.sort((a, b) => a.partNumber - b.partNumber);
78
+ return results.map((r) => r.eTag);
79
+ }
80
+ /**
81
+ * Returns the number of pending uploads that haven't completed yet.
82
+ */
83
+ getPendingUploadCount() {
84
+ return this.pendingUploads.length;
85
+ }
86
+ }
87
+ exports.MultipartBufferManager = MultipartBufferManager;
88
+ //# sourceMappingURL=multipart-buffer-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart-buffer-manager.js","sourceRoot":"","sources":["../../src/upload-utils/multipart-buffer-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { createClient, MultiPartUploadInfo } from "@alwaysmeticulous/client";
4
+ export interface MultipartZipUploaderArgs {
5
+ folderPath: string;
6
+ uploadPartUrls: string[];
7
+ uploadChunkSize: number;
8
+ awsUploadId: string;
9
+ uploadId: string;
10
+ client: ReturnType<typeof createClient>;
11
+ uploadBufferToSignedUrl: (url: string, buffer: Buffer) => Promise<string>;
12
+ }
13
+ export declare class MultipartZipUploader {
14
+ private readonly args;
15
+ private totalUploadedBytes;
16
+ private preSignedUrlIndex;
17
+ private readonly logger;
18
+ private readonly bufferManager;
19
+ constructor(args: MultipartZipUploaderArgs);
20
+ execute(): Promise<MultiPartUploadInfo>;
21
+ private uploadPart;
22
+ private getUploadUrl;
23
+ private createArchive;
24
+ private createUploadStream;
25
+ private walkAndZipDirectory;
26
+ private getDirectoryEntriesWithStats;
27
+ private processDirectoryEntry;
28
+ private processSymbolicLink;
29
+ }
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MultipartZipUploader = void 0;
7
+ const promises_1 = require("fs/promises");
8
+ const path_1 = require("path");
9
+ const stream_1 = require("stream");
10
+ const client_1 = require("@alwaysmeticulous/client");
11
+ const common_1 = require("@alwaysmeticulous/common");
12
+ const archiver_1 = __importDefault(require("archiver"));
13
+ const p_limit_1 = __importDefault(require("p-limit"));
14
+ const multipart_buffer_manager_1 = require("./multipart-buffer-manager");
15
+ const MAX_CONCURRENT_UPLOADS = 4;
16
+ const FS_CONCURRENCY = 10;
17
+ const ZIP_COMPRESSION_LEVEL = 3;
18
+ const allWithLimit = async (items, limit, handler) => {
19
+ const limited = (0, p_limit_1.default)(limit);
20
+ return Promise.all(items.map((item) => limited(() => handler(item))));
21
+ };
22
+ class MultipartZipUploader {
23
+ constructor(args) {
24
+ this.args = args;
25
+ this.totalUploadedBytes = 0;
26
+ this.preSignedUrlIndex = 0;
27
+ this.logger = (0, common_1.initLogger)();
28
+ this.bufferManager = new multipart_buffer_manager_1.MultipartBufferManager({
29
+ uploadChunkSize: args.uploadChunkSize,
30
+ uploadPart: this.uploadPart.bind(this),
31
+ maxConcurrentUploads: MAX_CONCURRENT_UPLOADS,
32
+ });
33
+ }
34
+ async execute() {
35
+ return new Promise((resolve, reject) => {
36
+ const archive = this.createArchive();
37
+ const uploadStream = this.createUploadStream(resolve, reject);
38
+ archive.on("error", reject);
39
+ uploadStream.on("error", reject);
40
+ archive.pipe(uploadStream);
41
+ this.walkAndZipDirectory(archive).catch(reject);
42
+ });
43
+ }
44
+ async uploadPart(buffer, partNumber, isLastPart) {
45
+ const uploadUrl = await this.getUploadUrl(buffer, partNumber, isLastPart);
46
+ const eTag = await this.args.uploadBufferToSignedUrl(uploadUrl, buffer);
47
+ this.totalUploadedBytes += buffer.length;
48
+ this.logger.info(`Uploaded part ${partNumber} (${buffer.length} bytes, ${this.totalUploadedBytes} total)`);
49
+ return eTag;
50
+ }
51
+ async getUploadUrl(buffer, partNumber, isLastPart) {
52
+ const isFullSizeChunk = buffer.length === this.args.uploadChunkSize;
53
+ const canUsePreSignedUrl = isFullSizeChunk &&
54
+ !isLastPart &&
55
+ this.preSignedUrlIndex < this.args.uploadPartUrls.length;
56
+ if (canUsePreSignedUrl) {
57
+ return this.args.uploadPartUrls[this.preSignedUrlIndex++];
58
+ }
59
+ const { uploadPartUrl } = await (0, client_1.requestUploadPart)({
60
+ client: this.args.client,
61
+ uploadId: this.args.uploadId,
62
+ awsUploadId: this.args.awsUploadId,
63
+ partNumber,
64
+ size: buffer.length,
65
+ });
66
+ return uploadPartUrl;
67
+ }
68
+ createArchive() {
69
+ return (0, archiver_1.default)("zip", {
70
+ zlib: { level: ZIP_COMPRESSION_LEVEL },
71
+ });
72
+ }
73
+ createUploadStream(resolve, reject) {
74
+ return new stream_1.Writable({
75
+ write: (chunk, _encoding, callback) => {
76
+ this.bufferManager.addChunk(chunk);
77
+ if (this.bufferManager.getBufferSize() >= this.args.uploadChunkSize) {
78
+ this.bufferManager
79
+ .flush(false)
80
+ .then(() => callback())
81
+ .catch(callback);
82
+ }
83
+ else {
84
+ callback();
85
+ }
86
+ },
87
+ final: (callback) => {
88
+ this.bufferManager
89
+ .flush(true)
90
+ .then(() => this.bufferManager.finalize())
91
+ .then((sortedETags) => {
92
+ resolve({ awsUploadId: this.args.awsUploadId, eTags: sortedETags });
93
+ callback();
94
+ })
95
+ .catch((err) => {
96
+ callback(err);
97
+ reject(err);
98
+ });
99
+ },
100
+ });
101
+ }
102
+ async walkAndZipDirectory(archive) {
103
+ const stack = [
104
+ {
105
+ absolutePath: await (0, promises_1.realpath)(this.args.folderPath),
106
+ pathInArchive: "",
107
+ ancestors: new Set(),
108
+ },
109
+ ];
110
+ while (stack.length > 0) {
111
+ const { absolutePath, pathInArchive, ancestors } = stack.pop();
112
+ if (ancestors.has(absolutePath)) {
113
+ continue;
114
+ }
115
+ const newAncestors = new Set([...ancestors, absolutePath]);
116
+ const entriesWithStats = await this.getDirectoryEntriesWithStats(absolutePath, pathInArchive);
117
+ for (const entry of entriesWithStats) {
118
+ await this.processDirectoryEntry(archive, entry, newAncestors, stack);
119
+ }
120
+ }
121
+ await archive.finalize();
122
+ }
123
+ async getDirectoryEntriesWithStats(absolutePath, pathInArchive) {
124
+ const entries = await (0, promises_1.readdir)(absolutePath);
125
+ return allWithLimit(entries, FS_CONCURRENCY, async (entry) => {
126
+ const entryAbsolutePath = (0, path_1.join)(absolutePath, entry);
127
+ const entryPathInArchive = (0, path_1.join)(pathInArchive, entry);
128
+ const entryStats = await (0, promises_1.lstat)(entryAbsolutePath);
129
+ return { entryAbsolutePath, entryPathInArchive, entryStats };
130
+ });
131
+ }
132
+ async processDirectoryEntry(archive, entry, ancestors, stack) {
133
+ const { entryAbsolutePath, entryPathInArchive, entryStats } = entry;
134
+ if (entryStats.isSymbolicLink()) {
135
+ await this.processSymbolicLink(archive, entryAbsolutePath, entryPathInArchive, ancestors, stack);
136
+ return;
137
+ }
138
+ if (entryStats.isFile()) {
139
+ archive.file(entryAbsolutePath, { name: entryPathInArchive });
140
+ return;
141
+ }
142
+ if (entryStats.isDirectory()) {
143
+ stack.push({
144
+ absolutePath: entryAbsolutePath,
145
+ pathInArchive: entryPathInArchive,
146
+ ancestors,
147
+ });
148
+ return;
149
+ }
150
+ }
151
+ async processSymbolicLink(archive, entryAbsolutePath, entryPathInArchive, ancestors, stack) {
152
+ const targetAbsolutePath = await (0, promises_1.realpath)(entryAbsolutePath);
153
+ const targetStats = await (0, promises_1.stat)(targetAbsolutePath);
154
+ if (targetStats.isFile()) {
155
+ archive.file(targetAbsolutePath, { name: entryPathInArchive });
156
+ return;
157
+ }
158
+ if (targetStats.isDirectory() && !ancestors.has(targetAbsolutePath)) {
159
+ stack.push({
160
+ absolutePath: entryAbsolutePath,
161
+ pathInArchive: entryPathInArchive,
162
+ ancestors,
163
+ });
164
+ return;
165
+ }
166
+ }
167
+ }
168
+ exports.MultipartZipUploader = MultipartZipUploader;
169
+ //# sourceMappingURL=multipart-zip-uploader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart-zip-uploader.js","sourceRoot":"","sources":["../../src/upload-utils/multipart-zip-uploader.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwaysmeticulous/remote-replay-launcher",
3
- "version": "2.248.13",
3
+ "version": "2.248.15",
4
4
  "description": "Executes a remote replay on Meticulous' infrastructure",
5
5
  "license": "ISC",
6
6
  "main": "dist/index.js",
@@ -20,13 +20,14 @@
20
20
  "test": "vitest run"
21
21
  },
22
22
  "dependencies": {
23
- "@alwaysmeticulous/api": "2.248.0",
24
- "@alwaysmeticulous/client": "2.248.13",
25
- "@alwaysmeticulous/common": "2.248.13",
26
- "@alwaysmeticulous/tunnels-client": "2.248.13",
23
+ "@alwaysmeticulous/api": "2.248.14",
24
+ "@alwaysmeticulous/client": "2.248.15",
25
+ "@alwaysmeticulous/common": "2.248.14",
26
+ "@alwaysmeticulous/tunnels-client": "2.248.14",
27
27
  "@sentry/node": "^10.3.0",
28
28
  "archiver": "^7.0.0",
29
29
  "loglevel": "^1.8.0",
30
+ "p-limit": "^3.1.0",
30
31
  "systeminformation": "^5.25.11"
31
32
  },
32
33
  "devDependencies": {
@@ -50,5 +51,5 @@
50
51
  "bugs": {
51
52
  "url": "https://github.com/alwaysmeticulous/meticulous-sdk/issues"
52
53
  },
53
- "gitHead": "a2278304222b519661a7e5c3365667fe68200533"
54
+ "gitHead": "7d96c06f778da2d0f81d54eceba929d103a32cbf"
54
55
  }
@@ -1,41 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const fs_1 = require("fs");
4
- const os_1 = require("os");
5
- const path_1 = require("path");
6
- const vitest_1 = require("vitest");
7
- const asset_upload_utils_1 = require("../asset-upload-utils");
8
- (0, vitest_1.describe)("createZipFromFolder", () => {
9
- let tempDir;
10
- let outputDir;
11
- (0, vitest_1.beforeEach)(() => {
12
- tempDir = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), "zip-test-"));
13
- outputDir = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), "zip-output-"));
14
- // Create test files
15
- for (let i = 0; i < 20; i++) {
16
- (0, fs_1.writeFileSync)((0, path_1.join)(tempDir, `file-${i}.txt`), `content ${i}`);
17
- }
18
- });
19
- (0, vitest_1.afterEach)(() => {
20
- (0, fs_1.rmSync)(tempDir, { recursive: true, force: true });
21
- (0, fs_1.rmSync)(outputDir, { recursive: true, force: true });
22
- });
23
- (0, vitest_1.it)("should create a valid zip file", async () => {
24
- const zipPath = (0, path_1.join)(outputDir, "test.zip");
25
- await (0, asset_upload_utils_1.createZipFromFolder)(tempDir, zipPath);
26
- (0, vitest_1.expect)((0, fs_1.existsSync)(zipPath)).toBe(true);
27
- (0, vitest_1.expect)((0, fs_1.statSync)(zipPath).size).toBeGreaterThan(0);
28
- });
29
- (0, vitest_1.it)("should not throw EBADF when run many times in parallel", async () => {
30
- // Run 100 times in parallel to stress test the file descriptor handling.
31
- // Before the fix (autoClose: false), this would intermittently fail with:
32
- // "EBADF: bad file descriptor, fsync"
33
- const promises = Array.from({ length: 100 }, (_, i) => (0, asset_upload_utils_1.createZipFromFolder)(tempDir, (0, path_1.join)(outputDir, `test-${i}.zip`)));
34
- await Promise.all(promises);
35
- // Verify all zips were created
36
- for (let i = 0; i < 100; i++) {
37
- (0, vitest_1.expect)((0, fs_1.existsSync)((0, path_1.join)(outputDir, `test-${i}.zip`))).toBe(true);
38
- }
39
- });
40
- });
41
- //# sourceMappingURL=asset-upload-utils.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"asset-upload-utils.spec.js","sourceRoot":"","sources":["../../src/__tests__/asset-upload-utils.spec.ts"],"names":[],"mappings":";;AAAA,2BAA8E;AAC9E,2BAA4B;AAC5B,+BAA4B;AAC5B,mCAAqE;AACrE,8DAA4D;AAE5D,IAAA,iBAAQ,EAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAI,OAAe,CAAC;IACpB,IAAI,SAAiB,CAAC;IAEtB,IAAA,mBAAU,EAAC,GAAG,EAAE;QACd,OAAO,GAAG,IAAA,gBAAW,EAAC,IAAA,WAAI,EAAC,IAAA,WAAM,GAAE,EAAE,WAAW,CAAC,CAAC,CAAC;QACnD,SAAS,GAAG,IAAA,gBAAW,EAAC,IAAA,WAAI,EAAC,IAAA,WAAM,GAAE,EAAE,aAAa,CAAC,CAAC,CAAC;QAEvD,oBAAoB;QACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;YAC3B,IAAA,kBAAa,EAAC,IAAA,WAAI,EAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;SAC/D;IACH,CAAC,CAAC,CAAC;IAEH,IAAA,kBAAS,EAAC,GAAG,EAAE;QACb,IAAA,WAAM,EAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,IAAA,WAAM,EAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,OAAO,GAAG,IAAA,WAAI,EAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC5C,MAAM,IAAA,wCAAmB,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE5C,IAAA,eAAM,EAAC,IAAA,eAAU,EAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,IAAA,eAAM,EAAC,IAAA,aAAQ,EAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,yEAAyE;QACzE,0EAA0E;QAC1E,sCAAsC;QACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACpD,IAAA,wCAAmB,EAAC,OAAO,EAAE,IAAA,WAAI,EAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAC/D,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE5B,+BAA+B;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE;YAC5B,IAAA,eAAM,EAAC,IAAA,eAAU,EAAC,IAAA,WAAI,EAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACjE;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}