@eik/core 2.1.57 → 2.1.59

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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [2.1.59](https://github.com/eik-lib/core/compare/v2.1.58...v2.1.59) (2026-06-09)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Improve unpacking files ([#598](https://github.com/eik-lib/core/issues/598)) ([41cd672](https://github.com/eik-lib/core/commit/41cd672db44af05e06acd2dc047bffb0ed2006a7))
7
+
8
+ ## [2.1.58](https://github.com/eik-lib/core/compare/v2.1.57...v2.1.58) (2026-06-09)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **deps:** update eik packages ([#600](https://github.com/eik-lib/core/issues/600)) ([c33320b](https://github.com/eik-lib/core/commit/c33320bd5263b4e9e8820e8661440fcb457d6c4b))
14
+
1
15
  ## [2.1.57](https://github.com/eik-lib/core/compare/v2.1.56...v2.1.57) (2026-06-08)
2
16
 
3
17
 
@@ -93,9 +93,12 @@ const MultipartParser = class MultipartParser {
93
93
  done(item);
94
94
  })
95
95
  .catch((error) => {
96
- // Emit an error on busboy instead of rejecting
97
- // This will break and terminate the stream stright away
96
+ // Emit an error on busboy instead of rejecting.
97
+ // This breaks and terminates the stream straight away.
98
98
  busboy.emit("error", error);
99
+ // Settle this wrapper Promise so Promise.all(queue)
100
+ // in the close handler can always complete.
101
+ done(null);
99
102
  });
100
103
  }),
101
104
  );
@@ -142,6 +145,7 @@ const MultipartParser = class MultipartParser {
142
145
  `multipart - Start extracting package - Field: ${fieldname} - Filename: ${filename}`,
143
146
  );
144
147
 
148
+ const ac = new AbortController();
145
149
  /** @type {Promise<any>[]} */
146
150
  const queue = [];
147
151
 
@@ -149,6 +153,7 @@ const MultipartParser = class MultipartParser {
149
153
  this._log.info(
150
154
  `multipart - Uploaded package exceeds legal file size limit - Field: ${fieldname} - Filename: ${filename}`,
151
155
  );
156
+ ac.abort();
152
157
  file.emit("error", new HttpError.PayloadTooLarge());
153
158
  });
154
159
 
@@ -161,7 +166,15 @@ const MultipartParser = class MultipartParser {
161
166
  entry.resume();
162
167
  return;
163
168
  }
164
- queue.push(this._persistFile({ incoming, entry }));
169
+ const persist = this._persistFile({
170
+ incoming,
171
+ entry,
172
+ signal: ac.signal,
173
+ });
174
+ // Suppress unhandled rejections from writes aborted due to
175
+ // an upstream error — they are intentionally abandoned.
176
+ persist.catch(() => {});
177
+ queue.push(persist);
165
178
  },
166
179
  });
167
180
 
@@ -172,6 +185,8 @@ const MultipartParser = class MultipartParser {
172
185
  );
173
186
  this._log.trace(error);
174
187
 
