@eik/core 2.1.58 → 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 +7 -0
- package/lib/multipart/parser.js +72 -47
- package/package.json +1 -1
- package/types/handlers/alias.post.d.ts +2 -1
- package/types/handlers/alias.put.d.ts +2 -1
- package/types/handlers/auth.post.d.ts +2 -1
- package/types/handlers/pkg.put.d.ts +2 -1
- package/types/multipart/parser.d.ts +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
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
|
+
|
|
1
8
|
## [2.1.58](https://github.com/eik-lib/core/compare/v2.1.57...v2.1.58) (2026-06-09)
|
|
2
9
|
|
|
3
10
|
|
package/lib/multipart/parser.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
-
|
|
231
|
+
const path = createFilePathToAsset(asset);
|
|
219
232
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
233
|
+
this._log.info(
|
|
234
|
+
`multipart - Start writing asset to sink - Pathname: ${path}`,
|
|
235
|
+
);
|
|
223
236
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
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
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
248
|
+
return new Promise((resolve, reject) => {
|
|
249
|
+
const onAbort = () => {
|
|
250
|
+
entry.destroy();
|
|
251
|
+
integrityStream.destroy();
|
|
252
|
+
writer.destroy();
|
|
253
|
+
};
|
|
243
254
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
255
|
+
if (signal.aborted) {
|
|
256
|
+
onAbort();
|
|
257
|
+
reject(new Error("Aborted"));
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
247
260
|
|
|
248
|
-
|
|
261
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
249
262
|
|
|
250
|
-
|
|
251
|
-
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
@@ -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
|
};
|