@pierre/storage 0.0.10 → 0.1.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/README.md CHANGED
@@ -51,7 +51,7 @@ The SDK generates secure URLs with JWT authentication for Git operations:
51
51
  ```typescript
52
52
  // Get URL with default permissions (git:write, git:read) and 1-year TTL
53
53
  const url = await repo.getRemoteURL();
54
- // Returns: https://t:JWT@your-name.git.storage/repo-id.git
54
+ // Returns: https://t:JWT@your-name.code.storage/repo-id.git
55
55
 
56
56
  // Configure the Git remote
57
57
  console.log(`Run: git remote add origin ${url}`);
@@ -120,6 +120,89 @@ const commitDiff = await repo.getCommitDiff({
120
120
  });
121
121
  console.log(commitDiff.stats);
122
122
  console.log(commitDiff.files);
123
+
124
+ // Create a commit using the streaming helper
125
+ const fs = await import('node:fs/promises');
126
+ const result = await repo
127
+ .createCommit({
128
+ targetRef: 'refs/heads/main',
129
+ commitMessage: 'Update docs',
130
+ author: { name: 'Docs Bot', email: 'docs@example.com' },
131
+ })
132
+ .addFileFromString('docs/changelog.md', '# v2.0.1\n- add streaming SDK\n')
133
+ .addFile('docs/readme.md', await fs.readFile('README.md'))
134
+ .deletePath('docs/legacy.txt')
135
+ .send();
136
+
137
+ console.log(result.commitSha);
138
+ console.log(result.refUpdate.newSha);
139
+ console.log(result.refUpdate.oldSha); // All zeroes when the ref is created
140
+ ```
141
+
142
+ The builder exposes:
143
+
144
+ - `addFile(path, source, options)` to attach bytes from strings, typed arrays, ArrayBuffers, `Blob`
145
+ or `File` objects, `ReadableStream`s, or iterable/async-iterable sources.
146
+ - `addFileFromString(path, contents, options)` for text helpers (defaults to UTF-8 and accepts any
147
+ Node.js `BufferEncoding`).
148
+ - `deletePath(path)` to remove files or folders.
149
+ - `send()` to finalize the commit and receive metadata about the new commit.
150
+
151
+ `send()` resolves to an object with the new commit metadata plus the ref update:
152
+
153
+ ```ts
154
+ type CommitResult = {
155
+ commitSha: string;
156
+ treeSha: string;
157
+ targetRef: string;
158
+ packBytes: number;
159
+ blobCount: number;
160
+ refUpdate: {
161
+ ref: string;
162
+ oldSha: string; // All zeroes when the ref is created
163
+ newSha: string;
164
+ };
165
+ };
166
+ ```
167
+
168
+ If the backend reports a failure (for example, the branch advanced past `baseRef`) the builder
169
+ throws a `RefUpdateError` containing the status, reason, and ref details.
170
+
171
+ **Options**
172
+
173
+ - `targetRef` (required): Fully qualified ref that will receive the commit (for example
174
+ `refs/heads/main`).
175
+ - `baseRef` (optional): Branch or commit that must match the remote tip; omit to fast-forward
176
+ unconditionally.
177
+ - `commitMessage` (required): The commit message.
178
+ - `author` (required): Include `name` and `email` for the commit author.
179
+ - `committer` (optional): Include `name` and `email`. If omitted, the author identity is reused.
180
+ - `signal` (optional): Abort an in-flight upload with `AbortController`.
181
+
182
+ > Files are chunked into 4 MiB segments under the hood, so you can stream large assets without
183
+ > buffering them entirely in memory. File paths are normalized relative to the repository root.
184
+
185
+ > The `targetRef` must already exist on the remote repository. To seed an empty repository, point to
186
+ > the default branch and omit `baseRef`; the service will create the first commit only when no refs
187
+ > are present.
188
+
189
+ ### Streaming Large Files
190
+
191
+ The commit builder accepts any async iterable of bytes, so you can stream large assets without
192
+ buffering:
193
+
194
+ ```typescript
195
+ import { createReadStream } from 'node:fs';
196
+
197
+ await repo
198
+ .createCommit({
199
+ targetRef: 'refs/heads/assets',
200
+ baseRef: 'refs/heads/main',
201
+ commitMessage: 'Upload latest design bundle',
202
+ author: { name: 'Assets Uploader', email: 'assets@example.com' },
203
+ })
204
+ .addFile('assets/design-kit.zip', createReadStream('/tmp/design-kit.zip'))
205
+ .send();
123
206
  ```
124
207
 
125
208
  ## API Reference
