// NOTE This entire functionality seems non-crutial and maintainanece burden for no benefit
/** @typedef {import("./CmsMakeupEngine").ProductUsagePattern} ProductUsagePattern */
/**
* @typedef {Object} CmsApiConfiguration
*
* @property {string} url - base url of api
* @property {string} accessToken
* @property {string} languageCode
*/
export class FetchError extends Error {
/**
* @param {unknown} cause
* @param {string} message
*/
constructor(cause, message = "Fetch failed") {
super(message);
this.name = "FetchError";
this.cause = cause;
}
}
export class NotFoundError extends Error {
/**
* @param {string} entity
* @param {string | number} id
*/
constructor(entity, id) {
super(`${entity} with id ${id} was not found.`);
this.name = "NotFoundError";
this.entity = entity;
this.id = id;
}
}
/**
*
* @param {string} url
* @returns {Promise<unknown>}
*/
async function fetch_wrap(url) {
const json = await fetch(url, {
method: "GET",
headers: {
Accept: "application/json",
},
});
return (await json.json()).data;
}
/**
* @param {CmsApiConfiguration} conf
* @returns {Promise<unknown>}
*/
async function finishesMany(conf) {
return fetch_wrap(
`${conf.url}/finishes?access_token=${conf.accessToken}&language_code=${conf.languageCode}`,
);
}
/**
* @param {CmsApiConfiguration} conf
* @param {number} pup_id
* @returns {Promise<unknown>}
*/
async function productUsagePatternsSingle(conf, pup_id) {
return fetch_wrap(
`${conf.url}/product_usage_patterns/${pup_id}?access_token=${conf.accessToken}&language_code=${conf.languageCode}`,
);
}
/**
* @param {CmsApiConfiguration} conf
* @param {number} product_id
* @returns {Promise<unknown>}
*/
async function shadeColorsMany(conf, product_id) {
return fetch_wrap(
`${conf.url}/products/${product_id}/shade_colors?access_token=${conf.accessToken}&language_code=${conf.languageCode}`,
);
}
/**
* @param {CmsApiConfiguration} conf
* @param {number} pup_id
* @returns {Promise<unknown>}
*/
async function usagePatternAreasMany(conf, pup_id) {
return fetch_wrap(
`${conf.url}/product_usage_patterns/${pup_id}/usage_pattern_areas?access_token=${conf.accessToken}&language_code=${conf.languageCode}`,
);
}
/**
* @async
* @param {Omit<CmsApiConfiguration, "languageCode">} conf
* @param {number} shade_color_id
* @returns {Promise<number | undefined>}
*/
export async function tryToFetchshadeColorProductId(conf, shade_color_id) {
const shadeColors = await fetch_wrap(
`${conf.url}/shade_colors/${shade_color_id}?access_token=${conf.accessToken}`,
);
if (shadeColors instanceof Error) throw shadeColors;
const shadeColor = /** @type {Array<{product: number | undefined}>} */(shadeColors).at(0);
if (!shadeColor) throw new NotFoundError("ShadeColors", shade_color_id);
return shadeColor.product;
}
/**
* @async
* @param {CmsApiConfiguration} conf
* @param {number} pupId
* @returns {Promise<ProductUsagePattern>}
*/
export async function expandProductUsagePatternFetch(conf, pupId) {
// prettier-ignore
const finishProm = finishesMany(conf)
.catch((reason) => new FetchError(reason, "Couldn't fetch finishes."));
// prettier-ignore
const pupProm = productUsagePatternsSingle(conf, pupId)
.catch((reason) => new FetchError(reason, `Couldn't fetch product usage pattern ${pupId}.`));
// prettier-ignore
const upasProm = usagePatternAreasMany(conf, pupId)
.catch((reason) => new FetchError(reason, `Couldn't fetch usage pattern arreas for product usage pattern ${pupId}.`));
const [finishes, pups, upas] = await Promise.all([
finishProm,
pupProm,
upasProm,
]);
if (finishes instanceof Error) throw finishes; //TODO Appropriate error message and documented
if (pups instanceof Error) throw pups; //TODO Appropriate error message and documented
if (upas instanceof Error) throw upas; //TODO Appropriate error message and documented
const pup = pups.at(0);
if (!pup) throw new NotFoundError("ProductUsagePattern", pupId);
// prettier-ignore
const shadeProm = shadeColorsMany(conf, pup.product)
.catch(
(reason) => new FetchError(reason, `Couldn't fetch shadecolors for product ${pup.product}.`)
);
const [shades] = await Promise.all([shadeProm]);
if (shades instanceof Error) throw shades; //TODO Appropriate error message and documented
return {
id: pup.id,
product: pup.product,
usagePatternAreas: upas.map((upa) => {
const shadeColor = shades.find((s) => s.id === upa.shadeColor);
if (!shadeColor)
throw new NotFoundError("ShadeColor", upa.shadeColor);
const finish = finishes.find((f) => f.id === shadeColor.finish);
if (!finish) throw new NotFoundError("Finish", shadeColor.finish);
return {
applicationArea: upa.applicationArea,
shadeColor: {
id: shadeColor.id,
colorOpacity: shadeColor.colorOpacity,
finishOpacity: shadeColor.finishOpacity,
rendering: shadeColor.rendering,
finish: {
name: finish.name,
},
},
};
}),
};
}