diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..7a5fd3e86821a4adefa86484cda2ff9d5eee0ce6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 xuty + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index bce04add25360f754742d39413e3665bb64a536e..0154671f0bfbaf93c46d70851e720bac2472aafb 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,4 @@ -A library for Dart developers. - -Created from templates made available by Stagehand under a BSD-style -[license](https://github.com/dart-lang/stagehand/blob/master/LICENSE). +This is the _unofficial_ MinIO Dart Client SDK that provides simple APIs to access any Amazon S3 compatible object storage server. ## API @@ -21,20 +18,44 @@ Created from templates made available by Stagehand under a BSD-style ## Usage -A simple usage example: +### Initialize MinIO Client + +**MinIO** ```dart import 'package:minio/minio.dart'; -main() { - var awesome = new Awesome(); -} +final minio = Minio( + endPoint: 'play.min.io', + accessKey: 'Q3AM3UQ867SPQQA43P2F', + secretKey: 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG', +); ``` +**AWS S3** + +```dart +import 'package:minio/minio.dart'; + +final minio = Minio( + endPoint: 's3.amazonaws.com', + accessKey: 'YOUR-ACCESSKEYID', + secretKey: 'YOUR-SECRETACCESSKEY', +); +``` + +For complete example, see: [example] + ## Features and bugs Please file feature requests and bugs at the [issue tracker][tracker]. -[tracker]: http://example.com/issues/replaceme +Contributions to this repository are welcomed. + +## Lisence + +MIT +[tracker]: https://github.com/xtyxtyx/minio-dart/issues +[example]: https://example.com [link text itself]: http://www.reddit.com \ No newline at end of file diff --git a/example/minio_example.dart b/example/minio_example.dart index dcf4563d4938c1e7e746b082903aa6ce58b0a2de..345e8ae0481255205c2d1e08d373b6c9866bf809 100644 --- a/example/minio_example.dart +++ b/example/minio_example.dart @@ -6,7 +6,7 @@ void main() async { endPoint: 'play.min.io', accessKey: 'Q3AM3UQ867SPQQA43P2F', secretKey: 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG', - useSSL: false, + useSSL: true, // enableTrace: true, ); diff --git a/lib/io.dart b/lib/io.dart index 26f5ebf3fa63fa71c1c7111dff8c43a2657a1cb5..6b20b1985155aa2f5dc1848506e4e38d77dca192 100644 --- a/lib/io.dart +++ b/lib/io.dart @@ -6,6 +6,7 @@ import 'package:minio/src/minio_helpers.dart'; import 'package:path/path.dart' show dirname; extension MinioX on Minio { + // Uploads the object using contents from a file Future<String> fPutObject( String bucket, String object, @@ -30,6 +31,7 @@ extension MinioX on Minio { return putObject(bucket, object, file.openRead(), stat.size); } + /// Downloads and saves the object as a file in the local filesystem. Future<void> fGetObject( String bucket, String object, diff --git a/lib/src/minio.dart b/lib/src/minio.dart index 787e13d85789786596e50720b838701035269627..6726870ed1b9cb63d1c5007bb6eacf403035e3ca 100644 --- a/lib/src/minio.dart +++ b/lib/src/minio.dart @@ -1,212 +1,14 @@ -import 'dart:convert'; - import 'package:http/http.dart'; import 'package:minio/models.dart'; +import 'package:minio/src/minio_client.dart'; import 'package:minio/src/minio_errors.dart'; import 'package:minio/src/minio_helpers.dart'; -import 'package:minio/src/minio_s3.dart'; -import 'package:minio/src/minio_sign.dart'; import 'package:minio/src/minio_uploader.dart'; import 'package:minio/src/utils.dart'; import 'package:xml/xml.dart' as xml; -class MinioRequest extends BaseRequest { - MinioRequest(String method, Uri url) : super(method, url); - - dynamic body; - - @override - ByteStream finalize() { - super.finalize(); - if (body is String) { - return ByteStream.fromBytes(utf8.encode(body)); - } - if (body is List<int>) { - return ByteStream.fromBytes(body); - } - if (body is Stream<List<int>>) { - return ByteStream(body); - } - throw UnsupportedError('unsupported body type: ${body.runtimeType}'); - } -} - -class MinioClient { - MinioClient(this.minio) { - anonymous = minio.accessKey.isEmpty && minio.secretKey.isEmpty; - enableSHA256 = !anonymous && !minio.useSSL; - port = minio.port ?? implyPort(minio.useSSL); - } - - final Minio minio; - final String userAgent = 'MinIO (Unknown; Unknown) minio-js/0.0.1'; - - bool enableSHA256; - bool anonymous; - int port; - - Future<StreamedResponse> _request({ - String method, - String bucket, - String object, - String region, - String resource, - dynamic payload = '', - Map<String, String> queries, - Map<String, String> headers, - }) async { - final url = getRequestUrl(bucket, object, resource, queries); - final request = MinioRequest(method, url); - final date = DateTime.now().toUtc(); - final sha256sum = enableSHA256 ? sha256Hex(payload) : 'UNSIGNED-PAYLOAD'; - - region ??= await minio.getBucketRegion(bucket); - - request.body = payload; - - request.headers.addAll({ - 'host': url.host, - 'user-agent': userAgent, - 'x-amz-date': makeDateLong(date), - 'x-amz-content-sha256': sha256sum, - }); - - if (headers != null) { - request.headers.addAll(headers); - } - - final authorization = signV4(minio, request, date, 'us-east-1'); - request.headers['authorization'] = authorization; - - logRequest(request); - final response = await request.send(); - return response; - } - - Future<Response> request({ - String method, - String bucket, - String object, - String region, - String resource, - dynamic payload = '', - Map<String, String> queries, - Map<String, String> headers, - }) async { - final stream = _request( - method: method, - bucket: bucket, - object: object, - region: region, - payload: payload, - resource: resource, - queries: queries, - headers: headers, - ); - - final response = await Response.fromStream(await stream); - logResponse(response); - - return response; - } - - Future<StreamedResponse> requestStream({ - String method, - String bucket, - String object, - String region, - String resource, - dynamic payload = '', - Map<String, String> queries, - Map<String, String> headers, - }) async { - final response = await _request( - method: method, - bucket: bucket, - object: object, - region: region, - payload: payload, - resource: resource, - queries: queries, - headers: headers, - ); - - logResponse(response); - return response; - } - - Uri getRequestUrl( - String bucket, - String object, - String resource, - Map<String, String> queries, - ) { - var host = minio.endPoint.toLowerCase(); - var path = '/'; - - if (isAmazonEndpoint(host)) { - host = getS3Endpoint(minio.region); - } - - if (isVirtualHostStyle(host, minio.useSSL, bucket)) { - if (bucket != null) host = '${bucket}.${host}'; - if (object != null) path = '/${object}'; - } else { - if (bucket != null) path = '/${bucket}'; - if (object != null) path = '/${bucket}/${object}'; - } - - final resourcePart = resource == null ? '' : '$resource'; - final queryPart = queries == null ? '' : '&${encodeQueries(queries)}'; - final query = resourcePart + queryPart; - - return Uri( - scheme: minio.useSSL ? 'https' : 'http', - host: host, - port: minio.port, - pathSegments: path.split('/'), - query: query, - ); - } - - void logRequest(MinioRequest request) { - if (!minio.enableTrace) return; - - final buffer = StringBuffer(); - buffer.writeln('REQUEST: ${request.method} ${request.url}'); - for (var header in request.headers.entries) { - buffer.writeln('${header.key}: ${header.value}'); - } - - if (request.body is List<int>) { - buffer.writeln('List<int> of size ${request.body.length}'); - } else { - buffer.writeln(request.body); - } - - print(buffer.toString()); - } - - void logResponse(BaseResponse response) { - if (!minio.enableTrace) return; - - final buffer = StringBuffer(); - buffer.writeln('RESPONSE: ${response.statusCode} ${response.reasonPhrase}'); - for (var header in response.headers.entries) { - buffer.writeln('${header.key}: ${header.value}'); - } - - if (response is Response) { - buffer.writeln(response.body); - } else if (response is StreamedResponse) { - buffer.writeln('STREAMED BODY'); - } - - print(buffer.toString()); - } -} - class Minio { + /// Initializes a new client object. Minio({ this.endPoint, this.port, @@ -224,22 +26,43 @@ class Minio { _client = MinioClient(this); } + /// default part size for multipart uploads. final partSize = 64 * 1024 * 1024; + + /// maximum part size for multipart uploads. final maximumPartSize = 5 * 1024 * 1024 * 1024; + + /// maximum object size (5TB) final maxObjectSize = 5 * 1024 * 1024 * 1024 * 1024; + /// endPoint is a host name or an IP address. final String endPoint; + + /// TCP/IP port number. This input is optional. Default value set to 80 for HTTP and 443 for HTTPs. final int port; + + /// If set to true, https is used instead of http. Default is true. final bool useSSL; + + /// accessKey is like user-id that uniquely identifies your account. final String accessKey; + + /// secretKey is the password to your account. final String secretKey; + + /// Set this value to provide x-amz-security-token (AWS S3 specific). (Optional) final String sessionToken; + + /// Set this value to override region cache. (Optional) final String region; + + /// Set this value to enable tracing. (Optional) final bool enableTrace; MinioClient _client; final _regionMap = <String, String>{}; + /// Checks if a bucket exists. Future<bool> bucketExists(String bucket) async { MinioInvalidBucketNameError.check(bucket); try { @@ -252,7 +75,7 @@ class Minio { return true; } - int calculatePartSize(int size) { + int _calculatePartSize(int size) { assert(size != null && size >= 0); if (size > maxObjectSize) { @@ -272,6 +95,8 @@ class Minio { } } + /// Complete the multipart upload. After all the parts are uploaded issuing + /// this call will aggregate the parts on the server into a single object. Future<String> completeMultipartUpload( String bucket, String object, @@ -307,6 +132,7 @@ class Minio { return etag; } + /// Copy the object. Future<CopyObjectResult> copyObject( String bucket, String object, @@ -351,6 +177,7 @@ class Minio { return result; } + /// Find uploadId of an incomplete upload. Future<String> findUploadId(String bucket, String object) async { MinioInvalidBucketNameError.check(bucket); MinioInvalidObjectNameError.check(object); @@ -382,7 +209,8 @@ class Minio { return latestUpload?.uploadId; } - + + /// gets the region of the bucket Future<String> getBucketRegion(String bucket) async { MinioInvalidBucketNameError.check(bucket); @@ -409,12 +237,14 @@ class Minio { return location; } + /// get a readable stream of the object content. Future<ByteStream> getObject(String bucket, String object) { MinioInvalidBucketNameError.check(bucket); MinioInvalidObjectNameError.check(object); return getPartialObject(bucket, object, null, null); } + /// get a readable stream of the partial object content. Future<ByteStream> getPartialObject( String bucket, String object, [ @@ -454,6 +284,7 @@ class Minio { return resp.stream; } + /// Initiate a new multipart upload. Future<String> initiateNewMultipartUpload( String bucket, String object, @@ -475,6 +306,7 @@ class Minio { return node.findAllElements('UploadId').first.text; } + /// Returns a stream that emits objects that are partially uploaded. Stream<IncompleteUpload> listIncompleteUploads( String bucket, String prefix, [ @@ -508,6 +340,7 @@ class Minio { } while (isTruncated); } + /// Called by listIncompleteUploads to fetch a batch of incomplete uploads. Future<ListMultipartUploadsOutput> listIncompleteUploadsQuery( String bucket, String prefix, @@ -544,6 +377,7 @@ class Minio { return ListMultipartUploadsOutput.fromXml(node.root); } + /// List of buckets created. Future<List<Bucket>> listBuckets() async { final resp = await _client.request( method: 'GET', @@ -583,6 +417,7 @@ class Minio { } while (isTruncated); } + /// list a batch of objects Future<ListObjectsOutput> listObjectsQuery( String bucket, String prefix, @@ -655,6 +490,7 @@ class Minio { } while (isTruncated); } + /// listObjectsV2Query - (List Objects V2) - List some or all (up to 1000) of the objects in a bucket. Future<ListObjectsV2Output> listObjectsV2Query( String bucket, String prefix, @@ -708,6 +544,7 @@ class Minio { ..nextContinuationToken = nextContinuationToken; } + /// Get part-info of all parts of an incomplete upload specified by uploadId. Stream<Part> listParts( String bucket, String object, @@ -726,6 +563,7 @@ class Minio { } while (isTruncated); } + /// Called by listParts to fetch a batch of part-info Future<ListPartsOutput> listPartsQuery( String bucket, String object, @@ -751,6 +589,7 @@ class Minio { return ListPartsOutput.fromXml(node.root); } + /// Creates the bucket [bucket]. Future<void> makeBucket(String bucket, [String region]) async { MinioInvalidBucketNameError.check(bucket); if (this.region != null && region != null && this.region != region) { @@ -774,6 +613,7 @@ class Minio { return resp.body; } + /// Uploads the object. Future<String> putObject( String bucket, String object, @@ -790,7 +630,7 @@ class Minio { metadata = prependXAMZMeta(metadata ?? {}); size ??= maxObjectSize; - size = calculatePartSize(size); + size = _calculatePartSize(size); final chunker = BlockStream(size); final uploader = MinioUploader( @@ -805,6 +645,7 @@ class Minio { return etag.toString(); } + /// Remove a bucket. Future<void> removeBucket(String bucket) async { MinioInvalidBucketNameError.check(bucket); @@ -817,6 +658,7 @@ class Minio { _regionMap.remove(bucket); } + /// Remove the partially uploaded object. Future<void> removeIncompleteUpload(String bucket, String object) async { MinioInvalidBucketNameError.check(bucket); MinioInvalidObjectNameError.check(object); @@ -834,6 +676,7 @@ class Minio { validate(resp, expect: 204); } + /// Remove the specified object. Future<void> removeObject(String bucket, String object) async { MinioInvalidBucketNameError.check(bucket); MinioInvalidObjectNameError.check(object); @@ -847,6 +690,7 @@ class Minio { validate(resp, expect: 204); } + /// Remove all the objects residing in the objectsList. Future<void> removeObjects(String bucket, List<String> objects) async { MinioInvalidBucketNameError.check(bucket); @@ -869,6 +713,7 @@ class Minio { } } + /// Stat information of the object. Future<StatObjectResult> statObject(String bucket, String object) async { MinioInvalidBucketNameError.check(bucket); MinioInvalidObjectNameError.check(object); @@ -894,34 +739,3 @@ class Minio { ); } } - -Future<void> validateStreamed( - StreamedResponse streamedResponse, { - int expect, -}) async { - if (streamedResponse.statusCode >= 400) { - final response = await Response.fromStream(streamedResponse); - final body = xml.parse(response.body); - final error = Error.fromXml(body.rootElement); - throw MinioS3Error(error.message, error, response); - } - - if (expect != null && streamedResponse.statusCode != expect) { - final response = await Response.fromStream(streamedResponse); - throw MinioS3Error( - '$expect expected, got ${streamedResponse.statusCode}', null, response); - } -} - -void validate(Response response, {int expect}) { - if (response.statusCode >= 400) { - final body = xml.parse(response.body); - final error = Error.fromXml(body.rootElement); - throw MinioS3Error(error.message, error, response); - } - - if (expect != null && response.statusCode != expect) { - throw MinioS3Error( - '$expect expected, got ${response.statusCode}', null, response); - } -} diff --git a/lib/src/minio_client.dart b/lib/src/minio_client.dart new file mode 100644 index 0000000000000000000000000000000000000000..e6628c36325ffce22471063c15044297b2d4b044 --- /dev/null +++ b/lib/src/minio_client.dart @@ -0,0 +1,204 @@ +import 'dart:convert'; + +import 'package:http/http.dart'; +import 'package:minio/minio.dart'; +import 'package:minio/src/minio_helpers.dart'; +import 'package:minio/src/minio_s3.dart'; +import 'package:minio/src/minio_sign.dart'; +import 'package:minio/src/utils.dart'; + +class MinioRequest extends BaseRequest { + MinioRequest(String method, Uri url) : super(method, url); + + dynamic body; + + @override + ByteStream finalize() { + super.finalize(); + if (body is String) { + return ByteStream.fromBytes(utf8.encode(body)); + } + if (body is List<int>) { + return ByteStream.fromBytes(body); + } + if (body is Stream<List<int>>) { + return ByteStream(body); + } + throw UnsupportedError('unsupported body type: ${body.runtimeType}'); + } +} + +class MinioClient { + MinioClient(this.minio) { + anonymous = minio.accessKey.isEmpty && minio.secretKey.isEmpty; + enableSHA256 = !anonymous && !minio.useSSL; + port = minio.port ?? implyPort(minio.useSSL); + } + + final Minio minio; + final String userAgent = 'MinIO (Unknown; Unknown) minio-js/0.0.1'; + + bool enableSHA256; + bool anonymous; + int port; + + Future<StreamedResponse> _request({ + String method, + String bucket, + String object, + String region, + String resource, + dynamic payload = '', + Map<String, String> queries, + Map<String, String> headers, + }) async { + final url = getRequestUrl(bucket, object, resource, queries); + final request = MinioRequest(method, url); + final date = DateTime.now().toUtc(); + final sha256sum = enableSHA256 ? sha256Hex(payload) : 'UNSIGNED-PAYLOAD'; + + region ??= await minio.getBucketRegion(bucket); + + request.body = payload; + + request.headers.addAll({ + 'host': url.host, + 'user-agent': userAgent, + 'x-amz-date': makeDateLong(date), + 'x-amz-content-sha256': sha256sum, + }); + + if (headers != null) { + request.headers.addAll(headers); + } + + final authorization = signV4(minio, request, date, 'us-east-1'); + request.headers['authorization'] = authorization; + + logRequest(request); + final response = await request.send(); + return response; + } + + Future<Response> request({ + String method, + String bucket, + String object, + String region, + String resource, + dynamic payload = '', + Map<String, String> queries, + Map<String, String> headers, + }) async { + final stream = _request( + method: method, + bucket: bucket, + object: object, + region: region, + payload: payload, + resource: resource, + queries: queries, + headers: headers, + ); + + final response = await Response.fromStream(await stream); + logResponse(response); + + return response; + } + + Future<StreamedResponse> requestStream({ + String method, + String bucket, + String object, + String region, + String resource, + dynamic payload = '', + Map<String, String> queries, + Map<String, String> headers, + }) async { + final response = await _request( + method: method, + bucket: bucket, + object: object, + region: region, + payload: payload, + resource: resource, + queries: queries, + headers: headers, + ); + + logResponse(response); + return response; + } + + Uri getRequestUrl( + String bucket, + String object, + String resource, + Map<String, String> queries, + ) { + var host = minio.endPoint.toLowerCase(); + var path = '/'; + + if (isAmazonEndpoint(host)) { + host = getS3Endpoint(minio.region); + } + + if (isVirtualHostStyle(host, minio.useSSL, bucket)) { + if (bucket != null) host = '${bucket}.${host}'; + if (object != null) path = '/${object}'; + } else { + if (bucket != null) path = '/${bucket}'; + if (object != null) path = '/${bucket}/${object}'; + } + + final resourcePart = resource == null ? '' : '$resource'; + final queryPart = queries == null ? '' : '&${encodeQueries(queries)}'; + final query = resourcePart + queryPart; + + return Uri( + scheme: minio.useSSL ? 'https' : 'http', + host: host, + port: minio.port, + pathSegments: path.split('/'), + query: query, + ); + } + + void logRequest(MinioRequest request) { + if (!minio.enableTrace) return; + + final buffer = StringBuffer(); + buffer.writeln('REQUEST: ${request.method} ${request.url}'); + for (var header in request.headers.entries) { + buffer.writeln('${header.key}: ${header.value}'); + } + + if (request.body is List<int>) { + buffer.writeln('List<int> of size ${request.body.length}'); + } else { + buffer.writeln(request.body); + } + + print(buffer.toString()); + } + + void logResponse(BaseResponse response) { + if (!minio.enableTrace) return; + + final buffer = StringBuffer(); + buffer.writeln('RESPONSE: ${response.statusCode} ${response.reasonPhrase}'); + for (var header in response.headers.entries) { + buffer.writeln('${header.key}: ${header.value}'); + } + + if (response is Response) { + buffer.writeln(response.body); + } else if (response is StreamedResponse) { + buffer.writeln('STREAMED BODY'); + } + + print(buffer.toString()); + } +} \ No newline at end of file diff --git a/lib/src/minio_helpers.dart b/lib/src/minio_helpers.dart index 5c0bf5457790a99f2981d3d80c14fbe764d8d3cf..0f76f98fd8da708a225fb1ef6e34d5f542f49f9c 100644 --- a/lib/src/minio_helpers.dart +++ b/lib/src/minio_helpers.dart @@ -1,4 +1,8 @@ +import 'package:http/http.dart'; import 'package:mime/mime.dart' show lookupMimeType; +import 'package:minio/src/minio_errors.dart'; +import 'package:minio/src/minio_models_generated.dart'; +import 'package:xml/xml.dart' as xml; bool isValidBucketName(String bucket) { if (bucket == null) return false; @@ -192,3 +196,34 @@ Map<String, String> insertContentType( newMetadata['content-type'] = probeContentType(filePath); return newMetadata; } + +Future<void> validateStreamed( + StreamedResponse streamedResponse, { + int expect, +}) async { + if (streamedResponse.statusCode >= 400) { + final response = await Response.fromStream(streamedResponse); + final body = xml.parse(response.body); + final error = Error.fromXml(body.rootElement); + throw MinioS3Error(error.message, error, response); + } + + if (expect != null && streamedResponse.statusCode != expect) { + final response = await Response.fromStream(streamedResponse); + throw MinioS3Error( + '$expect expected, got ${streamedResponse.statusCode}', null, response); + } +} + +void validate(Response response, {int expect}) { + if (response.statusCode >= 400) { + final body = xml.parse(response.body); + final error = Error.fromXml(body.rootElement); + throw MinioS3Error(error.message, error, response); + } + + if (expect != null && response.statusCode != expect) { + throw MinioS3Error( + '$expect expected, got ${response.statusCode}', null, response); + } +} diff --git a/lib/src/minio_models_generated.dart b/lib/src/minio_models_generated.dart index 36a67a6c07998d29c43b876e8115d366dc9a0eb8..f23949cc0e548bcc7421530a709ebd96867662aa 100644 --- a/lib/src/minio_models_generated.dart +++ b/lib/src/minio_models_generated.dart @@ -486,7 +486,7 @@ class Condition { class ContinuationEvent { ContinuationEvent(); - ContinuationEvent.fromXml(XmlElement xml) {} + ContinuationEvent.fromXml(XmlElement xml); XmlNode toXml() { final builder = XmlBuilder(); @@ -1042,7 +1042,7 @@ class EncryptionConfiguration { class EndEvent { EndEvent(); - EndEvent.fromXml(XmlElement xml) {} + EndEvent.fromXml(XmlElement xml); XmlNode toXml() { final builder = XmlBuilder(); @@ -2540,7 +2540,7 @@ class Owner { class ParquetInput { ParquetInput(); - ParquetInput.fromXml(XmlElement xml) {} + ParquetInput.fromXml(XmlElement xml); XmlNode toXml() { final builder = XmlBuilder(); @@ -3658,7 +3658,7 @@ class SseKmsEncryptedObjects { class SSES3 { SSES3(); - SSES3.fromXml(XmlElement xml) {} + SSES3.fromXml(XmlElement xml); XmlNode toXml() { final builder = XmlBuilder(); diff --git a/lib/src/minio_sign.dart b/lib/src/minio_sign.dart index 2915ed6d6c6dddf90d759043c7fa717564563271..f79fd7cecf1f66fa78f194ce8fa0264b2b2d0ae2 100644 --- a/lib/src/minio_sign.dart +++ b/lib/src/minio_sign.dart @@ -1,6 +1,7 @@ import 'package:convert/convert.dart'; import 'package:crypto/crypto.dart'; import 'package:minio/minio.dart'; +import 'package:minio/src/minio_client.dart'; import 'package:minio/src/minio_helpers.dart'; import 'package:minio/src/utils.dart'; diff --git a/lib/src/minio_uploader.dart b/lib/src/minio_uploader.dart index 8c88c16569ba0bf9776db1c67a1aa66257d54323..dff64bd2d7ccc16f905f39c94fad7e3b42a5e3e2 100644 --- a/lib/src/minio_uploader.dart +++ b/lib/src/minio_uploader.dart @@ -5,6 +5,8 @@ import 'package:convert/convert.dart'; import 'package:crypto/crypto.dart'; import 'package:minio/minio.dart'; import 'package:minio/models.dart'; +import 'package:minio/src/minio_client.dart'; +import 'package:minio/src/minio_helpers.dart'; import 'package:minio/src/utils.dart'; class MinioUploader implements StreamConsumer<List<int>> { diff --git a/pubspec.yaml b/pubspec.yaml index 3bd02a1d1c6da1168e40b85f0da540a0150db926..1cf0fc12435f06f6b3af19b677b6ddd1ad2c99a4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,8 +1,8 @@ name: minio -description: Unofficial MinIO Dart Client for Amazon S3 Compatible Cloud Storage. +description: Unofficial MinIO Dart Client SDK that provides simple APIs to access any Amazon S3 compatible object storage server. version: 0.1.0 -# homepage: https://www.example.com -author: xuty <root@xuty.tk> +homepage: https://github.com/xtyxtyx/minio-dart +issue_tracker: https://github.com/xtyxtyx/minio-dart/issues environment: sdk: ">=2.7.0 <3.0.0" diff --git a/test/minio_dart_test.dart b/test/minio_dart_test.dart index 3c666688378d15664ac3e0080204c2ead59ab16d..f6775d5abcf6a772254b007b6870b59be68f6721 100644 --- a/test/minio_dart_test.dart +++ b/test/minio_dart_test.dart @@ -1,5 +1,3 @@ -import 'package:minio/minio.dart'; -import 'package:test/test.dart'; void main() { // group('A group of tests', () { diff --git a/bin/generate_models.dart b/util/generate_models.dart similarity index 100% rename from bin/generate_models.dart rename to util/generate_models.dart