@autofleet/sheilta 1.0.0-test-3 → 1.0.1-aaron-test

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.
@@ -1,48 +1,18 @@
1
- import type { LiteralAttribute } from '../middleware';
2
1
  declare type OrderItem = string | [string, string];
3
2
  declare type SequelizeOrder = string | OrderItem[];
4
- export declare type FormatPayloadOptions = {
5
- includeRawPayload?: boolean;
6
- literalAttributes?: LiteralAttribute[];
7
- DBFormatter?: any;
8
- skipSearchTermFormat?: boolean;
9
- };
10
- declare type ConditionWithOperator = {
11
- operator: string;
12
- value: string;
13
- };
14
- export declare type ConditionValue = ConditionWithOperator | ConditionWithOperator[] | string | string[];
15
- /**
16
- * Generates replacements for the given conditions.
17
- *
18
- * @param conditions - The conditions to generate replacements for.
19
- * @returns The replacements object.
20
- */
21
- export declare const generateFilterReplacements: (conditions: Record<string, ConditionValue>) => Record<string, string>;
22
- /**
23
- * Generates replacements for the given order array.
24
- *
25
- * @param order - The order array to generate replacements for.
26
- * @returns The replacements object.
27
- */
28
- export declare const generateOrderReplacements: (order: string[]) => Record<string, string>;
29
3
  declare const formatPayload: ({ order, page, perPage, include, query, attributes, searchTerm, }: {
30
- order?: any[];
4
+ order: any;
31
5
  page?: number;
32
6
  perPage?: number;
33
7
  include?: any[];
34
8
  query?: {};
35
9
  attributes?: any;
36
10
  searchTerm?: any;
37
- }, model?: any, options?: any) => {
38
- attributes: any[] | {
39
- include: any[];
40
- };
11
+ }, model?: any) => {
41
12
  query: {};
42
13
  order: SequelizeOrder[];
43
14
  page: any;
44
15
  perPage: any;
45
16
  include: any;
46
- scopes: any[];
47
17
  };
48
18
  export default formatPayload;
@@ -3,114 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.generateOrderReplacements = exports.generateFilterReplacements = void 0;
7
6
  const lodash_1 = __importDefault(require("lodash"));
8
- const common_types_1 = require("@autofleet/common-types");
9
7
  const utils_1 = require("../utils");
10
- const operators_1 = require("../operators");
11
- const DEFAULT_ORDER = 'id';
12
8
  const DESCENDING_KEY = 'DESC';
