@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,776 @@
|
|
|
1
|
+
import { parseRules } from "./rulesParser.js";
|
|
2
|
+
// OData key-segment encoding: double single quotes (OData literal escaping)
|
|
3
|
+
// before percent-encoding, matching every service's `enc` helper. Cube/dim
|
|
4
|
+
// names here come from semi-trusted rule text, so a `'` must not pass through raw.
|
|
5
|
+
const odataKey = (s) => encodeURIComponent(String(s).replace(/'/g, "''"));
|
|
6
|
+
// ─── String/comment neutralization ──────────────────────────────────────────
|
|
7
|
+
/** Replaces quoted strings with same-length spaces and strips trailing comments. */
|
|
8
|
+
/**
|
|
9
|
+
* Names out of an OData collection body (`{value:[{Name}]}`). Written against
|
|
10
|
+
* `unknown` rather than a cast: `JSON.parse` hands back `any`, and an assumed
|
|
11
|
+
* `{Name: string}` element would let a malformed body reach `String()` as
|
|
12
|
+
* undefined and land "undefined" in the resolved-name set.
|
|
13
|
+
*/
|
|
14
|
+
function odataNames(parsed) {
|
|
15
|
+
if (typeof parsed !== "object" || parsed === null)
|
|
16
|
+
return [];
|
|
17
|
+
const value = parsed.value;
|
|
18
|
+
if (!Array.isArray(value))
|
|
19
|
+
return [];
|
|
20
|
+
const names = [];
|
|
21
|
+
for (const entry of value) {
|
|
22
|
+
if (typeof entry !== "object" || entry === null)
|
|
23
|
+
continue;
|
|
24
|
+
const name = entry.Name;
|
|
25
|
+
if (typeof name === "string")
|
|
26
|
+
names.push(name);
|
|
27
|
+
}
|
|
28
|
+
return names;
|
|
29
|
+
}
|
|
30
|
+
function neutralizeLine(line) {
|
|
31
|
+
return line
|
|
32
|
+
.replace(/'[^']*'/g, (s) => " ".repeat(s.length))
|
|
33
|
+
.replace(/#.*$/, "");
|
|
34
|
+
}
|
|
35
|
+
// ─── Existing helpers ────────────────────────────────────────────────────────
|
|
36
|
+
function hasUnclosedBracket(trimmed) {
|
|
37
|
+
const stripped = neutralizeLine(trimmed);
|
|
38
|
+
let depth = 0;
|
|
39
|
+
for (const ch of stripped) {
|
|
40
|
+
if (ch === "[") {
|
|
41
|
+
depth++;
|
|
42
|
+
}
|
|
43
|
+
else if (ch === "]") {
|
|
44
|
+
depth--;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return depth > 0;
|
|
48
|
+
}
|
|
49
|
+
function endsSemicolon(trimmed) {
|
|
50
|
+
const noComment = trimmed.replace(/#.*$/, "").trim();
|
|
51
|
+
return noComment.endsWith(";");
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Returns the net change in parenthesis depth for a line (after neutralizing strings/comments).
|
|
55
|
+
* Positive = more open parens, negative = more close parens.
|
|
56
|
+
*/
|
|
57
|
+
function parenDepthChange(trimmed) {
|
|
58
|
+
const stripped = neutralizeLine(trimmed);
|
|
59
|
+
let delta = 0;
|
|
60
|
+
for (const ch of stripped) {
|
|
61
|
+
if (ch === "(") {
|
|
62
|
+
delta++;
|
|
63
|
+
}
|
|
64
|
+
else if (ch === ")") {
|
|
65
|
+
delta--;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return delta;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Returns true if the right-hand side of a rule assignment continues on the
|
|
72
|
+
* next line. Triggered when the line ends with a rule-type marker (N:, C:, S:)
|
|
73
|
+
* or a bare `=` (without `==`, without `=>`).
|
|
74
|
+
* Examples: `[plan_source:'goal']=N:` → true, `['Kennzahl':'Personalkapazitaet'] =` → true
|
|
75
|
+
*/
|
|
76
|
+
function endsWithRuleTypeMarker(trimmed) {
|
|
77
|
+
const stripped = neutralizeLine(trimmed);
|
|
78
|
+
if (/[CNS]\s*:\s*$/i.test(stripped)) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
if (/(^|[^=])=\s*$/.test(stripped)) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Returns true if the line ends with a TM1 backslash line-continuation marker.
|
|
88
|
+
* After stripping comments and trailing whitespace, the last char must be `\`.
|
|
89
|
+
*/
|
|
90
|
+
function endsWithBackslashContinuation(trimmed) {
|
|
91
|
+
const stripped = trimmed.replace(/#.*$/, "").replace(/\s+$/, "");
|
|
92
|
+
return stripped.endsWith("\\");
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Returns true if the line ends with a binary operator that requires an RHS
|
|
96
|
+
* on the following line: `|`, `+`, `-`, `*`, `/`, `\`, `&`, `,`.
|
|
97
|
+
* (Rule-specific: `\` is float division in TM1 rules.)
|
|
98
|
+
*/
|
|
99
|
+
function endsWithContinuingOperator(trimmed) {
|
|
100
|
+
const stripped = neutralizeLine(trimmed).replace(/\s+$/, "");
|
|
101
|
+
return /[|+\-*/\\&,]$/.test(stripped);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Returns true if the trimmed line begins with a binary operator
|
|
105
|
+
* (`*`, `/`, `\`, `+`, `-`, `|`, `&`). Such lines continue the previous statement.
|
|
106
|
+
*/
|
|
107
|
+
function startsWithContinuingOperator(trimmed) {
|
|
108
|
+
return /^[*/\\+\-|&]/.test(trimmed);
|
|
109
|
+
}
|
|
110
|
+
// ─── Phase 1: Bracket extraction & syntax validation ────────────────────────
|
|
111
|
+
/**
|
|
112
|
+
* Extracts all [...] block contents from a line (from original, not neutralized).
|
|
113
|
+
* Uses neutralized positions to avoid false positives inside strings/comments.
|
|
114
|
+
*/
|
|
115
|
+
export function extractBracketRefs(line) {
|
|
116
|
+
const neutralized = neutralizeLine(line);
|
|
117
|
+
const results = [];
|
|
118
|
+
let depth = 0;
|
|
119
|
+
let start = -1;
|
|
120
|
+
for (let i = 0; i < neutralized.length; i++) {
|
|
121
|
+
const ch = neutralized[i];
|
|
122
|
+
if (ch === "[") {
|
|
123
|
+
if (depth === 0) {
|
|
124
|
+
start = i + 1;
|
|
125
|
+
}
|
|
126
|
+
depth++;
|
|
127
|
+
}
|
|
128
|
+
else if (ch === "]") {
|
|
129
|
+
depth--;
|
|
130
|
+
if (depth === 0 && start !== -1) {
|
|
131
|
+
results.push(line.slice(start, i).trim());
|
|
132
|
+
start = -1;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return results;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Validates the syntax of a [...] cell reference content (without outer brackets).
|
|
140
|
+
* Returns an error message or null if valid.
|
|
141
|
+
*
|
|
142
|
+
* Valid forms:
|
|
143
|
+
* 'DimName':'ElemName'
|
|
144
|
+
* 'DimName':{'E1','E2',...}
|
|
145
|
+
* Multiple of the above separated by commas
|
|
146
|
+
*/
|
|
147
|
+
export function validateBracketRefSyntax(content) {
|
|
148
|
+
if (content.trim() === "") {
|
|
149
|
+
return "[invalid-cell-ref-syntax] Empty cell reference [].";
|
|
150
|
+
}
|
|
151
|
+
// No quotes → likely a dynamic/variable reference (e.g. !Year) — skip validation
|
|
152
|
+
if (!content.includes("'")) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
const singleElem = `'[^']+'\\s*:\\s*'[^']+'`;
|
|
156
|
+
const multiElem = `'[^']+'\\s*:\\s*\\{\\s*'[^']+'(?:\\s*,\\s*'[^']+')*\\s*\\}`;
|
|
157
|
+
const dimSpec = `(?:${multiElem}|${singleElem})`;
|
|
158
|
+
const fullRe = new RegExp(`^\\s*${dimSpec}(?:\\s*,\\s*${dimSpec})*\\s*$`);
|
|
159
|
+
if (fullRe.test(content)) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
// Identify the offending sub-spec: split content on top-level commas, find
|
|
163
|
+
// the first part that doesn't match the dimSpec pattern.
|
|
164
|
+
const parts = splitTopLevelCommas(content);
|
|
165
|
+
const partRe = new RegExp(`^\\s*${dimSpec}\\s*$`);
|
|
166
|
+
for (const part of parts) {
|
|
167
|
+
if (!partRe.test(part)) {
|
|
168
|
+
return `[invalid-cell-ref-syntax] '${part.trim()}' does not match the format 'Dimension':'Element' or 'Dimension':{'E1','E2'}.`;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return "[invalid-cell-ref-syntax] Cell reference does not match the format ['Dimension':'Element'] or ['Dimension':{'E1','E2'}].";
|
|
172
|
+
}
|
|
173
|
+
/** Splits a string by commas that are NOT inside `{...}` (brace-depth 0). */
|
|
174
|
+
function splitTopLevelCommas(s) {
|
|
175
|
+
const out = [];
|
|
176
|
+
let depth = 0;
|
|
177
|
+
let cur = "";
|
|
178
|
+
for (const ch of s) {
|
|
179
|
+
if (ch === "{") {
|
|
180
|
+
depth++;
|
|
181
|
+
}
|
|
182
|
+
else if (ch === "}") {
|
|
183
|
+
depth = Math.max(0, depth - 1);
|
|
184
|
+
}
|
|
185
|
+
if (ch === "," && depth === 0) {
|
|
186
|
+
out.push(cur);
|
|
187
|
+
cur = "";
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
cur += ch;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
out.push(cur);
|
|
194
|
+
return out.filter((p) => p.trim().length > 0);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Parses 'DimName':'ElemName' pairs from a bracket ref content.
|
|
198
|
+
* Only handles quoted string literals — dynamic refs are ignored.
|
|
199
|
+
*/
|
|
200
|
+
export function parseBracketDimRefs(content) {
|
|
201
|
+
const result = [];
|
|
202
|
+
const dimSpecRe = /'([^']+)'\s*:\s*(?:'([^']+)'|\{([^}]+)\})/g;
|
|
203
|
+
let m;
|
|
204
|
+
while ((m = dimSpecRe.exec(content)) !== null) {
|
|
205
|
+
const dim = m[1];
|
|
206
|
+
if (m[2] !== undefined) {
|
|
207
|
+
result.push({ dim, elems: [m[2]] });
|
|
208
|
+
}
|
|
209
|
+
else if (m[3] !== undefined) {
|
|
210
|
+
const elems = [...m[3].matchAll(/'([^']+)'/g)].map((r) => r[1]);
|
|
211
|
+
result.push({ dim, elems });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return result;
|
|
215
|
+
}
|
|
216
|
+
/** Splits a comma-separated DB() argument string, respecting nested parens and quotes. */
|
|
217
|
+
function splitArgs(argsStr) {
|
|
218
|
+
if (!argsStr.trim()) {
|
|
219
|
+
return [];
|
|
220
|
+
}
|
|
221
|
+
const args = [];
|
|
222
|
+
let depth = 0;
|
|
223
|
+
let inString = false;
|
|
224
|
+
let current = "";
|
|
225
|
+
for (const ch of argsStr) {
|
|
226
|
+
if (ch === "'" && !inString) {
|
|
227
|
+
inString = true;
|
|
228
|
+
current += ch;
|
|
229
|
+
}
|
|
230
|
+
else if (ch === "'" && inString) {
|
|
231
|
+
inString = false;
|
|
232
|
+
current += ch;
|
|
233
|
+
}
|
|
234
|
+
else if (!inString && ch === "(") {
|
|
235
|
+
depth++;
|
|
236
|
+
current += ch;
|
|
237
|
+
}
|
|
238
|
+
else if (!inString && ch === ")") {
|
|
239
|
+
depth--;
|
|
240
|
+
current += ch;
|
|
241
|
+
}
|
|
242
|
+
else if (!inString && depth === 0 && ch === ",") {
|
|
243
|
+
args.push(current.trim());
|
|
244
|
+
current = "";
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
current += ch;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
args.push(current.trim());
|
|
251
|
+
return args.filter((a) => a !== "");
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Extracts all DB(...) calls from a line with their parsed arguments.
|
|
255
|
+
* Uses neutralized positions to skip DB() inside strings/comments.
|
|
256
|
+
*/
|
|
257
|
+
export function extractDbCalls(line) {
|
|
258
|
+
const neutralized = neutralizeLine(line);
|
|
259
|
+
const results = [];
|
|
260
|
+
const dbRe = /\bDB\s*\(/gi;
|
|
261
|
+
let m;
|
|
262
|
+
while ((m = dbRe.exec(neutralized)) !== null) {
|
|
263
|
+
const openPos = m.index + m[0].length - 1; // index of '('
|
|
264
|
+
let depth = 1;
|
|
265
|
+
let i = openPos + 1;
|
|
266
|
+
while (i < neutralized.length && depth > 0) {
|
|
267
|
+
if (neutralized[i] === "(") {
|
|
268
|
+
depth++;
|
|
269
|
+
}
|
|
270
|
+
else if (neutralized[i] === ")") {
|
|
271
|
+
depth--;
|
|
272
|
+
}
|
|
273
|
+
i++;
|
|
274
|
+
}
|
|
275
|
+
if (depth !== 0) {
|
|
276
|
+
continue;
|
|
277
|
+
} // unmatched paren — skip
|
|
278
|
+
const argsStr = line.slice(openPos + 1, i - 1);
|
|
279
|
+
const args = splitArgs(argsStr);
|
|
280
|
+
const first = args[0]?.trim() ?? "";
|
|
281
|
+
const cubeName = first.startsWith("'") && first.endsWith("'") && first.length >= 3
|
|
282
|
+
? first.slice(1, -1)
|
|
283
|
+
: null;
|
|
284
|
+
results.push({ args, cubeName });
|
|
285
|
+
}
|
|
286
|
+
return results;
|
|
287
|
+
}
|
|
288
|
+
// ─── Synchronous linter ──────────────────────────────────────────────────────
|
|
289
|
+
export function lintRules(text) {
|
|
290
|
+
const ast = parseRules(text);
|
|
291
|
+
const diags = [];
|
|
292
|
+
// --- Structural checks ---
|
|
293
|
+
if (ast.feedersCount === 0) {
|
|
294
|
+
const hasContent = ast.lines.some((l) => !l.isBlank && !l.isComment && !l.isSkipcheck);
|
|
295
|
+
if (hasContent) {
|
|
296
|
+
diags.push({
|
|
297
|
+
line: 0,
|
|
298
|
+
message: "[no-feeders-section] No FEEDERS; block found. Without feeders no rules are calculated.",
|
|
299
|
+
severity: "warning",
|
|
300
|
+
ruleId: "no-feeders-section",
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (ast.feedersCount > 1) {
|
|
305
|
+
let seen = 0;
|
|
306
|
+
for (const l of ast.lines) {
|
|
307
|
+
if (l.isFeedersMarker) {
|
|
308
|
+
seen++;
|
|
309
|
+
if (seen > 1) {
|
|
310
|
+
diags.push({
|
|
311
|
+
line: l.lineIndex,
|
|
312
|
+
message: "[multiple-feeders] Multiple FEEDERS; markers found. Only the first is recognized by TM1.",
|
|
313
|
+
severity: "error",
|
|
314
|
+
ruleId: "multiple-feeders",
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// --- Per-line checks ---
|
|
321
|
+
// Pre-compute: for each statement line, does the NEXT statement line start
|
|
322
|
+
// with a binary operator (`*`, `/`, `\`, `+`, `-`, `|`, `&`)? If yes, the
|
|
323
|
+
// current line is continued and must not be flagged missing-semicolon.
|
|
324
|
+
const continuedByNextLine = new Set();
|
|
325
|
+
{
|
|
326
|
+
let prev = -1;
|
|
327
|
+
for (const l of ast.lines) {
|
|
328
|
+
if (l.isBlank || l.isComment || l.isSkipcheck || l.isFeedersMarker) {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
if (prev !== -1 && startsWithContinuingOperator(l.trimmed)) {
|
|
332
|
+
continuedByNextLine.add(prev);
|
|
333
|
+
}
|
|
334
|
+
prev = l.lineIndex;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
// Tracks net open parentheses across lines to detect continuation lines.
|
|
338
|
+
// A line is a continuation if parenDepth > 0 before it (previous line(s) left open parens).
|
|
339
|
+
let parenDepth = 0;
|
|
340
|
+
// True when the previous non-blank line ended with a bare rule-type marker (N:, C:, S:)
|
|
341
|
+
// meaning the expression part follows on the next line.
|
|
342
|
+
let pendingRuleExpr = false;
|
|
343
|
+
// True when we are inside a feeder statement whose => has not appeared yet.
|
|
344
|
+
// Prevents false missing-semicolon on feeder lines like `DB(...)` that are
|
|
345
|
+
// the LHS of a multi-line feeder where => comes on the following line.
|
|
346
|
+
let pendingFeedersArrow = false;
|
|
347
|
+
// True when previous line ended with a backslash line-continuation marker.
|
|
348
|
+
let pendingBackslashCont = false;
|
|
349
|
+
// True when previous line ended with a binary operator (|, +, -, *, /, \, &, ,).
|
|
350
|
+
let pendingContinuingOp = false;
|
|
351
|
+
// True when previous line is continued by the current one (current starts with operator).
|
|
352
|
+
let pendingNextStartsWithOp = false;
|
|
353
|
+
// True when previous feeder line ended with a closed target (`]` or `)`)
|
|
354
|
+
// without `,`/`;`/`=>` separator — next target must NOT directly follow.
|
|
355
|
+
let pendingFeederNeedsComma = false;
|
|
356
|
+
for (const l of ast.lines) {
|
|
357
|
+
if (l.isBlank || l.isComment || l.isSkipcheck || l.isFeedersMarker) {
|
|
358
|
+
// Comments/blanks can appear mid-statement — do not reset continuation flags.
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
// Is this line a continuation of a multi-line statement?
|
|
362
|
+
const isContinuation = parenDepth > 0 ||
|
|
363
|
+
pendingRuleExpr ||
|
|
364
|
+
pendingFeedersArrow ||
|
|
365
|
+
pendingBackslashCont ||
|
|
366
|
+
pendingContinuingOp ||
|
|
367
|
+
pendingNextStartsWithOp;
|
|
368
|
+
parenDepth = Math.max(0, parenDepth + parenDepthChange(l.trimmed));
|
|
369
|
+
// Does this line leave parens open (statement continues on next line)?
|
|
370
|
+
const hasOpenParens = parenDepth > 0;
|
|
371
|
+
// Does this line end with a bare rule-type marker? (expression on next line)
|
|
372
|
+
// Also suppresses missing-semicolon for the current line itself.
|
|
373
|
+
pendingRuleExpr = endsWithRuleTypeMarker(l.trimmed);
|
|
374
|
+
const thisLineEndsRuleType = pendingRuleExpr;
|
|
375
|
+
// Does this line end with `\` continuation? (statement continues on next line)
|
|
376
|
+
pendingBackslashCont = endsWithBackslashContinuation(l.trimmed);
|
|
377
|
+
const thisLineEndsBackslash = pendingBackslashCont;
|
|
378
|
+
// Does this line end with a binary operator (|, +, -, *, /, \, &, ,)?
|
|
379
|
+
pendingContinuingOp = endsWithContinuingOperator(l.trimmed);
|
|
380
|
+
const thisLineEndsContOp = pendingContinuingOp;
|
|
381
|
+
// Does the NEXT statement line start with an operator? (computed above)
|
|
382
|
+
const thisLineContinuedByNext = continuedByNextLine.has(l.lineIndex);
|
|
383
|
+
pendingNextStartsWithOp = thisLineContinuedByNext;
|
|
384
|
+
// Unbalanced brackets
|
|
385
|
+
if (hasUnclosedBracket(l.trimmed)) {
|
|
386
|
+
diags.push({
|
|
387
|
+
line: l.lineIndex,
|
|
388
|
+
message: "[unclosed-bracket] Unclosed square bracket `[`.",
|
|
389
|
+
severity: "error",
|
|
390
|
+
ruleId: "unclosed-bracket",
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
const hasSemi = endsSemicolon(l.trimmed);
|
|
394
|
+
if (l.section === "rules") {
|
|
395
|
+
// Only flag missing-semicolon on complete statements (not mid-expression lines).
|
|
396
|
+
// Also suppress when the line ends with a rule-type marker (N:, C:, S:) — expression on next line.
|
|
397
|
+
if (!hasSemi &&
|
|
398
|
+
!isContinuation &&
|
|
399
|
+
!hasOpenParens &&
|
|
400
|
+
!thisLineEndsRuleType &&
|
|
401
|
+
!thisLineEndsBackslash &&
|
|
402
|
+
!thisLineEndsContOp &&
|
|
403
|
+
!thisLineContinuedByNext) {
|
|
404
|
+
diags.push({
|
|
405
|
+
line: l.lineIndex,
|
|
406
|
+
message: "[missing-semicolon] Statement does not end with a semicolon.",
|
|
407
|
+
severity: "error",
|
|
408
|
+
ruleId: "missing-semicolon",
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (l.section === "feeders") {
|
|
413
|
+
// Compute once for all feeder checks on this line.
|
|
414
|
+
const neutralFeed = neutralizeLine(l.trimmed);
|
|
415
|
+
const hasArrow = neutralFeed.includes("=>");
|
|
416
|
+
// Missing-comma between two adjacent feeder targets (cell-ref or DB-call)
|
|
417
|
+
// on separate lines — fires when prev line closed a target without
|
|
418
|
+
// separator and current line starts a new target.
|
|
419
|
+
if (isContinuation && pendingFeederNeedsComma) {
|
|
420
|
+
const startsNewTarget = /^\s*(\[|[A-Za-z_]\w*\s*\()/.test(l.trimmed);
|
|
421
|
+
if (startsNewTarget) {
|
|
422
|
+
diags.push({
|
|
423
|
+
line: l.lineIndex,
|
|
424
|
+
message: "[feeder-missing-comma] Missing comma between feeder targets.",
|
|
425
|
+
severity: "error",
|
|
426
|
+
ruleId: "feeder-missing-comma",
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
// Multiple targets on LHS of feeder: feeder-multi-lhs (error).
|
|
431
|
+
// LHS is the part before `=>`. If LHS contains more than one closing `]`
|
|
432
|
+
// at top level (whether comma-separated or whitespace-separated), it
|
|
433
|
+
// means multiple cell-refs on LHS — invalid (LHS must be a single ref).
|
|
434
|
+
const arrowIdx = neutralFeed.indexOf("=>");
|
|
435
|
+
if (arrowIdx > 0) {
|
|
436
|
+
const lhs = neutralFeed.slice(0, arrowIdx);
|
|
437
|
+
const lhsCloseCount = (lhs.match(/\]/g) || []).length;
|
|
438
|
+
if (lhsCloseCount > 1) {
|
|
439
|
+
diags.push({
|
|
440
|
+
line: l.lineIndex,
|
|
441
|
+
message: "[feeder-multi-lhs] Left-hand side of a feeder must be a single cell reference, not several.",
|
|
442
|
+
severity: "error",
|
|
443
|
+
ruleId: "feeder-multi-lhs",
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
// Same-line missing comma between adjacent targets:
|
|
448
|
+
// `]<ws>[`, `]<ws>Func(`, `)<ws>[`, `)<ws>Func(`.
|
|
449
|
+
// Only fires once per line — first match is enough.
|
|
450
|
+
// Skip the LHS portion of the feeder (before `=>`) to avoid double-flagging
|
|
451
|
+
// the multi-LHS case — that's covered by feeder-multi-lhs.
|
|
452
|
+
const sameLineRe = /[\])]\s+(?:\[|[A-Za-z_]\w*\s*\()/g;
|
|
453
|
+
let m;
|
|
454
|
+
while ((m = sameLineRe.exec(neutralFeed)) !== null) {
|
|
455
|
+
if (arrowIdx >= 0 && m.index < arrowIdx) {
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
diags.push({
|
|
459
|
+
line: l.lineIndex,
|
|
460
|
+
message: "[feeder-missing-comma] Missing comma between feeder targets.",
|
|
461
|
+
severity: "error",
|
|
462
|
+
ruleId: "feeder-missing-comma",
|
|
463
|
+
});
|
|
464
|
+
break;
|
|
465
|
+
}
|
|
466
|
+
// Track whether the feeder statement is still open (no terminating `;`
|
|
467
|
+
// yet). Open feeders span as many lines as needed — => may be on the
|
|
468
|
+
// first line, the RHS may continue with `,` separators across lines.
|
|
469
|
+
if (!isContinuation) {
|
|
470
|
+
pendingFeedersArrow = !hasSemi;
|
|
471
|
+
}
|
|
472
|
+
else if (hasSemi) {
|
|
473
|
+
pendingFeedersArrow = false;
|
|
474
|
+
}
|
|
475
|
+
// Update pendingFeederNeedsComma for the next iteration: true when the
|
|
476
|
+
// current feeder line closes a target (`]` or `)`) without `,`/`;`/`=>`/
|
|
477
|
+
// `\` continuation and parens are balanced.
|
|
478
|
+
const stripped = neutralFeed.replace(/\s+$/, "");
|
|
479
|
+
const lastChar = stripped.slice(-1);
|
|
480
|
+
const endsWithTargetClose = lastChar === "]" || lastChar === ")";
|
|
481
|
+
pendingFeederNeedsComma =
|
|
482
|
+
pendingFeedersArrow &&
|
|
483
|
+
endsWithTargetClose &&
|
|
484
|
+
!hasSemi &&
|
|
485
|
+
!hasOpenParens &&
|
|
486
|
+
!thisLineEndsContOp &&
|
|
487
|
+
!thisLineEndsBackslash &&
|
|
488
|
+
!stripped.endsWith("=>");
|
|
489
|
+
if (!hasSemi &&
|
|
490
|
+
!isContinuation &&
|
|
491
|
+
!hasOpenParens &&
|
|
492
|
+
!thisLineEndsRuleType &&
|
|
493
|
+
!thisLineEndsBackslash &&
|
|
494
|
+
!thisLineEndsContOp &&
|
|
495
|
+
!thisLineContinuedByNext &&
|
|
496
|
+
!pendingFeedersArrow) {
|
|
497
|
+
diags.push({
|
|
498
|
+
line: l.lineIndex,
|
|
499
|
+
message: "[missing-semicolon] Statement does not end with a semicolon.",
|
|
500
|
+
severity: "error",
|
|
501
|
+
ruleId: "missing-semicolon",
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
if (!isContinuation) {
|
|
505
|
+
const strippedFeed = l.trimmed
|
|
506
|
+
.replace(/#.*$/, "")
|
|
507
|
+
.replace(/'[^']*'/g, '""');
|
|
508
|
+
if (!hasArrow && !pendingFeedersArrow) {
|
|
509
|
+
if (strippedFeed.includes("[")) {
|
|
510
|
+
diags.push({
|
|
511
|
+
line: l.lineIndex,
|
|
512
|
+
message: "[feeder-missing-arrow] Feeder line without `=>` operator.",
|
|
513
|
+
severity: "warning",
|
|
514
|
+
ruleId: "feeder-missing-arrow",
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
// DB() is only valid on the RHS of a feeder — the LHS must be a cell ref [...].
|
|
519
|
+
const dbIdx = neutralFeed.search(/\bDB\s*\(/i);
|
|
520
|
+
if (dbIdx !== -1 && (arrowIdx === -1 || dbIdx < arrowIdx)) {
|
|
521
|
+
diags.push({
|
|
522
|
+
line: l.lineIndex,
|
|
523
|
+
message: "[feeder-db-on-lhs] DB() is invalid on the left-hand side of a feeder. The source cell reference must be [...]; DB() is only allowed on the right-hand side.",
|
|
524
|
+
severity: "error",
|
|
525
|
+
ruleId: "feeder-db-on-lhs",
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
if (/=\s*[CNS]\s*:/i.test(strippedFeed)) {
|
|
529
|
+
diags.push({
|
|
530
|
+
line: l.lineIndex,
|
|
531
|
+
message: "[rule-after-feeders] Rule line (C:/N:/S:) after FEEDERS; — rules belong before the FEEDERS block.",
|
|
532
|
+
severity: "warning",
|
|
533
|
+
ruleId: "rule-after-feeders",
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
// Bracket syntax validation (both sections)
|
|
539
|
+
for (const refContent of extractBracketRefs(l.trimmed)) {
|
|
540
|
+
const msg = validateBracketRefSyntax(refContent);
|
|
541
|
+
if (msg !== null) {
|
|
542
|
+
diags.push({
|
|
543
|
+
line: l.lineIndex,
|
|
544
|
+
message: msg,
|
|
545
|
+
severity: "hint",
|
|
546
|
+
ruleId: "invalid-cell-ref-syntax",
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
// DB() static validation (both sections)
|
|
551
|
+
for (const call of extractDbCalls(l.trimmed)) {
|
|
552
|
+
if (call.args.length < 2) {
|
|
553
|
+
diags.push({
|
|
554
|
+
line: l.lineIndex,
|
|
555
|
+
message: "[db-too-few-args] DB() needs at least 2 arguments (cube name + 1 dimension).",
|
|
556
|
+
severity: "error",
|
|
557
|
+
ruleId: "db-too-few-args",
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
else if (call.cubeName === null) {
|
|
561
|
+
diags.push({
|
|
562
|
+
line: l.lineIndex,
|
|
563
|
+
message: "[db-invalid-cube-arg] First DB() argument must be a string literal (cube name in single quotes).",
|
|
564
|
+
severity: "error",
|
|
565
|
+
ruleId: "db-invalid-cube-arg",
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return diags;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Runs server-side lint checks against an active TM1 connection:
|
|
574
|
+
* - DB() argument count vs. actual cube dimension count
|
|
575
|
+
* - Element existence within the referenced dimension
|
|
576
|
+
*
|
|
577
|
+
* Silently returns [] if the server is unreachable or no relevant refs are found.
|
|
578
|
+
*/
|
|
579
|
+
export async function lintRulesServer(text, api) {
|
|
580
|
+
const ast = parseRules(text);
|
|
581
|
+
const diags = [];
|
|
582
|
+
// Maps: lowercase key → original casing (first occurrence wins)
|
|
583
|
+
const cubeOriginal = new Map();
|
|
584
|
+
const dimOriginal = new Map();
|
|
585
|
+
const lineData = [];
|
|
586
|
+
// First pass: collect all DB() calls and valid bracket refs
|
|
587
|
+
for (const l of ast.lines) {
|
|
588
|
+
if (l.isBlank || l.isComment || l.isSkipcheck || l.isFeedersMarker) {
|
|
589
|
+
continue;
|
|
590
|
+
}
|
|
591
|
+
const dbCalls = extractDbCalls(l.trimmed);
|
|
592
|
+
const rawRefs = extractBracketRefs(l.trimmed);
|
|
593
|
+
const bracketRefs = [];
|
|
594
|
+
for (const content of rawRefs) {
|
|
595
|
+
// Only check refs that passed syntax validation and contain quoted literals
|
|
596
|
+
if (validateBracketRefSyntax(content) === null && content.includes("'")) {
|
|
597
|
+
const dimRefs = parseBracketDimRefs(content);
|
|
598
|
+
if (dimRefs.length > 0) {
|
|
599
|
+
bracketRefs.push({ dimRefs });
|
|
600
|
+
for (const { dim } of dimRefs) {
|
|
601
|
+
const lc = dim.toLowerCase();
|
|
602
|
+
if (!dimOriginal.has(lc)) {
|
|
603
|
+
dimOriginal.set(lc, dim);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
for (const call of dbCalls) {
|
|
610
|
+
if (call.cubeName !== null && call.args.length >= 2) {
|
|
611
|
+
const lc = call.cubeName.toLowerCase();
|
|
612
|
+
if (!cubeOriginal.has(lc)) {
|
|
613
|
+
cubeOriginal.set(lc, call.cubeName);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
const hasRelevantDb = dbCalls.some((c) => c.cubeName !== null && c.args.length >= 2);
|
|
618
|
+
if (hasRelevantDb || bracketRefs.length > 0) {
|
|
619
|
+
lineData.push({ lineIndex: l.lineIndex, dbCalls, bracketRefs });
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
if (cubeOriginal.size === 0 && dimOriginal.size === 0) {
|
|
623
|
+
return [];
|
|
624
|
+
}
|
|
625
|
+
// Fetch cube dimensions in parallel (names, not just count)
|
|
626
|
+
const cubeDimDetails = new Map();
|
|
627
|
+
await Promise.all([...cubeOriginal.entries()].map(async ([lc, orig]) => {
|
|
628
|
+
try {
|
|
629
|
+
const res = await api("GET", `Cubes('${odataKey(orig)}')/Dimensions?$select=Name`);
|
|
630
|
+
if (res.statusCode === 404) {
|
|
631
|
+
cubeDimDetails.set(lc, "not-found");
|
|
632
|
+
}
|
|
633
|
+
else if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
634
|
+
const parsed = JSON.parse(res.body);
|
|
635
|
+
const dims = odataNames(parsed);
|
|
636
|
+
cubeDimDetails.set(lc, dims);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
catch {
|
|
640
|
+
/* network error — skip */
|
|
641
|
+
}
|
|
642
|
+
}));
|
|
643
|
+
// Add dimensions referenced by string-literal DB() args to dimOriginal,
|
|
644
|
+
// so their elements are fetched in the next step.
|
|
645
|
+
for (const { dbCalls } of lineData) {
|
|
646
|
+
for (const call of dbCalls) {
|
|
647
|
+
if (call.cubeName === null) {
|
|
648
|
+
continue;
|
|
649
|
+
}
|
|
650
|
+
const dims = cubeDimDetails.get(call.cubeName.toLowerCase());
|
|
651
|
+
if (!Array.isArray(dims) || call.args.length !== dims.length + 1) {
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
for (let i = 1; i < call.args.length; i++) {
|
|
655
|
+
const arg = call.args[i].trim();
|
|
656
|
+
if (!arg.startsWith("'") || !arg.endsWith("'") || arg.length < 3) {
|
|
657
|
+
continue;
|
|
658
|
+
}
|
|
659
|
+
if (arg.slice(1, -1).includes("'")) {
|
|
660
|
+
continue;
|
|
661
|
+
} // concatenation — skip
|
|
662
|
+
const dimIdx = i - 1;
|
|
663
|
+
if (dimIdx < dims.length) {
|
|
664
|
+
const dim = dims[dimIdx];
|
|
665
|
+
const lc = dim.toLowerCase();
|
|
666
|
+
if (!dimOriginal.has(lc)) {
|
|
667
|
+
dimOriginal.set(lc, dim);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
// Fetch dimension elements in parallel (one call per unique dimension)
|
|
674
|
+
const dimElements = new Map();
|
|
675
|
+
await Promise.all([...dimOriginal.entries()].map(async ([lc, orig]) => {
|
|
676
|
+
try {
|
|
677
|
+
const enc = odataKey(orig);
|
|
678
|
+
const res = await api("GET", `Dimensions('${enc}')/Hierarchies('${enc}')/Elements?$select=Name`);
|
|
679
|
+
if (res.statusCode === 404) {
|
|
680
|
+
dimElements.set(lc, "not-found");
|
|
681
|
+
}
|
|
682
|
+
else if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
683
|
+
const parsed = JSON.parse(res.body);
|
|
684
|
+
const names = new Set(odataNames(parsed).map((n) => n.toLowerCase()));
|
|
685
|
+
dimElements.set(lc, names);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
catch {
|
|
689
|
+
/* network error — skip */
|
|
690
|
+
}
|
|
691
|
+
}));
|
|
692
|
+
// Second pass: validate against fetched data
|
|
693
|
+
for (const { lineIndex, dbCalls, bracketRefs } of lineData) {
|
|
694
|
+
// DB() argument count + element checks
|
|
695
|
+
for (const call of dbCalls) {
|
|
696
|
+
if (call.cubeName === null || call.args.length < 2) {
|
|
697
|
+
continue;
|
|
698
|
+
}
|
|
699
|
+
const lc = call.cubeName.toLowerCase();
|
|
700
|
+
const dims = cubeDimDetails.get(lc);
|
|
701
|
+
if (dims === "not-found") {
|
|
702
|
+
diags.push({
|
|
703
|
+
line: lineIndex,
|
|
704
|
+
message: `[db-unknown-cube] Cube '${call.cubeName}' was not found on the server.`,
|
|
705
|
+
severity: "warning",
|
|
706
|
+
ruleId: "db-unknown-cube",
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
else if (Array.isArray(dims)) {
|
|
710
|
+
const expected = dims.length + 1; // cube name + one arg per dimension
|
|
711
|
+
if (call.args.length !== expected) {
|
|
712
|
+
diags.push({
|
|
713
|
+
line: lineIndex,
|
|
714
|
+
message: `[db-arg-count-mismatch] DB('${call.cubeName}') expects ${expected} argument${expected !== 1 ? "s" : ""} (${dims.length} dimension${dims.length !== 1 ? "s" : ""}), but has ${call.args.length}.`,
|
|
715
|
+
severity: "error",
|
|
716
|
+
ruleId: "db-arg-count-mismatch",
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
else {
|
|
720
|
+
// Element existence check for string-literal dimension args
|
|
721
|
+
for (let i = 1; i < call.args.length; i++) {
|
|
722
|
+
const arg = call.args[i].trim();
|
|
723
|
+
if (!arg.startsWith("'") || !arg.endsWith("'") || arg.length < 3) {
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
const inner = arg.slice(1, -1);
|
|
727
|
+
if (inner.includes("'")) {
|
|
728
|
+
continue;
|
|
729
|
+
} // concatenation — skip
|
|
730
|
+
const dimIdx = i - 1;
|
|
731
|
+
const dim = dims[dimIdx];
|
|
732
|
+
const elemSet = dimElements.get(dim.toLowerCase());
|
|
733
|
+
if (elemSet instanceof Set && !elemSet.has(inner.toLowerCase())) {
|
|
734
|
+
diags.push({
|
|
735
|
+
line: lineIndex,
|
|
736
|
+
message: `[db-element-not-found] Element '${inner}' not found in dimension '${dim}' (DB() arg ${i + 1}).`,
|
|
737
|
+
severity: "warning",
|
|
738
|
+
ruleId: "db-element-not-found",
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
// Element existence check
|
|
746
|
+
for (const { dimRefs } of bracketRefs) {
|
|
747
|
+
for (const { dim, elems } of dimRefs) {
|
|
748
|
+
const dimLc = dim.toLowerCase();
|
|
749
|
+
const elemSet = dimElements.get(dimLc);
|
|
750
|
+
if (elemSet === "not-found") {
|
|
751
|
+
diags.push({
|
|
752
|
+
line: lineIndex,
|
|
753
|
+
message: `[dimension-not-found] Dimension '${dim}' was not found on the server.`,
|
|
754
|
+
severity: "error",
|
|
755
|
+
ruleId: "dimension-not-found",
|
|
756
|
+
});
|
|
757
|
+
continue;
|
|
758
|
+
}
|
|
759
|
+
if (elemSet instanceof Set) {
|
|
760
|
+
for (const elem of elems) {
|
|
761
|
+
if (!elemSet.has(elem.toLowerCase())) {
|
|
762
|
+
diags.push({
|
|
763
|
+
line: lineIndex,
|
|
764
|
+
message: `[element-not-found] Element '${elem}' not found in dimension '${dim}'.`,
|
|
765
|
+
severity: "warning",
|
|
766
|
+
ruleId: "element-not-found",
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
return diags;
|
|
775
|
+
}
|
|
776
|
+
//# sourceMappingURL=rulesLinter.js.map
|