Skip to content

Commit

Permalink
fix(hydra-cli): ignore generating module import for self referenced e…
Browse files Browse the repository at this point in the history
…ntities (#322)

* fix(hydra-cli): ignore generating module import for self referenced entities

* test(hydra-cli): add tests for self reference imports

affects: @dzlzv/hydra-cli
  • Loading branch information
metmirr authored Mar 17, 2021
1 parent 6115f89 commit 2d09777
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 14 deletions.
22 changes: 8 additions & 14 deletions packages/hydra-cli/src/generate/ModelRenderer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as path from 'path'
import { ObjectType, WarthogModel, FieldResolver } from '../model'
import Debug from 'debug'
import { GeneratorContext } from './SourcesGenerator'
Expand Down Expand Up @@ -108,22 +107,15 @@ export class ModelRenderer extends AbstractRenderer {

withImportProps(): GeneratorContext {
const relatedEntityImports: Set<string> = new Set()

this.objType.fields
.filter((f) => f.relation)
.forEach((f) => {
const columnType = f.relation?.columnType
if (!columnType) {
// should never happen
throw new Error(`Relation column type for ${f.name} is undefined`)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const { columnType } = f.relation!
// Check if it is not a self reference so we don't add the object to import list
if (columnType !== this.objType.name) {
relatedEntityImports.add(utils.generateEntityImport(columnType))
}
relatedEntityImports.add(
path.join(
`import { ${columnType} } from '..`,
utils.kebabCase(columnType),
`${utils.kebabCase(columnType)}.model'`
)
)
})
return {
relatedEntityImports: Array.from(relatedEntityImports.values()),
Expand All @@ -145,7 +137,9 @@ export class ModelRenderer extends AbstractRenderer {
rootArgName: 'r', // disable utils.camelCase(entityName) could be a reverved ts/js keyword ie `class`
returnType: utils.generateResolverReturnType(returnTypeFunc, f.isList),
})
fieldResolverImports.add(utils.generateEntityImport(returnTypeFunc))
if (f.type !== this.objType.name) {
fieldResolverImports.add(utils.generateEntityImport(returnTypeFunc))
}
}
const imports = Array.from(fieldResolverImports.values())
// If there is at least one field resolver then add typeorm to imports
Expand Down
5 changes: 5 additions & 0 deletions packages/hydra-cli/src/model/relations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ function addOne2Many(rel: EntityRelationship): void {
field.name,
relatedField.nullable
)
// Re-organize relation types if it is a self reference
if (field.type === relatedField.type && rel.field.isList) {
rel.field.relation.type = 'otm'
rel.relatedField.relation.type = 'mto'
}
}

function addOne2One(rel: EntityRelationship): void {
Expand Down
35 changes: 35 additions & 0 deletions packages/hydra-cli/test/helpers/Relationships.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { expect } from 'chai'
import * as fs from 'fs-extra'
import { EnumContextProvider } from '../../src/generate/EnumContextProvider'
import { ModelRenderer } from '../../src/generate/ModelRenderer'
import { fromStringSchema } from './model'

describe('Entity Relationships', () => {
let generator: ModelRenderer
let modelTemplate: string
let enumCtxProvider: EnumContextProvider

before(() => {
modelTemplate = fs.readFileSync(
'./src/templates/entities/model.ts.mst',
'utf-8'
)
})

it('should not create import statement for self referenced entities', () => {
const model = fromStringSchema(`
type Member @entity {
invitor: Member
invitees: [Member!] @derivedFrom(field: "invitor")
}`)
generator = new ModelRenderer(
model,
model.lookupEntity('Member'),
enumCtxProvider
)
const rendered = generator.render(modelTemplate)
expect(rendered).to.not.include(
`import { Member } from '../member/member.model.ts'`
)
})
})

0 comments on commit 2d09777

Please sign in to comment.