@autofleet/sadot 0.13.0-beta.0 → 0.13.0-beta.10

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 (126) hide show
  1. package/dist/api/index.d.ts +3 -0
  2. package/dist/api/index.js +12 -0
  3. package/dist/api/v1/definition/index.d.ts +3 -0
  4. package/dist/api/v1/definition/index.js +116 -0
  5. package/dist/api/v1/definition/validations.d.ts +2 -0
  6. package/dist/api/v1/definition/validations.js +77 -0
  7. package/dist/api/v1/errors.d.ts +4 -0
  8. package/dist/api/v1/errors.js +12 -0
  9. package/dist/api/v1/index.d.ts +3 -0
  10. package/dist/api/v1/index.js +13 -0
  11. package/dist/api/v1/validator/index.d.ts +3 -0
  12. package/dist/api/v1/validator/index.js +132 -0
  13. package/dist/api/v1/validator/validations.d.ts +6 -0
  14. package/dist/api/v1/validator/validations.js +39 -0
  15. package/dist/errors/index.d.ts +24 -0
  16. package/dist/errors/index.js +66 -0
  17. package/dist/events/index.d.ts +4 -0
  18. package/dist/events/index.js +50 -0
  19. package/dist/hooks/create.d.ts +10 -0
  20. package/dist/hooks/create.js +95 -0
  21. package/dist/hooks/enrich.d.ts +30 -0
  22. package/dist/hooks/enrich.js +159 -0
  23. package/dist/hooks/find.d.ts +1 -0
  24. package/dist/hooks/find.js +29 -0
  25. package/dist/hooks/hooks.d.ts +17 -0
  26. package/dist/hooks/hooks.js +266 -0
  27. package/dist/hooks/index.d.ts +5 -0
  28. package/dist/hooks/index.js +17 -0
  29. package/dist/hooks/update.d.ts +10 -0
  30. package/dist/hooks/update.js +49 -0
  31. package/dist/hooks/utils/updateInstanceValues.d.ts +15 -0
  32. package/dist/hooks/utils/updateInstanceValues.js +50 -0
  33. package/dist/hooks/workaround.d.ts +10 -0
  34. package/dist/hooks/workaround.js +37 -0
  35. package/dist/index.d.ts +16 -0
  36. package/dist/index.js +71 -0
  37. package/dist/models/CustomFieldDefinition.d.ts +25 -0
  38. package/dist/models/CustomFieldDefinition.js +192 -0
  39. package/dist/models/CustomFieldEntries.d.ts +15 -0
  40. package/dist/models/CustomFieldEntries.js +123 -0
  41. package/dist/models/CustomFieldValue.d.ts +16 -0
  42. package/dist/models/CustomFieldValue.js +151 -0
  43. package/dist/models/CustomValidator.d.ts +17 -0
  44. package/dist/models/CustomValidator.js +97 -0
  45. package/dist/models/index.d.ts +18 -0
  46. package/dist/models/index.js +117 -0
  47. package/dist/models/tests/AssociatedTestModel.d.ts +12 -0
  48. package/dist/models/tests/AssociatedTestModel.js +71 -0
  49. package/dist/models/tests/TestModel.d.ts +12 -0
  50. package/dist/models/tests/TestModel.js +69 -0
  51. package/dist/models/tests/contextAwareModels/ContextAwareTestModel.d.ts +10 -0
  52. package/dist/models/tests/contextAwareModels/ContextAwareTestModel.js +53 -0
  53. package/dist/models/tests/contextAwareModels/ContextTestModel.d.ts +13 -0
  54. package/dist/models/tests/contextAwareModels/ContextTestModel.js +47 -0
  55. package/dist/repository/definition.d.ts +36 -0
  56. package/dist/repository/definition.js +121 -0
  57. package/dist/repository/entries.d.ts +13 -0
  58. package/dist/repository/entries.js +92 -0
  59. package/dist/repository/utils/formatValues.d.ts +3 -0
  60. package/dist/repository/utils/formatValues.js +16 -0
  61. package/dist/repository/validator.d.ts +18 -0
  62. package/dist/repository/validator.js +50 -0
  63. package/dist/repository/value.d.ts +28 -0
  64. package/dist/repository/value.js +124 -0
  65. package/dist/scopes/filter.d.ts +30 -0
  66. package/dist/scopes/filter.js +75 -0
  67. package/dist/scopes/helpers/filter.helpers.d.ts +42 -0
  68. package/dist/scopes/helpers/filter.helpers.js +204 -0
  69. package/dist/scopes/index.d.ts +2 -0
  70. package/dist/scopes/index.js +6 -0
  71. package/dist/tests/api/test-api.d.ts +2 -0
  72. package/dist/tests/api/test-api.js +38 -0
  73. package/dist/tests/functional/searching/index.d.ts +8 -0
  74. package/dist/tests/functional/searching/index.js +44 -0
  75. package/dist/tests/helpers/commonHooks.d.ts +6 -0
  76. package/dist/tests/helpers/commonHooks.js +62 -0
  77. package/dist/tests/helpers/database-config.d.ts +16 -0
  78. package/dist/tests/helpers/database-config.js +17 -0
  79. package/dist/tests/helpers/index.d.ts +7 -0
  80. package/dist/tests/helpers/index.js +33 -0
  81. package/dist/tests/mocks/definition.mock.d.ts +48 -0
  82. package/dist/tests/mocks/definition.mock.js +78 -0
  83. package/dist/tests/mocks/events.mock.d.ts +4 -0
  84. package/dist/tests/mocks/events.mock.js +21 -0
  85. package/dist/tests/mocks/testModel.d.ts +12 -0
  86. package/dist/tests/mocks/testModel.js +35 -0
  87. package/dist/types/definition/index.d.ts +25 -0
  88. package/dist/types/definition/index.js +2 -0
  89. package/dist/types/entries/index.d.ts +25 -0
  90. package/dist/types/entries/index.js +2 -0
  91. package/dist/types/index.d.ts +35 -0
  92. package/dist/types/index.js +2 -0
  93. package/dist/types/value/index.d.ts +15 -0
  94. package/dist/types/value/index.js +2 -0
  95. package/dist/utils/constants/index.d.ts +19 -0
  96. package/dist/utils/constants/index.js +22 -0
  97. package/dist/utils/db/index.d.ts +4 -0
  98. package/dist/utils/db/index.js +24 -0
  99. package/dist/utils/helpers/index.d.ts +26 -0
  100. package/dist/utils/helpers/index.js +40 -0
  101. package/dist/utils/init.d.ts +7 -0
  102. package/dist/utils/init.js +109 -0
  103. package/dist/utils/logger/index.d.ts +3 -0
  104. package/dist/utils/logger/index.js +42 -0
  105. package/dist/utils/scopeAttributes.d.ts +2 -0
  106. package/dist/utils/scopeAttributes.js +11 -0
  107. package/dist/utils/validations/index.d.ts +8 -0
  108. package/dist/utils/validations/index.js +41 -0
  109. package/dist/utils/validations/schema/custom-fields.d.ts +3 -0
  110. package/dist/utils/validations/schema/custom-fields.js +9 -0
  111. package/dist/utils/validations/schema/validator-schema.d.ts +9 -0
  112. package/dist/utils/validations/schema/validator-schema.js +95 -0
  113. package/dist/utils/validations/type.d.ts +15 -0
  114. package/dist/utils/validations/type.js +2 -0
  115. package/dist/utils/validations/validators/index.d.ts +14 -0
  116. package/dist/utils/validations/validators/index.js +40 -0
  117. package/dist/utils/validations/validators/select.validator.d.ts +5 -0
  118. package/dist/utils/validations/validators/select.validator.js +12 -0
  119. package/dist/utils/validations/validators/status.validator.d.ts +12 -0
  120. package/dist/utils/validations/validators/status.validator.js +15 -0
  121. package/package.json +2 -1
  122. package/src/api/v1/validator/index.ts +2 -2
  123. package/src/api/v1/validator/validations.ts +0 -1
  124. package/src/hooks/hooks.ts +22 -22
  125. package/src/utils/validations/schema/validator-schema.ts +3 -0
  126. package/validator-test.js +79 -0
