shoe-converter
Version:
Making it possible to convert the shoe size and gender of one brand to another.
138 lines (137 loc) • 6.16 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getShoeSizeData = exports.convert = void 0;
const constants_1 = require("./constants/constants");
const data_1 = require("./data/data");
const utils_1 = require("./utils/utils");
function findClosestSize(sizes, targetSize) {
let closestNumber = sizes[0];
for (let i = 0; i < sizes.length; i++) {
const currentNumber = sizes[i];
const currentDifference = Math.abs(targetSize - currentNumber);
const closestDifference = Math.abs(targetSize - closestNumber);
if (currentDifference < closestDifference) {
closestNumber = currentNumber;
}
}
return Number(closestNumber.toFixed(1));
}
function getDesiredSize(conversionParameters, cmSize) {
const isMan = (0, utils_1.isGenderMan)(conversionParameters.gender);
const cmSizes = (0, utils_1.getSizes)(data_1.data, conversionParameters.brand, constants_1.System.cm, isMan);
const foundIndex = cmSizes.findIndex((s) => s === cmSize);
if (foundIndex === -1) {
cmSize = findClosestSize(cmSizes.map(Number), parseFloat(cmSize)).toString();
}
const index = cmSizes.findIndex((s) => s === cmSize);
if (index < 0) {
throw new Error(`The size is not available for ${conversionParameters.gender} at ${(0, utils_1.capitalizeFirstLetter)(conversionParameters.brand)}`);
}
const sizes = (0, utils_1.getSizes)(data_1.data, conversionParameters.brand, conversionParameters.system, isMan);
if (!sizes[index]) {
throw new Error(`The size is not available for ${conversionParameters.gender} at ${(0, utils_1.capitalizeFirstLetter)(conversionParameters.brand)}`);
}
return sizes[index];
}
function getCmSize(conversionParameters) {
const isMan = (0, utils_1.isGenderMan)(conversionParameters.gender);
const sizes = (0, utils_1.getSizes)(data_1.data, conversionParameters.brand, conversionParameters.system, isMan);
const cmSizes = (0, utils_1.getSizes)(data_1.data, conversionParameters.brand, constants_1.System.cm, isMan);
const index = sizes.findIndex((s) => s === conversionParameters.size);
return cmSizes[index];
}
function validateSize(brand, system, gender, size) {
if (!size) {
throw new Error(`Size cannot be empty`);
}
const isMan = (0, utils_1.isGenderMan)(gender);
if (!(0, utils_1.isTypeValid)(size)) {
throw new Error(`The size '${size}' is not a string`);
}
if (!(0, utils_1.isSizeFormatValid)(size)) {
throw new Error(`The size '${size}' does not comply with the regex:\n^(?:\d{1,2}(?:\s\d\/\d)?|\d+\.\d+)$`);
}
const sizes = (0, utils_1.getSizes)(data_1.data, brand, system, isMan);
if (!sizes.some((s) => s === size)) {
throw new Error(`The size '${size}' is not available in ${system}`);
}
return size;
}
function validateBrand(brand) {
if (!brand) {
throw new Error(`Brand cannot be empty`);
}
const lowerCaseBrand = brand.toLowerCase();
if (!(0, utils_1.isTypeValid)(lowerCaseBrand)) {
throw new Error(`The brand '${(0, utils_1.capitalizeFirstLetter)(lowerCaseBrand)}' is not a string`);
}
if ((data_1.data === null || data_1.data === void 0 ? void 0 : data_1.data[lowerCaseBrand]) == null) {
throw new Error(`There is no data available for '${(0, utils_1.capitalizeFirstLetter)(lowerCaseBrand)}'`);
}
return lowerCaseBrand;
}
function validateSystem(brand, system) {
var _a;
if (!system) {
throw new Error(`System cannot be empty`);
}
let lowerCaseSystem = system === null || system === void 0 ? void 0 : system.toLowerCase();
if (!(0, utils_1.isTypeValid)(lowerCaseSystem)) {
throw new Error(`The system '${lowerCaseSystem}' is not a string`);
}
if (system === constants_1.System.jp) {
lowerCaseSystem = constants_1.System.cm;
}
if (((_a = data_1.data === null || data_1.data === void 0 ? void 0 : data_1.data[brand]) === null || _a === void 0 ? void 0 : _a[lowerCaseSystem]) == null) {
throw new Error(`The system '${lowerCaseSystem}' is not available for the brand '${(0, utils_1.capitalizeFirstLetter)(brand)}'`);
}
return lowerCaseSystem;
}
function validateGender(brand, system, gender) {
if (!gender) {
throw new Error(`Gender cannot be empty`);
}
const lowerCaseGender = gender.toLowerCase();
if (!(0, utils_1.isTypeValid)(lowerCaseGender)) {
throw new Error(`The gender '${lowerCaseGender}' is not a string`);
}
const manageableGender = (0, utils_1.convertGenderSynonym)(lowerCaseGender);
if (!(0, utils_1.isGenderManageable)(manageableGender)) {
throw new Error(`The gender '${manageableGender}' is not a gender used by the available shoe brands`);
}
if (!(0, utils_1.isGenderAvailable)(data_1.data, brand, system, manageableGender)) {
throw new Error(`The gender '${manageableGender}' is not available for ${system} sizes by ${(0, utils_1.capitalizeFirstLetter)(brand)}`);
}
return manageableGender;
}
function getPropertiesToConvertFrom(convertFrom) {
const brand = validateBrand(convertFrom.brand);
const system = validateSystem(brand, convertFrom.system);
const gender = validateGender(brand, system, convertFrom.gender);
const convertFromSize = validateSize(brand, system, gender, convertFrom.size);
return {
brand: brand,
system: system,
gender: gender,
size: convertFromSize,
};
}
function getPropertiesToConvertTo(convertTo) {
const brand = validateBrand(convertTo.brand);
const system = validateSystem(brand, convertTo.system);
const gender = validateGender(brand, system, convertTo.gender);
return {
brand: brand,
system: system,
gender: gender,
};
}
function convert(convert) {
const cmSize = getCmSize(getPropertiesToConvertFrom(convert.from));
return getDesiredSize(getPropertiesToConvertTo(convert.to), cmSize);
}
exports.convert = convert;
function getShoeSizeData() {
return JSON.stringify(data_1.data);
}
exports.getShoeSizeData = getShoeSizeData;