Skip to content

Commit 41a11ac

Browse files
authored
Support types mapping include float (#532)
* support float and types mapping,change eslint complexity back to 20 , add bn.js to dependency in common * Fix bn.js dependency * change BN to bn * remove bn.js in dependencies * fix extractType
1 parent ea32bf2 commit 41a11ac

34 files changed

+281
-100
lines changed

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ module.exports = {
6666
// "@typescript-eslint/no-param-reassign": "error",
6767
'@typescript-eslint/promise-function-async': ['error', {checkArrowFunctions: false}],
6868
// "arrow-body-style": "error",
69-
complexity: ['error', 21],
69+
complexity: ['error', 20],
7070
curly: ['error', 'multi-line'],
7171
'default-case': 'error',
7272
eqeqeq: ['error', 'always'],

packages/cli/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
All logs must start with the format: [x.y.z] - yyyy-mm-dd
88

99
## [Unreleased]
10+
### Added
11+
- Support Float type in Cli
1012

1113
## [0.15.0] - 2021-11-03
1214
### Changed

packages/cli/src/controller/codegen-controller.test.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
import path from 'path';
55
import {promisify} from 'util';
6+
67
import rimraf from 'rimraf';
78
import {codegen} from './codegen-controller';
8-
import {transformTypes} from './types-mapping';
99

1010
jest.setTimeout(30000);
1111

@@ -15,15 +15,6 @@ describe('Codegen can generate schema', () => {
1515
await promisify(rimraf)(path.join(__dirname, '../../test/schemaTest2/src'));
1616
});
1717

18-
it('can transform field into correct type', () => {
19-
const testClassName = 'transformTest;';
20-
expect(transformTypes(testClassName, 'ID')).toBe('string');
21-
expect(transformTypes(testClassName, 'Int')).toBe('number');
22-
expect(transformTypes(testClassName, 'BigInt')).toBe('bigint');
23-
expect(transformTypes(testClassName, 'String')).toBe('string');
24-
expect(transformTypes(testClassName, 'Date')).toBe('Date');
25-
});
26-
2718
it('codegen with correct schema should pass', async () => {
2819
const projectPath = path.join(__dirname, '../../test/schemaTest1');
2920
await codegen(projectPath);

packages/cli/src/controller/codegen-controller.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ import {
99
loadProjectManifest,
1010
getAllJsonObjects,
1111
setJsonObjectType,
12+
getTypeByScalarName,
13+
GraphQLEntityField,
14+
GraphQLJsonFieldType,
15+
GraphQLEntityIndex,
1216
getAllEnums,
1317
} from '@subql/common';
14-
import {GraphQLEntityField, GraphQLJsonFieldType, GraphQLEntityIndex} from '@subql/common/graphql/types';
1518
import ejs from 'ejs';
1619
import {upperFirst} from 'lodash';
1720
import rimraf from 'rimraf';
18-
import {transformTypes} from './types-mapping';
1921

2022
const MODEL_TEMPLATE_PATH = path.resolve(__dirname, '../template/model.ts.ejs');
2123
const MODELS_INDEX_TEMPLATE_PATH = path.resolve(__dirname, '../template/models-index.ts.ejs');
@@ -135,15 +137,14 @@ export function processFields(
135137
injectField.indexed = indexed;
136138
injectField.unique = unique;
137139
}
138-
139140
if ((field as GraphQLEntityField).isEnum) {
140141
injectField.type = field.type;
141142
injectField.isEnum = true;
142143
injectField.isJsonInterface = false;
143144
} else {
144145
switch (field.type) {
145146
default: {
146-
injectField.type = transformTypes(className, field.type.toString());
147+
injectField.type = getTypeByScalarName(field.type).tsType;
147148
if (!injectField.type) {
148149
throw new Error(
149150
`Schema: undefined type "${field.type.toString()}" on field "${

packages/cli/src/controller/types-mapping.ts

Lines changed: 0 additions & 21 deletions
This file was deleted.

packages/cli/test/schemaTest1/schema.graphql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ type goodEntity @entity {
77
field1: Int!
88

99
field2: String #filed2 is an optional field
10+
1011
field3: BigInt
1112

1213
field4: Date
1314

1415
field5: Test
16+
17+
field6: Float
1518
}
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
type badEntity @entity {
2-
3-
id: Float #give the unknown type
2+
id: BigDecimal
43
}

packages/common/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
All logs must start with the format: [x.y.z] - yyyy-mm-dd
88

99
## [Unreleased]
10+
### Added
11+
- Add Bytes type
1012

1113
## [0.13.0] - 2021-11-03
1214
### Added

packages/common/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
"graphql-tag": "^2.12.5",
2222
"js-yaml": "^4.1.0",
2323
"pino": "^6.13.3",
24-
"reflect-metadata": "^0.1.13"
24+
"reflect-metadata": "^0.1.13",
25+
"sequelize": "^6.6.2"
2526
},
2627
"devDependencies": {
2728
"@types/js-yaml": "^4.0.4",

packages/common/src/graphql/entities.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
import assert from 'assert';
5+
import {getTypeByScalarName} from '@subql/common';
56
import {
67
assertListType,
78
getDirectiveValues,
@@ -31,7 +32,6 @@ import {
3132
GraphQLRelationsType,
3233
IndexType,
3334
} from './types';
34-
import {isFieldScalar} from './utils';
3535

3636
export function getAllJsonObjects(_schema: GraphQLSchema | string): GraphQLObjectType[] {
3737
const schema = typeof _schema === 'string' ? buildSchema(_schema) : _schema;
@@ -48,6 +48,7 @@ export function getAllEnums(_schema: GraphQLSchema | string) {
4848
.map((node) => node);
4949
}
5050

51+
// eslint-disable-next-line complexity
5152
export function getAllEntitiesRelations(_schema: GraphQLSchema | string): GraphQLModelsRelationsEnums {
5253
const schema = typeof _schema === 'string' ? buildSchema(_schema) : _schema;
5354
const entities = Object.values(schema.getTypeMap())
@@ -83,7 +84,8 @@ export function getAllEntitiesRelations(_schema: GraphQLSchema | string): GraphQ
8384
const derivedFromDirectValues = getDirectiveValues(derivedFrom, field.astNode);
8485
const indexDirectiveVal = getDirectiveValues(indexDirective, field.astNode);
8586
//If is a basic scalar type
86-
if (isFieldScalar(typeString)) {
87+
const typeClass = getTypeByScalarName(typeString);
88+
if (typeClass?.fieldScalar) {
8789
newModel.fields.push(packEntityField(typeString, field, false));
8890
}
8991
// If is an enum
@@ -139,7 +141,7 @@ export function getAllEntitiesRelations(_schema: GraphQLSchema | string): GraphQ
139141
}
140142
// handle indexes
141143
if (indexDirectiveVal) {
142-
if (typeString !== 'ID' && isFieldScalar(typeString)) {
144+
if (typeString !== 'ID' && typeClass) {
143145
newModel.indexes.push({
144146
unique: indexDirectiveVal.unique,
145147
fields: [field.name],
@@ -223,7 +225,6 @@ export function setJsonObjectType(
223225
return graphQLJsonObject;
224226
}
225227

226-
type GraphQLNonListType = GraphQLScalarType | GraphQLObjectType<unknown, unknown>; // check | GraphQLInterfaceType | GraphQLUnionType | GraphQLEnumType;
227228
//Get the type, ready to be convert to string
228229
function extractType(type: GraphQLOutputType): string {
229230
if (isUnionType(type)) {

packages/common/src/graphql/graphql.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,18 @@ describe('utils that handle schema.graphql', () => {
4343
expect(() => buildSchemaFromDocumentNode(graphqlSchema)).toThrow();
4444
});
4545

46-
it('support Bytes types', () => {
46+
it('support Bytes and Float types', () => {
4747
const graphqlSchema = gql`
4848
type Test @entity {
4949
id: ID!
5050
hash: Bytes
51+
rate: Float
5152
}
5253
`;
5354
const schema = buildSchemaFromDocumentNode(graphqlSchema);
5455
const entities = getAllEntitiesRelations(schema);
5556
expect(entities.models[0].fields[1].type).toBe('Bytes');
57+
expect(entities.models[0].fields[2].type).toBe('Float');
5658
});
5759

5860
it('throw error for union/enum/interface type', () => {

packages/common/src/graphql/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33

44
export * from './entities';
55
export * from './schema';
6+
export * from './types';
67
export * from './builder';

packages/common/src/graphql/schema/scalas.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ export const scalas = gql`
88
scalar BigDecimal
99
scalar Date
1010
scalar Bytes
11+
scalar Float
1112
`;

packages/common/src/graphql/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,5 @@ export enum FieldScalar {
9393
Date = 'Date',
9494
Boolean = 'Boolean',
9595
Bytes = 'Bytes',
96+
Float = 'Float',
9697
}

packages/common/src/graphql/utils.ts

Lines changed: 0 additions & 8 deletions
This file was deleted.

packages/common/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export * from './project';
77
export * from './graphql';
88
export * from './query';
99
export {levelFilter, Logger, LoggerOption} from './logger';
10+
export * from './types';
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2020-2021 OnFinality Limited authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import assert from 'assert';
5+
import {DataTypes} from 'sequelize';
6+
type ValueOf<T> = T[keyof T];
7+
export type SequelizeTypes = string | ValueOf<typeof DataTypes>;
8+
9+
export class TypeClass {
10+
constructor(
11+
public name: string,
12+
private _hashCode: (data: unknown) => Uint8Array,
13+
private _tsType?: string,
14+
private _fieldScalar?: string,
15+
private _sequelizeType?: SequelizeTypes
16+
) {}
17+
get tsType(): string | undefined {
18+
return this._tsType;
19+
}
20+
get fieldScalar(): string | undefined {
21+
return this._fieldScalar;
22+
}
23+
get sequelizeType(): SequelizeTypes {
24+
assert(this._sequelizeType !== undefined, `Type ${this.name} associated sequelize type is not supported`);
25+
return this._sequelizeType;
26+
}
27+
hashCode(data: any): Uint8Array {
28+
if (this._hashCode === undefined) {
29+
return Buffer.from(JSON.stringify(data));
30+
}
31+
return this._hashCode(data);
32+
}
33+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2020-2021 OnFinality Limited authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import {getTypeByScalarName} from '@subql/common';
5+
6+
describe('general types', () => {
7+
it('can get json type', () => {
8+
const typeClass = getTypeByScalarName('Json');
9+
expect(typeClass.name).toBe('Json');
10+
});
11+
12+
it('get sequelize date type', () => {
13+
const typeClass = getTypeByScalarName('Date');
14+
expect(typeClass.sequelizeType).toBe('timestamp');
15+
});
16+
});
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright 2020-2021 OnFinality Limited authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import * as supportedTypes from './supported';
5+
import {TypeClass} from './TypeClass';
6+
7+
export function getTypeByScalarName(type: string): TypeClass | undefined {
8+
return Object.values(supportedTypes).find(({name}) => name === type) as TypeClass;
9+
}

packages/common/src/types/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright 2020-2021 OnFinality Limited authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
export * from './generalTypes';
5+
6+
export * from './TypeClass';
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2020-2021 OnFinality Limited authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import BN from 'bn.js';
5+
import {TypeClass} from '../TypeClass';
6+
7+
export const BigInt = new TypeClass(
8+
'BigInt',
9+
(data: bigint | string): Uint8Array => {
10+
return new BN(data.toString()).toBuffer();
11+
},
12+
'bigint',
13+
'BigInt',
14+
'numeric'
15+
);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2020-2021 OnFinality Limited authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import {numberToU8a} from '@polkadot/util';
5+
import {TypeClass} from '../TypeClass';
6+
7+
export const Boolean = new TypeClass(
8+
'Boolean',
9+
(data: boolean): Uint8Array => {
10+
return numberToU8a(data ? 1 : 0);
11+
},
12+
'boolean',
13+
'Boolean',
14+
'boolean'
15+
);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2020-2021 OnFinality Limited authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import {isHex, hexToU8a} from '@polkadot/util';
5+
import {DataTypes} from 'sequelize';
6+
import {TypeClass} from '../TypeClass';
7+
8+
export const Bytes = new TypeClass(
9+
'Bytes',
10+
(data: string | Uint8Array): Uint8Array => {
11+
if (data instanceof Uint8Array) return data;
12+
if (isHex(data)) {
13+
return hexToU8a(data);
14+
}
15+
throw new Error(`can not hash ${data}`);
16+
},
17+
'string',
18+
'Bytes',
19+
DataTypes.BLOB
20+
);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2020-2021 OnFinality Limited authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import assert from 'assert';
5+
import {numberToU8a} from '@polkadot/util';
6+
import {TypeClass} from '../TypeClass';
7+
8+
export const DateObj = new TypeClass(
9+
'Date',
10+
(data: Date): Uint8Array => {
11+
assert(data instanceof Date, `can not hash ${data}, expect instance of Date`);
12+
return numberToU8a(data.getTime());
13+
},
14+
'Date',
15+
'Date',
16+
'timestamp'
17+
);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2020-2021 OnFinality Limited authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import {DataTypes} from 'sequelize';
5+
import {TypeClass} from '../TypeClass';
6+
7+
export const Float = new TypeClass(
8+
'Float',
9+
(data: number): Uint8Array => {
10+
//TODO, check if this is proper way to handle float
11+
return Buffer.from(data.toString());
12+
},
13+
'number',
14+
'Float',
15+
DataTypes.FLOAT
16+
);

0 commit comments

Comments
 (0)