Product sync
This commit is contained in:
+37
-15
@@ -46,11 +46,16 @@ export namespace Printful {
|
||||
}
|
||||
|
||||
export namespace Products {
|
||||
interface MetaData<T = any> {
|
||||
export interface MetaDataSingle<T = any> {
|
||||
code: number;
|
||||
result: T;
|
||||
}
|
||||
|
||||
export interface MetaDataMulti<T = any> {
|
||||
code: number;
|
||||
result: T[];
|
||||
}
|
||||
|
||||
interface Option {
|
||||
id: string;
|
||||
value: string;
|
||||
@@ -77,7 +82,7 @@ export namespace Printful {
|
||||
stitch_count_tier: string;
|
||||
}
|
||||
|
||||
interface SyncProductData {
|
||||
export interface SyncProduct {
|
||||
sync_product: {
|
||||
id: number;
|
||||
external_id: string;
|
||||
@@ -115,20 +120,37 @@ export namespace Printful {
|
||||
|
||||
}[]
|
||||
}
|
||||
export type SyncProduct = MetaData<SyncProductData>;
|
||||
}
|
||||
|
||||
export async function getSyncProduct(syncProductId: number): Promise<Products.SyncProduct> {
|
||||
const payload: Products.SyncProduct = await (
|
||||
await fetch(`${Printful.API_URL}/store/products/${syncProductId}`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": `Bearer ${Bun.env.PRINTFUL_AUTH}`,
|
||||
"X-PF-Store-Id": `${Bun.env.PRINTFUL_STORE_ID}`
|
||||
}
|
||||
})
|
||||
).json();
|
||||
export async function getSyncProduct(syncProductId: number): Promise<SyncProduct> {
|
||||
const payload: MetaDataSingle<SyncProduct> = await (
|
||||
await fetch(`${Printful.API_URL}/store/products/${syncProductId}`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": `Bearer ${Bun.env.PRINTFUL_AUTH}`,
|
||||
"X-PF-Store-Id": `${Bun.env.PRINTFUL_STORE_ID}`
|
||||
}
|
||||
})
|
||||
).json();
|
||||
|
||||
return payload;
|
||||
return payload.result;
|
||||
}
|
||||
|
||||
export async function getSyncProducts(): Promise<SyncProduct[]> {
|
||||
const payload: MetaDataMulti<SyncProduct["sync_product"]> = await (
|
||||
await fetch(`${Printful.API_URL}/store/products`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": `Bearer ${Bun.env.PRINTFUL_AUTH}`,
|
||||
"X-PF-Store-Id": `${Bun.env.PRINTFUL_STORE_ID}`
|
||||
}
|
||||
})
|
||||
).json();
|
||||
|
||||
// need to fetch variants
|
||||
const syncProducts = await Promise.all(
|
||||
payload.result.map(p => getSyncProduct(p.id))
|
||||
);
|
||||
return syncProducts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class ProductRecords {
|
||||
this.db = new Database(dbPath);
|
||||
}
|
||||
|
||||
findFromWebflow(webflowProductId: number): ProductRecord | undefined {
|
||||
findUsingWebflow(webflowProductId: number): ProductRecord | undefined {
|
||||
const row = this.db.query(`
|
||||
SELECT * FROM product_records WHERE webflowProductId = ?
|
||||
`).get(webflowProductId);
|
||||
@@ -24,7 +24,7 @@ class ProductRecords {
|
||||
return row as ProductRecord | undefined;
|
||||
}
|
||||
|
||||
findFromPrintful(printfulProductId: number): ProductRecord | undefined {
|
||||
findUsingPrintful(printfulProductId: number): ProductRecord | undefined {
|
||||
const row = this.db.query(`
|
||||
SELECT * FROM product_records WHERE printfulProductId = ?
|
||||
`).get(printfulProductId);
|
||||
@@ -32,13 +32,13 @@ class ProductRecords {
|
||||
return row as ProductRecord | undefined;
|
||||
}
|
||||
|
||||
deleteFromWebflow(webflowProductId: number) {
|
||||
deleteUsingWebflow(webflowProductId: number) {
|
||||
this.db.run(`
|
||||
DELETE FROM product_records WHERE webflowProductId = ?
|
||||
`, [webflowProductId]);
|
||||
}
|
||||
|
||||
deleteFromPrintful(printfulProductId: number) {
|
||||
deleteUsingPrintful(printfulProductId: number) {
|
||||
this.db.run(`
|
||||
DELETE FROM product_records WHERE printfulProductId = ?
|
||||
`, [printfulProductId]);
|
||||
|
||||
+15
-16
@@ -26,7 +26,7 @@ export namespace Webflow {
|
||||
unit: string;
|
||||
currency: string;
|
||||
};
|
||||
"main-image": string;
|
||||
"main-image"?: string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ export namespace Webflow {
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteProductFromPrintful(printfulProductId: number) {
|
||||
const webflowProductId = productRecords.findFromPrintful(printfulProductId)?.webflowProductId;
|
||||
export async function deleteProductUsingPrintful(printfulProductId: number) {
|
||||
const webflowProductId = productRecords.findUsingPrintful(printfulProductId)?.webflowProductId;
|
||||
if (webflowProductId) {
|
||||
const res = await fetch(`${Webflow.API_COLLECTIONS_URL}/items/${webflowProductId}`, {
|
||||
method: "DELETE",
|
||||
@@ -63,17 +63,17 @@ export namespace Webflow {
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
productRecords.deleteFromWebflow(webflowProductId);
|
||||
productRecords.deleteUsingWebflow(webflowProductId);
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateProductFromPrintful(printfulProduct: Printful.Products.SyncProduct) {
|
||||
const webflowProductId = productRecords.findFromPrintful(printfulProduct.result.sync_product.id)?.webflowProductId;
|
||||
export async function updateProductUsingPrintful(printfulProduct: Printful.Products.SyncProduct) {
|
||||
const webflowProductId = productRecords.findUsingPrintful(printfulProduct.sync_product.id)?.webflowProductId;
|
||||
if (!webflowProductId) {
|
||||
throw new Error("Product is not recognized");
|
||||
}
|
||||
|
||||
const printfulVariants = printfulProduct.result.sync_variants;
|
||||
const printfulVariants = printfulProduct.sync_variants;
|
||||
const webflowVariants: Products.Sku[] = [];
|
||||
for (const printfulVariant of printfulVariants) {
|
||||
webflowVariants.push({
|
||||
@@ -107,8 +107,8 @@ export namespace Webflow {
|
||||
body: JSON.stringify({
|
||||
"product": {
|
||||
"fieldData": {
|
||||
"name": printfulProduct.result.sync_product.name,
|
||||
"slug": formatSlug(printfulProduct.result.sync_product.name),
|
||||
"name": printfulProduct.sync_product.name,
|
||||
"slug": formatSlug(printfulProduct.sync_product.name),
|
||||
"sku-properties": [
|
||||
{
|
||||
"id": "color",
|
||||
@@ -157,12 +157,11 @@ export namespace Webflow {
|
||||
"sku": webflowVariants[i]
|
||||
})
|
||||
});
|
||||
console.log(JSON.stringify((await res.json())));
|
||||
}
|
||||
}
|
||||
|
||||
export async function createProductFromPrintful(printfulProduct: Printful.Products.SyncProduct) {
|
||||
const printfulVariants = printfulProduct.result.sync_variants;
|
||||
export async function createProductUsingPrintful(printfulProduct: Printful.Products.SyncProduct) {
|
||||
const printfulVariants = printfulProduct.sync_variants;
|
||||
|
||||
const webflowVariants: Products.Sku[] = [];
|
||||
for (const printfulVariant of printfulVariants) {
|
||||
@@ -180,7 +179,7 @@ export namespace Webflow {
|
||||
"currency": printfulVariant.currency
|
||||
},
|
||||
// TODO: sync image
|
||||
"main-image": "https://www.example.com/image.jpg"
|
||||
// "main-image": "https://www.example.com/image.jpg"
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -198,8 +197,8 @@ export namespace Webflow {
|
||||
body: JSON.stringify({
|
||||
"product": {
|
||||
"fieldData": {
|
||||
"name": printfulProduct.result.sync_product.name,
|
||||
"slug": formatSlug(printfulProduct.result.sync_product.name),
|
||||
"name": printfulProduct.sync_product.name,
|
||||
"slug": formatSlug(printfulProduct.sync_product.name),
|
||||
"sku-properties": [
|
||||
{
|
||||
"id": "color",
|
||||
@@ -232,7 +231,7 @@ export namespace Webflow {
|
||||
}
|
||||
|
||||
const webflowProductId = addProductResponse["product"]["id"];
|
||||
const printfulProductId = printfulProduct.result.sync_product.id;
|
||||
const printfulProductId = printfulProduct.sync_product.id;
|
||||
|
||||
// CREATE WEBFLOW PRODUCT SKUs
|
||||
let createSkuResponse = await fetch(`${Webflow.API_SITES_URL}/products/${webflowProductId}/skus`, {
|
||||
|
||||
Reference in New Issue
Block a user