const _ = require("../tools/lodash");
const request = require('../tools/request');
/**
* Define and access to all metas of objects
*
* __Available methods :__ *create()*, *create_with_result()*, *update()*, *update_with_result()*, *delete()*, *delete_with_result()*, *all()*, *has()*, *get()*
*/
class ObjectsMeta {
/**
* Objects Meta constructor
*
* @param {OVHStorage} context OVHObjectStorage context
*/
constructor(context) {
this.context = context;
}
/**
* Create a new object meta
*
* @param {String} path Path of file with container
* @param {String} key Name of meta
* @param {String} value Value of meta
*
* @async
* @return {Promise<Object>}
*/
create(path, key, value) {
return new Promise((resolve, reject) => {
try {
// checks
if (_.isUndefined(path)) // noinspection ExceptionCaughtLocallyJS
throw new Error("File path parameter is expected.");
if (!_.isString(path)) // noinspection ExceptionCaughtLocallyJS
throw new Error("File path parameter is not a string.");
if (!_.includes(path, '/')) // noinspection ExceptionCaughtLocallyJS
throw new Error("File path parameter isn't valid : container/filename.ext.");
if (_.isUndefined(key)) // noinspection ExceptionCaughtLocallyJS
throw new Error("Key parameter is expected.");
if (!_.isString(key)) // noinspection ExceptionCaughtLocallyJS
throw new Error("Key parameter is not a string.");
if (_.includes(key, "/") || _.includes(key, ' ')) // noinspection ExceptionCaughtLocallyJS
throw new Error("Key parameter contains special chars.");
if (_.isUndefined(value)) // noinspection ExceptionCaughtLocallyJS
throw new Error("Value parameter is expected.");
if (!_.isString(value)) // noinspection ExceptionCaughtLocallyJS
throw new Error("Value parameter is not a string.");
// header
let header = {};
header["X-Object-Meta-" + _.toSlug(_.replace(_.toLower(key), /_/g, '-'))] = value;
// reformat path
let file = (() => {
let p = path.split('/');
if (p[0] === "")
delete p[0];
p = _.filter(p, (r) => {
return !_.isUndefined(r);
});
return p.join("/");
})();
// call
request({
method: 'POST',
uri: encodeURI(this.context.endpoint.url + '/' + file),
headers: Object.assign(
{
"X-Auth-Token": this.context.token,
"Accept": "application/json"
},
header)
}, (err, res, body) => {
err = err || request.checkIfResponseIsError(res);
if (err) // noinspection ExceptionCaughtLocallyJS
throw new Error(err);
return resolve(res.headers);
});
} catch (e) {
return reject(e);
}
});
}
/**
* Create a new object meta and return boolean as result
*
* @param {String} path Path of file with container
* @param {String} key Name of meta
* @param {String} value Value of meta
*
* @async
* @return {Promise<Boolean>}
*/
async create_with_result(path, key, value) {
try {
await this.context.objects().metas().create(path, key, value);
return true;
} catch (e) {
return false;
}
}
/**
* Update existing object meta
*
* @param {String} path Path of file with container
* @param {String} key Name of meta
* @param {String} value Value of meta
*
* @async
* @return {Promise<Object>}
*/
update(path, key, value) {
return this.context.objects().metas().create(path, key, value);
}
/**
* Update existing object meta and return boolean as result
*
* @param {String} path Path of file with container
* @param {String} key Name of meta
* @param {String} value Value of meta
*
* @async
* @return {Promise<Boolean>}
*/
async update_with_result(path, key, value) {
try {
await this.context.objects().metas().update(path, key, value);
return true;
} catch (e) {
return false;
}
}
/**
* Delete object meta
*
* @param {String} path Path of file with container
* @param {String} key Name of meta
*
* @async
* @return {Promise<Object>}
*/
delete(path, key) {
return new Promise((resolve, reject) => {
try {
// checks
if (_.isUndefined(path)) // noinspection ExceptionCaughtLocallyJS
throw new Error("File path parameter is expected.");
if (!_.isString(path)) // noinspection ExceptionCaughtLocallyJS
throw new Error("File path parameter is not a string.");
if (!_.includes(path, '/')) // noinspection ExceptionCaughtLocallyJS
throw new Error("File path parameter isn't valid : container/filename.ext.");
if (_.isUndefined(key)) // noinspection ExceptionCaughtLocallyJS
throw new Error("Key parameter is expected.");
if (!_.isString(key)) // noinspection ExceptionCaughtLocallyJS
throw new Error("Key parameter is not a string.");
if (_.includes(key, "/") || _.includes(key, ' ')) // noinspection ExceptionCaughtLocallyJS
throw new Error("Key parameter contains special chars.");
// headers
let header = {};
header["X-Remove-Object-Meta-" + _.toSlug(_.toLower(key))] = "x";
// reformat path
let file = (() => {
let p = path.split('/');
if (p[0] === "")
delete p[0];
p = _.filter(p, (r) => {
return !_.isUndefined(r);
});
return p.join("/");
})();
// call
request({
method: 'POST',
uri: encodeURI(this.context.endpoint.url + '/' + file),
headers: Object.assign(
{
"X-Auth-Token": this.context.token,
"Accept": "application/json"
},
header)
}, (err, res, body) => {
err = err || request.checkIfResponseIsError(res);
if (err) // noinspection ExceptionCaughtLocallyJS
throw new Error(err);
return resolve(res.headers);
});
} catch (e) {
return reject(e);
}
});
}
/**
* Delete object meta and return boolean as result
*
* @param {String} path Path of file with container
* @param {String} key Name of meta
*
* @async
* @return {Promise<Boolean>}
*/
async delete_with_result(path, key) {
try {
await this.context.objects().metas().delete(path, key);
return true;
} catch (e) {
return false;
}
}
/**
* Get object meta
*
* @param {String} path Path of file with container
* @param {String} key Name of meta
*
* @async
* @return {Promise<string>}
*/
get(path, key) {
return new Promise((resolve, reject) => {
try {
// checks
if (_.isUndefined(path)) // noinspection ExceptionCaughtLocallyJS
throw new Error("File path parameter is expected.");
if (!_.isString(path)) // noinspection ExceptionCaughtLocallyJS
throw new Error("File path parameter is not a string.");
if (!_.includes(path, '/')) // noinspection ExceptionCaughtLocallyJS
throw new Error("File path parameter isn't valid : container/filename.ext.");
if (_.isUndefined(key)) // noinspection ExceptionCaughtLocallyJS
throw new Error("Key parameter is expected.");
if (!_.isString(key)) // noinspection ExceptionCaughtLocallyJS
throw new Error("Key parameter is not a string.");
if (_.includes(key, "/") || _.includes(key, ' ')) // noinspection ExceptionCaughtLocallyJS
throw new Error("Key parameter contains special chars.");
// reformat path
let file = (() => {
let p = path.split('/');
if (p[0] === "")
delete p[0];
p = _.filter(p, (r) => {
return !_.isUndefined(r);
});
return p.join("/");
})();
// call
request({
method: 'HEAD',
uri: encodeURI(this.context.endpoint.url + '/' + file),
headers: {
"X-Auth-Token": this.context.token,
"Accept": "application/json"
}
}, (err, res, body) => {
err = err || request.checkIfResponseIsError(res);
if (err) // noinspection ExceptionCaughtLocallyJS
throw new Error(err);
let value = _.filter(res.headers, (value, header) => {
return (_.toLower(header) === _.toLower("X-Object-Meta-" + _.toSlug(_.replace(_.toLower(key), /_/g, '-'))));
})
value = ((_.count(value) <= 0) ? null : value[0]);
return resolve(value);
});
} catch (e) {
return reject(e);
}
});
}
/**
* Object has meta
*
* @param {String} path Path of container
* @param {String} key Name of meta
*
* @async
* @return {Promise<Boolean>}
*/
has(path, key) {
return new Promise(async (resolve, reject) => {
try {
resolve(!_.isNull(await this.context.objects().metas().get(path, key)));
} catch (e) {
return reject(e);
}
});
}
/**
* Get all object metas
*
* @async
* @return {Promise<Object>}
*/
all(path) {
return new Promise((resolve, reject) => {
try {
// checks
if (_.isUndefined(path)) // noinspection ExceptionCaughtLocallyJS
throw new Error("File path parameter is expected.");
if (!_.isString(path)) // noinspection ExceptionCaughtLocallyJS
throw new Error("File path parameter is not a string.");
if (!_.includes(path, '/')) // noinspection ExceptionCaughtLocallyJS
throw new Error("File path parameter isn't valid : container/filename.ext.");
// reformat path
let file = (() => {
let p = path.split('/');
if (p[0] === "")
delete p[0];
p = _.filter(p, (r) => {
return !_.isUndefined(r);
});
return p.join("/");
})();
// call
request({
method: 'HEAD',
uri: encodeURI(this.context.endpoint.url + '/' + file),
headers: {
"X-Auth-Token": this.context.token,
"Accept": "application/json"
}
}, (err, res, body) => {
err = err || request.checkIfResponseIsError(res);
if (err) // noinspection ExceptionCaughtLocallyJS
throw new Error(err);
let values = _.map(res.headers, (value, header) => {
if (_.includes(_.toLower(header), _.toLower("X-Object-Meta-"))) {
let a = {}
a[_.replace(_.toLower(header), _.toLower("X-Object-Meta-"), '')] = value;
return a;
}
});
values = _.filter(values, (v) => {
return (!_.isUndefined(v));
})
values = (() => {
let as = {}
_.map(values, (v) => {
return _.merge(as, v)
});
return as;
})();
return resolve(values);
});
} catch (e) {
return reject(e);
}
});
}
}
module.exports = ObjectsMeta;