snapshot.ts

1.8 kB · typescript · 54 lines

1import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";2import { join, resolve } from "node:path";3import { feed, type ProductRow } from "../lib/shop.ts";4import { loadEnv, need } from "../lib/env.ts";5import { client, getText, putBytes } from "../../aws/s3.ts";6import site from "../site.json";78loadEnv();910const org = resolve(import.meta.dir, "..");11const data = join(org, "data");12const s3 = client(need("CARLOMITCHENER_BUCKET"));13const SHOP = "data/shop.json";1415async function pull(key: string): Promise<string[]> {16  const local = join(data, "tasks", key, `${key}.json`);17  if (!existsSync(local)) {18    const found = await getText(s3, `data/tasks/${key}/${key}.json`);19    if (!found) {20      console.warn(`snapshot: no task for ${key}, no printfiles listed`);21      return [];22    }23    mkdirSync(join(data, "tasks", key), { recursive: true });24    writeFileSync(local, found);25  }26  try {27    const task = JSON.parse(readFileSync(local, "utf8"));28    return (task.printfiles ?? []).map((one: { name: string }) => one.name).filter(Boolean);29  } catch {30    return [];31  }32}3334const rows: ProductRow[] = await feed({35  shop: need("SHOPIFY_SHOP_URL"),36  token: need("SHOPIFY_PUBLIC_ACCESS_TOKEN"),37  api: site.api,38  country: site.country,39  live: site.live,40});4142for (const row of rows) row.files = await pull(row.key);4344const snapshot = { at: Date.now(), products: rows };45const path = join(data, "shop.json");46const body = JSON.stringify(snapshot, null, 2) + "\n";47mkdirSync(data, { recursive: true });48writeFileSync(path, body);49console.log(`snapshot: ${rows.length} products into data/shop.json`);5051if (process.argv.includes("--upload")) {52  await putBytes(s3, SHOP, body, { type: "application/json", cacheControl: "no-store" });53  console.log(`snapshot: uploaded to s3://${need("CARLOMITCHENER_BUCKET")}/${SHOP}`);54}