import { json, type ActionFunctionArgs, type LoaderFunctionArgs } from "@remix-run/node"; import { v4 as uuidv4 } from "uuid"; import { authenticate, unauthenticated } from "../shopify.server"; import { runActivityCheck } from "../services/activity.server"; import { getActivityConfig } from "../services/config.server"; import { callPush, callStatus } from "../services/dreame-client.server"; import { findSuccessfulPush, recordSuccessfulPush } from "../services/idempotency.server"; import { logActivityPush } from "../services/logger.server"; import { getOrderDetails } from "../services/order.server"; const CORS_HEADERS = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Authorization, Content-Type", "Access-Control-Allow-Methods": "POST, OPTIONS", }; type ActivityRequestBody = { orderId?: string; orderNumber?: string; locale?: string; }; export async function loader({ request }: LoaderFunctionArgs) { if (request.method === "OPTIONS") { return new Response(null, { status: 204, headers: CORS_HEADERS }); } return json({ success: false }, { status: 405, headers: CORS_HEADERS }); } export async function action({ request }: ActionFunctionArgs) { if (request.method === "OPTIONS") { return new Response(null, { status: 204, headers: CORS_HEADERS }); } if (request.method !== "POST") { return json({ success: false }, { status: 405, headers: CORS_HEADERS }); } try { const checkoutAuth = (authenticate as unknown as { public?: { checkout?: (request: Request) => Promise } }) .public?.checkout; if (!checkoutAuth) { throw new Error("Shopify checkout authentication is unavailable"); } const authResult = (await checkoutAuth(request)) as { shop?: string; admin?: unknown; sessionToken?: { dest?: string; iss?: string }; session?: { shop?: string }; }; const shop = authResult.shop || authResult.session?.shop || shopFromSessionToken(authResult.sessionToken); const adminResult = authResult.admin ? { admin: authResult.admin } : shop ? await unauthenticated.admin(shop) : null; const admin = adminResult?.admin as { graphql: (query: string, options?: { variables?: Record }) => Promise; }; if (!shop || !admin) { throw new Error("Invalid Shopify checkout session"); } const body = (await request.json()) as ActivityRequestBody; if (!body.orderId) { return json({ success: false }, { headers: CORS_HEADERS }); } const result = await runActivityCheck( { shop, orderId: body.orderId, orderNumber: body.orderNumber, locale: body.locale, }, { nowMs: () => Date.now(), uuid: uuidv4, getOrder: (_shop, orderId) => getOrderDetails(admin, orderId), getConfig: () => getActivityConfig(admin), findSuccess: findSuccessfulPush, recordSuccess: recordSuccessfulPush, log: logActivityPush, callStatus, callPush, }, ); return json(result, { headers: CORS_HEADERS }); } catch { return json({ success: false }, { headers: CORS_HEADERS }); } } function shopFromSessionToken(sessionToken: { dest?: string; iss?: string } | undefined): string | undefined { const source = sessionToken?.dest || sessionToken?.iss; if (!source) { return undefined; } try { return new URL(source).hostname; } catch { return source.replace(/^https?:\/\//, "").split("/")[0]; } }