@autofleet/sadot 0.8.1-beta-e7a88a64.0 → 0.8.1
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 +1 -1
- package/dist/scopes/filter.js +48 -38
- package/dist/tests/helpers/index.d.ts +4 -0
- package/dist/tests/helpers/index.js +7 -1
- package/package.json +2 -3
- package/src/scopes/filter.ts +59 -66
- package/src/tests/helpers/index.ts +6 -0
- package/tsconfig.build.json +7 -0
- package/tsconfig.json +1 -1
package/dist/scopes/filter.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ type customFieldsFilterScopeParams = {
|
|
|
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
|
-
export declare const customFieldsFilterScope: (name: string) => ({ replacementsMap: replacements, scopeValue: conditions
|
|
31
|
+
export declare const customFieldsFilterScope: (name: string) => ({ replacementsMap: replacements, scopeValue: conditions }: customFieldsFilterScopeParams) => CustomFieldFilterOptions;
|
|
32
32
|
export declare const scopeName = "filterByCustomFields";
|
|
33
33
|
export declare const customFieldsSortScope: (name: string) => ({ replacementsMap, scopeValue: sort }: {
|
|
34
34
|
replacementsMap: any;
|
package/dist/scopes/filter.js
CHANGED
|
@@ -7,23 +7,28 @@ const sequelize_typescript_1 = require("sequelize-typescript");
|
|
|
7
7
|
const common_types_1 = require("@autofleet/common-types");
|
|
8
8
|
const helpers_1 = require("../utils/helpers");
|
|
9
9
|
const { CUSTOM_FIELDS_FILTER_SCOPE } = common_types_1.customFields;
|
|
10
|
+
const isConditionStringArray = (input) => Array.isArray(input) && typeof input[0] === 'string';
|
|
11
|
+
const isBooleanString = (input) => ['true', 'false'].includes(input.toString());
|
|
10
12
|
const isDate = (input) => input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
|
|
11
|
-
const
|
|
13
|
+
const castValueToJsonb = (value, type) => `to_jsonb(${value}::${type})`;
|
|
14
|
+
const castValueToJsonbText = (value) => castValueToJsonb(value, 'text');
|
|
15
|
+
const castValueToJsonbBoolean = (value) => castValueToJsonb(value, 'boolean');
|
|
16
|
+
const castValueToJsonbNumeric = (value) => castValueToJsonb(value, 'numeric');
|
|
17
|
+
const castIfNeeded = (columnName, conditionValue) => {
|
|
12
18
|
if (isDate(conditionValue)) {
|
|
13
|
-
return '
|
|
19
|
+
return castValueToJsonb(columnName, 'timestamp');
|
|
14
20
|
}
|
|
15
21
|
if (!Number.isNaN(Number(conditionValue))) {
|
|
16
|
-
return
|
|
22
|
+
return castValueToJsonbNumeric(columnName);
|
|
17
23
|
}
|
|
18
|
-
return
|
|
24
|
+
return columnName;
|
|
19
25
|
};
|
|
20
|
-
const
|
|
21
|
-
const
|
|
26
|
+
const AND_DELIMITER = ' AND ';
|
|
27
|
+
const OR_DELIMITER = ' OR ';
|
|
22
28
|
const CD_TABLE_ALIAS = 'cd';
|
|
23
29
|
const CD_NAME_COLUMN = `${CD_TABLE_ALIAS}.name`;
|
|
24
30
|
const CV_TABLE_ALIAS = 'cv';
|
|
25
|
-
const CV_VALUE_COLUMN =
|
|
26
|
-
const castValueToJsonb = (value) => `to_jsonb(${value}::text)`;
|
|
31
|
+
const CV_VALUE_COLUMN = `${CV_TABLE_ALIAS}.value`;
|
|
27
32
|
/**
|
|
28
33
|
* A Sequelize scope for filtering models by custom fields.
|
|
29
34
|
* This scope builds a WHERE clause to be applied on the main query.
|
|
@@ -31,60 +36,65 @@ const castValueToJsonb = (value) => `to_jsonb(${value}::text)`;
|
|
|
31
36
|
* @param name - The model type name used to join custom_field_definitions.
|
|
32
37
|
* @returns A function that takes conditions and returns the Sequelize options object.
|
|
33
38
|
*/
|
|
34
|
-
const customFieldsFilterScope = (name) => ({ replacementsMap: replacements, scopeValue: conditions
|
|
39
|
+
const customFieldsFilterScope = (name) => ({ replacementsMap: replacements, scopeValue: conditions }) => {
|
|
35
40
|
if (!conditions || Object.keys(conditions).length === 0) {
|
|
36
41
|
return {};
|
|
37
42
|
}
|
|
43
|
+
const reverseReplacementsMap = new Map(Object.entries(replacements).map(([key, value]) => [value, key]));
|
|
38
44
|
// Build the WHERE clause for custom field filtering
|
|
39
|
-
const conditionsStrings = Object.entries(conditions)
|
|
40
|
-
.
|
|
41
|
-
|
|
42
|
-
const columnCondition = `(${CD_NAME_COLUMN} = :${replacemetKey})`;
|
|
43
|
-
if (!replacemetKey)
|
|
45
|
+
const conditionsStrings = Object.entries(conditions).map(([key, condition]) => {
|
|
46
|
+
const replacementKey = reverseReplacementsMap.get(key);
|
|
47
|
+
if (!replacementKey)
|
|
44
48
|
return false;
|
|
49
|
+
const columnCondition = `(${CD_NAME_COLUMN} = :${replacementKey})`;
|
|
45
50
|
if (Array.isArray(condition)) {
|
|
46
51
|
if (condition.length === 0) {
|
|
47
52
|
// if empty array, the condition is ignored
|
|
48
53
|
return false;
|
|
49
54
|
}
|
|
50
|
-
if (
|
|
51
|
-
const values = condition.
|
|
52
|
-
const valRandom =
|
|
53
|
-
|
|
55
|
+
if (isConditionStringArray(condition)) {
|
|
56
|
+
const values = condition.flatMap((v) => {
|
|
57
|
+
const valRandom = reverseReplacementsMap.get(v);
|
|
58
|
+
if (isBooleanString(v)) {
|
|
59
|
+
return [castValueToJsonbText(`:${valRandom}`), castValueToJsonbBoolean(`:${valRandom}`)];
|
|
60
|
+
}
|
|
61
|
+
if (!Number.isNaN(Number(v))) {
|
|
62
|
+
return castValueToJsonbNumeric(`:${valRandom}`);
|
|
63
|
+
}
|
|
64
|
+
return castValueToJsonbText(`:${valRandom}`);
|
|
54
65
|
}).join(',');
|
|
55
|
-
return `(${columnCondition}
|
|
66
|
+
return `(${columnCondition}${AND_DELIMITER}${CV_VALUE_COLUMN} IN (${values}))`;
|
|
56
67
|
}
|
|
57
|
-
return condition
|
|
58
|
-
.
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}).join(AND_DELIMETER);
|
|
68
|
+
return condition.map((c) => {
|
|
69
|
+
const valRep = reverseReplacementsMap.get(c.value);
|
|
70
|
+
const valueAsJsonb = castValueToJsonbText(`:${valRep}`);
|
|
71
|
+
return `(${columnCondition}${AND_DELIMITER}${castIfNeeded(CV_VALUE_COLUMN, c.value)} ${c.operator} ${valueAsJsonb})`;
|
|
72
|
+
}).join(AND_DELIMITER);
|
|
63
73
|
}
|
|
64
74
|
if (typeof condition === 'string' || typeof condition === 'number') {
|
|
65
|
-
const conditionRep =
|
|
66
|
-
const valueAsJsonb =
|
|
67
|
-
|
|
75
|
+
const conditionRep = reverseReplacementsMap.get(condition);
|
|
76
|
+
const valueAsJsonb = !Number.isNaN(Number(condition)) ? castValueToJsonbNumeric(`:${conditionRep}`) : castValueToJsonbText(`:${conditionRep}`);
|
|
77
|
+
const valueAsJsonbBoolean = isBooleanString(condition) ? `${OR_DELIMITER}${CV_VALUE_COLUMN} = ${castValueToJsonbBoolean(`:${conditionRep}`)}` : '';
|
|
78
|
+
return `(${columnCondition}${AND_DELIMITER}(${castIfNeeded(CV_VALUE_COLUMN, condition)} = ${valueAsJsonb}${valueAsJsonbBoolean}))`;
|
|
68
79
|
}
|
|
69
80
|
if (condition?.operator) {
|
|
70
|
-
const valueRep =
|
|
71
|
-
const valueAsJsonb =
|
|
72
|
-
return `( ${columnCondition}
|
|
81
|
+
const valueRep = reverseReplacementsMap.get(condition.value);
|
|
82
|
+
const valueAsJsonb = castValueToJsonbText(`:${valueRep}`);
|
|
83
|
+
return `( ${columnCondition}${AND_DELIMITER}${castIfNeeded(CV_VALUE_COLUMN, condition.value)} ${condition.operator} ${valueAsJsonb})`;
|
|
73
84
|
}
|
|
74
85
|
return false;
|
|
75
|
-
})
|
|
76
|
-
.filter(Boolean);
|
|
86
|
+
}).filter(Boolean);
|
|
77
87
|
if (conditionsStrings.length === 0) {
|
|
78
88
|
return {};
|
|
79
89
|
}
|
|
80
|
-
const customFieldConditions = conditionsStrings.join(
|
|
90
|
+
const customFieldConditions = conditionsStrings.join(OR_DELIMITER);
|
|
81
91
|
const subQuery = `
|
|
82
92
|
SELECT cv.model_id
|
|
83
93
|
FROM custom_field_values AS cv
|
|
84
94
|
INNER JOIN custom_field_definitions AS cd ON cv.custom_field_definition_id = cd.id
|
|
85
|
-
|
|
95
|
+
${AND_DELIMITER}cd.model_type = '${name}'
|
|
86
96
|
WHERE ${customFieldConditions}
|
|
87
|
-
|
|
97
|
+
${AND_DELIMITER}cv.deleted_at IS NULL${AND_DELIMITER}cd.deleted_at IS NULL
|
|
88
98
|
GROUP BY cv.model_id
|
|
89
99
|
HAVING COUNT(DISTINCT cv.custom_field_definition_id) = ${conditionsStrings.length}
|
|
90
100
|
`.replace(/\n/g, '');
|
|
@@ -112,9 +122,9 @@ const customFieldsSortScope = (name) => ({ replacementsMap, scopeValue: sort })
|
|
|
112
122
|
FROM (SELECT cv.model_id, cv.value
|
|
113
123
|
FROM custom_field_values AS cv INNER JOIN custom_field_definitions AS cd
|
|
114
124
|
ON cv.custom_field_definition_id = cd.id
|
|
115
|
-
|
|
125
|
+
${AND_DELIMITER}cd.model_type = '${name}'
|
|
116
126
|
WHERE cv.model_id = "${name}"."id"
|
|
117
|
-
|
|
127
|
+
${AND_DELIMITER}cd.name = :${replacemetKey}
|
|
118
128
|
) AS CustomFieldAggregation
|
|
119
129
|
)
|
|
120
130
|
`), randomStr,
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
export declare const cleanup: () => Promise<void>;
|
|
2
2
|
export declare const getModel: (name: string) => any;
|
|
3
|
+
export declare const getReplacementMapWithScopeValue: (conditions: Record<string, any>) => {
|
|
4
|
+
replacementsMap: Record<string, string>;
|
|
5
|
+
scopeValue: Record<string, any>;
|
|
6
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getModel = exports.cleanup = void 0;
|
|
3
|
+
exports.getReplacementMapWithScopeValue = exports.getModel = exports.cleanup = void 0;
|
|
4
|
+
const formatter_1 = require("@autofleet/sheilta/lib/formatter");
|
|
4
5
|
const models_1 = require("../../models");
|
|
5
6
|
// eslint-disable-next-line import/prefer-default-export
|
|
6
7
|
const cleanup = async () => {
|
|
@@ -18,3 +19,8 @@ const getModel = (name) => {
|
|
|
18
19
|
return models[name];
|
|
19
20
|
};
|
|
20
21
|
exports.getModel = getModel;
|
|
22
|
+
const getReplacementMapWithScopeValue = (conditions) => ({
|
|
23
|
+
replacementsMap: (0, formatter_1.generateFilterReplacements)(Object.fromEntries(Object.entries(conditions).map(([key, value]) => [`customFields.${key}`, value]))),
|
|
24
|
+
scopeValue: conditions,
|
|
25
|
+
});
|
|
26
|
+
exports.getReplacementMapWithScopeValue = getReplacementMapWithScopeValue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/sadot",
|
|
3
|
-
"version": "0.8.1
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -50,8 +50,7 @@
|
|
|
50
50
|
"npm-watch": "^0.11.0",
|
|
51
51
|
"ts-jest": "^29.1.2",
|
|
52
52
|
"ts-node": "^8.6.2",
|
|
53
|
-
"typescript": "^5.3.3"
|
|
54
|
-
"typescript-eslint": "^0.0.1-alpha.0"
|
|
53
|
+
"typescript": "^5.3.3"
|
|
55
54
|
},
|
|
56
55
|
"peerDependencies": {
|
|
57
56
|
"@autofleet/sheilta": ">=1.4.0"
|
package/src/scopes/filter.ts
CHANGED
|
@@ -32,24 +32,29 @@ type customFieldsFilterScopeParams = {
|
|
|
32
32
|
scopeValue: Record<string, ConditionValue>;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
const isConditionStringArray = (input: any): input is string[] => Array.isArray(input) && typeof input[0] === 'string';
|
|
36
|
+
const isBooleanString = (input: string): boolean => ['true', 'false'].includes(input.toString());
|
|
35
37
|
const isDate = (input: any): input is Date => input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
|
|
36
38
|
|
|
37
|
-
const
|
|
39
|
+
const castValueToJsonb = (value: string, type: string) => `to_jsonb(${value}::${type})`;
|
|
40
|
+
const castValueToJsonbText = (value: string) => castValueToJsonb(value, 'text');
|
|
41
|
+
const castValueToJsonbBoolean = (value: string) => castValueToJsonb(value, 'boolean');
|
|
42
|
+
const castValueToJsonbNumeric = (value: string) => castValueToJsonb(value, 'numeric');
|
|
43
|
+
const castIfNeeded = (columnName: string, conditionValue: string): string => {
|
|
38
44
|
if (isDate(conditionValue)) {
|
|
39
|
-
return '
|
|
45
|
+
return castValueToJsonb(columnName, 'timestamp');
|
|
40
46
|
}
|
|
41
47
|
if (!Number.isNaN(Number(conditionValue))) {
|
|
42
|
-
return
|
|
48
|
+
return castValueToJsonbNumeric(columnName);
|
|
43
49
|
}
|
|
44
|
-
return
|
|
50
|
+
return columnName;
|
|
45
51
|
};
|
|
46
|
-
const
|
|
47
|
-
const
|
|
52
|
+
const AND_DELIMITER = ' AND ';
|
|
53
|
+
const OR_DELIMITER = ' OR ';
|
|
48
54
|
const CD_TABLE_ALIAS = 'cd';
|
|
49
55
|
const CD_NAME_COLUMN = `${CD_TABLE_ALIAS}.name`;
|
|
50
56
|
const CV_TABLE_ALIAS = 'cv';
|
|
51
|
-
const CV_VALUE_COLUMN =
|
|
52
|
-
const castValueToJsonb = (value) => `to_jsonb(${value}::text)`;
|
|
57
|
+
const CV_VALUE_COLUMN = `${CV_TABLE_ALIAS}.value`;
|
|
53
58
|
|
|
54
59
|
/**
|
|
55
60
|
* A Sequelize scope for filtering models by custom fields.
|
|
@@ -60,77 +65,65 @@ const castValueToJsonb = (value) => `to_jsonb(${value}::text)`;
|
|
|
60
65
|
*/
|
|
61
66
|
export const customFieldsFilterScope = (
|
|
62
67
|
name: string,
|
|
63
|
-
) => (
|
|
64
|
-
{
|
|
65
|
-
replacementsMap: replacements,
|
|
66
|
-
scopeValue: conditions,
|
|
67
|
-
}: customFieldsFilterScopeParams,
|
|
68
|
-
): CustomFieldFilterOptions => {
|
|
68
|
+
) => ({ replacementsMap: replacements, scopeValue: conditions }: customFieldsFilterScopeParams): CustomFieldFilterOptions => {
|
|
69
69
|
if (!conditions || Object.keys(conditions).length === 0) {
|
|
70
70
|
return {};
|
|
71
71
|
}
|
|
72
|
+
const reverseReplacementsMap = new Map(Object.entries(replacements).map(([key, value]) => [value, key]));
|
|
72
73
|
// Build the WHERE clause for custom field filtering
|
|
73
|
-
const conditionsStrings = Object.entries(conditions)
|
|
74
|
-
.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
(randomString) => replacements[randomString] === key,
|
|
78
|
-
);
|
|
79
|
-
const columnCondition = `(${CD_NAME_COLUMN} = :${replacemetKey})`;
|
|
80
|
-
if (!replacemetKey) return false;
|
|
74
|
+
const conditionsStrings = Object.entries(conditions).map(([key, condition]) => {
|
|
75
|
+
const replacementKey = reverseReplacementsMap.get(key);
|
|
76
|
+
if (!replacementKey) return false;
|
|
77
|
+
const columnCondition = `(${CD_NAME_COLUMN} = :${replacementKey})`;
|
|
81
78
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
if (Array.isArray(condition)) {
|
|
80
|
+
if (condition.length === 0) {
|
|
81
|
+
// if empty array, the condition is ignored
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
if (isConditionStringArray(condition)) {
|
|
85
|
+
const values = condition.flatMap((v) => {
|
|
86
|
+
const valRandom = reverseReplacementsMap.get(v);
|
|
87
|
+
if (isBooleanString(v)) {
|
|
88
|
+
return [castValueToJsonbText(`:${valRandom}`), castValueToJsonbBoolean(`:${valRandom}`)];
|
|
86
89
|
}
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
const valRandom = Object.keys(replacements).find(
|
|
90
|
-
(randomString) => replacements[randomString] === v,
|
|
91
|
-
);
|
|
92
|
-
return castValueToJsonb(`:${valRandom}`);
|
|
93
|
-
}).join(',');
|
|
94
|
-
return `(${columnCondition} AND ${CV_VALUE_COLUMN} IN (${values}))`;
|
|
90
|
+
if (!Number.isNaN(Number(v))) {
|
|
91
|
+
return castValueToJsonbNumeric(`:${valRandom}`);
|
|
95
92
|
}
|
|
96
|
-
return
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return false;
|
|
120
|
-
},
|
|
121
|
-
)
|
|
122
|
-
.filter(Boolean);
|
|
93
|
+
return castValueToJsonbText(`:${valRandom}`);
|
|
94
|
+
}).join(',');
|
|
95
|
+
return `(${columnCondition}${AND_DELIMITER}${CV_VALUE_COLUMN} IN (${values}))`;
|
|
96
|
+
}
|
|
97
|
+
return condition.map((c) => {
|
|
98
|
+
const valRep = reverseReplacementsMap.get(c.value);
|
|
99
|
+
const valueAsJsonb = castValueToJsonbText(`:${valRep}`);
|
|
100
|
+
return `(${columnCondition}${AND_DELIMITER}${castIfNeeded(CV_VALUE_COLUMN, c.value)} ${c.operator} ${valueAsJsonb})`;
|
|
101
|
+
}).join(AND_DELIMITER);
|
|
102
|
+
}
|
|
103
|
+
if (typeof condition === 'string' || typeof condition === 'number') {
|
|
104
|
+
const conditionRep = reverseReplacementsMap.get(condition);
|
|
105
|
+
const valueAsJsonb = !Number.isNaN(Number(condition)) ? castValueToJsonbNumeric(`:${conditionRep}`) : castValueToJsonbText(`:${conditionRep}`);
|
|
106
|
+
const valueAsJsonbBoolean = isBooleanString(condition) ? `${OR_DELIMITER}${CV_VALUE_COLUMN} = ${castValueToJsonbBoolean(`:${conditionRep}`)}` : '';
|
|
107
|
+
return `(${columnCondition}${AND_DELIMITER}(${castIfNeeded(CV_VALUE_COLUMN, condition)} = ${valueAsJsonb}${valueAsJsonbBoolean}))`;
|
|
108
|
+
}
|
|
109
|
+
if (condition?.operator) {
|
|
110
|
+
const valueRep = reverseReplacementsMap.get(condition.value);
|
|
111
|
+
const valueAsJsonb = castValueToJsonbText(`:${valueRep}`);
|
|
112
|
+
return `( ${columnCondition}${AND_DELIMITER}${castIfNeeded(CV_VALUE_COLUMN, condition.value)} ${condition.operator} ${valueAsJsonb})`;
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}).filter(Boolean);
|
|
123
116
|
if (conditionsStrings.length === 0) {
|
|
124
117
|
return {};
|
|
125
118
|
}
|
|
126
|
-
const customFieldConditions = conditionsStrings.join(
|
|
119
|
+
const customFieldConditions = conditionsStrings.join(OR_DELIMITER);
|
|
127
120
|
const subQuery = `
|
|
128
121
|
SELECT cv.model_id
|
|
129
122
|
FROM custom_field_values AS cv
|
|
130
123
|
INNER JOIN custom_field_definitions AS cd ON cv.custom_field_definition_id = cd.id
|
|
131
|
-
|
|
124
|
+
${AND_DELIMITER}cd.model_type = '${name}'
|
|
132
125
|
WHERE ${customFieldConditions}
|
|
133
|
-
|
|
126
|
+
${AND_DELIMITER}cv.deleted_at IS NULL${AND_DELIMITER}cd.deleted_at IS NULL
|
|
134
127
|
GROUP BY cv.model_id
|
|
135
128
|
HAVING COUNT(DISTINCT cv.custom_field_definition_id) = ${conditionsStrings.length}
|
|
136
129
|
`.replace(/\n/g, '');
|
|
@@ -164,9 +157,9 @@ export const customFieldsSortScope = (
|
|
|
164
157
|
FROM (SELECT cv.model_id, cv.value
|
|
165
158
|
FROM custom_field_values AS cv INNER JOIN custom_field_definitions AS cd
|
|
166
159
|
ON cv.custom_field_definition_id = cd.id
|
|
167
|
-
|
|
160
|
+
${AND_DELIMITER}cd.model_type = '${name}'
|
|
168
161
|
WHERE cv.model_id = "${name}"."id"
|
|
169
|
-
|
|
162
|
+
${AND_DELIMITER}cd.name = :${replacemetKey}
|
|
170
163
|
) AS CustomFieldAggregation
|
|
171
164
|
)
|
|
172
165
|
`), randomStr,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { generateFilterReplacements } from '@autofleet/sheilta/lib/formatter';
|
|
1
2
|
import {
|
|
2
3
|
ContextAwareTestModel, ContextTestModel, CustomFieldDefinition, TestModel,
|
|
3
4
|
} from '../../models';
|
|
@@ -17,3 +18,8 @@ export const getModel = (name: string) => {
|
|
|
17
18
|
const models = require('../../models');
|
|
18
19
|
return models[name];
|
|
19
20
|
};
|
|
21
|
+
|
|
22
|
+
export const getReplacementMapWithScopeValue = (conditions: Record<string, any>) => ({
|
|
23
|
+
replacementsMap: generateFilterReplacements(Object.fromEntries(Object.entries(conditions).map(([key, value]) => [`customFields.${key}`, value]))),
|
|
24
|
+
scopeValue: conditions,
|
|
25
|
+
});
|
package/tsconfig.json
CHANGED