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