@@ -141,6 +224,7 @@ class GitStorage {
141
224
  interface GitStorageOptions {
142
225
  name: string; // Your identifier
143
226
  key: string; // Your API key
227
+ defaultTTL?: number; // Default TTL for generated JWTs (seconds)
144
228
  }
145
229
 
146
230
  interface CreateRepoOptions {
@@ -156,11 +240,11 @@ interface Repo {
156
240
  getRemoteURL(options?: GetRemoteURLOptions): Promise<string>;
157
241
 
158
242
  getFileStream(options: GetFileOptions): Promise<Response>;
159
- listFiles(options?: ListFilesOptions): Promise<ListFilesResponse>;
160
- listBranches(options?: ListBranchesOptions): Promise<ListBranchesResponse>;
161
- listCommits(options?: ListCommitsOptions): Promise<ListCommitsResponse>;
162
- getBranchDiff(options: GetBranchDiffOptions): Promise<GetBranchDiffResponse>;
163
- getCommitDiff(options: GetCommitDiffOptions): Promise<GetCommitDiffResponse>;
243
+ listFiles(options?: ListFilesOptions): Promise<ListFilesResult>;
244
+ listBranches(options?: ListBranchesOptions): Promise<ListBranchesResult>;
245
+ listCommits(options?: ListCommitsOptions): Promise<ListCommitsResult>;
246
+ getBranchDiff(options: GetBranchDiffOptions): Promise<GetBranchDiffResult>;
247
+ getCommitDiff(options: GetCommitDiffOptions): Promise<GetCommitDiffResult>;
164
248
  }
165
249
 
166
250
  interface GetRemoteURLOptions {
@@ -172,12 +256,14 @@ interface GetRemoteURLOptions {
172
256
  interface GetFileOptions {
173
257
  path: string;
174
258
  ref?: string; // Branch, tag, or commit SHA
259
+ ttl?: number;
175
260
  }
176
261
 
177
262
  // getFileStream() returns a standard Fetch Response for streaming bytes
178
263
 
179
264
  interface ListFilesOptions {
180
265
  ref?: string; // Branch, tag, or commit SHA
266
+ ttl?: number;
181
267
  }
182
268
 
183
269
  interface ListFilesResponse {
@@ -185,53 +271,75 @@ interface ListFilesResponse {
185
271
  ref: string; // The resolved reference
186
272
  }
187
273
 
274
+ interface ListFilesResult {
275
+ paths: string[];
276
+ ref: string;
277
+ }
278
+
188
279
  interface ListBranchesOptions {
189
280
  cursor?: string;
190
281
  limit?: number;
282
+ ttl?: number;
191
283
  }
192
284
 
193
285
  interface ListBranchesResponse {
194
286
  branches: BranchInfo[];
195
- next_cursor?: string;
196
- has_more: boolean;
287
+ nextCursor?: string;
288
+ hasMore: boolean;
289
+ }
290
+
291
+ interface ListBranchesResult {
292
+ branches: BranchInfo[];
293
+ nextCursor?: string;
294
+ hasMore: boolean;
197
295
  }
198
296
 
199
297
  interface BranchInfo {
200
298
  cursor: string;
201
299
  name: string;
202
- head_sha: string;
203
- created_at: string;
300
+ headSha: string;
301
+ createdAt: string;
204
302
  }
205
303
 
206
304
  interface ListCommitsOptions {
207
305
  branch?: string;
208
306
  cursor?: string;
209
307
  limit?: number;
308
+ ttl?: number;
210
309
  }
211
310
 
212
311
  interface ListCommitsResponse {
213
312
  commits: CommitInfo[];
214
- next_cursor?: string;
215
- has_more: boolean;
313
+ nextCursor?: string;
314
+ hasMore: boolean;
315
+ }
316
+
317
+ interface ListCommitsResult {
318
+ commits: CommitInfo[];
319
+ nextCursor?: string;
320
+ hasMore: boolean;
216
321
  }
217
322
 
218
323
  interface CommitInfo {
219
324
  sha: string;
220
325
  message: string;
221
- author_name: string;
222
- author_email: string;
223
- committer_name: string;
224
- committer_email: string;
225
- date: string;
326
+ authorName: string;
327
+ authorEmail: string;
328
+ committerName: string;
329
+ committerEmail: string;
330
+ date: Date;
331
+ rawDate: string;
226
332
  }
227
333
 
228
334
  interface GetBranchDiffOptions {
229
335
  branch: string;
230
336
  base?: string; // Defaults to 'main'
337
+ ttl?: number;
231
338
  }
232
339
 
233
340
  interface GetCommitDiffOptions {
234
341
  sha: string;
342
+ ttl?: number;
235
343
  }
236
344
 
237
345
  interface GetBranchDiffResponse {
@@ -239,16 +347,30 @@ interface GetBranchDiffResponse {
239
347
  base: string;
240
348
  stats: DiffStats;
241
349
  files: FileDiff[];
242
- filtered_files: FilteredFile[];
350
+ filteredFiles: FilteredFile[];
351
+ }
352
+
353
+ interface GetBranchDiffResult {
354
+ branch: string;
355
+ base: string;
356
+ stats: DiffStats;
357
+ files: FileDiff[];
358
+ filteredFiles: FilteredFile[];
243
359
  }
244
360
 
245
361
  interface GetCommitDiffResponse {
246
362
  sha: string;
247
363
  stats: DiffStats;
248
364
  files: FileDiff[];
249
- filtered_files: FilteredFile[];
365
+ filteredFiles: FilteredFile[];
250
366
  }
251
367
 
368
+ interface GetCommitDiffResult {
369
+ sha: string;
370
+ stats: DiffStats;
371
+ files: FileDiff[];
372
+ filteredFiles: FilteredFile[];
373
+ }
252
374
  interface DiffStats {
253
375
  files: number;
254
376
  additions: number;
@@ -256,21 +378,78 @@ interface DiffStats {
256
378
  changes: number;
257
379
  }
258
380
 
381
+ type DiffFileState =
382
+ | 'added'
383
+ | 'modified'
384
+ | 'deleted'
385
+ | 'renamed'
386
+ | 'copied'
387
+ | 'type_changed'
388
+ | 'unmerged'
389
+ | 'unknown';
390
+
391
+ interface DiffFileBase {
392
+ path: string;
393
+ state: DiffFileState;
394
+ rawState: string;
395
+ oldPath?: string;
396
+ bytes: number;
397
+ isEof: boolean;
398
+ }
399
+
259
400
  interface FileDiff {
260
401
  path: string;
261
- state: string;
262
- old_path?: string;
402
+ state: DiffFileState;
403
+ rawState: string;
404
+ oldPath?: string;
263
405
  bytes: number;
264
- is_eof: boolean;
265
- diff: string;
406
+ isEof: boolean;
407
+ raw: string;
266
408
  }
267
409
 
268
410
  interface FilteredFile {
269
411
  path: string;
270
- state: string;
271
- old_path?: string;
412
+ state: DiffFileState;
413
+ rawState: string;
414
+ oldPath?: string;
272
415
  bytes: number;
273
- is_eof: boolean;
416
+ isEof: boolean;
417
+ }
418
+
419
+ interface RefUpdate {
420
+ ref: string;
421
+ oldSha: string;
422
+ newSha: string;
423
+ }
424
+
425
+ interface CommitResult {
426
+ commitSha: string;
427
+ treeSha: string;
428
+ targetRef: string;
429
+ packBytes: number;
430
+ blobCount: number;
431
+ refUpdate: RefUpdate;
432
+ }
433
+
434
+ interface ResetCommitOptions {
435
+ targetBranch: string;
436
+ targetCommitSha: string;
437
+ commitMessage?: string;
438
+ expectedHeadSha?: string;
439
+ author: CommitSignature;
440
+ committer?: CommitSignature;
441
+ }
442
+
443
+ interface ResetCommitResult {
444
+ commitSha: string;
445
+ treeSha: string;
446
+ targetBranch: string;
447
+ packBytes: number;
448
+ refUpdate: {
449
+ branch: string;
450
+ oldSha: string;
451
+ newSha: string;
452
+ };
274
453
  }
275
454
  ```
276
455
 
@@ -301,28 +480,12 @@ try {
301
480
  } catch (error) {
302
481
  // Error: GitStorage key must be a non-empty string.
303
482
  }
483
+ -
304
484
  ```
305
485
 
306
- ## Development
307
-
308
- This package is part of the Pierre monorepo. To work on it locally:
309
-
310
- ```bash
311
- # Install dependencies
312
- pnpm install
313
-
314
- # Build the package
315
- moon git-storage-sdk:build
316
-
317
- # Run tests
318
- moon git-storage-sdk:test
319
-
320
- # Run in watch mode
321
- moon git-storage-sdk:dev
322
-
323
- # Format code
324
- moon git-storage-sdk:format-write
325
- ```
486
+ - Mutating operations (commit builder, `resetCommit`) throw `RefUpdateError` when the backend
487
+ reports a ref failure. Inspect `error.status`, `error.reason`, `error.message`, and
488
+ `error.refUpdate` for details.
326
489
 
327
490
  ## License
328
491