@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 +209 -46
- package/dist/index.cjs +1079 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +578 -62
- package/dist/index.d.ts +578 -62
- package/dist/index.js +1078 -51
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/src/commit.ts +649 -0
- package/src/errors.ts +50 -0
- package/src/fetch.ts +75 -5
- package/src/index.ts +408 -44
- package/src/schemas.ts +138 -0
- package/src/types.ts +211 -62
- package/src/util.ts +0 -18
- package/src/webhook.ts +75 -3
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.
|
|
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<
|
|
160
|
-
listBranches(options?: ListBranchesOptions): Promise<
|
|
161
|
-
listCommits(options?: ListCommitsOptions): Promise<
|
|
162
|
-
getBranchDiff(options: GetBranchDiffOptions): Promise<
|
|
163
|
-
getCommitDiff(options: GetCommitDiffOptions): Promise<
|
|
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
|
-
|
|
196
|
-
|
|
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
|
-
|
|
203
|
-
|
|
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
|
-
|
|
215
|
-
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
date:
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
262
|
-
|
|
402
|
+
state: DiffFileState;
|
|
403
|
+
rawState: string;
|
|
404
|
+
oldPath?: string;
|
|
263
405
|
bytes: number;
|
|
264
|
-
|
|
265
|
-
|
|
406
|
+
isEof: boolean;
|
|
407
|
+
raw: string;
|
|
266
408
|
}
|
|
267
409
|
|
|
268
410
|
interface FilteredFile {
|
|
269
411
|
path: string;
|
|
270
|
-
state:
|
|
271
|
-
|
|
412
|
+
state: DiffFileState;
|
|
413
|
+
rawState: string;
|
|
414
|
+
oldPath?: string;
|
|
272
415
|
bytes: number;
|
|
273
|
-
|
|
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
|
-
|
|
307
|
-
|
|
308
|
-
|
|
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
|
|