longcelot-sheet-db
Version:
Google Sheets-backed staging database adapter for Node.js with schema-first design
92 lines • 4.22 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.doctorCommand = doctorCommand;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const chalk_1 = __importDefault(require("chalk"));
const cliFiles_1 = require("../../utils/cliFiles");
function check(label, ok, message) {
return { label, ok, message };
}
async function doctorCommand() {
console.log(chalk_1.default.blue.bold('🩺 Running diagnostics...\n'));
require('dotenv').config();
const results = [];
// 1. Config file
const configPath = (0, cliFiles_1.resolveConfigPath)();
results.push(check(`Config file (${cliFiles_1.CONFIG_FILENAME})`, fs_1.default.existsSync(configPath)));
// 2. .env file
const envPath = path_1.default.join(process.cwd(), '.env');
results.push(check('.env file', fs_1.default.existsSync(envPath), 'Create a .env file with required variables'));
// 3. Required env vars
const requiredEnvVars = [
'GOOGLE_CLIENT_ID',
'GOOGLE_CLIENT_SECRET',
'GOOGLE_REDIRECT_URI',
'ADMIN_SHEET_ID',
];
for (const envVar of requiredEnvVars) {
results.push(check(`Env var: ${envVar}`, !!process.env[envVar], `Set ${envVar} in your .env file`));
}
// 4. Schemas directory
const schemasDir = path_1.default.join(process.cwd(), 'schemas');
results.push(check('schemas/ directory', fs_1.default.existsSync(schemasDir), 'Run: lsdb init'));
// 5. Schema files
let schemaCount = 0;
if (fs_1.default.existsSync(schemasDir)) {
const actorDirs = fs_1.default.readdirSync(schemasDir, { withFileTypes: true })
.filter((d) => d.isDirectory())
.map((d) => d.name);
for (const actor of actorDirs) {
const actorDir = path_1.default.join(schemasDir, actor);
const files = fs_1.default.readdirSync(actorDir).filter((f) => f.endsWith('.ts'));
schemaCount += files.length;
}
}
results.push(check(`Schema files (${schemaCount} found)`, schemaCount > 0, 'Run: lsdb generate <table-name> to create schemas'));
// 6. OAuth tokens
const tokensPath = (0, cliFiles_1.resolveTokensPath)();
results.push(check(`OAuth tokens (${cliFiles_1.TOKENS_FILENAME})`, fs_1.default.existsSync(tokensPath), 'Run: lsdb sync to authorize and create tokens'));
// 7. OAuth token validity (basic check)
if (fs_1.default.existsSync(tokensPath)) {
try {
const tokens = JSON.parse(fs_1.default.readFileSync(tokensPath, 'utf-8'));
const hasRefreshToken = !!tokens.refresh_token;
const expiryDate = tokens.expiry_date;
const expired = expiryDate ? Date.now() > expiryDate : false;
results.push(check('OAuth refresh token present', hasRefreshToken, 'Re-run: lsdb sync to get a refresh token'));
if (expiryDate) {
results.push(check(`Access token ${expired ? '(expired — will auto-refresh)' : '(valid)'}`, true));
}
}
catch {
results.push(check('OAuth token file parseable', false, `Delete ${cliFiles_1.TOKENS_FILENAME} and run: lsdb sync`));
}
}
// Print results
let passed = 0;
let failed = 0;
for (const result of results) {
if (result.ok) {
console.log(` ${chalk_1.default.green('✓')} ${result.label}`);
passed++;
}
else {
console.log(` ${chalk_1.default.red('✖')} ${result.label}${result.message ? chalk_1.default.gray(` — ${result.message}`) : ''}`);
failed++;
}
}
console.log();
if (failed === 0) {
console.log(chalk_1.default.green.bold(`✅ All ${passed} checks passed. You're good to go!`));
}
else {
console.log(chalk_1.default.yellow.bold(`⚠️ ${failed} check(s) failed, ${passed} passed.`));
console.log(chalk_1.default.gray('Fix the issues above before running lsdb sync.'));
process.exit(1);
}
}
//# sourceMappingURL=doctor.js.map