Skip to content

Commit

Permalink
Fix interface generation/references (#288)
Browse files Browse the repository at this point in the history
* Add basic interface to test generation

* Add places that need to be updated to handle generating interfaces

* Add imports for the possibleTypes of an interface and generate TS type

* Add root store imports for unions AND interfaces

* Use the generated type for interfaces if using TS

* Fix rogue comma in generation based on a missing .join("") call

* Update snapshot for interface generation

* Put babelrc back so tests pass

* Remove unneeded transform in babelrc so rollup can build successfully

https://www.npmjs.com/package/@rollup/plugin-babel#modules

* yarn test updated these files for some reason?

* Remove unneeded interface from example 3

Co-authored-by: Jesse Savary <[email protected]>
  • Loading branch information
special-character and jesse-savary authored Mar 13, 2021
1 parent f9a4f97 commit 9438884
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 32 deletions.
22 changes: 22 additions & 0 deletions examples/3-twitter-clone/src/app/models/BaseIDModelSelector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* This is a mst-gql generated file, don't modify it manually */
/* eslint-disable */
/* tslint:disable */

import { QueryBuilder } from "mst-gql"
import { MessageModelType } from "./MessageModel"
import { MessageModelSelector } from "./MessageModel.base"
import { UserModelType } from "./UserModel"
import { UserModelSelector } from "./UserModel.base"

export type BaseIDUnion = UserModelType | MessageModelType

export class BaseIDModelSelector extends QueryBuilder {
get id() { return this.__attr(`id`) }
user(builder?: string | UserModelSelector | ((selector: UserModelSelector) => UserModelSelector)) { return this.__inlineFragment(`User`, UserModelSelector, builder) }
message(builder?: string | MessageModelSelector | ((selector: MessageModelSelector) => MessageModelSelector)) { return this.__inlineFragment(`Message`, MessageModelSelector, builder) }
}
export function selectFromBaseID() {
return new BaseIDModelSelector()
}

export const baseIDModelPrimitives = selectFromBaseID()
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { MSTGQLStore, configureStoreMixin, QueryOptions, withTypedRefs } from "m
import { UserModel, UserModelType } from "./UserModel"
import { MessageModel, MessageModelType } from "./MessageModel"

import { searchResultModelPrimitives, SearchResultModelSelector , SearchResultUnion } from "./"


/* The TypeScript type that explicits the refs to other models in order to prevent a circular refs issue */
Expand Down
64 changes: 32 additions & 32 deletions generator/generate.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ function generate(

const files = [] // [[name, contents]]
const objectTypes = [] // all known OBJECT types for which MST classes are generated
const unionTypes = [] // all known UNION types for which ModelSelector classes are generated
const origObjectTypes = [] // all known OBJECT types for which MST classes are generated
const inputTypes = [] // all known INPUT_OBJECT types for which MST classes are generated
const knownTypes = [] // all known types (including enums and such) for which MST classes are generated
Expand All @@ -62,7 +61,6 @@ function generate(
const modelTypePostfix = "ModelType"

const interfaceAndUnionTypes = resolveInterfaceAndUnionTypes(types)

generateModelBase()
generateTypes()
generateRootStore()
Expand Down Expand Up @@ -323,7 +321,6 @@ ${generateFragments(name, primitiveFields, nonPrimitiveFields)}
const interfaceOrUnionType = interfaceAndUnionTypes.get(type.name)
const isUnion =
interfaceOrUnionType && interfaceOrUnionType.kind === "UNION"
if (isUnion) unionTypes.push(type.name)
const fileName = type.name + "ModelSelector"
const {
primitiveFields,
Expand All @@ -343,32 +340,28 @@ ${generateFragments(name, primitiveFields, nonPrimitiveFields)}
...toBeImported
)

/** Imports from core model */
if (isUnion) {
// Import <model>ModelType from the core file to be used in the TS union type
addImportToMap(
imports,
fileName,
`${t.name}Model`,
`${t.name}ModelType`
)
}
/** 1) Imports model type from the model */
addImportToMap(
imports,
fileName,
`${t.name}Model`,
`${t.name}ModelType`
)
})

// Start building out the ModelSelector file
let contents = header + "\n\n"
contents += 'import { QueryBuilder } from "mst-gql"\n'
contents += printRelativeImports(imports)

// Add the correct type for a TS union to the exports
if (isUnion) {
contents += ifTS(
`export type ${
interfaceOrUnionType.name
}Union = ${interfaceOrUnionType.ofTypes
.map((unionModel) => `${unionModel.name}ModelType`)
.join(" | ")}\n\n`
)
}
/** 2) Add the correct type for a TS union to the exports of the ModelSelector file */
contents += ifTS(
`export type ${
interfaceOrUnionType.name
}Union = ${interfaceOrUnionType.ofTypes
.map((unionModel) => `${unionModel.name}ModelType`)
.join(" | ")}\n\n`
)

contents += generateFragments(
type.name,
Expand Down Expand Up @@ -639,14 +632,17 @@ ${objectTypes
}`
)
.join("")}
${unionTypes
.map(
(t) =>
`\nimport { ${toFirstLower(t)}ModelPrimitives, ${t}ModelSelector ${ifTS(
`, ${t}Union`
)} } from "./"`
)
.join("")}
${
/** 3) Add imports for ModelPrimitives and ModelSelector in RootStore.base */
[...interfaceAndUnionTypes.values()]
.map(
(t) =>
`\nimport { ${toFirstLower(t.name)}ModelPrimitives, ${
t.name
}ModelSelector ${ifTS(`, ${t.name}Union`)} } from "./"`
)
.join("")
}
${enumTypes
.map(
(t) =>
Expand Down Expand Up @@ -832,14 +828,18 @@ ${enumContent}
let returnType = returnsList ? type.ofType : type
if (returnType.kind === "NON_NULL") returnType = returnType.ofType

/** 4) Add the return type of the query if TS */
const tsType =
format !== "ts"
? ""
: `<{ ${name}: ${
isScalar
? `${printTsPrimitiveType(type.name)} `
: `${returnType.name}${
returnType.kind === "UNION" ? "Union" : modelTypePostfix
returnType.kind === "UNION" ||
returnType.kind === "INTERFACE"
? "Union"
: modelTypePostfix
}${returnsList ? "[]" : ""}`
}}>`

Expand Down
5 changes: 5 additions & 0 deletions tests/generator/__snapshots__/generate.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1235,9 +1235,13 @@ export const RepoModel = RepoModelBase
/* tslint:disable */
import { QueryBuilder } from \\"mst-gql\\"
import { OrganizationModelType } from \\"./OrganizationModel\\"
import { OrganizationModelSelector } from \\"./OrganizationModel.base\\"
import { UserModelType } from \\"./UserModel\\"
import { UserModelSelector } from \\"./UserModel.base\\"
export type OwnerUnion = UserModelType | OrganizationModelType
export class OwnerModelSelector extends QueryBuilder {
get id() { return this.__attr(\`id\`) }
get name() { return this.__attr(\`name\`) }
Expand Down Expand Up @@ -1418,6 +1422,7 @@ import { userModelPrimitives, UserModelSelector } from \\"./UserModel.base\\"
import { OrganizationModel, OrganizationModelType } from \\"./OrganizationModel\\"
import { organizationModelPrimitives, OrganizationModelSelector } from \\"./OrganizationModel.base\\"
import { ownerModelPrimitives, OwnerModelSelector , OwnerUnion } from \\"./\\"
/* The TypeScript type that explicits the refs to other models in order to prevent a circular refs issue */
Expand Down
2 changes: 2 additions & 0 deletions tests/lib/abstractTypes/models/OwnerModelSelector.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
/* eslint-disable */

import { QueryBuilder } from "mst-gql"
import { OrganizationModelType } from "./OrganizationModel"
import { OrganizationModelSelector } from "./OrganizationModel.base"
import { UserModelType } from "./UserModel"
import { UserModelSelector } from "./UserModel.base"

export class OwnerModelSelector extends QueryBuilder {
Expand Down
1 change: 1 addition & 0 deletions tests/lib/abstractTypes/models/RootStore.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { OrganizationModel } from "./OrganizationModel"
import { organizationModelPrimitives, OrganizationModelSelector } from "./OrganizationModel.base"

import { searchItemModelPrimitives, SearchItemModelSelector } from "./"
import { ownerModelPrimitives, OwnerModelSelector } from "./"



Expand Down

0 comments on commit 9438884

Please sign in to comment.