@autofleet/sadot 0.7.7-beta.0 → 0.7.7-beta.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.
Files changed (88) hide show
  1. package/dist/hooks/create.js +32 -16
  2. package/dist/repository/definition.d.ts +12 -6
  3. package/dist/repository/value.d.ts +1 -1
  4. package/dist/repository/value.js +5 -18
  5. package/dist/scopes/filter.js +10 -4
  6. package/package.json +1 -1
  7. package/src/hooks/create.ts +42 -24
  8. package/src/repository/definition.ts +15 -6
  9. package/src/repository/value.ts +4 -20
  10. package/src/scopes/filter.ts +12 -4
  11. package/coverage/clover.xml +0 -1073
  12. package/coverage/coverage-final.json +0 -44
  13. package/coverage/lcov-report/base.css +0 -224
  14. package/coverage/lcov-report/block-navigation.js +0 -87
  15. package/coverage/lcov-report/favicon.png +0 -0
  16. package/coverage/lcov-report/index.html +0 -461
  17. package/coverage/lcov-report/prettify.css +0 -1
  18. package/coverage/lcov-report/prettify.js +0 -2
  19. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  20. package/coverage/lcov-report/sorter.js +0 -196
  21. package/coverage/lcov-report/src/api/index.html +0 -116
  22. package/coverage/lcov-report/src/api/index.ts.html +0 -112
  23. package/coverage/lcov-report/src/api/v1/definition/index.html +0 -131
  24. package/coverage/lcov-report/src/api/v1/definition/index.ts.html +0 -406
  25. package/coverage/lcov-report/src/api/v1/definition/validations.ts.html +0 -310
  26. package/coverage/lcov-report/src/api/v1/errors.ts.html +0 -133
  27. package/coverage/lcov-report/src/api/v1/index.html +0 -131
  28. package/coverage/lcov-report/src/api/v1/index.ts.html +0 -112
  29. package/coverage/lcov-report/src/errors/index.html +0 -116
  30. package/coverage/lcov-report/src/errors/index.ts.html +0 -211
  31. package/coverage/lcov-report/src/events/index.html +0 -116
  32. package/coverage/lcov-report/src/events/index.ts.html +0 -238
  33. package/coverage/lcov-report/src/hooks/create.ts.html +0 -262
  34. package/coverage/lcov-report/src/hooks/enrich.ts.html +0 -523
  35. package/coverage/lcov-report/src/hooks/find.ts.html +0 -166
  36. package/coverage/lcov-report/src/hooks/index.html +0 -191
  37. package/coverage/lcov-report/src/hooks/index.ts.html +0 -130
  38. package/coverage/lcov-report/src/hooks/update.ts.html +0 -211
  39. package/coverage/lcov-report/src/hooks/workaround.ts.html +0 -226
  40. package/coverage/lcov-report/src/index.html +0 -116
  41. package/coverage/lcov-report/src/index.ts.html +0 -235
  42. package/coverage/lcov-report/src/models/CustomFieldDefinition.ts.html +0 -550
  43. package/coverage/lcov-report/src/models/CustomFieldValue.ts.html +0 -415
  44. package/coverage/lcov-report/src/models/index.html +0 -146
  45. package/coverage/lcov-report/src/models/index.ts.html +0 -406
  46. package/coverage/lcov-report/src/models/tests/AssociatedTestModel.ts.html +0 -256
  47. package/coverage/lcov-report/src/models/tests/TestModel.ts.html +0 -247
  48. package/coverage/lcov-report/src/models/tests/contextAwareModels/ContextAwareTestModel.ts.html +0 -214
  49. package/coverage/lcov-report/src/models/tests/contextAwareModels/ContextTestModel.ts.html +0 -199
  50. package/coverage/lcov-report/src/models/tests/contextAwareModels/index.html +0 -131
  51. package/coverage/lcov-report/src/models/tests/index.html +0 -131
  52. package/coverage/lcov-report/src/repository/definition.ts.html +0 -466
  53. package/coverage/lcov-report/src/repository/index.html +0 -131
  54. package/coverage/lcov-report/src/repository/value.ts.html +0 -523
  55. package/coverage/lcov-report/src/scopes/filter.ts.html +0 -637
  56. package/coverage/lcov-report/src/scopes/index.html +0 -131
  57. package/coverage/lcov-report/src/scopes/index.ts.html +0 -103
  58. package/coverage/lcov-report/src/tests/api/index.html +0 -116
  59. package/coverage/lcov-report/src/tests/api/test-api.ts.html +0 -199
  60. package/coverage/lcov-report/src/tests/functional/searching/index.html +0 -116
  61. package/coverage/lcov-report/src/tests/functional/searching/index.ts.html +0 -202
  62. package/coverage/lcov-report/src/tests/helpers/database-config.ts.html +0 -130
  63. package/coverage/lcov-report/src/tests/helpers/index.html +0 -131
  64. package/coverage/lcov-report/src/tests/helpers/index.ts.html +0 -142
  65. package/coverage/lcov-report/src/tests/mocks/definition.mock.ts.html +0 -310
  66. package/coverage/lcov-report/src/tests/mocks/events.mock.ts.html +0 -139
  67. package/coverage/lcov-report/src/tests/mocks/index.html +0 -146
  68. package/coverage/lcov-report/src/tests/mocks/testModel.ts.html +0 -196
  69. package/coverage/lcov-report/src/utils/constants/index.html +0 -116
  70. package/coverage/lcov-report/src/utils/constants/index.ts.html +0 -160
  71. package/coverage/lcov-report/src/utils/db/index.html +0 -116
  72. package/coverage/lcov-report/src/utils/db/index.ts.html +0 -148
  73. package/coverage/lcov-report/src/utils/helpers/index.html +0 -116
  74. package/coverage/lcov-report/src/utils/helpers/index.ts.html +0 -283
  75. package/coverage/lcov-report/src/utils/index.html +0 -131
  76. package/coverage/lcov-report/src/utils/init.ts.html +0 -430
  77. package/coverage/lcov-report/src/utils/logger/index.html +0 -116
  78. package/coverage/lcov-report/src/utils/logger/index.ts.html +0 -100
  79. package/coverage/lcov-report/src/utils/scopeAttributes.ts.html +0 -121
  80. package/coverage/lcov-report/src/utils/validations/index.html +0 -116
  81. package/coverage/lcov-report/src/utils/validations/index.ts.html +0 -151
  82. package/coverage/lcov-report/src/utils/validations/schema/custom-fields.ts.html +0 -109
  83. package/coverage/lcov-report/src/utils/validations/schema/index.html +0 -116
  84. package/coverage/lcov-report/src/utils/validations/validators/index.html +0 -146
  85. package/coverage/lcov-report/src/utils/validations/validators/index.ts.html +0 -199
  86. package/coverage/lcov-report/src/utils/validations/validators/select.validator.ts.html +0 -118
  87. package/coverage/lcov-report/src/utils/validations/validators/status.validator.ts.html +0 -139
  88. package/coverage/lcov.info +0 -1818
