2023-10-03 11:14:36 +08:00
|
|
|
/* eslint-disable no-use-before-define */
|
|
|
|
const { checkBucketName: _checkBucketName } = require('../utils/checkBucketName');
|
|
|
|
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) {
|
|
|
|
_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 === 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) {
|
|
|
|
if (!rule.expiration.expiredObjectDeleteMarker) {
|
|
|
|
checkDaysAndDate(rule.expiration, 'Expiration');
|
|
|
|
} else if (rule.expiration.days || rule.expiration.createdBeforeDate) {
|
|
|
|
throw new Error('expiredObjectDeleteMarker cannot be used with days or createdBeforeDate');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rule.abortMultipartUpload) {
|
|
|
|
checkDaysAndDate(rule.abortMultipartUpload, 'AbortMultipartUpload');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!rule.expiration && !rule.abortMultipartUpload && !rule.transition && !rule.noncurrentVersionTransition) {
|
|
|
|
throw new Error(
|
|
|
|
'Rule must includes expiration or abortMultipartUpload or transition or noncurrentVersionTransition'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rule.tag) {
|
|
|
|
if (rule.abortMultipartUpload) {
|
|
|
|
throw new Error('Tag cannot be used with abortMultipartUpload');
|
|
|
|
}
|
|
|
|
handleCheckTag(rule.tag);
|
|
|
|
}
|
|
|
|
}
|