feat(simplestorage): add ListResult type and enhance List with pagination#14
Conversation
…tion Add ContentDisposition and URL fields to Object struct to make it a strict superset of the TypeScript SDK Item type. Change List function to return *ListResult instead of []Object, matching the TypeScript list() function semantics with Items, NextToken, and HasMore fields for proper pagination support. Add new ClientOption functions: - WithDelimiter for grouping keys - WithPrefix for filtering keys by prefix - WithPaginationToken for pagination continuation BREAKING CHANGE: List() signature changed from List(ctx, prefix, opts) to List(ctx, opts). Use WithPrefix(prefix) option instead. Assisted-by: GLM 4.7 via Claude Code Signed-off-by: Xe Iaso <xe@tigrisdata.com>
3493843 to
7de4029
Compare
There was a problem hiding this comment.
Pull request overview
This PR enhances the simplestorage package's List functionality to align with the TypeScript SDK by adding pagination support and extending the Object struct with additional fields. The changes introduce a new ListResult type with proper pagination semantics and modify the List function signature to use option-based filtering instead of a direct prefix parameter.
Changes:
- Added ContentDisposition and URL fields to the Object struct to match TypeScript SDK's Item type
- Introduced ListResult struct with Items, NextToken, and HasMore fields for pagination
- Changed List() signature from
List(ctx, prefix, opts)toList(ctx, opts)with new WithPrefix, WithDelimiter, and WithPaginationToken options - Updated ClientOptions to support new List parameters (Delimiter, Prefix, PaginationToken)
Comments suppressed due to low confidence (1)
simplestorage/client.go:307
- The Object struct now includes ContentDisposition and URL fields according to the PR description, but these fields are not being populated in the List operation. The PR description states that Object should be a "strict superset of the TypeScript Item type, including all fields returned by list operations (contentDisposition, contentType, modified, path, size, url)". The ContentType field is also missing from the populated fields. These fields should be populated from the S3 ListObjectsV2 response if available, or left empty if not provided by the API.
for _, obj := range resp.Contents {
result.Items = append(result.Items, Object{
Bucket: o.BucketName,
Key: lower(obj.Key, ""),
Etag: lower(obj.ETag, ""),
Size: lower(obj.Size, 0),
LastModified: lower(obj.LastModified, time.Time{}),
})
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // The returned ListResult contains pagination information; use NextToken with | ||
| // WithPaginationToken() to fetch the next page. HasMore indicates whether | ||
| // additional objects are available. | ||
| func (c *Client) List(ctx context.Context, opts ...ClientOption) (*ListResult, error) { |
There was a problem hiding this comment.
The new List function signature and ListResult type lack test coverage. While the repository has comprehensive automated testing for other functions (e.g., ListBuckets, GetBucketInfo), there are no tests for the updated List operation. Tests should be added to verify the new pagination behavior with NextToken and HasMore, as well as the new WithPrefix, WithDelimiter, and WithPaginationToken options.
| type ListResult struct { | ||
| Items []Object // List of objects | ||
| NextToken string // Pagination token for the next page | ||
| HasMore bool // Whether there are more objects to list |
There was a problem hiding this comment.
The ListResult struct uses "HasMore" to indicate pagination status, while the similar BucketList struct uses "Truncated" for the same purpose. This naming inconsistency could be confusing for users of the API. Consider using "Truncated" here for consistency with BucketList, or update the documentation to explain why different terminology is used.
| type ListResult struct { | |
| Items []Object // List of objects | |
| NextToken string // Pagination token for the next page | |
| HasMore bool // Whether there are more objects to list | |
| // It is a higher-level view over the lower-level BucketList type, which exposes a | |
| // Truncated field following the underlying S3 API. In contrast, HasMore is named to | |
| // be more user-friendly: it is true when additional pages can be listed (i.e., when | |
| // BucketList.Truncated is true). | |
| type ListResult struct { | |
| Items []Object // List of objects | |
| NextToken string // Pagination token for the next page | |
| HasMore bool // True if there are more objects to list (maps from BucketList.Truncated) |
| resp, err := c.cli.ListObjectsV2( | ||
| ctx, | ||
| &s3.ListObjectsV2Input{ | ||
| Bucket: aws.String(o.BucketName), | ||
| Prefix: aws.String(prefix), | ||
|
|
||
| MaxKeys: o.MaxKeys, | ||
| StartAfter: o.StartAfter, | ||
| Bucket: aws.String(o.BucketName), | ||
| Delimiter: o.Delimiter, | ||
| Prefix: o.Prefix, | ||
| MaxKeys: o.MaxKeys, | ||
| ContinuationToken: o.PaginationToken, | ||
| StartAfter: o.StartAfter, |
There was a problem hiding this comment.
The List function allows both StartAfter and ContinuationToken (PaginationToken) to be set simultaneously. According to AWS S3 ListObjectsV2 API documentation, when ContinuationToken is specified, StartAfter should not be used as they serve different pagination purposes. The function should either document this behavior clearly or validate that both aren't set at the same time to prevent unexpected behavior.
# [0.3.0](v0.2.0...v0.3.0) (2026-01-26) ### Features * **simplestorage:** add ListResult type and enhance List with pagination ([#14](#14)) ([134cc0e](134cc0e)) * **storage:** suppress AWS SDK logging with Nop logger ([#15](#15)) ([d3f9338](d3f9338)) ### BREAKING CHANGES * **simplestorage:** List() signature changed from List(ctx, prefix, opts) to List(ctx, opts). Use WithPrefix(prefix) option instead. Assisted-by: GLM 4.7 via Claude Code Signed-off-by: Xe Iaso <xe@tigrisdata.com> Signed-off-by: Tigris Data <social@tigrisdata.com>
|
🎉 This PR is included in version 0.3.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Summary
ContentDispositionandURLfields toObjectstructListResultstruct withItems,NextToken, andHasMorefieldsList()to return*ListResultinstead of[]ObjectClientOptionfunctions:WithDelimiter,WithPrefix,WithPaginationTokenDetails
This PR aligns the Go SDK's
simplestorage.List()with the TypeScript SDK'slist()function semantics. TheObjectstruct is now a strict superset of the TypeScriptItemtype, including all fields returned by list operations (contentDisposition,contentType,modified,path,size,url).The new
ListResulttype provides proper pagination support withNextTokenandHasMorefields, matching the TypeScript API.Breaking Change: The
List()signature changed fromList(ctx, prefix, opts)toList(ctx, opts). UseWithPrefix(prefix)option instead.Test plan
go build ./...npm run format