@shopnex/cj-plugin 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -60,7 +60,7 @@ async function mapMockProductToSchema({ product, payload, shopId, sdk }) {
|
|
60
60
|
const cjInventoryNum = data.data.reduce((sum, item)=>sum + (item?.cjInventoryNum || 0), 0);
|
61
61
|
variants.push({
|
62
62
|
gallery: [
|
63
|
-
imageId
|
63
|
+
+imageId
|
64
64
|
],
|
65
65
|
options: variant.variantKey?.split("-").map((key, index)=>({
|
66
66
|
option: index === 0 ? "Color" : "Size",
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../src/service/sync-products.ts"],"sourcesContent":["import type { BasePayload, Where } from \"payload\";\nimport { Product } from \"@shopnex/types\";\nimport {\n convertHTMLToLexical,\n editorConfigFactory,\n} from \"@payloadcms/richtext-lexical\";\nimport decimal from \"decimal.js\";\nimport { JSDOM } from \"jsdom\";\n\nimport type { ProductDetails } from \"../sdk/products/product-types\";\n\nimport { CjSdk, cjSdk } from \"../sdk/cj-sdk\";\nimport { CjData } from \"../CjCollection\";\nimport { retrieveAccessToken } from \"./access-token\";\n\nconst delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst upsertImage = async ({\n payload,\n imageUrl,\n filename,\n alt,\n shopId,\n}: {\n payload: BasePayload;\n imageUrl: string;\n filename: string;\n alt: string;\n shopId?: number;\n}) => {\n const whereClause: Where = {\n filename: {\n equals: filename,\n },\n };\n\n if (shopId !== undefined) {\n whereClause.shop = {\n equals: shopId,\n };\n }\n\n const imageData = await payload.find({\n collection: \"media\",\n where: whereClause,\n limit: 1,\n });\n if (imageData.totalDocs === 0) {\n return payload.create({\n collection: \"media\",\n data: {\n alt,\n filename,\n thumbnailURL: imageUrl,\n url: imageUrl,\n shop: shopId,\n },\n });\n }\n return imageData.docs[0];\n};\n\nasync function mapMockProductToSchema({\n product,\n payload,\n shopId,\n sdk,\n}: {\n product: ProductDetails;\n payload: BasePayload;\n shopId?: number;\n sdk: CjSdk;\n}) {\n const variants: Product[\"variants\"] = [];\n\n for (const variant of product.variants || []) {\n const filename = `${shopId}-${variant?.variantImage?.split(\"/\").pop()}`;\n if (!filename || !variant.variantImage) {\n continue;\n }\n const alt = filename.split(\".\")[0];\n const imageUrl = variant.variantImage;\n const imageData = await upsertImage({\n payload,\n imageUrl,\n filename,\n alt,\n shopId,\n });\n\n const imageId = imageData.id;\n\n const data = await sdk.products.getProductStockByVid({\n vid: variant.vid,\n });\n if (!data.data) {\n throw new Error(\"Failed to fetch stock information\");\n }\n const cjInventoryNum = data.data.reduce(\n (sum, item) => sum + (item?.cjInventoryNum || 0),\n 0\n );\n\n variants.push({\n gallery: [imageId],\n options: variant.variantKey?.split(\"-\").map((key, index) => ({\n option: index === 0 ? \"Color\" : \"Size\",\n value: key,\n })),\n price: Number(\n new decimal(variant.variantSellPrice || 0).toNumber().toFixed(2)\n ),\n vid: variant.vid,\n stockCount: cjInventoryNum,\n });\n }\n\n const cleanHtml = product.description?.replace(/<img[^>]*>/g, \"\");\n\n return {\n description: convertHTMLToLexical({\n editorConfig: await editorConfigFactory.default({\n config: payload.config, // Your Payload Config\n }),\n html: cleanHtml || \"<p></p>\",\n JSDOM, // Pass in the JSDOM import; it's not bundled to keep package size small\n }) as any,\n source: \"cj\" as any,\n pid: product.pid,\n title: product.productNameEn,\n variants,\n };\n}\n\nconst findProductById = async (productId: string, sdk: any) => {\n const result = await sdk.products.getProductDetails({\n pid: productId,\n });\n\n return result.data;\n};\n\nconst createOrUpdateProduct = async ({\n product,\n payload,\n shopId,\n}: {\n product: Omit<Product, \"createdAt\" | \"id\" | \"updatedAt\">;\n payload: BasePayload;\n shopId?: number;\n}) => {\n const { totalDocs } = await payload.count({\n collection: \"products\" as any,\n where: {\n pid: {\n equals: product.pid,\n },\n ...(shopId && {\n shop: {\n equals: shopId,\n },\n }),\n },\n });\n\n if (totalDocs === 0) {\n return payload.create({\n collection: \"products\" as any,\n data: {\n ...product,\n shop: shopId,\n } as any,\n });\n }\n};\n\nexport const syncProducts = async ({\n productIds,\n payload,\n shopId,\n data,\n}: {\n productIds: string[];\n payload: BasePayload;\n shopId?: number;\n data: Partial<CjData>;\n}) => {\n const accessToken = await retrieveAccessToken(data);\n const sdk = cjSdk({ accessToken });\n\n const fetchedProducts: ProductDetails[] = [];\n\n for (const productId of productIds) {\n const product = await findProductById(productId, sdk);\n if (product) {\n fetchedProducts.push(product);\n }\n await delay(1010); // throttle CJ API requests\n }\n\n // Wait for all async mapping to resolve\n const mappedProducts = await Promise.all(\n fetchedProducts.map((product) =>\n mapMockProductToSchema({ product, payload, shopId, sdk })\n )\n );\n\n // Create or update each mapped product\n await Promise.all(\n mappedProducts.map((product) =>\n createOrUpdateProduct({ product, payload, shopId })\n )\n );\n\n return fetchedProducts;\n};\n"],"names":["convertHTMLToLexical","editorConfigFactory","decimal","JSDOM","cjSdk","retrieveAccessToken","delay","ms","Promise","resolve","setTimeout","upsertImage","payload","imageUrl","filename","alt","shopId","whereClause","equals","undefined","shop","imageData","find","collection","where","limit","totalDocs","create","data","thumbnailURL","url","docs","mapMockProductToSchema","product","sdk","variants","variant","variantImage","split","pop","imageId","id","products","getProductStockByVid","vid","Error","cjInventoryNum","reduce","sum","item","push","gallery","options","variantKey","map","key","index","option","value","price","Number","variantSellPrice","toNumber","toFixed","stockCount","cleanHtml","description","replace","editorConfig","default","config","html","source","pid","title","productNameEn","findProductById","productId","result","getProductDetails","createOrUpdateProduct","count","syncProducts","productIds","accessToken","fetchedProducts","mappedProducts","all"],"mappings":"AAEA,SACIA,oBAAoB,EACpBC,mBAAmB,QAChB,+BAA+B;AACtC,OAAOC,aAAa,aAAa;AACjC,SAASC,KAAK,QAAQ,QAAQ;AAI9B,SAAgBC,KAAK,QAAQ,gBAAgB;AAE7C,SAASC,mBAAmB,QAAQ,iBAAiB;AAErD,MAAMC,QAAQ,CAACC,KAAe,IAAIC,QAAQ,CAACC,UAAYC,WAAWD,SAASF;AAE3E,MAAMI,cAAc,OAAO,EACvBC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,GAAG,EACHC,MAAM,EAOT;IACG,MAAMC,cAAqB;QACvBH,UAAU;YACNI,QAAQJ;QACZ;IACJ;IAEA,IAAIE,WAAWG,WAAW;QACtBF,YAAYG,IAAI,GAAG;YACfF,QAAQF;QACZ;IACJ;IAEA,MAAMK,YAAY,MAAMT,QAAQU,IAAI,CAAC;QACjCC,YAAY;QACZC,OAAOP;QACPQ,OAAO;IACX;IACA,IAAIJ,UAAUK,SAAS,KAAK,GAAG;QAC3B,OAAOd,QAAQe,MAAM,CAAC;YAClBJ,YAAY;YACZK,MAAM;gBACFb;gBACAD;gBACAe,cAAchB;gBACdiB,KAAKjB;gBACLO,MAAMJ;YACV;QACJ;IACJ;IACA,OAAOK,UAAUU,IAAI,CAAC,EAAE;AAC5B;AAEA,eAAeC,uBAAuB,EAClCC,OAAO,EACPrB,OAAO,EACPI,MAAM,EACNkB,GAAG,EAMN;IACG,MAAMC,WAAgC,EAAE;IAExC,KAAK,MAAMC,WAAWH,QAAQE,QAAQ,IAAI,EAAE,CAAE;QAC1C,MAAMrB,WAAW,GAAGE,OAAO,CAAC,EAAEoB,SAASC,cAAcC,MAAM,KAAKC,OAAO;QACvE,IAAI,CAACzB,YAAY,CAACsB,QAAQC,YAAY,EAAE;YACpC;QACJ;QACA,MAAMtB,MAAMD,SAASwB,KAAK,CAAC,IAAI,CAAC,EAAE;QAClC,MAAMzB,WAAWuB,QAAQC,YAAY;QACrC,MAAMhB,YAAY,MAAMV,YAAY;YAChCC;YACAC;YACAC;YACAC;YACAC;QACJ;QAEA,MAAMwB,UAAUnB,UAAUoB,EAAE;QAE5B,MAAMb,OAAO,MAAMM,IAAIQ,QAAQ,CAACC,oBAAoB,CAAC;YACjDC,KAAKR,QAAQQ,GAAG;QACpB;QACA,IAAI,CAAChB,KAAKA,IAAI,EAAE;YACZ,MAAM,IAAIiB,MAAM;QACpB;QACA,MAAMC,iBAAiBlB,KAAKA,IAAI,CAACmB,MAAM,CACnC,CAACC,KAAKC,OAASD,MAAOC,CAAAA,MAAMH,kBAAkB,CAAA,GAC9C;QAGJX,SAASe,IAAI,CAAC;YACVC,SAAS;
|
1
|
+
{"version":3,"sources":["../../src/service/sync-products.ts"],"sourcesContent":["import type { BasePayload, Where } from \"payload\";\nimport { Product } from \"@shopnex/types\";\nimport {\n convertHTMLToLexical,\n editorConfigFactory,\n} from \"@payloadcms/richtext-lexical\";\nimport decimal from \"decimal.js\";\nimport { JSDOM } from \"jsdom\";\n\nimport type { ProductDetails } from \"../sdk/products/product-types\";\n\nimport { CjSdk, cjSdk } from \"../sdk/cj-sdk\";\nimport { CjData } from \"../CjCollection\";\nimport { retrieveAccessToken } from \"./access-token\";\n\nconst delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst upsertImage = async ({\n payload,\n imageUrl,\n filename,\n alt,\n shopId,\n}: {\n payload: BasePayload;\n imageUrl: string;\n filename: string;\n alt: string;\n shopId?: number;\n}) => {\n const whereClause: Where = {\n filename: {\n equals: filename,\n },\n };\n\n if (shopId !== undefined) {\n whereClause.shop = {\n equals: shopId,\n };\n }\n\n const imageData = await payload.find({\n collection: \"media\",\n where: whereClause,\n limit: 1,\n });\n if (imageData.totalDocs === 0) {\n return payload.create({\n collection: \"media\",\n data: {\n alt,\n filename,\n thumbnailURL: imageUrl,\n url: imageUrl,\n shop: shopId,\n },\n });\n }\n return imageData.docs[0];\n};\n\nasync function mapMockProductToSchema({\n product,\n payload,\n shopId,\n sdk,\n}: {\n product: ProductDetails;\n payload: BasePayload;\n shopId?: number;\n sdk: CjSdk;\n}) {\n const variants: Product[\"variants\"] = [];\n\n for (const variant of product.variants || []) {\n const filename = `${shopId}-${variant?.variantImage?.split(\"/\").pop()}`;\n if (!filename || !variant.variantImage) {\n continue;\n }\n const alt = filename.split(\".\")[0];\n const imageUrl = variant.variantImage;\n const imageData = await upsertImage({\n payload,\n imageUrl,\n filename,\n alt,\n shopId,\n });\n\n const imageId = imageData.id;\n\n const data = await sdk.products.getProductStockByVid({\n vid: variant.vid,\n });\n if (!data.data) {\n throw new Error(\"Failed to fetch stock information\");\n }\n const cjInventoryNum = data.data.reduce(\n (sum, item) => sum + (item?.cjInventoryNum || 0),\n 0\n );\n\n variants.push({\n gallery: [+imageId],\n options: variant.variantKey?.split(\"-\").map((key, index) => ({\n option: index === 0 ? \"Color\" : \"Size\",\n value: key,\n })),\n price: Number(\n new decimal(variant.variantSellPrice || 0).toNumber().toFixed(2)\n ),\n vid: variant.vid,\n stockCount: cjInventoryNum,\n });\n }\n\n const cleanHtml = product.description?.replace(/<img[^>]*>/g, \"\");\n\n return {\n description: convertHTMLToLexical({\n editorConfig: await editorConfigFactory.default({\n config: payload.config, // Your Payload Config\n }),\n html: cleanHtml || \"<p></p>\",\n JSDOM, // Pass in the JSDOM import; it's not bundled to keep package size small\n }) as any,\n source: \"cj\" as any,\n pid: product.pid,\n title: product.productNameEn,\n variants,\n };\n}\n\nconst findProductById = async (productId: string, sdk: any) => {\n const result = await sdk.products.getProductDetails({\n pid: productId,\n });\n\n return result.data;\n};\n\nconst createOrUpdateProduct = async ({\n product,\n payload,\n shopId,\n}: {\n product: Omit<Product, \"createdAt\" | \"id\" | \"updatedAt\">;\n payload: BasePayload;\n shopId?: number;\n}) => {\n const { totalDocs } = await payload.count({\n collection: \"products\" as any,\n where: {\n pid: {\n equals: product.pid,\n },\n ...(shopId && {\n shop: {\n equals: shopId,\n },\n }),\n },\n });\n\n if (totalDocs === 0) {\n return payload.create({\n collection: \"products\" as any,\n data: {\n ...product,\n shop: shopId,\n } as any,\n });\n }\n};\n\nexport const syncProducts = async ({\n productIds,\n payload,\n shopId,\n data,\n}: {\n productIds: string[];\n payload: BasePayload;\n shopId?: number;\n data: Partial<CjData>;\n}) => {\n const accessToken = await retrieveAccessToken(data);\n const sdk = cjSdk({ accessToken });\n\n const fetchedProducts: ProductDetails[] = [];\n\n for (const productId of productIds) {\n const product = await findProductById(productId, sdk);\n if (product) {\n fetchedProducts.push(product);\n }\n await delay(1010); // throttle CJ API requests\n }\n\n // Wait for all async mapping to resolve\n const mappedProducts = await Promise.all(\n fetchedProducts.map((product) =>\n mapMockProductToSchema({ product, payload, shopId, sdk })\n )\n );\n\n // Create or update each mapped product\n await Promise.all(\n mappedProducts.map((product) =>\n createOrUpdateProduct({ product, payload, shopId })\n )\n );\n\n return fetchedProducts;\n};\n"],"names":["convertHTMLToLexical","editorConfigFactory","decimal","JSDOM","cjSdk","retrieveAccessToken","delay","ms","Promise","resolve","setTimeout","upsertImage","payload","imageUrl","filename","alt","shopId","whereClause","equals","undefined","shop","imageData","find","collection","where","limit","totalDocs","create","data","thumbnailURL","url","docs","mapMockProductToSchema","product","sdk","variants","variant","variantImage","split","pop","imageId","id","products","getProductStockByVid","vid","Error","cjInventoryNum","reduce","sum","item","push","gallery","options","variantKey","map","key","index","option","value","price","Number","variantSellPrice","toNumber","toFixed","stockCount","cleanHtml","description","replace","editorConfig","default","config","html","source","pid","title","productNameEn","findProductById","productId","result","getProductDetails","createOrUpdateProduct","count","syncProducts","productIds","accessToken","fetchedProducts","mappedProducts","all"],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@shopnex/cj-plugin",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.8",
|
4
4
|
"description": "A blank template to get started with Payload 3.0",
|
5
5
|
"type": "module",
|
6
6
|
"exports": {
|
@@ -34,7 +34,7 @@
|
|
34
34
|
"jsdom": "^26.0.0",
|
35
35
|
"lexical": "0.28.0",
|
36
36
|
"@shopnex/utils": "1.0.6",
|
37
|
-
"@shopnex/types": "0.0.
|
37
|
+
"@shopnex/types": "0.0.2"
|
38
38
|
},
|
39
39
|
"devDependencies": {
|
40
40
|
"@types/jsdom": "^21.1.7"
|