@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
@@ -0,0 +1,692 @@
1
+ /// <reference path="../../core/libs/globalTypes.ts"/>
2
+
3
+ import _ = require("lodash");
4
+ import { WorkTimeValidator} from '@webresto/worktime'
5
+ import getEmitter from "@webresto/core/libs/getEmitter";
6
+ import * as WLCriteria from 'waterline-criteria';
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+
11
+ const scalarTypes = {
12
+ string: "String",
13
+ text: "String",
14
+ date: "String",
15
+ datetime: "String",
16
+ integer: "Int",
17
+ float: "Float",
18
+ boolean: "Boolean",
19
+ // "json": "Json",
20
+ // "array": "Array",
21
+ }
22
+
23
+ /*
24
+ const typeDefsExample = {
25
+ types: [
26
+ `type Example{
27
+ id: ID!
28
+ label: String
29
+ text: String
30
+ }`,
31
+ `type Dish{
32
+ name: String
33
+ description: String
34
+ }`
35
+ ],
36
+ resolvers: {
37
+ Query: {
38
+ example: {
39
+ def: 'example(id: ID!): Example',
40
+ fn: async function (parent, args, context){
41
+ const example = await Example.find({id: args.id});
42
+ return example[0];
43
+ },
44
+ },
45
+ dish: {
46
+ def: 'dish(id: ID!): Dish',
47
+ fn: async function (parent, args, context){
48
+ return {
49
+ id: 1,
50
+ name: "test name",
51
+ price: "150"
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ */
59
+
60
+ const schemaResolvers = {};
61
+ const schemaTypes = [];
62
+ const schemaUnions = {};
63
+ const schemaScalars: Set<string> = new Set();
64
+ const blackList = [];
65
+ const customFields = {};
66
+ const replaceList = {};
67
+
68
+ const models: Set<string> = new Set();
69
+
70
+ /**
71
+ * Добавляет модель в список моделей для создания типов схемы graphql
72
+ *
73
+ *
74
+ * @param modelName string
75
+ * @returns void
76
+ */
77
+
78
+ function addModel (modelName: string) {
79
+ modelName = firstLetterToUpperCase(modelName);
80
+ if (blackList.includes(modelName)) {
81
+ // schemaScalars.add(modelName);
82
+ return;
83
+ }
84
+ models.add(modelName.toLowerCase());
85
+ }
86
+ function addType (typeString: String) {
87
+ schemaTypes.push(typeString);
88
+ }
89
+ /**
90
+ * Мержит новый резолвер с объектом резолверов. Новый резолвер заменит старый при совпадении имен
91
+ *
92
+ * @param resolvers
93
+ * resolverExample = {
94
+ * def: "user(id: String)",
95
+ * fn: function (parent, args, context) {
96
+ * return User.find({id: args.id})
97
+ * }
98
+ * }
99
+ */
100
+ function addResolvers (resolvers: Object) {
101
+ _.merge(schemaResolvers, resolvers);
102
+ }
103
+
104
+ /**
105
+ * Сканирует все модели sails и добавляет их в список моделей для создания типов схемы graphql
106
+ */
107
+ function addAllSailsModels() {
108
+ Object.keys(sails.models).forEach((key) => {
109
+ if (key.includes("__")) return;
110
+ if (sails.models[key].graphql && sails.models[key].graphql.public === false){
111
+ addToBlackList([key]);
112
+ return;
113
+ }
114
+ addModel(key);
115
+ });
116
+ }
117
+
118
+ /**
119
+ * Добавляет массив с исключениями к текущему списку
120
+ * Варианты:
121
+ * 1. ["Order.field"] - исключает поле field в модели Order
122
+ * 2. ["Order"] - исключает модель Order полностью
123
+ * 3. ["field] - исключает поле field из всех моделей
124
+ *
125
+ * @param list array<string>
126
+ */
127
+ function addToBlackList(list: Array<string>) {
128
+ blackList.push(...list);
129
+ }
130
+
131
+ /**
132
+ * Добавляет в указаную модель новое поле
133
+ * Пример: addCustomField("Order", "customField: String")
134
+ *
135
+ * @param model string
136
+ * @param field string
137
+ */
138
+ function addCustomField(model, field) {
139
+ customFields[model] = customFields[model] === undefined ? "" : customFields[model]
140
+ customFields[model] += `${field}\n`;
141
+ }
142
+
143
+ /**
144
+ * Добавляет в список автозамены поле.
145
+ * Пример: addToReplaceList("Dish.image", "image: [Image]");
146
+ *
147
+ * @param model string
148
+ * @param field string
149
+ */
150
+ function addToReplaceList(model, field) {
151
+ replaceList[model] = field;
152
+ }
153
+
154
+ /**
155
+ * Сканирует указанную директорию и добавляет найденные резолверсы в схему graphql
156
+ *
157
+ * @param dir
158
+ */
159
+ function addDirResolvers(dir) {
160
+ let files = fs.readdirSync(dir);
161
+ for (let file of files) {
162
+ if (file.substr(-3) == ".js") {
163
+ const resolver = require(path.join(dir, file)).default;
164
+ if (resolver) {
165
+ addResolvers(resolver);
166
+ }
167
+ }
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Запускает генерацию схемы и резолверсов
173
+ * Возвращает готовые данные для использования при инициализации apollo server
174
+ *
175
+ * @returns {schemaTypes, schemaResolvers}
176
+ */
177
+ function getSchema () {
178
+ Object.keys(whiteList).forEach(modelname => {
179
+ if (sails.models[modelname]?.graphql?.public !== false) {
180
+ addModelResolver(modelname);
181
+ }
182
+ });
183
+
184
+ addResolvers(modelsResolvers);
185
+ return createSchema({types: schemaTypes, resolvers: schemaResolvers});
186
+ }
187
+
188
+ function firstLetterToUpperCase(string) {
189
+ return string.charAt(0).toUpperCase() + string.slice(1);
190
+ }
191
+ function firstLetterToLowerCase(string) {
192
+ return string.charAt(0).toLowerCase() + string.slice(1);
193
+ }
194
+
195
+ /**
196
+ * Перебирает все поля модели и генерирует тип для схемы graphql
197
+ *
198
+ * @param model sails.model
199
+ * @returns string
200
+ */
201
+ function createType(model) {
202
+ const modelName = model.globalId;
203
+ const attributes = model._attributes || model.attributes;
204
+ let type = 'type ' + modelName + '{\n';
205
+ for (let prop in attributes) {
206
+ if (blackList.includes(`${modelName}.${prop}`) || blackList.includes(prop))
207
+ continue;
208
+ if (replaceList[`${modelName}.${prop}`] || replaceList[prop]) {
209
+ const newField = replaceList[`${modelName}.${prop}`] || replaceList[prop];
210
+ type += ` ${newField}\n`;
211
+ continue;
212
+ }
213
+
214
+ let scalarType;
215
+ if (attributes[prop].type) {
216
+ if (scalarTypes[attributes[prop].type.toLowerCase()]) {
217
+ scalarType = scalarTypes[attributes[prop].type.toLowerCase()];
218
+ } else {
219
+ scalarType = firstLetterToUpperCase(attributes[prop].type);
220
+ schemaScalars.add(scalarType);
221
+ }
222
+ type += ' ' + prop + ': ' + scalarType + '\n';
223
+ }
224
+
225
+ // MODEL SCHEMA GENERATION
226
+ if (attributes[prop].model) {
227
+ let relationModel = sails.models[attributes[prop].model.toLowerCase()]
228
+ scalarType = scalarTypes[relationModel.attributes[relationModel.primaryKey].type]
229
+ const name = sails.models[attributes[prop].model.toLowerCase()].globalId;
230
+ type += ` ${prop}: ${name}\n`;
231
+
232
+ // todelete
233
+ type += ` ${prop}Id: ${scalarType}\n`;
234
+ }
235
+
236
+ // COLLECTION SCHEMA GENERATION
237
+ if (attributes[prop].collection) {
238
+ scalarType = scalarTypes[attributes[sails.models[attributes[prop].collection.toLowerCase()].primaryKey].type.toLowerCase()]
239
+ const name = sails.models[attributes[prop].collection.toLowerCase()].globalId;
240
+ console.log(1,scalarType)
241
+ type += ` ${prop}: [${name}]\n`;
242
+
243
+ // todelete
244
+ type += ` ${prop}Ids: ${scalarType}\n`;
245
+ }
246
+ }
247
+ if (customFields[modelName]) {
248
+ type += ` ${customFields[modelName]}\n`;
249
+ }
250
+ if (!attributes.customData) {
251
+ type += '""" autogenerated """ customData: Json';
252
+ }
253
+ type += '}\n';
254
+ return type;
255
+ }
256
+
257
+ /**
258
+ * Соеденяет резолверсы и типы. Отделяет от резолверсов описание запросов.
259
+ * Возвращает готовую схему и резолверсы для использования в apollo server
260
+ *
261
+ * @param typeDefsObj
262
+ * @returns
263
+ */
264
+ function createSchema(typeDefsObj) {
265
+ let schema = '';
266
+ const resolvers: Resolvers = {};
267
+ if (Array.isArray(typeDefsObj.types)) {
268
+ schema += typeDefsObj.types.join('\n');
269
+ }
270
+ // add types from models
271
+ for (let model of models) {
272
+ schema += createType(sails.models[model]);
273
+ }
274
+ // add union
275
+ for (let prop in schemaUnions) {
276
+ schema += `scalar ${prop}\n`;
277
+ }
278
+ // add scalar
279
+ for (let scalar of schemaScalars) {
280
+ schema += `scalar ${scalar}\n`;
281
+ }
282
+ // add resolver and type definition
283
+ if (typeDefsObj.resolvers) {
284
+ Object.keys(typeDefsObj.resolvers).forEach(key => {
285
+ resolvers[key] = {};
286
+ const res = typeDefsObj.resolvers[key];
287
+
288
+ if (['Query', 'Mutation', 'Subscription'].includes(key)) {
289
+ let typeString = `extend type ${key}{\n`;
290
+ for (let prop in res) {
291
+ typeString += ' ' + res[prop].def + '\n';
292
+ resolvers[key][prop] = res[prop].fn;
293
+ }
294
+ typeString += '}\n';
295
+ schema += '\n' + typeString;
296
+ } else {
297
+ if (res.def) {
298
+ schema += '\n' + res.def + '\n';
299
+ }
300
+ if (res.fn) {
301
+ resolvers[key] = res.fn;
302
+ } else {
303
+ resolvers[key] = res;
304
+ }
305
+ }
306
+ })
307
+ }
308
+ return { typeDefs: schema, resolvers };
309
+ }
310
+
311
+
312
+ // AUTOGENERATE RESOLVERS -----------------------------------------------
313
+
314
+ // генерация резолверсов по списку моделей. Список моделей автоматически добавляется в схему.
315
+ const whiteList = {
316
+ // group: ['subscription', 'query'] // order - modelname , 'subscription' - resolver type
317
+ }
318
+ const userAuth = typeof sails.config.restographql?.authService === 'function' ? sails.config.restographql.authService : null;
319
+
320
+ let modelsResolvers: {Query?: Object, Subscription?: Object} = { Query: {}};
321
+ const { withFilter } = require("apollo-server");
322
+
323
+ /**
324
+ * Патчит waterline criteria во время автогенерации
325
+ *
326
+ * @param modelname
327
+ * @param criteria
328
+ * @returns
329
+ */
330
+ function sanitizeCriteria(modelname, criteria) {
331
+
332
+ if (sails.models[modelname].attributes.enable){
333
+ criteria.enable = true;
334
+ }
335
+
336
+ if (sails.models[modelname].attributes.isDeleted){
337
+ criteria.isDeleted = false;
338
+ }
339
+
340
+ switch (modelname) {
341
+ case 'dish':
342
+ criteria.balance = {'!=': 0};
343
+ criteria.isDeleted = false;
344
+ break;
345
+ case 'group':
346
+ criteria.isDeleted = false;
347
+ break;
348
+ }
349
+ return criteria;
350
+ }
351
+
352
+ /**
353
+ * Добавляет whiteList
354
+ * Пример: setWhiteList({
355
+ page: ['query'],
356
+ promotion: ['query'],
357
+ maintenance: ['query', 'subscription']
358
+ })
359
+ *
360
+ * @param list
361
+ */
362
+ function setWhiteList(list: Object) {
363
+ _.merge(whiteList, list);
364
+ }
365
+
366
+ /**
367
+ * Генерирует резолвер для модели. Учитывает список исключений и whiteList
368
+ *
369
+ * @param modelname string
370
+ * @returns void
371
+ */
372
+
373
+ function addModelResolver(modelname) {
374
+ if (!sails.models[modelname]) return;
375
+ let modelName = sails.models[modelname].globalId;
376
+ if (!modelName) {
377
+ sails.log.error('graphql >>> Wrong Model Name :' + modelname);
378
+ return;
379
+ }
380
+
381
+ // Query resolver
382
+ if (whiteList[modelname].includes('query') && !blackList.includes(`${modelName}`)) {
383
+ models.add(modelname); // make schema Type for Model
384
+ const methodName = firstLetterToLowerCase(modelName)
385
+ let resolverQuery = {
386
+ def: `""" autogenerated """ ${methodName}(criteria: Json): [${modelName}]`,
387
+ fn: async function (parent, args, context) {
388
+
389
+ let criteria = args.criteria || {};
390
+ criteria = sanitizeCriteria(modelname, criteria);
391
+
392
+ // If model has User field need auth
393
+ if (sails.models[modelname].attributes.user) {
394
+ if (userAuth) {
395
+ let user = await userAuth(
396
+ context.connectionParams.authorization
397
+ );
398
+ if (user.id) {
399
+ criteria.user = user.id;
400
+ } else return null;
401
+ } else {
402
+ return null;
403
+ }
404
+ }
405
+
406
+ let query: any = { where: criteria};
407
+ //sorting
408
+ if (sails.models[modelname].attributes.order) {
409
+ query.sort = 'order ASC'
410
+ }
411
+
412
+ let result = await sails.models[modelname].find(query);
413
+
414
+ getEmitter().emit(`graphql-query-${modelname}`, result);
415
+
416
+ //workTime filter
417
+
418
+ if (sails.models[modelname].attributes.workTime) {
419
+ result = result.filter(record => {
420
+ if (!record.workTime) return true;
421
+ try {
422
+ return (WorkTimeValidator.isWorkNow({workTime: record.workTime})).workNow
423
+ } catch (error) {
424
+ sails.log.error("Graphql > helper > error: ",error)
425
+ }
426
+ })
427
+ }
428
+
429
+ result.forEach(item => {
430
+
431
+ getEmitter().emit(
432
+ `http-api:before-send-${modelname.toLowerCase()}`,
433
+ item
434
+ );
435
+ });
436
+
437
+ return result;
438
+ },
439
+ };
440
+ modelsResolvers.Query[methodName] = resolverQuery;
441
+ }
442
+ // Model fields resolvers
443
+ let resolvers = {};
444
+ // iterate separate resolvers in model (type])
445
+ Object.keys(sails.models[modelname].attributes).forEach((key) => {
446
+ if (key.includes("__")) return;
447
+ if (blackList.includes(`${modelName}.${key}`) || blackList.includes(`${key}`)) return;
448
+ if (typeof sails.models[modelname].attributes[key] === 'function') return;
449
+
450
+ if (sails.models[modelname].attributes[key].graphql) {
451
+ if (sails.models[modelname].attributes[key].graphql.public === false)
452
+ return;
453
+ }
454
+
455
+ let modelAttribute = sails.models[modelname].attributes[key];
456
+
457
+ if (modelAttribute.collection || modelAttribute.model) {
458
+ let modelRelationType = modelAttribute.collection
459
+ ? "collection"
460
+ : "model";
461
+
462
+ let relationKey =
463
+ modelAttribute.via !== undefined
464
+ ? modelAttribute.via
465
+ : "id";
466
+
467
+ let criteria = {};
468
+ criteria = sanitizeCriteria(modelAttribute[modelRelationType], criteria);
469
+
470
+ switch (modelRelationType) {
471
+ case "model":
472
+ resolvers[key] = async (parent, args, context) => {
473
+ criteria[relationKey] = parent[key];
474
+ let result = await sails.models[modelAttribute[modelRelationType]].findOne(criteria);
475
+
476
+ // TODO: this need only for support legacy patching (discount)
477
+ getEmitter().emit(
478
+ `http-api:before-send-${modelAttribute.model.toLowerCase()}`,
479
+ result
480
+ );
481
+
482
+ // celan if not work time
483
+ if (result && result.workTime && !WorkTimeValidator.isWorkNow({workTime: result.workTime}).workNow) {
484
+ result = null;
485
+ }
486
+ };
487
+
488
+ return;
489
+ case "collection":
490
+ resolvers[key] = async (parent, args, context) => {
491
+
492
+
493
+ let subcriteria: any = {};
494
+
495
+ let subquery: any = { where: criteria};
496
+ //sorting
497
+ if (sails.models[modelname].attributes.order) {
498
+ subquery.sort = 'order ASC'
499
+ }
500
+
501
+ let result = (await sails.models[modelname].findOne({id: parent.id}).populate(key, subquery));
502
+ result = result ? result[key] : null;
503
+
504
+ // TODO: this need only for support legacy patching (discount)
505
+ if (result && result.length){
506
+ result.forEach(item => {
507
+ getEmitter().emit(
508
+ `http-api:before-send-${modelAttribute.collection.toLowerCase()}`,
509
+ item
510
+ );
511
+ });
512
+ }
513
+
514
+ if (sails.models[modelname].attributes.workTime && Array.isArray(result)) {
515
+ result = result.filter(record => {
516
+ if (!record.workTime) return true
517
+ try {
518
+ return (WorkTimeValidator.isWorkNow({workTime: record.workTime})).workNow
519
+ } catch (error) {
520
+ sails.log.error("Graphql > helper > error: ",error)
521
+ }
522
+ });
523
+ }
524
+ return result;
525
+ };
526
+
527
+ return;
528
+ default:
529
+ // empty
530
+ break;
531
+ }
532
+ }
533
+
534
+ resolvers[key] = async (parent, args, context) => {
535
+ return parent && parent[key];
536
+ };
537
+ });
538
+
539
+ console.log(modelName,resolvers)
540
+ modelsResolvers[modelName] = resolvers;
541
+
542
+
543
+ // Subscription resolver
544
+ if (!blackList.includes(`${modelName}`) && whiteList[modelname].includes('subscription')) {
545
+ models.add(modelname);
546
+ const methodName = `${firstLetterToLowerCase(modelName)}`;
547
+ let subscription = {
548
+ def: `""" Generated """ ${methodName}(criteria: Json): ${modelName}`,
549
+ fn: {
550
+ subscribe: withFilter(
551
+ (rootValue, args, context, info) =>
552
+ context.pubsub.asyncIterator(modelName),
553
+ async (payload, args, context, info) => {
554
+
555
+ // For User models
556
+ if (sails.models[modelname].attributes.user) {
557
+ if (userAuth) {
558
+ let user = await userAuth(
559
+ context.connectionParams.authorization
560
+ );
561
+ if (user.id === payload.user){
562
+ if (args.criteria) {
563
+ checkCriteria(payload, args.criteria)
564
+ } else {
565
+ return true;
566
+ }
567
+ };
568
+ } else {
569
+ return false;
570
+ }
571
+ }
572
+
573
+ return checkCriteria(payload, args.criteria)
574
+
575
+ // Filter by waterline criteria
576
+ function checkCriteria(payload: any, criteria: any): boolean{
577
+
578
+ // For id's array
579
+ if (Array.isArray(criteria) || typeof criteria === "string"){
580
+ return (WLCriteria(payload, { where: { id: criteria }}).results).length > 0
581
+ }
582
+
583
+ // Where cause
584
+ if ( typeof criteria === 'object' && !Array.isArray(criteria) && criteria !== null ) {
585
+ return (WLCriteria(payload, { where: criteria }).results).length > 0
586
+ }
587
+
588
+ return false
589
+ }
590
+
591
+ }
592
+ ),
593
+ resolve: (payload) => {
594
+ return payload;
595
+ },
596
+ },
597
+ };
598
+ // add publish in model
599
+ modelPublishExtend(modelname);
600
+ if (!modelsResolvers.Subscription) modelsResolvers.Subscription = {};
601
+ modelsResolvers.Subscription[methodName] = subscription;
602
+ }
603
+ }
604
+
605
+ /**
606
+ * Внутренняя функция используется при автогенерации резолверов
607
+ * Модифицирует модель. Добавляет рассылку сообщений при afterUpdate & afterCreate
608
+ *
609
+ * @param modelname
610
+ */
611
+ function modelPublishExtend(modelname) {
612
+ let modelName = sails.models[modelname].globalId;
613
+
614
+ let afterCreate = sails.models[modelname].afterCreate;
615
+ sails.models[modelname].afterCreate = async function (values, cb ) {
616
+ await sails.models[modelname].publish(values.id);
617
+ if (afterCreate) {
618
+ afterCreate(values, cb);
619
+ } else {
620
+ cb();
621
+ }
622
+ };
623
+
624
+ let afterUpdate = sails.models[modelname].afterUpdate;
625
+ sails.models[modelname].afterUpdate = async function (values, cb ) {
626
+ await sails.models[modelname].publish(values.id);
627
+ if (afterUpdate) {
628
+ afterUpdate(values, cb);
629
+ } else {
630
+ cb();
631
+ }
632
+ };
633
+
634
+ let modelPublishExtendObj = {
635
+ publish: async function (id) {
636
+ let data = await sails.models[modelname].findOne(id);
637
+ // `http-api:request-${modelAttribute.collection.toLowerCase()}model-list`,
638
+
639
+ getEmitter().emit(`http-api:before-send-${modelname.toLowerCase()}`, data);
640
+ sails.graphql.pubsub.publish(modelName, data);
641
+ },
642
+ };
643
+
644
+ _.merge(sails.models[modelname], modelPublishExtendObj);
645
+ }
646
+
647
+
648
+ export default {
649
+ addModel,
650
+ addType,
651
+ addResolvers,
652
+ getSchema,
653
+
654
+ addToBlackList,
655
+ addCustomField,
656
+ addToReplaceList,
657
+ addAllSailsModels,
658
+ addDirResolvers,
659
+
660
+ addModelResolver,
661
+ setWhiteList
662
+ }
663
+ export {
664
+ addModel,
665
+ addType,
666
+ addResolvers,
667
+ getSchema,
668
+
669
+ addToBlackList,
670
+ addCustomField,
671
+ addToReplaceList,
672
+ addAllSailsModels,
673
+ addDirResolvers,
674
+
675
+ addModelResolver,
676
+ setWhiteList
677
+ }
678
+
679
+ interface Resolvers {
680
+ Query?: Resolver,
681
+ Mutation?: Resolver,
682
+ Subscription?: Resolver
683
+ }
684
+ interface Resolver {
685
+ [name: string]: {
686
+ def?: string,
687
+ fn?: Object,
688
+ subscribe?: Object,
689
+ resolve?: Object,
690
+ [x: string]: Object
691
+ }
692
+ }
@@ -0,0 +1 @@
1
+ export default function ToInitialize(): (cb: any) => any;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const hookTools_1 = require("@webresto/core/libs/hookTools");
4
+ const afterHook_1 = require("@webresto/graphql/lib/afterHook");
5
+ function ToInitialize() {
6
+ /**
7
+ * List of hooks that required
8
+ */
9
+ const requiredHooks = [
10
+ 'restocore'
11
+ ];
12
+ return function initialize(cb) {
13
+ /**
14
+ * AFTER OTHERS HOOKS
15
+ */
16
+ sails.log.info('>>> graphql hook - initialize');
17
+ hookTools_1.default.waitForHooks('graphql', requiredHooks, afterHook_1.default);
18
+ return cb();
19
+ };
20
+ }
21
+ exports.default = ToInitialize;
22
+ ;