'use strict'; const fs = require('node:fs'); const path = require('node:path'); const { parseDsl } = require('../dsl-parser'); const { loadAtlasDirs } = require('../atlas-loader'); const { buildMap } = require('../builder'); const USAGE = 'usage: sporel-mapper build [--atlas-dir ...]\n'; function parseArgs(args) { const positional = []; const atlasDirs = []; let i = 0; while (i < args.length) { const a = args[i]; if (a === '--atlas-dir') { if (i + 1 >= args.length) { throw new Error(`--atlas-dir requires a path`); } atlasDirs.push(args[i + 1]); i += 2; } else { positional.push(a); i += 1; } } return { positional, atlasDirs }; } function run(args, { out, err }) { let parsed; try { parsed = parseArgs(args); } catch (e) { err.write(`error: ${e.message}\n${USAGE}`); return 1; } if (parsed.positional.length !== 2) { err.write(USAGE); return 1; } const [specPath, outPath] = parsed.positional; let dslText; try { dslText = fs.readFileSync(specPath, 'utf8'); } catch (e) { err.write(`error: cannot read ${specPath}: ${e.message}\n`); return 1; } let ast; try { ast = parseDsl(dslText); } catch (e) { const line = e.line || '?'; err.write(`${specPath}:${line}: ${e.message}\n`); return 1; } let registry; try { const result = loadAtlasDirs(parsed.atlasDirs); registry = result.registry; for (const w of result.warnings) { err.write(`warning: ${w}\n`); } } catch (e) { err.write(`error: ${e.message}\n`); return 1; } const defaultId = path.basename(outPath, path.extname(outPath)); let map; try { map = buildMap(ast, registry, { defaultId }); } catch (e) { const line = e.line || '?'; err.write(`${specPath}:${line}: ${e.message}\n`); return 1; } try { fs.writeFileSync(outPath, JSON.stringify(map, null, 2) + '\n'); } catch (e) { err.write(`error: cannot write ${outPath}: ${e.message}\n`); return 1; } return 0; } module.exports = { run };