@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.
@@ -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 {};
@@ -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 = exports.formatAjvErrors = void 0;
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 = []) => errors.map((err) => {
94
- const path = err.instancePath || '/';
95
- const { keyword } = err;
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
- const normalizedPath = path.replace(/\//g, '_').replace(/^_/, '');
98
- const errorCode = `${keyword}_${normalizedPath}`;
99
- return {
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
- throw new errors_1.BadRequest([
196
- new Error(`Validation failed for ${modelType}: ${errorDetails}`),
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
- throw new errors_1.BadRequest([new Error(`Validation failed for ${modelType}: ${errorDetails}`)]);
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
@@ -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
- entityId,
43
+ ...(!options.include && {
44
+ entityId,
45
+ }),
44
46
  }, options);
45
47
  };
46
48
  exports.findAllByModelType = findAllByModelType;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/sadot",
3
- "version": "0.13.5-beta",
3
+ "version": "0.13.5-beta-2",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -78,32 +78,28 @@ const getCompleteCustomFields = async (instance, options): Promise<Record<string
78
78
  return instance.customFields || {};
79
79
  };
80
80
 
81
- type AjvError = {
81
+ const formatAjvErrors = (
82
+ errors: {
82
83
  instancePath?: string;
83
84
  keyword: string;
84
85
  message?: string;
85
86
  params?: Record<string, any>;
86
- schemaPath?: string;
87
- [key: string]: any;
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
- export const formatAjvErrors = (errors: AjvError[] = []) =>
91
- errors.map((err) => {
92
- const path = err.instancePath || '/';
93
- const { keyword } = err;
94
- const message = err.message || 'Invalid value';
95
-
96
- const normalizedPath = path.replace(/\//g, '_').replace(/^_/, '');
97
- const errorCode = `${keyword}_${normalizedPath}`;
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
- throw new BadRequest([
223
- new Error(`Validation failed for ${modelType}: ${errorDetails}`),
224
- ...formattedErrors.map((err) => new Error(err.message)),
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
- throw new BadRequest([new Error(`Validation failed for ${modelType}: ${errorDetails}`)]);
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
- entityId,
72
+ ...(!options.include && {
73
+ entityId,
74
+ }),
72
75
  },
73
76
  options,
74
77
  );