@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.
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;