Skip to content

Commit

Permalink
refactor listBuckets (minio#1179)
Browse files Browse the repository at this point in the history
* refactor listBuckets

* remove unused

* address review comment

* address review comments and feedback

* format

* update doc example

* update note about top level await

* update note about top level await
  • Loading branch information
prakashsvmx authored Jul 6, 2023
1 parent 5276217 commit 6cf40a7
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 71 deletions.
22 changes: 13 additions & 9 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ var s3Client = new Minio.Client({
})
```

### _Note_: The below examples rely on top level await .

## 2. Bucket operations

<a name="makeBucket"></a>
Expand Down Expand Up @@ -183,17 +185,15 @@ minioClient.makeBucket('mybucket', 'us-east-1', { ObjectLocking: true }, functio

<a name="listBuckets"></a>

### listBuckets([callback])
### listBuckets()

Lists all buckets.

**Parameters**

| Param | Type | Description |
| ------------------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `callback(err, bucketStream) ` | _function_ | Callback function with error as the first argument. `bucketStream` is the stream emitting bucket information. If no callback is passed, a `Promise` is returned. |
NIL

bucketStream emits Object with the format:-
Returns Array of Objects with the format:-

| Param | Type | Description |
| --------------------- | -------- | ----------------------------- |
Expand All @@ -202,11 +202,15 @@ bucketStream emits Object with the format:-

**Example**

Please refer to: [list-buckets.mjs](..%2Fexamples%2Flist-buckets.mjs)

```js
minioClient.listBuckets(function (err, buckets) {
if (err) return console.log(err)
console.log('buckets :', buckets)
})
try {
const buckets = await s3Client.listBuckets()
console.log('Success', buckets)
} catch (err) {
console.log(err.message)
}
```

<a name="bucketExists"></a>
Expand Down
15 changes: 10 additions & 5 deletions examples/list-buckets.js → examples/list-buckets.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,23 @@
* limitations under the License.
*/

// Using the top-level await as we use .mjs extension
// run it like: node list-buckets.mjs

// Note: YOUR-ACCESSKEYID and YOUR-SECRETACCESSKEY are dummy values, please
// replace them with original values.

var Minio = require('minio')
import * as Minio from 'minio'

var s3Client = new Minio.Client({
endPoint: 's3.amazonaws.com',
accessKey: 'YOUR-ACCESSKEYID',
secretKey: 'YOUR-SECRETACCESSKEY',
})

s3Client.listBuckets(function (e, buckets) {
if (e) return console.log(e)
console.log('buckets :', buckets)
})
try {
const buckets = await s3Client.listBuckets()
console.log('Success', buckets)
} catch (err) {
console.log(err.message)
}
9 changes: 8 additions & 1 deletion src/internal/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { request } from './request.ts'
import { drainResponse, readAsString } from './response.ts'
import type { Region } from './s3-endpoints.ts'
import { getS3Endpoint } from './s3-endpoints.ts'
import type { Binary, IRequest, RequestHeaders, Transport } from './type.ts'
import type { Binary, BucketItemFromList, IRequest, RequestHeaders, Transport } from './type.ts'
import type { UploadedPart } from './xml-parser.ts'
import * as xmlParsers from './xml-parser.ts'

Expand Down Expand Up @@ -864,4 +864,11 @@ export class TypedClient {
const res = await this.makeRequestAsync({ method, bucketName, objectName, query })
return xmlParsers.parseListParts(await readAsString(res))
}

async listBuckets(): Promise<BucketItemFromList[]> {
const method = 'GET'
const httpRes = await this.makeRequestAsync({ method }, '', [200], DEFAULT_REGION)
const xmlResult = await readAsString(httpRes)
return xmlParsers.parseListBucket(xmlResult)
}
}
22 changes: 21 additions & 1 deletion src/internal/xml-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import type * as http from 'node:http'
import { XMLParser } from 'fast-xml-parser'

import * as errors from '../errors.ts'
import type { BucketItemWithMetadata } from '../minio'
import { parseXml, sanitizeETag, sanitizeObjectKey, toArray } from './helper.ts'
import { readAsString } from './response.ts'
import type { BucketItemFromList, BucketItemWithMetadata } from './type.ts'

// parse XML response for bucket region
export function parseBucketRegion(xml: string): string {
Expand Down Expand Up @@ -196,3 +196,23 @@ export function parseListParts(xml: string): {
}
return result
}

export function parseListBucket(xml: string) {
let result: BucketItemFromList[] = []
const parsedXmlRes = parseXml(xml)

if (!parsedXmlRes.ListAllMyBucketsResult) {
throw new errors.InvalidXMLError('Missing tag: "ListAllMyBucketsResult"')
}
const { ListAllMyBucketsResult: { Buckets = {} } = {} } = parsedXmlRes

if (Buckets.Bucket) {
result = toArray(Buckets.Bucket).map((bucket = {}) => {
const { Name: bucketName, CreationDate } = bucket
const creationDate = new Date(CreationDate)

return { name: bucketName, creationDate: creationDate }
})
}
return result
}
3 changes: 0 additions & 3 deletions src/minio.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,6 @@ export class Client extends TypedClient {
makeBucket(bucketName: string, callback: NoResultCallback): void
makeBucket(bucketName: string, region?: Region, makeOpts?: MakeBucketOpt): Promise<void>

listBuckets(callback: ResultCallback<BucketItemFromList[]>): void
listBuckets(): Promise<BucketItemFromList[]>

bucketExists(bucketName: string, callback: ResultCallback<boolean>): void
bucketExists(bucketName: string): Promise<boolean>

Expand Down
28 changes: 1 addition & 27 deletions src/minio.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,32 +209,6 @@ export class Client extends TypedClient {
this.makeRequest({ method, bucketName, headers }, payload, [200], region, false, processWithRetry)
}

// List of buckets created.
//
// __Arguments__
// * `callback(err, buckets)` _function_ - callback function with error as the first argument. `buckets` is an array of bucket information
//
// `buckets` array element:
// * `bucket.name` _string_ : bucket name
// * `bucket.creationDate` _Date_: date when bucket was created
listBuckets(cb) {
if (!isFunction(cb)) {
throw new TypeError('callback should be of type "function"')
}
var method = 'GET'
this.makeRequest({ method }, '', [200], DEFAULT_REGION, true, (e, response) => {
if (e) {
return cb(e)
}
var transformer = transformers.getListBucketTransformer()
var buckets
pipesetup(response, transformer)
.on('data', (result) => (buckets = result))
.on('error', (e) => cb(e))
.on('end', () => cb(null, buckets))
})
}

// Returns a stream that emits objects that are partially uploaded.
//
// __Arguments__
Expand Down Expand Up @@ -2860,7 +2834,6 @@ export class Client extends TypedClient {

// Promisify various public-facing APIs on the Client module.
Client.prototype.makeBucket = promisify(Client.prototype.makeBucket)
Client.prototype.listBuckets = promisify(Client.prototype.listBuckets)
Client.prototype.bucketExists = promisify(Client.prototype.bucketExists)
Client.prototype.removeBucket = promisify(Client.prototype.removeBucket)

Expand Down Expand Up @@ -2911,3 +2884,4 @@ Client.prototype.selectObjectContent = promisify(Client.prototype.selectObjectCo

// refactored API use promise internally
Client.prototype.removeObject = callbackify(Client.prototype.removeObject)
Client.prototype.listBuckets = callbackify(Client.prototype.listBuckets)
5 changes: 0 additions & 5 deletions src/transformers.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,6 @@ export function getCopyObjectTransformer() {
return getConcater(xmlParsers.parseCopyObject)
}

// Parses listBuckets response.
export function getListBucketTransformer() {
return getConcater(xmlParsers.parseListBucket)
}

// Parses listMultipartUploads response.
export function getListMultipartTransformer() {
return getConcater(xmlParsers.parseListMultipart)
Expand Down
20 changes: 0 additions & 20 deletions src/xml-parsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,26 +93,6 @@ export function parseListMultipart(xml) {
}

// parse XML response to list all the owned buckets
export function parseListBucket(xml) {
var result = []
var xmlobj = parseXml(xml)

if (!xmlobj.ListAllMyBucketsResult) {
throw new errors.InvalidXMLError('Missing tag: "ListAllMyBucketsResult"')
}
xmlobj = xmlobj.ListAllMyBucketsResult

if (xmlobj.Buckets) {
if (xmlobj.Buckets.Bucket) {
toArray(xmlobj.Buckets.Bucket).forEach((bucket) => {
var name = bucket.Name
var creationDate = new Date(bucket.CreationDate)
result.push({ name, creationDate })
})
}
}
return result
}

// parse XML response for bucket notification
export function parseBucketNotification(xml) {
Expand Down

0 comments on commit 6cf40a7

Please sign in to comment.