@webresto/graphql 1.3.6 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +2 -0
- package/.gitlab-ci.yml +18 -0
- package/.vscode/extensions.json +5 -0
- package/docs/actions.md +25 -0
- package/docs/authorization.md +215 -0
- package/docs/captcha.md +71 -0
- package/docs/device-id.md +30 -0
- package/docs/messages.md +10 -0
- package/docs/user.md +54 -0
- package/index.d.ts +0 -1
- package/index.js +6 -2
- package/index.ts +2 -2
- package/lib/afterHook.js +8 -0
- package/lib/afterHook.ts +9 -0
- package/lib/bindTranslations.d.ts +1 -0
- package/lib/bindTranslations.js +40 -0
- package/lib/bindTranslations.ts +39 -0
- package/lib/defaults.d.ts +1 -0
- package/lib/defaults.js +49 -10
- package/lib/defaults.ts +55 -0
- package/lib/eventHelper.d.ts +14 -5
- package/lib/eventHelper.js +28 -9
- package/lib/eventHelper.ts +41 -8
- package/lib/getRecomended.d.ts +1 -0
- package/lib/getRecomended.js +29 -0
- package/lib/getRecomended.ts +31 -0
- package/lib/graphqlHelper.d.ts +3 -4
- package/lib/graphqlHelper.js +184 -73
- package/lib/graphqlHelper.ts +329 -186
- package/lib/jwt.d.ts +10 -0
- package/lib/jwt.js +43 -0
- package/lib/jwt.ts +61 -0
- package/package.json +13 -6
- package/src/additionalResolvers.d.ts +72 -9
- package/src/additionalResolvers.js +93 -24
- package/src/additionalResolvers.ts +105 -34
- package/src/graphql.d.ts +5 -3
- package/src/graphql.js +170 -37
- package/src/graphql.ts +210 -60
- package/src/resolvers/bonusProgram.d.ts +32 -0
- package/src/resolvers/bonusProgram.js +65 -0
- package/src/resolvers/bonusProgram.ts +79 -0
- package/src/resolvers/captcha.d.ts +11 -0
- package/src/resolvers/captcha.js +19 -0
- package/src/resolvers/captcha.ts +16 -0
- package/src/resolvers/checkout.d.ts +43 -14
- package/src/resolvers/checkout.js +172 -122
- package/src/resolvers/checkout.ts +218 -142
- package/src/resolvers/dishAndModifier.js +8 -4
- package/src/resolvers/dishAndModifier.ts +4 -0
- package/src/resolvers/error.d.ts +9 -0
- package/src/resolvers/error.js +21 -0
- package/src/resolvers/error.ts +21 -0
- package/src/resolvers/menu.d.ts +9 -0
- package/src/resolvers/menu.js +12 -0
- package/src/resolvers/menu.ts +10 -0
- package/src/resolvers/order.d.ts +527 -0
- package/src/resolvers/order.js +349 -0
- package/src/resolvers/order.ts +435 -0
- package/src/resolvers/paymentMethod.js +7 -3
- package/src/resolvers/paymentMethod.ts +9 -5
- package/src/resolvers/pickupPoint.d.ts +1 -0
- package/src/resolvers/pickupPoint.js +24 -0
- package/src/resolvers/pickupPoint.ts +23 -0
- package/src/resolvers/recomended.d.ts +13 -0
- package/src/resolvers/recomended.js +80 -0
- package/src/resolvers/recomended.ts +86 -0
- package/src/resolvers/restrictions.d.ts +37 -1
- package/src/resolvers/restrictions.js +100 -15
- package/src/resolvers/restrictions.ts +106 -14
- package/src/resolvers/streets.d.ts +1 -1
- package/src/resolvers/streets.js +1 -4
- package/src/resolvers/streets.ts +1 -3
- package/src/resolvers/subscriptions.d.ts +4 -4
- package/src/resolvers/subscriptions.js +49 -12
- package/src/resolvers/subscriptions.ts +59 -14
- package/src/resolvers/telemetry.d.ts +14 -0
- package/src/resolvers/telemetry.js +25 -0
- package/src/resolvers/telemetry.ts +24 -0
- package/src/resolvers/user.d.ts +82 -0
- package/src/resolvers/user.js +416 -0
- package/src/resolvers/user.ts +621 -0
- package/src/resolvers/userLocation.d.ts +53 -0
- package/src/resolvers/userLocation.js +74 -0
- package/src/resolvers/userLocation.ts +125 -0
- package/src/resolvers/userOTPrequest.d.ts +21 -0
- package/src/resolvers/userOTPrequest.js +57 -0
- package/src/resolvers/userOTPrequest.ts +75 -0
- package/test/e2e_helper.js +157 -0
- package/test/e2e_helper.ts +212 -0
- package/test/fixture/config/i18n.js +7 -20
- package/test/fixture/config/locales/de.json +1 -0
- package/test/fixture/config/locales/en.json +10 -0
- package/test/fixture/config/locales/es.json +3 -0
- package/test/fixture/config/locales/fr.json +1 -0
- package/test/fixture/config/log.js +1 -1
- package/test/fixture/package.json +5 -6
- package/test/fixture/patches/rttc+10.0.1.patch +17 -0
- package/test/integration/captcha.test.js +20 -0
- package/test/integration/captcha.test.ts +25 -0
- package/test/integration/dish.test.js +35 -0
- package/test/integration/dish.test.ts +43 -0
- package/test/integration/graphql.test.js +5 -2
- package/test/integration/graphql.test.ts +2 -4
- package/test/integration/images.test.js +35 -0
- package/test/integration/images.test.ts +40 -0
- package/test/integration/locale.test.js +26 -0
- package/test/integration/locale.test.ts +32 -0
- package/test/integration/order.test.js +56 -43
- package/test/integration/order.test.ts +59 -59
- package/test/integration/subscriptions.test.js +136 -0
- package/test/integration/subscriptions.test.ts +162 -0
- package/test/integration/user.test.js +249 -0
- package/test/integration/user.test.ts +299 -0
- package/test/unit/first.test.js +4 -2
- package/test/unit/first.test.ts +1 -1
- package/test/unit/get-recomended.test.js +56 -0
- package/test/unit/get-recomended.test.ts +63 -0
- package/translations/de.json +2 -0
- package/translations/en.json +3 -0
- package/translations/es.json +3 -0
- package/translations/fr.json +2 -0
- package/translations/ru.json +36 -0
- package/tsconfig.json +20 -5
- package/types/global.d.ts +30 -0
- package/types/global.js +2 -0
- package/types/global.ts +31 -0
- package/types/primitives.d.ts +19 -0
- package/types/references.d.ts +1 -0
- package/types/restoGraphQLConfig.d.ts +13 -0
- package/lib/afterHook.ts___graphql-transport-ws +0 -138
- package/lib/afterHook.ts___graphql-ws +0 -133
- package/lib/errorWrapper.d.ts +0 -4
- package/lib/errorWrapper.js +0 -13
- package/lib/errorWrapper.ts +0 -12
- package/notes.md +0 -1976
- package/src/resolvers/cart.d.ts +0 -343
- package/src/resolvers/cart.js +0 -196
- package/src/resolvers/cart.ts +0 -277
- package/test/fixture/config/connections.js +0 -9
- package/test/integration/sails_not_crash.test.js +0 -3
- package/test/integration/sails_not_crash.test.ts +0 -3
package/lib/graphqlHelper.ts
CHANGED
|
@@ -1,23 +1,18 @@
|
|
|
1
|
-
/// <reference path="../../core/libs/globalTypes.ts"/>
|
|
2
|
-
|
|
3
1
|
import _ = require("lodash");
|
|
4
|
-
import { WorkTimeValidator} from '@webresto/worktime'
|
|
5
|
-
|
|
2
|
+
import { WorkTimeValidator } from '@webresto/worktime'
|
|
3
|
+
|
|
6
4
|
import * as WLCriteria from 'waterline-criteria';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
boolean: "Boolean",
|
|
19
|
-
// "json": "Json",
|
|
20
|
-
// "array": "Array",
|
|
5
|
+
import { JWTAuth } from "./jwt";
|
|
6
|
+
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
|
|
10
|
+
const scalarTypes = {
|
|
11
|
+
string: "String",
|
|
12
|
+
number: "Float",
|
|
13
|
+
boolean: "Boolean",
|
|
14
|
+
// json: "Json",
|
|
15
|
+
// "array": "Array",
|
|
21
16
|
}
|
|
22
17
|
|
|
23
18
|
/*
|
|
@@ -75,30 +70,31 @@ const models: Set<string> = new Set();
|
|
|
75
70
|
* @returns void
|
|
76
71
|
*/
|
|
77
72
|
|
|
78
|
-
function addModel
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
73
|
+
function addModel(modelName: string) {
|
|
74
|
+
modelName = firstLetterToUpperCase(modelName);
|
|
75
|
+
if (blackList.includes(modelName)) {
|
|
76
|
+
// schemaScalars.add(modelName);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
models.add(modelName.toLowerCase());
|
|
85
80
|
}
|
|
86
|
-
|
|
87
|
-
|
|
81
|
+
|
|
82
|
+
function addType(type: string) {
|
|
83
|
+
schemaTypes.push(type);
|
|
88
84
|
}
|
|
89
85
|
/**
|
|
90
86
|
* Мержит новый резолвер с объектом резолверов. Новый резолвер заменит старый при совпадении имен
|
|
91
87
|
*
|
|
92
88
|
* @param resolvers
|
|
93
89
|
* resolverExample = {
|
|
94
|
-
* def: "user(id:
|
|
90
|
+
* def: "user(id: string)",
|
|
95
91
|
* fn: function (parent, args, context) {
|
|
96
92
|
* return User.find({id: args.id})
|
|
97
93
|
* }
|
|
98
94
|
* }
|
|
99
95
|
*/
|
|
100
|
-
function addResolvers
|
|
101
|
-
|
|
96
|
+
function addResolvers(resolvers: Object) {
|
|
97
|
+
_.merge(schemaResolvers, resolvers);
|
|
102
98
|
}
|
|
103
99
|
|
|
104
100
|
/**
|
|
@@ -107,7 +103,7 @@ function addResolvers (resolvers: Object) {
|
|
|
107
103
|
function addAllSailsModels() {
|
|
108
104
|
Object.keys(sails.models).forEach((key) => {
|
|
109
105
|
if (key.includes("__")) return;
|
|
110
|
-
if (sails.models[key].graphql && sails.models[key].graphql.public === false){
|
|
106
|
+
if (sails.models[key].graphql && sails.models[key].graphql.public === false) {
|
|
111
107
|
addToBlackList([key]);
|
|
112
108
|
return;
|
|
113
109
|
}
|
|
@@ -125,12 +121,12 @@ function addAllSailsModels() {
|
|
|
125
121
|
* @param list array<string>
|
|
126
122
|
*/
|
|
127
123
|
function addToBlackList(list: Array<string>) {
|
|
128
|
-
|
|
124
|
+
blackList.push(...list);
|
|
129
125
|
}
|
|
130
126
|
|
|
131
127
|
/**
|
|
132
128
|
* Добавляет в указаную модель новое поле
|
|
133
|
-
* Пример: addCustomField("Order", "customField:
|
|
129
|
+
* Пример: addCustomField("Order", "customField: string")
|
|
134
130
|
*
|
|
135
131
|
* @param model string
|
|
136
132
|
* @param field string
|
|
@@ -148,7 +144,7 @@ function addCustomField(model, field) {
|
|
|
148
144
|
* @param field string
|
|
149
145
|
*/
|
|
150
146
|
function addToReplaceList(model, field) {
|
|
151
|
-
|
|
147
|
+
replaceList[model] = field;
|
|
152
148
|
}
|
|
153
149
|
|
|
154
150
|
/**
|
|
@@ -174,7 +170,7 @@ function addDirResolvers(dir) {
|
|
|
174
170
|
*
|
|
175
171
|
* @returns {schemaTypes, schemaResolvers}
|
|
176
172
|
*/
|
|
177
|
-
function getSchema
|
|
173
|
+
function getSchema() {
|
|
178
174
|
Object.keys(whiteList).forEach(modelname => {
|
|
179
175
|
if (sails.models[modelname]?.graphql?.public !== false) {
|
|
180
176
|
addModelResolver(modelname);
|
|
@@ -182,7 +178,7 @@ function getSchema () {
|
|
|
182
178
|
});
|
|
183
179
|
|
|
184
180
|
addResolvers(modelsResolvers);
|
|
185
|
-
return createSchema({types: schemaTypes, resolvers: schemaResolvers});
|
|
181
|
+
return createSchema({ types: schemaTypes, resolvers: schemaResolvers });
|
|
186
182
|
}
|
|
187
183
|
|
|
188
184
|
function firstLetterToUpperCase(string) {
|
|
@@ -213,26 +209,37 @@ function createType(model) {
|
|
|
213
209
|
|
|
214
210
|
let scalarType;
|
|
215
211
|
if (attributes[prop].type) {
|
|
216
|
-
|
|
217
|
-
|
|
212
|
+
|
|
213
|
+
// TODO: make method add AddModelFieldType(path, type) for pass custom type for specific model
|
|
214
|
+
if (modelName.toLowerCase() === "user" && prop === "phone") {
|
|
215
|
+
scalarType = "Phone"
|
|
218
216
|
} else {
|
|
219
|
-
|
|
220
|
-
|
|
217
|
+
if (scalarTypes[attributes[prop].type.toLowerCase()]) {
|
|
218
|
+
scalarType = scalarTypes[attributes[prop].type.toLowerCase()];
|
|
219
|
+
} else {
|
|
220
|
+
scalarType = firstLetterToUpperCase(attributes[prop].type);
|
|
221
|
+
schemaScalars.add(scalarType);
|
|
222
|
+
}
|
|
221
223
|
}
|
|
222
224
|
type += ' ' + prop + ': ' + scalarType + '\n';
|
|
223
225
|
}
|
|
224
|
-
|
|
226
|
+
|
|
225
227
|
// MODEL SCHEMA GENERATION
|
|
226
228
|
if (attributes[prop].model) {
|
|
227
229
|
let relationModel = sails.models[attributes[prop].model.toLowerCase()]
|
|
228
|
-
scalarType = scalarTypes[relationModel.attributes[relationModel.primaryKey].type]
|
|
230
|
+
scalarType = scalarTypes[relationModel.attributes[relationModel.primaryKey].type.toLowerCase()]
|
|
229
231
|
const name = sails.models[attributes[prop].model.toLowerCase()].globalId;
|
|
230
232
|
type += ` ${prop}: ${name}\n`;
|
|
233
|
+
|
|
234
|
+
// Virtual Id field
|
|
235
|
+
type += ` ${prop}Id: ${scalarType}\n`;
|
|
236
|
+
|
|
231
237
|
}
|
|
232
238
|
|
|
233
239
|
// COLLECTION SCHEMA GENERATION
|
|
234
240
|
if (attributes[prop].collection) {
|
|
235
|
-
|
|
241
|
+
let collectionModel = sails.models[attributes[prop].collection.toLowerCase()];
|
|
242
|
+
scalarType = scalarTypes[collectionModel.attributes[collectionModel.primaryKey].type.toLowerCase()];
|
|
236
243
|
const name = sails.models[attributes[prop].collection.toLowerCase()].globalId;
|
|
237
244
|
type += ` ${prop}: [${name}]\n`;
|
|
238
245
|
}
|
|
@@ -241,7 +248,7 @@ function createType(model) {
|
|
|
241
248
|
type += ` ${customFields[modelName]}\n`;
|
|
242
249
|
}
|
|
243
250
|
if (!attributes.customData) {
|
|
244
|
-
type +=
|
|
251
|
+
type += `""" [autogenerated] ${isAuthRequired(modelName) ? '\n[auth required]' : ''}""" customData: Json`;
|
|
245
252
|
}
|
|
246
253
|
type += '}\n';
|
|
247
254
|
return type;
|
|
@@ -308,10 +315,9 @@ function createSchema(typeDefsObj) {
|
|
|
308
315
|
const whiteList = {
|
|
309
316
|
// group: ['subscription', 'query'] // order - modelname , 'subscription' - resolver type
|
|
310
317
|
}
|
|
311
|
-
const userAuth = typeof sails.config.restographql?.authService === 'function' ? sails.config.restographql.authService : null;
|
|
312
318
|
|
|
313
|
-
let modelsResolvers: {Query?: Object, Subscription?: Object} = { Query: {}};
|
|
314
|
-
|
|
319
|
+
let modelsResolvers: { Query?: Object, Subscription?: Object } = { Query: {} };
|
|
320
|
+
import { withFilter } from "apollo-server";
|
|
315
321
|
|
|
316
322
|
/**
|
|
317
323
|
* Патчит waterline criteria во время автогенерации
|
|
@@ -322,17 +328,17 @@ const { withFilter } = require("apollo-server");
|
|
|
322
328
|
*/
|
|
323
329
|
function sanitizeCriteria(modelname, criteria) {
|
|
324
330
|
|
|
325
|
-
if (sails.models[modelname].attributes.enable){
|
|
331
|
+
if (sails.models[modelname].attributes.enable) {
|
|
326
332
|
criteria.enable = true;
|
|
327
333
|
}
|
|
328
334
|
|
|
329
|
-
if (sails.models[modelname].attributes.isDeleted){
|
|
335
|
+
if (sails.models[modelname].attributes.isDeleted) {
|
|
330
336
|
criteria.isDeleted = false;
|
|
331
337
|
}
|
|
332
338
|
|
|
333
339
|
switch (modelname) {
|
|
334
340
|
case 'dish':
|
|
335
|
-
criteria.balance = {'!=': 0};
|
|
341
|
+
criteria.balance = { '!=': 0 };
|
|
336
342
|
criteria.isDeleted = false;
|
|
337
343
|
break;
|
|
338
344
|
case 'group':
|
|
@@ -376,52 +382,81 @@ function addModelResolver(modelname) {
|
|
|
376
382
|
models.add(modelname); // make schema Type for Model
|
|
377
383
|
const methodName = firstLetterToLowerCase(modelName)
|
|
378
384
|
let resolverQuery = {
|
|
379
|
-
def: `""" autogenerated """ ${methodName}(criteria: Json): [${modelName}]`,
|
|
385
|
+
def: `""" [autogenerated] ${isAuthRequired(modelname) ? '\n[auth required]' : ''}""" ${methodName}(criteria: Json, skip: Int, limit: Int, sort: String): [${modelName}]`,
|
|
380
386
|
fn: async function (parent, args, context) {
|
|
381
387
|
|
|
382
388
|
let criteria = args.criteria || {};
|
|
383
389
|
criteria = sanitizeCriteria(modelname, criteria);
|
|
384
390
|
|
|
385
391
|
// If model has User field need auth
|
|
386
|
-
if (
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
392
|
+
if (isAuthRequired(modelName)) {
|
|
393
|
+
let auth = await JWTAuth.verify(
|
|
394
|
+
context.connectionParams.authorization
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
if (auth.userId && UserDevice.checkSession(auth.sessionId, auth.userId, { lastIP: "IP", userAgent: context.connectionParams["user-agent"] })) {
|
|
398
|
+
if (modelName.toLowerCase() === "user") {
|
|
399
|
+
criteria.id = auth.userId
|
|
400
|
+
} else {
|
|
401
|
+
criteria.user = auth.userId
|
|
402
|
+
}
|
|
394
403
|
} else {
|
|
395
|
-
|
|
404
|
+
throw 'Authorization failed'
|
|
396
405
|
}
|
|
397
406
|
}
|
|
398
407
|
|
|
399
|
-
|
|
408
|
+
|
|
409
|
+
let query: any;
|
|
410
|
+
if (criteria.where === undefined) {
|
|
411
|
+
query = { where: criteria }
|
|
412
|
+
} else {
|
|
413
|
+
query = criteria
|
|
414
|
+
}
|
|
415
|
+
|
|
400
416
|
//sorting
|
|
401
|
-
if (sails.models[modelname].attributes.
|
|
402
|
-
query.sort = '
|
|
417
|
+
if (sails.models[modelname].attributes.sortOrder) {
|
|
418
|
+
query.sort = 'sortOrder ASC'
|
|
403
419
|
}
|
|
404
420
|
|
|
405
|
-
let result = await sails.models[modelname].find(query);
|
|
406
421
|
|
|
407
|
-
|
|
422
|
+
let ORMrequest = sails.models[modelname].find(query);
|
|
423
|
+
|
|
424
|
+
if (args.skip) {
|
|
425
|
+
ORMrequest.skip(args.skip)
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (args.limit) {
|
|
429
|
+
ORMrequest.limit(args.limit)
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (args.sort) {
|
|
433
|
+
ORMrequest.sort(args.sort)
|
|
434
|
+
} else {
|
|
435
|
+
if (sails.models[modelname].attributes.sortOrder) {
|
|
436
|
+
ORMrequest.sort('sortOrder ASC')
|
|
437
|
+
}
|
|
438
|
+
}
|
|
408
439
|
|
|
409
|
-
|
|
440
|
+
let result = await ORMrequest
|
|
410
441
|
|
|
411
|
-
|
|
442
|
+
emitter.emit(`graphql-query-${modelname}`, result);
|
|
443
|
+
|
|
444
|
+
//worktime filter
|
|
445
|
+
|
|
446
|
+
if (sails.models[modelname].attributes.worktime) {
|
|
412
447
|
result = result.filter(record => {
|
|
413
|
-
if (!record.
|
|
448
|
+
if (!record.worktime) return true;
|
|
414
449
|
try {
|
|
415
|
-
|
|
450
|
+
return (WorkTimeValidator.isWorkNow({ worktime: record.worktime })).workNow
|
|
416
451
|
} catch (error) {
|
|
417
|
-
|
|
452
|
+
sails.log.error("Graphql > helper > error: ", error)
|
|
418
453
|
}
|
|
419
454
|
})
|
|
420
455
|
}
|
|
421
456
|
|
|
422
457
|
result.forEach(item => {
|
|
423
458
|
|
|
424
|
-
|
|
459
|
+
emitter.emit(
|
|
425
460
|
`http-api:before-send-${modelname.toLowerCase()}`,
|
|
426
461
|
item
|
|
427
462
|
);
|
|
@@ -431,106 +466,206 @@ function addModelResolver(modelname) {
|
|
|
431
466
|
},
|
|
432
467
|
};
|
|
433
468
|
modelsResolvers.Query[methodName] = resolverQuery;
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
let resolverQueryCount = {
|
|
472
|
+
def: `""" [autogenerated] ${isAuthRequired(modelname) ? '\n[auth required]' : ''}""" ${methodName}Count(criteria: Json): Int`,
|
|
473
|
+
fn: async function (parent, args, context) {
|
|
474
|
+
|
|
475
|
+
let criteria = args.criteria || {};
|
|
476
|
+
criteria = sanitizeCriteria(modelname, criteria);
|
|
477
|
+
|
|
478
|
+
// If model has User field need auth
|
|
479
|
+
if (isAuthRequired(modelName)) {
|
|
480
|
+
let auth = await JWTAuth.verify(
|
|
481
|
+
context.connectionParams.authorization
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
if (auth.userId && UserDevice.checkSession(auth.sessionId, auth.userId, { lastIP: "IP", userAgent: context.connectionParams["user-agent"] })) {
|
|
485
|
+
if (modelName.toLowerCase() === "user") {
|
|
486
|
+
criteria.id = auth.userId
|
|
487
|
+
} else {
|
|
488
|
+
criteria.user = auth.userId
|
|
489
|
+
}
|
|
490
|
+
} else {
|
|
491
|
+
throw 'Authorization failed'
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
let query: any;
|
|
497
|
+
if (criteria.where === undefined) {
|
|
498
|
+
query = { where: criteria }
|
|
499
|
+
} else {
|
|
500
|
+
query = criteria
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
let ORMrequest = sails.models[modelname].find(query);
|
|
506
|
+
|
|
507
|
+
let result = await ORMrequest
|
|
508
|
+
|
|
509
|
+
//worktime filter
|
|
510
|
+
if (sails.models[modelname].attributes.worktime) {
|
|
511
|
+
result = result.filter(record => {
|
|
512
|
+
if (!record.worktime) return true;
|
|
513
|
+
try {
|
|
514
|
+
return (WorkTimeValidator.isWorkNow({ worktime: record.worktime })).workNow
|
|
515
|
+
} catch (error) {
|
|
516
|
+
sails.log.error("Graphql > helper > error: ", error)
|
|
517
|
+
}
|
|
518
|
+
})
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
return result.length;
|
|
522
|
+
},
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
modelsResolvers.Query[`${methodName}Count`] = resolverQueryCount;
|
|
526
|
+
|
|
434
527
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
528
|
+
// Model fields resolvers
|
|
529
|
+
let resolvers = {};
|
|
530
|
+
// iterate separate resolvers in model (type])
|
|
531
|
+
Object.keys(sails.models[modelname].attributes).forEach((key) => {
|
|
532
|
+
if (key.includes("__")) return;
|
|
533
|
+
if (blackList.includes(`${modelName}.${key}`) || blackList.includes(`${key}`)) return;
|
|
534
|
+
if (typeof sails.models[modelname].attributes[key] === 'function') return;
|
|
535
|
+
|
|
536
|
+
if (sails.models[modelname].attributes[key].graphql) {
|
|
537
|
+
if (sails.models[modelname].attributes[key].graphql.public === false)
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
447
540
|
|
|
448
|
-
|
|
541
|
+
let modelAttribute = sails.models[modelname].attributes[key];
|
|
449
542
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
543
|
+
if (modelAttribute.collection || modelAttribute.model) {
|
|
544
|
+
let modelRelationType = modelAttribute.collection
|
|
545
|
+
? "collection"
|
|
546
|
+
: "model";
|
|
454
547
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
548
|
+
let relationKey =
|
|
549
|
+
modelAttribute.via !== undefined
|
|
550
|
+
? modelAttribute.via
|
|
551
|
+
: "id";
|
|
459
552
|
|
|
460
|
-
|
|
461
|
-
|
|
553
|
+
let criteria = {};
|
|
554
|
+
criteria = sanitizeCriteria(modelAttribute[modelRelationType], criteria);
|
|
462
555
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
let result = await sails.models[modelAttribute[modelRelationType]].findOne(criteria);
|
|
556
|
+
switch (modelRelationType) {
|
|
557
|
+
case "model":
|
|
558
|
+
resolvers[key] = async (parent, args, context) => {
|
|
559
|
+
criteria[relationKey] = parent[key];
|
|
468
560
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
561
|
+
// Check access rights
|
|
562
|
+
if (isAuthRequired(modelAttribute[modelRelationType])) {
|
|
563
|
+
let auth = await JWTAuth.verify(
|
|
564
|
+
context.connectionParams.authorization
|
|
473
565
|
);
|
|
474
566
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
567
|
+
if (auth.userId && UserDevice.checkSession(auth.sessionId, auth.userId, { lastIP: "IP", userAgent: context.connectionParams["user-agent"] })) {
|
|
568
|
+
if (modelName.toLowerCase() === "user") {
|
|
569
|
+
criteria["id"] = auth.userId
|
|
570
|
+
} else {
|
|
571
|
+
criteria["user"] = auth.userId
|
|
572
|
+
}
|
|
573
|
+
} else {
|
|
574
|
+
throw 'Authorization failed'
|
|
478
575
|
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
return;
|
|
482
|
-
case "collection":
|
|
483
|
-
resolvers[key] = async (parent, args, context) => {
|
|
576
|
+
}
|
|
484
577
|
|
|
578
|
+
let result = await sails.models[modelAttribute[modelRelationType]].findOne(criteria);
|
|
485
579
|
|
|
486
|
-
|
|
580
|
+
// TODO: this need only for support legacy patching (discount)
|
|
581
|
+
emitter.emit(
|
|
582
|
+
`http-api:before-send-${modelAttribute.model.toLowerCase()}`,
|
|
583
|
+
result
|
|
584
|
+
);
|
|
487
585
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
586
|
+
// celan if not work time
|
|
587
|
+
if (result && result.worktime && !WorkTimeValidator.isWorkNow({ worktime: result.worktime }).workNow) {
|
|
588
|
+
result = null;
|
|
589
|
+
}
|
|
590
|
+
return result;
|
|
591
|
+
};
|
|
493
592
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
593
|
+
// add virtual ids
|
|
594
|
+
resolvers[`${key}Id`] = async (parent, args, context) => {
|
|
595
|
+
return parent && parent[key];
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
return;
|
|
599
|
+
case "collection":
|
|
600
|
+
resolvers[key] = async (parent, args, context) => {
|
|
601
|
+
let parentPrimaryKey = sails.models[modelname].primaryKey
|
|
602
|
+
let criteria = {}
|
|
603
|
+
criteria[relationKey] = parent[parentPrimaryKey];
|
|
604
|
+
|
|
605
|
+
// Check access rights
|
|
606
|
+
if (isAuthRequired(modelAttribute[modelRelationType])) {
|
|
607
|
+
let auth = await JWTAuth.verify(
|
|
608
|
+
context.connectionParams.authorization
|
|
609
|
+
);
|
|
506
610
|
|
|
507
|
-
if (
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
});
|
|
611
|
+
if (auth.userId && UserDevice.checkSession(auth.sessionId, auth.userId, { lastIP: "IP", userAgent: context.connectionParams["user-agent"] })) {
|
|
612
|
+
if (modelName.toLowerCase() === "user") {
|
|
613
|
+
criteria["id"] = auth.userId
|
|
614
|
+
} else {
|
|
615
|
+
criteria["user"] = auth.userId
|
|
616
|
+
}
|
|
617
|
+
} else {
|
|
618
|
+
throw 'Authorization failed'
|
|
516
619
|
}
|
|
517
|
-
|
|
518
|
-
};
|
|
620
|
+
}
|
|
519
621
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
622
|
+
let result: any = null;
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
result = (await sails.models[modelname].findOne({ id: parent.id }).populate(key))[key];
|
|
626
|
+
if (result && sails.models[modelAttribute[modelRelationType]].attributes.sortOrder) {
|
|
627
|
+
result.sort((a, b) => a.sortOrder - b.sortOrder);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
if (!result) result = []
|
|
631
|
+
|
|
632
|
+
// TODO: this need only for support legacy patching (discount)
|
|
633
|
+
if (result && result.length) {
|
|
634
|
+
result.forEach(item => {
|
|
635
|
+
emitter.emit(
|
|
636
|
+
`http-api:before-send-${modelAttribute.collection.toLowerCase()}`,
|
|
637
|
+
item
|
|
638
|
+
);
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
if (sails.models[modelAttribute[modelRelationType]].attributes.worktime && Array.isArray(result) && result.length > 0) {
|
|
643
|
+
result = result.filter(record => {
|
|
644
|
+
if (!record.worktime) return true
|
|
645
|
+
try {
|
|
646
|
+
return (WorkTimeValidator.isWorkNow({ worktime: record.worktime })).workNow
|
|
647
|
+
} catch (error) {
|
|
648
|
+
sails.log.error("Graphql > helper > error: ", error)
|
|
649
|
+
}
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
return result;
|
|
654
|
+
};
|
|
655
|
+
|
|
656
|
+
return;
|
|
657
|
+
default:
|
|
658
|
+
// empty
|
|
659
|
+
break;
|
|
525
660
|
}
|
|
661
|
+
}
|
|
526
662
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
663
|
+
resolvers[key] = async (parent, args, context) => {
|
|
664
|
+
return parent && parent[key];
|
|
665
|
+
};
|
|
666
|
+
});
|
|
531
667
|
|
|
532
|
-
|
|
533
|
-
modelsResolvers[modelName] = resolvers;
|
|
668
|
+
modelsResolvers[modelName] = resolvers;
|
|
534
669
|
|
|
535
670
|
|
|
536
671
|
// Subscription resolver
|
|
@@ -538,7 +673,7 @@ function addModelResolver(modelname) {
|
|
|
538
673
|
models.add(modelname);
|
|
539
674
|
const methodName = `${firstLetterToLowerCase(modelName)}`;
|
|
540
675
|
let subscription = {
|
|
541
|
-
def: `"""
|
|
676
|
+
def: `""" [autogenerated] ${isAuthRequired(modelname) ? '\n[auth required]' : ''} """ ${methodName}(criteria: Json): ${modelName} `,
|
|
542
677
|
fn: {
|
|
543
678
|
subscribe: withFilter(
|
|
544
679
|
(rootValue, args, context, info) =>
|
|
@@ -546,38 +681,42 @@ function addModelResolver(modelname) {
|
|
|
546
681
|
async (payload, args, context, info) => {
|
|
547
682
|
|
|
548
683
|
// For User models
|
|
549
|
-
if (sails.models[modelname].attributes.user) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
684
|
+
if (sails.models[modelname].attributes.user || modelname === 'user') {
|
|
685
|
+
|
|
686
|
+
let auth = await JWTAuth.verify(
|
|
687
|
+
context.connectionParams.authorization
|
|
688
|
+
);
|
|
689
|
+
|
|
690
|
+
if (!args.criteria) {
|
|
691
|
+
args.criteria = {}
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
if (auth.userId) {
|
|
695
|
+
if (modelName.toLowerCase() === "user") {
|
|
696
|
+
args.criteria.id = auth.userId
|
|
697
|
+
} else {
|
|
698
|
+
args.criteria.user = auth.userId
|
|
699
|
+
}
|
|
561
700
|
} else {
|
|
562
|
-
|
|
701
|
+
throw 'Authorization failed'
|
|
563
702
|
}
|
|
564
703
|
}
|
|
565
704
|
|
|
566
705
|
return checkCriteria(payload, args.criteria)
|
|
567
|
-
|
|
706
|
+
|
|
568
707
|
// Filter by waterline criteria
|
|
569
|
-
function checkCriteria(payload: any, criteria: any): boolean{
|
|
708
|
+
function checkCriteria(payload: any, criteria: any): boolean {
|
|
570
709
|
|
|
571
710
|
// For id's array
|
|
572
|
-
if (Array.isArray(criteria) ||
|
|
573
|
-
return (WLCriteria(payload, { where: { id: criteria }}).results).length > 0
|
|
711
|
+
if (Array.isArray(criteria) || typeof criteria === "string") {
|
|
712
|
+
return (WLCriteria(payload, { where: { id: criteria } }).results).length > 0
|
|
574
713
|
}
|
|
575
714
|
|
|
576
715
|
// Where cause
|
|
577
|
-
if (
|
|
716
|
+
if (typeof criteria === 'object' && !Array.isArray(criteria) && criteria !== null) {
|
|
578
717
|
return (WLCriteria(payload, { where: criteria }).results).length > 0
|
|
579
718
|
}
|
|
580
|
-
|
|
719
|
+
|
|
581
720
|
return false
|
|
582
721
|
}
|
|
583
722
|
|
|
@@ -605,23 +744,23 @@ function modelPublishExtend(modelname) {
|
|
|
605
744
|
let modelName = sails.models[modelname].globalId;
|
|
606
745
|
|
|
607
746
|
let afterCreate = sails.models[modelname].afterCreate;
|
|
608
|
-
sails.models[modelname].afterCreate = async function (values, cb
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
747
|
+
sails.models[modelname].afterCreate = async function (values, cb) {
|
|
748
|
+
await sails.models[modelname].publish(values.id);
|
|
749
|
+
if (afterCreate) {
|
|
750
|
+
afterCreate(values, cb);
|
|
751
|
+
} else {
|
|
752
|
+
cb();
|
|
753
|
+
}
|
|
615
754
|
};
|
|
616
755
|
|
|
617
756
|
let afterUpdate = sails.models[modelname].afterUpdate;
|
|
618
|
-
sails.models[modelname].afterUpdate = async function (values, cb
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
757
|
+
sails.models[modelname].afterUpdate = async function (values, cb) {
|
|
758
|
+
await sails.models[modelname].publish(values.id);
|
|
759
|
+
if (afterUpdate) {
|
|
760
|
+
afterUpdate(values, cb);
|
|
761
|
+
} else {
|
|
762
|
+
cb();
|
|
763
|
+
}
|
|
625
764
|
};
|
|
626
765
|
|
|
627
766
|
let modelPublishExtendObj = {
|
|
@@ -629,7 +768,7 @@ function modelPublishExtend(modelname) {
|
|
|
629
768
|
let data = await sails.models[modelname].findOne(id);
|
|
630
769
|
// `http-api:request-${modelAttribute.collection.toLowerCase()}model-list`,
|
|
631
770
|
|
|
632
|
-
|
|
771
|
+
emitter.emit(`http-api:before-send-${modelname.toLowerCase()}`, data);
|
|
633
772
|
sails.graphql.pubsub.publish(modelName, data);
|
|
634
773
|
},
|
|
635
774
|
};
|
|
@@ -637,6 +776,10 @@ function modelPublishExtend(modelname) {
|
|
|
637
776
|
_.merge(sails.models[modelname], modelPublishExtendObj);
|
|
638
777
|
}
|
|
639
778
|
|
|
779
|
+
function isAuthRequired(modelname: string): Boolean {
|
|
780
|
+
modelname = modelname.toLowerCase();
|
|
781
|
+
return sails.models[modelname].attributes.user !== undefined || modelname === 'user';
|
|
782
|
+
}
|
|
640
783
|
|
|
641
784
|
export default {
|
|
642
785
|
addModel,
|