@@ -48,27 +48,43 @@ 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;
51
52
  const modelType = instance.constructor.name;
52
53
  const identifiers = (0, scopeAttributes_1.default)(instance, scopeAttributes);
53
- // get all model's required definitions
54
- const requiredFieldsNames = await DefinitionRepo.getRequiredFields(modelType, instance.id, identifiers, modelOptions);
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)));
55
61
  const customFieldsIdx = fields.indexOf('customFields');
56
- const { customFields } = instance;
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);
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
67
  // eslint-disable-next-line no-param-reassign
68
- fields.splice(customFieldsIdx, 1);
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
+ });
69
73
  }
70
- else if (requiredFieldsNames?.length > 0) {
71
- throw new errors_1.MissingRequiredCustomFieldError(requiredFieldsNames);
74
+ const { customFields } = instance;
75
+ if (customFieldsIdx === -1 || !customFields) {
76
+ return;
77
+ }
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);
72
82
  }
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);
73
89
  };
74
90
  exports.beforeCreate = beforeCreate;
@@ -1,20 +1,26 @@
1
- import { type FindOptions, type WhereOptions } from 'sequelize';
1
+ import { type Includeable, type Transaction, type FindOptions, type WhereOptions } from 'sequelize';
2
2
  import { CustomFieldDefinition } from '../models';
