@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,281 @@
|
|
|
1
|
+
import { createLogger } from "./logger.js";
|
|
2
|
+
import { createConnectionProfile, } from "./tm1-client/connection/profile.js";
|
|
3
|
+
import { getTm1Dispatcher, tm1Fetch } from "./tm1-client/dispatcher.js";
|
|
4
|
+
import { PRODUCT, VERSION } from "./version.js";
|
|
5
|
+
const USER_AGENT = `${PRODUCT}/${VERSION}`;
|
|
6
|
+
export class TimeoutError extends Error {
|
|
7
|
+
timeoutMs;
|
|
8
|
+
constructor(label, timeoutMs) {
|
|
9
|
+
super(`${label} request timed out after ${timeoutMs}ms`);
|
|
10
|
+
this.name = "TimeoutError";
|
|
11
|
+
this.timeoutMs = timeoutMs;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async function withTimeout(ms, label, fn) {
|
|
15
|
+
const controller = new AbortController();
|
|
16
|
+
const timer = setTimeout(() => controller.abort(), ms);
|
|
17
|
+
try {
|
|
18
|
+
return await fn(controller.signal);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
if (err instanceof DOMException && err.name === "AbortError") {
|
|
22
|
+
throw new TimeoutError(label, ms);
|
|
23
|
+
}
|
|
24
|
+
throw err;
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
clearTimeout(timer);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class SessionManager {
|
|
31
|
+
sessionCookie = null;
|
|
32
|
+
authInFlight = null;
|
|
33
|
+
keepAliveTimer = null;
|
|
34
|
+
config;
|
|
35
|
+
logger;
|
|
36
|
+
profile;
|
|
37
|
+
constructor(config, logger) {
|
|
38
|
+
this.config = config;
|
|
39
|
+
this.logger = logger ?? createLogger(config);
|
|
40
|
+
this.profile = createConnectionProfile(config);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Authenticate against TM1. The auth scheme (Basic / CAMNamespace /
|
|
44
|
+
* CAMPassport for v11, or the configured v12 auth mode) is selected by
|
|
45
|
+
* config — see ConnectionProfile.buildLoginRequest in
|
|
46
|
+
* tm1-client/connection/profile.ts.
|
|
47
|
+
*
|
|
48
|
+
* Concurrent callers share a single in-flight login. The HTTP transport
|
|
49
|
+
* re-authenticates directly from its 401 handler (http.ts), so two requests
|
|
50
|
+
* whose sessions expire at the same time both land here; without this dedup
|
|
51
|
+
* each opens a fresh TM1 session and the second login's cookie clobbers the
|
|
52
|
+
* first, leaving the first request retrying with a now-stale cookie (the
|
|
53
|
+
* "thundering herd on session expiry" race). All re-auth paths — ensureSession,
|
|
54
|
+
* keepAlive, and the transport 401 retry — funnel through this guard.
|
|
55
|
+
*
|
|
56
|
+
* `staleCookie` (optional): the cookie the caller was using when it decided to
|
|
57
|
+
* re-auth. If another caller has ALREADY rotated the session since then
|
|
58
|
+
* (current cookie ≠ stale, and non-null), this returns the fresh cookie
|
|
59
|
+
* without a logout+login. Without this, a delayed 401 carrying an
|
|
60
|
+
* already-replaced cookie would tear down the healthy session that concurrent
|
|
61
|
+
* requests are using — the "staggered-401 re-auth churn" cascade.
|
|
62
|
+
*/
|
|
63
|
+
async authenticate(staleCookie) {
|
|
64
|
+
if (staleCookie !== undefined &&
|
|
65
|
+
this.sessionCookie !== null &&
|
|
66
|
+
this.sessionCookie !== staleCookie) {
|
|
67
|
+
return this.sessionCookie;
|
|
68
|
+
}
|
|
69
|
+
this.authInFlight ??= this.doAuthenticate().finally(() => {
|
|
70
|
+
this.authInFlight = null;
|
|
71
|
+
});
|
|
72
|
+
return this.authInFlight;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Perform the actual login round-trip. The request (URL, method, headers,
|
|
76
|
+
* body) comes from the connection profile — v11 GETs
|
|
77
|
+
* /api/v1/Configuration/ProductVersion, v12 POSTs /{instance}/auth/v1/session.
|
|
78
|
+
* Extracts TM1SessionId cookie from the response.
|
|
79
|
+
*/
|
|
80
|
+
async doAuthenticate() {
|
|
81
|
+
// Close any existing session before opening a new one — prevents
|
|
82
|
+
// orphaned sessions accumulating on the TM1 server across re-auths.
|
|
83
|
+
if (this.sessionCookie) {
|
|
84
|
+
try {
|
|
85
|
+
await this.logout();
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
this.logger.warn({ err }, "Failed to logout existing session before re-auth");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const loginReq = await this.profile.buildLoginRequest();
|
|
92
|
+
this.logger.info({ endpoint: loginReq.url, authMode: this.authMode() }, "Authenticating with TM1");
|
|
93
|
+
const response = await withTimeout(this.config.requestTimeoutMs, "Authentication", (signal) => tm1Fetch(loginReq.url, {
|
|
94
|
+
method: loginReq.method,
|
|
95
|
+
headers: {
|
|
96
|
+
...loginReq.headers,
|
|
97
|
+
Accept: "application/json",
|
|
98
|
+
"User-Agent": USER_AGENT,
|
|
99
|
+
"TM1-SessionContext": USER_AGENT,
|
|
100
|
+
"TM1-Session-Context": USER_AGENT,
|
|
101
|
+
},
|
|
102
|
+
body: loginReq.body,
|
|
103
|
+
signal,
|
|
104
|
+
dispatcher: getTm1Dispatcher(this.config),
|
|
105
|
+
}));
|
|
106
|
+
// Always consume body to release connection
|
|
107
|
+
await response.text();
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
this.logger.error({ endpoint: loginReq.url, status: response.status }, "Authentication failed");
|
|
110
|
+
throw new Error(`Authentication failed with status ${response.status}: ${response.statusText}`);
|
|
111
|
+
}
|
|
112
|
+
const cookie = this.extractSessionCookie(response);
|
|
113
|
+
if (!cookie) {
|
|
114
|
+
throw new Error("Authentication succeeded but no TM1SessionId cookie found in response");
|
|
115
|
+
}
|
|
116
|
+
this.sessionCookie = cookie;
|
|
117
|
+
this.logger.info("Authentication successful, session established");
|
|
118
|
+
return cookie;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Send a keep-alive request to maintain the active session.
|
|
122
|
+
* GET /api/v1/ActiveSession with the session cookie.
|
|
123
|
+
* On 401, triggers re-authentication.
|
|
124
|
+
*/
|
|
125
|
+
async keepAlive() {
|
|
126
|
+
if (!this.sessionCookie) {
|
|
127
|
+
this.logger.warn("No active session for keep-alive, re-authenticating");
|
|
128
|
+
await this.authenticate();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const url = `${this.config.baseUrl}${this.profile.resolveApiPath("/api/v1/ActiveSession")}`;
|
|
132
|
+
this.logger.debug({ endpoint: url }, "Sending keep-alive");
|
|
133
|
+
// Snapshot the cookie this keep-alive is probing. If a concurrent request
|
|
134
|
+
// rotates the session mid-flight, we must not tear down the fresh cookie on
|
|
135
|
+
// our (now-stale) 401 — authenticate(usedCookie) handles that.
|
|
136
|
+
const usedCookie = this.sessionCookie;
|
|
137
|
+
let response;
|
|
138
|
+
try {
|
|
139
|
+
response = await withTimeout(this.config.requestTimeoutMs, "Keep-alive", (signal) => tm1Fetch(url, {
|
|
140
|
+
method: "GET",
|
|
141
|
+
headers: {
|
|
142
|
+
Cookie: `TM1SessionId=${usedCookie}`,
|
|
143
|
+
"User-Agent": USER_AGENT,
|
|
144
|
+
"TM1-SessionContext": USER_AGENT,
|
|
145
|
+
"TM1-Session-Context": USER_AGENT,
|
|
146
|
+
},
|
|
147
|
+
signal,
|
|
148
|
+
dispatcher: getTm1Dispatcher(this.config),
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
if (err instanceof TimeoutError) {
|
|
153
|
+
// Clear the cookie so the next real request re-authenticates up front
|
|
154
|
+
// (via ensureSession) instead of serving the possibly-dead session and
|
|
155
|
+
// eating a 401 round-trip under load. A keep-alive timeout is a strong
|
|
156
|
+
// signal the session is no longer healthy.
|
|
157
|
+
this.logger.error("Keep-alive request timed out; clearing session to force re-auth");
|
|
158
|
+
this.sessionCookie = null;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
throw err;
|
|
162
|
+
}
|
|
163
|
+
// Always consume body to release connection
|
|
164
|
+
await response.text();
|
|
165
|
+
if (response.status === 401) {
|
|
166
|
+
this.logger.warn("Session expired during keep-alive, re-authenticating");
|
|
167
|
+
// Pass the probed cookie so a race that already rotated the session is a
|
|
168
|
+
// no-op here instead of a redundant logout+login (staggered-401 churn).
|
|
169
|
+
await this.authenticate(usedCookie ?? undefined);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (!response.ok) {
|
|
173
|
+
this.logger.error({ endpoint: url, status: response.status }, "Keep-alive request failed");
|
|
174
|
+
throw new Error(`Keep-alive failed with status ${response.status}: ${response.statusText}`);
|
|
175
|
+
}
|
|
176
|
+
this.logger.debug("Keep-alive successful");
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Ensure an active session exists. If no session cookie is present,
|
|
180
|
+
* authenticate first. Returns the session cookie.
|
|
181
|
+
*/
|
|
182
|
+
async ensureSession() {
|
|
183
|
+
if (this.sessionCookie) {
|
|
184
|
+
return this.sessionCookie;
|
|
185
|
+
}
|
|
186
|
+
// authenticate() dedupes concurrent logins internally (see its doc), so
|
|
187
|
+
// first-auth races and 401 re-auth races share the same in-flight promise.
|
|
188
|
+
return this.authenticate();
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Start periodic keep-alive requests at the configured interval.
|
|
192
|
+
*/
|
|
193
|
+
startKeepAlive() {
|
|
194
|
+
if (this.keepAliveTimer) {
|
|
195
|
+
this.logger.debug("Keep-alive already running");
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
this.logger.info({ intervalMs: this.config.keepAliveIntervalMs }, "Starting keep-alive timer");
|
|
199
|
+
this.keepAliveTimer = setInterval(() => {
|
|
200
|
+
this.keepAlive().catch((err) => {
|
|
201
|
+
this.logger.error({ err }, "Keep-alive error");
|
|
202
|
+
});
|
|
203
|
+
}, this.config.keepAliveIntervalMs);
|
|
204
|
+
// Don't block Node.js from exiting
|
|
205
|
+
if (this.keepAliveTimer.unref) {
|
|
206
|
+
this.keepAliveTimer.unref();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Stop the periodic keep-alive timer.
|
|
211
|
+
*/
|
|
212
|
+
stopKeepAlive() {
|
|
213
|
+
if (this.keepAliveTimer) {
|
|
214
|
+
clearInterval(this.keepAliveTimer);
|
|
215
|
+
this.keepAliveTimer = null;
|
|
216
|
+
this.logger.info("Keep-alive timer stopped");
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Check whether a session cookie is currently held.
|
|
221
|
+
*/
|
|
222
|
+
isSessionActive() {
|
|
223
|
+
return this.sessionCookie !== null;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Logout from TM1 by deleting the active session.
|
|
227
|
+
* DELETE /api/v1/ActiveSession
|
|
228
|
+
*/
|
|
229
|
+
async logout() {
|
|
230
|
+
if (!this.sessionCookie) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const url = `${this.config.baseUrl}${this.profile.resolveApiPath("/api/v1/ActiveSession")}`;
|
|
234
|
+
this.logger.info("Logging out from TM1");
|
|
235
|
+
try {
|
|
236
|
+
// Bound the logout request — authenticate() calls logout() first, so a
|
|
237
|
+
// hung DELETE (slow/unreachable server) would otherwise block re-auth
|
|
238
|
+
// indefinitely. On timeout we still clear the cookie below.
|
|
239
|
+
const response = await withTimeout(this.config.requestTimeoutMs, "Logout", (signal) => tm1Fetch(url, {
|
|
240
|
+
method: "DELETE",
|
|
241
|
+
headers: {
|
|
242
|
+
Cookie: `TM1SessionId=${this.sessionCookie}`,
|
|
243
|
+
"User-Agent": USER_AGENT,
|
|
244
|
+
"TM1-SessionContext": USER_AGENT,
|
|
245
|
+
"TM1-Session-Context": USER_AGENT,
|
|
246
|
+
},
|
|
247
|
+
dispatcher: getTm1Dispatcher(this.config),
|
|
248
|
+
signal,
|
|
249
|
+
}));
|
|
250
|
+
// Consume body to release connection
|
|
251
|
+
await response.text();
|
|
252
|
+
this.sessionCookie = null;
|
|
253
|
+
this.logger.info("Logged out from TM1");
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
this.logger.error({ err: error }, "Error during logout");
|
|
257
|
+
this.sessionCookie = null;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/** Human-readable auth mode for logging (never logs the credential itself). */
|
|
261
|
+
authMode() {
|
|
262
|
+
if (this.config.version === 12)
|
|
263
|
+
return `v12:${this.config.authMode ?? "s2s"}`;
|
|
264
|
+
if (this.config.camPassport)
|
|
265
|
+
return "CAMPassport";
|
|
266
|
+
if (this.config.namespace)
|
|
267
|
+
return "CAMNamespace";
|
|
268
|
+
return "Basic";
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Extract TM1SessionId Set-Cookie response headers.
|
|
272
|
+
*/
|
|
273
|
+
extractSessionCookie(response) {
|
|
274
|
+
const setCookie = response.headers.get("set-cookie");
|
|
275
|
+
if (!setCookie)
|
|
276
|
+
return null;
|
|
277
|
+
const match = setCookie.match(/TM1SessionId=([^;]+)/);
|
|
278
|
+
return match ? (match[1] ?? null) : null;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=session-manager.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TM1Config } from "../../config.js";
|
|
2
|
+
export interface LoginRequest {
|
|
3
|
+
url: string;
|
|
4
|
+
method: "GET" | "POST";
|
|
5
|
+
headers: Record<string, string>;
|
|
6
|
+
body?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ConnectionProfile {
|
|
9
|
+
resolveApiPath(path: string): string;
|
|
10
|
+
buildLoginRequest(): Promise<LoginRequest>;
|
|
11
|
+
}
|
|
12
|
+
export declare function createConnectionProfile(config: TM1Config): ConnectionProfile;
|
|
13
|
+
//# sourceMappingURL=profile.d.ts.map
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// OData single-quote escaping for a key segment (double the apostrophes),
|
|
2
|
+
// then URL-encode. Mirrors the `enc` helper used across the service layer.
|
|
3
|
+
const enc = (s) => encodeURIComponent(String(s).replace(/'/g, "''"));
|
|
4
|
+
function buildBasicToken(user, password) {
|
|
5
|
+
return "Basic " + Buffer.from(`${user}:${password}`).toString("base64");
|
|
6
|
+
}
|
|
7
|
+
// v11 Authorization header (Basic / CAMNamespace / CAMPassport). Lives here
|
|
8
|
+
// (rather than on SessionManager) so all login-header logic — v11 and v12 —
|
|
9
|
+
// is in one place.
|
|
10
|
+
function buildV11Authorization(config) {
|
|
11
|
+
const { user, password, namespace, camPassport } = config;
|
|
12
|
+
if (camPassport)
|
|
13
|
+
return `CAMPassport ${camPassport}`;
|
|
14
|
+
if (namespace) {
|
|
15
|
+
return ("CAMNamespace " +
|
|
16
|
+
Buffer.from(`${user}:${password}:${namespace}`).toString("base64"));
|
|
17
|
+
}
|
|
18
|
+
return buildBasicToken(user, password);
|
|
19
|
+
}
|
|
20
|
+
export function createConnectionProfile(config) {
|
|
21
|
+
if (config.version === 12) {
|
|
22
|
+
// Implemented in Task 3.
|
|
23
|
+
return createV12Profile(config);
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
resolveApiPath: (path) => path,
|
|
27
|
+
buildLoginRequest: () => Promise.resolve({
|
|
28
|
+
url: `${config.baseUrl}/api/v1/Configuration/ProductVersion`,
|
|
29
|
+
method: "GET",
|
|
30
|
+
headers: { Authorization: buildV11Authorization(config) },
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// IBM IAM api-key → access_token exchange (v12 iam mode). Mirrors TM1py's
|
|
35
|
+
// _generate_ibm_iam_cloud_access_token. Bounded by timeoutMs so a hung IAM
|
|
36
|
+
// endpoint can't hang authenticate() forever.
|
|
37
|
+
async function exchangeIamApiKey(apiKey, iamUrl, timeoutMs) {
|
|
38
|
+
const body = "grant_type=urn%3Aibm%3Aparams%3Aoauth%3Agrant-type%3Aapikey&apikey=" +
|
|
39
|
+
encodeURIComponent(apiKey);
|
|
40
|
+
const response = await fetch(iamUrl, {
|
|
41
|
+
method: "POST",
|
|
42
|
+
headers: {
|
|
43
|
+
Accept: "application/json",
|
|
44
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
45
|
+
},
|
|
46
|
+
body,
|
|
47
|
+
signal: AbortSignal.timeout(timeoutMs ?? 30000),
|
|
48
|
+
});
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
throw new Error(`IAM token exchange failed with status ${response.status}`);
|
|
51
|
+
}
|
|
52
|
+
const json = (await response.json());
|
|
53
|
+
if (!json.access_token) {
|
|
54
|
+
throw new Error(`IAM token exchange returned no access_token from ${iamUrl}`);
|
|
55
|
+
}
|
|
56
|
+
return json.access_token;
|
|
57
|
+
}
|
|
58
|
+
// The Authorization header for a v12 login POST, by auth mode.
|
|
59
|
+
async function buildV12Authorization(config) {
|
|
60
|
+
switch (config.authMode) {
|
|
61
|
+
case "s2s":
|
|
62
|
+
return ("Basic " +
|
|
63
|
+
Buffer.from(`${config.clientId}:${config.clientSecret}`).toString("base64"));
|
|
64
|
+
case "basic":
|
|
65
|
+
return buildBasicToken(config.user, config.password);
|
|
66
|
+
case "access_token":
|
|
67
|
+
case "oidc":
|
|
68
|
+
return `Bearer ${config.accessToken}`;
|
|
69
|
+
case "iam": {
|
|
70
|
+
const token = await exchangeIamApiKey(config.apiKey ?? "", config.iamUrl ?? "", config.requestTimeoutMs);
|
|
71
|
+
return `Bearer ${token}`;
|
|
72
|
+
}
|
|
73
|
+
default:
|
|
74
|
+
throw new Error(`Unsupported v12 auth mode: ${String(config.authMode)}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function createV12Profile(config) {
|
|
78
|
+
const instance = config.instance ?? "";
|
|
79
|
+
const database = config.database ?? "";
|
|
80
|
+
// encodeURIComponent (not `enc`) for the instance: it's a bare path segment,
|
|
81
|
+
// not an OData quoted key — no apostrophe-doubling needed, just percent-encoding.
|
|
82
|
+
const dbRoot = `/${encodeURIComponent(instance)}/api/v1/Databases('${enc(database)}')`;
|
|
83
|
+
return {
|
|
84
|
+
// Replacement FUNCTION, not a string: String.replace treats "$&"/"$$"/"$1"
|
|
85
|
+
// in a string replacement specially, which would corrupt dbRoot if instance
|
|
86
|
+
// or database contained a literal "$". A function return is used verbatim.
|
|
87
|
+
resolveApiPath: (path) => path.replace(/^\/api\/v1/, () => dbRoot),
|
|
88
|
+
buildLoginRequest: async () => ({
|
|
89
|
+
url: `${config.baseUrl}/${encodeURIComponent(instance)}/auth/v1/session`,
|
|
90
|
+
method: "POST",
|
|
91
|
+
headers: {
|
|
92
|
+
Authorization: await buildV12Authorization(config),
|
|
93
|
+
"Content-Type": "application/json",
|
|
94
|
+
},
|
|
95
|
+
body: JSON.stringify({ User: config.user }),
|
|
96
|
+
}),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=profile.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Agent } from "undici";
|
|
2
|
+
import type { TM1Config } from "../config.js";
|
|
3
|
+
export declare function getTm1Dispatcher(config: TM1Config): Agent | undefined;
|
|
4
|
+
export declare function tm1Fetch(url: string, init: RequestInit): Promise<Response>;
|
|
5
|
+
//# sourceMappingURL=dispatcher.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Per-request TLS dispatcher for TM1 fetches. Replaces the previous
|
|
2
|
+
// `process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"` global side-effect, which
|
|
3
|
+
// disabled TLS verification for the entire Node process (including unrelated
|
|
4
|
+
// HTTPS calls from MCP transport, telemetry, etc.). With undici's Agent we
|
|
5
|
+
// scope `rejectUnauthorized: false` to TM1 fetches only.
|
|
6
|
+
//
|
|
7
|
+
// The Agent is cached so connection-pooling stays effective across requests.
|
|
8
|
+
import { Agent, fetch as undiciFetch } from "undici";
|
|
9
|
+
let cachedAgent;
|
|
10
|
+
export function getTm1Dispatcher(config) {
|
|
11
|
+
if (config.ssl.rejectUnauthorized)
|
|
12
|
+
return undefined;
|
|
13
|
+
if (!cachedAgent) {
|
|
14
|
+
cachedAgent = new Agent({ connect: { rejectUnauthorized: false } });
|
|
15
|
+
}
|
|
16
|
+
return cachedAgent;
|
|
17
|
+
}
|
|
18
|
+
// Node's BUILT-IN fetch silently drops Set-Cookie headers when handed a
|
|
19
|
+
// dispatcher from the npm undici package (cross-instance Headers handling;
|
|
20
|
+
// reproduced on Node 26 + undici 7.25 — auth broke with "no TM1SessionId
|
|
21
|
+
// cookie found"). Pair the npm Agent with the npm fetch instead, where the
|
|
22
|
+
// instances match. Unit tests stub globalThis.fetch — honor the stub when
|
|
23
|
+
// present (identity check against the built-in captured at module load).
|
|
24
|
+
const builtinFetch = globalThis.fetch;
|
|
25
|
+
export function tm1Fetch(url, init) {
|
|
26
|
+
if (globalThis.fetch !== builtinFetch) {
|
|
27
|
+
return globalThis.fetch(url, init);
|
|
28
|
+
}
|
|
29
|
+
return undiciFetch(url, init);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=dispatcher.js.map
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type pino from "pino";
|
|
2
|
+
import type { TM1Config } from "../config.js";
|
|
3
|
+
import type { SessionManager } from "../session-manager.js";
|
|
4
|
+
import { TM1Error } from "../types.js";
|
|
5
|
+
export interface RequestOptions {
|
|
6
|
+
timeoutMs?: number;
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
retry?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare class TM1HttpClient {
|
|
11
|
+
private readonly config;
|
|
12
|
+
readonly logger: pino.Logger;
|
|
13
|
+
protected readonly sessionManager: SessionManager;
|
|
14
|
+
private readonly profile;
|
|
15
|
+
constructor(config: TM1Config, sessionManager: SessionManager, logger: pino.Logger);
|
|
16
|
+
/**
|
|
17
|
+
* TM1 major version (11 | 12) — the single numeric source of truth for
|
|
18
|
+
* version-conditional service code. Branch on this, never on the display
|
|
19
|
+
* string (`tm1Version`): a v12 connection can carry a "11.x"-looking
|
|
20
|
+
* TM1_VERSION string, but `version` is always authoritative.
|
|
21
|
+
*/
|
|
22
|
+
get version(): 11 | 12;
|
|
23
|
+
/**
|
|
24
|
+
* TM1 server version STRING (e.g. "11.8.…") — DISPLAY ONLY (server_info
|
|
25
|
+
* output, log fields, user-facing error messages). Do NOT branch on this;
|
|
26
|
+
* use the numeric `version` getter instead.
|
|
27
|
+
*/
|
|
28
|
+
get tm1Version(): string;
|
|
29
|
+
/**
|
|
30
|
+
* Make an authenticated HTTP request to the TM1 REST API.
|
|
31
|
+
*
|
|
32
|
+
* - Ensures an active session via SessionManager
|
|
33
|
+
* - On 401: re-authenticates once and retries
|
|
34
|
+
* - On network error for safe methods (GET/HEAD): retries up to 3 times with exponential backoff (1s, 2s, 4s)
|
|
35
|
+
* - On network error for non-safe methods (POST/PUT/PATCH/DELETE): does NOT retry — these are not idempotent
|
|
36
|
+
* and a retry could spawn duplicate side-effects (e.g. parallel TI runs on tm1.Execute)
|
|
37
|
+
* - On other HTTP errors: classifies and throws TM1Error
|
|
38
|
+
*/
|
|
39
|
+
/** @internal — for Service-layer use; not part of the public consumer API. */
|
|
40
|
+
request<T = unknown>(method: string, path: string, body?: unknown, opts?: RequestOptions): Promise<T>;
|
|
41
|
+
/**
|
|
42
|
+
* Make an authenticated HTTP request that returns raw text (not JSON).
|
|
43
|
+
* Used for file content downloads where the response is CSV/TXT/etc.
|
|
44
|
+
* Re-auths once on 401 like request().
|
|
45
|
+
*/
|
|
46
|
+
/** @internal — for Service-layer use; not part of the public consumer API. */
|
|
47
|
+
requestRaw(method: string, path: string, opts?: RequestOptions): Promise<string>;
|
|
48
|
+
/**
|
|
49
|
+
* Make an authenticated HTTP request with a binary body (Buffer/Uint8Array).
|
|
50
|
+
* Used for blob/file uploads where the body is raw bytes (not JSON).
|
|
51
|
+
* Sends Content-Type: application/octet-stream by default.
|
|
52
|
+
* Re-auths once on 401 like request(). No network-error retries (non-safe methods).
|
|
53
|
+
*/
|
|
54
|
+
/** @internal — for Service-layer use; not part of the public consumer API. */
|
|
55
|
+
requestBinary(method: string, path: string, body: Uint8Array, contentType?: string, opts?: RequestOptions): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Low-level single fetch with timeout + AbortSignal wiring.
|
|
58
|
+
* Does NOT handle 401, retries, or error classification — callers own that.
|
|
59
|
+
*/
|
|
60
|
+
private sendOnce;
|
|
61
|
+
/**
|
|
62
|
+
* Wraps a send function with cookie-refresh-on-401 and timeout→LOCK_TIMEOUT mapping.
|
|
63
|
+
* Used by requestRaw and requestBinary (which have no network-retry loop).
|
|
64
|
+
* On 401: calls sessionManager.authenticate() and retries once with the new cookie.
|
|
65
|
+
* The caller is responsible for obtaining the initial cookie via ensureSession().
|
|
66
|
+
*/
|
|
67
|
+
private withReauth;
|
|
68
|
+
private executeRequest;
|
|
69
|
+
private handleResponse;
|
|
70
|
+
private classifyHttpError;
|
|
71
|
+
private isNetworkError;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Map an HTTP status + TM1 error text onto a TM1Error. Module-level (not just a
|
|
75
|
+
* TM1HttpClient method) because `$batch` sub-responses arrive as plain
|
|
76
|
+
* {status, body} records inside a 200 envelope — BatchService has to classify
|
|
77
|
+
* them itself, and must do it identically to a standalone request rather than
|
|
78
|
+
* with a drifting copy of these rules.
|
|
79
|
+
*/
|
|
80
|
+
export declare function classifyHttpError(status: number, endpoint: string, rawDetails?: string): TM1Error;
|
|
81
|
+
//# sourceMappingURL=http.d.ts.map
|