attio-mcp 1.3.5 → 1.4.0

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.
Files changed (305) hide show
  1. package/CHANGELOG.md +263 -9
  2. package/README.md +315 -235
  3. package/dist/api/attio-client.d.ts +13 -3
  4. package/dist/api/attio-client.d.ts.map +1 -1
  5. package/dist/api/attio-client.js +37 -7
  6. package/dist/api/attio-client.js.map +1 -1
  7. package/dist/api/attribute-types.d.ts.map +1 -1
  8. package/dist/api/attribute-types.js +59 -29
  9. package/dist/api/attribute-types.js.map +1 -1
  10. package/dist/api/client-context.d.ts.map +1 -1
  11. package/dist/api/client-context.js +28 -42
  12. package/dist/api/client-context.js.map +1 -1
  13. package/dist/api/operations/batch.d.ts.map +1 -1
  14. package/dist/api/operations/batch.js +3 -1
  15. package/dist/api/operations/batch.js.map +1 -1
  16. package/dist/cli/commands/generate-skill.d.ts +28 -0
  17. package/dist/cli/commands/generate-skill.d.ts.map +1 -0
  18. package/dist/cli/commands/generate-skill.js +101 -0
  19. package/dist/cli/commands/generate-skill.js.map +1 -0
  20. package/dist/cli/discover.js +65 -0
  21. package/dist/cli/discover.js.map +1 -1
  22. package/dist/config/deal-defaults.d.ts +2 -2
  23. package/dist/config/deal-defaults.d.ts.map +1 -1
  24. package/dist/config/deal-defaults.js +15 -6
  25. package/dist/config/deal-defaults.js.map +1 -1
  26. package/dist/config/tool-aliases.d.ts +12 -0
  27. package/dist/config/tool-aliases.d.ts.map +1 -1
  28. package/dist/config/tool-aliases.js +213 -69
  29. package/dist/config/tool-aliases.js.map +1 -1
  30. package/dist/constants/tool-names.d.ts +84 -0
  31. package/dist/constants/tool-names.d.ts.map +1 -0
  32. package/dist/constants/tool-names.js +81 -0
  33. package/dist/constants/tool-names.js.map +1 -0
  34. package/dist/constants/universal.constants.d.ts +24 -0
  35. package/dist/constants/universal.constants.d.ts.map +1 -1
  36. package/dist/constants/universal.constants.js +81 -9
  37. package/dist/constants/universal.constants.js.map +1 -1
  38. package/dist/handlers/tool-configs/tasks.d.ts.map +1 -1
  39. package/dist/handlers/tool-configs/tasks.js +28 -0
  40. package/dist/handlers/tool-configs/tasks.js.map +1 -1
  41. package/dist/handlers/tool-configs/universal/batch-search.js +4 -4
  42. package/dist/handlers/tool-configs/universal/core/crud-error-handlers.d.ts +26 -4
  43. package/dist/handlers/tool-configs/universal/core/crud-error-handlers.d.ts.map +1 -1
  44. package/dist/handlers/tool-configs/universal/core/crud-error-handlers.js +181 -21
  45. package/dist/handlers/tool-configs/universal/core/crud-error-handlers.js.map +1 -1
  46. package/dist/handlers/tool-configs/universal/core/crud-operations.d.ts.map +1 -1
  47. package/dist/handlers/tool-configs/universal/core/crud-operations.js +52 -13
  48. package/dist/handlers/tool-configs/universal/core/crud-operations.js.map +1 -1
  49. package/dist/handlers/tool-configs/universal/core/detailed-info-operations.js +3 -3
  50. package/dist/handlers/tool-configs/universal/core/detailed-info-operations.js.map +1 -1
  51. package/dist/handlers/tool-configs/universal/core/error-enhancers/attribute-enhancer.d.ts +17 -0
  52. package/dist/handlers/tool-configs/universal/core/error-enhancers/attribute-enhancer.d.ts.map +1 -0
  53. package/dist/handlers/tool-configs/universal/core/error-enhancers/attribute-enhancer.js +118 -0
  54. package/dist/handlers/tool-configs/universal/core/error-enhancers/attribute-enhancer.js.map +1 -0
  55. package/dist/handlers/tool-configs/universal/core/error-enhancers/complex-type-enhancer.d.ts +14 -0
  56. package/dist/handlers/tool-configs/universal/core/error-enhancers/complex-type-enhancer.d.ts.map +1 -0
  57. package/dist/handlers/tool-configs/universal/core/error-enhancers/complex-type-enhancer.js +77 -0
  58. package/dist/handlers/tool-configs/universal/core/error-enhancers/complex-type-enhancer.js.map +1 -0
  59. package/dist/handlers/tool-configs/universal/core/error-enhancers/index.d.ts +24 -0
  60. package/dist/handlers/tool-configs/universal/core/error-enhancers/index.d.ts.map +1 -0
  61. package/dist/handlers/tool-configs/universal/core/error-enhancers/index.js +35 -0
  62. package/dist/handlers/tool-configs/universal/core/error-enhancers/index.js.map +1 -0
  63. package/dist/handlers/tool-configs/universal/core/error-enhancers/record-reference-enhancer.d.ts +15 -0
  64. package/dist/handlers/tool-configs/universal/core/error-enhancers/record-reference-enhancer.d.ts.map +1 -0
  65. package/dist/handlers/tool-configs/universal/core/error-enhancers/record-reference-enhancer.js +108 -0
  66. package/dist/handlers/tool-configs/universal/core/error-enhancers/record-reference-enhancer.js.map +1 -0
  67. package/dist/handlers/tool-configs/universal/core/error-enhancers/required-fields-enhancer.d.ts +14 -0
  68. package/dist/handlers/tool-configs/universal/core/error-enhancers/required-fields-enhancer.d.ts.map +1 -0
  69. package/dist/handlers/tool-configs/universal/core/error-enhancers/required-fields-enhancer.js +91 -0
  70. package/dist/handlers/tool-configs/universal/core/error-enhancers/required-fields-enhancer.js.map +1 -0
  71. package/dist/handlers/tool-configs/universal/core/error-enhancers/select-status-enhancer.d.ts +14 -0
  72. package/dist/handlers/tool-configs/universal/core/error-enhancers/select-status-enhancer.d.ts.map +1 -0
  73. package/dist/handlers/tool-configs/universal/core/error-enhancers/select-status-enhancer.js +118 -0
  74. package/dist/handlers/tool-configs/universal/core/error-enhancers/select-status-enhancer.js.map +1 -0
  75. package/dist/handlers/tool-configs/universal/core/error-enhancers/types.d.ts +77 -0
  76. package/dist/handlers/tool-configs/universal/core/error-enhancers/types.d.ts.map +1 -0
  77. package/dist/handlers/tool-configs/universal/core/error-enhancers/types.js +42 -0
  78. package/dist/handlers/tool-configs/universal/core/error-enhancers/types.js.map +1 -0
  79. package/dist/handlers/tool-configs/universal/core/error-enhancers/uniqueness-enhancer.d.ts +15 -0
  80. package/dist/handlers/tool-configs/universal/core/error-enhancers/uniqueness-enhancer.d.ts.map +1 -0
  81. package/dist/handlers/tool-configs/universal/core/error-enhancers/uniqueness-enhancer.js +109 -0
  82. package/dist/handlers/tool-configs/universal/core/error-enhancers/uniqueness-enhancer.js.map +1 -0
  83. package/dist/handlers/tool-configs/universal/core/index.d.ts +63 -22
  84. package/dist/handlers/tool-configs/universal/core/index.d.ts.map +1 -1
  85. package/dist/handlers/tool-configs/universal/core/index.js +24 -22
  86. package/dist/handlers/tool-configs/universal/core/index.js.map +1 -1
  87. package/dist/handlers/tool-configs/universal/core/metadata-operations.d.ts +43 -1
  88. package/dist/handlers/tool-configs/universal/core/metadata-operations.d.ts.map +1 -1
  89. package/dist/handlers/tool-configs/universal/core/metadata-operations.js +117 -11
  90. package/dist/handlers/tool-configs/universal/core/metadata-operations.js.map +1 -1
  91. package/dist/handlers/tool-configs/universal/core/notes-operations.d.ts.map +1 -1
  92. package/dist/handlers/tool-configs/universal/core/notes-operations.js +27 -12
  93. package/dist/handlers/tool-configs/universal/core/notes-operations.js.map +1 -1
  94. package/dist/handlers/tool-configs/universal/core/record-details-operations.d.ts.map +1 -1
  95. package/dist/handlers/tool-configs/universal/core/record-details-operations.js +20 -3
  96. package/dist/handlers/tool-configs/universal/core/record-details-operations.js.map +1 -1
  97. package/dist/handlers/tool-configs/universal/core/search-operations.d.ts.map +1 -1
  98. package/dist/handlers/tool-configs/universal/core/search-operations.js +11 -4
  99. package/dist/handlers/tool-configs/universal/core/search-operations.js.map +1 -1
  100. package/dist/handlers/tool-configs/universal/field-mapper/constants/companies.d.ts.map +1 -1
  101. package/dist/handlers/tool-configs/universal/field-mapper/constants/companies.js +32 -9
  102. package/dist/handlers/tool-configs/universal/field-mapper/constants/companies.js.map +1 -1
  103. package/dist/handlers/tool-configs/universal/field-mapper/constants/deals.d.ts.map +1 -1
  104. package/dist/handlers/tool-configs/universal/field-mapper/constants/deals.js +45 -6
  105. package/dist/handlers/tool-configs/universal/field-mapper/constants/deals.js.map +1 -1
  106. package/dist/handlers/tool-configs/universal/field-mapper/constants/people.d.ts.map +1 -1
  107. package/dist/handlers/tool-configs/universal/field-mapper/constants/people.js +36 -5
  108. package/dist/handlers/tool-configs/universal/field-mapper/constants/people.js.map +1 -1
  109. package/dist/handlers/tool-configs/universal/field-mapper/transformers/value-transformer.d.ts +1 -1
  110. package/dist/handlers/tool-configs/universal/field-mapper/transformers/value-transformer.d.ts.map +1 -1
  111. package/dist/handlers/tool-configs/universal/field-mapper/transformers/value-transformer.js +17 -1
  112. package/dist/handlers/tool-configs/universal/field-mapper/transformers/value-transformer.js.map +1 -1
  113. package/dist/handlers/tool-configs/universal/field-mapper/validators/field-validator.d.ts.map +1 -1
  114. package/dist/handlers/tool-configs/universal/field-mapper/validators/field-validator.js +3 -1
  115. package/dist/handlers/tool-configs/universal/field-mapper/validators/field-validator.js.map +1 -1
  116. package/dist/handlers/tool-configs/universal/index.d.ts +75 -34
  117. package/dist/handlers/tool-configs/universal/index.d.ts.map +1 -1
  118. package/dist/handlers/tool-configs/universal/index.js +58 -58
  119. package/dist/handlers/tool-configs/universal/index.js.map +1 -1
  120. package/dist/handlers/tool-configs/universal/operations/advanced-search.d.ts.map +1 -1
  121. package/dist/handlers/tool-configs/universal/operations/advanced-search.js +5 -4
  122. package/dist/handlers/tool-configs/universal/operations/advanced-search.js.map +1 -1
  123. package/dist/handlers/tool-configs/universal/operations/batch-operations.js +3 -3
  124. package/dist/handlers/tool-configs/universal/operations/content-search.js +3 -3
  125. package/dist/handlers/tool-configs/universal/operations/index.d.ts +10 -10
  126. package/dist/handlers/tool-configs/universal/operations/index.js +15 -15
  127. package/dist/handlers/tool-configs/universal/operations/relationship-search.js +3 -3
  128. package/dist/handlers/tool-configs/universal/operations/timeframe-search.js +3 -3
  129. package/dist/handlers/tool-configs/universal/schemas/utility-schemas.d.ts.map +1 -1
  130. package/dist/handlers/tool-configs/universal/schemas/utility-schemas.js +5 -2
  131. package/dist/handlers/tool-configs/universal/schemas/utility-schemas.js.map +1 -1
  132. package/dist/handlers/tool-configs/universal/schemas/validation-schemas.d.ts +29 -0
  133. package/dist/handlers/tool-configs/universal/schemas/validation-schemas.d.ts.map +1 -1
  134. package/dist/handlers/tool-configs/universal/schemas/validation-schemas.js +28 -0
  135. package/dist/handlers/tool-configs/universal/schemas/validation-schemas.js.map +1 -1
  136. package/dist/handlers/tool-configs/universal/schemas.d.ts +1 -1
  137. package/dist/handlers/tool-configs/universal/schemas.d.ts.map +1 -1
  138. package/dist/handlers/tool-configs/universal/schemas.js +1 -1
  139. package/dist/handlers/tool-configs/universal/schemas.js.map +1 -1
  140. package/dist/handlers/tool-configs/universal/shared-handlers.d.ts +20 -1
  141. package/dist/handlers/tool-configs/universal/shared-handlers.d.ts.map +1 -1
  142. package/dist/handlers/tool-configs/universal/shared-handlers.js +216 -0
  143. package/dist/handlers/tool-configs/universal/shared-handlers.js.map +1 -1
  144. package/dist/handlers/tool-configs/universal/smithery-diagnostics.js +2 -2
  145. package/dist/handlers/tool-configs/universal/types.d.ts +9 -0
  146. package/dist/handlers/tool-configs/universal/types.d.ts.map +1 -1
  147. package/dist/handlers/tool-configs/universal/validators/schema-validator.d.ts +11 -0
  148. package/dist/handlers/tool-configs/universal/validators/schema-validator.d.ts.map +1 -1
  149. package/dist/handlers/tool-configs/universal/validators/schema-validator.js +63 -9
  150. package/dist/handlers/tool-configs/universal/validators/schema-validator.js.map +1 -1
  151. package/dist/handlers/tool-types.d.ts +9 -0
  152. package/dist/handlers/tool-types.d.ts.map +1 -1
  153. package/dist/handlers/tools/dispatcher/core.d.ts.map +1 -1
  154. package/dist/handlers/tools/dispatcher/core.js +24 -5
  155. package/dist/handlers/tools/dispatcher/core.js.map +1 -1
  156. package/dist/handlers/tools/formatters.d.ts +8 -1
  157. package/dist/handlers/tools/formatters.d.ts.map +1 -1
  158. package/dist/handlers/tools/formatters.js +30 -14
  159. package/dist/handlers/tools/formatters.js.map +1 -1
  160. package/dist/handlers/tools/registry.d.ts +125 -84
  161. package/dist/handlers/tools/registry.d.ts.map +1 -1
  162. package/dist/handlers/tools/registry.js +14 -9
  163. package/dist/handlers/tools/registry.js.map +1 -1
  164. package/dist/handlers/tools/standards/index.d.ts.map +1 -1
  165. package/dist/handlers/tools/standards/index.js +19 -11
  166. package/dist/handlers/tools/standards/index.js.map +1 -1
  167. package/dist/objects/companies/attributes.d.ts +5 -0
  168. package/dist/objects/companies/attributes.d.ts.map +1 -1
  169. package/dist/objects/companies/attributes.js +45 -31
  170. package/dist/objects/companies/attributes.js.map +1 -1
  171. package/dist/server/createServer.d.ts.map +1 -1
  172. package/dist/server/createServer.js +4 -3
  173. package/dist/server/createServer.js.map +1 -1
  174. package/dist/services/ErrorService.js +3 -3
  175. package/dist/services/ErrorService.js.map +1 -1
  176. package/dist/services/UniversalCreateService.d.ts.map +1 -1
  177. package/dist/services/UniversalCreateService.js +136 -12
  178. package/dist/services/UniversalCreateService.js.map +1 -1
  179. package/dist/services/UniversalSearchService.d.ts +4 -25
  180. package/dist/services/UniversalSearchService.d.ts.map +1 -1
  181. package/dist/services/UniversalSearchService.js +14 -324
  182. package/dist/services/UniversalSearchService.js.map +1 -1
  183. package/dist/services/UniversalUpdateService.d.ts +15 -4
  184. package/dist/services/UniversalUpdateService.d.ts.map +1 -1
  185. package/dist/services/UniversalUpdateService.js +79 -151
  186. package/dist/services/UniversalUpdateService.js.map +1 -1
  187. package/dist/services/create/factory.d.ts.map +1 -1
  188. package/dist/services/create/factory.js +2 -1
  189. package/dist/services/create/factory.js.map +1 -1
  190. package/dist/services/metadata/AttributeOptionsService.d.ts +38 -0
  191. package/dist/services/metadata/AttributeOptionsService.d.ts.map +1 -0
  192. package/dist/services/metadata/AttributeOptionsService.js +92 -0
  193. package/dist/services/metadata/AttributeOptionsService.js.map +1 -0
  194. package/dist/services/metadata/index.d.ts +1 -0
  195. package/dist/services/metadata/index.d.ts.map +1 -1
  196. package/dist/services/metadata/index.js +1 -0
  197. package/dist/services/metadata/index.js.map +1 -1
  198. package/dist/services/search/QueryApiService.d.ts +27 -0
  199. package/dist/services/search/QueryApiService.d.ts.map +1 -0
  200. package/dist/services/search/QueryApiService.js +144 -0
  201. package/dist/services/search/QueryApiService.js.map +1 -0
  202. package/dist/services/search/RecordsSearchService.d.ts +27 -0
  203. package/dist/services/search/RecordsSearchService.d.ts.map +1 -0
  204. package/dist/services/search/RecordsSearchService.js +122 -0
  205. package/dist/services/search/RecordsSearchService.js.map +1 -0
  206. package/dist/services/search/SearchCoordinator.d.ts +41 -0
  207. package/dist/services/search/SearchCoordinator.d.ts.map +1 -0
  208. package/dist/services/search/SearchCoordinator.js +83 -0
  209. package/dist/services/search/SearchCoordinator.js.map +1 -0
  210. package/dist/services/search/StrategyFactory.d.ts +31 -0
  211. package/dist/services/search/StrategyFactory.d.ts.map +1 -0
  212. package/dist/services/search/StrategyFactory.js +100 -0
  213. package/dist/services/search/StrategyFactory.js.map +1 -0
  214. package/dist/services/skill-generator/OutputWriterService.d.ts +41 -0
  215. package/dist/services/skill-generator/OutputWriterService.d.ts.map +1 -0
  216. package/dist/services/skill-generator/OutputWriterService.js +100 -0
  217. package/dist/services/skill-generator/OutputWriterService.js.map +1 -0
  218. package/dist/services/skill-generator/SchemaFormatterService.d.ts +61 -0
  219. package/dist/services/skill-generator/SchemaFormatterService.d.ts.map +1 -0
  220. package/dist/services/skill-generator/SchemaFormatterService.js +168 -0
  221. package/dist/services/skill-generator/SchemaFormatterService.js.map +1 -0
  222. package/dist/services/skill-generator/WorkspaceSchemaService.d.ts +84 -0
  223. package/dist/services/skill-generator/WorkspaceSchemaService.d.ts.map +1 -0
  224. package/dist/services/skill-generator/WorkspaceSchemaService.js +292 -0
  225. package/dist/services/skill-generator/WorkspaceSchemaService.js.map +1 -0
  226. package/dist/services/skill-generator/index.d.ts +12 -0
  227. package/dist/services/skill-generator/index.d.ts.map +1 -0
  228. package/dist/services/skill-generator/index.js +11 -0
  229. package/dist/services/skill-generator/index.js.map +1 -0
  230. package/dist/services/skill-generator/types.d.ts +137 -0
  231. package/dist/services/skill-generator/types.d.ts.map +1 -0
  232. package/dist/services/skill-generator/types.js +10 -0
  233. package/dist/services/skill-generator/types.js.map +1 -0
  234. package/dist/services/update/FieldPersistenceHandler.d.ts +101 -0
  235. package/dist/services/update/FieldPersistenceHandler.d.ts.map +1 -0
  236. package/dist/services/update/FieldPersistenceHandler.js +198 -0
  237. package/dist/services/update/FieldPersistenceHandler.js.map +1 -0
  238. package/dist/services/update/FieldValidationHandler.d.ts +77 -0
  239. package/dist/services/update/FieldValidationHandler.d.ts.map +1 -0
  240. package/dist/services/update/FieldValidationHandler.js +157 -0
  241. package/dist/services/update/FieldValidationHandler.js.map +1 -0
  242. package/dist/services/update/MetadataResolver.d.ts +50 -0
  243. package/dist/services/update/MetadataResolver.d.ts.map +1 -0
  244. package/dist/services/update/MetadataResolver.js +110 -0
  245. package/dist/services/update/MetadataResolver.js.map +1 -0
  246. package/dist/services/update/UpdateOrchestrator.d.ts +37 -0
  247. package/dist/services/update/UpdateOrchestrator.d.ts.map +1 -0
  248. package/dist/services/update/UpdateOrchestrator.js +58 -0
  249. package/dist/services/update/UpdateOrchestrator.js.map +1 -0
  250. package/dist/services/update/UpdateValidation.d.ts +5 -1
  251. package/dist/services/update/UpdateValidation.d.ts.map +1 -1
  252. package/dist/services/update/UpdateValidation.js +46 -14
  253. package/dist/services/update/UpdateValidation.js.map +1 -1
  254. package/dist/services/value-transformer/index.d.ts +57 -0
  255. package/dist/services/value-transformer/index.d.ts.map +1 -0
  256. package/dist/services/value-transformer/index.js +326 -0
  257. package/dist/services/value-transformer/index.js.map +1 -0
  258. package/dist/services/value-transformer/multi-select-transformer.d.ts +63 -0
  259. package/dist/services/value-transformer/multi-select-transformer.d.ts.map +1 -0
  260. package/dist/services/value-transformer/multi-select-transformer.js +144 -0
  261. package/dist/services/value-transformer/multi-select-transformer.js.map +1 -0
  262. package/dist/services/value-transformer/record-reference-transformer.d.ts +43 -0
  263. package/dist/services/value-transformer/record-reference-transformer.d.ts.map +1 -0
  264. package/dist/services/value-transformer/record-reference-transformer.js +245 -0
  265. package/dist/services/value-transformer/record-reference-transformer.js.map +1 -0
  266. package/dist/services/value-transformer/select-transformer.d.ts +48 -0
  267. package/dist/services/value-transformer/select-transformer.d.ts.map +1 -0
  268. package/dist/services/value-transformer/select-transformer.js +232 -0
  269. package/dist/services/value-transformer/select-transformer.js.map +1 -0
  270. package/dist/services/value-transformer/status-transformer.d.ts +32 -0
  271. package/dist/services/value-transformer/status-transformer.d.ts.map +1 -0
  272. package/dist/services/value-transformer/status-transformer.js +294 -0
  273. package/dist/services/value-transformer/status-transformer.js.map +1 -0
  274. package/dist/services/value-transformer/types.d.ts +100 -0
  275. package/dist/services/value-transformer/types.d.ts.map +1 -0
  276. package/dist/services/value-transformer/types.js +6 -0
  277. package/dist/services/value-transformer/types.js.map +1 -0
  278. package/dist/templates/skill/SKILL.template.md +78 -0
  279. package/dist/templates/skill/attribute-reference.template.md +126 -0
  280. package/dist/templates/skill/complex-types.template.md +255 -0
  281. package/dist/utils/client-resolver.d.ts.map +1 -1
  282. package/dist/utils/client-resolver.js +8 -16
  283. package/dist/utils/client-resolver.js.map +1 -1
  284. package/dist/utils/complex-type-validation.d.ts +16 -0
  285. package/dist/utils/complex-type-validation.d.ts.map +1 -0
  286. package/dist/utils/complex-type-validation.js +196 -0
  287. package/dist/utils/complex-type-validation.js.map +1 -0
  288. package/dist/utils/error-utilities.d.ts.map +1 -1
  289. package/dist/utils/error-utilities.js +16 -9
  290. package/dist/utils/error-utilities.js.map +1 -1
  291. package/dist/utils/location-normalizer.d.ts +26 -0
  292. package/dist/utils/location-normalizer.d.ts.map +1 -0
  293. package/dist/utils/location-normalizer.js +39 -0
  294. package/dist/utils/location-normalizer.js.map +1 -0
  295. package/dist/utils/metadata-utils.d.ts +27 -0
  296. package/dist/utils/metadata-utils.d.ts.map +1 -0
  297. package/dist/utils/metadata-utils.js +59 -0
  298. package/dist/utils/metadata-utils.js.map +1 -0
  299. package/dist/utils/personal-name-parser.d.ts.map +1 -1
  300. package/dist/utils/personal-name-parser.js +26 -17
  301. package/dist/utils/personal-name-parser.js.map +1 -1
  302. package/dist/validators/company/field_detector.d.ts.map +1 -1
  303. package/dist/validators/company/field_detector.js +5 -0
  304. package/dist/validators/company/field_detector.js.map +1 -1
  305. package/package.json +28 -25
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Select transformer - converts select option titles to ["title"] array format
3
+ *
4
+ * Problem: LLMs commonly pass select values as human-readable strings
5
+ * (e.g., "Technology", "Potential Customer") but Attio API requires
6
+ * array format: ["title"]
7
+ *
8
+ * Solution: Auto-detect single-select attributes (type="select" AND
9
+ * is_multiselect !== true) and transform string titles to title arrays.
10
+ *
11
+ * NOTE: Attio API accepts ["title"] format and silently rejects ["uuid"] format
12
+ * despite returning HTTP 200 OK (Issue #1045). This transformer uses titles.
13
+ *
14
+ * @see Issue #1019, #1045
15
+ */
16
+ import { AttributeOptionsService } from '../../services/metadata/index.js';
17
+ import { isValidUUID } from '../../utils/validation/uuid-validation.js';
18
+ import { debug, error as logError, OperationType } from '../../utils/logger.js';
19
+ import { DEFAULT_ATTRIBUTES_CACHE_TTL } from '../../constants/universal.constants.js';
20
+ /**
21
+ * In-memory cache for select options
22
+ * Key format: {objectSlug}:{attributeSlug}
23
+ */
24
+ const selectOptionsCache = new Map();
25
+ /**
26
+ * TTL for select options cache (5 minutes)
27
+ */
28
+ const SELECT_CACHE_TTL = DEFAULT_ATTRIBUTES_CACHE_TTL;
29
+ /**
30
+ * Generate cache key for select options
31
+ */
32
+ function getCacheKey(objectSlug, attributeSlug) {
33
+ return `${objectSlug}:${attributeSlug}`;
34
+ }
35
+ /**
36
+ * Clear all cached select options (for testing)
37
+ */
38
+ export function clearSelectCache() {
39
+ selectOptionsCache.clear();
40
+ }
41
+ /**
42
+ * Clean up expired cache entries
43
+ * Called periodically (10% chance) to prevent memory growth
44
+ */
45
+ function cleanupExpiredEntries() {
46
+ const now = Date.now();
47
+ const keysToDelete = [];
48
+ for (const [key, entry] of selectOptionsCache.entries()) {
49
+ if (now - entry.timestamp >= SELECT_CACHE_TTL) {
50
+ keysToDelete.push(key);
51
+ }
52
+ }
53
+ for (const key of keysToDelete) {
54
+ selectOptionsCache.delete(key);
55
+ }
56
+ if (keysToDelete.length > 0) {
57
+ debug('select-transformer', `Cleaned up ${keysToDelete.length} expired cache entries`, { expiredKeys: keysToDelete.length }, 'cleanupExpiredEntries', OperationType.DATA_PROCESSING);
58
+ }
59
+ }
60
+ /**
61
+ * Fetch select options with TTL-based caching
62
+ *
63
+ * @param objectSlug - Object slug (e.g., "companies")
64
+ * @param attributeSlug - Attribute slug (e.g., "industry")
65
+ * @returns Array of select options
66
+ */
67
+ async function getSelectOptionsWithCache(objectSlug, attributeSlug) {
68
+ const cacheKey = getCacheKey(objectSlug, attributeSlug);
69
+ const now = Date.now();
70
+ // Check cache with TTL validation
71
+ if (selectOptionsCache.has(cacheKey)) {
72
+ const cached = selectOptionsCache.get(cacheKey);
73
+ const age = now - cached.timestamp;
74
+ if (age < SELECT_CACHE_TTL) {
75
+ debug('select-transformer', `Using cached select options for ${objectSlug}.${attributeSlug}`, {
76
+ age: `${Math.round(age / 1000)}s`,
77
+ ttl: `${SELECT_CACHE_TTL / 1000}s`,
78
+ }, 'getSelectOptionsWithCache', OperationType.DATA_PROCESSING);
79
+ return cached.data;
80
+ }
81
+ // Expired entry: delete and continue to fetch
82
+ selectOptionsCache.delete(cacheKey);
83
+ debug('select-transformer', 'Cache expired, fetching fresh data', { objectSlug, attributeSlug }, 'getSelectOptionsWithCache', OperationType.DATA_PROCESSING);
84
+ }
85
+ // Periodic cleanup (10% of requests)
86
+ if (Math.random() < 0.1) {
87
+ cleanupExpiredEntries();
88
+ }
89
+ // Fetch fresh data via AttributeOptionsService
90
+ try {
91
+ const result = await AttributeOptionsService.getOptions(objectSlug, attributeSlug, true // include archived for complete matching
92
+ );
93
+ // Map result to normalized AttributeOption format
94
+ const options = result.options.map((opt) => ({
95
+ id: 'id' in opt ? opt.id : '',
96
+ title: opt.title,
97
+ is_archived: opt.is_archived,
98
+ }));
99
+ // Store with timestamp
100
+ selectOptionsCache.set(cacheKey, {
101
+ data: options,
102
+ timestamp: now,
103
+ });
104
+ debug('select-transformer', 'Cached fresh select options', { objectSlug, attributeSlug, optionCount: options.length }, 'getSelectOptionsWithCache', OperationType.DATA_PROCESSING);
105
+ return options;
106
+ }
107
+ catch (err) {
108
+ logError('select-transformer', `Failed to fetch select options for ${objectSlug}.${attributeSlug}`, err);
109
+ return [];
110
+ }
111
+ }
112
+ /**
113
+ * Find a select option by title (case-insensitive with partial matching)
114
+ *
115
+ * @param options - Available select options
116
+ * @param title - Title to match
117
+ * @returns Matched option or undefined
118
+ */
119
+ function findOptionByTitle(options, title) {
120
+ const titleLower = title.toLowerCase().trim();
121
+ // Priority 1: Exact match (case-insensitive)
122
+ const exactMatch = options.find((opt) => opt.title.toLowerCase() === titleLower);
123
+ if (exactMatch)
124
+ return exactMatch;
125
+ // Priority 2: Partial match (one-directional: option title contains input)
126
+ return options.find((opt) => opt.title.toLowerCase().includes(titleLower));
127
+ }
128
+ /**
129
+ * Check if an attribute is a single-select (NOT multi-select)
130
+ *
131
+ * CRITICAL (Issue #992): Attio uses type="select" for BOTH single-select
132
+ * and multi-select. The is_multiselect flag distinguishes them.
133
+ *
134
+ * - Single-select: type="select" && is_multiselect !== true
135
+ * - Multi-select: type="select" && is_multiselect === true
136
+ *
137
+ * Multi-select is handled by multi-select-transformer, so we skip here.
138
+ */
139
+ function isSingleSelectAttribute(meta) {
140
+ return meta.type === 'select' && meta.is_multiselect !== true;
141
+ }
142
+ /**
143
+ * Create a "no transformation needed" result
144
+ */
145
+ function noTransform(value) {
146
+ return { transformed: false, originalValue: value, transformedValue: value };
147
+ }
148
+ /**
149
+ * Transform a select value from string title to ["title"] array format
150
+ *
151
+ * Supports:
152
+ * - Case-insensitive title matching: "technology" → ["Technology"]
153
+ * - Partial matching: "Tech" → ["Technology"] (if matches "Technology")
154
+ * - UUID pass-through: "uuid-string" → ["uuid-string"] (no API lookup)
155
+ * - Error suggestions: Lists valid options on invalid input
156
+ *
157
+ * NOTE: Uses ["title"] format not ["uuid"] because Attio API silently
158
+ * rejects UUID arrays despite returning HTTP 200 OK (Issue #1045).
159
+ *
160
+ * @param value - The value to transform
161
+ * @param attributeSlug - The attribute slug
162
+ * @param context - Transformation context
163
+ * @param attributeMeta - Attribute metadata (must be single-select)
164
+ * @returns Transform result with ["title"] array format
165
+ */
166
+ export async function transformSelectValue(value, attributeSlug, context, attributeMeta) {
167
+ // Guard: Only transform single-select string values not already in array format
168
+ if (!isSingleSelectAttribute(attributeMeta))
169
+ return noTransform(value);
170
+ if (Array.isArray(value))
171
+ return noTransform(value);
172
+ if (typeof value !== 'string')
173
+ return noTransform(value);
174
+ // Short-circuit: UUID string detection (skip lookup)
175
+ if (isValidUUID(value)) {
176
+ const transformedValue = [value];
177
+ debug('select-transformer', 'Detected UUID string for select attribute', { attribute: attributeSlug, matchType: 'uuid-passthrough' }, 'transformSelectValue', OperationType.DATA_PROCESSING);
178
+ return {
179
+ transformed: true,
180
+ originalValue: value,
181
+ transformedValue,
182
+ description: `Wrapped UUID string in array for ${attributeSlug}`,
183
+ };
184
+ }
185
+ // Map resource type to object slug
186
+ const objectSlug = context.resourceType.toLowerCase();
187
+ // Fetch select options with caching
188
+ const options = await getSelectOptionsWithCache(objectSlug, attributeSlug);
189
+ if (options.length === 0) {
190
+ debug('select-transformer', `No select options found for ${objectSlug}.${attributeSlug}`, { hasValue: !!value, valueType: typeof value }, 'transformSelectValue', OperationType.DATA_PROCESSING);
191
+ return noTransform(value);
192
+ }
193
+ // Find matching option
194
+ const match = findOptionByTitle(options, value);
195
+ if (!match) {
196
+ // No match - throw error with valid options
197
+ const validOptions = options
198
+ .filter((opt) => !opt.is_archived)
199
+ .map((opt) => `"${opt.title}"`)
200
+ .join(', ');
201
+ throw new Error(`Invalid select value "${value}" for ${attributeSlug}. ` +
202
+ `Valid options are: ${validOptions}`);
203
+ }
204
+ // Transform to array format with option title
205
+ // NOTE: Attio API accepts ["title"] format, but silently rejects ["uuid"] format (Issue #1045)
206
+ const transformedValue = [match.title];
207
+ debug('select-transformer', 'Transformed select value', {
208
+ attribute: attributeSlug,
209
+ matchType: match.title.toLowerCase() === value.toLowerCase().trim()
210
+ ? 'exact'
211
+ : 'partial',
212
+ matchedTitle: match.title,
213
+ }, 'transformSelectValue', OperationType.DATA_PROCESSING);
214
+ return {
215
+ transformed: true,
216
+ originalValue: value,
217
+ transformedValue,
218
+ description: `Converted select title "${value}" to ["${match.title}"]`,
219
+ };
220
+ }
221
+ /**
222
+ * Get valid select options for error messages
223
+ *
224
+ * @param objectSlug - Object slug
225
+ * @param attributeSlug - Attribute slug
226
+ * @returns Array of valid option titles
227
+ */
228
+ export async function getValidSelectOptions(objectSlug, attributeSlug) {
229
+ const options = await getSelectOptionsWithCache(objectSlug, attributeSlug);
230
+ return options.filter((opt) => !opt.is_archived).map((opt) => opt.title);
231
+ }
232
+ //# sourceMappingURL=select-transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-transformer.js","sourceRoot":"","sources":["../../../src/services/value-transformer/select-transformer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Status transformer - converts status titles to Attio status object format
3
+ *
4
+ * Problem: LLMs commonly pass status values as strings (e.g., "Demo Scheduling")
5
+ * but Attio API requires a structured object for status attributes.
6
+ *
7
+ * Solution: Auto-detect status attributes and transform string titles to the
8
+ * required object format by looking up the status ID from the workspace options.
9
+ *
10
+ * Note: Attio expects the key `status` (not `status_id`). The value can be the
11
+ * status UUID. We always wrap as an array to match Attio attribute value shapes.
12
+ */
13
+ import { TransformContext, TransformResult, AttributeMetadata } from './types.js';
14
+ /**
15
+ * Clear the status options cache (useful for testing)
16
+ */
17
+ export declare function clearStatusCache(): void;
18
+ /**
19
+ * Transform a status value from string title to Attio status object format
20
+ *
21
+ * @param value - The value to transform
22
+ * @param attributeSlug - The attribute slug (e.g., "stage")
23
+ * @param context - Transformation context
24
+ * @param attributeMeta - Attribute metadata (must have type "status")
25
+ * @returns Transform result
26
+ */
27
+ export declare function transformStatusValue(value: unknown, attributeSlug: string, context: TransformContext, attributeMeta: AttributeMetadata): Promise<TransformResult>;
28
+ /**
29
+ * Get valid status options for error messages
30
+ */
31
+ export declare function getValidStatusOptions(objectSlug: string, attributeSlug: string): Promise<string[]>;
32
+ //# sourceMappingURL=status-transformer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-transformer.d.ts","sourceRoot":"","sources":["../../../src/services/value-transformer/status-transformer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAiCpB;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAsOD;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,OAAO,EACd,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,gBAAgB,EACzB,aAAa,EAAE,iBAAiB,GAC/B,OAAO,CAAC,eAAe,CAAC,CA6H1B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnB"}
@@ -0,0 +1,294 @@
1
+ /**
2
+ * Status transformer - converts status titles to Attio status object format
3
+ *
4
+ * Problem: LLMs commonly pass status values as strings (e.g., "Demo Scheduling")
5
+ * but Attio API requires a structured object for status attributes.
6
+ *
7
+ * Solution: Auto-detect status attributes and transform string titles to the
8
+ * required object format by looking up the status ID from the workspace options.
9
+ *
10
+ * Note: Attio expects the key `status` (not `status_id`). The value can be the
11
+ * status UUID. We always wrap as an array to match Attio attribute value shapes.
12
+ */
13
+ import { AttributeOptionsService } from '../../services/metadata/index.js';
14
+ import { isValidUUID } from '../../utils/validation/uuid-validation.js';
15
+ import { debug, error as logError, OperationType } from '../../utils/logger.js';
16
+ import { DEFAULT_ATTRIBUTES_CACHE_TTL } from '../../constants/universal.constants.js';
17
+ /**
18
+ * Cache for status options with TTL-based expiration
19
+ * @see Issue #984 - Add 5-minute TTL to prevent stale data
20
+ */
21
+ const statusOptionsCache = new Map();
22
+ /**
23
+ * TTL for status options cache (5 minutes)
24
+ */
25
+ const STATUS_CACHE_TTL = DEFAULT_ATTRIBUTES_CACHE_TTL;
26
+ /**
27
+ * Get cache key for status options
28
+ */
29
+ function getCacheKey(objectSlug, attributeSlug) {
30
+ return `${objectSlug}:${attributeSlug}`;
31
+ }
32
+ /**
33
+ * Clear the status options cache (useful for testing)
34
+ */
35
+ export function clearStatusCache() {
36
+ statusOptionsCache.clear();
37
+ }
38
+ /**
39
+ * Clean up expired cache entries (lazy eviction)
40
+ * @see Issue #984 - Remove expired entries to prevent memory growth
41
+ */
42
+ function cleanupExpiredEntries() {
43
+ const now = Date.now();
44
+ const keysToDelete = [];
45
+ for (const [key, entry] of statusOptionsCache.entries()) {
46
+ if (now - entry.timestamp >= STATUS_CACHE_TTL) {
47
+ keysToDelete.push(key);
48
+ }
49
+ }
50
+ for (const key of keysToDelete) {
51
+ statusOptionsCache.delete(key);
52
+ }
53
+ if (keysToDelete.length > 0) {
54
+ debug('status-transformer', `Cleaned up ${keysToDelete.length} expired cache entries`, { expiredKeys: keysToDelete.length }, 'cleanupExpiredEntries', OperationType.DATA_PROCESSING);
55
+ }
56
+ }
57
+ /**
58
+ * Fetch status options with TTL-based caching
59
+ * @see Issue #984 - Add TTL expiration to prevent stale data
60
+ */
61
+ async function getStatusOptionsWithCache(objectSlug, attributeSlug) {
62
+ const cacheKey = getCacheKey(objectSlug, attributeSlug);
63
+ const now = Date.now();
64
+ // Check cache with TTL
65
+ if (statusOptionsCache.has(cacheKey)) {
66
+ const cached = statusOptionsCache.get(cacheKey);
67
+ const age = now - cached.timestamp;
68
+ if (age < STATUS_CACHE_TTL) {
69
+ debug('status-transformer', `Using cached status options for ${objectSlug}.${attributeSlug}`, {
70
+ age: `${Math.round(age / 1000)}s`,
71
+ ttl: `${STATUS_CACHE_TTL / 1000}s`,
72
+ }, 'getStatusOptionsWithCache', OperationType.DATA_PROCESSING);
73
+ return cached.data;
74
+ }
75
+ // Expired, remove it
76
+ statusOptionsCache.delete(cacheKey);
77
+ debug('status-transformer', `Cache expired for ${objectSlug}.${attributeSlug}`, { age: `${Math.round(age / 1000)}s` }, 'getStatusOptionsWithCache', OperationType.DATA_PROCESSING);
78
+ }
79
+ // Periodically clean up expired entries (every 10th fetch)
80
+ if (Math.random() < 0.1) {
81
+ cleanupExpiredEntries();
82
+ }
83
+ // Fetch fresh data
84
+ try {
85
+ const result = await AttributeOptionsService.getOptions(objectSlug, attributeSlug, true // include archived for complete matching
86
+ );
87
+ const options = result.options.map((opt) => {
88
+ // Extract status ID - handle both string and object formats from Attio API
89
+ let id = '';
90
+ if ('id' in opt && opt.id) {
91
+ if (typeof opt.id === 'string') {
92
+ // Simple string ID
93
+ id = opt.id;
94
+ }
95
+ else if (typeof opt.id === 'object' && opt.id !== null) {
96
+ // Object ID structure: { workspace_id, object_id, attribute_id, option_id }
97
+ const idObj = opt.id;
98
+ if ('option_id' in idObj && typeof idObj.option_id === 'string') {
99
+ id = idObj.option_id;
100
+ }
101
+ else if ('status_id' in idObj &&
102
+ typeof idObj.status_id === 'string') {
103
+ id = idObj.status_id;
104
+ }
105
+ }
106
+ }
107
+ return {
108
+ id,
109
+ title: opt.title,
110
+ is_archived: opt.is_archived,
111
+ };
112
+ });
113
+ // Cache with timestamp
114
+ statusOptionsCache.set(cacheKey, {
115
+ data: options,
116
+ timestamp: now,
117
+ });
118
+ debug('status-transformer', `Cached fresh status options for ${objectSlug}.${attributeSlug}`, { optionCount: options.length }, 'getStatusOptionsWithCache', OperationType.DATA_PROCESSING);
119
+ return options;
120
+ }
121
+ catch (err) {
122
+ logError('status-transformer', `Failed to fetch status options for ${objectSlug}.${attributeSlug}`, err);
123
+ return [];
124
+ }
125
+ }
126
+ /**
127
+ * Find status ID by title (case-insensitive)
128
+ */
129
+ function findStatusByTitle(options, title) {
130
+ const titleLower = title.toLowerCase().trim();
131
+ // First try exact match (case-insensitive)
132
+ const exactMatch = options.find((opt) => opt.title.toLowerCase() === titleLower);
133
+ if (exactMatch)
134
+ return exactMatch;
135
+ // Then try partial match
136
+ const partialMatch = options.find((opt) => opt.title.toLowerCase().includes(titleLower) ||
137
+ titleLower.includes(opt.title.toLowerCase()));
138
+ return partialMatch;
139
+ }
140
+ /**
141
+ * Check if a value is already in the correct status format
142
+ */
143
+ function isStatusFormat(value) {
144
+ if (!Array.isArray(value) || value.length === 0)
145
+ return false;
146
+ const first = value[0];
147
+ if (!first || typeof first !== 'object' || Array.isArray(first))
148
+ return false;
149
+ return 'status' in first;
150
+ }
151
+ function hasStringKey(value, key) {
152
+ return (typeof value === 'object' &&
153
+ value !== null &&
154
+ !Array.isArray(value) &&
155
+ key in value &&
156
+ typeof value[key] === 'string');
157
+ }
158
+ function normalizeIncomingStatusValue(value) {
159
+ // Already-correct Attio form: [{ status: "..." }]
160
+ if (isStatusFormat(value)) {
161
+ return { normalized: value };
162
+ }
163
+ // Handle array-of-objects with the legacy key: [{ status_id: "..." }] → [{ status: "..." }]
164
+ if (Array.isArray(value) &&
165
+ value.length > 0 &&
166
+ hasStringKey(value[0], 'status_id')) {
167
+ return { normalized: [{ status: value[0].status_id }] };
168
+ }
169
+ // Handle single object forms (common mistakes): { status: "..." } / { status_id: "..." }
170
+ if (hasStringKey(value, 'status')) {
171
+ return {
172
+ normalized: [{ status: value.status }],
173
+ extractedText: value.status,
174
+ };
175
+ }
176
+ if (hasStringKey(value, 'status_id')) {
177
+ return {
178
+ normalized: [{ status: value.status_id }],
179
+ extractedText: value.status_id,
180
+ };
181
+ }
182
+ // Handle array of string values: ["Demo Scheduling"] → "Demo Scheduling"
183
+ if (Array.isArray(value) &&
184
+ value.length > 0 &&
185
+ typeof value[0] === 'string') {
186
+ return { normalized: value, extractedText: value[0] };
187
+ }
188
+ return { normalized: value };
189
+ }
190
+ /**
191
+ * Transform a status value from string title to Attio status object format
192
+ *
193
+ * @param value - The value to transform
194
+ * @param attributeSlug - The attribute slug (e.g., "stage")
195
+ * @param context - Transformation context
196
+ * @param attributeMeta - Attribute metadata (must have type "status")
197
+ * @returns Transform result
198
+ */
199
+ export async function transformStatusValue(value, attributeSlug, context, attributeMeta) {
200
+ // Only transform status type attributes
201
+ if (attributeMeta.type !== 'status') {
202
+ return {
203
+ transformed: false,
204
+ originalValue: value,
205
+ transformedValue: value,
206
+ };
207
+ }
208
+ const normalizedIncoming = normalizeIncomingStatusValue(value);
209
+ const normalizedValue = normalizedIncoming.normalized;
210
+ // Skip if already in correct Attio format after normalization
211
+ if (isStatusFormat(normalizedValue)) {
212
+ return {
213
+ transformed: normalizedValue !== value,
214
+ originalValue: value,
215
+ transformedValue: normalizedValue,
216
+ description: normalizedValue !== value
217
+ ? `Normalized status value format for ${attributeSlug}`
218
+ : undefined,
219
+ };
220
+ }
221
+ const extractedText = typeof normalizedIncoming.extractedText === 'string'
222
+ ? normalizedIncoming.extractedText
223
+ : typeof normalizedValue === 'string'
224
+ ? normalizedValue
225
+ : undefined;
226
+ // Only transform string-like values
227
+ if (typeof extractedText !== 'string') {
228
+ return {
229
+ transformed: false,
230
+ originalValue: value,
231
+ transformedValue: normalizedValue,
232
+ };
233
+ }
234
+ // Short-circuit if value is already a UUID
235
+ if (isValidUUID(extractedText)) {
236
+ const transformedValue = [{ status: extractedText }];
237
+ debug('status-transformer', `Detected UUID string for status attribute`, {
238
+ attribute: attributeSlug,
239
+ from: extractedText,
240
+ to: transformedValue,
241
+ }, 'transformStatusValue', OperationType.DATA_PROCESSING);
242
+ return {
243
+ transformed: true,
244
+ originalValue: value,
245
+ transformedValue,
246
+ description: `Converted UUID string to status object for ${attributeSlug}`,
247
+ };
248
+ }
249
+ // Map resource type to object slug
250
+ const objectSlug = context.resourceType.toLowerCase();
251
+ // Fetch status options
252
+ const options = await getStatusOptionsWithCache(objectSlug, attributeSlug);
253
+ if (options.length === 0) {
254
+ debug('status-transformer', `No status options found for ${objectSlug}.${attributeSlug}`, { value: extractedText }, 'transformStatusValue', OperationType.DATA_PROCESSING);
255
+ return {
256
+ transformed: false,
257
+ originalValue: value,
258
+ transformedValue: normalizedValue,
259
+ };
260
+ }
261
+ // Find matching status
262
+ const match = findStatusByTitle(options, extractedText);
263
+ if (!match) {
264
+ // No match found - return error with valid options
265
+ const validOptions = options
266
+ .filter((opt) => !opt.is_archived)
267
+ .map((opt) => `"${opt.title}"`)
268
+ .join(', ');
269
+ throw new Error(`Invalid status value "${extractedText}" for ${attributeSlug}. ` +
270
+ `Valid options are: ${validOptions}`);
271
+ }
272
+ // Transform to status ID format
273
+ const transformedValue = [{ status: match.id }];
274
+ debug('status-transformer', `Transformed status value`, {
275
+ attribute: attributeSlug,
276
+ from: extractedText,
277
+ to: transformedValue,
278
+ matchedTitle: match.title,
279
+ }, 'transformStatusValue', OperationType.DATA_PROCESSING);
280
+ return {
281
+ transformed: true,
282
+ originalValue: value,
283
+ transformedValue,
284
+ description: `Converted status title "${extractedText}" to status "${match.id}" (matched: "${match.title}")`,
285
+ };
286
+ }
287
+ /**
288
+ * Get valid status options for error messages
289
+ */
290
+ export async function getValidStatusOptions(objectSlug, attributeSlug) {
291
+ const options = await getStatusOptionsWithCache(objectSlug, attributeSlug);
292
+ return options.filter((opt) => !opt.is_archived).map((opt) => opt.title);
293
+ }
294
+ //# sourceMappingURL=status-transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-transformer.js","sourceRoot":"","sources":["../../../src/services/value-transformer/status-transformer.ts"],"names":[],"mappings":"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"}