188
+ ac.abort();
189
+
175
190
  switch (error.code) {
176
191
  case "TAR_BAD_ARCHIVE":
177
192
  case "TAR_ABORT":
@@ -201,61 +216,71 @@ const MultipartParser = class MultipartParser {
201
216
  }
202
217
 
203
218
  /**
204
- * @param {{ incoming: any, entry: any }} options
219
+ * @param {{ incoming: any, entry: any, signal: AbortSignal }} options
205
220
  */
206
- _persistFile({ incoming, entry }) {
207
- // eslint-disable-next-line no-async-promise-executor
208
- return new Promise(async (resolve, reject) => {
209
- const asset = new Asset({
210
- pathname: entry.path,
211
- version: incoming.version,
212
- name: incoming.name,
213
- type: incoming.type,
214
- org: incoming.org,
215
- });
216
- asset.size = entry.size;
221
+ async _persistFile({ incoming, entry, signal }) {
222
+ const asset = new Asset({
223
+ pathname: entry.path,
224
+ version: incoming.version,
225
+ name: incoming.name,
226
+ type: incoming.type,
227
+ org: incoming.org,
228
+ });
229
+ asset.size = entry.size;
217
230
 
218
- const path = createFilePathToAsset(asset);
231
+ const path = createFilePathToAsset(asset);
219
232
 
220
- this._log.info(
221
- `multipart - Start writing asset to sink - Pathname: ${path}`,
222
- );
233
+ this._log.info(
234
+ `multipart - Start writing asset to sink - Pathname: ${path}`,
235
+ );
223
236
 
224
- try {
225
- if (!this._sink) {
226
- reject(new Error("No sink configured"));
227
- return;
228
- }
229
- const writer = await this._sink.write(path, asset.mimeType);
237
+ if (!this._sink) {
238
+ throw new Error("No sink configured");
239
+ }
240
+ const writer = await this._sink.write(path, asset.mimeType);
230
241
 
231
- const integrityStream = ssri.integrityStream({ single: true });
232
- let hash = "";
233
- integrityStream.once("integrity", (/** @type {any} */ integrity) => {
234
- hash = integrity;
235
- });
242
+ const integrityStream = ssri.integrityStream({ single: true });
243
+ let hash = "";
244
+ integrityStream.once("integrity", (/** @type {any} */ integrity) => {
245
+ hash = integrity;
246
+ });
236
247
 
237
- pipeline(entry, integrityStream, writer, (error) => {
238
- if (error) {
239
- this._log.error(
240
- `multipart - Failed writing asset to sink - Pathname: ${path}`,
241
- );
242
- this._log.trace(error);
248
+ return new Promise((resolve, reject) => {
249
+ const onAbort = () => {
250
+ entry.destroy();
251
+ integrityStream.destroy();
252
+ writer.destroy();
253
+ };
243
254
 
244
- reject(error);
245
- return;
246
- }
255
+ if (signal.aborted) {
256
+ onAbort();
257
+ reject(new Error("Aborted"));
258
+ return;
259
+ }
247
260
 
248
- asset.integrity = hash.toString();
261
+ signal.addEventListener("abort", onAbort, { once: true });
249
262
 
250
- this._log.info(
251
- `multipart - Successfully wrote asset to sink - Pathname: ${path}`,
263
+ pipeline(entry, integrityStream, writer, (error) => {
264
+ signal.removeEventListener("abort", onAbort);
265
+
266
+ if (error) {
267
+ this._log.error(
268
+ `multipart - Failed writing asset to sink - Pathname: ${path}`,
252
269
  );
270
+ this._log.trace(error);
253
271
 
254
- resolve(asset);
255
- });
256
- } catch (error) {
257
- reject(error);
258
- }
272
+ reject(error);
273
+ return;
274
+ }
275
+
276
+ asset.integrity = hash.toString();
277
+
278
+ this._log.info(
279
+ `multipart - Successfully wrote asset to sink - Pathname: ${path}`,
280
+ );
281
+
282
+ resolve(asset);
283
+ });
259
284
  });
260
285
  }
261
286
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eik/core",
3
- "version": "2.1.57",
3
+ "version": "2.1.59",
4
4
  "description": "Core server package",
5
5
  "main": "lib/main.js",
6
6
  "types": "./types/main.d.ts",
@@ -29,10 +29,10 @@
29
29
  "author": "",
30
30
  "license": "MIT",
31
31
  "dependencies": {
32
- "@eik/common": "5.1.31",
32
+ "@eik/common": "5.1.32",
33
33
  "@eik/sink": "1.2.7",
34
- "@eik/sink-file-system": "2.0.37",
35
- "@eik/sink-memory": "2.0.34",
34
+ "@eik/sink-file-system": "2.0.38",
35
+ "@eik/sink-memory": "2.0.35",
36
36
  "@metrics/client": "2.5.5",
37
37
  "abslog": "2.4.4",
38
38
  "busboy": "1.6.0",
@@ -51,9 +51,10 @@ declare const AliasPost: {
51
51
  filename: any;
52
52
  incoming: any;
53
53
  }): Promise<any>;
54
- _persistFile({ incoming, entry }: {
54
+ _persistFile({ incoming, entry, signal }: {
55
55
  incoming: any;
56
56
  entry: any;
57
+ signal: AbortSignal;
57
58
  }): Promise<any>;
58
59
  get [Symbol.toStringTag](): string;
59
60
  };
@@ -51,9 +51,10 @@ declare const AliasPut: {
51
51
  filename: any;
52
52
  incoming: any;
53
53
  }): Promise<any>;
54
- _persistFile({ incoming, entry }: {
54
+ _persistFile({ incoming, entry, signal }: {
55
55
  incoming: any;
56
56
  entry: any;
57
+ signal: AbortSignal;
57
58
  }): Promise<any>;
58
59
  get [Symbol.toStringTag](): string;
59
60
  };
@@ -51,9 +51,10 @@ declare const AuthPost: {
51
51
  filename: any;
52
52
  incoming: any;
53
53
  }): Promise<any>;
54
- _persistFile({ incoming, entry }: {
54
+ _persistFile({ incoming, entry, signal }: {
55
55
  incoming: any;
56
56
  entry: any;
57
+ signal: AbortSignal;
57
58
  }): Promise<any>;
58
59
  get [Symbol.toStringTag](): string;
59
60
  };
@@ -54,9 +54,10 @@ declare const PkgPut: {
54
54
  filename: any;
55
55
  incoming: any;
56
56
  }): Promise<any>;
57
- _persistFile({ incoming, entry }: {
57
+ _persistFile({ incoming, entry, signal }: {
58
58
  incoming: any;
59
59
  entry: any;
60
+ signal: AbortSignal;
60
61
  }): Promise<any>;
61
62
  get [Symbol.toStringTag](): string;
62
63
  };
@@ -52,11 +52,12 @@ declare const MultipartParser: {
52
52
  incoming: any;
53
53
  }): Promise<any>;
54
54
  /**
55
- * @param {{ incoming: any, entry: any }} options
55
+ * @param {{ incoming: any, entry: any, signal: AbortSignal }} options
56
56
  */
57
- _persistFile({ incoming, entry }: {
57
+ _persistFile({ incoming, entry, signal }: {
58
58
  incoming: any;
59
59
  entry: any;
60
+ signal: AbortSignal;
60
61
  }): Promise<any>;
61
62
  get [Symbol.toStringTag](): string;
62
63
  };