@pierre/storage 0.0.3 → 0.0.5

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
@@ -68,6 +68,59 @@ const readOnlyUrl = await repo.getRemoteURL({
68
68
  // - 'repo:write' - Create a repository
69
69
  ```
70
70
 
71
+ ### Working with Repository Content
72
+
73
+ Once you have a repository instance, you can perform various Git operations:
74
+
75
+ ```typescript
76
+ const repo = await store.createRepo();
77
+ // or
78
+ const repo = await store.findOne({ id: 'existing-repo-id' });
79
+
80
+ // Get file content
81
+ const file = await repo.getFile({
82
+ path: 'README.md',
83
+ ref: 'main', // optional, defaults to default branch
84
+ });
85
+ console.log(file.content);
86
+
87
+ // List all files in the repository
88
+ const files = await repo.listFiles({
89
+ ref: 'main', // optional, defaults to default branch
90
+ });
91
+ console.log(files.paths); // Array of file paths
92
+
93
+ // List branches
94
+ const branches = await repo.listBranches({
95
+ limit: 10,
96
+ cursor: undefined, // for pagination
97
+ });
98
+ console.log(branches.branches);
99
+
100
+ // List commits
101
+ const commits = await repo.listCommits({
102
+ branch: 'main', // optional
103
+ limit: 20,
104
+ cursor: undefined, // for pagination
105
+ });
106
+ console.log(commits.commits);
107
+
108
+ // Get branch diff
109
+ const branchDiff = await repo.getBranchDiff({
110
+ branch: 'feature-branch',
111
+ base: 'main', // optional, defaults to main
112
+ });
113
+ console.log(branchDiff.stats);
114
+ console.log(branchDiff.files);
115
+
116
+ // Get commit diff
117
+ const commitDiff = await repo.getCommitDiff({
118
+ sha: 'abc123...',
119
+ });
120
+ console.log(commitDiff.stats);
121
+ console.log(commitDiff.files);
122
+ ```
123
+
71
124
  ## API Reference
72
125
 
73
126
  ### GitStorage
@@ -100,12 +153,129 @@ interface FindOneOptions {
100
153
  interface Repo {
101
154
  id: string;
102
155
  getRemoteURL(options?: GetRemoteURLOptions): Promise<string>;
156
+ getFile(options: GetFileOptions): Promise<GetFileResponse>;
157
+ listFiles(options?: ListFilesOptions): Promise<ListFilesResponse>;
158
+ listBranches(options?: ListBranchesOptions): Promise<ListBranchesResponse>;
159
+ listCommits(options?: ListCommitsOptions): Promise<ListCommitsResponse>;
160
+ getBranchDiff(options: GetBranchDiffOptions): Promise<GetBranchDiffResponse>;
161
+ getCommitDiff(options: GetCommitDiffOptions): Promise<GetCommitDiffResponse>;
103
162
  }
104
163
 
105
164
  interface GetRemoteURLOptions {
106
165
  permissions?: ('git:write' | 'git:read' | 'repo:write')[];
107
166
  ttl?: number; // Time to live in seconds (default: 31536000 = 1 year)
108
167
  }
168
+
169
+ // Git operation interfaces
170
+ interface GetFileOptions {
171
+ path: string;
172
+ ref?: string; // Branch, tag, or commit SHA
173
+ }
174
+
175
+ interface GetFileResponse {
176
+ path: string;
177
+ ref: string;
178
+ content: string;
179
+ size: number;
180
+ is_binary: boolean;
181
+ }
182
+
183
+ interface ListFilesOptions {
184
+ ref?: string; // Branch, tag, or commit SHA
185
+ }
186
+
187
+ interface ListFilesResponse {
188
+ paths: string[]; // Array of file paths
189
+ ref: string; // The resolved reference
190
+ }
191
+
192
+ interface ListBranchesOptions {
193
+ cursor?: string;
194
+ limit?: number;
195
+ }
196
+
197
+ interface ListBranchesResponse {
198
+ branches: BranchInfo[];
199
+ next_cursor?: string;
200
+ has_more: boolean;
201
+ }
202
+
203
+ interface BranchInfo {
204
+ cursor: string;
205
+ name: string;
206
+ head_sha: string;
207
+ created_at: string;
208
+ }
209
+
210
+ interface ListCommitsOptions {
211
+ branch?: string;
212
+ cursor?: string;
213
+ limit?: number;
214
+ }
215
+
216
+ interface ListCommitsResponse {
217
+ commits: CommitInfo[];
218
+ next_cursor?: string;
219
+ has_more: boolean;
220
+ }
221
+
222
+ interface CommitInfo {
223
+ sha: string;
224
+ message: string;
225
+ author_name: string;
226
+ author_email: string;
227
+ committer_name: string;
228
+ committer_email: string;
229
+ date: string;
230
+ }
231
+
232
+ interface GetBranchDiffOptions {
233
+ branch: string;
234
+ base?: string; // Defaults to 'main'
235
+ }
236
+
237
+ interface GetCommitDiffOptions {
238
+ sha: string;
239
+ }
240
+
241
+ interface GetBranchDiffResponse {
242
+ branch: string;
243
+ base: string;
244
+ stats: DiffStats;
245
+ files: FileDiff[];
246
+ filtered_files: FilteredFile[];
247
+ }
248
+
249
+ interface GetCommitDiffResponse {
250
+ sha: string;
251
+ stats: DiffStats;
252
+ files: FileDiff[];
253
+ filtered_files: FilteredFile[];
254
+ }
255
+
256
+ interface DiffStats {
257
+ files: number;
258
+ additions: number;
259
+ deletions: number;
260
+ changes: number;
261
+ }
262
+
263
+ interface FileDiff {
264
+ path: string;
265
+ state: string;
266
+ old_path?: string;
267
+ bytes: number;
268
+ is_eof: boolean;
269
+ diff: string;
270
+ }
271
+
272
+ interface FilteredFile {
273
+ path: string;
274
+ state: string;
275
+ old_path?: string;
276
+ bytes: number;
277
+ is_eof: boolean;
278
+ }
109
279
  ```
110
280
 
111
281
  ## Authentication
package/dist/index.cjs CHANGED
@@ -5,6 +5,174 @@ var jose = require('jose');
5
5
  // src/index.ts
6
6
  var API_BASE_URL = "https://api.git.storage";
7
7
  var STORAGE_BASE_URL = "git.storage";
8
+ var RepoImpl = class {
9
+ constructor(id, options, generateJWT) {
10
+ this.id = id;
11
+ this.options = options;
12
+ this.generateJWT = generateJWT;
13
+ }
14
+ async getRemoteURL(urlOptions) {
15
+ const url = new URL(`https://${this.options.name}.${STORAGE_BASE_URL}/${this.id}.git`);
16
+ url.username = `t`;
17
+ url.password = await this.generateJWT(this.id, urlOptions);
18
+ return url.toString();
19
+ }
20
+ async getFile(options) {
21
+ const jwt = await this.generateJWT(this.id, {
22
+ permissions: ["git:read"],
23
+ ttl: 1 * 60 * 60
24
+ // 1hr in seconds
25
+ });
26
+ const url = new URL(`${API_BASE_URL}/api/v1/repos/file`);
27
+ url.searchParams.set("path", options.path);
28
+ if (options.ref) {
29
+ url.searchParams.set("ref", options.ref);
30
+ }
31
+ const response = await fetch(url.toString(), {
32
+ method: "GET",
33
+ headers: {
34
+ Authorization: `Bearer ${jwt}`
35
+ }
36
+ });
37
+ if (!response.ok) {
38
+ throw new Error(`Failed to get file: ${response.statusText}`);
39
+ }
40
+ return await response.json();
41
+ }
42
+ async listFiles(options) {
43
+ const jwt = await this.generateJWT(this.id, {
44
+ permissions: ["git:read"],
45
+ ttl: 1 * 60 * 60
46
+ // 1hr in seconds
47
+ });
48
+ const url = new URL(`${API_BASE_URL}/api/v1/repos/files`);
49
+ if (options?.ref) {
50
+ url.searchParams.set("ref", options.ref);
51
+ }
52
+ const response = await fetch(url.toString(), {
53
+ method: "GET",
54
+ headers: {
55
+ Authorization: `Bearer ${jwt}`
56
+ }
57
+ });
58
+ if (!response.ok) {
59
+ throw new Error(`Failed to list files: ${response.statusText}`);
60
+ }
61
+ return await response.json();
62
+ }
63
+ async listBranches(options) {
64
+ const jwt = await this.generateJWT(this.id, {
65
+ permissions: ["git:read"],
66
+ ttl: 1 * 60 * 60
67
+ // 1hr in seconds
68
+ });
69
+ const url = new URL(`${API_BASE_URL}/api/v1/repos/branches`);
70
+ if (options?.cursor) {
71
+ url.searchParams.set("cursor", options.cursor);
72
+ }
73
+ if (options?.limit) {
74
+ url.searchParams.set("limit", options.limit.toString());
75
+ }
76
+ const response = await fetch(url.toString(), {
77
+ method: "GET",
78
+ headers: {
79
+ Authorization: `Bearer ${jwt}`
80
+ }
81
+ });
82
+ if (!response.ok) {
83
+ throw new Error(`Failed to list branches: ${response.statusText}`);
84
+ }
85
+ return await response.json();
86
+ }
87
+ async listCommits(options) {
88
+ const jwt = await this.generateJWT(this.id, {
89
+ permissions: ["git:read"],
90
+ ttl: 1 * 60 * 60
91
+ // 1hr in seconds
92
+ });
93
+ const url = new URL(`${API_BASE_URL}/api/v1/repos/commits`);
94
+ if (options?.branch) {
95
+ url.searchParams.set("branch", options.branch);
96
+ }
97
+ if (options?.cursor) {
98
+ url.searchParams.set("cursor", options.cursor);
99
+ }
100
+ if (options?.limit) {
101
+ url.searchParams.set("limit", options.limit.toString());
102
+ }
103
+ const response = await fetch(url.toString(), {
104
+ method: "GET",
105
+ headers: {
106
+ Authorization: `Bearer ${jwt}`
107
+ }
108
+ });
109
+ if (!response.ok) {
110
+ throw new Error(`Failed to list commits: ${response.statusText}`);
111
+ }
112
+ return await response.json();
113
+ }
114
+ async getBranchDiff(options) {
115
+ const jwt = await this.generateJWT(this.id, {
116
+ permissions: ["git:read"],
117
+ ttl: 1 * 60 * 60
118
+ // 1hr in seconds
119
+ });
120
+ const url = new URL(`${API_BASE_URL}/api/v1/repos/branches/diff`);
121
+ url.searchParams.set("branch", options.branch);
122
+ if (options.base) {
123
+ url.searchParams.set("base", options.base);
124
+ }
125
+ const response = await fetch(url.toString(), {
126
+ method: "GET",
127
+ headers: {
128
+ Authorization: `Bearer ${jwt}`
129
+ }
130
+ });
131
+ if (!response.ok) {
132
+ throw new Error(`Failed to get branch diff: ${response.statusText}`);
133
+ }
134
+ return await response.json();
135
+ }
136
+ async getCommitDiff(options) {
137
+ const jwt = await this.generateJWT(this.id, {
138
+ permissions: ["git:read"],
139
+ ttl: 1 * 60 * 60
140
+ // 1hr in seconds
141
+ });
142
+ const url = new URL(`${API_BASE_URL}/api/v1/repos/diff`);
143
+ url.searchParams.set("sha", options.sha);
144
+ const response = await fetch(url.toString(), {
145
+ method: "GET",
146
+ headers: {
147
+ Authorization: `Bearer ${jwt}`
148
+ }
149
+ });
150
+ if (!response.ok) {
151
+ throw new Error(`Failed to get commit diff: ${response.statusText}`);
152
+ }
153
+ return await response.json();
154
+ }
155
+ async getCommit(options) {
156
+ const jwt = await this.generateJWT(this.id, {
157
+ permissions: ["git:read"],
158
+ ttl: 1 * 60 * 60
159
+ // 1hr in seconds
160
+ });
161
+ const url = new URL(`${API_BASE_URL}/commit`);
162
+ url.searchParams.set("repo", this.id);
163
+ url.searchParams.set("sha", options.sha);
164
+ const response = await fetch(url.toString(), {
165
+ method: "GET",
166
+ headers: {
167
+ Authorization: `Bearer ${jwt}`
168
+ }
169
+ });
170
+ if (!response.ok) {
171
+ throw new Error(`Failed to get commit: ${response.statusText}`);
172
+ }
173
+ return await response.json();
174
+ }
175
+ };
8
176
  var GitStorage = class {
9
177
  options;
10
178
  constructor(options) {
@@ -44,15 +212,7 @@ var GitStorage = class {
44
212
  if (!response.ok) {
45
213
  throw new Error(`Failed to create repository: ${response.statusText}`);
46
214
  }
47
- return {
48
- id: repoId,
49
- getRemoteURL: async (urlOptions) => {
50
- const url = new URL(`https://${this.options.name}.${STORAGE_BASE_URL}/${repoId}.git`);
51
- url.username = `t`;
52
- url.password = await this.generateJWT(repoId, urlOptions);
53
- return url.toString();
54
- }
55
- };
215
+ return new RepoImpl(repoId, this.options, this.generateJWT.bind(this));
56
216
  }
57
217
  /**
58
218
  * Find a repository by ID
@@ -60,15 +220,7 @@ var GitStorage = class {
60
220
  * @returns The found repository
61
221
  */
62
222
  async findOne(options) {
63
- return {
64
- id: options.id,
65
- getRemoteURL: async (urlOptions) => {
66
- const url = new URL(`https://${this.options.name}.${STORAGE_BASE_URL}/${options.id}.git`);
67
- url.username = `t`;
68
- url.password = await this.generateJWT(options.id, urlOptions);
69
- return url.toString();
70
- }
71
- };
223
+ return new RepoImpl(options.id, this.options, this.generateJWT.bind(this));
72
224
  }
73
225
  /**
74
226
  * Get the current configuration
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["importPKCS8","SignJWT"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Pierre Git Storage SDK\n *\n * A TypeScript SDK for interacting with Pierre's git storage system\n */\n\nimport { importPKCS8, SignJWT } from 'jose';\n\n/**\n * Type definitions for Pierre Git Storage SDK\n */\n\nexport interface GitStorageOptions {\n\tkey: string;\n\tname: string;\n}\n\nexport interface GetRemoteURLOptions {\n\tpermissions?: ('git:write' | 'git:read' | 'repo:write')[];\n\tttl?: number;\n}\n\nexport interface Repo {\n\tid: string;\n\tgetRemoteURL(options?: GetRemoteURLOptions): Promise<string>;\n}\n\nexport interface FindOneOptions {\n\tid: string;\n}\n\nexport interface CreateRepoOptions {\n\tid?: string;\n}\n\nexport interface CreateRepoResponse {\n\trepo_id: string;\n\turl: string;\n}\n\n/**\n * Git Storage API\n */\ndeclare const __API_BASE_URL__: string;\ndeclare const __STORAGE_BASE_URL__: string;\n\nconst API_BASE_URL = __API_BASE_URL__;\nconst STORAGE_BASE_URL = __STORAGE_BASE_URL__;\n\nexport class GitStorage {\n\tprivate options: GitStorageOptions;\n\n\tconstructor(options: GitStorageOptions) {\n\t\tif (\n\t\t\t!options ||\n\t\t\toptions.name === undefined ||\n\t\t\toptions.key === undefined ||\n\t\t\toptions.name === null ||\n\t\t\toptions.key === null\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t'GitStorage requires a name and key. Please check your configuration and try again.',\n\t\t\t);\n\t\t}\n\n\t\tif (typeof options.name !== 'string' || options.name.trim() === '') {\n\t\t\tthrow new Error('GitStorage name must be a non-empty string.');\n\t\t}\n\n\t\tif (typeof options.key !== 'string' || options.key.trim() === '') {\n\t\t\tthrow new Error('GitStorage key must be a non-empty string.');\n\t\t}\n\n\t\tthis.options = {\n\t\t\tkey: options.key,\n\t\t\tname: options.name,\n\t\t};\n\t}\n\n\t/**\n\t * Create a new repository\n\t * @returns The created repository\n\t */\n\tasync createRepo(options?: CreateRepoOptions): Promise<Repo> {\n\t\tconst repoId = options?.id || crypto.randomUUID();\n\n\t\tconst jwt = await this.generateJWT(repoId, {\n\t\t\tpermissions: ['repo:write'],\n\t\t\tttl: 1 * 60 * 60, // 1hr in seconds\n\t\t});\n\n\t\tconst response = await fetch(`${API_BASE_URL}/api/v1/repos`, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\t},\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to create repository: ${response.statusText}`);\n\t\t}\n\n\t\treturn {\n\t\t\tid: repoId,\n\t\t\tgetRemoteURL: async (urlOptions?: GetRemoteURLOptions): Promise<string> => {\n\t\t\t\tconst url = new URL(`https://${this.options.name}.${STORAGE_BASE_URL}/${repoId}.git`);\n\t\t\t\turl.username = `t`;\n\t\t\t\turl.password = await this.generateJWT(repoId, urlOptions);\n\t\t\t\treturn url.toString();\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Find a repository by ID\n\t * @param options The search options\n\t * @returns The found repository\n\t */\n\tasync findOne(options: FindOneOptions): Promise<Repo | null> {\n\t\treturn {\n\t\t\tid: options.id,\n\t\t\tgetRemoteURL: async (urlOptions?: GetRemoteURLOptions): Promise<string> => {\n\t\t\t\tconst url = new URL(`https://${this.options.name}.${STORAGE_BASE_URL}/${options.id}.git`);\n\t\t\t\turl.username = `t`;\n\t\t\t\turl.password = await this.generateJWT(options.id, urlOptions);\n\t\t\t\treturn url.toString();\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Get the current configuration\n\t * @returns The client configuration\n\t */\n\tgetConfig(): GitStorageOptions {\n\t\treturn { ...this.options };\n\t}\n\n\t/**\n\t * Generate a JWT token for git storage URL authentication\n\t * @private\n\t */\n\tprivate async generateJWT(repoId: string, options?: GetRemoteURLOptions): Promise<string> {\n\t\t// Default permissions and TTL\n\t\tconst permissions = options?.permissions || ['git:write', 'git:read'];\n\t\tconst ttl = options?.ttl || 365 * 24 * 60 * 60; // 1 year in seconds\n\n\t\t// Create the JWT payload\n\t\tconst now = Math.floor(Date.now() / 1000);\n\t\tconst payload = {\n\t\t\tiss: this.options.name,\n\t\t\tsub: '@pierre/storage',\n\t\t\trepo: repoId,\n\t\t\tscopes: permissions,\n\t\t\tiat: now,\n\t\t\texp: now + ttl,\n\t\t};\n\n\t\t// Sign the JWT with the key as the secret\n\t\t// Using HS256 for symmetric signing with the key\n\t\tconst key = await importPKCS8(this.options.key, 'ES256');\n\t\t// Sign the JWT with the key as the secret\n\t\tconst jwt = await new SignJWT(payload)\n\t\t\t.setProtectedHeader({ alg: 'ES256', typ: 'JWT' })\n\t\t\t.sign(key);\n\n\t\treturn jwt;\n\t}\n}\n\n// Export a default client factory\nexport function createClient(options: GitStorageOptions): GitStorage {\n\treturn new GitStorage(options);\n}\n\n// Type alias for backward compatibility\nexport type StorageOptions = GitStorageOptions;\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["importPKCS8","SignJWT"],"mappings":";;;;;AA+DA,IAAM,YAAe,GAAA,yBAAA;AACrB,IAAM,gBAAmB,GAAA,aAAA;AAKzB,IAAM,WAAN,MAA+B;AAAA,EAC9B,WAAA,CACiB,EACC,EAAA,OAAA,EACA,WAIhB,EAAA;AANe,IAAA,IAAA,CAAA,EAAA,GAAA,EAAA;AACC,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAAA;AAIf,EAEH,MAAM,aAAa,UAAmD,EAAA;AACrE,IAAA,MAAM,GAAM,GAAA,IAAI,GAAI,CAAA,CAAA,QAAA,EAAW,IAAK,CAAA,OAAA,CAAQ,IAAI,CAAA,CAAA,EAAI,gBAAgB,CAAA,CAAA,EAAI,IAAK,CAAA,EAAE,CAAM,IAAA,CAAA,CAAA;AACrF,IAAA,GAAA,CAAI,QAAW,GAAA,CAAA,CAAA,CAAA;AACf,IAAA,GAAA,CAAI,WAAW,MAAM,IAAA,CAAK,WAAY,CAAA,IAAA,CAAK,IAAI,UAAU,CAAA;AACzD,IAAA,OAAO,IAAI,QAAS,EAAA;AAAA;AACrB,EAEA,MAAM,QAAQ,OAAmD,EAAA;AAChE,IAAA,MAAM,GAAM,GAAA,MAAM,IAAK,CAAA,WAAA,CAAY,KAAK,EAAI,EAAA;AAAA,MAC3C,WAAA,EAAa,CAAC,UAAU,CAAA;AAAA,MACxB,GAAA,EAAK,IAAI,EAAK,GAAA;AAAA;AAAA,KACd,CAAA;AAED,IAAA,MAAM,GAAM,GAAA,IAAI,GAAI,CAAA,CAAA,EAAG,YAAY,CAAoB,kBAAA,CAAA,CAAA;AACvD,IAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,MAAQ,EAAA,OAAA,CAAQ,IAAI,CAAA;AACzC,IAAA,IAAI,QAAQ,GAAK,EAAA;AAChB,MAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,KAAO,EAAA,OAAA,CAAQ,GAAG,CAAA;AAAA;AAGxC,IAAA,MAAM,QAAW,GAAA,MAAM,KAAM,CAAA,GAAA,CAAI,UAAY,EAAA;AAAA,MAC5C,MAAQ,EAAA,KAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACR,aAAA,EAAe,UAAU,GAAG,CAAA;AAAA;AAC7B,KACA,CAAA;AAED,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AACjB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAuB,oBAAA,EAAA,QAAA,CAAS,UAAU,CAAE,CAAA,CAAA;AAAA;AAG7D,IAAQ,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAC7B,EAEA,MAAM,UAAU,OAAwD,EAAA;AACvE,IAAA,MAAM,GAAM,GAAA,MAAM,IAAK,CAAA,WAAA,CAAY,KAAK,EAAI,EAAA;AAAA,MAC3C,WAAA,EAAa,CAAC,UAAU,CAAA;AAAA,MACxB,GAAA,EAAK,IAAI,EAAK,GAAA;AAAA;AAAA,KACd,CAAA;AAED,IAAA,MAAM,GAAM,GAAA,IAAI,GAAI,CAAA,CAAA,EAAG,YAAY,CAAqB,mBAAA,CAAA,CAAA;AACxD,IAAA,IAAI,SAAS,GAAK,EAAA;AACjB,MAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,KAAO,EAAA,OAAA,CAAQ,GAAG,CAAA;AAAA;AAGxC,IAAA,MAAM,QAAW,GAAA,MAAM,KAAM,CAAA,GAAA,CAAI,UAAY,EAAA;AAAA,MAC5C,MAAQ,EAAA,KAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACR,aAAA,EAAe,UAAU,GAAG,CAAA;AAAA;AAC7B,KACA,CAAA;AAED,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AACjB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAyB,sBAAA,EAAA,QAAA,CAAS,UAAU,CAAE,CAAA,CAAA;AAAA;AAG/D,IAAQ,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAC7B,EAEA,MAAM,aAAa,OAA8D,EAAA;AAChF,IAAA,MAAM,GAAM,GAAA,MAAM,IAAK,CAAA,WAAA,CAAY,KAAK,EAAI,EAAA;AAAA,MAC3C,WAAA,EAAa,CAAC,UAAU,CAAA;AAAA,MACxB,GAAA,EAAK,IAAI,EAAK,GAAA;AAAA;AAAA,KACd,CAAA;AAED,IAAA,MAAM,GAAM,GAAA,IAAI,GAAI,CAAA,CAAA,EAAG,YAAY,CAAwB,sBAAA,CAAA,CAAA;AAC3D,IAAA,IAAI,SAAS,MAAQ,EAAA;AACpB,MAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,QAAU,EAAA,OAAA,CAAQ,MAAM,CAAA;AAAA;AAE9C,IAAA,IAAI,SAAS,KAAO,EAAA;AACnB,MAAA,GAAA,CAAI,aAAa,GAAI,CAAA,OAAA,EAAS,OAAQ,CAAA,KAAA,CAAM,UAAU,CAAA;AAAA;AAGvD,IAAA,MAAM,QAAW,GAAA,MAAM,KAAM,CAAA,GAAA,CAAI,UAAY,EAAA;AAAA,MAC5C,MAAQ,EAAA,KAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACR,aAAA,EAAe,UAAU,GAAG,CAAA;AAAA;AAC7B,KACA,CAAA;AAED,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AACjB,MAAA,MAAM,IAAI,KAAA,CAAM,CAA4B,yBAAA,EAAA,QAAA,CAAS,UAAU,CAAE,CAAA,CAAA;AAAA;AAGlE,IAAQ,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAC7B,EAEA,MAAM,YAAY,OAA4D,EAAA;AAC7E,IAAA,MAAM,GAAM,GAAA,MAAM,IAAK,CAAA,WAAA,CAAY,KAAK,EAAI,EAAA;AAAA,MAC3C,WAAA,EAAa,CAAC,UAAU,CAAA;AAAA,MACxB,GAAA,EAAK,IAAI,EAAK,GAAA;AAAA;AAAA,KACd,CAAA;AAED,IAAA,MAAM,GAAM,GAAA,IAAI,GAAI,CAAA,CAAA,EAAG,YAAY,CAAuB,qBAAA,CAAA,CAAA;AAC1D,IAAA,IAAI,SAAS,MAAQ,EAAA;AACpB,MAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,QAAU,EAAA,OAAA,CAAQ,MAAM,CAAA;AAAA;AAE9C,IAAA,IAAI,SAAS,MAAQ,EAAA;AACpB,MAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,QAAU,EAAA,OAAA,CAAQ,MAAM,CAAA;AAAA;AAE9C,IAAA,IAAI,SAAS,KAAO,EAAA;AACnB,MAAA,GAAA,CAAI,aAAa,GAAI,CAAA,OAAA,EAAS,OAAQ,CAAA,KAAA,CAAM,UAAU,CAAA;AAAA;AAGvD,IAAA,MAAM,QAAW,GAAA,MAAM,KAAM,CAAA,GAAA,CAAI,UAAY,EAAA;AAAA,MAC5C,MAAQ,EAAA,KAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACR,aAAA,EAAe,UAAU,GAAG,CAAA;AAAA;AAC7B,KACA,CAAA;AAED,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AACjB,MAAA,MAAM,IAAI,KAAA,CAAM,CAA2B,wBAAA,EAAA,QAAA,CAAS,UAAU,CAAE,CAAA,CAAA;AAAA;AAGjE,IAAQ,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAC7B,EAEA,MAAM,cAAc,OAA+D,EAAA;AAClF,IAAA,MAAM,GAAM,GAAA,MAAM,IAAK,CAAA,WAAA,CAAY,KAAK,EAAI,EAAA;AAAA,MAC3C,WAAA,EAAa,CAAC,UAAU,CAAA;AAAA,MACxB,GAAA,EAAK,IAAI,EAAK,GAAA;AAAA;AAAA,KACd,CAAA;AAED,IAAA,MAAM,GAAM,GAAA,IAAI,GAAI,CAAA,CAAA,EAAG,YAAY,CAA6B,2BAAA,CAAA,CAAA;AAChE,IAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,QAAU,EAAA,OAAA,CAAQ,MAAM,CAAA;AAC7C,IAAA,IAAI,QAAQ,IAAM,EAAA;AACjB,MAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,MAAQ,EAAA,OAAA,CAAQ,IAAI,CAAA;AAAA;AAG1C,IAAA,MAAM,QAAW,GAAA,MAAM,KAAM,CAAA,GAAA,CAAI,UAAY,EAAA;AAAA,MAC5C,MAAQ,EAAA,KAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACR,aAAA,EAAe,UAAU,GAAG,CAAA;AAAA;AAC7B,KACA,CAAA;AAED,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AACjB,MAAA,MAAM,IAAI,KAAA,CAAM,CAA8B,2BAAA,EAAA,QAAA,CAAS,UAAU,CAAE,CAAA,CAAA;AAAA;AAGpE,IAAQ,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAC7B,EAEA,MAAM,cAAc,OAA+D,EAAA;AAClF,IAAA,MAAM,GAAM,GAAA,MAAM,IAAK,CAAA,WAAA,CAAY,KAAK,EAAI,EAAA;AAAA,MAC3C,WAAA,EAAa,CAAC,UAAU,CAAA;AAAA,MACxB,GAAA,EAAK,IAAI,EAAK,GAAA;AAAA;AAAA,KACd,CAAA;AAED,IAAA,MAAM,GAAM,GAAA,IAAI,GAAI,CAAA,CAAA,EAAG,YAAY,CAAoB,kBAAA,CAAA,CAAA;AACvD,IAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,KAAO,EAAA,OAAA,CAAQ,GAAG,CAAA;AAEvC,IAAA,MAAM,QAAW,GAAA,MAAM,KAAM,CAAA,GAAA,CAAI,UAAY,EAAA;AAAA,MAC5C,MAAQ,EAAA,KAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACR,aAAA,EAAe,UAAU,GAAG,CAAA;AAAA;AAC7B,KACA,CAAA;AAED,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AACjB,MAAA,MAAM,IAAI,KAAA,CAAM,CAA8B,2BAAA,EAAA,QAAA,CAAS,UAAU,CAAE,CAAA,CAAA;AAAA;AAGpE,IAAQ,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAC7B,EAEA,MAAM,UAAU,OAAuD,EAAA;AACtE,IAAA,MAAM,GAAM,GAAA,MAAM,IAAK,CAAA,WAAA,CAAY,KAAK,EAAI,EAAA;AAAA,MAC3C,WAAA,EAAa,CAAC,UAAU,CAAA;AAAA,MACxB,GAAA,EAAK,IAAI,EAAK,GAAA;AAAA;AAAA,KACd,CAAA;AAED,IAAA,MAAM,GAAM,GAAA,IAAI,GAAI,CAAA,CAAA,EAAG,YAAY,CAAS,OAAA,CAAA,CAAA;AAC5C,IAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,MAAQ,EAAA,IAAA,CAAK,EAAE,CAAA;AACpC,IAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,KAAO,EAAA,OAAA,CAAQ,GAAG,CAAA;AAEvC,IAAA,MAAM,QAAW,GAAA,MAAM,KAAM,CAAA,GAAA,CAAI,UAAY,EAAA;AAAA,MAC5C,MAAQ,EAAA,KAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACR,aAAA,EAAe,UAAU,GAAG,CAAA;AAAA;AAC7B,KACA,CAAA;AAED,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AACjB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAyB,sBAAA,EAAA,QAAA,CAAS,UAAU,CAAE,CAAA,CAAA;AAAA;AAG/D,IAAQ,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAE9B,CAAA;AAEO,IAAM,aAAN,MAAiB;AAAA,EACf,OAAA;AAAA,EAER,YAAY,OAA4B,EAAA;AACvC,IAAA,IACC,CAAC,OAAA,IACD,OAAQ,CAAA,IAAA,KAAS,MACjB,IAAA,OAAA,CAAQ,GAAQ,KAAA,MAAA,IAChB,OAAQ,CAAA,IAAA,KAAS,IACjB,IAAA,OAAA,CAAQ,QAAQ,IACf,EAAA;AACD,MAAA,MAAM,IAAI,KAAA;AAAA,QACT;AAAA,OACD;AAAA;AAGD,IAAI,IAAA,OAAO,QAAQ,IAAS,KAAA,QAAA,IAAY,QAAQ,IAAK,CAAA,IAAA,OAAW,EAAI,EAAA;AACnE,MAAM,MAAA,IAAI,MAAM,6CAA6C,CAAA;AAAA;AAG9D,IAAI,IAAA,OAAO,QAAQ,GAAQ,KAAA,QAAA,IAAY,QAAQ,GAAI,CAAA,IAAA,OAAW,EAAI,EAAA;AACjE,MAAM,MAAA,IAAI,MAAM,4CAA4C,CAAA;AAAA;AAG7D,IAAA,IAAA,CAAK,OAAU,GAAA;AAAA,MACd,KAAK,OAAQ,CAAA,GAAA;AAAA,MACb,MAAM,OAAQ,CAAA;AAAA,KACf;AAAA;AACD;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAW,OAA4C,EAAA;AAC5D,IAAA,MAAM,MAAS,GAAA,OAAA,EAAS,EAAM,IAAA,MAAA,CAAO,UAAW,EAAA;AAEhD,IAAA,MAAM,GAAM,GAAA,MAAM,IAAK,CAAA,WAAA,CAAY,MAAQ,EAAA;AAAA,MAC1C,WAAA,EAAa,CAAC,YAAY,CAAA;AAAA,MAC1B,GAAA,EAAK,IAAI,EAAK,GAAA;AAAA;AAAA,KACd,CAAA;AAED,IAAA,MAAM,QAAW,GAAA,MAAM,KAAM,CAAA,CAAA,EAAG,YAAY,CAAiB,aAAA,CAAA,EAAA;AAAA,MAC5D,MAAQ,EAAA,MAAA;AAAA,MACR,OAAS,EAAA;AAAA,QACR,aAAA,EAAe,UAAU,GAAG,CAAA;AAAA;AAC7B,KACA,CAAA;AAED,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AACjB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAgC,6BAAA,EAAA,QAAA,CAAS,UAAU,CAAE,CAAA,CAAA;AAAA;AAGtE,IAAO,OAAA,IAAI,SAAS,MAAQ,EAAA,IAAA,CAAK,SAAS,IAAK,CAAA,WAAA,CAAY,IAAK,CAAA,IAAI,CAAC,CAAA;AAAA;AACtE;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,QAAQ,OAA+C,EAAA;AAC5D,IAAO,OAAA,IAAI,QAAS,CAAA,OAAA,CAAQ,EAAI,EAAA,IAAA,CAAK,SAAS,IAAK,CAAA,WAAA,CAAY,IAAK,CAAA,IAAI,CAAC,CAAA;AAAA;AAC1E;AAAA;AAAA;AAAA;AAAA,EAMA,SAA+B,GAAA;AAC9B,IAAO,OAAA,EAAE,GAAG,IAAA,CAAK,OAAQ,EAAA;AAAA;AAC1B;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,WAAY,CAAA,MAAA,EAAgB,OAAgD,EAAA;AAEzF,IAAA,MAAM,WAAc,GAAA,OAAA,EAAS,WAAe,IAAA,CAAC,aAAa,UAAU,CAAA;AACpE,IAAA,MAAM,GAAM,GAAA,OAAA,EAAS,GAAO,IAAA,GAAA,GAAM,KAAK,EAAK,GAAA,EAAA;AAG5C,IAAA,MAAM,MAAM,IAAK,CAAA,KAAA,CAAM,IAAK,CAAA,GAAA,KAAQ,GAAI,CAAA;AACxC,IAAA,MAAM,OAAU,GAAA;AAAA,MACf,GAAA,EAAK,KAAK,OAAQ,CAAA,IAAA;AAAA,MAClB,GAAK,EAAA,iBAAA;AAAA,MACL,IAAM,EAAA,MAAA;AAAA,MACN,MAAQ,EAAA,WAAA;AAAA,MACR,GAAK,EAAA,GAAA;AAAA,MACL,KAAK,GAAM,GAAA;AAAA,KACZ;AAIA,IAAA,MAAM,MAAM,MAAMA,gBAAA,CAAY,IAAK,CAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AAEvD,IAAA,MAAM,GAAM,GAAA,MAAM,IAAIC,YAAA,CAAQ,OAAO,CACnC,CAAA,kBAAA,CAAmB,EAAE,GAAA,EAAK,SAAS,GAAK,EAAA,KAAA,EAAO,CAAA,CAC/C,KAAK,GAAG,CAAA;AAEV,IAAO,OAAA,GAAA;AAAA;AAET;AAGO,SAAS,aAAa,OAAwC,EAAA;AACpE,EAAO,OAAA,IAAI,WAAW,OAAO,CAAA;AAC9B","file":"index.cjs","sourcesContent":["/**\n * Pierre Git Storage SDK\n *\n * A TypeScript SDK for interacting with Pierre's git storage system\n */\n\nimport { importPKCS8, SignJWT } from 'jose';\nimport type {\n\tGetBranchDiffOptions,\n\tGetBranchDiffResponse,\n\tGetCommitDiffOptions,\n\tGetCommitDiffResponse,\n\tGetCommitOptions,\n\tGetCommitResponse,\n\tGetFileOptions,\n\tGetFileResponse,\n\tListBranchesOptions,\n\tListBranchesResponse,\n\tListCommitsOptions,\n\tListCommitsResponse,\n\tListFilesOptions,\n\tListFilesResponse,\n\tRepo,\n} from './types';\n\n/**\n * Type definitions for Pierre Git Storage SDK\n */\n\nexport interface GitStorageOptions {\n\tkey: string;\n\tname: string;\n}\n\nexport interface GetRemoteURLOptions {\n\tpermissions?: ('git:write' | 'git:read' | 'repo:write')[];\n\tttl?: number;\n}\n\n// Repo interface is now imported from types.ts\n\nexport interface FindOneOptions {\n\tid: string;\n}\n\nexport interface CreateRepoOptions {\n\tid?: string;\n}\n\nexport interface CreateRepoResponse {\n\trepo_id: string;\n\turl: string;\n}\n\n// Import additional types from types.ts\nexport * from './types';\n\n/**\n * Git Storage API\n */\ndeclare const __API_BASE_URL__: string;\ndeclare const __STORAGE_BASE_URL__: string;\n\nconst API_BASE_URL = __API_BASE_URL__;\nconst STORAGE_BASE_URL = __STORAGE_BASE_URL__;\n\n/**\n * Implementation of the Repo interface\n */\nclass RepoImpl implements Repo {\n\tconstructor(\n\t\tpublic readonly id: string,\n\t\tprivate readonly options: GitStorageOptions,\n\t\tprivate readonly generateJWT: (\n\t\t\trepoId: string,\n\t\t\toptions?: GetRemoteURLOptions,\n\t\t) => Promise<string>,\n\t) {}\n\n\tasync getRemoteURL(urlOptions?: GetRemoteURLOptions): Promise<string> {\n\t\tconst url = new URL(`https://${this.options.name}.${STORAGE_BASE_URL}/${this.id}.git`);\n\t\turl.username = `t`;\n\t\turl.password = await this.generateJWT(this.id, urlOptions);\n\t\treturn url.toString();\n\t}\n\n\tasync getFile(options: GetFileOptions): Promise<GetFileResponse> {\n\t\tconst jwt = await this.generateJWT(this.id, {\n\t\t\tpermissions: ['git:read'],\n\t\t\tttl: 1 * 60 * 60, // 1hr in seconds\n\t\t});\n\n\t\tconst url = new URL(`${API_BASE_URL}/api/v1/repos/file`);\n\t\turl.searchParams.set('path', options.path);\n\t\tif (options.ref) {\n\t\t\turl.searchParams.set('ref', options.ref);\n\t\t}\n\n\t\tconst response = await fetch(url.toString(), {\n\t\t\tmethod: 'GET',\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\t},\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to get file: ${response.statusText}`);\n\t\t}\n\n\t\treturn (await response.json()) as GetFileResponse;\n\t}\n\n\tasync listFiles(options?: ListFilesOptions): Promise<ListFilesResponse> {\n\t\tconst jwt = await this.generateJWT(this.id, {\n\t\t\tpermissions: ['git:read'],\n\t\t\tttl: 1 * 60 * 60, // 1hr in seconds\n\t\t});\n\n\t\tconst url = new URL(`${API_BASE_URL}/api/v1/repos/files`);\n\t\tif (options?.ref) {\n\t\t\turl.searchParams.set('ref', options.ref);\n\t\t}\n\n\t\tconst response = await fetch(url.toString(), {\n\t\t\tmethod: 'GET',\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\t},\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to list files: ${response.statusText}`);\n\t\t}\n\n\t\treturn (await response.json()) as ListFilesResponse;\n\t}\n\n\tasync listBranches(options?: ListBranchesOptions): Promise<ListBranchesResponse> {\n\t\tconst jwt = await this.generateJWT(this.id, {\n\t\t\tpermissions: ['git:read'],\n\t\t\tttl: 1 * 60 * 60, // 1hr in seconds\n\t\t});\n\n\t\tconst url = new URL(`${API_BASE_URL}/api/v1/repos/branches`);\n\t\tif (options?.cursor) {\n\t\t\turl.searchParams.set('cursor', options.cursor);\n\t\t}\n\t\tif (options?.limit) {\n\t\t\turl.searchParams.set('limit', options.limit.toString());\n\t\t}\n\n\t\tconst response = await fetch(url.toString(), {\n\t\t\tmethod: 'GET',\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\t},\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to list branches: ${response.statusText}`);\n\t\t}\n\n\t\treturn (await response.json()) as ListBranchesResponse;\n\t}\n\n\tasync listCommits(options?: ListCommitsOptions): Promise<ListCommitsResponse> {\n\t\tconst jwt = await this.generateJWT(this.id, {\n\t\t\tpermissions: ['git:read'],\n\t\t\tttl: 1 * 60 * 60, // 1hr in seconds\n\t\t});\n\n\t\tconst url = new URL(`${API_BASE_URL}/api/v1/repos/commits`);\n\t\tif (options?.branch) {\n\t\t\turl.searchParams.set('branch', options.branch);\n\t\t}\n\t\tif (options?.cursor) {\n\t\t\turl.searchParams.set('cursor', options.cursor);\n\t\t}\n\t\tif (options?.limit) {\n\t\t\turl.searchParams.set('limit', options.limit.toString());\n\t\t}\n\n\t\tconst response = await fetch(url.toString(), {\n\t\t\tmethod: 'GET',\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\t},\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to list commits: ${response.statusText}`);\n\t\t}\n\n\t\treturn (await response.json()) as ListCommitsResponse;\n\t}\n\n\tasync getBranchDiff(options: GetBranchDiffOptions): Promise<GetBranchDiffResponse> {\n\t\tconst jwt = await this.generateJWT(this.id, {\n\t\t\tpermissions: ['git:read'],\n\t\t\tttl: 1 * 60 * 60, // 1hr in seconds\n\t\t});\n\n\t\tconst url = new URL(`${API_BASE_URL}/api/v1/repos/branches/diff`);\n\t\turl.searchParams.set('branch', options.branch);\n\t\tif (options.base) {\n\t\t\turl.searchParams.set('base', options.base);\n\t\t}\n\n\t\tconst response = await fetch(url.toString(), {\n\t\t\tmethod: 'GET',\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\t},\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to get branch diff: ${response.statusText}`);\n\t\t}\n\n\t\treturn (await response.json()) as GetBranchDiffResponse;\n\t}\n\n\tasync getCommitDiff(options: GetCommitDiffOptions): Promise<GetCommitDiffResponse> {\n\t\tconst jwt = await this.generateJWT(this.id, {\n\t\t\tpermissions: ['git:read'],\n\t\t\tttl: 1 * 60 * 60, // 1hr in seconds\n\t\t});\n\n\t\tconst url = new URL(`${API_BASE_URL}/api/v1/repos/diff`);\n\t\turl.searchParams.set('sha', options.sha);\n\n\t\tconst response = await fetch(url.toString(), {\n\t\t\tmethod: 'GET',\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\t},\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to get commit diff: ${response.statusText}`);\n\t\t}\n\n\t\treturn (await response.json()) as GetCommitDiffResponse;\n\t}\n\n\tasync getCommit(options: GetCommitOptions): Promise<GetCommitResponse> {\n\t\tconst jwt = await this.generateJWT(this.id, {\n\t\t\tpermissions: ['git:read'],\n\t\t\tttl: 1 * 60 * 60, // 1hr in seconds\n\t\t});\n\n\t\tconst url = new URL(`${API_BASE_URL}/commit`);\n\t\turl.searchParams.set('repo', this.id);\n\t\turl.searchParams.set('sha', options.sha);\n\n\t\tconst response = await fetch(url.toString(), {\n\t\t\tmethod: 'GET',\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\t},\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to get commit: ${response.statusText}`);\n\t\t}\n\n\t\treturn (await response.json()) as GetCommitResponse;\n\t}\n}\n\nexport class GitStorage {\n\tprivate options: GitStorageOptions;\n\n\tconstructor(options: GitStorageOptions) {\n\t\tif (\n\t\t\t!options ||\n\t\t\toptions.name === undefined ||\n\t\t\toptions.key === undefined ||\n\t\t\toptions.name === null ||\n\t\t\toptions.key === null\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t'GitStorage requires a name and key. Please check your configuration and try again.',\n\t\t\t);\n\t\t}\n\n\t\tif (typeof options.name !== 'string' || options.name.trim() === '') {\n\t\t\tthrow new Error('GitStorage name must be a non-empty string.');\n\t\t}\n\n\t\tif (typeof options.key !== 'string' || options.key.trim() === '') {\n\t\t\tthrow new Error('GitStorage key must be a non-empty string.');\n\t\t}\n\n\t\tthis.options = {\n\t\t\tkey: options.key,\n\t\t\tname: options.name,\n\t\t};\n\t}\n\n\t/**\n\t * Create a new repository\n\t * @returns The created repository\n\t */\n\tasync createRepo(options?: CreateRepoOptions): Promise<Repo> {\n\t\tconst repoId = options?.id || crypto.randomUUID();\n\n\t\tconst jwt = await this.generateJWT(repoId, {\n\t\t\tpermissions: ['repo:write'],\n\t\t\tttl: 1 * 60 * 60, // 1hr in seconds\n\t\t});\n\n\t\tconst response = await fetch(`${API_BASE_URL}/api/v1/repos`, {\n\t\t\tmethod: 'POST',\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${jwt}`,\n\t\t\t},\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to create repository: ${response.statusText}`);\n\t\t}\n\n\t\treturn new RepoImpl(repoId, this.options, this.generateJWT.bind(this));\n\t}\n\n\t/**\n\t * Find a repository by ID\n\t * @param options The search options\n\t * @returns The found repository\n\t */\n\tasync findOne(options: FindOneOptions): Promise<Repo | null> {\n\t\treturn new RepoImpl(options.id, this.options, this.generateJWT.bind(this));\n\t}\n\n\t/**\n\t * Get the current configuration\n\t * @returns The client configuration\n\t */\n\tgetConfig(): GitStorageOptions {\n\t\treturn { ...this.options };\n\t}\n\n\t/**\n\t * Generate a JWT token for git storage URL authentication\n\t * @private\n\t */\n\tprivate async generateJWT(repoId: string, options?: GetRemoteURLOptions): Promise<string> {\n\t\t// Default permissions and TTL\n\t\tconst permissions = options?.permissions || ['git:write', 'git:read'];\n\t\tconst ttl = options?.ttl || 365 * 24 * 60 * 60; // 1 year in seconds\n\n\t\t// Create the JWT payload\n\t\tconst now = Math.floor(Date.now() / 1000);\n\t\tconst payload = {\n\t\t\tiss: this.options.name,\n\t\t\tsub: '@pierre/storage',\n\t\t\trepo: repoId,\n\t\t\tscopes: permissions,\n\t\t\tiat: now,\n\t\t\texp: now + ttl,\n\t\t};\n\n\t\t// Sign the JWT with the key as the secret\n\t\t// Using HS256 for symmetric signing with the key\n\t\tconst key = await importPKCS8(this.options.key, 'ES256');\n\t\t// Sign the JWT with the key as the secret\n\t\tconst jwt = await new SignJWT(payload)\n\t\t\t.setProtectedHeader({ alg: 'ES256', typ: 'JWT' })\n\t\t\t.sign(key);\n\n\t\treturn jwt;\n\t}\n}\n\n// Export a default client factory\nexport function createClient(options: GitStorageOptions): GitStorage {\n\treturn new GitStorage(options);\n}\n\n// Type alias for backward compatibility\nexport type StorageOptions = GitStorageOptions;\n"]}
package/dist/index.d.cts CHANGED
@@ -1,8 +1,139 @@
1
+ interface GetRemoteURLOptions$1 {
2
+ permissions?: ('git:write' | 'git:read' | 'repo:write')[];
3
+ ttl?: number;
4
+ }
5
+ interface Repo {
6
+ id: string;
7
+ getRemoteURL(options?: GetRemoteURLOptions$1): Promise<string>;
8
+ getFile(options: GetFileOptions): Promise<GetFileResponse>;
9
+ listFiles(options?: ListFilesOptions): Promise<ListFilesResponse>;
10
+ listBranches(options?: ListBranchesOptions): Promise<ListBranchesResponse>;
11
+ listCommits(options?: ListCommitsOptions): Promise<ListCommitsResponse>;
12
+ getBranchDiff(options: GetBranchDiffOptions): Promise<GetBranchDiffResponse>;
13
+ getCommitDiff(options: GetCommitDiffOptions): Promise<GetCommitDiffResponse>;
14
+ getCommit(options: GetCommitOptions): Promise<GetCommitResponse>;
15
+ }
16
+ interface GetFileOptions {
17
+ path: string;
18
+ ref?: string;
19
+ }
20
+ interface GetFileResponse {
21
+ path: string;
22
+ ref: string;
23
+ content: string;
24
+ size: number;
25
+ is_binary: boolean;
26
+ }
27
+ interface ListFilesOptions {
28
+ ref?: string;
29
+ }
30
+ interface ListFilesResponse {
31
+ paths: string[];
32
+ ref: string;
33
+ }
34
+ interface ListBranchesOptions {
35
+ cursor?: string;
36
+ limit?: number;
37
+ }
38
+ interface BranchInfo {
39
+ cursor: string;
40
+ name: string;
41
+ head_sha: string;
42
+ created_at: string;
43
+ }
44
+ interface ListBranchesResponse {
45
+ branches: BranchInfo[];
46
+ next_cursor?: string;
47
+ has_more: boolean;
48
+ }
49
+ interface ListCommitsOptions {
50
+ branch?: string;
51
+ cursor?: string;
52
+ limit?: number;
53
+ }
54
+ interface CommitInfo {
55
+ sha: string;
56
+ message: string;
57
+ author_name: string;
58
+ author_email: string;
59
+ committer_name: string;
60
+ committer_email: string;
61
+ date: string;
62
+ }
63
+ interface ListCommitsResponse {
64
+ commits: CommitInfo[];
65
+ next_cursor?: string;
66
+ has_more: boolean;
67
+ }
68
+ interface GetBranchDiffOptions {
69
+ branch: string;
70
+ base?: string;
71
+ }
72
+ interface GetBranchDiffResponse {
73
+ branch: string;
74
+ base: string;
75
+ stats: DiffStats;
76
+ files: FileDiff[];
77
+ filtered_files: FilteredFile[];
78
+ }
79
+ interface GetCommitDiffOptions {
80
+ sha: string;
81
+ }
82
+ interface GetCommitDiffResponse {
83
+ sha: string;
84
+ stats: DiffStats;
85
+ files: FileDiff[];
86
+ filtered_files: FilteredFile[];
87
+ }
88
+ interface DiffStats {
89
+ files: number;
90
+ additions: number;
91
+ deletions: number;
92
+ changes: number;
93
+ }
94
+ interface FileDiff {
95
+ path: string;
96
+ state: string;
97
+ old_path?: string;
98
+ bytes: number;
99
+ is_eof: boolean;
100
+ diff: string;
101
+ }
102
+ interface FilteredFile {
103
+ path: string;
104
+ state: string;
105
+ old_path?: string;
106
+ bytes: number;
107
+ is_eof: boolean;
108
+ }
109
+ interface GetCommitOptions {
110
+ sha: string;
111
+ }
112
+ interface GetCommitResponse {
113
+ sha: string;
114
+ message: string;
115
+ author: {
116
+ name: string;
117
+ email: string;
118
+ };
119
+ committer: {
120
+ name: string;
121
+ email: string;
122
+ };
123
+ date: string;
124
+ stats: {
125
+ additions: number;
126
+ deletions: number;
127
+ total: number;
128
+ };
129
+ }
130
+
1
131
  /**
2
132
  * Pierre Git Storage SDK
3
133
  *
4
134
  * A TypeScript SDK for interacting with Pierre's git storage system
5
135
  */
136
+
6
137
  /**
7
138
  * Type definitions for Pierre Git Storage SDK
8
139
  */
@@ -14,10 +145,6 @@ interface GetRemoteURLOptions {
14
145
  permissions?: ('git:write' | 'git:read' | 'repo:write')[];
15
146
  ttl?: number;
16
147
  }
17
- interface Repo {
18
- id: string;
19
- getRemoteURL(options?: GetRemoteURLOptions): Promise<string>;
20
- }
21
148
  interface FindOneOptions {
22
149
  id: string;
23
150
  }
@@ -28,6 +155,7 @@ interface CreateRepoResponse {
28
155
  repo_id: string;
29
156
  url: string;
30
157
  }
158
+
31
159
  declare class GitStorage {
32
160
  private options;
33
161
  constructor(options: GitStorageOptions);
@@ -56,4 +184,4 @@ declare class GitStorage {
56
184
  declare function createClient(options: GitStorageOptions): GitStorage;
57
185
  type StorageOptions = GitStorageOptions;
58
186
 
59
- export { type CreateRepoOptions, type CreateRepoResponse, type FindOneOptions, type GetRemoteURLOptions, GitStorage, type GitStorageOptions, type Repo, type StorageOptions, createClient };
187
+ export { type BranchInfo, type CommitInfo, type CreateRepoOptions, type CreateRepoResponse, type DiffStats, type FileDiff, type FilteredFile, type FindOneOptions, type GetBranchDiffOptions, type GetBranchDiffResponse, type GetCommitDiffOptions, type GetCommitDiffResponse, type GetCommitOptions, type GetCommitResponse, type GetFileOptions, type GetFileResponse, type GetRemoteURLOptions, GitStorage, type GitStorageOptions, type ListBranchesOptions, type ListBranchesResponse, type ListCommitsOptions, type ListCommitsResponse, type ListFilesOptions, type ListFilesResponse, type Repo, type StorageOptions, createClient };