Something went wrong. Try again.
Migrating content using the Ghost API to Offprint / Standard Site on atproto
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768import 'dotenv/config';import { program } from 'commander';
export interface Config { ghostUrl: string; ghostApiKey: string; atpIdentifier: string; atpAppPassword: string; atpService: string; publicationAtUri: string; exportDir: string; stateFile: string; sessionFile: string; dryRun: boolean; verbose: boolean;}
function requireEnv(name: string, value: string | undefined): string { if (!value) { throw new Error(`Missing required configuration: ${name}`); } return value;}
export function loadConfig(argv?: string[]): Config { program .name('ghostoff') .description('Export Ghost posts to Offprint via AT Protocol') .option('--ghost-url <url>', 'Ghost publication URL') .option('--ghost-api-key <key>', 'Ghost Content API key') .option('--atproto-identifier <id>', 'atproto handle or DID') .option('--atproto-app-password <password>', 'atproto app password') .option('--atproto-service <service>', 'atproto PDS/service URL') .option('--publication-at-uri <uri>', 'existing site.standard.publication AT-URI') .option('--export-dir <dir>', 'local asset export/cache directory', 'ghostoff-export') .option('--state-file <file>', 'idempotency state file', 'ghostoff-state.json') .option('--session-file <file>', 'persisted session file', 'ghostoff-session.json') .option('--dry-run', 'build records without uploading', false) .option('--verbose', 'verbose logging', false);
program.parse(argv); const opts = program.opts();
const ghostUrl = requireEnv('GHOST_URL or --ghost-url', opts.ghostUrl ?? process.env.GHOST_URL); const ghostApiKey = requireEnv('GHOST_API_KEY or --ghost-api-key', opts.ghostApiKey ?? process.env.GHOST_API_KEY); const atpIdentifier = requireEnv('ATP_IDENTIFIER or --atproto-identifier', opts.atprotoIdentifier ?? process.env.ATP_IDENTIFIER); const atpAppPassword = requireEnv('ATP_APP_PASSWORD or --atproto-app-password', opts.atpAppPassword ?? process.env.ATP_APP_PASSWORD); const atpService = opts.atprotoService ?? process.env.ATP_SERVICE ?? 'https://bsky.social'; const publicationAtUri = requireEnv( 'ATPUBLICATION_AT_URI or --publication-at-uri', opts.publicationAtUri ?? process.env.ATPUBLICATION_AT_URI );
return { ghostUrl: ghostUrl.replace(/\/$/, ''), ghostApiKey, atpIdentifier, atpAppPassword, atpService: atpService.replace(/\/$/, ''), publicationAtUri, exportDir: opts.exportDir, stateFile: opts.stateFile, sessionFile: opts.sessionFile, dryRun: !!opts.dryRun, verbose: !!opts.verbose, };}