UNPKG

longcelot-sheet-db

Version:

Google Sheets-backed staging database adapter for Node.js with schema-first design

114 lines 4.96 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.loadCLIConfig = loadCLIConfig; exports.buildAdminAdapter = buildAdminAdapter; exports.resolveSheetTargets = resolveSheetTargets; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const chalk_1 = __importDefault(require("chalk")); const sheetAdapter_1 = require("../../adapter/sheetAdapter"); const oauth_1 = require("../../auth/oauth"); const cliFiles_1 = require("../../utils/cliFiles"); const actorConfig_1 = require("../../utils/actorConfig"); const oauthFlow_1 = require("./oauthFlow"); function loadCLIConfig() { try { return require((0, cliFiles_1.resolveConfigPath)()).default; } catch { console.error(chalk_1.default.red('❌ lsdb.config.ts not found. Run: lsdb init')); process.exit(1); } } /** * Sets up a fully-wired SheetAdapter (env checks, OAuth, admin context) with the given schemas * registered — shared by drop-table/drop-column/rename-column, which each also need direct * SheetClient access (via adapter.getClient()) alongside normal table() CRUD for reading the * admin `users` table on --all-users. */ async function buildAdminAdapter(params) { require('dotenv').config(); const requiredEnvVars = ['GOOGLE_CLIENT_ID', 'GOOGLE_CLIENT_SECRET', 'GOOGLE_REDIRECT_URI']; for (const envVar of requiredEnvVars) { if (!process.env[envVar]) { console.error(chalk_1.default.red(`❌ Missing environment variable: ${envVar}`)); process.exit(1); } } const adminActor = params.config.actors.find((a) => (0, actorConfig_1.resolveActorName)(a) === 'admin'); const adminSheetId = adminActor ? process.env[adminActor.sheetIdEnv] : process.env.ADMIN_SHEET_ID; if (!adminSheetId) { console.error(chalk_1.default.red(`❌ Admin sheet ID not set. Add ${adminActor?.sheetIdEnv ?? 'ADMIN_SHEET_ID'} to your .env`)); process.exit(1); } const oauth = (0, oauth_1.createOAuthManager)({ clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, redirectUri: process.env.GOOGLE_REDIRECT_URI, }); let tokens; try { if (params.tokenFile) { const tokenFilePath = path_1.default.resolve(process.cwd(), params.tokenFile); if (!fs_1.default.existsSync(tokenFilePath)) { console.error(chalk_1.default.red(`❌ Token file not found: ${tokenFilePath}`)); process.exit(1); } tokens = JSON.parse(fs_1.default.readFileSync(tokenFilePath, 'utf-8')); console.log(chalk_1.default.green(`✅ Loaded tokens from ${params.tokenFile}\n`)); } else { tokens = await (0, oauthFlow_1.resolveTokens)(oauth); } } catch (err) { console.error(chalk_1.default.red(`❌ Authentication failed: ${err}`)); process.exit(1); } const adapter = (0, sheetAdapter_1.createSheetAdapter)({ adminSheetId, credentials: { clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, redirectUri: process.env.GOOGLE_REDIRECT_URI, }, tokens, }); adapter.registerSchemas(params.schemas); const adminCtx = adapter.withContext({ userId: 'schema-cli', actor: 'admin', actorSheetId: adminSheetId }); return { adapter, adminCtx, adminSheetId }; } /** * Resolves which live Google Sheets a change to an actor's table should apply to: the admin * sheet for actor:'admin', or the actor's configured dev/shared sheet plus (with --all-users) * every registered user's personal actor sheet, read from the admin `users` table exactly like * sync.ts's --all-users flow does. */ async function resolveSheetTargets(adminCtx, actor, adminSheetId, actorCfg, allUsers) { if (actor === 'admin') { return [{ sheetId: adminSheetId, label: 'admin' }]; } const targets = []; const configuredSheetId = actorCfg ? process.env[actorCfg.sheetIdEnv] : undefined; if (configuredSheetId) { targets.push({ sheetId: configuredSheetId, label: `${actor} (dev/shared)` }); } if (allUsers) { try { const users = await adminCtx.table('users').findMany({}); for (const user of users) { if (user.role === actor && user.actor_sheet_id) { targets.push({ sheetId: user.actor_sheet_id, label: `${actor}:${user.user_id}` }); } } } catch (err) { console.log(chalk_1.default.yellow(` ⚠ Could not fetch registered users for --all-users: ${err}`)); } } return targets; } //# sourceMappingURL=adminAdapter.js.map