@autofleet/sadot 1.1.1 → 1.1.2-beta
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/api/index.d.ts +3 -0
- package/dist/api/index.js +12 -2
- package/dist/api/v1/definition/index.d.ts +3 -0
- package/dist/api/v1/definition/index.js +116 -2
- package/dist/api/v1/definition/validations.d.ts +2 -0
- package/dist/api/v1/definition/validations.js +77 -2
- package/dist/api/v1/errors.d.ts +4 -0
- package/dist/api/v1/errors.js +12 -2
- package/dist/api/v1/index.d.ts +3 -0
- package/dist/api/v1/index.js +13 -2
- package/dist/api/v1/validator/index.d.ts +3 -0
- package/dist/api/v1/validator/index.js +143 -2
- package/dist/api/v1/validator/validations.d.ts +6 -23
- package/dist/api/v1/validator/validations.js +38 -2
- package/dist/errors/index.d.ts +24 -0
- package/dist/errors/index.js +66 -3
- package/dist/events/index.d.ts +5 -0
- package/dist/events/index.js +54 -2
- package/dist/hooks/create.d.ts +10 -0
- package/dist/hooks/create.js +95 -0
- package/dist/hooks/enrich.d.ts +25 -0
- package/dist/hooks/enrich.js +198 -2
- package/dist/hooks/find.d.ts +1 -0
- package/dist/hooks/find.js +29 -2
- package/dist/hooks/hooks.d.ts +17 -0
- package/dist/hooks/hooks.js +391 -2
- package/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/index.js +17 -1
- package/dist/hooks/update.d.ts +10 -0
- package/dist/hooks/update.js +49 -0
- package/dist/hooks/utils/updateInstanceValues.d.ts +15 -0
- package/dist/hooks/utils/updateInstanceValues.js +50 -2
- package/dist/hooks/workaround.d.ts +10 -0
- package/dist/hooks/workaround.js +37 -0
- package/dist/index.d.ts +12 -22
- package/dist/index.js +67 -2
- package/dist/models/CustomFieldDefinition.d.ts +23 -29
- package/dist/models/CustomFieldDefinition.js +192 -2
- package/dist/models/CustomFieldEntries.d.ts +13 -14
- package/dist/models/CustomFieldEntries.js +123 -2
- package/dist/models/CustomFieldValue.d.ts +14 -20
- package/dist/models/CustomFieldValue.js +151 -2
- package/dist/models/CustomValidator.d.ts +15 -17
- package/dist/models/CustomValidator.js +98 -2
- package/dist/models/index.d.ts +18 -6
- package/dist/models/index.js +131 -2
- package/dist/models/tests/AssociatedTestModel.d.ts +12 -0
- package/dist/models/tests/AssociatedTestModel.js +71 -2
- package/dist/models/tests/TestModel.d.ts +12 -0
- package/dist/models/tests/TestModel.js +69 -2
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.d.ts +10 -0
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.js +53 -2
- package/dist/models/tests/contextAwareModels/ContextTestModel.d.ts +13 -0
- package/dist/models/tests/contextAwareModels/ContextTestModel.js +47 -2
- package/dist/repository/definition.d.ts +36 -0
- package/dist/repository/definition.js +121 -2
- package/dist/repository/entries.d.ts +13 -0
- package/dist/repository/entries.js +92 -2
- package/dist/repository/utils/formatValues.d.ts +3 -0
- package/dist/repository/utils/formatValues.js +16 -2
- package/dist/repository/validator.d.ts +21 -0
- package/dist/repository/validator.js +62 -2
- package/dist/repository/value.d.ts +28 -0
- package/dist/repository/value.js +124 -2
- package/dist/scopes/filter.d.ts +29 -22
- package/dist/scopes/filter.js +75 -2
- package/dist/scopes/helpers/filter.helpers.d.ts +40 -15
- package/dist/scopes/helpers/filter.helpers.js +183 -25
- package/dist/scopes/index.d.ts +2 -0
- package/dist/scopes/index.js +6 -1
- package/dist/tests/api/test-api.d.ts +2 -0
- package/dist/tests/api/test-api.js +38 -0
- package/dist/tests/functional/searching/index.d.ts +8 -0
- package/dist/tests/functional/searching/index.js +44 -0
- package/dist/tests/helpers/commonHooks.d.ts +6 -0
- package/dist/tests/helpers/commonHooks.js +62 -0
- package/dist/tests/helpers/database-config.d.ts +16 -0
- package/dist/tests/helpers/database-config.js +17 -0
- package/dist/tests/helpers/index.d.ts +7 -0
- package/dist/tests/helpers/index.js +33 -0
- package/dist/tests/mocks/definition.mock.d.ts +48 -0
- package/dist/tests/mocks/definition.mock.js +78 -0
- package/dist/tests/mocks/events.mock.d.ts +4 -0
- package/dist/tests/mocks/events.mock.js +21 -0
- package/dist/tests/mocks/testModel.d.ts +12 -0
- package/dist/tests/mocks/testModel.js +35 -0
- package/dist/types/definition/index.d.ts +25 -0
- package/dist/types/definition/index.js +2 -0
- package/dist/types/entries/index.d.ts +25 -0
- package/dist/types/entries/index.js +2 -0
- package/dist/types/index.d.ts +46 -45
- package/dist/types/index.js +2 -0
- package/dist/types/value/index.d.ts +15 -0
- package/dist/types/value/index.js +2 -0
- package/dist/utils/constants/index.d.ts +17 -20
- package/dist/utils/constants/index.js +22 -2
- package/dist/utils/db/index.d.ts +4 -0
- package/dist/utils/db/index.js +24 -2
- package/dist/utils/helpers/index.d.ts +23 -28
- package/dist/utils/helpers/index.js +40 -2
- package/dist/utils/init.d.ts +7 -0
- package/dist/utils/init.js +111 -2
- package/dist/utils/logger/index.d.ts +3 -0
- package/dist/utils/logger/index.js +42 -2
- package/dist/utils/scopeAttributes.d.ts +2 -0
- package/dist/utils/scopeAttributes.js +11 -2
- package/dist/utils/validations/index.d.ts +8 -0
- package/dist/utils/validations/index.js +41 -2
- package/dist/utils/validations/schema/custom-fields.d.ts +2 -6
- package/dist/utils/validations/schema/custom-fields.js +9 -2
- package/dist/utils/validations/schema/validator-schema.d.ts +9 -0
- package/dist/utils/validations/schema/validator-schema.js +95 -2
- package/dist/utils/validations/type.d.ts +15 -0
- package/dist/utils/validations/type.js +2 -0
- package/dist/utils/validations/validators/index.d.ts +14 -0
- package/dist/utils/validations/validators/index.js +40 -2
- package/dist/utils/validations/validators/select.validator.d.ts +5 -0
- package/dist/utils/validations/validators/select.validator.js +12 -2
- package/dist/utils/validations/validators/status.validator.d.ts +12 -0
- package/dist/utils/validations/validators/status.validator.js +15 -2
- package/package.json +39 -40
- package/src/api/index.ts +10 -0
- package/src/api/v1/definition/index.ts +104 -0
- package/src/api/v1/definition/validations.ts +75 -0
- package/src/api/v1/errors.ts +13 -0
- package/src/api/v1/index.ts +11 -0
- package/src/api/v1/validator/index.ts +141 -0
- package/src/api/v1/validator/validations.ts +38 -0
- package/src/errors/index.ts +70 -0
- package/src/events/index.ts +63 -0
- package/src/hooks/create.ts +81 -0
- package/src/hooks/enrich.ts +255 -0
- package/src/hooks/find.ts +27 -0
- package/src/hooks/hooks.ts +482 -0
- package/src/hooks/index.ts +20 -0
- package/src/hooks/update.ts +55 -0
- package/src/hooks/utils/updateInstanceValues.ts +63 -0
- package/src/hooks/workaround.ts +47 -0
- package/src/index.ts +52 -0
- package/src/models/CustomFieldDefinition.ts +162 -0
- package/src/models/CustomFieldEntries.ts +81 -0
- package/src/models/CustomFieldValue.ts +118 -0
- package/src/models/CustomValidator.ts +78 -0
- package/src/models/index.ts +165 -0
- package/src/models/tests/AssociatedTestModel.ts +57 -0
- package/src/models/tests/TestModel.ts +54 -0
- package/src/models/tests/contextAwareModels/ContextAwareTestModel.ts +43 -0
- package/src/models/tests/contextAwareModels/ContextTestModel.ts +38 -0
- package/src/repository/definition.ts +175 -0
- package/src/repository/entries.ts +88 -0
- package/src/repository/utils/formatValues.ts +14 -0
- package/src/repository/validator.ts +104 -0
- package/src/repository/value.ts +116 -0
- package/src/scopes/filter.ts +100 -0
- package/src/scopes/helpers/filter.helpers.ts +227 -0
- package/src/scopes/index.ts +6 -0
- package/src/tests/api/test-api.ts +40 -0
- package/src/tests/functional/searching/index.ts +39 -0
- package/src/tests/helpers/commonHooks.ts +43 -0
- package/src/tests/helpers/database-config.ts +15 -0
- package/src/tests/helpers/index.ts +35 -0
- package/src/tests/mocks/definition.mock.ts +84 -0
- package/src/tests/mocks/events.mock.ts +21 -0
- package/src/tests/mocks/testModel.ts +37 -0
- package/src/types/definition/index.ts +24 -0
- package/src/types/entries/index.ts +27 -0
- package/src/types/index.ts +52 -0
- package/src/types/value/index.ts +14 -0
- package/src/utils/constants/index.ts +25 -0
- package/src/utils/db/index.ts +21 -0
- package/src/utils/helpers/index.ts +66 -0
- package/src/utils/init.ts +120 -0
- package/src/utils/logger/index.ts +14 -0
- package/src/utils/scopeAttributes.ts +12 -0
- package/src/utils/validations/index.ts +46 -0
- package/src/utils/validations/schema/README.md +93 -0
- package/src/utils/validations/schema/custom-fields.ts +8 -0
- package/src/utils/validations/schema/validator-schema.ts +106 -0
- package/src/utils/validations/type.ts +20 -0
- package/src/utils/validations/validators/index.ts +38 -0
- package/src/utils/validations/validators/select.validator.ts +12 -0
- package/src/utils/validations/validators/status.validator.ts +22 -0
- package/tsconfig.build.json +7 -0
- package/tsconfig.json +16 -0
- package/dist/_virtual/_@oxc-project_runtime@0.97.0/helpers/decorate.cjs +0 -1
- package/dist/_virtual/_@oxc-project_runtime@0.97.0/helpers/decorate.js +0 -1
- package/dist/_virtual/_@oxc-project_runtime@0.97.0/helpers/decorateMetadata.cjs +0 -1
- package/dist/_virtual/_@oxc-project_runtime@0.97.0/helpers/decorateMetadata.js +0 -1
- package/dist/_virtual/rolldown_runtime.cjs +0 -1
- package/dist/api/index.cjs +0 -2
- package/dist/api/index.cjs.map +0 -1
- package/dist/api/index.js.map +0 -1
- package/dist/api/v1/definition/index.cjs +0 -2
- package/dist/api/v1/definition/index.cjs.map +0 -1
- package/dist/api/v1/definition/index.js.map +0 -1
- package/dist/api/v1/definition/validations.cjs +0 -2
- package/dist/api/v1/definition/validations.cjs.map +0 -1
- package/dist/api/v1/definition/validations.js.map +0 -1
- package/dist/api/v1/errors.cjs +0 -2
- package/dist/api/v1/errors.cjs.map +0 -1
- package/dist/api/v1/errors.js.map +0 -1
- package/dist/api/v1/index.cjs +0 -2
- package/dist/api/v1/index.cjs.map +0 -1
- package/dist/api/v1/index.js.map +0 -1
- package/dist/api/v1/validator/index.cjs +0 -2
- package/dist/api/v1/validator/index.cjs.map +0 -1
- package/dist/api/v1/validator/index.js.map +0 -1
- package/dist/api/v1/validator/validations.cjs +0 -2
- package/dist/api/v1/validator/validations.cjs.map +0 -1
- package/dist/api/v1/validator/validations.d.cts +0 -23
- package/dist/api/v1/validator/validations.js.map +0 -1
- package/dist/errors/index.cjs +0 -3
- package/dist/errors/index.cjs.map +0 -1
- package/dist/errors/index.js.map +0 -1
- package/dist/events/index.cjs +0 -2
- package/dist/events/index.cjs.map +0 -1
- package/dist/events/index.js.map +0 -1
- package/dist/hooks/enrich.cjs +0 -2
- package/dist/hooks/enrich.cjs.map +0 -1
- package/dist/hooks/enrich.js.map +0 -1
- package/dist/hooks/find.cjs +0 -2
- package/dist/hooks/find.cjs.map +0 -1
- package/dist/hooks/find.js.map +0 -1
- package/dist/hooks/hooks.cjs +0 -2
- package/dist/hooks/hooks.cjs.map +0 -1
- package/dist/hooks/hooks.js.map +0 -1
- package/dist/hooks/index.cjs +0 -1
- package/dist/hooks/utils/updateInstanceValues.cjs +0 -2
- package/dist/hooks/utils/updateInstanceValues.cjs.map +0 -1
- package/dist/hooks/utils/updateInstanceValues.js.map +0 -1
- package/dist/index.cjs +0 -2
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -23
- package/dist/index.js.map +0 -1
- package/dist/models/CustomFieldDefinition.cjs +0 -2
- package/dist/models/CustomFieldDefinition.cjs.map +0 -1
- package/dist/models/CustomFieldDefinition.d.cts +0 -31
- package/dist/models/CustomFieldDefinition.js.map +0 -1
- package/dist/models/CustomFieldEntries.cjs +0 -2
- package/dist/models/CustomFieldEntries.cjs.map +0 -1
- package/dist/models/CustomFieldEntries.d.cts +0 -16
- package/dist/models/CustomFieldEntries.js.map +0 -1
- package/dist/models/CustomFieldValue.cjs +0 -2
- package/dist/models/CustomFieldValue.cjs.map +0 -1
- package/dist/models/CustomFieldValue.d.cts +0 -22
- package/dist/models/CustomFieldValue.js.map +0 -1
- package/dist/models/CustomValidator.cjs +0 -2
- package/dist/models/CustomValidator.cjs.map +0 -1
- package/dist/models/CustomValidator.d.cts +0 -19
- package/dist/models/CustomValidator.js.map +0 -1
- package/dist/models/index.cjs +0 -2
- package/dist/models/index.cjs.map +0 -1
- package/dist/models/index.d.cts +0 -6
- package/dist/models/index.js.map +0 -1
- package/dist/models/tests/AssociatedTestModel.cjs +0 -2
- package/dist/models/tests/AssociatedTestModel.cjs.map +0 -1
- package/dist/models/tests/AssociatedTestModel.js.map +0 -1
- package/dist/models/tests/TestModel.cjs +0 -2
- package/dist/models/tests/TestModel.cjs.map +0 -1
- package/dist/models/tests/TestModel.js.map +0 -1
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.cjs +0 -2
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.cjs.map +0 -1
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.js.map +0 -1
- package/dist/models/tests/contextAwareModels/ContextTestModel.cjs +0 -2
- package/dist/models/tests/contextAwareModels/ContextTestModel.cjs.map +0 -1
- package/dist/models/tests/contextAwareModels/ContextTestModel.js.map +0 -1
- package/dist/repository/definition.cjs +0 -2
- package/dist/repository/definition.cjs.map +0 -1
- package/dist/repository/definition.js.map +0 -1
- package/dist/repository/entries.cjs +0 -2
- package/dist/repository/entries.cjs.map +0 -1
- package/dist/repository/entries.js.map +0 -1
- package/dist/repository/utils/formatValues.cjs +0 -2
- package/dist/repository/utils/formatValues.cjs.map +0 -1
- package/dist/repository/utils/formatValues.js.map +0 -1
- package/dist/repository/validator.cjs +0 -2
- package/dist/repository/validator.cjs.map +0 -1
- package/dist/repository/validator.js.map +0 -1
- package/dist/repository/value.cjs +0 -2
- package/dist/repository/value.cjs.map +0 -1
- package/dist/repository/value.js.map +0 -1
- package/dist/scopes/filter.cjs +0 -2
- package/dist/scopes/filter.cjs.map +0 -1
- package/dist/scopes/filter.d.cts +0 -23
- package/dist/scopes/filter.js.map +0 -1
- package/dist/scopes/helpers/filter.helpers.cjs +0 -46
- package/dist/scopes/helpers/filter.helpers.cjs.map +0 -1
- package/dist/scopes/helpers/filter.helpers.d.cts +0 -17
- package/dist/scopes/helpers/filter.helpers.js.map +0 -1
- package/dist/scopes/index.cjs +0 -1
- package/dist/types/index.d.cts +0 -45
- package/dist/utils/constants/index.cjs +0 -2
- package/dist/utils/constants/index.cjs.map +0 -1
- package/dist/utils/constants/index.d.cts +0 -22
- package/dist/utils/constants/index.js.map +0 -1
- package/dist/utils/db/index.cjs +0 -2
- package/dist/utils/db/index.cjs.map +0 -1
- package/dist/utils/db/index.js.map +0 -1
- package/dist/utils/helpers/index.cjs +0 -2
- package/dist/utils/helpers/index.cjs.map +0 -1
- package/dist/utils/helpers/index.d.cts +0 -31
- package/dist/utils/helpers/index.js.map +0 -1
- package/dist/utils/init.cjs +0 -2
- package/dist/utils/init.cjs.map +0 -1
- package/dist/utils/init.js.map +0 -1
- package/dist/utils/logger/index.cjs +0 -2
- package/dist/utils/logger/index.cjs.map +0 -1
- package/dist/utils/logger/index.js.map +0 -1
- package/dist/utils/scopeAttributes.cjs +0 -2
- package/dist/utils/scopeAttributes.cjs.map +0 -1
- package/dist/utils/scopeAttributes.js.map +0 -1
- package/dist/utils/validations/index.cjs +0 -2
- package/dist/utils/validations/index.cjs.map +0 -1
- package/dist/utils/validations/index.js.map +0 -1
- package/dist/utils/validations/schema/custom-fields.cjs +0 -2
- package/dist/utils/validations/schema/custom-fields.cjs.map +0 -1
- package/dist/utils/validations/schema/custom-fields.d.cts +0 -7
- package/dist/utils/validations/schema/custom-fields.js.map +0 -1
- package/dist/utils/validations/schema/validator-schema.cjs +0 -2
- package/dist/utils/validations/schema/validator-schema.cjs.map +0 -1
- package/dist/utils/validations/schema/validator-schema.js.map +0 -1
- package/dist/utils/validations/validators/index.cjs +0 -2
- package/dist/utils/validations/validators/index.cjs.map +0 -1
- package/dist/utils/validations/validators/index.js.map +0 -1
- package/dist/utils/validations/validators/select.validator.cjs +0 -2
- package/dist/utils/validations/validators/select.validator.cjs.map +0 -1
- package/dist/utils/validations/validators/select.validator.js.map +0 -1
- package/dist/utils/validations/validators/status.validator.cjs +0 -2
- package/dist/utils/validations/validators/status.validator.cjs.map +0 -1
- package/dist/utils/validations/validators/status.validator.js.map +0 -1
|
@@ -1,2 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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.validateStatus = void 0;
|
|
7
|
+
const joi_1 = __importDefault(require("joi"));
|
|
8
|
+
/**
|
|
9
|
+
* Validate that the value is one of the status values
|
|
10
|
+
*/
|
|
11
|
+
const validateStatus = (value, statusValues) => (joi_1.default.string()
|
|
12
|
+
.allow(null)
|
|
13
|
+
.valid(...statusValues.map((statusValue) => statusValue.value))
|
|
14
|
+
.validate(value));
|
|
15
|
+
exports.validateStatus = validateStatus;
|
package/package.json
CHANGED
|
@@ -1,27 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/sadot",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2-beta",
|
|
4
4
|
"description": "",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"default": "./dist/index.cjs"
|
|
18
|
-
}
|
|
19
|
-
}
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "ts-node src/index.ts",
|
|
8
|
+
"build": "rm -rf dist && tsc",
|
|
9
|
+
"linter": "eslint .",
|
|
10
|
+
"test": "jest --runInBand",
|
|
11
|
+
"test-debug": "node --inspect-brk node_modules/.bin/jest --testTimeout=10000000",
|
|
12
|
+
"coverage": "jest --coverage --runInBand",
|
|
13
|
+
"build-to-local-repo": "node --run build && cp -r dist/* ../$REPO/node_modules/$npm_package_name/dist",
|
|
14
|
+
"dev": "nodemon",
|
|
15
|
+
"watch": "npm-watch build-to-local-repo",
|
|
16
|
+
"publish-dev": "node --run build && npm publish --tag dev"
|
|
20
17
|
},
|
|
21
|
-
"files": [
|
|
22
|
-
"dist",
|
|
23
|
-
"README.md"
|
|
24
|
-
],
|
|
25
18
|
"watch": {
|
|
26
19
|
"build-to-local-repo": {
|
|
27
20
|
"extensions": [
|
|
@@ -35,27 +28,37 @@
|
|
|
35
28
|
}
|
|
36
29
|
},
|
|
37
30
|
"dependencies": {
|
|
38
|
-
"@autofleet/common-types": "4.
|
|
31
|
+
"@autofleet/common-types": "^4.4.0",
|
|
32
|
+
"@autofleet/events": "^5.2.0",
|
|
39
33
|
"ajv": "^8.12.0",
|
|
40
34
|
"ajv-errors": "^3.0.0",
|
|
41
35
|
"ajv-formats": "^3.0.1",
|
|
42
36
|
"http-status-codes": "^2.3.0",
|
|
43
37
|
"joi": "^17.7.0",
|
|
44
|
-
"pg": "^8.
|
|
38
|
+
"pg": "^8.10.0",
|
|
45
39
|
"reflect-metadata": "^0.1.13",
|
|
46
|
-
"sequelize": "^6.
|
|
47
|
-
"sequelize-typescript": "^2.1.
|
|
48
|
-
"@autofleet/events": "^5.2.23"
|
|
40
|
+
"sequelize": "^6.31.1",
|
|
41
|
+
"sequelize-typescript": "^2.1.5"
|
|
49
42
|
},
|
|
50
43
|
"devDependencies": {
|
|
44
|
+
"@autofleet/errors": "^3.0.1",
|
|
45
|
+
"@autofleet/logger": "^4.2.1",
|
|
46
|
+
"@autofleet/node-common": "^4.0.2",
|
|
47
|
+
"@autofleet/zehut": "^4.0.1",
|
|
51
48
|
"@types/express": "^4.17.17",
|
|
49
|
+
"@types/jest": "^29.5.13",
|
|
50
|
+
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
51
|
+
"@typescript-eslint/parser": "^7.18.0",
|
|
52
|
+
"eslint": "^8.57.0",
|
|
53
|
+
"eslint-config-airbnb-base": "^15.0.0",
|
|
54
|
+
"eslint-plugin-import": "^2.22.1",
|
|
52
55
|
"express": "^4.21.2",
|
|
56
|
+
"jest": "^29.7.0",
|
|
53
57
|
"npm-watch": "^0.11.0",
|
|
54
58
|
"supertest": "^7.0.0",
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"@autofleet/zehut": "^4.5.12"
|
|
59
|
+
"ts-jest": "^29.1.2",
|
|
60
|
+
"ts-node": "^8.6.2",
|
|
61
|
+
"typescript": "^5.3.3"
|
|
59
62
|
},
|
|
60
63
|
"peerDependencies": {
|
|
61
64
|
"@autofleet/errors": "^3",
|
|
@@ -64,18 +67,14 @@
|
|
|
64
67
|
"@autofleet/sheilta": "^2",
|
|
65
68
|
"@autofleet/zehut": "^4"
|
|
66
69
|
},
|
|
70
|
+
"peerDependenciesMeta": {
|
|
71
|
+
"@autofleet/zehut": {
|
|
72
|
+
"optional": true
|
|
73
|
+
}
|
|
74
|
+
},
|
|
67
75
|
"engines": {
|
|
68
76
|
"node": ">=18.0.0"
|
|
69
77
|
},
|
|
70
78
|
"author": "Autofleet",
|
|
71
|
-
"license": "ISC"
|
|
72
|
-
|
|
73
|
-
"build": "tsdown",
|
|
74
|
-
"linter": "eslint .",
|
|
75
|
-
"test": "vitest",
|
|
76
|
-
"test-debug": "node --inspect-brk node_modules/.bin/vitest --testTimeout=10000000",
|
|
77
|
-
"coverage": "vitest --coverage",
|
|
78
|
-
"build-to-local-repo": "node --run build && cp -r dist/* ../$REPO/node_modules/$npm_package_name/dist",
|
|
79
|
-
"watch": "npm-watch build-to-local-repo"
|
|
80
|
-
}
|
|
81
|
-
}
|
|
79
|
+
"license": "ISC"
|
|
80
|
+
}
|
package/src/api/index.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { ResourceNotFoundError } from '@autofleet/errors';
|
|
2
|
+
import { Router } from '@autofleet/node-common';
|
|
3
|
+
import handleError from '../errors';
|
|
4
|
+
import * as DefinitionRepo from '../../../repository/definition';
|
|
5
|
+
import type { CreateCustomFieldDefinition, UpdateCustomFieldDefinition } from '../../../types/definition';
|
|
6
|
+
import { validateCustomFieldDefinitionCreation, validateCustomFieldDefinitionUpdate } from './validations';
|
|
7
|
+
import logger from '../../../utils/logger';
|
|
8
|
+
import type { CustomFieldDefinition } from '../../../models';
|
|
9
|
+
|
|
10
|
+
const router = Router({ logger });
|
|
11
|
+
const ENTITY = 'CustomFieldDefinition';
|
|
12
|
+
|
|
13
|
+
const toPascalCase = (str: string): string => str.replace(/(^\w|-\w)/g, (subStr) => subStr.replace(/-/, '').toUpperCase());
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create
|
|
17
|
+
*/
|
|
18
|
+
router.post<{ modelName: string; }>('/', async (req, res) => {
|
|
19
|
+
const { modelName } = req.params;
|
|
20
|
+
const modelType = toPascalCase(modelName);
|
|
21
|
+
try {
|
|
22
|
+
const validatedPayload: CreateCustomFieldDefinition = await validateCustomFieldDefinitionCreation(req.body);
|
|
23
|
+
|
|
24
|
+
const customFieldDefinition = await DefinitionRepo.create({
|
|
25
|
+
...validatedPayload,
|
|
26
|
+
modelType,
|
|
27
|
+
});
|
|
28
|
+
return res.status(201).json(customFieldDefinition);
|
|
29
|
+
} catch (err) {
|
|
30
|
+
logger.error('Failed to create custom field definition', err);
|
|
31
|
+
return handleError(err, res, { logger, message: `Error in create ${ENTITY} request` });
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get by id
|
|
37
|
+
*/
|
|
38
|
+
router.get<{ modelName: string; customFieldDefinitionId: string; }, CustomFieldDefinition>('/:customFieldDefinitionId', async (req, res) => {
|
|
39
|
+
const { customFieldDefinitionId } = req.params;
|
|
40
|
+
try {
|
|
41
|
+
const customFieldDefinition = await DefinitionRepo.findById(customFieldDefinitionId);
|
|
42
|
+
|
|
43
|
+
if (!customFieldDefinition) {
|
|
44
|
+
throw new ResourceNotFoundError();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return res.json(customFieldDefinition);
|
|
48
|
+
} catch (err) {
|
|
49
|
+
logger.error('Failed to fetch custom field definition', err);
|
|
50
|
+
return handleError(err, res, { logger, message: `Error in get ${ENTITY} request` });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Get all
|
|
56
|
+
*/
|
|
57
|
+
router.get<{ modelName: string; }, CustomFieldDefinition[], never, { entityIds?: string[]; }>('/', async (req, res) => {
|
|
58
|
+
const { params: { modelName }, query: { entityIds } } = req;
|
|
59
|
+
|
|
60
|
+
const modelType = toPascalCase(modelName);
|
|
61
|
+
try {
|
|
62
|
+
const where = {
|
|
63
|
+
modelType,
|
|
64
|
+
...(entityIds?.length > 0 && { entityId: entityIds }),
|
|
65
|
+
};
|
|
66
|
+
const customFieldDefinitions = await DefinitionRepo.findAll(where, { withDisabled: true });
|
|
67
|
+
return res.json(customFieldDefinitions);
|
|
68
|
+
} catch (err) {
|
|
69
|
+
logger.error('Failed to fetch custom field definitions', err);
|
|
70
|
+
return handleError(err, res, { logger, message: `Error in get all ${ENTITY} request` });
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Update
|
|
76
|
+
*/
|
|
77
|
+
router.patch<{ modelName: string; customFieldDefinitionId: string; }, CustomFieldDefinition>('/:customFieldDefinitionId', async (req, res) => {
|
|
78
|
+
const { customFieldDefinitionId, modelName } = req.params;
|
|
79
|
+
const modelType = toPascalCase(modelName);
|
|
80
|
+
try {
|
|
81
|
+
const validatedPayload: UpdateCustomFieldDefinition = await validateCustomFieldDefinitionUpdate(req.body);
|
|
82
|
+
|
|
83
|
+
const customFieldDefinition = await DefinitionRepo.findByWhere({
|
|
84
|
+
id: customFieldDefinitionId,
|
|
85
|
+
modelType,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
if (!customFieldDefinition) {
|
|
89
|
+
throw new ResourceNotFoundError();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const updatedCustomFieldDefinition = await DefinitionRepo.update(
|
|
93
|
+
customFieldDefinitionId,
|
|
94
|
+
{ ...validatedPayload, modelType },
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
return res.status(200).json(updatedCustomFieldDefinition);
|
|
98
|
+
} catch (err) {
|
|
99
|
+
logger.error('Failed to patch custom field definition', err);
|
|
100
|
+
return handleError(err, res, { logger, message: `Error in update ${ENTITY} request` });
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
export default router;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/* eslint-disable newline-per-chained-call */
|
|
2
|
+
import Joi from 'joi';
|
|
3
|
+
import { CustomFieldDefinitionType } from '../../../utils/constants';
|
|
4
|
+
|
|
5
|
+
const FileValidationSchema = Joi.object({
|
|
6
|
+
name: Joi.string().required(),
|
|
7
|
+
type: Joi.string(),
|
|
8
|
+
size: Joi.string(),
|
|
9
|
+
addedBy: Joi.string().uuid(),
|
|
10
|
+
});
|
|
11
|
+
const statusValidationObject = Joi.object({
|
|
12
|
+
value: Joi.string().required(),
|
|
13
|
+
color: Joi.string().required(),
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* Schema for the validation of custom field definition
|
|
17
|
+
* The only custom validation is for
|
|
18
|
+
* {@link CustomFieldDefinitionType.SELECT SELECT}
|
|
19
|
+
* and
|
|
20
|
+
* {@link CustomFieldDefinitionType.STATUS STATUS}
|
|
21
|
+
* field types.
|
|
22
|
+
* The rest of the field types are validated by Joi
|
|
23
|
+
*/
|
|
24
|
+
const ValidationSchema = Joi.when('fieldType', {
|
|
25
|
+
is: CustomFieldDefinitionType.SELECT,
|
|
26
|
+
then: Joi.array().required().items(Joi.string()).min(1).unique(),
|
|
27
|
+
otherwise: Joi.when('fieldType', {
|
|
28
|
+
is: CustomFieldDefinitionType.STATUS,
|
|
29
|
+
then: Joi.array().required().items(statusValidationObject).min(1).unique('value'),
|
|
30
|
+
otherwise: Joi.forbidden(),
|
|
31
|
+
}),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const DefaultValueSchema = Joi.when('fieldType', {
|
|
35
|
+
switch: [
|
|
36
|
+
{ is: CustomFieldDefinitionType.BOOLEAN, then: Joi.boolean().allow(null) },
|
|
37
|
+
{ is: CustomFieldDefinitionType.DATE, then: Joi.date().allow(null) },
|
|
38
|
+
{ is: CustomFieldDefinitionType.DATETIME, then: Joi.date().allow(null) },
|
|
39
|
+
{ is: CustomFieldDefinitionType.FILE, then: Joi.array().items(FileValidationSchema).allow(null) },
|
|
40
|
+
{ is: CustomFieldDefinitionType.IMAGE, then: Joi.array().items(Joi.string().uri()).allow(null) },
|
|
41
|
+
{ is: CustomFieldDefinitionType.NUMBER, then: Joi.number().allow(null) },
|
|
42
|
+
{ is: CustomFieldDefinitionType.SELECT, then: Joi.string().allow(null) },
|
|
43
|
+
{ is: CustomFieldDefinitionType.STATUS, then: Joi.string().allow(null) },
|
|
44
|
+
{ is: CustomFieldDefinitionType.TEXT, then: Joi.string().allow(null) },
|
|
45
|
+
],
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const CustomFieldDefinitionCreationSchema = Joi.object({
|
|
49
|
+
name: Joi.string().required(),
|
|
50
|
+
displayName: Joi.string().required(),
|
|
51
|
+
validation: ValidationSchema,
|
|
52
|
+
defaultValue: DefaultValueSchema,
|
|
53
|
+
fieldType: Joi.string().valid(...Object.values(CustomFieldDefinitionType)).required(),
|
|
54
|
+
entityId: Joi.string().guid().required(),
|
|
55
|
+
entityType: Joi.string().required(),
|
|
56
|
+
description: Joi.string(),
|
|
57
|
+
required: Joi.boolean(),
|
|
58
|
+
disabled: Joi.boolean(),
|
|
59
|
+
blockEditingFromUI: Joi.boolean(),
|
|
60
|
+
}).oxor('required', 'blockEditingFromUI', { isPresent: (value) => value === true });
|
|
61
|
+
|
|
62
|
+
const CustomFieldDefinitionUpdateSchema = Joi.object({
|
|
63
|
+
displayName: Joi.string(),
|
|
64
|
+
validation: ValidationSchema,
|
|
65
|
+
defaultValue: DefaultValueSchema,
|
|
66
|
+
fieldType: Joi.string().valid(...Object.values(CustomFieldDefinitionType)),
|
|
67
|
+
description: Joi.string().allow(null),
|
|
68
|
+
required: Joi.boolean(),
|
|
69
|
+
disabled: Joi.boolean(),
|
|
70
|
+
blockEditingFromUI: Joi.boolean(),
|
|
71
|
+
}).oxor('required', 'blockEditingFromUI', { isPresent: (value) => value === true });
|
|
72
|
+
|
|
73
|
+
export const validateCustomFieldDefinitionCreation = (payload) => CustomFieldDefinitionCreationSchema.validateAsync(payload, { abortEarly: false });
|
|
74
|
+
|
|
75
|
+
export const validateCustomFieldDefinitionUpdate = (payload) => CustomFieldDefinitionUpdateSchema.validateAsync(payload, { abortEarly: false });
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Response } from 'express';
|
|
2
|
+
import { handleError, BadRequest, type LogPayload } from '@autofleet/errors';
|
|
3
|
+
import { ValidationError as InputValidationError } from 'joi';
|
|
4
|
+
import { ValidationError as DatabaseValidationError } from 'sequelize';
|
|
5
|
+
|
|
6
|
+
export default (err, res: Response, additionalData: LogPayload = undefined) => {
|
|
7
|
+
let error = err;
|
|
8
|
+
if ([InputValidationError, DatabaseValidationError].some((ErrClass) => err instanceof ErrClass)) {
|
|
9
|
+
error = new BadRequest([err], null);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return handleError(error, res, additionalData);
|
|
13
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Router } from '@autofleet/node-common';
|
|
2
|
+
import logger from '../../utils/logger';
|
|
3
|
+
import definitionRouter from './definition';
|
|
4
|
+
import validatorRouter from './validator';
|
|
5
|
+
|
|
6
|
+
const router = Router({ logger });
|
|
7
|
+
|
|
8
|
+
router.use('/custom-field-definitions/:modelName', definitionRouter);
|
|
9
|
+
router.use('/custom-validators/:modelName', validatorRouter);
|
|
10
|
+
|
|
11
|
+
export default router;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { ResourceNotFoundError } from '@autofleet/errors';
|
|
2
|
+
import { Router } from '@autofleet/node-common';
|
|
3
|
+
import { StatusCodes } from 'http-status-codes';
|
|
4
|
+
import handleError from '../errors';
|
|
5
|
+
import * as ValidatorRepo from '../../../repository/validator';
|
|
6
|
+
import validations from './validations';
|
|
7
|
+
import logger from '../../../utils/logger';
|
|
8
|
+
import { validateValidatorSchema } from '../../../utils/validations/schema/validator-schema';
|
|
9
|
+
import type { CustomValidator } from '../../../models';
|
|
10
|
+
|
|
11
|
+
const router = Router({ logger });
|
|
12
|
+
const ENTITY = 'CustomValidator';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Create
|
|
16
|
+
*/
|
|
17
|
+
router.post<{ modelName: string }>('/', async (req, res) => {
|
|
18
|
+
const { modelName } = req.params;
|
|
19
|
+
try {
|
|
20
|
+
// Validate the request body
|
|
21
|
+
const validatedPayload = await validations.create.validateAsync(req.body);
|
|
22
|
+
|
|
23
|
+
// Validate that the schema is a valid AJV schema
|
|
24
|
+
validateValidatorSchema(validatedPayload.schema);
|
|
25
|
+
|
|
26
|
+
const validator = await ValidatorRepo.create({
|
|
27
|
+
...validatedPayload,
|
|
28
|
+
modelType: modelName,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return res.status(StatusCodes.CREATED).json(validator);
|
|
32
|
+
} catch (err) {
|
|
33
|
+
return handleError(err, res, { logger, message: `Error in create ${ENTITY} request` });
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get all
|
|
39
|
+
*/
|
|
40
|
+
router.get<
|
|
41
|
+
{ modelName: string },
|
|
42
|
+
{ validators: CustomValidator[] },
|
|
43
|
+
never,
|
|
44
|
+
{ entityId?: string; entityType?: string }
|
|
45
|
+
>('/', async (req, res) => {
|
|
46
|
+
try {
|
|
47
|
+
const { modelName } = req.params;
|
|
48
|
+
const { entityId, entityType } = req.query;
|
|
49
|
+
|
|
50
|
+
const where = {
|
|
51
|
+
modelType: modelName,
|
|
52
|
+
...(entityId && { entityId }),
|
|
53
|
+
...(entityType && { entityType }),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const validators = await ValidatorRepo.findAll(where);
|
|
57
|
+
|
|
58
|
+
return res.status(StatusCodes.OK).json({ validators });
|
|
59
|
+
} catch (err) {
|
|
60
|
+
return handleError(err, res, { logger, message: `Error in get all ${ENTITY} request` });
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get by id
|
|
66
|
+
*/
|
|
67
|
+
router.get<{ modelName: string; validatorId: string }, CustomValidator>('/:validatorId', async (req, res) => {
|
|
68
|
+
try {
|
|
69
|
+
const { validatorId, modelName } = req.params;
|
|
70
|
+
// Include disabled validators when fetching by ID
|
|
71
|
+
const validators = await ValidatorRepo.findAll({ id: validatorId, modelType: modelName }, { withDisabled: true });
|
|
72
|
+
|
|
73
|
+
if (!validators.length) {
|
|
74
|
+
throw new ResourceNotFoundError('Validator not found');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return res.status(StatusCodes.OK).json(validators[0]);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
return handleError(err, res, { logger, message: `Error in get ${ENTITY} request` });
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Update
|
|
85
|
+
*/
|
|
86
|
+
router.patch<{ modelName: string; validatorId: string }, CustomValidator>('/:validatorId', async (req, res) => {
|
|
87
|
+
try {
|
|
88
|
+
const { validatorId } = req.params;
|
|
89
|
+
|
|
90
|
+
// Validate the request body
|
|
91
|
+
const validatedPayload = await validations.update.validateAsync(req.body);
|
|
92
|
+
|
|
93
|
+
// If schema is included in the update, validate that it's a valid AJV schema
|
|
94
|
+
if (validatedPayload.schema) {
|
|
95
|
+
validateValidatorSchema(validatedPayload.schema);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// First verify the validator exists, including disabled ones
|
|
99
|
+
const existingValidators = await ValidatorRepo.findAll({ id: validatorId }, { withDisabled: true });
|
|
100
|
+
if (!existingValidators.length) {
|
|
101
|
+
throw new ResourceNotFoundError('Validator not found');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const [count, validators] = await ValidatorRepo.update(validatorId, validatedPayload);
|
|
105
|
+
|
|
106
|
+
if (!count) {
|
|
107
|
+
throw new ResourceNotFoundError('Validator not found');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return res.status(StatusCodes.OK).json(validators[0]);
|
|
111
|
+
} catch (err) {
|
|
112
|
+
return handleError(err, res, { logger, message: `Error in update ${ENTITY} request` });
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Delete (disable)
|
|
118
|
+
*/
|
|
119
|
+
router.delete<{ modelName: string; validatorId: string }>('/:validatorId', async (req, res) => {
|
|
120
|
+
try {
|
|
121
|
+
const { validatorId } = req.params;
|
|
122
|
+
|
|
123
|
+
// First verify the validator exists, including disabled ones
|
|
124
|
+
const existingValidators = await ValidatorRepo.findAll({ id: validatorId }, { withDisabled: true });
|
|
125
|
+
if (!existingValidators.length) {
|
|
126
|
+
throw new ResourceNotFoundError('Validator not found');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const [count] = await ValidatorRepo.disable(validatorId);
|
|
130
|
+
|
|
131
|
+
if (!count) {
|
|
132
|
+
throw new ResourceNotFoundError('Validator failed to be disabled');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return res.status(StatusCodes.NO_CONTENT).send();
|
|
136
|
+
} catch (err) {
|
|
137
|
+
return handleError(err, res, { logger, message: `Error in delete ${ENTITY} request` });
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
export default router;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import Joi from 'joi';
|
|
2
|
+
|
|
3
|
+
const jsonSchemaValidation = Joi.object().unknown(true);
|
|
4
|
+
|
|
5
|
+
const schemaObject = Joi.object({
|
|
6
|
+
type: Joi.string().valid('object'),
|
|
7
|
+
properties: Joi.object({
|
|
8
|
+
before: jsonSchemaValidation,
|
|
9
|
+
after: jsonSchemaValidation,
|
|
10
|
+
}).required(),
|
|
11
|
+
required: Joi.array().items(Joi.string()),
|
|
12
|
+
allOf: Joi.array().items(Joi.object()),
|
|
13
|
+
anyOf: Joi.array().items(Joi.object()),
|
|
14
|
+
oneOf: Joi.array().items(Joi.object()),
|
|
15
|
+
additionalProperties: Joi.alternatives().try(Joi.boolean(), Joi.object()),
|
|
16
|
+
$id: Joi.string(),
|
|
17
|
+
$schema: Joi.string(),
|
|
18
|
+
if: Joi.object(),
|
|
19
|
+
then: Joi.object(),
|
|
20
|
+
else: Joi.object(),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const validationSchemas = {
|
|
24
|
+
create: Joi.object({
|
|
25
|
+
entityId: Joi.string().uuid().required(),
|
|
26
|
+
entityType: Joi.string().required(),
|
|
27
|
+
schema: schemaObject.required(),
|
|
28
|
+
}),
|
|
29
|
+
|
|
30
|
+
update: Joi.object({
|
|
31
|
+
entityId: Joi.string().uuid(),
|
|
32
|
+
entityType: Joi.string(),
|
|
33
|
+
schema: schemaObject,
|
|
34
|
+
disabled: Joi.boolean(),
|
|
35
|
+
}).min(1),
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default validationSchemas;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/* eslint-disable max-classes-per-file */
|
|
2
|
+
import { BadRequest } from '@autofleet/errors';
|
|
3
|
+
import type { ValidationError } from 'joi';
|
|
4
|
+
import type { EntriesValidationError } from '../types/entries';
|
|
5
|
+
|
|
6
|
+
export class MissingRequiredCustomFieldError extends BadRequest {
|
|
7
|
+
constructor(missingFields: string[]) {
|
|
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
|
+
|
|
14
|
+
export class UnsupportedCustomFieldTypeError extends BadRequest {
|
|
15
|
+
constructor(fieldType: string) {
|
|
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
|
+
|
|
22
|
+
export class UnsupportedCustomValidationError extends BadRequest {
|
|
23
|
+
constructor(fieldType: string) {
|
|
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
|
+
|
|
30
|
+
export class InvalidFieldTypeError extends BadRequest {
|
|
31
|
+
constructor(fieldType: string) {
|
|
32
|
+
const err = new Error(`Invalid field type ${fieldType}`);
|
|
33
|
+
super([err], null, null);
|
|
34
|
+
this.message = 'INVALID_FIELD_TYPE';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class InvalidValueError extends BadRequest {
|
|
39
|
+
constructor(value: any, fieldDefinitionName: string, joiValidationError: ValidationError) {
|
|
40
|
+
const formattedErrorMessage = joiValidationError.message
|
|
41
|
+
.replace(/"/g, '')
|
|
42
|
+
.replace('value', `'${fieldDefinitionName}'`);
|
|
43
|
+
|
|
44
|
+
const formattedValue = typeof value === 'object' ? JSON.stringify(value) : value;
|
|
45
|
+
|
|
46
|
+
const invalidValueMessage = `Invalid Value on field '${fieldDefinitionName}'. ${formattedErrorMessage}. received: '${formattedValue}'`;
|
|
47
|
+
|
|
48
|
+
const err = new Error(invalidValueMessage);
|
|
49
|
+
super([err], null, null);
|
|
50
|
+
this.message = invalidValueMessage;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export class InvalidEntriesError extends BadRequest {
|
|
55
|
+
constructor(modelId: string, validationErrors: EntriesValidationError[]) {
|
|
56
|
+
const errors = validationErrors.map((validationError) => new InvalidValueError(validationError.value, validationError.fieldDefinitionName, validationError.joiValidationError));
|
|
57
|
+
super(errors, null, null);
|
|
58
|
+
this.message = `Invalid entries on ${modelId}\n${validationErrors.map((validationError) => (
|
|
59
|
+
`${validationError.fieldDefinitionName} - ${validationError.joiValidationError.message}`
|
|
60
|
+
)).join('\n')}`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export class MissingDefinitionError extends BadRequest {
|
|
65
|
+
constructor(fieldNames: string[]) {
|
|
66
|
+
const err = new Error(`Missing custom field definition for field ${fieldNames.join(',')}`);
|
|
67
|
+
super([err], null, null);
|
|
68
|
+
this.message = 'MISSING_DEFINITION';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import Events from '@autofleet/events';
|
|
2
|
+
import { getUser } from '@autofleet/zehut';
|
|
3
|
+
import logger from '../utils/logger';
|
|
4
|
+
import type {
|
|
5
|
+
CustomFieldDefinition,
|
|
6
|
+
CustomFieldEntries,
|
|
7
|
+
CustomFieldValue,
|
|
8
|
+
CustomValidator,
|
|
9
|
+
} from '../models';
|
|
10
|
+
|
|
11
|
+
const events = new Events({
|
|
12
|
+
logger,
|
|
13
|
+
getUserId: (payload) => payload?.user_id ?? getUser()?.id ?? null,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const KEYS_TO_CONVERT = ['value', 'defaultValue', 'blockEditingFromUI'];
|
|
17
|
+
|
|
18
|
+
const stringifyBooleans = (savedObject: any, keysToConvert: string[]) => {
|
|
19
|
+
const savedObjectKeySet = new Set(Object.keys(savedObject));
|
|
20
|
+
if (keysToConvert.every((key) => !savedObjectKeySet.has(key))) {
|
|
21
|
+
return savedObject;
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
...savedObject,
|
|
25
|
+
...Object.fromEntries(keysToConvert.map((key) => [key, typeof savedObject[key] === 'boolean' ? savedObject[key].toString() : savedObject[key]])),
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const modelTableMapping = {
|
|
30
|
+
CustomFieldDefinition: {
|
|
31
|
+
tableName: 'dim_custom_field_definition',
|
|
32
|
+
eventVersion: '1',
|
|
33
|
+
},
|
|
34
|
+
CustomFieldValue: {
|
|
35
|
+
tableName: 'dim_custom_field_value',
|
|
36
|
+
eventVersion: '1',
|
|
37
|
+
},
|
|
38
|
+
CustomFieldEntries: {
|
|
39
|
+
tableName: 'dim_custom_field_entries',
|
|
40
|
+
eventVersion: '1',
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const sendDimEvent = (instance: CustomFieldDefinition | CustomFieldValue | CustomFieldEntries | CustomValidator): void => {
|
|
45
|
+
const mapping = modelTableMapping[instance.constructor.name];
|
|
46
|
+
if (!mapping) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
let objectToSend = instance.get();
|
|
50
|
+
try {
|
|
51
|
+
objectToSend = stringifyBooleans(instance.get(), KEYS_TO_CONVERT);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
logger.error('Failed to convert booleans in dim event payload', err);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
events.sendObject(
|
|
57
|
+
mapping.tableName,
|
|
58
|
+
mapping.eventVersion,
|
|
59
|
+
objectToSend,
|
|
60
|
+
).catch(() => {});
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export default events;
|