3
3
  import type { CreateCustomFieldDefinition, UpdateCustomFieldDefinition } from '../types/definition';
4
4
  import type { ModelOptions } from '../types';
5
5
  export declare const create: (data: CreateCustomFieldDefinition) => Promise<CustomFieldDefinition>;
6
- export declare const findAll: (where: WhereOptions, options?: any) => Promise<CustomFieldDefinition[]>;
7
- export declare const findByIds: (ids: string[], options?: any) => Promise<CustomFieldDefinition[]>;
8
- export declare const findById: (id: string, options?: any) => Promise<CustomFieldDefinition | null>;
6
+ interface SadotFindOptions {
7
+ withDisabled?: boolean;
8
+ transaction?: Transaction;
9
+ include?: Includeable | Includeable[];
10
+ }
11
+ export declare const findAll: (where: WhereOptions, options?: SadotFindOptions) => Promise<CustomFieldDefinition[]>;
12
+ export declare const findByIds: (ids: string[], options?: SadotFindOptions) => Promise<CustomFieldDefinition[]>;
13
+ export declare const findById: (id: string, options?: Pick<SadotFindOptions, 'withDisabled'>) => Promise<CustomFieldDefinition | null>;
9
14
  export declare const findByEntityIds: (modelType: string, entityIds: string[], options?: FindOptions & {
10
15
  modelOptions?: ModelOptions;
11
16
  }) => Promise<CustomFieldDefinition[]>;
12
17
  export declare const findByWhere: (where: any) => Promise<CustomFieldDefinition | null>;
13
18
  export declare const findDefinitionsByModels: (modelTypes: string[], options?: any) => Promise<CustomFieldDefinition[]>;
14
19
  export declare const update: (id: string, data: UpdateCustomFieldDefinition) => Promise<CustomFieldDefinition>;
15
- export declare const disable: (id: string) => Promise<any>;
16
- export declare const destroy: (id: string) => Promise<any>;
20
+ export declare const disable: (id: string) => Promise<[affectedCount: number]>;
21
+ export declare const destroy: (id: string) => Promise<number>;
17
22
  /**
18
23
  * Return the names of the required fields for a given model
19
24
  */
20
25
  export declare const getRequiredFields: (modelType: string, modelId: string | string[], entityId: string | string[], modelOptions?: ModelOptions) => Promise<string[]>;
