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

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 (494) hide show
  1. package/LICENSE +81 -30
  2. package/README.md +59 -95
  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/index.d.ts +33 -0
  10. package/lib/adapters/index.js +50 -0
  11. package/lib/adapters/index.js.map +1 -0
  12. package/lib/adapters/lifecycle.d.ts +119 -0
  13. package/lib/adapters/lifecycle.js +94 -0
  14. package/lib/adapters/lifecycle.js.map +1 -0
  15. package/lib/adapters/rest/cache.d.ts +69 -0
  16. package/lib/adapters/rest/cache.js +133 -0
  17. package/lib/adapters/rest/cache.js.map +1 -0
  18. package/lib/adapters/rest/index.d.ts +11 -0
  19. package/lib/adapters/rest/index.js +18 -0
  20. package/lib/adapters/rest/index.js.map +1 -0
  21. package/lib/adapters/rest/profiling-rest-client.d.ts +137 -0
  22. package/lib/adapters/rest/profiling-rest-client.js +115 -0
  23. package/lib/adapters/rest/profiling-rest-client.js.map +1 -0
  24. package/lib/adapters/rest/rest-api-adapter.d.ts +389 -0
  25. package/lib/adapters/rest/rest-api-adapter.js +747 -0
  26. package/lib/adapters/rest/rest-api-adapter.js.map +1 -0
  27. package/lib/adapters/rest/types.d.ts +34 -0
  28. package/lib/adapters/rest/types.js +9 -0
  29. package/lib/adapters/rest/types.js.map +1 -0
  30. package/lib/adapters/retry.d.ts +91 -0
  31. package/lib/adapters/retry.js +215 -0
  32. package/lib/adapters/retry.js.map +1 -0
  33. package/lib/adapters/soql/cuneiform-query-builder.d.ts +391 -0
  34. package/lib/adapters/soql/cuneiform-query-builder.js +559 -0
  35. package/lib/adapters/soql/cuneiform-query-builder.js.map +1 -0
  36. package/lib/adapters/soql/index.d.ts +13 -0
  37. package/lib/adapters/soql/index.js +21 -0
  38. package/lib/adapters/soql/index.js.map +1 -0
  39. package/lib/adapters/soql/soql-query-adapter.d.ts +141 -0
  40. package/lib/adapters/soql/soql-query-adapter.js +259 -0
  41. package/lib/adapters/soql/soql-query-adapter.js.map +1 -0
  42. package/lib/adapters/soql/types.d.ts +37 -0
  43. package/lib/adapters/soql/types.js +19 -0
  44. package/lib/adapters/soql/types.js.map +1 -0
  45. package/lib/adapters/testing/index.d.ts +37 -0
  46. package/lib/adapters/testing/index.js +20 -0
  47. package/lib/adapters/testing/index.js.map +1 -0
  48. package/lib/adapters/testing/mock-connection.d.ts +77 -0
  49. package/lib/adapters/testing/mock-connection.js +207 -0
  50. package/lib/adapters/testing/mock-connection.js.map +1 -0
  51. package/lib/adapters/testing/mock-logger.d.ts +29 -0
  52. package/lib/adapters/testing/mock-logger.js +57 -0
  53. package/lib/adapters/testing/mock-logger.js.map +1 -0
  54. package/lib/adapters/testing/mock-mcp-adapters.d.ts +32 -0
  55. package/lib/adapters/testing/mock-mcp-adapters.js +52 -0
  56. package/lib/adapters/testing/mock-mcp-adapters.js.map +1 -0
  57. package/lib/adapters/testing/mock-oclif-config.d.ts +22 -0
  58. package/lib/adapters/testing/mock-oclif-config.js +90 -0
  59. package/lib/adapters/testing/mock-oclif-config.js.map +1 -0
  60. package/lib/adapters/testing/mock-rest-adapter.d.ts +26 -0
  61. package/lib/adapters/testing/mock-rest-adapter.js +243 -0
  62. package/lib/adapters/testing/mock-rest-adapter.js.map +1 -0
  63. package/lib/adapters/testing/mock-salesforce-connection.d.ts +40 -0
  64. package/lib/adapters/testing/mock-salesforce-connection.js +61 -0
  65. package/lib/adapters/testing/mock-salesforce-connection.js.map +1 -0
  66. package/lib/adapters/testing/mock-soql-adapter.d.ts +30 -0
  67. package/lib/adapters/testing/mock-soql-adapter.js +120 -0
  68. package/lib/adapters/testing/mock-soql-adapter.js.map +1 -0
  69. package/lib/adapters/testing/mock-tooling-adapter.d.ts +24 -0
  70. package/lib/adapters/testing/mock-tooling-adapter.js +163 -0
  71. package/lib/adapters/testing/mock-tooling-adapter.js.map +1 -0
  72. package/lib/adapters/testing/stub-connection.d.ts +93 -0
  73. package/lib/adapters/testing/stub-connection.js +97 -0
  74. package/lib/adapters/testing/stub-connection.js.map +1 -0
  75. package/lib/adapters/testing/stub-rest-adapter.d.ts +52 -0
  76. package/lib/adapters/testing/stub-rest-adapter.js +58 -0
  77. package/lib/adapters/testing/stub-rest-adapter.js.map +1 -0
  78. package/lib/adapters/testing/stub-soql-adapter.d.ts +56 -0
  79. package/lib/adapters/testing/stub-soql-adapter.js +50 -0
  80. package/lib/adapters/testing/stub-soql-adapter.js.map +1 -0
  81. package/lib/adapters/testing/types.d.ts +71 -0
  82. package/lib/adapters/testing/types.js +9 -0
  83. package/lib/adapters/testing/types.js.map +1 -0
  84. package/lib/adapters/tooling/index.d.ts +10 -0
  85. package/lib/adapters/tooling/index.js +17 -0
  86. package/lib/adapters/tooling/index.js.map +1 -0
  87. package/lib/adapters/tooling/tooling-api-adapter.d.ts +157 -0
  88. package/lib/adapters/tooling/tooling-api-adapter.js +339 -0
  89. package/lib/adapters/tooling/tooling-api-adapter.js.map +1 -0
  90. package/lib/adapters/tooling/types.d.ts +81 -0
  91. package/lib/adapters/tooling/types.js +9 -0
  92. package/lib/adapters/tooling/types.js.map +1 -0
  93. package/lib/adapters/types.d.ts +112 -0
  94. package/lib/adapters/types.js +169 -0
  95. package/lib/adapters/types.js.map +1 -0
  96. package/lib/base/cuneiform-command.d.ts +152 -0
  97. package/lib/base/cuneiform-command.js +243 -0
  98. package/lib/base/cuneiform-command.js.map +1 -0
  99. package/lib/commands/cuneiform/compatibility/check.d.ts +43 -0
  100. package/lib/commands/cuneiform/compatibility/check.js +114 -0
  101. package/lib/commands/cuneiform/compatibility/check.js.map +1 -0
  102. package/lib/commands/cuneiform/definition/create.d.ts +119 -0
  103. package/lib/commands/cuneiform/definition/create.js +693 -0
  104. package/lib/commands/cuneiform/definition/create.js.map +1 -0
  105. package/lib/commands/cuneiform/definition/export.d.ts +57 -0
  106. package/lib/commands/cuneiform/definition/export.js +133 -0
  107. package/lib/commands/cuneiform/definition/export.js.map +1 -0
  108. package/lib/commands/cuneiform/definition/get.d.ts +86 -0
  109. package/lib/commands/cuneiform/definition/get.js +270 -0
  110. package/lib/commands/cuneiform/definition/get.js.map +1 -0
  111. package/lib/commands/cuneiform/definition/import.d.ts +54 -0
  112. package/lib/commands/cuneiform/definition/import.js +118 -0
  113. package/lib/commands/cuneiform/definition/import.js.map +1 -0
  114. package/lib/commands/cuneiform/definition/list.d.ts +110 -0
  115. package/lib/commands/cuneiform/definition/list.js +344 -0
  116. package/lib/commands/cuneiform/definition/list.js.map +1 -0
  117. package/lib/commands/cuneiform/definition/purge.d.ts +105 -0
  118. package/lib/commands/cuneiform/definition/purge.js +533 -0
  119. package/lib/commands/cuneiform/definition/purge.js.map +1 -0
  120. package/lib/commands/cuneiform/definition/update.d.ts +58 -0
  121. package/lib/commands/cuneiform/definition/update.js +206 -0
  122. package/lib/commands/cuneiform/definition/update.js.map +1 -0
  123. package/lib/commands/cuneiform/mcp/serve.d.ts +56 -0
  124. package/lib/commands/cuneiform/mcp/serve.js +109 -0
  125. package/lib/commands/cuneiform/mcp/serve.js.map +1 -0
  126. package/lib/commands/cuneiform/object/describe.d.ts +61 -0
  127. package/lib/commands/cuneiform/object/describe.js +461 -0
  128. package/lib/commands/cuneiform/object/describe.js.map +1 -0
  129. package/lib/commands/cuneiform/object/list.d.ts +111 -0
  130. package/lib/commands/cuneiform/object/list.js +239 -0
  131. package/lib/commands/cuneiform/object/list.js.map +1 -0
  132. package/lib/commands/cuneiform/org/details.d.ts +99 -0
  133. package/lib/commands/cuneiform/org/details.js +521 -0
  134. package/lib/commands/cuneiform/org/details.js.map +1 -0
  135. package/lib/commands/cuneiform/org/reset.d.ts +46 -0
  136. package/lib/commands/cuneiform/org/reset.js +135 -0
  137. package/lib/commands/cuneiform/org/reset.js.map +1 -0
  138. package/lib/commands/cuneiform/profile/request/cancel.d.ts +59 -0
  139. package/lib/commands/cuneiform/profile/request/cancel.js +202 -0
  140. package/lib/commands/cuneiform/profile/request/cancel.js.map +1 -0
  141. package/lib/commands/cuneiform/profile/request/delete.d.ts +59 -0
  142. package/lib/commands/cuneiform/profile/request/delete.js +223 -0
  143. package/lib/commands/cuneiform/profile/request/delete.js.map +1 -0
  144. package/lib/commands/cuneiform/profile/request/list.d.ts +35 -0
  145. package/lib/commands/cuneiform/profile/request/list.js +102 -0
  146. package/lib/commands/cuneiform/profile/request/list.js.map +1 -0
  147. package/lib/commands/cuneiform/profile.d.ts +90 -0
  148. package/lib/commands/cuneiform/profile.js +322 -0
  149. package/lib/commands/cuneiform/profile.js.map +1 -0
  150. package/lib/commands/cuneiform/summary/purge.d.ts +77 -0
  151. package/lib/commands/cuneiform/summary/purge.js +429 -0
  152. package/lib/commands/cuneiform/summary/purge.js.map +1 -0
  153. package/lib/commands/cuneiform/summary/reprofile.d.ts +60 -0
  154. package/lib/commands/cuneiform/summary/reprofile.js +236 -0
  155. package/lib/commands/cuneiform/summary/reprofile.js.map +1 -0
  156. package/lib/commands/cuneiform/summary/stop.d.ts +59 -0
  157. package/lib/commands/cuneiform/summary/stop.js +234 -0
  158. package/lib/commands/cuneiform/summary/stop.js.map +1 -0
  159. package/lib/commands/cuneiform/user/details.d.ts +73 -0
  160. package/lib/commands/cuneiform/user/details.js +391 -0
  161. package/lib/commands/cuneiform/user/details.js.map +1 -0
  162. package/lib/constants/index.d.ts +8 -0
  163. package/lib/constants/index.js +16 -0
  164. package/lib/constants/index.js.map +1 -0
  165. package/lib/constants/namespace-constants.d.ts +91 -0
  166. package/lib/constants/namespace-constants.js +211 -0
  167. package/lib/constants/namespace-constants.js.map +1 -0
  168. package/lib/debug/command-debug-proxy.d.ts +101 -0
  169. package/lib/debug/command-debug-proxy.js +171 -0
  170. package/lib/debug/command-debug-proxy.js.map +1 -0
  171. package/lib/debug/debug-logger.d.ts +85 -0
  172. package/lib/debug/debug-logger.js +133 -0
  173. package/lib/debug/debug-logger.js.map +1 -0
  174. package/lib/debug/index.d.ts +12 -0
  175. package/lib/debug/index.js +20 -0
  176. package/lib/debug/index.js.map +1 -0
  177. package/lib/debug/service-debug-proxy.d.ts +30 -0
  178. package/lib/debug/service-debug-proxy.js +102 -0
  179. package/lib/debug/service-debug-proxy.js.map +1 -0
  180. package/lib/hooks/prerun.d.ts +25 -0
  181. package/lib/hooks/prerun.js +47 -0
  182. package/lib/hooks/prerun.js.map +1 -0
  183. package/lib/mcp/config/mcp-config.d.ts +55 -0
  184. package/lib/mcp/config/mcp-config.js +51 -0
  185. package/lib/mcp/config/mcp-config.js.map +1 -0
  186. package/lib/mcp/config/pagination.d.ts +96 -0
  187. package/lib/mcp/config/pagination.js +108 -0
  188. package/lib/mcp/config/pagination.js.map +1 -0
  189. package/lib/mcp/config/system-prompts.d.ts +18 -0
  190. package/lib/mcp/config/system-prompts.js +92 -0
  191. package/lib/mcp/config/system-prompts.js.map +1 -0
  192. package/lib/mcp/errors.d.ts +23 -0
  193. package/lib/mcp/errors.js +27 -0
  194. package/lib/mcp/errors.js.map +1 -0
  195. package/lib/mcp/schemas/input-schemas.d.ts +327 -0
  196. package/lib/mcp/schemas/input-schemas.js +302 -0
  197. package/lib/mcp/schemas/input-schemas.js.map +1 -0
  198. package/lib/mcp/server.d.ts +40 -0
  199. package/lib/mcp/server.js +316 -0
  200. package/lib/mcp/server.js.map +1 -0
  201. package/lib/mcp/tools/contactpoint-tools.d.ts +14 -0
  202. package/lib/mcp/tools/contactpoint-tools.js +34 -0
  203. package/lib/mcp/tools/contactpoint-tools.js.map +1 -0
  204. package/lib/mcp/tools/definition-io-tools.d.ts +19 -0
  205. package/lib/mcp/tools/definition-io-tools.js +152 -0
  206. package/lib/mcp/tools/definition-io-tools.js.map +1 -0
  207. package/lib/mcp/tools/definition-tools.d.ts +51 -0
  208. package/lib/mcp/tools/definition-tools.js +199 -0
  209. package/lib/mcp/tools/definition-tools.js.map +1 -0
  210. package/lib/mcp/tools/index.d.ts +37 -0
  211. package/lib/mcp/tools/index.js +88 -0
  212. package/lib/mcp/tools/index.js.map +1 -0
  213. package/lib/mcp/tools/object-tools.d.ts +22 -0
  214. package/lib/mcp/tools/object-tools.js +306 -0
  215. package/lib/mcp/tools/object-tools.js.map +1 -0
  216. package/lib/mcp/tools/org-tools.d.ts +14 -0
  217. package/lib/mcp/tools/org-tools.js +177 -0
  218. package/lib/mcp/tools/org-tools.js.map +1 -0
  219. package/lib/mcp/tools/profile-tools.d.ts +59 -0
  220. package/lib/mcp/tools/profile-tools.js +213 -0
  221. package/lib/mcp/tools/profile-tools.js.map +1 -0
  222. package/lib/mcp/tools/summary-tools.d.ts +14 -0
  223. package/lib/mcp/tools/summary-tools.js +38 -0
  224. package/lib/mcp/tools/summary-tools.js.map +1 -0
  225. package/lib/mcp/tools/tool-factory.d.ts +63 -0
  226. package/lib/mcp/tools/tool-factory.js +146 -0
  227. package/lib/mcp/tools/tool-factory.js.map +1 -0
  228. package/lib/mcp/tools/user-tools.d.ts +25 -0
  229. package/lib/mcp/tools/user-tools.js +167 -0
  230. package/lib/mcp/tools/user-tools.js.map +1 -0
  231. package/lib/models/date-literal.d.ts +211 -0
  232. package/lib/models/date-literal.js +615 -0
  233. package/lib/models/date-literal.js.map +1 -0
  234. package/lib/models/object-describe-types.d.ts +173 -0
  235. package/lib/models/object-describe-types.js +9 -0
  236. package/lib/models/object-describe-types.js.map +1 -0
  237. package/lib/models/profile-request-types.d.ts +118 -0
  238. package/lib/models/profile-request-types.js +23 -0
  239. package/lib/models/profile-request-types.js.map +1 -0
  240. package/lib/models/profiling-execution-types.d.ts +154 -0
  241. package/lib/models/profiling-execution-types.js +14 -0
  242. package/lib/models/profiling-execution-types.js.map +1 -0
  243. package/lib/models/service-result.d.ts +114 -0
  244. package/lib/models/service-result.js +81 -0
  245. package/lib/models/service-result.js.map +1 -0
  246. package/lib/models/sfdmu-types.d.ts +53 -0
  247. package/lib/models/sfdmu-types.js +23 -0
  248. package/lib/models/sfdmu-types.js.map +1 -0
  249. package/lib/models/status-types.d.ts +38 -0
  250. package/lib/models/status-types.js +12 -0
  251. package/lib/models/status-types.js.map +1 -0
  252. package/lib/models/summary-bulk-types.d.ts +61 -0
  253. package/lib/models/summary-bulk-types.js +23 -0
  254. package/lib/models/summary-bulk-types.js.map +1 -0
  255. package/lib/models/user-details-types.d.ts +163 -0
  256. package/lib/models/user-details-types.js +9 -0
  257. package/lib/models/user-details-types.js.map +1 -0
  258. package/lib/models/year-range.d.ts +78 -0
  259. package/lib/models/year-range.js +153 -0
  260. package/lib/models/year-range.js.map +1 -0
  261. package/lib/operations/CompatibilityCheckOperation.d.ts +62 -0
  262. package/lib/operations/CompatibilityCheckOperation.js +102 -0
  263. package/lib/operations/CompatibilityCheckOperation.js.map +1 -0
  264. package/lib/operations/DefinitionCreateOperation.d.ts +411 -0
  265. package/lib/operations/DefinitionCreateOperation.js +1121 -0
  266. package/lib/operations/DefinitionCreateOperation.js.map +1 -0
  267. package/lib/operations/DefinitionExportOperation.d.ts +155 -0
  268. package/lib/operations/DefinitionExportOperation.js +281 -0
  269. package/lib/operations/DefinitionExportOperation.js.map +1 -0
  270. package/lib/operations/DefinitionImportOperation.d.ts +144 -0
  271. package/lib/operations/DefinitionImportOperation.js +357 -0
  272. package/lib/operations/DefinitionImportOperation.js.map +1 -0
  273. package/lib/operations/DefinitionListOperation.d.ts +66 -0
  274. package/lib/operations/DefinitionListOperation.js +108 -0
  275. package/lib/operations/DefinitionListOperation.js.map +1 -0
  276. package/lib/operations/DefinitionPurgeOperation.d.ts +199 -0
  277. package/lib/operations/DefinitionPurgeOperation.js +465 -0
  278. package/lib/operations/DefinitionPurgeOperation.js.map +1 -0
  279. package/lib/operations/DefinitionUpdateOperation.d.ts +78 -0
  280. package/lib/operations/DefinitionUpdateOperation.js +142 -0
  281. package/lib/operations/DefinitionUpdateOperation.js.map +1 -0
  282. package/lib/operations/OrgDetailsOperation.d.ts +253 -0
  283. package/lib/operations/OrgDetailsOperation.js +456 -0
  284. package/lib/operations/OrgDetailsOperation.js.map +1 -0
  285. package/lib/operations/OrgResetOperation.d.ts +114 -0
  286. package/lib/operations/OrgResetOperation.js +209 -0
  287. package/lib/operations/OrgResetOperation.js.map +1 -0
  288. package/lib/operations/ProfileOperation.d.ts +187 -0
  289. package/lib/operations/ProfileOperation.js +373 -0
  290. package/lib/operations/ProfileOperation.js.map +1 -0
  291. package/lib/operations/ProfileRequestCancelOperation.d.ts +59 -0
  292. package/lib/operations/ProfileRequestCancelOperation.js +137 -0
  293. package/lib/operations/ProfileRequestCancelOperation.js.map +1 -0
  294. package/lib/operations/ProfileRequestDeleteOperation.d.ts +64 -0
  295. package/lib/operations/ProfileRequestDeleteOperation.js +134 -0
  296. package/lib/operations/ProfileRequestDeleteOperation.js.map +1 -0
  297. package/lib/operations/ProfileRequestListOperation.d.ts +39 -0
  298. package/lib/operations/ProfileRequestListOperation.js +61 -0
  299. package/lib/operations/ProfileRequestListOperation.js.map +1 -0
  300. package/lib/operations/SummaryPurgeOperation.d.ts +134 -0
  301. package/lib/operations/SummaryPurgeOperation.js +257 -0
  302. package/lib/operations/SummaryPurgeOperation.js.map +1 -0
  303. package/lib/operations/SummaryReprofileOperation.d.ts +88 -0
  304. package/lib/operations/SummaryReprofileOperation.js +174 -0
  305. package/lib/operations/SummaryReprofileOperation.js.map +1 -0
  306. package/lib/operations/SummaryStopOperation.d.ts +87 -0
  307. package/lib/operations/SummaryStopOperation.js +175 -0
  308. package/lib/operations/SummaryStopOperation.js.map +1 -0
  309. package/lib/services/BulkExecutionService.d.ts +120 -0
  310. package/lib/services/BulkExecutionService.js +535 -0
  311. package/lib/services/BulkExecutionService.js.map +1 -0
  312. package/lib/services/CompatibilityService.d.ts +81 -0
  313. package/lib/services/CompatibilityService.js +118 -0
  314. package/lib/services/CompatibilityService.js.map +1 -0
  315. package/lib/services/ConfigureMode.d.ts +85 -0
  316. package/lib/services/ConfigureMode.js +390 -0
  317. package/lib/services/ConfigureMode.js.map +1 -0
  318. package/lib/services/ContactPointService.d.ts +111 -0
  319. package/lib/services/ContactPointService.js +286 -0
  320. package/lib/services/ContactPointService.js.map +1 -0
  321. package/lib/services/DataAvailabilityService.d.ts +81 -0
  322. package/lib/services/DataAvailabilityService.js +128 -0
  323. package/lib/services/DataAvailabilityService.js.map +1 -0
  324. package/lib/services/DefinitionFieldGenerationService.d.ts +309 -0
  325. package/lib/services/DefinitionFieldGenerationService.js +795 -0
  326. package/lib/services/DefinitionFieldGenerationService.js.map +1 -0
  327. package/lib/services/DefinitionQueryBuilder.d.ts +59 -0
  328. package/lib/services/DefinitionQueryBuilder.js +234 -0
  329. package/lib/services/DefinitionQueryBuilder.js.map +1 -0
  330. package/lib/services/ObjectDescribeService.d.ts +436 -0
  331. package/lib/services/ObjectDescribeService.js +869 -0
  332. package/lib/services/ObjectDescribeService.js.map +1 -0
  333. package/lib/services/ObjectFilteringService.d.ts +400 -0
  334. package/lib/services/ObjectFilteringService.js +878 -0
  335. package/lib/services/ObjectFilteringService.js.map +1 -0
  336. package/lib/services/ObjectListCommandService.d.ts +429 -0
  337. package/lib/services/ObjectListCommandService.js +873 -0
  338. package/lib/services/ObjectListCommandService.js.map +1 -0
  339. package/lib/services/ObjectListService.d.ts +201 -0
  340. package/lib/services/ObjectListService.js +345 -0
  341. package/lib/services/ObjectListService.js.map +1 -0
  342. package/lib/services/OrgInfoService.d.ts +485 -0
  343. package/lib/services/OrgInfoService.js +1122 -0
  344. package/lib/services/OrgInfoService.js.map +1 -0
  345. package/lib/services/PollingService.d.ts +105 -0
  346. package/lib/services/PollingService.js +117 -0
  347. package/lib/services/PollingService.js.map +1 -0
  348. package/lib/services/ProfileRequestService.d.ts +186 -0
  349. package/lib/services/ProfileRequestService.js +555 -0
  350. package/lib/services/ProfileRequestService.js.map +1 -0
  351. package/lib/services/ProfilingDefinitionService.d.ts +535 -0
  352. package/lib/services/ProfilingDefinitionService.js +981 -0
  353. package/lib/services/ProfilingDefinitionService.js.map +1 -0
  354. package/lib/services/ProfilingExecutionService.d.ts +122 -0
  355. package/lib/services/ProfilingExecutionService.js +320 -0
  356. package/lib/services/ProfilingExecutionService.js.map +1 -0
  357. package/lib/services/ProfilingSummaryService.d.ts +292 -0
  358. package/lib/services/ProfilingSummaryService.js +685 -0
  359. package/lib/services/ProfilingSummaryService.js.map +1 -0
  360. package/lib/services/RecordTypeService.d.ts +129 -0
  361. package/lib/services/RecordTypeService.js +284 -0
  362. package/lib/services/RecordTypeService.js.map +1 -0
  363. package/lib/services/SFDMUService.d.ts +133 -0
  364. package/lib/services/SFDMUService.js +295 -0
  365. package/lib/services/SFDMUService.js.map +1 -0
  366. package/lib/services/TabDetectionService.d.ts +105 -0
  367. package/lib/services/TabDetectionService.js +206 -0
  368. package/lib/services/TabDetectionService.js.map +1 -0
  369. package/lib/services/UnconfigureMode.d.ts +74 -0
  370. package/lib/services/UnconfigureMode.js +378 -0
  371. package/lib/services/UnconfigureMode.js.map +1 -0
  372. package/lib/services/UserConfigurationService.d.ts +155 -0
  373. package/lib/services/UserConfigurationService.js +573 -0
  374. package/lib/services/UserConfigurationService.js.map +1 -0
  375. package/lib/services/UserConfigurationTypes.d.ts +181 -0
  376. package/lib/services/UserConfigurationTypes.js +14 -0
  377. package/lib/services/UserConfigurationTypes.js.map +1 -0
  378. package/lib/services/UserReadinessService.d.ts +330 -0
  379. package/lib/services/UserReadinessService.js +831 -0
  380. package/lib/services/UserReadinessService.js.map +1 -0
  381. package/lib/services/constants.d.ts +53 -0
  382. package/lib/services/constants.js +71 -0
  383. package/lib/services/constants.js.map +1 -0
  384. package/lib/services/namespace-constants.d.ts +1 -0
  385. package/lib/services/namespace-constants.js +11 -0
  386. package/lib/services/namespace-constants.js.map +1 -0
  387. package/lib/services/validation.d.ts +47 -0
  388. package/lib/services/validation.js +119 -0
  389. package/lib/services/validation.js.map +1 -0
  390. package/lib/utils/batch-processor.d.ts +13 -0
  391. package/lib/utils/batch-processor.js +39 -0
  392. package/lib/utils/batch-processor.js.map +1 -0
  393. package/lib/utils/formatting/availability-grid.d.ts +81 -0
  394. package/lib/utils/formatting/availability-grid.js +94 -0
  395. package/lib/utils/formatting/availability-grid.js.map +1 -0
  396. package/lib/utils/formatting/business-process-grid.d.ts +51 -0
  397. package/lib/utils/formatting/business-process-grid.js +58 -0
  398. package/lib/utils/formatting/business-process-grid.js.map +1 -0
  399. package/lib/utils/formatting/command-display.d.ts +154 -0
  400. package/lib/utils/formatting/command-display.js +154 -0
  401. package/lib/utils/formatting/command-display.js.map +1 -0
  402. package/lib/utils/formatting/definition-create-display.d.ts +118 -0
  403. package/lib/utils/formatting/definition-create-display.js +231 -0
  404. package/lib/utils/formatting/definition-create-display.js.map +1 -0
  405. package/lib/utils/formatting/empty-states.d.ts +35 -0
  406. package/lib/utils/formatting/empty-states.js +70 -0
  407. package/lib/utils/formatting/empty-states.js.map +1 -0
  408. package/lib/utils/formatting/errors.d.ts +33 -0
  409. package/lib/utils/formatting/errors.js +72 -0
  410. package/lib/utils/formatting/errors.js.map +1 -0
  411. package/lib/utils/formatting/field-types.d.ts +32 -0
  412. package/lib/utils/formatting/field-types.js +88 -0
  413. package/lib/utils/formatting/field-types.js.map +1 -0
  414. package/lib/utils/formatting/index.d.ts +29 -0
  415. package/lib/utils/formatting/index.js +28 -0
  416. package/lib/utils/formatting/index.js.map +1 -0
  417. package/lib/utils/formatting/indicators.d.ts +113 -0
  418. package/lib/utils/formatting/indicators.js +161 -0
  419. package/lib/utils/formatting/indicators.js.map +1 -0
  420. package/lib/utils/formatting/loading-messages.d.ts +37 -0
  421. package/lib/utils/formatting/loading-messages.js +50 -0
  422. package/lib/utils/formatting/loading-messages.js.map +1 -0
  423. package/lib/utils/formatting/namespace-display.d.ts +31 -0
  424. package/lib/utils/formatting/namespace-display.js +64 -0
  425. package/lib/utils/formatting/namespace-display.js.map +1 -0
  426. package/lib/utils/formatting/numbers.d.ts +73 -0
  427. package/lib/utils/formatting/numbers.js +187 -0
  428. package/lib/utils/formatting/numbers.js.map +1 -0
  429. package/lib/utils/formatting/object-describe-display.d.ts +114 -0
  430. package/lib/utils/formatting/object-describe-display.js +440 -0
  431. package/lib/utils/formatting/object-describe-display.js.map +1 -0
  432. package/lib/utils/formatting/object-list-display.d.ts +213 -0
  433. package/lib/utils/formatting/object-list-display.js +672 -0
  434. package/lib/utils/formatting/object-list-display.js.map +1 -0
  435. package/lib/utils/formatting/org-identity.d.ts +15 -0
  436. package/lib/utils/formatting/org-identity.js +28 -0
  437. package/lib/utils/formatting/org-identity.js.map +1 -0
  438. package/lib/utils/formatting/record-age-grid.d.ts +41 -0
  439. package/lib/utils/formatting/record-age-grid.js +56 -0
  440. package/lib/utils/formatting/record-age-grid.js.map +1 -0
  441. package/lib/utils/formatting/sections.d.ts +108 -0
  442. package/lib/utils/formatting/sections.js +150 -0
  443. package/lib/utils/formatting/sections.js.map +1 -0
  444. package/lib/utils/formatting/tables.d.ts +90 -0
  445. package/lib/utils/formatting/tables.js +113 -0
  446. package/lib/utils/formatting/tables.js.map +1 -0
  447. package/lib/utils/formatting/user-details-display.d.ts +101 -0
  448. package/lib/utils/formatting/user-details-display.js +425 -0
  449. package/lib/utils/formatting/user-details-display.js.map +1 -0
  450. package/lib/utils/pagination/index.d.ts +11 -0
  451. package/lib/utils/pagination/index.js +18 -0
  452. package/lib/utils/pagination/index.js.map +1 -0
  453. package/lib/utils/pagination/keypress-reader.d.ts +20 -0
  454. package/lib/utils/pagination/keypress-reader.js +63 -0
  455. package/lib/utils/pagination/keypress-reader.js.map +1 -0
  456. package/lib/utils/pagination/paginate-output.d.ts +48 -0
  457. package/lib/utils/pagination/paginate-output.js +136 -0
  458. package/lib/utils/pagination/paginate-output.js.map +1 -0
  459. package/messages/compatibility.check.md +71 -0
  460. package/messages/cuneiform.access.md +138 -0
  461. package/messages/definition.create.md +511 -0
  462. package/messages/definition.export.md +84 -0
  463. package/messages/definition.get.md +147 -0
  464. package/messages/definition.import.md +65 -0
  465. package/messages/definition.list.md +264 -0
  466. package/messages/definition.purge.md +318 -0
  467. package/messages/definition.update.md +118 -0
  468. package/messages/mcp.serve.md +66 -0
  469. package/messages/object.describe.md +201 -0
  470. package/messages/object.list.md +443 -0
  471. package/messages/org.details.md +386 -0
  472. package/messages/org.reset.md +71 -0
  473. package/messages/profile.md +231 -0
  474. package/messages/profile.request.cancel.md +143 -0
  475. package/messages/profile.request.delete.md +139 -0
  476. package/messages/profile.request.list.md +89 -0
  477. package/messages/summary.purge.md +218 -0
  478. package/messages/summary.reprofile.md +150 -0
  479. package/messages/summary.stop.md +157 -0
  480. package/messages/user.details.md +501 -0
  481. package/oclif.lock +2887 -2149
  482. package/oclif.manifest.json +2813 -31
  483. package/package.json +94 -19
  484. package/lib/commands/cuneiform/about.d.ts +0 -13
  485. package/lib/commands/cuneiform/about.js +0 -26
  486. package/lib/commands/cuneiform/about.js.map +0 -1
  487. package/lib/commands/hello/world.d.ts +0 -14
  488. package/lib/commands/hello/world.js +0 -27
  489. package/lib/commands/hello/world.js.map +0 -1
  490. package/lib/index.d.ts +0 -2
  491. package/lib/index.js +0 -2
  492. package/lib/index.js.map +0 -1
  493. package/messages/cuneiform.about.md +0 -19
  494. package/messages/hello.world.md +0 -29
