Skip to content

Commit e866bd6

Browse files
author
ekjotmultani
committed
allow the s3 list api to accept an optional bucket
1 parent 3eafd51 commit e866bd6

File tree

6 files changed

+92
-16
lines changed

6 files changed

+92
-16
lines changed

packages/amplify_core/lib/src/category/amplify_storage_category.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ class StorageCategory extends AmplifyCategory<StoragePluginInterface> {
153153
data: data,
154154
onProgress: onProgress,
155155
options: options,
156+
bucket: bucket,
156157
),
157158
);
158159
}

packages/amplify_core/lib/src/types/storage/list_options.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
import 'package:aws_common/aws_common.dart';
4+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
5+
// SPDX-License-Identifier: Apache-2.0
6+
7+
import 'package:amplify_core/amplify_core.dart';
58

69
/// {@template amplify_core.storage.list_options}
710
/// Configurable options for `Amplify.Storage.list`.
@@ -15,6 +18,7 @@ class StorageListOptions
1518
const StorageListOptions({
1619
this.pageSize = 1000,
1720
this.nextToken,
21+
this.bucket,
1822
this.pluginOptions,
1923
});
2024

@@ -26,9 +30,12 @@ class StorageListOptions
2630

2731
/// {@macro amplify_core.storage.list_plugin_options}
2832
final StorageListPluginOptions? pluginOptions;
33+
34+
/// an optional bucket to specify which bucket to return the list for
35+
final StorageBucket? bucket;
2936

3037
@override
31-
List<Object?> get props => [pageSize, nextToken, pluginOptions];
38+
List<Object?> get props => [pageSize, nextToken, pluginOptions, bucket];
3239

3340
@override
3441
String get runtimeTypeName => 'StorageListOptions';
@@ -37,6 +44,7 @@ class StorageListOptions
3744
Map<String, Object?> toJson() => {
3845
'pageSize': pageSize,
3946
'nextToken': nextToken,
47+
'bucket': bucket,
4048
'pluginOptions': pluginOptions?.toJson(),
4149
};
4250
}

packages/storage/amplify_storage_s3/example/integration_test/list_test.dart

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,51 @@ void main() {
2020
'$uniquePrefix/file2.txt',
2121
'$uniquePrefix/subdir/file3.txt',
2222
'$uniquePrefix/subdir2#file4.txt',
23+
'$uniquePrefix/file5.txt',
24+
'$uniquePrefix/file6.txt',
25+
'$uniquePrefix/subdir3/file7.txt',
26+
'$uniquePrefix/subdir4#file8.txt',
2327
];
2428
group('standard config', () {
2529
setUpAll(() async {
2630
await configure(amplifyEnvironments['main']!);
27-
28-
for (final path in uploadedPaths) {
31+
for (var i = 0; i < 4; i++) {
2932
await Amplify.Storage.uploadData(
30-
path: StoragePath.fromString(path),
33+
path: StoragePath.fromString(uploadedPaths[i]),
3134
data: StorageDataPayload.bytes('test content'.codeUnits),
35+
bucket: StorageBucket.fromOutputs('Storage Integ Test main bucket'),
36+
).result;
37+
}
38+
for (var i = 4; i < 8; i++) {
39+
await Amplify.Storage.uploadData(
40+
path: StoragePath.fromString(uploadedPaths[i]),
41+
data: StorageDataPayload.bytes('test content'.codeUnits),
42+
bucket: StorageBucket.fromOutputs('Storage Integ Test secondary bucket'),
3243
).result;
3344
}
34-
3545
for (final path in uploadedPaths) {
3646
addTearDownPath(StoragePath.fromString(path));
3747
}
3848
});
3949

4050
group('list() without options', () {
4151
testWidgets('should list all files with unique prefix', (_) async {
42-
final listResult = await Amplify.Storage.list(
52+
final listResultMainBucket = await Amplify.Storage.list(
4353
path: StoragePath.fromString(uniquePrefix),
4454
).result;
45-
46-
for (final uploadedPath in uploadedPaths) {
55+
final listResultSecondaryBucket = await Amplify.Storage.list(
56+
path: StoragePath.fromString(uniquePrefix),
57+
options: StorageListOptions(bucket: StorageBucket.fromOutputs('Storage Integ Test secondary bucket')),
58+
).result;
59+
for (var i = 0; i < 4; i++) {
60+
expect(
61+
listResultMainBucket.items.any((item) => item.path == uploadedPaths[i]),
62+
isTrue,
63+
);
64+
}
65+
for (var i = 4; i < 8; i++) {
4766
expect(
48-
listResult.items.any((item) => item.path == uploadedPath),
67+
listResultSecondaryBucket.items.any((item) => item.path == uploadedPaths[i]),
4968
isTrue,
5069
);
5170
}
@@ -101,6 +120,17 @@ void main() {
101120
),
102121
).result as S3ListResult;
103122

123+
final listResultSecondaryBucket = await Amplify.Storage.list(
124+
path: StoragePath.fromString('$uniquePrefix/'),
125+
options: StorageListOptions(
126+
pluginOptions: const S3ListPluginOptions(
127+
excludeSubPaths: true,
128+
delimiter: '#',
129+
),
130+
bucket: StorageBucket.fromOutputs('Storage Integ Test secondary bucket'),
131+
),
132+
).result as S3ListResult;
133+
104134
expect(listResult.items.length, 3);
105135
expect(listResult.items.first.path, contains('file1.txt'));
106136

@@ -110,6 +140,16 @@ void main() {
110140
'$uniquePrefix/subdir2#',
111141
);
112142
expect(listResult.metadata.delimiter, '#');
143+
144+
expect(listResultSecondaryBucket.items.length, 3);
145+
expect(listResultSecondaryBucket.items.first.path, contains('file5.txt'));
146+
147+
expect(listResultSecondaryBucket.metadata.subPaths.length, 1);
148+
expect(
149+
listResultSecondaryBucket.metadata.subPaths.first,
150+
'$uniquePrefix/subdir4#',
151+
);
152+
expect(listResultSecondaryBucket.metadata.delimiter, '#');
113153
});
114154
});
115155

@@ -123,6 +163,17 @@ void main() {
123163

124164
expect(listResult.items.length, 2);
125165
expect(listResult.items.first.path, contains('file1.txt'));
166+
167+
final listResultSecondaryBucket = await Amplify.Storage.list(
168+
path: StoragePath.fromString(uniquePrefix),
169+
options: StorageListOptions(
170+
pageSize: 2,
171+
bucket: StorageBucket.fromOutputs('Storage Integ Test secondary bucket'),
172+
),
173+
).result;
174+
175+
expect(listResultSecondaryBucket.items.length, 2);
176+
expect(listResultSecondaryBucket.items.first.path, contains('file5.txt'));
126177
});
127178

128179
testWidgets('should list files with pagination', (_) async {
@@ -157,8 +208,19 @@ void main() {
157208
),
158209
).result;
159210

160-
expect(listResult.items.length, uploadedPaths.length);
211+
expect(listResult.items.length, uploadedPaths.length~/2);
161212
expect(listResult.nextToken, isNull);
213+
214+
final listResultSecondaryBucket = await Amplify.Storage.list(
215+
path: StoragePath.fromString(uniquePrefix),
216+
options: StorageListOptions(
217+
pluginOptions: const S3ListPluginOptions.listAll(),
218+
bucket: StorageBucket.fromOutputs('Storage Integ Test secondary bucket'),
219+
),
220+
).result;
221+
222+
expect(listResultSecondaryBucket.items.length, uploadedPaths.length~/2);
223+
expect(listResultSecondaryBucket.nextToken, isNull);
162224
});
163225
});
164226
});