26
+ export {};
@@ -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
- }, defineAllDefaults?: boolean) => Promise<CustomFieldValue[]>;
27
+ }) => 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 = {}, defineAllDefaults = false) => {
87
+ const updateValues = async (modelType, modelId, identifiers, valuesToUpdate, options = {}) => {
88
88
  const names = Object.keys(valuesToUpdate);
89
89
  logger_1.default.debug(`custom-fields: updating values for ${modelType} ${modelId}`, {
90
90
  names,
@@ -96,11 +96,9 @@ const updateValues = async (modelType, modelId, identifiers, valuesToUpdate, opt
96
96
  const where = {
97
97
  modelType,
98
98
  name: names,
99
+ ...(!options.modelOptions?.useEntityIdFromInclude && { entityId: identifiers }),
99
100
  };
100
- if (!options.modelOptions?.useEntityIdFromInclude) {
101
- where.entityId = identifiers;
102
- }
103
- const fieldDefinitions = await DefinitionRepo.findAll(where, { withDisabled: true, transaction, include: modelOptions.include?.(identifiers) }) || [];
101
+ const fieldDefinitions = await DefinitionRepo.findAll(where, { withDisabled: true, transaction, include: modelOptions.include?.(identifiers) }) ?? [];
104
102
  const disabledDefinitions = fieldDefinitions.filter((def) => def.disabled);
105
103
  if (fieldDefinitions.length !== names.length) {
106
104
  logger_1.default.warn(`custom-fields: missing definitions for ${modelType} ${modelId}`, { names, fieldDefinitions });
@@ -112,28 +110,17 @@ const updateValues = async (modelType, modelId, identifiers, valuesToUpdate, opt
112
110
  if (valuesWithDisabledDefinitions?.length > 0) {
113
111
  logger_1.default.warn(`custom-fields: trying to update disabled values: ${valuesWithDisabledDefinitions.join(', ')}`);
114
112
  }
115
- const visitedFields = new Set();
116
113
  const values = names.map((name) => {
117
114
  const fieldDefinition = fieldDefinitions.find((def) => def.name === name);
118
- visitedFields.add(fieldDefinition);
119
115
  const formatFunction = formatFunctions[fieldDefinition.fieldType];
116
+ const value = formatFunction ? formatFunction(valuesToUpdate[name]) : valuesToUpdate[name];
120
117
  return {
121
118
  modelId,
122
- value: (formatFunction ? formatFunction(valuesToUpdate[name]) : valuesToUpdate[name]) ?? fieldDefinition.defaultValue,
123
119
  updatedAt: new Date(),
124
120
  customFieldDefinitionId: fieldDefinition.id,
121
+ value: value !== undefined ? value : fieldDefinition.defaultValue,
125
122
  };
126
123
  });
127
- if (defineAllDefaults) {
128
- fieldDefinitions.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
- }
137
124
  return Promise.all(values.map(async (value) => {
138
125
  const [cfv] = await models_1.CustomFieldValue.upsert(value, {
139
126
  transaction: options.transaction,
@@ -21,6 +21,12 @@ const castIfNeeded = (conditionValue) => {
21
21
  }
22
22
  return '';
23
23
  };
24
+ const addQuotationIfNeeded = (conditionValue, valRep) => {
25
+ if (typeof conditionValue === 'string') {
26
+ return `'"' || :${valRep} || '"'`;
27
+ }
28
+ return `:${valRep}`;
29
+ };
24
30
  const AND_DELIMETER = ' AND ';
25
31
  const OR_DELIMETER = ' OR ';
26
32
  const CD_TABLE_ALIAS = 'cd';
@@ -53,23 +59,23 @@ const customFieldsFilterScope = (name) => ({ replacementsMap: replacements, scop
53
59
  if (typeof condition[0] === 'string') {
54
60
  const values = condition.map((v) => {
55
61
  const valRandom = Object.keys(replacements).find((randomString) => replacements[randomString] === v);
56
- return `'"' || :${valRandom} || '"'`;
62
+ return addQuotationIfNeeded(v, valRandom);
57
63
  }).join(',');
58
64
  return `(${columnCondition} AND ${CV_VALUE_COLUMN} IN ( ${values} ))`;
59
65
  }
60
66
  return condition
61
67
  .map((c) => {
62
68
  const valRep = Object.keys(replacements).find((replacementKey) => replacements[replacementKey] === c.value);
63
- return `( ${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(c.value)} ${c.operator} '"' || :${valRep} || '"' )`;
69
+ return `( ${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(c.value)} ${c.operator} ${addQuotationIfNeeded(c.value, valRep)} )`;
64
70
  }).join(AND_DELIMETER);
65
71
  }
66
72
  if (typeof condition === 'string' || typeof condition === 'number') {
67
73
  const conditionRep = Object.keys(replacements).find((replacementKey) => replacements[replacementKey] === condition);
68
- return `(${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(condition)} = '"' || :${conditionRep} || '"')`;
74
+ return `(${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(condition)} = ${addQuotationIfNeeded(condition, conditionRep)})`;
69
75
  }
70
76
  if (condition?.operator) {
71
77
  const valueRep = Object.keys(replacements).find((replacementKey) => replacements[replacementKey] === condition.value);
72
- return `( ${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(condition.value)} ${condition.operator} '"' || :${valueRep} || '"')`;
78
+ return `( ${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(condition.value)} ${condition.operator} ${addQuotationIfNeeded(condition.value, valueRep)})`;
73
79
  }
74
80
  return false;
75
81
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/sadot",
3
- "version": "0.7.7-beta.0",
3
+ "version": "0.7.7-beta.1",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -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
- // get all model's required definitions
31
- const requiredFieldsNames = await DefinitionRepo.getRequiredFields(modelType, instance.id, identifiers, modelOptions);
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
- // eslint-disable-next-line no-param-reassign
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 { Op, type FindOptions, type WhereOptions } from 'sequelize';
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: any = { withDisabled: false },
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: any = { withDisabled: false },
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: any = { withDisabled: false },
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<any> =>
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<any> =>
105
+ export const destroy = (id: string): Promise<number> =>
97
106
  CustomFieldDefinition.destroy({ where: { id } });
98
107
 
99
108
  /**
@@ -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
- if (!options.modelOptions?.useEntityIdFromInclude) {
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,
@@ -44,6 +44,14 @@ const castIfNeeded = (conditionValue: string): string => {
44
44
  }
45
45
  return '';
46
46
  };
47
+
48
+ const addQuotationIfNeeded = (conditionValue: string, valRep: string): string => {
49
+ if (typeof conditionValue === 'string') {
50
+ return `'"' || :${valRep} || '"'`;
51
+ }
52
+ return `:${valRep}`;
53
+ };
54
+
47
55
  const AND_DELIMETER = ' AND ';
48
56
  const OR_DELIMETER = ' OR ';
49
57
 
@@ -90,7 +98,7 @@ export const customFieldsFilterScope = (
90
98
  const valRandom = Object.keys(replacements).find(
91
99
  (randomString) => replacements[randomString] === v,
92
100
  );
93
- return `'"' || :${valRandom} || '"'`;
101
+ return addQuotationIfNeeded(v, valRandom);
94
102
  }).join(',');
95
103
  return `(${columnCondition} AND ${CV_VALUE_COLUMN} IN ( ${values} ))`;
96
104
  }
@@ -99,20 +107,20 @@ export const customFieldsFilterScope = (
99
107
  const valRep = Object.keys(replacements).find(
100
108
  (replacementKey) => replacements[replacementKey] === c.value,
101
109
  );
102
- return `( ${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(c.value)} ${c.operator} '"' || :${valRep} || '"' )`;
110
+ return `( ${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(c.value)} ${c.operator} ${addQuotationIfNeeded(c.value, valRep)} )`;
103
111
  }).join(AND_DELIMETER);
104
112
  }
105
113
  if (typeof condition === 'string' || typeof condition === 'number') {
106
114
  const conditionRep = Object.keys(replacements).find(
107
115
  (replacementKey) => replacements[replacementKey] === condition,
108
116
  );
109
- return `(${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(condition)} = '"' || :${conditionRep} || '"')`;
117
+ return `(${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(condition)} = ${addQuotationIfNeeded(condition, conditionRep)})`;
110
118
  }
111
119
  if (condition?.operator) {
112
120
  const valueRep = Object.keys(replacements).find(
113
121
  (replacementKey) => replacements[replacementKey] === condition.value,
114
122
  );
115
- return `( ${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(condition.value)} ${condition.operator} '"' || :${valueRep} || '"')`;
123
+ return `( ${columnCondition} AND ${CV_VALUE_COLUMN}${castIfNeeded(condition.value)} ${condition.operator} ${addQuotationIfNeeded(condition.value, valueRep)})`;
116
124
  }
117
125
  return false;
118
126
  },