diff --git a/flake.nix b/flake.nix index b02dd6b..c02d699 100644 --- a/flake.nix +++ b/flake.nix @@ -39,7 +39,8 @@ rustfmt pre-commit rustPackages.clippy - cargo-tarpaulin]; + cargo-tarpaulin + deno]; RUST_SRC_PATH = rustPlatform.rustLibSrc; }; }); diff --git a/migrations/avro/events.ts b/migrations/avro/events.ts new file mode 100644 index 0000000..bddb894 --- /dev/null +++ b/migrations/avro/events.ts @@ -0,0 +1,125 @@ +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);