packages/storage/amplify_storage_s3_dart/lib/src/amplify_storage_s3_dart_impl.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class AmplifyStorageS3Dart extends StoragePluginInterface
124124
});
125125
}
126126

127-
@override
127+
@override
128128
S3ListOperation list({
129129
required StoragePath path,
130130
StorageListOptions? options,
@@ -136,6 +136,7 @@ class AmplifyStorageS3Dart extends StoragePluginInterface
136136
final s3Options = StorageListOptions(
137137
pluginOptions: s3PluginOptions,
138138
nextToken: options?.nextToken,
139+
bucket: options?.bucket,
139140
pageSize: options?.pageSize ?? 1000,
140141
);
141142

@@ -151,6 +152,7 @@ class AmplifyStorageS3Dart extends StoragePluginInterface
151152
);
152153
}
153154

155+
154156
@override
155157
S3GetPropertiesOperation getProperties({
156158
required StoragePath path,

packages/storage/amplify_storage_s3_dart/lib/src/storage_s3_service/service/storage_s3_service_impl.dart

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,12 @@ class StorageS3Service {
125125
const S3ListPluginOptions();
126126

127127
final resolvedPath = await _pathResolver.resolvePath(path: path);
128+
final s3ClientInfo = options.bucket == null ? getS3ClientInfo() : getS3ClientInfo(storageBucket: options.bucket);
128129

129130
if (!s3PluginOptions.listAll) {
130131
final request = s3.ListObjectsV2Request.build((builder) {
131132
builder
132-
..bucket = _storageOutputs.bucketName
133+
..bucket = s3ClientInfo.bucketName
133134
..prefix = resolvedPath
134135
..maxKeys = options.pageSize
135136
..continuationToken = options.nextToken
@@ -140,7 +141,7 @@ class StorageS3Service {
140141

141142
try {
142143
return S3ListResult.fromPaginatedResult(
143-
await _defaultS3Client.listObjectsV2(request).result,
144+
await s3ClientInfo.client.listObjectsV2(request).result,
144145
);
145146
} on smithy.UnknownSmithyHttpException catch (error) {
146147
// S3Client.headObject may return 403 error
@@ -156,14 +157,15 @@ class StorageS3Service {
156157
try {
157158
final request = s3.ListObjectsV2Request.build((builder) {
158159
builder
159-
..bucket = _storageOutputs.bucketName
160+
// ignore: invalid_use_of_internal_member
161+
..bucket = options.bucket == null ? _storageOutputs.bucketName : options.bucket!.resolveBucketInfo(_storageOutputs).bucketName
160162
..prefix = resolvedPath
161163
..delimiter = s3PluginOptions.excludeSubPaths
162164
? s3PluginOptions.delimiter
163165
: null;
164166
});
165167

166-
listResult = await _defaultS3Client.listObjectsV2(request).result;
168+
listResult = await s3ClientInfo.client.listObjectsV2(request).result;
167169
recursiveResult = S3ListResult.fromPaginatedResult(
168170
listResult,
169171
);

packages/storage/amplify_storage_s3_dart/test/amplify_storage_s3_dart_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ void main() {
140140
const testOptions = StorageListOptions(
141141
pluginOptions: S3ListPluginOptions(excludeSubPaths: true),
142142
nextToken: 'next-token-123',
143+
bucket: StorageBucket.fromBucketInfo(BucketInfo(bucketName: 'unit-test-bucket', region: 'us-east-2')),
143144
pageSize: 2,
144145
);
145146

0 commit comments

Comments
 (0)