348 lines
16 KiB
TypeScript
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());
|