@pierre/storage 0.4.0 → 0.4.2

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,39 +1,40 @@
1
1
  {
2
- "name": "@pierre/storage",
3
- "version": "0.4.0",
4
- "description": "Pierre Git Storage SDK",
5
- "license": "MIT",
6
- "type": "module",
7
- "main": "./dist/index.cjs",
8
- "module": "./dist/index.js",
9
- "types": "./dist/index.d.ts",
10
- "exports": {
11
- ".": {
12
- "types": "./dist/index.d.ts",
13
- "import": "./dist/index.js",
14
- "require": "./dist/index.cjs",
15
- "default": "./dist/index.js"
16
- }
17
- },
18
- "files": [
19
- "dist",
20
- "src"
21
- ],
22
- "dependencies": {
23
- "jose": "^5.10.0",
24
- "snakecase-keys": "^9.0.2",
25
- "zod": "^3.23.8"
26
- },
27
- "devDependencies": {
28
- "tsup": "8.5.0",
29
- "typescript": "5.8.3",
30
- "vitest": "3.2.4"
31
- },
32
- "publishConfig": {
33
- "access": "public"
34
- },
35
- "scripts": {
36
- "build": "tsup",
37
- "dev": "tsup --watch"
38
- }
39
- }
2
+ "name": "@pierre/storage",
3
+ "version": "0.4.2",
4
+ "description": "Pierre Git Storage SDK",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "src"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsup",
24
+ "dev": "tsup --watch",
25
+ "prepublishOnly": "pnpm build"
26
+ },
27
+ "dependencies": {
28
+ "jose": "^5.10.0",
29
+ "snakecase-keys": "^9.0.2",
30
+ "zod": "^3.23.8"
31
+ },
32
+ "devDependencies": {
33
+ "tsup": "8.5.0",
34
+ "typescript": "5.8.3",
35
+ "vitest": "3.2.4"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ }
40
+ }
package/src/index.ts CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  branchDiffResponseSchema,
16
16
  commitDiffResponseSchema,
17
17
  createBranchResponseSchema,
18
+ grepResponseSchema,
18
19
  listBranchesResponseSchema,
19
20
  listCommitsResponseSchema,
20
21
  listFilesResponseSchema,
@@ -47,6 +48,10 @@ import type {
47
48
  GetFileOptions,
48
49
  GetRemoteURLOptions,
49
50
  GitStorageOptions,
51
+ GrepFileMatch,
52
+ GrepLine,
53
+ GrepOptions,
54
+ GrepResult,
50
55
  ListBranchesOptions,
51
56
  ListBranchesResponse,
52
57
  ListBranchesResult,
@@ -332,6 +337,24 @@ function transformCreateBranchResult(raw: CreateBranchResponse): CreateBranchRes
332
337
  };
333
338
  }
334
339
 
340
+ function transformGrepLine(raw: { line_number: number; text: string; type: string }): GrepLine {
341
+ return {
342
+ lineNumber: raw.line_number,
343
+ text: raw.text,
344
+ type: raw.type,
345
+ };
346
+ }
347
+
348
+ function transformGrepFileMatch(raw: {
349
+ path: string;
350
+ lines: { line_number: number; text: string; type: string }[];
351
+ }): GrepFileMatch {
352
+ return {
353
+ path: raw.path,
354
+ lines: raw.lines.map(transformGrepLine),
355
+ };
356
+ }
357
+
335
358
  /**
336
359
  * Implementation of the Repo interface
337
360
  */
@@ -524,6 +547,91 @@ class RepoImpl implements Repo {
524
547
  return transformCommitDiffResult(raw);
525
548
  }
526
549
 
