@peernova/cuneiform-sf 1.0.2 → 1.0.4-beta.10

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 (488) hide show
  1. package/LICENSE +81 -30
  2. package/README.md +168 -134
  3. package/lib/adapters/connection-facade.d.ts +458 -0
  4. package/lib/adapters/connection-facade.js +379 -0
  5. package/lib/adapters/connection-facade.js.map +1 -0
  6. package/lib/adapters/errors.d.ts +547 -0
  7. package/lib/adapters/errors.js +937 -0
  8. package/lib/adapters/errors.js.map +1 -0
  9. package/lib/adapters/lifecycle.d.ts +112 -0
  10. package/lib/adapters/lifecycle.js +94 -0
  11. package/lib/adapters/lifecycle.js.map +1 -0
  12. package/lib/adapters/rest/cache.d.ts +69 -0
  13. package/lib/adapters/rest/cache.js +133 -0
  14. package/lib/adapters/rest/cache.js.map +1 -0
  15. package/lib/adapters/rest/index.d.ts +11 -0
  16. package/lib/adapters/rest/index.js +18 -0
  17. package/lib/adapters/rest/index.js.map +1 -0
  18. package/lib/adapters/rest/profiling-rest-client.d.ts +137 -0
  19. package/lib/adapters/rest/profiling-rest-client.js +115 -0
  20. package/lib/adapters/rest/profiling-rest-client.js.map +1 -0
  21. package/lib/adapters/rest/rest-api-adapter.d.ts +393 -0
  22. package/lib/adapters/rest/rest-api-adapter.js +764 -0
  23. package/lib/adapters/rest/rest-api-adapter.js.map +1 -0
  24. package/lib/adapters/rest/types.d.ts +34 -0
  25. package/lib/adapters/rest/types.js +9 -0
  26. package/lib/adapters/rest/types.js.map +1 -0
  27. package/lib/adapters/retry.d.ts +91 -0
  28. package/lib/adapters/retry.js +215 -0
  29. package/lib/adapters/retry.js.map +1 -0
  30. package/lib/adapters/soql/cuneiform-query-builder.d.ts +418 -0
  31. package/lib/adapters/soql/cuneiform-query-builder.js +606 -0
  32. package/lib/adapters/soql/cuneiform-query-builder.js.map +1 -0
  33. package/lib/adapters/soql/soql-query-adapter.d.ts +141 -0
  34. package/lib/adapters/soql/soql-query-adapter.js +259 -0
  35. package/lib/adapters/soql/soql-query-adapter.js.map +1 -0
  36. package/lib/adapters/soql/types.d.ts +37 -0
  37. package/lib/adapters/soql/types.js +19 -0
  38. package/lib/adapters/soql/types.js.map +1 -0
  39. package/lib/adapters/testing/index.d.ts +37 -0
  40. package/lib/adapters/testing/index.js +20 -0
  41. package/lib/adapters/testing/index.js.map +1 -0
  42. package/lib/adapters/testing/mock-connection.d.ts +77 -0
  43. package/lib/adapters/testing/mock-connection.js +207 -0
  44. package/lib/adapters/testing/mock-connection.js.map +1 -0
  45. package/lib/adapters/testing/mock-logger.d.ts +29 -0
  46. package/lib/adapters/testing/mock-logger.js +57 -0
  47. package/lib/adapters/testing/mock-logger.js.map +1 -0
  48. package/lib/adapters/testing/mock-mcp-adapters.d.ts +32 -0
  49. package/lib/adapters/testing/mock-mcp-adapters.js +52 -0
  50. package/lib/adapters/testing/mock-mcp-adapters.js.map +1 -0
  51. package/lib/adapters/testing/mock-oclif-config.d.ts +22 -0
  52. package/lib/adapters/testing/mock-oclif-config.js +90 -0
  53. package/lib/adapters/testing/mock-oclif-config.js.map +1 -0
  54. package/lib/adapters/testing/mock-rest-adapter.d.ts +26 -0
  55. package/lib/adapters/testing/mock-rest-adapter.js +243 -0
  56. package/lib/adapters/testing/mock-rest-adapter.js.map +1 -0
  57. package/lib/adapters/testing/mock-salesforce-connection.d.ts +40 -0
  58. package/lib/adapters/testing/mock-salesforce-connection.js +61 -0
  59. package/lib/adapters/testing/mock-salesforce-connection.js.map +1 -0
  60. package/lib/adapters/testing/mock-soql-adapter.d.ts +30 -0
  61. package/lib/adapters/testing/mock-soql-adapter.js +120 -0
  62. package/lib/adapters/testing/mock-soql-adapter.js.map +1 -0
  63. package/lib/adapters/testing/mock-tooling-adapter.d.ts +24 -0
  64. package/lib/adapters/testing/mock-tooling-adapter.js +163 -0
  65. package/lib/adapters/testing/mock-tooling-adapter.js.map +1 -0
  66. package/lib/adapters/testing/stub-connection.d.ts +93 -0
  67. package/lib/adapters/testing/stub-connection.js +97 -0
  68. package/lib/adapters/testing/stub-connection.js.map +1 -0
  69. package/lib/adapters/testing/stub-rest-adapter.d.ts +52 -0
  70. package/lib/adapters/testing/stub-rest-adapter.js +58 -0
  71. package/lib/adapters/testing/stub-rest-adapter.js.map +1 -0
  72. package/lib/adapters/testing/stub-soql-adapter.d.ts +56 -0
  73. package/lib/adapters/testing/stub-soql-adapter.js +50 -0
  74. package/lib/adapters/testing/stub-soql-adapter.js.map +1 -0
  75. package/lib/adapters/testing/types.d.ts +71 -0
  76. package/lib/adapters/testing/types.js +9 -0
  77. package/lib/adapters/testing/types.js.map +1 -0
  78. package/lib/adapters/tooling/index.d.ts +10 -0
  79. package/lib/adapters/tooling/index.js +17 -0
  80. package/lib/adapters/tooling/index.js.map +1 -0
  81. package/lib/adapters/tooling/tooling-api-adapter.d.ts +157 -0
  82. package/lib/adapters/tooling/tooling-api-adapter.js +339 -0
  83. package/lib/adapters/tooling/tooling-api-adapter.js.map +1 -0
  84. package/lib/adapters/tooling/types.d.ts +81 -0
  85. package/lib/adapters/tooling/types.js +9 -0
  86. package/lib/adapters/tooling/types.js.map +1 -0
  87. package/lib/adapters/types.d.ts +112 -0
  88. package/lib/adapters/types.js +169 -0
  89. package/lib/adapters/types.js.map +1 -0
  90. package/lib/base/cuneiform-command.d.ts +175 -0
  91. package/lib/base/cuneiform-command.js +326 -0
  92. package/lib/base/cuneiform-command.js.map +1 -0
  93. package/lib/commands/cuneiform/compatibility/check.d.ts +43 -0
  94. package/lib/commands/cuneiform/compatibility/check.js +114 -0
  95. package/lib/commands/cuneiform/compatibility/check.js.map +1 -0
  96. package/lib/commands/cuneiform/definition/create.d.ts +120 -0
  97. package/lib/commands/cuneiform/definition/create.js +737 -0
  98. package/lib/commands/cuneiform/definition/create.js.map +1 -0
  99. package/lib/commands/cuneiform/definition/export.d.ts +57 -0
  100. package/lib/commands/cuneiform/definition/export.js +133 -0
  101. package/lib/commands/cuneiform/definition/export.js.map +1 -0
  102. package/lib/commands/cuneiform/definition/get.d.ts +86 -0
  103. package/lib/commands/cuneiform/definition/get.js +277 -0
  104. package/lib/commands/cuneiform/definition/get.js.map +1 -0
  105. package/lib/commands/cuneiform/definition/import.d.ts +54 -0
  106. package/lib/commands/cuneiform/definition/import.js +118 -0
  107. package/lib/commands/cuneiform/definition/import.js.map +1 -0
  108. package/lib/commands/cuneiform/definition/list.d.ts +110 -0
  109. package/lib/commands/cuneiform/definition/list.js +351 -0
  110. package/lib/commands/cuneiform/definition/list.js.map +1 -0
  111. package/lib/commands/cuneiform/definition/purge.d.ts +109 -0
  112. package/lib/commands/cuneiform/definition/purge.js +578 -0
  113. package/lib/commands/cuneiform/definition/purge.js.map +1 -0
  114. package/lib/commands/cuneiform/definition/update.d.ts +58 -0
  115. package/lib/commands/cuneiform/definition/update.js +209 -0
  116. package/lib/commands/cuneiform/definition/update.js.map +1 -0
  117. package/lib/commands/cuneiform/mcp/serve.d.ts +56 -0
  118. package/lib/commands/cuneiform/mcp/serve.js +109 -0
  119. package/lib/commands/cuneiform/mcp/serve.js.map +1 -0
  120. package/lib/commands/cuneiform/object/describe.d.ts +61 -0
  121. package/lib/commands/cuneiform/object/describe.js +461 -0
  122. package/lib/commands/cuneiform/object/describe.js.map +1 -0
  123. package/lib/commands/cuneiform/object/list.d.ts +123 -0
  124. package/lib/commands/cuneiform/object/list.js +264 -0
  125. package/lib/commands/cuneiform/object/list.js.map +1 -0
  126. package/lib/commands/cuneiform/org/details.d.ts +99 -0
  127. package/lib/commands/cuneiform/org/details.js +521 -0
  128. package/lib/commands/cuneiform/org/details.js.map +1 -0
  129. package/lib/commands/cuneiform/org/reset.d.ts +46 -0
  130. package/lib/commands/cuneiform/org/reset.js +135 -0
  131. package/lib/commands/cuneiform/org/reset.js.map +1 -0
  132. package/lib/commands/cuneiform/profile/request/cancel.d.ts +59 -0
  133. package/lib/commands/cuneiform/profile/request/cancel.js +202 -0
  134. package/lib/commands/cuneiform/profile/request/cancel.js.map +1 -0
  135. package/lib/commands/cuneiform/profile/request/delete.d.ts +59 -0
  136. package/lib/commands/cuneiform/profile/request/delete.js +223 -0
  137. package/lib/commands/cuneiform/profile/request/delete.js.map +1 -0
  138. package/lib/commands/cuneiform/profile/request/list.d.ts +35 -0
  139. package/lib/commands/cuneiform/profile/request/list.js +102 -0
  140. package/lib/commands/cuneiform/profile/request/list.js.map +1 -0
  141. package/lib/commands/cuneiform/profile.d.ts +93 -0
  142. package/lib/commands/cuneiform/profile.js +353 -0
  143. package/lib/commands/cuneiform/profile.js.map +1 -0
  144. package/lib/commands/cuneiform/summary/purge.d.ts +80 -0
  145. package/lib/commands/cuneiform/summary/purge.js +467 -0
  146. package/lib/commands/cuneiform/summary/purge.js.map +1 -0
  147. package/lib/commands/cuneiform/summary/reprofile.d.ts +60 -0
  148. package/lib/commands/cuneiform/summary/reprofile.js +236 -0
  149. package/lib/commands/cuneiform/summary/reprofile.js.map +1 -0
  150. package/lib/commands/cuneiform/summary/stop.d.ts +59 -0
  151. package/lib/commands/cuneiform/summary/stop.js +234 -0
  152. package/lib/commands/cuneiform/summary/stop.js.map +1 -0
  153. package/lib/commands/cuneiform/user/details.d.ts +77 -0
  154. package/lib/commands/cuneiform/user/details.js +414 -0
  155. package/lib/commands/cuneiform/user/details.js.map +1 -0
  156. package/lib/constants/namespace-constants.d.ts +102 -0
  157. package/lib/constants/namespace-constants.js +225 -0
  158. package/lib/constants/namespace-constants.js.map +1 -0
  159. package/lib/debug/command-debug-proxy.d.ts +101 -0
  160. package/lib/debug/command-debug-proxy.js +171 -0
  161. package/lib/debug/command-debug-proxy.js.map +1 -0
  162. package/lib/debug/debug-logger.d.ts +85 -0
  163. package/lib/debug/debug-logger.js +133 -0
  164. package/lib/debug/debug-logger.js.map +1 -0
  165. package/lib/debug/service-debug-proxy.d.ts +30 -0
  166. package/lib/debug/service-debug-proxy.js +102 -0
  167. package/lib/debug/service-debug-proxy.js.map +1 -0
  168. package/lib/hooks/prerun.d.ts +25 -0
  169. package/lib/hooks/prerun.js +47 -0
  170. package/lib/hooks/prerun.js.map +1 -0
  171. package/lib/mcp/config/mcp-config.d.ts +55 -0
  172. package/lib/mcp/config/mcp-config.js +51 -0
  173. package/lib/mcp/config/mcp-config.js.map +1 -0
  174. package/lib/mcp/config/pagination.d.ts +96 -0
  175. package/lib/mcp/config/pagination.js +108 -0
  176. package/lib/mcp/config/pagination.js.map +1 -0
  177. package/lib/mcp/config/system-prompts.d.ts +18 -0
  178. package/lib/mcp/config/system-prompts.js +92 -0
  179. package/lib/mcp/config/system-prompts.js.map +1 -0
  180. package/lib/mcp/errors.d.ts +23 -0
  181. package/lib/mcp/errors.js +27 -0
  182. package/lib/mcp/errors.js.map +1 -0
  183. package/lib/mcp/schemas/input-schemas.d.ts +327 -0
  184. package/lib/mcp/schemas/input-schemas.js +310 -0
  185. package/lib/mcp/schemas/input-schemas.js.map +1 -0
  186. package/lib/mcp/server.d.ts +40 -0
  187. package/lib/mcp/server.js +316 -0
  188. package/lib/mcp/server.js.map +1 -0
  189. package/lib/mcp/tools/contactpoint-tools.d.ts +14 -0
  190. package/lib/mcp/tools/contactpoint-tools.js +34 -0
  191. package/lib/mcp/tools/contactpoint-tools.js.map +1 -0
  192. package/lib/mcp/tools/definition-io-tools.d.ts +19 -0
  193. package/lib/mcp/tools/definition-io-tools.js +152 -0
  194. package/lib/mcp/tools/definition-io-tools.js.map +1 -0
  195. package/lib/mcp/tools/definition-tools.d.ts +51 -0
  196. package/lib/mcp/tools/definition-tools.js +220 -0
  197. package/lib/mcp/tools/definition-tools.js.map +1 -0
  198. package/lib/mcp/tools/index.d.ts +37 -0
  199. package/lib/mcp/tools/index.js +88 -0
  200. package/lib/mcp/tools/index.js.map +1 -0
  201. package/lib/mcp/tools/object-tools.d.ts +22 -0
  202. package/lib/mcp/tools/object-tools.js +327 -0
  203. package/lib/mcp/tools/object-tools.js.map +1 -0
  204. package/lib/mcp/tools/org-tools.d.ts +14 -0
  205. package/lib/mcp/tools/org-tools.js +177 -0
  206. package/lib/mcp/tools/org-tools.js.map +1 -0
  207. package/lib/mcp/tools/profile-tools.d.ts +59 -0
  208. package/lib/mcp/tools/profile-tools.js +213 -0
  209. package/lib/mcp/tools/profile-tools.js.map +1 -0
  210. package/lib/mcp/tools/summary-tools.d.ts +14 -0
  211. package/lib/mcp/tools/summary-tools.js +38 -0
  212. package/lib/mcp/tools/summary-tools.js.map +1 -0
  213. package/lib/mcp/tools/tool-factory.d.ts +63 -0
  214. package/lib/mcp/tools/tool-factory.js +146 -0
  215. package/lib/mcp/tools/tool-factory.js.map +1 -0
  216. package/lib/mcp/tools/user-tools.d.ts +25 -0
  217. package/lib/mcp/tools/user-tools.js +167 -0
  218. package/lib/mcp/tools/user-tools.js.map +1 -0
  219. package/lib/models/cascade-skip-accumulator.d.ts +25 -0
  220. package/lib/models/cascade-skip-accumulator.js +9 -0
  221. package/lib/models/cascade-skip-accumulator.js.map +1 -0
  222. package/lib/models/date-literal.d.ts +280 -0
  223. package/lib/models/date-literal.js +1164 -0
  224. package/lib/models/date-literal.js.map +1 -0
  225. package/lib/models/object-describe-types.d.ts +173 -0
  226. package/lib/models/object-describe-types.js +9 -0
  227. package/lib/models/object-describe-types.js.map +1 -0
  228. package/lib/models/portability-recipe.d.ts +35 -0
  229. package/lib/models/portability-recipe.js +113 -0
  230. package/lib/models/portability-recipe.js.map +1 -0
  231. package/lib/models/profile-request-types.d.ts +118 -0
  232. package/lib/models/profile-request-types.js +23 -0
  233. package/lib/models/profile-request-types.js.map +1 -0
  234. package/lib/models/profiling-execution-types.d.ts +154 -0
  235. package/lib/models/profiling-execution-types.js +14 -0
  236. package/lib/models/profiling-execution-types.js.map +1 -0
  237. package/lib/models/service-result.d.ts +114 -0
  238. package/lib/models/service-result.js +81 -0
  239. package/lib/models/service-result.js.map +1 -0
  240. package/lib/models/sfdmu-types.d.ts +49 -0
  241. package/lib/models/sfdmu-types.js +23 -0
  242. package/lib/models/sfdmu-types.js.map +1 -0
  243. package/lib/models/status-types.d.ts +38 -0
  244. package/lib/models/status-types.js +12 -0
  245. package/lib/models/status-types.js.map +1 -0
  246. package/lib/models/summary-bulk-types.d.ts +61 -0
  247. package/lib/models/summary-bulk-types.js +23 -0
  248. package/lib/models/summary-bulk-types.js.map +1 -0
  249. package/lib/models/user-details-types.d.ts +188 -0
  250. package/lib/models/user-details-types.js +9 -0
  251. package/lib/models/user-details-types.js.map +1 -0
  252. package/lib/models/year-range.d.ts +78 -0
  253. package/lib/models/year-range.js +153 -0
  254. package/lib/models/year-range.js.map +1 -0
  255. package/lib/operations/CompatibilityCheckOperation.d.ts +62 -0
  256. package/lib/operations/CompatibilityCheckOperation.js +102 -0
  257. package/lib/operations/CompatibilityCheckOperation.js.map +1 -0
  258. package/lib/operations/DefinitionCreateOperation.d.ts +427 -0
  259. package/lib/operations/DefinitionCreateOperation.js +1270 -0
  260. package/lib/operations/DefinitionCreateOperation.js.map +1 -0
  261. package/lib/operations/DefinitionExportOperation.d.ts +155 -0
  262. package/lib/operations/DefinitionExportOperation.js +281 -0
  263. package/lib/operations/DefinitionExportOperation.js.map +1 -0
  264. package/lib/operations/DefinitionImportOperation.d.ts +144 -0
  265. package/lib/operations/DefinitionImportOperation.js +357 -0
  266. package/lib/operations/DefinitionImportOperation.js.map +1 -0
  267. package/lib/operations/DefinitionListOperation.d.ts +66 -0
  268. package/lib/operations/DefinitionListOperation.js +108 -0
  269. package/lib/operations/DefinitionListOperation.js.map +1 -0
  270. package/lib/operations/DefinitionPurgeOperation.d.ts +203 -0
  271. package/lib/operations/DefinitionPurgeOperation.js +465 -0
  272. package/lib/operations/DefinitionPurgeOperation.js.map +1 -0
  273. package/lib/operations/DefinitionUpdateOperation.d.ts +78 -0
  274. package/lib/operations/DefinitionUpdateOperation.js +142 -0
  275. package/lib/operations/DefinitionUpdateOperation.js.map +1 -0
  276. package/lib/operations/OrgDetailsOperation.d.ts +253 -0
  277. package/lib/operations/OrgDetailsOperation.js +456 -0
  278. package/lib/operations/OrgDetailsOperation.js.map +1 -0
  279. package/lib/operations/OrgResetOperation.d.ts +114 -0
  280. package/lib/operations/OrgResetOperation.js +209 -0
  281. package/lib/operations/OrgResetOperation.js.map +1 -0
  282. package/lib/operations/ProfileOperation.d.ts +192 -0
  283. package/lib/operations/ProfileOperation.js +371 -0
  284. package/lib/operations/ProfileOperation.js.map +1 -0
  285. package/lib/operations/ProfileRequestCancelOperation.d.ts +59 -0
  286. package/lib/operations/ProfileRequestCancelOperation.js +137 -0
  287. package/lib/operations/ProfileRequestCancelOperation.js.map +1 -0
  288. package/lib/operations/ProfileRequestDeleteOperation.d.ts +64 -0
  289. package/lib/operations/ProfileRequestDeleteOperation.js +134 -0
  290. package/lib/operations/ProfileRequestDeleteOperation.js.map +1 -0
  291. package/lib/operations/ProfileRequestListOperation.d.ts +39 -0
  292. package/lib/operations/ProfileRequestListOperation.js +61 -0
  293. package/lib/operations/ProfileRequestListOperation.js.map +1 -0
  294. package/lib/operations/SummaryPurgeOperation.d.ts +134 -0
  295. package/lib/operations/SummaryPurgeOperation.js +257 -0
  296. package/lib/operations/SummaryPurgeOperation.js.map +1 -0
  297. package/lib/operations/SummaryReprofileOperation.d.ts +88 -0
  298. package/lib/operations/SummaryReprofileOperation.js +174 -0
  299. package/lib/operations/SummaryReprofileOperation.js.map +1 -0
  300. package/lib/operations/SummaryStopOperation.d.ts +87 -0
  301. package/lib/operations/SummaryStopOperation.js +175 -0
  302. package/lib/operations/SummaryStopOperation.js.map +1 -0
  303. package/lib/services/BulkExecutionService.d.ts +120 -0
  304. package/lib/services/BulkExecutionService.js +535 -0
  305. package/lib/services/BulkExecutionService.js.map +1 -0
  306. package/lib/services/CompatibilityService.d.ts +81 -0
  307. package/lib/services/CompatibilityService.js +118 -0
  308. package/lib/services/CompatibilityService.js.map +1 -0
  309. package/lib/services/ConfigureMode.d.ts +98 -0
  310. package/lib/services/ConfigureMode.js +413 -0
  311. package/lib/services/ConfigureMode.js.map +1 -0
  312. package/lib/services/ContactPointService.d.ts +111 -0
  313. package/lib/services/ContactPointService.js +286 -0
  314. package/lib/services/ContactPointService.js.map +1 -0
  315. package/lib/services/DataAvailabilityService.d.ts +81 -0
  316. package/lib/services/DataAvailabilityService.js +128 -0
  317. package/lib/services/DataAvailabilityService.js.map +1 -0
  318. package/lib/services/DefinitionFieldGenerationService.d.ts +357 -0
  319. package/lib/services/DefinitionFieldGenerationService.js +899 -0
  320. package/lib/services/DefinitionFieldGenerationService.js.map +1 -0
  321. package/lib/services/DefinitionQueryBuilder.d.ts +92 -0
  322. package/lib/services/DefinitionQueryBuilder.js +328 -0
  323. package/lib/services/DefinitionQueryBuilder.js.map +1 -0
  324. package/lib/services/ObjectDescribeService.d.ts +436 -0
  325. package/lib/services/ObjectDescribeService.js +881 -0
  326. package/lib/services/ObjectDescribeService.js.map +1 -0
  327. package/lib/services/ObjectFilteringService.d.ts +484 -0
  328. package/lib/services/ObjectFilteringService.js +1080 -0
  329. package/lib/services/ObjectFilteringService.js.map +1 -0
  330. package/lib/services/ObjectListCommandService.d.ts +467 -0
  331. package/lib/services/ObjectListCommandService.js +904 -0
  332. package/lib/services/ObjectListCommandService.js.map +1 -0
  333. package/lib/services/ObjectListService.d.ts +201 -0
  334. package/lib/services/ObjectListService.js +350 -0
  335. package/lib/services/ObjectListService.js.map +1 -0
  336. package/lib/services/OrgInfoService.d.ts +493 -0
  337. package/lib/services/OrgInfoService.js +1142 -0
  338. package/lib/services/OrgInfoService.js.map +1 -0
  339. package/lib/services/PollingService.d.ts +105 -0
  340. package/lib/services/PollingService.js +117 -0
  341. package/lib/services/PollingService.js.map +1 -0
  342. package/lib/services/ProfileRequestService.d.ts +186 -0
  343. package/lib/services/ProfileRequestService.js +555 -0
  344. package/lib/services/ProfileRequestService.js.map +1 -0
  345. package/lib/services/ProfilingDefinitionService.d.ts +575 -0
  346. package/lib/services/ProfilingDefinitionService.js +1029 -0
  347. package/lib/services/ProfilingDefinitionService.js.map +1 -0
  348. package/lib/services/ProfilingExecutionService.d.ts +122 -0
  349. package/lib/services/ProfilingExecutionService.js +320 -0
  350. package/lib/services/ProfilingExecutionService.js.map +1 -0
  351. package/lib/services/ProfilingSummaryService.d.ts +292 -0
  352. package/lib/services/ProfilingSummaryService.js +688 -0
  353. package/lib/services/ProfilingSummaryService.js.map +1 -0
  354. package/lib/services/RecordTypeService.d.ts +129 -0
  355. package/lib/services/RecordTypeService.js +284 -0
  356. package/lib/services/RecordTypeService.js.map +1 -0
  357. package/lib/services/SFDMUService.d.ts +146 -0
  358. package/lib/services/SFDMUService.js +323 -0
  359. package/lib/services/SFDMUService.js.map +1 -0
  360. package/lib/services/TabDetectionService.d.ts +105 -0
  361. package/lib/services/TabDetectionService.js +206 -0
  362. package/lib/services/TabDetectionService.js.map +1 -0
  363. package/lib/services/UnconfigureMode.d.ts +74 -0
  364. package/lib/services/UnconfigureMode.js +378 -0
  365. package/lib/services/UnconfigureMode.js.map +1 -0
  366. package/lib/services/UserConfigurationService.d.ts +158 -0
  367. package/lib/services/UserConfigurationService.js +574 -0
  368. package/lib/services/UserConfigurationService.js.map +1 -0
  369. package/lib/services/UserConfigurationTypes.d.ts +181 -0
  370. package/lib/services/UserConfigurationTypes.js +14 -0
  371. package/lib/services/UserConfigurationTypes.js.map +1 -0
  372. package/lib/services/UserReadinessService.d.ts +347 -0
  373. package/lib/services/UserReadinessService.js +891 -0
  374. package/lib/services/UserReadinessService.js.map +1 -0
  375. package/lib/services/constants.d.ts +54 -0
  376. package/lib/services/constants.js +71 -0
  377. package/lib/services/constants.js.map +1 -0
  378. package/lib/services/namespace-constants.d.ts +1 -0
  379. package/lib/services/namespace-constants.js +11 -0
  380. package/lib/services/namespace-constants.js.map +1 -0
  381. package/lib/services/namespace-filter.d.ts +36 -0
  382. package/lib/services/namespace-filter.js +109 -0
  383. package/lib/services/namespace-filter.js.map +1 -0
  384. package/lib/services/validation.d.ts +47 -0
  385. package/lib/services/validation.js +119 -0
  386. package/lib/services/validation.js.map +1 -0
  387. package/lib/utils/batch-processor.d.ts +13 -0
  388. package/lib/utils/batch-processor.js +39 -0
  389. package/lib/utils/batch-processor.js.map +1 -0
  390. package/lib/utils/formatting/availability-grid.d.ts +81 -0
  391. package/lib/utils/formatting/availability-grid.js +94 -0
  392. package/lib/utils/formatting/availability-grid.js.map +1 -0
  393. package/lib/utils/formatting/business-process-grid.d.ts +51 -0
  394. package/lib/utils/formatting/business-process-grid.js +58 -0
  395. package/lib/utils/formatting/business-process-grid.js.map +1 -0
  396. package/lib/utils/formatting/command-display.d.ts +154 -0
  397. package/lib/utils/formatting/command-display.js +154 -0
  398. package/lib/utils/formatting/command-display.js.map +1 -0
  399. package/lib/utils/formatting/definition-create-display.d.ts +118 -0
  400. package/lib/utils/formatting/definition-create-display.js +230 -0
  401. package/lib/utils/formatting/definition-create-display.js.map +1 -0
  402. package/lib/utils/formatting/empty-states.d.ts +35 -0
  403. package/lib/utils/formatting/empty-states.js +70 -0
  404. package/lib/utils/formatting/empty-states.js.map +1 -0
  405. package/lib/utils/formatting/errors.d.ts +33 -0
  406. package/lib/utils/formatting/errors.js +72 -0
  407. package/lib/utils/formatting/errors.js.map +1 -0
  408. package/lib/utils/formatting/field-types.d.ts +32 -0
  409. package/lib/utils/formatting/field-types.js +88 -0
  410. package/lib/utils/formatting/field-types.js.map +1 -0
  411. package/lib/utils/formatting/index.d.ts +29 -0
  412. package/lib/utils/formatting/index.js +28 -0
  413. package/lib/utils/formatting/index.js.map +1 -0
  414. package/lib/utils/formatting/indicators.d.ts +113 -0
  415. package/lib/utils/formatting/indicators.js +161 -0
  416. package/lib/utils/formatting/indicators.js.map +1 -0
  417. package/lib/utils/formatting/loading-messages.d.ts +37 -0
  418. package/lib/utils/formatting/loading-messages.js +50 -0
  419. package/lib/utils/formatting/loading-messages.js.map +1 -0
  420. package/lib/utils/formatting/namespace-display.d.ts +31 -0
  421. package/lib/utils/formatting/namespace-display.js +64 -0
  422. package/lib/utils/formatting/namespace-display.js.map +1 -0
  423. package/lib/utils/formatting/numbers.d.ts +73 -0
  424. package/lib/utils/formatting/numbers.js +187 -0
  425. package/lib/utils/formatting/numbers.js.map +1 -0
  426. package/lib/utils/formatting/object-describe-display.d.ts +117 -0
  427. package/lib/utils/formatting/object-describe-display.js +447 -0
  428. package/lib/utils/formatting/object-describe-display.js.map +1 -0
  429. package/lib/utils/formatting/object-list-display.d.ts +225 -0
  430. package/lib/utils/formatting/object-list-display.js +718 -0
  431. package/lib/utils/formatting/object-list-display.js.map +1 -0
  432. package/lib/utils/formatting/org-identity.d.ts +15 -0
  433. package/lib/utils/formatting/org-identity.js +28 -0
  434. package/lib/utils/formatting/org-identity.js.map +1 -0
  435. package/lib/utils/formatting/record-age-grid.d.ts +41 -0
  436. package/lib/utils/formatting/record-age-grid.js +56 -0
  437. package/lib/utils/formatting/record-age-grid.js.map +1 -0
  438. package/lib/utils/formatting/sections.d.ts +108 -0
  439. package/lib/utils/formatting/sections.js +150 -0
  440. package/lib/utils/formatting/sections.js.map +1 -0
  441. package/lib/utils/formatting/tables.d.ts +90 -0
  442. package/lib/utils/formatting/tables.js +113 -0
  443. package/lib/utils/formatting/tables.js.map +1 -0
  444. package/lib/utils/formatting/user-details-display.d.ts +101 -0
  445. package/lib/utils/formatting/user-details-display.js +425 -0
  446. package/lib/utils/formatting/user-details-display.js.map +1 -0
  447. package/lib/utils/pagination/keypress-reader.d.ts +20 -0
  448. package/lib/utils/pagination/keypress-reader.js +63 -0
  449. package/lib/utils/pagination/keypress-reader.js.map +1 -0
  450. package/lib/utils/pagination/paginate-output.d.ts +48 -0
  451. package/lib/utils/pagination/paginate-output.js +136 -0
  452. package/lib/utils/pagination/paginate-output.js.map +1 -0
  453. package/messages/compatibility.check.md +71 -0
  454. package/messages/cuneiform.access.md +138 -0
  455. package/messages/definition.create.md +525 -0
  456. package/messages/definition.export.md +84 -0
  457. package/messages/definition.get.md +147 -0
  458. package/messages/definition.import.md +65 -0
  459. package/messages/definition.list.md +264 -0
  460. package/messages/definition.purge.md +330 -0
  461. package/messages/definition.update.md +118 -0
  462. package/messages/mcp.serve.md +66 -0
  463. package/messages/object.describe.md +205 -0
  464. package/messages/object.list.md +463 -0
  465. package/messages/org.details.md +386 -0
  466. package/messages/org.reset.md +71 -0
  467. package/messages/profile.md +243 -0
  468. package/messages/profile.request.cancel.md +143 -0
  469. package/messages/profile.request.delete.md +139 -0
  470. package/messages/profile.request.list.md +89 -0
  471. package/messages/summary.purge.md +218 -0
  472. package/messages/summary.reprofile.md +150 -0
  473. package/messages/summary.stop.md +157 -0
  474. package/messages/user.details.md +501 -0
  475. package/oclif.lock +3267 -2148
  476. package/oclif.manifest.json +2829 -31
  477. package/package.json +104 -18
  478. package/lib/commands/cuneiform/about.d.ts +0 -13
  479. package/lib/commands/cuneiform/about.js +0 -26
  480. package/lib/commands/cuneiform/about.js.map +0 -1
  481. package/lib/commands/hello/world.d.ts +0 -14
  482. package/lib/commands/hello/world.js +0 -27
  483. package/lib/commands/hello/world.js.map +0 -1
  484. package/lib/index.d.ts +0 -2
  485. package/lib/index.js +0 -2
  486. package/lib/index.js.map +0 -1
  487. package/messages/cuneiform.about.md +0 -19
  488. package/messages/hello.world.md +0 -29
