@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.
- package/CHANGELOG.md +1211 -0
- package/LICENSE +21 -0
- package/NOTICE +34 -0
- package/README.md +276 -0
- package/dist/config.d.ts +35 -0
- package/dist/config.js +238 -0
- package/dist/http-transport.d.ts +8 -0
- package/dist/http-transport.js +132 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +164 -0
- package/dist/lib/callgraph/callGraph.d.ts +124 -0
- package/dist/lib/callgraph/callGraph.js +334 -0
- package/dist/lib/callgraph/choreGraph.d.ts +23 -0
- package/dist/lib/callgraph/choreGraph.js +102 -0
- package/dist/lib/callgraph/dataFlow.d.ts +74 -0
- package/dist/lib/callgraph/dataFlow.js +271 -0
- package/dist/lib/callgraph/datasourceMembership.d.ts +31 -0
- package/dist/lib/callgraph/datasourceMembership.js +142 -0
- package/dist/lib/callgraph/lintTypes.d.ts +28 -0
- package/dist/lib/callgraph/lintTypes.js +2 -0
- package/dist/lib/callgraph/mdxMembers.d.ts +29 -0
- package/dist/lib/callgraph/mdxMembers.js +97 -0
- package/dist/lib/callgraph/referenceIndex.d.ts +179 -0
- package/dist/lib/callgraph/referenceIndex.js +584 -0
- package/dist/lib/callgraph/rulesLinter.d.ts +55 -0
- package/dist/lib/callgraph/rulesLinter.js +776 -0
- package/dist/lib/callgraph/rulesParser.d.ts +26 -0
- package/dist/lib/callgraph/rulesParser.js +71 -0
- package/dist/lib/callgraph/subsetUsage.d.ts +16 -0
- package/dist/lib/callgraph/subsetUsage.js +134 -0
- package/dist/lib/callgraph/tiParser.d.ts +21 -0
- package/dist/lib/callgraph/tiParser.js +672 -0
- package/dist/lib/callgraph/tiSignatures.d.ts +32 -0
- package/dist/lib/callgraph/tiSignatures.js +6185 -0
- package/dist/lib/callgraph/tm1-adapter.d.ts +32 -0
- package/dist/lib/callgraph/tm1-adapter.js +159 -0
- package/dist/lib/callgraph/types.d.ts +53 -0
- package/dist/lib/callgraph/types.js +2 -0
- package/dist/lib/callgraph/variableEnv.d.ts +86 -0
- package/dist/lib/callgraph/variableEnv.js +214 -0
- package/dist/lib/cell-address.d.ts +12 -0
- package/dist/lib/cell-address.js +71 -0
- package/dist/lib/complexity/antipatterns.d.ts +22 -0
- package/dist/lib/complexity/antipatterns.js +302 -0
- package/dist/lib/complexity/comment-classifier.d.ts +24 -0
- package/dist/lib/complexity/comment-classifier.js +43 -0
- package/dist/lib/complexity/cross-process.d.ts +78 -0
- package/dist/lib/complexity/cross-process.js +114 -0
- package/dist/lib/complexity/process-metrics.d.ts +78 -0
- package/dist/lib/complexity/process-metrics.js +278 -0
- package/dist/lib/complexity/rules-metrics.d.ts +31 -0
- package/dist/lib/complexity/rules-metrics.js +99 -0
- package/dist/lib/concurrency.d.ts +11 -0
- package/dist/lib/concurrency.js +27 -0
- package/dist/lib/control-name.d.ts +10 -0
- package/dist/lib/control-name.js +10 -0
- package/dist/lib/coordinate-error.d.ts +3 -0
- package/dist/lib/coordinate-error.js +29 -0
- package/dist/lib/credential-format.d.ts +23 -0
- package/dist/lib/credential-format.js +25 -0
- package/dist/lib/cube-stats/fetcher.d.ts +106 -0
- package/dist/lib/cube-stats/fetcher.js +194 -0
- package/dist/lib/feeders/brackets.d.ts +47 -0
- package/dist/lib/feeders/brackets.js +195 -0
- package/dist/lib/feeders/element-type-cache.d.ts +42 -0
- package/dist/lib/feeders/element-type-cache.js +86 -0
- package/dist/lib/feeders/static-heuristics.d.ts +101 -0
- package/dist/lib/feeders/static-heuristics.js +202 -0
- package/dist/lib/git-process.d.ts +67 -0
- package/dist/lib/git-process.js +243 -0
- package/dist/lib/mask-secrets.d.ts +10 -0
- package/dist/lib/mask-secrets.js +99 -0
- package/dist/lib/mdx.d.ts +3 -0
- package/dist/lib/mdx.js +13 -0
- package/dist/lib/naming/odata-filter.d.ts +15 -0
- package/dist/lib/naming/odata-filter.js +81 -0
- package/dist/lib/naming/rules.d.ts +34 -0
- package/dist/lib/naming/rules.js +215 -0
- package/dist/lib/pro-parser.d.ts +19 -0
- package/dist/lib/pro-parser.js +260 -0
- package/dist/lib/pro-serializer.d.ts +19 -0
- package/dist/lib/pro-serializer.js +170 -0
- package/dist/lib/process-parts-schema.d.ts +45 -0
- package/dist/lib/process-parts-schema.js +46 -0
- package/dist/lib/process-refs.d.ts +88 -0
- package/dist/lib/process-refs.js +441 -0
- package/dist/lib/rules-outline.d.ts +29 -0
- package/dist/lib/rules-outline.js +68 -0
- package/dist/lib/rules-patch.d.ts +6 -0
- package/dist/lib/rules-patch.js +59 -0
- package/dist/lib/safe-regex.d.ts +15 -0
- package/dist/lib/safe-regex.js +37 -0
- package/dist/lib/sample-cells.d.ts +48 -0
- package/dist/lib/sample-cells.js +146 -0
- package/dist/lib/slim-json-schema.d.ts +20 -0
- package/dist/lib/slim-json-schema.js +68 -0
- package/dist/lib/strip-comments.d.ts +23 -0
- package/dist/lib/strip-comments.js +61 -0
- package/dist/lib/tm1-events.d.ts +16 -0
- package/dist/lib/tm1-events.js +29 -0
- package/dist/lib/v12-compat/deprecated-ti.d.ts +17 -0
- package/dist/lib/v12-compat/deprecated-ti.js +257 -0
- package/dist/lib/v12-compat/scanner.d.ts +10 -0
- package/dist/lib/v12-compat/scanner.js +43 -0
- package/dist/lib/variables-ui-data.d.ts +26 -0
- package/dist/lib/variables-ui-data.js +77 -0
- package/dist/load-env.d.ts +2 -0
- package/dist/load-env.js +29 -0
- package/dist/logger.d.ts +4 -0
- package/dist/logger.js +60 -0
- package/dist/prompts/index.d.ts +3 -0
- package/dist/prompts/index.js +141 -0
- package/dist/resources/index.d.ts +5 -0
- package/dist/resources/index.js +237 -0
- package/dist/resources/list-handler.d.ts +40 -0
- package/dist/resources/list-handler.js +86 -0
- package/dist/resources/subscriptions.d.ts +19 -0
- package/dist/resources/subscriptions.js +80 -0
- package/dist/schemas/cells.d.ts +17 -0
- package/dist/schemas/cells.js +13 -0
- package/dist/schemas/common.d.ts +16 -0
- package/dist/schemas/common.js +14 -0
- package/dist/schemas/index.d.ts +10 -0
- package/dist/schemas/index.js +23 -0
- package/dist/schemas/metadata.d.ts +70 -0
- package/dist/schemas/metadata.js +47 -0
- package/dist/schemas/monitoring.d.ts +95 -0
- package/dist/schemas/monitoring.js +69 -0
- package/dist/schemas/processes.d.ts +74 -0
- package/dist/schemas/processes.js +66 -0
- package/dist/schemas/scheduling.d.ts +13 -0
- package/dist/schemas/scheduling.js +13 -0
- package/dist/schemas/security.d.ts +19 -0
- package/dist/schemas/security.js +16 -0
- package/dist/schemas/subsets.d.ts +12 -0
- package/dist/schemas/subsets.js +12 -0
- package/dist/schemas/views.d.ts +9 -0
- package/dist/schemas/views.js +9 -0
- package/dist/session-manager.d.ts +79 -0
- package/dist/session-manager.js +281 -0
- package/dist/tm1-client/connection/profile.d.ts +13 -0
- package/dist/tm1-client/connection/profile.js +99 -0
- package/dist/tm1-client/dispatcher.d.ts +5 -0
- package/dist/tm1-client/dispatcher.js +31 -0
- package/dist/tm1-client/http.d.ts +81 -0
- package/dist/tm1-client/http.js +547 -0
- package/dist/tm1-client/services/batch-service.d.ts +123 -0
- package/dist/tm1-client/services/batch-service.js +455 -0
- package/dist/tm1-client/services/cell-service.d.ts +71 -0
- package/dist/tm1-client/services/cell-service.js +333 -0
- package/dist/tm1-client/services/cellset-transform.d.ts +26 -0
- package/dist/tm1-client/services/cellset-transform.js +80 -0
- package/dist/tm1-client/services/chore-service.d.ts +68 -0
- package/dist/tm1-client/services/chore-service.js +179 -0
- package/dist/tm1-client/services/chore-status.d.ts +11 -0
- package/dist/tm1-client/services/chore-status.js +127 -0
- package/dist/tm1-client/services/cube-service.d.ts +134 -0
- package/dist/tm1-client/services/cube-service.js +294 -0
- package/dist/tm1-client/services/dimension-service.d.ts +118 -0
- package/dist/tm1-client/services/dimension-service.js +249 -0
- package/dist/tm1-client/services/element-service.d.ts +245 -0
- package/dist/tm1-client/services/element-service.js +809 -0
- package/dist/tm1-client/services/fallback.d.ts +44 -0
- package/dist/tm1-client/services/fallback.js +72 -0
- package/dist/tm1-client/services/file-service.d.ts +53 -0
- package/dist/tm1-client/services/file-service.js +218 -0
- package/dist/tm1-client/services/hierarchy-service.d.ts +129 -0
- package/dist/tm1-client/services/hierarchy-service.js +332 -0
- package/dist/tm1-client/services/monitoring-service.d.ts +34 -0
- package/dist/tm1-client/services/monitoring-service.js +123 -0
- package/dist/tm1-client/services/odata-page.d.ts +71 -0
- package/dist/tm1-client/services/odata-page.js +87 -0
- package/dist/tm1-client/services/process-service.d.ts +278 -0
- package/dist/tm1-client/services/process-service.js +874 -0
- package/dist/tm1-client/services/process-status.d.ts +21 -0
- package/dist/tm1-client/services/process-status.js +89 -0
- package/dist/tm1-client/services/security-service.d.ts +50 -0
- package/dist/tm1-client/services/security-service.js +93 -0
- package/dist/tm1-client/services/server-service.d.ts +116 -0
- package/dist/tm1-client/services/server-service.js +504 -0
- package/dist/tm1-client/services/subset-service.d.ts +37 -0
- package/dist/tm1-client/services/subset-service.js +122 -0
- package/dist/tm1-client/services/view-service.d.ts +46 -0
- package/dist/tm1-client/services/view-service.js +287 -0
- package/dist/tm1-client.d.ts +56 -0
- package/dist/tm1-client.js +126 -0
- package/dist/tools/analysis/analyze-callgraph.d.ts +28 -0
- package/dist/tools/analysis/analyze-callgraph.js +350 -0
- package/dist/tools/analysis/analyze-chore-graph.d.ts +2 -0
- package/dist/tools/analysis/analyze-chore-graph.js +148 -0
- package/dist/tools/analysis/analyze-object-usage.d.ts +2 -0
- package/dist/tools/analysis/analyze-object-usage.js +143 -0
- package/dist/tools/analysis/audit-complexity.d.ts +2 -0
- package/dist/tools/analysis/audit-complexity.js +255 -0
- package/dist/tools/analysis/audit-feeders.d.ts +2 -0
- package/dist/tools/analysis/audit-feeders.js +417 -0
- package/dist/tools/analysis/audit-naming.d.ts +2 -0
- package/dist/tools/analysis/audit-naming.js +379 -0
- package/dist/tools/analysis/check-v12-readiness.d.ts +2 -0
- package/dist/tools/analysis/check-v12-readiness.js +136 -0
- package/dist/tools/analysis/find-orphan-dimensions.d.ts +2 -0
- package/dist/tools/analysis/find-orphan-dimensions.js +55 -0
- package/dist/tools/analysis/invalidate-callgraph-cache.d.ts +2 -0
- package/dist/tools/analysis/invalidate-callgraph-cache.js +40 -0
- package/dist/tools/analysis/trace-data-flow.d.ts +2 -0
- package/dist/tools/analysis/trace-data-flow.js +138 -0
- package/dist/tools/annotations.d.ts +12 -0
- package/dist/tools/annotations.js +61 -0
- package/dist/tools/celldata/check-feeders.d.ts +2 -0
- package/dist/tools/celldata/check-feeders.js +48 -0
- package/dist/tools/celldata/check-writable-coords.d.ts +2 -0
- package/dist/tools/celldata/check-writable-coords.js +126 -0
- package/dist/tools/celldata/execute-mdx.d.ts +17 -0
- package/dist/tools/celldata/execute-mdx.js +126 -0
- package/dist/tools/celldata/get-cell-value.d.ts +2 -0
- package/dist/tools/celldata/get-cell-value.js +30 -0
- package/dist/tools/celldata/get-view-definition.d.ts +2 -0
- package/dist/tools/celldata/get-view-definition.js +29 -0
- package/dist/tools/celldata/get-view.d.ts +2 -0
- package/dist/tools/celldata/get-view.js +55 -0
- package/dist/tools/celldata/sample-cells.d.ts +2 -0
- package/dist/tools/celldata/sample-cells.js +101 -0
- package/dist/tools/celldata/trace-cell-calculation.d.ts +2 -0
- package/dist/tools/celldata/trace-cell-calculation.js +53 -0
- package/dist/tools/celldata/trace-feeders.d.ts +2 -0
- package/dist/tools/celldata/trace-feeders.js +44 -0
- package/dist/tools/celldata/write-cells.d.ts +2 -0
- package/dist/tools/celldata/write-cells.js +65 -0
- package/dist/tools/confirm.d.ts +10 -0
- package/dist/tools/confirm.js +64 -0
- package/dist/tools/define-tool.d.ts +51 -0
- package/dist/tools/define-tool.js +49 -0
- package/dist/tools/dimension-management/bulk-upsert-elements.d.ts +2 -0
- package/dist/tools/dimension-management/bulk-upsert-elements.js +103 -0
- package/dist/tools/dimension-management/create-dimension.d.ts +2 -0
- package/dist/tools/dimension-management/create-dimension.js +22 -0
- package/dist/tools/dimension-management/create-element-attribute.d.ts +2 -0
- package/dist/tools/dimension-management/create-element-attribute.js +26 -0
- package/dist/tools/dimension-management/create-element.d.ts +2 -0
- package/dist/tools/dimension-management/create-element.js +31 -0
- package/dist/tools/dimension-management/create-hierarchy.d.ts +2 -0
- package/dist/tools/dimension-management/create-hierarchy.js +22 -0
- package/dist/tools/dimension-management/delete-dimension.d.ts +2 -0
- package/dist/tools/dimension-management/delete-dimension.js +25 -0
- package/dist/tools/dimension-management/delete-element.d.ts +2 -0
- package/dist/tools/dimension-management/delete-element.js +26 -0
- package/dist/tools/dimension-management/delete-elements.d.ts +2 -0
- package/dist/tools/dimension-management/delete-elements.js +44 -0
- package/dist/tools/dimension-management/delete-hierarchy.d.ts +2 -0
- package/dist/tools/dimension-management/delete-hierarchy.js +35 -0
- package/dist/tools/dimension-management/get-element-attribute-values.d.ts +2 -0
- package/dist/tools/dimension-management/get-element-attribute-values.js +77 -0
- package/dist/tools/dimension-management/list-element-attributes.d.ts +2 -0
- package/dist/tools/dimension-management/list-element-attributes.js +31 -0
- package/dist/tools/dimension-management/move-element.d.ts +2 -0
- package/dist/tools/dimension-management/move-element.js +28 -0
- package/dist/tools/dimension-management/update-element-attribute-value.d.ts +2 -0
- package/dist/tools/dimension-management/update-element-attribute-value.js +80 -0
- package/dist/tools/dimension-management/update-element.d.ts +2 -0
- package/dist/tools/dimension-management/update-element.js +35 -0
- package/dist/tools/error-format.d.ts +22 -0
- package/dist/tools/error-format.js +130 -0
- package/dist/tools/fileops/delete-file.d.ts +2 -0
- package/dist/tools/fileops/delete-file.js +32 -0
- package/dist/tools/fileops/get-file-content.d.ts +2 -0
- package/dist/tools/fileops/get-file-content.js +76 -0
- package/dist/tools/fileops/list-files.d.ts +2 -0
- package/dist/tools/fileops/list-files.js +43 -0
- package/dist/tools/fileops/search-files.d.ts +2 -0
- package/dist/tools/fileops/search-files.js +76 -0
- package/dist/tools/fileops/upload-file.d.ts +2 -0
- package/dist/tools/fileops/upload-file.js +69 -0
- package/dist/tools/format.d.ts +57 -0
- package/dist/tools/format.js +157 -0
- package/dist/tools/hierarchy.d.ts +6 -0
- package/dist/tools/hierarchy.js +27 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.js +263 -0
- package/dist/tools/local-file.d.ts +16 -0
- package/dist/tools/local-file.js +88 -0
- package/dist/tools/metadata/get-ancestors.d.ts +2 -0
- package/dist/tools/metadata/get-ancestors.js +36 -0
- package/dist/tools/metadata/get-descendants.d.ts +2 -0
- package/dist/tools/metadata/get-descendants.js +64 -0
- package/dist/tools/metadata/get-hierarchy.d.ts +2 -0
- package/dist/tools/metadata/get-hierarchy.js +130 -0
- package/dist/tools/metadata/list-chores.d.ts +2 -0
- package/dist/tools/metadata/list-chores.js +62 -0
- package/dist/tools/metadata/list-cubes.d.ts +2 -0
- package/dist/tools/metadata/list-cubes.js +128 -0
- package/dist/tools/metadata/list-dimensions.d.ts +2 -0
- package/dist/tools/metadata/list-dimensions.js +131 -0
- package/dist/tools/metadata/list-processes-grouped.d.ts +2 -0
- package/dist/tools/metadata/list-processes-grouped.js +96 -0
- package/dist/tools/metadata/list-processes.d.ts +2 -0
- package/dist/tools/metadata/list-processes.js +108 -0
- package/dist/tools/metadata/resolve-default-members.d.ts +2 -0
- package/dist/tools/metadata/resolve-default-members.js +46 -0
- package/dist/tools/model-building/check-cube-rule.d.ts +2 -0
- package/dist/tools/model-building/check-cube-rule.js +51 -0
- package/dist/tools/model-building/clear-cube.d.ts +2 -0
- package/dist/tools/model-building/clear-cube.js +46 -0
- package/dist/tools/model-building/create-cube.d.ts +2 -0
- package/dist/tools/model-building/create-cube.js +34 -0
- package/dist/tools/model-building/delete-cube.d.ts +2 -0
- package/dist/tools/model-building/delete-cube.js +27 -0
- package/dist/tools/model-building/get-all-cube-rules.d.ts +2 -0
- package/dist/tools/model-building/get-all-cube-rules.js +149 -0
- package/dist/tools/model-building/get-cube-rules.d.ts +2 -0
- package/dist/tools/model-building/get-cube-rules.js +69 -0
- package/dist/tools/model-building/rules-source.d.ts +21 -0
- package/dist/tools/model-building/rules-source.js +49 -0
- package/dist/tools/model-building/search-rules.d.ts +2 -0
- package/dist/tools/model-building/search-rules.js +132 -0
- package/dist/tools/model-building/set-cube-rules.d.ts +2 -0
- package/dist/tools/model-building/set-cube-rules.js +81 -0
- package/dist/tools/model-building/unload-cube.d.ts +2 -0
- package/dist/tools/model-building/unload-cube.js +23 -0
- package/dist/tools/operations/diagnose-process-error.d.ts +2 -0
- package/dist/tools/operations/diagnose-process-error.js +178 -0
- package/dist/tools/operations/error-log-helpers.d.ts +25 -0
- package/dist/tools/operations/error-log-helpers.js +57 -0
- package/dist/tools/operations/get-audit-log.d.ts +2 -0
- package/dist/tools/operations/get-audit-log.js +70 -0
- package/dist/tools/operations/get-cube-stats.d.ts +2 -0
- package/dist/tools/operations/get-cube-stats.js +107 -0
- package/dist/tools/operations/get-error-log-content.d.ts +2 -0
- package/dist/tools/operations/get-error-log-content.js +164 -0
- package/dist/tools/operations/get-jobs.d.ts +3 -0
- package/dist/tools/operations/get-jobs.js +51 -0
- package/dist/tools/operations/get-message-log.d.ts +2 -0
- package/dist/tools/operations/get-message-log.js +63 -0
- package/dist/tools/operations/get-server-info.d.ts +2 -0
- package/dist/tools/operations/get-server-info.js +180 -0
- package/dist/tools/operations/get-server-state.d.ts +2 -0
- package/dist/tools/operations/get-server-state.js +129 -0
- package/dist/tools/operations/get-sessions.d.ts +2 -0
- package/dist/tools/operations/get-sessions.js +76 -0
- package/dist/tools/operations/get-threads.d.ts +3 -0
- package/dist/tools/operations/get-threads.js +50 -0
- package/dist/tools/operations/get-transaction-log.d.ts +2 -0
- package/dist/tools/operations/get-transaction-log.js +63 -0
- package/dist/tools/operations/list-error-logs.d.ts +8 -0
- package/dist/tools/operations/list-error-logs.js +157 -0
- package/dist/tools/operations/save-data.d.ts +2 -0
- package/dist/tools/operations/save-data.js +50 -0
- package/dist/tools/pagination.d.ts +32 -0
- package/dist/tools/pagination.js +116 -0
- package/dist/tools/scheduling/create-chore.d.ts +2 -0
- package/dist/tools/scheduling/create-chore.js +93 -0
- package/dist/tools/scheduling/delete-chore.d.ts +2 -0
- package/dist/tools/scheduling/delete-chore.js +22 -0
- package/dist/tools/scheduling/execute-chore.d.ts +2 -0
- package/dist/tools/scheduling/execute-chore.js +52 -0
- package/dist/tools/scheduling/toggle-chore.d.ts +2 -0
- package/dist/tools/scheduling/toggle-chore.js +22 -0
- package/dist/tools/scheduling/update-chore.d.ts +2 -0
- package/dist/tools/scheduling/update-chore.js +71 -0
- package/dist/tools/schemas/common.d.ts +10 -0
- package/dist/tools/schemas/common.js +23 -0
- package/dist/tools/schemas/items-analysis.d.ts +394 -0
- package/dist/tools/schemas/items-analysis.js +419 -0
- package/dist/tools/schemas/items-cells.d.ts +70 -0
- package/dist/tools/schemas/items-cells.js +65 -0
- package/dist/tools/schemas/items-common.d.ts +18 -0
- package/dist/tools/schemas/items-common.js +39 -0
- package/dist/tools/schemas/items-fileops.d.ts +11 -0
- package/dist/tools/schemas/items-fileops.js +13 -0
- package/dist/tools/schemas/items-metadata.d.ts +262 -0
- package/dist/tools/schemas/items-metadata.js +184 -0
- package/dist/tools/schemas/items-monitoring.d.ts +79 -0
- package/dist/tools/schemas/items-monitoring.js +78 -0
- package/dist/tools/schemas/items-processes.d.ts +279 -0
- package/dist/tools/schemas/items-processes.js +235 -0
- package/dist/tools/schemas/items-scheduling.d.ts +25 -0
- package/dist/tools/schemas/items-scheduling.js +26 -0
- package/dist/tools/schemas/items-security.d.ts +19 -0
- package/dist/tools/schemas/items-security.js +12 -0
- package/dist/tools/schemas/items-subsets.d.ts +2 -0
- package/dist/tools/schemas/items-subsets.js +4 -0
- package/dist/tools/schemas/items-views.d.ts +38 -0
- package/dist/tools/schemas/items-views.js +26 -0
- package/dist/tools/schemas/items.d.ts +12 -0
- package/dist/tools/schemas/items.js +23 -0
- package/dist/tools/schemas/markdown-capable.d.ts +21 -0
- package/dist/tools/schemas/markdown-capable.js +58 -0
- package/dist/tools/schemas/output-schema.d.ts +24 -0
- package/dist/tools/schemas/output-schema.js +25 -0
- package/dist/tools/security/assign-client-group.d.ts +2 -0
- package/dist/tools/security/assign-client-group.js +20 -0
- package/dist/tools/security/create-client.d.ts +2 -0
- package/dist/tools/security/create-client.js +28 -0
- package/dist/tools/security/delete-client.d.ts +2 -0
- package/dist/tools/security/delete-client.js +22 -0
- package/dist/tools/security/get-client.d.ts +2 -0
- package/dist/tools/security/get-client.js +20 -0
- package/dist/tools/security/list-clients.d.ts +2 -0
- package/dist/tools/security/list-clients.js +86 -0
- package/dist/tools/security/list-groups.d.ts +2 -0
- package/dist/tools/security/list-groups.js +43 -0
- package/dist/tools/security/remove-client-group.d.ts +2 -0
- package/dist/tools/security/remove-client-group.js +27 -0
- package/dist/tools/security/update-client.d.ts +2 -0
- package/dist/tools/security/update-client.js +22 -0
- package/dist/tools/subsets/create-subset.d.ts +2 -0
- package/dist/tools/subsets/create-subset.js +44 -0
- package/dist/tools/subsets/delete-subset.d.ts +2 -0
- package/dist/tools/subsets/delete-subset.js +26 -0
- package/dist/tools/subsets/get-subset.d.ts +2 -0
- package/dist/tools/subsets/get-subset.js +29 -0
- package/dist/tools/subsets/list-subsets.d.ts +2 -0
- package/dist/tools/subsets/list-subsets.js +36 -0
- package/dist/tools/subsets/update-subset.d.ts +2 -0
- package/dist/tools/subsets/update-subset.js +33 -0
- package/dist/tools/ti-development/check-process-code.d.ts +2 -0
- package/dist/tools/ti-development/check-process-code.js +96 -0
- package/dist/tools/ti-development/compile-process.d.ts +2 -0
- package/dist/tools/ti-development/compile-process.js +32 -0
- package/dist/tools/ti-development/copy-process.d.ts +2 -0
- package/dist/tools/ti-development/copy-process.js +32 -0
- package/dist/tools/ti-development/delete-process.d.ts +2 -0
- package/dist/tools/ti-development/delete-process.js +26 -0
- package/dist/tools/ti-development/diff-process-with-file.d.ts +2 -0
- package/dist/tools/ti-development/diff-process-with-file.js +208 -0
- package/dist/tools/ti-development/diff-processes.d.ts +2 -0
- package/dist/tools/ti-development/diff-processes.js +312 -0
- package/dist/tools/ti-development/execute-process.d.ts +8 -0
- package/dist/tools/ti-development/execute-process.js +109 -0
- package/dist/tools/ti-development/export-process-to-git.d.ts +2 -0
- package/dist/tools/ti-development/export-process-to-git.js +113 -0
- package/dist/tools/ti-development/export-process-to-pro.d.ts +2 -0
- package/dist/tools/ti-development/export-process-to-pro.js +117 -0
- package/dist/tools/ti-development/get-all-processes-code.d.ts +2 -0
- package/dist/tools/ti-development/get-all-processes-code.js +131 -0
- package/dist/tools/ti-development/get-process-code.d.ts +2 -0
- package/dist/tools/ti-development/get-process-code.js +100 -0
- package/dist/tools/ti-development/get-process-datasource.d.ts +2 -0
- package/dist/tools/ti-development/get-process-datasource.js +20 -0
- package/dist/tools/ti-development/get-process-parameters.d.ts +2 -0
- package/dist/tools/ti-development/get-process-parameters.js +25 -0
- package/dist/tools/ti-development/get-process-variables.d.ts +2 -0
- package/dist/tools/ti-development/get-process-variables.js +38 -0
- package/dist/tools/ti-development/get-process.d.ts +2 -0
- package/dist/tools/ti-development/get-process.js +163 -0
- package/dist/tools/ti-development/import-pro-file.d.ts +2 -0
- package/dist/tools/ti-development/import-pro-file.js +153 -0
- package/dist/tools/ti-development/import-process-from-git.d.ts +2 -0
- package/dist/tools/ti-development/import-process-from-git.js +198 -0
- package/dist/tools/ti-development/install-pro-bundle.d.ts +2 -0
- package/dist/tools/ti-development/install-pro-bundle.js +288 -0
- package/dist/tools/ti-development/preflight.d.ts +39 -0
- package/dist/tools/ti-development/preflight.js +56 -0
- package/dist/tools/ti-development/process-backup.d.ts +29 -0
- package/dist/tools/ti-development/process-backup.js +118 -0
- package/dist/tools/ti-development/search-code.d.ts +2 -0
- package/dist/tools/ti-development/search-code.js +208 -0
- package/dist/tools/ti-development/upsert-process.d.ts +2 -0
- package/dist/tools/ti-development/upsert-process.js +167 -0
- package/dist/tools/ti-development/validate-process-refs.d.ts +2 -0
- package/dist/tools/ti-development/validate-process-refs.js +73 -0
- package/dist/tools/views/create-mdx-view.d.ts +2 -0
- package/dist/tools/views/create-mdx-view.js +21 -0
- package/dist/tools/views/create-native-view.d.ts +2 -0
- package/dist/tools/views/create-native-view.js +81 -0
- package/dist/tools/views/delete-view.d.ts +2 -0
- package/dist/tools/views/delete-view.js +23 -0
- package/dist/tools/views/list-views.d.ts +2 -0
- package/dist/tools/views/list-views.js +32 -0
- package/dist/tools/with-annotations.d.ts +6 -0
- package/dist/tools/with-annotations.js +339 -0
- package/dist/types.d.ts +409 -0
- package/dist/types.js +91 -0
- package/dist/version.d.ts +4 -0
- package/dist/version.js +18 -0
- package/package.json +107 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
// Hierarchy domain service. Owns the OData calls under
|
|
2
|
+
// /api/v1/Dimensions('{d}')/Hierarchies(...) — get, create, delete, plus the
|
|
3
|
+
// derived ancestors/descendants traversals that fetch a hierarchy and walk it
|
|
4
|
+
// client-side. See docs/ARCHITECTURE.md for the layering.
|
|
5
|
+
import { TM1Error, TM1ErrorCode } from "../../types.js";
|
|
6
|
+
import { compileUserRegex } from "../../lib/safe-regex.js";
|
|
7
|
+
import { pageClauseList, readNestedCount } from "./odata-page.js";
|
|
8
|
+
// OData key encoder: double ' per OData literal rules, then percent-encode.
|
|
9
|
+
const enc = (s) => encodeURIComponent(String(s).replace(/'/g, "''"));
|
|
10
|
+
// elementType pushes down as the ORDINAL, not the name: `Type eq
|
|
11
|
+
// 'Consolidated'` is accepted and matches nothing — silently, which is
|
|
12
|
+
// worse than an error and is why this filter used to run client-side.
|
|
13
|
+
// `Type eq 3` works (verified live on 11.8: 1 → Numeric, 2 → String,
|
|
14
|
+
// 3 → Consolidated).
|
|
15
|
+
//
|
|
16
|
+
// Doing it server-side matters more since elements carry their Edges: a
|
|
17
|
+
// client-side type filter means fetching every element of the dimension
|
|
18
|
+
// with its edges attached — measured at 99 MB on a 171k-element dimension,
|
|
19
|
+
// against 300 KB for the pushed-down page.
|
|
20
|
+
//
|
|
21
|
+
// nameRegex stays client-side; OData has no regex.
|
|
22
|
+
const TYPE_ORDINAL = {
|
|
23
|
+
Numeric: 1,
|
|
24
|
+
String: 2,
|
|
25
|
+
Consolidated: 3,
|
|
26
|
+
};
|
|
27
|
+
function elementFilters(opts) {
|
|
28
|
+
const filters = [];
|
|
29
|
+
if (opts?.level !== undefined)
|
|
30
|
+
filters.push(`Level eq ${opts.level}`);
|
|
31
|
+
if (opts?.levelMax !== undefined)
|
|
32
|
+
filters.push(`Level le ${opts.levelMax}`);
|
|
33
|
+
const escapeOdata = (s) => s.replace(/'/g, "''");
|
|
34
|
+
if (opts?.nameContains)
|
|
35
|
+
filters.push(`contains(Name, '${escapeOdata(opts.nameContains)}')`);
|
|
36
|
+
if (opts?.nameStartsWith)
|
|
37
|
+
filters.push(`startswith(Name, '${escapeOdata(opts.nameStartsWith)}')`);
|
|
38
|
+
const typeOrdinal = opts?.elementType && opts.elementType !== "All"
|
|
39
|
+
? TYPE_ORDINAL[opts.elementType]
|
|
40
|
+
: undefined;
|
|
41
|
+
if (typeOrdinal !== undefined)
|
|
42
|
+
filters.push(`Type eq ${typeOrdinal}`);
|
|
43
|
+
const regex = opts?.nameRegex !== undefined
|
|
44
|
+
? compileUserRegex(opts.nameRegex, undefined, "nameRegex")
|
|
45
|
+
: undefined;
|
|
46
|
+
return { filters, regex };
|
|
47
|
+
}
|
|
48
|
+
export class HierarchyService {
|
|
49
|
+
http;
|
|
50
|
+
constructor(http) {
|
|
51
|
+
this.http = http;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get a specific hierarchy with its elements, including parent/child
|
|
55
|
+
* relationships. TM1 11.8 does not expose `Children` on Element, only
|
|
56
|
+
* `Parents` — children are derived client-side. Filtered-out parents are
|
|
57
|
+
* removed from the surviving elements' parents/children arrays to avoid
|
|
58
|
+
* dangling references.
|
|
59
|
+
*
|
|
60
|
+
* GET /api/v1/Dimensions('{d}')/Hierarchies('{h}')?$expand=Elements(...)
|
|
61
|
+
*
|
|
62
|
+
* Paging: when no client-side post-filter is needed, `topN`/`skip` are
|
|
63
|
+
* pushed into the nested Elements expand together with `$orderby=Name` and
|
|
64
|
+
* `$count=true`. On a live 211k-element dimension that is 48 KB/page against
|
|
65
|
+
* 67 MB for the unbounded fetch. `$orderby` is not optional — without it
|
|
66
|
+
* `$skip` walks TM1's internal index order, which shifts on every element
|
|
67
|
+
* create/delete and would duplicate or drop elements between pages.
|
|
68
|
+
*/
|
|
69
|
+
async get(dimensionName, hierarchyName, opts) {
|
|
70
|
+
const elementClauses = [
|
|
71
|
+
"$select=Name,Type,Level",
|
|
72
|
+
// Parents for the tree, Edges for the child weights. Both are element
|
|
73
|
+
// navigations, so one request answers both — see the weight join below
|
|
74
|
+
// for why the separate Edges scan is gone.
|
|
75
|
+
"$expand=Parents($select=Name),Edges($select=ComponentName,Weight)",
|
|
76
|
+
];
|
|
77
|
+
const { filters, regex } = elementFilters(opts);
|
|
78
|
+
const needsClientPostFilter = regex !== undefined;
|
|
79
|
+
if (filters.length > 0)
|
|
80
|
+
elementClauses.push(`$filter=${filters.join(" and ")}`);
|
|
81
|
+
const skip = opts?.skip ?? 0;
|
|
82
|
+
const topN = opts?.topN;
|
|
83
|
+
// Push the window down only when nothing is filtered afterwards. With a
|
|
84
|
+
// client post-filter active, `Elements@odata.count` would count rows the
|
|
85
|
+
// caller never sees, so both the window and the total have to be computed
|
|
86
|
+
// here, on the filtered set.
|
|
87
|
+
const pushDown = topN !== undefined && !needsClientPostFilter;
|
|
88
|
+
if (pushDown)
|
|
89
|
+
elementClauses.push(...pageClauseList({ top: topN, skip }));
|
|
90
|
+
const path = `/api/v1/Dimensions('${enc(dimensionName)}')/Hierarchies('${enc(hierarchyName)}')?$expand=Elements(${elementClauses.join(";")})`;
|
|
91
|
+
const rawResponse = await this.http.request("GET", path);
|
|
92
|
+
let filteredElements = rawResponse.Elements;
|
|
93
|
+
if (regex !== undefined)
|
|
94
|
+
filteredElements = filteredElements.filter((e) => regex.test(e.Name));
|
|
95
|
+
// Total of everything the filters kept, before the window is applied.
|
|
96
|
+
// Server-side count when it was pushed down; otherwise the post-filter
|
|
97
|
+
// length, which is exact because we hold the whole filtered set.
|
|
98
|
+
let totalElements = pushDown
|
|
99
|
+
? (readNestedCount(rawResponse, "Elements") ??
|
|
100
|
+
skip + filteredElements.length)
|
|
101
|
+
: filteredElements.length;
|
|
102
|
+
if (!pushDown && (skip > 0 || topN !== undefined)) {
|
|
103
|
+
filteredElements = filteredElements.slice(skip, skip + (topN ?? filteredElements.length));
|
|
104
|
+
}
|
|
105
|
+
// A count below what we already hold means the hierarchy shrank between
|
|
106
|
+
// count and slice — trust the rows in hand.
|
|
107
|
+
totalElements = Math.max(totalElements, skip + filteredElements.length);
|
|
108
|
+
const response = { Name: rawResponse.Name, Elements: filteredElements };
|
|
109
|
+
const keptNames = new Set(response.Elements.map((e) => e.Name));
|
|
110
|
+
// Edge weights ride along with the elements: `Element` has an `Edges`
|
|
111
|
+
// navigation carrying its OUTGOING edges — its children, with weights —
|
|
112
|
+
// so the page already fetched above answers the question. Verified live:
|
|
113
|
+
// every consolidated row's edges had ParentName equal to that row, and no
|
|
114
|
+
// row carried an edge belonging to anything else.
|
|
115
|
+
//
|
|
116
|
+
// The alternative this replaces was reading the hierarchy's whole `Edges`
|
|
117
|
+
// collection: 21.6 MB and 594 ms for a 171k-element dimension, against
|
|
118
|
+
// 309 KB and 98 ms for the page-with-edges — one round trip instead of
|
|
119
|
+
// two, and bounded by the page's fan-out rather than by the dimension.
|
|
120
|
+
//
|
|
121
|
+
// A missing edge still falls back to 1, TM1's default. That fallback is
|
|
122
|
+
// why tests/live/dimension.live.test.ts pins a weight of -1: with 1 there
|
|
123
|
+
// is no way to tell a weight that was read from one that was invented.
|
|
124
|
+
const weightByEdge = new Map();
|
|
125
|
+
for (const e of response.Elements) {
|
|
126
|
+
for (const edge of e.Edges ?? []) {
|
|
127
|
+
let byChild = weightByEdge.get(e.Name);
|
|
128
|
+
if (!byChild) {
|
|
129
|
+
byChild = new Map();
|
|
130
|
+
weightByEdge.set(e.Name, byChild);
|
|
131
|
+
}
|
|
132
|
+
byChild.set(edge.ComponentName, edge.Weight);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const childrenByParent = new Map();
|
|
136
|
+
for (const e of response.Elements) {
|
|
137
|
+
for (const p of e.Parents ?? []) {
|
|
138
|
+
if (!keptNames.has(p.Name))
|
|
139
|
+
continue;
|
|
140
|
+
const list = childrenByParent.get(p.Name) ?? [];
|
|
141
|
+
list.push({
|
|
142
|
+
name: e.Name,
|
|
143
|
+
weight: weightByEdge.get(p.Name)?.get(e.Name) ?? 1,
|
|
144
|
+
});
|
|
145
|
+
childrenByParent.set(p.Name, list);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const elements = response.Elements.map((e) => ({
|
|
149
|
+
name: e.Name,
|
|
150
|
+
type: e.Type,
|
|
151
|
+
level: e.Level,
|
|
152
|
+
parents: (e.Parents ?? [])
|
|
153
|
+
.filter((p) => keptNames.has(p.Name))
|
|
154
|
+
.map((p) => p.Name),
|
|
155
|
+
children: childrenByParent.get(e.Name) ?? [],
|
|
156
|
+
}));
|
|
157
|
+
return {
|
|
158
|
+
name: response.Name,
|
|
159
|
+
dimensionName,
|
|
160
|
+
elements,
|
|
161
|
+
totalElements,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Element totals by type and level for a (filtered) hierarchy — no element
|
|
166
|
+
* rows. Reads the Elements collection with `$select=Type,Level` (plus Name
|
|
167
|
+
* only when a regex has to run client-side), so a count over a 200k-element
|
|
168
|
+
* dimension costs a few MB of wire traffic and a few hundred bytes of reply,
|
|
169
|
+
* where probing with growing `topN` returned the elements themselves.
|
|
170
|
+
*
|
|
171
|
+
* GET /api/v1/Dimensions('{d}')/Hierarchies('{h}')/Elements?$select=Type,Level
|
|
172
|
+
*/
|
|
173
|
+
async getCounts(dimensionName, hierarchyName, opts) {
|
|
174
|
+
const { filters, regex } = elementFilters(opts);
|
|
175
|
+
const clauses = [regex ? "$select=Name,Type,Level" : "$select=Type,Level"];
|
|
176
|
+
if (filters.length > 0)
|
|
177
|
+
clauses.push(`$filter=${filters.join(" and ")}`);
|
|
178
|
+
const path = `/api/v1/Dimensions('${enc(dimensionName)}')/Hierarchies('${enc(hierarchyName)}')` +
|
|
179
|
+
`/Elements?${clauses.join("&")}`;
|
|
180
|
+
const response = await this.http.request("GET", path);
|
|
181
|
+
let rows = response.value ?? [];
|
|
182
|
+
if (regex !== undefined)
|
|
183
|
+
rows = rows.filter((e) => regex.test(e.Name ?? ""));
|
|
184
|
+
const counts = {
|
|
185
|
+
total: rows.length,
|
|
186
|
+
byType: { Numeric: 0, String: 0, Consolidated: 0 },
|
|
187
|
+
byLevel: {},
|
|
188
|
+
maxLevel: 0,
|
|
189
|
+
};
|
|
190
|
+
for (const e of rows) {
|
|
191
|
+
if (e.Type === "Numeric" ||
|
|
192
|
+
e.Type === "String" ||
|
|
193
|
+
e.Type === "Consolidated")
|
|
194
|
+
counts.byType[e.Type]++;
|
|
195
|
+
const lvl = String(e.Level);
|
|
196
|
+
counts.byLevel[lvl] = (counts.byLevel[lvl] ?? 0) + 1;
|
|
197
|
+
if (e.Level > counts.maxLevel)
|
|
198
|
+
counts.maxLevel = e.Level;
|
|
199
|
+
}
|
|
200
|
+
return counts;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Element name + type for a whole hierarchy — nothing else.
|
|
204
|
+
*
|
|
205
|
+
* `get()` is the wrong tool for a type lookup: it expands `Parents` and
|
|
206
|
+
* `Edges` on every element to build the tree and weight the children. This
|
|
207
|
+
* reads the Elements collection directly with `$select=Name,Type` — no
|
|
208
|
+
* expand at all — which is the minimum payload for name → type resolution.
|
|
209
|
+
*
|
|
210
|
+
* GET /api/v1/Dimensions('{d}')/Hierarchies('{h}')/Elements?$select=Name,Type
|
|
211
|
+
*/
|
|
212
|
+
async getElementTypes(dimensionName, hierarchyName) {
|
|
213
|
+
const path = `/api/v1/Dimensions('${enc(dimensionName)}')/Hierarchies('${enc(hierarchyName)}')` +
|
|
214
|
+
`/Elements?$select=Name,Type`;
|
|
215
|
+
const response = await this.http.request("GET", path);
|
|
216
|
+
return (response.value ?? []).map((e) => ({
|
|
217
|
+
name: e.Name,
|
|
218
|
+
type: e.Type,
|
|
219
|
+
}));
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Resolve descendants of a consolidation element via client-side BFS over
|
|
223
|
+
* the full hierarchy. Returns a flat list with depth from the start element.
|
|
224
|
+
* Reuses get() — REST traffic identical, but the LLM-facing payload is a
|
|
225
|
+
* focused subtree, not the whole dimension.
|
|
226
|
+
*/
|
|
227
|
+
async getDescendants(dimensionName, hierarchyName, element, opts) {
|
|
228
|
+
const hierarchy = await this.get(dimensionName, hierarchyName);
|
|
229
|
+
const byName = new Map();
|
|
230
|
+
for (const e of hierarchy.elements)
|
|
231
|
+
byName.set(e.name, e);
|
|
232
|
+
if (!byName.has(element)) {
|
|
233
|
+
throw new TM1Error({
|
|
234
|
+
code: TM1ErrorCode.NOT_FOUND,
|
|
235
|
+
message: `Element '${element}' not found in ${dimensionName}.${hierarchyName}`,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
const out = [];
|
|
239
|
+
const seen = new Set([element]);
|
|
240
|
+
const queue = [
|
|
241
|
+
{ name: element, depth: 0 },
|
|
242
|
+
];
|
|
243
|
+
while (queue.length > 0) {
|
|
244
|
+
const cur = queue.shift();
|
|
245
|
+
const node = byName.get(cur.name);
|
|
246
|
+
if (!node)
|
|
247
|
+
continue;
|
|
248
|
+
const nextDepth = cur.depth + 1;
|
|
249
|
+
if (opts?.depth !== undefined && nextDepth > opts.depth)
|
|
250
|
+
continue;
|
|
251
|
+
for (const child of node.children) {
|
|
252
|
+
if (seen.has(child.name))
|
|
253
|
+
continue;
|
|
254
|
+
seen.add(child.name);
|
|
255
|
+
const childNode = byName.get(child.name);
|
|
256
|
+
if (!childNode)
|
|
257
|
+
continue;
|
|
258
|
+
const isLeaf = childNode.children.length === 0;
|
|
259
|
+
if (!opts?.leavesOnly || isLeaf) {
|
|
260
|
+
out.push({
|
|
261
|
+
name: childNode.name,
|
|
262
|
+
type: childNode.type,
|
|
263
|
+
level: childNode.level,
|
|
264
|
+
depth: nextDepth,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
queue.push({ name: child.name, depth: nextDepth });
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return { element, descendants: out };
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Resolve ancestors of an element via parent-walk. Handles multi-parent
|
|
274
|
+
* hierarchies — returns the unique flat ancestor set AND every distinct
|
|
275
|
+
* root-to-element path so consumers can see consolidation alternatives.
|
|
276
|
+
*/
|
|
277
|
+
async getAncestors(dimensionName, hierarchyName, element) {
|
|
278
|
+
const hierarchy = await this.get(dimensionName, hierarchyName);
|
|
279
|
+
const byName = new Map();
|
|
280
|
+
for (const e of hierarchy.elements)
|
|
281
|
+
byName.set(e.name, e);
|
|
282
|
+
if (!byName.has(element)) {
|
|
283
|
+
throw new TM1Error({
|
|
284
|
+
code: TM1ErrorCode.NOT_FOUND,
|
|
285
|
+
message: `Element '${element}' not found in ${dimensionName}.${hierarchyName}`,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
const ancestorMap = new Map();
|
|
289
|
+
const paths = [];
|
|
290
|
+
const walk = (name, currentPath, visited) => {
|
|
291
|
+
const node = byName.get(name);
|
|
292
|
+
if (!node)
|
|
293
|
+
return;
|
|
294
|
+
const parents = node.parents;
|
|
295
|
+
if (parents.length === 0) {
|
|
296
|
+
paths.push([...currentPath]);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
for (const parentName of parents) {
|
|
300
|
+
if (visited.has(parentName))
|
|
301
|
+
continue;
|
|
302
|
+
const parentNode = byName.get(parentName);
|
|
303
|
+
if (!parentNode)
|
|
304
|
+
continue;
|
|
305
|
+
ancestorMap.set(parentName, parentNode.level);
|
|
306
|
+
const nextVisited = new Set(visited);
|
|
307
|
+
nextVisited.add(parentName);
|
|
308
|
+
walk(parentName, [...currentPath, parentName], nextVisited);
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
walk(element, [element], new Set([element]));
|
|
312
|
+
const ancestors = [...ancestorMap.entries()]
|
|
313
|
+
.map(([name, level]) => ({ name, level }))
|
|
314
|
+
.sort((a, b) => a.level - b.level || a.name.localeCompare(b.name));
|
|
315
|
+
return { element, ancestors, paths };
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Create a new hierarchy inside an existing dimension.
|
|
319
|
+
* POST /api/v1/Dimensions('{d}')/Hierarchies
|
|
320
|
+
*/
|
|
321
|
+
async create(dimensionName, hierarchyName) {
|
|
322
|
+
await this.http.request("POST", `/api/v1/Dimensions('${enc(dimensionName)}')/Hierarchies`, { Name: hierarchyName });
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Delete a hierarchy from a dimension.
|
|
326
|
+
* DELETE /api/v1/Dimensions('{d}')/Hierarchies('{h}')
|
|
327
|
+
*/
|
|
328
|
+
async delete(dimensionName, hierarchyName) {
|
|
329
|
+
await this.http.request("DELETE", `/api/v1/Dimensions('${enc(dimensionName)}')/Hierarchies('${enc(hierarchyName)}')`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
//# sourceMappingURL=hierarchy-service.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Job, Session, Thread } from "../../types.js";
|
|
2
|
+
import type { TM1HttpClient } from "../http.js";
|
|
3
|
+
export declare class MonitoringService {
|
|
4
|
+
private readonly http;
|
|
5
|
+
constructor(http: TM1HttpClient);
|
|
6
|
+
/**
|
|
7
|
+
* List all active threads on the TM1 server.
|
|
8
|
+
* GET /api/v1/Threads
|
|
9
|
+
*/
|
|
10
|
+
getThreads(): Promise<Thread[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Cancel a running TM1 server thread.
|
|
13
|
+
* POST /api/v1/Threads({id})/tm1.CancelOperation
|
|
14
|
+
*/
|
|
15
|
+
cancelThread(threadId: number): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* List all active sessions on the TM1 server with associated user and
|
|
18
|
+
* threads. TM1 v11.8 returns ID as number; v12 as string — coerced to
|
|
19
|
+
* string. Numeric Type codes are mapped to symbolic names where known.
|
|
20
|
+
* GET /api/v1/Sessions?$expand=Threads,User($select=Name)
|
|
21
|
+
*/
|
|
22
|
+
getSessions(): Promise<Session[]>;
|
|
23
|
+
/**
|
|
24
|
+
* List all active jobs on v12 database replica.
|
|
25
|
+
* GET /api/v1/Jobs?$select=ID,Description,State,ElapsedTime,WaitTime&$expand=Session,WaitingOn
|
|
26
|
+
*/
|
|
27
|
+
getJobs(): Promise<Job[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Cancel running v12 job.
|
|
30
|
+
* POST /api/v1/Jobs('{id}')/tm1.Cancel
|
|
31
|
+
*/
|
|
32
|
+
cancelJob(jobId: string): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=monitoring-service.d.ts.map
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
function encKey(s) {
|
|
2
|
+
// Double single-quotes for OData escaping, then percent-encode all URL-unsafe chars
|
|
3
|
+
return encodeURIComponent(String(s).replace(/'/g, "''")).replace(/'/g, "%27");
|
|
4
|
+
}
|
|
5
|
+
export class MonitoringService {
|
|
6
|
+
http;
|
|
7
|
+
constructor(http) {
|
|
8
|
+
this.http = http;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* List all active threads on the TM1 server.
|
|
12
|
+
* GET /api/v1/Threads
|
|
13
|
+
*/
|
|
14
|
+
async getThreads() {
|
|
15
|
+
const response = await this.http.request("GET", "/api/v1/Threads?$select=ID,Type,Name,Context,State,Function,ObjectName,ElapsedTime");
|
|
16
|
+
const typeNames = {
|
|
17
|
+
1: "User",
|
|
18
|
+
2: "System",
|
|
19
|
+
4: "Admin",
|
|
20
|
+
8: "Chore",
|
|
21
|
+
16: "Extern",
|
|
22
|
+
};
|
|
23
|
+
return (response.value ?? []).map((t) => ({
|
|
24
|
+
id: t.ID,
|
|
25
|
+
type: typeNames[t.Type] ?? `Type${t.Type}`,
|
|
26
|
+
name: t.Name,
|
|
27
|
+
state: t.State,
|
|
28
|
+
function: t.Function,
|
|
29
|
+
objectName: t.ObjectName,
|
|
30
|
+
elapsedTime: t.ElapsedTime,
|
|
31
|
+
context: t.Context,
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Cancel a running TM1 server thread.
|
|
36
|
+
* POST /api/v1/Threads({id})/tm1.CancelOperation
|
|
37
|
+
*/
|
|
38
|
+
async cancelThread(threadId) {
|
|
39
|
+
await this.http.request("POST", `/api/v1/Threads(${threadId})/tm1.CancelOperation`, {});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* List all active sessions on the TM1 server with associated user and
|
|
43
|
+
* threads. TM1 v11.8 returns ID as number; v12 as string — coerced to
|
|
44
|
+
* string. Numeric Type codes are mapped to symbolic names where known.
|
|
45
|
+
* GET /api/v1/Sessions?$expand=Threads,User($select=Name)
|
|
46
|
+
*/
|
|
47
|
+
async getSessions() {
|
|
48
|
+
const response = await this.http.request("GET", "/api/v1/Sessions?$expand=Threads,User($select=Name)");
|
|
49
|
+
const typeNames = {
|
|
50
|
+
1: "User",
|
|
51
|
+
2: "System",
|
|
52
|
+
4: "Admin",
|
|
53
|
+
8: "Chore",
|
|
54
|
+
16: "Extern",
|
|
55
|
+
};
|
|
56
|
+
return (response.value ?? []).map((s) => ({
|
|
57
|
+
id: String(s.ID),
|
|
58
|
+
user: s.User?.Name ?? "",
|
|
59
|
+
...(s.Active !== undefined ? { active: s.Active } : {}),
|
|
60
|
+
threads: (s.Threads ?? []).map((t) => ({
|
|
61
|
+
id: t.ID,
|
|
62
|
+
type: typeof t.Type === "number"
|
|
63
|
+
? (typeNames[t.Type] ?? `Type${t.Type}`)
|
|
64
|
+
: (t.Type ?? ""),
|
|
65
|
+
name: t.Name ?? "",
|
|
66
|
+
state: t.State ?? "",
|
|
67
|
+
function: t.Function ?? "",
|
|
68
|
+
objectName: t.ObjectName ?? "",
|
|
69
|
+
...(t.ObjectType !== undefined ? { objectType: t.ObjectType } : {}),
|
|
70
|
+
...(t.ElapsedTime !== undefined ? { elapsedTime: t.ElapsedTime } : {}),
|
|
71
|
+
...(t.WaitTime !== undefined ? { waitTime: t.WaitTime } : {}),
|
|
72
|
+
...(t.Info !== undefined ? { info: t.Info } : {}),
|
|
73
|
+
})),
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* List all active jobs on v12 database replica.
|
|
78
|
+
* GET /api/v1/Jobs?$select=ID,Description,State,ElapsedTime,WaitTime&$expand=Session,WaitingOn
|
|
79
|
+
*/
|
|
80
|
+
async getJobs() {
|
|
81
|
+
// Fields below are typed loosely to match observed reality: the PA Engine
|
|
82
|
+
// can send `null` (not just omit) for any of these, and IDs have been seen
|
|
83
|
+
// as both string and number. Mapping below is null/undefined-safe.
|
|
84
|
+
const response = await this.http.request("GET", "/api/v1/Jobs?$select=ID,Description,State,ElapsedTime,WaitTime&$expand=Session($select=ID,Context;$expand=User($select=Name)),WaitingOn($select=ID,Description,State)");
|
|
85
|
+
return (response.value ?? []).map((j) => ({
|
|
86
|
+
id: String(j.ID),
|
|
87
|
+
description: j.Description ?? "",
|
|
88
|
+
state: j.State ?? "",
|
|
89
|
+
...(j.ElapsedTime != null ? { elapsedTime: j.ElapsedTime } : {}),
|
|
90
|
+
...(j.WaitTime != null ? { waitTime: j.WaitTime } : {}),
|
|
91
|
+
...(j.Session
|
|
92
|
+
? {
|
|
93
|
+
session: {
|
|
94
|
+
id: String(j.Session.ID),
|
|
95
|
+
...(j.Session.Context != null
|
|
96
|
+
? { context: j.Session.Context }
|
|
97
|
+
: {}),
|
|
98
|
+
...(j.Session.User?.Name != null
|
|
99
|
+
? { user: j.Session.User.Name }
|
|
100
|
+
: {}),
|
|
101
|
+
},
|
|
102
|
+
}
|
|
103
|
+
: {}),
|
|
104
|
+
...(j.WaitingOn
|
|
105
|
+
? {
|
|
106
|
+
waitingOn: j.WaitingOn.map((w) => ({
|
|
107
|
+
id: String(w.ID),
|
|
108
|
+
description: w.Description ?? "",
|
|
109
|
+
state: w.State ?? "",
|
|
110
|
+
})),
|
|
111
|
+
}
|
|
112
|
+
: {}),
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Cancel running v12 job.
|
|
117
|
+
* POST /api/v1/Jobs('{id}')/tm1.Cancel
|
|
118
|
+
*/
|
|
119
|
+
async cancelJob(jobId) {
|
|
120
|
+
await this.http.request("POST", `/api/v1/Jobs('${encKey(jobId)}')/tm1.Cancel`, {});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=monitoring-service.js.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export interface PageOpts {
|
|
2
|
+
/** `$top` — page size. Positive integer (comes from a Zod-validated `limit`). */
|
|
3
|
+
top: number;
|
|
4
|
+
/** `$skip` — items to skip. Non-negative integer (Zod-validated `offset`). */
|
|
5
|
+
skip: number;
|
|
6
|
+
/** `$orderby` property. Service-internal literal, never caller input. Default `Name`. */
|
|
7
|
+
orderBy?: string;
|
|
8
|
+
}
|
|
9
|
+
/** Result of a pushed-down list call. */
|
|
10
|
+
export interface Paged<T> {
|
|
11
|
+
items: T[];
|
|
12
|
+
/** `@odata.count`; undefined when the server omitted it (caller must fall back). */
|
|
13
|
+
total: number | undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The paging clauses as separate `$…=…` fragments, in a fixed order.
|
|
17
|
+
* Returns `[]` when no page was requested.
|
|
18
|
+
*
|
|
19
|
+
* Use this for nested `$expand(...)` option lists (joined with `;`);
|
|
20
|
+
* use {@link pageClauses} for top-level query strings (joined with `&`).
|
|
21
|
+
*/
|
|
22
|
+
export declare function pageClauseList(page: PageOpts | undefined): string[];
|
|
23
|
+
/**
|
|
24
|
+
* Top-level paging clauses with a leading `&`, ready to append to a query
|
|
25
|
+
* string that already has at least one parameter. Empty string when unpaged.
|
|
26
|
+
*/
|
|
27
|
+
export declare function pageClauses(page: PageOpts | undefined): string;
|
|
28
|
+
/** Read the collection-level `@odata.count` a `$count=true` request adds. */
|
|
29
|
+
export declare function readCount(response: {
|
|
30
|
+
"@odata.count"?: number;
|
|
31
|
+
} | null | undefined): number | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Read the `<Nav>@odata.count` that a nested `$expand=Nav($count=true)` adds to
|
|
34
|
+
* the *parent* entity (TM1 hangs the count off the owner, not the array).
|
|
35
|
+
*/
|
|
36
|
+
export declare function readNestedCount(response: Record<string, unknown> | null | undefined, navigationProperty: string): number | undefined;
|
|
37
|
+
/** Double `'` per OData literal rules so a caller string cannot break out of a literal. */
|
|
38
|
+
export declare function escapeOdataLiteral(value: string): string;
|
|
39
|
+
/** Join filter predicates with `and` into a `&$filter=…` fragment. Empty string when none. */
|
|
40
|
+
export declare function filterClause(predicates: readonly string[]): string;
|
|
41
|
+
/**
|
|
42
|
+
* Name-based predicates the `/Cubes`, `/Dimensions` and `/Processes` listings
|
|
43
|
+
* share. Only filters TM1 can evaluate itself belong here — a filter that
|
|
44
|
+
* stays client-side must disable push-down entirely, or `@odata.count` (and
|
|
45
|
+
* with it `total`/`has_more`) over-reports.
|
|
46
|
+
*
|
|
47
|
+
* `nameExact` uses `eq`, which TM1 evaluates case-sensitively — same semantics
|
|
48
|
+
* as the handlers' client-side `===`. `nameContains`/`nameNotContains` are
|
|
49
|
+
* case-insensitive via `tolower`, matching the handlers' `toLowerCase()`.
|
|
50
|
+
*/
|
|
51
|
+
export interface NameFilterOpts {
|
|
52
|
+
/** false ⇒ exclude `}`-prefixed control objects. */
|
|
53
|
+
includeControl?: boolean;
|
|
54
|
+
nameExact?: string;
|
|
55
|
+
nameContains?: string;
|
|
56
|
+
nameNotContains?: string;
|
|
57
|
+
}
|
|
58
|
+
export declare function nameFilterPredicates(opts: NameFilterOpts): string[];
|
|
59
|
+
/**
|
|
60
|
+
* Ordinal (UTF-16 code-unit) name comparator. TM1's `$orderby=Name` was
|
|
61
|
+
* live-probed against a 340-dimension / 319-process / 121-cube model and
|
|
62
|
+
* matched this ordering exactly, so the client-side fallback path can present
|
|
63
|
+
* the same order as the pushed-down path. Do not swap in `localeCompare` —
|
|
64
|
+
* it collates case- and accent-insensitively and would diverge.
|
|
65
|
+
*/
|
|
66
|
+
export declare function compareByName(a: {
|
|
67
|
+
name: string;
|
|
68
|
+
}, b: {
|
|
69
|
+
name: string;
|
|
70
|
+
}): number;
|
|
71
|
+
//# sourceMappingURL=odata-page.d.ts.map
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Shared OData paging/filter clause builder for server-side $top/$skip
|
|
2
|
+
// push-down.
|
|
3
|
+
//
|
|
4
|
+
// Lives in the service layer on purpose: `lint:no-flat-api` keeps every OData
|
|
5
|
+
// query fragment inside a service, so handlers pass semantic options
|
|
6
|
+
// ({page, nameContains, includeControl}) and the service turns them into a
|
|
7
|
+
// query string. Nothing here interpolates a caller string without escaping it.
|
|
8
|
+
//
|
|
9
|
+
// Why the clauses always travel together:
|
|
10
|
+
// $orderby — mandatory. `$skip` without a stable sort is undefined in OData;
|
|
11
|
+
// TM1 answers in internal index order, which shifts whenever an
|
|
12
|
+
// object is created or deleted, so a two-page walk would silently
|
|
13
|
+
// duplicate or drop rows.
|
|
14
|
+
// $count — the server-side total *after* $filter, which is what the
|
|
15
|
+
// Page<T> envelope's `total` means. Callers must therefore only
|
|
16
|
+
// push down when every active filter is expressible in OData.
|
|
17
|
+
/**
|
|
18
|
+
* The paging clauses as separate `$…=…` fragments, in a fixed order.
|
|
19
|
+
* Returns `[]` when no page was requested.
|
|
20
|
+
*
|
|
21
|
+
* Use this for nested `$expand(...)` option lists (joined with `;`);
|
|
22
|
+
* use {@link pageClauses} for top-level query strings (joined with `&`).
|
|
23
|
+
*/
|
|
24
|
+
export function pageClauseList(page) {
|
|
25
|
+
if (page === undefined)
|
|
26
|
+
return [];
|
|
27
|
+
return [
|
|
28
|
+
`$orderby=${page.orderBy ?? "Name"}`,
|
|
29
|
+
`$top=${page.top}`,
|
|
30
|
+
`$skip=${page.skip}`,
|
|
31
|
+
"$count=true",
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Top-level paging clauses with a leading `&`, ready to append to a query
|
|
36
|
+
* string that already has at least one parameter. Empty string when unpaged.
|
|
37
|
+
*/
|
|
38
|
+
export function pageClauses(page) {
|
|
39
|
+
const list = pageClauseList(page);
|
|
40
|
+
return list.length === 0 ? "" : `&${list.join("&")}`;
|
|
41
|
+
}
|
|
42
|
+
/** Read the collection-level `@odata.count` a `$count=true` request adds. */
|
|
43
|
+
export function readCount(response) {
|
|
44
|
+
return response?.["@odata.count"];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Read the `<Nav>@odata.count` that a nested `$expand=Nav($count=true)` adds to
|
|
48
|
+
* the *parent* entity (TM1 hangs the count off the owner, not the array).
|
|
49
|
+
*/
|
|
50
|
+
export function readNestedCount(response, navigationProperty) {
|
|
51
|
+
const raw = response?.[`${navigationProperty}@odata.count`];
|
|
52
|
+
return typeof raw === "number" ? raw : undefined;
|
|
53
|
+
}
|
|
54
|
+
/** Double `'` per OData literal rules so a caller string cannot break out of a literal. */
|
|
55
|
+
export function escapeOdataLiteral(value) {
|
|
56
|
+
return value.replace(/'/g, "''");
|
|
57
|
+
}
|
|
58
|
+
/** Join filter predicates with `and` into a `&$filter=…` fragment. Empty string when none. */
|
|
59
|
+
export function filterClause(predicates) {
|
|
60
|
+
return predicates.length === 0 ? "" : `&$filter=${predicates.join(" and ")}`;
|
|
61
|
+
}
|
|
62
|
+
export function nameFilterPredicates(opts) {
|
|
63
|
+
const predicates = [];
|
|
64
|
+
if (opts.includeControl !== true)
|
|
65
|
+
predicates.push("not startswith(Name,'}')");
|
|
66
|
+
if (opts.nameExact !== undefined && opts.nameExact.length > 0) {
|
|
67
|
+
predicates.push(`Name eq '${escapeOdataLiteral(opts.nameExact)}'`);
|
|
68
|
+
}
|
|
69
|
+
if (opts.nameContains !== undefined && opts.nameContains.length > 0) {
|
|
70
|
+
predicates.push(`contains(tolower(Name),'${escapeOdataLiteral(opts.nameContains.toLowerCase())}')`);
|
|
71
|
+
}
|
|
72
|
+
if (opts.nameNotContains !== undefined && opts.nameNotContains.length > 0) {
|
|
73
|
+
predicates.push(`not contains(tolower(Name),'${escapeOdataLiteral(opts.nameNotContains.toLowerCase())}')`);
|
|
74
|
+
}
|
|
75
|
+
return predicates;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Ordinal (UTF-16 code-unit) name comparator. TM1's `$orderby=Name` was
|
|
79
|
+
* live-probed against a 340-dimension / 319-process / 121-cube model and
|
|
80
|
+
* matched this ordering exactly, so the client-side fallback path can present
|
|
81
|
+
* the same order as the pushed-down path. Do not swap in `localeCompare` —
|
|
82
|
+
* it collates case- and accent-insensitively and would diverge.
|
|
83
|
+
*/
|
|
84
|
+
export function compareByName(a, b) {
|
|
85
|
+
return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=odata-page.js.map
|