/** * Schema Fetching * * Fetches mizan and channels schemas from Django management commands. */ import { spawn } from 'child_process' import path from 'path' /** * Run a Django management command and parse JSON output. */ function runDjangoCommand(source, cwd, command) { const managePath = path.resolve(cwd, source.django.managePath) const manageDir = path.dirname(managePath) let cmd, args if (source.django.command) { cmd = source.django.command[0] args = [...source.django.command.slice(1), 'manage.py', command, '--indent', '0'] } else { const python = source.django.python || 'python' cmd = python args = [managePath, command, '--indent', '0'] } const env = source.django.env ? { ...process.env, ...source.django.env } : undefined return new Promise((resolve, reject) => { const proc = spawn(cmd, args, { cwd: manageDir, stdio: ['ignore', 'pipe', 'pipe'], shell: process.platform === 'win32', env, }) let stdout = '' let stderr = '' proc.stdout.on('data', (data) => { stdout += data.toString() }) proc.stderr.on('data', (data) => { stderr += data.toString() }) proc.on('close', (code) => { if (code !== 0) { reject(new Error(`Django command failed (exit ${code}):\n${stderr}`)) return } const jsonStart = stdout.indexOf('{') if (jsonStart === -1) { reject(new Error(`No JSON found in Django output:\n${stdout}\n${stderr}`)) return } try { resolve(JSON.parse(stdout.slice(jsonStart))) } catch (err) { reject(new Error(`Failed to parse JSON from Django:\n${err.message}\n${stdout}`)) } }) proc.on('error', (err) => { reject(new Error(`Failed to spawn Django command: ${err.message}`)) }) }) } /** * Fetch channels schema from Django. */ export async function fetchChannelsSchema(source, cwd) { if (!source.django) { throw new Error('Channels schema export requires django source configuration') } return runDjangoCommand(source, cwd, 'export_channels_schema') } /** * Fetch mizan schema from Django. */ export async function fetchMizanSchema(source, cwd) { if (!source.django) { throw new Error('mizan schema export requires django source configuration') } return runDjangoCommand(source, cwd, 'export_djarea_schema') }