From d132f9c9f6ea5283e40a8d913f3abefe5a8ad5f8 Mon Sep 17 00:00:00 2001 From: Dotan Simha Date: Mon, 18 Mar 2024 16:55:21 +0200 Subject: [PATCH] New `Timestamp` scalar (#1522) * New `Timestamp` scalar * fix timestamp --------- Co-authored-by: Saihajpreet Singh --- .changeset/cold-shoes-thank.md | 6 ++++ packages/cli/src/codegen/schema.test.ts | 21 +++++++++++ packages/cli/src/codegen/types/conversions.ts | 5 +++ packages/cli/src/validation/schema.ts | 3 ++ packages/ts/common/numbers.ts | 1 + packages/ts/common/value.ts | 35 +++++++++++++++++++ 6 files changed, 71 insertions(+) create mode 100644 .changeset/cold-shoes-thank.md diff --git a/.changeset/cold-shoes-thank.md b/.changeset/cold-shoes-thank.md new file mode 100644 index 000000000..dc966ce0d --- /dev/null +++ b/.changeset/cold-shoes-thank.md @@ -0,0 +1,6 @@ +--- +'@graphprotocol/graph-cli': minor +'@graphprotocol/graph-ts': minor +--- + +Added support for handling GraphQL `Timestamp` scalar as `i64` (AssemblyScript) diff --git a/packages/cli/src/codegen/schema.test.ts b/packages/cli/src/codegen/schema.test.ts index d802d4b2d..cce534d43 100644 --- a/packages/cli/src/codegen/schema.test.ts +++ b/packages/cli/src/codegen/schema.test.ts @@ -77,6 +77,7 @@ describe.concurrent('Schema code generator', () => { # New scalars int8: Int8! + timestamp: Timestamp! } type Wallet @entity { @@ -287,6 +288,26 @@ describe.concurrent('Schema code generator', () => { this.set('int8', Value.fromI64(value)) `, }, + { + name: 'get timestamp', + params: [], + returnType: new NamedType('i64'), + body: `let value = this.get('timestamp') + if (!value || value.kind == ValueKind.NULL) { + return 0 + } else { + return value.toTimestamp() + } + `, + }, + { + name: 'set timestamp', + params: [new Param('value', new NamedType('i64'))], + returnType: undefined, + body: ` + this.set('timestamp', Value.fromTimestamp(value)) + `, + }, { name: 'get wallets', params: [], diff --git a/packages/cli/src/codegen/types/conversions.ts b/packages/cli/src/codegen/types/conversions.ts index c1113fba0..eece42cd1 100644 --- a/packages/cli/src/codegen/types/conversions.ts +++ b/packages/cli/src/codegen/types/conversions.ts @@ -271,6 +271,7 @@ const VALUE_TO_ASSEMBLYSCRIPT = [ ['[Boolean]', 'Array', (code: any) => `${code}.toBooleanArray()`], ['[Int]', 'Array', (code: any) => `${code}.toI32Array()`], ['[Int8]', 'Array', (code: any) => `${code}.toI64Array()`], + ['[Timestamp]', 'Array', (code: any) => `${code}.toTimestampArray()`], ['[BigInt]', 'Array', (code: any) => `${code}.toBigIntArray()`], ['[ID]', 'Array', (code: any) => `${code}.toStringArray()`], ['[String]', 'Array', (code: any) => `${code}.toStringArray()`], @@ -287,6 +288,7 @@ const VALUE_TO_ASSEMBLYSCRIPT = [ ['ID', 'string', (code: any) => `${code}.toString()`], ['String', 'string', (code: any) => `${code}.toString()`], ['BigDecimal', 'BigDecimal', (code: any) => `${code}.toBigDecimal()`], + ['Timestamp', 'i64', (code: any) => `${code}.toTimestamp()`], [/.*/, 'string', (code: any) => `${code}.toString()`], ]; @@ -305,6 +307,7 @@ const ASSEMBLYSCRIPT_TO_VALUE = [ ['Array>', '[[Boolean]]', (code: any) => `Value.fromBooleanMatrix(${code})`], ['Array>', '[[Int]]', (code: any) => `Value.fromI32Matrix(${code})`], ['Array>', '[[Int8]]', (code: any) => `Value.fromI64Matrix(${code})`], + ['Array>', '[[Timestamp]]', (code: any) => `Value.fromTimestampMatrix(${code})`], ['Array>', '[[BigInt]]', (code: any) => `Value.fromBigIntMatrix(${code})`], ['Array>', '[[String]]', (code: any) => `Value.fromStringMatrix(${code})`], ['Array>', '[[ID]]', (code: any) => `Value.fromStringMatrix(${code})`], @@ -323,6 +326,7 @@ const ASSEMBLYSCRIPT_TO_VALUE = [ ['Array', '[Boolean]', (code: any) => `Value.fromBooleanArray(${code})`], ['Array', '[Int]', (code: any) => `Value.fromI32Array(${code})`], ['Array', '[Int8]', (code: any) => `Value.fromI64Array(${code})`], + ['Array', '[Timestamp]', (code: any) => `Value.fromTimestampArray(${code})`], ['Array', '[BigInt]', (code: any) => `Value.fromBigIntArray(${code})`], ['Array', '[String]', (code: any) => `Value.fromStringArray(${code})`], ['Array', '[ID]', (code: any) => `Value.fromStringArray(${code})`], @@ -337,6 +341,7 @@ const ASSEMBLYSCRIPT_TO_VALUE = [ ['boolean', 'Boolean', (code: any) => `Value.fromBoolean(${code})`], ['i32', 'Int', (code: any) => `Value.fromI32(${code})`], ['i64', 'Int8', (code: any) => `Value.fromI64(${code})`], + ['i64', 'Timestamp', (code: any) => `Value.fromTimestamp(${code})`], ['BigInt', 'BigInt', (code: any) => `Value.fromBigInt(${code})`], ['string', 'String', (code: any) => `Value.fromString(${code})`], ['string', 'ID', (code: any) => `Value.fromString(${code})`], diff --git a/packages/cli/src/validation/schema.ts b/packages/cli/src/validation/schema.ts index 8085d1c31..8f83df3fd 100644 --- a/packages/cli/src/validation/schema.ts +++ b/packages/cli/src/validation/schema.ts @@ -18,6 +18,7 @@ const BUILTIN_SCALAR_TYPES = [ 'Bytes', 'ID', 'Int8', + 'Timestamp', ]; // Type suggestions for common mistakes @@ -39,6 +40,8 @@ const TYPE_SUGGESTIONS = [ ['Float', 'BigDecimal'], ['int', 'Int'], ['int8', 'Int8'], + ['timestamp', 'Timestamp'], + ['ts', 'Timestamp'], ['uint', 'BigInt'], ['owner', 'String'], ['Owner', 'String'], diff --git a/packages/ts/common/numbers.ts b/packages/ts/common/numbers.ts index 4e19b9638..438fd7ab7 100644 --- a/packages/ts/common/numbers.ts +++ b/packages/ts/common/numbers.ts @@ -30,6 +30,7 @@ export declare namespace bigDecimal { } export type Int8 = i64; +export type Timestamp = i64; /** An Ethereum address (20 bytes). */ export class Address extends Bytes { diff --git a/packages/ts/common/value.ts b/packages/ts/common/value.ts index 88c6ae454..ce2a576e3 100644 --- a/packages/ts/common/value.ts +++ b/packages/ts/common/value.ts @@ -15,6 +15,7 @@ export enum ValueKind { BYTES = 6, BIGINT = 7, INT8 = 8, + TIMESTAMP = 9, } const VALUE_KIND_NAMES = [ @@ -27,6 +28,7 @@ const VALUE_KIND_NAMES = [ 'Bytes', 'BigInt', 'Int8', + 'Timestamp', ]; /** @@ -79,6 +81,14 @@ export class Value { return this.data as i64; } + toTimestamp(): i64 { + if (this.kind == ValueKind.NULL) { + return 0; + } + assert(this.kind == ValueKind.TIMESTAMP, 'Value is not an i64.'); + return this.data as i64; + } + toString(): string { assert(this.kind == ValueKind.STRING, 'Value is not a string.'); return changetype(this.data as u32); @@ -153,6 +163,15 @@ export class Value { return output; } + toTimestampArray(): Array { + const values = this.toArray(); + const output = new Array(values.length); + for (let i: i32 = 0; i < values.length; i++) { + output[i] = values[i].toTimestamp(); + } + return output; + } + toBigIntArray(): Array { const values = this.toArray(); const output = new Array(values.length); @@ -274,6 +293,7 @@ export class Value { case ValueKind.INT: return this.toI32().toString(); case ValueKind.INT8: + case ValueKind.TIMESTAMP: return this.toI64().toString(); case ValueKind.BIGDECIMAL: return this.toBigDecimal().toString(); @@ -379,6 +399,10 @@ export class Value { return new Value(ValueKind.INT8, n as i64); } + static fromTimestamp(n: i64): Value { + return new Value(ValueKind.TIMESTAMP, n as i64); + } + static fromString(s: string): Value { return new Value(ValueKind.STRING, changetype(s)); } @@ -465,6 +489,17 @@ export class Value { return Value.fromMatrix(out); } + static fromTimestampMatrix(values: Array>): Value { + const out = new Array>(values.length); + for (let i: i32 = 0; i < values.length; i++) { + out[i] = new Array(values[i].length); + for (let j: i32 = 0; j < values[i].length; j++) { + out[i][j] = Value.fromTimestamp(values[i][j]); + } + } + return Value.fromMatrix(out); + } + static fromBigIntMatrix(values: Array>): Value { const out = new Array>(values.length); for (let i: i32 = 0; i < values.length; i++) {