@autofleet/sadot 1.2.16-beta-e2ec42dc.0 → 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.
@@ -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=e=>!e||!Array.isArray(e)?[]:e.map(e=>e.modelTypeId||e.dataValues?.modelTypeId).filter(e=>!!e),o=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},s=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 o=await r.scope(`userScope`).findAll({where:e,transaction:t.transaction,raw:!t.enrichWithModelTypeIds,include:i});return t.enrichWithModelTypeIds?o.map(e=>{let t=e;return e.modelTypeIds=a(t.modelTypeMappings??t.dataValues?.modelTypeMappings),e}):o},c=(e,t={withDisabled:!1})=>s({id:{[i.Op.in]:e}},t),l=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`]}]});if(!i)return null;let o=i;return i.modelTypeIds=a(o.modelTypeMappings??o.dataValues?.modelTypeMappings),i},u=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})},d=e=>n.default.scope(`userScope`).findOne({where:e}),f=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},p=async(e,t={withDisabled:!1,modelType:``})=>{let{withDisabled:r,entityIds:o,modelType:s,modelOptions:c}=t,{include:l,useEntityIdFromInclude:u}=c??{},d={modelType:s,...!u&&o&&o.length>0&&{entityId:{[i.Op.in]:o}}},f=r?n.default.unscoped():n.default,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: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(e=>(e.modelTypeIds=a(e.modelTypeMappings||e.dataValues?.modelTypeMappings),e))},m=async(e,{findAll:n,modelOptions:r={},withDisabled:a=!1,...o}={withDisabled:!1,modelOptions:{}})=>{let{modelType:c}=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:c,entityId:{[i.Op.in]:Array.from(d)},name:{[i.Op.in]:Array.from(l)}},p=await(n??s)(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=o,exports.findAll=s,exports.findByEntityIds=u,exports.findById=l,exports.findByIds=c,exports.findByModelTypeId=p,exports.findByWhere=d,exports.getCustomFieldDefinitionsDictionary=m,exports.update=f;
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":["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\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((def: CustomFieldDefinition) => {\n const defWithMappings = def as CustomFieldDefinition & {\n modelTypeMappings?: MappingData[];\n dataValues?: { modelTypeMappings?: MappingData[]; };\n };\n const mappings = defWithMappings.modelTypeMappings ?? defWithMappings.dataValues?.modelTypeMappings;\n def.modelTypeIds = extractModelTypeIdsFromMappings(mappings);\n return def as CustomFieldDefinition & { modelTypeIds?: string[]; };\n });\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 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\n return definition as CustomFieldDefinition & { modelTypeIds?: string[]; };\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((def: any) => {\n const mappings = def.modelTypeMappings || def.dataValues?.modelTypeMappings;\n def.modelTypeIds = extractModelTypeIdsFromMappings(mappings);\n return def as CustomFieldDefinition & { modelTypeIds?: string[]; };\n });\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":"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"}
@@ -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=e=>!e||!Array.isArray(e)?[]:e.map(e=>e.modelTypeId||e.dataValues?.modelTypeId).filter(e=>!!e),a=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},o=async(e,n={withDisabled:!1})=>{let r=n.withDisabled?t.unscoped():t,a=n.include;if(n.enrichWithModelTypeIds){let e={association:`modelTypeMappings`,required:!1,attributes:[`modelTypeId`]};a=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:a});return n.enrichWithModelTypeIds?o.map(e=>{let t=e;return e.modelTypeIds=i(t.modelTypeMappings??t.dataValues?.modelTypeMappings),e}):o},s=(e,t={withDisabled:!1})=>o({id:{[r.in]:e}},t),c=async(e,n={withDisabled:!1})=>{let{withDisabled:r}=n,a=await(r?t.unscoped().scope(`userScope`):t.scope(`userScope`)).findByPk(e,{include:[{association:`modelTypeMappings`,required:!1,attributes:[`modelTypeId`]}]});if(!a)return null;let o=a;return a.modelTypeIds=i(o.modelTypeMappings??o.dataValues?.modelTypeMappings),a},l=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})},u=e=>t.scope(`userScope`).findOne({where:e}),d=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},f=async(e,n={withDisabled:!1,modelType:``})=>{let{withDisabled:a,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=a?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(e=>(e.modelTypeIds=i(e.modelTypeMappings||e.dataValues?.modelTypeMappings),e))},p=async(t,{findAll:n,modelOptions:i={},withDisabled:a=!1,...s}={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??o)(f,{withDisabled:a,modelOptions:i,...s}),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{a as create,o as findAll,l as findByEntityIds,c as findById,s as findByIds,f as findByModelTypeId,u as findByWhere,p as getCustomFieldDefinitionsDictionary,d as update};
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":["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\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((def: CustomFieldDefinition) => {\n const defWithMappings = def as CustomFieldDefinition & {\n modelTypeMappings?: MappingData[];\n dataValues?: { modelTypeMappings?: MappingData[]; };\n };\n const mappings = defWithMappings.modelTypeMappings ?? defWithMappings.dataValues?.modelTypeMappings;\n def.modelTypeIds = extractModelTypeIdsFromMappings(mappings);\n return def as CustomFieldDefinition & { modelTypeIds?: string[]; };\n });\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 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\n return definition as CustomFieldDefinition & { modelTypeIds?: string[]; };\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((def: any) => {\n const mappings = def.modelTypeMappings || def.dataValues?.modelTypeMappings;\n def.modelTypeIds = extractModelTypeIdsFromMappings(mappings);\n return def as CustomFieldDefinition & { modelTypeIds?: string[]; };\n });\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":"4NAuBA,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,EAAsB,UAAW,YAAY,KAAO,IAA6B,CACpG,IAAM,EAAwB,MAAMA,EAAsB,OAAO,EAAuB,CACtF,cACD,CAAC,CAYF,OAVI,GAAc,QAChB,MAAMC,EAAwB,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,EAAsB,UAAU,CAChCA,EAGAE,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,EAAG,EAAG,IAAK,EAAK,CAAE,CAAE,EAAQ,CAEpE,EAAW,MACtB,EACA,EAAkD,CAAE,aAAc,GAAO,GAC/B,CAC1C,GAAM,CAAE,gBAAiB,EAMnB,EAAa,MAJA,EACfH,EAAsB,UAAU,CAAC,MAAM,YAAY,CACnDA,EAAsB,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,aAC9CI,EAAsB,CAC1B,YACA,GAAI,CAAC,GAA0B,CAAE,SAAU,EAAG,EAAG,IAAK,EAAW,CAAE,CACpE,CAED,OAAOJ,EAAsB,QAAQ,CACnC,QACA,YAAa,EAAQ,YACrB,QAAS,IAAU,EAAU,CAC7B,IAAK,GACN,CAAC,EAGS,EAAe,GAC1BA,EAAsB,MAAM,YAAY,CAAC,QAAQ,CAC/C,QACD,CAAC,CAaS,EAAS,MACpB,EACA,IACmC,CACnC,GAAM,CAAE,eAAc,GAAG,GAAmB,EAEtC,EAAS,MAAMA,EAAsB,UAAW,YAAY,KAAO,IAA6B,CACpG,IAAM,GAAqB,MAAMA,EAAsB,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,EAAwB,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,EAAwB,QAAQ,CACpC,MAAO,CACL,GAAI,EAAS,IAAI,GAAK,EAAE,GAAG,CAC5B,CACD,cACD,CAAC,CAGA,EAAM,OAAS,GACjB,MAAMA,EAAwB,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,CAExDI,EAA0B,CAC9B,YACA,GAAI,CAAC,GAA0B,GAAa,EAAU,OAAS,GAAK,CAAE,SAAU,EAAG,EAAG,IAAK,EAAW,CAAE,CACzG,CAEK,EAAa,EACdL,EAA8B,UAAU,CACzCA,EAEEM,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,EAAG,EAAG,IAAK,MAAM,KAAK,EAAU,CAAE,CAC5C,KAAM,EAAG,EAAG,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,IAAI,EADoB,MAAM,KAAK,EAAa,CAAC,OAAO,GAAe,CAAC,EAAyB,GAAa,CAC7D,CAGzD,OAAO"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/sadot",
3
- "version": "1.2.16-beta-e2ec42dc.0",
3
+ "version": "1.2.16-beta-e2ec42dc.1",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",