@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,455 @@
|
|
|
1
|
+
// Batch domain service. Owns the one OData endpoint that is not tied to a TM1
|
|
2
|
+
// object type: POST /api/v1/$batch. It folds many independent REST calls into a
|
|
3
|
+
// single HTTP round-trip and hands each sub-response back to the caller
|
|
4
|
+
// separately.
|
|
5
|
+
//
|
|
6
|
+
// Verified live (TM1 v11 11.8.02900.8 and v12 / PA Engine 12.5.9):
|
|
7
|
+
// - Only the OData 4.01 **JSON** batch format is accepted. A multipart/mixed
|
|
8
|
+
// body is rejected with 400 "No acceptable mime type specified. $batch
|
|
9
|
+
// produces application/json responses!".
|
|
10
|
+
// - The batch is NOT atomic. `atomicityGroup` is refused outright: 400
|
|
11
|
+
// "$batch implementation DOES NOT support atomicity groups, hence the
|
|
12
|
+
// 'atomicityGroup' property MUST NOT be defined".
|
|
13
|
+
// - Continue-on-error is the DEFAULT: with [ok, fail, ok] all three run and
|
|
14
|
+
// both successes are committed; a leading failure does not stop the rest.
|
|
15
|
+
// - The envelope is HTTP 200 even when sub-requests fail; each entry carries
|
|
16
|
+
// its own `status` and error `body`.
|
|
17
|
+
//
|
|
18
|
+
// That combination is what makes this safe for the bulk paths: partial success
|
|
19
|
+
// is the server's native behaviour, so per-item success/failure reporting is
|
|
20
|
+
// preserved rather than collapsed into one all-or-nothing result.
|
|
21
|
+
//
|
|
22
|
+
// Scope: exactly one consumer today — `ElementService.bulkUpsert`
|
|
23
|
+
// (`element-service.ts`), which folds the per-element writes of
|
|
24
|
+
// tm1_bulk_upsert_elements into one round-trip. It stays a service of its own
|
|
25
|
+
// rather than moving into ElementService for two reasons that outlive the
|
|
26
|
+
// single caller: `$batch` is the one endpoint bound to no TM1 object type, so
|
|
27
|
+
// it belongs to no other service by the rule in docs/ARCHITECTURE.md; and the
|
|
28
|
+
// `supported` verdict below is CONNECTION-scoped, probed once and reused, so it
|
|
29
|
+
// cannot live inside a per-object-type service without being re-probed per
|
|
30
|
+
// caller. `TM1Client` exposes it as `client.batch` for the live suite, which
|
|
31
|
+
// asserts the probe's behaviour directly.
|
|
32
|
+
//
|
|
33
|
+
// See docs/ARCHITECTURE.md for the layering.
|
|
34
|
+
import { TM1Error, TM1ErrorCode } from "../../types.js";
|
|
35
|
+
import { classifyHttpError } from "../http.js";
|
|
36
|
+
import { rethrowIfSystemic } from "./fallback.js";
|
|
37
|
+
const BATCH_PATH = "/api/v1/$batch";
|
|
38
|
+
// The counter-probe's sub-request: the cheapest read in the API surface, and
|
|
39
|
+
// the one this codebase already trusts as a reachability check — the v11 login
|
|
40
|
+
// round-trip IS a GET of it (`connection/profile.ts`), and `ServerService`
|
|
41
|
+
// reads the same scalar on v12 for the ProductVersion the Configuration body
|
|
42
|
+
// omits. So it is known to exist and to be answerable on both versions, it
|
|
43
|
+
// takes no arguments, and it mutates nothing.
|
|
44
|
+
const BATCH_PROBE_PATH = "/api/v1/Configuration/ProductVersion";
|
|
45
|
+
/**
|
|
46
|
+
* Correlation id of the counter-probe's single sub-request. Namespaced so it
|
|
47
|
+
* can never collide with a caller id, and recognisable in a server-side log.
|
|
48
|
+
*/
|
|
49
|
+
export const BATCH_PROBE_ID = "__tm1_mcp_batch_probe__";
|
|
50
|
+
// Sub-requests per HTTP round-trip. TM1 accepts far larger batches (5000
|
|
51
|
+
// element creates succeeded live) but processes them SEQUENTIALLY server-side,
|
|
52
|
+
// so a huge batch just builds one very long request: 5000 creates took ~47s,
|
|
53
|
+
// well past a normal 30s request timeout, and a timeout mid-batch leaves an
|
|
54
|
+
// unknown amount committed. Chunking keeps each round-trip bounded and gives
|
|
55
|
+
// natural progress boundaries, while still collapsing ~200 calls into one.
|
|
56
|
+
export const BATCH_MAX_REQUESTS = 200;
|
|
57
|
+
// Serialized bytes per HTTP round-trip. The request COUNT alone does not bound
|
|
58
|
+
// the payload: 200 sub-requests carrying long element names, MDX, or a
|
|
59
|
+
// Components list are easily megabytes, and the request counter is still
|
|
60
|
+
// happily under its cap when the body hits a hard limit somewhere on the way.
|
|
61
|
+
// The limit that bites first is almost never TM1's — it is whatever sits in
|
|
62
|
+
// front of it: nginx caps request bodies at 1 MiB by default
|
|
63
|
+
// (`client_max_body_size 1m`), and that is the smallest default in the usual
|
|
64
|
+
// deployment shapes. A body over the limit comes back 400/413, which is in
|
|
65
|
+
// UNSUPPORTED_STATUSES, so an oversized chunk would be misread as "this server
|
|
66
|
+
// has no $batch" and silently re-drive every write down the caller's fallback
|
|
67
|
+
// path. Budget 1_000_000 bytes: just under that 1 MiB floor, leaving ~48 KB of
|
|
68
|
+
// headroom for request headers, the auth cookie and the envelope itself. Big
|
|
69
|
+
// enough that ordinary bulk work (a 200-element create batch is ~25 KB) never
|
|
70
|
+
// notices it, small enough to keep the pathological payload off the wire.
|
|
71
|
+
export const BATCH_MAX_PAYLOAD_BYTES = 1_000_000;
|
|
72
|
+
// A batch performs N operations in one HTTP call, so the per-call default
|
|
73
|
+
// timeout is the wrong budget for it. Scale with the chunk size instead.
|
|
74
|
+
const BATCH_TIMEOUT_BASE_MS = 30_000;
|
|
75
|
+
const BATCH_TIMEOUT_PER_REQUEST_MS = 200;
|
|
76
|
+
/**
|
|
77
|
+
* Thrown when the server cannot serve `$batch` at all (endpoint absent, method
|
|
78
|
+
* refused, or an envelope we cannot read). Distinct from a sub-request failure,
|
|
79
|
+
* which is reported per item. Callers catch ONLY this to fall back to their
|
|
80
|
+
* per-request path — never a sub-request error, and never a systemic
|
|
81
|
+
* transport/auth failure (those propagate).
|
|
82
|
+
*
|
|
83
|
+
* GUARANTEE for those callers: this is raised only before the first successful
|
|
84
|
+
* batch on the connection — i.e. only ever out of the caller's FIRST pass.
|
|
85
|
+
*
|
|
86
|
+
* What that does NOT mean: "nothing was committed". TM1's `$batch` is
|
|
87
|
+
* non-atomic (verified live against 11.8: a failing sub-request leaves its
|
|
88
|
+
* siblings in the same envelope committed), and an ambiguous status such as 500
|
|
89
|
+
* can arrive after the server already applied part of the envelope. A caller
|
|
90
|
+
* that restarts per-request MAY therefore re-issue writes that already took
|
|
91
|
+
* effect.
|
|
92
|
+
*
|
|
93
|
+
* The requirement on callers is therefore: THE FIRST PASS MUST BE REPLAY-SAFE.
|
|
94
|
+
* `ElementService.bulkUpsert` satisfies this because its first pass is
|
|
95
|
+
* create-only, and re-creating an existing element degrades to the upsert path.
|
|
96
|
+
* A future caller whose first pass mutates existing state must NOT rely on this
|
|
97
|
+
* error to fall back. See `BatchService.markUnsupported`.
|
|
98
|
+
*/
|
|
99
|
+
export class BatchUnsupportedError extends Error {
|
|
100
|
+
constructor(reason) {
|
|
101
|
+
super(`TM1 $batch is not usable on this server: ${reason}`);
|
|
102
|
+
this.name = "BatchUnsupportedError";
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Statuses that can mean "this server has no usable $batch endpoint". The
|
|
106
|
+
// obvious ones are 501 Not Implemented / 405 Method Not Allowed / 404 Not Found,
|
|
107
|
+
// but a server or gateway that does not know the endpoint may just as well
|
|
108
|
+
// answer 400 ("invalid URL"), 403, or 500 — and every one of those would
|
|
109
|
+
// otherwise fail the whole bulk operation instead of falling back to the
|
|
110
|
+
// caller's per-request path.
|
|
111
|
+
//
|
|
112
|
+
// Read this set ONLY together with `markUnsupported`: a status here counts as
|
|
113
|
+
// "unsupported" exclusively before the first successful batch on this
|
|
114
|
+
// connection. Once `$batch` has demonstrably worked, a 400 means "your payload
|
|
115
|
+
// was bad" and must propagate rather than silently re-drive the caller's writes.
|
|
116
|
+
//
|
|
117
|
+
// 400 is the one member of this set that is genuinely AMBIGUOUS even before the
|
|
118
|
+
// first success, so it alone gets a counter-probe first (`counterProbe`). See
|
|
119
|
+
// PROBE_STATUS below for why the others do not.
|
|
120
|
+
const UNSUPPORTED_STATUSES = new Set([400, 403, 404, 405, 500, 501]);
|
|
121
|
+
// The only status worth counter-probing. The other members of
|
|
122
|
+
// UNSUPPORTED_STATUSES are unambiguous *given what this service controls*: the
|
|
123
|
+
// URL and the method are constants (`POST /api/v1/$batch`), so nothing in the
|
|
124
|
+
// caller's payload can produce them, and a probe could not come back with a
|
|
125
|
+
// different answer than the chunk already got.
|
|
126
|
+
//
|
|
127
|
+
// 404 / 405 / 501 — verdicts about the URL and the METHOD. The endpoint is
|
|
128
|
+
// not routed, POST is refused there, or the feature is declared
|
|
129
|
+
// unimplemented. All three are payload-independent by construction.
|
|
130
|
+
// 403 — a verdict about the caller's IDENTITY, not about the body. The
|
|
131
|
+
// identity is the same for the probe (same session, same cookie), so the
|
|
132
|
+
// probe would return 403 again by construction: a probe that cannot change
|
|
133
|
+
// its answer is pure cost.
|
|
134
|
+
// 500 — ambiguous in the abstract, but deliberately excluded. Unlike a 400,
|
|
135
|
+
// a 500 can arrive AFTER the server already applied part of the envelope
|
|
136
|
+
// (`$batch` is non-atomic; see BatchUnsupportedError's docstring), and the
|
|
137
|
+
// per-request fallback is the path whose replay-safety the caller contract
|
|
138
|
+
// already guarantees. Marking the connection supported and hard-failing
|
|
139
|
+
// instead would trade a safe, slow recovery for an abort of unknown commit
|
|
140
|
+
// extent. A 500 is also frequently transient, so a passing probe would not
|
|
141
|
+
// even establish that the caller's payload was at fault.
|
|
142
|
+
//
|
|
143
|
+
// 400, by contrast, is doubly overloaded AND safe to be strict about: a
|
|
144
|
+
// gateway that does not know the endpoint answers "invalid URL" 400, while TM1
|
|
145
|
+
// answers 400 for a payload it refuses (duplicate sub-request ids,
|
|
146
|
+
// `atomicityGroup`, a body past a proxy's limit). An envelope-level 400 means
|
|
147
|
+
// the envelope was rejected as a whole, before any sub-request ran — so there
|
|
148
|
+
// is no partial commit to protect, and propagating it is the honest outcome.
|
|
149
|
+
const PROBE_STATUS = 400;
|
|
150
|
+
/**
|
|
151
|
+
* Pull TM1's human-readable error text out of a sub-response body.
|
|
152
|
+
*
|
|
153
|
+
* Mirrors `handleResponse`'s extraction in http.ts — INCLUDING its final
|
|
154
|
+
* raw-body fallback. That fallback is load-bearing, not cosmetic: callers
|
|
155
|
+
* classify by message text (e.g. `isAlreadyExists` substring-matches
|
|
156
|
+
* "already exists"), so returning `undefined` for a body that does not nest
|
|
157
|
+
* under `error.message` would downgrade a recognisable error into a generic
|
|
158
|
+
* "TM1 API error (HTTP 400)" and break bulk upsert's idempotency.
|
|
159
|
+
*/
|
|
160
|
+
function extractErrorDetails(body) {
|
|
161
|
+
if (body === null || body === undefined)
|
|
162
|
+
return undefined;
|
|
163
|
+
if (typeof body === "string")
|
|
164
|
+
return body || undefined;
|
|
165
|
+
if (typeof body !== "object")
|
|
166
|
+
return String(body);
|
|
167
|
+
const err = body.error;
|
|
168
|
+
if (err !== null && typeof err === "object") {
|
|
169
|
+
const message = err.message;
|
|
170
|
+
if (typeof message === "string")
|
|
171
|
+
return message;
|
|
172
|
+
if (message !== null && typeof message === "object") {
|
|
173
|
+
const value = message.value;
|
|
174
|
+
if (typeof value === "string")
|
|
175
|
+
return value;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Unrecognised shape — hand back the raw body text, as http.ts does.
|
|
179
|
+
try {
|
|
180
|
+
return JSON.stringify(body) || undefined;
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function toRelativeUrl(path) {
|
|
187
|
+
return path.replace(/^\/api\/v1\//, "");
|
|
188
|
+
}
|
|
189
|
+
function prepare(request) {
|
|
190
|
+
const sub = {
|
|
191
|
+
id: request.id,
|
|
192
|
+
method: request.method,
|
|
193
|
+
// Sub-request URLs are relative to the batch endpoint's service root.
|
|
194
|
+
// Callers pass the same absolute `/api/v1/...` path they would give
|
|
195
|
+
// http.request(), so strip that prefix here — for v12 the profile
|
|
196
|
+
// reroots the `$batch` URL itself, and the relative sub-URL rides along.
|
|
197
|
+
url: toRelativeUrl(request.path),
|
|
198
|
+
...(request.body === undefined
|
|
199
|
+
? {}
|
|
200
|
+
: {
|
|
201
|
+
headers: { "Content-Type": "application/json" },
|
|
202
|
+
body: request.body,
|
|
203
|
+
}),
|
|
204
|
+
};
|
|
205
|
+
// Measure what actually goes on the wire — the whole sub-object, not just
|
|
206
|
+
// the raw body — and in BYTES: an element name in umlauts or CJK costs two
|
|
207
|
+
// to three times its `String.length`.
|
|
208
|
+
return {
|
|
209
|
+
request,
|
|
210
|
+
sub,
|
|
211
|
+
bytes: Buffer.byteLength(JSON.stringify(sub), "utf8") + 1,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Split prepared sub-requests into chunks bounded by BOTH caps: a chunk closes
|
|
216
|
+
* when one more sub-request would push it past the request count OR past the
|
|
217
|
+
* serialized byte budget.
|
|
218
|
+
*
|
|
219
|
+
* A sub-request larger than the entire budget still goes out — alone, in its
|
|
220
|
+
* own chunk. Dropping it would silently lose a write, and refusing to place it
|
|
221
|
+
* would spin forever; the `chunk.length > 0` guard is what buys both.
|
|
222
|
+
*/
|
|
223
|
+
function chunkRequests(prepared) {
|
|
224
|
+
const chunks = [];
|
|
225
|
+
let chunk = [];
|
|
226
|
+
let bytes = 0;
|
|
227
|
+
for (const item of prepared) {
|
|
228
|
+
if (chunk.length > 0 &&
|
|
229
|
+
(chunk.length >= BATCH_MAX_REQUESTS ||
|
|
230
|
+
bytes + item.bytes > BATCH_MAX_PAYLOAD_BYTES)) {
|
|
231
|
+
chunks.push(chunk);
|
|
232
|
+
chunk = [];
|
|
233
|
+
bytes = 0;
|
|
234
|
+
}
|
|
235
|
+
chunk.push(item);
|
|
236
|
+
bytes += item.bytes;
|
|
237
|
+
}
|
|
238
|
+
if (chunk.length > 0)
|
|
239
|
+
chunks.push(chunk);
|
|
240
|
+
return chunks;
|
|
241
|
+
}
|
|
242
|
+
export class BatchService {
|
|
243
|
+
http;
|
|
244
|
+
// Tri-state support verdict, remembered for the lifetime of the client so a
|
|
245
|
+
// server without $batch is probed once, not once per bulk operation.
|
|
246
|
+
supported = null;
|
|
247
|
+
// Whether the counter-probe has already been spent on this connection. Set
|
|
248
|
+
// BEFORE the probe goes out, so an inconclusive probe (systemic failure) is
|
|
249
|
+
// still counted: the bound is "at most once", not "once per undecided 400".
|
|
250
|
+
// Without it a bulk operation that keeps failing 400 would issue one extra
|
|
251
|
+
// round-trip per attempt — a probe storm on top of an already failing run.
|
|
252
|
+
probeSpent = false;
|
|
253
|
+
constructor(http) {
|
|
254
|
+
this.http = http;
|
|
255
|
+
}
|
|
256
|
+
/** True once a probe has established the server rejects `$batch` outright. */
|
|
257
|
+
get isKnownUnsupported() {
|
|
258
|
+
return this.supported === false;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Record a "this server has no usable `$batch`" verdict — but ONLY while no
|
|
262
|
+
* batch has ever succeeded on this connection.
|
|
263
|
+
*
|
|
264
|
+
* That precondition is the whole safety argument for the caller's fallback.
|
|
265
|
+
* `BatchUnsupportedError` makes callers restart their operation on the
|
|
266
|
+
* per-request path. While `supported === null` no chunk has ever come back
|
|
267
|
+
* 200, so the failure can only be in the caller's FIRST pass. Note what that
|
|
268
|
+
* bounds: WHICH writes may be replayed, not WHETHER anything was committed —
|
|
269
|
+
* `$batch` is non-atomic, so sub-requests processed before the failure stay
|
|
270
|
+
* committed. Callers must keep that first pass replay-safe.
|
|
271
|
+
*
|
|
272
|
+
* Once `supported === true`, a later failure — a flaky gateway answering
|
|
273
|
+
* chunk 2 with HTML or a 400 — is a real error and is propagated verbatim, so
|
|
274
|
+
* a half-finished batch is never silently replayed. That is what keeps the
|
|
275
|
+
* destructive later passes (type PATCH, Components) out of the fallback
|
|
276
|
+
* window entirely: they only ever run after a batch has already succeeded.
|
|
277
|
+
*
|
|
278
|
+
* NOTE: for HTTP 400 the caller in `executeChunk` runs `counterProbe` BEFORE
|
|
279
|
+
* reaching here, so a payload-caused 400 never gets this far. This method
|
|
280
|
+
* still sees every other unsupported status directly.
|
|
281
|
+
*
|
|
282
|
+
* Returns the error to throw, or `undefined` when the verdict was refused.
|
|
283
|
+
*/
|
|
284
|
+
markUnsupported(reason) {
|
|
285
|
+
if (this.supported !== null)
|
|
286
|
+
return undefined;
|
|
287
|
+
this.supported = false;
|
|
288
|
+
return new BatchUnsupportedError(reason);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Settle an ambiguous first-call 400 by asking the endpoint the simplest
|
|
292
|
+
* question there is: one minimal, side-effect-free GET in a well-formed
|
|
293
|
+
* envelope.
|
|
294
|
+
*
|
|
295
|
+
* Judges the ENVELOPE only, exactly as `executeChunk` does — a readable
|
|
296
|
+
* `responses` array means `$batch` is served here, whatever status the probe's
|
|
297
|
+
* own sub-request came back with. That distinction is load-bearing: a
|
|
298
|
+
* locked-down account may well be refused `Configuration/ProductVersion`
|
|
299
|
+
* (reported INSIDE the envelope), and reading that as "no $batch" would
|
|
300
|
+
* reintroduce the very misdiagnosis this probe exists to remove.
|
|
301
|
+
*
|
|
302
|
+
* Returns `true` when `$batch` demonstrably works, `false` when the endpoint
|
|
303
|
+
* refuses even this envelope. THROWS on a systemic transport/auth/timeout
|
|
304
|
+
* failure: that proves nothing either way, so the caller must draw no
|
|
305
|
+
* conclusion and the outage surfaces instead — same rule `executeChunk`
|
|
306
|
+
* already applies via `rethrowIfSystemic`.
|
|
307
|
+
*
|
|
308
|
+
* Does not go through `execute`/`executeChunk`, so it cannot recurse into
|
|
309
|
+
* itself or into the unsupported-detection path.
|
|
310
|
+
*/
|
|
311
|
+
async counterProbe() {
|
|
312
|
+
const payload = {
|
|
313
|
+
requests: [
|
|
314
|
+
{
|
|
315
|
+
id: BATCH_PROBE_ID,
|
|
316
|
+
method: "GET",
|
|
317
|
+
url: toRelativeUrl(BATCH_PROBE_PATH),
|
|
318
|
+
},
|
|
319
|
+
],
|
|
320
|
+
};
|
|
321
|
+
let envelope;
|
|
322
|
+
try {
|
|
323
|
+
envelope = await this.http.request("POST", BATCH_PATH, payload, {
|
|
324
|
+
// Same budget a 1-request chunk gets. Deliberately not a short
|
|
325
|
+
// fail-fast timeout: a timeout maps to LOCK_TIMEOUT, which is systemic
|
|
326
|
+
// and would surface instead of the caller's 400 — turning a slow-but-
|
|
327
|
+
// working server into a hard failure where today it merely falls back.
|
|
328
|
+
timeoutMs: BATCH_TIMEOUT_BASE_MS + BATCH_TIMEOUT_PER_REQUEST_MS,
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
catch (err) {
|
|
332
|
+
rethrowIfSystemic(err);
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
return Array.isArray(envelope?.responses);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Run `requests` in as few round-trips as possible and return one result per
|
|
339
|
+
* request, in the order given.
|
|
340
|
+
*
|
|
341
|
+
* A failing sub-request is DATA, not an exception: it comes back as
|
|
342
|
+
* `{ok:false, error}` so the caller can report partial success. Only a
|
|
343
|
+
* whole-envelope failure throws — `BatchUnsupportedError` if the server has no
|
|
344
|
+
* `$batch`, or the underlying TM1Error for a transport/auth/timeout failure.
|
|
345
|
+
*
|
|
346
|
+
* POST /api/v1/$batch
|
|
347
|
+
*/
|
|
348
|
+
async execute(requests) {
|
|
349
|
+
if (requests.length === 0)
|
|
350
|
+
return [];
|
|
351
|
+
if (this.supported === false) {
|
|
352
|
+
throw new BatchUnsupportedError("a previous probe on this connection was rejected");
|
|
353
|
+
}
|
|
354
|
+
const results = [];
|
|
355
|
+
// Chunks stay SERIAL. These are mutations: overlapping envelopes would make
|
|
356
|
+
// "how much committed before the failure" unanswerable, and TM1 processes a
|
|
357
|
+
// batch sequentially server-side anyway, so there is nothing to win.
|
|
358
|
+
for (const chunk of chunkRequests(requests.map(prepare))) {
|
|
359
|
+
results.push(...(await this.executeChunk(chunk)));
|
|
360
|
+
}
|
|
361
|
+
return results;
|
|
362
|
+
}
|
|
363
|
+
async executeChunk(chunk) {
|
|
364
|
+
// Sub-objects were built (and measured) once during chunking.
|
|
365
|
+
const payload = { requests: chunk.map((c) => c.sub) };
|
|
366
|
+
let envelope;
|
|
367
|
+
try {
|
|
368
|
+
envelope = await this.http.request("POST", BATCH_PATH, payload, {
|
|
369
|
+
timeoutMs: BATCH_TIMEOUT_BASE_MS + chunk.length * BATCH_TIMEOUT_PER_REQUEST_MS,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
catch (err) {
|
|
373
|
+
// A transport/auth/timeout failure is NOT evidence that $batch is
|
|
374
|
+
// missing. Swallowing it into "unsupported" would silently re-run every
|
|
375
|
+
// write down the fallback path on a network blip.
|
|
376
|
+
rethrowIfSystemic(err);
|
|
377
|
+
if (err instanceof TM1Error &&
|
|
378
|
+
err.httpStatus !== undefined &&
|
|
379
|
+
UNSUPPORTED_STATUSES.has(err.httpStatus)) {
|
|
380
|
+
// A 400 before the first success is ambiguous: missing endpoint, or a
|
|
381
|
+
// payload this server refuses? Getting that wrong pins the connection
|
|
382
|
+
// to "no $batch" for the whole session and silently drops every later
|
|
383
|
+
// bulk write onto the N-times-slower per-request path. So counter-probe
|
|
384
|
+
// once — but only while the verdict is still open, and only for the one
|
|
385
|
+
// status where the answer can differ (see PROBE_STATUS).
|
|
386
|
+
if (err.httpStatus === PROBE_STATUS &&
|
|
387
|
+
this.supported === null &&
|
|
388
|
+
!this.probeSpent) {
|
|
389
|
+
this.probeSpent = true;
|
|
390
|
+
if (await this.counterProbe()) {
|
|
391
|
+
// $batch works here; the 400 was about the caller's payload. Record
|
|
392
|
+
// that so no later failure ever reaches the fallback path, and let
|
|
393
|
+
// the original error through as the real failure it is. The
|
|
394
|
+
// caller's writes are NOT retried here — an envelope-level 400 was
|
|
395
|
+
// refused whole, and re-driving it would just fail again.
|
|
396
|
+
this.supported = true;
|
|
397
|
+
throw err;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
const unsupported = this.markUnsupported(`POST ${BATCH_PATH} returned HTTP ${err.httpStatus}`);
|
|
401
|
+
if (unsupported)
|
|
402
|
+
throw unsupported;
|
|
403
|
+
}
|
|
404
|
+
throw err;
|
|
405
|
+
}
|
|
406
|
+
const responses = envelope?.responses;
|
|
407
|
+
if (!Array.isArray(responses)) {
|
|
408
|
+
// 200 but not an OData batch envelope — a proxy or a look-alike endpoint.
|
|
409
|
+
// Treat as unsupported rather than guessing at the shape, but only if
|
|
410
|
+
// $batch never worked here; mid-operation this is a hard error (see
|
|
411
|
+
// markUnsupported).
|
|
412
|
+
const unsupported = this.markUnsupported(`response had no "responses" array`);
|
|
413
|
+
if (unsupported)
|
|
414
|
+
throw unsupported;
|
|
415
|
+
throw new TM1Error({
|
|
416
|
+
code: TM1ErrorCode.TM1_ERROR,
|
|
417
|
+
message: `TM1 $batch returned a 200 response without a "responses" array after $batch had already worked on this connection`,
|
|
418
|
+
endpoint: BATCH_PATH,
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
this.supported = true;
|
|
422
|
+
// OData does not promise response order, so correlate by id.
|
|
423
|
+
const byId = new Map();
|
|
424
|
+
for (const raw of responses) {
|
|
425
|
+
if (raw && raw.id !== undefined)
|
|
426
|
+
byId.set(String(raw.id), raw);
|
|
427
|
+
}
|
|
428
|
+
return chunk.map(({ request: req }) => {
|
|
429
|
+
const raw = byId.get(req.id);
|
|
430
|
+
if (!raw) {
|
|
431
|
+
return {
|
|
432
|
+
id: req.id,
|
|
433
|
+
status: 0,
|
|
434
|
+
ok: false,
|
|
435
|
+
error: new TM1Error({
|
|
436
|
+
code: TM1ErrorCode.TM1_ERROR,
|
|
437
|
+
message: `TM1 $batch returned no response for request id "${req.id}"`,
|
|
438
|
+
endpoint: req.path,
|
|
439
|
+
}),
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
const status = typeof raw.status === "number" ? raw.status : 0;
|
|
443
|
+
if (status >= 200 && status < 300) {
|
|
444
|
+
return { id: req.id, status, ok: true, body: raw.body };
|
|
445
|
+
}
|
|
446
|
+
return {
|
|
447
|
+
id: req.id,
|
|
448
|
+
status,
|
|
449
|
+
ok: false,
|
|
450
|
+
error: classifyHttpError(status, req.path, extractErrorDetails(raw.body)),
|
|
451
|
+
};
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
//# sourceMappingURL=batch-service.js.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { CalculationTraceNode, CellValue, FedCellDescriptor, FeederTraceResult, MdxResult } from "../../types.js";
|
|
2
|
+
import type { RequestOptions, TM1HttpClient } from "../http.js";
|
|
3
|
+
export declare class CellService {
|
|
4
|
+
private readonly http;
|
|
5
|
+
constructor(http: TM1HttpClient);
|
|
6
|
+
/**
|
|
7
|
+
* Get a single cell value via a 1-tuple MDX query.
|
|
8
|
+
*
|
|
9
|
+
* TM1 11.8 returns 0 cells for `SELECT {} ON COLUMNS WHERE (...)` — the
|
|
10
|
+
* empty axis collapses the cellset. Put the first element on COLUMNS and
|
|
11
|
+
* the rest in WHERE to force a 1-cell cellset. Each element is qualified
|
|
12
|
+
* with its dimension to avoid name collisions in control cubes.
|
|
13
|
+
*/
|
|
14
|
+
getValue(cubeName: string, elements: string[]): Promise<CellValue>;
|
|
15
|
+
/**
|
|
16
|
+
* Execute an MDX query and return structured cells + axes. Supports
|
|
17
|
+
* pagination via top/skip on the Cells expand. opts.timeoutMs overrides the
|
|
18
|
+
* 30s default for heavy queries.
|
|
19
|
+
* POST /api/v1/ExecuteMDX
|
|
20
|
+
*/
|
|
21
|
+
executeMdx(mdx: string, top?: number, skip?: number, opts?: RequestOptions): Promise<MdxResult>;
|
|
22
|
+
/**
|
|
23
|
+
* Write multiple cells via the cellset PATCH path.
|
|
24
|
+
*
|
|
25
|
+
* TM1 11.8's Cube /tm1.Update action rejects every documented payload
|
|
26
|
+
* variant ("Invalid CellDescriptor property" / "Unexpected entity reference
|
|
27
|
+
* type" / "Expecting Object or EntityBind"). The cellset PATCH path is the
|
|
28
|
+
* supported route in 11.8:
|
|
29
|
+
* 1. POST /api/v1/ExecuteMDX with a slice MDX over the target cell
|
|
30
|
+
* 2. PATCH /api/v1/Cellsets('{id}')/Cells(0) with {Value}
|
|
31
|
+
* 3. DELETE /api/v1/Cellsets('{id}')
|
|
32
|
+
*
|
|
33
|
+
* Values can be numeric (for N-cubes) or strings (for string cells). Writes
|
|
34
|
+
* to consolidated cells are rejected by TM1.
|
|
35
|
+
*
|
|
36
|
+
* Prefer TI processes for reproducible data loads. Use this REST path only
|
|
37
|
+
* for ad-hoc / debugging writes.
|
|
38
|
+
*/
|
|
39
|
+
writeCells(cubeName: string, dimensions: string[], cells: Array<{
|
|
40
|
+
elements: string[];
|
|
41
|
+
value: number | string;
|
|
42
|
+
}>): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Resolve the cube's dimension order and build Tuple@odata.bind paths for
|
|
45
|
+
* the cell-bound trace actions. Elements address the default hierarchy
|
|
46
|
+
* (same name as the dimension) — alternate hierarchies are not supported
|
|
47
|
+
* by these diagnostics tools.
|
|
48
|
+
*/
|
|
49
|
+
private tupleBinds;
|
|
50
|
+
/**
|
|
51
|
+
* Check the feeders of a cell: returns the cells fed by this cell with a
|
|
52
|
+
* Fed flag per target — Fed=false marks a broken/missing feeder. v11 only.
|
|
53
|
+
* POST /api/v1/Cubes('{cube}')/tm1.CheckFeeders
|
|
54
|
+
*/
|
|
55
|
+
checkFeeders(cubeName: string, elements: string[], opts?: RequestOptions): Promise<FedCellDescriptor[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Trace the feeders of a cell: returns the cells this cell feeds plus the
|
|
58
|
+
* feeder statements involved. v11 only.
|
|
59
|
+
* POST /api/v1/Cubes('{cube}')/tm1.TraceFeeders
|
|
60
|
+
*/
|
|
61
|
+
traceFeeders(cubeName: string, elements: string[], opts?: RequestOptions): Promise<FeederTraceResult>;
|
|
62
|
+
/**
|
|
63
|
+
* Trace how a cell value is calculated: recursive component tree with
|
|
64
|
+
* per-component type (consolidation/rule), status, value, and rule
|
|
65
|
+
* statements. The server returns the full tree; maxDepth/maxComponents
|
|
66
|
+
* truncate client-side to keep responses bounded. v11 only.
|
|
67
|
+
* POST /api/v1/Cubes('{cube}')/tm1.TraceCellCalculation
|
|
68
|
+
*/
|
|
69
|
+
traceCellCalculation(cubeName: string, elements: string[], maxDepth?: number, maxComponents?: number, opts?: RequestOptions): Promise<CalculationTraceNode>;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=cell-service.d.ts.map
|