diff --git a/docs/API.md b/docs/API.md
index 4dfc5cb4..ad428e49 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -1403,18 +1403,17 @@ minioClient.removeIncompleteUpload('mybucket', 'photo.jpg', function (err) {
-### putObjectRetention(bucketName, objectName [, retentionOpts] [, callback])
+### async putObjectRetention(bucketName, objectName [, retentionOpts])
Apply retention on an object.
**Parameters**
-| Param | Type | Description |
-| --------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `bucketName` | _string_ | Name of the bucket. |
-| `objectName` | _string_ | Name of the object. |
-| `retentionOpts` | _object_ | Options for retention like : `{ governanceBypass:true/false ,mode:COMPLIANCE/GOVERNANCE, retainUntilDate: _date_ , versionId:"my-versionId" }` Default is `{}` (Optional) |
-| `callback(err)` | _function_ | Callback function is called with non `null` value in case of error. If no callback is passed, a `Promise` is returned. |
+| Param | Type | Description |
+| --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `bucketName` | _string_ | Name of the bucket. |
+| `objectName` | _string_ | Name of the object. |
+| `retentionOpts` | _object_ | Options for retention like : `{ governanceBypass:true/false ,mode:COMPLIANCE/GOVERNANCE, retainUntilDate: _date_ , versionId:"my-versionId" }` Default is `{}` (Optional) |
**Example**
Apply object retention on an object
@@ -1428,17 +1427,11 @@ expirationDate.setDate(expirationDate.getDate() + 1)
expirationDate.setUTCHours(0, 0, 0, 0) //Should be start of the day.(midnight)
const versionId = 'e67b4b08-144d-4fc4-ba15-43c3f7f9ba74'
-const objRetPromise = minioClient.putObjectRetention(
- bucketName,
- objectName,
- { Mode: 'GOVERNANCE', retainUntilDate: retainUntilDate.toISOString(), versionId: versionId },
- function (err) {
- if (err) {
- return console.log(err)
- }
- console.log('Success')
- },
-)
+await minioClient.putObjectRetention(bucketName, objectName, {
+ Mode: 'GOVERNANCE',
+ retainUntilDate: retainUntilDate.toISOString(),
+ versionId: versionId,
+})
```
diff --git a/examples/put-object-retention.js b/examples/put-object-retention.js
index 55f6d920..d57b958f 100644
--- a/examples/put-object-retention.js
+++ b/examples/put-object-retention.js
@@ -17,9 +17,9 @@
// 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',
@@ -33,15 +33,8 @@ expirationDate.setDate(expirationDate.getDate() + 1)
expirationDate.setUTCHours(0, 0, 0, 0) //Should be start of the day.(midnight)
const versionId = 'my-versionId'
-const objRetPromise = s3Client.putObjectRetention(bucketName, objectName, {
+await s3Client.putObjectRetention(bucketName, objectName, {
mode: 'GOVERNANCE',
retainUntilDate: expirationDate.toISOString(),
versionId: versionId,
})
-objRetPromise
- .then(() => {
- console.log('Success')
- })
- .catch((e) => {
- console.log(' Error', e)
- })
diff --git a/src/internal/client.ts b/src/internal/client.ts
index cf6237d4..c0d6d1e8 100644
--- a/src/internal/client.ts
+++ b/src/internal/client.ts
@@ -54,6 +54,7 @@ import type {
RequestHeaders,
ResponseHeader,
ResultCallback,
+ Retention,
StatObjectOpts,
Tag,
Transport,
@@ -1169,6 +1170,59 @@ export class TypedClient {
return xmlParsers.parseTagging(body)
}
+ async putObjectRetention(bucketName: string, objectName: string, retentionOpts: Retention = {}): Promise {
+ if (!isValidBucketName(bucketName)) {
+ throw new errors.InvalidBucketNameError(`Invalid bucket name: ${bucketName}`)
+ }
+ if (!isValidObjectName(objectName)) {
+ throw new errors.InvalidObjectNameError(`Invalid object name: ${objectName}`)
+ }
+ if (!isObject(retentionOpts)) {
+ throw new errors.InvalidArgumentError('retentionOpts should be of type "object"')
+ } else {
+ if (retentionOpts.governanceBypass && !isBoolean(retentionOpts.governanceBypass)) {
+ throw new errors.InvalidArgumentError(`Invalid value for governanceBypass: ${retentionOpts.governanceBypass}`)
+ }
+ if (
+ retentionOpts.mode &&
+ ![RETENTION_MODES.COMPLIANCE, RETENTION_MODES.GOVERNANCE].includes(retentionOpts.mode)
+ ) {
+ throw new errors.InvalidArgumentError(`Invalid object retention mode: ${retentionOpts.mode}`)
+ }
+ if (retentionOpts.retainUntilDate && !isString(retentionOpts.retainUntilDate)) {
+ throw new errors.InvalidArgumentError(`Invalid value for retainUntilDate: ${retentionOpts.retainUntilDate}`)
+ }
+ if (retentionOpts.versionId && !isString(retentionOpts.versionId)) {
+ throw new errors.InvalidArgumentError(`Invalid value for versionId: ${retentionOpts.versionId}`)
+ }
+ }
+
+ const method = 'PUT'
+ let query = 'retention'
+
+ const headers: RequestHeaders = {}
+ if (retentionOpts.governanceBypass) {
+ headers['X-Amz-Bypass-Governance-Retention'] = true
+ }
+
+ const builder = new xml2js.Builder({ rootName: 'Retention', renderOpts: { pretty: false }, headless: true })
+ const params: Record = {}
+
+ if (retentionOpts.mode) {
+ params.Mode = retentionOpts.mode
+ }
+ if (retentionOpts.retainUntilDate) {
+ params.RetainUntilDate = retentionOpts.retainUntilDate
+ }
+ if (retentionOpts.versionId) {
+ query += `&versionId=${retentionOpts.versionId}`
+ }
+
+ const payload = builder.buildObject(params)
+
+ headers['Content-MD5'] = toMd5(payload)
+ await this.makeRequestAsyncOmit({ method, bucketName, objectName, query, headers }, payload, [200, 204])
+ }
getObjectLockConfig(bucketName: string, callback: ResultCallback): void
getObjectLockConfig(bucketName: string): void
async getObjectLockConfig(bucketName: string): Promise
diff --git a/src/internal/type.ts b/src/internal/type.ts
index 55b3cfb9..b7e28b29 100644
--- a/src/internal/type.ts
+++ b/src/internal/type.ts
@@ -209,7 +209,14 @@ export type PutObjectLegalHoldOptions = {
versionId?: string
status: LEGAL_HOLD_STATUS
}
-
+export interface RetentionOptions {
+ versionId: string
+ mode?: RETENTION_MODES
+ retainUntilDate?: IsoDate
+ governanceBypass?: boolean
+}
+export type Retention = RetentionOptions | EmptyObject
+export type IsoDate = string
export type EmptyObject = Record
export type ObjectLockInfo =
diff --git a/src/minio.d.ts b/src/minio.d.ts
index 6d5c4ab7..8d715c79 100644
--- a/src/minio.d.ts
+++ b/src/minio.d.ts
@@ -23,9 +23,11 @@ import type {
BucketItemStat,
BucketItemWithMetadata,
BucketStream,
+ EmptyObject,
ExistingObjectReplication,
GetObjectLegalHoldOptions,
IncompleteUploadedBucketItem,
+ IsoDate,
ItemBucketMetadata,
ItemBucketMetadataList,
MetadataItem,
@@ -40,8 +42,11 @@ import type {
ReplicationRuleFilter,
ReplicationRuleStatus,
ResultCallback,
+ Retention,
+ RetentionOptions,
SourceSelectionCriteria,
Tag,
+ VersionIdentificator,
} from './internal/type.ts'
export * from './helpers.ts'
@@ -55,9 +60,11 @@ export type {
BucketItemWithMetadata,
BucketStream,
ClientOptions,
+ EmptyObject,
ExistingObjectReplication,
GetObjectLegalHoldOptions,
IncompleteUploadedBucketItem,
+ IsoDate,
ItemBucketMetadata,
ItemBucketMetadataList,
MetadataItem,
@@ -73,6 +80,8 @@ export type {
ReplicationRuleDestination,
ReplicationRuleFilter,
ReplicationRuleStatus,
+ Retention,
+ RetentionOptions,
SourceSelectionCriteria,
Tag,
}
@@ -113,13 +122,8 @@ export type LockUnit = RETENTION_VALIDITY_UNITS
export type LegalHoldStatus = LEGAL_HOLD_STATUS
export type VersioningConfig = Record
export type TagList = Record
-export type EmptyObject = Record
-export type VersionIdentificator = Pick
export type Lifecycle = LifecycleConfig | null | ''
export type Encryption = EncryptionConfig | EmptyObject
-export type Retention = RetentionOptions | EmptyObject
-export type IsoDate = string
-
export interface PostPolicyResult {
postURL: string
formData: {
@@ -154,13 +158,6 @@ export interface EncryptionRule {
[key: string]: any
}
-export interface RetentionOptions {
- versionId: string
- mode?: RETENTION_MODES
- retainUntilDate?: IsoDate
- governanceBypass?: boolean
-}
-
export interface LegalHoldOptions {
versionId: string
status: LEGAL_HOLD_STATUS
@@ -370,15 +367,6 @@ export class Client extends TypedClient {
removeIncompleteUpload(bucketName: string, objectName: string, callback: NoResultCallback): void
removeIncompleteUpload(bucketName: string, objectName: string): Promise
- putObjectRetention(bucketName: string, objectName: string, callback: NoResultCallback): void
- putObjectRetention(
- bucketName: string,
- objectName: string,
- retentionOptions: Retention,
- callback: NoResultCallback,
- ): void
- putObjectRetention(bucketName: string, objectName: string, retentionOptions?: Retention): Promise
-
getObjectRetention(
bucketName: string,
objectName: string,
diff --git a/src/minio.js b/src/minio.js
index 98d2651c..f9587dbb 100644
--- a/src/minio.js
+++ b/src/minio.js
@@ -60,7 +60,6 @@ import {
uriResourceEscape,
} from './internal/helper.ts'
import { PostPolicy } from './internal/post-policy.ts'
-import { RETENTION_MODES } from './internal/type.ts'
import { NotificationConfig, NotificationPoller } from './notification.js'
import { ObjectUploader } from './object-uploader.js'
import { promisify } from './promisify.js'
@@ -1898,63 +1897,6 @@ export class Client extends TypedClient {
})
}
- putObjectRetention(bucketName, objectName, retentionOpts = {}, cb) {
- if (!isValidBucketName(bucketName)) {
- throw new errors.InvalidBucketNameError('Invalid bucket name: ' + bucketName)
- }
- if (!isValidObjectName(objectName)) {
- throw new errors.InvalidObjectNameError(`Invalid object name: ${objectName}`)
- }
- if (!isObject(retentionOpts)) {
- throw new errors.InvalidArgumentError('retentionOpts should be of type "object"')
- } else {
- if (retentionOpts.governanceBypass && !isBoolean(retentionOpts.governanceBypass)) {
- throw new errors.InvalidArgumentError('Invalid value for governanceBypass', retentionOpts.governanceBypass)
- }
- if (
- retentionOpts.mode &&
- ![RETENTION_MODES.COMPLIANCE, RETENTION_MODES.GOVERNANCE].includes(retentionOpts.mode)
- ) {
- throw new errors.InvalidArgumentError('Invalid object retention mode ', retentionOpts.mode)
- }
- if (retentionOpts.retainUntilDate && !isString(retentionOpts.retainUntilDate)) {
- throw new errors.InvalidArgumentError('Invalid value for retainUntilDate', retentionOpts.retainUntilDate)
- }
- if (retentionOpts.versionId && !isString(retentionOpts.versionId)) {
- throw new errors.InvalidArgumentError('Invalid value for versionId', retentionOpts.versionId)
- }
- }
- if (!isFunction(cb)) {
- throw new TypeError('callback should be of type "function"')
- }
-
- const method = 'PUT'
- let query = 'retention'
-
- const headers = {}
- if (retentionOpts.governanceBypass) {
- headers['X-Amz-Bypass-Governance-Retention'] = true
- }
-
- const builder = new xml2js.Builder({ rootName: 'Retention', renderOpts: { pretty: false }, headless: true })
- const params = {}
-
- if (retentionOpts.mode) {
- params.Mode = retentionOpts.mode
- }
- if (retentionOpts.retainUntilDate) {
- params.RetainUntilDate = retentionOpts.retainUntilDate
- }
- if (retentionOpts.versionId) {
- query += `&versionId=${retentionOpts.versionId}`
- }
-
- let payload = builder.buildObject(params)
-
- headers['Content-MD5'] = toMd5(payload)
- this.makeRequest({ method, bucketName, objectName, query, headers }, payload, [200, 204], '', false, cb)
- }
-
getObjectRetention(bucketName, objectName, getOpts, cb) {
if (!isValidBucketName(bucketName)) {
throw new errors.InvalidBucketNameError('Invalid bucket name: ' + bucketName)
@@ -2410,7 +2352,6 @@ Client.prototype.removeObjectTagging = promisify(Client.prototype.removeObjectTa
Client.prototype.setBucketLifecycle = promisify(Client.prototype.setBucketLifecycle)
Client.prototype.getBucketLifecycle = promisify(Client.prototype.getBucketLifecycle)
Client.prototype.removeBucketLifecycle = promisify(Client.prototype.removeBucketLifecycle)
-Client.prototype.putObjectRetention = promisify(Client.prototype.putObjectRetention)
Client.prototype.getObjectRetention = promisify(Client.prototype.getObjectRetention)
Client.prototype.setBucketEncryption = promisify(Client.prototype.setBucketEncryption)
Client.prototype.getBucketEncryption = promisify(Client.prototype.getBucketEncryption)
@@ -2430,5 +2371,6 @@ Client.prototype.getObjectLegalHold = callbackify(Client.prototype.getObjectLega
Client.prototype.setObjectLegalHold = callbackify(Client.prototype.setObjectLegalHold)
Client.prototype.getBucketTagging = callbackify(Client.prototype.getBucketTagging)
Client.prototype.getObjectTagging = callbackify(Client.prototype.getObjectTagging)
+Client.prototype.putObjectRetention = callbackify(Client.prototype.putObjectRetention)
Client.prototype.setObjectLockConfig = callbackify(Client.prototype.setObjectLockConfig)
Client.prototype.getObjectLockConfig = callbackify(Client.prototype.getObjectLockConfig)
diff --git a/tests/unit/test.js b/tests/unit/test.js
index 14135d9b..5b876ce1 100644
--- a/tests/unit/test.js
+++ b/tests/unit/test.js
@@ -1187,61 +1187,77 @@ describe('Client', function () {
describe('putObjectRetention(bucket, objectName, retentionConfig, callback)', () => {
it('should fail on null bucket', (done) => {
- try {
- client.putObjectRetention(null, '', {}, function () {})
- } catch (e) {
- done()
- }
+ client.putObjectRetention(null, '', {}, function (err) {
+ if (err) {
+ done()
+ } else {
+ done(new Error('expecting error'))
+ }
+ })
})
it('should fail on empty bucket', (done) => {
- try {
- client.putObjectRetention('', '', {}, function () {})
- } catch (e) {
- done()
- }
+ client.putObjectRetention('', '', {}, function (err) {
+ if (err) {
+ done()
+ } else {
+ done(new Error('expecting error'))
+ }
+ })
})
it('should fail on null object', (done) => {
- try {
- client.putObjectRetention('my-bucket', null, {}, function () {})
- } catch (e) {
- done()
- }
+ client.putObjectRetention('my-bucket', null, {}, function (err) {
+ if (err) {
+ done()
+ } else {
+ done(new Error('expecting error'))
+ }
+ })
})
it('should fail on empty object', (done) => {
- try {
- client.putObjectRetention('my-bucket', '', {}, function () {})
- } catch (e) {
- done()
- }
+ client.putObjectRetention('my-bucket', '', {}, function (err) {
+ if (err) {
+ done()
+ } else {
+ done(new Error('expecting error'))
+ }
+ })
})
it('should fail on passing invalid mode ', (done) => {
- try {
- client.putObjectRetention('my-bucket', 'my-object', { mode: 'invalid_mode' }, function () {})
- } catch (e) {
- done()
- }
+ client.putObjectRetention('my-bucket', 'my-object', { mode: 'invalid_mode' }, function (err) {
+ if (err) {
+ done()
+ } else {
+ done(new Error('expecting error'))
+ }
+ })
})
it('should fail on passing invalid governanceBypass ', (done) => {
- try {
- client.putObjectRetention('my-bucket', 'my-object', { governanceBypass: 'nonbool' }, function () {})
- } catch (e) {
- done()
- }
+ client.putObjectRetention('my-bucket', 'my-object', { governanceBypass: 'nonbool' }, function (err) {
+ if (err) {
+ done()
+ } else {
+ done(new Error('expecting error'))
+ }
+ })
})
it('should fail on passing invalid (null) retainUntilDate ', (done) => {
- try {
- client.putObjectRetention('my-bucket', 'my-object', { retainUntilDate: 12345 }, function () {})
- } catch (e) {
- done()
- }
+ client.putObjectRetention('my-bucket', 'my-object', { retainUntilDate: 12345 }, function (err) {
+ if (err) {
+ done()
+ } else {
+ done(new Error('expecting error'))
+ }
+ })
})
it('should fail on passing invalid versionId ', (done) => {
- try {
- client.putObjectRetention('my-bucket', { versionId: 'COMPLIANCE' }, function () {})
- } catch (e) {
- done()
- }
+ client.putObjectRetention('my-bucket', { versionId: 'COMPLIANCE' }, function (err) {
+ if (err) {
+ done()
+ } else {
+ done(new Error('expecting error'))
+ }
+ })
})
})
})