@autofleet/sadot 0.7.0-beta.2.3 → 0.7.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.
- package/dist/scopes/filter.d.ts +5 -4
- package/dist/scopes/filter.js +4 -6
- package/package.json +3 -3
- package/src/scopes/filter.ts +43 -22
package/dist/scopes/filter.d.ts
CHANGED
|
@@ -17,6 +17,10 @@ export type CustomFieldFilterOptions = {
|
|
|
17
17
|
where?: WhereOptions;
|
|
18
18
|
replacements?: Record<string, string>;
|
|
19
19
|
};
|
|
20
|
+
type customFieldsFilterScopeParams = {
|
|
21
|
+
replacementsMap: Record<string, string>;
|
|
22
|
+
scopeValue: Record<string, ConditionValue>;
|
|
23
|
+
};
|
|
20
24
|
/**
|
|
21
25
|
* A Sequelize scope for filtering models by custom fields.
|
|
22
26
|
* This scope builds a WHERE clause to be applied on the main query.
|
|
@@ -24,10 +28,7 @@ export type CustomFieldFilterOptions = {
|
|
|
24
28
|
* @param name - The model type name used to join custom_field_definitions.
|
|
25
29
|
* @returns A function that takes conditions and returns the Sequelize options object.
|
|
26
30
|
*/
|
|
27
|
-
export declare const customFieldsFilterScope: (name: string) => ({ replacementsMap, scopeValue }:
|
|
28
|
-
replacementsMap: any;
|
|
29
|
-
scopeValue: any;
|
|
30
|
-
}) => CustomFieldFilterOptions;
|
|
31
|
+
export declare const customFieldsFilterScope: (name: string) => ({ replacementsMap: replacements, scopeValue: conditions, }: customFieldsFilterScopeParams) => CustomFieldFilterOptions;
|
|
31
32
|
export declare const scopeName = "filterByCustomFields";
|
|
32
33
|
export declare const customFieldsSortScope: (name: string) => ({ replacementsMap, scopeValue: sort }: {
|
|
33
34
|
replacementsMap: any;
|
package/dist/scopes/filter.js
CHANGED
|
@@ -28,9 +28,7 @@ const AND_DELIMETER = ' AND ';
|
|
|
28
28
|
* @param name - The model type name used to join custom_field_definitions.
|
|
29
29
|
* @returns A function that takes conditions and returns the Sequelize options object.
|
|
30
30
|
*/
|
|
31
|
-
const customFieldsFilterScope = (name) => ({ replacementsMap, scopeValue }) => {
|
|
32
|
-
const conditions = scopeValue;
|
|
33
|
-
const replacements = replacementsMap;
|
|
31
|
+
const customFieldsFilterScope = (name) => ({ replacementsMap: replacements, scopeValue: conditions, }) => {
|
|
34
32
|
if (!conditions || Object.keys(conditions).length === 0) {
|
|
35
33
|
return {};
|
|
36
34
|
}
|
|
@@ -54,16 +52,16 @@ const customFieldsFilterScope = (name) => ({ replacementsMap, scopeValue }) => {
|
|
|
54
52
|
}
|
|
55
53
|
return condition
|
|
56
54
|
.map((c) => {
|
|
57
|
-
const valRep = Object.keys(replacements).find((
|
|
55
|
+
const valRep = Object.keys(replacements).find((replacementKey) => replacements[replacementKey] === c.value);
|
|
58
56
|
return `(custom_fields->> :${replacemetKey} )${castIfNeeded(c.value)} ${c.operator} :${valRep}`;
|
|
59
57
|
}).join(AND_DELIMETER);
|
|
60
58
|
}
|
|
61
59
|
if (typeof condition === 'string' || typeof condition === 'number') {
|
|
62
|
-
const conditionRep = Object.keys(replacements).find((
|
|
60
|
+
const conditionRep = Object.keys(replacements).find((replacementKey) => replacements[replacementKey] === condition);
|
|
63
61
|
return `(custom_fields->> :${replacemetKey} ) ${castIfNeeded(condition)} = :${conditionRep}`;
|
|
64
62
|
}
|
|
65
63
|
if (condition?.operator) {
|
|
66
|
-
const valueRep = Object.keys(replacements).find((
|
|
64
|
+
const valueRep = Object.keys(replacements).find((replacementKey) => replacements[replacementKey] === condition.value);
|
|
67
65
|
return `(custom_fields->> :${replacemetKey} ) ${castIfNeeded(condition.value)} ${condition.operator} :${valueRep}`;
|
|
68
66
|
}
|
|
69
67
|
return false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/sadot",
|
|
3
|
-
"version": "0.7.0
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"linter": "./node_modules/.bin/eslint .",
|
|
10
10
|
"test": "jest --forceExit --runInBand",
|
|
11
11
|
"coverage": "jest --coverage --forceExit --runInBand && rm -rf ./coverage",
|
|
12
|
-
"build-to-local-repo": "npm run build && cp -r dist/*
|
|
12
|
+
"build-to-local-repo": "npm run build && cp -r dist/* ../$REPO/node_modules/$npm_package_name/dist",
|
|
13
13
|
"dev": "nodemon",
|
|
14
14
|
"watch": "npm-watch build-to-local-repo",
|
|
15
15
|
"publish-dev": "npm run build && npm publish --tag dev"
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"typescript-eslint": "^0.0.1-alpha.0"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
|
-
"@autofleet/sheilta": ">=1.4.0
|
|
63
|
+
"@autofleet/sheilta": ">=1.4.0"
|
|
64
64
|
},
|
|
65
65
|
"engines": {
|
|
66
66
|
"node": ">=16.0.0"
|
package/src/scopes/filter.ts
CHANGED
|
@@ -13,25 +13,31 @@ const { CUSTOM_FIELDS_FILTER_SCOPE } = customFields;
|
|
|
13
13
|
* More types to be added (TBA).
|
|
14
14
|
*/
|
|
15
15
|
type ConditionWithOperator = {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
operator: string;
|
|
17
|
+
value: string;
|
|
18
18
|
};
|
|
19
19
|
export type ConditionValue = ConditionWithOperator | ConditionWithOperator[] | string | string[];
|
|
20
20
|
|
|
21
21
|
export type CustomFieldSort = {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
field: string;
|
|
23
|
+
direction: 'ASC' | 'DESC';
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export type CustomFieldFilterOptions = {
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
where?: WhereOptions;
|
|
28
|
+
replacements?: Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type customFieldsFilterScopeParams = {
|
|
32
|
+
replacementsMap: Record<string, string>;
|
|
33
|
+
scopeValue: Record<string, ConditionValue>;
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
const castIfNeeded = (conditionValue: string): string => {
|
|
32
37
|
if (moment.isDate(conditionValue)) {
|
|
33
38
|
return '::timestamp';
|
|
34
|
-
}
|
|
39
|
+
}
|
|
40
|
+
if (!Number.isNaN(Number(conditionValue))) {
|
|
35
41
|
return '::numeric';
|
|
36
42
|
}
|
|
37
43
|
return '';
|
|
@@ -47,9 +53,12 @@ const AND_DELIMETER = ' AND ';
|
|
|
47
53
|
*/
|
|
48
54
|
export const customFieldsFilterScope = (
|
|
49
55
|
name: string,
|
|
50
|
-
) => (
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
) => (
|
|
57
|
+
{
|
|
58
|
+
replacementsMap: replacements,
|
|
59
|
+
scopeValue: conditions,
|
|
60
|
+
}: customFieldsFilterScopeParams,
|
|
61
|
+
): CustomFieldFilterOptions => {
|
|
53
62
|
if (!conditions || Object.keys(conditions).length === 0) {
|
|
54
63
|
return {};
|
|
55
64
|
}
|
|
@@ -57,7 +66,9 @@ export const customFieldsFilterScope = (
|
|
|
57
66
|
const conditionsStrings = Object.entries(conditions)
|
|
58
67
|
.map(
|
|
59
68
|
([key, condition]) => {
|
|
60
|
-
const replacemetKey = Object.keys(replacements).find(
|
|
69
|
+
const replacemetKey = Object.keys(replacements).find(
|
|
70
|
+
(randomString) => replacements[randomString] === key,
|
|
71
|
+
);
|
|
61
72
|
if (!replacemetKey) return false;
|
|
62
73
|
|
|
63
74
|
if (Array.isArray(condition)) {
|
|
@@ -67,23 +78,31 @@ export const customFieldsFilterScope = (
|
|
|
67
78
|
}
|
|
68
79
|
if (typeof condition[0] === 'string') {
|
|
69
80
|
const values = condition.map((v) => {
|
|
70
|
-
const valRandom = Object.keys(replacements).find(
|
|
81
|
+
const valRandom = Object.keys(replacements).find(
|
|
82
|
+
(randomString) => replacements[randomString] === v,
|
|
83
|
+
);
|
|
71
84
|
return ` :${valRandom} `;
|
|
72
85
|
}).join(',');
|
|
73
86
|
return `(custom_fields->> :${replacemetKey} ) IN ( ${values} )`;
|
|
74
87
|
}
|
|
75
88
|
return condition
|
|
76
89
|
.map((c) => {
|
|
77
|
-
const valRep = Object.keys(replacements).find(
|
|
90
|
+
const valRep = Object.keys(replacements).find(
|
|
91
|
+
(replacementKey) => replacements[replacementKey] === c.value,
|
|
92
|
+
);
|
|
78
93
|
return `(custom_fields->> :${replacemetKey} )${castIfNeeded(c.value)} ${c.operator} :${valRep}`;
|
|
79
94
|
}).join(AND_DELIMETER);
|
|
80
95
|
}
|
|
81
96
|
if (typeof condition === 'string' || typeof condition === 'number') {
|
|
82
|
-
const conditionRep = Object.keys(replacements).find(
|
|
97
|
+
const conditionRep = Object.keys(replacements).find(
|
|
98
|
+
(replacementKey) => replacements[replacementKey] === condition,
|
|
99
|
+
);
|
|
83
100
|
return `(custom_fields->> :${replacemetKey} ) ${castIfNeeded(condition)} = :${conditionRep}`;
|
|
84
101
|
}
|
|
85
102
|
if (condition?.operator) {
|
|
86
|
-
const valueRep = Object.keys(replacements).find(
|
|
103
|
+
const valueRep = Object.keys(replacements).find(
|
|
104
|
+
(replacementKey) => replacements[replacementKey] === condition.value,
|
|
105
|
+
);
|
|
87
106
|
return `(custom_fields->> :${replacemetKey} ) ${castIfNeeded(condition.value)} ${condition.operator} :${valueRep}`;
|
|
88
107
|
}
|
|
89
108
|
return false;
|
|
@@ -95,12 +114,12 @@ export const customFieldsFilterScope = (
|
|
|
95
114
|
}
|
|
96
115
|
const customFieldConditions = conditionsStrings.join(AND_DELIMETER);
|
|
97
116
|
const subQuery = `${'SELECT model_id FROM ('
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
117
|
+
+ 'SELECT cv.model_id, jsonb_object_agg(cd.name, cv.value) AS custom_fields '
|
|
118
|
+
+ 'FROM custom_field_values AS cv '
|
|
119
|
+
+ 'INNER JOIN custom_field_definitions AS cd ON cv.custom_field_definition_id = cd.id '
|
|
120
|
+
+ `AND cd.model_type = '${name}'`
|
|
121
|
+
+ 'GROUP BY cv.model_id'
|
|
122
|
+
+ ') AS CustomFieldAggregation WHERE '} ${customFieldConditions}`;
|
|
104
123
|
return {
|
|
105
124
|
where: {
|
|
106
125
|
id: {
|
|
@@ -121,7 +140,9 @@ export const customFieldsSortScope = (
|
|
|
121
140
|
}
|
|
122
141
|
const randomStr = generateRandomString();
|
|
123
142
|
const includes = Object.entries(sort).map(([key]) => {
|
|
124
|
-
const replacemetKey = Object.keys(replacementsMap).find(
|
|
143
|
+
const replacemetKey = Object.keys(replacementsMap).find(
|
|
144
|
+
(randomString) => replacementsMap[randomString] === key,
|
|
145
|
+
);
|
|
125
146
|
return ([
|
|
126
147
|
Sequelize.literal(`(
|
|
127
148
|
SELECT value
|