@@ -0,0 +1,831 @@
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 { CuneiformQueryBuilder } from '../adapters/soql/cuneiform-query-builder.js';
9
+ import { createSuccessResult, createFailureResult } from '../models/service-result.js';
10
+ import { ServiceErrorCodes } from '../adapters/errors.js';
11
+ import { CUNEIFORM_NAMESPACE } from './namespace-constants.js';
12
+ import { validateRequiredString } from './validation.js';
13
+ /**
14
+ * Permission set names required for Cuneiform operations.
15
+ */
16
+ export const REQUIRED_PERMISSION_SETS = [
17
+ 'Cuneiform_for_CRM_PRO_Administrative_User',
18
+ 'Cuneiform_for_CRM_Global_Profiling_Support',
19
+ ];
20
+ /**
21
+ * Maps required permission set API names to their human-readable labels.
22
+ * Used for user-facing display across both details and configure commands.
23
+ */
24
+ export const REQUIRED_PERMISSION_SET_LABELS = {
25
+ [REQUIRED_PERMISSION_SETS[0]]: 'Cuneiform for CRM PRO Administrative User',
26
+ [REQUIRED_PERMISSION_SETS[1]]: 'Cuneiform for CRM Global Profiling Support',
27
+ };
28
+ /**
29
+ * Org types that allow configure operations.
30
+ * Production is the only blocked type.
31
+ */
32
+ export const CONFIGURE_ALLOWED_ORG_TYPES = ['Developer', 'Sandbox', 'Scratch', 'Trial'];
33
+ /**
34
+ * Service for validating user readiness to use Cuneiform.
35
+ *
36
+ * Checks whether a user has the required permission sets and configuration
37
+ * profile to execute Cuneiform operations. Also detects if Cuneiform is
38
+ * installed in the org.
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const service = new UserReadinessService({ soqlAdapter });
43
+ *
44
+ * const result = await service.checkReadiness(userId);
45
+ * if (result.success) {
46
+ * if (result.data.isReady) {
47
+ * console.log('User is ready to use Cuneiform');
48
+ * } else {
49
+ * console.log('Issues:', result.data.messages.join(', '));
50
+ * }
51
+ * }
52
+ * ```
53
+ */
54
+ export class UserReadinessService {
55
+ soqlAdapter;
56
+ logger;
57
+ restClient;
58
+ constructor(config) {
59
+ this.soqlAdapter = config.soqlAdapter;
60
+ this.logger = config.logger;
61
+ this.restClient = config.restClient;
62
+ }
63
+ /**
64
+ * Checks whether configure operations are allowed in the given org type.
65
+ *
66
+ * Only Production orgs are blocked. Developer, Sandbox, Scratch, and Trial
67
+ * orgs are all allowed to run configure operations.
68
+ *
69
+ * @param orgType - The classified org type
70
+ * @returns true if configure is allowed, false for Production
71
+ */
72
+ static isConfigureAllowed(orgType) {
73
+ return CONFIGURE_ALLOWED_ORG_TYPES.includes(orgType);
74
+ }
75
+ /**
76
+ * Creates an empty UserReadiness result for error cases.
77
+ */
78
+ static createEmptyReadiness(userId) {
79
+ return {
80
+ userId,
81
+ isReady: false,
82
+ isCuneiformInstalled: false,
83
+ permissionSets: {
84
+ hasAllRequired: false,
85
+ assignments: [],
86
+ missingRequired: [...REQUIRED_PERMISSION_SETS],
87
+ },
88
+ configProfile: { isConfigured: false },
89
+ messages: [],
90
+ };
91
+ }
92
+ /**
93
+ * Creates an empty UserInfo result for error cases.
94
+ */
95
+ static createEmptyUserInfo(userId) {
96
+ return {
97
+ id: userId,
98
+ username: '',
99
+ fullName: '',
100
+ email: '',
101
+ profileName: '',
102
+ roleName: null,
103
+ isActive: false,
104
+ };
105
+ }
106
+ /**
107
+ * Checks if an error message indicates Cuneiform namespace is not found.
108
+ *
109
+ * This typically means the Cuneiform for Salesforce package is not installed in the org.
110
+ * The Salesforce API returns "sObject type not supported" or similar when
111
+ * querying namespaced objects that don't exist.
112
+ */
113
+ static isCuneiformNamespaceNotFoundError(message) {
114
+ const lowerMessage = message.toLowerCase();
115
+ return (lowerMessage.includes('sobject type') &&
116
+ (lowerMessage.includes('not supported') || lowerMessage.includes('invalid')));
117
+ }
118
+ /**
119
+ * Maps the ISV REST API payload to the canonical UserReadiness shape.
120
+ *
121
+ * The Apex endpoint returns flat booleans and differently-named fields
122
+ * (e.g. `assigned` instead of `isAssigned`, `cuneiformInstalled` instead
123
+ * of `isCuneiformInstalled`). This mapper bridges the wire format to
124
+ * the TypeScript domain type so downstream code (buildResult, display)
125
+ * works unchanged.
126
+ */
127
+ static mapRestPayloadToUserReadiness(userId, payload) {
128
+ const assignments = (payload.permissionSets ?? []).map((ps) => ({
129
+ name: ps.name,
130
+ label: ps.label,
131
+ isAssigned: ps.assigned,
132
+ isRequired: REQUIRED_PERMISSION_SETS.includes(ps.name),
133
+ }));
134
+ return {
135
+ userId,
136
+ // Normalize isReady: the ISV REST endpoint may return isReady=true when only
137
+ // permission sets are assigned but API-only profiling is not enabled at the org
138
+ // level. Override to false when apiOnlyProfilingEnabled is not explicitly true
139
+ // so the display layer stays consistent with validateProfilingAccess() gate 3.
140
+ isReady: payload.isReady,
141
+ isCuneiformInstalled: payload.cuneiformInstalled,
142
+ permissionSets: {
143
+ hasAllRequired: payload.allPermissionsAssigned,
144
+ assignments,
145
+ missingRequired: payload.missingPermissionSets ?? [],
146
+ },
147
+ configProfile: {
148
+ isConfigured: payload.hasConfigurationProfile,
149
+ profileLabel: payload.configurationProfileLabel,
150
+ profileDeveloperName: payload.configurationProfileDeveloperName,
151
+ apiOnlyProfilingEnabled: payload.apiOnlyProfilingEnabled,
152
+ selfRegistrationEnabled: payload.selfRegistrationEnabled,
153
+ },
154
+ messages: [],
155
+ };
156
+ }
157
+ /**
158
+ * Retrieves user identity information.
159
+ *
160
+ * Queries the User object with Profile and UserRole relationships to build
161
+ * a complete user identity record. Handles null UserRole gracefully since
162
+ * users may not have a role assigned.
163
+ *
164
+ * @param userId - The Salesforce user ID to query
165
+ * @returns ServiceResult containing UserInfo
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * const result = await service.getUserInfo(userId);
170
+ * if (result.success) {
171
+ * console.log(`User: ${result.data.fullName} (${result.data.profileName})`);
172
+ * if (result.data.roleName) {
173
+ * console.log(`Role: ${result.data.roleName}`);
174
+ * }
175
+ * }
176
+ * ```
177
+ */
178
+ async getUserInfo(userId) {
179
+ const startTime = Date.now();
180
+ const emptyResult = UserReadinessService.createEmptyUserInfo(userId);
181
+ // Validate userId
182
+ const validationError = validateRequiredString(userId, 'User ID');
183
+ if (validationError) {
184
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_ID_REQUIRED, validationError, {
185
+ metadata: { duration: Date.now() - startTime },
186
+ });
187
+ }
188
+ try {
189
+ this.logger?.log(`Querying user info for: ${userId}`);
190
+ const soql = new CuneiformQueryBuilder()
191
+ .select(['Id', 'Username', 'Name', 'Email', 'Profile.Name', 'UserRole.Name', 'IsActive'])
192
+ .from('User')
193
+ .where('Id', '=', userId)
194
+ .limit(1)
195
+ .toSOQL();
196
+ const result = await this.soqlAdapter.query(soql);
197
+ if (!result.success) {
198
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_INFO_QUERY_FAILED, result.message ?? 'User query failed', {
199
+ metadata: { duration: Date.now() - startTime },
200
+ });
201
+ }
202
+ if (result.data.records.length === 0) {
203
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_INFO_QUERY_FAILED, `User not found: ${userId}`, {
204
+ metadata: { duration: Date.now() - startTime },
205
+ });
206
+ }
207
+ const record = result.data.records[0];
208
+ const userInfo = {
209
+ id: record.Id,
210
+ username: record.Username,
211
+ fullName: record.Name,
212
+ email: record.Email,
213
+ profileName: record.Profile.Name,
214
+ roleName: record.UserRole?.Name ?? null,
215
+ isActive: record.IsActive,
216
+ };
217
+ const duration = Date.now() - startTime;
218
+ this.logger?.log(`User info retrieved: ${userInfo.fullName}`);
219
+ return createSuccessResult(userInfo, {
220
+ message: `User: ${userInfo.fullName}`,
221
+ metadata: { duration },
222
+ });
223
+ }
224
+ catch (error) {
225
+ const errorMessage = error instanceof Error ? error.message : String(error);
226
+ this.logger?.log(`User info query failed: ${errorMessage}`);
227
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_INFO_QUERY_FAILED, errorMessage, {
228
+ metadata: { duration: Date.now() - startTime },
229
+ });
230
+ }
231
+ }
232
+ /**
233
+ * Checks complete user readiness for Cuneiform operations.
234
+ *
235
+ * Validates:
236
+ * 1. Cuneiform is installed (by querying CMT)
237
+ * 2. User has required permission sets
238
+ * 3. Configuration profile is set up
239
+ *
240
+ * @param userId - The Salesforce user ID to check
241
+ * @returns ServiceResult containing UserReadiness
242
+ */
243
+ async checkReadiness(userId) {
244
+ const startTime = Date.now();
245
+ // Validate userId
246
+ const validationError = validateRequiredString(userId, 'User ID');
247
+ if (validationError) {
248
+ const emptyResult = UserReadinessService.createEmptyReadiness(userId);
249
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_ID_REQUIRED, validationError, {
250
+ metadata: { duration: Date.now() - startTime },
251
+ });
252
+ }
253
+ // REST API path: delegate to server when restClient is available.
254
+ // Falls back to local SOQL if REST returns unexpected results.
255
+ const restFallbackResult = await this.tryRestReadiness(userId, startTime);
256
+ if (restFallbackResult) {
257
+ return restFallbackResult;
258
+ }
259
+ const messages = [];
260
+ try {
261
+ this.logger?.log(`Checking readiness for user: ${userId}`);
262
+ // Check permission sets and config profile in parallel
263
+ const [permissionResult, configResult] = await Promise.all([
264
+ this.hasRequiredPermissionSets(userId),
265
+ this.hasConfigProfile(),
266
+ ]);
267
+ // Determine if Cuneiform is installed
268
+ let isCuneiformInstalled = true;
269
+ if (!configResult.success && configResult.errorCode === ServiceErrorCodes.USER_CUNEIFORM_NAMESPACE_NOT_FOUND) {
270
+ isCuneiformInstalled = false;
271
+ messages.push('Cuneiform for Salesforce is not installed in this org');
272
+ }
273
+ // Build permission set status
274
+ let permissionSets;
275
+ if (!permissionResult.success) {
276
+ permissionSets = {
277
+ hasAllRequired: false,
278
+ assignments: [],
279
+ missingRequired: [...REQUIRED_PERMISSION_SETS],
280
+ };
281
+ messages.push(`Permission check failed: ${permissionResult.message ?? 'Unknown error'}`);
282
+ }
283
+ else {
284
+ permissionSets = permissionResult.data;
285
+ if (!permissionSets.hasAllRequired) {
286
+ messages.push(`Missing permission sets: ${permissionSets.missingRequired.join(', ')}`);
287
+ }
288
+ }
289
+ // Build config profile status
290
+ let configProfile;
291
+ if (!configResult.success) {
292
+ configProfile = { isConfigured: false };
293
+ if (configResult.errorCode !== ServiceErrorCodes.USER_CUNEIFORM_NAMESPACE_NOT_FOUND) {
294
+ messages.push(`Config profile check failed: ${configResult.message ?? 'Unknown error'}`);
295
+ }
296
+ }
297
+ else {
298
+ configProfile = configResult.data;
299
+ if (!configProfile.isConfigured) {
300
+ messages.push('No active configuration profile found');
301
+ }
302
+ }
303
+ // Determine overall readiness — mirrors the gate chain in validateProfilingAccess().
304
+ // configProfile.isConfigured alone is not enough: the org must also have API-only
305
+ // profiling explicitly enabled, or the user will hit E4659 on every other command.
306
+ const isReady = isCuneiformInstalled &&
307
+ permissionSets.hasAllRequired &&
308
+ configProfile.isConfigured &&
309
+ configProfile.apiOnlyProfilingEnabled === true;
310
+ if (isReady) {
311
+ messages.push('User is ready to use Cuneiform');
312
+ }
313
+ const result = {
314
+ userId,
315
+ isReady,
316
+ isCuneiformInstalled,
317
+ permissionSets,
318
+ configProfile,
319
+ messages,
320
+ };
321
+ const duration = Date.now() - startTime;
322
+ this.logger?.log(`Readiness check complete: ${isReady ? 'READY' : 'NOT READY'}`);
323
+ return createSuccessResult(result, {
324
+ message: isReady ? 'User is ready' : 'User is not ready',
325
+ metadata: { duration },
326
+ });
327
+ }
328
+ catch (error) {
329
+ const errorMessage = error instanceof Error ? error.message : String(error);
330
+ this.logger?.log(`Readiness check failed: ${errorMessage}`);
331
+ const emptyResult = UserReadinessService.createEmptyReadiness(userId);
332
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_READINESS_QUERY_FAILED, errorMessage, {
333
+ metadata: { duration: Date.now() - startTime },
334
+ });
335
+ }
336
+ }
337
+ /**
338
+ * Checks if the user has required Cuneiform permission sets.
339
+ *
340
+ * @param userId - The Salesforce user ID to check
341
+ * @returns ServiceResult containing PermissionSetStatus
342
+ */
343
+ async hasRequiredPermissionSets(userId) {
344
+ const startTime = Date.now();
345
+ // Validate userId
346
+ const validationError = validateRequiredString(userId, 'User ID');
347
+ if (validationError) {
348
+ const emptyResult = {
349
+ hasAllRequired: false,
350
+ assignments: [],
351
+ missingRequired: [...REQUIRED_PERMISSION_SETS],
352
+ };
353
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_ID_REQUIRED, validationError, {
354
+ metadata: { duration: Date.now() - startTime },
355
+ });
356
+ }
357
+ try {
358
+ this.logger?.log(`Checking permission sets for user: ${userId}`);
359
+ // Step 1: Check direct PermissionSetAssignment records
360
+ const directSoql = new CuneiformQueryBuilder()
361
+ .select([
362
+ 'Id',
363
+ 'PermissionSet.Id',
364
+ 'PermissionSet.Name',
365
+ 'PermissionSet.Label',
366
+ 'PermissionSet.NamespacePrefix',
367
+ ])
368
+ .from('PermissionSetAssignment')
369
+ .where('AssigneeId', '=', userId)
370
+ .andWhereIn('PermissionSet.Name', [...REQUIRED_PERMISSION_SETS])
371
+ .andWhere('PermissionSet.NamespacePrefix', '=', CUNEIFORM_NAMESPACE)
372
+ .toSOQL();
373
+ const directResult = await this.soqlAdapter.query(directSoql);
374
+ if (!directResult.success) {
375
+ const emptyResult = {
376
+ hasAllRequired: false,
377
+ assignments: [],
378
+ missingRequired: [...REQUIRED_PERMISSION_SETS],
379
+ };
380
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_PERMISSION_SET_CHECK_FAILED, directResult.message ?? 'Permission set query failed', {
381
+ metadata: { duration: Date.now() - startTime },
382
+ });
383
+ }
384
+ // Build map of assigned permission set names to their labels
385
+ const assignedLabels = new Map(directResult.data.records.map((r) => [r.PermissionSet.Name, r.PermissionSet.Label]));
386
+ // Step 2: If any required permission sets are still missing, check group-based access
387
+ const directMissing = REQUIRED_PERMISSION_SETS.filter((name) => !assignedLabels.has(name));
388
+ if (directMissing.length > 0) {
389
+ const groupLabels = await this.getGroupAssignedPermissionSets(userId, directMissing);
390
+ for (const [name, label] of groupLabels) {
391
+ assignedLabels.set(name, label);
392
+ }
393
+ }
394
+ // Build final status from combined direct + group results
395
+ const assignments = REQUIRED_PERMISSION_SETS.map((name) => ({
396
+ name,
397
+ label: assignedLabels.get(name),
398
+ isAssigned: assignedLabels.has(name),
399
+ isRequired: true,
400
+ }));
401
+ const missingRequired = REQUIRED_PERMISSION_SETS.filter((name) => !assignedLabels.has(name));
402
+ const hasAllRequired = missingRequired.length === 0;
403
+ const status = {
404
+ hasAllRequired,
405
+ assignments,
406
+ missingRequired,
407
+ };
408
+ const duration = Date.now() - startTime;
409
+ this.logger?.log(`Permission check: ${hasAllRequired ? 'all assigned' : `missing ${missingRequired.length}`}`);
410
+ return createSuccessResult(status, {
411
+ message: hasAllRequired
412
+ ? 'All required permission sets assigned'
413
+ : `Missing ${missingRequired.length} permission sets`,
414
+ metadata: { duration },
415
+ });
416
+ }
417
+ catch (error) {
418
+ const errorMessage = error instanceof Error ? error.message : String(error);
419
+ this.logger?.log(`Permission set check failed: ${errorMessage}`);
420
+ const emptyResult = {
421
+ hasAllRequired: false,
422
+ assignments: [],
423
+ missingRequired: [...REQUIRED_PERMISSION_SETS],
424
+ };
425
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_PERMISSION_SET_CHECK_FAILED, errorMessage, {
426
+ metadata: { duration: Date.now() - startTime },
427
+ });
428
+ }
429
+ }
430
+ /**
431
+ * Retrieves the ID of a permission set by name and namespace.
432
+ *
433
+ * Queries the PermissionSet object directly to find a permission set by
434
+ * its Name and NamespacePrefix. This method returns the permission set ID
435
+ * for use in permission set assignment operations.
436
+ *
437
+ * @param permissionSetName - The permission set API name (e.g., 'Cuneiform_for_CRM_Global_Profiling_Support')
438
+ * @param namespacePrefix - The namespace prefix (e.g., 'pnova')
439
+ * @returns ServiceResult containing the permission set ID or null if not found
440
+ *
441
+ * @example
442
+ * ```typescript
443
+ * const result = await service.getPermissionSetId(
444
+ * 'Cuneiform_for_CRM_Global_Profiling_Support',
445
+ * 'pnova'
446
+ * );
447
+ * if (result.success && result.data) {
448
+ * console.log(`Permission Set ID: ${result.data}`);
449
+ * } else if (result.success && result.data === null) {
450
+ * console.log('Permission set not found in org');
451
+ * }
452
+ * ```
453
+ */
454
+ async getPermissionSetId(permissionSetName, namespacePrefix) {
455
+ const startTime = Date.now();
456
+ const emptyResult = null;
457
+ // Validate permissionSetName
458
+ const nameError = validateRequiredString(permissionSetName, 'Permission set name');
459
+ if (nameError) {
460
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_PERMISSION_SET_CHECK_FAILED, nameError, {
461
+ metadata: { duration: Date.now() - startTime },
462
+ });
463
+ }
464
+ // Validate namespacePrefix
465
+ const namespaceError = validateRequiredString(namespacePrefix, 'Namespace prefix');
466
+ if (namespaceError) {
467
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_PERMISSION_SET_CHECK_FAILED, namespaceError, {
468
+ metadata: { duration: Date.now() - startTime },
469
+ });
470
+ }
471
+ try {
472
+ this.logger?.log(`Querying permission set: ${namespacePrefix}__${permissionSetName}`);
473
+ const soql = new CuneiformQueryBuilder()
474
+ .select(['Id'])
475
+ .from('PermissionSet')
476
+ .where('Name', '=', permissionSetName)
477
+ .andWhere('NamespacePrefix', '=', namespacePrefix)
478
+ .limit(1)
479
+ .toSOQL();
480
+ const result = await this.soqlAdapter.query(soql);
481
+ if (!result.success) {
482
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_PERMISSION_SET_CHECK_FAILED, result.message ?? 'Permission set query failed', {
483
+ metadata: { duration: Date.now() - startTime },
484
+ });
485
+ }
486
+ // Permission set not found - return null (not an error)
487
+ if (result.data.records.length === 0) {
488
+ const duration = Date.now() - startTime;
489
+ this.logger?.log(`Permission set not found: ${namespacePrefix}__${permissionSetName}`);
490
+ return createSuccessResult(null, {
491
+ message: `Permission set not found: ${namespacePrefix}__${permissionSetName}`,
492
+ warnings: [`Permission set '${permissionSetName}' not found in namespace '${namespacePrefix}'`],
493
+ metadata: { duration },
494
+ });
495
+ }
496
+ const permissionSetId = result.data.records[0].Id;
497
+ const duration = Date.now() - startTime;
498
+ this.logger?.log(`Permission set found: ${permissionSetId}`);
499
+ return createSuccessResult(permissionSetId, {
500
+ message: `Permission set found: ${permissionSetId}`,
501
+ metadata: { duration },
502
+ });
503
+ }
504
+ catch (error) {
505
+ const errorMessage = error instanceof Error ? error.message : String(error);
506
+ this.logger?.log(`Permission set query failed: ${errorMessage}`);
507
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_PERMISSION_SET_CHECK_FAILED, errorMessage, {
508
+ metadata: { duration: Date.now() - startTime },
509
+ });
510
+ }
511
+ }
512
+ /**
513
+ * Checks if a configuration profile is configured.
514
+ *
515
+ * Queries the Cuneiform Active Configuration CMT to determine if a profile
516
+ * is set up. If the CMT doesn't exist, returns E4654 indicating Cuneiform
517
+ * is not installed.
518
+ *
519
+ * @returns ServiceResult containing ConfigProfileStatus
520
+ */
521
+ async hasConfigProfile() {
522
+ const startTime = Date.now();
523
+ try {
524
+ this.logger?.log('Checking configuration profile...');
525
+ const soql = new CuneiformQueryBuilder()
526
+ .select([
527
+ 'Id',
528
+ 'DeveloperName',
529
+ 'pnova__Active_Configuration_Profile__r.DeveloperName',
530
+ 'pnova__Active_Configuration_Profile__r.Label',
531
+ 'pnova__Active_Configuration_Profile__r.pnova__Enable_API_Only_Profiling__c',
532
+ 'pnova__Active_Configuration_Profile__r.pnova__Enable_API_Only_Profiling_Registration__c',
533
+ ])
534
+ .from('pnova__Active_Configuration__mdt')
535
+ .where('DeveloperName', '=', 'Active_Configuration')
536
+ .limit(1)
537
+ .toSOQL();
538
+ const result = await this.soqlAdapter.query(soql);
539
+ // Check for namespace not found error (Cuneiform not installed)
540
+ if (!result.success) {
541
+ if (UserReadinessService.isCuneiformNamespaceNotFoundError(result.message ?? '')) {
542
+ return createFailureResult({ isConfigured: false }, ServiceErrorCodes.USER_CUNEIFORM_NAMESPACE_NOT_FOUND, 'Cuneiform namespace not found - package may not be installed', { metadata: { duration: Date.now() - startTime } });
543
+ }
544
+ return createFailureResult({ isConfigured: false }, ServiceErrorCodes.USER_CONFIG_PROFILE_CHECK_FAILED, result.message ?? 'Config profile query failed', { metadata: { duration: Date.now() - startTime } });
545
+ }
546
+ // No config record found
547
+ if (result.data.records.length === 0) {
548
+ const duration = Date.now() - startTime;
549
+ return createSuccessResult({ isConfigured: false }, {
550
+ message: 'No active configuration found',
551
+ metadata: { duration },
552
+ });
553
+ }
554
+ const record = result.data.records[0];
555
+ const profile = record.pnova__Active_Configuration_Profile__r;
556
+ // Config record exists but no profile linked
557
+ if (!profile) {
558
+ const duration = Date.now() - startTime;
559
+ return createSuccessResult({ isConfigured: false }, {
560
+ message: 'Configuration exists but no profile is linked',
561
+ metadata: { duration },
562
+ });
563
+ }
564
+ const status = {
565
+ isConfigured: true,
566
+ profileDeveloperName: profile.DeveloperName,
567
+ profileLabel: profile.Label,
568
+ apiOnlyProfilingEnabled: profile.pnova__Enable_API_Only_Profiling__c,
569
+ selfRegistrationEnabled: profile.pnova__Enable_API_Only_Profiling_Registration__c,
570
+ };
571
+ const duration = Date.now() - startTime;
572
+ this.logger?.log(`Config profile found: ${status.profileLabel ?? 'Unknown'}`);
573
+ return createSuccessResult(status, {
574
+ message: `Active profile: ${status.profileLabel ?? 'Unknown'}`,
575
+ metadata: { duration },
576
+ });
577
+ }
578
+ catch (error) {
579
+ const errorMessage = error instanceof Error ? error.message : String(error);
580
+ this.logger?.log(`Config profile check failed: ${errorMessage}`);
581
+ // Check for namespace not found in exception
582
+ if (UserReadinessService.isCuneiformNamespaceNotFoundError(errorMessage)) {
583
+ return createFailureResult({ isConfigured: false }, ServiceErrorCodes.USER_CUNEIFORM_NAMESPACE_NOT_FOUND, 'Cuneiform namespace not found - package may not be installed', { metadata: { duration: Date.now() - startTime } });
584
+ }
585
+ return createFailureResult({ isConfigured: false }, ServiceErrorCodes.USER_CONFIG_PROFILE_CHECK_FAILED, errorMessage, { metadata: { duration: Date.now() - startTime } });
586
+ }
587
+ }
588
+ /**
589
+ * Validates that the user has profiling access to use Cuneiform commands.
590
+ *
591
+ * Checks in order:
592
+ * 1. Cuneiform is installed in the org
593
+ * 2. Required permission sets are assigned
594
+ * 3. Global Profiling is enabled
595
+ *
596
+ * Returns success if all checks pass. Returns a specific error code for the
597
+ * first failing check, with a user-friendly message including remediation steps.
598
+ *
599
+ * @param userId - The Salesforce user ID to validate
600
+ * @returns ServiceResult<void> — success or failure with specific error code
601
+ */
602
+ async validateProfilingAccess(userId) {
603
+ const startTime = Date.now();
604
+ const readinessResult = await this.checkReadiness(userId);
605
+ if (!readinessResult.success) {
606
+ return createFailureResult(undefined, readinessResult.errorCode ?? ServiceErrorCodes.USER_READINESS_QUERY_FAILED, readinessResult.message ?? 'Readiness check failed', { metadata: { duration: Date.now() - startTime } });
607
+ }
608
+ const readiness = readinessResult.data;
609
+ // Gate 1: Cuneiform must be installed
610
+ if (!readiness.isCuneiformInstalled) {
611
+ return createFailureResult(undefined, ServiceErrorCodes.USER_CUNEIFORM_NAMESPACE_NOT_FOUND, 'Cuneiform for Salesforce is not installed in this org.', { metadata: { duration: Date.now() - startTime } });
612
+ }
613
+ // Gate 2: Required permission sets must be assigned
614
+ if (!readiness.permissionSets.hasAllRequired) {
615
+ const missingLabels = readiness.permissionSets.missingRequired.map((name) => REQUIRED_PERMISSION_SET_LABELS[name] ?? name);
616
+ return createFailureResult(undefined, ServiceErrorCodes.PROFILING_ACCESS_DENIED, "Cuneiform is installed, but you don't have profiling access. " +
617
+ `Missing permission sets: ${missingLabels.join(', ')}. ` +
618
+ 'Run "sf cuneiform user details --target-org <org>" for a full readiness diagnostic.', { metadata: { duration: Date.now() - startTime } });
619
+ }
620
+ // Gate 3: Global Profiling must be explicitly enabled
621
+ // Checks both: (a) config profile must exist, and (b) apiOnlyProfilingEnabled must be exactly true.
622
+ // When apiOnlyProfilingEnabled is undefined (e.g., Salesforce field returns null), access is denied.
623
+ if (!readiness.configProfile.isConfigured || readiness.configProfile.apiOnlyProfilingEnabled !== true) {
624
+ return createFailureResult(undefined, ServiceErrorCodes.GLOBAL_PROFILING_NOT_ENABLED, 'Cuneiform is installed and your permission sets are assigned, but Global Profiling is not enabled. ' +
625
+ 'Run "sf cuneiform user details --target-org <org> --configure" to enable it, ' +
626
+ 'or ask your Salesforce administrator to enable API-Only Profiling in the Configuration Profile.', { metadata: { duration: Date.now() - startTime } });
627
+ }
628
+ // Gate 4: Self-registration must be enabled for CLI self-provisioning
629
+ // This gate only applies to the configure flow (checked by callers), but validateProfilingAccess
630
+ // does NOT enforce it — it validates read access only. The configure flow checks this gate separately.
631
+ // See UserConfigurationService.buildConfigurationActions() for the enforcement point.
632
+ return createSuccessResult(undefined, {
633
+ message: 'Profiling access validated',
634
+ metadata: { duration: Date.now() - startTime },
635
+ });
636
+ }
637
+ /**
638
+ * Checks the feature status via the ISV profiling status REST endpoint.
639
+ *
640
+ * Calls `GET /services/apexrest/pnova/v1/profiling/status` to determine whether
641
+ * API-Based Profiling is enabled for this organization. This is Gate 0 — if the
642
+ * feature is not enabled, all other gates are moot.
643
+ *
644
+ * Graceful degradation:
645
+ * - On 404 (endpoint not found): returns success with `featureEnabled: true`.
646
+ * Older ISV packages may not expose this endpoint; we don't block them.
647
+ * - On other errors: returns failure with `FEATURE_STATUS_CHECK_FAILED`.
648
+ *
649
+ * @param restAdapter - The REST API adapter for making the HTTP request
650
+ * @returns ServiceResult containing FeatureStatus
651
+ *
652
+ * @example
653
+ * ```typescript
654
+ * const result = await service.checkFeatureStatus(restAdapter);
655
+ * if (result.success && !result.data.featureEnabled) {
656
+ * // Block command execution — feature is disabled
657
+ * }
658
+ * ```
659
+ */
660
+ async checkFeatureStatus(restAdapter) {
661
+ const startTime = Date.now();
662
+ const statusUrl = '/services/apexrest/pnova/v1/profiling/status';
663
+ try {
664
+ this.logger?.log('Checking feature status via REST endpoint');
665
+ const result = await restAdapter.request({
666
+ url: statusUrl,
667
+ method: 'GET',
668
+ });
669
+ if (result.success) {
670
+ const duration = Date.now() - startTime;
671
+ this.logger?.log(`Feature status: featureEnabled=${String(result.data.featureEnabled)}`);
672
+ return createSuccessResult(result.data, {
673
+ message: `Feature status: ${result.data.featureEnabled ? 'enabled' : 'disabled'}`,
674
+ metadata: { duration },
675
+ });
676
+ }
677
+ // Check for 404 — graceful degradation for older ISV packages
678
+ const errorMessage = result.message ?? '';
679
+ if (errorMessage.includes('404') || errorMessage.includes('Not Found') || errorMessage.includes('NOT_FOUND')) {
680
+ this.logger?.log('Feature status endpoint not found (404) — assuming enabled (older ISV package)');
681
+ const duration = Date.now() - startTime;
682
+ return createSuccessResult({
683
+ featureEnabled: true,
684
+ apiBasedProfilingEnabled: true,
685
+ selfRegistrationEnabled: false,
686
+ packageVersion: 'unknown',
687
+ }, {
688
+ message: 'Feature status endpoint not available — assuming enabled (older ISV package)',
689
+ warnings: ['Status endpoint not found; feature status assumed enabled for backward compatibility'],
690
+ metadata: { duration },
691
+ });
692
+ }
693
+ // Other errors — return failure
694
+ const duration = Date.now() - startTime;
695
+ return createFailureResult({
696
+ featureEnabled: false,
697
+ apiBasedProfilingEnabled: false,
698
+ selfRegistrationEnabled: false,
699
+ packageVersion: 'unknown',
700
+ }, ServiceErrorCodes.FEATURE_STATUS_CHECK_FAILED, errorMessage || 'Feature status check failed', { metadata: { duration } });
701
+ }
702
+ catch (error) {
703
+ const errorMessage = error instanceof Error ? error.message : String(error);
704
+ this.logger?.log(`Feature status check failed: ${errorMessage}`);
705
+ // Check for 404 in exception messages too
706
+ if (errorMessage.includes('404') || errorMessage.includes('Not Found') || errorMessage.includes('NOT_FOUND')) {
707
+ const duration = Date.now() - startTime;
708
+ return createSuccessResult({
709
+ featureEnabled: true,
710
+ apiBasedProfilingEnabled: true,
711
+ selfRegistrationEnabled: false,
712
+ packageVersion: 'unknown',
713
+ }, {
714
+ message: 'Feature status endpoint not available — assuming enabled (older ISV package)',
715
+ warnings: ['Status endpoint not found; feature status assumed enabled for backward compatibility'],
716
+ metadata: { duration },
717
+ });
718
+ }
719
+ return createFailureResult({
720
+ featureEnabled: false,
721
+ apiBasedProfilingEnabled: false,
722
+ selfRegistrationEnabled: false,
723
+ packageVersion: 'unknown',
724
+ }, ServiceErrorCodes.FEATURE_STATUS_CHECK_FAILED, errorMessage, { metadata: { duration: Date.now() - startTime } });
725
+ }
726
+ }
727
+ /**
728
+ * Attempts REST delegation for user readiness.
729
+ * Returns the successful result, or null to signal fallback to the local SOQL path.
730
+ * Falls back when REST returns cuneiformInstalled=false (Apex endpoint bug on some orgs).
731
+ */
732
+ async tryRestReadiness(userId, startTime) {
733
+ if (!this.restClient) {
734
+ return null;
735
+ }
736
+ const restResult = await this.checkReadinessViaRest(userId, startTime);
737
+ if (restResult.success && restResult.data.isCuneiformInstalled) {
738
+ return restResult;
739
+ }
740
+ this.logger?.log('REST readiness returned not-installed or failed — falling back to local SOQL');
741
+ return null;
742
+ }
743
+ /**
744
+ * Delegates user readiness check to the ISV REST API.
745
+ *
746
+ * @param userId - The Salesforce user ID to check
747
+ * @param startTime - Timestamp for duration tracking
748
+ * @returns ServiceResult containing UserReadiness from REST endpoint
749
+ */
750
+ async checkReadinessViaRest(userId, startTime) {
751
+ this.logger?.log('Delegating user readiness to ISV REST API (user-readiness)');
752
+ const emptyResult = UserReadinessService.createEmptyReadiness(userId);
753
+ const restResult = await this.restClient.checkUserReadiness(userId);
754
+ if (!restResult.success) {
755
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_READINESS_QUERY_FAILED, restResult.message ?? 'REST user-readiness failed', {
756
+ metadata: { duration: Date.now() - startTime },
757
+ });
758
+ }
759
+ const response = restResult.data;
760
+ if (!response.success) {
761
+ const errorMsg = response.errors?.length > 0 ? response.errors[0] : 'Server-side readiness check failed';
762
+ return createFailureResult(emptyResult, ServiceErrorCodes.USER_READINESS_QUERY_FAILED, errorMsg, {
763
+ metadata: { duration: Date.now() - startTime },
764
+ });
765
+ }
766
+ const mappedResult = response.result
767
+ ? UserReadinessService.mapRestPayloadToUserReadiness(userId, response.result)
768
+ : emptyResult;
769
+ return createSuccessResult(mappedResult, {
770
+ message: 'User readiness checked via REST API',
771
+ metadata: { duration: Date.now() - startTime, strategyUsed: 'rest-api' },
772
+ });
773
+ }
774
+ /**
775
+ * Checks for required permission sets accessible through PermissionSetGroup membership.
776
+ *
777
+ * Two-step query approach for precision:
778
+ * 1. Get the specific PermissionSetGroup IDs assigned to this user
779
+ * 2. Check if those specific groups contain any of the missing required permission sets
780
+ *
781
+ * Both queries are tightly filtered to avoid pulling excess records:
782
+ * - Group query: filtered by AssigneeId AND PermissionSetGroupId != null
783
+ * - Component query: filtered by specific group IDs, permission set names, AND namespace
784
+ *
785
+ * @param userId - The Salesforce user ID
786
+ * @param missingNames - Permission set names not found via direct assignment
787
+ * @returns Map of permission set names to labels found through group membership
788
+ */
789
+ async getGroupAssignedPermissionSets(userId, missingNames) {
790
+ const foundLabels = new Map();
791
+ try {
792
+ // Step 2a: Get the user's PermissionSetGroup assignments
793
+ // Precise filter: only this user, only rows that ARE group assignments
794
+ const groupSoql = new CuneiformQueryBuilder()
795
+ .select(['PermissionSetGroupId'])
796
+ .from('PermissionSetAssignment')
797
+ .where('AssigneeId', '=', userId)
798
+ .andWhereNull('PermissionSetGroupId', false)
799
+ .toSOQL();
800
+ const groupResult = await this.soqlAdapter.query(groupSoql);
801
+ if (!groupResult.success || groupResult.data.records.length === 0) {
802
+ return foundLabels;
803
+ }
804
+ const groupIds = groupResult.data.records.map((r) => r.PermissionSetGroupId);
805
+ this.logger?.log(`User belongs to ${groupIds.length} permission set group(s)`);
806
+ // Step 2b: Check if those groups contain any of the missing required permission sets
807
+ // Precise filter: only the user's groups, only the missing names, only our namespace
808
+ const componentSoql = new CuneiformQueryBuilder()
809
+ .select(['PermissionSet.Name', 'PermissionSet.Label'])
810
+ .from('PermissionSetGroupComponent')
811
+ .where('PermissionSet.NamespacePrefix', '=', CUNEIFORM_NAMESPACE)
812
+ .andWhereIn('PermissionSetGroupId', groupIds)
813
+ .andWhereIn('PermissionSet.Name', [...missingNames])
814
+ .toSOQL();
815
+ const componentResult = await this.soqlAdapter.query(componentSoql);
816
+ if (!componentResult.success) {
817
+ return foundLabels;
818
+ }
819
+ for (const record of componentResult.data.records) {
820
+ foundLabels.set(record.PermissionSet.Name, record.PermissionSet.Label);
821
+ }
822
+ this.logger?.log(`Found ${foundLabels.size} permission set(s) via group membership`);
823
+ }
824
+ catch (error) {
825
+ // Group check is supplementary — don't fail the entire permission check
826
+ this.logger?.log(`Group permission check failed: ${error instanceof Error ? error.message : String(error)}`);
827
+ }
828
+ return foundLabels;
829
+ }
830
+ }
831
+ //# sourceMappingURL=UserReadinessService.js.map