13
- const ASCENDING_KEY = 'ASC';
14
- const CUSTOM_FIELDS_QUERY_PREFIX = 'customFields.';
15
- const { CUSTOM_FIELDS_FILTER_SCOPE, CUSTOM_FIELDS_SORT_SCOPE } = common_types_1.customFields;
16
- const parseCustomFieldScopeQueryValue = (value) => {
17
- if (['string', 'number'].includes(typeof value) || Array.isArray(value)) {
18
- return value;
19
- }
20
- return Object.entries(value).map(([operator, conditionValue]) => ({
21
- operator: operators_1.OPERATORS_TO_SQL[operator],
22
- value: conditionValue,
23
- }));
24
- };
25
- const getAttributeFromOrder = (order, options = {}) => {
26
- const { literalAttributes = [], DBFormatter = undefined } = options;
27
- const [formattedOrder, attributes] = order.reduce((acc, o) => {
28
- const [item, orderStyle = 'ASC'] = Array.isArray(o) ? o : [o];
29
- const found = literalAttributes === null || literalAttributes === void 0 ? void 0 : literalAttributes.find(obj => obj.attribute === item);
30
- if (found) {
31
- acc[1].push(found.literal);
32
- acc[0].push([DBFormatter ? DBFormatter(`"${found.attribute}" ${orderStyle}`) : `${found.attribute} ${orderStyle}`]);
33
- }
34
- else {
35
- acc[0].push(o);
36
- }
37
- return acc;
38
- }, [[], []]);
39
- return [formattedOrder, attributes];
40
- };
41
- /**
42
- * Generates replacements for the given conditions.
43
- *
44
- * @param conditions - The conditions to generate replacements for.
45
- * @returns The replacements object.
46
- */
47
- exports.generateFilterReplacements = (conditions) => {
48
- const replacements = {};
49
- Object.entries(conditions).forEach(([key, condition]) => {
50
- const replacementKey = utils_1.generateRandomString();
51
- // eslint-disable-next-line prefer-destructuring
52
- replacements[replacementKey] = key.split(CUSTOM_FIELDS_QUERY_PREFIX)[1];
53
- if (Array.isArray(condition)) {
54
- condition.forEach((value) => {
55
- const valueKey = utils_1.generateRandomString();
56
- replacements[valueKey] = typeof value === 'string' ? value : value.value;
57
- });
58
- }
59
- else if (typeof condition === 'string' || typeof condition === 'number') {
60
- const conditionKey = utils_1.generateRandomString();
61
- replacements[conditionKey] = condition;
62
- }
63
- else if (condition === null || condition === void 0 ? void 0 : condition.operator) {
64
- const operatorKey = utils_1.generateRandomString();
65
- replacements[operatorKey] = condition.value;
66
- }
67
- });
68
- return replacements;
69
- };
70
- /**
71
- * Generates replacements for the given order array.
72
- *
73
- * @param order - The order array to generate replacements for.
74
- * @returns The replacements object.
75
- */
76
- exports.generateOrderReplacements = (order) => {
77
- const replacementMap = {};
78
- order.forEach((o) => {
79
- if (o.startsWith(CUSTOM_FIELDS_QUERY_PREFIX)) {
80
- const rand = utils_1.generateRandomString();
81
- // eslint-disable-next-line prefer-destructuring
82
- replacementMap[rand] = o.split(CUSTOM_FIELDS_QUERY_PREFIX)[1];
83
- }
84
- else if (o.substring(1).startsWith(CUSTOM_FIELDS_QUERY_PREFIX)) {
85
- const rand = utils_1.generateRandomString();
86
- // eslint-disable-next-line prefer-destructuring
87
- replacementMap[rand] = o.substring(1).split(CUSTOM_FIELDS_QUERY_PREFIX)[1];
88
- }
89
- });
90
- return replacementMap;
91
- };
92
- /**
93
- * Creates a combined replacement map from order and query.
94
- *
95
- * @param order - The order array.
96
- * @param query - The query object.
97
- * @returns The combined replacements object.
98
- */
99
- const createReplacementMap = (order, query) => (Object.assign(Object.assign({}, exports.generateOrderReplacements(order)), exports.generateFilterReplacements(query)));
100
- const formatOrder = ({ order, associationModels = [], replacementsMap = {}, }) => {
101
- const formattedOrders = [];
102
- const orderScopesMap = new Map();
103
- order.forEach((o) => {
104
- if ([o, o.substring(1)].some(t => t.startsWith(CUSTOM_FIELDS_QUERY_PREFIX))) {
105
- if (!orderScopesMap.has(CUSTOM_FIELDS_SORT_SCOPE)) {
106
- orderScopesMap.set(CUSTOM_FIELDS_SORT_SCOPE, {});
107
- }
108
- const scopeKey = o.split(CUSTOM_FIELDS_QUERY_PREFIX)[1];
109
- orderScopesMap.get(CUSTOM_FIELDS_SORT_SCOPE)[scopeKey] = (utils_1.isOrderDesc(o) ?
110
- DESCENDING_KEY :
111
- ASCENDING_KEY);
112
- return;
113
- }
9
+ const formatOrder = ({ order = [], associationModels = [], }) => (order.length === 0 ? undefined :
10
+ order.map((o) => {
114
11
  const formattedOrder = [utils_1.extractAttributeNameFromOrder(o, associationModels)];
115
12
  const isOrderDescOrder = utils_1.isOrderDesc(o);
116
13
  const isOrderAssociation = utils_1.isAttributeByAssociation(isOrderDescOrder
@@ -122,71 +19,17 @@ const formatOrder = ({ order, associationModels = [], replacementsMap = {}, }) =
122
19
  if (isOrderDescOrder) {
123
20
  formattedOrder.push(DESCENDING_KEY);
124
21
  }
125
- formattedOrders.push(formattedOrder);
126
- });
127
- return {
128
- formattedOrders,
129
- replacementsMap,
130
- orderScopes: Array.from(orderScopesMap.entries()).map(([scopeName, scopeValue]) => {
131
- if (!scopeValue) {
132
- return scopeName;
133
- }
134
- return {
135
- method: [scopeName, {
136
- replacementsMap,
137
- scopeValue,
138
- }],
139
- };
140
- }),
141
- };
142
- };
22
+ return formattedOrder;
23
+ }));
143
24
  const formatPage = page => page || utils_1.PAGE_DEFAULT;
144
25
  const formatPerPage = perPage => perPage || utils_1.PER_PAGE_DEFAULT;
145
26
  const formatInclude = (include, associationsMap = {}) => {
146
- let formattedInclude = include.map((i) => {
147
- var _a;
148
- const includedAssociation = associationsMap[typeof i === 'string' ? i : (i.association || i.model)];
149
- return Object.assign(Object.assign(Object.assign({}, i), { association: includedAssociation, required: i.required !== false }), (i.include && {
150
- include: formatInclude(i.include, (_a = includedAssociation === null || includedAssociation === void 0 ? void 0 : includedAssociation.target) === null || _a === void 0 ? void 0 : _a.associations),
151
- }));
152
- });
27
+ let formattedInclude = include.map(i => (Object.assign(Object.assign({}, i), { association: associationsMap[i.association || i.model], required: i.required !== 'false' })));
153
28
  formattedInclude = formattedInclude.map(i => lodash_1.default.omit(i, ['model']));
154
29
  return formattedInclude;
155
30
  };
156
- const formatQuery = (query, associationModels, replacementsMap) => {
157
- const formattedQuery = {};
158
- const formattedScopeMap = new Map();
159
- Object.entries(query).forEach(([queryItemKey, queryItemValue]) => {
160
- if (queryItemKey.startsWith(CUSTOM_FIELDS_QUERY_PREFIX)) {
161
- if (!formattedScopeMap.has(CUSTOM_FIELDS_FILTER_SCOPE)) {
162
- formattedScopeMap.set(CUSTOM_FIELDS_FILTER_SCOPE, {});
163
- }
164
- const scopeKey = queryItemKey.split(CUSTOM_FIELDS_QUERY_PREFIX)[1];
165
- formattedScopeMap.get(CUSTOM_FIELDS_FILTER_SCOPE)[scopeKey] =
166
- parseCustomFieldScopeQueryValue(queryItemValue);
167
- return;
168
- }
169
- const key = utils_1.isAttributeByAssociation(queryItemKey, associationModels)
170
- ? utils_1.wrapAttributeWithOperator(queryItemKey)
171
- : queryItemKey;
172
- formattedQuery[key] = queryItemValue;
173
- });
174
- const formattedScopes = Array.from(formattedScopeMap.entries()).map(([scopeName, scopeValue]) => {
175
- if (!scopeValue) {
176
- return scopeName;
177
- }
178
- return {
179
- method: [scopeName, {
180
- replacementsMap,
181
- scopeValue,
182
- }],
183
- };
184
- });
185
- return {
186
- formattedQuery,
187
- formattedScopes,
188
- };
189
- };
31
+ const formatQuery = (query, associationModels) => Object.keys(query).reduce((acc, queryItemKey) => (Object.assign(Object.assign({}, acc), { [utils_1.isAttributeByAssociation(queryItemKey, associationModels)
32
+ ? utils_1.wrapAttributeWithOperator(queryItemKey) : queryItemKey]: query[queryItemKey] })), {});
190
33
  const formatSearchTerm = (searchTerm, attributesToSend, rawAttributes) => ({
191
34
  $and: searchTerm.split(' ').map(term => ({
192
35
  $or: attributesToSend.filter(attrKey => rawAttributes[attrKey].type.key === 'STRING').map(attr => ({
@@ -196,24 +39,17 @@ const formatSearchTerm = (searchTerm, attributesToSend, rawAttributes) => ({
196
39
  })),
197
40
  })),
198
41
  });
199
- const formatPayload = ({ order = [], page = utils_1.PAGE_DEFAULT, perPage = utils_1.PER_PAGE_DEFAULT, include = [], query = {}, attributes = null, searchTerm = null, }, model, options) => {
200
- const replacementsMap = createReplacementMap(order, query);
42
+ const formatPayload = ({ order, page = utils_1.PAGE_DEFAULT, perPage = utils_1.PER_PAGE_DEFAULT, include = [], query = {}, attributes = null, searchTerm = null, }, model) => {
201
43
  const associationModels = Object.keys((model === null || model === void 0 ? void 0 : model.associations) || {});
202
- const { formattedOrders, orderScopes } = formatOrder({
203
- order: [...order, DEFAULT_ORDER],
44
+ const formattedOrder = formatOrder({
45
+ order,
204
46
  associationModels,
205
- replacementsMap,
206
47
  });
207
- const [filteredFormattedOrder, filteredLiteralAttributes] = getAttributeFromOrder(formattedOrders, options);
208
- const allAttributes = [...filteredLiteralAttributes, ...(attributes || [])];
209
- const formattedAttribute = (attributes === null || attributes === void 0 ? void 0 : attributes.length) ? allAttributes : { include: allAttributes };
210
48
  const formattedInclude = formatInclude(include, model === null || model === void 0 ? void 0 : model.associations);
211
49
  const formattedPage = formatPage(page);
212
50
  const formattedPerPage = formatPerPage(perPage);
213
- const result = formatQuery(query, associationModels, replacementsMap);
214
- const queryScopes = result.formattedScopes;
215
- let { formattedQuery } = result;
216
- if (searchTerm && !(options === null || options === void 0 ? void 0 : options.skipSearchTermFormat)) {
51
+ let formattedQuery = formatQuery(query, associationModels);
52
+ if (searchTerm) {
217
53
  const attributesToSend = (attributes === null || attributes === void 0 ? void 0 : attributes.length) ? attributes : Object.keys(model.rawAttributes);
218
54
  const queryWithSearchTerm = formatSearchTerm(searchTerm, attributesToSend, model.rawAttributes);
219
55
  formattedQuery = lodash_1.default.isEmpty(formattedQuery) ? queryWithSearchTerm : {
@@ -223,6 +59,12 @@ const formatPayload = ({ order = [], page = utils_1.PAGE_DEFAULT, perPage = util
223
59
  ],
224
60
  };
225
61
  }
226
- return Object.assign({ query: formattedQuery, order: filteredFormattedOrder, page: formattedPage, perPage: formattedPerPage, include: formattedInclude, scopes: [...queryScopes, ...orderScopes] }, (formattedAttribute && { attributes: formattedAttribute }));
62
+ return {
63
+ query: formattedQuery,
64
+ order: formattedOrder,
65
+ page: formattedPage,
66
+ perPage: formattedPerPage,
67
+ include: formattedInclude,
68
+ };
227
69
  };
228
70
  exports.default = formatPayload;
@@ -135,13 +135,13 @@ describe('formatting test', () => {
135
135
  const { order } = _1.default({
136
136
  order: ['startTime', '-endTime'],
137
137
  });
138
- expect(JSON.stringify(order)).toBe(JSON.stringify([['startTime'], ['endTime', 'DESC'], ['id']]));
138
+ expect(JSON.stringify(order)).toBe(JSON.stringify([['startTime'], ['endTime', 'DESC']]));
139
139
  });
140
140
  it('simple check asc', () => {
141
141
  const { order } = _1.default({
142
142
  order: ['startTime', 'endTime'],
143
143
  });
144
- expect(JSON.stringify(order)).toBe(JSON.stringify([['startTime'], ['endTime'], ['id']]));
144
+ expect(JSON.stringify(order)).toBe(JSON.stringify([['startTime'], ['endTime']]));
145
145
  });
146
146
  it('by included model', () => {
147
147
  const { order } = _1.default({
@@ -154,7 +154,7 @@ describe('formatting test', () => {
154
154
  status: {},
155
155
  },
156
156
  });
157
- expect(JSON.stringify(order)).toBe(JSON.stringify([['status', 'name'], ['id']]));
157
+ expect(JSON.stringify(order)).toBe(JSON.stringify([['status', 'name']]));
158
158
  });
159
159
  it('by included model descending', () => {
160
160
  const { order } = _1.default({
@@ -167,7 +167,7 @@ describe('formatting test', () => {
167
167
  status: {},
168
168
  },
169
169
  });
170
- expect(JSON.stringify(order)).toBe(JSON.stringify([['status', 'name', 'DESC'], ['id']]));
170
+ expect(JSON.stringify(order)).toBe(JSON.stringify([['status', 'name', 'DESC']]));
171
171
  });
172
172
  it('by json field', () => {
173
173
  const { order } = _1.default({
@@ -177,7 +177,7 @@ describe('formatting test', () => {
177
177
  startTime: '', endTime: '', currencySymbol: '', currencyCode: '', startStationId: '', json: '',
178
178
  },
179
179
  });
180
- expect(JSON.stringify(order)).toBe(JSON.stringify([['status.name'], ['id']]));
180
+ expect(JSON.stringify(order)).toBe(JSON.stringify([['status.name']]));
181
181
  });
182
182
  it('by json field descending', () => {
183
183
  const { order } = _1.default({
@@ -187,81 +187,7 @@ describe('formatting test', () => {
187
187
  startTime: '', endTime: '', currencySymbol: '', currencyCode: '', startStationId: '', json: '',
188
188
  },
189
189
  });
190
- expect(JSON.stringify(order)).toBe(JSON.stringify([['status.name', 'DESC'], ['id']]));
191
- });
192
- it('by literal field ascending', () => {
193
- const literalAttribute = { attribute: 'genericField', literal: [{ 0: e => `${e}0` }] };
194
- const { order, attributes } = _1.default({
195
- order: [literalAttribute.attribute],
196
- }, {
197
- rawAttributes: {
198
- startTime: '', endTime: '', currencySymbol: '', currencyCode: '', startStationId: '',
199
- },
200
- }, {
201
- literalAttributes: [literalAttribute],
202
- });
203
- expect(JSON.stringify(order)).toBe(JSON.stringify([[`${literalAttribute.attribute} ASC`], ['id']]));
204
- expect(JSON.stringify(attributes))
205
- .toBe(JSON.stringify({ include: [literalAttribute.literal] }));
206
- });
207
- it('by literal field descending', () => {
208
- const literalAttribute = { attribute: 'genericField', literal: ['void', 'field'] };
209
- const { order, attributes } = _1.default({
210
- order: [`-${literalAttribute.attribute}`, 'currencySymbol'],
211
- attributes: ['endTime'],
212
- }, {
213
- rawAttributes: {
214
- startTime: '', endTime: '', currencySymbol: '', currencyCode: '', startStationId: '',
215
- },
216
- }, {
217
- literalAttributes: [literalAttribute],
218
- });
219
- expect(JSON.stringify(order)).toBe(JSON.stringify([[`${literalAttribute.attribute} DESC`], ['currencySymbol'], ['id']]));
220
- expect(JSON.stringify(attributes))
221
- .toBe(JSON.stringify([[literalAttribute.literal[0], literalAttribute.literal[1]], 'endTime']));
222
- });
223
- it('by literal field - not found', () => {
224
- const literalAttribute = { attribute: 'genericField', literal: 'void' };
225
- const { order, attributes } = _1.default({
226
- order: [`-O${literalAttribute.attribute}`],
227
- }, {
228
- rawAttributes: {
229
- startTime: '', endTime: '', currencySymbol: '', currencyCode: '', startStationId: '',
230
- },
231
- }, {
232
- literalAttributes: [literalAttribute],
233
- });
234
- expect(JSON.stringify(order)).toBe(JSON.stringify([[`O${literalAttribute.attribute}`, 'DESC'], ['id']]));
235
- expect(JSON.stringify(attributes)).toBe(JSON.stringify({ include: [] }));
236
- });
237
- });
238
- describe('include formatting', () => {
239
- it('include required should be true', () => {
240
- const { include } = _1.default({
241
- order: [],
242
- include: [{
243
- model: 'status',
244
- }],
245
- }, {
246
- associations: {
247
- status: {},
248
- },
249
- });
250
- expect(include[0].required).toBe(true);
251
- });
252
- it('include required should be false', () => {
253
- const { include } = _1.default({
254
- order: [],
255
- include: [{
256
- model: 'status',
257
- required: false,
258
- }],
259
- }, {
260
- associations: {
261
- status: {},
262
- },
263
- });
264
- expect(include[0].required).toBe(false);
190
+ expect(JSON.stringify(order)).toBe(JSON.stringify([['status.name', 'DESC']]));
265
191
  });
266
192
  });
267
193
  });
package/lib/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { formatOperators } from './operators';
2
- import { queryFormatMiddleware, queryValidationMiddleware, MiddlewareValidationOption, LiteralAttribute } from './middleware';
3
- export { formatOperators, queryFormatMiddleware, queryValidationMiddleware, MiddlewareValidationOption, LiteralAttribute, };
2
+ import { queryFormatMiddleware, queryValidationMiddleware } from './middleware';
3
+ export { formatOperators, queryFormatMiddleware, queryValidationMiddleware, };
@@ -1,16 +1,4 @@
1
- import { FormatPayloadOptions } from '../formatter';
2
- declare type literal = any;
3
- declare type LiteralQuery = (literal | string)[] | literal;
4
- export declare type LiteralAttribute = {
5
- attribute: string;
6
- literal: LiteralQuery;
7
- };
8
- export declare type MiddlewareValidationOption = {
9
- literalAttributes?: LiteralAttribute[];
10
- enrichmentAttributes?: string[];
11
- };
12
- export declare const newQueryValidationMiddleware: (inner?: string) => (model: any, options?: MiddlewareValidationOption) => (req: any, res: any, next: any) => Promise<void>;
13
- export declare const newQueryFormatMiddleware: (inner?: string) => (model: any, options?: FormatPayloadOptions) => (req: any, res: any, next: any) => Promise<void>;
14
- export declare const queryValidationMiddleware: (model: any, options?: MiddlewareValidationOption) => (req: any, res: any, next: any) => Promise<void>;
15
- export declare const queryFormatMiddleware: (model: any, options?: FormatPayloadOptions) => (req: any, res: any, next: any) => Promise<void>;
16
- export {};
1
+ export declare const newQueryValidationMiddleware: (inner?: string) => (model: any) => (req: any, res: any, next: any) => Promise<any>;
2
+ export declare const newQueryFormatMiddleware: (inner?: string) => (model: any) => (req: any, res: any, next: any) => Promise<any>;
3
+ export declare const queryValidationMiddleware: (model: any) => (req: any, res: any, next: any) => Promise<any>;
4
+ export declare const queryFormatMiddleware: (model: any) => (req: any, res: any, next: any) => Promise<any>;
@@ -18,17 +18,15 @@ const joi_1 = require("joi");
18
18
  const formatter_1 = __importDefault(require("../formatter"));
19
19
  const validations_1 = require("../validations");
20
20
  const querySchema = joi_1.object({
21
- query: joi_1.object(),
21
+ query: joi_1.any(),
22
22
  attributes: joi_1.array().items(joi_1.string()),
23
23
  order: joi_1.array().items(joi_1.string()),
24
24
  page: joi_1.number(),
25
25
  perPage: joi_1.number(),
26
26
  include: joi_1.array().items(joi_1.any()),
27
- searchTerm: joi_1.string(),
28
- enrichments: joi_1.array().items(joi_1.string()),
29
27
  });
30
- exports.newQueryValidationMiddleware = (inner = 'body') => (model, options = {}) => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
31
- const { query, attributes, order, page, perPage, include, enrichments, } = req[inner];
28
+ exports.newQueryValidationMiddleware = (inner = 'body') => model => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
29
+ const { query, attributes, order, page, perPage, include, } = req[inner];
32
30
  try {
33
31
  const result = querySchema.validate(req[inner]);
34
32
  if (result.error) {
@@ -41,8 +39,7 @@ exports.newQueryValidationMiddleware = (inner = 'body') => (model, options = {})
41
39
  page,
42
40
  perPage,
43
41
  include,
44
- enrichments,
45
- }, model, options);
42
+ }, model);
46
43
  return next();
47
44
  }
48
45
  catch (error) {
@@ -57,9 +54,9 @@ exports.newQueryValidationMiddleware = (inner = 'body') => (model, options = {})
57
54
  });
58
55
  }
59
56
  });
60
- exports.newQueryFormatMiddleware = (inner = 'body') => (model, options = {}) => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
57
+ exports.newQueryFormatMiddleware = (inner = 'body') => model => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
61
58
  const { order, page, perPage, include, query, attributes, searchTerm, } = req[inner];
62
- const { query: formattedQuery, order: formattedOrder, page: formattedPage, perPage: formattedPerPage, include: formattedInclude, scopes: formattedScopes, attributes: formattedAttribute, } = formatter_1.default({
59
+ const { query: formattedQuery, order: formattedOrder, page: formattedPage, perPage: formattedPerPage, include: formattedInclude, } = formatter_1.default({
63
60
  query,
64
61
  order,
65
62
  page,
@@ -67,25 +64,12 @@ exports.newQueryFormatMiddleware = (inner = 'body') => (model, options = {}) =>
67
64
  include,
68
65
  attributes,
69
66
  searchTerm,
70
- }, model, options);
67
+ }, model);
71
68
  req[inner].query = formattedQuery;
72
69
  req[inner].order = formattedOrder;
73
- req[inner].attributes = formattedAttribute;
74
70
  req[inner].page = formattedPage;
75
71
  req[inner].perPage = formattedPerPage;
76
72
  req[inner].include = formattedInclude;
77
- req[inner].scopes = formattedScopes;
78
- if (options.includeRawPayload) {
79
- req[inner].rawPayload = {
80
- order,
81
- page,
82
- perPage,
83
- include,
84
- query,
85
- attributes,
86
- searchTerm,
87
- };
88
- }
89
73
  return next();
90
74
  });
