@webresto/graphql 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. package/.editorconfig +10 -0
  2. package/index.d.ts +3 -0
  3. package/index.js +22 -0
  4. package/index.ts +14 -0
  5. package/lib/afterHook.d.ts +1 -0
  6. package/lib/afterHook.js +24 -0
  7. package/lib/afterHook.ts +26 -0
  8. package/lib/afterHook.ts___graphql-transport-ws +138 -0
  9. package/lib/afterHook.ts___graphql-ws +133 -0
  10. package/lib/defaults.js +12 -0
  11. package/lib/errorWrapper.d.ts +4 -0
  12. package/lib/errorWrapper.js +13 -0
  13. package/lib/errorWrapper.ts +12 -0
  14. package/lib/eventHelper.d.ts +21 -0
  15. package/lib/eventHelper.js +32 -0
  16. package/lib/eventHelper.ts +35 -0
  17. package/lib/graphqlHelper.d.ts +115 -0
  18. package/lib/graphqlHelper.js +596 -0
  19. package/lib/graphqlHelper.ts +692 -0
  20. package/lib/initialize.d.ts +1 -0
  21. package/lib/initialize.js +22 -0
  22. package/lib/initialize.ts +21 -0
  23. package/notes.md +1976 -0
  24. package/package.json +47 -0
  25. package/readme.md +258 -0
  26. package/restApi.http +11 -0
  27. package/src/additionalResolvers.d.ts +19 -0
  28. package/src/additionalResolvers.js +114 -0
  29. package/src/additionalResolvers.ts +111 -0
  30. package/src/graphql.d.ts +7 -0
  31. package/src/graphql.js +144 -0
  32. package/src/graphql.ts +160 -0
  33. package/src/resolvers/cart.d.ts +123 -0
  34. package/src/resolvers/cart.js +176 -0
  35. package/src/resolvers/cart.ts +256 -0
  36. package/src/resolvers/checkout.d.ts +30 -0
  37. package/src/resolvers/checkout.js +226 -0
  38. package/src/resolvers/checkout.ts +242 -0
  39. package/src/resolvers/dishAndModifier.d.ts +2 -0
  40. package/src/resolvers/dishAndModifier.js +35 -0
  41. package/src/resolvers/dishAndModifier.ts +38 -0
  42. package/src/resolvers/maintenance.d.ts +9 -0
  43. package/src/resolvers/maintenance.js +12 -0
  44. package/src/resolvers/maintenance.ts +11 -0
  45. package/src/resolvers/paymentMethod.d.ts +9 -0
  46. package/src/resolvers/paymentMethod.js +22 -0
  47. package/src/resolvers/paymentMethod.ts +20 -0
  48. package/src/resolvers/restrictions.d.ts +9 -0
  49. package/src/resolvers/restrictions.js +24 -0
  50. package/src/resolvers/restrictions.ts +22 -0
  51. package/src/resolvers/streets.d.ts +9 -0
  52. package/src/resolvers/streets.js +16 -0
  53. package/src/resolvers/streets.ts +13 -0
  54. package/src/resolvers/subscriptions.d.ts +33 -0
  55. package/src/resolvers/subscriptions.js +52 -0
  56. package/src/resolvers/subscriptions.ts +63 -0
  57. package/test/.eslintrc +8 -0
  58. package/test/_bootstrap.js +29 -0
  59. package/test/fixtures/v0.12-app/.gitignore +11 -0
  60. package/test/fixtures/v0.12-app/.sailsrc +11 -0
  61. package/test/fixtures/v0.12-app/api/controllers/.gitkeep +0 -0
  62. package/test/fixtures/v0.12-app/api/models/.gitkeep +0 -0
  63. package/test/fixtures/v0.12-app/api/models/TestModel.js +22 -0
  64. package/test/fixtures/v0.12-app/api/responses/badRequest.js +76 -0
  65. package/test/fixtures/v0.12-app/api/responses/created.js +60 -0
  66. package/test/fixtures/v0.12-app/api/responses/forbidden.js +89 -0
  67. package/test/fixtures/v0.12-app/api/responses/notFound.js +94 -0
  68. package/test/fixtures/v0.12-app/api/responses/ok.js +60 -0
  69. package/test/fixtures/v0.12-app/api/responses/serverError.js +89 -0
  70. package/test/fixtures/v0.12-app/api/services/.gitkeep +0 -0
  71. package/test/fixtures/v0.12-app/app.js +73 -0
  72. package/test/fixtures/v0.12-app/config/bootstrap.js +6 -0
  73. package/test/fixtures/v0.12-app/config/connections.js +5 -0
  74. package/test/fixtures/v0.12-app/config/cors.js +78 -0
  75. package/test/fixtures/v0.12-app/config/csrf.js +64 -0
  76. package/test/fixtures/v0.12-app/config/env/development.js +10 -0
  77. package/test/fixtures/v0.12-app/config/env/production.js +16 -0
  78. package/test/fixtures/v0.12-app/config/globals.js +63 -0
  79. package/test/fixtures/v0.12-app/config/hookTimeout.js +8 -0
  80. package/test/fixtures/v0.12-app/config/http.js +93 -0
  81. package/test/fixtures/v0.12-app/config/i18n.js +57 -0
  82. package/test/fixtures/v0.12-app/config/log.js +29 -0
  83. package/test/fixtures/v0.12-app/config/models.js +3 -0
  84. package/test/fixtures/v0.12-app/config/policies.js +51 -0
  85. package/test/fixtures/v0.12-app/config/restoapi.js +3 -0
  86. package/test/fixtures/v0.12-app/config/restocore.js +39 -0
  87. package/test/fixtures/v0.12-app/config/routes.js +49 -0
  88. package/test/fixtures/v0.12-app/config/session.js +100 -0
  89. package/test/fixtures/v0.12-app/config/sockets.js +141 -0
  90. package/test/fixtures/v0.12-app/config/stateflow.js +4 -0
  91. package/test/fixtures/v0.12-app/config/views.js +95 -0
  92. package/test/fixtures/v0.12-app/package.json +34 -0
  93. package/test/fixtures/v0.12-app/views/403.ejs +68 -0
  94. package/test/fixtures/v0.12-app/views/404.ejs +68 -0
  95. package/test/fixtures/v0.12-app/views/500.ejs +73 -0
  96. package/test/fixtures/v0.12-app/views/homepage.ejs +74 -0
  97. package/test/fixtures/v0.12-app/views/layout.ejs +91 -0
  98. package/test/mocha.opts +2 -0
  99. package/test/readme.md +0 -0
  100. package/test/todo +0 -0
  101. package/test/tslint.json +18 -0
  102. package/test/unit/first.test.js +11 -0
  103. package/test/unit/sails_not_crash.test.js +3 -0
  104. package/todo.md +1 -0
  105. 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,11 @@
1
+ @host = http://127.0.0.1:42777
2
+
3
+ @host2 = https://api.lifenadym.webresto.dev
4
+
5
+ GET {{host}}/api/0.5/menu
6
+
7
+ ###
8
+ GET {{host2}}/api/0.5/api/getNomenclature
9
+
10
+ ###
11
+ GET {{host}}/api/0.5/menu?groupSlug=sousy
@@ -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
+ }
@@ -0,0 +1,7 @@
1
+ declare const _default: {
2
+ getPubsub: () => any;
3
+ getServer: () => any;
4
+ addAdditionalResolver: (resolver: any) => void;
5
+ init: () => Promise<any>;
6
+ };
7
+ export default _default;