@autofleet/sadot 0.7.6 → 0.7.7-beta-0ecad376.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/hooks/create.js +16 -32
- package/dist/repository/value.d.ts +1 -1
- package/dist/repository/value.js +18 -5
- package/package.json +1 -1
- package/src/hooks/create.ts +24 -42
- package/src/repository/value.ts +20 -4
package/dist/hooks/create.js
CHANGED
|
@@ -48,43 +48,27 @@ exports.beforeBulkCreate = beforeBulkCreate;
|
|
|
48
48
|
const beforeCreate = (scopeAttributes, modelOptions = {}) => async (instance, options) => {
|
|
49
49
|
logger_1.default.debug('sadot - before create hook');
|
|
50
50
|
const { fields } = options;
|
|
51
|
-
const { include, useEntityIdFromInclude } = modelOptions;
|
|
52
51
|
const modelType = instance.constructor.name;
|
|
53
52
|
const identifiers = (0, scopeAttributes_1.default)(instance, scopeAttributes);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
disabled: false,
|
|
57
|
-
...(!useEntityIdFromInclude && { entityId: identifiers }),
|
|
58
|
-
};
|
|
59
|
-
const fieldDefinitions = await DefinitionRepo.findAll(where, { withDisabled: false, transaction: options.transaction, include: include?.(identifiers) });
|
|
60
|
-
const requiredFieldsNames = Array.from(new Set(fieldDefinitions.filter(({ required }) => required).map(({ name }) => name)));
|
|
53
|
+
// get all model's required definitions
|
|
54
|
+
const requiredFieldsNames = await DefinitionRepo.getRequiredFields(modelType, instance.id, identifiers, modelOptions);
|
|
61
55
|
const customFieldsIdx = fields.indexOf('customFields');
|
|
62
|
-
if ((customFieldsIdx === -1 || !instance.customFields) && requiredFieldsNames?.length > 0) {
|
|
63
|
-
throw new errors_1.MissingRequiredCustomFieldError(requiredFieldsNames);
|
|
64
|
-
}
|
|
65
|
-
const fieldsWithDefaultValue = fieldDefinitions.filter((def) => ![null, undefined].includes(def.defaultValue));
|
|
66
|
-
if (fieldsWithDefaultValue.length) {
|
|
67
|
-
// eslint-disable-next-line no-param-reassign
|
|
68
|
-
instance.customFields || (instance.customFields = {});
|
|
69
|
-
fieldsWithDefaultValue.filter((def) => !(def.name in instance.customFields)).forEach(({ name, defaultValue }) => {
|
|
70
|
-
// eslint-disable-next-line no-param-reassign
|
|
71
|
-
instance.customFields[name] = defaultValue;
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
56
|
const { customFields } = instance;
|
|
75
|
-
if (customFieldsIdx
|
|
76
|
-
|
|
57
|
+
if (customFieldsIdx > -1 && customFields) {
|
|
58
|
+
const fieldsNames = Object.keys(customFields);
|
|
59
|
+
const missingFields = requiredFieldsNames.filter((name) => !fieldsNames.includes(name));
|
|
60
|
+
if (missingFields?.length > 0) {
|
|
61
|
+
throw new errors_1.MissingRequiredCustomFieldError(missingFields);
|
|
62
|
+
}
|
|
63
|
+
await ValueRepo.updateValues(modelType, instance.id, identifiers, customFields, {
|
|
64
|
+
transaction: options.transaction,
|
|
65
|
+
modelOptions,
|
|
66
|
+
}, true);
|
|
67
|
+
// eslint-disable-next-line no-param-reassign
|
|
68
|
+
fields.splice(customFieldsIdx, 1);
|
|
77
69
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (missingFields?.length > 0) {
|
|
81
|
-
throw new errors_1.MissingRequiredCustomFieldError(missingFields);
|
|
70
|
+
else if (requiredFieldsNames?.length > 0) {
|
|
71
|
+
throw new errors_1.MissingRequiredCustomFieldError(requiredFieldsNames);
|
|
82
72
|
}
|
|
83
|
-
await ValueRepo.updateValues(modelType, instance.id, identifiers, customFields, {
|
|
84
|
-
transaction: options.transaction,
|
|
85
|
-
modelOptions,
|
|
86
|
-
});
|
|
87
|
-
// eslint-disable-next-line no-param-reassign
|
|
88
|
-
fields.splice(customFieldsIdx, 1);
|
|
89
73
|
};
|
|
90
74
|
exports.beforeCreate = beforeCreate;
|
|
@@ -24,5 +24,5 @@ export declare const findValuesByModelIds: (modelIds: string[], options?: any) =
|
|
|
24
24
|
*/
|
|
25
25
|
export declare const updateValues: (modelType: string, modelId: string, identifiers: string[], valuesToUpdate: ValuesToUpdate, options?: FindOptions & {
|
|
26
26
|
modelOptions?: ModelOptions;
|
|
27
|
-
}) => Promise<CustomFieldValue[]>;
|
|
27
|
+
}, defineAllDefaults?: boolean) => Promise<CustomFieldValue[]>;
|
|
28
28
|
export declare const deleteValue: (id: string, options?: any) => Promise<any>;
|
package/dist/repository/value.js
CHANGED
|
@@ -84,7 +84,7 @@ const formatFunctions = {
|
|
|
84
84
|
* Create new value record if not exists, but fails if value's definition not exist.
|
|
85
85
|
* Return the updated values
|
|
86
86
|
*/
|
|
87
|
-
const updateValues = async (modelType, modelId, identifiers, valuesToUpdate, options = {}) => {
|
|
87
|
+
const updateValues = async (modelType, modelId, identifiers, valuesToUpdate, options = {}, defineAllDefaults = false) => {
|
|
88
88
|
const names = Object.keys(valuesToUpdate);
|
|
89
89
|
logger_1.default.debug(`custom-fields: updating values for ${modelType} ${modelId}`, {
|
|
90
90
|
names,
|
|
@@ -95,10 +95,12 @@ const updateValues = async (modelType, modelId, identifiers, valuesToUpdate, opt
|
|
|
95
95
|
const { modelOptions, transaction } = options;
|
|
96
96
|
const where = {
|
|
97
97
|
modelType,
|
|
98
|
-
name: names,
|
|
98
|
+
...(!defineAllDefaults && { name: names }),
|
|
99
99
|
...(!options.modelOptions?.useEntityIdFromInclude && { entityId: identifiers }),
|
|
100
100
|
};
|
|
101
|
-
const
|
|
101
|
+
const allFieldDefinitions = await DefinitionRepo.findAll(where, { withDisabled: true, transaction, include: modelOptions.include?.(identifiers) }) || [];
|
|
102
|
+
const namesSet = new Set(defineAllDefaults ? names : undefined);
|
|
103
|
+
const fieldDefinitions = defineAllDefaults ? allFieldDefinitions.filter((cfd) => namesSet.has(cfd.name)) : allFieldDefinitions;
|
|
102
104
|
const disabledDefinitions = fieldDefinitions.filter((def) => def.disabled);
|
|
103
105
|
if (fieldDefinitions.length !== names.length) {
|
|
104
106
|
logger_1.default.warn(`custom-fields: missing definitions for ${modelType} ${modelId}`, { names, fieldDefinitions });
|
|
@@ -110,17 +112,28 @@ const updateValues = async (modelType, modelId, identifiers, valuesToUpdate, opt
|
|
|
110
112
|
if (valuesWithDisabledDefinitions?.length > 0) {
|
|
111
113
|
logger_1.default.warn(`custom-fields: trying to update disabled values: ${valuesWithDisabledDefinitions.join(', ')}`);
|
|
112
114
|
}
|
|
115
|
+
const visitedFields = new Set();
|
|
113
116
|
const values = names.map((name) => {
|
|
114
117
|
const fieldDefinition = fieldDefinitions.find((def) => def.name === name);
|
|
118
|
+
visitedFields.add(fieldDefinition);
|
|
115
119
|
const formatFunction = formatFunctions[fieldDefinition.fieldType];
|
|
116
|
-
const value = formatFunction ? formatFunction(valuesToUpdate[name]) : valuesToUpdate[name];
|
|
117
120
|
return {
|
|
118
121
|
modelId,
|
|
122
|
+
value: (formatFunction ? formatFunction(valuesToUpdate[name]) : valuesToUpdate[name]) ?? fieldDefinition.defaultValue,
|
|
119
123
|
updatedAt: new Date(),
|
|
120
124
|
customFieldDefinitionId: fieldDefinition.id,
|
|
121
|
-
value: value !== undefined ? value : fieldDefinition.defaultValue,
|
|
122
125
|
};
|
|
123
126
|
});
|
|
127
|
+
if (defineAllDefaults) {
|
|
128
|
+
allFieldDefinitions.filter((def) => !visitedFields.has(def) && ![null, undefined].includes(def.defaultValue)).forEach(({ id, defaultValue }) => {
|
|
129
|
+
values.push({
|
|
130
|
+
modelId,
|
|
131
|
+
value: defaultValue,
|
|
132
|
+
updatedAt: new Date(),
|
|
133
|
+
customFieldDefinitionId: id,
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
}
|
|
124
137
|
return Promise.all(values.map(async (value) => {
|
|
125
138
|
const [cfv] = await models_1.CustomFieldValue.upsert(value, {
|
|
126
139
|
transaction: options.transaction,
|
package/package.json
CHANGED
package/src/hooks/create.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { WhereOptions } from 'sequelize';
|
|
2
1
|
import logger from '../utils/logger';
|
|
3
2
|
import * as ValueRepo from '../repository/value';
|
|
4
3
|
import * as DefinitionRepo from '../repository/definition';
|
|
@@ -24,54 +23,37 @@ export const beforeCreate = (scopeAttributes: string[], modelOptions: ModelOptio
|
|
|
24
23
|
): Promise<void> => {
|
|
25
24
|
logger.debug('sadot - before create hook');
|
|
26
25
|
const { fields } = options;
|
|
27
|
-
const { include, useEntityIdFromInclude } = modelOptions;
|
|
28
26
|
const modelType = instance.constructor.name;
|
|
29
27
|
|
|
30
28
|
const identifiers = applyScopeToInstance(instance, scopeAttributes);
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
|
|
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)));
|
|
30
|
+
// get all model's required definitions
|
|
31
|
+
const requiredFieldsNames = await DefinitionRepo.getRequiredFields(modelType, instance.id, identifiers, modelOptions);
|
|
39
32
|
|
|
40
33
|
const customFieldsIdx = fields.indexOf('customFields');
|
|
41
|
-
|
|
42
|
-
if ((customFieldsIdx === -1 || !instance.customFields) && requiredFieldsNames?.length > 0) {
|
|
43
|
-
throw new MissingRequiredCustomFieldError(requiredFieldsNames);
|
|
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
34
|
const { customFields } = instance;
|
|
55
|
-
if (customFieldsIdx
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
throw new MissingRequiredCustomFieldError(missingFields);
|
|
62
|
-
}
|
|
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
|
+
}
|
|
63
41
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
42
|
+
await ValueRepo.updateValues(
|
|
43
|
+
modelType,
|
|
44
|
+
instance.id,
|
|
45
|
+
identifiers,
|
|
46
|
+
customFields,
|
|
47
|
+
{
|
|
48
|
+
transaction: options.transaction,
|
|
49
|
+
modelOptions,
|
|
50
|
+
},
|
|
51
|
+
true,
|
|
52
|
+
);
|
|
74
53
|
|
|
75
|
-
|
|
76
|
-
|
|
54
|
+
// eslint-disable-next-line no-param-reassign
|
|
55
|
+
fields.splice(customFieldsIdx, 1);
|
|
56
|
+
} else if (requiredFieldsNames?.length > 0) {
|
|
57
|
+
throw new MissingRequiredCustomFieldError(requiredFieldsNames);
|
|
58
|
+
}
|
|
77
59
|
};
|
package/src/repository/value.ts
CHANGED
|
@@ -67,6 +67,7 @@ export const updateValues = async (
|
|
|
67
67
|
identifiers: string[],
|
|
68
68
|
valuesToUpdate: ValuesToUpdate,
|
|
69
69
|
options: FindOptions & { modelOptions?: ModelOptions } = {},
|
|
70
|
+
defineAllDefaults = false,
|
|
70
71
|
): Promise<CustomFieldValue[]> => {
|
|
71
72
|
const names = Object.keys(valuesToUpdate);
|
|
72
73
|
logger.debug(`custom-fields: updating values for ${modelType} ${modelId}`, {
|
|
@@ -79,11 +80,13 @@ export const updateValues = async (
|
|
|
79
80
|
|
|
80
81
|
const where: WhereOptions = {
|
|
81
82
|
modelType,
|
|
82
|
-
name: names,
|
|
83
|
+
...(!defineAllDefaults && { name: names }),
|
|
83
84
|
...(!options.modelOptions?.useEntityIdFromInclude && { entityId: identifiers }),
|
|
84
85
|
};
|
|
85
86
|
|
|
86
|
-
const
|
|
87
|
+
const allFieldDefinitions = await DefinitionRepo.findAll(where, { withDisabled: true, transaction, include: modelOptions.include?.(identifiers) }) || [];
|
|
88
|
+
const namesSet = new Set(defineAllDefaults ? names : undefined);
|
|
89
|
+
const fieldDefinitions = defineAllDefaults ? allFieldDefinitions.filter((cfd) => namesSet.has(cfd.name)) : allFieldDefinitions;
|
|
87
90
|
|
|
88
91
|
const disabledDefinitions = fieldDefinitions.filter((def) => def.disabled);
|
|
89
92
|
if (fieldDefinitions.length !== names.length) {
|
|
@@ -98,18 +101,31 @@ export const updateValues = async (
|
|
|
98
101
|
logger.warn(`custom-fields: trying to update disabled values: ${valuesWithDisabledDefinitions.join(', ')}`);
|
|
99
102
|
}
|
|
100
103
|
|
|
104
|
+
const visitedFields = new Set<CustomFieldDefinition>();
|
|
105
|
+
|
|
101
106
|
const values: CreateCustomFieldValue[] = names.map((name) => {
|
|
102
107
|
const fieldDefinition = fieldDefinitions.find((def) => def.name === name);
|
|
108
|
+
visitedFields.add(fieldDefinition);
|
|
103
109
|
const formatFunction = formatFunctions[fieldDefinition.fieldType];
|
|
104
|
-
const value = formatFunction ? formatFunction(valuesToUpdate[name]) : valuesToUpdate[name];
|
|
105
110
|
return {
|
|
106
111
|
modelId,
|
|
112
|
+
value: (formatFunction ? formatFunction(valuesToUpdate[name]) : valuesToUpdate[name]) ?? fieldDefinition.defaultValue,
|
|
107
113
|
updatedAt: new Date(),
|
|
108
114
|
customFieldDefinitionId: fieldDefinition.id,
|
|
109
|
-
value: value !== undefined ? value : fieldDefinition.defaultValue,
|
|
110
115
|
};
|
|
111
116
|
});
|
|
112
117
|
|
|
118
|
+
if (defineAllDefaults) {
|
|
119
|
+
allFieldDefinitions.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
|
+
|
|
113
129
|
return Promise.all(values.map(async (value) => {
|
|
114
130
|
const [cfv] = await CustomFieldValue.upsert(value, {
|
|
115
131
|
transaction: options.transaction,
|