hammerkit 1.20.0 → 1.21.1

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.
@@ -108,20 +108,18 @@ class RegistryClient {
108
108
  this.authorization = `Bearer ${token}`;
109
109
  return true;
110
110
  }
111
- // Send a request, performing the auth handshake once on a 401. `body` is a
112
- // factory because a streamed body cannot be replayed after the challenge.
111
+ // Send a request, performing the auth handshake once on a 401. A string,
112
+ // buffer or blob body is replayable and fetch derives its content-length;
113
+ // never set that header by hand, the undici that serves `fetch` rejects it
114
+ // on some Node versions.
113
115
  async request(method, urlOrPath, init = {}) {
114
116
  const url = urlOrPath.startsWith('http') ? urlOrPath : this.url(urlOrPath);
115
- const send = () => {
116
- const body = init.body?.();
117
- return fetch(url, {
118
- method,
119
- headers: { ...(init.headers ?? {}), ...(this.authorization ? { authorization: this.authorization } : {}) },
120
- body: body instanceof stream_1.Readable ? stream_1.Readable.toWeb(body) : body,
121
- redirect: init.redirect ?? 'follow',
122
- ...(body instanceof stream_1.Readable ? { duplex: 'half' } : {}),
123
- });
124
- };
117
+ const send = () => fetch(url, {
118
+ method,
119
+ headers: { ...(init.headers ?? {}), ...(this.authorization ? { authorization: this.authorization } : {}) },
120
+ body: init.body?.(),
121
+ redirect: init.redirect ?? 'follow',
122
+ });
125
123
  let response = await send();
126
124
  if (response.status === 401 && (await this.authenticate(response.headers.get('www-authenticate')))) {
127
125
  await response.body?.cancel();
@@ -223,8 +221,10 @@ class RegistryClient {
223
221
  return true;
224
222
  }
225
223
  // Upload a blob from a buffer or a file (monolithic upload: POST to open the
226
- // session, PUT the content with its digest to commit it).
227
- async uploadBlob(digest, size, content) {
224
+ // session, PUT the content with its digest to commit it). A file is sent as a
225
+ // blob backed by the file, so it is read lazily and fetch sends its size as
226
+ // the content-length.
227
+ async uploadBlob(digest, content) {
228
228
  if (await this.blobExists(digest)) {
229
229
  return;
230
230
  }
@@ -238,9 +238,10 @@ class RegistryClient {
238
238
  }
239
239
  const uploadUrl = new URL(location, this.url(''));
240
240
  uploadUrl.searchParams.set('digest', digest);
241
+ const body = 'buffer' in content ? content.buffer : await (0, fs_1.openAsBlob)(content.file);
241
242
  const response = await this.request('PUT', uploadUrl.toString(), {
242
- headers: { 'content-type': 'application/octet-stream', 'content-length': `${size}` },
243
- body: () => ('buffer' in content ? content.buffer : (0, fs_1.createReadStream)(content.file)),
243
+ headers: { 'content-type': 'application/octet-stream' },
244
+ body: () => body,
244
245
  });
245
246
  if (response.status !== 201) {
246
247
  return this.fail(response, `uploading blob ${digest}`);
@@ -85,8 +85,8 @@ function createRegistryCacheBackend(spec) {
85
85
  config: { Labels: { 'dev.hammerkit.task-id': taskId, 'dev.hammerkit.state-key': stateKey } },
86
86
  }));
87
87
  const configDigest = (0, registry_client_1.digestBuffer)(config);
88
- await registry.uploadBlob(layer.digest, layer.size, { file: layerFile });
89
- await registry.uploadBlob(configDigest.digest, configDigest.size, { buffer: config });
88
+ await registry.uploadBlob(layer.digest, { file: layerFile });
89
+ await registry.uploadBlob(configDigest.digest, { buffer: config });
90
90
  const manifest = {
91
91
  schemaVersion: 2,
92
92
  mediaType: registry_client_1.OCI_MANIFEST,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hammerkit",
3
3
  "description": "Containerized build tool with incremental caching that runs the same build file locally, in Docker and on Kubernetes.",
4
- "version": "1.20.0",
4
+ "version": "1.21.1",
5
5
  "keywords": [
6
6
  "build",
7
7
  "build-tool",