'use strict';
/**
* The file mapping definition
* @exports zanata/fileMapping
*
* @requires util
* @requires minimatch
* @requires glob
*/
const util = require('util');
const minimatch = require('minimatch');
const glob = require('glob');
/**
* @class
* @classdesc The class to handle the mapping from the project type to the file name rule.
*/
class FileMappingRule {
/**
*
*
* @param {object[]|object} args - the Translation files mapping rules object represented by `xml2json` rules tags in zanata.xml
* @param {object} args.rule
* @param {string} args.rule.$t
* @param {string} args.rule.pattern
*
* @see {@link http://docs.zanata.org/en/release/client/configuration/#translation-files-mapping-rules|Translation files mapping rules}
*/
constructor(args) {
this.defaultMapping = {
'gettext': '{path}/{locale_with_underscore}.{extension}',
'podir': '{locale}/{path}/{filename}.{extension}',
'properties': '{path}/{filename}_{locale_with_underscore}.{extension}',
'utf8properties': '{path}/{filename}_{locale_with_underscore}.{extension}',
'xliff': '{path}/{filename}_{locale_with_underscore}.{extension}',
'xml': '{path}/{filename}_{locale_with_underscore}.{extension}',
'file': '{locale}/{path}/{filename}.{extension}'
};
this.customMapping = (args instanceof Array) ? args : [args];
this.customMapping = this.customMapping.filter((v) => v != undefined);
}
__applyMapping(tmpl, pattern) {
Object.keys(pattern).forEach(function(k) {
let restr = util.format('{%s}', k);
let re = new RegExp(restr, 'g');
tmpl = tmpl.replace(re, pattern[k]);
});
return tmpl;
}
__getMapping(type, pattern) {
if (this.defaultMapping[type] == undefined) {
throw new Error('Unknown mapping type: ' + type);
}
return this.__applyMapping(this.defaultMapping[type], pattern);
}
/**
* Set the mapping rule
*
* @param {string} type - the project type
* @param {string} pattern - the file name pattern
*/
setMapping(type, pattern) {
this.defaultMapping[type] = pattern;
}
/**
* Obtain the file path
*
* @param {string} type - the project type
* @param {object} params
* @param {string} params.source - the source document filename
* @param {string} [params.locale] - the locale name
* @param {string} [params.path]
* @param {string} [params.filename]
* @param {string} [params.extension]
*
* @throws {Error} Unknown mapping type
*/
getPath(type, params) {
let self = this;
let src = !params || !params.source ? null : params.source;
if (params && params.locale)
params.locale_with_underscore = params.locale.replace(/-/g, '_');
let ret = self.__getMapping(type, params);
if (self.customMapping.length > 0 && !src) {
console.warn("No source document filename is given in params. ignoring customMapping");
} else {
self.customMapping.forEach(function(o) {
let r = o.rule;
if (!Array.isArray(r))
r = [r];
for (let i = 0; i < r.length; i++) {
if (!r[i].pattern || minimatch(params.source, r[i].pattern)) {
ret = self.__applyMapping(r[i]['$t'], params);
break;
}
}
});
}
return ret;
}
/**
* Obtain the absolute file path
*
* @param {string} type - the project type
* @param {object} params
* @param {string} params.source - the source document filename
* @param {string} [params.locale] - the locale name
* @param {string} [params.path]
* @param {string} [params.filename]
* @param {string} [params.extension]
*
* @throws {Error} Unknown mapping type
*/
getRealPath(type, params) {
let p = this.getPath(type, params).replace(/^\.\//, '');
return glob.sync(p, {nocase: true, nodir: true})[0];
}
}
exports.FileMappingRule = FileMappingRule;