mirror of
https://github.com/cerc-io/watcher-ts
synced 2024-11-19 20:36:19 +00:00
Handle additional subgraph types BigDecimal and Bytes in codegen (#89)
* Handle additional subgraph types BigDecimal and Bytes * Use bigint and Decimal array transformers
This commit is contained in:
parent
18f73e57c0
commit
2a204d8a32
@ -244,6 +244,9 @@ export class Entity {
|
||||
// Add subgraph entity specific columns.
|
||||
entityObject = this._addSubgraphColumns(subgraphTypeDefs, entityObject, def);
|
||||
|
||||
// Add decimalTransformer column option if required.
|
||||
this._addDecimalTransformerOption(entityObject);
|
||||
|
||||
// Add bigintTransformer column option if required.
|
||||
this._addBigIntTransformerOption(entityObject);
|
||||
|
||||
@ -282,9 +285,13 @@ export class Entity {
|
||||
}
|
||||
|
||||
_addBigIntTransformerOption (entityObject: any): void {
|
||||
let importObject = entityObject.imports.find((element: any) => {
|
||||
return element.from === '@vulcanize/util';
|
||||
});
|
||||
|
||||
entityObject.columns.forEach((column: any) => {
|
||||
// Implement bigintTransformer for bigint types.
|
||||
if (['bigint', 'bigint[]'].includes(column.tsType)) {
|
||||
// Implement bigintTransformer for bigint type.
|
||||
if (column.tsType === 'bigint') {
|
||||
column.columnOptions.push(
|
||||
{
|
||||
option: 'transformer',
|
||||
@ -292,24 +299,106 @@ export class Entity {
|
||||
}
|
||||
);
|
||||
|
||||
const importObject = entityObject.imports.find((element: any) => {
|
||||
return element.from === '@vulcanize/util';
|
||||
});
|
||||
|
||||
if (importObject) {
|
||||
importObject.toImport.add('bigintTransformer');
|
||||
} else {
|
||||
entityObject.imports.push(
|
||||
{
|
||||
toImport: new Set(['bigintTransformer']),
|
||||
from: '@vulcanize/util'
|
||||
}
|
||||
);
|
||||
importObject = {
|
||||
toImport: new Set(['bigintTransformer']),
|
||||
from: '@vulcanize/util'
|
||||
};
|
||||
|
||||
entityObject.imports.push(importObject);
|
||||
}
|
||||
}
|
||||
|
||||
// Implement bigintArrayTransformer for array of bigint type.
|
||||
if (column.tsType === 'bigint[]') {
|
||||
column.columnOptions.push(
|
||||
{
|
||||
option: 'transformer',
|
||||
value: 'bigintArrayTransformer'
|
||||
}
|
||||
);
|
||||
|
||||
if (importObject) {
|
||||
importObject.toImport.add('bigintArrayTransformer');
|
||||
} else {
|
||||
importObject = {
|
||||
toImport: new Set(['bigintArrayTransformer']),
|
||||
from: '@vulcanize/util'
|
||||
};
|
||||
|
||||
entityObject.imports.push(importObject);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_addDecimalTransformerOption (entityObject: any): void {
|
||||
let importObject = entityObject.imports.find((element: any) => {
|
||||
return element.from === '@vulcanize/util';
|
||||
});
|
||||
|
||||
let isDecimalRequired = false;
|
||||
|
||||
entityObject.columns.forEach((column: any) => {
|
||||
// Implement decimalTransformer for Decimal type.
|
||||
if (column.tsType === 'Decimal') {
|
||||
isDecimalRequired = true;
|
||||
|
||||
column.columnOptions.push(
|
||||
{
|
||||
option: 'transformer',
|
||||
value: 'decimalTransformer'
|
||||
}
|
||||
);
|
||||
|
||||
if (importObject) {
|
||||
importObject.toImport.add('decimalTransformer');
|
||||
} else {
|
||||
importObject = {
|
||||
toImport: new Set(['decimalTransformer']),
|
||||
from: '@vulcanize/util'
|
||||
};
|
||||
|
||||
entityObject.imports.push(importObject);
|
||||
}
|
||||
}
|
||||
|
||||
// Implement decimalArrayTransformer for array of Decimal type.
|
||||
if (column.tsType === 'Decimal[]') {
|
||||
isDecimalRequired = true;
|
||||
|
||||
column.columnOptions.push(
|
||||
{
|
||||
option: 'transformer',
|
||||
value: 'decimalArrayTransformer'
|
||||
}
|
||||
);
|
||||
|
||||
if (importObject) {
|
||||
importObject.toImport.add('decimalArrayTransformer');
|
||||
} else {
|
||||
importObject = {
|
||||
toImport: new Set(['decimalArrayTransformer']),
|
||||
from: '@vulcanize/util'
|
||||
};
|
||||
|
||||
entityObject.imports.push(importObject);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (isDecimalRequired) {
|
||||
entityObject.imports.push(
|
||||
{
|
||||
toImport: new Set(['Decimal']),
|
||||
from: 'decimal.js'
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_addSubgraphColumns (subgraphTypeDefs: any, entityObject: any, def: any): any {
|
||||
def.fields.forEach((field: any) => {
|
||||
if (field.directives.some((directive: any) => directive.name.value === 'derivedFrom')) {
|
||||
|
@ -198,6 +198,18 @@ export class Schema {
|
||||
});
|
||||
this._composer.addSchemaMustHaveType(typeComposer);
|
||||
|
||||
// Create a scalar type composer to add the scalar BigDecimal in the schema composer.
|
||||
typeComposer = this._composer.createScalarTC({
|
||||
name: 'BigDecimal'
|
||||
});
|
||||
this._composer.addSchemaMustHaveType(typeComposer);
|
||||
|
||||
// Create a scalar type composer to add the scalar Bytes in the schema composer.
|
||||
typeComposer = this._composer.createScalarTC({
|
||||
name: 'Bytes'
|
||||
});
|
||||
this._composer.addSchemaMustHaveType(typeComposer);
|
||||
|
||||
// Create a type composer to add the type Proof in the schema composer.
|
||||
typeComposer = this._composer.createObjectTC({
|
||||
name: 'Proof',
|
||||
@ -243,19 +255,10 @@ export class Schema {
|
||||
}
|
||||
});
|
||||
this._composer.addSchemaMustHaveType(typeComposer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds types 'ResultEvent' and 'WatchedEvent' to the schema.
|
||||
*/
|
||||
_addEventsRelatedTypes (): void {
|
||||
let typeComposer;
|
||||
|
||||
// Create Ethereum types.
|
||||
// Create the Block type.
|
||||
const blockName = 'Block';
|
||||
typeComposer = this._composer.createObjectTC({
|
||||
name: blockName,
|
||||
name: '_Block_',
|
||||
fields: {
|
||||
cid: 'String!',
|
||||
hash: 'String!',
|
||||
@ -265,9 +268,17 @@ export class Schema {
|
||||
}
|
||||
});
|
||||
this._composer.addSchemaMustHaveType(typeComposer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds types 'ResultEvent' and 'WatchedEvent' to the schema.
|
||||
*/
|
||||
_addEventsRelatedTypes (): void {
|
||||
let typeComposer;
|
||||
|
||||
// Create Ethereum types.
|
||||
// Create the Transaction type.
|
||||
const transactionName = 'Transaction';
|
||||
const transactionName = '_Transaction_';
|
||||
typeComposer = this._composer.createObjectTC({
|
||||
name: transactionName,
|
||||
fields: {
|
||||
@ -285,7 +296,7 @@ export class Schema {
|
||||
name: resultEventName,
|
||||
fields: {
|
||||
// Get type composer object for 'blockName' type from the schema composer.
|
||||
block: () => this._composer.getOTC(blockName).NonNull,
|
||||
block: () => this._composer.getOTC('_Block_').NonNull,
|
||||
tx: () => this._composer.getOTC(transactionName).NonNull,
|
||||
contract: 'String!',
|
||||
eventIndex: 'Int!',
|
||||
@ -326,7 +337,7 @@ export class Schema {
|
||||
const typeComposer = this._composer.createObjectTC({
|
||||
name: 'ResultIPLDBlock',
|
||||
fields: {
|
||||
block: () => this._composer.getOTC('Block').NonNull,
|
||||
block: () => this._composer.getOTC('_Block_').NonNull,
|
||||
contractAddress: 'String!',
|
||||
cid: 'String!',
|
||||
kind: 'String!',
|
||||
|
@ -17,10 +17,8 @@ import { IPLDBlock } from './entity/IPLDBlock';
|
||||
|
||||
{{#each queries as | query |}}
|
||||
import { {{query.entityName}} } from './entity/{{query.entityName}}';
|
||||
{{#unless @last}}
|
||||
|
||||
{{/unless}}
|
||||
{{/each}}
|
||||
|
||||
export class Database implements IPLDDatabaseInterface {
|
||||
_config: ConnectionOptions;
|
||||
_conn!: Connection;
|
||||
|
@ -4,11 +4,6 @@ import fs from 'fs';
|
||||
|
||||
import { loadFilesSync } from '@graphql-tools/load-files';
|
||||
|
||||
const SCALAR_MAPPING: any = {
|
||||
BigDecimal: 'String',
|
||||
Bytes: 'String'
|
||||
};
|
||||
|
||||
export function parseSubgraphSchema (subgraphPath: string): any {
|
||||
const subgraphSchemaPath = path.join(path.resolve(subgraphPath), '/schema.graphql');
|
||||
|
||||
@ -51,15 +46,7 @@ export function getFieldType (typeNode: any): { typeName: string, array: boolean
|
||||
|
||||
function parseType (typeNode: any): any {
|
||||
// Check if 'NamedType' is reached.
|
||||
if (typeNode.kind === 'NamedType') {
|
||||
const typeName: string = typeNode.name.value;
|
||||
|
||||
// TODO Handle extra types provided by the graph.
|
||||
// Replace unknown scalars using SCALAR_MAPPING.
|
||||
if (typeName in SCALAR_MAPPING) {
|
||||
typeNode.name.value = SCALAR_MAPPING[typeName];
|
||||
}
|
||||
} else {
|
||||
if (typeNode.kind !== 'NamedType') {
|
||||
typeNode.type = parseType(typeNode.type);
|
||||
}
|
||||
|
||||
|
@ -33,12 +33,15 @@ _tsToPg.set('string', 'varchar');
|
||||
_tsToPg.set('number', 'integer');
|
||||
_tsToPg.set('bigint', 'numeric');
|
||||
_tsToPg.set('boolean', 'boolean');
|
||||
_tsToPg.set('Decimal', 'numeric');
|
||||
|
||||
// Graphql to Typescript type-mapping.
|
||||
_gqlToTs.set('String', 'string');
|
||||
_gqlToTs.set('Int', 'number');
|
||||
_gqlToTs.set('BigInt', 'bigint');
|
||||
_gqlToTs.set('Boolean', 'boolean');
|
||||
_gqlToTs.set('BigDecimal', 'Decimal');
|
||||
_gqlToTs.set('Bytes', 'string');
|
||||
|
||||
function getTsForSol (solType: string): string | undefined {
|
||||
return _solToTs.get(solType);
|
||||
|
Loading…
Reference in New Issue
Block a user