@autofleet/sadot 1.2.15 → 1.2.16-beta-e2ec42dc.1
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.cjs +1 -1
- package/dist/hooks/hooks.cjs.map +1 -1
- package/dist/hooks/hooks.js +1 -1
- package/dist/hooks/hooks.js.map +1 -1
- package/dist/models/CustomFieldDefinition.cjs +1 -1
- package/dist/models/CustomFieldDefinition.cjs.map +1 -1
- package/dist/models/CustomFieldDefinition.d.cts +6 -0
- package/dist/models/CustomFieldDefinition.d.ts +6 -0
- package/dist/models/CustomFieldDefinition.js +1 -1
- package/dist/models/CustomFieldDefinition.js.map +1 -1
- package/dist/repository/definition.cjs +1 -1
- package/dist/repository/definition.cjs.map +1 -1
- package/dist/repository/definition.js +1 -1
- package/dist/repository/definition.js.map +1 -1
- package/package.json +2 -2
package/dist/hooks/hooks.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`../_virtual/rolldown_runtime.cjs`),t=require(`../utils/logger/index.cjs`),n=require(`../utils/constants/index.cjs`),r=require(`../errors/index.cjs`),i=require(`../repository/definition.cjs`),a=require(`../repository/validator.cjs`),o=require(`../utils/scopeAttributes.cjs`),s=require(`./utils/updateInstanceValues.cjs`);let c=require(`joi`);c=e.__toESM(c);let l=require(`@autofleet/errors`),u=require(`ajv`);u=e.__toESM(u);let d=require(`ajv-formats`);d=e.__toESM(d);let f=require(`ajv-errors`);f=e.__toESM(f);const p=[`id`,`schema`,`modelType`,`entityId`,`disabled`],m=new u.default({allErrors:!0,strict:!1,strictTypes:!1,$data:!0});(0,d.default)(m),(0,f.default)(m);const h=(e,t)=>({__proto__:null,...e,...t}),g=async(e,n)=>{if(!e.id||!e.customFields||Object.keys(e.customFields).length===0)return e.customFields||{};try{let r=await e.constructor.findOne({where:{id:e.id},attributes:[`customFields`],transaction:n.transaction,raw:!0});if(r?.customFields){let n=h(r.customFields,e.customFields);return t.default.debug(`sadot - fetched complete custom fields for validation`,{fieldsCount:Object.keys(n).length,updateFieldsCount:Object.keys(e.customFields).length}),n}}catch(e){t.default.error(`sadot - error fetching complete model for validation`,{error:e})}return e.customFields||{}},_=e=>{let t={...e.dataValues};(e.changed?.()||[]).forEach(n=>{let r=e.previous?.(n);r!==void 0&&(t[n]=r)});let n=e.previous?.(`customFields`);return n!==void 0&&(t.customFields=n),t},v=e=>e.reduce((e,t)=>{let n=((t.instancePath||``).split(`/`).filter(Boolean).join(`.`).replace(/^after\./,``)+(t.keyword===`required`?`.${t.params?.missingProperty}`:``)).replace(/^\./,``)||`root`;return e[n]=t.message||`Invalid value`,e},{}),y=async(e,n,r,i={},s=!1)=>{let c=e.constructor.name;t.default.debug(`sadot - validating model`,{isCreate:s,modelType:c});let u=o.default(e,r);if(t.default.debug(`sadot - identifiers`,{identifiers:u}),!u||Object.keys(u).length===0){t.default.debug(`sadot - skipping validation: no identifiers`);return}let d=Object.values(u)[0];if(t.default.debug(`sadot - entityId`,{entityId:d}),!d){t.default.debug(`sadot - skipping validation: no entityId`);return}let f,y;n.transaction&&(n.transaction.validationsCache??=new Map,y=`${c}-${d}`,f=n.transaction.validationsCache.get(y)),f||(f=a.findAllByModelType(c,d,{transaction:n.transaction,attributes:p,modelOptions:i}),n.transaction&&n?.transaction?.validationsCache.set(y,f));let b=await f;if(t.default.debug(`sadot - validators found`,{count:b.length}),!b.length){t.default.debug(`sadot - skipping validation: no validators found`);return}let x=null;s||(x=_(e));let S=s?e.customFields||{}:await g(e,n);for(let n of b){let{schema:r}=n,i=r;if(t.default.debug(`sadot - validating with schema`,{schema:r,hasAfterProps:!!i.properties?.after,hasBeforeProps:!!i.properties?.before}),s){if(i.properties?.after){let t=m.compile({...r,properties:{after:i.properties.after}});if(!t(JSON.parse(JSON.stringify({after:{...e.dataValues,customFields:S}})))){let e=t.errors?.map(e=>`${e.instancePath||``} ${e.message||`Invalid value`}`).join(`, `),n=v(t.errors);throw new l.BadRequest([Error(`Validation failed for ${c}: ${e}`)],void 0,{customError:n})}}}else{let n=m.compile(i),r=h(e.dataValues);r.customFields=S;let a={before:x,after:r},o=n(JSON.parse(JSON.stringify(a)));if(t.default.debug(`sadot - validation result`,{isValid:o,test:{before:x,after:r}}),!o){let e=n.errors?.map(e=>`${e.instancePath||``} ${e.message||`Invalid value`}`).join(`, `),t=v(n.errors);throw new l.BadRequest([Error(`Validation failed for ${c}: ${e}`)],void 0,{customError:t})}}}},b=async({modelType:e,modelOptions:t,identifiers:n,options:r})=>{let{include:
|
|
1
|
+
const e=require(`../_virtual/rolldown_runtime.cjs`),t=require(`../utils/logger/index.cjs`),n=require(`../utils/constants/index.cjs`),r=require(`../errors/index.cjs`),i=require(`../repository/definition.cjs`),a=require(`../repository/validator.cjs`),o=require(`../utils/scopeAttributes.cjs`),s=require(`./utils/updateInstanceValues.cjs`);let c=require(`joi`);c=e.__toESM(c);let l=require(`@autofleet/errors`),u=require(`ajv`);u=e.__toESM(u);let d=require(`ajv-formats`);d=e.__toESM(d);let f=require(`ajv-errors`);f=e.__toESM(f);const p=[`id`,`schema`,`modelType`,`entityId`,`disabled`],m=new u.default({allErrors:!0,strict:!1,strictTypes:!1,$data:!0});(0,d.default)(m),(0,f.default)(m);const h=(e,t)=>({__proto__:null,...e,...t}),g=async(e,n)=>{if(!e.id||!e.customFields||Object.keys(e.customFields).length===0)return e.customFields||{};try{let r=await e.constructor.findOne({where:{id:e.id},attributes:[`customFields`],transaction:n.transaction,raw:!0});if(r?.customFields){let n=h(r.customFields,e.customFields);return t.default.debug(`sadot - fetched complete custom fields for validation`,{fieldsCount:Object.keys(n).length,updateFieldsCount:Object.keys(e.customFields).length}),n}}catch(e){t.default.error(`sadot - error fetching complete model for validation`,{error:e})}return e.customFields||{}},_=e=>{let t={...e.dataValues};(e.changed?.()||[]).forEach(n=>{let r=e.previous?.(n);r!==void 0&&(t[n]=r)});let n=e.previous?.(`customFields`);return n!==void 0&&(t.customFields=n),t},v=e=>e.reduce((e,t)=>{let n=((t.instancePath||``).split(`/`).filter(Boolean).join(`.`).replace(/^after\./,``)+(t.keyword===`required`?`.${t.params?.missingProperty}`:``)).replace(/^\./,``)||`root`;return e[n]=t.message||`Invalid value`,e},{}),y=async(e,n,r,i={},s=!1)=>{let c=e.constructor.name;t.default.debug(`sadot - validating model`,{isCreate:s,modelType:c});let u=o.default(e,r);if(t.default.debug(`sadot - identifiers`,{identifiers:u}),!u||Object.keys(u).length===0){t.default.debug(`sadot - skipping validation: no identifiers`);return}let d=Object.values(u)[0];if(t.default.debug(`sadot - entityId`,{entityId:d}),!d){t.default.debug(`sadot - skipping validation: no entityId`);return}let f,y;n.transaction&&(n.transaction.validationsCache??=new Map,y=`${c}-${d}`,f=n.transaction.validationsCache.get(y)),f||(f=a.findAllByModelType(c,d,{transaction:n.transaction,attributes:p,modelOptions:i}),n.transaction&&n?.transaction?.validationsCache.set(y,f));let b=await f;if(t.default.debug(`sadot - validators found`,{count:b.length}),!b.length){t.default.debug(`sadot - skipping validation: no validators found`);return}let x=null;s||(x=_(e));let S=s?e.customFields||{}:await g(e,n);for(let n of b){let{schema:r}=n,i=r;if(t.default.debug(`sadot - validating with schema`,{schema:r,hasAfterProps:!!i.properties?.after,hasBeforeProps:!!i.properties?.before}),s){if(i.properties?.after){let t=m.compile({...r,properties:{after:i.properties.after}});if(!t(JSON.parse(JSON.stringify({after:{...e.dataValues,customFields:S}})))){let e=t.errors?.map(e=>`${e.instancePath||``} ${e.message||`Invalid value`}`).join(`, `),n=v(t.errors);throw new l.BadRequest([Error(`Validation failed for ${c}: ${e}`)],void 0,{customError:n})}}}else{let n=m.compile(i),r=h(e.dataValues);r.customFields=S;let a={before:x,after:r},o=n(JSON.parse(JSON.stringify(a)));if(t.default.debug(`sadot - validation result`,{isValid:o,test:{before:x,after:r}}),!o){let e=n.errors?.map(e=>`${e.instancePath||``} ${e.message||`Invalid value`}`).join(`, `),t=v(n.errors);throw new l.BadRequest([Error(`Validation failed for ${c}: ${e}`)],void 0,{customError:t})}}}},b=async({modelType:e,modelOptions:t,identifiers:n,options:r,instance:a,hasTypeId:o})=>{let{include:s,useEntityIdFromInclude:c}=t;if(o&&a?.typeId)return i.findByModelTypeId(a.typeId,{withDisabled:!1,transaction:r.transaction,entityIds:n,modelType:e,modelOptions:t});let l={modelType:e,disabled:!1,...!c&&{entityId:n}};return await i.findAll(l,{withDisabled:!1,transaction:r.transaction,include:s?.(n)})},x=(e,t)=>{(e||[]).forEach(e=>{let{fieldType:i,name:a}=e;if([n.CustomFieldDefinitionType.DATE,n.CustomFieldDefinitionType.DATETIME].includes(i)){let e=t.customFields?.[a];if(e){let{value:n,error:i}=c.default.date().validate(e);if(i)throw new r.InvalidValueError(e,a,i);t.customFields[a]=n.toISOString()}}})},S=(e,n={},i={useCustomFieldsEntries:!1})=>async(a,c)=>{t.default.debug(`sadot - before create hook`);let{fields:l}=c,u=a.constructor.name,d=o.default(a,e),f=await b({modelType:u,modelOptions:n,identifiers:d,options:c,instance:a,hasTypeId:i.hasTypeId}),p=f.filter(e=>![null,void 0].includes(e.defaultValue));p.length&&(a.customFields||={},p.filter(e=>a.customFields?.[e.name]===void 0).forEach(({name:e,defaultValue:t})=>{a.customFields[e]=t}));let m;m=i.getRequiredCustomFields?await Promise.resolve(i.getRequiredCustomFields(a,f,c)):Array.from(new Set(f.filter(({required:e})=>e).map(({name:e})=>e)));let{customFields:h}=a,g=Object.keys(h??{}),_=m.filter(e=>!g.includes(e));if(_?.length)throw new r.MissingRequiredCustomFieldError(_);await y(a,c,e,n,!0),x(f,a);let v=l.indexOf(`customFields`);v===-1||!h||!Object.keys(h).length||(await s.default({modelId:a.id,modelType:u,identifiers:d,customFields:h,options:{useCustomFieldsEntries:i.useCustomFieldsEntries,transaction:c.transaction,modelOptions:n}}),l.splice(v,1))},C=(e,n={},r={useCustomFieldsEntries:!1})=>async(i,a)=>{t.default.debug(`sadot - before update hook`);let{fields:c}=a,l=i.constructor.name,u=o.default(i,e),d=await b({modelType:l,modelOptions:n,identifiers:u,options:a,instance:i,hasTypeId:r.hasTypeId});await y(i,a,e,n,!1),x(d,i);let f=c.indexOf(`customFields`);if(f>-1){let{customFields:e}=i;if(!Object.keys(e).length)return;await s.default({modelId:i.id,modelType:l,identifiers:u,customFields:e,options:{useCustomFieldsEntries:r.useCustomFieldsEntries,transaction:a.transaction,modelOptions:n}}),c.splice(f,1)}},w=e=>{e.individualHooks=!0},T=e=>{e.individualHooks=!0};exports.beforeBulkCreate=w,exports.beforeBulkUpdate=T,exports.beforeCreate=S,exports.beforeUpdate=C;
|
|
2
2
|
//# sourceMappingURL=hooks.cjs.map
|
package/dist/hooks/hooks.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.cjs","names":["ajv","Ajv","beforeFull: any","applyScopeToInstance","cacheKey: string | undefined","BadRequest","where: WhereOptions","CustomFieldDefinitionType","Joi","InvalidValueError","requiredFieldsNames: string[]","MissingRequiredCustomFieldError","updateInstanceValues"],"sources":["../../src/hooks/hooks.ts"],"sourcesContent":["import type {\n BulkCreateOptions, CreateOptions, Transactionable, UpdateOptions, WhereOptions,\n} from 'sequelize';\nimport Ajv from 'ajv';\nimport Joi from 'joi';\nimport addFormats from 'ajv-formats';\nimport { BadRequest } from '@autofleet/errors';\nimport ajvErrors from 'ajv-errors';\nimport logger from '../utils/logger';\nimport * as ValidatorRepo from '../repository/validator';\nimport * as DefinitionRepo from '../repository/definition';\nimport { InvalidValueError, MissingRequiredCustomFieldError } from '../errors';\nimport type { CustomFieldOptions, ModelOptions, TransactionOptions } from '../types';\nimport applyScopeToInstance from '../utils/scopeAttributes';\nimport updateInstanceValues from './utils/updateInstanceValues';\nimport { CustomFieldDefinitionType } from '../utils/constants';\nimport type { CustomFieldDefinition } from '../models';\n\n// Include all required fields for proper validation\nconst CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL = ['id', 'schema', 'modelType', 'entityId', 'disabled'];\n\n// Initialize Ajv with relaxed settings to avoid warnings\nconst ajv = new Ajv({\n allErrors: true,\n strict: false, // Disable strict mode to avoid warnings\n strictTypes: false, // Disable strict type checking\n $data: true, // Enable $data references\n});\n\naddFormats(ajv);\najvErrors(ajv);\n\n/**\n * Helper function to manually copy object properties\n * This is more efficient for large objects and avoids excessive object creation\n */\nconst manualObjectCopy = (sourceObj: Record<string, any>, additionalProps?: Record<string, any>): Record<string, any> =>\n ({ __proto__: null, ...sourceObj, ...additionalProps });\n\n/**\n * Fetches complete custom fields for an instance by merging DB values with update values\n * This is needed for partial updates to ensure all related fields are available for validation\n */\nconst getCompleteCustomFields = async (instance: any, options: Transactionable): Promise<Record<string, any>> => {\n // If we don't have an instance id or no custom fields being updated, return original fields\n if (!instance.id || !instance.customFields || Object.keys(instance.customFields).length === 0) {\n return instance.customFields || {};\n }\n\n try {\n const ModelClass = instance.constructor;\n // Only select the customFields column to minimize data transfer\n const currentCustomFields = await ModelClass.findOne({\n where: { id: instance.id },\n attributes: ['customFields'],\n transaction: options.transaction,\n raw: true, // Get plain object instead of model instance for better performance\n });\n\n if (currentCustomFields?.customFields) {\n // Merge existing fields with update fields using our helper function\n const completeFields = manualObjectCopy(\n currentCustomFields.customFields,\n instance.customFields,\n );\n\n logger.debug('sadot - fetched complete custom fields for validation', {\n fieldsCount: Object.keys(completeFields).length,\n updateFieldsCount: Object.keys(instance.customFields).length,\n });\n\n return completeFields;\n }\n } catch (error) {\n logger.error('sadot - error fetching complete model for validation', { error });\n // Continue with partial data if we can't fetch the complete model\n }\n\n return instance.customFields || {};\n};\n\nconst buildPreChangeState = (instance: any) => {\n const beforeFull: any = { ...instance.dataValues };\n\n const changedKeys: string[] = instance.changed?.() || [];\n changedKeys.forEach((key) => {\n const prevVal = instance.previous?.(key);\n if (prevVal !== undefined) {\n beforeFull[key] = prevVal;\n }\n });\n\n const prevCF = instance.previous?.('customFields');\n if (prevCF !== undefined) {\n beforeFull.customFields = prevCF;\n }\n\n return beforeFull;\n};\n\nconst formatAjvErrors = (\n errors: {\n instancePath?: string;\n keyword: string;\n message?: string;\n params?: Record<string, any>;\n }[],\n): Record<string, string> => errors.reduce((acc, err) => {\n const basePath = (err.instancePath || '')\n .split('/')\n .filter(Boolean)\n .join('.')\n .replace(/^after\\./, '');\n\n const missingProp = err.keyword === 'required' ? `.${err.params?.missingProperty}` : '';\n const key = (basePath + missingProp).replace(/^\\./, '') || 'root';\n\n const message = err.message || 'Invalid value';\n acc[key] = message;\n\n return acc;\n}, {} as Record<string, string>);\n\n/**\n * Validates the model using custom validators\n */\nconst validateModel = async (\n instance: any,\n options: TransactionOptions,\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n isCreate = false,\n): Promise<void> => {\n const modelType = instance.constructor.name;\n\n logger.debug('sadot - validating model', { isCreate, modelType });\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n logger.debug('sadot - identifiers', { identifiers });\n\n // Skip if no identifiers\n if (!identifiers || Object.keys(identifiers).length === 0) {\n logger.debug('sadot - skipping validation: no identifiers');\n return;\n }\n\n // Find the entityId from identifiers (fleetId, businessModelId, etc.)\n const entityId = Object.values(identifiers)[0]; // Get the first value as entityId\n\n logger.debug('sadot - entityId', { entityId });\n\n if (!entityId) {\n logger.debug('sadot - skipping validation: no entityId');\n return;\n }\n\n let validatorsPromise;\n let cacheKey: string | undefined;\n if (options.transaction) {\n options.transaction.validationsCache ??= new Map();\n cacheKey = `${modelType}-${entityId}`;\n validatorsPromise = options.transaction.validationsCache.get(cacheKey);\n }\n\n if (!validatorsPromise) {\n validatorsPromise = ValidatorRepo.findAllByModelType(\n modelType,\n entityId,\n {\n transaction: options.transaction,\n attributes: CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL,\n modelOptions,\n },\n );\n if (options.transaction) {\n options?.transaction?.validationsCache!.set(cacheKey!, validatorsPromise);\n }\n }\n const validators = await validatorsPromise;\n\n logger.debug('sadot - validators found', { count: validators.length });\n\n if (!validators.length) {\n logger.debug('sadot - skipping validation: no validators found');\n return;\n }\n\n // For updates, get the previous values\n let originalValues = null;\n if (!isCreate) {\n originalValues = buildPreChangeState(instance);\n }\n\n // Get complete custom fields by merging DB values with update values\n // This is especially important for partial updates to ensure all related fields are available\n const completeCustomFields = !isCreate\n ? await getCompleteCustomFields(instance, options)\n : instance.customFields || {};\n\n for (const validator of validators) {\n const { schema } = validator;\n const typedSchema = schema as Record<string, any>;\n\n logger.debug('sadot - validating with schema', {\n schema,\n hasAfterProps: !!typedSchema.properties?.after,\n hasBeforeProps: !!typedSchema.properties?.before,\n });\n\n if (isCreate) {\n // For create operations, we only need the 'after' state\n if (typedSchema.properties?.after) {\n const validateSchema = ajv.compile({\n ...schema,\n // Focus only on the 'after' validation part for create\n properties: {\n after: typedSchema.properties.after,\n },\n });\n\n const isValid = validateSchema(JSON.parse(JSON.stringify({\n after: {\n ...instance.dataValues,\n customFields: completeCustomFields,\n },\n })));\n\n if (!isValid) {\n const errorDetails = validateSchema.errors?.map(err =>\n `${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');\n\n const formattedErrors = formatAjvErrors(validateSchema.errors!);\n throw new BadRequest(\n [new Error(`Validation failed for ${modelType}: ${errorDetails}`)],\n undefined,\n {\n customError: formattedErrors,\n },\n );\n }\n }\n } else {\n // For update operations, we need both before and after\n const validateSchema = ajv.compile(typedSchema);\n\n // Create after object with our helper function\n const afterObj = manualObjectCopy(instance.dataValues);\n\n // Add complete custom fields\n afterObj.customFields = completeCustomFields;\n\n // Create validation payload\n const payload = {\n before: originalValues,\n after: afterObj,\n };\n\n // Validate\n const isValid = validateSchema(JSON.parse(JSON.stringify(payload)));\n\n logger.debug('sadot - validation result', {\n isValid,\n test: {\n before: originalValues,\n after: afterObj,\n },\n });\n\n if (!isValid) {\n const errorDetails = validateSchema\n .errors\n ?.map(err => `${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');\n\n const formattedErrors = formatAjvErrors(validateSchema.errors!);\n throw new BadRequest(\n [new Error(`Validation failed for ${modelType}: ${errorDetails}`)],\n undefined,\n {\n customError: formattedErrors,\n },\n );\n }\n }\n }\n};\n\nconst getFieldDefinitions = async ({\n modelType,\n modelOptions,\n identifiers,\n options,\n}: {\n modelType: any;\n modelOptions: ModelOptions;\n identifiers: any[];\n options: any;\n}) => {\n const { include, useEntityIdFromInclude } = modelOptions;\n const where: WhereOptions = {\n modelType,\n disabled: false,\n ...(!useEntityIdFromInclude && { entityId: identifiers }),\n };\n\n const fieldDefinitions = await DefinitionRepo.findAll(where, {\n withDisabled: false,\n transaction: options.transaction,\n include: include?.(identifiers),\n });\n return fieldDefinitions;\n};\n\nconst formatDates = (fieldDefinitions: CustomFieldDefinition[], instance: any) => {\n (fieldDefinitions || []).forEach((fieldDefinition) => {\n const { fieldType, name } = fieldDefinition;\n if ([CustomFieldDefinitionType.DATE, CustomFieldDefinitionType.DATETIME].includes(fieldType)) {\n const value = instance.customFields?.[name];\n if (value) {\n const { value: joiValue, error: validationError } = Joi.date().validate(value);\n if (validationError) {\n throw new InvalidValueError(value, name, validationError);\n }\n instance.customFields[name] = joiValue.toISOString();\n }\n }\n });\n};\n\n/**\n * Hook to handle validation and custom fields during creation\n */\nexport const beforeCreate = (\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n sadotOptions: Pick<CustomFieldOptions, 'useCustomFieldsEntries' | 'getRequiredCustomFields'> = {\n useCustomFieldsEntries: false,\n },\n) => async (\n instance: any,\n options: CreateOptions,\n): Promise<void> => {\n logger.debug('sadot - before create hook');\n const { fields } = options;\n const modelType = instance.constructor.name;\n\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n // Step 1: Handle custom fields default values and required fields\n\n const fieldDefinitions = await getFieldDefinitions({\n modelType, modelOptions, identifiers, options,\n });\n\n // Apply default values\n const fieldsWithDefaultValue = fieldDefinitions.filter(def => ![null, undefined].includes(def.defaultValue));\n if (fieldsWithDefaultValue.length) {\n instance.customFields ||= {};\n fieldsWithDefaultValue\n .filter(def => (instance.customFields?.[def.name] === undefined))\n .forEach(({ name, defaultValue }) => {\n instance.customFields[name] = defaultValue;\n });\n }\n\n // Check for required fields\n let requiredFieldsNames: string[];\n\n if (sadotOptions.getRequiredCustomFields) {\n // Use consumer-provided logic to determine required fields\n requiredFieldsNames = await Promise.resolve(\n sadotOptions.getRequiredCustomFields(instance, fieldDefinitions, options),\n );\n } else {\n // Default behavior: use required flag from fieldDefinitions\n requiredFieldsNames = Array.from(\n new Set(fieldDefinitions.filter(({ required }) => required).map(({ name }) => name)),\n );\n }\n\n const { customFields } = instance;\n const fieldsNames = Object.keys(customFields ?? {});\n const missingFields = requiredFieldsNames.filter(name => !fieldsNames.includes(name));\n if (missingFields?.length) {\n throw new MissingRequiredCustomFieldError(missingFields);\n }\n\n // Step 2: Validate the model data (including custom fields)\n await validateModel(instance, options as TransactionOptions, scopeAttributes, modelOptions, true);\n\n // format date and datetime fields\n formatDates(fieldDefinitions, instance);\n\n // Step 3: Save custom field values if they exist\n const customFieldsIdx = fields!.indexOf('customFields');\n if (customFieldsIdx === -1 || !customFields || !Object.keys(customFields).length) {\n // No custom fields to update\n return;\n }\n\n // Save custom field values\n await updateInstanceValues({\n modelId: instance.id,\n modelType,\n identifiers,\n customFields,\n options: {\n useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,\n transaction: options.transaction,\n modelOptions,\n },\n });\n\n // Remove customFields from fields array after handling\n fields!.splice(customFieldsIdx, 1);\n};\n\n/**\n * Hook to handle validation and custom fields during update\n */\nexport const beforeUpdate = (\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n sadotOptions: Pick<CustomFieldOptions, 'useCustomFieldsEntries' | 'getRequiredCustomFields'> = {\n useCustomFieldsEntries: false,\n },\n) => async (\n instance: any,\n options: UpdateOptions,\n): Promise<void> => {\n logger.debug('sadot - before update hook');\n const { fields } = options;\n const modelType = instance.constructor.name;\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n const fieldDefinitions = await getFieldDefinitions({\n modelType, modelOptions, identifiers, options,\n });\n\n // Step 1: Validate the model data (including custom fields)\n await validateModel(instance, options as TransactionOptions, scopeAttributes, modelOptions, false);\n\n // format date and datetime fields\n formatDates(fieldDefinitions, instance);\n\n // Step 2: Update custom field values if they exist\n const customFieldsIdx = fields!.indexOf('customFields');\n if (customFieldsIdx > -1) {\n const { customFields } = instance;\n\n if (!Object.keys(customFields).length) {\n return;\n }\n\n // Save custom field values\n await updateInstanceValues({\n modelId: instance.id,\n modelType,\n identifiers,\n customFields,\n options: {\n useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,\n transaction: options.transaction,\n modelOptions,\n },\n });\n\n // Remove customFields from fields array after handling\n fields!.splice(customFieldsIdx, 1);\n }\n};\n\n/**\n * Hook to enable individual hooks for bulk create operations\n */\nexport const beforeBulkCreate = (options: BulkCreateOptions): void => {\n // This will activate the beforeCreate hook on each instance\n options.individualHooks = true;\n};\n\n/**\n * Hook to enable individual hooks for bulk update operations\n */\nexport const beforeBulkUpdate = (options: UpdateOptions): void => {\n // This will activate the beforeUpdate hook on each instance\n options.individualHooks = true;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hooks.cjs","names":["ajv","Ajv","beforeFull: any","applyScopeToInstance","cacheKey: string | undefined","BadRequest","where: WhereOptions","CustomFieldDefinitionType","Joi","InvalidValueError","requiredFieldsNames: string[]","MissingRequiredCustomFieldError","updateInstanceValues"],"sources":["../../src/hooks/hooks.ts"],"sourcesContent":["import type {\n BulkCreateOptions, CreateOptions, Transactionable, UpdateOptions, WhereOptions,\n} from 'sequelize';\nimport Ajv from 'ajv';\nimport Joi from 'joi';\nimport addFormats from 'ajv-formats';\nimport { BadRequest } from '@autofleet/errors';\nimport ajvErrors from 'ajv-errors';\nimport logger from '../utils/logger';\nimport * as ValidatorRepo from '../repository/validator';\nimport * as DefinitionRepo from '../repository/definition';\nimport { InvalidValueError, MissingRequiredCustomFieldError } from '../errors';\nimport type { CustomFieldOptions, ModelOptions, TransactionOptions } from '../types';\nimport applyScopeToInstance from '../utils/scopeAttributes';\nimport updateInstanceValues from './utils/updateInstanceValues';\nimport { CustomFieldDefinitionType } from '../utils/constants';\nimport type { CustomFieldDefinition } from '../models';\n\n// Include all required fields for proper validation\nconst CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL = ['id', 'schema', 'modelType', 'entityId', 'disabled'];\n\n// Initialize Ajv with relaxed settings to avoid warnings\nconst ajv = new Ajv({\n allErrors: true,\n strict: false, // Disable strict mode to avoid warnings\n strictTypes: false, // Disable strict type checking\n $data: true, // Enable $data references\n});\n\naddFormats(ajv);\najvErrors(ajv);\n\n/**\n * Helper function to manually copy object properties\n * This is more efficient for large objects and avoids excessive object creation\n */\nconst manualObjectCopy = (sourceObj: Record<string, any>, additionalProps?: Record<string, any>): Record<string, any> =>\n ({ __proto__: null, ...sourceObj, ...additionalProps });\n\n/**\n * Fetches complete custom fields for an instance by merging DB values with update values\n * This is needed for partial updates to ensure all related fields are available for validation\n */\nconst getCompleteCustomFields = async (instance: any, options: Transactionable): Promise<Record<string, any>> => {\n // If we don't have an instance id or no custom fields being updated, return original fields\n if (!instance.id || !instance.customFields || Object.keys(instance.customFields).length === 0) {\n return instance.customFields || {};\n }\n\n try {\n const ModelClass = instance.constructor;\n // Only select the customFields column to minimize data transfer\n const currentCustomFields = await ModelClass.findOne({\n where: { id: instance.id },\n attributes: ['customFields'],\n transaction: options.transaction,\n raw: true, // Get plain object instead of model instance for better performance\n });\n\n if (currentCustomFields?.customFields) {\n // Merge existing fields with update fields using our helper function\n const completeFields = manualObjectCopy(\n currentCustomFields.customFields,\n instance.customFields,\n );\n\n logger.debug('sadot - fetched complete custom fields for validation', {\n fieldsCount: Object.keys(completeFields).length,\n updateFieldsCount: Object.keys(instance.customFields).length,\n });\n\n return completeFields;\n }\n } catch (error) {\n logger.error('sadot - error fetching complete model for validation', { error });\n // Continue with partial data if we can't fetch the complete model\n }\n\n return instance.customFields || {};\n};\n\nconst buildPreChangeState = (instance: any) => {\n const beforeFull: any = { ...instance.dataValues };\n\n const changedKeys: string[] = instance.changed?.() || [];\n changedKeys.forEach((key) => {\n const prevVal = instance.previous?.(key);\n if (prevVal !== undefined) {\n beforeFull[key] = prevVal;\n }\n });\n\n const prevCF = instance.previous?.('customFields');\n if (prevCF !== undefined) {\n beforeFull.customFields = prevCF;\n }\n\n return beforeFull;\n};\n\nconst formatAjvErrors = (\n errors: {\n instancePath?: string;\n keyword: string;\n message?: string;\n params?: Record<string, any>;\n }[],\n): Record<string, string> => errors.reduce((acc, err) => {\n const basePath = (err.instancePath || '')\n .split('/')\n .filter(Boolean)\n .join('.')\n .replace(/^after\\./, '');\n\n const missingProp = err.keyword === 'required' ? `.${err.params?.missingProperty}` : '';\n const key = (basePath + missingProp).replace(/^\\./, '') || 'root';\n\n const message = err.message || 'Invalid value';\n acc[key] = message;\n\n return acc;\n}, {} as Record<string, string>);\n\n/**\n * Validates the model using custom validators\n */\nconst validateModel = async (\n instance: any,\n options: TransactionOptions,\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n isCreate = false,\n): Promise<void> => {\n const modelType = instance.constructor.name;\n\n logger.debug('sadot - validating model', { isCreate, modelType });\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n logger.debug('sadot - identifiers', { identifiers });\n\n // Skip if no identifiers\n if (!identifiers || Object.keys(identifiers).length === 0) {\n logger.debug('sadot - skipping validation: no identifiers');\n return;\n }\n\n // Find the entityId from identifiers (fleetId, businessModelId, etc.)\n const entityId = Object.values(identifiers)[0]; // Get the first value as entityId\n\n logger.debug('sadot - entityId', { entityId });\n\n if (!entityId) {\n logger.debug('sadot - skipping validation: no entityId');\n return;\n }\n\n let validatorsPromise;\n let cacheKey: string | undefined;\n if (options.transaction) {\n options.transaction.validationsCache ??= new Map();\n cacheKey = `${modelType}-${entityId}`;\n validatorsPromise = options.transaction.validationsCache.get(cacheKey);\n }\n\n if (!validatorsPromise) {\n validatorsPromise = ValidatorRepo.findAllByModelType(\n modelType,\n entityId,\n {\n transaction: options.transaction,\n attributes: CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL,\n modelOptions,\n },\n );\n if (options.transaction) {\n options?.transaction?.validationsCache!.set(cacheKey!, validatorsPromise);\n }\n }\n const validators = await validatorsPromise;\n\n logger.debug('sadot - validators found', { count: validators.length });\n\n if (!validators.length) {\n logger.debug('sadot - skipping validation: no validators found');\n return;\n }\n\n // For updates, get the previous values\n let originalValues = null;\n if (!isCreate) {\n originalValues = buildPreChangeState(instance);\n }\n\n // Get complete custom fields by merging DB values with update values\n // This is especially important for partial updates to ensure all related fields are available\n const completeCustomFields = !isCreate\n ? await getCompleteCustomFields(instance, options)\n : instance.customFields || {};\n\n for (const validator of validators) {\n const { schema } = validator;\n const typedSchema = schema as Record<string, any>;\n\n logger.debug('sadot - validating with schema', {\n schema,\n hasAfterProps: !!typedSchema.properties?.after,\n hasBeforeProps: !!typedSchema.properties?.before,\n });\n\n if (isCreate) {\n // For create operations, we only need the 'after' state\n if (typedSchema.properties?.after) {\n const validateSchema = ajv.compile({\n ...schema,\n // Focus only on the 'after' validation part for create\n properties: {\n after: typedSchema.properties.after,\n },\n });\n\n const isValid = validateSchema(JSON.parse(JSON.stringify({\n after: {\n ...instance.dataValues,\n customFields: completeCustomFields,\n },\n })));\n\n if (!isValid) {\n const errorDetails = validateSchema.errors?.map(err =>\n `${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');\n\n const formattedErrors = formatAjvErrors(validateSchema.errors!);\n throw new BadRequest(\n [new Error(`Validation failed for ${modelType}: ${errorDetails}`)],\n undefined,\n {\n customError: formattedErrors,\n },\n );\n }\n }\n } else {\n // For update operations, we need both before and after\n const validateSchema = ajv.compile(typedSchema);\n\n // Create after object with our helper function\n const afterObj = manualObjectCopy(instance.dataValues);\n\n // Add complete custom fields\n afterObj.customFields = completeCustomFields;\n\n // Create validation payload\n const payload = {\n before: originalValues,\n after: afterObj,\n };\n\n // Validate\n const isValid = validateSchema(JSON.parse(JSON.stringify(payload)));\n\n logger.debug('sadot - validation result', {\n isValid,\n test: {\n before: originalValues,\n after: afterObj,\n },\n });\n\n if (!isValid) {\n const errorDetails = validateSchema\n .errors\n ?.map(err => `${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');\n\n const formattedErrors = formatAjvErrors(validateSchema.errors!);\n throw new BadRequest(\n [new Error(`Validation failed for ${modelType}: ${errorDetails}`)],\n undefined,\n {\n customError: formattedErrors,\n },\n );\n }\n }\n }\n};\n\nconst getFieldDefinitions = async ({\n modelType,\n modelOptions,\n identifiers,\n options,\n instance,\n hasTypeId,\n}: {\n modelType: any;\n modelOptions: ModelOptions;\n identifiers: any[];\n options: any;\n instance?: any;\n hasTypeId?: boolean;\n}) => {\n const { include, useEntityIdFromInclude } = modelOptions;\n\n // If hasTypeId is enabled and instance has a typeId, filter by modelTypeId\n if (hasTypeId && instance?.typeId) {\n return DefinitionRepo.findByModelTypeId(instance.typeId, {\n withDisabled: false,\n transaction: options.transaction,\n entityIds: identifiers,\n modelType,\n modelOptions,\n });\n }\n\n // Otherwise, use the standard findAll\n const where: WhereOptions = {\n modelType,\n disabled: false,\n ...(!useEntityIdFromInclude && { entityId: identifiers }),\n };\n\n const fieldDefinitions = await DefinitionRepo.findAll(where, {\n withDisabled: false,\n transaction: options.transaction,\n include: include?.(identifiers),\n });\n return fieldDefinitions;\n};\n\nconst formatDates = (fieldDefinitions: CustomFieldDefinition[], instance: any) => {\n (fieldDefinitions || []).forEach((fieldDefinition) => {\n const { fieldType, name } = fieldDefinition;\n if ([CustomFieldDefinitionType.DATE, CustomFieldDefinitionType.DATETIME].includes(fieldType)) {\n const value = instance.customFields?.[name];\n if (value) {\n const { value: joiValue, error: validationError } = Joi.date().validate(value);\n if (validationError) {\n throw new InvalidValueError(value, name, validationError);\n }\n instance.customFields[name] = joiValue.toISOString();\n }\n }\n });\n};\n\n/**\n * Hook to handle validation and custom fields during creation\n */\nexport const beforeCreate = (\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n sadotOptions: Pick<CustomFieldOptions, 'useCustomFieldsEntries' | 'getRequiredCustomFields' | 'hasTypeId'> = {\n useCustomFieldsEntries: false,\n },\n) => async (\n instance: any,\n options: CreateOptions,\n): Promise<void> => {\n logger.debug('sadot - before create hook');\n const { fields } = options;\n const modelType = instance.constructor.name;\n\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n // Step 1: Handle custom fields default values and required fields\n\n const fieldDefinitions = await getFieldDefinitions({\n modelType, modelOptions, identifiers, options, instance, hasTypeId: sadotOptions.hasTypeId,\n });\n\n // Apply default values\n const fieldsWithDefaultValue = fieldDefinitions.filter(def => ![null, undefined].includes(def.defaultValue));\n if (fieldsWithDefaultValue.length) {\n instance.customFields ||= {};\n fieldsWithDefaultValue\n .filter(def => (instance.customFields?.[def.name] === undefined))\n .forEach(({ name, defaultValue }) => {\n instance.customFields[name] = defaultValue;\n });\n }\n\n // Check for required fields\n let requiredFieldsNames: string[];\n\n if (sadotOptions.getRequiredCustomFields) {\n // Use consumer-provided logic to determine required fields\n requiredFieldsNames = await Promise.resolve(\n sadotOptions.getRequiredCustomFields(instance, fieldDefinitions, options),\n );\n } else {\n // Default behavior: use required flag from fieldDefinitions\n requiredFieldsNames = Array.from(\n new Set(fieldDefinitions.filter(({ required }) => required).map(({ name }) => name)),\n );\n }\n\n const { customFields } = instance;\n const fieldsNames = Object.keys(customFields ?? {});\n const missingFields = requiredFieldsNames.filter(name => !fieldsNames.includes(name));\n if (missingFields?.length) {\n throw new MissingRequiredCustomFieldError(missingFields);\n }\n\n // Step 2: Validate the model data (including custom fields)\n await validateModel(instance, options as TransactionOptions, scopeAttributes, modelOptions, true);\n\n // format date and datetime fields\n formatDates(fieldDefinitions, instance);\n\n // Step 3: Save custom field values if they exist\n const customFieldsIdx = fields!.indexOf('customFields');\n if (customFieldsIdx === -1 || !customFields || !Object.keys(customFields).length) {\n // No custom fields to update\n return;\n }\n\n // Save custom field values\n await updateInstanceValues({\n modelId: instance.id,\n modelType,\n identifiers,\n customFields,\n options: {\n useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,\n transaction: options.transaction,\n modelOptions,\n },\n });\n\n // Remove customFields from fields array after handling\n fields!.splice(customFieldsIdx, 1);\n};\n\n/**\n * Hook to handle validation and custom fields during update\n */\nexport const beforeUpdate = (\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n sadotOptions: Pick<CustomFieldOptions, 'useCustomFieldsEntries' | 'getRequiredCustomFields' | 'hasTypeId'> = {\n useCustomFieldsEntries: false,\n },\n) => async (\n instance: any,\n options: UpdateOptions,\n): Promise<void> => {\n logger.debug('sadot - before update hook');\n const { fields } = options;\n const modelType = instance.constructor.name;\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n const fieldDefinitions = await getFieldDefinitions({\n modelType, modelOptions, identifiers, options, instance, hasTypeId: sadotOptions.hasTypeId,\n });\n\n // Step 1: Validate the model data (including custom fields)\n await validateModel(instance, options as TransactionOptions, scopeAttributes, modelOptions, false);\n\n // format date and datetime fields\n formatDates(fieldDefinitions, instance);\n\n // Step 2: Update custom field values if they exist\n const customFieldsIdx = fields!.indexOf('customFields');\n if (customFieldsIdx > -1) {\n const { customFields } = instance;\n\n if (!Object.keys(customFields).length) {\n return;\n }\n\n // Save custom field values\n await updateInstanceValues({\n modelId: instance.id,\n modelType,\n identifiers,\n customFields,\n options: {\n useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,\n transaction: options.transaction,\n modelOptions,\n },\n });\n\n // Remove customFields from fields array after handling\n fields!.splice(customFieldsIdx, 1);\n }\n};\n\n/**\n * Hook to enable individual hooks for bulk create operations\n */\nexport const beforeBulkCreate = (options: BulkCreateOptions): void => {\n // This will activate the beforeCreate hook on each instance\n options.individualHooks = true;\n};\n\n/**\n * Hook to enable individual hooks for bulk update operations\n */\nexport const beforeBulkUpdate = (options: UpdateOptions): void => {\n // This will activate the beforeUpdate hook on each instance\n options.individualHooks = true;\n};\n"],"mappings":"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"}
|
package/dist/hooks/hooks.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"../utils/logger/index.js";import{CustomFieldDefinitionType as t}from"../utils/constants/index.js";import{InvalidValueError as n,MissingRequiredCustomFieldError as r}from"../errors/index.js";import{findAll as i}from"../repository/definition.js";import{findAllByModelType as
|
|
1
|
+
import e from"../utils/logger/index.js";import{CustomFieldDefinitionType as t}from"../utils/constants/index.js";import{InvalidValueError as n,MissingRequiredCustomFieldError as r}from"../errors/index.js";import{findAll as i,findByModelTypeId as a}from"../repository/definition.js";import{findAllByModelType as o}from"../repository/validator.js";import s from"../utils/scopeAttributes.js";import c from"./utils/updateInstanceValues.js";import l from"joi";import{BadRequest as u}from"@autofleet/errors";import d from"ajv";import f from"ajv-formats";import p from"ajv-errors";const m=[`id`,`schema`,`modelType`,`entityId`,`disabled`],h=new d({allErrors:!0,strict:!1,strictTypes:!1,$data:!0});f(h),p(h);const g=(e,t)=>({__proto__:null,...e,...t}),_=async(t,n)=>{if(!t.id||!t.customFields||Object.keys(t.customFields).length===0)return t.customFields||{};try{let r=await t.constructor.findOne({where:{id:t.id},attributes:[`customFields`],transaction:n.transaction,raw:!0});if(r?.customFields){let n=g(r.customFields,t.customFields);return e.debug(`sadot - fetched complete custom fields for validation`,{fieldsCount:Object.keys(n).length,updateFieldsCount:Object.keys(t.customFields).length}),n}}catch(t){e.error(`sadot - error fetching complete model for validation`,{error:t})}return t.customFields||{}},v=e=>{let t={...e.dataValues};(e.changed?.()||[]).forEach(n=>{let r=e.previous?.(n);r!==void 0&&(t[n]=r)});let n=e.previous?.(`customFields`);return n!==void 0&&(t.customFields=n),t},y=e=>e.reduce((e,t)=>{let n=((t.instancePath||``).split(`/`).filter(Boolean).join(`.`).replace(/^after\./,``)+(t.keyword===`required`?`.${t.params?.missingProperty}`:``)).replace(/^\./,``)||`root`;return e[n]=t.message||`Invalid value`,e},{}),b=async(t,n,r,i={},a=!1)=>{let c=t.constructor.name;e.debug(`sadot - validating model`,{isCreate:a,modelType:c});let l=s(t,r);if(e.debug(`sadot - identifiers`,{identifiers:l}),!l||Object.keys(l).length===0){e.debug(`sadot - skipping validation: no identifiers`);return}let d=Object.values(l)[0];if(e.debug(`sadot - entityId`,{entityId:d}),!d){e.debug(`sadot - skipping validation: no entityId`);return}let f,p;n.transaction&&(n.transaction.validationsCache??=new Map,p=`${c}-${d}`,f=n.transaction.validationsCache.get(p)),f||(f=o(c,d,{transaction:n.transaction,attributes:m,modelOptions:i}),n.transaction&&n?.transaction?.validationsCache.set(p,f));let b=await f;if(e.debug(`sadot - validators found`,{count:b.length}),!b.length){e.debug(`sadot - skipping validation: no validators found`);return}let x=null;a||(x=v(t));let S=a?t.customFields||{}:await _(t,n);for(let n of b){let{schema:r}=n,i=r;if(e.debug(`sadot - validating with schema`,{schema:r,hasAfterProps:!!i.properties?.after,hasBeforeProps:!!i.properties?.before}),a){if(i.properties?.after){let e=h.compile({...r,properties:{after:i.properties.after}});if(!e(JSON.parse(JSON.stringify({after:{...t.dataValues,customFields:S}})))){let t=e.errors?.map(e=>`${e.instancePath||``} ${e.message||`Invalid value`}`).join(`, `),n=y(e.errors);throw new u([Error(`Validation failed for ${c}: ${t}`)],void 0,{customError:n})}}}else{let n=h.compile(i),r=g(t.dataValues);r.customFields=S;let a={before:x,after:r},o=n(JSON.parse(JSON.stringify(a)));if(e.debug(`sadot - validation result`,{isValid:o,test:{before:x,after:r}}),!o){let e=n.errors?.map(e=>`${e.instancePath||``} ${e.message||`Invalid value`}`).join(`, `),t=y(n.errors);throw new u([Error(`Validation failed for ${c}: ${e}`)],void 0,{customError:t})}}}},x=async({modelType:e,modelOptions:t,identifiers:n,options:r,instance:o,hasTypeId:s})=>{let{include:c,useEntityIdFromInclude:l}=t;return s&&o?.typeId?a(o.typeId,{withDisabled:!1,transaction:r.transaction,entityIds:n,modelType:e,modelOptions:t}):await i({modelType:e,disabled:!1,...!l&&{entityId:n}},{withDisabled:!1,transaction:r.transaction,include:c?.(n)})},S=(e,r)=>{(e||[]).forEach(e=>{let{fieldType:i,name:a}=e;if([t.DATE,t.DATETIME].includes(i)){let e=r.customFields?.[a];if(e){let{value:t,error:i}=l.date().validate(e);if(i)throw new n(e,a,i);r.customFields[a]=t.toISOString()}}})},C=(t,n={},i={useCustomFieldsEntries:!1})=>async(a,o)=>{e.debug(`sadot - before create hook`);let{fields:l}=o,u=a.constructor.name,d=s(a,t),f=await x({modelType:u,modelOptions:n,identifiers:d,options:o,instance:a,hasTypeId:i.hasTypeId}),p=f.filter(e=>![null,void 0].includes(e.defaultValue));p.length&&(a.customFields||={},p.filter(e=>a.customFields?.[e.name]===void 0).forEach(({name:e,defaultValue:t})=>{a.customFields[e]=t}));let m;m=i.getRequiredCustomFields?await Promise.resolve(i.getRequiredCustomFields(a,f,o)):Array.from(new Set(f.filter(({required:e})=>e).map(({name:e})=>e)));let{customFields:h}=a,g=Object.keys(h??{}),_=m.filter(e=>!g.includes(e));if(_?.length)throw new r(_);await b(a,o,t,n,!0),S(f,a);let v=l.indexOf(`customFields`);v===-1||!h||!Object.keys(h).length||(await c({modelId:a.id,modelType:u,identifiers:d,customFields:h,options:{useCustomFieldsEntries:i.useCustomFieldsEntries,transaction:o.transaction,modelOptions:n}}),l.splice(v,1))},w=(t,n={},r={useCustomFieldsEntries:!1})=>async(i,a)=>{e.debug(`sadot - before update hook`);let{fields:o}=a,l=i.constructor.name,u=s(i,t),d=await x({modelType:l,modelOptions:n,identifiers:u,options:a,instance:i,hasTypeId:r.hasTypeId});await b(i,a,t,n,!1),S(d,i);let f=o.indexOf(`customFields`);if(f>-1){let{customFields:e}=i;if(!Object.keys(e).length)return;await c({modelId:i.id,modelType:l,identifiers:u,customFields:e,options:{useCustomFieldsEntries:r.useCustomFieldsEntries,transaction:a.transaction,modelOptions:n}}),o.splice(f,1)}},T=e=>{e.individualHooks=!0},E=e=>{e.individualHooks=!0};export{T as beforeBulkCreate,E as beforeBulkUpdate,C as beforeCreate,w as beforeUpdate};
|
|
2
2
|
//# sourceMappingURL=hooks.js.map
|
package/dist/hooks/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","names":["beforeFull: any","applyScopeToInstance","cacheKey: string | undefined","ValidatorRepo.findAllByModelType","where: WhereOptions","DefinitionRepo.findAll","requiredFieldsNames: string[]","updateInstanceValues"],"sources":["../../src/hooks/hooks.ts"],"sourcesContent":["import type {\n BulkCreateOptions, CreateOptions, Transactionable, UpdateOptions, WhereOptions,\n} from 'sequelize';\nimport Ajv from 'ajv';\nimport Joi from 'joi';\nimport addFormats from 'ajv-formats';\nimport { BadRequest } from '@autofleet/errors';\nimport ajvErrors from 'ajv-errors';\nimport logger from '../utils/logger';\nimport * as ValidatorRepo from '../repository/validator';\nimport * as DefinitionRepo from '../repository/definition';\nimport { InvalidValueError, MissingRequiredCustomFieldError } from '../errors';\nimport type { CustomFieldOptions, ModelOptions, TransactionOptions } from '../types';\nimport applyScopeToInstance from '../utils/scopeAttributes';\nimport updateInstanceValues from './utils/updateInstanceValues';\nimport { CustomFieldDefinitionType } from '../utils/constants';\nimport type { CustomFieldDefinition } from '../models';\n\n// Include all required fields for proper validation\nconst CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL = ['id', 'schema', 'modelType', 'entityId', 'disabled'];\n\n// Initialize Ajv with relaxed settings to avoid warnings\nconst ajv = new Ajv({\n allErrors: true,\n strict: false, // Disable strict mode to avoid warnings\n strictTypes: false, // Disable strict type checking\n $data: true, // Enable $data references\n});\n\naddFormats(ajv);\najvErrors(ajv);\n\n/**\n * Helper function to manually copy object properties\n * This is more efficient for large objects and avoids excessive object creation\n */\nconst manualObjectCopy = (sourceObj: Record<string, any>, additionalProps?: Record<string, any>): Record<string, any> =>\n ({ __proto__: null, ...sourceObj, ...additionalProps });\n\n/**\n * Fetches complete custom fields for an instance by merging DB values with update values\n * This is needed for partial updates to ensure all related fields are available for validation\n */\nconst getCompleteCustomFields = async (instance: any, options: Transactionable): Promise<Record<string, any>> => {\n // If we don't have an instance id or no custom fields being updated, return original fields\n if (!instance.id || !instance.customFields || Object.keys(instance.customFields).length === 0) {\n return instance.customFields || {};\n }\n\n try {\n const ModelClass = instance.constructor;\n // Only select the customFields column to minimize data transfer\n const currentCustomFields = await ModelClass.findOne({\n where: { id: instance.id },\n attributes: ['customFields'],\n transaction: options.transaction,\n raw: true, // Get plain object instead of model instance for better performance\n });\n\n if (currentCustomFields?.customFields) {\n // Merge existing fields with update fields using our helper function\n const completeFields = manualObjectCopy(\n currentCustomFields.customFields,\n instance.customFields,\n );\n\n logger.debug('sadot - fetched complete custom fields for validation', {\n fieldsCount: Object.keys(completeFields).length,\n updateFieldsCount: Object.keys(instance.customFields).length,\n });\n\n return completeFields;\n }\n } catch (error) {\n logger.error('sadot - error fetching complete model for validation', { error });\n // Continue with partial data if we can't fetch the complete model\n }\n\n return instance.customFields || {};\n};\n\nconst buildPreChangeState = (instance: any) => {\n const beforeFull: any = { ...instance.dataValues };\n\n const changedKeys: string[] = instance.changed?.() || [];\n changedKeys.forEach((key) => {\n const prevVal = instance.previous?.(key);\n if (prevVal !== undefined) {\n beforeFull[key] = prevVal;\n }\n });\n\n const prevCF = instance.previous?.('customFields');\n if (prevCF !== undefined) {\n beforeFull.customFields = prevCF;\n }\n\n return beforeFull;\n};\n\nconst formatAjvErrors = (\n errors: {\n instancePath?: string;\n keyword: string;\n message?: string;\n params?: Record<string, any>;\n }[],\n): Record<string, string> => errors.reduce((acc, err) => {\n const basePath = (err.instancePath || '')\n .split('/')\n .filter(Boolean)\n .join('.')\n .replace(/^after\\./, '');\n\n const missingProp = err.keyword === 'required' ? `.${err.params?.missingProperty}` : '';\n const key = (basePath + missingProp).replace(/^\\./, '') || 'root';\n\n const message = err.message || 'Invalid value';\n acc[key] = message;\n\n return acc;\n}, {} as Record<string, string>);\n\n/**\n * Validates the model using custom validators\n */\nconst validateModel = async (\n instance: any,\n options: TransactionOptions,\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n isCreate = false,\n): Promise<void> => {\n const modelType = instance.constructor.name;\n\n logger.debug('sadot - validating model', { isCreate, modelType });\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n logger.debug('sadot - identifiers', { identifiers });\n\n // Skip if no identifiers\n if (!identifiers || Object.keys(identifiers).length === 0) {\n logger.debug('sadot - skipping validation: no identifiers');\n return;\n }\n\n // Find the entityId from identifiers (fleetId, businessModelId, etc.)\n const entityId = Object.values(identifiers)[0]; // Get the first value as entityId\n\n logger.debug('sadot - entityId', { entityId });\n\n if (!entityId) {\n logger.debug('sadot - skipping validation: no entityId');\n return;\n }\n\n let validatorsPromise;\n let cacheKey: string | undefined;\n if (options.transaction) {\n options.transaction.validationsCache ??= new Map();\n cacheKey = `${modelType}-${entityId}`;\n validatorsPromise = options.transaction.validationsCache.get(cacheKey);\n }\n\n if (!validatorsPromise) {\n validatorsPromise = ValidatorRepo.findAllByModelType(\n modelType,\n entityId,\n {\n transaction: options.transaction,\n attributes: CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL,\n modelOptions,\n },\n );\n if (options.transaction) {\n options?.transaction?.validationsCache!.set(cacheKey!, validatorsPromise);\n }\n }\n const validators = await validatorsPromise;\n\n logger.debug('sadot - validators found', { count: validators.length });\n\n if (!validators.length) {\n logger.debug('sadot - skipping validation: no validators found');\n return;\n }\n\n // For updates, get the previous values\n let originalValues = null;\n if (!isCreate) {\n originalValues = buildPreChangeState(instance);\n }\n\n // Get complete custom fields by merging DB values with update values\n // This is especially important for partial updates to ensure all related fields are available\n const completeCustomFields = !isCreate\n ? await getCompleteCustomFields(instance, options)\n : instance.customFields || {};\n\n for (const validator of validators) {\n const { schema } = validator;\n const typedSchema = schema as Record<string, any>;\n\n logger.debug('sadot - validating with schema', {\n schema,\n hasAfterProps: !!typedSchema.properties?.after,\n hasBeforeProps: !!typedSchema.properties?.before,\n });\n\n if (isCreate) {\n // For create operations, we only need the 'after' state\n if (typedSchema.properties?.after) {\n const validateSchema = ajv.compile({\n ...schema,\n // Focus only on the 'after' validation part for create\n properties: {\n after: typedSchema.properties.after,\n },\n });\n\n const isValid = validateSchema(JSON.parse(JSON.stringify({\n after: {\n ...instance.dataValues,\n customFields: completeCustomFields,\n },\n })));\n\n if (!isValid) {\n const errorDetails = validateSchema.errors?.map(err =>\n `${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');\n\n const formattedErrors = formatAjvErrors(validateSchema.errors!);\n throw new BadRequest(\n [new Error(`Validation failed for ${modelType}: ${errorDetails}`)],\n undefined,\n {\n customError: formattedErrors,\n },\n );\n }\n }\n } else {\n // For update operations, we need both before and after\n const validateSchema = ajv.compile(typedSchema);\n\n // Create after object with our helper function\n const afterObj = manualObjectCopy(instance.dataValues);\n\n // Add complete custom fields\n afterObj.customFields = completeCustomFields;\n\n // Create validation payload\n const payload = {\n before: originalValues,\n after: afterObj,\n };\n\n // Validate\n const isValid = validateSchema(JSON.parse(JSON.stringify(payload)));\n\n logger.debug('sadot - validation result', {\n isValid,\n test: {\n before: originalValues,\n after: afterObj,\n },\n });\n\n if (!isValid) {\n const errorDetails = validateSchema\n .errors\n ?.map(err => `${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');\n\n const formattedErrors = formatAjvErrors(validateSchema.errors!);\n throw new BadRequest(\n [new Error(`Validation failed for ${modelType}: ${errorDetails}`)],\n undefined,\n {\n customError: formattedErrors,\n },\n );\n }\n }\n }\n};\n\nconst getFieldDefinitions = async ({\n modelType,\n modelOptions,\n identifiers,\n options,\n}: {\n modelType: any;\n modelOptions: ModelOptions;\n identifiers: any[];\n options: any;\n}) => {\n const { include, useEntityIdFromInclude } = modelOptions;\n const where: WhereOptions = {\n modelType,\n disabled: false,\n ...(!useEntityIdFromInclude && { entityId: identifiers }),\n };\n\n const fieldDefinitions = await DefinitionRepo.findAll(where, {\n withDisabled: false,\n transaction: options.transaction,\n include: include?.(identifiers),\n });\n return fieldDefinitions;\n};\n\nconst formatDates = (fieldDefinitions: CustomFieldDefinition[], instance: any) => {\n (fieldDefinitions || []).forEach((fieldDefinition) => {\n const { fieldType, name } = fieldDefinition;\n if ([CustomFieldDefinitionType.DATE, CustomFieldDefinitionType.DATETIME].includes(fieldType)) {\n const value = instance.customFields?.[name];\n if (value) {\n const { value: joiValue, error: validationError } = Joi.date().validate(value);\n if (validationError) {\n throw new InvalidValueError(value, name, validationError);\n }\n instance.customFields[name] = joiValue.toISOString();\n }\n }\n });\n};\n\n/**\n * Hook to handle validation and custom fields during creation\n */\nexport const beforeCreate = (\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n sadotOptions: Pick<CustomFieldOptions, 'useCustomFieldsEntries' | 'getRequiredCustomFields'> = {\n useCustomFieldsEntries: false,\n },\n) => async (\n instance: any,\n options: CreateOptions,\n): Promise<void> => {\n logger.debug('sadot - before create hook');\n const { fields } = options;\n const modelType = instance.constructor.name;\n\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n // Step 1: Handle custom fields default values and required fields\n\n const fieldDefinitions = await getFieldDefinitions({\n modelType, modelOptions, identifiers, options,\n });\n\n // Apply default values\n const fieldsWithDefaultValue = fieldDefinitions.filter(def => ![null, undefined].includes(def.defaultValue));\n if (fieldsWithDefaultValue.length) {\n instance.customFields ||= {};\n fieldsWithDefaultValue\n .filter(def => (instance.customFields?.[def.name] === undefined))\n .forEach(({ name, defaultValue }) => {\n instance.customFields[name] = defaultValue;\n });\n }\n\n // Check for required fields\n let requiredFieldsNames: string[];\n\n if (sadotOptions.getRequiredCustomFields) {\n // Use consumer-provided logic to determine required fields\n requiredFieldsNames = await Promise.resolve(\n sadotOptions.getRequiredCustomFields(instance, fieldDefinitions, options),\n );\n } else {\n // Default behavior: use required flag from fieldDefinitions\n requiredFieldsNames = Array.from(\n new Set(fieldDefinitions.filter(({ required }) => required).map(({ name }) => name)),\n );\n }\n\n const { customFields } = instance;\n const fieldsNames = Object.keys(customFields ?? {});\n const missingFields = requiredFieldsNames.filter(name => !fieldsNames.includes(name));\n if (missingFields?.length) {\n throw new MissingRequiredCustomFieldError(missingFields);\n }\n\n // Step 2: Validate the model data (including custom fields)\n await validateModel(instance, options as TransactionOptions, scopeAttributes, modelOptions, true);\n\n // format date and datetime fields\n formatDates(fieldDefinitions, instance);\n\n // Step 3: Save custom field values if they exist\n const customFieldsIdx = fields!.indexOf('customFields');\n if (customFieldsIdx === -1 || !customFields || !Object.keys(customFields).length) {\n // No custom fields to update\n return;\n }\n\n // Save custom field values\n await updateInstanceValues({\n modelId: instance.id,\n modelType,\n identifiers,\n customFields,\n options: {\n useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,\n transaction: options.transaction,\n modelOptions,\n },\n });\n\n // Remove customFields from fields array after handling\n fields!.splice(customFieldsIdx, 1);\n};\n\n/**\n * Hook to handle validation and custom fields during update\n */\nexport const beforeUpdate = (\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n sadotOptions: Pick<CustomFieldOptions, 'useCustomFieldsEntries' | 'getRequiredCustomFields'> = {\n useCustomFieldsEntries: false,\n },\n) => async (\n instance: any,\n options: UpdateOptions,\n): Promise<void> => {\n logger.debug('sadot - before update hook');\n const { fields } = options;\n const modelType = instance.constructor.name;\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n const fieldDefinitions = await getFieldDefinitions({\n modelType, modelOptions, identifiers, options,\n });\n\n // Step 1: Validate the model data (including custom fields)\n await validateModel(instance, options as TransactionOptions, scopeAttributes, modelOptions, false);\n\n // format date and datetime fields\n formatDates(fieldDefinitions, instance);\n\n // Step 2: Update custom field values if they exist\n const customFieldsIdx = fields!.indexOf('customFields');\n if (customFieldsIdx > -1) {\n const { customFields } = instance;\n\n if (!Object.keys(customFields).length) {\n return;\n }\n\n // Save custom field values\n await updateInstanceValues({\n modelId: instance.id,\n modelType,\n identifiers,\n customFields,\n options: {\n useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,\n transaction: options.transaction,\n modelOptions,\n },\n });\n\n // Remove customFields from fields array after handling\n fields!.splice(customFieldsIdx, 1);\n }\n};\n\n/**\n * Hook to enable individual hooks for bulk create operations\n */\nexport const beforeBulkCreate = (options: BulkCreateOptions): void => {\n // This will activate the beforeCreate hook on each instance\n options.individualHooks = true;\n};\n\n/**\n * Hook to enable individual hooks for bulk update operations\n */\nexport const beforeBulkUpdate = (options: UpdateOptions): void => {\n // This will activate the beforeUpdate hook on each instance\n options.individualHooks = true;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hooks.js","names":["beforeFull: any","applyScopeToInstance","cacheKey: string | undefined","ValidatorRepo.findAllByModelType","DefinitionRepo.findByModelTypeId","where: WhereOptions","DefinitionRepo.findAll","requiredFieldsNames: string[]","updateInstanceValues"],"sources":["../../src/hooks/hooks.ts"],"sourcesContent":["import type {\n BulkCreateOptions, CreateOptions, Transactionable, UpdateOptions, WhereOptions,\n} from 'sequelize';\nimport Ajv from 'ajv';\nimport Joi from 'joi';\nimport addFormats from 'ajv-formats';\nimport { BadRequest } from '@autofleet/errors';\nimport ajvErrors from 'ajv-errors';\nimport logger from '../utils/logger';\nimport * as ValidatorRepo from '../repository/validator';\nimport * as DefinitionRepo from '../repository/definition';\nimport { InvalidValueError, MissingRequiredCustomFieldError } from '../errors';\nimport type { CustomFieldOptions, ModelOptions, TransactionOptions } from '../types';\nimport applyScopeToInstance from '../utils/scopeAttributes';\nimport updateInstanceValues from './utils/updateInstanceValues';\nimport { CustomFieldDefinitionType } from '../utils/constants';\nimport type { CustomFieldDefinition } from '../models';\n\n// Include all required fields for proper validation\nconst CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL = ['id', 'schema', 'modelType', 'entityId', 'disabled'];\n\n// Initialize Ajv with relaxed settings to avoid warnings\nconst ajv = new Ajv({\n allErrors: true,\n strict: false, // Disable strict mode to avoid warnings\n strictTypes: false, // Disable strict type checking\n $data: true, // Enable $data references\n});\n\naddFormats(ajv);\najvErrors(ajv);\n\n/**\n * Helper function to manually copy object properties\n * This is more efficient for large objects and avoids excessive object creation\n */\nconst manualObjectCopy = (sourceObj: Record<string, any>, additionalProps?: Record<string, any>): Record<string, any> =>\n ({ __proto__: null, ...sourceObj, ...additionalProps });\n\n/**\n * Fetches complete custom fields for an instance by merging DB values with update values\n * This is needed for partial updates to ensure all related fields are available for validation\n */\nconst getCompleteCustomFields = async (instance: any, options: Transactionable): Promise<Record<string, any>> => {\n // If we don't have an instance id or no custom fields being updated, return original fields\n if (!instance.id || !instance.customFields || Object.keys(instance.customFields).length === 0) {\n return instance.customFields || {};\n }\n\n try {\n const ModelClass = instance.constructor;\n // Only select the customFields column to minimize data transfer\n const currentCustomFields = await ModelClass.findOne({\n where: { id: instance.id },\n attributes: ['customFields'],\n transaction: options.transaction,\n raw: true, // Get plain object instead of model instance for better performance\n });\n\n if (currentCustomFields?.customFields) {\n // Merge existing fields with update fields using our helper function\n const completeFields = manualObjectCopy(\n currentCustomFields.customFields,\n instance.customFields,\n );\n\n logger.debug('sadot - fetched complete custom fields for validation', {\n fieldsCount: Object.keys(completeFields).length,\n updateFieldsCount: Object.keys(instance.customFields).length,\n });\n\n return completeFields;\n }\n } catch (error) {\n logger.error('sadot - error fetching complete model for validation', { error });\n // Continue with partial data if we can't fetch the complete model\n }\n\n return instance.customFields || {};\n};\n\nconst buildPreChangeState = (instance: any) => {\n const beforeFull: any = { ...instance.dataValues };\n\n const changedKeys: string[] = instance.changed?.() || [];\n changedKeys.forEach((key) => {\n const prevVal = instance.previous?.(key);\n if (prevVal !== undefined) {\n beforeFull[key] = prevVal;\n }\n });\n\n const prevCF = instance.previous?.('customFields');\n if (prevCF !== undefined) {\n beforeFull.customFields = prevCF;\n }\n\n return beforeFull;\n};\n\nconst formatAjvErrors = (\n errors: {\n instancePath?: string;\n keyword: string;\n message?: string;\n params?: Record<string, any>;\n }[],\n): Record<string, string> => errors.reduce((acc, err) => {\n const basePath = (err.instancePath || '')\n .split('/')\n .filter(Boolean)\n .join('.')\n .replace(/^after\\./, '');\n\n const missingProp = err.keyword === 'required' ? `.${err.params?.missingProperty}` : '';\n const key = (basePath + missingProp).replace(/^\\./, '') || 'root';\n\n const message = err.message || 'Invalid value';\n acc[key] = message;\n\n return acc;\n}, {} as Record<string, string>);\n\n/**\n * Validates the model using custom validators\n */\nconst validateModel = async (\n instance: any,\n options: TransactionOptions,\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n isCreate = false,\n): Promise<void> => {\n const modelType = instance.constructor.name;\n\n logger.debug('sadot - validating model', { isCreate, modelType });\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n logger.debug('sadot - identifiers', { identifiers });\n\n // Skip if no identifiers\n if (!identifiers || Object.keys(identifiers).length === 0) {\n logger.debug('sadot - skipping validation: no identifiers');\n return;\n }\n\n // Find the entityId from identifiers (fleetId, businessModelId, etc.)\n const entityId = Object.values(identifiers)[0]; // Get the first value as entityId\n\n logger.debug('sadot - entityId', { entityId });\n\n if (!entityId) {\n logger.debug('sadot - skipping validation: no entityId');\n return;\n }\n\n let validatorsPromise;\n let cacheKey: string | undefined;\n if (options.transaction) {\n options.transaction.validationsCache ??= new Map();\n cacheKey = `${modelType}-${entityId}`;\n validatorsPromise = options.transaction.validationsCache.get(cacheKey);\n }\n\n if (!validatorsPromise) {\n validatorsPromise = ValidatorRepo.findAllByModelType(\n modelType,\n entityId,\n {\n transaction: options.transaction,\n attributes: CUSTOM_VALIDATOR_ATTRIBUTES_TO_PULL,\n modelOptions,\n },\n );\n if (options.transaction) {\n options?.transaction?.validationsCache!.set(cacheKey!, validatorsPromise);\n }\n }\n const validators = await validatorsPromise;\n\n logger.debug('sadot - validators found', { count: validators.length });\n\n if (!validators.length) {\n logger.debug('sadot - skipping validation: no validators found');\n return;\n }\n\n // For updates, get the previous values\n let originalValues = null;\n if (!isCreate) {\n originalValues = buildPreChangeState(instance);\n }\n\n // Get complete custom fields by merging DB values with update values\n // This is especially important for partial updates to ensure all related fields are available\n const completeCustomFields = !isCreate\n ? await getCompleteCustomFields(instance, options)\n : instance.customFields || {};\n\n for (const validator of validators) {\n const { schema } = validator;\n const typedSchema = schema as Record<string, any>;\n\n logger.debug('sadot - validating with schema', {\n schema,\n hasAfterProps: !!typedSchema.properties?.after,\n hasBeforeProps: !!typedSchema.properties?.before,\n });\n\n if (isCreate) {\n // For create operations, we only need the 'after' state\n if (typedSchema.properties?.after) {\n const validateSchema = ajv.compile({\n ...schema,\n // Focus only on the 'after' validation part for create\n properties: {\n after: typedSchema.properties.after,\n },\n });\n\n const isValid = validateSchema(JSON.parse(JSON.stringify({\n after: {\n ...instance.dataValues,\n customFields: completeCustomFields,\n },\n })));\n\n if (!isValid) {\n const errorDetails = validateSchema.errors?.map(err =>\n `${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');\n\n const formattedErrors = formatAjvErrors(validateSchema.errors!);\n throw new BadRequest(\n [new Error(`Validation failed for ${modelType}: ${errorDetails}`)],\n undefined,\n {\n customError: formattedErrors,\n },\n );\n }\n }\n } else {\n // For update operations, we need both before and after\n const validateSchema = ajv.compile(typedSchema);\n\n // Create after object with our helper function\n const afterObj = manualObjectCopy(instance.dataValues);\n\n // Add complete custom fields\n afterObj.customFields = completeCustomFields;\n\n // Create validation payload\n const payload = {\n before: originalValues,\n after: afterObj,\n };\n\n // Validate\n const isValid = validateSchema(JSON.parse(JSON.stringify(payload)));\n\n logger.debug('sadot - validation result', {\n isValid,\n test: {\n before: originalValues,\n after: afterObj,\n },\n });\n\n if (!isValid) {\n const errorDetails = validateSchema\n .errors\n ?.map(err => `${(err as any).instancePath || ''} ${(err as any).message || 'Invalid value'}`).join(', ');\n\n const formattedErrors = formatAjvErrors(validateSchema.errors!);\n throw new BadRequest(\n [new Error(`Validation failed for ${modelType}: ${errorDetails}`)],\n undefined,\n {\n customError: formattedErrors,\n },\n );\n }\n }\n }\n};\n\nconst getFieldDefinitions = async ({\n modelType,\n modelOptions,\n identifiers,\n options,\n instance,\n hasTypeId,\n}: {\n modelType: any;\n modelOptions: ModelOptions;\n identifiers: any[];\n options: any;\n instance?: any;\n hasTypeId?: boolean;\n}) => {\n const { include, useEntityIdFromInclude } = modelOptions;\n\n // If hasTypeId is enabled and instance has a typeId, filter by modelTypeId\n if (hasTypeId && instance?.typeId) {\n return DefinitionRepo.findByModelTypeId(instance.typeId, {\n withDisabled: false,\n transaction: options.transaction,\n entityIds: identifiers,\n modelType,\n modelOptions,\n });\n }\n\n // Otherwise, use the standard findAll\n const where: WhereOptions = {\n modelType,\n disabled: false,\n ...(!useEntityIdFromInclude && { entityId: identifiers }),\n };\n\n const fieldDefinitions = await DefinitionRepo.findAll(where, {\n withDisabled: false,\n transaction: options.transaction,\n include: include?.(identifiers),\n });\n return fieldDefinitions;\n};\n\nconst formatDates = (fieldDefinitions: CustomFieldDefinition[], instance: any) => {\n (fieldDefinitions || []).forEach((fieldDefinition) => {\n const { fieldType, name } = fieldDefinition;\n if ([CustomFieldDefinitionType.DATE, CustomFieldDefinitionType.DATETIME].includes(fieldType)) {\n const value = instance.customFields?.[name];\n if (value) {\n const { value: joiValue, error: validationError } = Joi.date().validate(value);\n if (validationError) {\n throw new InvalidValueError(value, name, validationError);\n }\n instance.customFields[name] = joiValue.toISOString();\n }\n }\n });\n};\n\n/**\n * Hook to handle validation and custom fields during creation\n */\nexport const beforeCreate = (\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n sadotOptions: Pick<CustomFieldOptions, 'useCustomFieldsEntries' | 'getRequiredCustomFields' | 'hasTypeId'> = {\n useCustomFieldsEntries: false,\n },\n) => async (\n instance: any,\n options: CreateOptions,\n): Promise<void> => {\n logger.debug('sadot - before create hook');\n const { fields } = options;\n const modelType = instance.constructor.name;\n\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n // Step 1: Handle custom fields default values and required fields\n\n const fieldDefinitions = await getFieldDefinitions({\n modelType, modelOptions, identifiers, options, instance, hasTypeId: sadotOptions.hasTypeId,\n });\n\n // Apply default values\n const fieldsWithDefaultValue = fieldDefinitions.filter(def => ![null, undefined].includes(def.defaultValue));\n if (fieldsWithDefaultValue.length) {\n instance.customFields ||= {};\n fieldsWithDefaultValue\n .filter(def => (instance.customFields?.[def.name] === undefined))\n .forEach(({ name, defaultValue }) => {\n instance.customFields[name] = defaultValue;\n });\n }\n\n // Check for required fields\n let requiredFieldsNames: string[];\n\n if (sadotOptions.getRequiredCustomFields) {\n // Use consumer-provided logic to determine required fields\n requiredFieldsNames = await Promise.resolve(\n sadotOptions.getRequiredCustomFields(instance, fieldDefinitions, options),\n );\n } else {\n // Default behavior: use required flag from fieldDefinitions\n requiredFieldsNames = Array.from(\n new Set(fieldDefinitions.filter(({ required }) => required).map(({ name }) => name)),\n );\n }\n\n const { customFields } = instance;\n const fieldsNames = Object.keys(customFields ?? {});\n const missingFields = requiredFieldsNames.filter(name => !fieldsNames.includes(name));\n if (missingFields?.length) {\n throw new MissingRequiredCustomFieldError(missingFields);\n }\n\n // Step 2: Validate the model data (including custom fields)\n await validateModel(instance, options as TransactionOptions, scopeAttributes, modelOptions, true);\n\n // format date and datetime fields\n formatDates(fieldDefinitions, instance);\n\n // Step 3: Save custom field values if they exist\n const customFieldsIdx = fields!.indexOf('customFields');\n if (customFieldsIdx === -1 || !customFields || !Object.keys(customFields).length) {\n // No custom fields to update\n return;\n }\n\n // Save custom field values\n await updateInstanceValues({\n modelId: instance.id,\n modelType,\n identifiers,\n customFields,\n options: {\n useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,\n transaction: options.transaction,\n modelOptions,\n },\n });\n\n // Remove customFields from fields array after handling\n fields!.splice(customFieldsIdx, 1);\n};\n\n/**\n * Hook to handle validation and custom fields during update\n */\nexport const beforeUpdate = (\n scopeAttributes: string[],\n modelOptions: ModelOptions = {},\n sadotOptions: Pick<CustomFieldOptions, 'useCustomFieldsEntries' | 'getRequiredCustomFields' | 'hasTypeId'> = {\n useCustomFieldsEntries: false,\n },\n) => async (\n instance: any,\n options: UpdateOptions,\n): Promise<void> => {\n logger.debug('sadot - before update hook');\n const { fields } = options;\n const modelType = instance.constructor.name;\n const identifiers = applyScopeToInstance(instance, scopeAttributes);\n\n const fieldDefinitions = await getFieldDefinitions({\n modelType, modelOptions, identifiers, options, instance, hasTypeId: sadotOptions.hasTypeId,\n });\n\n // Step 1: Validate the model data (including custom fields)\n await validateModel(instance, options as TransactionOptions, scopeAttributes, modelOptions, false);\n\n // format date and datetime fields\n formatDates(fieldDefinitions, instance);\n\n // Step 2: Update custom field values if they exist\n const customFieldsIdx = fields!.indexOf('customFields');\n if (customFieldsIdx > -1) {\n const { customFields } = instance;\n\n if (!Object.keys(customFields).length) {\n return;\n }\n\n // Save custom field values\n await updateInstanceValues({\n modelId: instance.id,\n modelType,\n identifiers,\n customFields,\n options: {\n useCustomFieldsEntries: sadotOptions.useCustomFieldsEntries,\n transaction: options.transaction,\n modelOptions,\n },\n });\n\n // Remove customFields from fields array after handling\n fields!.splice(customFieldsIdx, 1);\n }\n};\n\n/**\n * Hook to enable individual hooks for bulk create operations\n */\nexport const beforeBulkCreate = (options: BulkCreateOptions): void => {\n // This will activate the beforeCreate hook on each instance\n options.individualHooks = true;\n};\n\n/**\n * Hook to enable individual hooks for bulk update operations\n */\nexport const beforeBulkUpdate = (options: UpdateOptions): void => {\n // This will activate the beforeUpdate hook on each instance\n options.individualHooks = true;\n};\n"],"mappings":"6jBAmBA,MAAM,EAAsC,CAAC,KAAM,SAAU,YAAa,WAAY,WAAW,CAG3F,EAAM,IAAI,EAAI,CAClB,UAAW,GACX,OAAQ,GACR,YAAa,GACb,MAAO,GACR,CAAC,CAEF,EAAW,EAAI,CACf,EAAU,EAAI,CAMd,MAAM,GAAoB,EAAgC,KACvD,CAAE,UAAW,KAAM,GAAG,EAAW,GAAG,EAAiB,EAMlD,EAA0B,MAAO,EAAe,IAA2D,CAE/G,GAAI,CAAC,EAAS,IAAM,CAAC,EAAS,cAAgB,OAAO,KAAK,EAAS,aAAa,CAAC,SAAW,EAC1F,OAAO,EAAS,cAAgB,EAAE,CAGpC,GAAI,CAGF,IAAM,EAAsB,MAFT,EAAS,YAEiB,QAAQ,CACnD,MAAO,CAAE,GAAI,EAAS,GAAI,CAC1B,WAAY,CAAC,eAAe,CAC5B,YAAa,EAAQ,YACrB,IAAK,GACN,CAAC,CAEF,GAAI,GAAqB,aAAc,CAErC,IAAM,EAAiB,EACrB,EAAoB,aACpB,EAAS,aACV,CAOD,OALA,EAAO,MAAM,wDAAyD,CACpE,YAAa,OAAO,KAAK,EAAe,CAAC,OACzC,kBAAmB,OAAO,KAAK,EAAS,aAAa,CAAC,OACvD,CAAC,CAEK,SAEF,EAAO,CACd,EAAO,MAAM,uDAAwD,CAAE,QAAO,CAAC,CAIjF,OAAO,EAAS,cAAgB,EAAE,EAG9B,EAAuB,GAAkB,CAC7C,IAAMA,EAAkB,CAAE,GAAG,EAAS,WAAY,EAEpB,EAAS,WAAW,EAAI,EAAE,EAC5C,QAAS,GAAQ,CAC3B,IAAM,EAAU,EAAS,WAAW,EAAI,CACpC,IAAY,IAAA,KACd,EAAW,GAAO,IAEpB,CAEF,IAAM,EAAS,EAAS,WAAW,eAAe,CAKlD,OAJI,IAAW,IAAA,KACb,EAAW,aAAe,GAGrB,GAGH,EACJ,GAM2B,EAAO,QAAQ,EAAK,IAAQ,CAQvD,IAAM,IAPY,EAAI,cAAgB,IACnC,MAAM,IAAI,CACV,OAAO,QAAQ,CACf,KAAK,IAAI,CACT,QAAQ,WAAY,GAAG,EAEN,EAAI,UAAY,WAAa,IAAI,EAAI,QAAQ,kBAAoB,KAChD,QAAQ,MAAO,GAAG,EAAI,OAK3D,MAFA,GAAI,GADY,EAAI,SAAW,gBAGxB,GACN,EAAE,CAA2B,CAK1B,EAAgB,MACpB,EACA,EACA,EACA,EAA6B,EAAE,CAC/B,EAAW,KACO,CAClB,IAAM,EAAY,EAAS,YAAY,KAEvC,EAAO,MAAM,2BAA4B,CAAE,WAAU,YAAW,CAAC,CACjE,IAAM,EAAcC,EAAqB,EAAU,EAAgB,CAKnE,GAHA,EAAO,MAAM,sBAAuB,CAAE,cAAa,CAAC,CAGhD,CAAC,GAAe,OAAO,KAAK,EAAY,CAAC,SAAW,EAAG,CACzD,EAAO,MAAM,8CAA8C,CAC3D,OAIF,IAAM,EAAW,OAAO,OAAO,EAAY,CAAC,GAI5C,GAFA,EAAO,MAAM,mBAAoB,CAAE,WAAU,CAAC,CAE1C,CAAC,EAAU,CACb,EAAO,MAAM,2CAA2C,CACxD,OAGF,IAAI,EACAC,EACA,EAAQ,cACV,EAAQ,YAAY,mBAAqB,IAAI,IAC7C,EAAW,GAAG,EAAU,GAAG,IAC3B,EAAoB,EAAQ,YAAY,iBAAiB,IAAI,EAAS,EAGnE,IACH,EAAoBC,EAClB,EACA,EACA,CACE,YAAa,EAAQ,YACrB,WAAY,EACZ,eACD,CACF,CACG,EAAQ,aACV,GAAS,aAAa,iBAAkB,IAAI,EAAW,EAAkB,EAG7E,IAAM,EAAa,MAAM,EAIzB,GAFA,EAAO,MAAM,2BAA4B,CAAE,MAAO,EAAW,OAAQ,CAAC,CAElE,CAAC,EAAW,OAAQ,CACtB,EAAO,MAAM,mDAAmD,CAChE,OAIF,IAAI,EAAiB,KAChB,IACH,EAAiB,EAAoB,EAAS,EAKhD,IAAM,EAAwB,EAE1B,EAAS,cAAgB,EAAE,CAD3B,MAAM,EAAwB,EAAU,EAAQ,CAGpD,IAAK,IAAM,KAAa,EAAY,CAClC,GAAM,CAAE,UAAW,EACb,EAAc,EAQpB,GANA,EAAO,MAAM,iCAAkC,CAC7C,SACA,cAAe,CAAC,CAAC,EAAY,YAAY,MACzC,eAAgB,CAAC,CAAC,EAAY,YAAY,OAC3C,CAAC,CAEE,MAEE,EAAY,YAAY,MAAO,CACjC,IAAM,EAAiB,EAAI,QAAQ,CACjC,GAAG,EAEH,WAAY,CACV,MAAO,EAAY,WAAW,MAC/B,CACF,CAAC,CASF,GAAI,CAPY,EAAe,KAAK,MAAM,KAAK,UAAU,CACvD,MAAO,CACL,GAAG,EAAS,WACZ,aAAc,EACf,CACF,CAAC,CAAC,CAAC,CAEU,CACZ,IAAM,EAAe,EAAe,QAAQ,IAAI,GAC9C,GAAI,EAAY,cAAgB,GAAG,GAAI,EAAY,SAAW,kBAAkB,CAAC,KAAK,KAAK,CAEvF,EAAkB,EAAgB,EAAe,OAAQ,CAC/D,MAAM,IAAI,EACR,CAAK,MAAM,yBAAyB,EAAU,IAAI,IAAe,CAAC,CAClE,IAAA,GACA,CACE,YAAa,EACd,CACF,OAGA,CAEL,IAAM,EAAiB,EAAI,QAAQ,EAAY,CAGzC,EAAW,EAAiB,EAAS,WAAW,CAGtD,EAAS,aAAe,EAGxB,IAAM,EAAU,CACd,OAAQ,EACR,MAAO,EACR,CAGK,EAAU,EAAe,KAAK,MAAM,KAAK,UAAU,EAAQ,CAAC,CAAC,CAUnE,GARA,EAAO,MAAM,4BAA6B,CACxC,UACA,KAAM,CACJ,OAAQ,EACR,MAAO,EACR,CACF,CAAC,CAEE,CAAC,EAAS,CACZ,IAAM,EAAe,EAClB,QACC,IAAI,GAAO,GAAI,EAAY,cAAgB,GAAG,GAAI,EAAY,SAAW,kBAAkB,CAAC,KAAK,KAAK,CAEpG,EAAkB,EAAgB,EAAe,OAAQ,CAC/D,MAAM,IAAI,EACR,CAAK,MAAM,yBAAyB,EAAU,IAAI,IAAe,CAAC,CAClE,IAAA,GACA,CACE,YAAa,EACd,CACF,KAMH,EAAsB,MAAO,CACjC,YACA,eACA,cACA,UACA,WACA,eAQI,CACJ,GAAM,CAAE,UAAS,0BAA2B,EAyB5C,OAtBI,GAAa,GAAU,OAClBC,EAAiC,EAAS,OAAQ,CACvD,aAAc,GACd,YAAa,EAAQ,YACrB,UAAW,EACX,YACA,eACD,CAAC,CAUqB,MAAME,EANH,CAC1B,YACA,SAAU,GACV,GAAI,CAAC,GAA0B,CAAE,SAAU,EAAa,CACzD,CAE4D,CAC3D,aAAc,GACd,YAAa,EAAQ,YACrB,QAAS,IAAU,EAAY,CAChC,CAAC,EAIE,GAAe,EAA2C,IAAkB,EAC/E,GAAoB,EAAE,EAAE,QAAS,GAAoB,CACpD,GAAM,CAAE,YAAW,QAAS,EAC5B,GAAI,CAAC,EAA0B,KAAM,EAA0B,SAAS,CAAC,SAAS,EAAU,CAAE,CAC5F,IAAM,EAAQ,EAAS,eAAe,GACtC,GAAI,EAAO,CACT,GAAM,CAAE,MAAO,EAAU,MAAO,GAAoB,EAAI,MAAM,CAAC,SAAS,EAAM,CAC9E,GAAI,EACF,MAAM,IAAI,EAAkB,EAAO,EAAM,EAAgB,CAE3D,EAAS,aAAa,GAAQ,EAAS,aAAa,IAGxD,EAMS,GACX,EACA,EAA6B,EAAE,CAC/B,EAA6G,CAC3G,uBAAwB,GACzB,GACE,MACH,EACA,IACkB,CAClB,EAAO,MAAM,6BAA6B,CAC1C,GAAM,CAAE,UAAW,EACb,EAAY,EAAS,YAAY,KAEjC,EAAcL,EAAqB,EAAU,EAAgB,CAI7D,EAAmB,MAAM,EAAoB,CACjD,YAAW,eAAc,cAAa,UAAS,WAAU,UAAW,EAAa,UAClF,CAAC,CAGI,EAAyB,EAAiB,OAAO,GAAO,CAAC,CAAC,KAAM,IAAA,GAAU,CAAC,SAAS,EAAI,aAAa,CAAC,CACxG,EAAuB,SACzB,EAAS,eAAiB,EAAE,CAC5B,EACG,OAAO,GAAQ,EAAS,eAAe,EAAI,QAAU,IAAA,GAAW,CAChE,SAAS,CAAE,OAAM,kBAAmB,CACnC,EAAS,aAAa,GAAQ,GAC9B,EAIN,IAAIM,EAEJ,AAOE,EAPE,EAAa,wBAEO,MAAM,QAAQ,QAClC,EAAa,wBAAwB,EAAU,EAAkB,EAAQ,CAC1E,CAGqB,MAAM,KAC1B,IAAI,IAAI,EAAiB,QAAQ,CAAE,cAAe,EAAS,CAAC,KAAK,CAAE,UAAW,EAAK,CAAC,CACrF,CAGH,GAAM,CAAE,gBAAiB,EACnB,EAAc,OAAO,KAAK,GAAgB,EAAE,CAAC,CAC7C,EAAgB,EAAoB,OAAO,GAAQ,CAAC,EAAY,SAAS,EAAK,CAAC,CACrF,GAAI,GAAe,OACjB,MAAM,IAAI,EAAgC,EAAc,CAI1D,MAAM,EAAc,EAAU,EAA+B,EAAiB,EAAc,GAAK,CAGjG,EAAY,EAAkB,EAAS,CAGvC,IAAM,EAAkB,EAAQ,QAAQ,eAAe,CACnD,IAAoB,IAAM,CAAC,GAAgB,CAAC,OAAO,KAAK,EAAa,CAAC,SAM1E,MAAMC,EAAqB,CACzB,QAAS,EAAS,GAClB,YACA,cACA,eACA,QAAS,CACP,uBAAwB,EAAa,uBACrC,YAAa,EAAQ,YACrB,eACD,CACF,CAAC,CAGF,EAAQ,OAAO,EAAiB,EAAE,GAMvB,GACX,EACA,EAA6B,EAAE,CAC/B,EAA6G,CAC3G,uBAAwB,GACzB,GACE,MACH,EACA,IACkB,CAClB,EAAO,MAAM,6BAA6B,CAC1C,GAAM,CAAE,UAAW,EACb,EAAY,EAAS,YAAY,KACjC,EAAcP,EAAqB,EAAU,EAAgB,CAE7D,EAAmB,MAAM,EAAoB,CACjD,YAAW,eAAc,cAAa,UAAS,WAAU,UAAW,EAAa,UAClF,CAAC,CAGF,MAAM,EAAc,EAAU,EAA+B,EAAiB,EAAc,GAAM,CAGlG,EAAY,EAAkB,EAAS,CAGvC,IAAM,EAAkB,EAAQ,QAAQ,eAAe,CACvD,GAAI,EAAkB,GAAI,CACxB,GAAM,CAAE,gBAAiB,EAEzB,GAAI,CAAC,OAAO,KAAK,EAAa,CAAC,OAC7B,OAIF,MAAMO,EAAqB,CACzB,QAAS,EAAS,GAClB,YACA,cACA,eACA,QAAS,CACP,uBAAwB,EAAa,uBACrC,YAAa,EAAQ,YACrB,eACD,CACF,CAAC,CAGF,EAAQ,OAAO,EAAiB,EAAE,GAOzB,EAAoB,GAAqC,CAEpE,EAAQ,gBAAkB,IAMf,EAAoB,GAAiC,CAEhE,EAAQ,gBAAkB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`../_virtual/rolldown_runtime.cjs`),t=require(`../utils/logger/index.cjs`),n=require(`../utils/constants/index.cjs`),r=require(`../utils/validations/validators/index.cjs`),i=require(`../events/index.cjs`),a=require(`../errors/index.cjs`),o=require(`../utils/validations/index.cjs`),s=require(`../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.cjs`),c=require(`../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.cjs`),l=require(`./CustomFieldValue.cjs`);let u=require(`sequelize-typescript`);var d,f,p,m,h,g;let _=class extends u.Model{get modelTypeIds(){return this._modelTypeIds}set modelTypeIds(e){this._modelTypeIds=e,this.setDataValue(`modelTypeIds`,e)}static displayNameDefaultValue(e){if(e?.displayName||(e.displayName=e.name),![null,void 0].includes(e.defaultValue)){let t=o.validateValue(e.defaultValue,e.fieldType,e.validation);if(t.error)throw new a.InvalidValueError(e.defaultValue,e.name,t.error)}}static afterSaveHandler(e,t){t.transaction?t.transaction.afterCommit(()=>i.sendDimEvent(e)):i.sendDimEvent(e)}};c.__decorate([u.PrimaryKey,(0,u.Column)({type:u.DataType.UUID,defaultValue:u.DataType.UUIDV4,allowNull:!1}),s.__decorateMetadata(`design:type`,String)],_.prototype,`id`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.STRING,allowNull:!1}),s.__decorateMetadata(`design:type`,String)],_.prototype,`name`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.STRING}),s.__decorateMetadata(`design:type`,String)],_.prototype,`displayName`,void 0),c.__decorate([(0,u.Is)(`SupportedType`,e=>{if(!Object.values(n.CustomFieldDefinitionType).includes(e))throw new a.UnsupportedCustomFieldTypeError(`"${e}" is not a supported type.`)}),(0,u.Column)({type:u.DataType.STRING,allowNull:!1}),s.__decorateMetadata(`design:type`,typeof(d=n.CustomFieldDefinitionType!==void 0&&n.CustomFieldDefinitionType)==`function`?d:Object)],_.prototype,`fieldType`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.JSONB}),s.__decorateMetadata(`design:type`,Object)],_.prototype,`validation`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.UUID,allowNull:!1}),s.__decorateMetadata(`design:type`,String)],_.prototype,`entityId`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.STRING,allowNull:!1}),s.__decorateMetadata(`design:type`,String)],_.prototype,`entityType`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.STRING,allowNull:!1}),s.__decorateMetadata(`design:type`,String)],_.prototype,`modelType`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.TEXT}),s.__decorateMetadata(`design:type`,String)],_.prototype,`description`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.BOOLEAN,defaultValue:!1}),s.__decorateMetadata(`design:type`,Boolean)],_.prototype,`required`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.BOOLEAN,defaultValue:!1}),s.__decorateMetadata(`design:type`,Boolean)],_.prototype,`disabled`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.JSONB,allowNull:!0}),s.__decorateMetadata(`design:type`,Object)],_.prototype,`defaultValue`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.DATE,allowNull:!1}),s.__decorateMetadata(`design:type`,typeof(f=typeof Date<`u`&&Date)==`function`?f:Object)],_.prototype,`createdAt`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.DATE,allowNull:!0}),s.__decorateMetadata(`design:type`,typeof(p=typeof Date<`u`&&Date)==`function`?p:Object)],_.prototype,`updatedAt`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.DATE,allowNull:!0}),s.__decorateMetadata(`design:type`,typeof(m=typeof Date<`u`&&Date)==`function`?m:Object)],_.prototype,`deletedAt`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.BOOLEAN,defaultValue:!1,allowNull:!1}),s.__decorateMetadata(`design:type`,Boolean)],_.prototype,`blockEditingFromUI`,void 0),c.__decorate([(0,u.HasMany)(()=>l.default),s.__decorateMetadata(`design:type`,Array)],_.prototype,`values`,void 0),c.__decorate([u.BeforeCreate,s.__decorateMetadata(`design:type`,Function),s.__decorateMetadata(`design:paramtypes`,[typeof(h=_!==void 0&&_)==`function`?h:Object]),s.__decorateMetadata(`design:returntype`,void 0)],_,`displayNameDefaultValue`,null),c.__decorate([u.AfterSave,s.__decorateMetadata(`design:type`,Function),s.__decorateMetadata(`design:paramtypes`,[typeof(g=_!==void 0&&_)==`function`?g:Object,Object]),s.__decorateMetadata(`design:returntype`,void 0)],_,`afterSaveHandler`,null),_=c.__decorate([(0,u.DefaultScope)(()=>({where:{disabled:!1}})),(0,u.Table)({tableName:`custom_field_definitions`,modelName:`CustomFieldDefinition`,indexes:[{name:`unique_name_model_type`,fields:[`model_type`,`entity_id`,`name`],unique:!0}],timestamps:!0,validate:{validationByType(){if(!this.validation&&r.CustomValidationTypes[this.fieldType])throw t.default.error(`No custom validation for custom field type ${this.fieldType} found`),new a.UnsupportedCustomValidationError(`Validation provided for "${this.fieldType}" is not supported`)}}})],_);var v=_;exports.default=v;
|
|
1
|
+
const e=require(`../_virtual/rolldown_runtime.cjs`),t=require(`../utils/logger/index.cjs`),n=require(`../utils/constants/index.cjs`),r=require(`../utils/validations/validators/index.cjs`),i=require(`../events/index.cjs`),a=require(`../errors/index.cjs`),o=require(`../utils/validations/index.cjs`),s=require(`../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.cjs`),c=require(`../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.cjs`),l=require(`./CustomFieldValue.cjs`);let u=require(`sequelize-typescript`);var d,f,p,m,h,g;let _=class extends u.Model{get modelTypeIds(){return this._modelTypeIds}set modelTypeIds(e){this._modelTypeIds=e,this.setDataValue(`modelTypeIds`,e)}static displayNameDefaultValue(e){if(e?.displayName||(e.displayName=e.name),![null,void 0].includes(e.defaultValue)){let t=o.validateValue(e.defaultValue,e.fieldType,e.validation);if(t.error)throw new a.InvalidValueError(e.defaultValue,e.name,t.error)}}static afterSaveHandler(e,t){t.transaction?t.transaction.afterCommit(()=>i.sendDimEvent(e)):i.sendDimEvent(e)}toJSON(){let e={...this.get()};return delete e.modelTypeMappings,e}};c.__decorate([u.PrimaryKey,(0,u.Column)({type:u.DataType.UUID,defaultValue:u.DataType.UUIDV4,allowNull:!1}),s.__decorateMetadata(`design:type`,String)],_.prototype,`id`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.STRING,allowNull:!1}),s.__decorateMetadata(`design:type`,String)],_.prototype,`name`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.STRING}),s.__decorateMetadata(`design:type`,String)],_.prototype,`displayName`,void 0),c.__decorate([(0,u.Is)(`SupportedType`,e=>{if(!Object.values(n.CustomFieldDefinitionType).includes(e))throw new a.UnsupportedCustomFieldTypeError(`"${e}" is not a supported type.`)}),(0,u.Column)({type:u.DataType.STRING,allowNull:!1}),s.__decorateMetadata(`design:type`,typeof(d=n.CustomFieldDefinitionType!==void 0&&n.CustomFieldDefinitionType)==`function`?d:Object)],_.prototype,`fieldType`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.JSONB}),s.__decorateMetadata(`design:type`,Object)],_.prototype,`validation`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.UUID,allowNull:!1}),s.__decorateMetadata(`design:type`,String)],_.prototype,`entityId`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.STRING,allowNull:!1}),s.__decorateMetadata(`design:type`,String)],_.prototype,`entityType`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.STRING,allowNull:!1}),s.__decorateMetadata(`design:type`,String)],_.prototype,`modelType`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.TEXT}),s.__decorateMetadata(`design:type`,String)],_.prototype,`description`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.BOOLEAN,defaultValue:!1}),s.__decorateMetadata(`design:type`,Boolean)],_.prototype,`required`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.BOOLEAN,defaultValue:!1}),s.__decorateMetadata(`design:type`,Boolean)],_.prototype,`disabled`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.JSONB,allowNull:!0}),s.__decorateMetadata(`design:type`,Object)],_.prototype,`defaultValue`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.DATE,allowNull:!1}),s.__decorateMetadata(`design:type`,typeof(f=typeof Date<`u`&&Date)==`function`?f:Object)],_.prototype,`createdAt`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.DATE,allowNull:!0}),s.__decorateMetadata(`design:type`,typeof(p=typeof Date<`u`&&Date)==`function`?p:Object)],_.prototype,`updatedAt`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.DATE,allowNull:!0}),s.__decorateMetadata(`design:type`,typeof(m=typeof Date<`u`&&Date)==`function`?m:Object)],_.prototype,`deletedAt`,void 0),c.__decorate([(0,u.Column)({type:u.DataType.BOOLEAN,defaultValue:!1,allowNull:!1}),s.__decorateMetadata(`design:type`,Boolean)],_.prototype,`blockEditingFromUI`,void 0),c.__decorate([(0,u.HasMany)(()=>l.default),s.__decorateMetadata(`design:type`,Array)],_.prototype,`values`,void 0),c.__decorate([u.BeforeCreate,s.__decorateMetadata(`design:type`,Function),s.__decorateMetadata(`design:paramtypes`,[typeof(h=_!==void 0&&_)==`function`?h:Object]),s.__decorateMetadata(`design:returntype`,void 0)],_,`displayNameDefaultValue`,null),c.__decorate([u.AfterSave,s.__decorateMetadata(`design:type`,Function),s.__decorateMetadata(`design:paramtypes`,[typeof(g=_!==void 0&&_)==`function`?g:Object,Object]),s.__decorateMetadata(`design:returntype`,void 0)],_,`afterSaveHandler`,null),_=c.__decorate([(0,u.DefaultScope)(()=>({where:{disabled:!1}})),(0,u.Table)({tableName:`custom_field_definitions`,modelName:`CustomFieldDefinition`,indexes:[{name:`unique_name_model_type`,fields:[`model_type`,`entity_id`,`name`],unique:!0}],timestamps:!0,validate:{validationByType(){if(!this.validation&&r.CustomValidationTypes[this.fieldType])throw t.default.error(`No custom validation for custom field type ${this.fieldType} found`),new a.UnsupportedCustomValidationError(`Validation provided for "${this.fieldType}" is not supported`)}}})],_);var v=_;exports.default=v;
|
|
2
2
|
//# sourceMappingURL=CustomFieldDefinition.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomFieldDefinition.cjs","names":["CustomFieldDefinition","Model","validateValue","InvalidValueError","sendDimEvent","PrimaryKey","DataType","CustomFieldDefinitionType","UnsupportedCustomFieldTypeError","CustomFieldValue","BeforeCreate","AfterSave","CustomValidationTypes","UnsupportedCustomValidationError"],"sources":["../../src/models/CustomFieldDefinition.ts"],"sourcesContent":["import {\n Table,\n Column,\n Model,\n DataType,\n HasMany,\n PrimaryKey,\n BeforeCreate,\n DefaultScope,\n AfterSave,\n Is,\n} from 'sequelize-typescript';\nimport type { CreateOptions } from 'sequelize';\nimport { CustomFieldDefinitionType } from '../utils/constants';\nimport { CustomValidationTypes } from '../utils/validations/validators';\nimport CustomFieldValue from './CustomFieldValue';\nimport CustomFieldModelTypeMap from './CustomFieldModelTypeMap';\nimport { sendDimEvent } from '../events';\nimport { InvalidValueError, UnsupportedCustomFieldTypeError, UnsupportedCustomValidationError } from '../errors';\nimport logger from '../utils/logger';\nimport { validateValue } from '../utils/validations';\n\n@DefaultScope(() => ({ where: { disabled: false } }))\n@Table({\n tableName: 'custom_field_definitions',\n modelName: 'CustomFieldDefinition',\n indexes: [\n {\n name: 'unique_name_model_type',\n fields: ['model_type', 'entity_id', 'name'],\n unique: true,\n },\n ],\n timestamps: true,\n validate: {\n validationByType(this: CustomFieldDefinition) {\n // Verify the validation is provided if needed\n if (!this.validation && CustomValidationTypes[this.fieldType as keyof typeof CustomValidationTypes]) {\n // TODO: enforce the validation-object schema based on the fieldType\n logger.error(`No custom validation for custom field type ${this.fieldType} found`);\n throw new UnsupportedCustomValidationError(`Validation provided for \"${this.fieldType}\" is not supported`);\n }\n },\n },\n})\nclass CustomFieldDefinition extends Model {\n @PrimaryKey\n @Column({\n type: DataType.UUID,\n defaultValue: DataType.UUIDV4,\n allowNull: false,\n })\n declare id: string;\n\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n name!: string;\n\n @Column({\n type: DataType.STRING,\n })\n displayName?: string; // Defaulted to name with beforeCreate hook\n\n @Is('SupportedType', (value) => {\n if (!Object.values(CustomFieldDefinitionType).includes(value as CustomFieldDefinitionType)) {\n throw new UnsupportedCustomFieldTypeError(`\"${value}\" is not a supported type.`);\n }\n })\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n fieldType!: CustomFieldDefinitionType;\n\n @Column({\n type: DataType.JSONB,\n })\n validation?: any;\n\n @Column({\n type: DataType.UUID,\n allowNull: false,\n })\n entityId!: string; /** Client association entity id */\n\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n entityType!: string; /** Client association entity type (demand source / fleet / etc.) */\n\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n modelType!: string; /** Model type. e.g. Vehicle / StopPoint / etc. */\n\n @Column({\n type: DataType.TEXT,\n })\n description?: string;\n\n @Column({\n type: DataType.BOOLEAN,\n defaultValue: false,\n })\n required?: boolean;\n\n @Column({\n type: DataType.BOOLEAN,\n defaultValue: false,\n })\n disabled?: boolean;\n\n @Column({\n type: DataType.JSONB,\n allowNull: true,\n })\n defaultValue?: any;\n\n @Column({\n type: DataType.DATE,\n allowNull: false,\n })\n declare createdAt?: Date;\n\n @Column({\n type: DataType.DATE,\n allowNull: true,\n })\n declare updatedAt?: Date;\n\n @Column({\n type: DataType.DATE,\n allowNull: true,\n })\n declare deletedAt?: Date;\n\n @Column({\n type: DataType.BOOLEAN,\n defaultValue: false,\n allowNull: false,\n })\n blockEditingFromUI!: boolean;\n\n @HasMany(() => CustomFieldValue)\n declare values: CustomFieldValue[];\n\n // Association added programmatically when useModelTypeMapping is enabled\n declare modelTypeMappings?: CustomFieldModelTypeMap[];\n\n // Virtual property for modelTypeIds - set manually after fetch\n private _modelTypeIds?: string[];\n\n get modelTypeIds(): string[] | undefined {\n return this._modelTypeIds;\n }\n\n set modelTypeIds(value: string[] | undefined) {\n this._modelTypeIds = value;\n this.setDataValue('modelTypeIds', value);\n }\n\n @BeforeCreate\n static displayNameDefaultValue(instance: CustomFieldDefinition): void {\n if (!instance?.displayName) {\n instance.displayName = instance.name;\n }\n if (![null, undefined].includes(instance.defaultValue)) {\n const isValid = validateValue(instance.defaultValue, instance.fieldType, instance.validation);\n if (isValid.error) {\n throw new InvalidValueError(instance.defaultValue, instance.name, isValid.error);\n }\n }\n }\n\n @AfterSave\n static afterSaveHandler(instance: CustomFieldDefinition, options: CreateOptions): void {\n if (options.transaction) {\n options.transaction.afterCommit(() => sendDimEvent(instance));\n } else {\n sendDimEvent(instance);\n }\n }\n}\n\nexport default CustomFieldDefinition;\n"],"mappings":"oiBAsBA,IAAA,EAAA,cAuBoCC,EAAAA,KAAM,CA+GxC,IAAI,cAAqC,CACvC,OAAO,KAAK,cAGd,IAAI,aAAa,EAA6B,CAC5C,KAAK,cAAgB,EACrB,KAAK,aAAa,eAAgB,EAAM,CAG1C,OACO,wBAAwB,EAAuC,CAIpE,GAHK,GAAU,cACb,EAAS,YAAc,EAAS,MAE9B,CAAC,CAAC,KAAM,IAAA,GAAU,CAAC,SAAS,EAAS,aAAa,CAAE,CACtD,IAAM,EAAUC,EAAAA,cAAc,EAAS,aAAc,EAAS,UAAW,EAAS,WAAW,CAC7F,GAAI,EAAQ,MACV,MAAM,IAAIC,EAAAA,kBAAkB,EAAS,aAAc,EAAS,KAAM,EAAQ,MAAM,EAKtF,OACO,iBAAiB,EAAiC,EAA8B,CACjF,EAAQ,YACV,EAAQ,YAAY,gBAAkBC,EAAAA,aAAa,EAAS,CAAC,CAE7D,EAAA,aAAa,EAAS,
|
|
1
|
+
{"version":3,"file":"CustomFieldDefinition.cjs","names":["CustomFieldDefinition","Model","validateValue","InvalidValueError","sendDimEvent","PrimaryKey","DataType","CustomFieldDefinitionType","UnsupportedCustomFieldTypeError","CustomFieldValue","BeforeCreate","AfterSave","CustomValidationTypes","UnsupportedCustomValidationError"],"sources":["../../src/models/CustomFieldDefinition.ts"],"sourcesContent":["import {\n Table,\n Column,\n Model,\n DataType,\n HasMany,\n PrimaryKey,\n BeforeCreate,\n DefaultScope,\n AfterSave,\n Is,\n} from 'sequelize-typescript';\nimport type { CreateOptions } from 'sequelize';\nimport { CustomFieldDefinitionType } from '../utils/constants';\nimport { CustomValidationTypes } from '../utils/validations/validators';\nimport CustomFieldValue from './CustomFieldValue';\nimport CustomFieldModelTypeMap from './CustomFieldModelTypeMap';\nimport { sendDimEvent } from '../events';\nimport { InvalidValueError, UnsupportedCustomFieldTypeError, UnsupportedCustomValidationError } from '../errors';\nimport logger from '../utils/logger';\nimport { validateValue } from '../utils/validations';\n\n@DefaultScope(() => ({ where: { disabled: false } }))\n@Table({\n tableName: 'custom_field_definitions',\n modelName: 'CustomFieldDefinition',\n indexes: [\n {\n name: 'unique_name_model_type',\n fields: ['model_type', 'entity_id', 'name'],\n unique: true,\n },\n ],\n timestamps: true,\n validate: {\n validationByType(this: CustomFieldDefinition) {\n // Verify the validation is provided if needed\n if (!this.validation && CustomValidationTypes[this.fieldType as keyof typeof CustomValidationTypes]) {\n // TODO: enforce the validation-object schema based on the fieldType\n logger.error(`No custom validation for custom field type ${this.fieldType} found`);\n throw new UnsupportedCustomValidationError(`Validation provided for \"${this.fieldType}\" is not supported`);\n }\n },\n },\n})\nclass CustomFieldDefinition extends Model {\n @PrimaryKey\n @Column({\n type: DataType.UUID,\n defaultValue: DataType.UUIDV4,\n allowNull: false,\n })\n declare id: string;\n\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n name!: string;\n\n @Column({\n type: DataType.STRING,\n })\n displayName?: string; // Defaulted to name with beforeCreate hook\n\n @Is('SupportedType', (value) => {\n if (!Object.values(CustomFieldDefinitionType).includes(value as CustomFieldDefinitionType)) {\n throw new UnsupportedCustomFieldTypeError(`\"${value}\" is not a supported type.`);\n }\n })\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n fieldType!: CustomFieldDefinitionType;\n\n @Column({\n type: DataType.JSONB,\n })\n validation?: any;\n\n @Column({\n type: DataType.UUID,\n allowNull: false,\n })\n entityId!: string; /** Client association entity id */\n\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n entityType!: string; /** Client association entity type (demand source / fleet / etc.) */\n\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n modelType!: string; /** Model type. e.g. Vehicle / StopPoint / etc. */\n\n @Column({\n type: DataType.TEXT,\n })\n description?: string;\n\n @Column({\n type: DataType.BOOLEAN,\n defaultValue: false,\n })\n required?: boolean;\n\n @Column({\n type: DataType.BOOLEAN,\n defaultValue: false,\n })\n disabled?: boolean;\n\n @Column({\n type: DataType.JSONB,\n allowNull: true,\n })\n defaultValue?: any;\n\n @Column({\n type: DataType.DATE,\n allowNull: false,\n })\n declare createdAt?: Date;\n\n @Column({\n type: DataType.DATE,\n allowNull: true,\n })\n declare updatedAt?: Date;\n\n @Column({\n type: DataType.DATE,\n allowNull: true,\n })\n declare deletedAt?: Date;\n\n @Column({\n type: DataType.BOOLEAN,\n defaultValue: false,\n allowNull: false,\n })\n blockEditingFromUI!: boolean;\n\n @HasMany(() => CustomFieldValue)\n declare values: CustomFieldValue[];\n\n // Association added programmatically when useModelTypeMapping is enabled\n declare modelTypeMappings?: CustomFieldModelTypeMap[];\n\n // Virtual property for modelTypeIds - set manually after fetch\n private _modelTypeIds?: string[];\n\n get modelTypeIds(): string[] | undefined {\n return this._modelTypeIds;\n }\n\n set modelTypeIds(value: string[] | undefined) {\n this._modelTypeIds = value;\n this.setDataValue('modelTypeIds', value);\n }\n\n @BeforeCreate\n static displayNameDefaultValue(instance: CustomFieldDefinition): void {\n if (!instance?.displayName) {\n instance.displayName = instance.name;\n }\n if (![null, undefined].includes(instance.defaultValue)) {\n const isValid = validateValue(instance.defaultValue, instance.fieldType, instance.validation);\n if (isValid.error) {\n throw new InvalidValueError(instance.defaultValue, instance.name, isValid.error);\n }\n }\n }\n\n @AfterSave\n static afterSaveHandler(instance: CustomFieldDefinition, options: CreateOptions): void {\n if (options.transaction) {\n options.transaction.afterCommit(() => sendDimEvent(instance));\n } else {\n sendDimEvent(instance);\n }\n }\n\n /**\n * Override toJSON to exclude internal associations from API responses\n * The modelTypeMappings association is used internally to optimize queries\n * but should not be exposed in the API response (use modelTypeIds instead)\n */\n toJSON(): object {\n const values = { ...this.get() };\n // Remove the internal association used for query optimization\n delete values.modelTypeMappings;\n return values;\n }\n}\n\nexport default CustomFieldDefinition;\n"],"mappings":"oiBAsBA,IAAA,EAAA,cAuBoCC,EAAAA,KAAM,CA+GxC,IAAI,cAAqC,CACvC,OAAO,KAAK,cAGd,IAAI,aAAa,EAA6B,CAC5C,KAAK,cAAgB,EACrB,KAAK,aAAa,eAAgB,EAAM,CAG1C,OACO,wBAAwB,EAAuC,CAIpE,GAHK,GAAU,cACb,EAAS,YAAc,EAAS,MAE9B,CAAC,CAAC,KAAM,IAAA,GAAU,CAAC,SAAS,EAAS,aAAa,CAAE,CACtD,IAAM,EAAUC,EAAAA,cAAc,EAAS,aAAc,EAAS,UAAW,EAAS,WAAW,CAC7F,GAAI,EAAQ,MACV,MAAM,IAAIC,EAAAA,kBAAkB,EAAS,aAAc,EAAS,KAAM,EAAQ,MAAM,EAKtF,OACO,iBAAiB,EAAiC,EAA8B,CACjF,EAAQ,YACV,EAAQ,YAAY,gBAAkBC,EAAAA,aAAa,EAAS,CAAC,CAE7D,EAAA,aAAa,EAAS,CAS1B,QAAiB,CACf,IAAM,EAAS,CAAE,GAAG,KAAK,KAAK,CAAE,CAGhC,OADA,OAAO,EAAO,kBACP,kBAtJRC,EAAAA,wBACO,CACN,KAAMC,EAAAA,SAAS,KACf,aAAcA,EAAAA,SAAS,OACvB,UAAW,GACZ,CAAC,iGAGM,CACN,KAAMA,EAAAA,SAAS,OACf,UAAW,GACZ,CAAC,CAAA,EAAA,mBAAA,cAAA,OAAA,CAAA,CAAA,EAAA,UAAA,OAAA,IAAA,GAAA,4BAGM,CACN,KAAMA,EAAAA,SAAS,OAChB,CAAC,CAAA,EAAA,mBAAA,cAAA,OAAA,CAAA,CAAA,EAAA,UAAA,cAAA,IAAA,GAAA,wBAGE,gBAAkB,GAAU,CAC9B,GAAI,CAAC,OAAO,OAAOC,EAAAA,0BAA0B,CAAC,SAAS,EAAmC,CACxF,MAAM,IAAIC,EAAAA,gCAAgC,IAAI,EAAM,4BAA4B,EAElF,cACM,CACN,KAAMF,EAAAA,SAAS,OACf,UAAW,GACZ,CAAC,kMAGM,CACN,KAAMA,EAAAA,SAAS,MAChB,CAAC,CAAA,EAAA,mBAAA,cAAA,OAAA,CAAA,CAAA,EAAA,UAAA,aAAA,IAAA,GAAA,4BAGM,CACN,KAAMA,EAAAA,SAAS,KACf,UAAW,GACZ,CAAC,CAAA,EAAA,mBAAA,cAAA,OAAA,CAAA,CAAA,EAAA,UAAA,WAAA,IAAA,GAAA,4BAGM,CACN,KAAMA,EAAAA,SAAS,OACf,UAAW,GACZ,CAAC,CAAA,EAAA,mBAAA,cAAA,OAAA,CAAA,CAAA,EAAA,UAAA,aAAA,IAAA,GAAA,4BAGM,CACN,KAAMA,EAAAA,SAAS,OACf,UAAW,GACZ,CAAC,CAAA,EAAA,mBAAA,cAAA,OAAA,CAAA,CAAA,EAAA,UAAA,YAAA,IAAA,GAAA,4BAGM,CACN,KAAMA,EAAAA,SAAS,KAChB,CAAC,CAAA,EAAA,mBAAA,cAAA,OAAA,CAAA,CAAA,EAAA,UAAA,cAAA,IAAA,GAAA,4BAGM,CACN,KAAMA,EAAAA,SAAS,QACf,aAAc,GACf,CAAC,CAAA,EAAA,mBAAA,cAAA,QAAA,CAAA,CAAA,EAAA,UAAA,WAAA,IAAA,GAAA,4BAGM,CACN,KAAMA,EAAAA,SAAS,QACf,aAAc,GACf,CAAC,CAAA,EAAA,mBAAA,cAAA,QAAA,CAAA,CAAA,EAAA,UAAA,WAAA,IAAA,GAAA,4BAGM,CACN,KAAMA,EAAAA,SAAS,MACf,UAAW,GACZ,CAAC,CAAA,EAAA,mBAAA,cAAA,OAAA,CAAA,CAAA,EAAA,UAAA,eAAA,IAAA,GAAA,4BAGM,CACN,KAAMA,EAAAA,SAAS,KACf,UAAW,GACZ,CAAC,CAAA,EAAA,mBAAA,cAAA,OAAA,EAAA,OAAA,KAAA,KAAA,OAAA,WAAA,EAAA,OAAA,CAAA,CAAA,EAAA,UAAA,YAAA,IAAA,GAAA,4BAGM,CACN,KAAMA,EAAAA,SAAS,KACf,UAAW,GACZ,CAAC,CAAA,EAAA,mBAAA,cAAA,OAAA,EAAA,OAAA,KAAA,KAAA,OAAA,WAAA,EAAA,OAAA,CAAA,CAAA,EAAA,UAAA,YAAA,IAAA,GAAA,4BAGM,CACN,KAAMA,EAAAA,SAAS,KACf,UAAW,GACZ,CAAC,CAAA,EAAA,mBAAA,cAAA,OAAA,EAAA,OAAA,KAAA,KAAA,OAAA,WAAA,EAAA,OAAA,CAAA,CAAA,EAAA,UAAA,YAAA,IAAA,GAAA,4BAGM,CACN,KAAMA,EAAAA,SAAS,QACf,aAAc,GACd,UAAW,GACZ,CAAC,CAAA,EAAA,mBAAA,cAAA,QAAA,CAAA,CAAA,EAAA,UAAA,qBAAA,IAAA,GAAA,iCAGaG,EAAAA,QAAiB,CAAA,EAAA,mBAAA,cAAA,MAAA,CAAA,CAAA,EAAA,UAAA,SAAA,IAAA,GAAA,eAkB/BC,EAAAA,qPAaAC,EAAAA,4QA5JkB,CAAE,MAAO,CAAE,SAAU,GAAO,CAAE,EAAE,EAAA,EAAA,EAAA,OAC9C,CACL,UAAW,2BACX,UAAW,wBACX,QAAS,CACP,CACE,KAAM,yBACN,OAAQ,CAAC,aAAc,YAAa,OAAO,CAC3C,OAAQ,GACT,CACF,CACD,WAAY,GACZ,SAAU,CACR,kBAA8C,CAE5C,GAAI,CAAC,KAAK,YAAcC,EAAAA,sBAAsB,KAAK,WAGjD,MADA,EAAA,QAAO,MAAM,8CAA8C,KAAK,UAAU,QAAQ,CAC5E,IAAIC,EAAAA,iCAAiC,4BAA4B,KAAK,UAAU,oBAAoB,EAG/G,CACF,CAAC,CAAA,CAAA,EAAA,CA4JF,IAAA,EAAe"}
|
|
@@ -29,6 +29,12 @@ declare class CustomFieldDefinition extends Model {
|
|
|
29
29
|
set modelTypeIds(value: string[] | undefined);
|
|
30
30
|
static displayNameDefaultValue(instance: CustomFieldDefinition): void;
|
|
31
31
|
static afterSaveHandler(instance: CustomFieldDefinition, options: CreateOptions): void;
|
|
32
|
+
/**
|
|
33
|
+
* Override toJSON to exclude internal associations from API responses
|
|
34
|
+
* The modelTypeMappings association is used internally to optimize queries
|
|
35
|
+
* but should not be exposed in the API response (use modelTypeIds instead)
|
|
36
|
+
*/
|
|
37
|
+
toJSON(): object;
|
|
32
38
|
}
|
|
33
39
|
//#endregion
|
|
34
40
|
export { CustomFieldDefinition };
|
|
@@ -29,6 +29,12 @@ declare class CustomFieldDefinition extends Model {
|
|
|
29
29
|
set modelTypeIds(value: string[] | undefined);
|
|
30
30
|
static displayNameDefaultValue(instance: CustomFieldDefinition): void;
|
|
31
31
|
static afterSaveHandler(instance: CustomFieldDefinition, options: CreateOptions): void;
|
|
32
|
+
/**
|
|
33
|
+
* Override toJSON to exclude internal associations from API responses
|
|
34
|
+
* The modelTypeMappings association is used internally to optimize queries
|
|
35
|
+
* but should not be exposed in the API response (use modelTypeIds instead)
|
|
36
|
+
*/
|
|
37
|
+
toJSON(): object;
|
|
32
38
|
}
|
|
33
39
|
//#endregion
|
|
34
40
|
export { CustomFieldDefinition };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"../utils/logger/index.js";import{CustomFieldDefinitionType as t}from"../utils/constants/index.js";import{CustomValidationTypes as n}from"../utils/validations/validators/index.js";import{sendDimEvent as r}from"../events/index.js";import{InvalidValueError as i,UnsupportedCustomFieldTypeError as a,UnsupportedCustomValidationError as o}from"../errors/index.js";import{validateValue as s}from"../utils/validations/index.js";import{__decorateMetadata as c}from"../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.js";import{__decorate as l}from"../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.js";import u from"./CustomFieldValue.js";import{AfterSave as d,BeforeCreate as f,Column as p,DataType as m,DefaultScope as h,HasMany as g,Is as _,Model as v,PrimaryKey as y,Table as b}from"sequelize-typescript";var x,S,C,w,T,E;let D=class extends v{get modelTypeIds(){return this._modelTypeIds}set modelTypeIds(e){this._modelTypeIds=e,this.setDataValue(`modelTypeIds`,e)}static displayNameDefaultValue(e){if(e?.displayName||(e.displayName=e.name),![null,void 0].includes(e.defaultValue)){let t=s(e.defaultValue,e.fieldType,e.validation);if(t.error)throw new i(e.defaultValue,e.name,t.error)}}static afterSaveHandler(e,t){t.transaction?t.transaction.afterCommit(()=>r(e)):r(e)}};l([y,p({type:m.UUID,defaultValue:m.UUIDV4,allowNull:!1}),c(`design:type`,String)],D.prototype,`id`,void 0),l([p({type:m.STRING,allowNull:!1}),c(`design:type`,String)],D.prototype,`name`,void 0),l([p({type:m.STRING}),c(`design:type`,String)],D.prototype,`displayName`,void 0),l([_(`SupportedType`,e=>{if(!Object.values(t).includes(e))throw new a(`"${e}" is not a supported type.`)}),p({type:m.STRING,allowNull:!1}),c(`design:type`,typeof(x=t!==void 0&&t)==`function`?x:Object)],D.prototype,`fieldType`,void 0),l([p({type:m.JSONB}),c(`design:type`,Object)],D.prototype,`validation`,void 0),l([p({type:m.UUID,allowNull:!1}),c(`design:type`,String)],D.prototype,`entityId`,void 0),l([p({type:m.STRING,allowNull:!1}),c(`design:type`,String)],D.prototype,`entityType`,void 0),l([p({type:m.STRING,allowNull:!1}),c(`design:type`,String)],D.prototype,`modelType`,void 0),l([p({type:m.TEXT}),c(`design:type`,String)],D.prototype,`description`,void 0),l([p({type:m.BOOLEAN,defaultValue:!1}),c(`design:type`,Boolean)],D.prototype,`required`,void 0),l([p({type:m.BOOLEAN,defaultValue:!1}),c(`design:type`,Boolean)],D.prototype,`disabled`,void 0),l([p({type:m.JSONB,allowNull:!0}),c(`design:type`,Object)],D.prototype,`defaultValue`,void 0),l([p({type:m.DATE,allowNull:!1}),c(`design:type`,typeof(S=typeof Date<`u`&&Date)==`function`?S:Object)],D.prototype,`createdAt`,void 0),l([p({type:m.DATE,allowNull:!0}),c(`design:type`,typeof(C=typeof Date<`u`&&Date)==`function`?C:Object)],D.prototype,`updatedAt`,void 0),l([p({type:m.DATE,allowNull:!0}),c(`design:type`,typeof(w=typeof Date<`u`&&Date)==`function`?w:Object)],D.prototype,`deletedAt`,void 0),l([p({type:m.BOOLEAN,defaultValue:!1,allowNull:!1}),c(`design:type`,Boolean)],D.prototype,`blockEditingFromUI`,void 0),l([g(()=>u),c(`design:type`,Array)],D.prototype,`values`,void 0),l([f,c(`design:type`,Function),c(`design:paramtypes`,[typeof(T=D!==void 0&&D)==`function`?T:Object]),c(`design:returntype`,void 0)],D,`displayNameDefaultValue`,null),l([d,c(`design:type`,Function),c(`design:paramtypes`,[typeof(E=D!==void 0&&D)==`function`?E:Object,Object]),c(`design:returntype`,void 0)],D,`afterSaveHandler`,null),D=l([h(()=>({where:{disabled:!1}})),b({tableName:`custom_field_definitions`,modelName:`CustomFieldDefinition`,indexes:[{name:`unique_name_model_type`,fields:[`model_type`,`entity_id`,`name`],unique:!0}],timestamps:!0,validate:{validationByType(){if(!this.validation&&n[this.fieldType])throw e.error(`No custom validation for custom field type ${this.fieldType} found`),new o(`Validation provided for "${this.fieldType}" is not supported`)}}})],D);var O=D;export{O as default};
|
|
1
|
+
import e from"../utils/logger/index.js";import{CustomFieldDefinitionType as t}from"../utils/constants/index.js";import{CustomValidationTypes as n}from"../utils/validations/validators/index.js";import{sendDimEvent as r}from"../events/index.js";import{InvalidValueError as i,UnsupportedCustomFieldTypeError as a,UnsupportedCustomValidationError as o}from"../errors/index.js";import{validateValue as s}from"../utils/validations/index.js";import{__decorateMetadata as c}from"../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.js";import{__decorate as l}from"../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.js";import u from"./CustomFieldValue.js";import{AfterSave as d,BeforeCreate as f,Column as p,DataType as m,DefaultScope as h,HasMany as g,Is as _,Model as v,PrimaryKey as y,Table as b}from"sequelize-typescript";var x,S,C,w,T,E;let D=class extends v{get modelTypeIds(){return this._modelTypeIds}set modelTypeIds(e){this._modelTypeIds=e,this.setDataValue(`modelTypeIds`,e)}static displayNameDefaultValue(e){if(e?.displayName||(e.displayName=e.name),![null,void 0].includes(e.defaultValue)){let t=s(e.defaultValue,e.fieldType,e.validation);if(t.error)throw new i(e.defaultValue,e.name,t.error)}}static afterSaveHandler(e,t){t.transaction?t.transaction.afterCommit(()=>r(e)):r(e)}toJSON(){let e={...this.get()};return delete e.modelTypeMappings,e}};l([y,p({type:m.UUID,defaultValue:m.UUIDV4,allowNull:!1}),c(`design:type`,String)],D.prototype,`id`,void 0),l([p({type:m.STRING,allowNull:!1}),c(`design:type`,String)],D.prototype,`name`,void 0),l([p({type:m.STRING}),c(`design:type`,String)],D.prototype,`displayName`,void 0),l([_(`SupportedType`,e=>{if(!Object.values(t).includes(e))throw new a(`"${e}" is not a supported type.`)}),p({type:m.STRING,allowNull:!1}),c(`design:type`,typeof(x=t!==void 0&&t)==`function`?x:Object)],D.prototype,`fieldType`,void 0),l([p({type:m.JSONB}),c(`design:type`,Object)],D.prototype,`validation`,void 0),l([p({type:m.UUID,allowNull:!1}),c(`design:type`,String)],D.prototype,`entityId`,void 0),l([p({type:m.STRING,allowNull:!1}),c(`design:type`,String)],D.prototype,`entityType`,void 0),l([p({type:m.STRING,allowNull:!1}),c(`design:type`,String)],D.prototype,`modelType`,void 0),l([p({type:m.TEXT}),c(`design:type`,String)],D.prototype,`description`,void 0),l([p({type:m.BOOLEAN,defaultValue:!1}),c(`design:type`,Boolean)],D.prototype,`required`,void 0),l([p({type:m.BOOLEAN,defaultValue:!1}),c(`design:type`,Boolean)],D.prototype,`disabled`,void 0),l([p({type:m.JSONB,allowNull:!0}),c(`design:type`,Object)],D.prototype,`defaultValue`,void 0),l([p({type:m.DATE,allowNull:!1}),c(`design:type`,typeof(S=typeof Date<`u`&&Date)==`function`?S:Object)],D.prototype,`createdAt`,void 0),l([p({type:m.DATE,allowNull:!0}),c(`design:type`,typeof(C=typeof Date<`u`&&Date)==`function`?C:Object)],D.prototype,`updatedAt`,void 0),l([p({type:m.DATE,allowNull:!0}),c(`design:type`,typeof(w=typeof Date<`u`&&Date)==`function`?w:Object)],D.prototype,`deletedAt`,void 0),l([p({type:m.BOOLEAN,defaultValue:!1,allowNull:!1}),c(`design:type`,Boolean)],D.prototype,`blockEditingFromUI`,void 0),l([g(()=>u),c(`design:type`,Array)],D.prototype,`values`,void 0),l([f,c(`design:type`,Function),c(`design:paramtypes`,[typeof(T=D!==void 0&&D)==`function`?T:Object]),c(`design:returntype`,void 0)],D,`displayNameDefaultValue`,null),l([d,c(`design:type`,Function),c(`design:paramtypes`,[typeof(E=D!==void 0&&D)==`function`?E:Object,Object]),c(`design:returntype`,void 0)],D,`afterSaveHandler`,null),D=l([h(()=>({where:{disabled:!1}})),b({tableName:`custom_field_definitions`,modelName:`CustomFieldDefinition`,indexes:[{name:`unique_name_model_type`,fields:[`model_type`,`entity_id`,`name`],unique:!0}],timestamps:!0,validate:{validationByType(){if(!this.validation&&n[this.fieldType])throw e.error(`No custom validation for custom field type ${this.fieldType} found`),new o(`Validation provided for "${this.fieldType}" is not supported`)}}})],D);var O=D;export{O as default};
|
|
2
2
|
//# sourceMappingURL=CustomFieldDefinition.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomFieldDefinition.js","names":["CustomFieldDefinition","CustomFieldValue"],"sources":["../../src/models/CustomFieldDefinition.ts"],"sourcesContent":["import {\n Table,\n Column,\n Model,\n DataType,\n HasMany,\n PrimaryKey,\n BeforeCreate,\n DefaultScope,\n AfterSave,\n Is,\n} from 'sequelize-typescript';\nimport type { CreateOptions } from 'sequelize';\nimport { CustomFieldDefinitionType } from '../utils/constants';\nimport { CustomValidationTypes } from '../utils/validations/validators';\nimport CustomFieldValue from './CustomFieldValue';\nimport CustomFieldModelTypeMap from './CustomFieldModelTypeMap';\nimport { sendDimEvent } from '../events';\nimport { InvalidValueError, UnsupportedCustomFieldTypeError, UnsupportedCustomValidationError } from '../errors';\nimport logger from '../utils/logger';\nimport { validateValue } from '../utils/validations';\n\n@DefaultScope(() => ({ where: { disabled: false } }))\n@Table({\n tableName: 'custom_field_definitions',\n modelName: 'CustomFieldDefinition',\n indexes: [\n {\n name: 'unique_name_model_type',\n fields: ['model_type', 'entity_id', 'name'],\n unique: true,\n },\n ],\n timestamps: true,\n validate: {\n validationByType(this: CustomFieldDefinition) {\n // Verify the validation is provided if needed\n if (!this.validation && CustomValidationTypes[this.fieldType as keyof typeof CustomValidationTypes]) {\n // TODO: enforce the validation-object schema based on the fieldType\n logger.error(`No custom validation for custom field type ${this.fieldType} found`);\n throw new UnsupportedCustomValidationError(`Validation provided for \"${this.fieldType}\" is not supported`);\n }\n },\n },\n})\nclass CustomFieldDefinition extends Model {\n @PrimaryKey\n @Column({\n type: DataType.UUID,\n defaultValue: DataType.UUIDV4,\n allowNull: false,\n })\n declare id: string;\n\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n name!: string;\n\n @Column({\n type: DataType.STRING,\n })\n displayName?: string; // Defaulted to name with beforeCreate hook\n\n @Is('SupportedType', (value) => {\n if (!Object.values(CustomFieldDefinitionType).includes(value as CustomFieldDefinitionType)) {\n throw new UnsupportedCustomFieldTypeError(`\"${value}\" is not a supported type.`);\n }\n })\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n fieldType!: CustomFieldDefinitionType;\n\n @Column({\n type: DataType.JSONB,\n })\n validation?: any;\n\n @Column({\n type: DataType.UUID,\n allowNull: false,\n })\n entityId!: string; /** Client association entity id */\n\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n entityType!: string; /** Client association entity type (demand source / fleet / etc.) */\n\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n modelType!: string; /** Model type. e.g. Vehicle / StopPoint / etc. */\n\n @Column({\n type: DataType.TEXT,\n })\n description?: string;\n\n @Column({\n type: DataType.BOOLEAN,\n defaultValue: false,\n })\n required?: boolean;\n\n @Column({\n type: DataType.BOOLEAN,\n defaultValue: false,\n })\n disabled?: boolean;\n\n @Column({\n type: DataType.JSONB,\n allowNull: true,\n })\n defaultValue?: any;\n\n @Column({\n type: DataType.DATE,\n allowNull: false,\n })\n declare createdAt?: Date;\n\n @Column({\n type: DataType.DATE,\n allowNull: true,\n })\n declare updatedAt?: Date;\n\n @Column({\n type: DataType.DATE,\n allowNull: true,\n })\n declare deletedAt?: Date;\n\n @Column({\n type: DataType.BOOLEAN,\n defaultValue: false,\n allowNull: false,\n })\n blockEditingFromUI!: boolean;\n\n @HasMany(() => CustomFieldValue)\n declare values: CustomFieldValue[];\n\n // Association added programmatically when useModelTypeMapping is enabled\n declare modelTypeMappings?: CustomFieldModelTypeMap[];\n\n // Virtual property for modelTypeIds - set manually after fetch\n private _modelTypeIds?: string[];\n\n get modelTypeIds(): string[] | undefined {\n return this._modelTypeIds;\n }\n\n set modelTypeIds(value: string[] | undefined) {\n this._modelTypeIds = value;\n this.setDataValue('modelTypeIds', value);\n }\n\n @BeforeCreate\n static displayNameDefaultValue(instance: CustomFieldDefinition): void {\n if (!instance?.displayName) {\n instance.displayName = instance.name;\n }\n if (![null, undefined].includes(instance.defaultValue)) {\n const isValid = validateValue(instance.defaultValue, instance.fieldType, instance.validation);\n if (isValid.error) {\n throw new InvalidValueError(instance.defaultValue, instance.name, isValid.error);\n }\n }\n }\n\n @AfterSave\n static afterSaveHandler(instance: CustomFieldDefinition, options: CreateOptions): void {\n if (options.transaction) {\n options.transaction.afterCommit(() => sendDimEvent(instance));\n } else {\n sendDimEvent(instance);\n }\n }\n}\n\nexport default CustomFieldDefinition;\n"],"mappings":"w1BAsBA,IAAA,EAAA,cAuBoC,CAAM,CA+GxC,IAAI,cAAqC,CACvC,OAAO,KAAK,cAGd,IAAI,aAAa,EAA6B,CAC5C,KAAK,cAAgB,EACrB,KAAK,aAAa,eAAgB,EAAM,CAG1C,OACO,wBAAwB,EAAuC,CAIpE,GAHK,GAAU,cACb,EAAS,YAAc,EAAS,MAE9B,CAAC,CAAC,KAAM,IAAA,GAAU,CAAC,SAAS,EAAS,aAAa,CAAE,CACtD,IAAM,EAAU,EAAc,EAAS,aAAc,EAAS,UAAW,EAAS,WAAW,CAC7F,GAAI,EAAQ,MACV,MAAM,IAAI,EAAkB,EAAS,aAAc,EAAS,KAAM,EAAQ,MAAM,EAKtF,OACO,iBAAiB,EAAiC,EAA8B,CACjF,EAAQ,YACV,EAAQ,YAAY,gBAAkB,EAAa,EAAS,CAAC,CAE7D,EAAa,EAAS,
|
|
1
|
+
{"version":3,"file":"CustomFieldDefinition.js","names":["CustomFieldDefinition","CustomFieldValue"],"sources":["../../src/models/CustomFieldDefinition.ts"],"sourcesContent":["import {\n Table,\n Column,\n Model,\n DataType,\n HasMany,\n PrimaryKey,\n BeforeCreate,\n DefaultScope,\n AfterSave,\n Is,\n} from 'sequelize-typescript';\nimport type { CreateOptions } from 'sequelize';\nimport { CustomFieldDefinitionType } from '../utils/constants';\nimport { CustomValidationTypes } from '../utils/validations/validators';\nimport CustomFieldValue from './CustomFieldValue';\nimport CustomFieldModelTypeMap from './CustomFieldModelTypeMap';\nimport { sendDimEvent } from '../events';\nimport { InvalidValueError, UnsupportedCustomFieldTypeError, UnsupportedCustomValidationError } from '../errors';\nimport logger from '../utils/logger';\nimport { validateValue } from '../utils/validations';\n\n@DefaultScope(() => ({ where: { disabled: false } }))\n@Table({\n tableName: 'custom_field_definitions',\n modelName: 'CustomFieldDefinition',\n indexes: [\n {\n name: 'unique_name_model_type',\n fields: ['model_type', 'entity_id', 'name'],\n unique: true,\n },\n ],\n timestamps: true,\n validate: {\n validationByType(this: CustomFieldDefinition) {\n // Verify the validation is provided if needed\n if (!this.validation && CustomValidationTypes[this.fieldType as keyof typeof CustomValidationTypes]) {\n // TODO: enforce the validation-object schema based on the fieldType\n logger.error(`No custom validation for custom field type ${this.fieldType} found`);\n throw new UnsupportedCustomValidationError(`Validation provided for \"${this.fieldType}\" is not supported`);\n }\n },\n },\n})\nclass CustomFieldDefinition extends Model {\n @PrimaryKey\n @Column({\n type: DataType.UUID,\n defaultValue: DataType.UUIDV4,\n allowNull: false,\n })\n declare id: string;\n\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n name!: string;\n\n @Column({\n type: DataType.STRING,\n })\n displayName?: string; // Defaulted to name with beforeCreate hook\n\n @Is('SupportedType', (value) => {\n if (!Object.values(CustomFieldDefinitionType).includes(value as CustomFieldDefinitionType)) {\n throw new UnsupportedCustomFieldTypeError(`\"${value}\" is not a supported type.`);\n }\n })\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n fieldType!: CustomFieldDefinitionType;\n\n @Column({\n type: DataType.JSONB,\n })\n validation?: any;\n\n @Column({\n type: DataType.UUID,\n allowNull: false,\n })\n entityId!: string; /** Client association entity id */\n\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n entityType!: string; /** Client association entity type (demand source / fleet / etc.) */\n\n @Column({\n type: DataType.STRING,\n allowNull: false,\n })\n modelType!: string; /** Model type. e.g. Vehicle / StopPoint / etc. */\n\n @Column({\n type: DataType.TEXT,\n })\n description?: string;\n\n @Column({\n type: DataType.BOOLEAN,\n defaultValue: false,\n })\n required?: boolean;\n\n @Column({\n type: DataType.BOOLEAN,\n defaultValue: false,\n })\n disabled?: boolean;\n\n @Column({\n type: DataType.JSONB,\n allowNull: true,\n })\n defaultValue?: any;\n\n @Column({\n type: DataType.DATE,\n allowNull: false,\n })\n declare createdAt?: Date;\n\n @Column({\n type: DataType.DATE,\n allowNull: true,\n })\n declare updatedAt?: Date;\n\n @Column({\n type: DataType.DATE,\n allowNull: true,\n })\n declare deletedAt?: Date;\n\n @Column({\n type: DataType.BOOLEAN,\n defaultValue: false,\n allowNull: false,\n })\n blockEditingFromUI!: boolean;\n\n @HasMany(() => CustomFieldValue)\n declare values: CustomFieldValue[];\n\n // Association added programmatically when useModelTypeMapping is enabled\n declare modelTypeMappings?: CustomFieldModelTypeMap[];\n\n // Virtual property for modelTypeIds - set manually after fetch\n private _modelTypeIds?: string[];\n\n get modelTypeIds(): string[] | undefined {\n return this._modelTypeIds;\n }\n\n set modelTypeIds(value: string[] | undefined) {\n this._modelTypeIds = value;\n this.setDataValue('modelTypeIds', value);\n }\n\n @BeforeCreate\n static displayNameDefaultValue(instance: CustomFieldDefinition): void {\n if (!instance?.displayName) {\n instance.displayName = instance.name;\n }\n if (![null, undefined].includes(instance.defaultValue)) {\n const isValid = validateValue(instance.defaultValue, instance.fieldType, instance.validation);\n if (isValid.error) {\n throw new InvalidValueError(instance.defaultValue, instance.name, isValid.error);\n }\n }\n }\n\n @AfterSave\n static afterSaveHandler(instance: CustomFieldDefinition, options: CreateOptions): void {\n if (options.transaction) {\n options.transaction.afterCommit(() => sendDimEvent(instance));\n } else {\n sendDimEvent(instance);\n }\n }\n\n /**\n * Override toJSON to exclude internal associations from API responses\n * The modelTypeMappings association is used internally to optimize queries\n * but should not be exposed in the API response (use modelTypeIds instead)\n */\n toJSON(): object {\n const values = { ...this.get() };\n // Remove the internal association used for query optimization\n delete values.modelTypeMappings;\n return values;\n }\n}\n\nexport default CustomFieldDefinition;\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`../_virtual/rolldown_runtime.cjs`),t=require(`../errors/index.cjs`),n=require(`../models/CustomFieldDefinition.cjs`),r=require(`../models/CustomFieldModelTypeMap.cjs`);require(`../models/index.cjs`);let i=require(`sequelize`);const a=
|
|
1
|
+
const e=require(`../_virtual/rolldown_runtime.cjs`),t=require(`../errors/index.cjs`),n=require(`../models/CustomFieldDefinition.cjs`),r=require(`../models/CustomFieldModelTypeMap.cjs`);require(`../models/index.cjs`);let i=require(`sequelize`);const a=e=>!e||!Array.isArray(e)?[]:e.map(e=>e.modelTypeId||e.dataValues?.modelTypeId).filter(e=>!!e),o=e=>{let t=e;return e.modelTypeIds=a(t.modelTypeMappings??t.dataValues?.modelTypeMappings),e},s=async e=>{let{modelTypeIds:t,...i}=e,a=await n.default.sequelize.transaction(async e=>{let a=await n.default.create(i,{transaction:e});return t?.length&&await r.default.bulkCreate(t.map(e=>({customFieldDefinitionId:a.id,modelTypeId:e})),{transaction:e}),a});return a.modelTypeIds=t??[],a},c=async(e,t={withDisabled:!1})=>{let r=t.withDisabled?n.default.unscoped():n.default,i=t.include;if(t.enrichWithModelTypeIds){let e={association:`modelTypeMappings`,required:!1,attributes:[`modelTypeId`]};i=t.include?Array.isArray(t.include)?[...t.include,e]:[t.include,e]:e}let a=await r.scope(`userScope`).findAll({where:e,transaction:t.transaction,raw:!t.enrichWithModelTypeIds,include:i});return t.enrichWithModelTypeIds?a.map(o):a},l=(e,t={withDisabled:!1})=>c({id:{[i.Op.in]:e}},t),u=async(e,t={withDisabled:!1})=>{let{withDisabled:r}=t,i=await(r?n.default.unscoped().scope(`userScope`):n.default.scope(`userScope`)).findByPk(e,{include:[{association:`modelTypeMappings`,required:!1,attributes:[`modelTypeId`]}]});return i?o(i):null},d=async(e,t,r={})=>{let{include:a,useEntityIdFromInclude:o}=r.modelOptions,s={modelType:e,...!o&&{entityId:{[i.Op.in]:t}}};return n.default.findAll({where:s,transaction:r.transaction,include:a?.(t),raw:!0})},f=e=>n.default.scope(`userScope`).findOne({where:e}),p=async(e,t)=>{let{modelTypeIds:i,...a}=t,o=await n.default.sequelize.transaction(async t=>{let o=(await n.default.scope(`userScope`).update(a,{where:{id:e},returning:!0,individualHooks:!0,transaction:t}))[1][0];if(i){let n=await r.default.findAll({where:{customFieldDefinitionId:e},attributes:[`id`,`modelTypeId`],raw:!0,transaction:t}),a=n.map(e=>e.modelTypeId),s=i.filter(e=>!a.includes(e)),c=n.filter(e=>!i.includes(e.modelTypeId)),l=c.length>0||s.length>0;c.length>0&&await r.default.destroy({where:{id:c.map(e=>e.id)},transaction:t}),s.length>0&&await r.default.bulkCreate(s.map(t=>({customFieldDefinitionId:e,modelTypeId:t})),{transaction:t}),l&&(o.changed(`updatedAt`,!0),await o.save({transaction:t}))}return o});return o.modelTypeIds=i??[],o},m=async(e,t={withDisabled:!1,modelType:``})=>{let{withDisabled:r,entityIds:a,modelType:s,modelOptions:c}=t,{include:l,useEntityIdFromInclude:u}=c??{},d={modelType:s,...!u&&a&&a.length>0&&{entityId:{[i.Op.in]:a}}},f=r?n.default.unscoped():n.default,p=[{association:`modelTypeMappings`,required:!1,attributes:[`id`,`modelTypeId`]}];if(u&&l&&a){let e=l(a);p.push(...e)}return(await f.scope(`userScope`).findAll({where:d,include:p,raw:!1,transaction:t.transaction})).filter(t=>{let n=t.modelTypeMappings||t.dataValues?.modelTypeMappings||[];return!Array.isArray(n)||n.length===0?!0:n.some(t=>(t.modelTypeId||t.dataValues?.modelTypeId)===e)}).map(o)},h=async(e,{findAll:n,modelOptions:r={},withDisabled:a=!1,...o}={withDisabled:!1,modelOptions:{}})=>{let{modelType:s}=e[0]?.dataValues??{},l=new Set,u=[],d=new Set;e.forEach(e=>{let{dataValues:{modelId:t,entityId:n,customFields:r}}=e;u.push(t),d.add(n),Object.keys(r??{}).forEach(e=>{l.add(e)})});let f={modelType:s,entityId:{[i.Op.in]:Array.from(d)},name:{[i.Op.in]:Array.from(l)}},p=await(n??c)(f,{withDisabled:a,modelOptions:r,...o}),m=p.filter(e=>l.has(e.name)),h=Object.fromEntries(m.map(e=>[e.name,e]));if(!p?.length||m.length!==l.size)throw new t.MissingDefinitionError(Array.from(l).filter(e=>!h[e]));return h};exports.create=s,exports.findAll=c,exports.findByEntityIds=d,exports.findById=u,exports.findByIds=l,exports.findByModelTypeId=m,exports.findByWhere=f,exports.getCustomFieldDefinitionsDictionary=h,exports.update=p;
|
|
2
2
|
//# sourceMappingURL=definition.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.cjs","names":["CustomFieldModelTypeMap","CustomFieldDefinition","Op","where: WhereOptions","baseWhere: WhereOptions","includeArray: any[]","MissingDefinitionError"],"sources":["../../src/repository/definition.ts"],"sourcesContent":["import {\n Op,\n type Includeable, type Transaction, type FindOptions, type WhereOptions, type Transactionable,\n} from 'sequelize';\nimport { CustomFieldDefinition, CustomFieldModelTypeMap, type CustomFieldEntries } from '../models';\nimport type { CreateCustomFieldDefinition, UpdateCustomFieldDefinition } from '../types/definition';\nimport type { ModelOptions } from '../types';\nimport { MissingDefinitionError } from '../errors';\n\n/**\n * Enriches a custom field definition with modelTypeIds array\n * Uses the model's setter which handles both the property and serialization\n */\nconst enrichWithModelTypeIds = async (\n definition: CustomFieldDefinition,\n): Promise<CustomFieldDefinition & { modelTypeIds?: string[]; }> => {\n try {\n const mappings = await CustomFieldModelTypeMap.findAll({\n where: { customFieldDefinitionId: definition.id },\n attributes: ['modelTypeId'],\n raw: true,\n });\n\n const modelTypeIds = mappings.map((m: { modelTypeId: string; }) => m.modelTypeId);\n\n definition.modelTypeIds = modelTypeIds;\n } catch {\n definition.modelTypeIds = [];\n }\n\n return definition as CustomFieldDefinition & { modelTypeIds?: string[]; };\n};\n\nexport const create = async (\n data: CreateCustomFieldDefinition,\n): Promise<CustomFieldDefinition> => {\n const { modelTypeIds, ...definitionData } = data;\n\n const result = await CustomFieldDefinition.sequelize!.transaction(async (transaction: Transaction) => {\n const customFieldDefinition = await CustomFieldDefinition.create(definitionData as any, {\n transaction,\n });\n\n if (modelTypeIds?.length) {\n await Promise.all(\n modelTypeIds.map(modelTypeId =>\n CustomFieldModelTypeMap.create({\n customFieldDefinitionId: customFieldDefinition.id,\n modelTypeId,\n }, {\n transaction,\n }),\n ),\n );\n }\n\n return customFieldDefinition;\n });\n\n return enrichWithModelTypeIds(result);\n};\n\ninterface SadotFindOptions {\n withDisabled?: boolean;\n transaction?: Transaction | null;\n include?: Includeable | Includeable[];\n enrichWithModelTypeIds?: boolean;\n}\n\ntype SadotGetDefinitionsByEntityIdsOptions = FindOptions & { modelOptions?: ModelOptions; findAll?: typeof findAll; } & Pick<SadotFindOptions, 'withDisabled'>;\n\nexport const findAll = async (\n where: WhereOptions,\n options: SadotFindOptions = { withDisabled: false },\n): Promise<CustomFieldDefinition[]> => {\n const queryModel = options.withDisabled\n ? CustomFieldDefinition.unscoped()\n : CustomFieldDefinition;\n\n const definitions = await queryModel.scope('userScope').findAll({\n where,\n transaction: options.transaction,\n raw: !options.enrichWithModelTypeIds,\n include: options.include,\n });\n\n if (options.enrichWithModelTypeIds) {\n return Promise.all(definitions.map(def => enrichWithModelTypeIds(def)));\n }\n\n return definitions;\n};\n\nexport const findByIds = (\n ids: string[],\n options: SadotFindOptions = { withDisabled: false },\n): Promise<CustomFieldDefinition[]> => findAll({ id: { [Op.in]: ids } }, options);\n\nexport const findById = async (\n id: string,\n options: Pick<SadotFindOptions, 'withDisabled'> = { withDisabled: false },\n): Promise<CustomFieldDefinition | null> => {\n const { withDisabled } = options;\n const definition = withDisabled\n ? await CustomFieldDefinition.unscoped().scope('userScope').findByPk(id)\n : await CustomFieldDefinition.scope('userScope').findByPk(id);\n\n if (!definition) {\n return null;\n }\n\n return enrichWithModelTypeIds(definition);\n};\n\nexport const findByEntityIds = async (\n modelType: string,\n entityIds: string[],\n options: FindOptions & { modelOptions?: ModelOptions; } = {},\n): Promise<CustomFieldDefinition[]> => {\n const { include, useEntityIdFromInclude } = options.modelOptions!;\n const where: WhereOptions = {\n modelType,\n ...(!useEntityIdFromInclude && { entityId: { [Op.in]: entityIds } }),\n };\n\n return CustomFieldDefinition.findAll({\n where,\n transaction: options.transaction,\n include: include?.(entityIds),\n raw: true,\n });\n};\n\nexport const findByWhere = (where: WhereOptions<CustomFieldDefinition>): Promise<CustomFieldDefinition | null> =>\n CustomFieldDefinition.scope('userScope').findOne({\n where,\n });\n\nexport const findDefinitionsByModels = async (\n modelTypes: string[],\n options?: Transactionable,\n): Promise<CustomFieldDefinition[]> => {\n const query: WhereOptions<CreateCustomFieldDefinition> = { modelType: { [Op.in]: modelTypes } };\n return CustomFieldDefinition.findAll({\n where: query,\n transaction: options?.transaction,\n });\n};\n\nexport const update = async (\n id: string,\n data: UpdateCustomFieldDefinition,\n): Promise<CustomFieldDefinition> => {\n const { modelTypeIds, ...definitionData } = data;\n\n const result = await CustomFieldDefinition.sequelize!.transaction(async (transaction: Transaction) => {\n const updatedDefinition = (await CustomFieldDefinition.scope('userScope').update(definitionData, {\n where: { id },\n returning: true,\n individualHooks: true,\n transaction,\n }))[1][0];\n\n if (modelTypeIds) {\n const existingMappings = await CustomFieldModelTypeMap.findAll({\n where: { customFieldDefinitionId: id },\n attributes: ['id', 'modelTypeId'],\n raw: true,\n transaction,\n });\n\n const existingTypeIds = existingMappings.map(m => m.modelTypeId);\n\n const toAdd = modelTypeIds.filter(typeId => !existingTypeIds.includes(typeId));\n const toRemove = existingMappings.filter(m => !modelTypeIds.includes(m.modelTypeId));\n\n // Check if there are any mapping changes\n const hasMappingChanges = toRemove.length > 0 || toAdd.length > 0;\n\n if (toRemove.length > 0) {\n await CustomFieldModelTypeMap.destroy({\n where: {\n id: toRemove.map(m => m.id),\n },\n transaction,\n });\n }\n\n if (toAdd.length > 0) {\n await Promise.all(\n toAdd.map(modelTypeId =>\n CustomFieldModelTypeMap.create({\n customFieldDefinitionId: id,\n modelTypeId,\n }, {\n transaction,\n }),\n ),\n );\n }\n\n // Touch the definition to update its updatedAt timestamp after mapping changes\n if (hasMappingChanges) {\n updatedDefinition.changed('updatedAt', true);\n await updatedDefinition.save({ transaction });\n }\n }\n\n return updatedDefinition;\n });\n\n return enrichWithModelTypeIds(result);\n};\n\nexport const disable = (id: string): Promise<[affectedCount: number]> =>\n CustomFieldDefinition.update(\n { disabled: true },\n { where: { id } },\n );\n\nexport const destroy = (id: string): Promise<number> =>\n CustomFieldDefinition.destroy({ where: { id } });\n\n/**\n * Return the names of the required fields for a given model\n */\nexport const getRequiredFields = async (\n modelType: string,\n modelId: string | string[],\n entityId: string | string[],\n modelOptions: ModelOptions = {},\n): Promise<string[]> => {\n const entityIds = Array.isArray(entityId) ? entityId : [entityId];\n const { include, useEntityIdFromInclude } = modelOptions;\n\n const where: WhereOptions = {\n modelType,\n required: true,\n ...(!useEntityIdFromInclude && { entityId: { [Op.in]: entityIds } }),\n };\n\n const requiredFields = await CustomFieldDefinition.findAll({\n where,\n include: include?.(entityIds),\n logging: true,\n });\n const requiredFieldsNames = requiredFields.map(definition => definition.name);\n return [...new Set(requiredFieldsNames)];\n};\n\n/**\n * @returns A promise resolving with a dictionary of custom field definitions by name.\n * @throws A {@link MissingDefinitionError} if any of the custom fields doesn't have a definition.\n */\n/**\n * Find custom field definitions applicable to a specific model type instance\n *\n * Returns definitions that either:\n * 1. Have NO mappings (apply to all instances of this model type)\n * 2. Have a mapping to this specific model type instance\n */\nexport const findByModelTypeId = async (\n modelTypeId: string,\n options: Pick<SadotFindOptions, 'withDisabled' | 'transaction'> & { entityIds?: string[]; modelType: string; modelOptions?: ModelOptions; } = { withDisabled: false, modelType: '' },\n): Promise<CustomFieldDefinition[]> => {\n const { withDisabled, entityIds, modelType, modelOptions } = options;\n\n const { include, useEntityIdFromInclude } = modelOptions ?? {};\n\n const baseWhere: WhereOptions = {\n modelType,\n ...(!useEntityIdFromInclude && entityIds && entityIds.length > 0 && { entityId: { [Op.in]: entityIds } }),\n };\n\n const queryModel = withDisabled\n ? (CustomFieldDefinition as any).unscoped()\n : CustomFieldDefinition;\n\n const includeArray: any[] = [\n {\n association: 'modelTypeMappings',\n required: false,\n attributes: ['id', 'modelTypeId'],\n },\n ];\n\n if (useEntityIdFromInclude && include && entityIds) {\n const contextIncludes = include(entityIds);\n includeArray.push(...contextIncludes);\n }\n\n const definitions = await queryModel.scope('userScope').findAll({\n where: baseWhere,\n include: includeArray,\n raw: false,\n transaction: options.transaction,\n });\n\n const filteredDefinitions = definitions.filter((def: any) => {\n const mappings = def.modelTypeMappings || def.dataValues?.modelTypeMappings || [];\n\n if (!Array.isArray(mappings) || mappings.length === 0) {\n return true;\n }\n\n const hasMatch = mappings.some((mapping: any) => {\n const mappingTypeId = mapping.modelTypeId || mapping.dataValues?.modelTypeId;\n return mappingTypeId === modelTypeId;\n });\n\n return hasMatch;\n });\n\n return Promise.all(filteredDefinitions.map((def: CustomFieldDefinition) => enrichWithModelTypeIds(def)));\n};\n\nexport const getCustomFieldDefinitionsDictionary = async (\n instances: CustomFieldEntries[],\n {\n findAll: _findAll,\n modelOptions = {},\n withDisabled = false,\n ...options\n }: SadotGetDefinitionsByEntityIdsOptions = { withDisabled: false, modelOptions: {} },\n): Promise<Record<string, CustomFieldDefinition>> => {\n const { modelType } = instances[0]?.dataValues ?? {};\n const customFields = new Set<string>();\n const modelIds = [];\n const entityIds = new Set<string>();\n instances.forEach((instance) => {\n const { dataValues: { modelId, entityId, customFields: instanceCustomFields } } = instance;\n modelIds.push(modelId);\n entityIds.add(entityId);\n\n Object.keys(instanceCustomFields ?? {}).forEach((fieldName) => {\n customFields.add(fieldName);\n });\n });\n\n const where: WhereOptions = {\n modelType,\n entityId: { [Op.in]: Array.from(entityIds) },\n name: { [Op.in]: Array.from(customFields) },\n };\n\n const findAllToUse = _findAll ?? findAll;\n\n // @ts-expect-error findAll doesn't expect modelOptions at all.\n const definitions = await findAllToUse(where, { withDisabled, modelOptions, ...options });\n\n const matchedDefinitions = definitions.filter(def => customFields.has(def.name));\n const matchedDefinitionsByName = Object.fromEntries(matchedDefinitions.map(definition => [definition.name, definition]));\n\n if (!definitions?.length || matchedDefinitions.length !== customFields.size) {\n const unmatchedCustomFields = Array.from(customFields).filter(customField => !matchedDefinitionsByName[customField]);\n throw new MissingDefinitionError(unmatchedCustomFields);\n }\n\n return matchedDefinitionsByName;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"definition.cjs","names":["CustomFieldDefinition","CustomFieldModelTypeMap","includeToUse: Includeable | Includeable[] | undefined","modelTypeMappingsInclude: Includeable","Op","where: WhereOptions","baseWhere: WhereOptions","includeArray: any[]","MissingDefinitionError"],"sources":["../../src/repository/definition.ts"],"sourcesContent":["import {\n Op,\n type Includeable, type Transaction, type FindOptions, type WhereOptions, type Transactionable,\n} from 'sequelize';\nimport { CustomFieldDefinition, CustomFieldModelTypeMap, type CustomFieldEntries } from '../models';\nimport type { CreateCustomFieldDefinition, UpdateCustomFieldDefinition } from '../types/definition';\nimport type { ModelOptions } from '../types';\nimport { MissingDefinitionError } from '../errors';\n\n/**\n * Interface for mapping association data (can be raw or Sequelize model instance)\n */\ninterface MappingData {\n modelTypeId?: string;\n dataValues?: {\n modelTypeId?: string;\n };\n}\n\n/**\n * Helper to extract modelTypeIds from the modelTypeMappings association data\n * Handles both raw and non-raw Sequelize results\n */\nconst extractModelTypeIdsFromMappings = (mappings: MappingData[]): string[] => {\n if (!mappings || !Array.isArray(mappings)) {\n return [];\n }\n\n return mappings\n .map((m: MappingData) => m.modelTypeId || m.dataValues?.modelTypeId)\n .filter(id => Boolean(id)) as string[];\n};\n\n/**\n * Helper to extract modelTypeIds from a definition with loaded association\n * Handles the common pattern of getting mappings from a definition\n */\nconst enrichDefinitionWithModelTypeIds = (\n definition: CustomFieldDefinition,\n): CustomFieldDefinition & { modelTypeIds?: string[]; } => {\n const defWithMappings = definition as CustomFieldDefinition & {\n modelTypeMappings?: MappingData[];\n dataValues?: { modelTypeMappings?: MappingData[]; };\n };\n const mappings = defWithMappings.modelTypeMappings ?? defWithMappings.dataValues?.modelTypeMappings;\n definition.modelTypeIds = extractModelTypeIdsFromMappings(mappings);\n return definition as CustomFieldDefinition & { modelTypeIds?: string[]; };\n};\n\nexport const create = async (\n data: CreateCustomFieldDefinition,\n): Promise<CustomFieldDefinition> => {\n const { modelTypeIds, ...definitionData } = data;\n\n const result = await CustomFieldDefinition.sequelize!.transaction(async (transaction: Transaction) => {\n const customFieldDefinition = await CustomFieldDefinition.create(definitionData as any, {\n transaction,\n });\n\n if (modelTypeIds?.length) {\n await CustomFieldModelTypeMap.bulkCreate(\n modelTypeIds.map(modelTypeId => ({\n customFieldDefinitionId: customFieldDefinition.id,\n modelTypeId,\n })),\n { transaction },\n );\n }\n\n return customFieldDefinition;\n });\n\n result.modelTypeIds = modelTypeIds ?? [];\n\n return result as CustomFieldDefinition & { modelTypeIds?: string[]; };\n};\n\ninterface SadotFindOptions {\n withDisabled?: boolean;\n transaction?: Transaction | null;\n include?: Includeable | Includeable[];\n enrichWithModelTypeIds?: boolean;\n}\n\ntype SadotGetDefinitionsByEntityIdsOptions = FindOptions & { modelOptions?: ModelOptions; findAll?: typeof findAll; } & Pick<SadotFindOptions, 'withDisabled'>;\n\nexport const findAll = async (\n where: WhereOptions,\n options: SadotFindOptions = { withDisabled: false },\n): Promise<CustomFieldDefinition[]> => {\n const queryModel = options.withDisabled\n ? CustomFieldDefinition.unscoped()\n : CustomFieldDefinition;\n\n // Build include array - ensure we maintain the type compatibility\n let includeToUse: Includeable | Includeable[] | undefined = options.include;\n\n // If enrichWithModelTypeIds is requested, include the association to avoid N+1 queries\n if (options.enrichWithModelTypeIds) {\n const modelTypeMappingsInclude: Includeable = {\n association: 'modelTypeMappings',\n required: false,\n attributes: ['modelTypeId'],\n };\n\n if (options.include) {\n // Combine existing includes with modelTypeMappings\n includeToUse = Array.isArray(options.include)\n ? [...options.include, modelTypeMappingsInclude]\n : [options.include, modelTypeMappingsInclude];\n } else {\n includeToUse = modelTypeMappingsInclude;\n }\n }\n\n const definitions = await queryModel.scope('userScope').findAll({\n where,\n transaction: options.transaction,\n raw: !options.enrichWithModelTypeIds,\n include: includeToUse,\n });\n\n if (options.enrichWithModelTypeIds) {\n // Extract modelTypeIds from the included association data instead of making N queries\n return definitions.map(enrichDefinitionWithModelTypeIds);\n }\n\n return definitions;\n};\n\nexport const findByIds = (\n ids: string[],\n options: SadotFindOptions = { withDisabled: false },\n): Promise<CustomFieldDefinition[]> => findAll({ id: { [Op.in]: ids } }, options);\n\nexport const findById = async (\n id: string,\n options: Pick<SadotFindOptions, 'withDisabled'> = { withDisabled: false },\n): Promise<CustomFieldDefinition | null> => {\n const { withDisabled } = options;\n\n const queryModel = withDisabled\n ? CustomFieldDefinition.unscoped().scope('userScope')\n : CustomFieldDefinition.scope('userScope');\n\n const definition = await queryModel.findByPk(id, {\n include: [\n {\n association: 'modelTypeMappings',\n required: false,\n attributes: ['modelTypeId'],\n },\n ],\n });\n\n if (!definition) {\n return null;\n }\n\n // Extract modelTypeIds from the included association data\n return enrichDefinitionWithModelTypeIds(definition);\n};\n\nexport const findByEntityIds = async (\n modelType: string,\n entityIds: string[],\n options: FindOptions & { modelOptions?: ModelOptions; } = {},\n): Promise<CustomFieldDefinition[]> => {\n const { include, useEntityIdFromInclude } = options.modelOptions!;\n const where: WhereOptions = {\n modelType,\n ...(!useEntityIdFromInclude && { entityId: { [Op.in]: entityIds } }),\n };\n\n return CustomFieldDefinition.findAll({\n where,\n transaction: options.transaction,\n include: include?.(entityIds),\n raw: true,\n });\n};\n\nexport const findByWhere = (where: WhereOptions<CustomFieldDefinition>): Promise<CustomFieldDefinition | null> =>\n CustomFieldDefinition.scope('userScope').findOne({\n where,\n });\n\nexport const findDefinitionsByModels = async (\n modelTypes: string[],\n options?: Transactionable,\n): Promise<CustomFieldDefinition[]> => {\n const query: WhereOptions<CreateCustomFieldDefinition> = { modelType: { [Op.in]: modelTypes } };\n return CustomFieldDefinition.findAll({\n where: query,\n transaction: options?.transaction,\n });\n};\n\nexport const update = async (\n id: string,\n data: UpdateCustomFieldDefinition,\n): Promise<CustomFieldDefinition> => {\n const { modelTypeIds, ...definitionData } = data;\n\n const result = await CustomFieldDefinition.sequelize!.transaction(async (transaction: Transaction) => {\n const updatedDefinition = (await CustomFieldDefinition.scope('userScope').update(definitionData, {\n where: { id },\n returning: true,\n individualHooks: true,\n transaction,\n }))[1][0];\n\n if (modelTypeIds) {\n const existingMappings = await CustomFieldModelTypeMap.findAll({\n where: { customFieldDefinitionId: id },\n attributes: ['id', 'modelTypeId'],\n raw: true,\n transaction,\n });\n\n const existingTypeIds = existingMappings.map(m => m.modelTypeId);\n\n const toAdd = modelTypeIds.filter(typeId => !existingTypeIds.includes(typeId));\n const toRemove = existingMappings.filter(m => !modelTypeIds.includes(m.modelTypeId));\n\n // Check if there are any mapping changes\n const hasMappingChanges = toRemove.length > 0 || toAdd.length > 0;\n\n if (toRemove.length > 0) {\n await CustomFieldModelTypeMap.destroy({\n where: {\n id: toRemove.map(m => m.id),\n },\n transaction,\n });\n }\n\n if (toAdd.length > 0) {\n await CustomFieldModelTypeMap.bulkCreate(\n toAdd.map(modelTypeId => ({\n customFieldDefinitionId: id,\n modelTypeId,\n })),\n { transaction },\n );\n }\n\n // Touch the definition to update its updatedAt timestamp after mapping changes\n if (hasMappingChanges) {\n updatedDefinition.changed('updatedAt', true);\n await updatedDefinition.save({ transaction });\n }\n }\n\n return updatedDefinition;\n });\n\n result.modelTypeIds = modelTypeIds ?? [];\n\n return result as CustomFieldDefinition & { modelTypeIds?: string[]; };\n};\n\nexport const disable = (id: string): Promise<[affectedCount: number]> =>\n CustomFieldDefinition.update(\n { disabled: true },\n { where: { id } },\n );\n\nexport const destroy = (id: string): Promise<number> =>\n CustomFieldDefinition.destroy({ where: { id } });\n\n/**\n * Return the names of the required fields for a given model\n */\nexport const getRequiredFields = async (\n modelType: string,\n modelId: string | string[],\n entityId: string | string[],\n modelOptions: ModelOptions = {},\n): Promise<string[]> => {\n const entityIds = Array.isArray(entityId) ? entityId : [entityId];\n const { include, useEntityIdFromInclude } = modelOptions;\n\n const where: WhereOptions = {\n modelType,\n required: true,\n ...(!useEntityIdFromInclude && { entityId: { [Op.in]: entityIds } }),\n };\n\n const requiredFields = await CustomFieldDefinition.findAll({\n where,\n include: include?.(entityIds),\n logging: true,\n });\n const requiredFieldsNames = requiredFields.map(definition => definition.name);\n return [...new Set(requiredFieldsNames)];\n};\n\n/**\n * @returns A promise resolving with a dictionary of custom field definitions by name.\n * @throws A {@link MissingDefinitionError} if any of the custom fields doesn't have a definition.\n */\n/**\n * Find custom field definitions applicable to a specific model type instance\n *\n * Returns definitions that either:\n * 1. Have NO mappings (apply to all instances of this model type)\n * 2. Have a mapping to this specific model type instance\n */\nexport const findByModelTypeId = async (\n modelTypeId: string,\n options: Pick<SadotFindOptions, 'withDisabled' | 'transaction'> & { entityIds?: string[]; modelType: string; modelOptions?: ModelOptions; } = { withDisabled: false, modelType: '' },\n): Promise<CustomFieldDefinition[]> => {\n const { withDisabled, entityIds, modelType, modelOptions } = options;\n\n const { include, useEntityIdFromInclude } = modelOptions ?? {};\n\n const baseWhere: WhereOptions = {\n modelType,\n ...(!useEntityIdFromInclude && entityIds && entityIds.length > 0 && { entityId: { [Op.in]: entityIds } }),\n };\n\n const queryModel = withDisabled\n ? (CustomFieldDefinition as any).unscoped()\n : CustomFieldDefinition;\n\n const includeArray: any[] = [\n {\n association: 'modelTypeMappings',\n required: false,\n attributes: ['id', 'modelTypeId'],\n },\n ];\n\n if (useEntityIdFromInclude && include && entityIds) {\n const contextIncludes = include(entityIds);\n includeArray.push(...contextIncludes);\n }\n\n const definitions = await queryModel.scope('userScope').findAll({\n where: baseWhere,\n include: includeArray,\n raw: false,\n transaction: options.transaction,\n });\n\n const filteredDefinitions = definitions.filter((def: any) => {\n const mappings = def.modelTypeMappings || def.dataValues?.modelTypeMappings || [];\n\n if (!Array.isArray(mappings) || mappings.length === 0) {\n return true;\n }\n\n const hasMatch = mappings.some((mapping: any) => {\n const mappingTypeId = mapping.modelTypeId || mapping.dataValues?.modelTypeId;\n return mappingTypeId === modelTypeId;\n });\n\n return hasMatch;\n });\n\n // Use association data to extract modelTypeIds instead of making N additional queries\n return filteredDefinitions.map(enrichDefinitionWithModelTypeIds);\n};\n\nexport const getCustomFieldDefinitionsDictionary = async (\n instances: CustomFieldEntries[],\n {\n findAll: _findAll,\n modelOptions = {},\n withDisabled = false,\n ...options\n }: SadotGetDefinitionsByEntityIdsOptions = { withDisabled: false, modelOptions: {} },\n): Promise<Record<string, CustomFieldDefinition>> => {\n const { modelType } = instances[0]?.dataValues ?? {};\n const customFields = new Set<string>();\n const modelIds = [];\n const entityIds = new Set<string>();\n instances.forEach((instance) => {\n const { dataValues: { modelId, entityId, customFields: instanceCustomFields } } = instance;\n modelIds.push(modelId);\n entityIds.add(entityId);\n\n Object.keys(instanceCustomFields ?? {}).forEach((fieldName) => {\n customFields.add(fieldName);\n });\n });\n\n const where: WhereOptions = {\n modelType,\n entityId: { [Op.in]: Array.from(entityIds) },\n name: { [Op.in]: Array.from(customFields) },\n };\n\n const findAllToUse = _findAll ?? findAll;\n\n // @ts-expect-error findAll doesn't expect modelOptions at all.\n const definitions = await findAllToUse(where, { withDisabled, modelOptions, ...options });\n\n const matchedDefinitions = definitions.filter(def => customFields.has(def.name));\n const matchedDefinitionsByName = Object.fromEntries(matchedDefinitions.map(definition => [definition.name, definition]));\n\n if (!definitions?.length || matchedDefinitions.length !== customFields.size) {\n const unmatchedCustomFields = Array.from(customFields).filter(customField => !matchedDefinitionsByName[customField]);\n throw new MissingDefinitionError(unmatchedCustomFields);\n }\n\n return matchedDefinitionsByName;\n};\n"],"mappings":"mPAuBA,MAAM,EAAmC,GACnC,CAAC,GAAY,CAAC,MAAM,QAAQ,EAAS,CAChC,EAAE,CAGJ,EACJ,IAAK,GAAmB,EAAE,aAAe,EAAE,YAAY,YAAY,CACnE,OAAO,GAAM,EAAQ,EAAI,CAOxB,EACJ,GACyD,CACzD,IAAM,EAAkB,EAMxB,MADA,GAAW,aAAe,EADT,EAAgB,mBAAqB,EAAgB,YAAY,kBACf,CAC5D,GAGI,EAAS,KACpB,IACmC,CACnC,GAAM,CAAE,eAAc,GAAG,GAAmB,EAEtC,EAAS,MAAMA,EAAAA,QAAsB,UAAW,YAAY,KAAO,IAA6B,CACpG,IAAM,EAAwB,MAAMA,EAAAA,QAAsB,OAAO,EAAuB,CACtF,cACD,CAAC,CAYF,OAVI,GAAc,QAChB,MAAMC,EAAAA,QAAwB,WAC5B,EAAa,IAAI,IAAgB,CAC/B,wBAAyB,EAAsB,GAC/C,cACD,EAAE,CACH,CAAE,cAAa,CAChB,CAGI,GACP,CAIF,MAFA,GAAO,aAAe,GAAgB,EAAE,CAEjC,GAYI,EAAU,MACrB,EACA,EAA4B,CAAE,aAAc,GAAO,GACd,CACrC,IAAM,EAAa,EAAQ,aACvBD,EAAAA,QAAsB,UAAU,CAChCA,EAAAA,QAGAE,EAAwD,EAAQ,QAGpE,GAAI,EAAQ,uBAAwB,CAClC,IAAMC,EAAwC,CAC5C,YAAa,oBACb,SAAU,GACV,WAAY,CAAC,cAAc,CAC5B,CAED,AAME,EANE,EAAQ,QAEK,MAAM,QAAQ,EAAQ,QAAQ,CACzC,CAAC,GAAG,EAAQ,QAAS,EAAyB,CAC9C,CAAC,EAAQ,QAAS,EAAyB,CAEhC,EAInB,IAAM,EAAc,MAAM,EAAW,MAAM,YAAY,CAAC,QAAQ,CAC9D,QACA,YAAa,EAAQ,YACrB,IAAK,CAAC,EAAQ,uBACd,QAAS,EACV,CAAC,CAOF,OALI,EAAQ,uBAEH,EAAY,IAAI,EAAiC,CAGnD,GAGI,GACX,EACA,EAA4B,CAAE,aAAc,GAAO,GACd,EAAQ,CAAE,GAAI,EAAGC,EAAAA,GAAG,IAAK,EAAK,CAAE,CAAE,EAAQ,CAEpE,EAAW,MACtB,EACA,EAAkD,CAAE,aAAc,GAAO,GAC/B,CAC1C,GAAM,CAAE,gBAAiB,EAMnB,EAAa,MAJA,EACfJ,EAAAA,QAAsB,UAAU,CAAC,MAAM,YAAY,CACnDA,EAAAA,QAAsB,MAAM,YAAY,EAER,SAAS,EAAI,CAC/C,QAAS,CACP,CACE,YAAa,oBACb,SAAU,GACV,WAAY,CAAC,cAAc,CAC5B,CACF,CACF,CAAC,CAOF,OALK,EAKE,EAAiC,EAAW,CAJ1C,MAOE,EAAkB,MAC7B,EACA,EACA,EAA0D,EAAE,GACvB,CACrC,GAAM,CAAE,UAAS,0BAA2B,EAAQ,aAC9CK,EAAsB,CAC1B,YACA,GAAI,CAAC,GAA0B,CAAE,SAAU,EAAGD,EAAAA,GAAG,IAAK,EAAW,CAAE,CACpE,CAED,OAAOJ,EAAAA,QAAsB,QAAQ,CACnC,QACA,YAAa,EAAQ,YACrB,QAAS,IAAU,EAAU,CAC7B,IAAK,GACN,CAAC,EAGS,EAAe,GAC1BA,EAAAA,QAAsB,MAAM,YAAY,CAAC,QAAQ,CAC/C,QACD,CAAC,CAaS,EAAS,MACpB,EACA,IACmC,CACnC,GAAM,CAAE,eAAc,GAAG,GAAmB,EAEtC,EAAS,MAAMA,EAAAA,QAAsB,UAAW,YAAY,KAAO,IAA6B,CACpG,IAAM,GAAqB,MAAMA,EAAAA,QAAsB,MAAM,YAAY,CAAC,OAAO,EAAgB,CAC/F,MAAO,CAAE,KAAI,CACb,UAAW,GACX,gBAAiB,GACjB,cACD,CAAC,EAAE,GAAG,GAEP,GAAI,EAAc,CAChB,IAAM,EAAmB,MAAMC,EAAAA,QAAwB,QAAQ,CAC7D,MAAO,CAAE,wBAAyB,EAAI,CACtC,WAAY,CAAC,KAAM,cAAc,CACjC,IAAK,GACL,cACD,CAAC,CAEI,EAAkB,EAAiB,IAAI,GAAK,EAAE,YAAY,CAE1D,EAAQ,EAAa,OAAO,GAAU,CAAC,EAAgB,SAAS,EAAO,CAAC,CACxE,EAAW,EAAiB,OAAO,GAAK,CAAC,EAAa,SAAS,EAAE,YAAY,CAAC,CAG9E,EAAoB,EAAS,OAAS,GAAK,EAAM,OAAS,EAE5D,EAAS,OAAS,GACpB,MAAMA,EAAAA,QAAwB,QAAQ,CACpC,MAAO,CACL,GAAI,EAAS,IAAI,GAAK,EAAE,GAAG,CAC5B,CACD,cACD,CAAC,CAGA,EAAM,OAAS,GACjB,MAAMA,EAAAA,QAAwB,WAC5B,EAAM,IAAI,IAAgB,CACxB,wBAAyB,EACzB,cACD,EAAE,CACH,CAAE,cAAa,CAChB,CAIC,IACF,EAAkB,QAAQ,YAAa,GAAK,CAC5C,MAAM,EAAkB,KAAK,CAAE,cAAa,CAAC,EAIjD,OAAO,GACP,CAIF,MAFA,GAAO,aAAe,GAAgB,EAAE,CAEjC,GAkDI,EAAoB,MAC/B,EACA,EAA8I,CAAE,aAAc,GAAO,UAAW,GAAI,GAC/I,CACrC,GAAM,CAAE,eAAc,YAAW,YAAW,gBAAiB,EAEvD,CAAE,UAAS,0BAA2B,GAAgB,EAAE,CAExDK,EAA0B,CAC9B,YACA,GAAI,CAAC,GAA0B,GAAa,EAAU,OAAS,GAAK,CAAE,SAAU,EAAGF,EAAAA,GAAG,IAAK,EAAW,CAAE,CACzG,CAEK,EAAa,EACdJ,EAAAA,QAA8B,UAAU,CACzCA,EAAAA,QAEEO,EAAsB,CAC1B,CACE,YAAa,oBACb,SAAU,GACV,WAAY,CAAC,KAAM,cAAc,CAClC,CACF,CAED,GAAI,GAA0B,GAAW,EAAW,CAClD,IAAM,EAAkB,EAAQ,EAAU,CAC1C,EAAa,KAAK,GAAG,EAAgB,CA0BvC,OAvBoB,MAAM,EAAW,MAAM,YAAY,CAAC,QAAQ,CAC9D,MAAO,EACP,QAAS,EACT,IAAK,GACL,YAAa,EAAQ,YACtB,CAAC,EAEsC,OAAQ,GAAa,CAC3D,IAAM,EAAW,EAAI,mBAAqB,EAAI,YAAY,mBAAqB,EAAE,CAWjF,MATI,CAAC,MAAM,QAAQ,EAAS,EAAI,EAAS,SAAW,EAC3C,GAGQ,EAAS,KAAM,IACR,EAAQ,aAAe,EAAQ,YAAY,eACxC,EACzB,EAGF,CAGyB,IAAI,EAAiC,EAGrD,EAAsC,MACjD,EACA,CACE,QAAS,EACT,eAAe,EAAE,CACjB,eAAe,GACf,GAAG,GACsC,CAAE,aAAc,GAAO,aAAc,EAAE,CAAE,GACjC,CACnD,GAAM,CAAE,aAAc,EAAU,IAAI,YAAc,EAAE,CAC9C,EAAe,IAAI,IACnB,EAAW,EAAE,CACb,EAAY,IAAI,IACtB,EAAU,QAAS,GAAa,CAC9B,GAAM,CAAE,WAAY,CAAE,UAAS,WAAU,aAAc,IAA2B,EAClF,EAAS,KAAK,EAAQ,CACtB,EAAU,IAAI,EAAS,CAEvB,OAAO,KAAK,GAAwB,EAAE,CAAC,CAAC,QAAS,GAAc,CAC7D,EAAa,IAAI,EAAU,EAC3B,EACF,CAEF,IAAMF,EAAsB,CAC1B,YACA,SAAU,EAAGD,EAAAA,GAAG,IAAK,MAAM,KAAK,EAAU,CAAE,CAC5C,KAAM,EAAGA,EAAAA,GAAG,IAAK,MAAM,KAAK,EAAa,CAAE,CAC5C,CAKK,EAAc,MAHC,GAAY,GAGM,EAAO,CAAE,eAAc,eAAc,GAAG,EAAS,CAAC,CAEnF,EAAqB,EAAY,OAAO,GAAO,EAAa,IAAI,EAAI,KAAK,CAAC,CAC1E,EAA2B,OAAO,YAAY,EAAmB,IAAI,GAAc,CAAC,EAAW,KAAM,EAAW,CAAC,CAAC,CAExH,GAAI,CAAC,GAAa,QAAU,EAAmB,SAAW,EAAa,KAErE,MAAM,IAAII,EAAAA,uBADoB,MAAM,KAAK,EAAa,CAAC,OAAO,GAAe,CAAC,EAAyB,GAAa,CAC7D,CAGzD,OAAO"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{MissingDefinitionError as e}from"../errors/index.js";import t from"../models/CustomFieldDefinition.js";import n from"../models/CustomFieldModelTypeMap.js";import"../models/index.js";import{Op as r}from"sequelize";const i=
|
|
1
|
+
import{MissingDefinitionError as e}from"../errors/index.js";import t from"../models/CustomFieldDefinition.js";import n from"../models/CustomFieldModelTypeMap.js";import"../models/index.js";import{Op as r}from"sequelize";const i=e=>!e||!Array.isArray(e)?[]:e.map(e=>e.modelTypeId||e.dataValues?.modelTypeId).filter(e=>!!e),a=e=>{let t=e;return e.modelTypeIds=i(t.modelTypeMappings??t.dataValues?.modelTypeMappings),e},o=async e=>{let{modelTypeIds:r,...i}=e,a=await t.sequelize.transaction(async e=>{let a=await t.create(i,{transaction:e});return r?.length&&await n.bulkCreate(r.map(e=>({customFieldDefinitionId:a.id,modelTypeId:e})),{transaction:e}),a});return a.modelTypeIds=r??[],a},s=async(e,n={withDisabled:!1})=>{let r=n.withDisabled?t.unscoped():t,i=n.include;if(n.enrichWithModelTypeIds){let e={association:`modelTypeMappings`,required:!1,attributes:[`modelTypeId`]};i=n.include?Array.isArray(n.include)?[...n.include,e]:[n.include,e]:e}let o=await r.scope(`userScope`).findAll({where:e,transaction:n.transaction,raw:!n.enrichWithModelTypeIds,include:i});return n.enrichWithModelTypeIds?o.map(a):o},c=(e,t={withDisabled:!1})=>s({id:{[r.in]:e}},t),l=async(e,n={withDisabled:!1})=>{let{withDisabled:r}=n,i=await(r?t.unscoped().scope(`userScope`):t.scope(`userScope`)).findByPk(e,{include:[{association:`modelTypeMappings`,required:!1,attributes:[`modelTypeId`]}]});return i?a(i):null},u=async(e,n,i={})=>{let{include:a,useEntityIdFromInclude:o}=i.modelOptions,s={modelType:e,...!o&&{entityId:{[r.in]:n}}};return t.findAll({where:s,transaction:i.transaction,include:a?.(n),raw:!0})},d=e=>t.scope(`userScope`).findOne({where:e}),f=async(e,r)=>{let{modelTypeIds:i,...a}=r,o=await t.sequelize.transaction(async r=>{let o=(await t.scope(`userScope`).update(a,{where:{id:e},returning:!0,individualHooks:!0,transaction:r}))[1][0];if(i){let t=await n.findAll({where:{customFieldDefinitionId:e},attributes:[`id`,`modelTypeId`],raw:!0,transaction:r}),a=t.map(e=>e.modelTypeId),s=i.filter(e=>!a.includes(e)),c=t.filter(e=>!i.includes(e.modelTypeId)),l=c.length>0||s.length>0;c.length>0&&await n.destroy({where:{id:c.map(e=>e.id)},transaction:r}),s.length>0&&await n.bulkCreate(s.map(t=>({customFieldDefinitionId:e,modelTypeId:t})),{transaction:r}),l&&(o.changed(`updatedAt`,!0),await o.save({transaction:r}))}return o});return o.modelTypeIds=i??[],o},p=async(e,n={withDisabled:!1,modelType:``})=>{let{withDisabled:i,entityIds:o,modelType:s,modelOptions:c}=n,{include:l,useEntityIdFromInclude:u}=c??{},d={modelType:s,...!u&&o&&o.length>0&&{entityId:{[r.in]:o}}},f=i?t.unscoped():t,p=[{association:`modelTypeMappings`,required:!1,attributes:[`id`,`modelTypeId`]}];if(u&&l&&o){let e=l(o);p.push(...e)}return(await f.scope(`userScope`).findAll({where:d,include:p,raw:!1,transaction:n.transaction})).filter(t=>{let n=t.modelTypeMappings||t.dataValues?.modelTypeMappings||[];return!Array.isArray(n)||n.length===0?!0:n.some(t=>(t.modelTypeId||t.dataValues?.modelTypeId)===e)}).map(a)},m=async(t,{findAll:n,modelOptions:i={},withDisabled:a=!1,...o}={withDisabled:!1,modelOptions:{}})=>{let{modelType:c}=t[0]?.dataValues??{},l=new Set,u=[],d=new Set;t.forEach(e=>{let{dataValues:{modelId:t,entityId:n,customFields:r}}=e;u.push(t),d.add(n),Object.keys(r??{}).forEach(e=>{l.add(e)})});let f={modelType:c,entityId:{[r.in]:Array.from(d)},name:{[r.in]:Array.from(l)}},p=await(n??s)(f,{withDisabled:a,modelOptions:i,...o}),m=p.filter(e=>l.has(e.name)),h=Object.fromEntries(m.map(e=>[e.name,e]));if(!p?.length||m.length!==l.size)throw new e(Array.from(l).filter(e=>!h[e]));return h};export{o as create,s as findAll,u as findByEntityIds,l as findById,c as findByIds,p as findByModelTypeId,d as findByWhere,m as getCustomFieldDefinitionsDictionary,f as update};
|
|
2
2
|
//# sourceMappingURL=definition.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.js","names":["CustomFieldModelTypeMap","CustomFieldDefinition","where: WhereOptions","baseWhere: WhereOptions","includeArray: any[]"],"sources":["../../src/repository/definition.ts"],"sourcesContent":["import {\n Op,\n type Includeable, type Transaction, type FindOptions, type WhereOptions, type Transactionable,\n} from 'sequelize';\nimport { CustomFieldDefinition, CustomFieldModelTypeMap, type CustomFieldEntries } from '../models';\nimport type { CreateCustomFieldDefinition, UpdateCustomFieldDefinition } from '../types/definition';\nimport type { ModelOptions } from '../types';\nimport { MissingDefinitionError } from '../errors';\n\n/**\n * Enriches a custom field definition with modelTypeIds array\n * Uses the model's setter which handles both the property and serialization\n */\nconst enrichWithModelTypeIds = async (\n definition: CustomFieldDefinition,\n): Promise<CustomFieldDefinition & { modelTypeIds?: string[]; }> => {\n try {\n const mappings = await CustomFieldModelTypeMap.findAll({\n where: { customFieldDefinitionId: definition.id },\n attributes: ['modelTypeId'],\n raw: true,\n });\n\n const modelTypeIds = mappings.map((m: { modelTypeId: string; }) => m.modelTypeId);\n\n definition.modelTypeIds = modelTypeIds;\n } catch {\n definition.modelTypeIds = [];\n }\n\n return definition as CustomFieldDefinition & { modelTypeIds?: string[]; };\n};\n\nexport const create = async (\n data: CreateCustomFieldDefinition,\n): Promise<CustomFieldDefinition> => {\n const { modelTypeIds, ...definitionData } = data;\n\n const result = await CustomFieldDefinition.sequelize!.transaction(async (transaction: Transaction) => {\n const customFieldDefinition = await CustomFieldDefinition.create(definitionData as any, {\n transaction,\n });\n\n if (modelTypeIds?.length) {\n await Promise.all(\n modelTypeIds.map(modelTypeId =>\n CustomFieldModelTypeMap.create({\n customFieldDefinitionId: customFieldDefinition.id,\n modelTypeId,\n }, {\n transaction,\n }),\n ),\n );\n }\n\n return customFieldDefinition;\n });\n\n return enrichWithModelTypeIds(result);\n};\n\ninterface SadotFindOptions {\n withDisabled?: boolean;\n transaction?: Transaction | null;\n include?: Includeable | Includeable[];\n enrichWithModelTypeIds?: boolean;\n}\n\ntype SadotGetDefinitionsByEntityIdsOptions = FindOptions & { modelOptions?: ModelOptions; findAll?: typeof findAll; } & Pick<SadotFindOptions, 'withDisabled'>;\n\nexport const findAll = async (\n where: WhereOptions,\n options: SadotFindOptions = { withDisabled: false },\n): Promise<CustomFieldDefinition[]> => {\n const queryModel = options.withDisabled\n ? CustomFieldDefinition.unscoped()\n : CustomFieldDefinition;\n\n const definitions = await queryModel.scope('userScope').findAll({\n where,\n transaction: options.transaction,\n raw: !options.enrichWithModelTypeIds,\n include: options.include,\n });\n\n if (options.enrichWithModelTypeIds) {\n return Promise.all(definitions.map(def => enrichWithModelTypeIds(def)));\n }\n\n return definitions;\n};\n\nexport const findByIds = (\n ids: string[],\n options: SadotFindOptions = { withDisabled: false },\n): Promise<CustomFieldDefinition[]> => findAll({ id: { [Op.in]: ids } }, options);\n\nexport const findById = async (\n id: string,\n options: Pick<SadotFindOptions, 'withDisabled'> = { withDisabled: false },\n): Promise<CustomFieldDefinition | null> => {\n const { withDisabled } = options;\n const definition = withDisabled\n ? await CustomFieldDefinition.unscoped().scope('userScope').findByPk(id)\n : await CustomFieldDefinition.scope('userScope').findByPk(id);\n\n if (!definition) {\n return null;\n }\n\n return enrichWithModelTypeIds(definition);\n};\n\nexport const findByEntityIds = async (\n modelType: string,\n entityIds: string[],\n options: FindOptions & { modelOptions?: ModelOptions; } = {},\n): Promise<CustomFieldDefinition[]> => {\n const { include, useEntityIdFromInclude } = options.modelOptions!;\n const where: WhereOptions = {\n modelType,\n ...(!useEntityIdFromInclude && { entityId: { [Op.in]: entityIds } }),\n };\n\n return CustomFieldDefinition.findAll({\n where,\n transaction: options.transaction,\n include: include?.(entityIds),\n raw: true,\n });\n};\n\nexport const findByWhere = (where: WhereOptions<CustomFieldDefinition>): Promise<CustomFieldDefinition | null> =>\n CustomFieldDefinition.scope('userScope').findOne({\n where,\n });\n\nexport const findDefinitionsByModels = async (\n modelTypes: string[],\n options?: Transactionable,\n): Promise<CustomFieldDefinition[]> => {\n const query: WhereOptions<CreateCustomFieldDefinition> = { modelType: { [Op.in]: modelTypes } };\n return CustomFieldDefinition.findAll({\n where: query,\n transaction: options?.transaction,\n });\n};\n\nexport const update = async (\n id: string,\n data: UpdateCustomFieldDefinition,\n): Promise<CustomFieldDefinition> => {\n const { modelTypeIds, ...definitionData } = data;\n\n const result = await CustomFieldDefinition.sequelize!.transaction(async (transaction: Transaction) => {\n const updatedDefinition = (await CustomFieldDefinition.scope('userScope').update(definitionData, {\n where: { id },\n returning: true,\n individualHooks: true,\n transaction,\n }))[1][0];\n\n if (modelTypeIds) {\n const existingMappings = await CustomFieldModelTypeMap.findAll({\n where: { customFieldDefinitionId: id },\n attributes: ['id', 'modelTypeId'],\n raw: true,\n transaction,\n });\n\n const existingTypeIds = existingMappings.map(m => m.modelTypeId);\n\n const toAdd = modelTypeIds.filter(typeId => !existingTypeIds.includes(typeId));\n const toRemove = existingMappings.filter(m => !modelTypeIds.includes(m.modelTypeId));\n\n // Check if there are any mapping changes\n const hasMappingChanges = toRemove.length > 0 || toAdd.length > 0;\n\n if (toRemove.length > 0) {\n await CustomFieldModelTypeMap.destroy({\n where: {\n id: toRemove.map(m => m.id),\n },\n transaction,\n });\n }\n\n if (toAdd.length > 0) {\n await Promise.all(\n toAdd.map(modelTypeId =>\n CustomFieldModelTypeMap.create({\n customFieldDefinitionId: id,\n modelTypeId,\n }, {\n transaction,\n }),\n ),\n );\n }\n\n // Touch the definition to update its updatedAt timestamp after mapping changes\n if (hasMappingChanges) {\n updatedDefinition.changed('updatedAt', true);\n await updatedDefinition.save({ transaction });\n }\n }\n\n return updatedDefinition;\n });\n\n return enrichWithModelTypeIds(result);\n};\n\nexport const disable = (id: string): Promise<[affectedCount: number]> =>\n CustomFieldDefinition.update(\n { disabled: true },\n { where: { id } },\n );\n\nexport const destroy = (id: string): Promise<number> =>\n CustomFieldDefinition.destroy({ where: { id } });\n\n/**\n * Return the names of the required fields for a given model\n */\nexport const getRequiredFields = async (\n modelType: string,\n modelId: string | string[],\n entityId: string | string[],\n modelOptions: ModelOptions = {},\n): Promise<string[]> => {\n const entityIds = Array.isArray(entityId) ? entityId : [entityId];\n const { include, useEntityIdFromInclude } = modelOptions;\n\n const where: WhereOptions = {\n modelType,\n required: true,\n ...(!useEntityIdFromInclude && { entityId: { [Op.in]: entityIds } }),\n };\n\n const requiredFields = await CustomFieldDefinition.findAll({\n where,\n include: include?.(entityIds),\n logging: true,\n });\n const requiredFieldsNames = requiredFields.map(definition => definition.name);\n return [...new Set(requiredFieldsNames)];\n};\n\n/**\n * @returns A promise resolving with a dictionary of custom field definitions by name.\n * @throws A {@link MissingDefinitionError} if any of the custom fields doesn't have a definition.\n */\n/**\n * Find custom field definitions applicable to a specific model type instance\n *\n * Returns definitions that either:\n * 1. Have NO mappings (apply to all instances of this model type)\n * 2. Have a mapping to this specific model type instance\n */\nexport const findByModelTypeId = async (\n modelTypeId: string,\n options: Pick<SadotFindOptions, 'withDisabled' | 'transaction'> & { entityIds?: string[]; modelType: string; modelOptions?: ModelOptions; } = { withDisabled: false, modelType: '' },\n): Promise<CustomFieldDefinition[]> => {\n const { withDisabled, entityIds, modelType, modelOptions } = options;\n\n const { include, useEntityIdFromInclude } = modelOptions ?? {};\n\n const baseWhere: WhereOptions = {\n modelType,\n ...(!useEntityIdFromInclude && entityIds && entityIds.length > 0 && { entityId: { [Op.in]: entityIds } }),\n };\n\n const queryModel = withDisabled\n ? (CustomFieldDefinition as any).unscoped()\n : CustomFieldDefinition;\n\n const includeArray: any[] = [\n {\n association: 'modelTypeMappings',\n required: false,\n attributes: ['id', 'modelTypeId'],\n },\n ];\n\n if (useEntityIdFromInclude && include && entityIds) {\n const contextIncludes = include(entityIds);\n includeArray.push(...contextIncludes);\n }\n\n const definitions = await queryModel.scope('userScope').findAll({\n where: baseWhere,\n include: includeArray,\n raw: false,\n transaction: options.transaction,\n });\n\n const filteredDefinitions = definitions.filter((def: any) => {\n const mappings = def.modelTypeMappings || def.dataValues?.modelTypeMappings || [];\n\n if (!Array.isArray(mappings) || mappings.length === 0) {\n return true;\n }\n\n const hasMatch = mappings.some((mapping: any) => {\n const mappingTypeId = mapping.modelTypeId || mapping.dataValues?.modelTypeId;\n return mappingTypeId === modelTypeId;\n });\n\n return hasMatch;\n });\n\n return Promise.all(filteredDefinitions.map((def: CustomFieldDefinition) => enrichWithModelTypeIds(def)));\n};\n\nexport const getCustomFieldDefinitionsDictionary = async (\n instances: CustomFieldEntries[],\n {\n findAll: _findAll,\n modelOptions = {},\n withDisabled = false,\n ...options\n }: SadotGetDefinitionsByEntityIdsOptions = { withDisabled: false, modelOptions: {} },\n): Promise<Record<string, CustomFieldDefinition>> => {\n const { modelType } = instances[0]?.dataValues ?? {};\n const customFields = new Set<string>();\n const modelIds = [];\n const entityIds = new Set<string>();\n instances.forEach((instance) => {\n const { dataValues: { modelId, entityId, customFields: instanceCustomFields } } = instance;\n modelIds.push(modelId);\n entityIds.add(entityId);\n\n Object.keys(instanceCustomFields ?? {}).forEach((fieldName) => {\n customFields.add(fieldName);\n });\n });\n\n const where: WhereOptions = {\n modelType,\n entityId: { [Op.in]: Array.from(entityIds) },\n name: { [Op.in]: Array.from(customFields) },\n };\n\n const findAllToUse = _findAll ?? findAll;\n\n // @ts-expect-error findAll doesn't expect modelOptions at all.\n const definitions = await findAllToUse(where, { withDisabled, modelOptions, ...options });\n\n const matchedDefinitions = definitions.filter(def => customFields.has(def.name));\n const matchedDefinitionsByName = Object.fromEntries(matchedDefinitions.map(definition => [definition.name, definition]));\n\n if (!definitions?.length || matchedDefinitions.length !== customFields.size) {\n const unmatchedCustomFields = Array.from(customFields).filter(customField => !matchedDefinitionsByName[customField]);\n throw new MissingDefinitionError(unmatchedCustomFields);\n }\n\n return matchedDefinitionsByName;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"definition.js","names":["CustomFieldDefinition","CustomFieldModelTypeMap","includeToUse: Includeable | Includeable[] | undefined","modelTypeMappingsInclude: Includeable","where: WhereOptions","baseWhere: WhereOptions","includeArray: any[]"],"sources":["../../src/repository/definition.ts"],"sourcesContent":["import {\n Op,\n type Includeable, type Transaction, type FindOptions, type WhereOptions, type Transactionable,\n} from 'sequelize';\nimport { CustomFieldDefinition, CustomFieldModelTypeMap, type CustomFieldEntries } from '../models';\nimport type { CreateCustomFieldDefinition, UpdateCustomFieldDefinition } from '../types/definition';\nimport type { ModelOptions } from '../types';\nimport { MissingDefinitionError } from '../errors';\n\n/**\n * Interface for mapping association data (can be raw or Sequelize model instance)\n */\ninterface MappingData {\n modelTypeId?: string;\n dataValues?: {\n modelTypeId?: string;\n };\n}\n\n/**\n * Helper to extract modelTypeIds from the modelTypeMappings association data\n * Handles both raw and non-raw Sequelize results\n */\nconst extractModelTypeIdsFromMappings = (mappings: MappingData[]): string[] => {\n if (!mappings || !Array.isArray(mappings)) {\n return [];\n }\n\n return mappings\n .map((m: MappingData) => m.modelTypeId || m.dataValues?.modelTypeId)\n .filter(id => Boolean(id)) as string[];\n};\n\n/**\n * Helper to extract modelTypeIds from a definition with loaded association\n * Handles the common pattern of getting mappings from a definition\n */\nconst enrichDefinitionWithModelTypeIds = (\n definition: CustomFieldDefinition,\n): CustomFieldDefinition & { modelTypeIds?: string[]; } => {\n const defWithMappings = definition as CustomFieldDefinition & {\n modelTypeMappings?: MappingData[];\n dataValues?: { modelTypeMappings?: MappingData[]; };\n };\n const mappings = defWithMappings.modelTypeMappings ?? defWithMappings.dataValues?.modelTypeMappings;\n definition.modelTypeIds = extractModelTypeIdsFromMappings(mappings);\n return definition as CustomFieldDefinition & { modelTypeIds?: string[]; };\n};\n\nexport const create = async (\n data: CreateCustomFieldDefinition,\n): Promise<CustomFieldDefinition> => {\n const { modelTypeIds, ...definitionData } = data;\n\n const result = await CustomFieldDefinition.sequelize!.transaction(async (transaction: Transaction) => {\n const customFieldDefinition = await CustomFieldDefinition.create(definitionData as any, {\n transaction,\n });\n\n if (modelTypeIds?.length) {\n await CustomFieldModelTypeMap.bulkCreate(\n modelTypeIds.map(modelTypeId => ({\n customFieldDefinitionId: customFieldDefinition.id,\n modelTypeId,\n })),\n { transaction },\n );\n }\n\n return customFieldDefinition;\n });\n\n result.modelTypeIds = modelTypeIds ?? [];\n\n return result as CustomFieldDefinition & { modelTypeIds?: string[]; };\n};\n\ninterface SadotFindOptions {\n withDisabled?: boolean;\n transaction?: Transaction | null;\n include?: Includeable | Includeable[];\n enrichWithModelTypeIds?: boolean;\n}\n\ntype SadotGetDefinitionsByEntityIdsOptions = FindOptions & { modelOptions?: ModelOptions; findAll?: typeof findAll; } & Pick<SadotFindOptions, 'withDisabled'>;\n\nexport const findAll = async (\n where: WhereOptions,\n options: SadotFindOptions = { withDisabled: false },\n): Promise<CustomFieldDefinition[]> => {\n const queryModel = options.withDisabled\n ? CustomFieldDefinition.unscoped()\n : CustomFieldDefinition;\n\n // Build include array - ensure we maintain the type compatibility\n let includeToUse: Includeable | Includeable[] | undefined = options.include;\n\n // If enrichWithModelTypeIds is requested, include the association to avoid N+1 queries\n if (options.enrichWithModelTypeIds) {\n const modelTypeMappingsInclude: Includeable = {\n association: 'modelTypeMappings',\n required: false,\n attributes: ['modelTypeId'],\n };\n\n if (options.include) {\n // Combine existing includes with modelTypeMappings\n includeToUse = Array.isArray(options.include)\n ? [...options.include, modelTypeMappingsInclude]\n : [options.include, modelTypeMappingsInclude];\n } else {\n includeToUse = modelTypeMappingsInclude;\n }\n }\n\n const definitions = await queryModel.scope('userScope').findAll({\n where,\n transaction: options.transaction,\n raw: !options.enrichWithModelTypeIds,\n include: includeToUse,\n });\n\n if (options.enrichWithModelTypeIds) {\n // Extract modelTypeIds from the included association data instead of making N queries\n return definitions.map(enrichDefinitionWithModelTypeIds);\n }\n\n return definitions;\n};\n\nexport const findByIds = (\n ids: string[],\n options: SadotFindOptions = { withDisabled: false },\n): Promise<CustomFieldDefinition[]> => findAll({ id: { [Op.in]: ids } }, options);\n\nexport const findById = async (\n id: string,\n options: Pick<SadotFindOptions, 'withDisabled'> = { withDisabled: false },\n): Promise<CustomFieldDefinition | null> => {\n const { withDisabled } = options;\n\n const queryModel = withDisabled\n ? CustomFieldDefinition.unscoped().scope('userScope')\n : CustomFieldDefinition.scope('userScope');\n\n const definition = await queryModel.findByPk(id, {\n include: [\n {\n association: 'modelTypeMappings',\n required: false,\n attributes: ['modelTypeId'],\n },\n ],\n });\n\n if (!definition) {\n return null;\n }\n\n // Extract modelTypeIds from the included association data\n return enrichDefinitionWithModelTypeIds(definition);\n};\n\nexport const findByEntityIds = async (\n modelType: string,\n entityIds: string[],\n options: FindOptions & { modelOptions?: ModelOptions; } = {},\n): Promise<CustomFieldDefinition[]> => {\n const { include, useEntityIdFromInclude } = options.modelOptions!;\n const where: WhereOptions = {\n modelType,\n ...(!useEntityIdFromInclude && { entityId: { [Op.in]: entityIds } }),\n };\n\n return CustomFieldDefinition.findAll({\n where,\n transaction: options.transaction,\n include: include?.(entityIds),\n raw: true,\n });\n};\n\nexport const findByWhere = (where: WhereOptions<CustomFieldDefinition>): Promise<CustomFieldDefinition | null> =>\n CustomFieldDefinition.scope('userScope').findOne({\n where,\n });\n\nexport const findDefinitionsByModels = async (\n modelTypes: string[],\n options?: Transactionable,\n): Promise<CustomFieldDefinition[]> => {\n const query: WhereOptions<CreateCustomFieldDefinition> = { modelType: { [Op.in]: modelTypes } };\n return CustomFieldDefinition.findAll({\n where: query,\n transaction: options?.transaction,\n });\n};\n\nexport const update = async (\n id: string,\n data: UpdateCustomFieldDefinition,\n): Promise<CustomFieldDefinition> => {\n const { modelTypeIds, ...definitionData } = data;\n\n const result = await CustomFieldDefinition.sequelize!.transaction(async (transaction: Transaction) => {\n const updatedDefinition = (await CustomFieldDefinition.scope('userScope').update(definitionData, {\n where: { id },\n returning: true,\n individualHooks: true,\n transaction,\n }))[1][0];\n\n if (modelTypeIds) {\n const existingMappings = await CustomFieldModelTypeMap.findAll({\n where: { customFieldDefinitionId: id },\n attributes: ['id', 'modelTypeId'],\n raw: true,\n transaction,\n });\n\n const existingTypeIds = existingMappings.map(m => m.modelTypeId);\n\n const toAdd = modelTypeIds.filter(typeId => !existingTypeIds.includes(typeId));\n const toRemove = existingMappings.filter(m => !modelTypeIds.includes(m.modelTypeId));\n\n // Check if there are any mapping changes\n const hasMappingChanges = toRemove.length > 0 || toAdd.length > 0;\n\n if (toRemove.length > 0) {\n await CustomFieldModelTypeMap.destroy({\n where: {\n id: toRemove.map(m => m.id),\n },\n transaction,\n });\n }\n\n if (toAdd.length > 0) {\n await CustomFieldModelTypeMap.bulkCreate(\n toAdd.map(modelTypeId => ({\n customFieldDefinitionId: id,\n modelTypeId,\n })),\n { transaction },\n );\n }\n\n // Touch the definition to update its updatedAt timestamp after mapping changes\n if (hasMappingChanges) {\n updatedDefinition.changed('updatedAt', true);\n await updatedDefinition.save({ transaction });\n }\n }\n\n return updatedDefinition;\n });\n\n result.modelTypeIds = modelTypeIds ?? [];\n\n return result as CustomFieldDefinition & { modelTypeIds?: string[]; };\n};\n\nexport const disable = (id: string): Promise<[affectedCount: number]> =>\n CustomFieldDefinition.update(\n { disabled: true },\n { where: { id } },\n );\n\nexport const destroy = (id: string): Promise<number> =>\n CustomFieldDefinition.destroy({ where: { id } });\n\n/**\n * Return the names of the required fields for a given model\n */\nexport const getRequiredFields = async (\n modelType: string,\n modelId: string | string[],\n entityId: string | string[],\n modelOptions: ModelOptions = {},\n): Promise<string[]> => {\n const entityIds = Array.isArray(entityId) ? entityId : [entityId];\n const { include, useEntityIdFromInclude } = modelOptions;\n\n const where: WhereOptions = {\n modelType,\n required: true,\n ...(!useEntityIdFromInclude && { entityId: { [Op.in]: entityIds } }),\n };\n\n const requiredFields = await CustomFieldDefinition.findAll({\n where,\n include: include?.(entityIds),\n logging: true,\n });\n const requiredFieldsNames = requiredFields.map(definition => definition.name);\n return [...new Set(requiredFieldsNames)];\n};\n\n/**\n * @returns A promise resolving with a dictionary of custom field definitions by name.\n * @throws A {@link MissingDefinitionError} if any of the custom fields doesn't have a definition.\n */\n/**\n * Find custom field definitions applicable to a specific model type instance\n *\n * Returns definitions that either:\n * 1. Have NO mappings (apply to all instances of this model type)\n * 2. Have a mapping to this specific model type instance\n */\nexport const findByModelTypeId = async (\n modelTypeId: string,\n options: Pick<SadotFindOptions, 'withDisabled' | 'transaction'> & { entityIds?: string[]; modelType: string; modelOptions?: ModelOptions; } = { withDisabled: false, modelType: '' },\n): Promise<CustomFieldDefinition[]> => {\n const { withDisabled, entityIds, modelType, modelOptions } = options;\n\n const { include, useEntityIdFromInclude } = modelOptions ?? {};\n\n const baseWhere: WhereOptions = {\n modelType,\n ...(!useEntityIdFromInclude && entityIds && entityIds.length > 0 && { entityId: { [Op.in]: entityIds } }),\n };\n\n const queryModel = withDisabled\n ? (CustomFieldDefinition as any).unscoped()\n : CustomFieldDefinition;\n\n const includeArray: any[] = [\n {\n association: 'modelTypeMappings',\n required: false,\n attributes: ['id', 'modelTypeId'],\n },\n ];\n\n if (useEntityIdFromInclude && include && entityIds) {\n const contextIncludes = include(entityIds);\n includeArray.push(...contextIncludes);\n }\n\n const definitions = await queryModel.scope('userScope').findAll({\n where: baseWhere,\n include: includeArray,\n raw: false,\n transaction: options.transaction,\n });\n\n const filteredDefinitions = definitions.filter((def: any) => {\n const mappings = def.modelTypeMappings || def.dataValues?.modelTypeMappings || [];\n\n if (!Array.isArray(mappings) || mappings.length === 0) {\n return true;\n }\n\n const hasMatch = mappings.some((mapping: any) => {\n const mappingTypeId = mapping.modelTypeId || mapping.dataValues?.modelTypeId;\n return mappingTypeId === modelTypeId;\n });\n\n return hasMatch;\n });\n\n // Use association data to extract modelTypeIds instead of making N additional queries\n return filteredDefinitions.map(enrichDefinitionWithModelTypeIds);\n};\n\nexport const getCustomFieldDefinitionsDictionary = async (\n instances: CustomFieldEntries[],\n {\n findAll: _findAll,\n modelOptions = {},\n withDisabled = false,\n ...options\n }: SadotGetDefinitionsByEntityIdsOptions = { withDisabled: false, modelOptions: {} },\n): Promise<Record<string, CustomFieldDefinition>> => {\n const { modelType } = instances[0]?.dataValues ?? {};\n const customFields = new Set<string>();\n const modelIds = [];\n const entityIds = new Set<string>();\n instances.forEach((instance) => {\n const { dataValues: { modelId, entityId, customFields: instanceCustomFields } } = instance;\n modelIds.push(modelId);\n entityIds.add(entityId);\n\n Object.keys(instanceCustomFields ?? {}).forEach((fieldName) => {\n customFields.add(fieldName);\n });\n });\n\n const where: WhereOptions = {\n modelType,\n entityId: { [Op.in]: Array.from(entityIds) },\n name: { [Op.in]: Array.from(customFields) },\n };\n\n const findAllToUse = _findAll ?? findAll;\n\n // @ts-expect-error findAll doesn't expect modelOptions at all.\n const definitions = await findAllToUse(where, { withDisabled, modelOptions, ...options });\n\n const matchedDefinitions = definitions.filter(def => customFields.has(def.name));\n const matchedDefinitionsByName = Object.fromEntries(matchedDefinitions.map(definition => [definition.name, definition]));\n\n if (!definitions?.length || matchedDefinitions.length !== customFields.size) {\n const unmatchedCustomFields = Array.from(customFields).filter(customField => !matchedDefinitionsByName[customField]);\n throw new MissingDefinitionError(unmatchedCustomFields);\n }\n\n return matchedDefinitionsByName;\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/sadot",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.16-beta-e2ec42dc.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -53,8 +53,8 @@
|
|
|
53
53
|
"npm-watch": "^0.11.0",
|
|
54
54
|
"supertest": "^7.0.0",
|
|
55
55
|
"@autofleet/errors": "^3.1.41",
|
|
56
|
-
"@autofleet/logger": "^4.2.45",
|
|
57
56
|
"@autofleet/node-common": "^4.2.23",
|
|
57
|
+
"@autofleet/logger": "^4.2.45",
|
|
58
58
|
"@autofleet/zehut": "^4.7.5"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|