550
+ async grep(options: GrepOptions): Promise<GrepResult> {
551
+ const pattern = options?.query?.pattern?.trim();
552
+ if (!pattern) {
553
+ throw new Error('grep query.pattern is required');
554
+ }
555
+
556
+ const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
557
+ const jwt = await this.generateJWT(this.id, {
558
+ permissions: ['git:read'],
559
+ ttl,
560
+ });
561
+
562
+ const body: Record<string, unknown> = {
563
+ query: {
564
+ pattern,
565
+ ...(typeof options.query.caseSensitive === 'boolean'
566
+ ? { case_sensitive: options.query.caseSensitive }
567
+ : {}),
568
+ },
569
+ };
570
+
571
+ if (options.ref) {
572
+ body.rev = options.ref;
573
+ }
574
+ if (Array.isArray(options.paths) && options.paths.length > 0) {
575
+ body.paths = options.paths;
576
+ }
577
+ if (options.fileFilters) {
578
+ body.file_filters = {
579
+ ...(options.fileFilters.includeGlobs
580
+ ? { include_globs: options.fileFilters.includeGlobs }
581
+ : {}),
582
+ ...(options.fileFilters.excludeGlobs
583
+ ? { exclude_globs: options.fileFilters.excludeGlobs }
584
+ : {}),
585
+ ...(options.fileFilters.extensionFilters
586
+ ? { extension_filters: options.fileFilters.extensionFilters }
587
+ : {}),
588
+ };
589
+ }
590
+ if (options.context) {
591
+ body.context = {
592
+ ...(typeof options.context.before === 'number' ? { before: options.context.before } : {}),
593
+ ...(typeof options.context.after === 'number' ? { after: options.context.after } : {}),
594
+ };
595
+ }
596
+ if (options.limits) {
597
+ body.limits = {
598
+ ...(typeof options.limits.maxLines === 'number'
599
+ ? { max_lines: options.limits.maxLines }
600
+ : {}),
601
+ ...(typeof options.limits.maxMatchesPerFile === 'number'
602
+ ? { max_matches_per_file: options.limits.maxMatchesPerFile }
603
+ : {}),
604
+ };
605
+ }
606
+ if (options.pagination) {
607
+ body.pagination = {
608
+ ...(typeof options.pagination.cursor === 'string' && options.pagination.cursor.trim() !== ''
609
+ ? { cursor: options.pagination.cursor }
610
+ : {}),
611
+ ...(typeof options.pagination.limit === 'number'
612
+ ? { limit: options.pagination.limit }
613
+ : {}),
614
+ };
615
+ }
616
+
617
+ const response = await this.api.post({ path: 'repos/grep', body }, jwt);
618
+ const raw = grepResponseSchema.parse(await response.json());
619
+
620
+ return {
621
+ query: {
622
+ pattern: raw.query.pattern,
623
+ caseSensitive: raw.query.case_sensitive,
624
+ },
625
+ repo: {
626
+ ref: raw.repo.ref,
627
+ commit: raw.repo.commit,
628
+ },
629
+ matches: raw.matches.map(transformGrepFileMatch),
630
+ nextCursor: raw.next_cursor ?? undefined,
631
+ hasMore: raw.has_more,
632
+ };
633
+ }
634
+
527
635
  async pullUpstream(options: PullUpstreamOptions = {}): Promise<void> {
528
636
  const ttl = resolveInvocationTtlSeconds(options, DEFAULT_TOKEN_TTL_SECONDS);
529
637
  const jwt = await this.generateJWT(this.id, {
package/src/schemas.ts CHANGED
@@ -128,6 +128,31 @@ export const restoreCommitResponseSchema = z.object({
128
128
  result: refUpdateResultWithOptionalsSchema,
129
129
  });
130
130
 
131
+ export const grepLineSchema = z.object({
132
+ line_number: z.number(),
133
+ text: z.string(),
134
+ type: z.string(),
135
+ });
136
+
137
+ export const grepFileMatchSchema = z.object({
138
+ path: z.string(),
139
+ lines: z.array(grepLineSchema),
140
+ });
141
+
142
+ export const grepResponseSchema = z.object({
143
+ query: z.object({
144
+ pattern: z.string(),
145
+ case_sensitive: z.boolean(),
146
+ }),
147
+ repo: z.object({
148
+ ref: z.string(),
149
+ commit: z.string(),
150
+ }),
151
+ matches: z.array(grepFileMatchSchema),
152
+ next_cursor: z.string().nullable().optional(),
153
+ has_more: z.boolean(),
154
+ });
155
+
131
156
  export const errorEnvelopeSchema = z.object({
132
157
  error: z.string(),
133
158
  });
@@ -144,3 +169,4 @@ export type GetCommitDiffResponseRaw = z.infer<typeof commitDiffResponseSchema>;
144
169
  export type CreateBranchResponseRaw = z.infer<typeof createBranchResponseSchema>;
145
170
  export type CommitPackAckRaw = z.infer<typeof commitPackAckSchema>;
146
171
  export type RestoreCommitAckRaw = z.infer<typeof restoreCommitAckSchema>;
172
+ export type GrepResponseRaw = z.infer<typeof grepResponseSchema>;
package/src/types.ts CHANGED
@@ -46,6 +46,7 @@ export interface Repo {
46
46
  listCommits(options?: ListCommitsOptions): Promise<ListCommitsResult>;
47
47
  getBranchDiff(options: GetBranchDiffOptions): Promise<GetBranchDiffResult>;
48
48
  getCommitDiff(options: GetCommitDiffOptions): Promise<GetCommitDiffResult>;
49
+ grep(options: GrepOptions): Promise<GrepResult>;
49
50
  pullUpstream(options?: PullUpstreamOptions): Promise<void>;
50
51
  restoreCommit(options: RestoreCommitOptions): Promise<RestoreCommitResult>;
51
52
  createBranch(options: CreateBranchOptions): Promise<CreateBranchResult>;
@@ -223,6 +224,62 @@ export interface GetCommitDiffResult {
223
224
  filteredFiles: FilteredFile[];
224
225
  }
225
226
 
227
+ // Grep API types
228
+ export interface GrepOptions extends GitStorageInvocationOptions {
229
+ ref?: string;
230
+ paths?: string[];
231
+ query: {
232
+ pattern: string;
233
+ /**
234
+ * Default is case-sensitive.
235
+ * When omitted, the server default is used.
236
+ */
237
+ caseSensitive?: boolean;
238
+ };
239
+ fileFilters?: {
240
+ includeGlobs?: string[];
241
+ excludeGlobs?: string[];
242
+ extensionFilters?: string[];
243
+ };
244
+ context?: {
245
+ before?: number;
246
+ after?: number;
247
+ };
248
+ limits?: {
249
+ maxLines?: number;
250
+ maxMatchesPerFile?: number;
251
+ };
252
+ pagination?: {
253
+ cursor?: string;
254
+ limit?: number;
255
+ };
256
+ }
257
+
258
+ export interface GrepLine {
259
+ lineNumber: number;
260
+ text: string;
261
+ type: string;
262
+ }
263
+
264
+ export interface GrepFileMatch {
265
+ path: string;
266
+ lines: GrepLine[];
267
+ }
268
+
269
+ export interface GrepResult {
270
+ query: {
271
+ pattern: string;
272
+ caseSensitive: boolean;
273
+ };
274
+ repo: {
275
+ ref: string;
276
+ commit: string;
277
+ };
278
+ matches: GrepFileMatch[];
279
+ nextCursor?: string;
280
+ hasMore: boolean;
281
+ }
282
+
226
283
  // Shared diff types
227
284
  export interface DiffStats {
228
285
  files: number;