Skip to content

Commit b969d8d

Browse files
authored
fixes #313 (#315)
1 parent 9438884 commit b969d8d

19 files changed

+413
-15
lines changed

jest.config.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
module.exports = {
22
testEnvironment: "node",
33
testPathIgnorePatterns: ["/node_modules/", "/examples/"],
4-
watchPathIgnorePatterns: ["/tests/lib/todos/models/"],
4+
watchPathIgnorePatterns: [
5+
"/tests/lib/todos/models/",
6+
"/tests/lib/unionTypes/models/"
7+
],
58
moduleNameMapper: {
69
"^mst-gql$": "<rootDir>/src/mst-gql.ts"
710
}

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@
7373
"husky": "^4.3.0",
7474
"jest": "^26.4.2",
7575
"microbundle": "^0.12.3",
76-
"mobx": "^6.0.4",
76+
"mobx": "^6.1.0",
7777
"mobx-react": "^7.0.5",
78-
"mobx-state-tree": "^4.0.2",
78+
"mobx-state-tree": "^5.0.1",
7979
"prettier": "^2.1.2",
8080
"pretty-quick": "^3.0.2",
8181
"react": "^16.13.1",

src/MSTGQLObject.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,19 @@ import { StoreType } from "./MSTGQLStore"
1313
For detached objects (objects that are not part of the Roots, or one of their children, for example: query results),
1414
we cannot use the default resolution mechanism, since they are not part of the store. So, first fetch the store and resolve from there
1515
*/
16+
const MSTGQL_ID_DELIM = "::"
17+
export function getMSTGQLRefLabelAndId(labeledId: string) {
18+
const [label, ...id] = labeledId.split(MSTGQL_ID_DELIM)
19+
return { label, id: id.join("") }
20+
}
21+
1622
export function MSTGQLRef<T extends IAnyModelType>(
17-
targetType: T
23+
targetType: T,
24+
label: string = targetType.name
1825
): IReferenceType<T> {
1926
return types.reference(targetType, {
20-
get(id: string, parent: any) {
27+
get(labeledId: string, parent: any) {
28+
const id = getMSTGQLRefLabelAndId(labeledId).id
2129
const node = resolveIdentifier(
2230
targetType,
2331
parent.store || getParent<any>(parent).store,
@@ -31,7 +39,7 @@ export function MSTGQLRef<T extends IAnyModelType>(
3139
return node
3240
},
3341
set(value: any) {
34-
return value.id
42+
return [label, MSTGQL_ID_DELIM, value.id].join("")
3543
}
3644
})
3745
}

src/mst-gql.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export { MSTGQLStore, configureStoreMixin } from "./MSTGQLStore"
22
export { Query, CaseHandlers, QueryOptions, FetchPolicy } from "./Query"
3-
export { MSTGQLObject, MSTGQLRef } from "./MSTGQLObject"
3+
export { MSTGQLObject, MSTGQLRef, getMSTGQLRefLabelAndId } from "./MSTGQLObject"
44
export { createHttpClient, HttpClientOptions } from "./createHttpClient"
55
export { QueryBuilder } from "./queryBuilder"
66
export * from "./localStorageMixin"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* This is a mst-gql generated file, don't modify it manually */
2+
/* eslint-disable */
3+
4+
import { types } from "mobx-state-tree"
5+
import { QueryBuilder } from "mst-gql"
6+
import { ModelBase } from "./ModelBase"
7+
8+
9+
/**
10+
* BasicTodoBase
11+
* auto generated base class for the model BasicTodoModel.
12+
*/
13+
export const BasicTodoModelBase = ModelBase
14+
.named('BasicTodo')
15+
.props({
16+
__typename: types.optional(types.literal("BasicTodo"), "BasicTodo"),
17+
id: types.identifier,
18+
text: types.union(types.undefined, types.null, types.string),
19+
complete: types.union(types.undefined, types.null, types.boolean),
20+
})
21+
.views(self => ({
22+
get store() {
23+
return self.__getStore()
24+
}
25+
}))
26+
27+
export class BasicTodoModelSelector extends QueryBuilder {
28+
get id() { return this.__attr(`id`) }
29+
get text() { return this.__attr(`text`) }
30+
get complete() { return this.__attr(`complete`) }
31+
}
32+
export function selectFromBasicTodo() {
33+
return new BasicTodoModelSelector()
34+
}
35+
36+
export const basicTodoModelPrimitives = selectFromBasicTodo().text.complete
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { BasicTodoModelBase } from "./BasicTodoModel.base"
2+
3+
/* A graphql query fragment builders for BasicTodoModel */
4+
export {
5+
selectFromBasicTodo,
6+
basicTodoModelPrimitives,
7+
BasicTodoModelSelector
8+
} from "./BasicTodoModel.base"
9+
10+
/**
11+
* BasicTodoModel
12+
*/
13+
export const BasicTodoModel = BasicTodoModelBase.actions((self) => ({
14+
// This is an auto-generated example action.
15+
log() {
16+
console.log(JSON.stringify(self))
17+
}
18+
}))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* This is a mst-gql generated file, don't modify it manually */
2+
/* eslint-disable */
3+
4+
import { types } from "mobx-state-tree"
5+
import { QueryBuilder } from "mst-gql"
6+
import { ModelBase } from "./ModelBase"
7+
8+
9+
/**
10+
* FancyTodoBase
11+
* auto generated base class for the model FancyTodoModel.
12+
*/
13+
export const FancyTodoModelBase = ModelBase
14+
.named('FancyTodo')
15+
.props({
16+
__typename: types.optional(types.literal("FancyTodo"), "FancyTodo"),
17+
id: types.identifier,
18+
label: types.union(types.undefined, types.null, types.string),
19+
color: types.union(types.undefined, types.null, types.string),
20+
complete: types.union(types.undefined, types.null, types.boolean),
21+
})
22+
.views(self => ({
23+
get store() {
24+
return self.__getStore()
25+
}
26+
}))
27+
28+
export class FancyTodoModelSelector extends QueryBuilder {
29+
get id() { return this.__attr(`id`) }
30+
get label() { return this.__attr(`label`) }
31+
get color() { return this.__attr(`color`) }
32+
get complete() { return this.__attr(`complete`) }
33+
}
34+
export function selectFromFancyTodo() {
35+
return new FancyTodoModelSelector()
36+
}
37+
38+
export const fancyTodoModelPrimitives = selectFromFancyTodo().label.color.complete
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { FancyTodoModelBase } from "./FancyTodoModel.base"
2+
3+
/* A graphql query fragment builders for FancyTodoModel */
4+
export {
5+
selectFromFancyTodo,
6+
fancyTodoModelPrimitives,
7+
FancyTodoModelSelector
8+
} from "./FancyTodoModel.base"
9+
10+
/**
11+
* FancyTodoModel
12+
*/
13+
export const FancyTodoModel = FancyTodoModelBase.actions((self) => ({
14+
// This is an auto-generated example action.
15+
log() {
16+
console.log(JSON.stringify(self))
17+
}
18+
}))
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { MSTGQLObject } from "mst-gql"
2+
3+
export const ModelBase = MSTGQLObject
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/* This is a mst-gql generated file, don't modify it manually */
2+
/* eslint-disable */
3+
import { types } from "mobx-state-tree"
4+
import { MSTGQLStore, configureStoreMixin } from "mst-gql"
5+
6+
import { TodoListModel } from "./TodoListModel"
7+
import { todoListModelPrimitives, TodoListModelSelector } from "./TodoListModel.base"
8+
import { BasicTodoModel } from "./BasicTodoModel"
9+
import { basicTodoModelPrimitives, BasicTodoModelSelector } from "./BasicTodoModel.base"
10+
import { FancyTodoModel } from "./FancyTodoModel"
11+
import { fancyTodoModelPrimitives, FancyTodoModelSelector } from "./FancyTodoModel.base"
12+
13+
import { todoModelPrimitives, TodoModelSelector } from "./"
14+
15+
16+
17+
18+
19+
20+
/**
21+
* Store, managing, among others, all the objects received through graphQL
22+
*/
23+
export const RootStoreBase = MSTGQLStore
24+
.named("RootStore")
25+
.extend(configureStoreMixin([['TodoList', () => TodoListModel], ['BasicTodo', () => BasicTodoModel], ['FancyTodo', () => FancyTodoModel]], ['TodoList', 'BasicTodo', 'FancyTodo'], "js"))
26+
.props({
27+
todoLists: types.optional(types.map(types.late(() => TodoListModel)), {}),
28+
basicTodos: types.optional(types.map(types.late(() => BasicTodoModel)), {}),
29+
fancyTodos: types.optional(types.map(types.late(() => FancyTodoModel)), {})
30+
})
31+
.actions(self => ({
32+
queryTodoLists(variables, resultSelector = todoListModelPrimitives.toString(), options = {}) {
33+
return self.query(`query todoLists { todoLists {
34+
${typeof resultSelector === "function" ? resultSelector(new TodoListModelSelector()).toString() : resultSelector}
35+
} }`, variables, options)
36+
},
37+
}))
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { RootStoreBase } from "./RootStore.base"
2+
3+
export const RootStore = RootStoreBase.actions((self) => ({
4+
// This is an auto-generated example action.
5+
log() {
6+
console.log(JSON.stringify(self))
7+
}
8+
}))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/* This is a mst-gql generated file, don't modify it manually */
2+
/* eslint-disable */
3+
4+
import { types } from "mobx-state-tree"
5+
import { QueryBuilder } from "mst-gql"
6+
import { ModelBase } from "./ModelBase"
7+
import { BasicTodoModel } from "./BasicTodoModel"
8+
import { FancyTodoModel } from "./FancyTodoModel"
9+
import { TodoModelSelector } from "./TodoModelSelector"
10+
11+
12+
/**
13+
* TodoListBase
14+
* auto generated base class for the model TodoListModel.
15+
*/
16+
export const TodoListModelBase = ModelBase
17+
.named('TodoList')
18+
.props({
19+
__typename: types.optional(types.literal("TodoList"), "TodoList"),
20+
id: types.identifier,
21+
todos: types.union(types.undefined, types.array(types.union(types.late(() => BasicTodoModel), types.late(() => FancyTodoModel)))),
22+
})
23+
.views(self => ({
24+
get store() {
25+
return self.__getStore()
26+
}
27+
}))
28+
29+
export class TodoListModelSelector extends QueryBuilder {
30+
get id() { return this.__attr(`id`) }
31+
todos(builder) { return this.__child(`todos`, TodoModelSelector, builder) }
32+
}
33+
export function selectFromTodoList() {
34+
return new TodoListModelSelector()
35+
}
36+
37+
export const todoListModelPrimitives = selectFromTodoList()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { types } from "mobx-state-tree"
2+
import { BasicTodoModel } from "./BasicTodoModel"
3+
import { FancyTodoModel } from "./FancyTodoModel"
4+
import { TodoListModelBase } from "./TodoListModel.base"
5+
import { MSTGQLRef, getMSTGQLRefLabelAndId } from "mst-gql"
6+
7+
/* A graphql query fragment builders for TodoListModel */
8+
export {
9+
selectFromTodoList,
10+
todoListModelPrimitives,
11+
TodoListModelSelector
12+
} from "./TodoListModel.base"
13+
14+
/**
15+
* TodoListModel
16+
*/
17+
export const TodoListModel = TodoListModelBase.props({
18+
todos: types.union(
19+
types.undefined,
20+
types.array(
21+
types.union(
22+
{
23+
dispatcher: (ss) => {
24+
const modelName = ss.__typename
25+
? ss.__typename
26+
: getMSTGQLRefLabelAndId(ss).label
27+
if (modelName === "FancyTodo") {
28+
return MSTGQLRef(
29+
types.late(() => FancyTodoModel),
30+
"FancyTodo"
31+
)
32+
} else {
33+
return MSTGQLRef(
34+
types.late(() => BasicTodoModel),
35+
"BasicTodo"
36+
)
37+
}
38+
}
39+
},
40+
MSTGQLRef(
41+
types.late(() => FancyTodoModel),
42+
"FancyTodo"
43+
),
44+
MSTGQLRef(
45+
types.late(() => BasicTodoModel),
46+
"BasicTodo"
47+
)
48+
)
49+
)
50+
)
51+
}).actions((self) => ({
52+
// This is an auto-generated example action.
53+
log() {
54+
console.log(JSON.stringify(self))
55+
}
56+
}))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* This is a mst-gql generated file, don't modify it manually */
2+
/* eslint-disable */
3+
4+
import { QueryBuilder } from "mst-gql"
5+
import { BasicTodoModelType } from "./BasicTodoModel"
6+
import { BasicTodoModelSelector, basicTodoModelPrimitives } from "./BasicTodoModel.base"
7+
import { FancyTodoModelType } from "./FancyTodoModel"
8+
import { FancyTodoModelSelector, fancyTodoModelPrimitives } from "./FancyTodoModel.base"
9+
10+
export class TodoModelSelector extends QueryBuilder {
11+
basicTodo(builder) { return this.__inlineFragment(`BasicTodo`, BasicTodoModelSelector, builder) }
12+
fancyTodo(builder) { return this.__inlineFragment(`FancyTodo`, FancyTodoModelSelector, builder) }
13+
}
14+
export function selectFromTodo() {
15+
return new TodoModelSelector()
16+
}
17+
18+
// provides all primitive fields of union member types combined together
19+
export const todoModelPrimitives = selectFromTodo().basicTodo(basicTodoModelPrimitives).fancyTodo(fancyTodoModelPrimitives)

tests/lib/unionTypes/models/index.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* This is a mst-gql generated file, don't modify it manually */
2+
/* eslint-disable */
3+
4+
export * from "./TodoListModel"
5+
export * from "./TodoModelSelector"
6+
export * from "./BasicTodoModel"
7+
export * from "./FancyTodoModel"
8+
export * from "./RootStore"
9+
export * from "./reactUtils"
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* This is a mst-gql generated file, don't modify it manually */
2+
/* eslint-disable */
3+
4+
import { createStoreContext, createUseQueryHook } from "mst-gql"
5+
import * as React from "react"
6+
7+
8+
export const StoreContext = createStoreContext(React)
9+
10+
export const useQuery = createUseQueryHook(StoreContext, React)

tests/lib/unionTypes/todos.graphql

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
type Query {
2+
todoLists: [TodoList!]!
3+
}
4+
5+
union Todo = BasicTodo | FancyTodo
6+
7+
type BasicTodo {
8+
id: ID
9+
text: String
10+
complete: Boolean
11+
}
12+
type FancyTodo {
13+
id: ID
14+
label: String
15+
color: String
16+
complete: Boolean
17+
}
18+
type TodoList {
19+
id: ID!
20+
todos: [Todo!]!
21+
}

0 commit comments

Comments
 (0)