@pierre/storage 1.3.2 → 1.4.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pierre/storage",
3
- "version": "1.3.2",
3
+ "version": "1.4.1",
4
4
  "description": "Pierre Git Storage SDK",
5
5
  "repository": {
6
6
  "type": "git",
package/src/index.ts CHANGED
@@ -19,6 +19,8 @@ import {
19
19
  branchDiffResponseSchema,
20
20
  commitDiffResponseSchema,
21
21
  createBranchResponseSchema,
22
+ createTagResponseSchema,
23
+ deleteTagResponseSchema,
22
24
  errorEnvelopeSchema,
23
25
  grepResponseSchema,
24
26
  listBranchesResponseSchema,
@@ -26,6 +28,7 @@ import {
26
28
  listFilesResponseSchema,
27
29
  listFilesWithMetadataResponseSchema,
28
30
  listReposResponseSchema,
31
+ listTagsResponseSchema,
29
32
  noteReadResponseSchema,
30
33
  noteWriteResponseSchema,
31
34
  restoreCommitAckSchema,
@@ -44,9 +47,15 @@ import type {
44
47
  CreateBranchResult,
45
48
  CreateCommitFromDiffOptions,
46
49
  CreateCommitOptions,
50
+ CreateTagOptions,
51
+ CreateTagResponse,
52
+ CreateTagResult,
47
53
  CreateGitCredentialOptions,
48
54
  CreateNoteOptions,
49
55
  CreateRepoOptions,
56
+ DeleteTagOptions,
57
+ DeleteTagResponse,
58
+ DeleteTagResult,
50
59
  DeleteGitCredentialOptions,
51
60
  DeleteNoteOptions,
52
61
  DeleteRepoOptions,
@@ -88,6 +97,9 @@ import type {
88
97
  ListReposOptions,
89
98
  ListReposResponse,
90
99
  ListReposResult,
100
+ ListTagsOptions,
101
+ ListTagsResponse,
102
+ ListTagsResult,
91
103
  NoteWriteResult,
92
104
  PullUpstreamOptions,
93
105
  RawBranchInfo,
@@ -96,11 +108,13 @@ import type {
96
108
  RawFileWithMetadata,
97
109
  RawFileDiff,
98
110
  RawFilteredFile,
111
+ RawTagInfo,
99
112
  RefUpdate,
100
113
  RepoOptions,
101
114
  Repo,
102
115
  RestoreCommitOptions,
103
116
  RestoreCommitResult,
117
+ TagInfo,
104
118
  UpdateGitCredentialOptions,
105
119
  ValidAPIVersion,
106
120
  } from './types';
@@ -444,6 +458,37 @@ function transformCreateBranchResult(
444
458
  };
445
459
  }
446
460
 
461
+ function transformTagInfo(raw: RawTagInfo): TagInfo {
462
+ return {
463
+ cursor: raw.cursor,
464
+ name: raw.name,
465
+ sha: raw.sha,
466
+ };
467
+ }
468
+
469
+ function transformListTagsResult(raw: ListTagsResponse): ListTagsResult {
470
+ return {
471
+ tags: raw.tags.map(transformTagInfo),
472
+ nextCursor: raw.next_cursor ?? undefined,
473
+ hasMore: raw.has_more,
474
+ };
475
+ }
476
+
477
+ function transformCreateTagResult(raw: CreateTagResponse): CreateTagResult {
478
+ return {
479
+ name: raw.name,
480
+ sha: raw.sha,
481
+ message: raw.message,
482
+ };
483
+ }
484
+
485
+ function transformDeleteTagResult(raw: DeleteTagResponse): DeleteTagResult {
486
+ return {
487
+ name: raw.name,
488
+ message: raw.message,
489
+ };
490
+ }
491
+
447
492
  function transformListReposResult(raw: ListReposResponse): ListReposResult {
448
493
  return {
449
494
  repos: raw.repos.map((repo) => ({
@@ -799,6 +844,36 @@ class RepoImpl implements Repo {
799
844
  });
800
845
  }
801
846
 
847
+ async listTags(options?: ListTagsOptions): Promise<ListTagsResult> {
848
+ const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
849
+ const jwt = await this.generateJWT(this.id, {
850
+ permissions: ['git:read'],
851
+ ttl,
852
+ });
853
+
854
+ const cursor = options?.cursor;
855
+ const limit = options?.limit;
856
+
857
+ let params: Record<string, string> | undefined;
858
+
859
+ if (typeof cursor === 'string' || typeof limit === 'number') {
860
+ params = {};
861
+ if (typeof cursor === 'string') {
862
+ params.cursor = cursor;
863
+ }
864
+ if (typeof limit === 'number') {
865
+ params.limit = limit.toString();
866
+ }
867
+ }
868
+
869
+ const response = await this.api.get({ path: 'repos/tags', params }, jwt);
870
+ const raw = listTagsResponseSchema.parse(await response.json());
871
+ return transformListTagsResult({
872
+ ...raw,
873
+ next_cursor: raw.next_cursor ?? undefined,
874
+ });
875
+ }
876
+
802
877
  async listCommits(options?: ListCommitsOptions): Promise<ListCommitsResult> {
803
878
  const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
804
879
  const jwt = await this.generateJWT(this.id, {
@@ -1215,6 +1290,57 @@ class RepoImpl implements Repo {
1215
1290
  return transformCreateBranchResult(raw);
1216
1291
  }
1217
1292
 
1293
+ async createTag(options: CreateTagOptions): Promise<CreateTagResult> {
1294
+ const name = options?.name?.trim();
1295
+ if (!name) {
1296
+ throw new Error('createTag name is required');
1297
+ }
1298
+ if (name.startsWith('refs/')) {
1299
+ throw new Error('createTag name must not start with refs/');
1300
+ }
1301
+
1302
+ const target = options?.target?.trim();
1303
+ if (!target) {
1304
+ throw new Error('createTag target is required');
1305
+ }
1306
+
1307
+ const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
1308
+ const jwt = await this.generateJWT(this.id, {
1309
+ permissions: ['git:write'],
1310
+ ttl,
1311
+ });
1312
+
1313
+ const response = await this.api.post(
1314
+ { path: 'repos/tags', body: { name, target } },
1315
+ jwt
1316
+ );
1317
+ const raw = createTagResponseSchema.parse(await response.json());
1318
+ return transformCreateTagResult(raw);
1319
+ }
1320
+
1321
+ async deleteTag(options: DeleteTagOptions): Promise<DeleteTagResult> {
1322
+ const name = options?.name?.trim();
1323
+ if (!name) {
1324
+ throw new Error('deleteTag name is required');
1325
+ }
1326
+ if (name.startsWith('refs/')) {
1327
+ throw new Error('deleteTag name must not start with refs/');
1328
+ }
1329
+
1330
+ const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
1331
+ const jwt = await this.generateJWT(this.id, {
1332
+ permissions: ['git:read', 'git:write'],
1333
+ ttl,
1334
+ });
1335
+
1336
+ const response = await this.api.delete(
1337
+ { path: 'repos/tags', body: { name } },
1338
+ jwt
1339
+ );
1340
+ const raw = deleteTagResponseSchema.parse(await response.json());
1341
+ return transformDeleteTagResult(raw);
1342
+ }
1343
+
1218
1344
  async restoreCommit(
1219
1345
  options: RestoreCommitOptions
1220
1346
  ): Promise<RestoreCommitResult> {
@@ -1723,6 +1849,7 @@ export class GitStorage {
1723
1849
  scopes: permissions,
1724
1850
  iat: now,
1725
1851
  exp: now + ttl,
1852
+ ...(options?.ops && options.ops.length > 0 ? { ops: options.ops } : {}),
1726
1853
  };
1727
1854
 
1728
1855
  // Sign the JWT with the key as the secret
package/src/schemas.ts CHANGED
@@ -141,6 +141,29 @@ export const createBranchResponseSchema = z.object({
141
141
  commit_sha: z.string().nullable().optional(),
142
142
  });
143
143
 
144
+ export const tagInfoSchema = z.object({
145
+ cursor: z.string(),
146
+ name: z.string(),
147
+ sha: z.string(),
148
+ });
149
+
150
+ export const listTagsResponseSchema = z.object({
151
+ tags: z.array(tagInfoSchema),
152
+ next_cursor: z.string().nullable().optional(),
153
+ has_more: z.boolean(),
154
+ });
155
+
156
+ export const createTagResponseSchema = z.object({
157
+ name: z.string(),
158
+ sha: z.string(),
159
+ message: z.string(),
160
+ });
161
+
162
+ export const deleteTagResponseSchema = z.object({
163
+ name: z.string(),
164
+ message: z.string(),
165
+ });
166
+
144
167
  export const refUpdateResultSchema = z.object({
145
168
  branch: z.string(),
146
169
  old_sha: z.string(),
@@ -244,6 +267,10 @@ export type GetCommitDiffResponseRaw = z.infer<typeof commitDiffResponseSchema>;
244
267
  export type CreateBranchResponseRaw = z.infer<
245
268
  typeof createBranchResponseSchema
246
269
  >;
270
+ export type RawTagInfo = z.infer<typeof tagInfoSchema>;
271
+ export type ListTagsResponseRaw = z.infer<typeof listTagsResponseSchema>;
272
+ export type CreateTagResponseRaw = z.infer<typeof createTagResponseSchema>;
273
+ export type DeleteTagResponseRaw = z.infer<typeof deleteTagResponseSchema>;
247
274
  export type CommitPackAckRaw = z.infer<typeof commitPackAckSchema>;
248
275
  export type RestoreCommitAckRaw = z.infer<typeof restoreCommitAckSchema>;
249
276
  export type GrepResponseRaw = z.infer<typeof grepResponseSchema>;
package/src/types.ts CHANGED
@@ -3,6 +3,8 @@
3
3
  */
4
4
  import type {
5
5
  CreateBranchResponseRaw,
6
+ CreateTagResponseRaw,
7
+ DeleteTagResponseRaw,
6
8
  GetBranchDiffResponseRaw,
7
9
  GetCommitDiffResponseRaw,
8
10
  ListBranchesResponseRaw,
@@ -10,6 +12,7 @@ import type {
10
12
  ListFilesResponseRaw,
11
13
  ListFilesWithMetadataResponseRaw,
12
14
  ListReposResponseRaw,
15
+ ListTagsResponseRaw,
13
16
  NoteReadResponseRaw,
14
17
  NoteWriteResponseRaw,
15
18
  RawBranchInfo as SchemaRawBranchInfo,
@@ -20,6 +23,7 @@ import type {
20
23
  RawFilteredFile as SchemaRawFilteredFile,
21
24
  RawRepoBaseInfo as SchemaRawRepoBaseInfo,
22
25
  RawRepoInfo as SchemaRawRepoInfo,
26
+ RawTagInfo as SchemaRawTagInfo,
23
27
  } from './schemas';
24
28
 
25
29
  export interface OverrideableGitStorageOptions {
@@ -37,9 +41,18 @@ export interface GitStorageOptions extends OverrideableGitStorageOptions {
37
41
 
38
42
  export type ValidAPIVersion = 1;
39
43
 
44
+ /** A policy operation included in the JWT. */
45
+ export type Op = string;
46
+
47
+ export const OP_NO_FORCE_PUSH: Op = 'no-force-push';
48
+
49
+ /** A list of policy operations. */
50
+ export type Ops = Op[];
51
+
40
52
  export interface GetRemoteURLOptions {
41
53
  permissions?: ('git:write' | 'git:read' | 'repo:write' | 'org:read')[];
42
54
  ttl?: number;
55
+ ops?: Ops;
43
56
  }
44
57
 
45
58
  export interface Repo {
@@ -57,7 +70,10 @@ export interface Repo {
57
70
  options?: ListFilesWithMetadataOptions
58
71
  ): Promise<ListFilesWithMetadataResult>;
59
72
  listBranches(options?: ListBranchesOptions): Promise<ListBranchesResult>;
73
+ listTags(options?: ListTagsOptions): Promise<ListTagsResult>;
60
74
  listCommits(options?: ListCommitsOptions): Promise<ListCommitsResult>;
75
+ createTag(options: CreateTagOptions): Promise<CreateTagResult>;
76
+ deleteTag(options: DeleteTagOptions): Promise<DeleteTagResult>;
61
77
  getNote(options: GetNoteOptions): Promise<GetNoteResult>;
62
78
  createNote(options: CreateNoteOptions): Promise<NoteWriteResult>;
63
79
  appendNote(options: AppendNoteOptions): Promise<NoteWriteResult>;
@@ -321,6 +337,51 @@ export interface CreateBranchResult {
321
337
  commitSha?: string;
322
338
  }
323
339
 
340
+ export interface ListTagsOptions extends GitStorageInvocationOptions {
341
+ cursor?: string;
342
+ limit?: number;
343
+ }
344
+
345
+ export type RawTagInfo = SchemaRawTagInfo;
346
+
347
+ export interface TagInfo {
348
+ cursor: string;
349
+ name: string;
350
+ sha: string;
351
+ }
352
+
353
+ export type ListTagsResponse = ListTagsResponseRaw;
354
+
355
+ export interface ListTagsResult {
356
+ tags: TagInfo[];
357
+ nextCursor?: string;
358
+ hasMore: boolean;
359
+ }
360
+
361
+ export interface CreateTagOptions extends GitStorageInvocationOptions {
362
+ name: string;
363
+ target: string;
364
+ }
365
+
366
+ export type CreateTagResponse = CreateTagResponseRaw;
367
+
368
+ export interface CreateTagResult {
369
+ name: string;
370
+ sha: string;
371
+ message: string;
372
+ }
373
+
374
+ export interface DeleteTagOptions extends GitStorageInvocationOptions {
375
+ name: string;
376
+ }
377
+
378
+ export type DeleteTagResponse = DeleteTagResponseRaw;
379
+
380
+ export interface DeleteTagResult {
381
+ name: string;
382
+ message: string;
383
+ }
384
+
324
385
  // List Commits API types
325
386
  export interface ListCommitsOptions extends GitStorageInvocationOptions {
326
387
  branch?: string;