@autofleet/sadot 0.3.2 → 0.4.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.
- package/.nvmrc +1 -0
- package/dist/jest.config.d.ts +12 -0
- package/dist/{api → src/api}/index.js +0 -1
- package/dist/{api → src/api}/v1/definition/index.js +19 -26
- package/dist/{api → src/api}/v1/definition/validations.js +0 -1
- package/dist/src/api/v1/errors.d.ts +2 -0
- package/dist/{api → src/api}/v1/errors.js +1 -2
- package/dist/{api → src/api}/v1/index.js +0 -1
- package/dist/{errors → src/errors}/index.js +0 -1
- package/dist/{events → src/events}/index.js +1 -2
- package/dist/{hooks → src/hooks}/create.js +6 -16
- package/dist/{hooks → src/hooks}/enrich.js +23 -27
- package/dist/{hooks → src/hooks}/find.js +3 -5
- package/dist/{hooks → src/hooks}/index.js +0 -1
- package/dist/{hooks → src/hooks}/update.js +3 -13
- package/dist/{hooks → src/hooks}/workaround.js +3 -13
- package/dist/{index.d.ts → src/index.d.ts} +2 -1
- package/dist/src/index.js +52 -0
- package/dist/{models → src/models}/CustomFieldDefinition.js +1 -2
- package/dist/{models → src/models}/CustomFieldValue.js +20 -34
- package/dist/{models → src/models}/index.js +13 -23
- package/dist/{models → src/models}/tests/AssociatedTestModel.js +0 -1
- package/dist/{models → src/models}/tests/TestModel.d.ts +1 -0
- package/dist/{models → src/models}/tests/TestModel.js +6 -1
- package/dist/{repository → src/repository}/definition.js +19 -33
- package/dist/{repository → src/repository}/value.js +18 -28
- package/dist/src/scopes/filter.d.ts +23 -0
- package/dist/src/scopes/filter.js +43 -0
- package/dist/src/scopes/index.d.ts +2 -0
- package/dist/src/scopes/index.js +6 -0
- package/dist/{tests → src/tests}/api/test-api.js +12 -22
- package/dist/{tests → src/tests}/helpers/database-config.js +0 -1
- package/dist/src/tests/helpers/index.js +18 -0
- package/dist/{tests → src/tests}/mocks/definition.mock.js +18 -13
- package/dist/{tests → src/tests}/mocks/events.mock.js +0 -1
- package/dist/{tests → src/tests}/mocks/testModel.js +4 -14
- package/dist/{types → src/types}/definition/index.js +0 -1
- package/dist/{types → src/types}/index.js +0 -1
- package/dist/{types → src/types}/value/index.js +0 -1
- package/dist/src/utils/constants/index.d.ts +2 -0
- package/dist/{utils → src/utils}/constants/index.js +2 -2
- package/dist/{utils → src/utils}/db/index.js +0 -1
- package/dist/src/utils/init.d.ts +4 -0
- package/dist/{index.js → src/utils/init.js} +41 -57
- package/dist/{utils → src/utils}/logger/index.js +0 -1
- package/dist/{utils → src/utils}/validations/custom-fields.js +0 -1
- package/dist/{utils → src/utils}/validations/custom.js +1 -2
- package/dist/{utils → src/utils}/validations/index.js +0 -1
- package/dist/{utils → src/utils}/validations/type.js +0 -1
- package/dist/{utils → src/utils}/validations/validators.js +0 -1
- package/package.json +2 -2
- package/src/api/v1/errors.ts +1 -1
- package/src/hooks/find.ts +1 -1
- package/src/index.ts +9 -65
- package/src/models/tests/TestModel.ts +5 -0
- package/src/scopes/filter.ts +63 -0
- package/src/scopes/index.ts +6 -0
- package/src/utils/constants/index.ts +2 -0
- package/src/utils/init.ts +101 -0
- package/tsconfig.json +9 -26
- package/dist/api/index.js.map +0 -1
- package/dist/api/v1/definition/index.js.map +0 -1
- package/dist/api/v1/definition/validations.js.map +0 -1
- package/dist/api/v1/errors.d.ts +0 -2
- package/dist/api/v1/errors.js.map +0 -1
- package/dist/api/v1/index.js.map +0 -1
- package/dist/errors/index.js.map +0 -1
- package/dist/events/index.js.map +0 -1
- package/dist/hooks/create.js.map +0 -1
- package/dist/hooks/enrich.js.map +0 -1
- package/dist/hooks/find.js.map +0 -1
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/update.js.map +0 -1
- package/dist/hooks/workaround.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/models/CustomFieldDefinition.js.map +0 -1
- package/dist/models/CustomFieldValue.js.map +0 -1
- package/dist/models/index.js.map +0 -1
- package/dist/models/tests/AssociatedTestModel.js.map +0 -1
- package/dist/models/tests/TestModel.js.map +0 -1
- package/dist/repository/definition.js.map +0 -1
- package/dist/repository/value.js.map +0 -1
- package/dist/tests/api/test-api.js.map +0 -1
- package/dist/tests/helpers/database-config.js.map +0 -1
- package/dist/tests/helpers/index.js +0 -28
- package/dist/tests/helpers/index.js.map +0 -1
- package/dist/tests/mocks/definition.mock.js.map +0 -1
- package/dist/tests/mocks/events.mock.js.map +0 -1
- package/dist/tests/mocks/testModel.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/dist/types/definition/index.js.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/types/value/index.js.map +0 -1
- package/dist/utils/constants/index.d.ts +0 -1
- package/dist/utils/constants/index.js.map +0 -1
- package/dist/utils/db/index.js.map +0 -1
- package/dist/utils/logger/index.js.map +0 -1
- package/dist/utils/validations/custom-fields.js.map +0 -1
- package/dist/utils/validations/custom.js.map +0 -1
- package/dist/utils/validations/index.js.map +0 -1
- package/dist/utils/validations/type.js.map +0 -1
- package/dist/utils/validations/validators.js.map +0 -1
- package/dist/{api → src/api}/index.d.ts +0 -0
- package/dist/{api → src/api}/v1/definition/index.d.ts +0 -0
- package/dist/{api → src/api}/v1/definition/validations.d.ts +0 -0
- package/dist/{api → src/api}/v1/index.d.ts +0 -0
- package/dist/{errors → src/errors}/index.d.ts +0 -0
- package/dist/{events → src/events}/index.d.ts +0 -0
- package/dist/{hooks → src/hooks}/create.d.ts +0 -0
- package/dist/{hooks → src/hooks}/enrich.d.ts +0 -0
- package/dist/{hooks → src/hooks}/find.d.ts +0 -0
- package/dist/{hooks → src/hooks}/index.d.ts +0 -0
- package/dist/{hooks → src/hooks}/update.d.ts +0 -0
- package/dist/{hooks → src/hooks}/workaround.d.ts +0 -0
- package/dist/{models → src/models}/CustomFieldDefinition.d.ts +0 -0
- package/dist/{models → src/models}/CustomFieldValue.d.ts +0 -0
- package/dist/{models → src/models}/index.d.ts +0 -0
- package/dist/{models → src/models}/tests/AssociatedTestModel.d.ts +0 -0
- package/dist/{repository → src/repository}/definition.d.ts +0 -0
- package/dist/{repository → src/repository}/value.d.ts +0 -0
- package/dist/{tests → src/tests}/api/test-api.d.ts +0 -0
- package/dist/{tests → src/tests}/helpers/database-config.d.ts +0 -0
- package/dist/{tests → src/tests}/helpers/index.d.ts +0 -0
- package/dist/{tests → src/tests}/mocks/definition.mock.d.ts +4 -4
- /package/dist/{tests → src/tests}/mocks/events.mock.d.ts +0 -0
- /package/dist/{tests → src/tests}/mocks/testModel.d.ts +0 -0
- /package/dist/{types → src/types}/definition/index.d.ts +0 -0
- /package/dist/{types → src/types}/index.d.ts +0 -0
- /package/dist/{types → src/types}/value/index.d.ts +0 -0
- /package/dist/{utils → src/utils}/db/index.d.ts +0 -0
- /package/dist/{utils → src/utils}/logger/index.d.ts +0 -0
- /package/dist/{utils → src/utils}/validations/custom-fields.d.ts +0 -0
- /package/dist/{utils → src/utils}/validations/custom.d.ts +0 -0
- /package/dist/{utils → src/utils}/validations/index.d.ts +0 -0
- /package/dist/{utils → src/utils}/validations/type.d.ts +0 -0
- /package/dist/{utils → src/utils}/validations/validators.d.ts +0 -0
package/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
18.17.1
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const testEnvironment: string;
|
|
2
|
+
export const roots: string[];
|
|
3
|
+
export const transform: {
|
|
4
|
+
'^.+\\.tsx?$': string;
|
|
5
|
+
};
|
|
6
|
+
export const testRegex: string;
|
|
7
|
+
export const moduleFileExtensions: string[];
|
|
8
|
+
export namespace coverageThreshold {
|
|
9
|
+
namespace global {
|
|
10
|
+
const lines: number;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -22,15 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
27
|
};
|
|
@@ -47,26 +38,29 @@ const toPascalCase = (str) => str.replace(/(^\w|-\w)/g, (subStr) => subStr.repla
|
|
|
47
38
|
/**
|
|
48
39
|
* Create
|
|
49
40
|
*/
|
|
50
|
-
router.post('/', (req, res) =>
|
|
41
|
+
router.post('/', async (req, res) => {
|
|
51
42
|
const { modelName } = req.params;
|
|
52
43
|
const modelType = toPascalCase(modelName);
|
|
53
44
|
try {
|
|
54
|
-
const validatedPayload =
|
|
55
|
-
const customFieldDefinition =
|
|
45
|
+
const validatedPayload = await (0, validations_1.validateCustomFieldDefinitionCreation)(req.body);
|
|
46
|
+
const customFieldDefinition = await DefinitionRepo.create({
|
|
47
|
+
...validatedPayload,
|
|
48
|
+
modelType,
|
|
49
|
+
});
|
|
56
50
|
return res.status(201).json(customFieldDefinition);
|
|
57
51
|
}
|
|
58
52
|
catch (err) {
|
|
59
53
|
logger_1.default.error('Failed to create custom field definition', err);
|
|
60
54
|
return (0, errors_2.default)(err, res, { message: `Error in create ${ENTITY} request` });
|
|
61
55
|
}
|
|
62
|
-
})
|
|
56
|
+
});
|
|
63
57
|
/**
|
|
64
58
|
* Get by id
|
|
65
59
|
*/
|
|
66
|
-
router.get('/:customFieldDefinitionId', (req, res) =>
|
|
60
|
+
router.get('/:customFieldDefinitionId', async (req, res) => {
|
|
67
61
|
const { customFieldDefinitionId } = req.params;
|
|
68
62
|
try {
|
|
69
|
-
const customFieldDefinition =
|
|
63
|
+
const customFieldDefinition = await DefinitionRepo.findById(customFieldDefinitionId);
|
|
70
64
|
if (!customFieldDefinition) {
|
|
71
65
|
throw new errors_1.ResourceNotFoundError();
|
|
72
66
|
}
|
|
@@ -76,50 +70,49 @@ router.get('/:customFieldDefinitionId', (req, res) => __awaiter(void 0, void 0,
|
|
|
76
70
|
logger_1.default.error('Failed to fetch custom field definition', err);
|
|
77
71
|
return (0, errors_2.default)(err, res, { message: `Error in get ${ENTITY} request` });
|
|
78
72
|
}
|
|
79
|
-
})
|
|
73
|
+
});
|
|
80
74
|
/**
|
|
81
75
|
* Get all
|
|
82
76
|
*/
|
|
83
|
-
router.get('/', (req, res) =>
|
|
77
|
+
router.get('/', async (req, res) => {
|
|
84
78
|
const { modelName } = req.params;
|
|
85
79
|
const { entityIds } = req.query;
|
|
86
80
|
const modelType = toPascalCase(modelName);
|
|
87
81
|
try {
|
|
88
82
|
const where = { modelType };
|
|
89
|
-
if (
|
|
83
|
+
if (entityIds?.length > 0) {
|
|
90
84
|
where.entityId = entityIds;
|
|
91
85
|
}
|
|
92
|
-
const customFieldDefinitions =
|
|
86
|
+
const customFieldDefinitions = await DefinitionRepo.findAll({ ...where }, { withDisabled: true });
|
|
93
87
|
return res.json(customFieldDefinitions);
|
|
94
88
|
}
|
|
95
89
|
catch (err) {
|
|
96
90
|
logger_1.default.error('Failed to fetch custom field definitions', err);
|
|
97
91
|
return (0, errors_2.default)(err, res, { message: `Error in get all ${ENTITY} request` });
|
|
98
92
|
}
|
|
99
|
-
})
|
|
93
|
+
});
|
|
100
94
|
/**
|
|
101
95
|
* Update
|
|
102
96
|
*/
|
|
103
|
-
router.patch('/:customFieldDefinitionId', (req, res) =>
|
|
97
|
+
router.patch('/:customFieldDefinitionId', async (req, res) => {
|
|
104
98
|
const { customFieldDefinitionId, modelName } = req.params;
|
|
105
99
|
const modelType = toPascalCase(modelName);
|
|
106
100
|
try {
|
|
107
101
|
// eslint-disable-next-line max-len
|
|
108
|
-
const validatedPayload =
|
|
109
|
-
const customFieldDefinition =
|
|
102
|
+
const validatedPayload = await (0, validations_1.validateCustomFieldDefinitionUpdate)(req.body);
|
|
103
|
+
const customFieldDefinition = await DefinitionRepo.findByWhere({
|
|
110
104
|
id: customFieldDefinitionId,
|
|
111
105
|
modelType,
|
|
112
106
|
});
|
|
113
107
|
if (!customFieldDefinition) {
|
|
114
108
|
throw new errors_1.ResourceNotFoundError();
|
|
115
109
|
}
|
|
116
|
-
const updatedCustomFieldDefinition =
|
|
110
|
+
const updatedCustomFieldDefinition = await DefinitionRepo.update(customFieldDefinitionId, { ...validatedPayload, modelType });
|
|
117
111
|
return res.status(200).json(updatedCustomFieldDefinition);
|
|
118
112
|
}
|
|
119
113
|
catch (err) {
|
|
120
114
|
logger_1.default.error('Failed to patch custom field definition', err);
|
|
121
115
|
return (0, errors_2.default)(err, res, { message: `Error in update ${ENTITY} request` });
|
|
122
116
|
}
|
|
123
|
-
})
|
|
117
|
+
});
|
|
124
118
|
exports.default = router;
|
|
125
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -34,4 +34,3 @@ const validateCustomFieldDefinitionCreation = (payload) => CustomFieldDefinition
|
|
|
34
34
|
exports.validateCustomFieldDefinitionCreation = validateCustomFieldDefinitionCreation;
|
|
35
35
|
const validateCustomFieldDefinitionUpdate = (payload) => CustomFieldDefinitionUpdateSchema.validateAsync(payload, { abortEarly: false });
|
|
36
36
|
exports.validateCustomFieldDefinitionUpdate = validateCustomFieldDefinitionUpdate;
|
|
37
|
-
//# sourceMappingURL=validations.js.map
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const errors_1 = require("@autofleet/errors");
|
|
4
4
|
const joi_1 = require("@hapi/joi");
|
|
5
5
|
const sequelize_1 = require("sequelize");
|
|
6
|
-
exports.default = (err, res, additionalData =
|
|
6
|
+
exports.default = (err, res, additionalData = undefined) => {
|
|
7
7
|
let error = err;
|
|
8
8
|
if (err instanceof joi_1.ValidationError) {
|
|
9
9
|
error = new errors_1.BadRequest([err], null);
|
|
@@ -13,4 +13,3 @@ exports.default = (err, res, additionalData = {}) => {
|
|
|
13
13
|
}
|
|
14
14
|
return (0, errors_1.handleError)(error, res, additionalData);
|
|
15
15
|
};
|
|
16
|
-
//# sourceMappingURL=errors.js.map
|
|
@@ -10,7 +10,7 @@ const events = new events_1.default({ logger: logger_1.default });
|
|
|
10
10
|
const KEYS_TO_CONVERT = ['value'];
|
|
11
11
|
const stringifyBools = (savedObject, keysToConvert) => {
|
|
12
12
|
if (Object.keys(savedObject).some((key) => keysToConvert.includes(key))) {
|
|
13
|
-
const objectToReturn =
|
|
13
|
+
const objectToReturn = { ...savedObject };
|
|
14
14
|
keysToConvert.forEach((key) => {
|
|
15
15
|
if (typeof savedObject[key] === 'boolean') {
|
|
16
16
|
objectToReturn[key] = savedObject[key].toString();
|
|
@@ -45,4 +45,3 @@ const sendDimEvent = (instance) => {
|
|
|
45
45
|
};
|
|
46
46
|
exports.sendDimEvent = sendDimEvent;
|
|
47
47
|
exports.default = events;
|
|
48
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -22,15 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
27
|
};
|
|
@@ -53,28 +44,27 @@ exports.beforeBulkCreate = beforeBulkCreate;
|
|
|
53
44
|
* A hook to create the custom fields when updating a model instance.
|
|
54
45
|
* TODO - cleanup if update fail
|
|
55
46
|
*/
|
|
56
|
-
const beforeCreate = (scopeAttributes) => (instance, options) =>
|
|
47
|
+
const beforeCreate = (scopeAttributes) => async (instance, options) => {
|
|
57
48
|
logger_1.default.debug('sadot - before create hook');
|
|
58
49
|
const { fields } = options;
|
|
59
50
|
const modelType = instance.constructor.name;
|
|
60
51
|
const identifiers = scopeAttributes.map((attribute) => instance[attribute]);
|
|
61
52
|
// get all model's required definitions
|
|
62
|
-
const requiredFieldsNames =
|
|
53
|
+
const requiredFieldsNames = await DefinitionRepo.getRequiredFields(modelType, instance.id, identifiers);
|
|
63
54
|
const customFieldsIdx = fields.indexOf('customFields');
|
|
64
55
|
const { customFields } = instance;
|
|
65
56
|
if (customFieldsIdx > -1 && customFields) {
|
|
66
57
|
const fieldsNames = Object.keys(customFields);
|
|
67
58
|
const missingFields = requiredFieldsNames.filter((name) => !fieldsNames.includes(name));
|
|
68
|
-
if (
|
|
59
|
+
if (missingFields?.length > 0) {
|
|
69
60
|
throw new errors_1.MissingRequiredCustomFieldError(missingFields);
|
|
70
61
|
}
|
|
71
|
-
|
|
62
|
+
await ValueRepo.updateValues(modelType, instance.id, identifiers, customFields, { transaction: options.transaction });
|
|
72
63
|
// eslint-disable-next-line no-param-reassign
|
|
73
64
|
fields.splice(customFieldsIdx, 1);
|
|
74
65
|
}
|
|
75
|
-
else if (
|
|
66
|
+
else if (requiredFieldsNames?.length > 0) {
|
|
76
67
|
throw new errors_1.MissingRequiredCustomFieldError(requiredFieldsNames);
|
|
77
68
|
}
|
|
78
|
-
}
|
|
69
|
+
};
|
|
79
70
|
exports.beforeCreate = beforeCreate;
|
|
80
|
-
//# sourceMappingURL=create.js.map
|
|
@@ -22,15 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
26
|
/* eslint-disable no-param-reassign */
|
|
36
27
|
const ValueRepo = __importStar(require("../repository/value"));
|
|
@@ -39,17 +30,19 @@ const DefinitionRepo = __importStar(require("../repository/definition"));
|
|
|
39
30
|
* Serialize custom fields value into the format of {[name] -> [fieldData]}
|
|
40
31
|
*/
|
|
41
32
|
const serializeCustomFields = (customFieldValues, customFieldDefinitionsHash) => {
|
|
42
|
-
const customFields = customFieldValues.reduce((acc, cfv) => (
|
|
43
|
-
|
|
33
|
+
const customFields = customFieldValues.reduce((acc, cfv) => ({
|
|
34
|
+
...acc,
|
|
35
|
+
...(customFieldDefinitionsHash[cfv.customFieldDefinitionId]
|
|
36
|
+
&& { [customFieldDefinitionsHash[cfv.customFieldDefinitionId].name]: cfv.value }),
|
|
37
|
+
}), {});
|
|
44
38
|
return customFields;
|
|
45
39
|
};
|
|
46
40
|
/**
|
|
47
41
|
* A hook to attach the custom fields when fetching a model instances.
|
|
48
42
|
*/
|
|
49
|
-
const enrichResults = (modelType, scopeAttributes) => (instancesOrInstance, options) =>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
&& !((_c = (_b = options.originalAttributes) === null || _b === void 0 ? void 0 : _b.includes) === null || _c === void 0 ? void 0 : _c.call(_b, 'customFields'))) {
|
|
43
|
+
const enrichResults = (modelType, scopeAttributes) => async (instancesOrInstance, options) => {
|
|
44
|
+
if (options.originalAttributes?.length > 0
|
|
45
|
+
&& !options.originalAttributes?.includes?.('customFields')) {
|
|
53
46
|
return;
|
|
54
47
|
}
|
|
55
48
|
const primaryKey = 'id';
|
|
@@ -60,15 +53,21 @@ const enrichResults = (modelType, scopeAttributes) => (instancesOrInstance, opti
|
|
|
60
53
|
const identifiers = instances.map((instance) => scopeAttributes
|
|
61
54
|
.map((attr) => instance[attr])).flat();
|
|
62
55
|
const uniqueIdentifiers = [...new Set(identifiers)].filter(Boolean);
|
|
63
|
-
const identifierCustomFieldDefinitionsMapping = uniqueIdentifiers.reduce((map, identifier) => (
|
|
64
|
-
|
|
65
|
-
|
|
56
|
+
const identifierCustomFieldDefinitionsMapping = uniqueIdentifiers.reduce((map, identifier) => ({
|
|
57
|
+
...map,
|
|
58
|
+
[identifier]: [],
|
|
59
|
+
}), {});
|
|
60
|
+
const customFieldDefinitions = await DefinitionRepo.findByEntityIds(modelType, uniqueIdentifiers, { transaction: options.transaction });
|
|
61
|
+
const definitionsMap = customFieldDefinitions.reduce((map, definition) => ({
|
|
62
|
+
...map,
|
|
63
|
+
[definition.id]: definition,
|
|
64
|
+
}), {});
|
|
66
65
|
customFieldDefinitions.forEach((cfd) => {
|
|
67
66
|
identifierCustomFieldDefinitionsMapping[cfd.entityId].push(cfd);
|
|
68
67
|
});
|
|
69
68
|
// Get the values per instates ids:
|
|
70
69
|
const instancesIds = instances.map((i) => i[primaryKey]);
|
|
71
|
-
const customFieldValues =
|
|
70
|
+
const customFieldValues = await ValueRepo.findValuesByModelIds(instancesIds, { transaction: options.transaction });
|
|
72
71
|
// Group fields by modelId
|
|
73
72
|
const valuesGroupByInstance = customFieldValues.reduce((acc, v) => {
|
|
74
73
|
const { modelId } = v;
|
|
@@ -80,7 +79,6 @@ const enrichResults = (modelType, scopeAttributes) => (instancesOrInstance, opti
|
|
|
80
79
|
}, {});
|
|
81
80
|
// Attach custom fields to the instances
|
|
82
81
|
instances.forEach((instance) => {
|
|
83
|
-
var _a, _b;
|
|
84
82
|
const customFields = {};
|
|
85
83
|
const { id } = instance;
|
|
86
84
|
const instanceValues = valuesGroupByInstance[id];
|
|
@@ -91,7 +89,7 @@ const enrichResults = (modelType, scopeAttributes) => (instancesOrInstance, opti
|
|
|
91
89
|
scopeAttributes.forEach((attribute) => {
|
|
92
90
|
const identifier = instance[attribute];
|
|
93
91
|
const entityCustomFieldDefinitions = identifierCustomFieldDefinitionsMapping[identifier];
|
|
94
|
-
if (
|
|
92
|
+
if (entityCustomFieldDefinitions?.length > 0) {
|
|
95
93
|
entityCustomFieldDefinitions.forEach((customFieldDefinition) => {
|
|
96
94
|
if (customFields[customFieldDefinition.name] === undefined) {
|
|
97
95
|
customFields[customFieldDefinition.name] = null;
|
|
@@ -100,13 +98,11 @@ const enrichResults = (modelType, scopeAttributes) => (instancesOrInstance, opti
|
|
|
100
98
|
}
|
|
101
99
|
});
|
|
102
100
|
instance.customFields = customFields;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
(_a = instance.dataValues) === null || _a === void 0 ? true : delete _a[attribute];
|
|
101
|
+
options.attributesToRemove?.forEach?.((attribute) => {
|
|
102
|
+
delete instance.dataValues?.[attribute];
|
|
106
103
|
// if raw:
|
|
107
|
-
|
|
104
|
+
delete instance?.[attribute];
|
|
108
105
|
});
|
|
109
106
|
});
|
|
110
|
-
}
|
|
107
|
+
};
|
|
111
108
|
exports.default = enrichResults;
|
|
112
|
-
//# sourceMappingURL=enrich.js.map
|
|
@@ -7,10 +7,9 @@ exports.beforeFind = void 0;
|
|
|
7
7
|
/* eslint-disable no-param-reassign */
|
|
8
8
|
const logger_1 = __importDefault(require("../utils/logger"));
|
|
9
9
|
const doScopeAttributesMissing = (scopeAttributes, queryAttributes) => {
|
|
10
|
-
var _a;
|
|
11
10
|
const attributes = scopeAttributes
|
|
12
11
|
.filter((attribute) => !queryAttributes.includes(attribute));
|
|
13
|
-
if (!
|
|
12
|
+
if (!queryAttributes.includes?.('id')) {
|
|
14
13
|
attributes.push('id');
|
|
15
14
|
}
|
|
16
15
|
return attributes;
|
|
@@ -18,14 +17,13 @@ const doScopeAttributesMissing = (scopeAttributes, queryAttributes) => {
|
|
|
18
17
|
// eslint-disable-next-line import/prefer-default-export
|
|
19
18
|
const beforeFind = (scopeAttributes) => (options) => {
|
|
20
19
|
const { attributes: queryAttributes } = options;
|
|
21
|
-
if (queryAttributes
|
|
20
|
+
if (queryAttributes?.includes?.('customFields')) {
|
|
22
21
|
const missingScopeAttributes = doScopeAttributesMissing(scopeAttributes, queryAttributes);
|
|
23
22
|
logger_1.default.debug('sadot - before find hook');
|
|
24
|
-
if (
|
|
23
|
+
if (missingScopeAttributes?.length > 0) {
|
|
25
24
|
queryAttributes.push(...missingScopeAttributes);
|
|
26
25
|
options.attributesToRemove = missingScopeAttributes;
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
};
|
|
30
29
|
exports.beforeFind = beforeFind;
|
|
31
|
-
//# sourceMappingURL=find.js.map
|
|
@@ -16,4 +16,3 @@ Object.defineProperty(exports, "beforeBulkCreate", { enumerable: true, get: func
|
|
|
16
16
|
Object.defineProperty(exports, "beforeCreate", { enumerable: true, get: function () { return create_1.beforeCreate; } });
|
|
17
17
|
const workaround_1 = __importDefault(require("./workaround"));
|
|
18
18
|
exports.workaround = workaround_1.default;
|
|
19
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -22,15 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
27
|
};
|
|
@@ -51,7 +42,7 @@ exports.beforeBulkUpdate = beforeBulkUpdate;
|
|
|
51
42
|
* A hook to update the custom fields when updating a model instance.
|
|
52
43
|
* TODO - cleanup if update fail
|
|
53
44
|
*/
|
|
54
|
-
const beforeUpdate = (scopeAttributes) => (instance, options) =>
|
|
45
|
+
const beforeUpdate = (scopeAttributes) => async (instance, options) => {
|
|
55
46
|
logger_1.default.debug('sadot - before update hook');
|
|
56
47
|
const { fields } = options;
|
|
57
48
|
const modelType = instance.constructor.name;
|
|
@@ -59,10 +50,9 @@ const beforeUpdate = (scopeAttributes) => (instance, options) => __awaiter(void
|
|
|
59
50
|
const customFieldsIdx = fields.indexOf('customFields');
|
|
60
51
|
if (customFieldsIdx > -1) {
|
|
61
52
|
const { customFields } = instance;
|
|
62
|
-
|
|
53
|
+
await ValueRepo.updateValues(modelType, instance.id, identifiers, customFields, { transaction: options.transaction });
|
|
63
54
|
// eslint-disable-next-line no-param-reassign
|
|
64
55
|
fields.splice(customFieldsIdx, 1);
|
|
65
56
|
}
|
|
66
|
-
}
|
|
57
|
+
};
|
|
67
58
|
exports.beforeUpdate = beforeUpdate;
|
|
68
|
-
//# sourceMappingURL=update.js.map
|
|
@@ -7,17 +7,8 @@
|
|
|
7
7
|
* which manually calls the afterFind hook of each model, recursively
|
|
8
8
|
* https://github.com/sequelize/sequelize/issues/4627
|
|
9
9
|
*/
|
|
10
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
11
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
12
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
13
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
14
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
15
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
16
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
17
|
-
});
|
|
18
|
-
};
|
|
19
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
const handleChildrenAfterFindHook = (instances, options, level = 0) =>
|
|
11
|
+
const handleChildrenAfterFindHook = async (instances, options, level = 0) => {
|
|
21
12
|
if (!instances)
|
|
22
13
|
return Promise.resolve();
|
|
23
14
|
if (Array.isArray(instances)) {
|
|
@@ -33,7 +24,7 @@ const handleChildrenAfterFindHook = (instances, options, level = 0) => __awaiter
|
|
|
33
24
|
* Only run children "afterFind" hooks.
|
|
34
25
|
*/
|
|
35
26
|
if (level >= 1) {
|
|
36
|
-
|
|
27
|
+
await constructor.runHooks('afterFind', instance, options);
|
|
37
28
|
}
|
|
38
29
|
const { associations } = constructor;
|
|
39
30
|
const associatedNames = Object.keys(instance).filter((attribute) => Object.keys(associations).includes(attribute));
|
|
@@ -42,6 +33,5 @@ const handleChildrenAfterFindHook = (instances, options, level = 0) => __awaiter
|
|
|
42
33
|
return handleChildrenAfterFindHook(childInstances, options, level + 1);
|
|
43
34
|
}
|
|
44
35
|
return Promise.resolve();
|
|
45
|
-
}
|
|
36
|
+
};
|
|
46
37
|
exports.default = handleChildrenAfterFindHook;
|
|
47
|
-
//# sourceMappingURL=workaround.js.map
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Application } from 'express';
|
|
2
2
|
import { Sequelize } from 'sequelize-typescript';
|
|
3
|
-
import { CustomFieldOptions, ModelFetcher } from './types';
|
|
3
|
+
import type { CustomFieldOptions, ModelFetcher } from './types';
|
|
4
4
|
export * from './utils/validations/custom-fields';
|
|
5
|
+
export * from './utils/constants';
|
|
5
6
|
/**
|
|
6
7
|
* Adding custom fields enrichment to the models inside the MODELS_FILE_NAME json file
|
|
7
8
|
* @see {@link 'custom-fields/config'} for configurations
|
|
@@ -0,0 +1,52 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.disableCustomFields = void 0;
|
|
21
|
+
const models_1 = require("./models");
|
|
22
|
+
const api_1 = __importDefault(require("./api"));
|
|
23
|
+
const db_1 = __importDefault(require("./utils/db"));
|
|
24
|
+
const logger_1 = __importDefault(require("./utils/logger"));
|
|
25
|
+
const init_1 = require("./utils/init");
|
|
26
|
+
__exportStar(require("./utils/validations/custom-fields"), exports);
|
|
27
|
+
__exportStar(require("./utils/constants"), exports);
|
|
28
|
+
/**
|
|
29
|
+
* Adding custom fields enrichment to the models inside the MODELS_FILE_NAME json file
|
|
30
|
+
* @see {@link 'custom-fields/config'} for configurations
|
|
31
|
+
*/
|
|
32
|
+
const useCustomFields = async (app, getModel, options) => {
|
|
33
|
+
const { models } = options;
|
|
34
|
+
if (app) {
|
|
35
|
+
app.use('/api', api_1.default);
|
|
36
|
+
}
|
|
37
|
+
const sequelize = (0, db_1.default)(options.databaseConfig);
|
|
38
|
+
if (process.env.NODE_ENV === 'test') {
|
|
39
|
+
await (0, models_1.initTestModels)(sequelize);
|
|
40
|
+
}
|
|
41
|
+
// The order is important
|
|
42
|
+
(0, init_1.addHooks)(models, getModel);
|
|
43
|
+
await (0, models_1.initTables)(sequelize, options.getUser);
|
|
44
|
+
(0, init_1.addScopes)(models, getModel);
|
|
45
|
+
logger_1.default.debug('sadot - custom fields finished initializing with models', models);
|
|
46
|
+
return sequelize;
|
|
47
|
+
};
|
|
48
|
+
exports.default = useCustomFields;
|
|
49
|
+
const disableCustomFields = (models, getModel) => {
|
|
50
|
+
(0, init_1.removeHooks)(models, getModel);
|
|
51
|
+
};
|
|
52
|
+
exports.disableCustomFields = disableCustomFields;
|
|
@@ -19,7 +19,7 @@ const events_1 = require("../events");
|
|
|
19
19
|
const errors_1 = require("../errors");
|
|
20
20
|
let CustomFieldDefinition = class CustomFieldDefinition extends sequelize_typescript_1.Model {
|
|
21
21
|
static displayNameDefaultValue(instance) {
|
|
22
|
-
if (!
|
|
22
|
+
if (!instance?.displayName) {
|
|
23
23
|
// eslint-disable-next-line no-param-reassign
|
|
24
24
|
instance.displayName = instance.name;
|
|
25
25
|
}
|
|
@@ -163,4 +163,3 @@ CustomFieldDefinition = __decorate([
|
|
|
163
163
|
})
|
|
164
164
|
], CustomFieldDefinition);
|
|
165
165
|
exports.default = CustomFieldDefinition;
|
|
166
|
-
//# sourceMappingURL=CustomFieldDefinition.js.map
|
|
@@ -31,15 +31,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
31
31
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
32
32
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
33
33
|
};
|
|
34
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
35
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
36
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
37
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
38
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
39
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
40
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
41
|
-
});
|
|
42
|
-
};
|
|
43
34
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
44
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
45
36
|
};
|
|
@@ -53,36 +44,32 @@ const validations_1 = __importDefault(require("../utils/validations"));
|
|
|
53
44
|
const CustomFieldDefinitionRepo = __importStar(require("../repository/definition"));
|
|
54
45
|
const errors_1 = require("../errors");
|
|
55
46
|
let CustomFieldValue = class CustomFieldValue extends sequelize_typescript_1.Model {
|
|
56
|
-
static validateValues(instances) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
.find((definition) => definition.id === instance.customFieldDefinitionId);
|
|
67
|
-
const isValid = (0, validations_1.default)(instance.value, fieldType, validation);
|
|
68
|
-
if (!isValid) {
|
|
69
|
-
throw new errors_1.InvalidValueError(instance.value, fieldType);
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
static validateValue(instance) {
|
|
75
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
-
const { customFieldDefinitionId } = instance;
|
|
77
|
-
// eslint-disable-next-line max-len
|
|
78
|
-
const cfd = yield CustomFieldDefinitionRepo.findById(customFieldDefinitionId, { withDisabled: true });
|
|
79
|
-
const { validation, fieldType } = cfd;
|
|
47
|
+
static async validateValues(instances) {
|
|
48
|
+
const ids = instances.map((instance) => instance.customFieldDefinitionId);
|
|
49
|
+
const uniqueIds = [...new Set(ids)];
|
|
50
|
+
const definitions = await CustomFieldDefinitionRepo.findByIds(uniqueIds, { withDisabled: true });
|
|
51
|
+
if (!definitions || definitions.length !== uniqueIds.length) {
|
|
52
|
+
throw new Error('Definitions not found');
|
|
53
|
+
}
|
|
54
|
+
instances.forEach((instance) => {
|
|
55
|
+
const { validation, fieldType, } = definitions
|
|
56
|
+
.find((definition) => definition.id === instance.customFieldDefinitionId);
|
|
80
57
|
const isValid = (0, validations_1.default)(instance.value, fieldType, validation);
|
|
81
58
|
if (!isValid) {
|
|
82
59
|
throw new errors_1.InvalidValueError(instance.value, fieldType);
|
|
83
60
|
}
|
|
84
61
|
});
|
|
85
62
|
}
|
|
63
|
+
static async validateValue(instance) {
|
|
64
|
+
const { customFieldDefinitionId } = instance;
|
|
65
|
+
// eslint-disable-next-line max-len
|
|
66
|
+
const cfd = await CustomFieldDefinitionRepo.findById(customFieldDefinitionId, { withDisabled: true });
|
|
67
|
+
const { validation, fieldType } = cfd;
|
|
68
|
+
const isValid = (0, validations_1.default)(instance.value, fieldType, validation);
|
|
69
|
+
if (!isValid) {
|
|
70
|
+
throw new errors_1.InvalidValueError(instance.value, fieldType);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
86
73
|
static afterSaveHandler(instance, options) {
|
|
87
74
|
if (options.transaction) {
|
|
88
75
|
options.transaction.afterCommit(() => (0, events_1.sendDimEvent)(instance[0]));
|
|
@@ -159,4 +146,3 @@ CustomFieldValue = __decorate([
|
|
|
159
146
|
})
|
|
160
147
|
], CustomFieldValue);
|
|
161
148
|
exports.default = CustomFieldValue;
|
|
162
|
-
//# sourceMappingURL=CustomFieldValue.js.map
|