@@ -0,0 +1,764 @@
1
+ /*
2
+ * Copyright (c) 2026, PeerNova, Inc. All Rights Reserved.
3
+ * PROPRIETARY AND CONFIDENTIAL. Unauthorized copying, modification,
4
+ * or distribution is strictly prohibited. Use is governed by the
5
+ * Master Subscription Agreement (MSA) between PeerNova, Inc. and the
6
+ * licensee. See LICENSE file in the repo root.
7
+ */
8
+ import { createSuccessResult, createFailureResult, createEmptyFailureResult } from '../../models/service-result.js';
9
+ import { CUNEIFORM_NAMESPACE_PREFIX } from '../../constants/namespace-constants.js';
10
+ import { AdapterErrorCodes, mapSalesforceError, mapDmlInsertError, mapDmlUpdateError, mapDmlDeleteError, extractSalesforceErrorCode, sanitizeSoqlIdentifier, } from '../errors.js';
11
+ import { createLifecycleEmitter } from '../lifecycle.js';
12
+ import { withRetry } from '../retry.js';
13
+ import { getCacheTtl, warnApiVersion } from '../types.js';
14
+ import { CuneiformQueryBuilder } from '../soql/cuneiform-query-builder.js';
15
+ import { LruCache } from './cache.js';
16
+ /**
17
+ * Standard objects allowed for specific write operations.
18
+ * Maps object names to the set of permitted operations.
19
+ * These are objects that services legitimately need to write to
20
+ * that don't use the pnova__ namespace prefix.
21
+ *
22
+ * - PermissionSetAssignment: insert (configure) + delete (unconfigure)
23
+ */
24
+ const WRITE_ALLOWLIST = new Map([
25
+ ['PermissionSetAssignment', new Set(['insert', 'delete'])],
26
+ ]);
27
+ /**
28
+ * Cache key prefixes for different operation types.
29
+ */
30
+ const CACHE_KEYS = {
31
+ DESCRIBE: 'describe:',
32
+ GLOBAL: 'global',
33
+ COUNT: 'count:',
34
+ };
35
+ /**
36
+ * Adapter for REST API operations against Salesforce.
37
+ *
38
+ * Provides caching for describe operations to reduce API calls.
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const adapter = new RestApiAdapter(connectionFacade);
43
+ *
44
+ * // Describe an object (cached)
45
+ * const result = await adapter.describeObject('Account');
46
+ *
47
+ * // Get global describe (cached)
48
+ * const global = await adapter.describeGlobal();
49
+ *
50
+ * // Describe multiple objects
51
+ * const describes = await adapter.describeObjects(['Account', 'Contact', 'Opportunity']);
52
+ *
53
+ * // Invalidate cache
54
+ * adapter.invalidateCache('describe:Account'); // Single object
55
+ * adapter.invalidateCache('describe:*'); // All describes
56
+ * adapter.invalidateCache(); // Everything
57
+ * ```
58
+ */
59
+ export class RestApiAdapter {
60
+ connection;
61
+ logger;
62
+ cache;
63
+ cacheEnabled;
64
+ lifecycle;
65
+ retryConfig;
66
+ recordCountBatchSize;
67
+ /**
68
+ * Creates a new RestApiAdapter.
69
+ *
70
+ * @param connection - The connection facade to use for API calls
71
+ * @param config - Optional configuration
72
+ */
73
+ constructor(connection, config) {
74
+ this.connection = connection;
75
+ this.logger = config?.logger;
76
+ this.cacheEnabled = config?.cacheEnabled ?? true;
77
+ this.lifecycle = createLifecycleEmitter('describe', config?.emitLifecycleEvents ?? false);
78
+ this.retryConfig = config?.retry;
79
+ // CLI-1744: Raised default from 10 → 25 to reduce sequential batch count in the SOQL fallback path
80
+ this.recordCountBatchSize = Math.min(Math.max(config?.recordCountBatchSize ?? 25, 1), 50);
81
+ const ttl = getCacheTtl(config?.cacheTtl);
82
+ this.cache = new LruCache(100, ttl);
83
+ // Warn if API version is below recommended minimum
84
+ warnApiVersion(connection.version, 'RestApiAdapter', this.logger);
85
+ }
86
+ /**
87
+ * Validates that a write operation targets a permitted object.
88
+ *
89
+ * Only objects with the pnova__ namespace prefix are allowed for all write operations.
90
+ * A small set of standard objects (WRITE_ALLOWLIST) are allowed for specific operations.
91
+ *
92
+ * @param objectName - The API name of the target object
93
+ * @param operation - The write operation type
94
+ * @returns undefined if allowed, or an error code and message if blocked
95
+ */
96
+ static validateWriteNamespace(objectName, operation) {
97
+ if (objectName.startsWith(CUNEIFORM_NAMESPACE_PREFIX)) {
98
+ return undefined;
99
+ }
100
+ const allowedOps = WRITE_ALLOWLIST.get(objectName);
101
+ if (allowedOps?.has(operation)) {
102
+ return undefined;
103
+ }
104
+ const errorCodeMap = {
105
+ insert: AdapterErrorCodes.INSERT_NAMESPACE_VIOLATION,
106
+ update: AdapterErrorCodes.UPDATE_NAMESPACE_VIOLATION,
107
+ delete: AdapterErrorCodes.DELETE_NAMESPACE_VIOLATION,
108
+ };
109
+ const errorCode = errorCodeMap[operation];
110
+ const operationLabel = operation.charAt(0).toUpperCase() + operation.slice(1);
111
+ // Show allowlist hint for operations that have allowlisted objects
112
+ const hasAllowlistEntries = [...WRITE_ALLOWLIST.values()].some((ops) => ops.has(operation));
113
+ return {
114
+ errorCode,
115
+ message: `${operationLabel} blocked: object '${objectName}' must use the ${CUNEIFORM_NAMESPACE_PREFIX} namespace` +
116
+ (hasAllowlistEntries ? ' or be in the explicit allowlist' : ''),
117
+ };
118
+ }
119
+ /**
120
+ * Describes a single Salesforce object.
121
+ *
122
+ * @param objectName - The API name of the object
123
+ * @returns ServiceResult containing the describe result
124
+ */
125
+ async describeObject(objectName) {
126
+ const startTime = Date.now();
127
+ const cacheKey = `${CACHE_KEYS.DESCRIBE}${objectName}`;
128
+ const emptyResult = {
129
+ name: objectName,
130
+ label: '',
131
+ labelPlural: '',
132
+ custom: false,
133
+ createable: false,
134
+ updateable: false,
135
+ deletable: false,
136
+ queryable: false,
137
+ searchable: false,
138
+ fields: [],
139
+ };
140
+ try {
141
+ // Check cache first
142
+ if (this.cacheEnabled) {
143
+ const cached = this.cache.get(cacheKey);
144
+ if (cached) {
145
+ this.logger?.log(`Cache hit for describe: ${objectName}`);
146
+ return createSuccessResult(cached, {
147
+ message: `Describe result for ${objectName} (cached)`,
148
+ metadata: { duration: Date.now() - startTime, cached: true },
149
+ });
150
+ }
151
+ }
152
+ this.logger?.log(`Describing object: ${objectName}`);
153
+ await this.lifecycle.start('describeObject', { objectName });
154
+ const executeDescribe = () => this.connection.sobject(objectName).describe();
155
+ const result = this.retryConfig ? await withRetry(executeDescribe, this.retryConfig) : await executeDescribe();
156
+ const duration = Date.now() - startTime;
157
+ // Cache the result
158
+ if (this.cacheEnabled) {
159
+ this.cache.set(cacheKey, result);
160
+ }
161
+ this.logger?.log(`Describe complete for ${objectName}: ${result.fields.length} fields`);
162
+ await this.lifecycle.complete('describeObject', startTime, { objectName, fieldCount: result.fields.length });
163
+ return createSuccessResult(result, {
164
+ message: `Describe result for ${objectName}`,
165
+ metadata: { duration, cached: false },
166
+ });
167
+ }
168
+ catch (error) {
169
+ const errorMessage = error instanceof Error ? error.message : String(error);
170
+ await this.lifecycle.error('describeObject', startTime, errorMessage, { objectName });
171
+ return this.handleError(error, startTime, emptyResult, objectName);
172
+ }
173
+ }
174
+ /**
175
+ * Retrieves global describe information for all accessible objects.
176
+ *
177
+ * @returns ServiceResult containing the global describe result
178
+ */
179
+ async describeGlobal() {
180
+ const startTime = Date.now();
181
+ const cacheKey = CACHE_KEYS.GLOBAL;
182
+ const emptyResult = { maxBatchSize: 0, sobjects: [] };
183
+ try {
184
+ // Check cache first
185
+ if (this.cacheEnabled) {
186
+ const cached = this.cache.get(cacheKey);
187
+ if (cached) {
188
+ this.logger?.log('Cache hit for global describe');
189
+ return createSuccessResult(cached, {
190
+ message: `Global describe result (cached): ${cached.sobjects.length} objects`,
191
+ metadata: { duration: Date.now() - startTime, cached: true },
192
+ });
193
+ }
194
+ }
195
+ this.logger?.log('Executing global describe');
196
+ await this.lifecycle.start('describeGlobal', {});
197
+ const executeGlobal = () => this.connection.request('/sobjects');
198
+ const result = this.retryConfig ? await withRetry(executeGlobal, this.retryConfig) : await executeGlobal();
199
+ const duration = Date.now() - startTime;
200
+ // Cache the result
201
+ if (this.cacheEnabled) {
202
+ this.cache.set(cacheKey, result);
203
+ }
204
+ this.logger?.log(`Global describe complete: ${result.sobjects.length} objects`);
205
+ await this.lifecycle.complete('describeGlobal', startTime, { objectCount: result.sobjects.length });
206
+ return createSuccessResult(result, {
207
+ message: `Global describe result: ${result.sobjects.length} objects`,
208
+ metadata: { duration, cached: false },
209
+ });
210
+ }
211
+ catch (error) {
212
+ const errorMessage = error instanceof Error ? error.message : String(error);
213
+ await this.lifecycle.error('describeGlobal', startTime, errorMessage);
214
+ return this.handleError(error, startTime, emptyResult, 'global describe', AdapterErrorCodes.GLOBAL_DESCRIBE_FAILED);
215
+ }
216
+ }
217
+ /**
218
+ * Gets the record count for a Salesforce object.
219
+ *
220
+ * @param objectName - The API name of the object
221
+ * @returns ServiceResult containing the record count
222
+ */
223
+ async getRecordCount(objectName) {
224
+ const startTime = Date.now();
225
+ const cacheKey = `${CACHE_KEYS.COUNT}${objectName}`;
226
+ try {
227
+ // Check cache first
228
+ if (this.cacheEnabled) {
229
+ const cached = this.cache.get(cacheKey);
230
+ if (cached !== undefined) {
231
+ this.logger?.log(`Cache hit for record count: ${objectName}`);
232
+ return createSuccessResult(cached, {
233
+ message: `Record count for ${objectName}: ${cached} (cached)`,
234
+ metadata: { duration: Date.now() - startTime, cached: true },
235
+ });
236
+ }
237
+ }
238
+ this.logger?.log(`Getting record count for: ${objectName}`);
239
+ // Sanitize objectName to prevent SOQL injection (validates API name format)
240
+ const sanitizedObjectName = sanitizeSoqlIdentifier(objectName);
241
+ // Build COUNT() query using CuneiformQueryBuilder for type-safe SOQL generation.
242
+ // SELECT COUNT() returns the count in totalSize, not as a record field.
243
+ // This is more efficient than SELECT COUNT(Id) which returns records.
244
+ const countQuery = CuneiformQueryBuilder.create().count().from(sanitizedObjectName).toSOQL();
245
+ const executeCount = () => this.connection.query(countQuery);
246
+ const result = this.retryConfig ? await withRetry(executeCount, this.retryConfig) : await executeCount();
247
+ const count = result.totalSize;
248
+ const duration = Date.now() - startTime;
249
+ // Cache the result
250
+ if (this.cacheEnabled) {
251
+ this.cache.set(cacheKey, count);
252
+ }
253
+ this.logger?.log(`Record count for ${objectName}: ${count}`);
254
+ return createSuccessResult(count, {
255
+ message: `Record count for ${objectName}: ${count}`,
256
+ metadata: { duration, cached: false },
257
+ });
258
+ }
259
+ catch (error) {
260
+ return this.handleError(error, startTime, 0, `record count for ${objectName}`);
261
+ }
262
+ }
263
+ /**
264
+ * Describes multiple Salesforce objects.
265
+ *
266
+ * @param objectNames - Array of object API names
267
+ * @returns ServiceResult containing a map of object names to describe results
268
+ */
269
+ async describeObjects(objectNames) {
270
+ const startTime = Date.now();
271
+ const results = new Map();
272
+ const warnings = [];
273
+ this.logger?.log(`Describing ${objectNames.length} objects`);
274
+ // Process in parallel
275
+ const promises = objectNames.map(async (name) => {
276
+ const result = await this.describeObject(name);
277
+ if (result.success) {
278
+ results.set(name, result.data);
279
+ }
280
+ else {
281
+ const errorInfo = result.errorCode ? `[${result.errorCode}] ` : '';
282
+ warnings.push(`Failed to describe ${name}: ${errorInfo}${result.message ?? 'Unknown error'}`);
283
+ }
284
+ });
285
+ await Promise.all(promises);
286
+ const duration = Date.now() - startTime;
287
+ this.logger?.log(`Described ${results.size}/${objectNames.length} objects`);
288
+ return createSuccessResult(results, {
289
+ message: `Described ${results.size}/${objectNames.length} objects`,
290
+ warnings: warnings.length > 0 ? warnings : undefined,
291
+ metadata: { duration },
292
+ });
293
+ }
294
+ /**
295
+ * Gets record counts for multiple Salesforce objects using the bulk REST endpoint.
296
+ *
297
+ * Uses `GET /limits/recordCount` for a single API call instead of
298
+ * N individual SOQL `SELECT COUNT()` queries. Falls back to per-object SOQL queries
299
+ * if the REST endpoint is unavailable or fails.
300
+ *
301
+ * CLI-4214: the `/limits/recordCount` endpoint is a HINT — it returns ONLY objects with
302
+ * count > 0. Objects it omits (genuine empties and not-yet-counted recent writes) are
303
+ * ABSENT from the returned map, NOT fabricated as 0, so callers can distinguish a limits
304
+ * omission (reconcile it) from an authoritative 0. Counts present in the map (limits hits
305
+ * and SOQL-fallback results, including genuine 0s) are cached so subsequent
306
+ * `getRecordCount()` calls benefit; omitted objects leave the cache untouched.
307
+ *
308
+ * @param objectNames - Array of object API names
309
+ * @returns ServiceResult containing Map of object name to count (omits unknown objects)
310
+ */
311
+ async getRecordCounts(objectNames) {
312
+ const startTime = Date.now();
313
+ const results = new Map();
314
+ if (objectNames.length === 0) {
315
+ return createSuccessResult(results, {
316
+ message: 'Retrieved counts for 0/0 objects',
317
+ metadata: { duration: Date.now() - startTime },
318
+ });
319
+ }
320
+ this.logger?.log(`Getting record counts for ${objectNames.length} objects`);
321
+ // Resolve cached counts first, collect uncached for bulk fetch
322
+ const uncached = [];
323
+ for (const name of objectNames) {
324
+ if (this.cacheEnabled) {
325
+ const cacheKey = `${CACHE_KEYS.COUNT}${name}`;
326
+ const cached = this.cache.get(cacheKey);
327
+ if (cached !== undefined) {
328
+ results.set(name, cached);
329
+ continue;
330
+ }
331
+ }
332
+ uncached.push(name);
333
+ }
334
+ if (uncached.length > 0) {
335
+ // Try the bulk /limits/recordCount REST endpoint first
336
+ const bulkSuccess = await this.fetchRecordCountsViaRest(uncached, results);
337
+ if (!bulkSuccess) {
338
+ // Fall back to individual SOQL COUNT() queries
339
+ this.logger?.log(`REST /limits/recordCount failed, falling back to individual SOQL for ${uncached.length} objects`);
340
+ await this.fetchRecordCountsViaSoql(uncached, results);
341
+ }
342
+ }
343
+ const duration = Date.now() - startTime;
344
+ this.logger?.log(`Retrieved counts for ${results.size}/${objectNames.length} objects`);
345
+ return createSuccessResult(results, {
346
+ message: `Retrieved counts for ${results.size}/${objectNames.length} objects`,
347
+ // CLI-4214: a size shortfall now means the /limits/recordCount hint OMITTED some
348
+ // requested objects (it only returns objects with count > 0). Those are NOT zeros —
349
+ // they are unknown until the caller reconciles them. The message reflects that.
350
+ warnings: results.size < objectNames.length
351
+ ? ['Some objects were omitted by /limits/recordCount (count unknown until reconciled)']
352
+ : undefined,
353
+ metadata: { duration },
354
+ });
355
+ }
356
+ /**
357
+ * Inserts a new record into a Salesforce object.
358
+ *
359
+ * Uses the REST API POST /sobjects/{objectName} endpoint to create a record.
360
+ * Does not use caching since write operations should always execute.
361
+ *
362
+ * @param objectName - The API name of the object (e.g., 'Account', 'PermissionSetAssignment')
363
+ * @param record - The field values for the new record
364
+ * @returns ServiceResult containing the created record's ID
365
+ *
366
+ * @example
367
+ * ```typescript
368
+ * const result = await adapter.insertRecord('PermissionSetAssignment', {
369
+ * AssigneeId: '005xx000001234567',
370
+ * PermissionSetId: '0PS000000000001'
371
+ * });
372
+ * ```
373
+ */
374
+ async insertRecord(objectName, record) {
375
+ const startTime = Date.now();
376
+ const emptyResult = { id: '' };
377
+ try {
378
+ this.logger?.log(`Inserting record into: ${objectName}`);
379
+ await this.lifecycle.start('insertRecord', { objectName });
380
+ // Sanitize objectName to prevent injection (validates API name format)
381
+ const sanitizedObjectName = sanitizeSoqlIdentifier(objectName);
382
+ // Namespace guard: only pnova__ objects and allowlisted standard objects permitted
383
+ const namespaceViolation = RestApiAdapter.validateWriteNamespace(sanitizedObjectName, 'insert');
384
+ if (namespaceViolation) {
385
+ this.logger?.log(`Insert blocked by namespace guard: ${objectName}`);
386
+ await this.lifecycle.error('insertRecord', startTime, namespaceViolation.message, { objectName });
387
+ return createFailureResult(emptyResult, namespaceViolation.errorCode, namespaceViolation.message);
388
+ }
389
+ // Build REST API endpoint for sObject insert
390
+ const endpoint = `/sobjects/${sanitizedObjectName}`;
391
+ const executeInsert = () => this.connection.request({
392
+ url: endpoint,
393
+ method: 'POST',
394
+ body: JSON.stringify(record),
395
+ headers: { 'content-type': 'application/json' },
396
+ });
397
+ const result = this.retryConfig ? await withRetry(executeInsert, this.retryConfig) : await executeInsert();
398
+ const duration = Date.now() - startTime;
399
+ // Check if the API returned success=false with errors
400
+ if (!result.success) {
401
+ const apiErrorMessage = Array.isArray(result.errors) ? JSON.stringify(result.errors) : 'Insert failed';
402
+ this.logger?.log(`Insert failed for ${objectName}: ${apiErrorMessage}`);
403
+ await this.lifecycle.error('insertRecord', startTime, apiErrorMessage, { objectName });
404
+ return createFailureResult(emptyResult, AdapterErrorCodes.INSERT_RECORD_FAILED, apiErrorMessage, {
405
+ metadata: { duration },
406
+ });
407
+ }
408
+ this.logger?.log(`Insert complete for ${objectName}: ${result.id}`);
409
+ await this.lifecycle.complete('insertRecord', startTime, { objectName, recordId: result.id });
410
+ return createSuccessResult({ id: result.id }, {
411
+ message: `Inserted record into ${objectName}: ${result.id}`,
412
+ metadata: { duration },
413
+ });
414
+ }
415
+ catch (error) {
416
+ const errorMessage = error instanceof Error ? error.message : String(error);
417
+ await this.lifecycle.error('insertRecord', startTime, errorMessage, { objectName });
418
+ return this.handleInsertError(error, startTime, emptyResult, objectName);
419
+ }
420
+ }
421
+ /**
422
+ * Updates an existing record in a Salesforce object.
423
+ *
424
+ * Uses the REST API PATCH /sobjects/{objectName}/{recordId} endpoint to update a record.
425
+ * Does not use caching since write operations should always execute.
426
+ *
427
+ * @param objectName - The API name of the object (e.g., 'Account', 'Contact')
428
+ * @param recordId - The ID of the record to update
429
+ * @param record - The field values to update
430
+ * @returns ServiceResult containing the update result with record ID and success status
431
+ */
432
+ async updateRecord(objectName, recordId, record) {
433
+ const startTime = Date.now();
434
+ const emptyResult = { id: recordId, success: false };
435
+ try {
436
+ this.logger?.log(`Updating record ${recordId} in: ${objectName}`);
437
+ await this.lifecycle.start('updateRecord', { objectName, recordId });
438
+ // Sanitize objectName to prevent injection (validates API name format)
439
+ const sanitizedObjectName = sanitizeSoqlIdentifier(objectName);
440
+ // Namespace guard: only pnova__ objects permitted for update
441
+ const namespaceViolation = RestApiAdapter.validateWriteNamespace(sanitizedObjectName, 'update');
442
+ if (namespaceViolation) {
443
+ this.logger?.log(`Update blocked by namespace guard: ${objectName}`);
444
+ await this.lifecycle.error('updateRecord', startTime, namespaceViolation.message, { objectName, recordId });
445
+ return createFailureResult(emptyResult, namespaceViolation.errorCode, namespaceViolation.message);
446
+ }
447
+ // Build REST API endpoint for sObject update
448
+ const endpoint = `/sobjects/${sanitizedObjectName}/${recordId}`;
449
+ // PATCH request returns 204 No Content on success, error response on failure
450
+ const executeUpdate = () => this.connection.request({
451
+ url: endpoint,
452
+ method: 'PATCH',
453
+ body: JSON.stringify(record),
454
+ headers: { 'content-type': 'application/json' },
455
+ });
456
+ await (this.retryConfig ? withRetry(executeUpdate, this.retryConfig) : executeUpdate());
457
+ const duration = Date.now() - startTime;
458
+ this.logger?.log(`Update complete for ${objectName}/${recordId}`);
459
+ await this.lifecycle.complete('updateRecord', startTime, { objectName, recordId });
460
+ return createSuccessResult({ id: recordId, success: true }, {
461
+ message: `Updated record in ${objectName}: ${recordId}`,
462
+ metadata: { duration },
463
+ });
464
+ }
465
+ catch (error) {
466
+ const errorMessage = error instanceof Error ? error.message : String(error);
467
+ await this.lifecycle.error('updateRecord', startTime, errorMessage, { objectName, recordId });
468
+ return this.handleUpdateError(error, startTime, emptyResult, `${objectName}/${recordId}`);
469
+ }
470
+ }
471
+ /**
472
+ * Deletes a record from a Salesforce object.
473
+ *
474
+ * Uses the REST API DELETE /sobjects/{objectName}/{recordId} endpoint to delete a record.
475
+ * Does not use caching since write operations should always execute.
476
+ *
477
+ * @param objectName - The API name of the object (e.g., 'Account', 'Contact')
478
+ * @param recordId - The ID of the record to delete
479
+ * @returns ServiceResult containing the delete result with record ID and success status
480
+ */
481
+ async deleteRecord(objectName, recordId) {
482
+ const startTime = Date.now();
483
+ const emptyResult = { id: recordId, success: false };
484
+ try {
485
+ this.logger?.log(`Deleting record ${recordId} from: ${objectName}`);
486
+ await this.lifecycle.start('deleteRecord', { objectName, recordId });
487
+ // Sanitize objectName to prevent injection (validates API name format)
488
+ const sanitizedObjectName = sanitizeSoqlIdentifier(objectName);
489
+ // Namespace guard: only pnova__ objects permitted for delete
490
+ const namespaceViolation = RestApiAdapter.validateWriteNamespace(sanitizedObjectName, 'delete');
491
+ if (namespaceViolation) {
492
+ this.logger?.log(`Delete blocked by namespace guard: ${objectName}`);
493
+ await this.lifecycle.error('deleteRecord', startTime, namespaceViolation.message, { objectName, recordId });
494
+ return createFailureResult(emptyResult, namespaceViolation.errorCode, namespaceViolation.message);
495
+ }
496
+ // Build REST API endpoint for sObject delete
497
+ const endpoint = `/sobjects/${sanitizedObjectName}/${recordId}`;
498
+ // DELETE request returns 204 No Content on success, error response on failure
499
+ const executeDelete = () => this.connection.request({
500
+ url: endpoint,
501
+ method: 'DELETE',
502
+ });
503
+ await (this.retryConfig ? withRetry(executeDelete, this.retryConfig) : executeDelete());
504
+ const duration = Date.now() - startTime;
505
+ this.logger?.log(`Delete complete for ${objectName}/${recordId}`);
506
+ await this.lifecycle.complete('deleteRecord', startTime, { objectName, recordId });
507
+ return createSuccessResult({ id: recordId, success: true }, {
508
+ message: `Deleted record from ${objectName}: ${recordId}`,
509
+ metadata: { duration },
510
+ });
511
+ }
512
+ catch (error) {
513
+ const errorMessage = error instanceof Error ? error.message : String(error);
514
+ await this.lifecycle.error('deleteRecord', startTime, errorMessage, { objectName, recordId });
515
+ return this.handleDeleteError(error, startTime, emptyResult, `${objectName}/${recordId}`);
516
+ }
517
+ }
518
+ /**
519
+ * Makes a generic HTTP request to a custom Salesforce REST endpoint.
520
+ *
521
+ * Supports custom Apex REST endpoints and any other Salesforce REST API path.
522
+ * Does not use caching since custom endpoints have unpredictable response shapes.
523
+ *
524
+ * The namespace guard is enforced for write operations (POST, PATCH, PUT, DELETE) that
525
+ * target sObject endpoints (`/sobjects/{objectName}`). Custom Apex REST endpoints
526
+ * (e.g., `/services/apexrest/pnova/v1/...`) and GET requests are not affected.
527
+ *
528
+ * @param httpRequest - The HTTP request configuration
529
+ * @returns ServiceResult containing the deserialized response of type T
530
+ */
531
+ async request(httpRequest) {
532
+ const startTime = Date.now();
533
+ const SOBJECT_WRITE_METHODS = new Set(['POST', 'PATCH', 'PUT', 'DELETE']);
534
+ try {
535
+ this.logger?.log(`REST request: ${httpRequest.method} ${httpRequest.url}`);
536
+ // Namespace guard: block write operations to non-pnova__ sObject endpoints
537
+ const sobjectPattern = /^\/sobjects\/([^/]+)/;
538
+ const sobjectMatch = sobjectPattern.exec(httpRequest.url);
539
+ if (sobjectMatch && SOBJECT_WRITE_METHODS.has(httpRequest.method)) {
540
+ const objectName = sobjectMatch[1];
541
+ const operation = httpRequest.method === 'POST' ? 'insert' : httpRequest.method === 'DELETE' ? 'delete' : 'update';
542
+ const violation = RestApiAdapter.validateWriteNamespace(objectName, operation);
543
+ if (violation) {
544
+ this.logger?.log(`Request blocked by namespace guard: ${httpRequest.method} ${httpRequest.url}`);
545
+ await this.lifecycle.error('request', startTime, violation.message, {
546
+ url: httpRequest.url,
547
+ method: httpRequest.method,
548
+ });
549
+ return createEmptyFailureResult(violation.errorCode, violation.message);
550
+ }
551
+ }
552
+ await this.lifecycle.start('request', { url: httpRequest.url, method: httpRequest.method });
553
+ const executeRequest = () => this.connection.request({
554
+ url: httpRequest.url,
555
+ method: httpRequest.method,
556
+ body: httpRequest.body != null
557
+ ? typeof httpRequest.body === 'string'
558
+ ? httpRequest.body
559
+ : JSON.stringify(httpRequest.body)
560
+ : undefined,
561
+ headers: httpRequest.headers ?? { 'content-type': 'application/json' },
562
+ });
563
+ const raw = this.retryConfig ? await withRetry(executeRequest, this.retryConfig) : await executeRequest();
564
+ // jsforce connection.request() may return a raw JSON string for custom REST endpoints;
565
+ // parse it so callers always receive a typed object.
566
+ const result = typeof raw === 'string' ? JSON.parse(raw) : raw;
567
+ const duration = Date.now() - startTime;
568
+ this.logger?.log(`REST request complete: ${httpRequest.method} ${httpRequest.url}`);
569
+ await this.lifecycle.complete('request', startTime, { url: httpRequest.url, method: httpRequest.method });
570
+ return createSuccessResult(result, {
571
+ message: `${httpRequest.method} ${httpRequest.url}`,
572
+ metadata: { duration },
573
+ });
574
+ }
575
+ catch (error) {
576
+ const errorMessage = error instanceof Error ? error.message : String(error);
577
+ await this.lifecycle.error('request', startTime, errorMessage, {
578
+ url: httpRequest.url,
579
+ method: httpRequest.method,
580
+ });
581
+ return this.handleError(error, startTime, undefined, `${httpRequest.method} ${httpRequest.url}`, AdapterErrorCodes.REQUEST_FAILED);
582
+ }
583
+ }
584
+ /**
585
+ * Invalidates cached entries.
586
+ *
587
+ * @param pattern - Optional pattern to match keys (supports * wildcard). If not provided, clears all entries.
588
+ */
589
+ invalidateCache(pattern) {
590
+ this.logger?.log(`Invalidating cache${pattern ? `: ${pattern}` : ' (all)'}`);
591
+ this.cache.invalidate(pattern);
592
+ }
593
+ /**
594
+ * Fetches record counts via the bulk REST endpoint `/limits/recordCount`.
595
+ *
596
+ * @param objectNames - Object API names to fetch counts for
597
+ * @param results - Map to populate with counts
598
+ * @returns true if the REST endpoint succeeded, false if it failed
599
+ */
600
+ async fetchRecordCountsViaRest(objectNames, results) {
601
+ try {
602
+ // CLI-1744: Call /limits/recordCount WITHOUT sObjects param to get ALL counts in one call.
603
+ // The previous approach joined all object names into the URL query string, which exceeded
604
+ // URL length limits (8K+) for orgs with 500+ objects and triggered the SOQL fallback (67-72s).
605
+ // A single parameterless call returns all org counts in ~1-2s.
606
+ const endpoint = '/limits/recordCount';
607
+ const response = await (this.retryConfig
608
+ ? withRetry(() => this.connection.request(endpoint), this.retryConfig)
609
+ : this.connection.request(endpoint));
610
+ // Build a lookup from the full org response
611
+ const countsByName = new Map();
612
+ for (const entry of response.sObjects) {
613
+ countsByName.set(entry.name, entry.count);
614
+ }
615
+ // CLI-4214: /limits/recordCount is a HINT, not authority — it returns ONLY objects
616
+ // with count > 0. Every empty object AND every not-yet-counted (recently written)
617
+ // object is OMITTED from the response. The previous `?? 0` fabricated a 0 for those
618
+ // omissions and cached it, poisoning later getRecordCount() cache reads and collapsing
619
+ // populated-but-omitted objects to 0 (the --with-records silent-skip bug).
620
+ //
621
+ // Only record/cache counts for objects ACTUALLY PRESENT in the limits response. Omitted
622
+ // objects are left ABSENT from the results map so the caller can distinguish a limits
623
+ // omission (reconcile it) from a genuine, authoritative 0 (the SOQL fallback path).
624
+ for (const name of objectNames) {
625
+ const count = countsByName.get(name);
626
+ if (count === undefined) {
627
+ continue;
628
+ }
629
+ results.set(name, count);
630
+ if (this.cacheEnabled) {
631
+ this.cache.set(`${CACHE_KEYS.COUNT}${name}`, count);
632
+ }
633
+ }
634
+ return true;
635
+ }
636
+ catch (error) {
637
+ const errorMessage = error instanceof Error ? error.message : String(error);
638
+ this.logger?.log(`REST /limits/recordCount unavailable: ${errorMessage}, falling back to individual queries`);
639
+ return false;
640
+ }
641
+ }
642
+ /**
643
+ * Fallback: fetches record counts via individual SOQL COUNT() queries.
644
+ *
645
+ * @param objectNames - Object API names to fetch counts for
646
+ * @param results - Map to populate with counts
647
+ */
648
+ async fetchRecordCountsViaSoql(objectNames, results) {
649
+ /* eslint-disable no-await-in-loop -- Intentional sequential batching to avoid overwhelming Salesforce API */
650
+ for (let i = 0; i < objectNames.length; i += this.recordCountBatchSize) {
651
+ const batch = objectNames.slice(i, i + this.recordCountBatchSize);
652
+ const batchPromises = batch.map(async (name) => {
653
+ const result = await this.getRecordCount(name);
654
+ if (result.success) {
655
+ results.set(name, result.data);
656
+ }
657
+ });
658
+ await Promise.all(batchPromises);
659
+ }
660
+ /* eslint-enable no-await-in-loop */
661
+ }
662
+ /**
663
+ * Handles DML insert errors and maps them to appropriate error codes.
664
+ *
665
+ * @param error - The caught error
666
+ * @param startTime - The operation start time for duration calculation
667
+ * @param emptyResult - The empty result to return on failure
668
+ * @param context - Context for logging (object name)
669
+ * @returns ServiceResult with success=false and mapped error code
670
+ */
671
+ handleInsertError(error, startTime, emptyResult, context) {
672
+ const duration = Date.now() - startTime;
673
+ const errorMessage = error instanceof Error
674
+ ? error.message
675
+ : typeof error === 'object' && error !== null
676
+ ? JSON.stringify(error)
677
+ : String(error);
678
+ const sfErrorCode = extractSalesforceErrorCode(error);
679
+ const adapterErrorCode = sfErrorCode ? mapDmlInsertError(sfErrorCode) : AdapterErrorCodes.INSERT_RECORD_FAILED;
680
+ this.logger?.log(`REST API insert failed (${context}): ${errorMessage}`);
681
+ return createFailureResult(emptyResult, adapterErrorCode, errorMessage, {
682
+ metadata: { duration, sfErrorCode },
683
+ });
684
+ }
685
+ /**
686
+ * Handles DML update errors and maps them to appropriate error codes.
687
+ *
688
+ * @param error - The caught error
689
+ * @param startTime - The operation start time for duration calculation
690
+ * @param emptyResult - The empty result to return on failure
691
+ * @param context - Context for logging (object name/record ID)
692
+ * @returns ServiceResult with success=false and mapped error code
693
+ */
694
+ handleUpdateError(error, startTime, emptyResult, context) {
695
+ const duration = Date.now() - startTime;
696
+ const errorMessage = error instanceof Error
697
+ ? error.message
698
+ : typeof error === 'object' && error !== null
699
+ ? JSON.stringify(error)
700
+ : String(error);
701
+ const sfErrorCode = extractSalesforceErrorCode(error);
702
+ const adapterErrorCode = sfErrorCode ? mapDmlUpdateError(sfErrorCode) : AdapterErrorCodes.UPDATE_RECORD_FAILED;
703
+ this.logger?.log(`REST API update failed (${context}): ${errorMessage}`);
704
+ return createFailureResult(emptyResult, adapterErrorCode, errorMessage, {
705
+ metadata: { duration, sfErrorCode },
706
+ });
707
+ }
708
+ /**
709
+ * Handles DML delete errors and maps them to appropriate error codes.
710
+ *
711
+ * @param error - The caught error
712
+ * @param startTime - The operation start time for duration calculation
713
+ * @param emptyResult - The empty result to return on failure
714
+ * @param context - Context for logging (object name/record ID)
715
+ * @returns ServiceResult with success=false and mapped error code
716
+ */
717
+ handleDeleteError(error, startTime, emptyResult, context) {
718
+ const duration = Date.now() - startTime;
719
+ const errorMessage = error instanceof Error
720
+ ? error.message
721
+ : typeof error === 'object' && error !== null
722
+ ? JSON.stringify(error)
723
+ : String(error);
724
+ const sfErrorCode = extractSalesforceErrorCode(error);
725
+ const adapterErrorCode = sfErrorCode ? mapDmlDeleteError(sfErrorCode) : AdapterErrorCodes.DELETE_RECORD_FAILED;
726
+ this.logger?.log(`REST API delete failed (${context}): ${errorMessage}`);
727
+ return createFailureResult(emptyResult, adapterErrorCode, errorMessage, {
728
+ metadata: { duration, sfErrorCode },
729
+ });
730
+ }
731
+ /**
732
+ * Handles errors and maps them to appropriate error codes.
733
+ *
734
+ * Accepts SfError, jsforce errors, or unknown error types. Extracts Salesforce
735
+ * error codes when available and maps them to adapter-specific error codes.
736
+ *
737
+ * @param error - The caught error (SfError, jsforce error, or unknown)
738
+ * @param startTime - The operation start time for duration calculation
739
+ * @param emptyResult - The empty result to return on failure
740
+ * @param context - Context for logging (e.g., "Account", "global describe")
741
+ * @param defaultErrorCode - The default error code if no SF error code is found
742
+ * @returns ServiceResult with success=false and mapped error code
743
+ */
744
+ handleError(error, startTime, emptyResult, context, defaultErrorCode = AdapterErrorCodes.DESCRIBE_FAILED) {
745
+ const duration = Date.now() - startTime;
746
+ const errorMessage = error instanceof Error
747
+ ? error.message
748
+ : typeof error === 'object' && error !== null
749
+ ? JSON.stringify(error)
750
+ : String(error);
751
+ const sfErrorCode = extractSalesforceErrorCode(error);
752
+ const adapterErrorCode = sfErrorCode ? mapSalesforceError(sfErrorCode, 'rest') : defaultErrorCode;
753
+ this.logger?.log(`REST API failed (${context}): ${errorMessage}`);
754
+ if (emptyResult === undefined) {
755
+ return createEmptyFailureResult(adapterErrorCode, errorMessage, {
756
+ metadata: { duration, sfErrorCode },
757
+ });
758
+ }
759
+ return createFailureResult(emptyResult, adapterErrorCode, errorMessage, {
760
+ metadata: { duration, sfErrorCode },
761
+ });
762
+ }
763
+ }
764
+ //# sourceMappingURL=rest-api-adapter.js.map