@webresto/graphql 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +10 -0
- package/index.d.ts +3 -0
- package/index.js +22 -0
- package/index.ts +14 -0
- package/lib/afterHook.d.ts +1 -0
- package/lib/afterHook.js +24 -0
- package/lib/afterHook.ts +26 -0
- package/lib/afterHook.ts___graphql-transport-ws +138 -0
- package/lib/afterHook.ts___graphql-ws +133 -0
- package/lib/defaults.js +12 -0
- package/lib/errorWrapper.d.ts +4 -0
- package/lib/errorWrapper.js +13 -0
- package/lib/errorWrapper.ts +12 -0
- package/lib/eventHelper.d.ts +21 -0
- package/lib/eventHelper.js +32 -0
- package/lib/eventHelper.ts +35 -0
- package/lib/graphqlHelper.d.ts +115 -0
- package/lib/graphqlHelper.js +596 -0
- package/lib/graphqlHelper.ts +692 -0
- package/lib/initialize.d.ts +1 -0
- package/lib/initialize.js +22 -0
- package/lib/initialize.ts +21 -0
- package/notes.md +1976 -0
- package/package.json +47 -0
- package/readme.md +258 -0
- package/restApi.http +11 -0
- package/src/additionalResolvers.d.ts +19 -0
- package/src/additionalResolvers.js +114 -0
- package/src/additionalResolvers.ts +111 -0
- package/src/graphql.d.ts +7 -0
- package/src/graphql.js +144 -0
- package/src/graphql.ts +160 -0
- package/src/resolvers/cart.d.ts +123 -0
- package/src/resolvers/cart.js +176 -0
- package/src/resolvers/cart.ts +256 -0
- package/src/resolvers/checkout.d.ts +30 -0
- package/src/resolvers/checkout.js +226 -0
- package/src/resolvers/checkout.ts +242 -0
- package/src/resolvers/dishAndModifier.d.ts +2 -0
- package/src/resolvers/dishAndModifier.js +35 -0
- package/src/resolvers/dishAndModifier.ts +38 -0
- package/src/resolvers/maintenance.d.ts +9 -0
- package/src/resolvers/maintenance.js +12 -0
- package/src/resolvers/maintenance.ts +11 -0
- package/src/resolvers/paymentMethod.d.ts +9 -0
- package/src/resolvers/paymentMethod.js +22 -0
- package/src/resolvers/paymentMethod.ts +20 -0
- package/src/resolvers/restrictions.d.ts +9 -0
- package/src/resolvers/restrictions.js +24 -0
- package/src/resolvers/restrictions.ts +22 -0
- package/src/resolvers/streets.d.ts +9 -0
- package/src/resolvers/streets.js +16 -0
- package/src/resolvers/streets.ts +13 -0
- package/src/resolvers/subscriptions.d.ts +33 -0
- package/src/resolvers/subscriptions.js +52 -0
- package/src/resolvers/subscriptions.ts +63 -0
- package/test/.eslintrc +8 -0
- package/test/_bootstrap.js +29 -0
- package/test/fixtures/v0.12-app/.gitignore +11 -0
- package/test/fixtures/v0.12-app/.sailsrc +11 -0
- package/test/fixtures/v0.12-app/api/controllers/.gitkeep +0 -0
- package/test/fixtures/v0.12-app/api/models/.gitkeep +0 -0
- package/test/fixtures/v0.12-app/api/models/TestModel.js +22 -0
- package/test/fixtures/v0.12-app/api/responses/badRequest.js +76 -0
- package/test/fixtures/v0.12-app/api/responses/created.js +60 -0
- package/test/fixtures/v0.12-app/api/responses/forbidden.js +89 -0
- package/test/fixtures/v0.12-app/api/responses/notFound.js +94 -0
- package/test/fixtures/v0.12-app/api/responses/ok.js +60 -0
- package/test/fixtures/v0.12-app/api/responses/serverError.js +89 -0
- package/test/fixtures/v0.12-app/api/services/.gitkeep +0 -0
- package/test/fixtures/v0.12-app/app.js +73 -0
- package/test/fixtures/v0.12-app/config/bootstrap.js +6 -0
- package/test/fixtures/v0.12-app/config/connections.js +5 -0
- package/test/fixtures/v0.12-app/config/cors.js +78 -0
- package/test/fixtures/v0.12-app/config/csrf.js +64 -0
- package/test/fixtures/v0.12-app/config/env/development.js +10 -0
- package/test/fixtures/v0.12-app/config/env/production.js +16 -0
- package/test/fixtures/v0.12-app/config/globals.js +63 -0
- package/test/fixtures/v0.12-app/config/hookTimeout.js +8 -0
- package/test/fixtures/v0.12-app/config/http.js +93 -0
- package/test/fixtures/v0.12-app/config/i18n.js +57 -0
- package/test/fixtures/v0.12-app/config/log.js +29 -0
- package/test/fixtures/v0.12-app/config/models.js +3 -0
- package/test/fixtures/v0.12-app/config/policies.js +51 -0
- package/test/fixtures/v0.12-app/config/restoapi.js +3 -0
- package/test/fixtures/v0.12-app/config/restocore.js +39 -0
- package/test/fixtures/v0.12-app/config/routes.js +49 -0
- package/test/fixtures/v0.12-app/config/session.js +100 -0
- package/test/fixtures/v0.12-app/config/sockets.js +141 -0
- package/test/fixtures/v0.12-app/config/stateflow.js +4 -0
- package/test/fixtures/v0.12-app/config/views.js +95 -0
- package/test/fixtures/v0.12-app/package.json +34 -0
- package/test/fixtures/v0.12-app/views/403.ejs +68 -0
- package/test/fixtures/v0.12-app/views/404.ejs +68 -0
- package/test/fixtures/v0.12-app/views/500.ejs +73 -0
- package/test/fixtures/v0.12-app/views/homepage.ejs +74 -0
- package/test/fixtures/v0.12-app/views/layout.ejs +91 -0
- package/test/mocha.opts +2 -0
- package/test/readme.md +0 -0
- package/test/todo +0 -0
- package/test/tslint.json +18 -0
- package/test/unit/first.test.js +11 -0
- package/test/unit/sails_not_crash.test.js +3 -0
- package/todo.md +1 -0
- package/tsconfig.json +10 -0
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": {
|
|
3
|
+
"name": "Webresto"
|
|
4
|
+
},
|
|
5
|
+
"bundleDependencies": false,
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"apollo-fetch": "^0.7.0",
|
|
8
|
+
"apollo-server": "^2.25.2",
|
|
9
|
+
"dataloader": "^2.0.0",
|
|
10
|
+
"graphql": "^15.5.0",
|
|
11
|
+
"waterline-criteria": "^2.0.0"
|
|
12
|
+
},
|
|
13
|
+
"deprecated": false,
|
|
14
|
+
"description": "Webresto graphql api",
|
|
15
|
+
"directories": {
|
|
16
|
+
"doc": "docs",
|
|
17
|
+
"lib": "lib"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"iiko",
|
|
21
|
+
"sails",
|
|
22
|
+
"resto",
|
|
23
|
+
"graphql"
|
|
24
|
+
],
|
|
25
|
+
"license": "ISC",
|
|
26
|
+
"main": "index.js",
|
|
27
|
+
"name": "@webresto/graphql",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "http://git.42team.org/webresto/graphql.git"
|
|
31
|
+
},
|
|
32
|
+
"sails": {
|
|
33
|
+
"isHook": true,
|
|
34
|
+
"hookName": "restographql"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"gendoc": "apidoc -o apidoc/ && apidoc-markdown2 -p apidoc -o docs/api.md",
|
|
38
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
39
|
+
"test:js": "mocha test/_bootstrap.js test/**/*.test.js",
|
|
40
|
+
"test:init": "cd ./test/fixtures/v0.12-app && npm i --no-package-lock --prefix ./ && cd -"
|
|
41
|
+
},
|
|
42
|
+
"version": "1.3.0",
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^14.14.35",
|
|
45
|
+
"@webresto/core": "^1.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# Order
|
|
2
|
+
Корзина
|
|
3
|
+
- Запросить новую корзину getNewOrder
|
|
4
|
+
- Подписатся на изменения корзины order(id: String)
|
|
5
|
+
- Добавить блюдо addToOrder
|
|
6
|
+
- Изменить количество orderSetAmount
|
|
7
|
+
- Удалить блюдо removeFromOrder
|
|
8
|
+
|
|
9
|
+
# Menu
|
|
10
|
+
- Получение блюд dish, dishes (без параметров вернет все блюда)
|
|
11
|
+
- Получение групп group, groups (без параметров вернет корневые группы)
|
|
12
|
+
|
|
13
|
+
# Checkout
|
|
14
|
+
- Проверка checkOrder
|
|
15
|
+
- Заказ sendOrder
|
|
16
|
+
|
|
17
|
+
# Subscription
|
|
18
|
+
- сообщения и ошибки - message
|
|
19
|
+
- переходы и экшены - action
|
|
20
|
+
- измененная корзина - order
|
|
21
|
+
|
|
22
|
+
# criteria: Json
|
|
23
|
+
query запросы waterline ORM
|
|
24
|
+
https://0.12.sailsjs.com/documentation/concepts/models-and-orm/query-language#?criteria-modifiers
|
|
25
|
+
```js
|
|
26
|
+
// поиск по полю id
|
|
27
|
+
criteria = {id: "some-unique-id"}
|
|
28
|
+
// можно перечислить массив (условие OR), вернутся записи имеющие slug1 или slug2
|
|
29
|
+
criteria = {slug: ["slag1", "slag2"]}
|
|
30
|
+
// перечисление полей равносильно условию AND, вернутся записи с id = "some-unique-id" AND slug = "slug1"
|
|
31
|
+
criteria = {id: "some-unique-id", slug: "slug1"}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
// дополнительный условия
|
|
35
|
+
'lessThan'
|
|
36
|
+
'lessThanOrEqual'
|
|
37
|
+
'greaterThan'
|
|
38
|
+
'greaterThanOrEqual'
|
|
39
|
+
'not'
|
|
40
|
+
'like'
|
|
41
|
+
'contains'
|
|
42
|
+
'startsWith'
|
|
43
|
+
'endsWith'
|
|
44
|
+
// пример
|
|
45
|
+
criteria = {price: {lessThan: 100}}
|
|
46
|
+
|
|
47
|
+
// сортировка и пагинация. Чтобы использовать сортировку или лимиты основной запрос нужно поместить в where: {}
|
|
48
|
+
criteria = {
|
|
49
|
+
where: {price: {lessThan: 100}},
|
|
50
|
+
skip: 20,
|
|
51
|
+
limit: 10,
|
|
52
|
+
sort: 'price DESC'
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// graphql аналоги запросов для LF :
|
|
56
|
+
/*
|
|
57
|
+
1. https://api.lifenadym.com/navigation
|
|
58
|
+
query{
|
|
59
|
+
navigation{
|
|
60
|
+
...
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
2. https://api.lifenadym.com/page/kafe
|
|
64
|
+
query{
|
|
65
|
+
pages(criteria: {path: "kafe"}}){
|
|
66
|
+
...
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
3. https://api.lifenadym.com/api/0.5/menu?groupSlug=dostavka
|
|
70
|
+
query{
|
|
71
|
+
groups(criteria: {slug: "dostavka"}){
|
|
72
|
+
...
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
4. Запрос по поду с json
|
|
77
|
+
promotions(criteria: {section: {contains:"dostavka"}})
|
|
78
|
+
*/
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# Backend helpers
|
|
83
|
+
- sendMessage(orderId, message) - отправление собщения через подписку PubSub
|
|
84
|
+
- sendAction(orderId, action)
|
|
85
|
+
- addModel(modelName) - генерирует тип из модели. Не использовать! при автоматической генерации всех моделей через addAllSailsModels
|
|
86
|
+
- addType(string) - добавить тип в виде готовой схемы
|
|
87
|
+
- addResolvers - добавить resolvers
|
|
88
|
+
- getSchema - возвращает сгенерированную схему и соедененные резолверсы
|
|
89
|
+
- addToBlackList
|
|
90
|
+
- addCustomField
|
|
91
|
+
- addToReplaceList
|
|
92
|
+
- addAllSailsModels - Генерирует схему по sails моделям.
|
|
93
|
+
|
|
94
|
+
# Пример использования
|
|
95
|
+
## Использование хука
|
|
96
|
+
Хук должен находиться в папке node_modules.
|
|
97
|
+
|
|
98
|
+
Код можно вставить в config/bootstrap.js или в afterHook при оспользовании в друших хуках. Главное чтобы код был выполнен до sails lifted, т.к. генерация GraphQL схемы происходит на этом событии.
|
|
99
|
+
|
|
100
|
+
Хук автоматически сканирует и добавляет в схему все модели проекта, находящиеся в sails.models
|
|
101
|
+
|
|
102
|
+
Автоматически добавляются резолверсы в папке проекта api/resolvers
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
// импортируем хелпер
|
|
107
|
+
import * as helper from '@webresto/graphql'
|
|
108
|
+
// доп импорты
|
|
109
|
+
const path = require('path');
|
|
110
|
+
|
|
111
|
+
// добавляем resolvers из указанной папки
|
|
112
|
+
helper.addDirResolvers(path.resolve(__dirname, './resolvers'));
|
|
113
|
+
// все модели sails будут автоматически занесены в схему GraphQL
|
|
114
|
+
|
|
115
|
+
// Игнорируем при генерации поле dontShow модели Picture
|
|
116
|
+
helper.addToBlackList(["Picture.dontShow"]);
|
|
117
|
+
|
|
118
|
+
// для простых задач выше перечисленного достаточно. Ниже описанны дополнительные возможности.
|
|
119
|
+
|
|
120
|
+
// Добавляем резолверс вручную
|
|
121
|
+
helper.addResolvers(
|
|
122
|
+
// структура резолверса
|
|
123
|
+
{
|
|
124
|
+
// Название основного элемента, обычно Query, Mutation, Subscription
|
|
125
|
+
Query: {
|
|
126
|
+
// имя должно совпадать с именем метода в GraphQL схеме ниже
|
|
127
|
+
sayHi: {
|
|
128
|
+
// описание метода в GraphQL схеме. При генерации будет полностью перенесено в неизменном виде
|
|
129
|
+
def: 'sayHi: String',
|
|
130
|
+
// функция резолвер. Стандартный резолвер GraphQL, после генерации схемы будет расположен в переменной sayHi. Для подписок может быть объектом, а не функцией
|
|
131
|
+
fn: function (parent, args, context){
|
|
132
|
+
return "Hi there! Welcome to GraphQL!";
|
|
133
|
+
},
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// пример добавления типов в схему. Для существующих типов обязательно расширять тип, то есть писать extend type. Такие типы как Query, Mutation, Subscription определены поумолчанию, их обязательно расширять. Если добавляется метод, к нему обязательно нужно добавить резолвер.
|
|
140
|
+
helper.addType(`extend type Query {
|
|
141
|
+
sayAnotherWord: String
|
|
142
|
+
}
|
|
143
|
+
`);
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
пример резолверса
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
export default {
|
|
151
|
+
// основные типы Query, Mutation, Subscription будут записаны в соответствующий тип
|
|
152
|
+
Query: {
|
|
153
|
+
dish: {
|
|
154
|
+
def: 'dish(id: String): Dish',
|
|
155
|
+
fn: async function (parent, args, context, info) {
|
|
156
|
+
return await Dish.findOne({id: args.id});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
Subscription: {
|
|
161
|
+
dish: {
|
|
162
|
+
def: 'dish: Dish',
|
|
163
|
+
// для типа Subscription резолвер должен содержать функции subscribe & resolve
|
|
164
|
+
fn: {
|
|
165
|
+
subscribe: function (parent, args, context, info) {
|
|
166
|
+
return context.pubsub.asyncIterator("dish-changed");
|
|
167
|
+
},
|
|
168
|
+
resolve: payload => {
|
|
169
|
+
return payload;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
// пример резолверса полей типа Dish
|
|
176
|
+
Dish: {
|
|
177
|
+
// функция по умолчанию, можно не писать. Можно заменить любой логикой, главное что бы возвращаемый тип соответствовал схеме
|
|
178
|
+
filed1: (parent, args, context, info) => parent.field1
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
## Black List
|
|
187
|
+
Варианты:
|
|
188
|
+
1. ["Order.field"] - исключает поле field в модели Order
|
|
189
|
+
2. ["Order"] - исключает модель Order полностью
|
|
190
|
+
3. ["field] - исключает поле field из всех моделей
|
|
191
|
+
|
|
192
|
+
### example
|
|
193
|
+
```
|
|
194
|
+
grqlHelper.addToBlackList(["createdAt", "updatedAt"]);
|
|
195
|
+
```
|
|
196
|
+
исключает поля "createdAt", "updatedAt" из автоматической генерации
|
|
197
|
+
|
|
198
|
+
## addResolvers
|
|
199
|
+
Пример добавления:
|
|
200
|
+
- def - описание метода для graphQl schema. Попадет в основные типы Query, Mutation, Subscription. Для примера ниже будет "type Query { orderDish(id: Int!): OrderDish }"
|
|
201
|
+
- fn - метод или объект. Попадет в Resolvers согласно структуре, для примера ниже будет - Resolvers = {Query:{orderDish: fn}}
|
|
202
|
+
- При вызове соеденяет объекты: _.merge(oldResolvers, newResolvers);
|
|
203
|
+
```
|
|
204
|
+
const resolvers = {
|
|
205
|
+
Query: {
|
|
206
|
+
orderDish: {
|
|
207
|
+
def: 'orderDish(id: Int!): OrderDish',
|
|
208
|
+
fn: async function (parent, args, context) {
|
|
209
|
+
return await OrderDish.findOne({id: args.id});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## addToReplaceList
|
|
217
|
+
addToReplaceList(path, field)
|
|
218
|
+
### example
|
|
219
|
+
Замена поля и его типизация. Если добавляется новый тип, его необходимо описать, иначе вылетит исключение graphql
|
|
220
|
+
```
|
|
221
|
+
grqlHelper.addToReplaceList("Dish.image", "image: [Image]");
|
|
222
|
+
grqlHelper.addType("scalar Image");
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## addCustomField
|
|
226
|
+
Добавляет поле в указанную модель. Нет проверки на совпадение полей. Если поля совпадут graphql не запустится.
|
|
227
|
+
```
|
|
228
|
+
grqlHelper.addCustomField("Order", "customField: String")
|
|
229
|
+
```
|
|
230
|
+
Результат:
|
|
231
|
+
type Order {
|
|
232
|
+
...
|
|
233
|
+
customField: String
|
|
234
|
+
...
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
## setWhiteList
|
|
238
|
+
Добавляет модели в белый лист автогенератора. Можно установить генерацию для query запросов и подписок
|
|
239
|
+
```ts
|
|
240
|
+
/**
|
|
241
|
+
* Добавляет whiteList
|
|
242
|
+
* Пример: setWhiteList({
|
|
243
|
+
page: ['query'],
|
|
244
|
+
promotion: ['query'],
|
|
245
|
+
maintenance: ['query', 'subscription']
|
|
246
|
+
})
|
|
247
|
+
*
|
|
248
|
+
* @param list
|
|
249
|
+
*/
|
|
250
|
+
// Пример использования в хуках или проекте
|
|
251
|
+
import * as helper from '@webresto/graphql'
|
|
252
|
+
|
|
253
|
+
helper.setWhiteList({
|
|
254
|
+
page: ['query'],
|
|
255
|
+
promotion: ['query'],
|
|
256
|
+
maintenance: ['query', 'subscription']
|
|
257
|
+
})
|
|
258
|
+
```
|
package/restApi.http
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const additionalResolver: {
|
|
2
|
+
GroupModifier: {
|
|
3
|
+
group: (parent: any, args: any, context: any, info: any) => Promise<any>;
|
|
4
|
+
};
|
|
5
|
+
Modifier: {
|
|
6
|
+
dish: (parent: any, args: any, context: any, info: any) => Promise<any>;
|
|
7
|
+
};
|
|
8
|
+
OrderModifier: {
|
|
9
|
+
dish: (parent: any, args: any, context: any, info: any) => Promise<any>;
|
|
10
|
+
group: (parent: any, args: any) => Promise<any>;
|
|
11
|
+
};
|
|
12
|
+
Dish: {
|
|
13
|
+
parentGroup: (parent: any, args: any, context: any, info: any) => Promise<any>;
|
|
14
|
+
images: (parent: any, args: any, context: any, info: any) => Promise<any>;
|
|
15
|
+
};
|
|
16
|
+
Group: {
|
|
17
|
+
parentGroup: (parent: any, args: any, context: any, info: any) => Promise<any>;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.additionalResolver = void 0;
|
|
4
|
+
const DataLoader = require('dataloader');
|
|
5
|
+
exports.additionalResolver = {
|
|
6
|
+
GroupModifier: {
|
|
7
|
+
group: async (parent, args, context, info) => {
|
|
8
|
+
if (!parent.modifierId)
|
|
9
|
+
return;
|
|
10
|
+
if (!context.dataloaders)
|
|
11
|
+
context.dataloaders = new WeakMap();
|
|
12
|
+
const dataloaders = context.dataloaders;
|
|
13
|
+
let dl = dataloaders.get(info.fieldNodes);
|
|
14
|
+
if (!dl) {
|
|
15
|
+
dl = new DataLoader(async (ids) => {
|
|
16
|
+
const rows = await Group.find({ id: ids });
|
|
17
|
+
const sortedInIdsOrder = ids.map(id => rows.find(x => x.id === id));
|
|
18
|
+
return sortedInIdsOrder;
|
|
19
|
+
});
|
|
20
|
+
dataloaders.set(info.fieldNodes, dl);
|
|
21
|
+
}
|
|
22
|
+
return dl.load(parent.modifierId);
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
Modifier: {
|
|
26
|
+
dish: async (parent, args, context, info) => {
|
|
27
|
+
if (!parent.modifierId)
|
|
28
|
+
return;
|
|
29
|
+
if (!context.dataloaders)
|
|
30
|
+
context.dataloaders = new WeakMap();
|
|
31
|
+
const dataloaders = context.dataloaders;
|
|
32
|
+
let dl = dataloaders.get(info.fieldNodes);
|
|
33
|
+
if (!dl) {
|
|
34
|
+
dl = new DataLoader(async (ids) => {
|
|
35
|
+
const rows = await Dish.find({ id: ids, balance: { "!=": 0 }, isDeleted: false });
|
|
36
|
+
const sortedInIdsOrder = ids.map(id => rows.find(x => x.id === id));
|
|
37
|
+
return sortedInIdsOrder;
|
|
38
|
+
});
|
|
39
|
+
// ложим инстанс дата-лоадера в WeakMap для повторного использования
|
|
40
|
+
dataloaders.set(info.fieldNodes, dl);
|
|
41
|
+
}
|
|
42
|
+
// юзаем метод `load` из нашего дата-лоадера
|
|
43
|
+
return dl.load(parent.modifierId);
|
|
44
|
+
// return await Dish.findOne({id: parent.modifierId}).populateAll();
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
OrderModifier: {
|
|
48
|
+
dish: async (parent, args, context, info) => {
|
|
49
|
+
return (await Dish.find({ id: parent.id, balance: { "!": 0 }, isDeleted: false }).populateAll())[0];
|
|
50
|
+
},
|
|
51
|
+
group: async (parent, args) => {
|
|
52
|
+
return (await Group.find({ id: parent.groupId, isDeleted: false }).populateAll())[0];
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
Dish: {
|
|
56
|
+
parentGroup: async (parent, args, context, info) => {
|
|
57
|
+
if (!parent.parentGroup)
|
|
58
|
+
return;
|
|
59
|
+
if (!context.dataloaders)
|
|
60
|
+
context.dataloaders = new WeakMap();
|
|
61
|
+
const dataloaders = context.dataloaders;
|
|
62
|
+
// need to investigate why getting object instead of string
|
|
63
|
+
if (typeof parent.parentGroup === "object") {
|
|
64
|
+
return parent.parentGroup;
|
|
65
|
+
}
|
|
66
|
+
let dl = dataloaders.get(info.fieldNodes);
|
|
67
|
+
if (!dl) {
|
|
68
|
+
dl = new DataLoader(async (id) => {
|
|
69
|
+
return await Group.find(id);
|
|
70
|
+
});
|
|
71
|
+
dataloaders.set(info.fieldNodes, dl);
|
|
72
|
+
}
|
|
73
|
+
return dl.load(parent.parentGroup);
|
|
74
|
+
},
|
|
75
|
+
images: async (parent, args, context, info) => {
|
|
76
|
+
if (!parent.id)
|
|
77
|
+
return;
|
|
78
|
+
if (!context.dataloaders)
|
|
79
|
+
context.dataloaders = new WeakMap();
|
|
80
|
+
const dataloaders = context.dataloaders;
|
|
81
|
+
let dl = dataloaders.get(info.fieldNodes);
|
|
82
|
+
if (!dl) {
|
|
83
|
+
dl = new DataLoader(async (ids) => {
|
|
84
|
+
const rows = await Dish.find({ id: ids }).populate('images');
|
|
85
|
+
const images = ids.map(id => { var _a; return (_a = rows.find(x => x.id === id)) === null || _a === void 0 ? void 0 : _a.images; });
|
|
86
|
+
return images;
|
|
87
|
+
});
|
|
88
|
+
dataloaders.set(info.fieldNodes, dl);
|
|
89
|
+
}
|
|
90
|
+
return dl.load(parent.id);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
Group: {
|
|
94
|
+
parentGroup: async (parent, args, context, info) => {
|
|
95
|
+
if (!parent.parentGroup)
|
|
96
|
+
return;
|
|
97
|
+
if (!context.dataloaders)
|
|
98
|
+
context.dataloaders = new WeakMap();
|
|
99
|
+
const dataloaders = context.dataloaders;
|
|
100
|
+
// need to investigate why getting object instead of string
|
|
101
|
+
if (typeof parent.parentGroup === "object") {
|
|
102
|
+
return parent.parentGroup;
|
|
103
|
+
}
|
|
104
|
+
let dl = dataloaders.get(info.fieldNodes);
|
|
105
|
+
if (!dl) {
|
|
106
|
+
dl = new DataLoader(async (id) => {
|
|
107
|
+
return await Group.find(id);
|
|
108
|
+
});
|
|
109
|
+
dataloaders.set(info.fieldNodes, dl);
|
|
110
|
+
}
|
|
111
|
+
return dl.load(parent.parentGroup);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
const DataLoader = require('dataloader');
|
|
2
|
+
|
|
3
|
+
export const additionalResolver = {
|
|
4
|
+
GroupModifier: {
|
|
5
|
+
group: async (parent, args, context, info) => {
|
|
6
|
+
if (!parent.modifierId) return;
|
|
7
|
+
if (!context.dataloaders) context.dataloaders = new WeakMap();
|
|
8
|
+
const dataloaders = context.dataloaders;
|
|
9
|
+
|
|
10
|
+
let dl = dataloaders.get(info.fieldNodes);
|
|
11
|
+
if (!dl) {
|
|
12
|
+
dl = new DataLoader(async (ids: any) => {
|
|
13
|
+
const rows = await Group.find({id: ids});
|
|
14
|
+
const sortedInIdsOrder = ids.map(id => rows.find(x => x.id === id));
|
|
15
|
+
return sortedInIdsOrder;
|
|
16
|
+
});
|
|
17
|
+
dataloaders.set(info.fieldNodes, dl);
|
|
18
|
+
}
|
|
19
|
+
return dl.load(parent.modifierId);
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
Modifier: {
|
|
23
|
+
dish: async (parent, args, context, info) => {
|
|
24
|
+
if (!parent.modifierId) return;
|
|
25
|
+
if (!context.dataloaders) context.dataloaders = new WeakMap();
|
|
26
|
+
const dataloaders = context.dataloaders;
|
|
27
|
+
|
|
28
|
+
let dl = dataloaders.get(info.fieldNodes);
|
|
29
|
+
if (!dl) {
|
|
30
|
+
dl = new DataLoader(async (ids: any) => {
|
|
31
|
+
const rows = await Dish.find({id: ids, balance: { "!=": 0 }, isDeleted: false});
|
|
32
|
+
const sortedInIdsOrder = ids.map(id => rows.find(x => x.id === id));
|
|
33
|
+
return sortedInIdsOrder;
|
|
34
|
+
});
|
|
35
|
+
// ложим инстанс дата-лоадера в WeakMap для повторного использования
|
|
36
|
+
dataloaders.set(info.fieldNodes, dl);
|
|
37
|
+
}
|
|
38
|
+
// юзаем метод `load` из нашего дата-лоадера
|
|
39
|
+
return dl.load(parent.modifierId);
|
|
40
|
+
// return await Dish.findOne({id: parent.modifierId}).populateAll();
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
OrderModifier: {
|
|
45
|
+
dish: async (parent, args, context, info) => {
|
|
46
|
+
return (await Dish.find({id: parent.id, balance: { "!": 0 }, isDeleted: false}).populateAll())[0];
|
|
47
|
+
},
|
|
48
|
+
group: async (parent, args) => {
|
|
49
|
+
return (await Group.find({id: parent.groupId, isDeleted: false}).populateAll())[0];
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
Dish: {
|
|
54
|
+
parentGroup: async (parent, args, context, info) => {
|
|
55
|
+
if (!parent.parentGroup) return;
|
|
56
|
+
if (!context.dataloaders) context.dataloaders = new WeakMap();
|
|
57
|
+
const dataloaders = context.dataloaders;
|
|
58
|
+
|
|
59
|
+
// need to investigate why getting object instead of string
|
|
60
|
+
if (typeof parent.parentGroup === "object") {
|
|
61
|
+
return parent.parentGroup;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let dl = dataloaders.get(info.fieldNodes);
|
|
65
|
+
if (!dl) {
|
|
66
|
+
dl = new DataLoader(async (id: any) => {
|
|
67
|
+
return await Group.find(id);
|
|
68
|
+
});
|
|
69
|
+
dataloaders.set(info.fieldNodes, dl);
|
|
70
|
+
}
|
|
71
|
+
return dl.load(parent.parentGroup);
|
|
72
|
+
},
|
|
73
|
+
images: async (parent, args, context, info) => {
|
|
74
|
+
if (!parent.id) return;
|
|
75
|
+
if (!context.dataloaders) context.dataloaders = new WeakMap();
|
|
76
|
+
const dataloaders = context.dataloaders;
|
|
77
|
+
|
|
78
|
+
let dl = dataloaders.get(info.fieldNodes);
|
|
79
|
+
if (!dl) {
|
|
80
|
+
dl = new DataLoader(async (ids: any) => {
|
|
81
|
+
const rows = await Dish.find({id: ids}).populate('images');
|
|
82
|
+
const images = ids.map(id => rows.find(x => x.id === id)?.images);
|
|
83
|
+
return images;
|
|
84
|
+
});
|
|
85
|
+
dataloaders.set(info.fieldNodes, dl);
|
|
86
|
+
}
|
|
87
|
+
return dl.load(parent.id);
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
Group: {
|
|
91
|
+
parentGroup: async (parent, args, context, info) => {
|
|
92
|
+
if (!parent.parentGroup) return;
|
|
93
|
+
if (!context.dataloaders) context.dataloaders = new WeakMap();
|
|
94
|
+
const dataloaders = context.dataloaders;
|
|
95
|
+
|
|
96
|
+
// need to investigate why getting object instead of string
|
|
97
|
+
if (typeof parent.parentGroup === "object") {
|
|
98
|
+
return parent.parentGroup;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let dl = dataloaders.get(info.fieldNodes);
|
|
102
|
+
if (!dl) {
|
|
103
|
+
dl = new DataLoader(async (id: any) => {
|
|
104
|
+
return await Group.find(id);
|
|
105
|
+
});
|
|
106
|
+
dataloaders.set(info.fieldNodes, dl);
|
|
107
|
+
}
|
|
108
|
+
return dl.load(parent.parentGroup);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|