dashersupply/src/data/api-client.ts

348 lines
16 KiB
TypeScript

import * as core from "./core/client";
import { SCHEMAS } from "./models/schemas";
import { getAllContents } from "./core/client.js";
import { SupportedLocales, type Localized } from "./internals/LocalizedT.js";
import type { Component } from "./internals/Component";
import type { Brand } from "./models/multis/Brand";
import type { Page } from "./models/multis/Page";
import type { Site } from "./models/singles/Site";
import type { SiteConfig } from "./models/singles/SiteConfig";
import type { Marketplace } from "./models/multis/Marketplace";
import type { ProductCategory } from "./models/multis/ProductCategory";
import type { Product } from "./models/multis/Product";
import type { Slug } from "./models/multis/Slug";
import type { Seller } from "./models/multis/Seller";
import type { NonLocalized } from "./internals/NonLocalizedT.js";
import type { ContentsDto } from "./internals/ContentsDtoT";
import type { ContentDto } from "./internals/ContentDtoT";
import type { Listing } from "./models/multis/Listing.js";
import type { Offer } from "./models/multis/Offer.js";
import type { Redirect } from "./models/multis/Redirect.js";
import type { BrandSlots } from "./models/components/BrandSlots.js";
/** Generic helpers */
export const getLocaleField = function <T>(locale: SupportedLocales|string, field: Localized<T>) {
if (field && field[locale.toString()])
return field[locale.toString()];
}
export function getPageComponentOfType<T extends Component>(component: Component) {
return component as T;
}
/** Assets handlers */
export const getAssetById = core.getAssetById;
/** Brands handlers */
export const getBrandsByIds = async (ids: string) =>
await core.getContentsByIds<Brand>(SCHEMAS.BRANDS, ids);
export const getBrandsByLangSlug = async (forLang: SupportedLocales|string, slug: string) =>
await core.getContentsByLangSlug<Brand>(SCHEMAS.BRANDS, forLang, slug);
export const getBrandsUsingJsonQuery = async (jsonQuery: string|undefined = undefined) =>
await core.getContentsUsingJsonQuery<Brand>(SCHEMAS.BRANDS, jsonQuery);
/** Brands handlers */
export const getBrandSlotsByIds = async (ids: string) =>
await core.getContentsByIds<BrandSlots>(SCHEMAS.BRANDS_SLOTS, ids);
export const getBrandSlotsByLangSlug = async (forLang: SupportedLocales|string, slug: string) =>
await core.getContentsByLangSlug<BrandSlots>(SCHEMAS.BRANDS_SLOTS, forLang, slug);
export const getBrandSlotsUsingJsonQuery = async (jsonQuery: string|undefined = undefined) =>
await core.getContentsUsingJsonQuery<BrandSlots>(SCHEMAS.BRANDS_SLOTS, jsonQuery);
/** Marketplaces handlers */
export const getMarketplacesByIds = async (ids: string) =>
await core.getContentsByIds<Marketplace>(SCHEMAS.MARKETPLACES, ids);
export const getMarketplacesByLangSlug = async (forLang: SupportedLocales|string, slug: string) =>
await core.getContentsByLangSlug<Marketplace>(SCHEMAS.MARKETPLACES, forLang, slug);
export const getMarketplacesUsingJsonQuery = async (jsonQuery: string|undefined = undefined) =>
await core.getContentsUsingJsonQuery<Marketplace>(SCHEMAS.MARKETPLACES, jsonQuery);
/** Marketplaces handlers */
export const getSellersByIds = async (ids: string) =>
await core.getContentsByIds<Seller>(SCHEMAS.SELLERS, ids);
export const getSellersByLangSlug = async (forLang: SupportedLocales|string, slug: string) =>
await core.getContentsByLangSlug<Seller>(SCHEMAS.SELLERS, forLang, slug);
export const getSellersUsingJsonQuery = async (jsonQuery: string|undefined = undefined) =>
await core.getContentsUsingJsonQuery<Seller>(SCHEMAS.SELLERS, jsonQuery);
/** Pages handlers */
export const getPagesByIds = async (ids: string) =>
await core.getContentsByIds<Page>(SCHEMAS.PAGES, ids);
export const getPagesByLangSlug = async (forLang: SupportedLocales|string, slug: string) =>
await core.getContentsByLangSlug<Page>(SCHEMAS.PAGES, forLang, slug);
export const getPagesUsingJsonQuery = async (jsonQuery: string|undefined = undefined) =>
await core.getContentsUsingJsonQuery<Page>(SCHEMAS.PAGES, jsonQuery);
/** Product Categories handlers */
export const getProductCategoriesByIds = async (ids: string) =>
await core.getContentsByIds<ProductCategory>(SCHEMAS.PRODUCT_CATEGORIES, ids);
export const getProductCategoriesByLangSlug = async (forLang: SupportedLocales|string, slug: string) =>
await core.getContentsByLangSlug<ProductCategory>(SCHEMAS.PRODUCT_CATEGORIES, forLang, slug);
export const getProductCategoriesUsingJsonQuery = async (jsonQuery: string|undefined = undefined) =>
await core.getContentsUsingJsonQuery<ProductCategory>(SCHEMAS.PRODUCT_CATEGORIES, jsonQuery);
/** Products handlers */
export const getProductsByIds = async (ids: string) =>
await core.getContentsByIds<Product>(SCHEMAS.PRODUCTS, ids);
export const getProductsByLangSlug = async (forLang: SupportedLocales|string, slug: string) =>
await core.getContentsByLangSlug<Product>(SCHEMAS.PRODUCTS, forLang, slug);
export const getProductsUsingJsonQuery = async (jsonQuery: string|undefined = undefined) =>
await core.getContentsUsingJsonQuery<Product>(SCHEMAS.PRODUCTS, jsonQuery);
/** Product Listings handlers */
export const getProductListingsByIds = async (ids: string) =>
await core.getContentsByIds<Listing>(SCHEMAS.LISTINGS, ids);
export const getProductListingsUsingJsonQuery = async (jsonQuery: string|undefined = undefined) =>
await core.getContentsUsingJsonQuery<Listing>(SCHEMAS.LISTINGS, jsonQuery);
/** Offers handlers */
export const getOffersByListingId = async (listingId: string) =>
await core.getContentsUsingJsonQuery<Offer>(SCHEMAS.OFFERS, JSON.stringify({
filter: {
path: "data.listing.iv",
op: "eq",
value: listingId,
}
}));
export const getRedirectsByPreviousSlug = async (prevSlug: string) =>
await core.getContentsUsingJsonQuery<Redirect>(SCHEMAS.REDIRECTS, JSON.stringify({
filter: {
path: "data.prevSlug.iv",
op: "eq",
value: prevSlug,
}
}));
/** Slugs handlers */
export const getAllSlugs = async () =>
await core.getAllContents<Slug>(SCHEMAS.SLUGS);
export const getSlugByLangSlug = async (forLang: SupportedLocales|string, slug: string) =>
await core.getContentsUsingJsonQuery<Slug>(SCHEMAS.SLUGS, JSON.stringify({
filter: {
and: [
{ path: `data.locale.iv`, op: 'eq', value: forLang },
{ path: `data.localizedSlug.iv`, op: 'eq', value: slug }
]
}
}));
/** Site handlers */
export const getSite = async () =>
await getAllContents<Site>(SCHEMAS.SITE);
export const getSiteHomePage = async (site: Site) => {
if (site.homePage && site.homePage.iv.length > 0) {
let homePageIds: string[] = site!.homePage.iv;
let pageContents = getPagesByIds(homePageIds[0]);
return pageContents;
}
throw new Error('No site home page exists.');
}
export const getSiteConfig = async () =>
await getAllContents<SiteConfig>(SCHEMAS.SITE_CONFIG);
export async function performSyncLocalizedSlugs(logFn = console.log) {
logFn("Begin sync localized slugs.")
let allSlugs = await getAllSlugs();
let allPages = await core.getContentsUsingJsonQuery<Page>(SCHEMAS.PAGES);
let allBrands = await core.getContentsUsingJsonQuery<Brand>(SCHEMAS.BRANDS);
let allProducts = await core.getContentsUsingJsonQuery<Product>(SCHEMAS.PRODUCTS);
let allProductCategories = await core.getContentsUsingJsonQuery<ProductCategory>(SCHEMAS.PRODUCT_CATEGORIES);
let allSellers = await core.getContentsUsingJsonQuery<Seller>(SCHEMAS.SELLERS);
let allMarketplaces = await core.getContentsUsingJsonQuery<Marketplace>(SCHEMAS.MARKETPLACES);
const locales = Object.values(SupportedLocales);
const findSlugInMultilingual = function<T>(slug: Slug, schema: SCHEMAS|string, contents: ContentsDto<T>) {
for (let i = 0; i < contents.items.length; i++) {
let item = contents.items[i];
for (let l = 0; l < locales.length; l++) {
let locale = locales[l];
let testSlug = (item.data! as any).slug[locale]
if (testSlug) {
if (slug.locale.iv === locale
&& slug.localizedSlug.iv === testSlug
&& slug.referenceSchema.iv === schema
&& slug.reference.iv.length === 1
&& slug.reference.iv[0] === item.id) {
return item;
}
}
}
}
}
const findSlugInSlugs = function(locale: SupportedLocales|string, slug: Localized<string>, schema: SCHEMAS|string, referenceId: string) {
for (let i = 0; i < allSlugs.items.length; i++) {
let testSlug = allSlugs.items[i].data!;
if (testSlug.localizedSlug.iv === slug[locale]
&& testSlug.locale.iv === locale
&& testSlug.referenceSchema.iv === schema
&& testSlug.reference.iv.length === 1
&& testSlug.reference.iv[0] === referenceId) {
return allSlugs.items[i];
}
}
}
let batchAddSlugsQueue: Slug[] = [];
allPages.items.forEach((page) => {
for (let l = 0; l < locales.length; l++) {
let locale = locales[l];
let foundSlugDto = findSlugInSlugs(locale, (page.data! as Page).slug, SCHEMAS.PAGES, page.id);
if (!foundSlugDto) {
//cache slug for page
batchAddSlugsQueue.push({
locale: { iv: locale },
localizedSlug: { iv: (page.data! as Page).slug[locale] },
referenceSchema: { iv: SCHEMAS.PAGES },
reference: { iv: [page.id] }
});
}
}
});
allBrands.items.forEach((brand) => {
for (let l = 0; l < locales.length; l++) {
let locale = locales[l];
let foundSlugDto = findSlugInSlugs(locale, (brand.data! as Brand).slug, SCHEMAS.BRANDS, brand.id);
if (!foundSlugDto) {
//cache slug for brand
batchAddSlugsQueue.push({
locale: { iv: locale },
localizedSlug: { iv: (brand.data! as Brand).slug[locale] },
referenceSchema: { iv: SCHEMAS.BRANDS },
reference: { iv: [brand.id] }
});
}
}
});
allProducts.items.forEach((product) => {
for (let l = 0; l < locales.length; l++) {
let locale = locales[l];
let foundSlugDto = findSlugInSlugs(locale, (product.data! as Product).slug, SCHEMAS.PRODUCTS, product.id);
if (!foundSlugDto) {
//cache slug for product
batchAddSlugsQueue.push({
locale: { iv: locale },
localizedSlug: { iv: (product.data! as Product).slug[locale] },
referenceSchema: { iv: SCHEMAS.PRODUCTS },
reference: { iv: [product.id] }
});
}
}
});
allProductCategories.items.forEach((productCategory) => {
for (let l = 0; l < locales.length; l++) {
let locale = locales[l];
let foundSlugDto = findSlugInSlugs(locale, (productCategory.data! as ProductCategory).slug, SCHEMAS.PRODUCT_CATEGORIES, productCategory.id);
if (!foundSlugDto) {
//cache slug for product category
batchAddSlugsQueue.push({
locale: { iv: locale },
localizedSlug: { iv: (productCategory.data! as ProductCategory).slug[locale] },
referenceSchema: { iv: SCHEMAS.PRODUCT_CATEGORIES },
reference: { iv: [productCategory.id] }
});
}
}
});
allSellers.items.forEach((seller) => {
for (let l = 0; l < locales.length; l++) {
let locale = locales[l];
let foundSlugDto = findSlugInSlugs(locale, (seller.data! as Seller).slug, SCHEMAS.SELLERS, seller.id);
if (!foundSlugDto) {
//cache slug for product category
batchAddSlugsQueue.push({
locale: { iv: locale },
localizedSlug: { iv: (seller.data! as Seller).slug[locale] },
referenceSchema: { iv: SCHEMAS.SELLERS },
reference: { iv: [seller.id] }
});
}
}
});
allMarketplaces.items.forEach((marketplace) => {
for (let l = 0; l < locales.length; l++) {
let locale = locales[l];
let foundSlugDto = findSlugInSlugs(locale, (marketplace.data! as Marketplace).slug, SCHEMAS.MARKETPLACES, marketplace.id);
if (!foundSlugDto) {
//cache slug for product category
batchAddSlugsQueue.push({
locale: { iv: locale },
localizedSlug: { iv: (marketplace.data! as Marketplace).slug[locale] },
referenceSchema: { iv: SCHEMAS.MARKETPLACES },
reference: { iv: [marketplace.id] }
});
}
}
});
let batchRemoveSlugsQueue: string[] = [];
allSlugs.items.forEach((slugDto) => {
const doesSlugExistInPages = findSlugInMultilingual<Page>(slugDto.data! as Slug, SCHEMAS.PAGES, allPages);
const doesSlugExistInBrands = findSlugInMultilingual<Brand>(slugDto.data! as Slug, SCHEMAS.BRANDS, allBrands);
const doesSlugExistInProducts = findSlugInMultilingual<Product>(slugDto.data! as Slug, SCHEMAS.PRODUCTS, allProducts);
const doesSlugExistInProductCategories = findSlugInMultilingual<ProductCategory>(slugDto.data! as Slug, SCHEMAS.PRODUCT_CATEGORIES, allProductCategories);
const doesSlugExistInSellers = findSlugInMultilingual<Seller>(slugDto.data! as Slug, SCHEMAS.SELLERS, allSellers);
const doesSlugExistInMarketplaces = findSlugInMultilingual<Marketplace>(slugDto.data! as Slug, SCHEMAS.MARKETPLACES, allMarketplaces);
const doesSlugExistElsewhere = doesSlugExistInPages||doesSlugExistInBrands||doesSlugExistInProducts||doesSlugExistInProductCategories||doesSlugExistInSellers||doesSlugExistInMarketplaces;
const shouldPruneOrphanSlug = !doesSlugExistElsewhere;
if (shouldPruneOrphanSlug) {
//prune orphan slugs from cache
batchRemoveSlugsQueue.push(slugDto.id);
}
});
const MAX_TIME_TO_POST_SLUGS = 60;//s
logFn("Add", batchAddSlugsQueue.length, "slugs");
//postContents is deprecated, will loop with postContent
let bulkAddResult = [];//await core.client.contents.postContents(SCHEMAS.SLUGS, { datas: batchAddSlugsQueue as any, publish: true });
for (let bar = 0; bar < batchAddSlugsQueue.length; bar++) {
bulkAddResult.push(await core.client.contents.postContent(SCHEMAS.SLUGS, batchAddSlugsQueue[bar] as any, { publish: true }));
}
logFn("Remove by id", batchRemoveSlugsQueue.length, "slugs");
batchRemoveSlugsQueue.forEach(async (removeId) => {
await core.client.contents.deleteContent(SCHEMAS.SLUGS, removeId)
})
logFn("Finish sync localized slugs.")
}
export class AmazonPAApiSyncClient {
public async getSyncProducts () {
let amazonSlug = `${SupportedLocales["en-US"]}/amazon`;
let amazonMarketplaceId = (await core.getContentsByLangSlug<Marketplace>(SCHEMAS.MARKETPLACES, SupportedLocales['en-US'], amazonSlug)).items[0].id;
let allProducts = await core.getContentsUsingJsonQuery<Product>(SCHEMAS.PRODUCTS);
return allProducts.items.filter((product) => product.data?.marketplaceConnections.iv[0].marketplace[0] === amazonMarketplaceId);
};
public async getLastSync (productId: string) {
}
}
// console.log(await (new AmazonPAApiSyncClient()).getSyncProducts());