@autofleet/sadot 0.12.0 → 0.13.0-beta.0
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/package.json +3 -1
- package/src/api/v1/index.ts +2 -0
- package/src/api/v1/validator/index.ts +127 -0
- package/src/api/v1/validator/validations.ts +39 -0
- package/src/events/index.ts +1 -1
- package/src/hooks/hooks.ts +304 -0
- package/src/hooks/index.ts +10 -5
- package/src/index.ts +6 -0
- package/src/models/CustomValidator.ts +76 -0
- package/src/models/index.ts +7 -2
- package/src/repository/validator.ts +91 -0
- package/src/tests/helpers/commonHooks.ts +9 -2
- package/src/tests/helpers/index.ts +7 -2
- package/src/types/index.ts +1 -0
- package/src/utils/validations/schema/README.md +93 -0
- package/src/utils/validations/schema/validator-schema.ts +103 -0
- package/dist/api/index.d.ts +0 -3
- package/dist/api/index.js +0 -12
- package/dist/api/v1/definition/index.d.ts +0 -3
- package/dist/api/v1/definition/index.js +0 -116
- package/dist/api/v1/definition/validations.d.ts +0 -2
- package/dist/api/v1/definition/validations.js +0 -77
- package/dist/api/v1/errors.d.ts +0 -4
- package/dist/api/v1/errors.js +0 -12
- package/dist/api/v1/index.d.ts +0 -3
- package/dist/api/v1/index.js +0 -11
- package/dist/errors/index.d.ts +0 -24
- package/dist/errors/index.js +0 -66
- package/dist/events/index.d.ts +0 -4
- package/dist/events/index.js +0 -50
- package/dist/hooks/create.d.ts +0 -10
- package/dist/hooks/create.js +0 -95
- package/dist/hooks/enrich.d.ts +0 -30
- package/dist/hooks/enrich.js +0 -159
- package/dist/hooks/find.d.ts +0 -1
- package/dist/hooks/find.js +0 -29
- package/dist/hooks/index.d.ts +0 -6
- package/dist/hooks/index.js +0 -18
- package/dist/hooks/update.d.ts +0 -10
- package/dist/hooks/update.js +0 -49
- package/dist/hooks/utils/updateInstanceValues.d.ts +0 -15
- package/dist/hooks/utils/updateInstanceValues.js +0 -50
- package/dist/hooks/workaround.d.ts +0 -10
- package/dist/hooks/workaround.js +0 -37
- package/dist/index.d.ts +0 -13
- package/dist/index.js +0 -67
- package/dist/models/CustomFieldDefinition.d.ts +0 -25
- package/dist/models/CustomFieldDefinition.js +0 -192
- package/dist/models/CustomFieldEntries.d.ts +0 -15
- package/dist/models/CustomFieldEntries.js +0 -123
- package/dist/models/CustomFieldValue.d.ts +0 -16
- package/dist/models/CustomFieldValue.js +0 -151
- package/dist/models/index.d.ts +0 -17
- package/dist/models/index.js +0 -113
- package/dist/models/tests/AssociatedTestModel.d.ts +0 -12
- package/dist/models/tests/AssociatedTestModel.js +0 -71
- package/dist/models/tests/TestModel.d.ts +0 -12
- package/dist/models/tests/TestModel.js +0 -69
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.d.ts +0 -10
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.js +0 -53
- package/dist/models/tests/contextAwareModels/ContextTestModel.d.ts +0 -13
- package/dist/models/tests/contextAwareModels/ContextTestModel.js +0 -47
- package/dist/repository/definition.d.ts +0 -36
- package/dist/repository/definition.js +0 -121
- package/dist/repository/entries.d.ts +0 -13
- package/dist/repository/entries.js +0 -92
- package/dist/repository/utils/formatValues.d.ts +0 -3
- package/dist/repository/utils/formatValues.js +0 -16
- package/dist/repository/value.d.ts +0 -28
- package/dist/repository/value.js +0 -124
- package/dist/scopes/filter.d.ts +0 -30
- package/dist/scopes/filter.js +0 -75
- package/dist/scopes/helpers/filter.helpers.d.ts +0 -42
- package/dist/scopes/helpers/filter.helpers.js +0 -204
- package/dist/scopes/index.d.ts +0 -2
- package/dist/scopes/index.js +0 -6
- package/dist/tests/api/test-api.d.ts +0 -2
- package/dist/tests/api/test-api.js +0 -38
- package/dist/tests/functional/searching/index.d.ts +0 -8
- package/dist/tests/functional/searching/index.js +0 -44
- package/dist/tests/helpers/commonHooks.d.ts +0 -5
- package/dist/tests/helpers/commonHooks.js +0 -55
- package/dist/tests/helpers/database-config.d.ts +0 -16
- package/dist/tests/helpers/database-config.js +0 -17
- package/dist/tests/helpers/index.d.ts +0 -7
- package/dist/tests/helpers/index.js +0 -29
- package/dist/tests/mocks/definition.mock.d.ts +0 -48
- package/dist/tests/mocks/definition.mock.js +0 -78
- package/dist/tests/mocks/events.mock.d.ts +0 -4
- package/dist/tests/mocks/events.mock.js +0 -21
- package/dist/tests/mocks/testModel.d.ts +0 -12
- package/dist/tests/mocks/testModel.js +0 -35
- package/dist/types/definition/index.d.ts +0 -25
- package/dist/types/definition/index.js +0 -2
- package/dist/types/entries/index.d.ts +0 -25
- package/dist/types/entries/index.js +0 -2
- package/dist/types/index.d.ts +0 -34
- package/dist/types/index.js +0 -2
- package/dist/types/value/index.d.ts +0 -15
- package/dist/types/value/index.js +0 -2
- package/dist/utils/constants/index.d.ts +0 -19
- package/dist/utils/constants/index.js +0 -22
- package/dist/utils/db/index.d.ts +0 -4
- package/dist/utils/db/index.js +0 -24
- package/dist/utils/helpers/index.d.ts +0 -26
- package/dist/utils/helpers/index.js +0 -40
- package/dist/utils/init.d.ts +0 -7
- package/dist/utils/init.js +0 -109
- package/dist/utils/logger/index.d.ts +0 -3
- package/dist/utils/logger/index.js +0 -42
- package/dist/utils/scopeAttributes.d.ts +0 -2
- package/dist/utils/scopeAttributes.js +0 -11
- package/dist/utils/validations/index.d.ts +0 -8
- package/dist/utils/validations/index.js +0 -41
- package/dist/utils/validations/schema/custom-fields.d.ts +0 -3
- package/dist/utils/validations/schema/custom-fields.js +0 -9
- package/dist/utils/validations/type.d.ts +0 -15
- package/dist/utils/validations/type.js +0 -2
- package/dist/utils/validations/validators/index.d.ts +0 -14
- package/dist/utils/validations/validators/index.js +0 -40
- package/dist/utils/validations/validators/select.validator.d.ts +0 -5
- package/dist/utils/validations/validators/select.validator.js +0 -12
- package/dist/utils/validations/validators/status.validator.d.ts +0 -12
- package/dist/utils/validations/validators/status.validator.js +0 -15
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { Transactionable } from 'sequelize';
|
|
2
|
+
import logger from '../utils/logger';
|
|
3
|
+
import { CustomValidator } from '../models';
|
|
4
|
+
|
|
5
|
+
export interface FindValidatorOptions extends Transactionable {
|
|
6
|
+
withDisabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Make sure this interface is compatible with the Sequelize model
|
|
10
|
+
export interface ValidatorAttributes {
|
|
11
|
+
entityId: string;
|
|
12
|
+
entityType: string;
|
|
13
|
+
modelType: string;
|
|
14
|
+
schema: Record<string, unknown>;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
[key: string]: unknown; // Add index signature for Sequelize compatibility
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const create = async (
|
|
20
|
+
validatorAttributes: ValidatorAttributes,
|
|
21
|
+
options: Transactionable = {},
|
|
22
|
+
): Promise<CustomValidator> => {
|
|
23
|
+
logger.debug('custom-validator - create validator');
|
|
24
|
+
|
|
25
|
+
// Use unknown type to bypass TypeScript errors while maintaining compatibility
|
|
26
|
+
const validator = await CustomValidator.create(validatorAttributes as Record<string, unknown>, options);
|
|
27
|
+
|
|
28
|
+
return validator;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const findAll = async (
|
|
32
|
+
where = {},
|
|
33
|
+
options: FindValidatorOptions = { withDisabled: false },
|
|
34
|
+
): Promise<CustomValidator[]> => {
|
|
35
|
+
logger.debug('custom-validator - find all validators');
|
|
36
|
+
|
|
37
|
+
const { transaction, withDisabled } = options;
|
|
38
|
+
|
|
39
|
+
const fullWhere = withDisabled
|
|
40
|
+
? where
|
|
41
|
+
: { ...where, disabled: false };
|
|
42
|
+
|
|
43
|
+
const validators = await CustomValidator.findAll({
|
|
44
|
+
where: fullWhere,
|
|
45
|
+
transaction,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return validators;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const findAllByModelType = async (
|
|
52
|
+
modelType: string,
|
|
53
|
+
entityId: string,
|
|
54
|
+
options: FindValidatorOptions = { withDisabled: false },
|
|
55
|
+
): Promise<CustomValidator[]> => {
|
|
56
|
+
logger.debug('custom-validator - find all validators by model type');
|
|
57
|
+
|
|
58
|
+
return findAll(
|
|
59
|
+
{
|
|
60
|
+
modelType,
|
|
61
|
+
entityId,
|
|
62
|
+
},
|
|
63
|
+
options,
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const update = async (
|
|
68
|
+
id: string,
|
|
69
|
+
updates: Partial<ValidatorAttributes>,
|
|
70
|
+
options?: Transactionable,
|
|
71
|
+
): Promise<[number, CustomValidator[]]> => {
|
|
72
|
+
logger.debug('custom-validator - update validator');
|
|
73
|
+
|
|
74
|
+
return CustomValidator.update(
|
|
75
|
+
updates,
|
|
76
|
+
{
|
|
77
|
+
where: { id },
|
|
78
|
+
returning: true,
|
|
79
|
+
...options,
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const disable = async (
|
|
85
|
+
id: string,
|
|
86
|
+
options?: Transactionable,
|
|
87
|
+
): Promise<[number, CustomValidator[]]> => {
|
|
88
|
+
logger.debug('custom-validator - disable validator');
|
|
89
|
+
|
|
90
|
+
return update(id, { disabled: true }, options);
|
|
91
|
+
};
|
|
@@ -9,7 +9,10 @@ import type { Models } from '../../types';
|
|
|
9
9
|
export function commonTestHooks(
|
|
10
10
|
app: Application | null = null,
|
|
11
11
|
models: Models[] = [{ name: 'TestModel', scopeAttributes: ['fleetId'] }],
|
|
12
|
-
options: { useCustomFieldsEntries: boolean } = {
|
|
12
|
+
options: { useCustomFieldsEntries: boolean, useValidators?: boolean } = {
|
|
13
|
+
useCustomFieldsEntries: false,
|
|
14
|
+
useValidators: false,
|
|
15
|
+
},
|
|
13
16
|
) {
|
|
14
17
|
let sequelize: Sequelize;
|
|
15
18
|
|
|
@@ -22,12 +25,16 @@ export function commonTestHooks(
|
|
|
22
25
|
getUser: () => undefined,
|
|
23
26
|
sequelize,
|
|
24
27
|
useCustomFieldsEntries: options.useCustomFieldsEntries,
|
|
28
|
+
useValidators: options.useValidators,
|
|
25
29
|
});
|
|
26
30
|
});
|
|
27
31
|
|
|
28
32
|
afterEach(async () => {
|
|
29
33
|
jest.clearAllMocks();
|
|
30
|
-
await cleanup({
|
|
34
|
+
await cleanup({
|
|
35
|
+
useCustomFieldsEntries: options.useCustomFieldsEntries,
|
|
36
|
+
useValidators: options.useValidators,
|
|
37
|
+
});
|
|
31
38
|
});
|
|
32
39
|
|
|
33
40
|
afterAll(async () => {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { generateFilterReplacements } from '@autofleet/sheilta';
|
|
2
2
|
import {
|
|
3
|
-
ContextAwareTestModel, ContextTestModel, CustomFieldDefinition, CustomFieldEntries, TestModel,
|
|
3
|
+
ContextAwareTestModel, ContextTestModel, CustomFieldDefinition, CustomFieldEntries, CustomValidator, TestModel,
|
|
4
4
|
} from '../../models';
|
|
5
5
|
import type { CustomFieldOptions } from '../../types';
|
|
6
6
|
|
|
7
7
|
// eslint-disable-next-line import/prefer-default-export
|
|
8
|
-
export const cleanup = async (options?: Pick<CustomFieldOptions, 'useCustomFieldsEntries'>): Promise<void> => {
|
|
8
|
+
export const cleanup = async (options?: Pick<CustomFieldOptions, 'useCustomFieldsEntries' | 'useValidators'>): Promise<void> => {
|
|
9
9
|
if (process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'development') {
|
|
10
10
|
await CustomFieldDefinition.unscoped().destroy({ where: {} });
|
|
11
11
|
await TestModel.destroy({ where: {} });
|
|
@@ -15,6 +15,11 @@ export const cleanup = async (options?: Pick<CustomFieldOptions, 'useCustomField
|
|
|
15
15
|
if (options?.useCustomFieldsEntries) {
|
|
16
16
|
await CustomFieldEntries.unscoped().destroy({ where: {} });
|
|
17
17
|
}
|
|
18
|
+
|
|
19
|
+
// Clean up validators if they were used
|
|
20
|
+
if (options?.useValidators) {
|
|
21
|
+
await CustomValidator.unscoped().destroy({ where: {} });
|
|
22
|
+
}
|
|
18
23
|
}
|
|
19
24
|
};
|
|
20
25
|
|
package/src/types/index.ts
CHANGED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Schema Validation
|
|
2
|
+
|
|
3
|
+
This directory contains schema validation utilities for the Sadot library, including:
|
|
4
|
+
|
|
5
|
+
1. **Custom Fields Schemas** - Schema definitions for custom field validation
|
|
6
|
+
2. **Validator Schemas** - Meta-validation for custom validator JSON schemas
|
|
7
|
+
|
|
8
|
+
## Custom Fields Schema
|
|
9
|
+
|
|
10
|
+
`custom-fields.ts` defines JSON Schema validation for custom field definitions, ensuring fields are created with valid configurations.
|
|
11
|
+
|
|
12
|
+
## Validator Schema Validation
|
|
13
|
+
|
|
14
|
+
`validator-schema.ts` provides meta-validation for custom validator schemas. It ensures that:
|
|
15
|
+
|
|
16
|
+
1. The validator schema follows the expected structure
|
|
17
|
+
2. The schema is a valid JSON Schema that can be compiled by AJV
|
|
18
|
+
3. The validation rules defined in the schema are syntactically correct
|
|
19
|
+
|
|
20
|
+
### Usage
|
|
21
|
+
|
|
22
|
+
The `validateValidatorSchema` function is used by the custom validator API to validate schemas at creation and update time:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { validateValidatorSchema } from '../utils/validations/schema/validator-schema';
|
|
26
|
+
|
|
27
|
+
// Validates a schema, throws BadRequest if invalid
|
|
28
|
+
validateValidatorSchema(schema);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Schema Structure
|
|
32
|
+
|
|
33
|
+
Validator schemas must follow this general structure:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"type": "object",
|
|
38
|
+
"properties": {
|
|
39
|
+
"before": {
|
|
40
|
+
"type": "object",
|
|
41
|
+
"properties": {
|
|
42
|
+
// Model properties to validate before update
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"after": {
|
|
46
|
+
"type": "object",
|
|
47
|
+
"properties": {
|
|
48
|
+
// Model properties to validate after update/create
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
For create operations, only the `after` section is used. For update operations, both `before` and `after` can be used.
|
|
56
|
+
|
|
57
|
+
### Conditional Validation
|
|
58
|
+
|
|
59
|
+
The schema can include conditional validation using JSON Schema's `if/then/else` constructs:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"type": "object",
|
|
64
|
+
"if": {
|
|
65
|
+
"properties": {
|
|
66
|
+
"before": {
|
|
67
|
+
"properties": {
|
|
68
|
+
"status": { "const": "PENDING" }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"then": {
|
|
74
|
+
"properties": {
|
|
75
|
+
"after": {
|
|
76
|
+
"properties": {
|
|
77
|
+
"status": { "enum": ["APPROVED", "REJECTED"] }
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This example validates that if a model's status was "PENDING", it can only be updated to "APPROVED" or "REJECTED".
|
|
86
|
+
|
|
87
|
+
### Error Handling
|
|
88
|
+
|
|
89
|
+
Schema validation errors are thrown as BadRequest errors with descriptive messages indicating:
|
|
90
|
+
|
|
91
|
+
1. The specific validation error in the schema
|
|
92
|
+
2. The path within the schema where the error occurred
|
|
93
|
+
3. A readable message for API consumers
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import Ajv from 'ajv';
|
|
2
|
+
import { BadRequest } from '@autofleet/errors';
|
|
3
|
+
import logger from '../../logger';
|
|
4
|
+
|
|
5
|
+
// Instantiate Ajv for meta-validation
|
|
6
|
+
const metaValidator = new Ajv({
|
|
7
|
+
allErrors: true,
|
|
8
|
+
strict: false,
|
|
9
|
+
strictTypes: false,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Schema for validating JSON Schema objects in custom validators
|
|
14
|
+
* This is a meta-schema to ensure that custom validator schemas are valid Ajv schemas
|
|
15
|
+
*/
|
|
16
|
+
const validatorMetaSchema = {
|
|
17
|
+
type: 'object',
|
|
18
|
+
properties: {
|
|
19
|
+
type: { type: 'string', enum: ['object'] },
|
|
20
|
+
properties: {
|
|
21
|
+
type: 'object',
|
|
22
|
+
properties: {
|
|
23
|
+
before: {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
type: { type: 'string', enum: ['object'] },
|
|
27
|
+
properties: { type: 'object' },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
after: {
|
|
31
|
+
type: 'object',
|
|
32
|
+
properties: {
|
|
33
|
+
type: { type: 'string', enum: ['object'] },
|
|
34
|
+
properties: { type: 'object' },
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: {
|
|
40
|
+
type: 'array',
|
|
41
|
+
items: { type: 'string' },
|
|
42
|
+
},
|
|
43
|
+
if: { type: 'object' },
|
|
44
|
+
then: { type: 'object' },
|
|
45
|
+
else: { type: 'object' },
|
|
46
|
+
},
|
|
47
|
+
required: ['type', 'properties'],
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Validates that a given schema is a valid Ajv schema
|
|
52
|
+
* This function is used to validate schemas passed to custom validators
|
|
53
|
+
*
|
|
54
|
+
* @param schema The schema to validate
|
|
55
|
+
* @returns true if valid, throws an error if invalid
|
|
56
|
+
*/
|
|
57
|
+
export const validateValidatorSchema = (schema: Record<string, unknown>): boolean => {
|
|
58
|
+
try {
|
|
59
|
+
// First validate the schema structure
|
|
60
|
+
const validateMetaSchema = metaValidator.compile(validatorMetaSchema);
|
|
61
|
+
const isValidStructure = validateMetaSchema(schema);
|
|
62
|
+
|
|
63
|
+
if (!isValidStructure) {
|
|
64
|
+
const errorDetails = validateMetaSchema.errors?.map((err) =>
|
|
65
|
+
`${(err as unknown as { instancePath: string }).instancePath || ''} ${(err as unknown as { message: string }).message || 'Invalid schema structure'}`).join(', ');
|
|
66
|
+
|
|
67
|
+
logger.error('Invalid validator schema structure', {
|
|
68
|
+
errors: validateMetaSchema.errors,
|
|
69
|
+
schema,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
throw new BadRequest(
|
|
73
|
+
[new Error(`Invalid validator schema structure: ${errorDetails}`)],
|
|
74
|
+
['Invalid validator schema structure'],
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Then try to compile the schema with Ajv to verify it's a valid JSON Schema
|
|
79
|
+
try {
|
|
80
|
+
metaValidator.compile(schema);
|
|
81
|
+
return true;
|
|
82
|
+
} catch (compileError) {
|
|
83
|
+
logger.error('Failed to compile validator schema', { error: compileError, schema });
|
|
84
|
+
|
|
85
|
+
throw new BadRequest(
|
|
86
|
+
[new Error(`Failed to compile validator schema: ${(compileError as Error).message}`)],
|
|
87
|
+
['Invalid validator schema'],
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
} catch (error) {
|
|
91
|
+
if (error instanceof BadRequest) {
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
logger.error('Error validating validator schema', { error, schema });
|
|
96
|
+
throw new BadRequest(
|
|
97
|
+
[new Error(`Error validating validator schema: ${(error as Error).message}`)],
|
|
98
|
+
['Invalid validator schema'],
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export default validateValidatorSchema;
|
package/dist/api/index.d.ts
DELETED
package/dist/api/index.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
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;
|
|
@@ -1,116 +0,0 @@
|
|
|
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;
|
|
@@ -1,77 +0,0 @@
|
|
|
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;
|
package/dist/api/v1/errors.d.ts
DELETED
package/dist/api/v1/errors.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
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
|
-
};
|
package/dist/api/v1/index.d.ts
DELETED
package/dist/api/v1/index.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
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 router = (0, node_common_1.Router)({ logger: logger_1.default });
|
|
10
|
-
router.use('/custom-field-definitions/:modelName', definition_1.default);
|
|
11
|
-
exports.default = router;
|
package/dist/errors/index.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
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
|
-
}
|