@pierre/storage 0.2.1 → 0.2.3

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
@@ -76,6 +76,26 @@ const readOnlyUrl = await repo.getRemoteURL({
76
76
  // - 'repo:write' - Create a repository
77
77
  ```
78
78
 
79
+ #### Ephemeral Branches
80
+
81
+ For working with ephemeral branches (temporary branches isolated from the main repository), use
82
+ `getEphemeralRemote()`:
83
+
84
+ ```typescript
85
+ // Get ephemeral namespace remote URL
86
+ const ephemeralUrl = await repo.getEphemeralRemoteURL();
87
+ // Returns: https://t:JWT@your-name.code.storage/repo-id+ephemeral.git
88
+
89
+ // Configure separate remotes for default and ephemeral branches
90
+ console.log(`Run: git remote add origin ${await repo.getRemoteURL()}`);
91
+ console.log(`Run: git remote add ephemeral ${await repo.getEphemeralRemoteURL()}`);
92
+
93
+ // Push ephemeral branch
94
+ // git push ephemeral feature-branch
95
+
96
+ // The ephemeral remote supports all the same options and permission as regular remotes
97
+ ```
98
+
79
99
  ### Working with Repository Content
80
100
 
81
101
  Once you have a repository instance, you can perform various Git operations:
@@ -129,6 +149,15 @@ const commitDiff = await repo.getCommitDiff({
129
149
  console.log(commitDiff.stats);
130
150
  console.log(commitDiff.files);
131
151
 
152
+ // Create a new branch from an existing one
153
+ const branch = await repo.createBranch({
154
+ baseBranch: 'main',
155
+ targetBranch: 'feature/demo',
156
+ // baseIsEphemeral: true,
157
+ // targetIsEphemeral: true,
158
+ });
159
+ console.log(branch.targetBranch, branch.commitSha);
160
+
132
161
  // Create a commit using the streaming helper
133
162
  const fs = await import('node:fs/promises');
134
163
  const result = await repo
@@ -281,6 +310,7 @@ interface FindOneOptions {
281
310
  interface Repo {
282
311
  id: string;
283
312
  getRemoteURL(options?: GetRemoteURLOptions): Promise<string>;
313
+ getEphemeralRemoteURL(options?: GetRemoteURLOptions): Promise<string>;
284
314
 
285
315
  getFileStream(options: GetFileOptions): Promise<Response>;
286
316
  listFiles(options?: ListFilesOptions): Promise<ListFilesResult>;
package/dist/index.cjs CHANGED
@@ -110,6 +110,12 @@ var commitDiffResponseSchema = zod.z.object({
110
110
  files: zod.z.array(diffFileRawSchema),
111
111
  filtered_files: zod.z.array(filteredFileRawSchema)
112
112
  });
113
+ var createBranchResponseSchema = zod.z.object({
114
+ message: zod.z.string(),
115
+ target_branch: zod.z.string(),
116
+ target_is_ephemeral: zod.z.boolean(),
117
+ commit_sha: zod.z.string().nullable().optional()
118
+ });
113
119
  var refUpdateResultSchema = zod.z.object({
114
120
  branch: zod.z.string(),
115
121
  old_sha: zod.z.string(),
@@ -1491,6 +1497,14 @@ function transformCommitDiffResult(raw) {
1491
1497
  filteredFiles: raw.filtered_files.map(transformFilteredFile)
1492
1498
  };
1493
1499
  }
1500
+ function transformCreateBranchResult(raw) {
1501
+ return {
1502
+ message: raw.message,
1503
+ targetBranch: raw.target_branch,
1504
+ targetIsEphemeral: raw.target_is_ephemeral,
1505
+ commitSha: raw.commit_sha ?? void 0
1506
+ };
1507
+ }
1494
1508
  var RepoImpl = class {
1495
1509
  constructor(id, options, generateJWT) {
1496
1510
  this.id = id;
@@ -1509,6 +1523,13 @@ var RepoImpl = class {
1509
1523
  url.password = await this.generateJWT(this.id, urlOptions);
1510
1524
  return url.toString();
1511
1525
  }
1526
+ async getEphemeralRemoteURL(urlOptions) {
1527
+ const storageBaseUrl = this.options.storageBaseUrl ?? STORAGE_BASE_URL;
1528
+ const url = new URL(`https://${this.options.name}.${storageBaseUrl}/${this.id}+ephemeral.git`);
1529
+ url.username = `t`;
1530
+ url.password = await this.generateJWT(this.id, urlOptions);
1531
+ return url.toString();
1532
+ }
1512
1533
  async getFileStream(options) {
1513
1534
  const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
1514
1535
  const jwt = await this.generateJWT(this.id, {
@@ -1626,7 +1647,7 @@ var RepoImpl = class {
1626
1647
  const raw = commitDiffResponseSchema.parse(await response.json());
1627
1648
  return transformCommitDiffResult(raw);
1628
1649
  }
1629
- async pullUpstream(options) {
1650
+ async pullUpstream(options = {}) {
1630
1651
  const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
1631
1652
  const jwt = await this.generateJWT(this.id, {
1632
1653
  permissions: ["git:write"],
@@ -1642,6 +1663,34 @@ var RepoImpl = class {
1642
1663
  }
1643
1664
  return;
1644
1665
  }
1666
+ async createBranch(options) {
1667
+ const baseBranch = options?.baseBranch?.trim();
1668
+ if (!baseBranch) {
1669
+ throw new Error("createBranch baseBranch is required");
1670
+ }
1671
+ const targetBranch = options?.targetBranch?.trim();
1672
+ if (!targetBranch) {
1673
+ throw new Error("createBranch targetBranch is required");
1674
+ }
1675
+ const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
1676
+ const jwt = await this.generateJWT(this.id, {
1677
+ permissions: ["git:write"],
1678
+ ttl
1679
+ });
1680
+ const body = {
1681
+ base_branch: baseBranch,
1682
+ target_branch: targetBranch
1683
+ };
1684
+ if (options.baseIsEphemeral === true) {
1685
+ body.base_is_ephemeral = true;
1686
+ }
1687
+ if (options.targetIsEphemeral === true) {
1688
+ body.target_is_ephemeral = true;
1689
+ }
1690
+ const response = await this.api.post({ path: "repos/branches/create", body }, jwt);
1691
+ const raw = createBranchResponseSchema.parse(await response.json());
1692
+ return transformCreateBranchResult(raw);
1693
+ }
1645
1694
  async restoreCommit(options) {
1646
1695
  const targetBranch = options?.targetBranch?.trim();
1647
1696
  if (!targetBranch) {