@autofleet/sadot 0.13.5-beta → 0.13.5-beta-2
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/dist/hooks/hooks.d.ts +0 -16
- package/dist/hooks/hooks.js +22 -25
- package/dist/models/index.js +0 -7
- package/dist/repository/validator.d.ts +2 -1
- package/dist/repository/validator.js +3 -1
- package/package.json +1 -1
- package/src/hooks/hooks.ts +35 -29
- package/src/repository/validator.ts +5 -2
package/dist/hooks/hooks.d.ts
CHANGED
|
@@ -1,19 +1,4 @@
|
|
|
1
1
|
import type { CustomFieldOptions, ModelOptions } from '../types';
|
|
2
|
-
type AjvError = {
|
|
3
|
-
instancePath?: string;
|
|
4
|
-
keyword: string;
|
|
5
|
-
message?: string;
|
|
6
|
-
params?: Record<string, any>;
|
|
7
|
-
schemaPath?: string;
|
|
8
|
-
[key: string]: any;
|
|
9
|
-
};
|
|
10
|
-
export declare const formatAjvErrors: (errors?: AjvError[]) => {
|
|
11
|
-
path: string;
|
|
12
|
-
keyword: string;
|
|
13
|
-
message: string;
|
|
14
|
-
errorCode: string;
|
|
15
|
-
details: Record<string, any>;
|
|
16
|
-
}[];
|
|
17
2
|
/**
|
|
18
3
|
* Hook to handle validation and custom fields during creation
|
|
19
4
|
*/
|
|
@@ -30,4 +15,3 @@ export declare const beforeBulkCreate: (options: any) => void;
|
|
|
30
15
|
* Hook to enable individual hooks for bulk update operations
|
|
31
16
|
*/
|
|
32
17
|
export declare const beforeBulkUpdate: (options: any) => void;
|
|
33
|
-
export {};
|
package/dist/hooks/hooks.js
CHANGED
|
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.beforeBulkUpdate = exports.beforeBulkCreate = exports.beforeUpdate = exports.beforeCreate =
|
|
29
|
+
exports.beforeBulkUpdate = exports.beforeBulkCreate = exports.beforeUpdate = exports.beforeCreate = void 0;
|
|
30
30
|
const ajv_1 = __importDefault(require("ajv"));
|
|
31
31
|
const joi_1 = __importDefault(require("joi"));
|
|
32
32
|
const ajv_formats_1 = __importDefault(require("ajv-formats"));
|
|
@@ -90,25 +90,22 @@ const getCompleteCustomFields = async (instance, options) => {
|
|
|
90
90
|
}
|
|
91
91
|
return instance.customFields || {};
|
|
92
92
|
};
|
|
93
|
-
const formatAjvErrors = (errors
|
|
94
|
-
const
|
|
95
|
-
|
|
93
|
+
const formatAjvErrors = (errors) => errors.reduce((acc, err) => {
|
|
94
|
+
const basePath = (err.instancePath || '')
|
|
95
|
+
.split('/')
|
|
96
|
+
.filter(Boolean)
|
|
97
|
+
.join('.')
|
|
98
|
+
.replace(/^after\./, '');
|
|
99
|
+
const missingProp = err.keyword === 'required' ? `.${err.params?.missingProperty}` : '';
|
|
100
|
+
const key = (basePath + missingProp).replace(/^\./, '') || 'root';
|
|
96
101
|
const message = err.message || 'Invalid value';
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
path,
|
|
101
|
-
keyword,
|
|
102
|
-
message,
|
|
103
|
-
errorCode,
|
|
104
|
-
details: err.params || {},
|
|
105
|
-
};
|
|
106
|
-
});
|
|
107
|
-
exports.formatAjvErrors = formatAjvErrors;
|
|
102
|
+
acc[key] = message;
|
|
103
|
+
return acc;
|
|
104
|
+
}, {});
|
|
108
105
|
/**
|
|
109
106
|
* Validates the model using custom validators
|
|
110
107
|
*/
|
|
111
|
-
const validateModel = async (instance, options, scopeAttributes, isCreate = false) => {
|
|
108
|
+
const validateModel = async (instance, options, scopeAttributes, modelOptions = {}, isCreate = false) => {
|
|
112
109
|
var _a;
|
|
113
110
|
const modelType = instance.constructor.name;
|
|
114
111
|
logger_1.default.debug('sadot - validating model', { isCreate, modelType });
|
|
@@ -138,6 +135,9 @@ const validateModel = async (instance, options, scopeAttributes, isCreate = fals
|
|
|
138
135
|
validatorsPromise = ValidatorRepo.findAllByModelType(modelType, entityId, {
|
|
139
136
|
transaction: options.transaction,
|
|
140
137
|
attributes: CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL,
|
|
138
|
+
...(modelOptions.include && {
|
|
139
|
+
include: modelOptions.include?.(entityId),
|
|
140
|
+
}),
|
|
141
141
|
raw: true,
|
|
142
142
|
});
|
|
143
143
|
if (options.transaction) {
|
|
@@ -189,13 +189,9 @@ const validateModel = async (instance, options, scopeAttributes, isCreate = fals
|
|
|
189
189
|
},
|
|
190
190
|
})));
|
|
191
191
|
if (!isValid) {
|
|
192
|
-
const formattedErrors = (0, exports.formatAjvErrors)(validateSchema.errors);
|
|
193
|
-
console.log(JSON.stringify({ AAAAAAA: formattedErrors, BBBBB: validateSchema.errors }));
|
|
194
192
|
const errorDetails = validateSchema.errors?.map((err) => `${err.instancePath || ''} ${err.message || 'Invalid value'}`).join(', ');
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
...formattedErrors.map((err) => new Error(err.message)),
|
|
198
|
-
]);
|
|
193
|
+
const formattedErrors = formatAjvErrors(validateSchema.errors);
|
|
194
|
+
throw new errors_1.BadRequest([new Error(`Validation failed for ${modelType}: ${errorDetails}`)], undefined, formattedErrors);
|
|
199
195
|
}
|
|
200
196
|
}
|
|
201
197
|
}
|
|
@@ -224,7 +220,8 @@ const validateModel = async (instance, options, scopeAttributes, isCreate = fals
|
|
|
224
220
|
const errorDetails = validateSchema
|
|
225
221
|
.errors
|
|
226
222
|
?.map((err) => `${err.instancePath || ''} ${err.message || 'Invalid value'}`).join(', ');
|
|
227
|
-
|
|
223
|
+
const formattedErrors = formatAjvErrors(validateSchema.errors);
|
|
224
|
+
throw new errors_1.BadRequest([new Error(`Validation failed for ${modelType}: ${errorDetails}`)], undefined, formattedErrors);
|
|
228
225
|
}
|
|
229
226
|
}
|
|
230
227
|
}
|
|
@@ -292,7 +289,7 @@ const beforeCreate = (scopeAttributes, modelOptions = {}, sadotOptions = { useCu
|
|
|
292
289
|
throw new errors_2.MissingRequiredCustomFieldError(missingFields);
|
|
293
290
|
}
|
|
294
291
|
// Step 2: Validate the model data (including custom fields)
|
|
295
|
-
await validateModel(instance, options, scopeAttributes, true);
|
|
292
|
+
await validateModel(instance, options, scopeAttributes, modelOptions, true);
|
|
296
293
|
// format date and datetime fields
|
|
297
294
|
formatDates(fieldDefinitions, instance);
|
|
298
295
|
// Step 3: Save custom field values if they exist
|
|
@@ -330,7 +327,7 @@ const beforeUpdate = (scopeAttributes, modelOptions = {}, sadotOptions = { useCu
|
|
|
330
327
|
modelType, modelOptions, identifiers, options,
|
|
331
328
|
});
|
|
332
329
|
// Step 1: Validate the model data (including custom fields)
|
|
333
|
-
await validateModel(instance, options, scopeAttributes, false);
|
|
330
|
+
await validateModel(instance, options, scopeAttributes, modelOptions, false);
|
|
334
331
|
// format date and datetime fields
|
|
335
332
|
formatDates(fieldDefinitions, instance);
|
|
336
333
|
// Step 2: Update custom field values if they exist
|
package/dist/models/index.js
CHANGED
|
@@ -59,13 +59,6 @@ const initTables = async (sequelize, getUser, { schemaPrefix = SADOT_MIGRATION_P
|
|
|
59
59
|
if (!user?.permissions) {
|
|
60
60
|
return {};
|
|
61
61
|
}
|
|
62
|
-
console.log({
|
|
63
|
-
PPPPPPPP: JSON.stringify([
|
|
64
|
-
...Object.keys(user.permissions.fleets),
|
|
65
|
-
...Object.keys(user.permissions.businessModels),
|
|
66
|
-
...Object.keys(user.permissions.demandSources),
|
|
67
|
-
]),
|
|
68
|
-
});
|
|
69
62
|
return {
|
|
70
63
|
where: {
|
|
71
64
|
entityId: [
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { Transactionable } from 'sequelize';
|
|
1
|
+
import type { IncludeOptions, Transactionable } from 'sequelize';
|
|
2
2
|
import { CustomValidator } from '../models';
|
|
3
3
|
export interface FindValidatorOptions extends Transactionable {
|
|
4
4
|
withDisabled?: boolean;
|
|
5
5
|
attributes?: string[];
|
|
6
6
|
raw?: boolean;
|
|
7
|
+
include?: IncludeOptions[];
|
|
7
8
|
}
|
|
8
9
|
export interface ValidatorAttributes {
|
|
9
10
|
entityId: string;
|
|
@@ -40,7 +40,9 @@ const findAllByModelType = async (modelType, entityId, options = { withDisabled:
|
|
|
40
40
|
logger_1.default.debug('custom-validator - find all validators by model type');
|
|
41
41
|
return (0, exports.findAll)({
|
|
42
42
|
modelType,
|
|
43
|
-
|
|
43
|
+
...(!options.include && {
|
|
44
|
+
entityId,
|
|
45
|
+
}),
|
|
44
46
|
}, options);
|
|
45
47
|
};
|
|
46
48
|
exports.findAllByModelType = findAllByModelType;
|
package/package.json
CHANGED
package/src/hooks/hooks.ts
CHANGED
|
@@ -78,32 +78,28 @@ const getCompleteCustomFields = async (instance, options): Promise<Record<string
|
|
|
78
78
|
return instance.customFields || {};
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
const formatAjvErrors = (
|
|
82
|
+
errors: {
|
|
82
83
|
instancePath?: string;
|
|
83
84
|
keyword: string;
|
|
84
85
|
message?: string;
|
|
85
86
|
params?: Record<string, any>;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
}[],
|
|
88
|
+
): Record<string, string> => errors.reduce((acc, err) => {
|
|
89
|
+
const basePath = (err.instancePath || '')
|
|
90
|
+
.split('/')
|
|
91
|
+
.filter(Boolean)
|
|
92
|
+
.join('.')
|
|
93
|
+
.replace(/^after\./, '');
|
|
89
94
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return {
|
|
100
|
-
path,
|
|
101
|
-
keyword,
|
|
102
|
-
message,
|
|
103
|
-
errorCode,
|
|
104
|
-
details: err.params || {},
|
|
105
|
-
};
|
|
106
|
-
});
|
|
95
|
+
const missingProp = err.keyword === 'required' ? `.${err.params?.missingProperty}` : '';
|
|
96
|
+
const key = (basePath + missingProp).replace(/^\./, '') || 'root';
|
|
97
|
+
|
|
98
|
+
const message = err.message || 'Invalid value';
|
|
99
|
+
acc[key] = message;
|
|
100
|
+
|
|
101
|
+
return acc;
|
|
102
|
+
}, {} as Record<string, string>);
|
|
107
103
|
|
|
108
104
|
/**
|
|
109
105
|
* Validates the model using custom validators
|
|
@@ -112,6 +108,7 @@ const validateModel = async (
|
|
|
112
108
|
instance,
|
|
113
109
|
options,
|
|
114
110
|
scopeAttributes: string[],
|
|
111
|
+
modelOptions: ModelOptions = {},
|
|
115
112
|
isCreate = false,
|
|
116
113
|
): Promise<void> => {
|
|
117
114
|
const modelType = instance.constructor.name;
|
|
@@ -153,6 +150,9 @@ const validateModel = async (
|
|
|
153
150
|
{
|
|
154
151
|
transaction: options.transaction,
|
|
155
152
|
attributes: CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL,
|
|
153
|
+
...(modelOptions.include && {
|
|
154
|
+
include: modelOptions.include?.(entityId),
|
|
155
|
+
}),
|
|
156
156
|
raw: true,
|
|
157
157
|
},
|
|
158
158
|
);
|
|
@@ -215,14 +215,15 @@ const validateModel = async (
|
|
|
215
215
|
})));
|
|
216
216
|
|
|
217
217
|
if (!isValid) {
|
|
218
|
-
const formattedErrors = formatAjvErrors(validateSchema.errors);
|
|
219
218
|
const errorDetails = validateSchema.errors?.map((err) =>
|
|
220
219
|
`${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');
|
|
221
220
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
221
|
+
const formattedErrors = formatAjvErrors(validateSchema.errors);
|
|
222
|
+
throw new BadRequest(
|
|
223
|
+
[new Error(`Validation failed for ${modelType}: ${errorDetails}`)],
|
|
224
|
+
undefined,
|
|
225
|
+
formattedErrors,
|
|
226
|
+
);
|
|
226
227
|
}
|
|
227
228
|
}
|
|
228
229
|
} else {
|
|
@@ -257,7 +258,12 @@ const validateModel = async (
|
|
|
257
258
|
.errors
|
|
258
259
|
?.map((err) => `${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');
|
|
259
260
|
|
|
260
|
-
|
|
261
|
+
const formattedErrors = formatAjvErrors(validateSchema.errors);
|
|
262
|
+
throw new BadRequest(
|
|
263
|
+
[new Error(`Validation failed for ${modelType}: ${errorDetails}`)],
|
|
264
|
+
undefined,
|
|
265
|
+
formattedErrors,
|
|
266
|
+
);
|
|
261
267
|
}
|
|
262
268
|
}
|
|
263
269
|
}
|
|
@@ -354,7 +360,7 @@ export const beforeCreate = (
|
|
|
354
360
|
}
|
|
355
361
|
|
|
356
362
|
// Step 2: Validate the model data (including custom fields)
|
|
357
|
-
await validateModel(instance, options, scopeAttributes, true);
|
|
363
|
+
await validateModel(instance, options, scopeAttributes, modelOptions, true);
|
|
358
364
|
|
|
359
365
|
// format date and datetime fields
|
|
360
366
|
formatDates(fieldDefinitions, instance);
|
|
@@ -405,7 +411,7 @@ export const beforeUpdate = (
|
|
|
405
411
|
});
|
|
406
412
|
|
|
407
413
|
// Step 1: Validate the model data (including custom fields)
|
|
408
|
-
await validateModel(instance, options, scopeAttributes, false);
|
|
414
|
+
await validateModel(instance, options, scopeAttributes, modelOptions, false);
|
|
409
415
|
|
|
410
416
|
// format date and datetime fields
|
|
411
417
|
formatDates(fieldDefinitions, instance);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Transactionable } from 'sequelize';
|
|
1
|
+
import type { IncludeOptions, Transactionable } from 'sequelize';
|
|
2
2
|
import logger from '../utils/logger';
|
|
3
3
|
import { CustomValidator } from '../models';
|
|
4
4
|
|
|
@@ -6,6 +6,7 @@ export interface FindValidatorOptions extends Transactionable {
|
|
|
6
6
|
withDisabled?: boolean;
|
|
7
7
|
attributes?: string[];
|
|
8
8
|
raw?: boolean;
|
|
9
|
+
include?: IncludeOptions[];
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
// Make sure this interface is compatible with the Sequelize model
|
|
@@ -68,7 +69,9 @@ export const findAllByModelType = async (
|
|
|
68
69
|
return findAll(
|
|
69
70
|
{
|
|
70
71
|
modelType,
|
|
71
|
-
|
|
72
|
+
...(!options.include && {
|
|
73
|
+
entityId,
|
|
74
|
+
}),
|
|
72
75
|
},
|
|
73
76
|
options,
|
|
74
77
|
);
|