91
75
  exports.queryValidationMiddleware = exports.newQueryValidationMiddleware();
@@ -1,20 +1,3 @@
1
1
  export declare const OPERATORS: string[];
2
2
  export declare const OPERATOR_PREFIX = "$";
3
- export declare const OPERATORS_TO_SQL: {
4
- $eq: string;
5
- $ne: string;
6
- $gte: string;
7
- $gt: string;
8
- $lte: string;
9
- $lt: string;
10
- $not: string;
11
- $in: string;
12
- $notIn: string;
13
- $is: string;
14
- $like: string;
15
- $iLike: string;
16
- $notLike: string;
17
- $and: string;
18
- $or: string;
19
- };
20
3
  export declare const formatOperators: (Sequelize: any) => {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.formatOperators = exports.OPERATORS_TO_SQL = exports.OPERATOR_PREFIX = exports.OPERATORS = void 0;
3
+ exports.formatOperators = exports.OPERATOR_PREFIX = exports.OPERATORS = void 0;
4
4
  exports.OPERATORS = [
5
5
  'eq',
6
6
  'ne',
@@ -22,23 +22,6 @@ exports.OPERATORS = [
22
22
  'contains',
23
23
  ];
24
24
  exports.OPERATOR_PREFIX = '$';
25
- exports.OPERATORS_TO_SQL = {
26
- $eq: '=',
27
- $ne: '!=',
28
- $gte: '>=',
29
- $gt: '>',
30
- $lte: '<=',
31
- $lt: '<',
32
- $not: 'NOT',
33
- $in: 'IN',
34
- $notIn: 'NOT IN',
35
- $is: 'IS',
36
- $like: 'LIKE',
37
- $iLike: 'ILIKE',
38
- $notLike: 'NOT LIKE',
39
- $and: 'AND',
40
- $or: 'OR',
41
- };
42
25
  exports.formatOperators = (Sequelize) => {
43
26
  const { Op } = Sequelize;
44
27
  return exports.OPERATORS.reduce((map, o) => {
package/lib/utils.d.ts CHANGED
@@ -11,4 +11,3 @@ export declare const extractAttributeNameFromOrder: (order: any, associationMode
11
11
  export declare const isOrderDesc: (order: any) => boolean;
12
12
  export declare const throwBadRequestError: (message: string) => never;
13
13
  export declare const extractAssociatedAttributeNameFromOrder: (order: any) => string;
14
- export declare const generateRandomString: (length?: number) => string;
package/lib/utils.js CHANGED
@@ -1,9 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateRandomString = exports.extractAssociatedAttributeNameFromOrder = exports.throwBadRequestError = exports.isOrderDesc = exports.extractAttributeNameFromOrder = exports.isAttributeByAssociation = exports.wrapAttributeWithOperator = exports.PAGE_MIN = exports.PER_PAGE_MIN_LIMIT = exports.PER_PAGE_MAX_LIMIT = exports.PAGE_DEFAULT = exports.PER_PAGE_DEFAULT = exports.ASSOCIATION_PREFIX = exports.ORDER_PREFIX = void 0;
3
+ exports.extractAssociatedAttributeNameFromOrder = exports.throwBadRequestError = exports.isOrderDesc = exports.extractAttributeNameFromOrder = exports.isAttributeByAssociation = exports.wrapAttributeWithOperator = exports.PAGE_MIN = exports.PER_PAGE_MIN_LIMIT = exports.PER_PAGE_MAX_LIMIT = exports.PAGE_DEFAULT = exports.PER_PAGE_DEFAULT = exports.ASSOCIATION_PREFIX = exports.ORDER_PREFIX = void 0;
4
4
  const errors_1 = require("@autofleet/errors");
5
5
  const operators_1 = require("./operators");
6
- const randomInt = max => Math.floor(Math.random() * Math.floor(max));
7
6
  exports.ORDER_PREFIX = '-';
8
7
  exports.ASSOCIATION_PREFIX = '.';
9
8
  exports.PER_PAGE_DEFAULT = 20;
@@ -30,7 +29,3 @@ exports.throwBadRequestError = (message) => {
30
29
  throw new errors_1.BadRequest([{ message }], null);
31
30
  };
32
31
  exports.extractAssociatedAttributeNameFromOrder = (order) => order.split(exports.ASSOCIATION_PREFIX)[1];
33
- exports.generateRandomString = (length = 5) => {
34
- const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
35
- return Array.from({ length }, () => characters.charAt(randomInt(characters.length))).join('');
36
- };
@@ -1,10 +1,8 @@
1
- import type { MiddlewareValidationOption } from '../middleware';
2
- export declare const validatePayload: ({ query, order, attributes, include, page, perPage, enrichments, }: {
1
+ export declare const validatePayload: ({ query, order, attributes, include, page, perPage, }: {
3
2
  query?: {};
4
3
  order?: any[];
5
4
  attributes?: any[];
6
5
  include?: any[];
7
6
  page?: number;
8
7
  perPage?: number;
9
- enrichments?: any[];
10
- }, model?: any, options?: MiddlewareValidationOption) => boolean;
8
+ }, model?: any) => boolean;
@@ -11,8 +11,7 @@ const validateOperator = (operator) => operators_1.OPERATORS.includes(operator.s
11
11
  const validateQueryAttribute = (attribute, modelAttributes = [], associationModels = []) => [...modelAttributes, ...associationModels]
12
12
  .includes(attribute.includes(utils_1.ASSOCIATION_PREFIX)
13
13
  ? attribute.split(utils_1.ASSOCIATION_PREFIX)[0] : attribute);
14
- const validateSingleOrder = (currentOrder, rawAttributes, associationModels, options = {}) => {
15
- var _a, _b;
14
+ const validateSingleOrder = (currentOrder, rawAttributes, associationModels) => {
16
15
  const isOrderDescOrder = utils_1.isOrderDesc(currentOrder);
17
16
  if (isOrderDescOrder && currentOrder[0] !== utils_1.ORDER_PREFIX) {
18
17
  utils_1.throwBadRequestError(`${utils_1.ORDER_PREFIX} must be only at the beginning of the word`);
@@ -21,12 +20,11 @@ const validateSingleOrder = (currentOrder, rawAttributes, associationModels, opt
21
20
  currentOrder.split(utils_1.ORDER_PREFIX)[1] : currentOrder;
22
21
  const isOrderAssociation = utils_1.isAttributeByAssociation(orderStringWithoutDesc, associationModels);
23
22
  let formattedOrderString = utils_1.extractAttributeNameFromOrder(currentOrder, associationModels);
24
- const isLiteralAttribute = (_b = (_a = options === null || options === void 0 ? void 0 : options.literalAttributes) === null || _a === void 0 ? void 0 : _a.map(la => la.attribute)) === null || _b === void 0 ? void 0 : _b.includes(orderStringWithoutDesc);
25
23
  if (!isOrderAssociation && formattedOrderString.includes(utils_1.ASSOCIATION_PREFIX)) {
26
24
  [formattedOrderString] = formattedOrderString.split(utils_1.ASSOCIATION_PREFIX);
27
25
  }
28
- if (!(rawAttributes.includes(formattedOrderString) || isOrderAssociation || isLiteralAttribute)) {
29
- utils_1.throwBadRequestError(`${currentOrder} is invalid. isLiteralAttribute: ${isLiteralAttribute}`);
26
+ if (!(rawAttributes.includes(formattedOrderString) || isOrderAssociation)) {
27
+ utils_1.throwBadRequestError(`${currentOrder} is invalid`);
30
28
  }
31
29
  };
32
30
  const validateSingleAttribute = (currentAttribute, rawAttributes) => {
@@ -34,27 +32,17 @@ const validateSingleAttribute = (currentAttribute, rawAttributes) => {
34
32
  utils_1.throwBadRequestError(`${currentAttribute} is invalid`);
35
33
  }
36
34
  };
37
- const validateOrderAttributes = (order, rawAttributes, associationModels = [], options = {}) => {
38
- order.map(o => validateSingleOrder(o, rawAttributes, associationModels, options));
35
+ const validateOrderAttributes = (order, rawAttributes, associationModels = []) => {
36
+ order.map(o => validateSingleOrder(o, rawAttributes, associationModels));
39
37
  };
40
38
  const validateAttributes = (attributes, rawAttributes) => {
41
39
  attributes.map(a => validateSingleAttribute(a, rawAttributes));
42
40
  };
43
- const validateEnrichments = (enrichments, options) => {
44
- if (!(enrichments === null || enrichments === void 0 ? void 0 : enrichments.length)) {
45
- return;
46
- }
47
- const invalidEnrichment = enrichments
48
- .find(enrichment => { var _a; return !((_a = options === null || options === void 0 ? void 0 : options.enrichmentAttributes) === null || _a === void 0 ? void 0 : _a.includes(enrichment)); });
49
- if (invalidEnrichment) {
50
- utils_1.throwBadRequestError(`enrichment attribute ${invalidEnrichment} is invalid`);
51
- }
52
- };
53
41
  const validateQueryPayload = (query, rawAttributes, associationModels = []) => {
54
42
  // eslint-disable-next-line array-callback-return
55
43
  Object.keys(query).map((key) => {
56
44
  const value = query[key];
57
- if (Array.isArray(value)) {
45
+ if (lodash_1.default.isArray(value)) {
58
46
  if (lodash_1.default.isObject(value[0])) {
59
47
  value.map(v => validateQueryPayload(v, rawAttributes, associationModels));
60
48
  }
@@ -88,22 +76,21 @@ const validateIncludePayload = (include, associations) => {
88
76
  utils_1.throwBadRequestError('model not found in associations');
89
77
  }
90
78
  const { rawAttributes } = target;
91
- const attributeKeys = Object.keys(rawAttributes);
92
- if (i.where) {
93
- validateQueryPayload(i.where, attributeKeys);
79
+ if (include.where) {
80
+ validateQueryPayload(i.where, rawAttributes);
94
81
  }
95
- if (i.order) {
96
- validateOrderAttributes(i.order, attributeKeys);
82
+ if (include.order) {
83
+ validateOrderAttributes(i.order, rawAttributes);
97
84
  }
98
- if (i.attributes) {
99
- validateAttributes(i.attributes, attributeKeys);
85
+ if (include.attributes) {
86
+ validateAttributes(i.attributes, rawAttributes);
100
87
  }
101
- if (!lodash_1.default.isNil(i.required) && !lodash_1.default.isBoolean(i.required)) {
88
+ if (!lodash_1.default.isNil(include.required) && !lodash_1.default.isBoolean(include.required)) {
102
89
  utils_1.throwBadRequestError('include.required must be a boolean');
103
90
  }
104
91
  });
105
92
  };
106
- exports.validatePayload = ({ query = {}, order = [], attributes = [], include = [], page = utils_1.PAGE_DEFAULT, perPage = utils_1.PER_PAGE_DEFAULT, enrichments = [], }, model, options = {}) => {
93
+ exports.validatePayload = ({ query = {}, order = [], attributes = [], include = [], page = utils_1.PAGE_DEFAULT, perPage = utils_1.PER_PAGE_DEFAULT, }, model) => {
107
94
  const rawAttributes = Object.keys(model.rawAttributes);
108
95
  const associationModels = Object.keys((model === null || model === void 0 ? void 0 : model.associations) || {});
109
96
  if (!attributes || attributes.length === 0) {
@@ -113,9 +100,8 @@ exports.validatePayload = ({ query = {}, order = [], attributes = [], include =
113
100
  else {
114
101
  validateAttributes(attributes, rawAttributes);
115
102
  }
116
- validateOrderAttributes(order, rawAttributes, associationModels, options);
103
+ validateOrderAttributes(order, rawAttributes, associationModels);
117
104
  validateQueryPayload(query, rawAttributes, associationModels);
118
- validateEnrichments(enrichments, options);
119
105
  if (include.length && typeof include === 'object') {
120
106
  validateIncludePayload(include, model === null || model === void 0 ? void 0 : model.associations);
121
107
  }
@@ -180,40 +180,5 @@ describe('validations test', () => {
180
180
  expect(error.statusCode).toBe(400);
181
181
  }
182
182
  });
183
- it('try order by literal field that exist', () => {
184
- const literalAttribute = { attribute: 'genericField', literal: 'void' };
185
- const payload = _1.validatePayload({ order: [literalAttribute.attribute] }, {
186
- rawAttributes: {
187
- startTime: '', endTime: '', currencySymbol: '', currencyCode: '', startStationId: '', status: '',
188
- },
189
- }, {
190
- literalAttributes: [literalAttribute],
191
- });
192
- expect(payload).toBe(true);
193
- });
194
- it('try order by literal field that exist - desc', () => {
195
- const literalAttribute = { attribute: 'genericField', literal: 'void' };
196
- const payload = _1.validatePayload({ order: [`-${literalAttribute.attribute}`] }, {
197
- rawAttributes: {
198
- startTime: '', endTime: '', currencySymbol: '', currencyCode: '', startStationId: '', status: '',
199
- },
200
- }, {
201
- literalAttributes: [literalAttribute],
202
- });
203
- expect(payload).toBe(true);
204
- });
205
- it('try order by literal field that doesnt exist', () => {
206
- const literalAttribute = { attribute: 'genericField', literal: 'void' };
207
- try {
208
- _1.validatePayload({ order: ['here'] }, {
209
- rawAttributes: {
210
- startTime: '', endTime: '', currencySymbol: '', currencyCode: '', startStationId: '', status: '',
211
- },
212
- }, { literalAttributes: [literalAttribute] });
213
- }
214
- catch (error) {
215
- expect(error.statusCode).toBe(400);
216
- }
217
- });
218
183
  });
219
184
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/sheilta",
3
- "version": "1.0.0-test-3",
3
+ "version": "1.0.1-aaron-test",
4
4
  "description": "manage cache",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -10,24 +10,7 @@
10
10
  "coverage": "jest --coverage --forceExit --runInBand",
11
11
  "test": "jest --forceExit --runInBand",
12
12
  "test-auto": "jest --watch --runInBand",
13
- "linter": "./node_modules/.bin/eslint src/**/*.ts",
14
- "build-to-local-repo": "npm run build && cp -r lib/* ../$REPO/node_modules/$npm_package_name/lib",
15
- "watch": "npm-watch build-to-local-repo"
16
- },
17
- "watch": {
18
- "build-to-local-repo": {
19
- "extensions": [
20
- "js",
21
- "jsx",
22
- "ts",
23
- "tsx",
24
- "css"
25
- ],
26
- "patterns": [
27
- "src"
28
- ],
29
- "quiet": false
30
- }
13
+ "linter": "./node_modules/.bin/eslint src/**/*.ts"
31
14
  },
32
15
  "jest": {
33
16
  "setupTestFrameworkScriptFile": "jest-extended",
@@ -44,14 +27,13 @@
44
27
  },
45
28
  "homepage": "https://github.com/Autofleet/sheilta",
46
29
  "dependencies": {
47
- "@autofleet/common-types": "^1.7.42",
48
30
  "@autofleet/errors": "^1.0.10",
31
+ "@types/node": "^14.14.20",
49
32
  "joi": "^17.9.2",
50
33
  "lodash": "^4.17.21"
51
34
  },
52
35
  "devDependencies": {
53
36
  "@types/jest": "^24.9.0",
54
- "@types/node": "^16.11.68",
55
37
  "@typescript-eslint/eslint-plugin": "^2.34.0",
56
38
  "@typescript-eslint/parser": "^2.23.0",
57
39
  "eslint": "^6.8.0",
@@ -60,8 +42,7 @@
60
42
  "jest": "^25.1.0",
61
43
  "ts-jest": "^25.0.0",
62
44
  "typescript": "^3.9.5",
63
- "typescript-eslint": "0.0.1-alpha.0",
64
- "npm-watch": "^0.13.0"
45
+ "typescript-eslint": "0.0.1-alpha.0"
65
46
  },
66
47
  "files": [
67
48
  "lib/**/*"