@autofleet/sheilta 1.3.8 → 1.3.10-beta-34f81272.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.
@@ -7,7 +7,7 @@ export declare type FormatPayloadOptions = {
7
7
  DBFormatter?: any;
8
8
  skipSearchTermFormat?: boolean;
9
9
  };
10
- declare const formatPayload: ({ order, page, perPage, include, query, attributes, searchTerm, }: {
10
+ declare const formatPayload: ({ order, page, perPage, include, query, attributes, searchTerm, allowedSearchableAttributes, }: {
11
11
  order?: any[];
12
12
  page?: number;
13
13
  perPage?: number;
@@ -15,6 +15,7 @@ declare const formatPayload: ({ order, page, perPage, include, query, attributes
15
15
  query?: {};
16
16
  attributes?: any;
17
17
  searchTerm?: any;
18
+ allowedSearchableAttributes?: any;
18
19
  }, model?: any, options?: any) => {
19
20
  attributes: any[] | {
20
21
  include: any[];
@@ -24,8 +25,6 @@ declare const formatPayload: ({ order, page, perPage, include, query, attributes
24
25
  page: any;
25
26
  perPage: any;
26
27
  include: any;
27
- scopes: (string | {
28
- method: any[];
29
- })[];
28
+ scopes: any[];
30
29
  };
31
30
  export default formatPayload;
@@ -9,8 +9,9 @@ const utils_1 = require("../utils");
9
9
  const operators_1 = require("../operators");
10
10
  const DEFAULT_ORDER = 'id';
11
11
  const DESCENDING_KEY = 'DESC';
12
+ const ASCENDING_KEY = 'ASC';
12
13
  const CUSTOM_FIELDS_QUERY_PREFIX = 'customFields.';
13
- const { CUSTOM_FIELDS_FILTER_SCOPE } = common_types_1.customFields;
14
+ const { CUSTOM_FIELDS_FILTER_SCOPE, CUSTOM_FIELDS_SORT_SCOPE } = common_types_1.customFields;
14
15
  const parseCustomFieldScopeQueryValue = (value) => {
15
16
  if (typeof value === 'string') {
16
17
  return value;
@@ -36,20 +37,43 @@ const getAttributeFromOrder = (order, options = {}) => {
36
37
  }, [[], []]);
37
38
  return [formattedOrder, attributes];
38
39
  };
39
- const formatOrder = ({ order, associationModels = [], }) => order.map((o) => {
40
- const formattedOrder = [utils_1.extractAttributeNameFromOrder(o, associationModels)];
41
- const isOrderDescOrder = utils_1.isOrderDesc(o);
42
- const isOrderAssociation = utils_1.isAttributeByAssociation(isOrderDescOrder
43
- ? o.split(utils_1.ORDER_PREFIX)[1]
44
- : o, associationModels);
45
- if (isOrderAssociation) {
46
- formattedOrder.push(utils_1.extractAssociatedAttributeNameFromOrder(o));
47
- }
48
- if (isOrderDescOrder) {
49
- formattedOrder.push(DESCENDING_KEY);
50
- }
51
- return formattedOrder;
52
- });
40
+ const formatOrder = ({ order, associationModels = [], }) => {
41
+ const formattedOrders = [];
42
+ const orderScopesMap = new Map();
43
+ order.forEach((o) => {
44
+ if ([o, o.substring(1)].some(t => t.startsWith(CUSTOM_FIELDS_QUERY_PREFIX))) {
45
+ if (!orderScopesMap.has(CUSTOM_FIELDS_SORT_SCOPE)) {
46
+ orderScopesMap.set(CUSTOM_FIELDS_SORT_SCOPE, {});
47
+ }
48
+ const scopeKey = o.split(CUSTOM_FIELDS_QUERY_PREFIX)[1];
49
+ orderScopesMap.get(CUSTOM_FIELDS_SORT_SCOPE)[scopeKey] = (utils_1.isOrderDesc(o) ?
50
+ DESCENDING_KEY :
51
+ ASCENDING_KEY);
52
+ return;
53
+ }
54
+ const formattedOrder = [utils_1.extractAttributeNameFromOrder(o, associationModels)];
55
+ const isOrderDescOrder = utils_1.isOrderDesc(o);
56
+ const isOrderAssociation = utils_1.isAttributeByAssociation(isOrderDescOrder
57
+ ? o.split(utils_1.ORDER_PREFIX)[1]
58
+ : o, associationModels);
59
+ if (isOrderAssociation) {
60
+ formattedOrder.push(utils_1.extractAssociatedAttributeNameFromOrder(o));
61
+ }
62
+ if (isOrderDescOrder) {
63
+ formattedOrder.push(DESCENDING_KEY);
64
+ }
65
+ formattedOrders.push(formattedOrder);
66
+ });
67
+ return {
68
+ formattedOrders,
69
+ orderScopes: Array.from(orderScopesMap.entries()).map(([scopeName, scopeValue]) => {
70
+ if (!scopeValue) {
71
+ return scopeName;
72
+ }
73
+ return { method: [scopeName, scopeValue] };
74
+ }),
75
+ };
76
+ };
53
77
  const formatPage = page => page || utils_1.PAGE_DEFAULT;
54
78
  const formatPerPage = perPage => perPage || utils_1.PER_PAGE_DEFAULT;
55
79
  const formatInclude = (include, associationsMap = {}) => {
@@ -94,29 +118,30 @@ const formatQuery = (query, associationModels) => {
94
118
  };
95
119
  const formatSearchTerm = (searchTerm, attributesToSend, rawAttributes) => ({
96
120
  $and: searchTerm.split(' ').map(term => ({
97
- $or: attributesToSend.filter(attrKey => rawAttributes[attrKey].type.key === 'STRING').map(attr => ({
121
+ $or: attributesToSend.filter(attrKey => { var _a; return ((_a = rawAttributes[attrKey]) === null || _a === void 0 ? void 0 : _a.type.key) === 'STRING'; }).map(attr => ({
98
122
  [attr]: {
99
123
  $iLike: `%${term}%`,
100
124
  },
101
125
  })),
102
126
  })),
103
127
  });
104
- const formatPayload = ({ order = [], page = utils_1.PAGE_DEFAULT, perPage = utils_1.PER_PAGE_DEFAULT, include = [], query = {}, attributes = null, searchTerm = null, }, model, options) => {
128
+ const formatPayload = ({ order = [], page = utils_1.PAGE_DEFAULT, perPage = utils_1.PER_PAGE_DEFAULT, include = [], query = {}, attributes = null, searchTerm = null, allowedSearchableAttributes = null, }, model, options) => {
105
129
  const associationModels = Object.keys((model === null || model === void 0 ? void 0 : model.associations) || {});
106
- const formattedOrder = formatOrder({
130
+ const { formattedOrders, orderScopes } = formatOrder({
107
131
  order: [...order, DEFAULT_ORDER],
108
132
  associationModels,
109
133
  });
110
- const [filteredFormattedOrder, filteredLiteralAttributes] = getAttributeFromOrder(formattedOrder, options);
134
+ const [filteredFormattedOrder, filteredLiteralAttributes] = getAttributeFromOrder(formattedOrders, options);
111
135
  const allAttributes = [...filteredLiteralAttributes, ...(attributes || [])];
112
136
  const formattedAttribute = (attributes === null || attributes === void 0 ? void 0 : attributes.length) ? allAttributes : { include: allAttributes };
113
137
  const formattedInclude = formatInclude(include, model === null || model === void 0 ? void 0 : model.associations);
114
138
  const formattedPage = formatPage(page);
115
139
  const formattedPerPage = formatPerPage(perPage);
116
140
  const result = formatQuery(query, associationModels);
141
+ const queryScopes = result.formattedScopes;
117
142
  let { formattedQuery } = result;
118
143
  if (searchTerm && !(options === null || options === void 0 ? void 0 : options.skipSearchTermFormat)) {
119
- const attributesToSend = (attributes === null || attributes === void 0 ? void 0 : attributes.length) ? attributes : Object.keys(model.rawAttributes);
144
+ const attributesToSend = allowedSearchableAttributes || ((attributes === null || attributes === void 0 ? void 0 : attributes.length) ? attributes : Object.keys(model.rawAttributes));
120
145
  const queryWithSearchTerm = formatSearchTerm(searchTerm, attributesToSend, model.rawAttributes);
121
146
  formattedQuery = lodash_1.default.isEmpty(formattedQuery) ? queryWithSearchTerm : {
122
147
  $and: [
@@ -125,6 +150,6 @@ const formatPayload = ({ order = [], page = utils_1.PAGE_DEFAULT, perPage = util
125
150
  ],
126
151
  };
127
152
  }
128
- return Object.assign({ query: formattedQuery, order: filteredFormattedOrder, page: formattedPage, perPage: formattedPerPage, include: formattedInclude, scopes: result.formattedScopes }, (formattedAttribute && { attributes: formattedAttribute }));
153
+ return Object.assign({ query: formattedQuery, order: filteredFormattedOrder, page: formattedPage, perPage: formattedPerPage, include: formattedInclude, scopes: [...queryScopes, ...orderScopes] }, (formattedAttribute && { attributes: formattedAttribute }));
129
154
  };
130
155
  exports.default = formatPayload;
@@ -25,6 +25,7 @@ const querySchema = joi_1.object({
25
25
  perPage: joi_1.number(),
26
26
  include: joi_1.array().items(joi_1.any()),
27
27
  searchTerm: joi_1.string(),
28
+ allowedSearchableAttributes: joi_1.array().items(joi_1.string()),
28
29
  });
29
30
  exports.newQueryValidationMiddleware = (inner = 'body') => (model, options = {}) => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
30
31
  const { query, attributes, order, page, perPage, include, } = req[inner];
@@ -56,7 +57,7 @@ exports.newQueryValidationMiddleware = (inner = 'body') => (model, options = {})
56
57
  }
57
58
  });
58
59
  exports.newQueryFormatMiddleware = (inner = 'body') => (model, options = {}) => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
59
- const { order, page, perPage, include, query, attributes, searchTerm, } = req[inner];
60
+ const { order, page, perPage, include, query, attributes, searchTerm, allowedSearchableAttributes, } = req[inner];
60
61
  const { query: formattedQuery, order: formattedOrder, page: formattedPage, perPage: formattedPerPage, include: formattedInclude, scopes: formattedScopes, attributes: formattedAttribute, } = formatter_1.default({
61
62
  query,
62
63
  order,
@@ -65,6 +66,7 @@ exports.newQueryFormatMiddleware = (inner = 'body') => (model, options = {}) =>
65
66
  include,
66
67
  attributes,
67
68
  searchTerm,
69
+ allowedSearchableAttributes,
68
70
  }, model, options);
69
71
  req[inner].query = formattedQuery;
70
72
  req[inner].order = formattedOrder;
@@ -73,6 +75,7 @@ exports.newQueryFormatMiddleware = (inner = 'body') => (model, options = {}) =>
73
75
  req[inner].perPage = formattedPerPage;
74
76
  req[inner].include = formattedInclude;
75
77
  req[inner].scopes = formattedScopes;
78
+ req[inner].allowedSearchableAttributes = new Set(allowedSearchableAttributes);
76
79
  if (options.includeRawPayload) {
77
80
  req[inner].rawPayload = {
78
81
  order,
@@ -7,10 +7,23 @@ exports.validatePayload = void 0;
7
7
  const lodash_1 = __importDefault(require("lodash"));
8
8
  const utils_1 = require("../utils");
9
9
  const operators_1 = require("../operators");
10
+ const cleanAttributeFromPrefix = (attr, prefix) => {
11
+ if (attr.startsWith(prefix)) {
12
+ return attr.slice(1);
13
+ }
14
+ return attr.endsWith(prefix) ? attr.slice(0, -1) : attr;
15
+ };
10
16
  const validateOperator = (operator) => operators_1.OPERATORS.includes(operator.split(operators_1.OPERATOR_PREFIX)[1]);
11
- const validateQueryAttribute = (attribute, modelAttributes = [], associationModels = []) => [...modelAttributes, ...associationModels]
12
- .includes(attribute.includes(utils_1.ASSOCIATION_PREFIX)
13
- ? attribute.split(utils_1.ASSOCIATION_PREFIX)[0] : attribute);
17
+ const validateQueryAttribute = (attribute, modelAttributes = [], associationModels = []) => {
18
+ const attributes = [...modelAttributes, ...associationModels];
19
+ if (attribute.includes(utils_1.ASSOCIATION_PREFIX) && attribute.includes(operators_1.OPERATOR_PREFIX)) {
20
+ const parts = attribute.split(utils_1.ASSOCIATION_PREFIX);
21
+ return parts.every(part => attributes.includes(cleanAttributeFromPrefix(part, operators_1.OPERATOR_PREFIX)));
22
+ }
23
+ return attributes
24
+ .includes(attribute.includes(utils_1.ASSOCIATION_PREFIX)
25
+ ? attribute.split(utils_1.ASSOCIATION_PREFIX)[0] : attribute);
26
+ };
14
27
  const validateSingleOrder = (currentOrder, rawAttributes, associationModels, options = {}) => {
15
28
  var _a, _b;
16
29
  const isOrderDescOrder = utils_1.isOrderDesc(currentOrder);
@@ -42,9 +55,8 @@ const validateAttributes = (attributes, rawAttributes) => {
42
55
  };
43
56
  const validateQueryPayload = (query, rawAttributes, associationModels = []) => {
44
57
  // eslint-disable-next-line array-callback-return
45
- Object.keys(query).map((key) => {
46
- const value = query[key];
47
- if (lodash_1.default.isArray(value)) {
58
+ Object.entries(query).map(([key, value]) => {
59
+ if (Array.isArray(value)) {
48
60
  if (lodash_1.default.isObject(value[0])) {
49
61
  value.map(v => validateQueryPayload(v, rawAttributes, associationModels));
50
62
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/sheilta",
3
- "version": "1.3.8",
3
+ "version": "1.3.10-beta-34f81272.0",
4
4
  "description": "manage cache",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -44,10 +44,12 @@
44
44
  },
45
45
  "homepage": "https://github.com/Autofleet/sheilta",
46
46
  "dependencies": {
47
- "@autofleet/common-types": "^1.7.29",
47
+ "@autofleet/common-types": "^1.7.42",
48
48
  "@autofleet/errors": "^1.0.10",
49
+ "@autofleet/sadot": "^0.6.6",
49
50
  "joi": "^17.9.2",
50
- "lodash": "^4.17.21"
51
+ "lodash": "^4.17.21",
52
+ "npm-watch": "^0.13.0"
51
53
  },
52
54
  "devDependencies": {
53
55
  "@types/jest": "^24.9.0",