@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.
@@ -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
- const where = {
55
- modelType,
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 === -1 || !customFields) {
76
- return;
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
- const fieldsNames = Object.keys(customFields);
79
- const missingFields = requiredFieldsNames.filter((name) => !fieldsNames.includes(name));
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>;
@@ -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 fieldDefinitions = await DefinitionRepo.findAll(where, { withDisabled: true, transaction, include: modelOptions.include?.(identifiers) }) ?? [];
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/sadot",
3
- "version": "0.7.6",
3
+ "version": "0.7.7-beta-0ecad376.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -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
- 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)));
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 === -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
- }
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
- await ValueRepo.updateValues(
65
- modelType,
66
- instance.id,
67
- identifiers,
68
- customFields,
69
- {
70
- transaction: options.transaction,
71
- modelOptions,
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
- // eslint-disable-next-line no-param-reassign
76
- fields.splice(customFieldsIdx, 1);
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
  };
@@ -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 fieldDefinitions = await DefinitionRepo.findAll(where, { withDisabled: true, transaction, include: modelOptions.include?.(identifiers) }) ?? [];
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,