@pierre/storage 0.1.3 → 0.2.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.
package/src/commit.ts CHANGED
@@ -40,6 +40,8 @@ interface CommitMetadataPayload {
40
40
  expected_head_sha?: string;
41
41
  base_branch?: string;
42
42
  commit_message: string;
43
+ ephemeral?: boolean;
44
+ ephemeral_base?: boolean;
43
45
  author: {
44
46
  name: string;
45
47
  email: string;
@@ -72,6 +74,8 @@ type NormalizedCommitOptions = {
72
74
  commitMessage: string;
73
75
  expectedHeadSha?: string;
74
76
  baseBranch?: string;
77
+ ephemeral?: boolean;
78
+ ephemeralBase?: boolean;
75
79
  author: CommitSignature;
76
80
  committer?: CommitSignature;
77
81
  signal?: AbortSignal;
@@ -135,6 +139,10 @@ export class CommitBuilderImpl implements CommitBuilder {
135
139
  this.options.baseBranch = trimmedBase;
136
140
  }
137
141
  }
142
+
143
+ if (this.options.ephemeralBase && !this.options.baseBranch) {
144
+ throw new Error('createCommit ephemeralBase requires baseBranch');
145
+ }
138
146
  }
139
147
 
140
148
  addFile(path: string, source: CommitFileSource, options?: CommitFileOptions): CommitBuilder {
@@ -246,6 +254,13 @@ export class CommitBuilderImpl implements CommitBuilder {
246
254
  };
247
255
  }
248
256
 
257
+ if (this.options.ephemeral) {
258
+ metadata.ephemeral = true;
259
+ }
260
+ if (this.options.ephemeralBase) {
261
+ metadata.ephemeral_base = true;
262
+ }
263
+
249
264
  return metadata;
250
265
  }
251
266
 
@@ -275,7 +290,7 @@ export class FetchCommitTransport implements CommitTransport {
275
290
  const bodyIterable = buildMessageIterable(request.metadata, request.blobs);
276
291
  const body = toRequestBody(bodyIterable);
277
292
 
278
- const response = await fetch(this.url, {
293
+ const init: RequestInit = {
279
294
  method: 'POST',
280
295
  headers: {
281
296
  Authorization: `Bearer ${request.authorization}`,
@@ -284,7 +299,13 @@ export class FetchCommitTransport implements CommitTransport {
284
299
  },
285
300
  body: body as any,
286
301
  signal: request.signal,
287
- });
302
+ };
303
+
304
+ if (requiresDuplex(body)) {
305
+ (init as RequestInit & { duplex: 'half' }).duplex = 'half';
306
+ }
307
+
308
+ const response = await fetch(this.url, init);
288
309
 
289
310
  if (!response.ok) {
290
311
  const { statusMessage, statusLabel, refUpdate } = await parseCommitPackError(response);
@@ -349,6 +370,27 @@ function buildMessageIterable(
349
370
  };
350
371
  }
351
372
 
373
+ function requiresDuplex(body: unknown): boolean {
374
+ if (!body || typeof body !== 'object') {
375
+ return false;
376
+ }
377
+
378
+ if (typeof (body as { [Symbol.asyncIterator]?: unknown })[Symbol.asyncIterator] === 'function') {
379
+ return true;
380
+ }
381
+
382
+ const readableStreamCtor = (
383
+ globalThis as {
384
+ ReadableStream?: new (...args: unknown[]) => unknown;
385
+ }
386
+ ).ReadableStream;
387
+ if (readableStreamCtor && body instanceof readableStreamCtor) {
388
+ return true;
389
+ }
390
+
391
+ return false;
392
+ }
393
+
352
394
  function buildCommitResult(ack: CommitPackAck): CommitResult {
353
395
  const refUpdate = toRefUpdate(ack.result);
354
396
  if (!ack.result.success) {
@@ -574,6 +616,8 @@ function normalizeCommitOptions(options: CreateCommitOptions): NormalizedCommitO
574
616
  commitMessage: options.commitMessage,
575
617
  expectedHeadSha: options.expectedHeadSha,
576
618
  baseBranch: options.baseBranch,
619
+ ephemeral: options.ephemeral === true,
620
+ ephemeralBase: options.ephemeralBase === true,
577
621
  author: options.author,
578
622
  committer: options.committer,
579
623
  signal: options.signal,
package/src/index.ts CHANGED
@@ -357,6 +357,9 @@ class RepoImpl implements Repo {
357
357
  if (options.ref) {
358
358
  params.ref = options.ref;
359
359
  }
360
+ if (typeof options.ephemeral === 'boolean') {
361
+ params.ephemeral = String(options.ephemeral);
362
+ }
360
363
 
361
364
  // Return the raw fetch Response for streaming
362
365
  return this.api.get({ path: 'repos/file', params }, jwt);
@@ -369,10 +372,17 @@ class RepoImpl implements Repo {
369
372
  ttl,
370
373
  });
371
374
 
372
- const params: Record<string, string> | undefined = options?.ref
373
- ? { ref: options.ref }
374
- : undefined;
375
- const response = await this.api.get({ path: 'repos/files', params }, jwt);
375
+ const params: Record<string, string> = {};
376
+ if (options?.ref) {
377
+ params.ref = options.ref;
378
+ }
379
+ if (typeof options?.ephemeral === 'boolean') {
380
+ params.ephemeral = String(options.ephemeral);
381
+ }
382
+ const response = await this.api.get(
383
+ { path: 'repos/files', params: Object.keys(params).length ? params : undefined },
384
+ jwt,
385
+ );
376
386
 
377
387
  const raw = listFilesResponseSchema.parse(await response.json());
378
388
  return { paths: raw.paths, ref: raw.ref };
package/src/types.ts CHANGED
@@ -88,6 +88,7 @@ export interface CreateRepoOptions extends GitStorageInvocationOptions {
88
88
  export interface GetFileOptions extends GitStorageInvocationOptions {
89
89
  path: string;
90
90
  ref?: string;
91
+ ephemeral?: boolean;
91
92
  }
92
93
 
93
94
  export interface PullUpstreamOptions extends GitStorageInvocationOptions {
@@ -97,6 +98,7 @@ export interface PullUpstreamOptions extends GitStorageInvocationOptions {
97
98
  // List Files API types
98
99
  export interface ListFilesOptions extends GitStorageInvocationOptions {
99
100
  ref?: string;
101
+ ephemeral?: boolean;
100
102
  }
101
103
 
102
104
  export type ListFilesResponse = ListFilesResponseRaw;
@@ -228,6 +230,8 @@ interface CreateCommitBaseOptions extends GitStorageInvocationOptions {
228
230
  commitMessage: string;
229
231
  expectedHeadSha?: string;
230
232
  baseBranch?: string;
233
+ ephemeral?: boolean;
234
+ ephemeralBase?: boolean;
231
235
  author: CommitSignature;
232
236
  committer?: CommitSignature;
233
237
  signal?: AbortSignal;