Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: remove immutable #1021

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/@graphprotocol_graph-cli-1021-dependencies.md
@@ -0,0 +1,5 @@
---
'@graphprotocol/graph-cli': patch
---
dependencies updates:
- Removed dependency [`immutable@3.8.2` ↗︎](https://www.npmjs.com/package/immutable/v/3.8.2) (from `dependencies`)
1 change: 0 additions & 1 deletion packages/cli/package.json
Expand Up @@ -16,7 +16,6 @@
"glob": "7.1.6",
"gluegun": "https://github.com/edgeandnode/gluegun#v4.3.1-pin-colors-dep",
"graphql": "15.5.0",
"immutable": "3.8.2",
"ipfs-http-client": "34.0.0",
"jayson": "3.6.6",
"js-yaml": "3.13.1",
Expand Down
107 changes: 49 additions & 58 deletions packages/cli/src/codegen/schema.js
@@ -1,54 +1,50 @@
const immutable = require('immutable')

const tsCodegen = require('./typescript')
const typesCodegen = require('./types')

const List = immutable.List

class IdField {
static BYTES = Symbol("Bytes")
static STRING = Symbol("String")
static BYTES = Symbol('Bytes')
static STRING = Symbol('String')

constructor(idField) {
const typeName = idField.getIn(['type', 'type', 'name', 'value'])
this.kind = typeName === "Bytes" ? IdField.BYTES : IdField.STRING
const typeName = idField.type?.type?.name?.value
this.kind = typeName === 'Bytes' ? IdField.BYTES : IdField.STRING
}

typeName() {
return this.kind === IdField.BYTES ? "Bytes" : "string"
return this.kind === IdField.BYTES ? 'Bytes' : 'string'
}

gqlTypeName() {
return this.kind === IdField.BYTES ? "Bytes" : "String"
return this.kind === IdField.BYTES ? 'Bytes' : 'String'
}

tsNamedType() {
return tsCodegen.namedType(this.typeName())
}

tsValueFrom() {
return this.kind === IdField.BYTES ? "Value.fromBytes(id)" : "Value.fromString(id)"
return this.kind === IdField.BYTES ? 'Value.fromBytes(id)' : 'Value.fromString(id)'
}

tsValueKind() {
return this.kind === IdField.BYTES ? "ValueKind.BYTES" : "ValueKind.STRING"
return this.kind === IdField.BYTES ? 'ValueKind.BYTES' : 'ValueKind.STRING'
}

tsValueToString() {
return this.kind == IdField.BYTES ? "id.toBytes().toHexString()" : "id.toString()"
return this.kind == IdField.BYTES ? 'id.toBytes().toHexString()' : 'id.toString()'
}

tsToString() {
return this.kind == IdField.BYTES ? "id.toHexString()" : "id"
return this.kind == IdField.BYTES ? 'id.toHexString()' : 'id'
}

static fromFields(fields) {
const idField = fields.find(field => field.getIn(['name', 'value']) === 'id')
const idField = fields.find(field => field.name?.value === 'id')
return new IdField(idField)
}

static fromTypeDef(def) {
return IdField.fromFields(def.get("fields"))
return IdField.fromFields(def.fields)
}
}

Expand Down Expand Up @@ -81,29 +77,26 @@ module.exports = class SchemaCodeGenerator {
}

generateTypes() {
return this.schema.ast
.get('definitions')
return this.schema.ast.definitions
.filter(def => this._isEntityTypeDefinition(def))
.map(def => this._generateEntityType(def))
}

_isEntityTypeDefinition(def) {
return (
def.get('kind') === 'ObjectTypeDefinition' &&
def
.get('directives')
.find(directive => directive.getIn(['name', 'value']) === 'entity') !== undefined
def.kind === 'ObjectTypeDefinition' &&
def.directives.find(directive => directive.name?.value === 'entity') !== undefined
)
}

_isInterfaceDefinition(def) {
return def.get('kind') === 'InterfaceTypeDefinition'
return def.kind === 'InterfaceTypeDefinition'
}

_generateEntityType(def) {
let name = def.getIn(['name', 'value'])
let name = def.name?.value
let klass = tsCodegen.klass(name, { export: true, extends: 'Entity' })
const fields = def.get('fields')
const fields = def.fields
const idField = IdField.fromFields(fields)

// Generate and add a constructor
Expand All @@ -113,11 +106,10 @@ module.exports = class SchemaCodeGenerator {
this._generateStoreMethods(name, idField).forEach(method => klass.addMethod(method))

// Generate and add entity field getters and setters
def
.get('fields')
def.fields
.reduce(
(methods, field) => methods.concat(this._generateEntityFieldMethods(def, field)),
List(),
[],
)
.forEach(method => klass.addMethod(method))

Expand All @@ -138,7 +130,7 @@ module.exports = class SchemaCodeGenerator {
}

_generateStoreMethods(entityName, idField) {
return List.of(
return [
tsCodegen.method(
'save',
[],
Expand All @@ -162,19 +154,19 @@ module.exports = class SchemaCodeGenerator {
return changetype<${entityName} | null>(store.get('${entityName}', ${idField.tsToString()}))
`,
),
)
]
}

_generateEntityFieldMethods(entityDef, fieldDef) {
return List([
return [
this._generateEntityFieldGetter(entityDef, fieldDef),
this._generateEntityFieldSetter(entityDef, fieldDef),
])
]
}

_generateEntityFieldGetter(entityDef, fieldDef) {
let name = fieldDef.getIn(['name', 'value'])
let gqlType = fieldDef.get('type')
let name = fieldDef.name?.value
let gqlType = fieldDef.type
let fieldValueType = this._valueTypeFromGraphQl(gqlType)
let returnType = this._typeFromGraphQl(gqlType)
let isNullable = returnType instanceof tsCodegen.NullableType
Expand All @@ -198,25 +190,21 @@ module.exports = class SchemaCodeGenerator {
}

_generateEntityFieldSetter(entityDef, fieldDef) {
let name = fieldDef.getIn(['name', 'value'])
let gqlType = fieldDef.get('type')
let name = fieldDef.name?.value
let gqlType = fieldDef.type
let fieldValueType = this._valueTypeFromGraphQl(gqlType)
let paramType = this._typeFromGraphQl(gqlType)
let isNullable = paramType instanceof tsCodegen.NullableType
let paramTypeString = isNullable ? paramType.inner.toString() : paramType.toString()
let isArray = paramType instanceof tsCodegen.ArrayType

if (
isArray &&
paramType.inner instanceof tsCodegen.NullableType
) {
if (isArray && paramType.inner instanceof tsCodegen.NullableType) {
let baseType = this._baseType(gqlType)

throw new Error(`
GraphQL schema can't have List's with Nullable members.
Error in '${name}' field of type '[${baseType}]'.
Suggestion: add an '!' to the member type of the List, change from '[${baseType}]' to '[${baseType}!]'`
)
Suggestion: add an '!' to the member type of the List, change from '[${baseType}]' to '[${baseType}!]'`)
}

let setNonNullable = `
Expand All @@ -242,12 +230,15 @@ Suggestion: add an '!' to the member type of the List, change from '[${baseType}
}

_resolveFieldType(gqlType) {
let typeName = gqlType.getIn(['name', 'value'])
let typeName = gqlType.name?.value

// If this is a reference to another type, the field has the type of
// the referred type's id field
const typeDef = this.schema.ast.get("definitions").
find(def => (this._isEntityTypeDefinition(def) || this._isInterfaceDefinition(def)) && def.getIn(["name", "value"]) === typeName)
const typeDef = this.schema.ast.definitions.find(
def =>
(this._isEntityTypeDefinition(def) || this._isInterfaceDefinition(def)) &&
def.name?.value === typeName,
)
if (typeDef) {
return IdField.fromTypeDef(typeDef).typeName()
} else {
Expand All @@ -260,10 +251,10 @@ Suggestion: add an '!' to the member type of the List, change from '[${baseType}
* other entity types, this is the same as the type of the id of the
* referred type, i.e., `string` or `Bytes`*/
_valueTypeFromGraphQl(gqlType) {
if (gqlType.get('kind') === 'NonNullType') {
return this._valueTypeFromGraphQl(gqlType.get('type'), false)
} else if (gqlType.get('kind') === 'ListType') {
return '[' + this._valueTypeFromGraphQl(gqlType.get('type')) + ']'
if (gqlType.kind === 'NonNullType') {
return this._valueTypeFromGraphQl(gqlType.type, false)
} else if (gqlType.kind === 'ListType') {
return '[' + this._valueTypeFromGraphQl(gqlType.type) + ']'
} else {
return this._resolveFieldType(gqlType)
}
Expand All @@ -272,20 +263,20 @@ Suggestion: add an '!' to the member type of the List, change from '[${baseType}
/** Determine the base type of `gqlType` by removing any non-null
* constraints and using the type of elements of lists */
_baseType(gqlType) {
if (gqlType.get('kind') === 'NonNullType') {
return this._baseType(gqlType.get('type'))
} else if (gqlType.get('kind') === 'ListType') {
return this._baseType(gqlType.get('type'))
if (gqlType.kind === 'NonNullType') {
return this._baseType(gqlType.type)
} else if (gqlType.kind === 'ListType') {
return this._baseType(gqlType.type)
} else {
return gqlType.getIn(['name', 'value'])
return gqlType.name?.value
}
}

_typeFromGraphQl(gqlType, nullable = true) {
if (gqlType.get('kind') === 'NonNullType') {
return this._typeFromGraphQl(gqlType.get('type'), false)
} else if (gqlType.get('kind') === 'ListType') {
let type = tsCodegen.arrayType(this._typeFromGraphQl(gqlType.get('type')))
if (gqlType.kind === 'NonNullType') {
return this._typeFromGraphQl(gqlType.type, false)
} else if (gqlType.kind === 'ListType') {
let type = tsCodegen.arrayType(this._typeFromGraphQl(gqlType.type))
return nullable ? tsCodegen.nullableType(type) : type
} else {
// NamedType
Expand Down