@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,504 @@
1
+ // Server domain service. Owns server-level read endpoints — configuration,
2
+ // message log, transaction log, error-log files. Stateless wrappers; nothing
3
+ // here mutates server state.
4
+ //
5
+ // See docs/ARCHITECTURE.md for the layering.
6
+ import { TM1Error, TM1ErrorCode } from "../../types.js";
7
+ import { rethrowIfSystemicOrDenied } from "./fallback.js";
8
+ // TM1 references the per-run TI error file inside the free-text message, either
9
+ // wrapped in angle brackets (e.g. German `Fehlerdatei: <…log>`) or bare
10
+ // (`see TM1ProcessError_…log`). Both regexes are linear (no nested quantifiers,
11
+ // delimiter excluded from the class) — no ReDoS guard needed for these literals.
12
+ const ANGLE_WRAPPED_LOG = /<([^<>\s]+\.log)>/i;
13
+ const BARE_PROCESS_ERROR_LOG = /TM1ProcessError_[^\s<>'"()]+\.log/i;
14
+ /**
15
+ * Pull the TM1 error log filename out of a message-log entry's free text, so it
16
+ * can be fed straight into `tm1_get_error_log_content(filename=…)`. Returns the
17
+ * exact filename (no surrounding brackets) or undefined when none is mentioned.
18
+ */
19
+ export function extractErrorFile(message) {
20
+ const angle = message.match(ANGLE_WRAPPED_LOG);
21
+ if (angle)
22
+ return angle[1];
23
+ const bare = message.match(BARE_PROCESS_ERROR_LOG);
24
+ return bare ? bare[0] : undefined;
25
+ }
26
+ // The TransactionLogEntries endpoint scans the whole log server-side and is
27
+ // slow; without log-read rights it can hang until the global request timeout.
28
+ // Before the real (orderby + filtered) query we fire a bare `$top=1` probe —
29
+ // NO $orderby, NO $filter, so TM1 can stop after the first row and the result
30
+ // is at most one entry — bounded by a short timeout to fail fast.
31
+ const TXLOG_PROBE_TIMEOUT_MS = 8000;
32
+ // Per-window query timeout. Each windowed/bounded query runs once (no retry),
33
+ // so a timeout means the range is too large/dense — not a transient blip.
34
+ const TXLOG_QUERY_TIMEOUT_MS = 20000;
35
+ // Expanding lookback windows (ms) for the no-`since` adaptive backfill. We walk
36
+ // backward from the anchor, widening until `top` rows are collected or the last
37
+ // window is exhausted — so an open-ended call never triggers a full-log scan.
38
+ const TXLOG_BACKFILL_WINDOWS_MS = [
39
+ 10 * 60_000, // 10 min
40
+ 60 * 60_000, // 1 h
41
+ 6 * 3_600_000, // 6 h
42
+ 24 * 3_600_000, // 1 d
43
+ 3 * 86_400_000, // 3 d
44
+ 7 * 86_400_000, // 7 d
45
+ 30 * 86_400_000, // 30 d
46
+ 90 * 86_400_000, // 90 d
47
+ 365 * 86_400_000, // 1 y
48
+ ];
49
+ // Format an epoch-ms instant as an OData UTC literal (second precision, no ms).
50
+ function epochToOData(ms) {
51
+ return `${new Date(ms).toISOString().slice(0, 19)}Z`;
52
+ }
53
+ /**
54
+ * Normalize a user timestamp into an OData v4 DateTimeOffset literal for a
55
+ * TM1 $filter. TM1 rejects a bare `2026-06-08T00:00:00` ("Syntax error … near
56
+ * -06") — the value MUST carry a timezone. Verified against TM1 11.8: only the
57
+ * `Z`-suffixed (or ±hh:mm-offset) form parses. Date-only input expands to
58
+ * start-of-day UTC; a zoneless datetime gets a `Z`; an already-zoned value is
59
+ * left untouched.
60
+ */
61
+ export function toOdataDateTime(input) {
62
+ let t = input.trim();
63
+ if (/^\d{4}-\d{2}-\d{2}$/.test(t))
64
+ t = `${t}T00:00:00`;
65
+ if (!/[zZ]$/.test(t) && !/[+-]\d{2}:\d{2}$/.test(t))
66
+ t = `${t}Z`;
67
+ // Validate before it reaches a $filter. Appending "Z" to whatever arrived
68
+ // turned "yesterday" into "yesterdayZ" and shipped it to TM1, which answers
69
+ // with an opaque OData parse error naming neither the parameter nor the bad
70
+ // value. Rejecting here names both.
71
+ //
72
+ // Shape check FIRST, then Date.parse — Date.parse alone is too permissive to
73
+ // be a gate. It accepts V8's legacy formats, so "08/06/2026" parses happily
74
+ // as 6 August; a caller who meant 8 June would silently get a different day
75
+ // and a plausible-looking, wrong result. Ambiguous input must fail loudly.
76
+ const ISO_DATETIME = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:\d{2})$/;
77
+ if (!ISO_DATETIME.test(t) || Number.isNaN(Date.parse(t))) {
78
+ throw new TM1Error({
79
+ code: TM1ErrorCode.VALIDATION_ERROR,
80
+ message: `Not a usable timestamp: '${input}'. Expected ISO-8601 — ` +
81
+ `'2026-06-08', '2026-06-08T14:30:00', or with a zone ` +
82
+ `('...Z' / '...+02:00'). A value without a zone is read as UTC.`,
83
+ });
84
+ }
85
+ return t;
86
+ }
87
+ // enc stays plain — it also wraps whole $filter/$orderby clauses below, where
88
+ // the inner string literals are already single-quote-escaped via esc().
89
+ const enc = encodeURIComponent;
90
+ // OData entity-key encoder: double ' per OData literal rules, then percent-encode.
91
+ const encKey = (s) => encodeURIComponent(String(s).replace(/'/g, "''"));
92
+ export class ServerService {
93
+ http;
94
+ constructor(http) {
95
+ this.http = http;
96
+ }
97
+ /**
98
+ * Fetch TM1 server configuration. Merges /Configuration and
99
+ * /ActiveConfiguration; tolerates ActiveConfiguration being absent on
100
+ * older builds.
101
+ */
102
+ async getInfo() {
103
+ const cfg = await this.http.request("GET", "/api/v1/Configuration");
104
+ let active = {};
105
+ try {
106
+ active = await this.http.request("GET", "/api/v1/ActiveConfiguration");
107
+ }
108
+ catch {
109
+ // Some TM1 versions don't expose ActiveConfiguration — ignore.
110
+ }
111
+ const merged = { ...cfg, ...active };
112
+ delete merged["@odata.context"];
113
+ // v12 (Planning Analytics Engine) omits ProductVersion from the
114
+ // Configuration object body; it is exposed only as a scalar sub-resource.
115
+ // Fall back to it when the inline field is absent (v11 has it inline, so
116
+ // this extra request never fires there).
117
+ let productVersion = String(merged.ProductVersion ?? "");
118
+ if (!productVersion) {
119
+ try {
120
+ const pv = await this.http.request("GET", "/api/v1/Configuration/ProductVersion");
121
+ if (typeof pv.value === "string") {
122
+ productVersion = pv.value;
123
+ }
124
+ }
125
+ catch {
126
+ // Scalar sub-resource unavailable — leave version empty.
127
+ }
128
+ }
129
+ return {
130
+ serverName: String(merged.ServerName ?? ""),
131
+ productVersion,
132
+ productEdition: merged.ProductEdition !== undefined
133
+ ? String(merged.ProductEdition)
134
+ : undefined,
135
+ adminHost: merged.AdminHost !== undefined ? String(merged.AdminHost) : undefined,
136
+ dataDirectory: merged.DataBaseDirectory !== undefined
137
+ ? String(merged.DataBaseDirectory)
138
+ : undefined,
139
+ timeZoneId: merged.TimeZoneID !== undefined ? String(merged.TimeZoneID) : undefined,
140
+ integratedSecurityMode: merged.IntegratedSecurityMode !== undefined
141
+ ? String(merged.IntegratedSecurityMode)
142
+ : undefined,
143
+ extra: merged,
144
+ };
145
+ }
146
+ /**
147
+ * Get recent TM1 server message log entries (newest first).
148
+ *
149
+ * The text/level/time filters are pushed to the server via `$filter` so a
150
+ * match OLDER than the `top`-row window is still found — filtering only the
151
+ * newest `top` rows client-side produced false negatives ("no error found")
152
+ * whenever the matching entry had scrolled past that window. TM1 v11 supports
153
+ * OData `contains`/`tolower`/`eq`/`ge`/`le` on the MessageLogEntries set.
154
+ *
155
+ * Text match is case-insensitive (tolower on both sides) to preserve the prior
156
+ * client-side `.toLowerCase().includes()` contract. If the server rejects the
157
+ * filtered query (older/limited builds without full string-function support),
158
+ * we fall back to fetching the newest `top` rows and filtering in-process —
159
+ * the same best-effort path as before, so the tool degrades rather than errors.
160
+ *
161
+ * GET /api/v1/MessageLogEntries?$orderby=TimeStamp desc&$top={top}[&$filter=…]
162
+ */
163
+ async getMessageLog(opts = {}) {
164
+ const top = opts.top ?? 100;
165
+ // Inner-literal single-quote escaping per OData; the whole clause is then
166
+ // URL-encoded with enc() below (mirrors getAuditLog()'s esc()+enc() pattern).
167
+ const esc = (s) => s.replace(/'/g, "''");
168
+ const filters = [];
169
+ if (opts.filter)
170
+ filters.push(`contains(tolower(Message),'${esc(opts.filter.toLowerCase())}')`);
171
+ if (opts.level)
172
+ filters.push(`toupper(Level) eq '${esc(opts.level.toUpperCase())}'`);
173
+ if (opts.logger)
174
+ filters.push(`Logger eq '${esc(opts.logger)}'`);
175
+ if (opts.since)
176
+ filters.push(`TimeStamp ge ${toOdataDateTime(opts.since)}`);
177
+ if (opts.until)
178
+ filters.push(`TimeStamp le ${toOdataDateTime(opts.until)}`);
179
+ const qs = [`$orderby=${enc("TimeStamp desc")}`, `$top=${top}`];
180
+ if (filters.length > 0)
181
+ qs.push(`$filter=${enc(filters.join(" and "))}`);
182
+ const map = (rows) => rows.map((e) => {
183
+ const message = e.Message ?? e.Text ?? "";
184
+ const errorFile = extractErrorFile(message);
185
+ return {
186
+ timestamp: e.TimeStamp ?? e.Timestamp ?? "",
187
+ level: (e.Level ?? "").toUpperCase(),
188
+ message,
189
+ ...(errorFile ? { errorFile } : {}),
190
+ };
191
+ });
192
+ if (filters.length === 0) {
193
+ const response = await this.http.request("GET", `/api/v1/MessageLogEntries?${qs.join("&")}`);
194
+ return map(response.value);
195
+ }
196
+ try {
197
+ const response = await this.http.request("GET", `/api/v1/MessageLogEntries?${qs.join("&")}`);
198
+ return map(response.value);
199
+ }
200
+ catch (err) {
201
+ // Systemic transport/auth failures and permission denials must surface —
202
+ // only a server-side rejection of the filter expression itself should
203
+ // trigger the degraded client-side fallback.
204
+ rethrowIfSystemicOrDenied(err);
205
+ const response = await this.http.request("GET", `/api/v1/MessageLogEntries?$orderby=${enc("TimeStamp desc")}&$top=${top}`);
206
+ // Degraded path: re-apply the FULL filter set client-side over the
207
+ // newest-`top` window. Filtering raw rows (pre-map) so Logger/TimeStamp
208
+ // are available — otherwise since/until/logger would be silently dropped
209
+ // and out-of-range rows returned mislabeled as matches.
210
+ let rows = response.value;
211
+ if (opts.filter) {
212
+ const needle = opts.filter.toLowerCase();
213
+ rows = rows.filter((e) => (e.Message ?? e.Text ?? "").toLowerCase().includes(needle));
214
+ }
215
+ if (opts.level) {
216
+ const want = opts.level.toUpperCase();
217
+ rows = rows.filter((e) => (e.Level ?? "").toUpperCase() === want);
218
+ }
219
+ if (opts.logger) {
220
+ rows = rows.filter((e) => e.Logger === opts.logger);
221
+ }
222
+ if (opts.since) {
223
+ const from = Date.parse(opts.since);
224
+ if (!Number.isNaN(from)) {
225
+ rows = rows.filter((e) => {
226
+ const ts = Date.parse(e.TimeStamp ?? e.Timestamp ?? "");
227
+ return !Number.isNaN(ts) && ts >= from;
228
+ });
229
+ }
230
+ }
231
+ if (opts.until) {
232
+ const to = Date.parse(opts.until);
233
+ if (!Number.isNaN(to)) {
234
+ rows = rows.filter((e) => {
235
+ const ts = Date.parse(e.TimeStamp ?? e.Timestamp ?? "");
236
+ return !Number.isNaN(ts) && ts <= to;
237
+ });
238
+ }
239
+ }
240
+ return map(rows);
241
+ }
242
+ }
243
+ /**
244
+ * Fetch recent TM1 audit log entries (metadata/security changes), newest
245
+ * first. Requires AuditLogOn=T in tm1s.cfg — with auditing disabled the
246
+ * entity set is empty.
247
+ * GET /api/v1/AuditLogEntries
248
+ */
249
+ async getAuditLog(opts) {
250
+ const esc = (s) => s.replace(/'/g, "''");
251
+ const filters = [];
252
+ if (opts.user)
253
+ filters.push(`UserName eq '${esc(opts.user)}'`);
254
+ if (opts.objectType)
255
+ filters.push(`ObjectType eq '${esc(opts.objectType)}'`);
256
+ if (opts.objectName)
257
+ filters.push(`ObjectName eq '${esc(opts.objectName)}'`);
258
+ if (opts.since)
259
+ filters.push(`TimeStamp ge ${toOdataDateTime(opts.since)}`);
260
+ if (opts.until)
261
+ filters.push(`TimeStamp le ${toOdataDateTime(opts.until)}`);
262
+ const top = opts.top ?? 100;
263
+ const qs = [`$top=${top}`, `$orderby=${enc("TimeStamp desc")}`];
264
+ if (filters.length > 0)
265
+ qs.push(`$filter=${enc(filters.join(" and "))}`);
266
+ if (opts.includeDetails)
267
+ qs.push("$expand=AuditDetails");
268
+ const response = await this.http.request("GET", `/api/v1/AuditLogEntries?${qs.join("&")}`);
269
+ const mapDetail = (d) => ({
270
+ id: d.ID ?? 0,
271
+ timestamp: d.TimeStamp ?? "",
272
+ user: d.UserName ?? "",
273
+ description: d.Description ?? "",
274
+ objectType: d.ObjectType ?? "",
275
+ objectName: d.ObjectName ?? "",
276
+ });
277
+ return response.value.map((e) => {
278
+ const entry = mapDetail(e);
279
+ if (e.AuditDetails !== undefined)
280
+ entry.details = e.AuditDetails.map(mapDetail);
281
+ return entry;
282
+ });
283
+ }
284
+ /**
285
+ * Fetch recent TM1 transaction log entries (cell writes).
286
+ * GET /api/v1/TransactionLogEntries
287
+ */
288
+ async getTransactionLog(opts) {
289
+ const top = opts.top ?? 100;
290
+ // Preflight: bare $top=1 (no orderby/filter) — cheap reachability/permission
291
+ // gate that fails fast instead of hanging.
292
+ await this.probeTransactionLog();
293
+ // Explicit lower bound → a single bounded query [since, until]. Coverage is
294
+ // well-defined by the bound: everything in the span is returned.
295
+ if (opts.since !== undefined) {
296
+ const entries = await this.queryTransactionLog({
297
+ top,
298
+ cubeName: opts.cubeName,
299
+ user: opts.user,
300
+ since: opts.since,
301
+ until: opts.until,
302
+ });
303
+ return {
304
+ entries,
305
+ coverage: "complete",
306
+ scannedFrom: toOdataDateTime(opts.since),
307
+ };
308
+ }
309
+ // No lower bound → adaptive backward windowing from `until` (or now). An
310
+ // unbounded TransactionLogEntries scan takes minutes-to-hours; instead we
311
+ // probe expanding windows and stop as soon as we have `top` rows. If a wide
312
+ // window times out we keep the rows already collected rather than failing.
313
+ // Coverage: "partial" if we stopped because `top` filled or a window failed
314
+ // (older matching rows may exist earlier); "complete" if windows exhausted.
315
+ const anchorMs = opts.until !== undefined
316
+ ? Date.parse(toOdataDateTime(opts.until))
317
+ : Date.now();
318
+ let collected = [];
319
+ let scannedFromMs = anchorMs;
320
+ for (const windowMs of TXLOG_BACKFILL_WINDOWS_MS) {
321
+ const floorMs = anchorMs - windowMs;
322
+ let entries;
323
+ try {
324
+ entries = await this.queryTransactionLog({
325
+ top,
326
+ cubeName: opts.cubeName,
327
+ user: opts.user,
328
+ since: epochToOData(floorMs),
329
+ until: opts.until,
330
+ });
331
+ }
332
+ catch (err) {
333
+ // Systemic transport/auth failures (CONNECTION_FAILED, AUTH_FAILED,
334
+ // LOCK_TIMEOUT) AND permission denials must surface — swallowing them
335
+ // would return an empty or partial window as if the range simply held no
336
+ // data (or as if a denied cube were empty). A window timeout (TM1_ERROR
337
+ // from queryTransactionLog) is expected and just stops widening — but we
338
+ // stopped short of exhausting the span, so coverage is partial.
339
+ rethrowIfSystemicOrDenied(err);
340
+ return {
341
+ entries: collected,
342
+ coverage: "partial",
343
+ scannedFrom: epochToOData(scannedFromMs),
344
+ };
345
+ }
346
+ scannedFromMs = floorMs;
347
+ collected = entries;
348
+ if (entries.length >= top) {
349
+ return {
350
+ entries,
351
+ coverage: "partial",
352
+ scannedFrom: epochToOData(floorMs),
353
+ };
354
+ }
355
+ }
356
+ return {
357
+ entries: collected,
358
+ coverage: "complete",
359
+ scannedFrom: epochToOData(scannedFromMs),
360
+ };
361
+ }
362
+ /**
363
+ * Single bounded TransactionLogEntries query. Runs once (retry disabled) under
364
+ * a dedicated timeout: the endpoint is deterministically slow, so a timeout
365
+ * means "range too large", not a transient blip. Our own timeout (the
366
+ * controller abort) and other non-systemic failures become an actionable
367
+ * "narrow the range" error; systemic transport/auth failures propagate
368
+ * unmasked and permission denials surface as-is.
369
+ */
370
+ async queryTransactionLog(q) {
371
+ const filters = [];
372
+ if (q.cubeName)
373
+ filters.push(`Cube eq '${q.cubeName.replace(/'/g, "''")}'`);
374
+ if (q.user)
375
+ filters.push(`User eq '${q.user.replace(/'/g, "''")}'`);
376
+ if (q.since)
377
+ filters.push(`TimeStamp ge ${toOdataDateTime(q.since)}`);
378
+ if (q.until)
379
+ filters.push(`TimeStamp le ${toOdataDateTime(q.until)}`);
380
+ const qs = [`$top=${q.top}`, `$orderby=TimeStamp desc`];
381
+ if (filters.length > 0)
382
+ qs.push(`$filter=${enc(filters.join(" and "))}`);
383
+ const path = `/api/v1/TransactionLogEntries?${qs.join("&")}`;
384
+ const controller = new AbortController();
385
+ const timer = setTimeout(() => controller.abort(), TXLOG_QUERY_TIMEOUT_MS);
386
+ try {
387
+ const response = await this.http.request("GET", path, undefined, { signal: controller.signal, retry: false });
388
+ return response.value.map((e) => ({
389
+ timestamp: e.TimeStamp ?? "",
390
+ user: e.User ?? "",
391
+ cubeName: e.Cube ?? "",
392
+ elements: e.Tuple ?? [],
393
+ oldValue: e.OldValue ?? null,
394
+ newValue: e.NewValue ?? null,
395
+ }));
396
+ }
397
+ catch (err) {
398
+ // Our own dedicated timeout aborts via the controller and surfaces as a
399
+ // raw (non-TM1) abort — that IS the "range too large" signal. For every
400
+ // other error, systemic transport/auth failures (CONNECTION_FAILED,
401
+ // AUTH_FAILED, LOCK_TIMEOUT) and unexpected non-TM1 throws must propagate
402
+ // unmasked, and a permission denial stays actionable; only then do we fall
403
+ // through and treat the failure as an actionable "narrow the range" error.
404
+ if (!controller.signal.aborted) {
405
+ rethrowIfSystemicOrDenied(err);
406
+ }
407
+ throw new TM1Error({
408
+ code: TM1ErrorCode.TM1_ERROR,
409
+ message: `Transaction log query exceeded ${TXLOG_QUERY_TIMEOUT_MS / 1000}s — the time range is too large or dense.`,
410
+ endpoint: path,
411
+ details: err instanceof Error ? err.message : String(err),
412
+ hint: "Bound the scan with a narrower since/until (from-to) range, or add cubeName/user.",
413
+ });
414
+ }
415
+ finally {
416
+ clearTimeout(timer);
417
+ }
418
+ }
419
+ /**
420
+ * Cheap reachability/permission probe for the transaction log. A bare
421
+ * `$top=1` (no $orderby/$filter) returns at most one row so TM1 can short-
422
+ * circuit; a dedicated short-timeout AbortController caps the wait. That
423
+ * timeout (and other non-systemic failures) becomes an actionable TM1_ERROR;
424
+ * permission denials surface as-is and systemic transport/auth failures
425
+ * (e.g. CONNECTION_FAILED) propagate unmasked.
426
+ */
427
+ async probeTransactionLog() {
428
+ const controller = new AbortController();
429
+ const timer = setTimeout(() => controller.abort(), TXLOG_PROBE_TIMEOUT_MS);
430
+ try {
431
+ await this.http.request("GET", "/api/v1/TransactionLogEntries?$top=1", undefined, { signal: controller.signal });
432
+ }
433
+ catch (err) {
434
+ // Our own probe timeout aborts via the controller and yields the friendly
435
+ // preflight message. For every other error, systemic transport/auth
436
+ // failures (CONNECTION_FAILED, AUTH_FAILED, LOCK_TIMEOUT) and unexpected
437
+ // non-TM1 throws must propagate unmasked, and a permission denial stays
438
+ // actionable (fail fast); only then do we wrap as a TM1_ERROR preflight.
439
+ if (!controller.signal.aborted) {
440
+ rethrowIfSystemicOrDenied(err);
441
+ }
442
+ throw new TM1Error({
443
+ code: TM1ErrorCode.TM1_ERROR,
444
+ message: `Transaction log preflight failed (timeout ${TXLOG_PROBE_TIMEOUT_MS / 1000}s): the endpoint scans the whole log and may hang or be denied without log-read rights.`,
445
+ endpoint: "/api/v1/TransactionLogEntries",
446
+ details: err instanceof Error ? err.message : String(err),
447
+ hint: "Narrow the query with `since`, `cubeName`, or `user`, or verify the account has transaction-log read rights.",
448
+ });
449
+ }
450
+ finally {
451
+ clearTimeout(timer);
452
+ }
453
+ }
454
+ /**
455
+ * List TI process error log files.
456
+ *
457
+ * TM1 v11 OData exposes only `Filename` on this entity set (no LastUpdated /
458
+ * $select / $orderby support). Sorting is filename-descending — filenames
459
+ * embed a yyyymmddhhmmss timestamp, so lexical desc sort matches
460
+ * chronological newest-first. Filters (processName, since, top) are applied
461
+ * client-side.
462
+ */
463
+ async listErrorLogFiles(opts = {}) {
464
+ const top = opts.top ?? 50;
465
+ const response = await this.http.request("GET", "/api/v1/ErrorLogFiles");
466
+ let entries = response.value
467
+ .map((e) => ({ filename: e.Filename ?? "" }))
468
+ .filter((e) => e.filename);
469
+ if (opts.processName) {
470
+ const proc = opts.processName.toLowerCase();
471
+ // TM1 v11+ pattern with session hash: TM1ProcessError_<ts>_<id>_<proc>_<hash>.log
472
+ // TM1 pattern without hash: TM1ProcessError_<ts>_<id>_<proc>.log
473
+ // Legacy/manual pattern: <proc>_<ts>.log
474
+ entries = entries.filter((e) => {
475
+ const f = e.filename.toLowerCase();
476
+ return (f === proc ||
477
+ f.startsWith(`${proc}_`) ||
478
+ f.endsWith(`_${proc}.log`) ||
479
+ f.includes(`_${proc}_`));
480
+ });
481
+ }
482
+ if (opts.since) {
483
+ const sinceCompact = opts.since.replace(/[^0-9]/g, "").slice(0, 14);
484
+ if (sinceCompact.length >= 8) {
485
+ entries = entries.filter((e) => {
486
+ const m = e.filename.match(/(?:TM1ProcessError_|_)(\d{14})/) ??
487
+ e.filename.match(/_(\d{8,14})\.log$/i);
488
+ return m ? m[1] >= sinceCompact.slice(0, m[1].length) : true;
489
+ });
490
+ }
491
+ }
492
+ entries.sort((a, b) => a.filename < b.filename ? 1 : a.filename > b.filename ? -1 : 0);
493
+ return entries.slice(0, top);
494
+ }
495
+ /**
496
+ * Fetch the raw text content of a single TI error log file.
497
+ * GET /api/v1/ErrorLogFiles('<filename>')/Content
498
+ */
499
+ async getErrorLogContent(filename) {
500
+ const path = `/api/v1/ErrorLogFiles('${encKey(filename)}')/Content`;
501
+ return await this.http.requestRaw("GET", path);
502
+ }
503
+ }
504
+ //# sourceMappingURL=server-service.js.map
@@ -0,0 +1,37 @@
1
+ import type { Subset, SubsetCreate } from "../../types.js";
2
+ import type { TM1HttpClient } from "../http.js";
3
+ export declare class SubsetService {
4
+ private readonly http;
5
+ constructor(http: TM1HttpClient);
6
+ /**
7
+ * List public + private subsets of a hierarchy.
8
+ * GET /api/v1/Dimensions('{d}')/Hierarchies('{h}')/Subsets|PrivateSubsets
9
+ */
10
+ list(dimensionName: string, hierarchyName: string): Promise<Subset[]>;
11
+ /**
12
+ * Get a single subset incl. resolved Elements.
13
+ * GET /api/v1/Dimensions('{d}')/Hierarchies('{h}')/Subsets('{s}')?$expand=Elements($select=Name)
14
+ */
15
+ get(dimensionName: string, hierarchyName: string, subsetName: string, isPrivate?: boolean): Promise<Subset>;
16
+ /**
17
+ * Create a public subset. Either MDX-based (expression) or static
18
+ * (elements). Mixed/empty inputs throw VALIDATION_ERROR.
19
+ * POST /api/v1/Dimensions('{d}')/Hierarchies('{h}')/Subsets
20
+ */
21
+ create(dimensionName: string, hierarchyName: string, subset: SubsetCreate): Promise<void>;
22
+ /**
23
+ * Update an existing public subset.
24
+ * PATCH /api/v1/Dimensions('{d}')/Hierarchies('{h}')/Subsets('{s}')
25
+ */
26
+ update(dimensionName: string, hierarchyName: string, subsetName: string, update: {
27
+ expression?: string | undefined;
28
+ elements?: string[] | undefined;
29
+ alias?: string | undefined;
30
+ }): Promise<void>;
31
+ /**
32
+ * Delete a public subset.
33
+ * DELETE /api/v1/Dimensions('{d}')/Hierarchies('{h}')/Subsets('{s}')
34
+ */
35
+ delete(dimensionName: string, hierarchyName: string, subsetName: string): Promise<void>;
36
+ }
37
+ //# sourceMappingURL=subset-service.d.ts.map
@@ -0,0 +1,122 @@
1
+ // Subset domain service. Owns the OData calls under
2
+ // /api/v1/Dimensions('{d}')/Hierarchies('{h}')/{Subsets|PrivateSubsets} —
3
+ // list, get, create, update, delete. Subsets are either MDX-based
4
+ // (Expression) or static (Elements list); both shapes are handled here.
5
+ //
6
+ // See docs/ARCHITECTURE.md for the layering.
7
+ import { TM1Error, TM1ErrorCode } from "../../types.js";
8
+ import { rethrowIfSystemic } from "./fallback.js";
9
+ // OData key encoder: double ' per OData literal rules, then percent-encode.
10
+ const enc = (s) => encodeURIComponent(String(s).replace(/'/g, "''"));
11
+ export class SubsetService {
12
+ http;
13
+ constructor(http) {
14
+ this.http = http;
15
+ }
16
+ /**
17
+ * List public + private subsets of a hierarchy.
18
+ * GET /api/v1/Dimensions('{d}')/Hierarchies('{h}')/Subsets|PrivateSubsets
19
+ */
20
+ async list(dimensionName, hierarchyName) {
21
+ const result = [];
22
+ const fetchScope = async (segment, isPrivate) => {
23
+ try {
24
+ const path = `/api/v1/Dimensions('${enc(dimensionName)}')/Hierarchies('${enc(hierarchyName)}')/${segment}?$select=Name,Expression,Alias`;
25
+ const response = await this.http.request("GET", path);
26
+ for (const s of response.value) {
27
+ result.push({
28
+ name: s.Name,
29
+ dimensionName,
30
+ hierarchyName,
31
+ private: isPrivate,
32
+ expression: s.Expression || undefined,
33
+ elements: [],
34
+ alias: s.Alias || undefined,
35
+ });
36
+ }
37
+ }
38
+ catch (e) {
39
+ rethrowIfSystemic(e);
40
+ // scope may not exist
41
+ }
42
+ };
43
+ await fetchScope("Subsets", false);
44
+ await fetchScope("PrivateSubsets", true);
45
+ return result;
46
+ }
47
+ /**
48
+ * Get a single subset incl. resolved Elements.
49
+ * GET /api/v1/Dimensions('{d}')/Hierarchies('{h}')/Subsets('{s}')?$expand=Elements($select=Name)
50
+ */
51
+ async get(dimensionName, hierarchyName, subsetName, isPrivate = false) {
52
+ const segment = isPrivate ? "PrivateSubsets" : "Subsets";
53
+ const path = `/api/v1/Dimensions('${enc(dimensionName)}')/Hierarchies('${enc(hierarchyName)}')/${segment}('${enc(subsetName)}')?$expand=Elements($select=Name)&$select=Name,Expression,Alias`;
54
+ const response = await this.http.request("GET", path);
55
+ return {
56
+ name: response.Name,
57
+ dimensionName,
58
+ hierarchyName,
59
+ private: isPrivate,
60
+ expression: response.Expression || undefined,
61
+ elements: (response.Elements ?? []).map((e) => e.Name),
62
+ alias: response.Alias || undefined,
63
+ };
64
+ }
65
+ /**
66
+ * Create a public subset. Either MDX-based (expression) or static
67
+ * (elements). Mixed/empty inputs throw VALIDATION_ERROR.
68
+ * POST /api/v1/Dimensions('{d}')/Hierarchies('{h}')/Subsets
69
+ */
70
+ async create(dimensionName, hierarchyName, subset) {
71
+ const path = `/api/v1/Dimensions('${enc(dimensionName)}')/Hierarchies('${enc(hierarchyName)}')/Subsets`;
72
+ if (subset.expression && subset.elements && subset.elements.length > 0) {
73
+ throw new TM1Error({
74
+ code: TM1ErrorCode.VALIDATION_ERROR,
75
+ message: "Subset must be either MDX-based (expression) OR static (elements), not both.",
76
+ });
77
+ }
78
+ if (!subset.expression &&
79
+ (!subset.elements || subset.elements.length === 0)) {
80
+ throw new TM1Error({
81
+ code: TM1ErrorCode.VALIDATION_ERROR,
82
+ message: "Subset requires either expression (MDX) or non-empty elements list.",
83
+ });
84
+ }
85
+ const body = { Name: subset.name };
86
+ if (subset.alias)
87
+ body.Alias = subset.alias;
88
+ if (subset.expression) {
89
+ body.Expression = subset.expression;
90
+ }
91
+ else {
92
+ body["Elements@odata.bind"] = subset.elements.map((e) => `Dimensions('${enc(dimensionName)}')/Hierarchies('${enc(hierarchyName)}')/Elements('${enc(e)}')`);
93
+ }
94
+ await this.http.request("POST", path, body);
95
+ }
96
+ /**
97
+ * Update an existing public subset.
98
+ * PATCH /api/v1/Dimensions('{d}')/Hierarchies('{h}')/Subsets('{s}')
99
+ */
100
+ async update(dimensionName, hierarchyName, subsetName, update) {
101
+ const path = `/api/v1/Dimensions('${enc(dimensionName)}')/Hierarchies('${enc(hierarchyName)}')/Subsets('${enc(subsetName)}')`;
102
+ const body = {};
103
+ if (update.alias !== undefined)
104
+ body.Alias = update.alias;
105
+ if (update.expression !== undefined) {
106
+ body.Expression = update.expression;
107
+ }
108
+ else if (update.elements !== undefined) {
109
+ body.Expression = "";
110
+ body["Elements@odata.bind"] = update.elements.map((e) => `Dimensions('${enc(dimensionName)}')/Hierarchies('${enc(hierarchyName)}')/Elements('${enc(e)}')`);
111
+ }
112
+ await this.http.request("PATCH", path, body);
113
+ }
114
+ /**
115
+ * Delete a public subset.
116
+ * DELETE /api/v1/Dimensions('{d}')/Hierarchies('{h}')/Subsets('{s}')
117
+ */
118
+ async delete(dimensionName, hierarchyName, subsetName) {
119
+ await this.http.request("DELETE", `/api/v1/Dimensions('${enc(dimensionName)}')/Hierarchies('${enc(hierarchyName)}')/Subsets('${enc(subsetName)}')`);
120
+ }
121
+ }
122
+ //# sourceMappingURL=subset-service.js.map