Files
spsays-training/scripts/seed-te.ts
T
2026-04-17 22:51:58 +05:30

170 lines
4.5 KiB
TypeScript

/**
* seed-te.ts — Push Two Essays JSON data into MongoDB.
*
* Uses the native MongoDB driver (same pattern as seed-ej.ts) to avoid
* Prisma replica-set write requirements.
*
* Two Essays is a collection of 2 standalone essays using the NEW `essays`
* collection (not `prose_chapters`).
*
* Collections written:
* - book_meta → one doc { book: "te", data: <intro.json> }
* - essays → 2 essay docs
*
* Usage:
* npx tsx scripts/seed-te.ts
*/
import dotenv from "dotenv";
import fs from "fs";
import path from "path";
import { MongoClient } from "mongodb";
// Load env
dotenv.config({ path: ".env.local" });
dotenv.config({ path: ".env" });
const DATABASE_URL = process.env.DATABASE_URL;
if (!DATABASE_URL) {
console.error("❌ DATABASE_URL is not set in .env");
process.exit(1);
}
const BASE_DIR = path.resolve(__dirname, "..");
const TE_DIR = path.join(BASE_DIR, "lib", "jsons", "books", "te");
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
function readJson<T>(filePath: string): T {
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
}
/**
* Insert documents one at a time with a small delay every N docs.
* Uses insertOne to avoid BSON wire-protocol corruption.
*/
async function insertBatched(
col: ReturnType<ReturnType<MongoClient["db"]>["collection"]>,
docs: Record<string, unknown>[],
) {
for (let i = 0; i < docs.length; i++) {
await col.insertOne(docs[i]);
if ((i + 1) % 100 === 0) {
await new Promise((r) => setTimeout(r, 100));
}
}
}
// ---------------------------------------------------------------------------
// Types for the JSON files
// ---------------------------------------------------------------------------
type TeIntroJson = {
group: string;
title: string;
author: string;
year: number;
description: string;
essays: { slug: string; title: string; order: number }[];
};
type TeEssayJson = {
slug: string;
title: string;
author: string;
year: number;
group: string;
order: number;
paragraphs: string[];
};
// ---------------------------------------------------------------------------
// Seed function
// ---------------------------------------------------------------------------
async function seedTe(db: ReturnType<MongoClient["db"]>) {
const introPath = path.join(TE_DIR, "intro.json");
if (!fs.existsSync(introPath)) {
console.error("❌ TE intro.json not found at", introPath);
process.exit(1);
}
const intro = readJson<TeIntroJson>(introPath);
// ---- 1. Book meta ----
const metaCol = db.collection("book_meta");
await metaCol.deleteMany({ book: "te" });
await metaCol.insertOne({ book: "te", data: intro });
console.log(" 📖 TE book meta inserted");
// ---- 2. Essays collection ----
const essaysCol = db.collection("essays");
await essaysCol.deleteMany({ group: "two-essays" });
const docs: Record<string, unknown>[] = [];
const essaysDir = path.join(TE_DIR, "essays");
if (!fs.existsSync(essaysDir)) {
console.error("❌ TE essays directory not found at", essaysDir);
process.exit(1);
}
const essayFiles = fs
.readdirSync(essaysDir)
.filter((f) => f.endsWith(".json"))
.sort();
for (const file of essayFiles) {
const essay = readJson<TeEssayJson>(path.join(essaysDir, file));
docs.push({
slug: essay.slug,
title: essay.title,
author: essay.author,
year: essay.year,
group: essay.group,
order: essay.order,
paragraphs: essay.paragraphs,
});
}
console.log(` 📝 Essays found: ${docs.length}`);
// Insert all docs
console.log(`\n Inserting ${docs.length} essay documents...`);
await insertBatched(essaysCol, docs);
const totalDocs = await essaysCol.countDocuments({ group: "two-essays" });
console.log(` ✅ TE: ${totalDocs} essays in MongoDB`);
}
// ---------------------------------------------------------------------------
// Main
// ---------------------------------------------------------------------------
async function main() {
console.log("🌱 Seeding Two Essays...\n");
const client = new MongoClient(DATABASE_URL!);
await client.connect();
console.log("📡 Connected to MongoDB\n");
const db = client.db();
const start = Date.now();
await seedTe(db);
const elapsed = ((Date.now() - start) / 1000).toFixed(1);
console.log(`\n🎉 Done in ${elapsed}s`);
await client.close();
}
main().catch((err) => {
console.error("❌ Seed failed:", err);
process.exit(1);
});