@graphprotocol/graph-ts
Version:
TypeScript/AssemblyScript library for writing subgraph mappings for The Graph
300 lines (238 loc) • 7.51 kB
text/typescript
import { Bytes, Result, TypedMap } from './collections';
import { BigInt } from './numbers';
/**
* Host YAML interface.
*/
export declare namespace yaml {
/**
* Parses a YAML document from UTF-8 encoded bytes.
* Aborts mapping execution if the bytes cannot be parsed.
*/
function fromBytes(data: Bytes): YAMLValue;
/**
* Parses a YAML document from UTF-8 encoded bytes.
* Returns `Result.error == true` if the bytes cannot be parsed.
*/
function try_fromBytes(data: Bytes): Result<YAMLValue, bool>;
}
export namespace yaml {
/**
* Parses a YAML document from a UTF-8 encoded string.
* Aborts mapping execution if the string cannot be parsed.
*/
export function fromString(data: string): YAMLValue {
const bytes = Bytes.fromUTF8(data);
return yaml.fromBytes(bytes);
}
/**
* Parses a YAML document from a UTF-8 encoded string.
* Returns `Result.error == true` if the string cannot be parsed.
*/
export function try_fromString(data: string): Result<YAMLValue, bool> {
const bytes = Bytes.fromUTF8(data);
return yaml.try_fromBytes(bytes);
}
}
/**
* All possible YAML value types.
*/
export enum YAMLValueKind {
NULL = 0,
BOOL = 1,
NUMBER = 2,
STRING = 3,
ARRAY = 4,
OBJECT = 5,
TAGGED = 6,
}
/**
* Pointer type for `YAMLValue` data.
*
* Big enough to fit any pointer or native `YAMLValue.data`.
*/
export type YAMLValuePayload = u64;
export class YAMLValue {
kind: YAMLValueKind;
data: YAMLValuePayload;
constructor(kind: YAMLValueKind, data: YAMLValuePayload) {
this.kind = kind;
this.data = data;
}
static newNull(): YAMLValue {
return new YAMLValue(YAMLValueKind.NULL, 0);
}
static newBool(data: bool): YAMLValue {
return new YAMLValue(YAMLValueKind.BOOL, data ? 1 : 0);
}
static newI64(data: i64): YAMLValue {
return new YAMLValue(YAMLValueKind.NUMBER, changetype<usize>(data.toString()));
}
static newU64(data: u64): YAMLValue {
return new YAMLValue(YAMLValueKind.NUMBER, changetype<usize>(data.toString()));
}
static newF64(data: f64): YAMLValue {
return new YAMLValue(YAMLValueKind.NUMBER, changetype<usize>(data.toString()));
}
static newBigInt(data: BigInt): YAMLValue {
return new YAMLValue(YAMLValueKind.STRING, changetype<usize>(data.toString()));
}
static newString(data: string): YAMLValue {
return new YAMLValue(YAMLValueKind.STRING, changetype<usize>(data));
}
static newArray(data: Array<YAMLValue>): YAMLValue {
return new YAMLValue(YAMLValueKind.ARRAY, changetype<usize>(data));
}
static newObject(data: TypedMap<YAMLValue, YAMLValue>): YAMLValue {
return new YAMLValue(YAMLValueKind.OBJECT, changetype<usize>(data));
}
static newTagged(tag: string, value: YAMLValue): YAMLValue {
const tagged = new YAMLTaggedValue(tag, value);
return new YAMLValue(YAMLValueKind.TAGGED, changetype<usize>(tagged));
}
isNull(): bool {
return this.kind == YAMLValueKind.NULL;
}
isBool(): bool {
return this.kind == YAMLValueKind.BOOL;
}
isNumber(): bool {
return this.kind == YAMLValueKind.NUMBER;
}
isString(): bool {
return this.kind == YAMLValueKind.STRING;
}
isArray(): bool {
return this.kind == YAMLValueKind.ARRAY;
}
isObject(): bool {
return this.kind == YAMLValueKind.OBJECT;
}
isTagged(): bool {
return this.kind == YAMLValueKind.TAGGED;
}
toBool(): bool {
assert(this.isBool(), 'YAML value is not a boolean');
return this.data != 0;
}
toNumber(): string {
assert(this.isNumber(), 'YAML value is not a number');
return changetype<string>(this.data as usize);
}
toI64(): i64 {
return I64.parseInt(this.toNumber());
}
toU64(): u64 {
return U64.parseInt(this.toNumber());
}
toF64(): f64 {
return F64.parseFloat(this.toNumber());
}
toBigInt(): BigInt {
assert(this.isNumber() || this.isString(), 'YAML value is not numeric');
return BigInt.fromString(changetype<string>(this.data as usize));
}
toString(): string {
assert(this.isString(), 'YAML value is not a string');
return changetype<string>(this.data as usize);
}
toArray(): Array<YAMLValue> {
assert(this.isArray(), 'YAML value is not an array');
return changetype<Array<YAMLValue>>(this.data as usize);
}
toObject(): TypedMap<YAMLValue, YAMLValue> {
assert(this.isObject(), 'YAML value is not an object');
return changetype<TypedMap<YAMLValue, YAMLValue>>(this.data as usize);
}
toTagged(): YAMLTaggedValue {
assert(this.isTagged(), 'YAML value is not tagged');
return changetype<YAMLTaggedValue>(this.data as usize);
}
// Allows access to YAML values from within an object.
static eq(a: YAMLValue, b: YAMLValue): bool {
if (a.isBool() && b.isBool()) {
return a.toBool() == b.toBool();
}
if (a.isNumber() && b.isNumber()) {
return a.toNumber() == b.toNumber();
}
if (a.isString() && b.isString()) {
return a.toString() == b.toString();
}
if (a.isArray() && b.isArray()) {
const arrA = a.toArray();
const arrB = b.toArray();
if (arrA.length == arrB.length) {
for (let i = 0; i < arrA.length; i++) {
if (arrA[i] != arrB[i]) {
return false;
}
}
return true;
}
return false;
}
if (a.isObject() && b.isObject()) {
const objA = a.toObject();
const objB = b.toObject();
if (objA.entries.length == objB.entries.length) {
for (let i = 0; i < objA.entries.length; i++) {
const valB = objB.get(objA.entries[i].key);
if (!valB || objA.entries[i].value != valB) {
return false;
}
}
return true;
}
return false;
}
if (a.isTagged() && b.isTagged()) {
return a.toTagged() == b.toTagged();
}
return false;
}
// Allows access to YAML values from within an object.
static ne(a: YAMLValue | null, b: YAMLValue | null): bool {
if (!a || !b) {
return true;
}
return !(a! == b!);
}
// Makes it easier to access a specific index in a YAML array or a string key in a YAML object.
//
// Examples:
// Usage in YAML objects: `yaml.fromString(subgraphManifest)['specVersion']`;
// Nesting is also supported: `yaml.fromString(subgraphManifest)['schema']['file']`;
// Usage in YAML arrays: `yaml.fromString(subgraphManifest)['dataSources']['0']`;
// YAML arrays and objects: `yaml.fromString(subgraphManifest)['dataSources']['0']['source']['address']`;
get(index: string): YAMLValue {
assert(this.isArray() || this.isObject(), 'YAML value can not be accessed by index');
if (this.isArray()) {
return this.toArray()[I32.parseInt(index)];
}
return this.toObject().mustGet(YAMLValue.newString(index));
}
}
export class YAMLTaggedValue {
tag: string;
value: YAMLValue;
constructor(tag: string, value: YAMLValue) {
this.tag = tag;
this.value = value;
}
// Allows access to YAML values from within an object.
static eq(a: YAMLTaggedValue, b: YAMLTaggedValue): bool {
return a.tag == b.tag && a.value == b.value;
}
// Allows access to YAML values from within an object.
static ne(a: YAMLTaggedValue | null, b: YAMLTaggedValue | null): bool {
if (!a || !b) {
return true;
}
return !(a! == b!);
}
}