longcelot-sheet-db
Version:
Google Sheets-backed staging database adapter for Node.js with schema-first design
141 lines • 6.35 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.dropTableCommand = dropTableCommand;
const fs_1 = __importDefault(require("fs"));
const chalk_1 = __importDefault(require("chalk"));
const inquirer_1 = __importDefault(require("inquirer"));
const adminAdapter_1 = require("../lib/adminAdapter");
const schemaLoader_1 = require("../lib/schemaLoader");
const resolveTable_1 = require("../lib/resolveTable");
const actorConfig_1 = require("../../utils/actorConfig");
function findReferencingTables(all, tableName, excluding) {
const referencing = [];
for (const { schema } of all) {
if (excluding.has(schema.name))
continue;
for (const col of Object.values(schema.columns)) {
if (col.ref?.split('.')[0] === tableName) {
referencing.push(schema.name);
break;
}
}
}
return referencing;
}
async function dropTableCommand(tableNames, options) {
console.log(chalk_1.default.blue.bold('🗑️ Drop table...\n'));
const config = (0, adminAdapter_1.loadCLIConfig)();
const all = (0, schemaLoader_1.loadSchemasWithPaths)(config);
if (all.length === 0) {
console.log(chalk_1.default.yellow('⚠️ No schemas found. Nothing to drop.'));
return;
}
let selected;
if (tableNames.length === 0) {
const { chosen } = await inquirer_1.default.prompt([
{
type: 'checkbox',
name: 'chosen',
message: 'Select table(s) to drop (space to toggle, enter to confirm):',
choices: all.map((s) => ({ name: `${s.actor}/${s.schema.name}`, value: `${s.actor}/${s.schema.name}` })),
},
]);
if (chosen.length === 0) {
console.log(chalk_1.default.yellow('No tables selected. Nothing to do.'));
return;
}
selected = chosen.map((ref) => {
const result = (0, resolveTable_1.resolveTableRef)(all, ref);
if (!result.ok)
throw new Error(result.error); // unreachable — ref came from the choices list itself
return result.table;
});
}
else {
const errors = [];
selected = [];
for (const name of tableNames) {
const result = (0, resolveTable_1.resolveTableRef)(all, name);
if (result.ok) {
selected.push(result.table);
}
else {
errors.push(result.error);
}
}
if (errors.length > 0) {
console.error(chalk_1.default.red.bold('❌ Invalid table name(s):\n'));
errors.forEach((e) => console.error(chalk_1.default.red(` - ${e}`)));
process.exit(1);
}
}
const selectedNames = new Set(selected.map((s) => s.schema.name));
console.log(chalk_1.default.bold('Plan:\n'));
for (const table of selected) {
console.log(` ${chalk_1.default.white(`${table.actor}/${table.schema.name}`)} ${chalk_1.default.gray(`(${table.filePath})`)}`);
const referencing = findReferencingTables(all, table.schema.name, selectedNames);
if (referencing.length > 0) {
console.log(chalk_1.default.yellow(` ⚠ referenced by ref() in: ${referencing.join(', ')} — those FK columns will break`));
}
}
console.log();
if (options.dryRun) {
console.log(chalk_1.default.yellow('[DRY RUN] No changes made.'));
return;
}
if (!options.yes) {
const { confirmed } = await inquirer_1.default.prompt([
{ type: 'confirm', name: 'confirmed', message: `Drop ${selected.length} table(s)? This deletes the schema file and the live Google Sheet tab.`, default: false },
]);
if (!confirmed) {
console.log(chalk_1.default.gray('Cancelled.'));
return;
}
}
const { adminCtx, adminSheetId } = await (0, adminAdapter_1.buildAdminAdapter)({
config,
schemas: all.map((s) => s.schema),
tokenFile: options.tokenFile,
});
const resultRows = [];
for (const table of selected) {
fs_1.default.unlinkSync(table.filePath);
const actorCfg = config.actors.find((a) => (0, actorConfig_1.resolveActorName)(a) === table.actor);
const targets = await (0, adminAdapter_1.resolveSheetTargets)(adminCtx, table.actor, adminSheetId, actorCfg, options.allUsers ?? false);
if (targets.length === 0) {
resultRows.push({ table: `${table.actor}/${table.schema.name}`, sheet: '(none)', status: chalk_1.default.gray('– file deleted, no sheet configured') });
continue;
}
for (const target of targets) {
try {
await adminCtx.getClient().deleteSheet(target.sheetId, table.schema.name);
resultRows.push({ table: `${table.actor}/${table.schema.name}`, sheet: target.label, status: chalk_1.default.green('✅ dropped') });
}
catch (err) {
const message = err instanceof Error ? err.message : String(err);
if (message.includes('not found')) {
resultRows.push({ table: `${table.actor}/${table.schema.name}`, sheet: target.label, status: chalk_1.default.gray('– tab already absent') });
}
else {
resultRows.push({ table: `${table.actor}/${table.schema.name}`, sheet: target.label, status: chalk_1.default.red(`❌ ${message}`) });
}
}
try {
await adminCtx.table('schema_versions').delete({ where: { actor_sheet_id: target.sheetId, table_name: table.schema.name } });
}
catch {
// best-effort cleanup — schema_versions bookkeeping, not fatal if it fails
}
}
}
console.log(chalk_1.default.bold('\nResult:\n'));
for (const row of resultRows) {
console.log(` ${chalk_1.default.white(row.table.padEnd(28))} ${chalk_1.default.gray(row.sheet.padEnd(24))} ${row.status}`);
}
console.log();
}
exports.default = dropTableCommand;
//# sourceMappingURL=drop-table.js.map