@jytextiles/medusa-plugin-faire-store-sync 0.1.0
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.
- package/.medusa/server/src/__tests__/ingest-faire-order-support.spec.js +74 -0
- package/.medusa/server/src/__tests__/webhook.spec.js +77 -0
- package/.medusa/server/src/admin/index.js +960 -0
- package/.medusa/server/src/admin/index.mjs +959 -0
- package/.medusa/server/src/api/admin/faire/auth/authorize/route.js +12 -0
- package/.medusa/server/src/api/admin/faire/auth/callback/route.js +25 -0
- package/.medusa/server/src/api/admin/faire/auth/disconnect/route.js +12 -0
- package/.medusa/server/src/api/admin/faire/brand/route.js +14 -0
- package/.medusa/server/src/api/admin/faire/ingest/orders/[batchId]/route.js +27 -0
- package/.medusa/server/src/api/admin/faire/ingest/orders/route.js +20 -0
- package/.medusa/server/src/api/admin/faire/products/route.js +16 -0
- package/.medusa/server/src/api/admin/faire/settings/route.js +19 -0
- package/.medusa/server/src/api/admin/faire/status/product/[id]/route.js +30 -0
- package/.medusa/server/src/api/admin/faire/status/route.js +46 -0
- package/.medusa/server/src/api/admin/faire/sync/bulk/[batchId]/route.js +29 -0
- package/.medusa/server/src/api/admin/faire/sync/bulk/route.js +20 -0
- package/.medusa/server/src/api/admin/faire/sync/product/[id]/route.js +14 -0
- package/.medusa/server/src/api/admin/faire/syncs/[id]/route.js +32 -0
- package/.medusa/server/src/api/admin/faire/syncs/route.js +18 -0
- package/.medusa/server/src/api/webhooks/faire/route.js +125 -0
- package/.medusa/server/src/jobs/pull-faire-orders.js +32 -0
- package/.medusa/server/src/jobs/refresh-faire-token.js +25 -0
- package/.medusa/server/src/lib/faire-client.js +321 -0
- package/.medusa/server/src/lib/types.js +10 -0
- package/.medusa/server/src/lib/webhook.js +58 -0
- package/.medusa/server/src/links/product-faire-sync-link.js +57 -0
- package/.medusa/server/src/modules/faire-sync/index.js +15 -0
- package/.medusa/server/src/modules/faire-sync/migrations/Migration20260707211346.js +34 -0
- package/.medusa/server/src/modules/faire-sync/models/faire-order.js +21 -0
- package/.medusa/server/src/modules/faire-sync/models/faire-sync-account.js +17 -0
- package/.medusa/server/src/modules/faire-sync/models/faire-sync-batch.js +18 -0
- package/.medusa/server/src/modules/faire-sync/models/faire-sync-record.js +22 -0
- package/.medusa/server/src/modules/faire-sync/models/faire-sync-settings.js +26 -0
- package/.medusa/server/src/modules/faire-sync/models/faire-webhook-event.js +21 -0
- package/.medusa/server/src/modules/faire-sync/service.js +222 -0
- package/.medusa/server/src/subscribers/faire-inventory-sync.js +87 -0
- package/.medusa/server/src/subscribers/faire-listing-events.js +46 -0
- package/.medusa/server/src/subscribers/faire-order-ingest.js +54 -0
- package/.medusa/server/src/subscribers/faire-order-lifecycle.js +71 -0
- package/.medusa/server/src/subscribers/faire-product-status-sync.js +71 -0
- package/.medusa/server/src/workflows/index.js +21 -0
- package/.medusa/server/src/workflows/ingest-faire-order-support.js +76 -0
- package/.medusa/server/src/workflows/ingest-faire-order.js +148 -0
- package/.medusa/server/src/workflows/ingest-faire-orders-bulk.js +124 -0
- package/.medusa/server/src/workflows/refresh-faire-token.js +20 -0
- package/.medusa/server/src/workflows/sync-product-to-faire.js +262 -0
- package/.medusa/server/src/workflows/sync-products-to-faire.js +90 -0
- package/LICENSE +21 -0
- package/README.md +180 -0
- package/package.json +84 -0
- package/scripts/postbuild.js +36 -0
- package/src/__tests__/ingest-faire-order-support.spec.ts +77 -0
- package/src/__tests__/webhook.spec.ts +81 -0
- package/src/admin/lib/api.ts +88 -0
- package/src/admin/routes/settings/faire/[id]/page.tsx +184 -0
- package/src/admin/routes/settings/faire/hooks/use-faire-sync-columns.tsx +80 -0
- package/src/admin/routes/settings/faire/page.tsx +445 -0
- package/src/admin/routes/settings/faire/settings/page.tsx +286 -0
- package/src/admin/routes/settings/oauth/faire/callback/page.tsx +67 -0
- package/src/admin/widgets/faire-product-widget.tsx +180 -0
- package/src/api/admin/faire/auth/authorize/route.ts +10 -0
- package/src/api/admin/faire/auth/callback/route.ts +29 -0
- package/src/api/admin/faire/auth/disconnect/route.ts +10 -0
- package/src/api/admin/faire/brand/route.ts +12 -0
- package/src/api/admin/faire/ingest/orders/[batchId]/route.ts +31 -0
- package/src/api/admin/faire/ingest/orders/route.ts +29 -0
- package/src/api/admin/faire/products/route.ts +14 -0
- package/src/api/admin/faire/settings/route.ts +17 -0
- package/src/api/admin/faire/status/product/[id]/route.ts +30 -0
- package/src/api/admin/faire/status/route.ts +47 -0
- package/src/api/admin/faire/sync/bulk/[batchId]/route.ts +33 -0
- package/src/api/admin/faire/sync/bulk/route.ts +27 -0
- package/src/api/admin/faire/sync/product/[id]/route.ts +13 -0
- package/src/api/admin/faire/syncs/[id]/route.ts +32 -0
- package/src/api/admin/faire/syncs/route.ts +17 -0
- package/src/api/webhooks/faire/route.ts +133 -0
- package/src/jobs/pull-faire-orders.ts +30 -0
- package/src/jobs/refresh-faire-token.ts +23 -0
- package/src/lib/faire-client.ts +436 -0
- package/src/lib/types.ts +117 -0
- package/src/lib/webhook.ts +85 -0
- package/src/links/product-faire-sync-link.ts +56 -0
- package/src/modules/faire-sync/index.ts +11 -0
- package/src/modules/faire-sync/migrations/.snapshot-medusa-faire-sync.json +1486 -0
- package/src/modules/faire-sync/migrations/Migration20260707211346.ts +43 -0
- package/src/modules/faire-sync/models/faire-order.ts +20 -0
- package/src/modules/faire-sync/models/faire-sync-account.ts +16 -0
- package/src/modules/faire-sync/models/faire-sync-batch.ts +17 -0
- package/src/modules/faire-sync/models/faire-sync-record.ts +21 -0
- package/src/modules/faire-sync/models/faire-sync-settings.ts +25 -0
- package/src/modules/faire-sync/models/faire-webhook-event.ts +20 -0
- package/src/modules/faire-sync/service.ts +252 -0
- package/src/subscribers/faire-inventory-sync.ts +97 -0
- package/src/subscribers/faire-listing-events.ts +48 -0
- package/src/subscribers/faire-order-ingest.ts +61 -0
- package/src/subscribers/faire-order-lifecycle.ts +81 -0
- package/src/subscribers/faire-product-status-sync.ts +76 -0
- package/src/workflows/index.ts +4 -0
- package/src/workflows/ingest-faire-order-support.ts +96 -0
- package/src/workflows/ingest-faire-order.ts +212 -0
- package/src/workflows/ingest-faire-orders-bulk.ts +168 -0
- package/src/workflows/refresh-faire-token.ts +28 -0
- package/src/workflows/sync-product-to-faire.ts +375 -0
- package/src/workflows/sync-products-to-faire.ts +133 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const faire_sync_1 = require("../../../../../modules/faire-sync");
|
|
5
|
+
// GET /admin/faire/auth/authorize — begins OAuth, returns the Faire authorize URL
|
|
6
|
+
const GET = async (req, res) => {
|
|
7
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
8
|
+
const { authorization_url, state } = await service.startOAuth();
|
|
9
|
+
res.json({ authorization_url, state });
|
|
10
|
+
};
|
|
11
|
+
exports.GET = GET;
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL2F1dGgvYXV0aG9yaXplL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLGtFQUFxRTtBQUdyRSxrRkFBa0Y7QUFDM0UsTUFBTSxHQUFHLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ25FLE1BQU0sT0FBTyxHQUFxQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyw4QkFBaUIsQ0FBQyxDQUFBO0lBQ3RFLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQTtJQUMvRCxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsaUJBQWlCLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQTtBQUN4QyxDQUFDLENBQUE7QUFKWSxRQUFBLEdBQUcsT0FJZiJ9
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const faire_sync_1 = require("../../../../../modules/faire-sync");
|
|
6
|
+
// POST /admin/faire/auth/callback — exchanges the OAuth code (called by the
|
|
7
|
+
// admin SPA callback page, so it runs with an authenticated admin session).
|
|
8
|
+
const POST = async (req, res) => {
|
|
9
|
+
const { code, state } = req.body;
|
|
10
|
+
if (!code || !state) {
|
|
11
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "code and state are required");
|
|
12
|
+
}
|
|
13
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
14
|
+
const { account, brand } = await service.completeOAuth(code, state);
|
|
15
|
+
res.json({
|
|
16
|
+
account: {
|
|
17
|
+
id: account.id,
|
|
18
|
+
brand_id: account.brand_id,
|
|
19
|
+
brand_name: account.brand_name,
|
|
20
|
+
},
|
|
21
|
+
brand,
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
exports.POST = POST;
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL2F1dGgvY2FsbGJhY2svcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EscURBQXVEO0FBQ3ZELGtFQUFxRTtBQUdyRSw0RUFBNEU7QUFDNUUsNEVBQTRFO0FBQ3JFLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFBRSxHQUFrQixFQUFFLEdBQW1CLEVBQUUsRUFBRTtJQUNwRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLEdBQUcsQ0FBQyxJQUF1QyxDQUFBO0lBRW5FLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNwQixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5Qiw2QkFBNkIsQ0FDOUIsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLE9BQU8sR0FBcUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsOEJBQWlCLENBQUMsQ0FBQTtJQUN0RSxNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLE1BQU0sT0FBTyxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUE7SUFFbkUsR0FBRyxDQUFDLElBQUksQ0FBQztRQUNQLE9BQU8sRUFBRTtZQUNQLEVBQUUsRUFBRyxPQUFlLENBQUMsRUFBRTtZQUN2QixRQUFRLEVBQUcsT0FBZSxDQUFDLFFBQVE7WUFDbkMsVUFBVSxFQUFHLE9BQWUsQ0FBQyxVQUFVO1NBQ3hDO1FBQ0QsS0FBSztLQUNOLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQTtBQXJCWSxRQUFBLElBQUksUUFxQmhCIn0=
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = void 0;
|
|
4
|
+
const faire_sync_1 = require("../../../../../modules/faire-sync");
|
|
5
|
+
// POST /admin/faire/auth/disconnect
|
|
6
|
+
const POST = async (req, res) => {
|
|
7
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
8
|
+
await service.disconnect();
|
|
9
|
+
res.json({ disconnected: true });
|
|
10
|
+
};
|
|
11
|
+
exports.POST = POST;
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL2F1dGgvZGlzY29ubmVjdC9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxrRUFBcUU7QUFHckUsb0NBQW9DO0FBQzdCLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFBRSxHQUFrQixFQUFFLEdBQW1CLEVBQUUsRUFBRTtJQUNwRSxNQUFNLE9BQU8sR0FBcUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsOEJBQWlCLENBQUMsQ0FBQTtJQUN0RSxNQUFNLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQTtJQUMxQixHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7QUFDbEMsQ0FBQyxDQUFBO0FBSlksUUFBQSxJQUFJLFFBSWhCIn0=
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const faire_sync_1 = require("../../../../modules/faire-sync");
|
|
5
|
+
// GET /admin/faire/brand — the connected Faire brand (fresh token)
|
|
6
|
+
const GET = async (req, res) => {
|
|
7
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
8
|
+
const account = await service.ensureFreshToken();
|
|
9
|
+
const client = service.getClient();
|
|
10
|
+
const brand = await client.getBrand(account.access_token);
|
|
11
|
+
res.json({ brand });
|
|
12
|
+
};
|
|
13
|
+
exports.GET = GET;
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL2JyYW5kL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLCtEQUFrRTtBQUdsRSxtRUFBbUU7QUFDNUQsTUFBTSxHQUFHLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ25FLE1BQU0sT0FBTyxHQUFxQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyw4QkFBaUIsQ0FBQyxDQUFBO0lBQ3RFLE1BQU0sT0FBTyxHQUFHLE1BQU0sT0FBTyxDQUFDLGdCQUFnQixFQUFFLENBQUE7SUFDaEQsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFBO0lBQ2xDLE1BQU0sS0FBSyxHQUFHLE1BQU0sTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUE7SUFDekQsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUE7QUFDckIsQ0FBQyxDQUFBO0FBTlksUUFBQSxHQUFHLE9BTWYifQ==
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const faire_sync_1 = require("../../../../../../modules/faire-sync");
|
|
6
|
+
// GET /admin/faire/ingest/orders/:batchId — poll bulk order-ingest progress
|
|
7
|
+
const GET = async (req, res) => {
|
|
8
|
+
const { batchId } = req.params;
|
|
9
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
10
|
+
const batch = await service.retrieveFaireSyncBatch(batchId).catch(() => null);
|
|
11
|
+
if (!batch) {
|
|
12
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Batch not found");
|
|
13
|
+
}
|
|
14
|
+
const total = batch.total_products || 0;
|
|
15
|
+
const done = (batch.synced_count || 0) + (batch.failed_count || 0);
|
|
16
|
+
res.json({
|
|
17
|
+
batch,
|
|
18
|
+
progress: {
|
|
19
|
+
total,
|
|
20
|
+
done,
|
|
21
|
+
pct: total ? Math.round((done / total) * 100) : 0,
|
|
22
|
+
finished: batch.status === "completed" || batch.status === "failed",
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
exports.GET = GET;
|
|
27
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL2luZ2VzdC9vcmRlcnMvW2JhdGNoSWRdL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHFEQUF1RDtBQUN2RCxxRUFBd0U7QUFHeEUsNEVBQTRFO0FBQ3JFLE1BQU0sR0FBRyxHQUFHLEtBQUssRUFBRSxHQUFrQixFQUFFLEdBQW1CLEVBQUUsRUFBRTtJQUNuRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQTtJQUM5QixNQUFNLE9BQU8sR0FBcUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsOEJBQWlCLENBQUMsQ0FBQTtJQUV0RSxNQUFNLEtBQUssR0FBRyxNQUFNLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUE7SUFFN0UsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1gsTUFBTSxJQUFJLG1CQUFXLENBQUMsbUJBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLGlCQUFpQixDQUFDLENBQUE7SUFDdkUsQ0FBQztJQUVELE1BQU0sS0FBSyxHQUFJLEtBQWEsQ0FBQyxjQUFjLElBQUksQ0FBQyxDQUFBO0lBQ2hELE1BQU0sSUFBSSxHQUNSLENBQUUsS0FBYSxDQUFDLFlBQVksSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFFLEtBQWEsQ0FBQyxZQUFZLElBQUksQ0FBQyxDQUFDLENBQUE7SUFFekUsR0FBRyxDQUFDLElBQUksQ0FBQztRQUNQLEtBQUs7UUFDTCxRQUFRLEVBQUU7WUFDUixLQUFLO1lBQ0wsSUFBSTtZQUNKLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakQsUUFBUSxFQUNMLEtBQWEsQ0FBQyxNQUFNLEtBQUssV0FBVyxJQUFLLEtBQWEsQ0FBQyxNQUFNLEtBQUssUUFBUTtTQUM5RTtLQUNGLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQTtBQXhCWSxRQUFBLEdBQUcsT0F3QmYifQ==
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const ingest_faire_orders_bulk_1 = require("../../../../../workflows/ingest-faire-orders-bulk");
|
|
6
|
+
// POST /admin/faire/ingest/orders — pull Faire orders and create Medusa orders
|
|
7
|
+
// for them. Runs as a long-running background workflow; returns a batch id the
|
|
8
|
+
// client can poll at GET /admin/faire/ingest/orders/:batchId.
|
|
9
|
+
const POST = async (req, res) => {
|
|
10
|
+
const limit = req.body?.limit;
|
|
11
|
+
if (limit != null && (!Number.isFinite(limit) || limit <= 0)) {
|
|
12
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "limit must be a positive number");
|
|
13
|
+
}
|
|
14
|
+
const { result } = await (0, ingest_faire_orders_bulk_1.ingestFaireOrdersBulkWorkflow)(req.scope).run({
|
|
15
|
+
input: { limit },
|
|
16
|
+
});
|
|
17
|
+
res.status(202).json({ batch_id: result.batch_id, status: "processing" });
|
|
18
|
+
};
|
|
19
|
+
exports.POST = POST;
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL2luZ2VzdC9vcmRlcnMvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EscURBQXVEO0FBQ3ZELGdHQUFpRztBQU1qRywrRUFBK0U7QUFDL0UsK0VBQStFO0FBQy9FLDhEQUE4RDtBQUN2RCxNQUFNLElBQUksR0FBRyxLQUFLLEVBQ3ZCLEdBQW9DLEVBQ3BDLEdBQW1CLEVBQ25CLEVBQUU7SUFDRixNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQTtJQUM3QixJQUFJLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDN0QsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsaUNBQWlDLENBQ2xDLENBQUE7SUFDSCxDQUFDO0lBRUQsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBQSx3REFBNkIsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ3BFLEtBQUssRUFBRSxFQUFFLEtBQUssRUFBRTtLQUNqQixDQUFDLENBQUE7SUFFRixHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLFFBQVEsRUFBRyxNQUFjLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFBO0FBQ3BGLENBQUMsQ0FBQTtBQWpCWSxRQUFBLElBQUksUUFpQmhCIn0=
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const faire_sync_1 = require("../../../../modules/faire-sync");
|
|
5
|
+
// GET /admin/faire/products — list products already on Faire (paginated)
|
|
6
|
+
const GET = async (req, res) => {
|
|
7
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
8
|
+
const account = await service.ensureFreshToken();
|
|
9
|
+
const client = service.getClient();
|
|
10
|
+
const limit = Number(req.query.limit) || 50;
|
|
11
|
+
const page = req.query.page ? Number(req.query.page) : 1;
|
|
12
|
+
const data = await client.listProducts(account.access_token, { limit, page });
|
|
13
|
+
res.json({ products: data.results, count: data.count });
|
|
14
|
+
};
|
|
15
|
+
exports.GET = GET;
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL3Byb2R1Y3RzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLCtEQUFrRTtBQUdsRSx5RUFBeUU7QUFDbEUsTUFBTSxHQUFHLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ25FLE1BQU0sT0FBTyxHQUFxQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyw4QkFBaUIsQ0FBQyxDQUFBO0lBQ3RFLE1BQU0sT0FBTyxHQUFHLE1BQU0sT0FBTyxDQUFDLGdCQUFnQixFQUFFLENBQUE7SUFDaEQsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFBO0lBQ2xDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQTtJQUMzQyxNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUN4RCxNQUFNLElBQUksR0FBRyxNQUFNLE1BQU0sQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0lBQzdFLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUE7QUFDekQsQ0FBQyxDQUFBO0FBUlksUUFBQSxHQUFHLE9BUWYifQ==
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = exports.GET = void 0;
|
|
4
|
+
const faire_sync_1 = require("../../../../modules/faire-sync");
|
|
5
|
+
// GET /admin/faire/settings
|
|
6
|
+
const GET = async (req, res) => {
|
|
7
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
8
|
+
const settings = await service.getSettings();
|
|
9
|
+
res.json({ settings });
|
|
10
|
+
};
|
|
11
|
+
exports.GET = GET;
|
|
12
|
+
// POST /admin/faire/settings
|
|
13
|
+
const POST = async (req, res) => {
|
|
14
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
15
|
+
const settings = await service.updateSettings(req.body || {});
|
|
16
|
+
res.json({ settings });
|
|
17
|
+
};
|
|
18
|
+
exports.POST = POST;
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL3NldHRpbmdzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLCtEQUFrRTtBQUdsRSw0QkFBNEI7QUFDckIsTUFBTSxHQUFHLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ25FLE1BQU0sT0FBTyxHQUFxQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyw4QkFBaUIsQ0FBQyxDQUFBO0lBQ3RFLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFBO0lBQzVDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFBO0FBQ3hCLENBQUMsQ0FBQTtBQUpZLFFBQUEsR0FBRyxPQUlmO0FBRUQsNkJBQTZCO0FBQ3RCLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFBRSxHQUFrQixFQUFFLEdBQW1CLEVBQUUsRUFBRTtJQUNwRSxNQUFNLE9BQU8sR0FBcUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsOEJBQWlCLENBQUMsQ0FBQTtJQUN0RSxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUM3RCxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQTtBQUN4QixDQUFDLENBQUE7QUFKWSxRQUFBLElBQUksUUFJaEIifQ==
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const faire_sync_1 = require("../../../../../../modules/faire-sync");
|
|
5
|
+
// GET /admin/faire/status/product/:id — latest sync state for a single product.
|
|
6
|
+
const GET = async (req, res) => {
|
|
7
|
+
const { id } = req.params;
|
|
8
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
9
|
+
const connected = !!(await service.getActiveAccount());
|
|
10
|
+
const [records] = await service.listSyncRecords({ product_id: id }, 1, 0);
|
|
11
|
+
const latest = records?.[0] ?? null;
|
|
12
|
+
res.json({
|
|
13
|
+
connected,
|
|
14
|
+
synced: !!latest,
|
|
15
|
+
latest: latest
|
|
16
|
+
? {
|
|
17
|
+
id: latest.id,
|
|
18
|
+
status: latest.status,
|
|
19
|
+
product_token: latest.product_token,
|
|
20
|
+
product_url: latest.product_url,
|
|
21
|
+
product_state: latest.product_state,
|
|
22
|
+
published: latest.published,
|
|
23
|
+
error_message: latest.error_message,
|
|
24
|
+
synced_at: latest.synced_at,
|
|
25
|
+
}
|
|
26
|
+
: null,
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
exports.GET = GET;
|
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL3N0YXR1cy9wcm9kdWN0L1tpZF0vcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EscUVBQXdFO0FBR3hFLGdGQUFnRjtBQUN6RSxNQUFNLEdBQUcsR0FBRyxLQUFLLEVBQUUsR0FBa0IsRUFBRSxHQUFtQixFQUFFLEVBQUU7SUFDbkUsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUE7SUFDekIsTUFBTSxPQUFPLEdBQXFCLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLDhCQUFpQixDQUFDLENBQUE7SUFFdEUsTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFBO0lBQ3RELE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxNQUFNLE9BQU8sQ0FBQyxlQUFlLENBQUMsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO0lBQ3pFLE1BQU0sTUFBTSxHQUFRLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQTtJQUV4QyxHQUFHLENBQUMsSUFBSSxDQUFDO1FBQ1AsU0FBUztRQUNULE1BQU0sRUFBRSxDQUFDLENBQUMsTUFBTTtRQUNoQixNQUFNLEVBQUUsTUFBTTtZQUNaLENBQUMsQ0FBQztnQkFDRSxFQUFFLEVBQUUsTUFBTSxDQUFDLEVBQUU7Z0JBQ2IsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNO2dCQUNyQixhQUFhLEVBQUUsTUFBTSxDQUFDLGFBQWE7Z0JBQ25DLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVztnQkFDL0IsYUFBYSxFQUFFLE1BQU0sQ0FBQyxhQUFhO2dCQUNuQyxTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVM7Z0JBQzNCLGFBQWEsRUFBRSxNQUFNLENBQUMsYUFBYTtnQkFDbkMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTO2FBQzVCO1lBQ0gsQ0FBQyxDQUFDLElBQUk7S0FDVCxDQUFDLENBQUE7QUFDSixDQUFDLENBQUE7QUF4QlksUUFBQSxHQUFHLE9Bd0JmIn0=
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const faire_sync_1 = require("../../../../modules/faire-sync");
|
|
5
|
+
// GET /admin/faire/status — connection status + readiness checklist
|
|
6
|
+
const GET = async (req, res) => {
|
|
7
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
8
|
+
const account = await service.getActiveAccount();
|
|
9
|
+
const settings = await service.getSettings();
|
|
10
|
+
const connected = !!account && account.is_active;
|
|
11
|
+
const hasBrand = !!settings.default_brand_id;
|
|
12
|
+
const hasMarkup = settings.default_wholesale_markup_percent != null &&
|
|
13
|
+
settings.default_wholesale_markup_percent > 0;
|
|
14
|
+
const hasShipping = !!settings.default_shipping_policy_id;
|
|
15
|
+
res.json({
|
|
16
|
+
connected,
|
|
17
|
+
account: account
|
|
18
|
+
? {
|
|
19
|
+
id: account.id,
|
|
20
|
+
brand_id: account.brand_id,
|
|
21
|
+
brand_name: account.brand_name,
|
|
22
|
+
currency: account.currency,
|
|
23
|
+
token_expires_at: account.token_expires_at,
|
|
24
|
+
}
|
|
25
|
+
: null,
|
|
26
|
+
settings: {
|
|
27
|
+
default_brand_id: settings.default_brand_id,
|
|
28
|
+
default_wholesale_markup_percent: settings.default_wholesale_markup_percent,
|
|
29
|
+
default_min_order_quantity: settings.default_min_order_quantity,
|
|
30
|
+
default_lead_time_days: settings.default_lead_time_days,
|
|
31
|
+
default_shipping_policy_id: settings.default_shipping_policy_id,
|
|
32
|
+
default_category: settings.default_category,
|
|
33
|
+
auto_publish: settings.auto_publish,
|
|
34
|
+
follow_product_status: settings.follow_product_status,
|
|
35
|
+
},
|
|
36
|
+
readiness: {
|
|
37
|
+
connected,
|
|
38
|
+
brand: hasBrand,
|
|
39
|
+
wholesale_pricing: hasMarkup,
|
|
40
|
+
shipping_policy: hasShipping,
|
|
41
|
+
ready_to_publish: connected && hasBrand,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
exports.GET = GET;
|
|
46
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL3N0YXR1cy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSwrREFBa0U7QUFHbEUsb0VBQW9FO0FBQzdELE1BQU0sR0FBRyxHQUFHLEtBQUssRUFBRSxHQUFrQixFQUFFLEdBQW1CLEVBQUUsRUFBRTtJQUNuRSxNQUFNLE9BQU8sR0FBcUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsOEJBQWlCLENBQUMsQ0FBQTtJQUN0RSxNQUFNLE9BQU8sR0FBRyxNQUFNLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFBO0lBQ2hELE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFBO0lBRTVDLE1BQU0sU0FBUyxHQUFHLENBQUMsQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLFNBQVMsQ0FBQTtJQUNoRCxNQUFNLFFBQVEsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFBO0lBQzVDLE1BQU0sU0FBUyxHQUNiLFFBQVEsQ0FBQyxnQ0FBZ0MsSUFBSSxJQUFJO1FBQ2pELFFBQVEsQ0FBQyxnQ0FBZ0MsR0FBRyxDQUFDLENBQUE7SUFDL0MsTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQywwQkFBMEIsQ0FBQTtJQUV6RCxHQUFHLENBQUMsSUFBSSxDQUFDO1FBQ1AsU0FBUztRQUNULE9BQU8sRUFBRSxPQUFPO1lBQ2QsQ0FBQyxDQUFDO2dCQUNFLEVBQUUsRUFBRSxPQUFPLENBQUMsRUFBRTtnQkFDZCxRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVE7Z0JBQzFCLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTtnQkFDOUIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO2dCQUMxQixnQkFBZ0IsRUFBRSxPQUFPLENBQUMsZ0JBQWdCO2FBQzNDO1lBQ0gsQ0FBQyxDQUFDLElBQUk7UUFDUixRQUFRLEVBQUU7WUFDUixnQkFBZ0IsRUFBRSxRQUFRLENBQUMsZ0JBQWdCO1lBQzNDLGdDQUFnQyxFQUFFLFFBQVEsQ0FBQyxnQ0FBZ0M7WUFDM0UsMEJBQTBCLEVBQUUsUUFBUSxDQUFDLDBCQUEwQjtZQUMvRCxzQkFBc0IsRUFBRSxRQUFRLENBQUMsc0JBQXNCO1lBQ3ZELDBCQUEwQixFQUFFLFFBQVEsQ0FBQywwQkFBMEI7WUFDL0QsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDLGdCQUFnQjtZQUMzQyxZQUFZLEVBQUUsUUFBUSxDQUFDLFlBQVk7WUFDbkMscUJBQXFCLEVBQUUsUUFBUSxDQUFDLHFCQUFxQjtTQUN0RDtRQUNELFNBQVMsRUFBRTtZQUNULFNBQVM7WUFDVCxLQUFLLEVBQUUsUUFBUTtZQUNmLGlCQUFpQixFQUFFLFNBQVM7WUFDNUIsZUFBZSxFQUFFLFdBQVc7WUFDNUIsZ0JBQWdCLEVBQUUsU0FBUyxJQUFJLFFBQVE7U0FDeEM7S0FDRixDQUFDLENBQUE7QUFDSixDQUFDLENBQUE7QUF6Q1ksUUFBQSxHQUFHLE9BeUNmIn0=
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const faire_sync_1 = require("../../../../../../modules/faire-sync");
|
|
6
|
+
// GET /admin/faire/sync/bulk/:batchId — poll the progress of a background batch
|
|
7
|
+
const GET = async (req, res) => {
|
|
8
|
+
const { batchId } = req.params;
|
|
9
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
10
|
+
const batch = await service
|
|
11
|
+
.retrieveFaireSyncBatch(batchId)
|
|
12
|
+
.catch(() => null);
|
|
13
|
+
if (!batch) {
|
|
14
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Batch not found");
|
|
15
|
+
}
|
|
16
|
+
const total = batch.total_products || 0;
|
|
17
|
+
const done = (batch.synced_count || 0) + (batch.failed_count || 0);
|
|
18
|
+
res.json({
|
|
19
|
+
batch,
|
|
20
|
+
progress: {
|
|
21
|
+
total,
|
|
22
|
+
done,
|
|
23
|
+
pct: total ? Math.round((done / total) * 100) : 0,
|
|
24
|
+
finished: batch.status === "completed" || batch.status === "failed",
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
exports.GET = GET;
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL3N5bmMvYnVsay9bYmF0Y2hJZF0vcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EscURBQXVEO0FBQ3ZELHFFQUF3RTtBQUd4RSxnRkFBZ0Y7QUFDekUsTUFBTSxHQUFHLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ25FLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFBO0lBQzlCLE1BQU0sT0FBTyxHQUFxQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyw4QkFBaUIsQ0FBQyxDQUFBO0lBRXRFLE1BQU0sS0FBSyxHQUFHLE1BQU0sT0FBTztTQUN4QixzQkFBc0IsQ0FBQyxPQUFPLENBQUM7U0FDL0IsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBRXBCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNYLE1BQU0sSUFBSSxtQkFBVyxDQUFDLG1CQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFBO0lBQ3ZFLENBQUM7SUFFRCxNQUFNLEtBQUssR0FBSSxLQUFhLENBQUMsY0FBYyxJQUFJLENBQUMsQ0FBQTtJQUNoRCxNQUFNLElBQUksR0FDUixDQUFFLEtBQWEsQ0FBQyxZQUFZLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBRSxLQUFhLENBQUMsWUFBWSxJQUFJLENBQUMsQ0FBQyxDQUFBO0lBRXpFLEdBQUcsQ0FBQyxJQUFJLENBQUM7UUFDUCxLQUFLO1FBQ0wsUUFBUSxFQUFFO1lBQ1IsS0FBSztZQUNMLElBQUk7WUFDSixHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2pELFFBQVEsRUFDTCxLQUFhLENBQUMsTUFBTSxLQUFLLFdBQVcsSUFBSyxLQUFhLENBQUMsTUFBTSxLQUFLLFFBQVE7U0FDOUU7S0FDRixDQUFDLENBQUE7QUFDSixDQUFDLENBQUE7QUExQlksUUFBQSxHQUFHLE9BMEJmIn0=
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const sync_products_to_faire_1 = require("../../../../../workflows/sync-products-to-faire");
|
|
6
|
+
// POST /admin/faire/sync/bulk — sync many products (long-running background workflow)
|
|
7
|
+
const POST = async (req, res) => {
|
|
8
|
+
const { product_ids } = req.body || {};
|
|
9
|
+
if (!product_ids?.length) {
|
|
10
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "product_ids array is required");
|
|
11
|
+
}
|
|
12
|
+
const { result } = await (0, sync_products_to_faire_1.syncProductsToFaireWorkflow)(req.scope).run({
|
|
13
|
+
input: { product_ids },
|
|
14
|
+
});
|
|
15
|
+
// The workflow runs the per-product sync in the background; we return the
|
|
16
|
+
// batch id immediately so the client can poll GET /admin/faire/sync/bulk/:id.
|
|
17
|
+
res.status(202).json({ batch_id: result.batch_id, status: "processing" });
|
|
18
|
+
};
|
|
19
|
+
exports.POST = POST;
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL3N5bmMvYnVsay9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxREFBdUQ7QUFDdkQsNEZBQTZGO0FBTTdGLHNGQUFzRjtBQUMvRSxNQUFNLElBQUksR0FBRyxLQUFLLEVBQUUsR0FBZ0MsRUFBRSxHQUFtQixFQUFFLEVBQUU7SUFDbEYsTUFBTSxFQUFFLFdBQVcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFBO0lBRXRDLElBQUksQ0FBQyxXQUFXLEVBQUUsTUFBTSxFQUFFLENBQUM7UUFDekIsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsK0JBQStCLENBQ2hDLENBQUE7SUFDSCxDQUFDO0lBRUQsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBQSxvREFBMkIsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ2xFLEtBQUssRUFBRSxFQUFFLFdBQVcsRUFBRTtLQUN2QixDQUFDLENBQUE7SUFFRiwwRUFBMEU7SUFDMUUsOEVBQThFO0lBQzlFLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFHLE1BQWMsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUE7QUFDcEYsQ0FBQyxDQUFBO0FBakJZLFFBQUEsSUFBSSxRQWlCaEIifQ==
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = void 0;
|
|
4
|
+
const sync_product_to_faire_1 = require("../../../../../../workflows/sync-product-to-faire");
|
|
5
|
+
// POST /admin/faire/sync/product/:id — sync a single product to Faire
|
|
6
|
+
const POST = async (req, res) => {
|
|
7
|
+
const { id } = req.params;
|
|
8
|
+
const { result } = await (0, sync_product_to_faire_1.syncProductToFaireWorkflow)(req.scope).run({
|
|
9
|
+
input: { product_id: id },
|
|
10
|
+
});
|
|
11
|
+
res.json({ result });
|
|
12
|
+
};
|
|
13
|
+
exports.POST = POST;
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL3N5bmMvcHJvZHVjdC9baWRdL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLDZGQUE4RjtBQUU5RixzRUFBc0U7QUFDL0QsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ3BFLE1BQU0sRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFBO0lBRXpCLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUEsa0RBQTBCLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUNqRSxLQUFLLEVBQUUsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFO0tBQzFCLENBQUMsQ0FBQTtJQUVGLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFBO0FBQ3RCLENBQUMsQ0FBQTtBQVJZLFFBQUEsSUFBSSxRQVFoQiJ9
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = exports.GET = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const faire_sync_1 = require("../../../../../modules/faire-sync");
|
|
6
|
+
const sync_product_to_faire_1 = require("../../../../../workflows/sync-product-to-faire");
|
|
7
|
+
// GET /admin/faire/syncs/:id — fetch a single sync record
|
|
8
|
+
const GET = async (req, res) => {
|
|
9
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
10
|
+
const { id } = req.params;
|
|
11
|
+
const [record] = await service.listFaireSyncRecords({ id }, { take: 1 });
|
|
12
|
+
if (!record) {
|
|
13
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Sync record not found");
|
|
14
|
+
}
|
|
15
|
+
res.json({ sync: record });
|
|
16
|
+
};
|
|
17
|
+
exports.GET = GET;
|
|
18
|
+
// POST /admin/faire/syncs/:id/retry — re-sync the product referenced by this record
|
|
19
|
+
const POST = async (req, res) => {
|
|
20
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
21
|
+
const { id } = req.params;
|
|
22
|
+
const [record] = await service.listFaireSyncRecords({ id }, { take: 1 });
|
|
23
|
+
if (!record) {
|
|
24
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Sync record not found");
|
|
25
|
+
}
|
|
26
|
+
const { result } = await (0, sync_product_to_faire_1.syncProductToFaireWorkflow)(req.scope).run({
|
|
27
|
+
input: { product_id: record.product_id },
|
|
28
|
+
});
|
|
29
|
+
res.json({ result });
|
|
30
|
+
};
|
|
31
|
+
exports.POST = POST;
|
|
32
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL3N5bmNzL1tpZF0vcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EscURBQXVEO0FBQ3ZELGtFQUFxRTtBQUVyRSwwRkFBMkY7QUFFM0YsMERBQTBEO0FBQ25ELE1BQU0sR0FBRyxHQUFHLEtBQUssRUFBRSxHQUFrQixFQUFFLEdBQW1CLEVBQUUsRUFBRTtJQUNuRSxNQUFNLE9BQU8sR0FBcUIsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsOEJBQWlCLENBQUMsQ0FBQTtJQUN0RSxNQUFNLEVBQUUsRUFBRSxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQTtJQUN6QixNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxPQUFPLENBQUMsb0JBQW9CLENBQUMsRUFBRSxFQUFFLEVBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQVMsQ0FBQyxDQUFBO0lBQ3RGLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE1BQU0sSUFBSSxtQkFBVyxDQUFDLG1CQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSx1QkFBdUIsQ0FBQyxDQUFBO0lBQzdFLENBQUM7SUFDRCxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUE7QUFDNUIsQ0FBQyxDQUFBO0FBUlksUUFBQSxHQUFHLE9BUWY7QUFFRCxvRkFBb0Y7QUFDN0UsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ3BFLE1BQU0sT0FBTyxHQUFxQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyw4QkFBaUIsQ0FBQyxDQUFBO0lBQ3RFLE1BQU0sRUFBRSxFQUFFLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFBO0lBQ3pCLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLEVBQUUsRUFBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBUyxDQUFDLENBQUE7SUFDdEYsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1osTUFBTSxJQUFJLG1CQUFXLENBQUMsbUJBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLHVCQUF1QixDQUFDLENBQUE7SUFDN0UsQ0FBQztJQUVELE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUEsa0RBQTBCLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUNqRSxLQUFLLEVBQUUsRUFBRSxVQUFVLEVBQUcsTUFBYyxDQUFDLFVBQVUsRUFBRTtLQUNsRCxDQUFDLENBQUE7SUFFRixHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQTtBQUN0QixDQUFDLENBQUE7QUFiWSxRQUFBLElBQUksUUFhaEIifQ==
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = void 0;
|
|
4
|
+
const faire_sync_1 = require("../../../../modules/faire-sync");
|
|
5
|
+
// GET /admin/faire/syncs — list recent sync records (paginated)
|
|
6
|
+
const GET = async (req, res) => {
|
|
7
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
8
|
+
const take = Number(req.query.take) || 20;
|
|
9
|
+
const skip = Number(req.query.skip) || 0;
|
|
10
|
+
const status = req.query.status;
|
|
11
|
+
const filters = {};
|
|
12
|
+
if (status)
|
|
13
|
+
filters.status = status;
|
|
14
|
+
const [records, count] = await service.listSyncRecords(filters, take, skip);
|
|
15
|
+
res.json({ syncs: records, count, take, skip });
|
|
16
|
+
};
|
|
17
|
+
exports.GET = GET;
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL2ZhaXJlL3N5bmNzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLCtEQUFrRTtBQUdsRSxnRUFBZ0U7QUFDekQsTUFBTSxHQUFHLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ25FLE1BQU0sT0FBTyxHQUFxQixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyw4QkFBaUIsQ0FBQyxDQUFBO0lBQ3RFLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQTtJQUN6QyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDeEMsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUE0QixDQUFBO0lBRXJELE1BQU0sT0FBTyxHQUFRLEVBQUUsQ0FBQTtJQUN2QixJQUFJLE1BQU07UUFBRSxPQUFPLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQTtJQUVuQyxNQUFNLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFBO0lBQzNFLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtBQUNqRCxDQUFDLENBQUE7QUFYWSxRQUFBLEdBQUcsT0FXZiJ9
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.POST = void 0;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
9
|
+
const faire_sync_1 = require("../../../modules/faire-sync");
|
|
10
|
+
const webhook_1 = require("../../../lib/webhook");
|
|
11
|
+
/**
|
|
12
|
+
* POST /webhooks/faire — inbound Faire webhook receiver.
|
|
13
|
+
*
|
|
14
|
+
* Faire signs each delivery with an HMAC-SHA256 of the raw body using the
|
|
15
|
+
* webhook secret shared at registration time, sent in the
|
|
16
|
+
* `X-Faire-Webhook-Signature` header. This route:
|
|
17
|
+
* 1. verifies the signature over the raw body,
|
|
18
|
+
* 2. records the delivery idempotently (unique delivery id),
|
|
19
|
+
* 3. best-effort fetches the resource referenced and re-emits a Medusa event
|
|
20
|
+
* `faire.<event_type>` so subscribers / visual flows can act on it,
|
|
21
|
+
* 4. always returns 200 once verified+recorded (Faire retries on non-2xx).
|
|
22
|
+
*
|
|
23
|
+
* Raw body is available because the host's middlewares.ts sets preserveRawBody
|
|
24
|
+
* for this path. Register the endpoint URL + copy the signing secret
|
|
25
|
+
* (FAIRE_WEBHOOK_SECRET) when you create the webhook via the Faire API.
|
|
26
|
+
*
|
|
27
|
+
* Faire emits events such as ORDER_PLACED, ORDER_CANCELED, ORDER_SHIPPED,
|
|
28
|
+
* INVENTORY_UPDATED, PRODUCT_UPDATED (verify against your Faire app's
|
|
29
|
+
* configuration). We normalize the event_type to lowercase for the emitted
|
|
30
|
+
* Medusa event name.
|
|
31
|
+
*/
|
|
32
|
+
const POST = async (req, res) => {
|
|
33
|
+
const logger = req.scope.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
|
|
34
|
+
const service = req.scope.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
35
|
+
const secret = service.getOptions().webhookSecret;
|
|
36
|
+
const rawBody = req.rawBody;
|
|
37
|
+
const rawStr = rawBody?.length ? rawBody.toString("utf8") : JSON.stringify(req.body ?? {});
|
|
38
|
+
const headers = {
|
|
39
|
+
signature: req.headers["x-faire-webhook-signature"],
|
|
40
|
+
timestamp: req.headers["x-faire-webhook-timestamp"],
|
|
41
|
+
};
|
|
42
|
+
const { valid, reason } = (0, webhook_1.verifyFaireWebhook)({ secret, headers, rawBody: rawStr });
|
|
43
|
+
if (!valid) {
|
|
44
|
+
logger?.warn?.(`[faire-webhook] rejected: ${reason}`);
|
|
45
|
+
return res.status(401).json({ error: "invalid signature" });
|
|
46
|
+
}
|
|
47
|
+
const payload = req.body ?? safeParse(rawStr);
|
|
48
|
+
const eventType = String(payload?.event_type || payload?.type || "unknown").toLowerCase();
|
|
49
|
+
// Delivery id — Faire sends a unique id per delivery; fall back to a hash of
|
|
50
|
+
// the body + type so we still dedupe if absent.
|
|
51
|
+
const webhookId = req.headers["x-faire-webhook-id"] ||
|
|
52
|
+
payload?.webhook_id ||
|
|
53
|
+
`${eventType}:${crypto_1.default.createHash("sha256").update(rawStr).digest("hex")}`;
|
|
54
|
+
// Idempotency — Faire retries with backoff; a verified duplicate is a no-op.
|
|
55
|
+
const existing = await service
|
|
56
|
+
.listFaireWebhookEvents({ webhook_id: webhookId })
|
|
57
|
+
.catch(() => []);
|
|
58
|
+
if (existing?.length) {
|
|
59
|
+
return res.status(200).json({ ok: true, duplicate: true });
|
|
60
|
+
}
|
|
61
|
+
let record;
|
|
62
|
+
try {
|
|
63
|
+
record = await service.createFaireWebhookEvents({
|
|
64
|
+
webhook_id: webhookId,
|
|
65
|
+
event_type: eventType,
|
|
66
|
+
brand_id: payload?.brand_id != null ? String(payload.brand_id) : null,
|
|
67
|
+
resource_url: payload?.resource_url ?? null,
|
|
68
|
+
payload,
|
|
69
|
+
received_at: new Date(),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Unique-constraint race → treat as duplicate.
|
|
74
|
+
return res.status(200).json({ ok: true, duplicate: true });
|
|
75
|
+
}
|
|
76
|
+
// Best-effort processing — never fail the webhook once it's verified+recorded.
|
|
77
|
+
try {
|
|
78
|
+
let resource = null;
|
|
79
|
+
if (payload?.resource_url) {
|
|
80
|
+
const account = await service.getActiveAccount();
|
|
81
|
+
if (account) {
|
|
82
|
+
resource = await service
|
|
83
|
+
.getClient()
|
|
84
|
+
.fetchResource(account.access_token, payload.resource_url)
|
|
85
|
+
.catch(() => null);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else if (payload?.data) {
|
|
89
|
+
resource = payload.data;
|
|
90
|
+
}
|
|
91
|
+
const eventBus = req.scope.resolve(utils_1.Modules.EVENT_BUS);
|
|
92
|
+
await eventBus.emit({
|
|
93
|
+
name: `faire.${eventType}`,
|
|
94
|
+
data: {
|
|
95
|
+
webhook_id: webhookId,
|
|
96
|
+
event_type: eventType,
|
|
97
|
+
brand_id: payload?.brand_id ?? null,
|
|
98
|
+
resource_url: payload?.resource_url ?? null,
|
|
99
|
+
resource,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
await service.updateFaireWebhookEvents({
|
|
103
|
+
id: record.id,
|
|
104
|
+
resource,
|
|
105
|
+
processed: true,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
logger?.warn?.(`[faire-webhook] processing failed for ${webhookId}: ${err?.message || err}`);
|
|
110
|
+
await service
|
|
111
|
+
.updateFaireWebhookEvents({ id: record.id, error: String(err?.message || err) })
|
|
112
|
+
.catch(() => { });
|
|
113
|
+
}
|
|
114
|
+
return res.status(200).json({ ok: true });
|
|
115
|
+
};
|
|
116
|
+
exports.POST = POST;
|
|
117
|
+
function safeParse(s) {
|
|
118
|
+
try {
|
|
119
|
+
return JSON.parse(s);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return {};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3dlYmhvb2tzL2ZhaXJlL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLG9EQUEyQjtBQUUzQixxREFBOEU7QUFDOUUsNERBQStEO0FBRS9ELGtEQUF5RDtBQUV6RDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSSxNQUFNLElBQUksR0FBRyxLQUFLLEVBQUUsR0FBa0IsRUFBRSxHQUFtQixFQUFFLEVBQUU7SUFDcEUsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsTUFBTSxDQUFRLENBQUE7SUFDekUsTUFBTSxPQUFPLEdBQXFCLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLDhCQUFpQixDQUFDLENBQUE7SUFDdEUsTUFBTSxNQUFNLEdBQUksT0FBTyxDQUFDLFVBQVUsRUFBVSxDQUFDLGFBQXVCLENBQUE7SUFFcEUsTUFBTSxPQUFPLEdBQUksR0FBVyxDQUFDLE9BQTZCLENBQUE7SUFDMUQsTUFBTSxNQUFNLEdBQUcsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0lBRTFGLE1BQU0sT0FBTyxHQUFHO1FBQ2QsU0FBUyxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsMkJBQTJCLENBQXVCO1FBQ3pFLFNBQVMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLDJCQUEyQixDQUF1QjtLQUMxRSxDQUFBO0lBRUQsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFBLDRCQUFrQixFQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFB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
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.config = void 0;
|
|
4
|
+
exports.default = pullFaireOrdersJob;
|
|
5
|
+
const faire_sync_1 = require("../modules/faire-sync");
|
|
6
|
+
const ingest_faire_orders_bulk_1 = require("../workflows/ingest-faire-orders-bulk");
|
|
7
|
+
/**
|
|
8
|
+
* Scheduled pull of new Faire orders. Runs the bulk order-ingestion workflow
|
|
9
|
+
* (a long-running background workflow) so new wholesale orders placed on Faire
|
|
10
|
+
* are mirrored into Medusa without a seller having to trigger it manually.
|
|
11
|
+
*
|
|
12
|
+
* Disable by setting FAIRE_AUTO_INGEST_ORDERS=false.
|
|
13
|
+
*/
|
|
14
|
+
async function pullFaireOrdersJob(container) {
|
|
15
|
+
if (process.env.FAIRE_AUTO_INGEST_ORDERS === "false")
|
|
16
|
+
return;
|
|
17
|
+
const service = container.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
18
|
+
const account = await service.getActiveAccount();
|
|
19
|
+
if (!account)
|
|
20
|
+
return;
|
|
21
|
+
try {
|
|
22
|
+
await (0, ingest_faire_orders_bulk_1.ingestFaireOrdersBulkWorkflow)(container).run({ input: {} });
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
console.error("[faire-sync] scheduled order pull failed:", err.message);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.config = {
|
|
29
|
+
name: "faire-pull-orders",
|
|
30
|
+
schedule: "*/30 * * * *", // every 30 minutes
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVsbC1mYWlyZS1vcmRlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvam9icy9wdWxsLWZhaXJlLW9yZGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFZQSxxQ0FZQztBQXZCRCxzREFBeUQ7QUFFekQsb0ZBQXFGO0FBRXJGOzs7Ozs7R0FNRztBQUNZLEtBQUssVUFBVSxrQkFBa0IsQ0FBQyxTQUEwQjtJQUN6RSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0JBQXdCLEtBQUssT0FBTztRQUFFLE9BQU07SUFFNUQsTUFBTSxPQUFPLEdBQXFCLFNBQVMsQ0FBQyxPQUFPLENBQUMsOEJBQWlCLENBQUMsQ0FBQTtJQUN0RSxNQUFNLE9BQU8sR0FBRyxNQUFNLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFBO0lBQ2hELElBQUksQ0FBQyxPQUFPO1FBQUUsT0FBTTtJQUVwQixJQUFJLENBQUM7UUFDSCxNQUFNLElBQUEsd0RBQTZCLEVBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFDbkUsQ0FBQztJQUFDLE9BQU8sR0FBUSxFQUFFLENBQUM7UUFDbEIsT0FBTyxDQUFDLEtBQUssQ0FBQywyQ0FBMkMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDekUsQ0FBQztBQUNILENBQUM7QUFFWSxRQUFBLE1BQU0sR0FBRztJQUNwQixJQUFJLEVBQUUsbUJBQW1CO0lBQ3pCLFFBQVEsRUFBRSxjQUFjLEVBQUUsbUJBQW1CO0NBQzlDLENBQUEifQ==
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.config = void 0;
|
|
4
|
+
exports.default = refreshFaireTokenJob;
|
|
5
|
+
const faire_sync_1 = require("../modules/faire-sync");
|
|
6
|
+
// Refreshes the Faire access token if it is set to expire (Faire tokens
|
|
7
|
+
// historically do not expire, but this keeps the OAuth2 path correct if yours do).
|
|
8
|
+
async function refreshFaireTokenJob(container) {
|
|
9
|
+
const service = container.resolve(faire_sync_1.FAIRE_SYNC_MODULE);
|
|
10
|
+
const account = await service.getActiveAccount();
|
|
11
|
+
if (!account) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
await service.ensureFreshToken(account);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
console.error("[faire-sync] token refresh failed:", err.message);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.config = {
|
|
22
|
+
name: "faire-refresh-token",
|
|
23
|
+
schedule: "*/10 * * * *",
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmcmVzaC1mYWlyZS10b2tlbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9qb2JzL3JlZnJlc2gtZmFpcmUtdG9rZW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBTUEsdUNBV0M7QUFoQkQsc0RBQXlEO0FBR3pELHdFQUF3RTtBQUN4RSxtRkFBbUY7QUFDcEUsS0FBSyxVQUFVLG9CQUFvQixDQUFDLFNBQTBCO0lBQzNFLE1BQU0sT0FBTyxHQUFxQixTQUFTLENBQUMsT0FBTyxDQUFDLDhCQUFpQixDQUFDLENBQUE7SUFDdEUsTUFBTSxPQUFPLEdBQUcsTUFBTSxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQTtJQUNoRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDYixPQUFNO0lBQ1IsQ0FBQztJQUNELElBQUksQ0FBQztRQUNILE1BQU0sT0FBTyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ3pDLENBQUM7SUFBQyxPQUFPLEdBQVEsRUFBRSxDQUFDO1FBQ2xCLE9BQU8sQ0FBQyxLQUFLLENBQUMsb0NBQW9DLEVBQUUsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ2xFLENBQUM7QUFDSCxDQUFDO0FBRVksUUFBQSxNQUFNLEdBQUc7SUFDcEIsSUFBSSxFQUFFLHFCQUFxQjtJQUMzQixRQUFRLEVBQUUsY0FBYztDQUN6QixDQUFBIn0=
|