-
Notifications
You must be signed in to change notification settings - Fork 576
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support for the latest putBucketLifecycle api features (#757)
- Loading branch information
Showing
12 changed files
with
699 additions
and
186 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const proto = exports; | ||
|
||
proto.deleteBucketLifecycle = async function deleteBucketLifecycle(name, options) { | ||
this._checkBucketName(name); | ||
const params = this._bucketRequestParams('DELETE', name, 'lifecycle', options); | ||
params.successStatuses = [204]; | ||
const result = await this.request(params); | ||
return { | ||
res: result.res | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
const isArray = require('../utils/isArray'); | ||
const formatObjKey = require('../utils/formatObjKey'); | ||
|
||
const proto = exports; | ||
|
||
proto.getBucketLifecycle = async function getBucketLifecycle(name, options) { | ||
this._checkBucketName(name); | ||
const params = this._bucketRequestParams('GET', name, 'lifecycle', options); | ||
params.successStatuses = [200]; | ||
params.xmlResponse = true; | ||
const result = await this.request(params); | ||
let rules = result.data.Rule || null; | ||
if (rules) { | ||
if (!isArray(rules)) { | ||
rules = [rules]; | ||
} | ||
rules = rules.map((_) => { | ||
if (_.ID) { | ||
_.id = _.ID; | ||
delete _.ID; | ||
} | ||
if (_.Tag && !isArray(_.Tag)) { | ||
_.Tag = [_.Tag]; | ||
} | ||
return formatObjKey(_, 'firstLowerCase'); | ||
}); | ||
} | ||
return { | ||
rules, | ||
res: result.res | ||
}; | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
/* eslint-disable no-use-before-define */ | ||
|
||
const isArray = require('../utils/isArray'); | ||
const deepCopy = require('../utils/deepCopy'); | ||
const isObject = require('../utils/isObject'); | ||
const obj2xml = require('../utils/obj2xml'); | ||
const checkObjectTag = require('../utils/checkObjectTag'); | ||
const getStrBytesCount = require('../utils/getStrBytesCount'); | ||
|
||
const proto = exports; | ||
|
||
|
||
proto.putBucketLifecycle = async function putBucketLifecycle(name, rules, options) { | ||
this._checkBucketName(name); | ||
|
||
if (!isArray(rules)) { | ||
throw new Error('rules must be Array'); | ||
} | ||
|
||
const params = this._bucketRequestParams('PUT', name, 'lifecycle', options); | ||
const Rule = []; | ||
const paramXMLObj = { | ||
LifecycleConfiguration: { | ||
Rule | ||
} | ||
}; | ||
|
||
rules.forEach((_) => { | ||
defaultDaysAndDate2Expiration(_); // todo delete, 兼容旧版本 | ||
checkRule(_); | ||
if (_.id) { | ||
_.ID = _.id; | ||
delete _.id; | ||
} | ||
Rule.push(_); | ||
}); | ||
|
||
const paramXML = obj2xml(paramXMLObj, { | ||
headers: true, | ||
firstUpperCase: true | ||
}); | ||
|
||
params.content = paramXML; | ||
params.mime = 'xml'; | ||
params.successStatuses = [200]; | ||
const result = await this.request(params); | ||
return { | ||
res: result.res | ||
}; | ||
}; | ||
|
||
// todo delete, 兼容旧版本 | ||
function defaultDaysAndDate2Expiration(obj) { | ||
if (obj.days) { | ||
obj.expiration = { | ||
days: obj.days | ||
}; | ||
} | ||
if (obj.date) { | ||
obj.expiration = { | ||
createdBeforeDate: obj.date | ||
}; | ||
} | ||
} | ||
|
||
function checkDaysAndDate(obj, key) { | ||
const { days, createdBeforeDate } = obj; | ||
if (!days && !createdBeforeDate) { | ||
throw new Error(`${key} must includes days or createdBeforeDate`); | ||
} else if (days && !/^[1-9][0-9]*$/.test(days)) { | ||
throw new Error('days must be a positive integer'); | ||
} else if (createdBeforeDate && !/\d{4}-\d{2}-\d{2}T00:00:00.000Z/.test(createdBeforeDate)) { | ||
throw new Error('createdBeforeDate must be date and conform to iso8601 format'); | ||
} | ||
} | ||
|
||
function handleCheckTag(tag) { | ||
if (!isArray(tag) && !isObject(tag)) { | ||
throw new Error('tag must be Object or Array'); | ||
} | ||
tag = isObject(tag) ? [tag] : tag; | ||
const tagObj = {}; | ||
const tagClone = deepCopy(tag); | ||
tagClone.forEach((v) => { | ||
tagObj[v.key] = v.value; | ||
}); | ||
|
||
checkObjectTag(tagObj); | ||
} | ||
|
||
function checkRule(rule) { | ||
if (rule.id && getStrBytesCount(rule.id) > 255) throw new Error('ID is composed of 255 bytes at most'); | ||
|
||
if (rule.prefix === '' || rule.prefix === undefined) throw new Error('Rule must includes prefix'); | ||
|
||
if (!['Enabled', 'Disabled'].includes(rule.status)) throw new Error('Status must be Enabled or Disabled'); | ||
|
||
if (rule.transition) { | ||
if (!['IA', 'Archive'].includes(rule.transition.storageClass)) throw new Error('StorageClass must be IA or Archive'); | ||
checkDaysAndDate(rule.transition, 'Transition'); | ||
} | ||
|
||
if (rule.expiration) { | ||
checkDaysAndDate(rule.expiration, 'Expiration'); | ||
} | ||
|
||
if (rule.abortMultipartUpload) { | ||
checkDaysAndDate(rule.abortMultipartUpload, 'AbortMultipartUpload'); | ||
} | ||
|
||
if (!rule.expiration && !rule.abortMultipartUpload && !rule.transition) { | ||
throw new Error('Rule must includes expiration or abortMultipartUpload or transition'); | ||
} | ||
|
||
if (rule.tag) { | ||
if (rule.abortMultipartUpload) { | ||
throw new Error('Tag cannot be used with abortMultipartUpload'); | ||
} | ||
handleCheckTag(rule.tag); | ||
} | ||
} | ||
|
Oops, something went wrong.