@ffschrattenecker/tm1-mcp-server 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (475) hide show
  1. package/CHANGELOG.md +1211 -0
  2. package/LICENSE +21 -0
  3. package/NOTICE +34 -0
  4. package/README.md +276 -0
  5. package/dist/config.d.ts +35 -0
  6. package/dist/config.js +238 -0
  7. package/dist/http-transport.d.ts +8 -0
  8. package/dist/http-transport.js +132 -0
  9. package/dist/index.d.ts +18 -0
  10. package/dist/index.js +164 -0
  11. package/dist/lib/callgraph/callGraph.d.ts +124 -0
  12. package/dist/lib/callgraph/callGraph.js +334 -0
  13. package/dist/lib/callgraph/choreGraph.d.ts +23 -0
  14. package/dist/lib/callgraph/choreGraph.js +102 -0
  15. package/dist/lib/callgraph/dataFlow.d.ts +74 -0
  16. package/dist/lib/callgraph/dataFlow.js +271 -0
  17. package/dist/lib/callgraph/datasourceMembership.d.ts +31 -0
  18. package/dist/lib/callgraph/datasourceMembership.js +142 -0
  19. package/dist/lib/callgraph/lintTypes.d.ts +28 -0
  20. package/dist/lib/callgraph/lintTypes.js +2 -0
  21. package/dist/lib/callgraph/mdxMembers.d.ts +29 -0
  22. package/dist/lib/callgraph/mdxMembers.js +97 -0
  23. package/dist/lib/callgraph/referenceIndex.d.ts +179 -0
  24. package/dist/lib/callgraph/referenceIndex.js +584 -0
  25. package/dist/lib/callgraph/rulesLinter.d.ts +55 -0
  26. package/dist/lib/callgraph/rulesLinter.js +776 -0
  27. package/dist/lib/callgraph/rulesParser.d.ts +26 -0
  28. package/dist/lib/callgraph/rulesParser.js +71 -0
  29. package/dist/lib/callgraph/subsetUsage.d.ts +16 -0
  30. package/dist/lib/callgraph/subsetUsage.js +134 -0
  31. package/dist/lib/callgraph/tiParser.d.ts +21 -0
  32. package/dist/lib/callgraph/tiParser.js +672 -0
  33. package/dist/lib/callgraph/tiSignatures.d.ts +32 -0
  34. package/dist/lib/callgraph/tiSignatures.js +6185 -0
  35. package/dist/lib/callgraph/tm1-adapter.d.ts +32 -0
  36. package/dist/lib/callgraph/tm1-adapter.js +159 -0
  37. package/dist/lib/callgraph/types.d.ts +53 -0
  38. package/dist/lib/callgraph/types.js +2 -0
  39. package/dist/lib/callgraph/variableEnv.d.ts +86 -0
  40. package/dist/lib/callgraph/variableEnv.js +214 -0
  41. package/dist/lib/cell-address.d.ts +12 -0
  42. package/dist/lib/cell-address.js +71 -0
  43. package/dist/lib/complexity/antipatterns.d.ts +22 -0
  44. package/dist/lib/complexity/antipatterns.js +302 -0
  45. package/dist/lib/complexity/comment-classifier.d.ts +24 -0
  46. package/dist/lib/complexity/comment-classifier.js +43 -0
  47. package/dist/lib/complexity/cross-process.d.ts +78 -0
  48. package/dist/lib/complexity/cross-process.js +114 -0
  49. package/dist/lib/complexity/process-metrics.d.ts +78 -0
  50. package/dist/lib/complexity/process-metrics.js +278 -0
  51. package/dist/lib/complexity/rules-metrics.d.ts +31 -0
  52. package/dist/lib/complexity/rules-metrics.js +99 -0
  53. package/dist/lib/concurrency.d.ts +11 -0
  54. package/dist/lib/concurrency.js +27 -0
  55. package/dist/lib/control-name.d.ts +10 -0
  56. package/dist/lib/control-name.js +10 -0
  57. package/dist/lib/coordinate-error.d.ts +3 -0
  58. package/dist/lib/coordinate-error.js +29 -0
  59. package/dist/lib/credential-format.d.ts +23 -0
  60. package/dist/lib/credential-format.js +25 -0
  61. package/dist/lib/cube-stats/fetcher.d.ts +106 -0
  62. package/dist/lib/cube-stats/fetcher.js +194 -0
  63. package/dist/lib/feeders/brackets.d.ts +47 -0
  64. package/dist/lib/feeders/brackets.js +195 -0
  65. package/dist/lib/feeders/element-type-cache.d.ts +42 -0
  66. package/dist/lib/feeders/element-type-cache.js +86 -0
  67. package/dist/lib/feeders/static-heuristics.d.ts +101 -0
  68. package/dist/lib/feeders/static-heuristics.js +202 -0
  69. package/dist/lib/git-process.d.ts +67 -0
  70. package/dist/lib/git-process.js +243 -0
  71. package/dist/lib/mask-secrets.d.ts +10 -0
  72. package/dist/lib/mask-secrets.js +99 -0
  73. package/dist/lib/mdx.d.ts +3 -0
  74. package/dist/lib/mdx.js +13 -0
  75. package/dist/lib/naming/odata-filter.d.ts +15 -0
  76. package/dist/lib/naming/odata-filter.js +81 -0
  77. package/dist/lib/naming/rules.d.ts +34 -0
  78. package/dist/lib/naming/rules.js +215 -0
  79. package/dist/lib/pro-parser.d.ts +19 -0
  80. package/dist/lib/pro-parser.js +260 -0
  81. package/dist/lib/pro-serializer.d.ts +19 -0
  82. package/dist/lib/pro-serializer.js +170 -0
  83. package/dist/lib/process-parts-schema.d.ts +45 -0
  84. package/dist/lib/process-parts-schema.js +46 -0
  85. package/dist/lib/process-refs.d.ts +88 -0
  86. package/dist/lib/process-refs.js +441 -0
  87. package/dist/lib/rules-outline.d.ts +29 -0
  88. package/dist/lib/rules-outline.js +68 -0
  89. package/dist/lib/rules-patch.d.ts +6 -0
  90. package/dist/lib/rules-patch.js +59 -0
  91. package/dist/lib/safe-regex.d.ts +15 -0
  92. package/dist/lib/safe-regex.js +37 -0
  93. package/dist/lib/sample-cells.d.ts +48 -0
  94. package/dist/lib/sample-cells.js +146 -0
  95. package/dist/lib/slim-json-schema.d.ts +20 -0
  96. package/dist/lib/slim-json-schema.js +68 -0
  97. package/dist/lib/strip-comments.d.ts +23 -0
  98. package/dist/lib/strip-comments.js +61 -0
  99. package/dist/lib/tm1-events.d.ts +16 -0
  100. package/dist/lib/tm1-events.js +29 -0
  101. package/dist/lib/v12-compat/deprecated-ti.d.ts +17 -0
  102. package/dist/lib/v12-compat/deprecated-ti.js +257 -0
  103. package/dist/lib/v12-compat/scanner.d.ts +10 -0
  104. package/dist/lib/v12-compat/scanner.js +43 -0
  105. package/dist/lib/variables-ui-data.d.ts +26 -0
  106. package/dist/lib/variables-ui-data.js +77 -0
  107. package/dist/load-env.d.ts +2 -0
  108. package/dist/load-env.js +29 -0
  109. package/dist/logger.d.ts +4 -0
  110. package/dist/logger.js +60 -0
  111. package/dist/prompts/index.d.ts +3 -0
  112. package/dist/prompts/index.js +141 -0
  113. package/dist/resources/index.d.ts +5 -0
  114. package/dist/resources/index.js +237 -0
  115. package/dist/resources/list-handler.d.ts +40 -0
  116. package/dist/resources/list-handler.js +86 -0
  117. package/dist/resources/subscriptions.d.ts +19 -0
  118. package/dist/resources/subscriptions.js +80 -0
  119. package/dist/schemas/cells.d.ts +17 -0
  120. package/dist/schemas/cells.js +13 -0
  121. package/dist/schemas/common.d.ts +16 -0
  122. package/dist/schemas/common.js +14 -0
  123. package/dist/schemas/index.d.ts +10 -0
  124. package/dist/schemas/index.js +23 -0
  125. package/dist/schemas/metadata.d.ts +70 -0
  126. package/dist/schemas/metadata.js +47 -0
  127. package/dist/schemas/monitoring.d.ts +95 -0
  128. package/dist/schemas/monitoring.js +69 -0
  129. package/dist/schemas/processes.d.ts +74 -0
  130. package/dist/schemas/processes.js +66 -0
  131. package/dist/schemas/scheduling.d.ts +13 -0
  132. package/dist/schemas/scheduling.js +13 -0
  133. package/dist/schemas/security.d.ts +19 -0
  134. package/dist/schemas/security.js +16 -0
  135. package/dist/schemas/subsets.d.ts +12 -0
  136. package/dist/schemas/subsets.js +12 -0
  137. package/dist/schemas/views.d.ts +9 -0
  138. package/dist/schemas/views.js +9 -0
  139. package/dist/session-manager.d.ts +79 -0
  140. package/dist/session-manager.js +281 -0
  141. package/dist/tm1-client/connection/profile.d.ts +13 -0
  142. package/dist/tm1-client/connection/profile.js +99 -0
  143. package/dist/tm1-client/dispatcher.d.ts +5 -0
  144. package/dist/tm1-client/dispatcher.js +31 -0
  145. package/dist/tm1-client/http.d.ts +81 -0
  146. package/dist/tm1-client/http.js +547 -0
  147. package/dist/tm1-client/services/batch-service.d.ts +123 -0
  148. package/dist/tm1-client/services/batch-service.js +455 -0
  149. package/dist/tm1-client/services/cell-service.d.ts +71 -0
  150. package/dist/tm1-client/services/cell-service.js +333 -0
  151. package/dist/tm1-client/services/cellset-transform.d.ts +26 -0
  152. package/dist/tm1-client/services/cellset-transform.js +80 -0
  153. package/dist/tm1-client/services/chore-service.d.ts +68 -0
  154. package/dist/tm1-client/services/chore-service.js +179 -0
  155. package/dist/tm1-client/services/chore-status.d.ts +11 -0
  156. package/dist/tm1-client/services/chore-status.js +127 -0
  157. package/dist/tm1-client/services/cube-service.d.ts +134 -0
  158. package/dist/tm1-client/services/cube-service.js +294 -0
  159. package/dist/tm1-client/services/dimension-service.d.ts +118 -0
  160. package/dist/tm1-client/services/dimension-service.js +249 -0
  161. package/dist/tm1-client/services/element-service.d.ts +245 -0
  162. package/dist/tm1-client/services/element-service.js +809 -0
  163. package/dist/tm1-client/services/fallback.d.ts +44 -0
  164. package/dist/tm1-client/services/fallback.js +72 -0
  165. package/dist/tm1-client/services/file-service.d.ts +53 -0
  166. package/dist/tm1-client/services/file-service.js +218 -0
  167. package/dist/tm1-client/services/hierarchy-service.d.ts +129 -0
  168. package/dist/tm1-client/services/hierarchy-service.js +332 -0
  169. package/dist/tm1-client/services/monitoring-service.d.ts +34 -0
  170. package/dist/tm1-client/services/monitoring-service.js +123 -0
  171. package/dist/tm1-client/services/odata-page.d.ts +71 -0
  172. package/dist/tm1-client/services/odata-page.js +87 -0
  173. package/dist/tm1-client/services/process-service.d.ts +278 -0
  174. package/dist/tm1-client/services/process-service.js +874 -0
  175. package/dist/tm1-client/services/process-status.d.ts +21 -0
  176. package/dist/tm1-client/services/process-status.js +89 -0
  177. package/dist/tm1-client/services/security-service.d.ts +50 -0
  178. package/dist/tm1-client/services/security-service.js +93 -0
  179. package/dist/tm1-client/services/server-service.d.ts +116 -0
  180. package/dist/tm1-client/services/server-service.js +504 -0
  181. package/dist/tm1-client/services/subset-service.d.ts +37 -0
  182. package/dist/tm1-client/services/subset-service.js +122 -0
  183. package/dist/tm1-client/services/view-service.d.ts +46 -0
  184. package/dist/tm1-client/services/view-service.js +287 -0
  185. package/dist/tm1-client.d.ts +56 -0
  186. package/dist/tm1-client.js +126 -0
  187. package/dist/tools/analysis/analyze-callgraph.d.ts +28 -0
  188. package/dist/tools/analysis/analyze-callgraph.js +350 -0
  189. package/dist/tools/analysis/analyze-chore-graph.d.ts +2 -0
  190. package/dist/tools/analysis/analyze-chore-graph.js +148 -0
  191. package/dist/tools/analysis/analyze-object-usage.d.ts +2 -0
  192. package/dist/tools/analysis/analyze-object-usage.js +143 -0
  193. package/dist/tools/analysis/audit-complexity.d.ts +2 -0
  194. package/dist/tools/analysis/audit-complexity.js +255 -0
  195. package/dist/tools/analysis/audit-feeders.d.ts +2 -0
  196. package/dist/tools/analysis/audit-feeders.js +417 -0
  197. package/dist/tools/analysis/audit-naming.d.ts +2 -0
  198. package/dist/tools/analysis/audit-naming.js +379 -0
  199. package/dist/tools/analysis/check-v12-readiness.d.ts +2 -0
  200. package/dist/tools/analysis/check-v12-readiness.js +136 -0
  201. package/dist/tools/analysis/find-orphan-dimensions.d.ts +2 -0
  202. package/dist/tools/analysis/find-orphan-dimensions.js +55 -0
  203. package/dist/tools/analysis/invalidate-callgraph-cache.d.ts +2 -0
  204. package/dist/tools/analysis/invalidate-callgraph-cache.js +40 -0
  205. package/dist/tools/analysis/trace-data-flow.d.ts +2 -0
  206. package/dist/tools/analysis/trace-data-flow.js +138 -0
  207. package/dist/tools/annotations.d.ts +12 -0
  208. package/dist/tools/annotations.js +61 -0
  209. package/dist/tools/celldata/check-feeders.d.ts +2 -0
  210. package/dist/tools/celldata/check-feeders.js +48 -0
  211. package/dist/tools/celldata/check-writable-coords.d.ts +2 -0
  212. package/dist/tools/celldata/check-writable-coords.js +126 -0
  213. package/dist/tools/celldata/execute-mdx.d.ts +17 -0
  214. package/dist/tools/celldata/execute-mdx.js +126 -0
  215. package/dist/tools/celldata/get-cell-value.d.ts +2 -0
  216. package/dist/tools/celldata/get-cell-value.js +30 -0
  217. package/dist/tools/celldata/get-view-definition.d.ts +2 -0
  218. package/dist/tools/celldata/get-view-definition.js +29 -0
  219. package/dist/tools/celldata/get-view.d.ts +2 -0
  220. package/dist/tools/celldata/get-view.js +55 -0
  221. package/dist/tools/celldata/sample-cells.d.ts +2 -0
  222. package/dist/tools/celldata/sample-cells.js +101 -0
  223. package/dist/tools/celldata/trace-cell-calculation.d.ts +2 -0
  224. package/dist/tools/celldata/trace-cell-calculation.js +53 -0
  225. package/dist/tools/celldata/trace-feeders.d.ts +2 -0
  226. package/dist/tools/celldata/trace-feeders.js +44 -0
  227. package/dist/tools/celldata/write-cells.d.ts +2 -0
  228. package/dist/tools/celldata/write-cells.js +65 -0
  229. package/dist/tools/confirm.d.ts +10 -0
  230. package/dist/tools/confirm.js +64 -0
  231. package/dist/tools/define-tool.d.ts +51 -0
  232. package/dist/tools/define-tool.js +49 -0
  233. package/dist/tools/dimension-management/bulk-upsert-elements.d.ts +2 -0
  234. package/dist/tools/dimension-management/bulk-upsert-elements.js +103 -0
  235. package/dist/tools/dimension-management/create-dimension.d.ts +2 -0
  236. package/dist/tools/dimension-management/create-dimension.js +22 -0
  237. package/dist/tools/dimension-management/create-element-attribute.d.ts +2 -0
  238. package/dist/tools/dimension-management/create-element-attribute.js +26 -0
  239. package/dist/tools/dimension-management/create-element.d.ts +2 -0
  240. package/dist/tools/dimension-management/create-element.js +31 -0
  241. package/dist/tools/dimension-management/create-hierarchy.d.ts +2 -0
  242. package/dist/tools/dimension-management/create-hierarchy.js +22 -0
  243. package/dist/tools/dimension-management/delete-dimension.d.ts +2 -0
  244. package/dist/tools/dimension-management/delete-dimension.js +25 -0
  245. package/dist/tools/dimension-management/delete-element.d.ts +2 -0
  246. package/dist/tools/dimension-management/delete-element.js +26 -0
  247. package/dist/tools/dimension-management/delete-elements.d.ts +2 -0
  248. package/dist/tools/dimension-management/delete-elements.js +44 -0
  249. package/dist/tools/dimension-management/delete-hierarchy.d.ts +2 -0
  250. package/dist/tools/dimension-management/delete-hierarchy.js +35 -0
  251. package/dist/tools/dimension-management/get-element-attribute-values.d.ts +2 -0
  252. package/dist/tools/dimension-management/get-element-attribute-values.js +77 -0
  253. package/dist/tools/dimension-management/list-element-attributes.d.ts +2 -0
  254. package/dist/tools/dimension-management/list-element-attributes.js +31 -0
  255. package/dist/tools/dimension-management/move-element.d.ts +2 -0
  256. package/dist/tools/dimension-management/move-element.js +28 -0
  257. package/dist/tools/dimension-management/update-element-attribute-value.d.ts +2 -0
  258. package/dist/tools/dimension-management/update-element-attribute-value.js +80 -0
  259. package/dist/tools/dimension-management/update-element.d.ts +2 -0
  260. package/dist/tools/dimension-management/update-element.js +35 -0
  261. package/dist/tools/error-format.d.ts +22 -0
  262. package/dist/tools/error-format.js +130 -0
  263. package/dist/tools/fileops/delete-file.d.ts +2 -0
  264. package/dist/tools/fileops/delete-file.js +32 -0
  265. package/dist/tools/fileops/get-file-content.d.ts +2 -0
  266. package/dist/tools/fileops/get-file-content.js +76 -0
  267. package/dist/tools/fileops/list-files.d.ts +2 -0
  268. package/dist/tools/fileops/list-files.js +43 -0
  269. package/dist/tools/fileops/search-files.d.ts +2 -0
  270. package/dist/tools/fileops/search-files.js +76 -0
  271. package/dist/tools/fileops/upload-file.d.ts +2 -0
  272. package/dist/tools/fileops/upload-file.js +69 -0
  273. package/dist/tools/format.d.ts +57 -0
  274. package/dist/tools/format.js +157 -0
  275. package/dist/tools/hierarchy.d.ts +6 -0
  276. package/dist/tools/hierarchy.js +27 -0
  277. package/dist/tools/index.d.ts +4 -0
  278. package/dist/tools/index.js +263 -0
  279. package/dist/tools/local-file.d.ts +16 -0
  280. package/dist/tools/local-file.js +88 -0
  281. package/dist/tools/metadata/get-ancestors.d.ts +2 -0
  282. package/dist/tools/metadata/get-ancestors.js +36 -0
  283. package/dist/tools/metadata/get-descendants.d.ts +2 -0
  284. package/dist/tools/metadata/get-descendants.js +64 -0
  285. package/dist/tools/metadata/get-hierarchy.d.ts +2 -0
  286. package/dist/tools/metadata/get-hierarchy.js +130 -0
  287. package/dist/tools/metadata/list-chores.d.ts +2 -0
  288. package/dist/tools/metadata/list-chores.js +62 -0
  289. package/dist/tools/metadata/list-cubes.d.ts +2 -0
  290. package/dist/tools/metadata/list-cubes.js +128 -0
  291. package/dist/tools/metadata/list-dimensions.d.ts +2 -0
  292. package/dist/tools/metadata/list-dimensions.js +131 -0
  293. package/dist/tools/metadata/list-processes-grouped.d.ts +2 -0
  294. package/dist/tools/metadata/list-processes-grouped.js +96 -0
  295. package/dist/tools/metadata/list-processes.d.ts +2 -0
  296. package/dist/tools/metadata/list-processes.js +108 -0
  297. package/dist/tools/metadata/resolve-default-members.d.ts +2 -0
  298. package/dist/tools/metadata/resolve-default-members.js +46 -0
  299. package/dist/tools/model-building/check-cube-rule.d.ts +2 -0
  300. package/dist/tools/model-building/check-cube-rule.js +51 -0
  301. package/dist/tools/model-building/clear-cube.d.ts +2 -0
  302. package/dist/tools/model-building/clear-cube.js +46 -0
  303. package/dist/tools/model-building/create-cube.d.ts +2 -0
  304. package/dist/tools/model-building/create-cube.js +34 -0
  305. package/dist/tools/model-building/delete-cube.d.ts +2 -0
  306. package/dist/tools/model-building/delete-cube.js +27 -0
  307. package/dist/tools/model-building/get-all-cube-rules.d.ts +2 -0
  308. package/dist/tools/model-building/get-all-cube-rules.js +149 -0
  309. package/dist/tools/model-building/get-cube-rules.d.ts +2 -0
  310. package/dist/tools/model-building/get-cube-rules.js +69 -0
  311. package/dist/tools/model-building/rules-source.d.ts +21 -0
  312. package/dist/tools/model-building/rules-source.js +49 -0
  313. package/dist/tools/model-building/search-rules.d.ts +2 -0
  314. package/dist/tools/model-building/search-rules.js +132 -0
  315. package/dist/tools/model-building/set-cube-rules.d.ts +2 -0
  316. package/dist/tools/model-building/set-cube-rules.js +81 -0
  317. package/dist/tools/model-building/unload-cube.d.ts +2 -0
  318. package/dist/tools/model-building/unload-cube.js +23 -0
  319. package/dist/tools/operations/diagnose-process-error.d.ts +2 -0
  320. package/dist/tools/operations/diagnose-process-error.js +178 -0
  321. package/dist/tools/operations/error-log-helpers.d.ts +25 -0
  322. package/dist/tools/operations/error-log-helpers.js +57 -0
  323. package/dist/tools/operations/get-audit-log.d.ts +2 -0
  324. package/dist/tools/operations/get-audit-log.js +70 -0
  325. package/dist/tools/operations/get-cube-stats.d.ts +2 -0
  326. package/dist/tools/operations/get-cube-stats.js +107 -0
  327. package/dist/tools/operations/get-error-log-content.d.ts +2 -0
  328. package/dist/tools/operations/get-error-log-content.js +164 -0
  329. package/dist/tools/operations/get-jobs.d.ts +3 -0
  330. package/dist/tools/operations/get-jobs.js +51 -0
  331. package/dist/tools/operations/get-message-log.d.ts +2 -0
  332. package/dist/tools/operations/get-message-log.js +63 -0
  333. package/dist/tools/operations/get-server-info.d.ts +2 -0
  334. package/dist/tools/operations/get-server-info.js +180 -0
  335. package/dist/tools/operations/get-server-state.d.ts +2 -0
  336. package/dist/tools/operations/get-server-state.js +129 -0
  337. package/dist/tools/operations/get-sessions.d.ts +2 -0
  338. package/dist/tools/operations/get-sessions.js +76 -0
  339. package/dist/tools/operations/get-threads.d.ts +3 -0
  340. package/dist/tools/operations/get-threads.js +50 -0
  341. package/dist/tools/operations/get-transaction-log.d.ts +2 -0
  342. package/dist/tools/operations/get-transaction-log.js +63 -0
  343. package/dist/tools/operations/list-error-logs.d.ts +8 -0
  344. package/dist/tools/operations/list-error-logs.js +157 -0
  345. package/dist/tools/operations/save-data.d.ts +2 -0
  346. package/dist/tools/operations/save-data.js +50 -0
  347. package/dist/tools/pagination.d.ts +32 -0
  348. package/dist/tools/pagination.js +116 -0
  349. package/dist/tools/scheduling/create-chore.d.ts +2 -0
  350. package/dist/tools/scheduling/create-chore.js +93 -0
  351. package/dist/tools/scheduling/delete-chore.d.ts +2 -0
  352. package/dist/tools/scheduling/delete-chore.js +22 -0
  353. package/dist/tools/scheduling/execute-chore.d.ts +2 -0
  354. package/dist/tools/scheduling/execute-chore.js +52 -0
  355. package/dist/tools/scheduling/toggle-chore.d.ts +2 -0
  356. package/dist/tools/scheduling/toggle-chore.js +22 -0
  357. package/dist/tools/scheduling/update-chore.d.ts +2 -0
  358. package/dist/tools/scheduling/update-chore.js +71 -0
  359. package/dist/tools/schemas/common.d.ts +10 -0
  360. package/dist/tools/schemas/common.js +23 -0
  361. package/dist/tools/schemas/items-analysis.d.ts +394 -0
  362. package/dist/tools/schemas/items-analysis.js +419 -0
  363. package/dist/tools/schemas/items-cells.d.ts +70 -0
  364. package/dist/tools/schemas/items-cells.js +65 -0
  365. package/dist/tools/schemas/items-common.d.ts +18 -0
  366. package/dist/tools/schemas/items-common.js +39 -0
  367. package/dist/tools/schemas/items-fileops.d.ts +11 -0
  368. package/dist/tools/schemas/items-fileops.js +13 -0
  369. package/dist/tools/schemas/items-metadata.d.ts +262 -0
  370. package/dist/tools/schemas/items-metadata.js +184 -0
  371. package/dist/tools/schemas/items-monitoring.d.ts +79 -0
  372. package/dist/tools/schemas/items-monitoring.js +78 -0
  373. package/dist/tools/schemas/items-processes.d.ts +279 -0
  374. package/dist/tools/schemas/items-processes.js +235 -0
  375. package/dist/tools/schemas/items-scheduling.d.ts +25 -0
  376. package/dist/tools/schemas/items-scheduling.js +26 -0
  377. package/dist/tools/schemas/items-security.d.ts +19 -0
  378. package/dist/tools/schemas/items-security.js +12 -0
  379. package/dist/tools/schemas/items-subsets.d.ts +2 -0
  380. package/dist/tools/schemas/items-subsets.js +4 -0
  381. package/dist/tools/schemas/items-views.d.ts +38 -0
  382. package/dist/tools/schemas/items-views.js +26 -0
  383. package/dist/tools/schemas/items.d.ts +12 -0
  384. package/dist/tools/schemas/items.js +23 -0
  385. package/dist/tools/schemas/markdown-capable.d.ts +21 -0
  386. package/dist/tools/schemas/markdown-capable.js +58 -0
  387. package/dist/tools/schemas/output-schema.d.ts +24 -0
  388. package/dist/tools/schemas/output-schema.js +25 -0
  389. package/dist/tools/security/assign-client-group.d.ts +2 -0
  390. package/dist/tools/security/assign-client-group.js +20 -0
  391. package/dist/tools/security/create-client.d.ts +2 -0
  392. package/dist/tools/security/create-client.js +28 -0
  393. package/dist/tools/security/delete-client.d.ts +2 -0
  394. package/dist/tools/security/delete-client.js +22 -0
  395. package/dist/tools/security/get-client.d.ts +2 -0
  396. package/dist/tools/security/get-client.js +20 -0
  397. package/dist/tools/security/list-clients.d.ts +2 -0
  398. package/dist/tools/security/list-clients.js +86 -0
  399. package/dist/tools/security/list-groups.d.ts +2 -0
  400. package/dist/tools/security/list-groups.js +43 -0
  401. package/dist/tools/security/remove-client-group.d.ts +2 -0
  402. package/dist/tools/security/remove-client-group.js +27 -0
  403. package/dist/tools/security/update-client.d.ts +2 -0
  404. package/dist/tools/security/update-client.js +22 -0
  405. package/dist/tools/subsets/create-subset.d.ts +2 -0
  406. package/dist/tools/subsets/create-subset.js +44 -0
  407. package/dist/tools/subsets/delete-subset.d.ts +2 -0
  408. package/dist/tools/subsets/delete-subset.js +26 -0
  409. package/dist/tools/subsets/get-subset.d.ts +2 -0
  410. package/dist/tools/subsets/get-subset.js +29 -0
  411. package/dist/tools/subsets/list-subsets.d.ts +2 -0
  412. package/dist/tools/subsets/list-subsets.js +36 -0
  413. package/dist/tools/subsets/update-subset.d.ts +2 -0
  414. package/dist/tools/subsets/update-subset.js +33 -0
  415. package/dist/tools/ti-development/check-process-code.d.ts +2 -0
  416. package/dist/tools/ti-development/check-process-code.js +96 -0
  417. package/dist/tools/ti-development/compile-process.d.ts +2 -0
  418. package/dist/tools/ti-development/compile-process.js +32 -0
  419. package/dist/tools/ti-development/copy-process.d.ts +2 -0
  420. package/dist/tools/ti-development/copy-process.js +32 -0
  421. package/dist/tools/ti-development/delete-process.d.ts +2 -0
  422. package/dist/tools/ti-development/delete-process.js +26 -0
  423. package/dist/tools/ti-development/diff-process-with-file.d.ts +2 -0
  424. package/dist/tools/ti-development/diff-process-with-file.js +208 -0
  425. package/dist/tools/ti-development/diff-processes.d.ts +2 -0
  426. package/dist/tools/ti-development/diff-processes.js +312 -0
  427. package/dist/tools/ti-development/execute-process.d.ts +8 -0
  428. package/dist/tools/ti-development/execute-process.js +109 -0
  429. package/dist/tools/ti-development/export-process-to-git.d.ts +2 -0
  430. package/dist/tools/ti-development/export-process-to-git.js +113 -0
  431. package/dist/tools/ti-development/export-process-to-pro.d.ts +2 -0
  432. package/dist/tools/ti-development/export-process-to-pro.js +117 -0
  433. package/dist/tools/ti-development/get-all-processes-code.d.ts +2 -0
  434. package/dist/tools/ti-development/get-all-processes-code.js +131 -0
  435. package/dist/tools/ti-development/get-process-code.d.ts +2 -0
  436. package/dist/tools/ti-development/get-process-code.js +100 -0
  437. package/dist/tools/ti-development/get-process-datasource.d.ts +2 -0
  438. package/dist/tools/ti-development/get-process-datasource.js +20 -0
  439. package/dist/tools/ti-development/get-process-parameters.d.ts +2 -0
  440. package/dist/tools/ti-development/get-process-parameters.js +25 -0
  441. package/dist/tools/ti-development/get-process-variables.d.ts +2 -0
  442. package/dist/tools/ti-development/get-process-variables.js +38 -0
  443. package/dist/tools/ti-development/get-process.d.ts +2 -0
  444. package/dist/tools/ti-development/get-process.js +163 -0
  445. package/dist/tools/ti-development/import-pro-file.d.ts +2 -0
  446. package/dist/tools/ti-development/import-pro-file.js +153 -0
  447. package/dist/tools/ti-development/import-process-from-git.d.ts +2 -0
  448. package/dist/tools/ti-development/import-process-from-git.js +198 -0
  449. package/dist/tools/ti-development/install-pro-bundle.d.ts +2 -0
  450. package/dist/tools/ti-development/install-pro-bundle.js +288 -0
  451. package/dist/tools/ti-development/preflight.d.ts +39 -0
  452. package/dist/tools/ti-development/preflight.js +56 -0
  453. package/dist/tools/ti-development/process-backup.d.ts +29 -0
  454. package/dist/tools/ti-development/process-backup.js +118 -0
  455. package/dist/tools/ti-development/search-code.d.ts +2 -0
  456. package/dist/tools/ti-development/search-code.js +208 -0
  457. package/dist/tools/ti-development/upsert-process.d.ts +2 -0
  458. package/dist/tools/ti-development/upsert-process.js +167 -0
  459. package/dist/tools/ti-development/validate-process-refs.d.ts +2 -0
  460. package/dist/tools/ti-development/validate-process-refs.js +73 -0
  461. package/dist/tools/views/create-mdx-view.d.ts +2 -0
  462. package/dist/tools/views/create-mdx-view.js +21 -0
  463. package/dist/tools/views/create-native-view.d.ts +2 -0
  464. package/dist/tools/views/create-native-view.js +81 -0
  465. package/dist/tools/views/delete-view.d.ts +2 -0
  466. package/dist/tools/views/delete-view.js +23 -0
  467. package/dist/tools/views/list-views.d.ts +2 -0
  468. package/dist/tools/views/list-views.js +32 -0
  469. package/dist/tools/with-annotations.d.ts +6 -0
  470. package/dist/tools/with-annotations.js +339 -0
  471. package/dist/types.d.ts +409 -0
  472. package/dist/types.js +91 -0
  473. package/dist/version.d.ts +4 -0
  474. package/dist/version.js +18 -0
  475. package/package.json +107 -0
