Skip to content

Commit

Permalink
refactor getBucketTagging, getObjectTagging to TypeScript (#1211)
Browse files Browse the repository at this point in the history
  • Loading branch information
trim21 authored Oct 23, 2023
1 parent 4f51755 commit a572dca
Show file tree
Hide file tree
Showing 12 changed files with 121 additions and 185 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ The full API Reference is available here.
- [get-bucket-versioning.js](https://github.com/minio/minio-js/blob/master/examples/get-bucket-versioning.js)
- [set-bucket-versioning.js](https://github.com/minio/minio-js/blob/master/examples/set-bucket-versioning.js)
- [set-bucket-tagging.js](https://github.com/minio/minio-js/blob/master/examples/set-bucket-tagging.js)
- [get-bucket-tagging.js](https://github.com/minio/minio-js/blob/master/examples/get-bucket-tagging.js)
- [get-bucket-tagging.mjs](https://github.com/minio/minio-js/blob/master/examples/get-bucket-tagging.mjs)
- [remove-bucket-tagging.js](https://github.com/minio/minio-js/blob/master/examples/remove-bucket-tagging.js)
- [set-bucket-lifecycle.js](https://github.com/minio/minio-js/blob/master/examples/set-bucket-lifecycle.js)
- [get-bucket-lifecycle.js](https://github.com/minio/minio-js/blob/master/examples/get-bucket-lifecycle.js)
Expand Down Expand Up @@ -205,7 +205,7 @@ The full API Reference is available here.
- [get-object-retention.js](https://github.com/minio/minio-js/blob/master/examples/get-object-retention.js)
- [put-object-retention.js](https://github.com/minio/minio-js/blob/master/examples/put-object-retention.js)
- [put-object-tagging.js](https://github.com/minio/minio-js/blob/master/examples/put-object-tagging.js)
- [get-object-tagging.js](https://github.com/minio/minio-js/blob/master/examples/get-object-tagging.js)
- [get-object-tagging.mjs](https://github.com/minio/minio-js/blob/master/examples/get-object-tagging.mjs)
- [remove-object-tagging.js](https://github.com/minio/minio-js/blob/master/examples/remove-object-tagging.js)
- [set-object-legal-hold.js](https://github.com/minio/minio-js/blob/master/examples/set-object-legalhold.mjs)
- [get-object-legal-hold.js](https://github.com/minio/minio-js/blob/master/examples/get-object-legal-hold.mjs)
Expand Down
33 changes: 9 additions & 24 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -1563,45 +1563,30 @@ minioClient.removeObjectTagging('bucketname', 'object-name', { versionId: 'my-ob

<a name="getObjectTagging"></a>

### getObjectTagging(bucketName, objectName[, getOpts, callback])
### getObjectTagging(bucketName, objectName[, getOpts])

Get Tags of an Object

**Parameters**

| Param | Type | Description |
| --------------- | ---------- | ------------------------------------------------------------- |
| `bucketName` | _string_ | Name of the bucket. |
| `objectName` | _string_ | Name of the object. |
| `getOpts` | _object_ | Defaults to {}. e.g `{versionId:"my-version-id"}`. (Optional) |
| `callback(err)` | _function_ | Callback is called with `err` in case of error. |
| Param | Type | Description |
| ------------ | -------- | ------------------------------------------------------------- |
| `bucketName` | _string_ | Name of the bucket. |
| `objectName` | _string_ | Name of the object. |
| `getOpts` | _object_ | Defaults to {}. e.g `{versionId:"my-version-id"}`. (Optional) |

**Example**

```js
minioClient.getObjectTagging('bucketname', 'object-name', function (err, tagsList) {
if (err) {
return console.log(err)
}
console.log('Success', tagsList)
})
const tagsList = await minioClient.getObjectTagging('bucketname', 'object-name')
console.log('Success', tagsList)
```

**Example1**
Get tags on a version of an object.

```js
minioClient.getObjectTagging(
'bucketname',
'object-name',
{ versionId: 'my-object-version-id' },
function (err, tagsList) {
if (err) {
return console.log(err)
}
console.log('Success', tagsList)
},
)
const tagsList = await minioClient.getObjectTagging('bucketname', 'object-name', { versionId: 'my-object-version-id' })
```

<a name="getObjectLegalHold"></a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,13 @@
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
// dummy values, please replace them with original values.

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

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

s3Client.getBucketTagging('bucketname', function (err, tagsList) {
if (err) {
return console.log(err)
}
console.log('Success', tagsList)
})
const tagsList = await s3Client.getBucketTagging('bucketname')
console.log('Success', tagsList)
19 changes: 4 additions & 15 deletions examples/get-object-tagging.js → examples/get-object-tagging.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,15 @@
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
// dummy values, please replace them with original values.

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

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

s3Client.getObjectTagging('bucketname', 'objectName', function (err, tagsList) {
if (err) {
return console.log(err)
}
console.log('Success', tagsList)
})
console.log(await s3Client.getObjectTagging('bucketname', 'objectName'))

//Get tags on a version of an object.

s3Client.getObjectTagging('bucketname', 'objectName', { versionId: '' }, function (err, tagsList) {
if (err) {
return console.log(err)
}
console.log('Success', tagsList)
})
console.log(await s3Client.getObjectTagging('bucketname', 'objectName', { versionId: '' }))
49 changes: 49 additions & 0 deletions src/internal/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ import type {
ResponseHeader,
ResultCallback,
StatObjectOpts,
Tag,
Transport,
VersionIdentificator,
} from './type.ts'
import type { UploadedPart } from './xml-parser.ts'
import * as xmlParsers from './xml-parser.ts'
Expand Down Expand Up @@ -1117,4 +1119,51 @@ export class TypedClient {

await this.makeRequestAsyncOmit({ method, bucketName, objectName, query, headers }, payload)
}

/**
* Get Tags associated with a Bucket
*/
async getBucketTagging(bucketName: string): Promise<Tag[]> {
if (!isValidBucketName(bucketName)) {
throw new errors.InvalidBucketNameError(`Invalid bucket name: ${bucketName}`)
}

const method = 'GET'
const query = 'tagging'
const requestOptions = { method, bucketName, query }

const response = await this.makeRequestAsync(requestOptions)
const body = await readAsString(response)
return xmlParsers.parseTagging(body)
}

/**
* Get the tags associated with a bucket OR an object
*/
async getObjectTagging(bucketName: string, objectName: string, getOpts: VersionIdentificator = {}): Promise<Tag[]> {
const method = 'GET'
let query = 'tagging'

if (!isValidBucketName(bucketName)) {
throw new errors.InvalidBucketNameError('Invalid bucket name: ' + bucketName)
}
if (!isValidObjectName(objectName)) {
throw new errors.InvalidBucketNameError('Invalid object name: ' + objectName)
}
if (!isObject(getOpts)) {
throw new errors.InvalidArgumentError('getOpts should be of type "object"')
}

if (getOpts && getOpts.versionId) {
query = `${query}&versionId=${getOpts.versionId}`
}
const requestOptions: RequestOption = { method, bucketName, query }
if (objectName) {
requestOptions['objectName'] = objectName
}

const response = await this.makeRequestAsync(requestOptions)
const body = await readAsString(response)
return xmlParsers.parseTagging(body)
}
}
4 changes: 4 additions & 0 deletions src/internal/type.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import type * as http from 'node:http'
import type { Readable as ReadableStream } from 'node:stream'

export type VersionIdentificator = {
versionId?: string
}

export type Binary = string | Buffer

// nodejs IncomingHttpHeaders is Record<string, string | string[]>, but it's actually this:
Expand Down
17 changes: 16 additions & 1 deletion src/internal/xml-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type * as http from 'node:http'
import { XMLParser } from 'fast-xml-parser'

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

Expand Down Expand Up @@ -246,3 +246,18 @@ export function parseObjectLegalHoldConfig(xml: string) {
const xmlObj = parseXml(xml)
return xmlObj.LegalHold
}

export function parseTagging(xml: string) {
const xmlObj = parseXml(xml)
let result = []
if (xmlObj.Tagging && xmlObj.Tagging.TagSet && xmlObj.Tagging.TagSet.Tag) {
const tagResult = xmlObj.Tagging.TagSet.Tag
// if it is a single tag convert into an array so that the return value is always an array.
if (isObject(tagResult)) {
result.push(tagResult)
} else {
result = tagResult
}
}
return result
}
15 changes: 2 additions & 13 deletions src/minio.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import type {
ResultCallback,
SourceSelectionCriteria,
Tag,
VersionIdentificator,
} from './internal/type.ts'

export * from './helpers.ts'
Expand Down Expand Up @@ -75,6 +76,7 @@ export type {
ReplicationRuleStatus,
SourceSelectionCriteria,
Tag,
VersionIdentificator,
}

// Exports only from typings
Expand Down Expand Up @@ -110,7 +112,6 @@ export type LockUnit = RETENTION_VALIDITY_UNITS
export type VersioningConfig = Record<string | number | symbol, unknown>
export type TagList = Record<string, string>
export type EmptyObject = Record<string, never>
export type VersionIdentificator = Pick<RetentionOptions, 'versionId'>
export type Lifecycle = LifecycleConfig | null | ''
export type Lock = LockConfig | EmptyObject
export type Encryption = EncryptionConfig | EmptyObject
Expand Down Expand Up @@ -252,9 +253,6 @@ export class Client extends TypedClient {
setBucketVersioning(bucketName: string, versioningConfig: any, callback: NoResultCallback): void
setBucketVersioning(bucketName: string, versioningConfig: any): Promise<void>

getBucketTagging(bucketName: string, callback: ResultCallback<Tag[]>): void
getBucketTagging(bucketName: string): Promise<Tag[]>

setBucketTagging(bucketName: string, tags: TagList, callback: NoResultCallback): void
setBucketTagging(bucketName: string, tags: TagList): Promise<void>

Expand Down Expand Up @@ -418,15 +416,6 @@ export class Client extends TypedClient {
): void
removeObjectTagging(bucketName: string, objectName: string, removeOptions?: VersionIdentificator): Promise<void>

getObjectTagging(bucketName: string, objectName: string, callback: ResultCallback<Tag[]>): void
getObjectTagging(
bucketName: string,
objectName: string,
getOptions: VersionIdentificator,
callback: ResultCallback<Tag[]>,
): void
getObjectTagging(bucketName: string, objectName: string, getOptions?: VersionIdentificator): Promise<Tag[]>

composeObject(
destObjConfig: CopyDestinationOptions,
sourceObjList: CopySourceOptions[],
Expand Down
79 changes: 2 additions & 77 deletions src/minio.js
Original file line number Diff line number Diff line change
Expand Up @@ -1819,81 +1819,6 @@ export class Client extends TypedClient {
return this.removeTagging({ bucketName, objectName, removeOpts, cb })
}

/** Get Tags associated with a Bucket
* __Arguments__
* bucketName _string_
* `cb(error, tags)` _function_ - callback function with `err` as the error argument. `err` is null if the operation is successful.
*/
getBucketTagging(bucketName, cb) {
if (!isValidBucketName(bucketName)) {
throw new errors.InvalidBucketNameError(`Invalid bucket name: ${bucketName}`)
}

const method = 'GET'
const query = 'tagging'
const requestOptions = { method, bucketName, query }

this.makeRequest(requestOptions, '', [200], '', true, (e, response) => {
var transformer = transformers.getTagsTransformer()
if (e) {
return cb(e)
}
let tagsList
pipesetup(response, transformer)
.on('data', (result) => (tagsList = result))
.on('error', (e) => cb(e))
.on('end', () => cb(null, tagsList))
})
}

/** Get the tags associated with a bucket OR an object
* bucketName _string_
* objectName _string_ (Optional)
* getOpts _object_ (Optional) e.g {versionId:"my-object-version-id"}
* `cb(error, tags)` _function_ - callback function with `err` as the error argument. `err` is null if the operation is successful.
*/
getObjectTagging(bucketName, objectName, getOpts = {}, cb = () => false) {
const method = 'GET'
let query = 'tagging'

if (!isValidBucketName(bucketName)) {
throw new errors.InvalidBucketNameError('Invalid bucket name: ' + bucketName)
}
if (!isValidObjectName(objectName)) {
throw new errors.InvalidBucketNameError('Invalid object name: ' + objectName)
}
if (isFunction(getOpts)) {
cb = getOpts
getOpts = {}
}
if (!isObject(getOpts)) {
throw new errors.InvalidArgumentError('getOpts should be of type "object"')
}
if (!isFunction(cb)) {
throw new TypeError('callback should be of type "function"')
}

if (getOpts && getOpts.versionId) {
query = `${query}&versionId=${getOpts.versionId}`
}
const requestOptions = { method, bucketName, query }
if (objectName) {
requestOptions['objectName'] = objectName
}

this.makeRequest(requestOptions, '', [200], '', true, (e, response) => {
const transformer = transformers.getTagsTransformer()
if (e) {
return cb(e)
}
let tagsList
pipesetup(response, transformer)
.on('data', (result) => (tagsList = result))
.on('error', (e) => cb(e))
.on('end', () => cb(null, tagsList))
})
}

/**
* Apply lifecycle configuration on a bucket.
* bucketName _string_
Expand Down Expand Up @@ -2566,10 +2491,8 @@ Client.prototype.getBucketVersioning = promisify(Client.prototype.getBucketVersi
Client.prototype.setBucketVersioning = promisify(Client.prototype.setBucketVersioning)
Client.prototype.setBucketTagging = promisify(Client.prototype.setBucketTagging)
Client.prototype.removeBucketTagging = promisify(Client.prototype.removeBucketTagging)
Client.prototype.getBucketTagging = promisify(Client.prototype.getBucketTagging)
Client.prototype.setObjectTagging = promisify(Client.prototype.setObjectTagging)
Client.prototype.removeObjectTagging = promisify(Client.prototype.removeObjectTagging)
Client.prototype.getObjectTagging = promisify(Client.prototype.getObjectTagging)
Client.prototype.setBucketLifecycle = promisify(Client.prototype.setBucketLifecycle)
Client.prototype.getBucketLifecycle = promisify(Client.prototype.getBucketLifecycle)
Client.prototype.removeBucketLifecycle = promisify(Client.prototype.removeBucketLifecycle)
Expand All @@ -2593,3 +2516,5 @@ Client.prototype.setBucketReplication = callbackify(Client.prototype.setBucketRe
Client.prototype.getBucketReplication = callbackify(Client.prototype.getBucketReplication)
Client.prototype.getObjectLegalHold = callbackify(Client.prototype.getObjectLegalHold)
Client.prototype.setObjectLegalHold = callbackify(Client.prototype.setObjectLegalHold)
Client.prototype.getBucketTagging = callbackify(Client.prototype.getBucketTagging)
Client.prototype.getObjectTagging = callbackify(Client.prototype.getObjectTagging)
4 changes: 0 additions & 4 deletions src/transformers.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,6 @@ export function bucketVersioningTransformer() {
return getConcater(xmlParsers.parseBucketVersioningConfig)
}

export function getTagsTransformer() {
return getConcater(xmlParsers.parseTagging)
}

export function lifecycleTransformer() {
return getConcater(xmlParsers.parseLifecycleConfig)
}
Expand Down
Loading

0 comments on commit a572dca

Please sign in to comment.