@autofleet/sadot 0.7.0-beta.2.2 → 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 +6 -11
- package/package.json +2 -2
- package/src/scopes/filter.ts +45 -27
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,25 +52,23 @@ 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
|
-
if (typeof condition === 'string') {
|
|
62
|
-
const conditionRep = Object.keys(replacements).find((
|
|
59
|
+
if (typeof condition === 'string' || typeof condition === 'number') {
|
|
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;
|
|
70
68
|
})
|
|
71
69
|
.filter(Boolean);
|
|
72
70
|
if (conditionsStrings.length === 0) {
|
|
73
|
-
return {
|
|
74
|
-
replacements,
|
|
75
|
-
};
|
|
71
|
+
return {};
|
|
76
72
|
}
|
|
77
73
|
const customFieldConditions = conditionsStrings.join(AND_DELIMETER);
|
|
78
74
|
const subQuery = `${'SELECT model_id FROM ('
|
|
@@ -100,7 +96,6 @@ const customFieldsSortScope = (name) => ({ replacementsMap, scopeValue: sort })
|
|
|
100
96
|
const randomStr = (0, helpers_1.generateRandomString)();
|
|
101
97
|
const includes = Object.entries(sort).map(([key]) => {
|
|
102
98
|
const replacemetKey = Object.keys(replacementsMap).find((randomString) => replacementsMap[randomString] === key);
|
|
103
|
-
console.log('sort replacemetKey:', replacemetKey);
|
|
104
99
|
return ([
|
|
105
100
|
sequelize_typescript_1.Sequelize.literal(`(
|
|
106
101
|
SELECT value
|
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": {
|
|
@@ -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
|
-
if (typeof condition === 'string') {
|
|
82
|
-
const conditionRep = Object.keys(replacements).find(
|
|
96
|
+
if (typeof condition === 'string' || typeof condition === 'number') {
|
|
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;
|
|
@@ -91,18 +110,16 @@ export const customFieldsFilterScope = (
|
|
|
91
110
|
)
|
|
92
111
|
.filter(Boolean);
|
|
93
112
|
if (conditionsStrings.length === 0) {
|
|
94
|
-
return {
|
|
95
|
-
replacements,
|
|
96
|
-
};
|
|
113
|
+
return {};
|
|
97
114
|
}
|
|
98
115
|
const customFieldConditions = conditionsStrings.join(AND_DELIMETER);
|
|
99
116
|
const subQuery = `${'SELECT model_id FROM ('
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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}`;
|
|
106
123
|
return {
|
|
107
124
|
where: {
|
|
108
125
|
id: {
|
|
@@ -123,8 +140,9 @@ export const customFieldsSortScope = (
|
|
|
123
140
|
}
|
|
124
141
|
const randomStr = generateRandomString();
|
|
125
142
|
const includes = Object.entries(sort).map(([key]) => {
|
|
126
|
-
const replacemetKey = Object.keys(replacementsMap).find(
|
|
127
|
-
|
|
143
|
+
const replacemetKey = Object.keys(replacementsMap).find(
|
|
144
|
+
(randomString) => replacementsMap[randomString] === key,
|
|
145
|
+
);
|
|
128
146
|
return ([
|
|
129
147
|
Sequelize.literal(`(
|
|
130
148
|
SELECT value
|