@autofleet/sadot 0.7.7-beta.0 → 0.7.7
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/api/v1/definition/validations.js +2 -24
- package/dist/events/index.js +20 -21
- package/dist/hooks/create.js +1 -1
- package/dist/models/CustomFieldDefinition.d.ts +0 -1
- package/dist/models/CustomFieldDefinition.js +0 -14
- package/dist/models/index.js +1 -1
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.js +3 -1
- package/dist/repository/value.d.ts +1 -1
- package/dist/repository/value.js +7 -36
- package/dist/scopes/filter.d.ts +3 -10
- package/dist/scopes/filter.js +40 -33
- package/dist/tests/mocks/definition.mock.d.ts +0 -2
- package/dist/tests/mocks/definition.mock.js +9 -10
- package/dist/types/definition/index.d.ts +0 -1
- package/dist/utils/logger/index.d.ts +1 -1
- package/dist/utils/logger/index.js +3 -5
- package/package.json +1 -2
- package/src/hooks/create.ts +42 -24
- package/src/repository/definition.ts +15 -6
- package/src/repository/value.ts +4 -20
- package/src/scopes/filter.ts +20 -18
- package/coverage/clover.xml +0 -1073
- package/coverage/coverage-final.json +0 -44
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -461
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov-report/src/api/index.html +0 -116
- package/coverage/lcov-report/src/api/index.ts.html +0 -112
- package/coverage/lcov-report/src/api/v1/definition/index.html +0 -131
- package/coverage/lcov-report/src/api/v1/definition/index.ts.html +0 -406
- package/coverage/lcov-report/src/api/v1/definition/validations.ts.html +0 -310
- package/coverage/lcov-report/src/api/v1/errors.ts.html +0 -133
- package/coverage/lcov-report/src/api/v1/index.html +0 -131
- package/coverage/lcov-report/src/api/v1/index.ts.html +0 -112
- package/coverage/lcov-report/src/errors/index.html +0 -116
- package/coverage/lcov-report/src/errors/index.ts.html +0 -211
- package/coverage/lcov-report/src/events/index.html +0 -116
- package/coverage/lcov-report/src/events/index.ts.html +0 -238
- package/coverage/lcov-report/src/hooks/create.ts.html +0 -262
- package/coverage/lcov-report/src/hooks/enrich.ts.html +0 -523
- package/coverage/lcov-report/src/hooks/find.ts.html +0 -166
- package/coverage/lcov-report/src/hooks/index.html +0 -191
- package/coverage/lcov-report/src/hooks/index.ts.html +0 -130
- package/coverage/lcov-report/src/hooks/update.ts.html +0 -211
- package/coverage/lcov-report/src/hooks/workaround.ts.html +0 -226
- package/coverage/lcov-report/src/index.html +0 -116
- package/coverage/lcov-report/src/index.ts.html +0 -235
- package/coverage/lcov-report/src/models/CustomFieldDefinition.ts.html +0 -550
- package/coverage/lcov-report/src/models/CustomFieldValue.ts.html +0 -415
- package/coverage/lcov-report/src/models/index.html +0 -146
- package/coverage/lcov-report/src/models/index.ts.html +0 -406
- package/coverage/lcov-report/src/models/tests/AssociatedTestModel.ts.html +0 -256
- package/coverage/lcov-report/src/models/tests/TestModel.ts.html +0 -247
- package/coverage/lcov-report/src/models/tests/contextAwareModels/ContextAwareTestModel.ts.html +0 -214
- package/coverage/lcov-report/src/models/tests/contextAwareModels/ContextTestModel.ts.html +0 -199
- package/coverage/lcov-report/src/models/tests/contextAwareModels/index.html +0 -131
- package/coverage/lcov-report/src/models/tests/index.html +0 -131
- package/coverage/lcov-report/src/repository/definition.ts.html +0 -466
- package/coverage/lcov-report/src/repository/index.html +0 -131
- package/coverage/lcov-report/src/repository/value.ts.html +0 -523
- package/coverage/lcov-report/src/scopes/filter.ts.html +0 -637
- package/coverage/lcov-report/src/scopes/index.html +0 -131
- package/coverage/lcov-report/src/scopes/index.ts.html +0 -103
- package/coverage/lcov-report/src/tests/api/index.html +0 -116
- package/coverage/lcov-report/src/tests/api/test-api.ts.html +0 -199
- package/coverage/lcov-report/src/tests/functional/searching/index.html +0 -116
- package/coverage/lcov-report/src/tests/functional/searching/index.ts.html +0 -202
- package/coverage/lcov-report/src/tests/helpers/database-config.ts.html +0 -130
- package/coverage/lcov-report/src/tests/helpers/index.html +0 -131
- package/coverage/lcov-report/src/tests/helpers/index.ts.html +0 -142
- package/coverage/lcov-report/src/tests/mocks/definition.mock.ts.html +0 -310
- package/coverage/lcov-report/src/tests/mocks/events.mock.ts.html +0 -139
- package/coverage/lcov-report/src/tests/mocks/index.html +0 -146
- package/coverage/lcov-report/src/tests/mocks/testModel.ts.html +0 -196
- package/coverage/lcov-report/src/utils/constants/index.html +0 -116
- package/coverage/lcov-report/src/utils/constants/index.ts.html +0 -160
- package/coverage/lcov-report/src/utils/db/index.html +0 -116
- package/coverage/lcov-report/src/utils/db/index.ts.html +0 -148
- package/coverage/lcov-report/src/utils/helpers/index.html +0 -116
- package/coverage/lcov-report/src/utils/helpers/index.ts.html +0 -283
- package/coverage/lcov-report/src/utils/index.html +0 -131
- package/coverage/lcov-report/src/utils/init.ts.html +0 -430
- package/coverage/lcov-report/src/utils/logger/index.html +0 -116
- package/coverage/lcov-report/src/utils/logger/index.ts.html +0 -100
- package/coverage/lcov-report/src/utils/scopeAttributes.ts.html +0 -121
- package/coverage/lcov-report/src/utils/validations/index.html +0 -116
- package/coverage/lcov-report/src/utils/validations/index.ts.html +0 -151
- package/coverage/lcov-report/src/utils/validations/schema/custom-fields.ts.html +0 -109
- package/coverage/lcov-report/src/utils/validations/schema/index.html +0 -116
- package/coverage/lcov-report/src/utils/validations/validators/index.html +0 -146
- package/coverage/lcov-report/src/utils/validations/validators/index.ts.html +0 -199
- package/coverage/lcov-report/src/utils/validations/validators/select.validator.ts.html +0 -118
- package/coverage/lcov-report/src/utils/validations/validators/status.validator.ts.html +0 -139
- package/coverage/lcov.info +0 -1818
package/src/hooks/create.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { WhereOptions } from 'sequelize';
|
|
1
2
|
import logger from '../utils/logger';
|
|
2
3
|
import * as ValueRepo from '../repository/value';
|
|
3
4
|
import * as DefinitionRepo from '../repository/definition';
|
|
@@ -23,37 +24,54 @@ export const beforeCreate = (scopeAttributes: string[], modelOptions: ModelOptio
|
|
|
23
24
|
): Promise<void> => {
|
|
24
25
|
logger.debug('sadot - before create hook');
|
|
25
26
|
const { fields } = options;
|
|
27
|
+
const { include, useEntityIdFromInclude } = modelOptions;
|
|
26
28
|
const modelType = instance.constructor.name;
|
|
27
29
|
|
|
28
30
|
const identifiers = applyScopeToInstance(instance, scopeAttributes);
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
const where: WhereOptions = {
|
|
33
|
+
modelType,
|
|
34
|
+
disabled: false,
|
|
35
|
+
...(!useEntityIdFromInclude && { entityId: identifiers }),
|
|
36
|
+
};
|
|
37
|
+
const fieldDefinitions = await DefinitionRepo.findAll(where, { withDisabled: false, transaction: options.transaction, include: include?.(identifiers) });
|
|
38
|
+
const requiredFieldsNames = Array.from(new Set(fieldDefinitions.filter(({ required }) => required).map(({ name }) => name)));
|
|
32
39
|
|
|
33
40
|
const customFieldsIdx = fields.indexOf('customFields');
|
|
34
|
-
const { customFields } = instance;
|
|
35
|
-
if (customFieldsIdx > -1 && customFields) {
|
|
36
|
-
const fieldsNames = Object.keys(customFields);
|
|
37
|
-
const missingFields = requiredFieldsNames.filter((name) => !fieldsNames.includes(name));
|
|
38
|
-
if (missingFields?.length > 0) {
|
|
39
|
-
throw new MissingRequiredCustomFieldError(missingFields);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
await ValueRepo.updateValues(
|
|
43
|
-
modelType,
|
|
44
|
-
instance.id,
|
|
45
|
-
identifiers,
|
|
46
|
-
customFields,
|
|
47
|
-
{
|
|
48
|
-
transaction: options.transaction,
|
|
49
|
-
modelOptions,
|
|
50
|
-
},
|
|
51
|
-
true,
|
|
52
|
-
);
|
|
53
41
|
|
|
54
|
-
|
|
55
|
-
fields.splice(customFieldsIdx, 1);
|
|
56
|
-
} else if (requiredFieldsNames?.length > 0) {
|
|
42
|
+
if ((customFieldsIdx === -1 || !instance.customFields) && requiredFieldsNames?.length > 0) {
|
|
57
43
|
throw new MissingRequiredCustomFieldError(requiredFieldsNames);
|
|
58
44
|
}
|
|
45
|
+
const fieldsWithDefaultValue = fieldDefinitions.filter((def) => ![null, undefined].includes(def.defaultValue));
|
|
46
|
+
if (fieldsWithDefaultValue.length) {
|
|
47
|
+
// eslint-disable-next-line no-param-reassign
|
|
48
|
+
instance.customFields ||= {};
|
|
49
|
+
fieldsWithDefaultValue.filter((def) => !(def.name in instance.customFields)).forEach(({ name, defaultValue }) => {
|
|
50
|
+
// eslint-disable-next-line no-param-reassign
|
|
51
|
+
instance.customFields[name] = defaultValue;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const { customFields } = instance;
|
|
55
|
+
if (customFieldsIdx === -1 || !customFields) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const fieldsNames = Object.keys(customFields);
|
|
59
|
+
const missingFields = requiredFieldsNames.filter((name) => !fieldsNames.includes(name));
|
|
60
|
+
if (missingFields?.length > 0) {
|
|
61
|
+
throw new MissingRequiredCustomFieldError(missingFields);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
await ValueRepo.updateValues(
|
|
65
|
+
modelType,
|
|
66
|
+
instance.id,
|
|
67
|
+
identifiers,
|
|
68
|
+
customFields,
|
|
69
|
+
{
|
|
70
|
+
transaction: options.transaction,
|
|
71
|
+
modelOptions,
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// eslint-disable-next-line no-param-reassign
|
|
76
|
+
fields.splice(customFieldsIdx, 1);
|
|
59
77
|
};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Op,
|
|
3
|
+
type Includeable, type Transaction, type FindOptions, type WhereOptions,
|
|
4
|
+
} from 'sequelize';
|
|
2
5
|
import { CustomFieldDefinition } from '../models';
|
|
3
6
|
import type { CreateCustomFieldDefinition, UpdateCustomFieldDefinition } from '../types/definition';
|
|
4
7
|
import type { ModelOptions } from '../types';
|
|
@@ -6,9 +9,15 @@ import type { ModelOptions } from '../types';
|
|
|
6
9
|
export const create = (data: CreateCustomFieldDefinition): Promise<CustomFieldDefinition> =>
|
|
7
10
|
CustomFieldDefinition.create(data);
|
|
8
11
|
|
|
12
|
+
interface SadotFindOptions {
|
|
13
|
+
withDisabled?: boolean;
|
|
14
|
+
transaction?: Transaction;
|
|
15
|
+
include?: Includeable | Includeable[];
|
|
16
|
+
}
|
|
17
|
+
|
|
9
18
|
export const findAll = (
|
|
10
19
|
where: WhereOptions,
|
|
11
|
-
options:
|
|
20
|
+
options: SadotFindOptions = { withDisabled: false },
|
|
12
21
|
): Promise<CustomFieldDefinition[]> => {
|
|
13
22
|
const queryModel = options.withDisabled
|
|
14
23
|
? CustomFieldDefinition.unscoped()
|
|
@@ -24,12 +33,12 @@ export const findAll = (
|
|
|
24
33
|
|
|
25
34
|
export const findByIds = (
|
|
26
35
|
ids: string[],
|
|
27
|
-
options:
|
|
36
|
+
options: SadotFindOptions = { withDisabled: false },
|
|
28
37
|
): Promise<CustomFieldDefinition[]> => findAll({ id: { [Op.in]: ids } }, options);
|
|
29
38
|
|
|
30
39
|
export const findById = (
|
|
31
40
|
id: string,
|
|
32
|
-
options:
|
|
41
|
+
options: Pick<SadotFindOptions, 'withDisabled'> = { withDisabled: false },
|
|
33
42
|
): Promise<CustomFieldDefinition | null> => {
|
|
34
43
|
const { withDisabled } = options;
|
|
35
44
|
if (withDisabled) {
|
|
@@ -87,13 +96,13 @@ export const update = async (
|
|
|
87
96
|
return updatedDefinition;
|
|
88
97
|
};
|
|
89
98
|
|
|
90
|
-
export const disable = (id: string): Promise<
|
|
99
|
+
export const disable = (id: string): Promise<[affectedCount: number]> =>
|
|
91
100
|
CustomFieldDefinition.update(
|
|
92
101
|
{ disabled: true },
|
|
93
102
|
{ where: { id } },
|
|
94
103
|
);
|
|
95
104
|
|
|
96
|
-
export const destroy = (id: string): Promise<
|
|
105
|
+
export const destroy = (id: string): Promise<number> =>
|
|
97
106
|
CustomFieldDefinition.destroy({ where: { id } });
|
|
98
107
|
|
|
99
108
|
/**
|
package/src/repository/value.ts
CHANGED
|
@@ -67,7 +67,6 @@ export const updateValues = async (
|
|
|
67
67
|
identifiers: string[],
|
|
68
68
|
valuesToUpdate: ValuesToUpdate,
|
|
69
69
|
options: FindOptions & { modelOptions?: ModelOptions } = {},
|
|
70
|
-
defineAllDefaults = false,
|
|
71
70
|
): Promise<CustomFieldValue[]> => {
|
|
72
71
|
const names = Object.keys(valuesToUpdate);
|
|
73
72
|
logger.debug(`custom-fields: updating values for ${modelType} ${modelId}`, {
|
|
@@ -81,12 +80,10 @@ export const updateValues = async (
|
|
|
81
80
|
const where: WhereOptions = {
|
|
82
81
|
modelType,
|
|
83
82
|
name: names,
|
|
83
|
+
...(!options.modelOptions?.useEntityIdFromInclude && { entityId: identifiers }),
|
|
84
84
|
};
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
where.entityId = identifiers;
|
|
88
|
-
}
|
|
89
|
-
const fieldDefinitions = await DefinitionRepo.findAll(where, { withDisabled: true, transaction, include: modelOptions.include?.(identifiers) }) || [];
|
|
86
|
+
const fieldDefinitions = await DefinitionRepo.findAll(where, { withDisabled: true, transaction, include: modelOptions.include?.(identifiers) }) ?? [];
|
|
90
87
|
|
|
91
88
|
const disabledDefinitions = fieldDefinitions.filter((def) => def.disabled);
|
|
92
89
|
if (fieldDefinitions.length !== names.length) {
|
|
@@ -101,31 +98,18 @@ export const updateValues = async (
|
|
|
101
98
|
logger.warn(`custom-fields: trying to update disabled values: ${valuesWithDisabledDefinitions.join(', ')}`);
|
|
102
99
|
}
|
|
103
100
|
|
|
104
|
-
const visitedFields = new Set<CustomFieldDefinition>();
|
|
105
|
-
|
|
106
101
|
const values: CreateCustomFieldValue[] = names.map((name) => {
|
|
107
102
|
const fieldDefinition = fieldDefinitions.find((def) => def.name === name);
|
|
108
|
-
visitedFields.add(fieldDefinition);
|
|
109
103
|
const formatFunction = formatFunctions[fieldDefinition.fieldType];
|
|
104
|
+
const value = formatFunction ? formatFunction(valuesToUpdate[name]) : valuesToUpdate[name];
|
|
110
105
|
return {
|
|
111
106
|
modelId,
|
|
112
|
-
value: (formatFunction ? formatFunction(valuesToUpdate[name]) : valuesToUpdate[name]) ?? fieldDefinition.defaultValue,
|
|
113
107
|
updatedAt: new Date(),
|
|
114
108
|
customFieldDefinitionId: fieldDefinition.id,
|
|
109
|
+
value: value !== undefined ? value : fieldDefinition.defaultValue,
|
|
115
110
|
};
|
|
116
111
|
});
|
|
117
112
|
|
|
118
|
-
if (defineAllDefaults) {
|
|
119
|
-
fieldDefinitions.filter((def) => !visitedFields.has(def) && ![null, undefined].includes(def.defaultValue)).forEach(({ id, defaultValue }) => {
|
|
120
|
-
values.push({
|
|
121
|
-
modelId,
|
|
122
|
-
value: defaultValue,
|
|
123
|
-
updatedAt: new Date(),
|
|
124
|
-
customFieldDefinitionId: id,
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
|
|
129
113
|
return Promise.all(values.map(async (value) => {
|
|
130
114
|
const [cfv] = await CustomFieldValue.upsert(value, {
|
|
131
115
|
transaction: options.transaction,
|
package/src/scopes/filter.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { Op, type WhereOptions } from 'sequelize';
|
|
|
3
3
|
import { Sequelize } from 'sequelize-typescript';
|
|
4
4
|
import { customFields } from '@autofleet/common-types';
|
|
5
5
|
import { generateRandomString } from '../utils/helpers';
|
|
6
|
-
import logger from '../utils/logger';
|
|
7
6
|
|
|
8
7
|
const { CUSTOM_FIELDS_FILTER_SCOPE } = customFields;
|
|
9
8
|
|
|
@@ -46,11 +45,11 @@ const castIfNeeded = (conditionValue: string): string => {
|
|
|
46
45
|
};
|
|
47
46
|
const AND_DELIMETER = ' AND ';
|
|
48
47
|
const OR_DELIMETER = ' OR ';
|
|
49
|
-
|
|
50
48
|
const CD_TABLE_ALIAS = 'cd';
|
|
51
49
|
const CD_NAME_COLUMN = `${CD_TABLE_ALIAS}.name`;
|
|
52
50
|
const CV_TABLE_ALIAS = 'cv';
|
|
53
|
-
const CV_VALUE_COLUMN = `(${CV_TABLE_ALIAS}.value
|
|
51
|
+
const CV_VALUE_COLUMN = `(${CV_TABLE_ALIAS}.value)`;
|
|
52
|
+
const castValueToJsonb = (value) => `to_jsonb(${value}::text)`;
|
|
54
53
|
|
|
55
54
|
/**
|
|
56
55
|
* A Sequelize scope for filtering models by custom fields.
|
|
@@ -77,8 +76,8 @@ export const customFieldsFilterScope = (
|
|
|
77
76
|
const replacemetKey = Object.keys(replacements).find(
|
|
78
77
|
(randomString) => replacements[randomString] === key,
|
|
79
78
|
);
|
|
80
|
-
if (!replacemetKey) return false;
|
|
81
79
|
const columnCondition = `(${CD_NAME_COLUMN} = :${replacemetKey})`;
|
|
80
|
+
if (!replacemetKey) return false;
|
|
82
81
|
|
|
83
82
|
if (Array.isArray(condition)) {
|
|
84
83
|
if (condition.length === 0) {
|
|
@@ -90,29 +89,32 @@ export const customFieldsFilterScope = (
|
|
|
90
89
|
const valRandom = Object.keys(replacements).find(
|
|
91
90
|
(randomString) => replacements[randomString] === v,
|
|
92
91
|
);
|
|
93
|
-
return
|
|
92
|
+
return castValueToJsonb(`:${valRandom}`);
|
|
94
93
|
}).join(',');
|
|
95
|
-
return `(${columnCondition} AND ${CV_VALUE_COLUMN} IN (
|
|
94
|
+
return `(${columnCondition} AND ${CV_VALUE_COLUMN} IN (${values}))`;
|
|
96
95
|
}
|
|
97
96
|
return condition
|
|
98
97
|
.map((c) => {
|
|
99
98
|
const valRep = Object.keys(replacements).find(
|
|
100
99
|
(replacementKey) => replacements[replacementKey] === c.value,
|
|
101
100
|
);
|
|
102
|
-
|
|
101
|
+
const valueAsJsonb = castValueToJsonb(`:${valRep}`);
|
|
102
|
+
return `(${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(c.value)} ${c.operator} ${valueAsJsonb})`;
|
|
103
103
|
}).join(AND_DELIMETER);
|
|
104
104
|
}
|
|
105
105
|
if (typeof condition === 'string' || typeof condition === 'number') {
|
|
106
106
|
const conditionRep = Object.keys(replacements).find(
|
|
107
107
|
(replacementKey) => replacements[replacementKey] === condition,
|
|
108
108
|
);
|
|
109
|
-
|
|
109
|
+
const valueAsJsonb = castValueToJsonb(`:${conditionRep}`);
|
|
110
|
+
return `(${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(condition)} = ${valueAsJsonb})`;
|
|
110
111
|
}
|
|
111
112
|
if (condition?.operator) {
|
|
112
113
|
const valueRep = Object.keys(replacements).find(
|
|
113
114
|
(replacementKey) => replacements[replacementKey] === condition.value,
|
|
114
115
|
);
|
|
115
|
-
|
|
116
|
+
const valueAsJsonb = castValueToJsonb(`:${valueRep}`);
|
|
117
|
+
return `( ${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(condition.value)} ${condition.operator} ${valueAsJsonb})`;
|
|
116
118
|
}
|
|
117
119
|
return false;
|
|
118
120
|
},
|
|
@@ -123,15 +125,15 @@ export const customFieldsFilterScope = (
|
|
|
123
125
|
}
|
|
124
126
|
const customFieldConditions = conditionsStrings.join(OR_DELIMETER);
|
|
125
127
|
const subQuery = `
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
`.replace(/\n/g, '');
|
|
134
|
-
|
|
128
|
+
SELECT cv.model_id
|
|
129
|
+
FROM custom_field_values AS cv
|
|
130
|
+
INNER JOIN custom_field_definitions AS cd ON cv.custom_field_definition_id = cd.id
|
|
131
|
+
|
|
132
|
+
WHERE ${customFieldConditions}
|
|
133
|
+
GROUP BY cv.model_id
|
|
134
|
+
HAVING COUNT(DISTINCT cv.custom_field_definition_id) = ${conditionsStrings.length}
|
|
135
|
+
`.replace(/\n/g, '');
|
|
136
|
+
console.log(subQuery);
|
|
135
137
|
return {
|
|
136
138
|
where: {
|
|
137
139
|
id: {
|