@@ -0,0 +1,3 @@
1
+ /// <reference types="express" />
2
+ declare const router: import("express").Router;
3
+ export default router;
@@ -0,0 +1,12 @@
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 node_common_1 = require("@autofleet/node-common");
8
+ const v1_1 = __importDefault(require("./v1"));
9
+ const logger_1 = __importDefault(require("../utils/logger"));
10
+ const router = (0, node_common_1.Router)({ logger: logger_1.default });
11
+ router.use('/v1', v1_1.default);
12
+ exports.default = router;
@@ -0,0 +1,3 @@
1
+ /// <reference types="express" />
2
+ declare const router: import("express").Router;
3
+ export default router;
@@ -0,0 +1,116 @@
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 node_common_1 = require("@autofleet/node-common");
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, node_common_1.Router)({ logger: logger_1.default });
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, { logger: logger_1.default, 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, { logger: logger_1.default, message: `Error in get ${ENTITY} request` });
72
+ }
73
+ });
74
+ /**
75
+ * Get all
76
+ */
77
+ router.get('/', async (req, res) => {
78
+ const { params: { modelName }, query: { entityIds } } = req;
79
+ const modelType = toPascalCase(modelName);
80
+ try {
81
+ const where = {
82
+ modelType,
83
+ ...(entityIds?.length > 0 && { entityId: entityIds }),
84
+ };
85
+ const customFieldDefinitions = await DefinitionRepo.findAll(where, { withDisabled: true });
86
+ return res.json(customFieldDefinitions);
87
+ }
88
+ catch (err) {
89
+ logger_1.default.error('Failed to fetch custom field definitions', err);
90
+ return (0, errors_2.default)(err, res, { logger: logger_1.default, message: `Error in get all ${ENTITY} request` });
91
+ }
92
+ });
93
+ /**
94
+ * Update
95
+ */
96
+ router.patch('/:customFieldDefinitionId', async (req, res) => {
97
+ const { customFieldDefinitionId, modelName } = req.params;
98
+ const modelType = toPascalCase(modelName);
99
+ try {
100
+ const validatedPayload = await (0, validations_1.validateCustomFieldDefinitionUpdate)(req.body);
101
+ const customFieldDefinition = await DefinitionRepo.findByWhere({
102
+ id: customFieldDefinitionId,
103
+ modelType,
104
+ });
105
+ if (!customFieldDefinition) {
106
+ throw new errors_1.ResourceNotFoundError();
107
+ }
108
+ const updatedCustomFieldDefinition = await DefinitionRepo.update(customFieldDefinitionId, { ...validatedPayload, modelType });
109
+ return res.status(200).json(updatedCustomFieldDefinition);
110
+ }
111
+ catch (err) {
112
+ logger_1.default.error('Failed to patch custom field definition', err);
113
+ return (0, errors_2.default)(err, res, { logger: logger_1.default, message: `Error in update ${ENTITY} request` });
114
+ }
115
+ });
116
+ 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,77 @@
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
+ /* eslint-disable newline-per-chained-call */
8
+ const joi_1 = __importDefault(require("joi"));
9
+ const constants_1 = require("../../../utils/constants");
10
+ const FileValidationSchema = joi_1.default.object({
11
+ name: joi_1.default.string().required(),
12
+ type: joi_1.default.string(),
13
+ size: joi_1.default.string(),
14
+ addedBy: joi_1.default.string().uuid(),
15
+ });
16
+ const statusValidationObject = joi_1.default.object({
17
+ value: joi_1.default.string().required(),
18
+ color: joi_1.default.string().required(),
19
+ });
20
+ /**
21
+ * Schema for the validation of custom field definition
22
+ * The only custom validation is for
23
+ * {@link CustomFieldDefinitionType.SELECT SELECT}
24
+ * and
25
+ * {@link CustomFieldDefinitionType.STATUS STATUS}
26
+ * field types.
27
+ * The rest of the field types are validated by Joi
28
+ */
29
+ const ValidationSchema = joi_1.default.when('fieldType', {
30
+ is: constants_1.CustomFieldDefinitionType.SELECT,
31
+ then: joi_1.default.array().required().items(joi_1.default.string()).min(1).unique(),
32
+ otherwise: joi_1.default.when('fieldType', {
33
+ is: constants_1.CustomFieldDefinitionType.STATUS,
34
+ then: joi_1.default.array().required().items(statusValidationObject).min(1).unique('value'),
35
+ otherwise: joi_1.default.forbidden(),
36
+ }),
37
+ });
38
+ const DefaultValueSchema = joi_1.default.when('fieldType', {
39
+ switch: [
40
+ { is: constants_1.CustomFieldDefinitionType.BOOLEAN, then: joi_1.default.boolean().allow(null) },
41
+ { is: constants_1.CustomFieldDefinitionType.DATE, then: joi_1.default.date().allow(null) },
42
+ { is: constants_1.CustomFieldDefinitionType.DATETIME, then: joi_1.default.date().allow(null) },
43
+ { is: constants_1.CustomFieldDefinitionType.FILE, then: joi_1.default.array().items(FileValidationSchema).allow(null) },
44
+ { is: constants_1.CustomFieldDefinitionType.IMAGE, then: joi_1.default.array().items(joi_1.default.string().uri()).allow(null) },
45
+ { is: constants_1.CustomFieldDefinitionType.NUMBER, then: joi_1.default.number().allow(null) },
46
+ { is: constants_1.CustomFieldDefinitionType.SELECT, then: joi_1.default.string().allow(null) },
47
+ { is: constants_1.CustomFieldDefinitionType.STATUS, then: joi_1.default.string().allow(null) },
48
+ { is: constants_1.CustomFieldDefinitionType.TEXT, then: joi_1.default.string().allow(null) },
49
+ ],
50
+ });
51
+ const CustomFieldDefinitionCreationSchema = joi_1.default.object({
52
+ name: joi_1.default.string().required(),
53
+ displayName: joi_1.default.string().required(),
54
+ validation: ValidationSchema,
55
+ defaultValue: DefaultValueSchema,
56
+ fieldType: joi_1.default.string().valid(...Object.values(constants_1.CustomFieldDefinitionType)).required(),
57
+ entityId: joi_1.default.string().guid().required(),
58
+ entityType: joi_1.default.string().required(),
59
+ description: joi_1.default.string(),
60
+ required: joi_1.default.boolean(),
61
+ disabled: joi_1.default.boolean(),
62
+ blockEditingFromUI: joi_1.default.boolean(),
63
+ }).oxor('required', 'blockEditingFromUI', { isPresent: (value) => value === true });
64
+ const CustomFieldDefinitionUpdateSchema = joi_1.default.object({
65
+ displayName: joi_1.default.string(),
66
+ validation: ValidationSchema,
67
+ defaultValue: DefaultValueSchema,
68
+ fieldType: joi_1.default.string().valid(...Object.values(constants_1.CustomFieldDefinitionType)),
69
+ description: joi_1.default.string().allow(null),
70
+ required: joi_1.default.boolean(),
71
+ disabled: joi_1.default.boolean(),
72
+ blockEditingFromUI: joi_1.default.boolean(),
73
+ }).oxor('required', 'blockEditingFromUI', { isPresent: (value) => value === true });
74
+ const validateCustomFieldDefinitionCreation = (payload) => CustomFieldDefinitionCreationSchema.validateAsync(payload, { abortEarly: false });
75
+ exports.validateCustomFieldDefinitionCreation = validateCustomFieldDefinitionCreation;
76
+ const validateCustomFieldDefinitionUpdate = (payload) => CustomFieldDefinitionUpdateSchema.validateAsync(payload, { abortEarly: false });
77
+ exports.validateCustomFieldDefinitionUpdate = validateCustomFieldDefinitionUpdate;
@@ -0,0 +1,4 @@
1
+ import type { Response } from 'express';
2
+ import { type LogPayload } from '@autofleet/errors';
3
+ declare const _default: (err: any, res: Response, additionalData?: LogPayload) => void;
4
+ export default _default;
@@ -0,0 +1,12 @@
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 ([joi_1.ValidationError, sequelize_1.ValidationError].some((ErrClass) => err instanceof ErrClass)) {
9
+ error = new errors_1.BadRequest([err], null);
10
+ }
11
+ return (0, errors_1.handleError)(error, res, additionalData);
12
+ };
@@ -0,0 +1,3 @@
1
+ /// <reference types="express" />
2
+ declare const router: import("express").Router;
3
+ export default router;
@@ -0,0 +1,13 @@
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 node_common_1 = require("@autofleet/node-common");
7
+ const logger_1 = __importDefault(require("../../utils/logger"));
8
+ const definition_1 = __importDefault(require("./definition"));
9
+ const validator_1 = __importDefault(require("./validator"));
10
+ const router = (0, node_common_1.Router)({ logger: logger_1.default });
11
+ router.use('/custom-field-definitions/:modelName', definition_1.default);
12
+ router.use('/custom-validators/:modelName', validator_1.default);
13
+ exports.default = router;
@@ -0,0 +1,3 @@
1
+ /// <reference types="express" />
2
+ declare const router: import("express").Router;
3
+ export default router;
@@ -0,0 +1,132 @@
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 node_common_1 = require("@autofleet/node-common");
31
+ const http_status_codes_1 = require("http-status-codes");
32
+ const errors_2 = __importDefault(require("../errors"));
33
+ const ValidatorRepo = __importStar(require("../../../repository/validator"));
34
+ const validations_1 = __importDefault(require("./validations"));
35
+ const logger_1 = __importDefault(require("../../../utils/logger"));
36
+ const validator_schema_1 = require("../../../utils/validations/schema/validator-schema");
37
+ const router = (0, node_common_1.Router)({ logger: logger_1.default });
38
+ const ENTITY = 'CustomValidator';
39
+ /**
40
+ * Create
41
+ */
42
+ router.post('/', async (req, res) => {
43
+ const { modelName } = req.params;
44
+ try {
45
+ // Validate the request body
46
+ const validatedPayload = await validations_1.default.create.validateAsync(req.body);
47
+ // Validate that the schema is a valid AJV schema
48
+ (0, validator_schema_1.validateValidatorSchema)(validatedPayload.schema);
49
+ const validator = await ValidatorRepo.create({
50
+ ...validatedPayload,
51
+ modelType: modelName,
52
+ });
53
+ return res.status(http_status_codes_1.StatusCodes.CREATED).json(validator);
54
+ }
55
+ catch (err) {
56
+ return (0, errors_2.default)(err, res, { logger: logger_1.default, message: `Error in create ${ENTITY} request` });
57
+ }
58
+ });
59
+ /**
60
+ * Get all
61
+ */
62
+ router.get('/', async (req, res) => {
63
+ try {
64
+ const { modelName } = req.params;
65
+ const { entityId, entityType } = req.query;
66
+ const where = {
67
+ modelType: modelName,
68
+ ...(entityId && { entityId }),
69
+ ...(entityType && { entityType }),
70
+ };
71
+ const validators = await ValidatorRepo.findAll(where);
72
+ return res.status(http_status_codes_1.StatusCodes.OK).json({ validators });
73
+ }
74
+ catch (err) {
75
+ return (0, errors_2.default)(err, res, { logger: logger_1.default, message: `Error in get all ${ENTITY} request` });
76
+ }
77
+ });
78
+ /**
79
+ * Get by id
80
+ */
81
+ router.get('/:validatorId', async (req, res) => {
82
+ try {
83
+ const { validatorId } = req.params;
84
+ const validators = await ValidatorRepo.findAll({ id: validatorId });
85
+ if (!validators.length) {
86
+ throw new errors_1.ResourceNotFoundError('Validator not found');
87
+ }
88
+ return res.status(http_status_codes_1.StatusCodes.OK).json(validators[0]);
89
+ }
90
+ catch (err) {
91
+ return (0, errors_2.default)(err, res, { logger: logger_1.default, message: `Error in get ${ENTITY} request` });
92
+ }
93
+ });
94
+ /**
95
+ * Update
96
+ */
97
+ router.patch('/:validatorId', async (req, res) => {
98
+ try {
99
+ const { validatorId } = req.params;
100
+ // Validate the request body
101
+ const validatedPayload = await validations_1.default.update.validateAsync(req.body);
102
+ // If schema is included in the update, validate that it's a valid AJV schema
103
+ if (validatedPayload.schema) {
104
+ (0, validator_schema_1.validateValidatorSchema)(validatedPayload.schema);
105
+ }
106
+ const [count, validators] = await ValidatorRepo.update(validatorId, validatedPayload);
107
+ if (!count) {
108
+ throw new errors_1.ResourceNotFoundError('Validator not found');
109
+ }
110
+ return res.status(http_status_codes_1.StatusCodes.OK).json(validators[0]);
111
+ }
112
+ catch (err) {
113
+ return (0, errors_2.default)(err, res, { logger: logger_1.default, message: `Error in update ${ENTITY} request` });
114
+ }
115
+ });
116
+ /**
117
+ * Delete (disable)
118
+ */
119
+ router.delete('/:validatorId', async (req, res) => {
120
+ try {
121
+ const { validatorId } = req.params;
122
+ const [count] = await ValidatorRepo.disable(validatorId);
123
+ if (!count) {
124
+ throw new errors_1.ResourceNotFoundError('Validator not found');
125
+ }
126
+ return res.status(http_status_codes_1.StatusCodes.NO_CONTENT).send();
127
+ }
128
+ catch (err) {
129
+ return (0, errors_2.default)(err, res, { logger: logger_1.default, message: `Error in delete ${ENTITY} request` });
130
+ }
131
+ });
132
+ exports.default = router;
@@ -0,0 +1,6 @@
1
+ import Joi from 'joi';
2
+ declare const validationSchemas: {
3
+ create: Joi.ObjectSchema<any>;
4
+ update: Joi.ObjectSchema<any>;
5
+ };
6
+ export default validationSchemas;
@@ -0,0 +1,39 @@
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 joi_1 = __importDefault(require("joi"));
7
+ // Schema for validating JSON Schema objects
8
+ const jsonSchemaValidation = joi_1.default.object().unknown(true);
9
+ const validationSchemas = {
10
+ create: joi_1.default.object({
11
+ entityId: joi_1.default.string().uuid().required(),
12
+ entityType: joi_1.default.string().required(),
13
+ schema: joi_1.default.object({
14
+ type: joi_1.default.string().valid('object').required(),
15
+ properties: joi_1.default.object({
16
+ before: jsonSchemaValidation,
17
+ after: jsonSchemaValidation,
18
+ }).required(),
19
+ if: joi_1.default.object().optional(),
20
+ then: joi_1.default.object().optional(),
21
+ else: joi_1.default.object().optional(),
22
+ }).required(),
23
+ }),
24
+ update: joi_1.default.object({
25
+ entityId: joi_1.default.string().uuid(),
26
+ schema: joi_1.default.object({
27
+ type: joi_1.default.string().valid('object'),
28
+ properties: joi_1.default.object({
29
+ before: jsonSchemaValidation,
30
+ after: jsonSchemaValidation,
31
+ }),
32
+ if: joi_1.default.object().optional(),
33
+ then: joi_1.default.object().optional(),
34
+ else: joi_1.default.object().optional(),
35
+ }),
36
+ disabled: joi_1.default.boolean(),
37
+ }).min(1),
38
+ };
39
+ exports.default = validationSchemas;
@@ -0,0 +1,24 @@
1
+ import { BadRequest } from '@autofleet/errors';
2
+ import type { ValidationError } from 'joi';
3
+ import type { EntriesValidationError } from '../types/entries';
4
+ export declare class MissingRequiredCustomFieldError extends BadRequest {
5
+ constructor(missingFields: string[]);
6
+ }
7
+ export declare class UnsupportedCustomFieldTypeError extends BadRequest {
8
+ constructor(fieldType: string);
9
+ }
10
+ export declare class UnsupportedCustomValidationError extends BadRequest {
11
+ constructor(fieldType: string);
12
+ }
13
+ export declare class InvalidFieldTypeError extends BadRequest {
14
+ constructor(fieldType: string);
15
+ }
16
+ export declare class InvalidValueError extends BadRequest {
17
+ constructor(value: any, fieldDefinitionName: string, joiValidationError: ValidationError);
18
+ }
19
+ export declare class InvalidEntriesError extends BadRequest {
20
+ constructor(modelId: string, validationErrors: EntriesValidationError[]);
21
+ }
22
+ export declare class MissingDefinitionError extends BadRequest {
23
+ constructor(fieldNames: string[]);
24
+ }
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MissingDefinitionError = exports.InvalidEntriesError = exports.InvalidValueError = exports.InvalidFieldTypeError = 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 InvalidFieldTypeError extends errors_1.BadRequest {
31
+ constructor(fieldType) {
32
+ const err = new Error(`Invalid field type ${fieldType}`);
33
+ super([err], null, null);
34
+ this.message = 'INVALID_FIELD_TYPE';
35
+ }
36
+ }
37
+ exports.InvalidFieldTypeError = InvalidFieldTypeError;
38
+ class InvalidValueError extends errors_1.BadRequest {
39
+ constructor(value, fieldDefinitionName, joiValidationError) {
40
+ const formattedErrorMessage = joiValidationError.message
41
+ .replace(/"/g, '')
42
+ .replace('value', `'${fieldDefinitionName}'`);
43
+ const formattedValue = typeof value === 'object' ? JSON.stringify(value) : value;
44
+ const invalidValueMessage = `Invalid Value on field '${fieldDefinitionName}'. ${formattedErrorMessage}. received: '${formattedValue}'`;
45
+ const err = new Error(invalidValueMessage);
46
+ super([err], null, null);
47
+ this.message = invalidValueMessage;
48
+ }
49
+ }
50
+ exports.InvalidValueError = InvalidValueError;
51
+ class InvalidEntriesError extends errors_1.BadRequest {
52
+ constructor(modelId, validationErrors) {
53
+ const errors = validationErrors.map((validationError) => new InvalidValueError(validationError.value, validationError.fieldDefinitionName, validationError.joiValidationError));
54
+ super(errors, null, null);
55
+ this.message = `Invalid entries on ${modelId}\n${validationErrors.map((validationError) => (`${validationError.fieldDefinitionName} - ${validationError.joiValidationError.message}`)).join('\n')}`;
56
+ }
57
+ }
58
+ exports.InvalidEntriesError = InvalidEntriesError;
59
+ class MissingDefinitionError extends errors_1.BadRequest {
60
+ constructor(fieldNames) {
61
+ const err = new Error(`Missing custom field definition for field ${fieldNames.join(',')}`);
62
+ super([err], null, null);
63
+ this.message = 'MISSING_DEFINITION';
64
+ }
65
+ }
66
+ 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,50 @@
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', 'defaultValue', 'blockEditingFromUI'];
11
+ const stringifyBooleans = (savedObject, keysToConvert) => {
12
+ const savedObjectKeySet = new Set(Object.keys(savedObject));
13
+ if (keysToConvert.every((key) => !savedObjectKeySet.has(key))) {
14
+ return savedObject;
15
+ }
16
+ return {
17
+ ...savedObject,
18
+ ...Object.fromEntries(keysToConvert.map((key) => [key, typeof savedObject[key] === 'boolean' ? savedObject[key].toString() : savedObject[key]])),
19
+ };
20
+ };
21
+ const modelTableMapping = {
22
+ CustomFieldDefinition: {
23
+ tableName: 'dim_custom_field_definition',
24
+ eventVersion: '1',
25
+ },
26
+ CustomFieldValue: {
27
+ tableName: 'dim_custom_field_value',
28
+ eventVersion: '1',
29
+ },
30
+ CustomFieldEntries: {
31
+ tableName: 'dim_custom_field_entries',
32
+ eventVersion: '1',
33
+ },
34
+ };
35
+ const sendDimEvent = (instance) => {
36
+ const mapping = modelTableMapping[instance.constructor.name];
37
+ if (!mapping) {
38
+ return;
39
+ }
40
+ let objectToSend = instance.get();
41
+ try {
42
+ objectToSend = stringifyBooleans(instance.get(), KEYS_TO_CONVERT);
43
+ }
44
+ catch (err) {
45
+ logger_1.default.error('Failed to convert booleans in dim event payload', err);
46
+ }
47
+ events.sendObject(mapping.tableName, mapping.eventVersion, objectToSend).catch(() => { });
48
+ };
49
+ exports.sendDimEvent = sendDimEvent;
50
+ exports.default = events;
@@ -0,0 +1,10 @@
1
+ import type { CustomFieldOptions, 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, sadotOptions?: Pick<CustomFieldOptions, 'useCustomFieldsEntries'>) => (instance: any, options: any) => Promise<void>;