@autofleet/sadot 0.13.0-beta.12 → 0.13.0-beta.4

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.
@@ -80,9 +80,8 @@ router.get('/', async (req, res) => {
80
80
  */
81
81
  router.get('/:validatorId', async (req, res) => {
82
82
  try {
83
- const { validatorId, modelName } = req.params;
84
- // Include disabled validators when fetching by ID
85
- const validators = await ValidatorRepo.findAll({ id: validatorId, modelType: modelName }, { withDisabled: true });
83
+ const { validatorId } = req.params;
84
+ const validators = await ValidatorRepo.findAll({ id: validatorId });
86
85
  if (!validators.length) {
87
86
  throw new errors_1.ResourceNotFoundError('Validator not found');
88
87
  }
@@ -104,11 +103,6 @@ router.patch('/:validatorId', async (req, res) => {
104
103
  if (validatedPayload.schema) {
105
104
  (0, validator_schema_1.validateValidatorSchema)(validatedPayload.schema);
106
105
  }
107
- // First verify the validator exists, including disabled ones
108
- const existingValidators = await ValidatorRepo.findAll({ id: validatorId }, { withDisabled: true });
109
- if (!existingValidators.length) {
110
- throw new errors_1.ResourceNotFoundError('Validator not found');
111
- }
112
106
  const [count, validators] = await ValidatorRepo.update(validatorId, validatedPayload);
113
107
  if (!count) {
114
108
  throw new errors_1.ResourceNotFoundError('Validator not found');
@@ -125,14 +119,9 @@ router.patch('/:validatorId', async (req, res) => {
125
119
  router.delete('/:validatorId', async (req, res) => {
126
120
  try {
127
121
  const { validatorId } = req.params;
128
- // First verify the validator exists, including disabled ones
129
- const existingValidators = await ValidatorRepo.findAll({ id: validatorId }, { withDisabled: true });
130
- if (!existingValidators.length) {
131
- throw new errors_1.ResourceNotFoundError('Validator not found');
132
- }
133
122
  const [count] = await ValidatorRepo.disable(validatorId);
134
123
  if (!count) {
135
- throw new errors_1.ResourceNotFoundError('Validator failed to be disabled');
124
+ throw new errors_1.ResourceNotFoundError('Validator not found');
136
125
  }
137
126
  return res.status(http_status_codes_1.StatusCodes.NO_CONTENT).send();
138
127
  }
@@ -6,10 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const joi_1 = __importDefault(require("joi"));
7
7
  // Schema for validating JSON Schema objects
8
8
  const jsonSchemaValidation = joi_1.default.object().unknown(true);
9
+ const entityType = joi_1.default.string().regex(/^[A-Z][a-z]+(?:[A-Z][a-z]+)*$/).required();
9
10
  const validationSchemas = {
10
11
  create: joi_1.default.object({
11
12
  entityId: joi_1.default.string().uuid().required(),
12
- entityType: joi_1.default.string().required(),
13
+ entityType,
13
14
  schema: joi_1.default.object({
14
15
  type: joi_1.default.string().valid('object').required(),
15
16
  properties: joi_1.default.object({
@@ -23,7 +24,6 @@ const validationSchemas = {
23
24
  }),
24
25
  update: joi_1.default.object({
25
26
  entityId: joi_1.default.string().uuid(),
26
- entityType: joi_1.default.string(),
27
27
  schema: joi_1.default.object({
28
28
  type: joi_1.default.string().valid('object'),
29
29
  properties: joi_1.default.object({
@@ -41,63 +41,8 @@ const ajv = new ajv_1.default({
41
41
  allErrors: true,
42
42
  strict: false, // Disable strict mode to avoid warnings
43
43
  strictTypes: false, // Disable strict type checking
44
- $data: true, // Enable $data references
45
44
  });
46
45
  (0, ajv_formats_1.default)(ajv);
47
- /**
48
- * Helper function to manually copy object properties
49
- * This is more efficient for large objects and avoids excessive object creation
50
- */
51
- const manualObjectCopy = (sourceObj, additionalProps) => {
52
- const resultObj = Object.create(null);
53
- // Copy properties from source object
54
- if (sourceObj) {
55
- Object.keys(sourceObj).forEach((key) => {
56
- resultObj[key] = sourceObj[key];
57
- });
58
- }
59
- // Add additional properties if provided
60
- if (additionalProps) {
61
- Object.keys(additionalProps).forEach((key) => {
62
- resultObj[key] = additionalProps[key];
63
- });
64
- }
65
- return resultObj;
66
- };
67
- /**
68
- * Fetches complete custom fields for an instance by merging DB values with update values
69
- * This is needed for partial updates to ensure all related fields are available for validation
70
- */
71
- const getCompleteCustomFields = async (instance, options) => {
72
- // If we don't have an instance id or no custom fields being updated, return original fields
73
- if (!instance.id || !instance.customFields || Object.keys(instance.customFields).length === 0) {
74
- return instance.customFields || {};
75
- }
76
- try {
77
- const ModelClass = instance.constructor;
78
- // Only select the customFields column to minimize data transfer
79
- const currentCustomFields = await ModelClass.findOne({
80
- where: { id: instance.id },
81
- attributes: ['customFields'],
82
- transaction: options.transaction,
83
- raw: true, // Get plain object instead of model instance for better performance
84
- });
85
- if (currentCustomFields?.customFields) {
86
- // Merge existing fields with update fields using our helper function
87
- const completeFields = manualObjectCopy(currentCustomFields.customFields, instance.customFields);
88
- logger_1.default.debug('sadot - fetched complete custom fields for validation', {
89
- fieldsCount: Object.keys(completeFields).length,
90
- updateFieldsCount: Object.keys(instance.customFields).length,
91
- });
92
- return completeFields;
93
- }
94
- }
95
- catch (error) {
96
- logger_1.default.error('sadot - error fetching complete model for validation', { error });
97
- // Continue with partial data if we can't fetch the complete model
98
- }
99
- return instance.customFields || {};
100
- };
101
46
  /**
102
47
  * Validates the model using custom validators
103
48
  */
@@ -125,26 +70,21 @@ const validateModel = async (instance, options, scopeAttributes, isCreate = fals
125
70
  return;
126
71
  }
127
72
  // For updates, get the previous values
128
- let originalValues = null;
129
- if (!isCreate) {
130
- // Create originalValues with our helper function
131
- originalValues = manualObjectCopy(instance.previous());
132
- // Add customFields separately
133
- originalValues.customFields = instance.previous('customFields') || {};
134
- }
135
- // Get complete custom fields by merging DB values with update values
136
- // This is especially important for partial updates to ensure all related fields are available
137
- const completeCustomFields = !isCreate
138
- ? await getCompleteCustomFields(instance, options)
139
- : instance.customFields || {};
73
+ const originalValues = isCreate
74
+ ? null
75
+ : {
76
+ ...instance.previous(),
77
+ customFields: instance.previous('customFields') || {},
78
+ };
140
79
  // For debugging in case of update
141
80
  if (!isCreate) {
142
- // Create after object for logging
143
- const logAfterObj = manualObjectCopy(instance.dataValues, { customFields: completeCustomFields });
144
81
  logger_1.default.debug('sadot - validate with values', {
145
82
  before: originalValues,
146
- after: logAfterObj,
147
- schema: validators[0].schema,
83
+ after: {
84
+ ...instance.dataValues,
85
+ ...instance.customFields,
86
+ },
87
+ schema: JSON.stringify(validators[0].schema),
148
88
  });
149
89
  }
150
90
  // eslint-disable-next-line no-restricted-syntax
@@ -152,7 +92,7 @@ const validateModel = async (instance, options, scopeAttributes, isCreate = fals
152
92
  const { schema } = validator;
153
93
  const typedSchema = schema;
154
94
  logger_1.default.debug('sadot - validating with schema', {
155
- schema,
95
+ schema: JSON.stringify(schema),
156
96
  hasAfterProps: !!typedSchema.properties?.after,
157
97
  hasBeforeProps: !!typedSchema.properties?.before,
158
98
  });
@@ -166,12 +106,12 @@ const validateModel = async (instance, options, scopeAttributes, isCreate = fals
166
106
  after: typedSchema.properties.after,
167
107
  },
168
108
  });
169
- const isValid = validateSchema(JSON.parse(JSON.stringify({
109
+ const isValid = validateSchema({
170
110
  after: {
171
111
  ...instance.dataValues,
172
- customFields: completeCustomFields,
112
+ ...instance.customFields,
173
113
  },
174
- })));
114
+ });
175
115
  if (!isValid) {
176
116
  const errorDetails = validateSchema.errors?.map((err) => `${err.instancePath || ''} ${err.message || 'Invalid value'}`).join(', ');
177
117
  throw new errors_1.BadRequest([new Error(`Validation failed for ${modelType}: ${errorDetails}`)]);
@@ -181,22 +121,11 @@ const validateModel = async (instance, options, scopeAttributes, isCreate = fals
181
121
  else {
182
122
  // For update operations, we need both before and after
183
123
  const validateSchema = ajv.compile(typedSchema);
184
- // Create after object with our helper function
185
- const afterObj = manualObjectCopy(instance.dataValues);
186
- // Add complete custom fields
187
- afterObj.customFields = completeCustomFields;
188
- // Create validation payload
189
- const payload = {
124
+ const isValid = validateSchema({
190
125
  before: originalValues,
191
- after: afterObj,
192
- };
193
- // Validate
194
- const isValid = validateSchema(JSON.parse(JSON.stringify(payload)));
195
- logger_1.default.info('sadot - validation result', {
196
- isValid,
197
- test: {
198
- before: originalValues,
199
- after: afterObj,
126
+ after: {
127
+ ...instance.dataValues,
128
+ ...instance.customFields,
200
129
  },
201
130
  });
202
131
  if (!isValid) {
package/dist/index.d.ts CHANGED
@@ -4,6 +4,9 @@ import type { CustomFieldOptions, ModelFetcher, Models } from './types';
4
4
  export * from './utils/validations/schema/custom-fields';
5
5
  export * from './utils/constants';
6
6
  export * from './utils/helpers';
7
+ export * as DefinitionRepo from './repository/definition';
8
+ export * as ValueRepo from './repository/value';
9
+ export * as ValidatorRepo from './repository/validator';
7
10
  /**
8
11
  * Adding custom fields enrichment to the models inside the MODELS_FILE_NAME json file
9
12
  * @see {@link 'custom-fields/config'} for configurations
package/dist/index.js CHANGED
@@ -29,7 +29,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
29
29
  return (mod && mod.__esModule) ? mod : { "default": mod };
30
30
  };
31
31
  Object.defineProperty(exports, "__esModule", { value: true });
32
- exports.disableCustomFields = void 0;
32
+ exports.disableCustomFields = exports.ValidatorRepo = exports.ValueRepo = exports.DefinitionRepo = void 0;
33
33
  const models_1 = require("./models");
34
34
  const api_1 = __importDefault(require("./api"));
35
35
  const db_1 = __importDefault(require("./utils/db"));
@@ -38,6 +38,10 @@ const init_1 = require("./utils/init");
38
38
  __exportStar(require("./utils/validations/schema/custom-fields"), exports);
39
39
  __exportStar(require("./utils/constants"), exports);
40
40
  __exportStar(require("./utils/helpers"), exports);
41
+ // Export repositories
42
+ exports.DefinitionRepo = __importStar(require("./repository/definition"));
43
+ exports.ValueRepo = __importStar(require("./repository/value"));
44
+ exports.ValidatorRepo = __importStar(require("./repository/validator"));
41
45
  /**
42
46
  * Adding custom fields enrichment to the models inside the MODELS_FILE_NAME json file
43
47
  * @see {@link 'custom-fields/config'} for configurations
@@ -90,7 +90,6 @@ __decorate([
90
90
  __metadata("design:returntype", void 0)
91
91
  ], CustomValidator, "afterSaveHandler", null);
92
92
  CustomValidator = __decorate([
93
- (0, sequelize_typescript_1.DefaultScope)(() => ({ where: { disabled: false } })),
94
93
  (0, sequelize_typescript_1.Table)({
95
94
  timestamps: true,
96
95
  })
@@ -58,21 +58,6 @@ const initTables = async (sequelize, getUser, { schemaPrefix, schemaVersion, use
58
58
  },
59
59
  };
60
60
  });
61
- CustomValidator_1.default.addScope('userScope', () => {
62
- const user = getUser();
63
- if (!user?.permissions) {
64
- return {};
65
- }
66
- return {
67
- where: {
68
- entityId: [
69
- ...Object.keys(user.permissions.fleets),
70
- ...Object.keys(user.permissions.businessModels),
71
- ...Object.keys(user.permissions.demandSources),
72
- ],
73
- },
74
- };
75
- });
76
61
  logger_1.default.info('custom-fields: models added');
77
62
  const SequelizeMeta = sequelize.define('SequelizeMeta', {
78
63
  name: {
@@ -7,7 +7,7 @@ export interface ValidatorAttributes {
7
7
  entityId: string;
8
8
  entityType: string;
9
9
  modelType: string;
10
- schema: CustomValidator['schema'];
10
+ schema: Record<string, unknown>;
11
11
  disabled?: boolean;
12
12
  [key: string]: unknown;
13
13
  }
@@ -16,23 +16,13 @@ exports.create = create;
16
16
  const findAll = async (where = {}, options = { withDisabled: false }) => {
17
17
  logger_1.default.debug('custom-validator - find all validators');
18
18
  const { transaction, withDisabled } = options;
19
- let validators;
20
- if (withDisabled) {
21
- // If withDisabled is true, use unscoped to ignore the default scope that filters disabled items
22
- // Apply the userScope separately to maintain permission filtering
23
- validators = await models_1.CustomValidator.unscoped().scope('userScope').findAll({
24
- where,
25
- transaction,
26
- });
27
- }
28
- else {
29
- // Use defaultScope and userScope to filter both disabled and by permissions
30
- // The defaultScope keeps only non-disabled validators
31
- validators = await models_1.CustomValidator.scope(['defaultScope', 'userScope']).findAll({
32
- where,
33
- transaction,
34
- });
35
- }
19
+ const fullWhere = withDisabled
20
+ ? where
21
+ : { ...where, disabled: false };
22
+ const validators = await models_1.CustomValidator.findAll({
23
+ where: fullWhere,
24
+ transaction,
25
+ });
36
26
  return validators;
37
27
  };
38
28
  exports.findAll = findAll;
@@ -4,7 +4,7 @@ exports.default = {
4
4
  test: {
5
5
  username: process.env.DB_USERNAME || '',
6
6
  password: process.env.DB_PASSWORD || null,
7
- database: process.env.DB_NAME || 'postgres',
7
+ database: process.env.DB_NAME || 'sadot_package_test',
8
8
  host: process.env.DB_HOST || '127.0.0.1',
9
9
  port: process.env.DB_PORT || 5432,
10
10
  dialect: process.env.DB_TYPE || 'postgres',
@@ -13,7 +13,6 @@ const metaValidator = new ajv_1.default({
13
13
  allErrors: true,
14
14
  strict: false,
15
15
  strictTypes: false,
16
- $data: true, // Enable $data references
17
16
  });
18
17
  (0, ajv_formats_1.default)(metaValidator);
19
18
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/sadot",
3
- "version": "0.13.0-beta.12",
3
+ "version": "0.13.0-beta.4",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -66,9 +66,8 @@ router.get<
66
66
  */
67
67
  router.get<{ modelName: string; validatorId: string }, CustomValidator>('/:validatorId', async (req, res) => {
68
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 });
69
+ const { validatorId } = req.params;
70
+ const validators = await ValidatorRepo.findAll({ id: validatorId });
72
71
 
73
72
  if (!validators.length) {
74
73
  throw new ResourceNotFoundError('Validator not found');
@@ -95,12 +94,6 @@ router.patch<{ modelName: string; validatorId: string }, CustomValidator>('/:val
95
94
  validateValidatorSchema(validatedPayload.schema);
96
95
  }
97
96
 
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
97
  const [count, validators] = await ValidatorRepo.update(validatorId, validatedPayload);
105
98
 
106
99
  if (!count) {
@@ -119,17 +112,10 @@ router.patch<{ modelName: string; validatorId: string }, CustomValidator>('/:val
119
112
  router.delete<{ modelName: string; validatorId: string }>('/:validatorId', async (req, res) => {
120
113
  try {
121
114
  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
115
  const [count] = await ValidatorRepo.disable(validatorId);
130
116
 
131
117
  if (!count) {
132
- throw new ResourceNotFoundError('Validator failed to be disabled');
118
+ throw new ResourceNotFoundError('Validator not found');
133
119
  }
134
120
 
135
121
  return res.status(StatusCodes.NO_CONTENT).send();
@@ -2,11 +2,12 @@ import Joi from 'joi';
2
2
 
3
3
  // Schema for validating JSON Schema objects
4
4
  const jsonSchemaValidation = Joi.object().unknown(true);
5
+ const entityType = Joi.string().regex(/^[A-Z][a-z]+(?:[A-Z][a-z]+)*$/).required();
5
6
 
6
7
  const validationSchemas = {
7
8
  create: Joi.object({
8
9
  entityId: Joi.string().uuid().required(),
9
- entityType: Joi.string().required(),
10
+ entityType,
10
11
  schema: Joi.object({
11
12
  type: Joi.string().valid('object').required(),
12
13
  properties: Joi.object({
@@ -21,7 +22,6 @@ const validationSchemas = {
21
22
 
22
23
  update: Joi.object({
23
24
  entityId: Joi.string().uuid(),
24
- entityType: Joi.string(),
25
25
  schema: Joi.object({
26
26
  type: Joi.string().valid('object'),
27
27
  properties: Joi.object({
@@ -1,6 +1,6 @@
1
1
  import type { WhereOptions } from 'sequelize';
2
2
  import Ajv from 'ajv';
3
- import addFormats from 'ajv-formats';
3
+ import addFormats from "ajv-formats";
4
4
  import { BadRequest } from '@autofleet/errors';
5
5
  import logger from '../utils/logger';
6
6
  import * as ValidatorRepo from '../repository/validator';
@@ -15,77 +15,10 @@ const ajv = new Ajv({
15
15
  allErrors: true,
16
16
  strict: false, // Disable strict mode to avoid warnings
17
17
  strictTypes: false, // Disable strict type checking
18
- $data: true, // Enable $data references
19
18
  });
20
19
 
21
20
  addFormats(ajv);
22
21
 
23
- /**
24
- * Helper function to manually copy object properties
25
- * This is more efficient for large objects and avoids excessive object creation
26
- */
27
- const manualObjectCopy = (sourceObj: Record<string, any>, additionalProps?: Record<string, any>): Record<string, any> => {
28
- const resultObj = Object.create(null);
29
-
30
- // Copy properties from source object
31
- if (sourceObj) {
32
- Object.keys(sourceObj).forEach((key) => {
33
- resultObj[key] = sourceObj[key];
34
- });
35
- }
36
-
37
- // Add additional properties if provided
38
- if (additionalProps) {
39
- Object.keys(additionalProps).forEach((key) => {
40
- resultObj[key] = additionalProps[key];
41
- });
42
- }
43
-
44
- return resultObj;
45
- };
46
-
47
- /**
48
- * Fetches complete custom fields for an instance by merging DB values with update values
49
- * This is needed for partial updates to ensure all related fields are available for validation
50
- */
51
- const getCompleteCustomFields = async (instance, options): Promise<Record<string, any>> => {
52
- // If we don't have an instance id or no custom fields being updated, return original fields
53
- if (!instance.id || !instance.customFields || Object.keys(instance.customFields).length === 0) {
54
- return instance.customFields || {};
55
- }
56
-
57
- try {
58
- const ModelClass = instance.constructor;
59
- // Only select the customFields column to minimize data transfer
60
- const currentCustomFields = await ModelClass.findOne({
61
- where: { id: instance.id },
62
- attributes: ['customFields'],
63
- transaction: options.transaction,
64
- raw: true, // Get plain object instead of model instance for better performance
65
- });
66
-
67
- if (currentCustomFields?.customFields) {
68
- // Merge existing fields with update fields using our helper function
69
- const completeFields = manualObjectCopy(
70
- currentCustomFields.customFields,
71
- instance.customFields,
72
- );
73
-
74
- logger.debug('sadot - fetched complete custom fields for validation', {
75
- fieldsCount: Object.keys(completeFields).length,
76
- updateFieldsCount: Object.keys(instance.customFields).length,
77
- });
78
-
79
- return completeFields;
80
- }
81
- } catch (error) {
82
- logger.error('sadot - error fetching complete model for validation', { error });
83
- // Continue with partial data if we can't fetch the complete model
84
- }
85
-
86
- return instance.customFields || {};
87
- };
88
-
89
22
  /**
90
23
  * Validates the model using custom validators
91
24
  */
@@ -132,30 +65,22 @@ const validateModel = async (
132
65
  }
133
66
 
134
67
  // For updates, get the previous values
135
- let originalValues = null;
136
- if (!isCreate) {
137
- // Create originalValues with our helper function
138
- originalValues = manualObjectCopy(instance.previous());
139
-
140
- // Add customFields separately
141
- originalValues.customFields = instance.previous('customFields') || {};
142
- }
143
-
144
- // Get complete custom fields by merging DB values with update values
145
- // This is especially important for partial updates to ensure all related fields are available
146
- const completeCustomFields = !isCreate
147
- ? await getCompleteCustomFields(instance, options)
148
- : instance.customFields || {};
68
+ const originalValues = isCreate
69
+ ? null
70
+ : {
71
+ ...instance.previous(),
72
+ customFields: instance.previous('customFields') || {},
73
+ };
149
74
 
150
75
  // For debugging in case of update
151
76
  if (!isCreate) {
152
- // Create after object for logging
153
- const logAfterObj = manualObjectCopy(instance.dataValues, { customFields: completeCustomFields });
154
-
155
77
  logger.debug('sadot - validate with values', {
156
78
  before: originalValues,
157
- after: logAfterObj,
158
- schema: validators[0].schema,
79
+ after: {
80
+ ...instance.dataValues,
81
+ ...instance.customFields,
82
+ },
83
+ schema: JSON.stringify(validators[0].schema),
159
84
  });
160
85
  }
161
86
 
@@ -165,7 +90,7 @@ const validateModel = async (
165
90
  const typedSchema = schema as Record<string, any>;
166
91
 
167
92
  logger.debug('sadot - validating with schema', {
168
- schema,
93
+ schema: JSON.stringify(schema),
169
94
  hasAfterProps: !!typedSchema.properties?.after,
170
95
  hasBeforeProps: !!typedSchema.properties?.before,
171
96
  });
@@ -181,12 +106,12 @@ const validateModel = async (
181
106
  },
182
107
  });
183
108
 
184
- const isValid = validateSchema(JSON.parse(JSON.stringify({
109
+ const isValid = validateSchema({
185
110
  after: {
186
111
  ...instance.dataValues,
187
- customFields: completeCustomFields,
112
+ ...instance.customFields,
188
113
  },
189
- })));
114
+ });
190
115
 
191
116
  if (!isValid) {
192
117
  const errorDetails = validateSchema.errors?.map((err) =>
@@ -199,26 +124,11 @@ const validateModel = async (
199
124
  // For update operations, we need both before and after
200
125
  const validateSchema = ajv.compile(typedSchema);
201
126
 
202
- // Create after object with our helper function
203
- const afterObj = manualObjectCopy(instance.dataValues);
204
-
205
- // Add complete custom fields
206
- afterObj.customFields = completeCustomFields;
207
-
208
- // Create validation payload
209
- const payload = {
127
+ const isValid = validateSchema({
210
128
  before: originalValues,
211
- after: afterObj,
212
- };
213
-
214
- // Validate
215
- const isValid = validateSchema(JSON.parse(JSON.stringify(payload)));
216
-
217
- logger.info('sadot - validation result', {
218
- isValid,
219
- test: {
220
- before: originalValues,
221
- after: afterObj,
129
+ after: {
130
+ ...instance.dataValues,
131
+ ...instance.customFields,
222
132
  },
223
133
  });
224
134
 
package/src/index.ts CHANGED
@@ -17,6 +17,11 @@ export * from './utils/constants';
17
17
 
18
18
  export * from './utils/helpers';
19
19
 
20
+ // Export repositories
21
+ export * as DefinitionRepo from './repository/definition';
22
+ export * as ValueRepo from './repository/value';
23
+ export * as ValidatorRepo from './repository/validator';
24
+
20
25
  /**
21
26
  * Adding custom fields enrichment to the models inside the MODELS_FILE_NAME json file
22
27
  * @see {@link 'custom-fields/config'} for configurations
@@ -6,12 +6,10 @@ import {
6
6
  DataType,
7
7
  Default,
8
8
  AfterUpsert,
9
- DefaultScope,
10
9
  } from 'sequelize-typescript';
11
10
  import { randomUUID } from 'node:crypto';
12
11
  import { sendDimEvent } from '../events';
13
12
 
14
- @DefaultScope(() => ({ where: { disabled: false } }))
15
13
  @Table({
16
14
  timestamps: true,
17
15
  })
@@ -68,22 +68,6 @@ const initTables = async (
68
68
  };
69
69
  });
70
70
 
71
- CustomValidator.addScope('userScope', () => {
72
- const user = getUser();
73
- if (!user?.permissions) {
74
- return {};
75
- }
76
- return {
77
- where: {
78
- entityId: [
79
- ...Object.keys(user.permissions.fleets),
80
- ...Object.keys(user.permissions.businessModels),
81
- ...Object.keys(user.permissions.demandSources),
82
- ],
83
- },
84
- };
85
- });
86
-
87
71
  logger.info('custom-fields: models added');
88
72
 
89
73
  const SequelizeMeta = sequelize.define(
@@ -11,7 +11,7 @@ export interface ValidatorAttributes {
11
11
  entityId: string;
12
12
  entityType: string;
13
13
  modelType: string;
14
- schema: CustomValidator['schema'];
14
+ schema: Record<string, unknown>;
15
15
  disabled?: boolean;
16
16
  [key: string]: unknown; // Add index signature for Sequelize compatibility
17
17
  }
@@ -36,22 +36,14 @@ export const findAll = async (
36
36
 
37
37
  const { transaction, withDisabled } = options;
38
38
 
39
- let validators;
40
- if (withDisabled) {
41
- // If withDisabled is true, use unscoped to ignore the default scope that filters disabled items
42
- // Apply the userScope separately to maintain permission filtering
43
- validators = await CustomValidator.unscoped().scope('userScope').findAll({
44
- where,
45
- transaction,
46
- });
47
- } else {
48
- // Use defaultScope and userScope to filter both disabled and by permissions
49
- // The defaultScope keeps only non-disabled validators
50
- validators = await CustomValidator.scope(['defaultScope', 'userScope']).findAll({
51
- where,
52
- transaction,
53
- });
54
- }
39
+ const fullWhere = withDisabled
40
+ ? where
41
+ : { ...where, disabled: false };
42
+
43
+ const validators = await CustomValidator.findAll({
44
+ where: fullWhere,
45
+ transaction,
46
+ });
55
47
 
56
48
  return validators;
57
49
  };
@@ -2,7 +2,7 @@ export default {
2
2
  test: {
3
3
  username: process.env.DB_USERNAME || '',
4
4
  password: process.env.DB_PASSWORD || null,
5
- database: process.env.DB_NAME || 'postgres',
5
+ database: process.env.DB_NAME || 'sadot_package_test',
6
6
  host: process.env.DB_HOST || '127.0.0.1',
7
7
  port: process.env.DB_PORT || 5432,
8
8
  dialect: process.env.DB_TYPE || 'postgres',
@@ -8,7 +8,6 @@ const metaValidator = new Ajv({
8
8
  allErrors: true,
9
9
  strict: false,
10
10
  strictTypes: false,
11
- $data: true, // Enable $data references
12
11
  });
13
12
  addFormats(metaValidator);
14
13
 
package/validator-test.js DELETED
@@ -1,79 +0,0 @@
1
- const Ajv = require("ajv");
2
- const addFormats = require("ajv-formats");
3
- const ajv = new Ajv({
4
- allErrors: true,
5
- strict: false, // Disable strict mode to avoid warnings
6
- strictTypes: false, // Disable strict type checking
7
- $data: true, // Enable $data references
8
- }); // options can be passed, e.g. {allErrors: true}
9
- addFormats(ajv);
10
-
11
-
12
- const schema = {
13
- "type": "object",
14
- "properties": {
15
- "after": {
16
- "type": "object",
17
- "properties": {
18
- "customFields": {
19
- "type": "object",
20
- "properties": {
21
- "actualStartTime": {
22
- "type": "string",
23
- "format": "date-time"
24
- },
25
- "actualEndTime": {
26
- "type": "string",
27
- "format": "date-time",
28
- "formatMinimum": {
29
- "$data": "/after/customFields/actualStartTime"
30
- }
31
- }
32
- }
33
- }
34
- }
35
- }
36
- }
37
- };
38
-
39
- const validate = ajv.compile(schema);
40
-
41
- const data = {
42
- "id": "c9c87cec-28c7-4a1f-9376-4d8a4ba0f49c",
43
- "typeId": "4fcd7096-4c90-46a2-a20e-91bb5bff3ced",
44
- "priorityId": null,
45
- "statusId": "51d28a37-c042-429f-a9cd-fbc81bba2b39",
46
- "subjectId": null,
47
- "subjectType": null,
48
- "title": "ff",
49
- "description": null,
50
- "dueTime": null,
51
- "startTime": null,
52
- "endTime": null,
53
- "driverId": null,
54
- "vendorId": null,
55
- "userId": null,
56
- "businessModelId": "72ecf740-42a1-46f4-81ca-8132b08c4f04",
57
- "createdAt": "2025-03-12T12:58:05.529Z",
58
- "updatedAt": "2025-03-12T12:58:05.529Z",
59
- "deletedAt": null,
60
- "actions": [],
61
- "customFields": {
62
- "actualStartTime": "2025-03-14T12:48:01.373Z",
63
- "actualEndTime": "2025-03-01T12:51:46.685Z"
64
- },
65
- "isBlocker": false
66
- };
67
-
68
- const valid = validate({after: data});
69
-
70
- if (!valid) {
71
- console.log("invalid, the errors is: ");
72
- validate.errors.forEach((error) =>
73
- console.log(error.instancePath, error.message)
74
- );
75
- } else {
76
- console.log("valid");
77
- }
78
-
79
- console.log("--------------------");