@@ -0,0 +1,874 @@
1
+ // Process domain service. Owns the OData calls under /api/v1/Processes(...) —
2
+ // listing, executing, code/parameters/variables/datasource CRUD, plus the
3
+ // CompileProcess (server-side syntax check, with and without saving).
4
+ //
5
+ // See docs/ARCHITECTURE.md for the layering.
6
+ import { TM1Error, TM1ErrorCode } from "../../types.js";
7
+ import { isUnsupportedQueryShape, rethrowIfSystemic, rethrowIfSystemicOrDenied, } from "./fallback.js";
8
+ import { classifyExecution } from "./process-status.js";
9
+ import { ignoredColumnsOf } from "../../lib/variables-ui-data.js";
10
+ import { filterClause, nameFilterPredicates, pageClauses, readCount, } from "./odata-page.js";
11
+ // OData key encoder: double ' per OData literal rules, then percent-encode.
12
+ const enc = (s) => encodeURIComponent(String(s).replace(/'/g, "''"));
13
+ function decodeVariable(v) {
14
+ return {
15
+ name: v.Name,
16
+ type: v.Type === "Numeric" ? "Numeric" : "String",
17
+ position: v.Position,
18
+ ...(v.StartByte !== undefined ? { startByte: v.StartByte } : {}),
19
+ ...(v.EndByte !== undefined ? { endByte: v.EndByte } : {}),
20
+ };
21
+ }
22
+ // Encode a TI parameter for the OData write body.
23
+ //
24
+ // `Type` uses the tm1.ProcessVariableType enum (String=1, Numeric=2 — verified
25
+ // against the live $metadata). On v11 TM1 actually ignores this field and
26
+ // classifies the parameter from the JSON type of `Value`, so the decisive part
27
+ // is coercing `Value` to match the declared `type`: a Numeric parameter whose
28
+ // defaultValue arrived as the string "0" would otherwise be stored as String.
29
+ function encodeParameter(p) {
30
+ const numeric = p.type === "Numeric";
31
+ let value;
32
+ if (numeric) {
33
+ const n = Number(p.defaultValue);
34
+ value = Number.isFinite(n) ? n : 0;
35
+ }
36
+ else {
37
+ value = String(p.defaultValue);
38
+ }
39
+ return {
40
+ Name: p.name,
41
+ Type: numeric ? 2 : 1,
42
+ Value: value,
43
+ ...(p.prompt ? { Prompt: p.prompt } : {}),
44
+ };
45
+ }
46
+ /**
47
+ * The OData query shapes `fetchForCallgraph` will accept, richest first. Each
48
+ * later entry gives up something the previous one asked for, so a stricter or
49
+ * older TM1 that cannot parse one shape can still be served by the next.
50
+ *
51
+ * The list is a ladder of CAPABILITY, nothing else: walking down it is only
52
+ * ever a valid response to the server rejecting the query shape itself.
53
+ */
54
+ const CALLGRAPH_QUERY_SHAPES = [
55
+ (f) => `/api/v1/Processes?$select=Name,PrologProcedure,MetadataProcedure,DataProcedure,EpilogProcedure,Parameters${f}`,
56
+ (f) => `/api/v1/Processes?$select=Name,PrologProcedure,MetadataProcedure,DataProcedure,EpilogProcedure,Parameters&$expand=Parameters($select=Name,Value,Type)${f}`,
57
+ (f) => `/api/v1/Processes?$expand=Parameters${f}`,
58
+ // Last resort: no parameter metadata at all. Callgraph edges still resolve;
59
+ // parameter-default folding degrades.
60
+ (f) => `/api/v1/Processes?$select=Name,PrologProcedure,MetadataProcedure,DataProcedure,EpilogProcedure${f}`,
61
+ ];
62
+ export class ProcessService {
63
+ http;
64
+ /**
65
+ * Index into `CALLGRAPH_QUERY_SHAPES` that this connection answered, or
66
+ * `null` while unprobed — the same tri-state verdict `BatchService.supported`
67
+ * keeps, for the same reason. Probing costs up to four full `/Processes`
68
+ * scans, so it must be paid once per connection and not once per callgraph
69
+ * build (P7).
70
+ */
71
+ callgraphShape = null;
72
+ constructor(http) {
73
+ this.http = http;
74
+ }
75
+ async list(opts = {}) {
76
+ // Filters are only emitted on the paged path; unpaged callers keep getting
77
+ // the whole collection and filter in-process. The degraded Name-only
78
+ // retry below reuses the same query — dropping it there would turn a
79
+ // paged request into a silent full, unfiltered fetch.
80
+ const query = opts.page === undefined
81
+ ? ""
82
+ : `${filterClause(nameFilterPredicates(opts))}${pageClauses(opts.page)}`;
83
+ const wrap = (items, total) => opts.page === undefined ? items : { items, total };
84
+ // Parameters is a structural (complex) property, not a navigation property
85
+ // — TM1 v11 rejects $expand=Parameters with a syntax error. Use $select
86
+ // instead, which returns Parameters inline. Param.Type comes back as the
87
+ // already-decoded string "Numeric" / "String" (not the legacy int code).
88
+ try {
89
+ const response = await this.http.request("GET", `/api/v1/Processes?$select=Name,Parameters${query}`);
90
+ return wrap(response.value.map((p) => ({
91
+ name: p.Name,
92
+ parameters: (p.Parameters ?? []).map((param) => ({
93
+ name: param.Name,
94
+ type: param.Type === "Numeric" ? "Numeric" : "String",
95
+ defaultValue: param.Value,
96
+ ...(param.Prompt ? { prompt: param.Prompt } : {}),
97
+ })),
98
+ })), readCount(response));
99
+ }
100
+ catch (e) {
101
+ rethrowIfSystemic(e);
102
+ const response = await this.http.request("GET", `/api/v1/Processes?$select=Name${query}`);
103
+ return wrap(response.value.map((p) => ({
104
+ name: p.Name,
105
+ parameters: [],
106
+ })), readCount(response));
107
+ }
108
+ }
109
+ /**
110
+ * Execute a TI process with optional parameters. opts.timeoutMs overrides
111
+ * the 30s default for long-running TI runs.
112
+ * POST /api/v1/Processes('{name}')/tm1.ExecuteWithReturn?$expand=ErrorLogFile
113
+ */
114
+ async execute(processName, params, opts) {
115
+ // $expand=ErrorLogFile is REQUIRED, not an optimization: ErrorLogFile is a
116
+ // navigation property on ProcessExecuteResult, so an unexpanded call returns
117
+ // only ProcessExecuteStatusCode and the filename is silently absent. Measured
118
+ // on 11.8.02900.8 and 12.5.9 — both omit the key entirely without it, and both
119
+ // return {"Filename": ...} with it (v11 `TM1ProcessError_*.log`, v12
120
+ // `ProcessLog_*.jsonl`).
121
+ const path = `/api/v1/Processes('${enc(processName)}')/tm1.ExecuteWithReturn?$expand=ErrorLogFile`;
122
+ const body = {};
123
+ if (params && Object.keys(params).length > 0) {
124
+ body.Parameters = Object.entries(params).map(([name, value]) => ({
125
+ Name: name,
126
+ Value: value,
127
+ }));
128
+ }
129
+ try {
130
+ // ExecuteWithReturn returns HTTP 200 even when the process aborts; the
131
+ // real outcome is in ProcessExecuteStatusCode. The plain tm1.Execute
132
+ // action also 2xx-es on CompletedWithMinorErrors/HasMinorErrors, which
133
+ // made partial failures (bad records + error log) invisible.
134
+ const response = await this.http.request("POST", path, body, opts);
135
+ return classifyExecution(response?.ProcessExecuteStatusCode, response?.ErrorLogFile?.Filename);
136
+ }
137
+ catch (error) {
138
+ // Systemic transport/auth failures (LOCK_TIMEOUT, CONNECTION_FAILED,
139
+ // AUTH_FAILED) must propagate: a timed-out TI run is still executing
140
+ // server-side, so reporting {success:false} would invite a duplicate run.
141
+ rethrowIfSystemic(error);
142
+ // The call itself errored, so TM1 never reported a status — and an error
143
+ // raised mid-run says nothing about whether the run committed. That is
144
+ // `indeterminate` by definition, not a rollback we can promise; the
145
+ // server's own text rides along in processErrorStatus so the caller still
146
+ // sees WHY.
147
+ if (error instanceof TM1Error) {
148
+ return {
149
+ success: false,
150
+ outcome: "indeterminate",
151
+ processErrorStatus: error.details ?? error.message,
152
+ errorLogFile: undefined,
153
+ };
154
+ }
155
+ throw error;
156
+ }
157
+ }
158
+ /**
159
+ * Persist in-memory cube data to disk — SaveDataAll (all cubes) or
160
+ * CubeSaveData (single cube). The REST API exposes no native SaveData
161
+ * action ($metadata verified), so this routes through the service-root
162
+ * ExecuteProcessWithReturn (available since 11.3) with an unbound TI
163
+ * process — no persistent process object is created. v11-only: both TI
164
+ * functions are removed in v12 (cloud engine persists automatically).
165
+ * POST /api/v1/ExecuteProcessWithReturn
166
+ */
167
+ async saveData(cubeName, opts) {
168
+ const prolog = cubeName !== undefined
169
+ ? `CubeSaveData('${cubeName.replace(/'/g, "''")}');`
170
+ : "SaveDataAll;";
171
+ const body = {
172
+ Process: {
173
+ Name: "}tm1-mcp-save-data",
174
+ HasSecurityAccess: false,
175
+ PrologProcedure: prolog,
176
+ MetadataProcedure: "",
177
+ DataProcedure: "",
178
+ EpilogProcedure: "",
179
+ DataSource: { Type: "None" },
180
+ },
181
+ };
182
+ try {
183
+ const response = await this.http.request("POST",
184
+ // See executeProcess: without $expand the ErrorLogFile nav property is
185
+ // never serialized, on either version.
186
+ "/api/v1/ExecuteProcessWithReturn?$expand=ErrorLogFile", body, opts);
187
+ return classifyExecution(response?.ProcessExecuteStatusCode, response?.ErrorLogFile?.Filename);
188
+ }
189
+ catch (error) {
190
+ // Systemic transport/auth failures (LOCK_TIMEOUT, CONNECTION_FAILED,
191
+ // AUTH_FAILED) must propagate: a timed-out TI run is still executing
192
+ // server-side, so reporting {success:false} would invite a duplicate run.
193
+ rethrowIfSystemic(error);
194
+ // The call itself errored, so TM1 never reported a status — and an error
195
+ // raised mid-run says nothing about whether the run committed. That is
196
+ // `indeterminate` by definition, not a rollback we can promise; the
197
+ // server's own text rides along in processErrorStatus so the caller still
198
+ // sees WHY.
199
+ if (error instanceof TM1Error) {
200
+ return {
201
+ success: false,
202
+ outcome: "indeterminate",
203
+ processErrorStatus: error.details ?? error.message,
204
+ errorLogFile: undefined,
205
+ };
206
+ }
207
+ throw error;
208
+ }
209
+ }
210
+ /**
211
+ * Get the parameters of a TI process.
212
+ * GET /api/v1/Processes('{name}')/Parameters
213
+ */
214
+ async getParameters(processName) {
215
+ const path = `/api/v1/Processes('${enc(processName)}')/Parameters`;
216
+ // TM1 v11 returns Type as the decoded string "Numeric" / "String"
217
+ // (not the legacy int code 1 / 2). The old `=== 1` check silently
218
+ // classified every Numeric parameter as String.
219
+ const response = await this.http.request("GET", path);
220
+ return response.value.map((param) => ({
221
+ name: param.Name,
222
+ type: param.Type === "Numeric" ? "Numeric" : "String",
223
+ defaultValue: param.Value,
224
+ ...(param.Prompt ? { prompt: param.Prompt } : {}),
225
+ }));
226
+ }
227
+ /**
228
+ * Create a new empty TI process.
229
+ * POST /api/v1/Processes with body {"Name": "..."}
230
+ * Throws CONFLICT (409) if a process with the same name already exists.
231
+ */
232
+ async create(name) {
233
+ await this.http.request("POST", "/api/v1/Processes", { Name: name });
234
+ }
235
+ /**
236
+ * Cheap existence probe: a single GET with $select=Name (404 → false)
237
+ * instead of list(), which pulls every process plus its parameters just to
238
+ * check one name. Rethrows anything that isn't NOT_FOUND.
239
+ */
240
+ async exists(name) {
241
+ try {
242
+ await this.http.request("GET", `/api/v1/Processes('${enc(name)}')?$select=Name`);
243
+ return true;
244
+ }
245
+ catch (e) {
246
+ if (e instanceof TM1Error && e.code === TM1ErrorCode.NOT_FOUND)
247
+ return false;
248
+ throw e;
249
+ }
250
+ }
251
+ /**
252
+ * Copy a TI process to a new name. Strips read-only / server-managed fields
253
+ * before re-POSTing to avoid TM1 rejecting the body.
254
+ */
255
+ async copy(sourceName, targetName) {
256
+ const path = `/api/v1/Processes('${enc(sourceName)}')`;
257
+ const source = await this.http.request("GET", path);
258
+ delete source["@odata.context"];
259
+ delete source["@odata.etag"];
260
+ delete source["Attributes"];
261
+ delete source["LocalizedAttributes"];
262
+ // `UIData` and `VariablesUIData` are undeclared in $metadata on both
263
+ // versions, so the plain GET above never returns them. Without the second
264
+ // request the copy silently loses every ignored datasource column (the
265
+ // ignore flag lives ONLY in VariablesUIData) and the Architect action
266
+ // settings — measured on 11.8 and 12.5.
267
+ const ui = await this.getUIData(sourceName);
268
+ if (ui.uiData !== undefined)
269
+ source.UIData = ui.uiData;
270
+ if (ui.variablesUIData !== undefined)
271
+ source.VariablesUIData = ui.variablesUIData;
272
+ source.Name = targetName;
273
+ await this.http.request("POST", "/api/v1/Processes", source);
274
+ }
275
+ /**
276
+ * The two UI-only properties TM1 stores but does not declare: `UIData`
277
+ * (Architect cube/data action settings) and `VariablesUIData` (per-column
278
+ * state, including which columns are ignored). Both have to be named in
279
+ * `$select`; a server that rejects the query shape yields an empty result
280
+ * rather than an error, since neither is required to use the process.
281
+ */
282
+ async getUIData(processName) {
283
+ const path = `/api/v1/Processes('${enc(processName)}')` +
284
+ `?$select=UIData,VariablesUIData`;
285
+ try {
286
+ const r = await this.http.request("GET", path);
287
+ return {
288
+ ...(r.UIData !== undefined ? { uiData: r.UIData } : {}),
289
+ ...(r.VariablesUIData !== undefined
290
+ ? { variablesUIData: r.VariablesUIData }
291
+ : {}),
292
+ };
293
+ }
294
+ catch (e) {
295
+ rethrowIfSystemic(e);
296
+ if (!isUnsupportedQueryShape(e))
297
+ throw e;
298
+ return {};
299
+ }
300
+ }
301
+ /**
302
+ * Run the callgraph fetch against the query shape this connection accepts,
303
+ * discovering it on first use.
304
+ *
305
+ * The discovery loop used to catch EVERY error and move on to the next,
306
+ * broader query. That turned an expired session, a request timeout or a
307
+ * security denial into three more full-collection scans (~4 × 30 s worst
308
+ * case, P7) and — worse — let a later shape that happened to answer mask the
309
+ * real first error (K6/T-9). Two guards now bound it:
310
+ *
311
+ * - `rethrowIfSystemicOrDenied` — transport/auth/timeout failures and
312
+ * permission denials leave immediately. A denial in particular must never
313
+ * become an empty process list: the callgraph would cache "this model has
314
+ * no processes" as truth.
315
+ * - `isUnsupportedQueryShape` — of what is left, only TM1 refusing the
316
+ * query shape justifies asking again in another form.
317
+ */
318
+ async fetchCallgraphBody(filter) {
319
+ const shapeAt = (i) => {
320
+ const build = CALLGRAPH_QUERY_SHAPES[i];
321
+ if (build === undefined)
322
+ throw new Error(`No callgraph query shape at index ${i}`);
323
+ return build(filter);
324
+ };
325
+ if (this.callgraphShape !== null) {
326
+ try {
327
+ return await this.http.request("GET", shapeAt(this.callgraphShape));
328
+ }
329
+ catch (e) {
330
+ // A shape this server has already answered cannot suddenly be
331
+ // "unsupported" — mirrors BatchService, where a 400 after the first
332
+ // success means the request was bad, not the feature missing. Drop the
333
+ // verdict so a genuinely changed server is re-probed next call, and let
334
+ // the error surface instead of silently re-walking the ladder.
335
+ this.callgraphShape = null;
336
+ throw e;
337
+ }
338
+ }
339
+ let lastErr;
340
+ for (let i = 0; i < CALLGRAPH_QUERY_SHAPES.length; i++) {
341
+ try {
342
+ const body = await this.http.request("GET", shapeAt(i));
343
+ this.callgraphShape = i;
344
+ return body;
345
+ }
346
+ catch (e) {
347
+ rethrowIfSystemicOrDenied(e);
348
+ if (!isUnsupportedQueryShape(e))
349
+ throw e;
350
+ lastErr = e;
351
+ }
352
+ }
353
+ throw lastErr instanceof Error
354
+ ? lastErr
355
+ : new Error(String(lastErr ?? "Processes fetch failed"));
356
+ }
357
+ /**
358
+ * Fetch every TI process with code AND parameter metadata for callgraph
359
+ * indexing. Single round trip once the connection's usable OData query shape
360
+ * is known — see `fetchCallgraphBody` for the discovery rules.
361
+ */
362
+ async fetchForCallgraph(includeControl = false) {
363
+ const filter = includeControl ? "" : "&$filter=not startswith(Name,'}')";
364
+ const body = await this.fetchCallgraphBody(filter);
365
+ return (body.value ?? [])
366
+ .map((p) => {
367
+ const parameters = (p.Parameters ?? [])
368
+ .map((x) => String(x.Name ?? ""))
369
+ .filter((n) => n !== "");
370
+ const parameterDefaults = new Map();
371
+ for (const x of p.Parameters ?? []) {
372
+ if (x.Name &&
373
+ x.Value !== undefined &&
374
+ x.Value !== null &&
375
+ x.Value !== "") {
376
+ parameterDefaults.set(String(x.Name), String(x.Value));
377
+ }
378
+ }
379
+ return {
380
+ name: String(p.Name ?? ""),
381
+ prolog: String(p.PrologProcedure ?? ""),
382
+ metadata: String(p.MetadataProcedure ?? ""),
383
+ data: String(p.DataProcedure ?? ""),
384
+ epilog: String(p.EpilogProcedure ?? ""),
385
+ parameters,
386
+ parameterDefaults,
387
+ };
388
+ })
389
+ .filter((p) => p.name !== "");
390
+ }
391
+ async getAllCode(includeControl = false, top) {
392
+ const filter = includeControl ? "" : "&$filter=not startswith(Name,'}')";
393
+ const cap = top !== undefined ? `&$orderby=Name&$top=${top}&$count=true` : "";
394
+ const path = `/api/v1/Processes?$select=Name,PrologProcedure,MetadataProcedure,DataProcedure,EpilogProcedure,HasSecurityAccess${filter}${cap}`;
395
+ const response = await this.http.request("GET", path);
396
+ const items = response.value.map((p) => ({
397
+ name: p.Name,
398
+ prolog: p.PrologProcedure ?? "",
399
+ metadata: p.MetadataProcedure ?? "",
400
+ data: p.DataProcedure ?? "",
401
+ epilog: p.EpilogProcedure ?? "",
402
+ hasSecurityAccess: p.HasSecurityAccess === true,
403
+ }));
404
+ if (top !== undefined) {
405
+ return { items, total: response["@odata.count"] };
406
+ }
407
+ return items;
408
+ }
409
+ /**
410
+ * Get the code of all four tabs of a TI process.
411
+ * GET /api/v1/Processes('{name}')
412
+ */
413
+ async getCode(processName) {
414
+ const path = `/api/v1/Processes('${enc(processName)}')`;
415
+ const response = await this.http.request("GET", path);
416
+ return {
417
+ prolog: response.PrologProcedure,
418
+ metadata: response.MetadataProcedure,
419
+ data: response.DataProcedure,
420
+ epilog: response.EpilogProcedure,
421
+ };
422
+ }
423
+ /**
424
+ * Read deploy-relevant entity metadata not covered by getCode/params/
425
+ * vars/datasource. Currently only HasSecurityAccess (functional elevation).
426
+ * GET /api/v1/Processes('{name}')?$select=HasSecurityAccess
427
+ */
428
+ async getDeployMeta(processName) {
429
+ const path = `/api/v1/Processes('${enc(processName)}')?$select=HasSecurityAccess`;
430
+ const response = await this.http.request("GET", path);
431
+ return { hasSecurityAccess: response.HasSecurityAccess === true };
432
+ }
433
+ /**
434
+ * Update one or more code tabs of a TI process (partial update).
435
+ * PATCH /api/v1/Processes('{name}') with only the tabs to update.
436
+ */
437
+ async updateCode(processName, code) {
438
+ const path = `/api/v1/Processes('${enc(processName)}')`;
439
+ const body = {};
440
+ if (code.prolog !== undefined)
441
+ body.PrologProcedure = code.prolog;
442
+ if (code.metadata !== undefined)
443
+ body.MetadataProcedure = code.metadata;
444
+ if (code.data !== undefined)
445
+ body.DataProcedure = code.data;
446
+ if (code.epilog !== undefined)
447
+ body.EpilogProcedure = code.epilog;
448
+ await this.http.request("PATCH", path, body);
449
+ }
450
+ /**
451
+ * Read the whole process code as TM1's native `#region <Tab>` / `#endregion`
452
+ * blob. GET /api/v1/Processes('{name}')/Code/$value (text/plain). Empty tabs
453
+ * are omitted by the server; newlines are CRLF.
454
+ */
455
+ async getCodeBlob(processName) {
456
+ const path = `/api/v1/Processes('${enc(processName)}')/Code/$value`;
457
+ return this.http.requestRaw("GET", path);
458
+ }
459
+ /**
460
+ * Write the whole process code from a native `#region` blob. PATCH
461
+ * /api/v1/Processes('{name}') { Code }. The server parses the region markers
462
+ * and does a FULL replace of all four tabs — tabs whose region is absent are
463
+ * cleared. `$value` PUT is not supported by TM1, so this JSON PATCH is the
464
+ * only write path.
465
+ */
466
+ async updateCodeBlob(processName, blob) {
467
+ const path = `/api/v1/Processes('${enc(processName)}')`;
468
+ await this.http.request("PATCH", path, { Code: blob });
469
+ }
470
+ /**
471
+ * Set HasSecurityAccess flag on process.
472
+ * PATCH /api/v1/Processes('{name}') { HasSecurityAccess }.
473
+ */
474
+ async updateSecurityAccess(processName, hasSecurityAccess) {
475
+ const path = `/api/v1/Processes('${enc(processName)}')`;
476
+ await this.http.request("PATCH", path, {
477
+ HasSecurityAccess: hasSecurityAccess,
478
+ });
479
+ }
480
+ /**
481
+ * Get the data source configuration of a TI process.
482
+ * GET /api/v1/Processes('{name}') and extract the DataSource field.
483
+ */
484
+ /**
485
+ * Read a process datasource. The ODBC password is redacted by default so it
486
+ * cannot reach the caller or the model; `includeSecrets` returns it verbatim
487
+ * and is meant for export paths that write straight to a file.
488
+ *
489
+ * Measured on 11.8: the value on the wire is a server-bound ciphertext
490
+ * (`W0br…==`) that TM1 stores unchanged when written back, so it survives a
491
+ * round trip on the same instance but decrypts to nothing on another one.
492
+ * TM1 v12 returns the password in plain text.
493
+ */
494
+ async getDataSource(processName, opts) {
495
+ const path = `/api/v1/Processes('${enc(processName)}')`;
496
+ const response = await this.http.request("GET", path);
497
+ const ds = response.DataSource;
498
+ // ds.Type is a raw string from the OData response. Surface (don't silently
499
+ // swallow) a type this client version doesn't know — a future TM1 API
500
+ // value would otherwise be cast to DataSource["type"] and could break a
501
+ // downstream switch (e.g. the .pro serializer's type map). Pass it through
502
+ // for forward-compat reads, but log so the gap is observable.
503
+ const KNOWN_DATASOURCE_TYPES = [
504
+ "None",
505
+ "TM1CubeView",
506
+ "TM1DimensionSubset",
507
+ "ASCII",
508
+ "ODBC",
509
+ "TM1Process",
510
+ ];
511
+ if (!KNOWN_DATASOURCE_TYPES.includes(ds.Type)) {
512
+ this.http.logger.warn({ processName, dataSourceType: ds.Type }, "Unknown TI datasource type from TM1; passing through unchanged");
513
+ }
514
+ return {
515
+ type: ds.Type,
516
+ ...(ds.dataSourceNameForServer !== undefined
517
+ ? { dataSourceNameForServer: ds.dataSourceNameForServer }
518
+ : {}),
519
+ ...(ds.dataSourceNameForClient !== undefined
520
+ ? { dataSourceNameForClient: ds.dataSourceNameForClient }
521
+ : {}),
522
+ ...(ds.asciiDelimiterType !== undefined
523
+ ? { asciiDelimiterType: ds.asciiDelimiterType }
524
+ : {}),
525
+ ...(ds.asciiDelimiterChar !== undefined
526
+ ? { asciiDelimiterChar: ds.asciiDelimiterChar }
527
+ : {}),
528
+ ...(ds.asciiQuoteCharacter !== undefined
529
+ ? { asciiQuoteCharacter: ds.asciiQuoteCharacter }
530
+ : {}),
531
+ ...(ds.asciiHeaderRecords !== undefined
532
+ ? { asciiHeaderRecords: ds.asciiHeaderRecords }
533
+ : {}),
534
+ ...(ds.asciiDecimalSeparator !== undefined
535
+ ? { asciiDecimalSeparator: ds.asciiDecimalSeparator }
536
+ : {}),
537
+ ...(ds.asciiThousandSeparator !== undefined
538
+ ? { asciiThousandSeparator: ds.asciiThousandSeparator }
539
+ : {}),
540
+ ...(ds.usesUnicode !== undefined ? { usesUnicode: ds.usesUnicode } : {}),
541
+ ...(ds.userName !== undefined ? { userName: ds.userName } : {}),
542
+ // Never surface the ODBC datasource password to the caller/LLM — return a
543
+ // presence marker so the field stays observable without leaking the credential.
544
+ ...(ds.password !== undefined
545
+ ? {
546
+ password: opts?.includeSecrets
547
+ ? ds.password
548
+ : ds.password
549
+ ? "[redacted]"
550
+ : "",
551
+ }
552
+ : {}),
553
+ ...(ds.query !== undefined ? { query: ds.query } : {}),
554
+ ...(ds.view !== undefined ? { view: ds.view } : {}),
555
+ ...(ds.subset !== undefined ? { subset: ds.subset } : {}),
556
+ };
557
+ }
558
+ /**
559
+ * Bulk-fetch the datasource of every process in one OData call, projected to
560
+ * the few fields data-flow analysis needs (type + source object). Credentials
561
+ * are never selected. Used by tm1_trace_data_flow to detect view-sourced reads
562
+ * that leave no CellGet in the code and so never reach the reference index.
563
+ * GET /api/v1/Processes?$select=Name,DataSource
564
+ */
565
+ async listDataSources(includeControl = false) {
566
+ const filter = includeControl ? "" : "&$filter=not startswith(Name,'}')";
567
+ const path = `/api/v1/Processes?$select=Name,DataSource${filter}`;
568
+ const response = await this.http.request("GET", path);
569
+ return response.value
570
+ .filter((p) => typeof p.Name === "string")
571
+ .map((p) => {
572
+ const ds = p.DataSource;
573
+ return {
574
+ name: p.Name,
575
+ type: ds?.Type ?? "None",
576
+ ...(ds?.dataSourceNameForServer !== undefined
577
+ ? { sourceName: ds.dataSourceNameForServer }
578
+ : {}),
579
+ ...(ds?.view !== undefined ? { view: ds.view } : {}),
580
+ ...(ds?.subset !== undefined ? { subset: ds.subset } : {}),
581
+ };
582
+ });
583
+ }
584
+ /**
585
+ * Update the data source configuration of a TI process.
586
+ * PATCH /api/v1/Processes('{name}') with DataSource object.
587
+ */
588
+ async updateDataSource(processName, dataSource) {
589
+ const path = `/api/v1/Processes('${enc(processName)}')`;
590
+ const dsBody = { Type: dataSource.type };
591
+ if (dataSource.dataSourceNameForServer !== undefined)
592
+ dsBody.dataSourceNameForServer = dataSource.dataSourceNameForServer;
593
+ if (dataSource.dataSourceNameForClient !== undefined)
594
+ dsBody.dataSourceNameForClient = dataSource.dataSourceNameForClient;
595
+ if (dataSource.asciiDelimiterType !== undefined)
596
+ dsBody.asciiDelimiterType = dataSource.asciiDelimiterType;
597
+ if (dataSource.asciiDelimiterChar !== undefined)
598
+ dsBody.asciiDelimiterChar = dataSource.asciiDelimiterChar;
599
+ if (dataSource.asciiQuoteCharacter !== undefined)
600
+ dsBody.asciiQuoteCharacter = dataSource.asciiQuoteCharacter;
601
+ if (dataSource.asciiHeaderRecords !== undefined)
602
+ dsBody.asciiHeaderRecords = dataSource.asciiHeaderRecords;
603
+ if (dataSource.asciiDecimalSeparator !== undefined)
604
+ dsBody.asciiDecimalSeparator = dataSource.asciiDecimalSeparator;
605
+ if (dataSource.asciiThousandSeparator !== undefined)
606
+ dsBody.asciiThousandSeparator = dataSource.asciiThousandSeparator;
607
+ if (dataSource.usesUnicode !== undefined) {
608
+ if (acceptsUsesUnicode(dataSource.type)) {
609
+ dsBody.usesUnicode = dataSource.usesUnicode;
610
+ }
611
+ else {
612
+ this.http.logger.warn({ processName, dataSourceType: dataSource.type }, "DataSource.usesUnicode applies to ODBC sources only and is being dropped from the PATCH (TM1 rejects it as 'unprocessed properties' for other types)");
613
+ }
614
+ }
615
+ if (dataSource.userName !== undefined)
616
+ dsBody.userName = dataSource.userName;
617
+ if (dataSource.password !== undefined)
618
+ dsBody.password = dataSource.password;
619
+ if (dataSource.query !== undefined)
620
+ dsBody.query = dataSource.query;
621
+ if (dataSource.view !== undefined)
622
+ dsBody.view = dataSource.view;
623
+ if (dataSource.subset !== undefined)
624
+ dsBody.subset = dataSource.subset;
625
+ await this.http.request("PATCH", path, { DataSource: dsBody });
626
+ }
627
+ /**
628
+ * Get the variables (column-mapped names) of a TI process.
629
+ * GET /api/v1/Processes('{name}')/Variables
630
+ */
631
+ async getVariables(processName) {
632
+ return (await this.getVariableLayout(processName)).variables;
633
+ }
634
+ /**
635
+ * Variables PLUS the columns the process ignores, in one request.
636
+ *
637
+ * `Variables` alone is an incomplete picture of the datasource: a column set
638
+ * to "Ignore" carries no variable and is simply absent from the list, which
639
+ * is why the remaining positions have gaps. The ignore flag lives in
640
+ * `VariablesUIData` — one entry per source column, undeclared in $metadata on
641
+ * both versions, so it must be named in `$select`.
642
+ *
643
+ * GET /api/v1/Processes('{name}')?$select=Variables,VariablesUIData
644
+ */
645
+ async getVariableLayout(processName) {
646
+ const path = `/api/v1/Processes('${enc(processName)}')` +
647
+ `?$select=Variables,VariablesUIData`;
648
+ try {
649
+ const r = await this.http.request("GET", path);
650
+ return {
651
+ variables: (r.Variables ?? []).map(decodeVariable),
652
+ ignoredColumns: ignoredColumnsOf(r.VariablesUIData),
653
+ ...(r.VariablesUIData !== undefined
654
+ ? { variablesUIData: r.VariablesUIData }
655
+ : {}),
656
+ };
657
+ }
658
+ catch (e) {
659
+ rethrowIfSystemic(e);
660
+ if (!isUnsupportedQueryShape(e))
661
+ throw e;
662
+ // A server that will not answer the $select still answers the plain
663
+ // collection — variables without the ignore information beat no answer.
664
+ const response = await this.http.request("GET", `/api/v1/Processes('${enc(processName)}')/Variables`);
665
+ return {
666
+ variables: response.value.map(decodeVariable),
667
+ ignoredColumns: [],
668
+ };
669
+ }
670
+ }
671
+ /**
672
+ * Variables of every process, in ONE request.
673
+ *
674
+ * `Variables` is a complex-typed property, not a navigation collection, so
675
+ * the process list can carry it directly — no `$expand`, and no follow-up
676
+ * call per process. `getVariables` above answers the same question for a
677
+ * single process and stays the right tool when that is all you need.
678
+ *
679
+ * The difference is not cosmetic: asking per process costs one round trip
680
+ * each, which on a 221-process model measured as 221 extra requests against
681
+ * a single 147 KB one. Whole-model analyses (audit_complexity) use this.
682
+ *
683
+ * GET /api/v1/Processes?$select=Name,Variables
684
+ */
685
+ async getAllVariables(includeControl = false) {
686
+ const filter = includeControl ? "" : "&$filter=not startswith(Name,'}')";
687
+ const path = `/api/v1/Processes?$select=Name,Variables${filter}`;
688
+ const response = await this.http.request("GET", path);
689
+ const byProcess = new Map();
690
+ for (const p of response.value) {
691
+ // A process without variables comes back with the property omitted
692
+ // rather than as an empty array.
693
+ byProcess.set(p.Name, (p.Variables ?? []).map(decodeVariable));
694
+ }
695
+ return byProcess;
696
+ }
697
+ /**
698
+ * Update the variables of a TI process (column-name mapping for ASCII/ODBC sources).
699
+ * Required after setting an ASCII DataSource.
700
+ * PATCH /api/v1/Processes('{name}') with Variables array.
701
+ */
702
+ async updateVariables(processName, vars, variablesUIData) {
703
+ const path = `/api/v1/Processes('${enc(processName)}')`;
704
+ const body = {
705
+ Variables: vars.map((v) => ({
706
+ Name: v.name,
707
+ Type: v.type,
708
+ Position: v.position,
709
+ StartByte: v.startByte ?? 0,
710
+ EndByte: v.endByte ?? 0,
711
+ })),
712
+ };
713
+ // Patching Variables alone leaves whatever VariablesUIData the process
714
+ // already has (measured on 12.5), which is right for an edit that keeps the
715
+ // column layout and wrong for one that changes it — hence the explicit
716
+ // parameter for callers that carry the source layout (git/.pro import).
717
+ if (variablesUIData !== undefined)
718
+ body.VariablesUIData = variablesUIData;
719
+ await this.http.request("PATCH", path, body);
720
+ }
721
+ /**
722
+ * Update the parameters of a TI process.
723
+ * PATCH /api/v1/Processes('{name}') with Parameters array.
724
+ */
725
+ async updateParameters(processName, params) {
726
+ const path = `/api/v1/Processes('${enc(processName)}')`;
727
+ const body = {
728
+ Parameters: params.map(encodeParameter),
729
+ };
730
+ await this.http.request("PATCH", path, body);
731
+ }
732
+ /**
733
+ * Delete a TI process.
734
+ * DELETE /api/v1/Processes('{name}')
735
+ */
736
+ async delete(processName) {
737
+ const path = `/api/v1/Processes('${enc(processName)}')`;
738
+ await this.http.request("DELETE", path);
739
+ }
740
+ /**
741
+ * Compile a saved TI process to check syntax without executing it.
742
+ * POST /api/v1/Processes('{name}')/tm1.Compile
743
+ */
744
+ async compile(processName) {
745
+ const path = `/api/v1/Processes('${enc(processName)}')/tm1.Compile`;
746
+ try {
747
+ const response = await this.http.request("POST", path, {});
748
+ const errors = (response?.value ?? []).map((e) => ({
749
+ lineNumber: e.LineNumber,
750
+ procedure: e.Procedure,
751
+ message: e.Message ?? "",
752
+ }));
753
+ return { success: errors.length === 0, errors };
754
+ }
755
+ catch (err) {
756
+ // Systemic transport/auth failures must propagate rather than be reported
757
+ // as a compile failure — an outage is not a broken process.
758
+ rethrowIfSystemic(err);
759
+ if (err instanceof TM1Error) {
760
+ return {
761
+ success: false,
762
+ errors: [{ message: err.details ?? err.message }],
763
+ };
764
+ }
765
+ throw err;
766
+ }
767
+ }
768
+ /**
769
+ * Validate a TI process WITHOUT saving it on the server. Mirrors tm1py's
770
+ * compile_process_with_body. Returns CompileResult identical to compile()
771
+ * for callers that already handle that shape.
772
+ * POST /api/v1/CompileProcess body { Process: <full process body> }
773
+ */
774
+ async check(input) {
775
+ const path = "/api/v1/CompileProcess";
776
+ const processBody = {
777
+ Name: input.name ?? "_compile_check",
778
+ PrologProcedure: input.prolog ?? "",
779
+ MetadataProcedure: input.metadata ?? "",
780
+ DataProcedure: input.data ?? "",
781
+ EpilogProcedure: input.epilog ?? "",
782
+ };
783
+ if (input.parameters) {
784
+ processBody.Parameters = input.parameters.map(encodeParameter);
785
+ }
786
+ if (input.variables) {
787
+ processBody.Variables = input.variables.map((v) => ({
788
+ Name: v.name,
789
+ Type: v.type,
790
+ Position: v.position,
791
+ StartByte: v.startByte ?? 0,
792
+ EndByte: v.endByte ?? 0,
793
+ }));
794
+ }
795
+ if (input.dataSource) {
796
+ const ds = input.dataSource;
797
+ const dsBody = { Type: ds.type };
798
+ if (ds.dataSourceNameForServer !== undefined)
799
+ dsBody.dataSourceNameForServer = ds.dataSourceNameForServer;
800
+ if (ds.dataSourceNameForClient !== undefined)
801
+ dsBody.dataSourceNameForClient = ds.dataSourceNameForClient;
802
+ if (ds.asciiDelimiterType !== undefined)
803
+ dsBody.asciiDelimiterType = ds.asciiDelimiterType;
804
+ if (ds.asciiDelimiterChar !== undefined)
805
+ dsBody.asciiDelimiterChar = ds.asciiDelimiterChar;
806
+ if (ds.asciiQuoteCharacter !== undefined)
807
+ dsBody.asciiQuoteCharacter = ds.asciiQuoteCharacter;
808
+ if (ds.asciiHeaderRecords !== undefined)
809
+ dsBody.asciiHeaderRecords = ds.asciiHeaderRecords;
810
+ if (ds.asciiDecimalSeparator !== undefined)
811
+ dsBody.asciiDecimalSeparator = ds.asciiDecimalSeparator;
812
+ if (ds.asciiThousandSeparator !== undefined)
813
+ dsBody.asciiThousandSeparator = ds.asciiThousandSeparator;
814
+ // usesUnicode: ODBC-only, on every version — see acceptsUsesUnicode().
815
+ if (ds.usesUnicode !== undefined && acceptsUsesUnicode(ds.type)) {
816
+ dsBody.usesUnicode = ds.usesUnicode;
817
+ }
818
+ if (ds.userName !== undefined)
819
+ dsBody.userName = ds.userName;
820
+ if (ds.password !== undefined)
821
+ dsBody.password = ds.password;
822
+ if (ds.query !== undefined)
823
+ dsBody.query = ds.query;
824
+ if (ds.view !== undefined)
825
+ dsBody.view = ds.view;
826
+ if (ds.subset !== undefined)
827
+ dsBody.subset = ds.subset;
828
+ processBody.DataSource = dsBody;
829
+ }
830
+ else {
831
+ processBody.DataSource = { Type: "None" };
832
+ }
833
+ try {
834
+ const response = await this.http.request("POST", path, { Process: processBody });
835
+ const errors = (response?.value ?? []).map((e) => ({
836
+ lineNumber: e.LineNumber,
837
+ procedure: e.Procedure,
838
+ message: e.Message ?? "",
839
+ }));
840
+ return { success: errors.length === 0, errors };
841
+ }
842
+ catch (err) {
843
+ // Systemic transport/auth failures must propagate rather than be reported
844
+ // as a compile failure — an outage is not a broken process.
845
+ rethrowIfSystemic(err);
846
+ if (err instanceof TM1Error) {
847
+ return {
848
+ success: false,
849
+ errors: [{ message: err.details ?? err.message }],
850
+ };
851
+ }
852
+ throw err;
853
+ }
854
+ }
855
+ }
856
+ /**
857
+ * `usesUnicode` is an ODBC datasource setting, not a version-specific one.
858
+ *
859
+ * It was carried here as "v12-only, TM1 11.x rejects it", which had it exactly
860
+ * backwards. TM1 validates datasource properties per source type: 11.8 rejects
861
+ * usesUnicode for an ASCII source ("unprocessed properties") but accepts it for
862
+ * an ODBC one, returns it from a plain GET, and writes it to the .pro file as
863
+ * line 559 (`usesUnicode: true` → `559,1`, `false` → `559,0`) — measured on
864
+ * both. On 12.5 the property is never returned for any source type, so there is
865
+ * no evidence it exists there; sending it costs nothing, since v12 silently
866
+ * ignores properties it does not know.
867
+ *
868
+ * Gating on the source type therefore serves both versions correctly, which
869
+ * gating on the version never did.
870
+ */
871
+ function acceptsUsesUnicode(type) {
872
+ return type === "ODBC";
873
+ }
874
+ //# sourceMappingURL=process-service.js.map