/** * Startup script: Indexes TinaCMS content into the database (Redis). * * In a self-hosted setup, the database (Redis) starts empty. * This script reads the generated schema files from the filesystem, * creates a database connection, and indexes all content into Redis. * * Run this BEFORE starting the Next.js server. */ import fs from "node:fs"; import path from "node:path"; import { createRequire } from "node:module"; import { createDatabase, FilesystemBridge, } from "@tinacms/datalayer"; const require = createRequire(import.meta.url); const { RedisLevel } = require("upstash-redis-level"); const branch = process.env.TINA_GIT_BRANCH || "main"; const kvUrl = process.env.KV_REST_API_URL; const kvToken = process.env.KV_REST_API_TOKEN; if (!kvUrl || !kvToken) { console.error( "[index-database] KV_REST_API_URL and KV_REST_API_TOKEN are required" ); process.exit(1); } const generatedDir = path.join(process.cwd(), "tina", "__generated__"); const graphqlPath = path.join(generatedDir, "_graphql.json"); const schemaPath = path.join(generatedDir, "_schema.json"); const lookupPath = path.join(generatedDir, "_lookup.json"); // Verify generated files exist for (const filePath of [graphqlPath, schemaPath, lookupPath]) { if (!fs.existsSync(filePath)) { console.error(`[index-database] Missing generated file: ${filePath}`); process.exit(1); } } const graphQLSchema = JSON.parse(fs.readFileSync(graphqlPath, "utf-8")); const tinaSchema = JSON.parse(fs.readFileSync(schemaPath, "utf-8")); const lookup = JSON.parse(fs.readFileSync(lookupPath, "utf-8")); // A no-op git provider since we only need to index, not push const noopGitProvider = { onPut: async () => { }, onDelete: async () => { }, }; const database = createDatabase({ gitProvider: noopGitProvider, databaseAdapter: new RedisLevel({ redis: { url: kvUrl, token: kvToken }, debug: process.env.DEBUG === "true" || false, }), bridge: new FilesystemBridge(process.cwd()), namespace: branch, }); async function indexContent() { console.log("[index-database] Starting content indexing..."); const startTime = Date.now(); try { await database.indexContent({ graphQLSchema, tinaSchema: { schema: tinaSchema }, lookup, }); const elapsed = Date.now() - startTime; console.log( `[index-database] Content indexed successfully in ${elapsed}ms` ); } catch (error) { console.error("[index-database] Failed to index content:", error); process.exit(1); } } indexContent();