126 lines
2.9 KiB
TypeScript
126 lines
2.9 KiB
TypeScript
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<void>;
|
|
|
|
function getOutputFileName(outputDir: string, rec: AvroRecord): string {
|
|
return join(outputDir, rec.name + '.json');
|
|
}
|
|
|
|
async function drySerializer(outputDir: string, rec: AvroRecord): Promise<void> {
|
|
console.log(getOutputFileName(outputDir, rec) + " : " + JSON.stringify(rec));
|
|
}
|
|
|
|
async function fileSerializer(outputDir: string, rec: AvroRecord): Promise<void> {
|
|
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<void> {
|
|
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);
|