@autofleet/sadot 0.6.2-temp-file-2 → 0.6.2-temp-file-4

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 (95) hide show
  1. package/dist/api/index.d.ts +2 -0
  2. package/dist/api/index.js +11 -0
  3. package/dist/api/v1/definition/index.d.ts +2 -0
  4. package/dist/api/v1/definition/index.js +118 -0
  5. package/dist/api/v1/definition/validations.d.ts +2 -0
  6. package/dist/api/v1/definition/validations.js +49 -0
  7. package/dist/api/v1/errors.d.ts +2 -0
  8. package/dist/api/v1/errors.js +15 -0
  9. package/dist/api/v1/index.d.ts +2 -0
  10. package/dist/api/v1/index.js +10 -0
  11. package/dist/errors/index.d.ts +16 -0
  12. package/dist/errors/index.js +45 -0
  13. package/dist/events/index.d.ts +4 -0
  14. package/dist/events/index.js +47 -0
  15. package/dist/hooks/create.d.ts +10 -0
  16. package/dist/hooks/create.js +74 -0
  17. package/dist/hooks/enrich.d.ts +7 -0
  18. package/dist/hooks/enrich.js +126 -0
  19. package/dist/hooks/find.d.ts +1 -0
  20. package/dist/hooks/find.js +29 -0
  21. package/dist/hooks/index.d.ts +6 -0
  22. package/dist/hooks/index.js +18 -0
  23. package/dist/hooks/update.d.ts +10 -0
  24. package/dist/hooks/update.js +59 -0
  25. package/dist/hooks/workaround.d.ts +10 -0
  26. package/dist/hooks/workaround.js +37 -0
  27. package/dist/index.d.ts +13 -0
  28. package/dist/index.js +54 -0
  29. package/dist/models/CustomFieldDefinition.d.ts +23 -0
  30. package/dist/models/CustomFieldDefinition.js +170 -0
  31. package/dist/models/CustomFieldValue.d.ts +15 -0
  32. package/dist/models/CustomFieldValue.js +143 -0
  33. package/dist/models/index.d.ts +10 -0
  34. package/dist/models/index.js +93 -0
  35. package/dist/models/tests/AssociatedTestModel.d.ts +12 -0
  36. package/dist/models/tests/AssociatedTestModel.js +71 -0
  37. package/dist/models/tests/TestModel.d.ts +12 -0
  38. package/dist/models/tests/TestModel.js +69 -0
  39. package/dist/models/tests/contextAwareModels/ContextAwareTestModel.d.ts +10 -0
  40. package/dist/models/tests/contextAwareModels/ContextAwareTestModel.js +55 -0
  41. package/dist/models/tests/contextAwareModels/ContextTestModel.d.ts +13 -0
  42. package/dist/models/tests/contextAwareModels/ContextTestModel.js +47 -0
  43. package/dist/repository/definition.d.ts +20 -0
  44. package/dist/repository/definition.js +92 -0
  45. package/dist/repository/value.d.ts +28 -0
  46. package/dist/repository/value.js +117 -0
  47. package/dist/scopes/filter.d.ts +23 -0
  48. package/dist/scopes/filter.js +55 -0
  49. package/dist/scopes/index.d.ts +2 -0
  50. package/dist/scopes/index.js +6 -0
  51. package/dist/tests/api/test-api.d.ts +2 -0
  52. package/dist/tests/api/test-api.js +56 -0
  53. package/dist/tests/functional/searching/index.d.ts +8 -0
  54. package/dist/tests/functional/searching/index.js +44 -0
  55. package/dist/tests/helpers/database-config.d.ts +16 -0
  56. package/dist/tests/helpers/database-config.js +17 -0
  57. package/dist/tests/helpers/index.d.ts +2 -0
  58. package/dist/tests/helpers/index.js +20 -0
  59. package/dist/tests/mocks/definition.mock.d.ts +43 -0
  60. package/dist/tests/mocks/definition.mock.js +68 -0
  61. package/dist/tests/mocks/events.mock.d.ts +3 -0
  62. package/dist/tests/mocks/events.mock.js +19 -0
  63. package/dist/tests/mocks/testModel.d.ts +12 -0
  64. package/dist/tests/mocks/testModel.js +35 -0
  65. package/dist/types/definition/index.d.ts +23 -0
  66. package/dist/types/definition/index.js +2 -0
  67. package/dist/types/index.d.ts +31 -0
  68. package/dist/types/index.js +2 -0
  69. package/dist/types/value/index.d.ts +15 -0
  70. package/dist/types/value/index.js +2 -0
  71. package/dist/utils/constants/index.d.ts +19 -0
  72. package/dist/utils/constants/index.js +22 -0
  73. package/dist/utils/db/index.d.ts +4 -0
  74. package/dist/utils/db/index.js +24 -0
  75. package/dist/utils/helpers/index.d.ts +25 -0
  76. package/dist/utils/helpers/index.js +34 -0
  77. package/dist/utils/init.d.ts +5 -0
  78. package/dist/utils/init.js +106 -0
  79. package/dist/utils/logger/index.d.ts +2 -0
  80. package/dist/utils/logger/index.js +6 -0
  81. package/dist/utils/scopeAttributes.d.ts +2 -0
  82. package/dist/utils/scopeAttributes.js +11 -0
  83. package/dist/utils/validations/index.d.ts +2 -0
  84. package/dist/utils/validations/index.js +20 -0
  85. package/dist/utils/validations/schema/custom-fields.d.ts +3 -0
  86. package/dist/utils/validations/schema/custom-fields.js +9 -0
  87. package/dist/utils/validations/type.d.ts +14 -0
  88. package/dist/utils/validations/type.js +2 -0
  89. package/dist/utils/validations/validators/index.d.ts +14 -0
  90. package/dist/utils/validations/validators/index.js +41 -0
  91. package/dist/utils/validations/validators/select.validator.d.ts +5 -0
  92. package/dist/utils/validations/validators/select.validator.js +9 -0
  93. package/dist/utils/validations/validators/status.validator.d.ts +12 -0
  94. package/dist/utils/validations/validators/status.validator.js +9 -0
  95. package/package.json +1 -1
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ // export the api object
7
+ const express_1 = require("express");
8
+ const v1_1 = __importDefault(require("./v1"));
9
+ const router = (0, express_1.Router)({ mergeParams: true });
10
+ router.use('/v1', v1_1.default);
11
+ exports.default = router;
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const errors_1 = require("@autofleet/errors");
30
+ const express_1 = require("express");
31
+ const errors_2 = __importDefault(require("../errors"));
32
+ const DefinitionRepo = __importStar(require("../../../repository/definition"));
33
+ const validations_1 = require("./validations");
34
+ const logger_1 = __importDefault(require("../../../utils/logger"));
35
+ const router = (0, express_1.Router)({ mergeParams: true });
36
+ const ENTITY = 'CustomFieldDefinition';
37
+ const toPascalCase = (str) => str.replace(/(^\w|-\w)/g, (subStr) => subStr.replace(/-/, '').toUpperCase());
38
+ /**
39
+ * Create
40
+ */
41
+ router.post('/', async (req, res) => {
42
+ const { modelName } = req.params;
43
+ const modelType = toPascalCase(modelName);
44
+ try {
45
+ const validatedPayload = await (0, validations_1.validateCustomFieldDefinitionCreation)(req.body);
46
+ const customFieldDefinition = await DefinitionRepo.create({
47
+ ...validatedPayload,
48
+ modelType,
49
+ });
50
+ return res.status(201).json(customFieldDefinition);
51
+ }
52
+ catch (err) {
53
+ logger_1.default.error('Failed to create custom field definition', err);
54
+ return (0, errors_2.default)(err, res, { message: `Error in create ${ENTITY} request` });
55
+ }
56
+ });
57
+ /**
58
+ * Get by id
59
+ */
60
+ router.get('/:customFieldDefinitionId', async (req, res) => {
61
+ const { customFieldDefinitionId } = req.params;
62
+ try {
63
+ const customFieldDefinition = await DefinitionRepo.findById(customFieldDefinitionId);
64
+ if (!customFieldDefinition) {
65
+ throw new errors_1.ResourceNotFoundError();
66
+ }
67
+ return res.json(customFieldDefinition);
68
+ }
69
+ catch (err) {
70
+ logger_1.default.error('Failed to fetch custom field definition', err);
71
+ return (0, errors_2.default)(err, res, { message: `Error in get ${ENTITY} request` });
72
+ }
73
+ });
74
+ /**
75
+ * Get all
76
+ */
77
+ router.get('/', async (req, res) => {
78
+ const { modelName } = req.params;
79
+ const { entityIds } = req.query;
80
+ const modelType = toPascalCase(modelName);
81
+ try {
82
+ const where = { modelType };
83
+ if (entityIds?.length > 0) {
84
+ where.entityId = entityIds;
85
+ }
86
+ const customFieldDefinitions = await DefinitionRepo.findAll({ ...where }, { withDisabled: true });
87
+ return res.json(customFieldDefinitions);
88
+ }
89
+ catch (err) {
90
+ logger_1.default.error('Failed to fetch custom field definitions', err);
91
+ return (0, errors_2.default)(err, res, { message: `Error in get all ${ENTITY} request` });
92
+ }
93
+ });
94
+ /**
95
+ * Update
96
+ */
97
+ router.patch('/:customFieldDefinitionId', async (req, res) => {
98
+ const { customFieldDefinitionId, modelName } = req.params;
99
+ const modelType = toPascalCase(modelName);
100
+ try {
101
+ // eslint-disable-next-line max-len
102
+ const validatedPayload = await (0, validations_1.validateCustomFieldDefinitionUpdate)(req.body);
103
+ const customFieldDefinition = await DefinitionRepo.findByWhere({
104
+ id: customFieldDefinitionId,
105
+ modelType,
106
+ });
107
+ if (!customFieldDefinition) {
108
+ throw new errors_1.ResourceNotFoundError();
109
+ }
110
+ const updatedCustomFieldDefinition = await DefinitionRepo.update(customFieldDefinitionId, { ...validatedPayload, modelType });
111
+ return res.status(200).json(updatedCustomFieldDefinition);
112
+ }
113
+ catch (err) {
114
+ logger_1.default.error('Failed to patch custom field definition', err);
115
+ return (0, errors_2.default)(err, res, { message: `Error in update ${ENTITY} request` });
116
+ }
117
+ });
118
+ exports.default = router;
@@ -0,0 +1,2 @@
1
+ export declare const validateCustomFieldDefinitionCreation: (payload: any) => Promise<any>;
2
+ export declare const validateCustomFieldDefinitionUpdate: (payload: any) => Promise<any>;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.validateCustomFieldDefinitionUpdate = exports.validateCustomFieldDefinitionCreation = void 0;
7
+ const joi_1 = __importDefault(require("joi"));
8
+ const constants_1 = require("../../../utils/constants");
9
+ /**
10
+ * Schema for the validation of custom field definition
11
+ * The only custom validation is for
12
+ * {@link CustomFieldDefinitionType.SELECT SELECT}
13
+ * and
14
+ * {@link CustomFieldDefinitionType.STATUS STATUS}
15
+ * field types.
16
+ * The rest of the field types are validated by Joi
17
+ */
18
+ const ValidationSchema = joi_1.default.when('fieldType', {
19
+ is: constants_1.CustomFieldDefinitionType.SELECT,
20
+ then: joi_1.default.array().items(joi_1.default.string()).min(1).unique(),
21
+ otherwise: joi_1.default.any(),
22
+ }).when('fieldType', {
23
+ is: constants_1.CustomFieldDefinitionType.STATUS,
24
+ then: joi_1.default.string().min(1).required(),
25
+ otherwise: joi_1.default.any(),
26
+ });
27
+ const CustomFieldDefinitionCreationSchema = joi_1.default.object({
28
+ name: joi_1.default.string().required(),
29
+ displayName: joi_1.default.string().required(),
30
+ validation: ValidationSchema,
31
+ fieldType: joi_1.default.string().valid(...Object.values(constants_1.CustomFieldDefinitionType)).required(),
32
+ entityId: joi_1.default.string().guid().required(),
33
+ entityType: joi_1.default.string().required(),
34
+ description: joi_1.default.string(),
35
+ required: joi_1.default.boolean(),
36
+ disabled: joi_1.default.boolean(),
37
+ });
38
+ const CustomFieldDefinitionUpdateSchema = joi_1.default.object({
39
+ displayName: joi_1.default.string(),
40
+ validation: ValidationSchema,
41
+ fieldType: joi_1.default.string().valid(...Object.values(constants_1.CustomFieldDefinitionType)),
42
+ description: joi_1.default.string().allow(null),
43
+ required: joi_1.default.boolean(),
44
+ disabled: joi_1.default.boolean(),
45
+ });
46
+ const validateCustomFieldDefinitionCreation = (payload) => CustomFieldDefinitionCreationSchema.validateAsync(payload, { abortEarly: false });
47
+ exports.validateCustomFieldDefinitionCreation = validateCustomFieldDefinitionCreation;
48
+ const validateCustomFieldDefinitionUpdate = (payload) => CustomFieldDefinitionUpdateSchema.validateAsync(payload, { abortEarly: false });
49
+ exports.validateCustomFieldDefinitionUpdate = validateCustomFieldDefinitionUpdate;
@@ -0,0 +1,2 @@
1
+ declare const _default: (err: any, res: any, additionalData?: any) => Promise<any>;
2
+ export default _default;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const errors_1 = require("@autofleet/errors");
4
+ const joi_1 = require("joi");
5
+ const sequelize_1 = require("sequelize");
6
+ exports.default = (err, res, additionalData = undefined) => {
7
+ let error = err;
8
+ if (err instanceof joi_1.ValidationError) {
9
+ error = new errors_1.BadRequest([err], null);
10
+ }
11
+ if (err instanceof sequelize_1.ValidationError) {
12
+ error = new errors_1.BadRequest([err], null);
13
+ }
14
+ return (0, errors_1.handleError)(error, res, additionalData);
15
+ };
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const express_1 = require("express");
7
+ const definition_1 = __importDefault(require("./definition"));
8
+ const router = (0, express_1.Router)({ mergeParams: true });
9
+ router.use('/custom-field-definitions/:modelName', definition_1.default);
10
+ exports.default = router;
@@ -0,0 +1,16 @@
1
+ import { BadRequest } from '@autofleet/errors';
2
+ export declare class MissingRequiredCustomFieldError extends BadRequest {
3
+ constructor(missingFields: string[]);
4
+ }
5
+ export declare class UnsupportedCustomFieldTypeError extends BadRequest {
6
+ constructor(fieldType: string);
7
+ }
8
+ export declare class UnsupportedCustomValidationError extends BadRequest {
9
+ constructor(fieldType: string);
10
+ }
11
+ export declare class InvalidValueError extends BadRequest {
12
+ constructor(value: any, fieldType: string);
13
+ }
14
+ export declare class MissingDefinitionError extends BadRequest {
15
+ constructor(fieldNames: string[]);
16
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MissingDefinitionError = exports.InvalidValueError = exports.UnsupportedCustomValidationError = exports.UnsupportedCustomFieldTypeError = exports.MissingRequiredCustomFieldError = void 0;
4
+ /* eslint-disable max-classes-per-file */
5
+ const errors_1 = require("@autofleet/errors");
6
+ class MissingRequiredCustomFieldError extends errors_1.BadRequest {
7
+ constructor(missingFields) {
8
+ const err = new Error(`The following custom fields are required: ${missingFields.join(',')}`);
9
+ super([err], null, missingFields);
10
+ this.message = 'MISSING_REQUIRED_CUSTOM_FIELDS';
11
+ }
12
+ }
13
+ exports.MissingRequiredCustomFieldError = MissingRequiredCustomFieldError;
14
+ class UnsupportedCustomFieldTypeError extends errors_1.BadRequest {
15
+ constructor(fieldType) {
16
+ const err = new Error(`Type "${fieldType}" is not supported`);
17
+ super([err], null, null);
18
+ this.message = 'UNSUPPORTED_CUSTOM_FIELD_TYPE';
19
+ }
20
+ }
21
+ exports.UnsupportedCustomFieldTypeError = UnsupportedCustomFieldTypeError;
22
+ class UnsupportedCustomValidationError extends errors_1.BadRequest {
23
+ constructor(fieldType) {
24
+ const err = new Error(`Validation for "${fieldType}" is not supported`);
25
+ super([err], null, null);
26
+ this.message = 'UNSUPPORTED_CUSTOM_VALIDATION_TYPE';
27
+ }
28
+ }
29
+ exports.UnsupportedCustomValidationError = UnsupportedCustomValidationError;
30
+ class InvalidValueError extends errors_1.BadRequest {
31
+ constructor(value, fieldType) {
32
+ const err = new Error(`Invalid "${fieldType}" value ${JSON.stringify(value)}`);
33
+ super([err], null, null);
34
+ this.message = 'INVALID_VALUE';
35
+ }
36
+ }
37
+ exports.InvalidValueError = InvalidValueError;
38
+ class MissingDefinitionError extends errors_1.BadRequest {
39
+ constructor(fieldNames) {
40
+ const err = new Error(`Missing custom field definition for field ${fieldNames.join(',')}`);
41
+ super([err], null, null);
42
+ this.message = 'MISSING_DEFINITION';
43
+ }
44
+ }
45
+ exports.MissingDefinitionError = MissingDefinitionError;
@@ -0,0 +1,4 @@
1
+ import Events from '@autofleet/events';
2
+ declare const events: Events;
3
+ export declare const sendDimEvent: (instance: any) => void;
4
+ export default events;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.sendDimEvent = void 0;
7
+ const events_1 = __importDefault(require("@autofleet/events"));
8
+ const logger_1 = __importDefault(require("../utils/logger"));
9
+ const events = new events_1.default({ logger: logger_1.default });
10
+ const KEYS_TO_CONVERT = ['value'];
11
+ const stringifyBools = (savedObject, keysToConvert) => {
12
+ if (Object.keys(savedObject).some((key) => keysToConvert.includes(key))) {
13
+ const objectToReturn = { ...savedObject };
14
+ keysToConvert.forEach((key) => {
15
+ if (typeof savedObject[key] === 'boolean') {
16
+ objectToReturn[key] = savedObject[key].toString();
17
+ }
18
+ });
19
+ return objectToReturn;
20
+ }
21
+ return savedObject;
22
+ };
23
+ const modelTableMapping = {
24
+ CustomFieldDefinition: {
25
+ tableName: 'dim_custom_field_definition',
26
+ eventVersion: '1',
27
+ },
28
+ CustomFieldValue: {
29
+ tableName: 'dim_custom_field_value',
30
+ eventVersion: '1',
31
+ },
32
+ };
33
+ const sendDimEvent = (instance) => {
34
+ const mapping = modelTableMapping[instance.constructor.name];
35
+ if (mapping) {
36
+ let objectToSend = instance.get();
37
+ try {
38
+ objectToSend = stringifyBools(instance.get(), KEYS_TO_CONVERT);
39
+ }
40
+ catch (err) {
41
+ logger_1.default.error('Failed to convert booleans in dim event payload', err);
42
+ }
43
+ events.sendObject(mapping.tableName, mapping.eventVersion, objectToSend);
44
+ }
45
+ };
46
+ exports.sendDimEvent = sendDimEvent;
47
+ exports.default = events;
@@ -0,0 +1,10 @@
1
+ import type { ModelOptions } from '../types';
2
+ /**
3
+ * A hook to create the custom fields when updating a model (more then one instance).
4
+ */
5
+ export declare const beforeBulkCreate: (options: any) => void;
6
+ /**
7
+ * A hook to create the custom fields when updating a model instance.
8
+ * TODO - cleanup if update fail
9
+ */
10
+ export declare const beforeCreate: (scopeAttributes: string[], modelOptions?: ModelOptions) => (instance: any, options: any) => Promise<void>;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.beforeCreate = exports.beforeBulkCreate = void 0;
30
+ const logger_1 = __importDefault(require("../utils/logger"));
31
+ const ValueRepo = __importStar(require("../repository/value"));
32
+ const DefinitionRepo = __importStar(require("../repository/definition"));
33
+ const errors_1 = require("../errors");
34
+ const scopeAttributes_1 = __importDefault(require("../utils/scopeAttributes"));
35
+ /**
36
+ * A hook to create the custom fields when updating a model (more then one instance).
37
+ */
38
+ const beforeBulkCreate = (options) => {
39
+ // This will activate the beforeCreate hook on each updating instance.
40
+ // eslint-disable-next-line no-param-reassign
41
+ options.individualHooks = true;
42
+ };
43
+ exports.beforeBulkCreate = beforeBulkCreate;
44
+ /**
45
+ * A hook to create the custom fields when updating a model instance.
46
+ * TODO - cleanup if update fail
47
+ */
48
+ const beforeCreate = (scopeAttributes, modelOptions = {}) => async (instance, options) => {
49
+ logger_1.default.debug('sadot - before create hook');
50
+ const { fields } = options;
51
+ const modelType = instance.constructor.name;
52
+ 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);
55
+ 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
+ });
67
+ // eslint-disable-next-line no-param-reassign
68
+ fields.splice(customFieldsIdx, 1);
69
+ }
70
+ else if (requiredFieldsNames?.length > 0) {
71
+ throw new errors_1.MissingRequiredCustomFieldError(requiredFieldsNames);
72
+ }
73
+ };
74
+ exports.beforeCreate = beforeCreate;
@@ -0,0 +1,7 @@
1
+ import type { ModelOptions } from '../types';
2
+ type SupportedHookTypes = 'afterFind' | 'afterCreate' | 'afterUpdate';
3
+ /**
4
+ * A hook to attach the custom fields when fetching a model instances.
5
+ */
6
+ declare const enrichResults: (modelType: string, scopeAttributes: string[], hookType?: SupportedHookTypes, modelOptions?: ModelOptions) => (instancesOrInstance: any | any[], options: any) => Promise<void>;
7
+ export default enrichResults;
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ /* eslint-disable no-param-reassign */
30
+ const ValueRepo = __importStar(require("../repository/value"));
31
+ const DefinitionRepo = __importStar(require("../repository/definition"));
32
+ const scopeAttributes_1 = __importDefault(require("../utils/scopeAttributes"));
33
+ /**
34
+ * Serialize custom fields value into the format of {[name] -> [fieldData]}
35
+ */
36
+ const serializeCustomFields = (customFieldValues, customFieldDefinitionsHash) => {
37
+ const customFields = customFieldValues.reduce((acc, cfv) => ({
38
+ ...acc,
39
+ ...(customFieldDefinitionsHash[cfv.customFieldDefinitionId]
40
+ && { [customFieldDefinitionsHash[cfv.customFieldDefinitionId].name]: cfv.value }),
41
+ }), {});
42
+ return customFields;
43
+ };
44
+ /**
45
+ * A hook to attach the custom fields when fetching a model instances.
46
+ */
47
+ const enrichResults = (modelType, scopeAttributes, hookType, modelOptions = {}) => async (instancesOrInstance, options) => {
48
+ if (options.originalAttributes?.length > 0
49
+ && !options.originalAttributes?.includes?.('customFields')) {
50
+ return;
51
+ }
52
+ const primaryKey = 'id';
53
+ let instances = Array.isArray(instancesOrInstance)
54
+ ? instancesOrInstance
55
+ : [instancesOrInstance];
56
+ instances = instances.filter(Boolean);
57
+ const identifiers = (0, scopeAttributes_1.default)(instances, scopeAttributes);
58
+ const uniqueIdentifiers = [...new Set(identifiers)].filter(Boolean);
59
+ const identifierCustomFieldDefinitionsMapping = uniqueIdentifiers.reduce((map, identifier) => ({
60
+ ...map,
61
+ [identifier]: [],
62
+ }), {});
63
+ const customFieldDefinitions = await DefinitionRepo.findByEntityIds(modelType, uniqueIdentifiers, { transaction: options.transaction, modelOptions });
64
+ if (modelOptions?.include && modelOptions.useEntityIdFromInclude) {
65
+ // if we pass useEntityIdFromInclude,
66
+ // map the entity from the options to the identifierCustomFieldDefinitionsMapping
67
+ modelOptions.include(identifiers).forEach(({ model }) => {
68
+ customFieldDefinitions.forEach((cfd) => {
69
+ const entityId = cfd[`${model.name}.entityId`];
70
+ identifierCustomFieldDefinitionsMapping[entityId] = [];
71
+ });
72
+ });
73
+ }
74
+ const definitionsMap = customFieldDefinitions.reduce((map, definition) => ({
75
+ ...map,
76
+ [definition.id]: definition,
77
+ }), {});
78
+ customFieldDefinitions.forEach((cfd) => {
79
+ identifierCustomFieldDefinitionsMapping[cfd.entityId].push(cfd);
80
+ });
81
+ // Get the values per instates ids:
82
+ const instancesIds = instances.map((i) => i[primaryKey]);
83
+ const customFieldValues = await ValueRepo.findValuesByModelIds(instancesIds, { transaction: options.transaction });
84
+ // Group fields by modelId
85
+ const valuesGroupByInstance = customFieldValues.reduce((acc, v) => {
86
+ const { modelId } = v;
87
+ if (!acc[modelId]) {
88
+ acc[modelId] = [];
89
+ }
90
+ acc[modelId].push(v);
91
+ return acc;
92
+ }, {});
93
+ // Attach custom fields to the instances
94
+ instances.forEach((instance) => {
95
+ const customFields = {};
96
+ const { id } = instance;
97
+ const instanceValues = valuesGroupByInstance[id];
98
+ if (instanceValues) {
99
+ const serializedCustomFields = serializeCustomFields(instanceValues, definitionsMap);
100
+ Object.assign(customFields, serializedCustomFields);
101
+ }
102
+ scopeAttributes.forEach((attribute) => {
103
+ const identifier = instance[attribute];
104
+ const entityCustomFieldDefinitions = identifierCustomFieldDefinitionsMapping[identifier];
105
+ if (entityCustomFieldDefinitions?.length > 0) {
106
+ entityCustomFieldDefinitions.forEach((customFieldDefinition) => {
107
+ if (customFields[customFieldDefinition.name] === undefined) {
108
+ customFields[customFieldDefinition.name] = null;
109
+ }
110
+ });
111
+ }
112
+ });
113
+ instance.customFields = customFields;
114
+ options.attributesToRemove?.forEach?.((attribute) => {
115
+ delete instance.dataValues?.[attribute];
116
+ // if raw:
117
+ delete instance?.[attribute];
118
+ });
119
+ // sequelize will think customFields changed also in 'find', so we need to mark it as unchanged
120
+ if (hookType === 'afterFind') {
121
+ // changed() could be undefined, i.e in raw: true
122
+ instance?.changed?.('customFields', false);
123
+ }
124
+ });
125
+ };
126
+ exports.default = enrichResults;
@@ -0,0 +1 @@
1
+ export declare const beforeFind: (scopeAttributes: string[]) => (options: any) => void;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.beforeFind = void 0;
7
+ /* eslint-disable no-param-reassign */
8
+ const logger_1 = __importDefault(require("../utils/logger"));
9
+ const doScopeAttributesMissing = (scopeAttributes, queryAttributes) => {
10
+ const attributes = scopeAttributes
11
+ .filter((attribute) => !queryAttributes.includes(attribute));
12
+ if (!queryAttributes.includes?.('id')) {
13
+ attributes.push('id');
14
+ }
15
+ return attributes;
16
+ };
17
+ // eslint-disable-next-line import/prefer-default-export
18
+ const beforeFind = (scopeAttributes) => (options) => {
19
+ const { attributes: queryAttributes } = options;
20
+ if (queryAttributes?.includes?.('customFields')) {
21
+ const missingScopeAttributes = doScopeAttributesMissing(scopeAttributes, queryAttributes);
22
+ logger_1.default.debug('sadot - before find hook');
23
+ if (missingScopeAttributes?.length > 0) {
24
+ queryAttributes.push(...missingScopeAttributes);
25
+ options.attributesToRemove = missingScopeAttributes;
26
+ }
27
+ }
28
+ };
29
+ exports.beforeFind = beforeFind;
@@ -0,0 +1,6 @@
1
+ import enrichResults from './enrich';
2
+ import { beforeFind } from './find';
3
+ import { beforeBulkUpdate, beforeUpdate } from './update';
4
+ import { beforeBulkCreate, beforeCreate } from './create';
5
+ import workaround from './workaround';
6
+ export { enrichResults, beforeFind, beforeBulkUpdate, beforeUpdate, beforeBulkCreate, beforeCreate, workaround, };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.workaround = exports.beforeCreate = exports.beforeBulkCreate = exports.beforeUpdate = exports.beforeBulkUpdate = exports.beforeFind = exports.enrichResults = void 0;
7
+ const enrich_1 = __importDefault(require("./enrich"));
8
+ exports.enrichResults = enrich_1.default;
9
+ const find_1 = require("./find");
10
+ Object.defineProperty(exports, "beforeFind", { enumerable: true, get: function () { return find_1.beforeFind; } });
11
+ const update_1 = require("./update");
12
+ Object.defineProperty(exports, "beforeBulkUpdate", { enumerable: true, get: function () { return update_1.beforeBulkUpdate; } });
13
+ Object.defineProperty(exports, "beforeUpdate", { enumerable: true, get: function () { return update_1.beforeUpdate; } });
14
+ const create_1 = require("./create");
15
+ Object.defineProperty(exports, "beforeBulkCreate", { enumerable: true, get: function () { return create_1.beforeBulkCreate; } });
16
+ Object.defineProperty(exports, "beforeCreate", { enumerable: true, get: function () { return create_1.beforeCreate; } });
17
+ const workaround_1 = __importDefault(require("./workaround"));
18
+ exports.workaround = workaround_1.default;
@@ -0,0 +1,10 @@
1
+ import type { ModelOptions } from '../types';
2
+ /**
3
+ * A hook to update the custom fields when updating a model (more then one instance).
4
+ */
5
+ export declare const beforeBulkUpdate: (options: any) => void;
6
+ /**
7
+ * A hook to update the custom fields when updating a model instance.
8
+ * TODO - cleanup if update fail
9
+ */
10
+ export declare const beforeUpdate: (scopeAttributes: string[], modelOptions?: ModelOptions) => (instance: any, options: any) => Promise<void>;