import {Command} from "https://deno.land/x/cliffy@v0.25.7/command/mod.ts"; import {concat, partial} from 'https://deno.land/x/lodash@4.17.15-es/lodash.js'; import {join, dirname} from "https://deno.land/std@0.171.0/path/mod.ts"; enum AvroPrimitives { Null = "null", Boolean = "boolean", Int = "int", Long = "long", Float = "float", Double = "double", Bytes = "bytes", String = "string" } interface AvroRecordField { name: string, doc?: string, default?: any, type: AvroTypes, } interface AvroRecord { name: string, type: "record", namespace?: string, doc?: string, aliases?: string[] fields: AvroRecordField[] } interface AvroEnum { name: string, namespace?: string, aliases?: string[], type: "enum", symbols: string[], } type AvroUnion = AvroTypes[]; type AvroTypes = AvroPrimitives | AvroRecord | AvroUnion | AvroEnum; const CacheChequeEvent: AvroRecord = { name: "event", type: "record", fields: [ {name: "account", type: AvroPrimitives.Long}, ] } const BogusEvent: AvroRecord = { name: "bogus", type: "record", fields: [ {name: "account", type: AvroPrimitives.Long}, {name: "foo", type: AvroPrimitives.Long}, ] } const allEvents: AvroRecord[] = [CacheChequeEvent, BogusEvent] const eventTypes: AvroEnum = { type: "enum", name: "EventType", symbols: allEvents.map(x => x.name), } const LedgerEventsSchema: AvroRecord = { name: "LedgerEvent", type: "record", fields: [ {name: "event_type", type: eventTypes}, {name: "event", type: allEvents}, ] }; interface CliOptions { dry: boolean, output: string, } type Serializer = (rec: AvroRecord) => Promise; function getOutputFileName(outputDir: string, rec: AvroRecord): string { return join(outputDir, rec.name + '.json'); } async function drySerializer(outputDir: string, rec: AvroRecord): Promise { console.log(getOutputFileName(outputDir, rec) + " : " + JSON.stringify(rec)); } async function fileSerializer(outputDir: string, rec: AvroRecord): Promise { let outputFile = getOutputFileName(outputDir, rec); await Deno.mkdir(dirname(outputFile), { recursive: true }); await Deno.writeTextFile(outputFile, JSON.stringify(rec, null, 4)); } function getSerializer(dry: boolean, outputDir: string): Serializer { return dry ? partial(drySerializer, outputDir) : partial(fileSerializer, outputDir); } async function main(options: CliOptions): Promise { let serializer = getSerializer(options.dry, options.output); for(let e of concat([], allEvents, LedgerEventsSchema)){ await serializer(e); } } await new Command() .name("ledger-avro-schemata-builder") .version("0.1.0") .description("Build avro schemata for ledger.") .option("--dry [value:boolean]", "Do not output any files", { default: false, }) .option("--output [value:file]", "directory to output schemata", { default: '.', }) .action(main) .parse(Deno.args);