@miragon/pulse-widget-shell 0.0.0-stage → 0.22.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/LICENSE +21 -0
- package/README.md +164 -2
- package/dist/adapt-data-widget.d.ts +7 -0
- package/dist/adapt-data-widget.d.ts.map +1 -0
- package/dist/adapt-data-widget.js +7 -0
- package/dist/adapt-data-widget.js.map +1 -0
- package/dist/bpmn-names.d.ts +42 -0
- package/dist/bpmn-names.d.ts.map +1 -0
- package/dist/bpmn-names.js +151 -0
- package/dist/bpmn-names.js.map +1 -0
- package/dist/bpmn-names.test.d.ts +2 -0
- package/dist/bpmn-names.test.d.ts.map +1 -0
- package/dist/bpmn-names.test.js +143 -0
- package/dist/bpmn-names.test.js.map +1 -0
- package/dist/build-data-feed-result.test.d.ts +2 -0
- package/dist/build-data-feed-result.test.d.ts.map +1 -0
- package/dist/build-data-feed-result.test.js +28 -0
- package/dist/build-data-feed-result.test.js.map +1 -0
- package/dist/build-single-widget-view.test.d.ts +2 -0
- package/dist/build-single-widget-view.test.d.ts.map +1 -0
- package/dist/build-single-widget-view.test.js +136 -0
- package/dist/build-single-widget-view.test.js.map +1 -0
- package/dist/builder-texts.d.ts +27 -0
- package/dist/builder-texts.d.ts.map +1 -0
- package/dist/builder-texts.js +32 -0
- package/dist/builder-texts.js.map +1 -0
- package/dist/builder-texts.test.d.ts +2 -0
- package/dist/builder-texts.test.d.ts.map +1 -0
- package/dist/builder-texts.test.js +54 -0
- package/dist/builder-texts.test.js.map +1 -0
- package/dist/catalogue-sync.d.ts +18 -0
- package/dist/catalogue-sync.d.ts.map +1 -0
- package/dist/catalogue-sync.js +31 -0
- package/dist/catalogue-sync.js.map +1 -0
- package/dist/catalogue-sync.test.d.ts +2 -0
- package/dist/catalogue-sync.test.d.ts.map +1 -0
- package/dist/catalogue-sync.test.js +22 -0
- package/dist/catalogue-sync.test.js.map +1 -0
- package/dist/composed-server.d.ts +110 -0
- package/dist/composed-server.d.ts.map +1 -0
- package/dist/composed-server.edge.test.d.ts +2 -0
- package/dist/composed-server.edge.test.d.ts.map +1 -0
- package/dist/composed-server.edge.test.js +184 -0
- package/dist/composed-server.edge.test.js.map +1 -0
- package/dist/composed-server.fonts.test.d.ts +2 -0
- package/dist/composed-server.fonts.test.d.ts.map +1 -0
- package/dist/composed-server.fonts.test.js +186 -0
- package/dist/composed-server.fonts.test.js.map +1 -0
- package/dist/composed-server.js +260 -0
- package/dist/composed-server.js.map +1 -0
- package/dist/composed-server.test.d.ts +2 -0
- package/dist/composed-server.test.d.ts.map +1 -0
- package/dist/composed-server.test.js +332 -0
- package/dist/composed-server.test.js.map +1 -0
- package/dist/composition.d.ts +155 -0
- package/dist/composition.d.ts.map +1 -0
- package/dist/composition.js +163 -0
- package/dist/composition.js.map +1 -0
- package/dist/composition.test.d.ts +2 -0
- package/dist/composition.test.d.ts.map +1 -0
- package/dist/composition.test.js +275 -0
- package/dist/composition.test.js.map +1 -0
- package/dist/dashboard-store-postgres.d.ts +43 -0
- package/dist/dashboard-store-postgres.d.ts.map +1 -0
- package/dist/dashboard-store-postgres.js +225 -0
- package/dist/dashboard-store-postgres.js.map +1 -0
- package/dist/dashboard-store-postgres.test.d.ts +2 -0
- package/dist/dashboard-store-postgres.test.d.ts.map +1 -0
- package/dist/dashboard-store-postgres.test.js +272 -0
- package/dist/dashboard-store-postgres.test.js.map +1 -0
- package/dist/font-assets.d.ts +47 -0
- package/dist/font-assets.d.ts.map +1 -0
- package/dist/font-assets.js +93 -0
- package/dist/font-assets.js.map +1 -0
- package/dist/font-assets.test.d.ts +2 -0
- package/dist/font-assets.test.d.ts.map +1 -0
- package/dist/font-assets.test.js +123 -0
- package/dist/font-assets.test.js.map +1 -0
- package/dist/health.d.ts +59 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +74 -0
- package/dist/health.js.map +1 -0
- package/dist/health.test.d.ts +2 -0
- package/dist/health.test.d.ts.map +1 -0
- package/dist/health.test.js +140 -0
- package/dist/health.test.js.map +1 -0
- package/dist/host-boot.d.ts +56 -0
- package/dist/host-boot.d.ts.map +1 -0
- package/dist/host-boot.js +64 -0
- package/dist/host-boot.js.map +1 -0
- package/dist/host-boot.test.d.ts +2 -0
- package/dist/host-boot.test.d.ts.map +1 -0
- package/dist/host-boot.test.js +59 -0
- package/dist/host-boot.test.js.map +1 -0
- package/dist/http-edge.d.ts +117 -0
- package/dist/http-edge.d.ts.map +1 -0
- package/dist/http-edge.js +219 -0
- package/dist/http-edge.js.map +1 -0
- package/dist/http-edge.test.d.ts +2 -0
- package/dist/http-edge.test.d.ts.map +1 -0
- package/dist/http-edge.test.js +255 -0
- package/dist/http-edge.test.js.map +1 -0
- package/dist/metrics.d.ts +48 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +124 -0
- package/dist/metrics.js.map +1 -0
- package/dist/metrics.test.d.ts +2 -0
- package/dist/metrics.test.d.ts.map +1 -0
- package/dist/metrics.test.js +154 -0
- package/dist/metrics.test.js.map +1 -0
- package/dist/node-listener.d.ts +61 -0
- package/dist/node-listener.d.ts.map +1 -0
- package/dist/node-listener.js +165 -0
- package/dist/node-listener.js.map +1 -0
- package/dist/node-listener.test.d.ts +2 -0
- package/dist/node-listener.test.d.ts.map +1 -0
- package/dist/node-listener.test.js +331 -0
- package/dist/node-listener.test.js.map +1 -0
- package/dist/oauth-env.d.ts +42 -0
- package/dist/oauth-env.d.ts.map +1 -0
- package/dist/oauth-env.js +78 -0
- package/dist/oauth-env.js.map +1 -0
- package/dist/oauth-env.test.d.ts +2 -0
- package/dist/oauth-env.test.d.ts.map +1 -0
- package/dist/oauth-env.test.js +76 -0
- package/dist/oauth-env.test.js.map +1 -0
- package/dist/postgres.d.ts +59 -0
- package/dist/postgres.d.ts.map +1 -0
- package/dist/postgres.js +80 -0
- package/dist/postgres.js.map +1 -0
- package/dist/profile-advisory.d.ts +19 -0
- package/dist/profile-advisory.d.ts.map +1 -0
- package/dist/profile-advisory.js +48 -0
- package/dist/profile-advisory.js.map +1 -0
- package/dist/profile-advisory.test.d.ts +2 -0
- package/dist/profile-advisory.test.d.ts.map +1 -0
- package/dist/profile-advisory.test.js +53 -0
- package/dist/profile-advisory.test.js.map +1 -0
- package/dist/profile-constants.d.ts +37 -0
- package/dist/profile-constants.d.ts.map +1 -0
- package/dist/profile-constants.js +37 -0
- package/dist/profile-constants.js.map +1 -0
- package/dist/profile-migrations.d.ts +71 -0
- package/dist/profile-migrations.d.ts.map +1 -0
- package/dist/profile-migrations.js +88 -0
- package/dist/profile-migrations.js.map +1 -0
- package/dist/profile-migrations.test.d.ts +2 -0
- package/dist/profile-migrations.test.d.ts.map +1 -0
- package/dist/profile-migrations.test.js +200 -0
- package/dist/profile-migrations.test.js.map +1 -0
- package/dist/profile-record.d.ts +60 -0
- package/dist/profile-record.d.ts.map +1 -0
- package/dist/profile-record.js +78 -0
- package/dist/profile-record.js.map +1 -0
- package/dist/profile-slice.d.ts +53 -0
- package/dist/profile-slice.d.ts.map +1 -0
- package/dist/profile-slice.js +73 -0
- package/dist/profile-slice.js.map +1 -0
- package/dist/profile-slice.test.d.ts +2 -0
- package/dist/profile-slice.test.d.ts.map +1 -0
- package/dist/profile-slice.test.js +73 -0
- package/dist/profile-slice.test.js.map +1 -0
- package/dist/profile-store-env.d.ts +34 -0
- package/dist/profile-store-env.d.ts.map +1 -0
- package/dist/profile-store-env.js +44 -0
- package/dist/profile-store-env.js.map +1 -0
- package/dist/profile-store-env.test.d.ts +2 -0
- package/dist/profile-store-env.test.d.ts.map +1 -0
- package/dist/profile-store-env.test.js +69 -0
- package/dist/profile-store-env.test.js.map +1 -0
- package/dist/profile-store-postgres.d.ts +33 -0
- package/dist/profile-store-postgres.d.ts.map +1 -0
- package/dist/profile-store-postgres.js +87 -0
- package/dist/profile-store-postgres.js.map +1 -0
- package/dist/profile-store-raw.test.d.ts +2 -0
- package/dist/profile-store-raw.test.d.ts.map +1 -0
- package/dist/profile-store-raw.test.js +185 -0
- package/dist/profile-store-raw.test.js.map +1 -0
- package/dist/profile-store.d.ts +85 -0
- package/dist/profile-store.d.ts.map +1 -0
- package/dist/profile-store.js +182 -0
- package/dist/profile-store.js.map +1 -0
- package/dist/profile-store.test.d.ts +2 -0
- package/dist/profile-store.test.d.ts.map +1 -0
- package/dist/profile-store.test.js +353 -0
- package/dist/profile-store.test.js.map +1 -0
- package/dist/profile.d.ts +75 -0
- package/dist/profile.d.ts.map +1 -0
- package/dist/profile.js +85 -0
- package/dist/profile.js.map +1 -0
- package/dist/profile.test.d.ts +2 -0
- package/dist/profile.test.d.ts.map +1 -0
- package/dist/profile.test.js +71 -0
- package/dist/profile.test.js.map +1 -0
- package/dist/request-context.d.ts +47 -0
- package/dist/request-context.d.ts.map +1 -0
- package/dist/request-context.js +85 -0
- package/dist/request-context.js.map +1 -0
- package/dist/request-context.test.d.ts +2 -0
- package/dist/request-context.test.d.ts.map +1 -0
- package/dist/request-context.test.js +107 -0
- package/dist/request-context.test.js.map +1 -0
- package/dist/served-fonts.d.ts +38 -0
- package/dist/served-fonts.d.ts.map +1 -0
- package/dist/served-fonts.js +51 -0
- package/dist/served-fonts.js.map +1 -0
- package/dist/served-fonts.test.d.ts +2 -0
- package/dist/served-fonts.test.d.ts.map +1 -0
- package/dist/served-fonts.test.js +30 -0
- package/dist/served-fonts.test.js.map +1 -0
- package/dist/server-locale.d.ts +58 -0
- package/dist/server-locale.d.ts.map +1 -0
- package/dist/server-locale.js +64 -0
- package/dist/server-locale.js.map +1 -0
- package/dist/server-locale.test.d.ts +2 -0
- package/dist/server-locale.test.d.ts.map +1 -0
- package/dist/server-locale.test.js +90 -0
- package/dist/server-locale.test.js.map +1 -0
- package/dist/server.d.ts +43 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +34 -0
- package/dist/server.js.map +1 -0
- package/dist/shell-catalogue.d.ts +12 -0
- package/dist/shell-catalogue.d.ts.map +1 -0
- package/dist/shell-catalogue.js +142 -0
- package/dist/shell-catalogue.js.map +1 -0
- package/dist/shell-settings-contract.d.ts +34 -0
- package/dist/shell-settings-contract.d.ts.map +1 -0
- package/dist/shell-settings-contract.js +21 -0
- package/dist/shell-settings-contract.js.map +1 -0
- package/dist/shell-settings.d.ts +24 -0
- package/dist/shell-settings.d.ts.map +1 -0
- package/dist/shell-settings.js +148 -0
- package/dist/shell-settings.js.map +1 -0
- package/dist/shell-settings.test.d.ts +2 -0
- package/dist/shell-settings.test.d.ts.map +1 -0
- package/dist/shell-settings.test.js +115 -0
- package/dist/shell-settings.test.js.map +1 -0
- package/dist/testing/catalog-text.d.ts +53 -0
- package/dist/testing/catalog-text.d.ts.map +1 -0
- package/dist/testing/catalog-text.js +146 -0
- package/dist/testing/catalog-text.js.map +1 -0
- package/dist/testing/catalog-text.test.d.ts +2 -0
- package/dist/testing/catalog-text.test.d.ts.map +1 -0
- package/dist/testing/catalog-text.test.js +137 -0
- package/dist/testing/catalog-text.test.js.map +1 -0
- package/dist/testing/colors.d.ts +34 -0
- package/dist/testing/colors.d.ts.map +1 -0
- package/dist/testing/colors.js +124 -0
- package/dist/testing/colors.js.map +1 -0
- package/dist/testing/colors.test.d.ts +2 -0
- package/dist/testing/colors.test.d.ts.map +1 -0
- package/dist/testing/colors.test.js +166 -0
- package/dist/testing/colors.test.js.map +1 -0
- package/dist/testing/contrast.d.ts +77 -0
- package/dist/testing/contrast.d.ts.map +1 -0
- package/dist/testing/contrast.js +382 -0
- package/dist/testing/contrast.js.map +1 -0
- package/dist/testing/contrast.test.d.ts +2 -0
- package/dist/testing/contrast.test.d.ts.map +1 -0
- package/dist/testing/contrast.test.js +230 -0
- package/dist/testing/contrast.test.js.map +1 -0
- package/dist/testing/display-texts.d.ts +23 -0
- package/dist/testing/display-texts.d.ts.map +1 -0
- package/dist/testing/display-texts.js +88 -0
- package/dist/testing/display-texts.js.map +1 -0
- package/dist/testing/display-texts.test.d.ts +2 -0
- package/dist/testing/display-texts.test.d.ts.map +1 -0
- package/dist/testing/display-texts.test.js +169 -0
- package/dist/testing/display-texts.test.js.map +1 -0
- package/dist/testing/glossary.d.ts +52 -0
- package/dist/testing/glossary.d.ts.map +1 -0
- package/dist/testing/glossary.js +135 -0
- package/dist/testing/glossary.js.map +1 -0
- package/dist/testing/glossary.test.d.ts +2 -0
- package/dist/testing/glossary.test.d.ts.map +1 -0
- package/dist/testing/glossary.test.js +78 -0
- package/dist/testing/glossary.test.js.map +1 -0
- package/dist/testing/glyphs.d.ts +27 -0
- package/dist/testing/glyphs.d.ts.map +1 -0
- package/dist/testing/glyphs.js +130 -0
- package/dist/testing/glyphs.js.map +1 -0
- package/dist/testing/glyphs.test.d.ts +2 -0
- package/dist/testing/glyphs.test.d.ts.map +1 -0
- package/dist/testing/glyphs.test.js +146 -0
- package/dist/testing/glyphs.test.js.map +1 -0
- package/dist/testing/icon-sizes.d.ts +22 -0
- package/dist/testing/icon-sizes.d.ts.map +1 -0
- package/dist/testing/icon-sizes.js +39 -0
- package/dist/testing/icon-sizes.js.map +1 -0
- package/dist/testing/icon-sizes.test.d.ts +2 -0
- package/dist/testing/icon-sizes.test.d.ts.map +1 -0
- package/dist/testing/icon-sizes.test.js +36 -0
- package/dist/testing/icon-sizes.test.js.map +1 -0
- package/dist/testing/index.d.ts +40 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +40 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/source-scan.d.ts +16 -0
- package/dist/testing/source-scan.d.ts.map +1 -0
- package/dist/testing/source-scan.js +57 -0
- package/dist/testing/source-scan.js.map +1 -0
- package/dist/testing/tone-pairs.d.ts +20 -0
- package/dist/testing/tone-pairs.d.ts.map +1 -0
- package/dist/testing/tone-pairs.js +154 -0
- package/dist/testing/tone-pairs.js.map +1 -0
- package/dist/testing/type-scale.d.ts +40 -0
- package/dist/testing/type-scale.d.ts.map +1 -0
- package/dist/testing/type-scale.js +55 -0
- package/dist/testing/type-scale.js.map +1 -0
- package/dist/testing/type-scale.test.d.ts +2 -0
- package/dist/testing/type-scale.test.d.ts.map +1 -0
- package/dist/testing/type-scale.test.js +61 -0
- package/dist/testing/type-scale.test.js.map +1 -0
- package/dist/tool-schema-trim.d.ts +24 -0
- package/dist/tool-schema-trim.d.ts.map +1 -0
- package/dist/tool-schema-trim.js +49 -0
- package/dist/tool-schema-trim.js.map +1 -0
- package/dist/tool-schema-trim.test.d.ts +2 -0
- package/dist/tool-schema-trim.test.d.ts.map +1 -0
- package/dist/tool-schema-trim.test.js +53 -0
- package/dist/tool-schema-trim.test.js.map +1 -0
- package/dist/toolsets.d.ts +76 -0
- package/dist/toolsets.d.ts.map +1 -0
- package/dist/toolsets.js +41 -0
- package/dist/toolsets.js.map +1 -0
- package/dist/toolsets.test.d.ts +2 -0
- package/dist/toolsets.test.d.ts.map +1 -0
- package/dist/toolsets.test.js +86 -0
- package/dist/toolsets.test.js.map +1 -0
- package/dist/ui/action-feedback.d.ts +33 -0
- package/dist/ui/action-feedback.d.ts.map +1 -0
- package/dist/ui/action-feedback.js +51 -0
- package/dist/ui/action-feedback.js.map +1 -0
- package/dist/ui/action-feedback.test.d.ts +2 -0
- package/dist/ui/action-feedback.test.d.ts.map +1 -0
- package/dist/ui/action-feedback.test.js +77 -0
- package/dist/ui/action-feedback.test.js.map +1 -0
- package/dist/ui/app-shell-providers.d.ts +18 -0
- package/dist/ui/app-shell-providers.d.ts.map +1 -0
- package/dist/ui/app-shell-providers.js +19 -0
- package/dist/ui/app-shell-providers.js.map +1 -0
- package/dist/ui/app-shell-providers.test.d.ts +2 -0
- package/dist/ui/app-shell-providers.test.d.ts.map +1 -0
- package/dist/ui/app-shell-providers.test.js +249 -0
- package/dist/ui/app-shell-providers.test.js.map +1 -0
- package/dist/ui/ask-ai-button.d.ts +56 -0
- package/dist/ui/ask-ai-button.d.ts.map +1 -0
- package/dist/ui/ask-ai-button.js +36 -0
- package/dist/ui/ask-ai-button.js.map +1 -0
- package/dist/ui/ask-ai-button.test.d.ts +2 -0
- package/dist/ui/ask-ai-button.test.d.ts.map +1 -0
- package/dist/ui/ask-ai-button.test.js +103 -0
- package/dist/ui/ask-ai-button.test.js.map +1 -0
- package/dist/ui/ask-ai-prompt.d.ts +115 -0
- package/dist/ui/ask-ai-prompt.d.ts.map +1 -0
- package/dist/ui/ask-ai-prompt.js +174 -0
- package/dist/ui/ask-ai-prompt.js.map +1 -0
- package/dist/ui/ask-ai-prompt.test.d.ts +2 -0
- package/dist/ui/ask-ai-prompt.test.d.ts.map +1 -0
- package/dist/ui/ask-ai-prompt.test.js +240 -0
- package/dist/ui/ask-ai-prompt.test.js.map +1 -0
- package/dist/ui/bpmn-heatmap/heat-ramp.test.d.ts +2 -0
- package/dist/ui/bpmn-heatmap/heat-ramp.test.d.ts.map +1 -0
- package/dist/ui/bpmn-heatmap/heat-ramp.test.js +174 -0
- package/dist/ui/bpmn-heatmap/heat-ramp.test.js.map +1 -0
- package/dist/ui/bpmn-heatmap/heat-utils.d.ts +119 -0
- package/dist/ui/bpmn-heatmap/heat-utils.d.ts.map +1 -0
- package/dist/ui/bpmn-heatmap/heat-utils.js +231 -0
- package/dist/ui/bpmn-heatmap/heat-utils.js.map +1 -0
- package/dist/ui/bpmn-heatmap/heat-utils.test.d.ts +2 -0
- package/dist/ui/bpmn-heatmap/heat-utils.test.d.ts.map +1 -0
- package/dist/ui/bpmn-heatmap/heat-utils.test.js +59 -0
- package/dist/ui/bpmn-heatmap/heat-utils.test.js.map +1 -0
- package/dist/ui/bpmn-heatmap-labels.d.ts +46 -0
- package/dist/ui/bpmn-heatmap-labels.d.ts.map +1 -0
- package/dist/ui/bpmn-heatmap-labels.js +16 -0
- package/dist/ui/bpmn-heatmap-labels.js.map +1 -0
- package/dist/ui/bpmn-heatmap-widget.d.ts +38 -0
- package/dist/ui/bpmn-heatmap-widget.d.ts.map +1 -0
- package/dist/ui/bpmn-heatmap-widget.js +65 -0
- package/dist/ui/bpmn-heatmap-widget.js.map +1 -0
- package/dist/ui/bpmn-heatmap-widget.test.d.ts +2 -0
- package/dist/ui/bpmn-heatmap-widget.test.d.ts.map +1 -0
- package/dist/ui/bpmn-heatmap-widget.test.js +173 -0
- package/dist/ui/bpmn-heatmap-widget.test.js.map +1 -0
- package/dist/ui/bpmn-heatmap.d.ts +61 -0
- package/dist/ui/bpmn-heatmap.d.ts.map +1 -0
- package/dist/ui/bpmn-heatmap.js +119 -0
- package/dist/ui/bpmn-heatmap.js.map +1 -0
- package/dist/ui/bpmn-tokens.d.ts +81 -0
- package/dist/ui/bpmn-tokens.d.ts.map +1 -0
- package/dist/ui/bpmn-tokens.js +114 -0
- package/dist/ui/bpmn-tokens.js.map +1 -0
- package/dist/ui/bpmn-tokens.test.d.ts +2 -0
- package/dist/ui/bpmn-tokens.test.d.ts.map +1 -0
- package/dist/ui/bpmn-tokens.test.js +98 -0
- package/dist/ui/bpmn-tokens.test.js.map +1 -0
- package/dist/ui/bpmn-zoom-controls.d.ts +30 -0
- package/dist/ui/bpmn-zoom-controls.d.ts.map +1 -0
- package/dist/ui/bpmn-zoom-controls.js +29 -0
- package/dist/ui/bpmn-zoom-controls.js.map +1 -0
- package/dist/ui/brand-gates.test.d.ts +2 -0
- package/dist/ui/brand-gates.test.d.ts.map +1 -0
- package/dist/ui/brand-gates.test.js +131 -0
- package/dist/ui/brand-gates.test.js.map +1 -0
- package/dist/ui/brand-mark.d.ts +37 -0
- package/dist/ui/brand-mark.d.ts.map +1 -0
- package/dist/ui/brand-mark.js +33 -0
- package/dist/ui/brand-mark.js.map +1 -0
- package/dist/ui/brand-mark.test.d.ts +2 -0
- package/dist/ui/brand-mark.test.d.ts.map +1 -0
- package/dist/ui/brand-mark.test.js +111 -0
- package/dist/ui/brand-mark.test.js.map +1 -0
- package/dist/ui/confirm-dialog.d.ts +55 -0
- package/dist/ui/confirm-dialog.d.ts.map +1 -0
- package/dist/ui/confirm-dialog.js +59 -0
- package/dist/ui/confirm-dialog.js.map +1 -0
- package/dist/ui/confirm-dialog.test.d.ts +2 -0
- package/dist/ui/confirm-dialog.test.d.ts.map +1 -0
- package/dist/ui/confirm-dialog.test.js +115 -0
- package/dist/ui/confirm-dialog.test.js.map +1 -0
- package/dist/ui/count-tone.d.ts +20 -0
- package/dist/ui/count-tone.d.ts.map +1 -0
- package/dist/ui/count-tone.js +27 -0
- package/dist/ui/count-tone.js.map +1 -0
- package/dist/ui/count-tone.test.d.ts +2 -0
- package/dist/ui/count-tone.test.d.ts.map +1 -0
- package/dist/ui/count-tone.test.js +27 -0
- package/dist/ui/count-tone.test.js.map +1 -0
- package/dist/ui/create-use-t.d.ts +15 -0
- package/dist/ui/create-use-t.d.ts.map +1 -0
- package/dist/ui/create-use-t.js +17 -0
- package/dist/ui/create-use-t.js.map +1 -0
- package/dist/ui/declare-served-fonts.d.ts +14 -0
- package/dist/ui/declare-served-fonts.d.ts.map +1 -0
- package/dist/ui/declare-served-fonts.js +38 -0
- package/dist/ui/declare-served-fonts.js.map +1 -0
- package/dist/ui/declare-served-fonts.test.d.ts +2 -0
- package/dist/ui/declare-served-fonts.test.d.ts.map +1 -0
- package/dist/ui/declare-served-fonts.test.js +44 -0
- package/dist/ui/declare-served-fonts.test.js.map +1 -0
- package/dist/ui/describe-error.d.ts +71 -0
- package/dist/ui/describe-error.d.ts.map +1 -0
- package/dist/ui/describe-error.js +175 -0
- package/dist/ui/describe-error.js.map +1 -0
- package/dist/ui/describe-error.test.d.ts +2 -0
- package/dist/ui/describe-error.test.d.ts.map +1 -0
- package/dist/ui/describe-error.test.js +274 -0
- package/dist/ui/describe-error.test.js.map +1 -0
- package/dist/ui/display-mode-toggle.d.ts +32 -0
- package/dist/ui/display-mode-toggle.d.ts.map +1 -0
- package/dist/ui/display-mode-toggle.js +39 -0
- package/dist/ui/display-mode-toggle.js.map +1 -0
- package/dist/ui/error-labels.d.ts +65 -0
- package/dist/ui/error-labels.d.ts.map +1 -0
- package/dist/ui/error-labels.js +111 -0
- package/dist/ui/error-labels.js.map +1 -0
- package/dist/ui/format.d.ts +81 -0
- package/dist/ui/format.d.ts.map +1 -0
- package/dist/ui/format.js +189 -0
- package/dist/ui/format.js.map +1 -0
- package/dist/ui/format.test.d.ts +2 -0
- package/dist/ui/format.test.d.ts.map +1 -0
- package/dist/ui/format.test.js +181 -0
- package/dist/ui/format.test.js.map +1 -0
- package/dist/ui/generic-widgets.d.ts +15 -0
- package/dist/ui/generic-widgets.d.ts.map +1 -0
- package/dist/ui/generic-widgets.js +122 -0
- package/dist/ui/generic-widgets.js.map +1 -0
- package/dist/ui/generic-widgets.test.d.ts +2 -0
- package/dist/ui/generic-widgets.test.d.ts.map +1 -0
- package/dist/ui/generic-widgets.test.js +139 -0
- package/dist/ui/generic-widgets.test.js.map +1 -0
- package/dist/ui/hand-off-button.d.ts +45 -0
- package/dist/ui/hand-off-button.d.ts.map +1 -0
- package/dist/ui/hand-off-button.js +44 -0
- package/dist/ui/hand-off-button.js.map +1 -0
- package/dist/ui/hand-off-button.test.d.ts +2 -0
- package/dist/ui/hand-off-button.test.d.ts.map +1 -0
- package/dist/ui/hand-off-button.test.js +78 -0
- package/dist/ui/hand-off-button.test.js.map +1 -0
- package/dist/ui/host-context.d.ts +66 -0
- package/dist/ui/host-context.d.ts.map +1 -0
- package/dist/ui/host-context.js +122 -0
- package/dist/ui/host-context.js.map +1 -0
- package/dist/ui/host-context.test.d.ts +2 -0
- package/dist/ui/host-context.test.d.ts.map +1 -0
- package/dist/ui/host-context.test.js +160 -0
- package/dist/ui/host-context.test.js.map +1 -0
- package/dist/ui/host-document.d.ts +25 -0
- package/dist/ui/host-document.d.ts.map +1 -0
- package/dist/ui/host-document.js +93 -0
- package/dist/ui/host-document.js.map +1 -0
- package/dist/ui/host-document.test.d.ts +2 -0
- package/dist/ui/host-document.test.d.ts.map +1 -0
- package/dist/ui/host-document.test.js +112 -0
- package/dist/ui/host-document.test.js.map +1 -0
- package/dist/ui/host-widgets.d.ts +8 -0
- package/dist/ui/host-widgets.d.ts.map +1 -0
- package/dist/ui/host-widgets.js +18 -0
- package/dist/ui/host-widgets.js.map +1 -0
- package/dist/ui/humanize-key.d.ts +11 -0
- package/dist/ui/humanize-key.d.ts.map +1 -0
- package/dist/ui/humanize-key.js +26 -0
- package/dist/ui/humanize-key.js.map +1 -0
- package/dist/ui/humanize-key.test.d.ts +2 -0
- package/dist/ui/humanize-key.test.d.ts.map +1 -0
- package/dist/ui/humanize-key.test.js +42 -0
- package/dist/ui/humanize-key.test.js.map +1 -0
- package/dist/ui/icon.d.ts +37 -0
- package/dist/ui/icon.d.ts.map +1 -0
- package/dist/ui/icon.js +32 -0
- package/dist/ui/icon.js.map +1 -0
- package/dist/ui/id-breaks.d.ts +17 -0
- package/dist/ui/id-breaks.d.ts.map +1 -0
- package/dist/ui/id-breaks.js +36 -0
- package/dist/ui/id-breaks.js.map +1 -0
- package/dist/ui/id-breaks.test.d.ts +2 -0
- package/dist/ui/id-breaks.test.d.ts.map +1 -0
- package/dist/ui/id-breaks.test.js +37 -0
- package/dist/ui/id-breaks.test.js.map +1 -0
- package/dist/ui/id-text.d.ts +29 -0
- package/dist/ui/id-text.d.ts.map +1 -0
- package/dist/ui/id-text.js +103 -0
- package/dist/ui/id-text.js.map +1 -0
- package/dist/ui/id-text.test.d.ts +2 -0
- package/dist/ui/id-text.test.d.ts.map +1 -0
- package/dist/ui/id-text.test.js +122 -0
- package/dist/ui/id-text.test.js.map +1 -0
- package/dist/ui/index.d.ts +57 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +65 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/index.test.d.ts +2 -0
- package/dist/ui/index.test.d.ts.map +1 -0
- package/dist/ui/index.test.js +34 -0
- package/dist/ui/index.test.js.map +1 -0
- package/dist/ui/inline-budget.d.ts +35 -0
- package/dist/ui/inline-budget.d.ts.map +1 -0
- package/dist/ui/inline-budget.js +27 -0
- package/dist/ui/inline-budget.js.map +1 -0
- package/dist/ui/inline-fit-registry.d.ts +56 -0
- package/dist/ui/inline-fit-registry.d.ts.map +1 -0
- package/dist/ui/inline-fit-registry.js +114 -0
- package/dist/ui/inline-fit-registry.js.map +1 -0
- package/dist/ui/inline-fit-solve.d.ts +50 -0
- package/dist/ui/inline-fit-solve.d.ts.map +1 -0
- package/dist/ui/inline-fit-solve.js +83 -0
- package/dist/ui/inline-fit-solve.js.map +1 -0
- package/dist/ui/inline-fit-solve.test.d.ts +2 -0
- package/dist/ui/inline-fit-solve.test.d.ts.map +1 -0
- package/dist/ui/inline-fit-solve.test.js +108 -0
- package/dist/ui/inline-fit-solve.test.js.map +1 -0
- package/dist/ui/inline-fit-time.test.d.ts +2 -0
- package/dist/ui/inline-fit-time.test.d.ts.map +1 -0
- package/dist/ui/inline-fit-time.test.js +110 -0
- package/dist/ui/inline-fit-time.test.js.map +1 -0
- package/dist/ui/inline-fit.d.ts +77 -0
- package/dist/ui/inline-fit.d.ts.map +1 -0
- package/dist/ui/inline-fit.js +242 -0
- package/dist/ui/inline-fit.js.map +1 -0
- package/dist/ui/inline-fit.test-support.d.ts +26 -0
- package/dist/ui/inline-fit.test-support.d.ts.map +1 -0
- package/dist/ui/inline-fit.test-support.js +34 -0
- package/dist/ui/inline-fit.test-support.js.map +1 -0
- package/dist/ui/inline-fit.test.d.ts +2 -0
- package/dist/ui/inline-fit.test.d.ts.map +1 -0
- package/dist/ui/inline-fit.test.js +159 -0
- package/dist/ui/inline-fit.test.js.map +1 -0
- package/dist/ui/kit-labels.d.ts +80 -0
- package/dist/ui/kit-labels.d.ts.map +1 -0
- package/dist/ui/kit-labels.js +110 -0
- package/dist/ui/kit-labels.js.map +1 -0
- package/dist/ui/kit-labels.test.d.ts +2 -0
- package/dist/ui/kit-labels.test.d.ts.map +1 -0
- package/dist/ui/kit-labels.test.js +98 -0
- package/dist/ui/kit-labels.test.js.map +1 -0
- package/dist/ui/kit-type-roles.test.d.ts +2 -0
- package/dist/ui/kit-type-roles.test.d.ts.map +1 -0
- package/dist/ui/kit-type-roles.test.js +122 -0
- package/dist/ui/kit-type-roles.test.js.map +1 -0
- package/dist/ui/komet-svg.d.ts +15 -0
- package/dist/ui/komet-svg.d.ts.map +1 -0
- package/dist/ui/komet-svg.js +21 -0
- package/dist/ui/komet-svg.js.map +1 -0
- package/dist/ui/list-table.d.ts +108 -0
- package/dist/ui/list-table.d.ts.map +1 -0
- package/dist/ui/list-table.js +161 -0
- package/dist/ui/list-table.js.map +1 -0
- package/dist/ui/list-table.test.d.ts +2 -0
- package/dist/ui/list-table.test.d.ts.map +1 -0
- package/dist/ui/list-table.test.js +169 -0
- package/dist/ui/list-table.test.js.map +1 -0
- package/dist/ui/localized-app-view.d.ts +40 -0
- package/dist/ui/localized-app-view.d.ts.map +1 -0
- package/dist/ui/localized-app-view.js +71 -0
- package/dist/ui/localized-app-view.js.map +1 -0
- package/dist/ui/log-text.d.ts +24 -0
- package/dist/ui/log-text.d.ts.map +1 -0
- package/dist/ui/log-text.js +31 -0
- package/dist/ui/log-text.js.map +1 -0
- package/dist/ui/menu-item.d.ts +12 -0
- package/dist/ui/menu-item.d.ts.map +1 -0
- package/dist/ui/menu-item.js +13 -0
- package/dist/ui/menu-item.js.map +1 -0
- package/dist/ui/named-id.d.ts +23 -0
- package/dist/ui/named-id.d.ts.map +1 -0
- package/dist/ui/named-id.js +21 -0
- package/dist/ui/named-id.js.map +1 -0
- package/dist/ui/named-id.test.d.ts +2 -0
- package/dist/ui/named-id.test.d.ts.map +1 -0
- package/dist/ui/named-id.test.js +57 -0
- package/dist/ui/named-id.test.js.map +1 -0
- package/dist/ui/native-select.d.ts +17 -0
- package/dist/ui/native-select.d.ts.map +1 -0
- package/dist/ui/native-select.js +20 -0
- package/dist/ui/native-select.js.map +1 -0
- package/dist/ui/navigation-focus.d.ts +20 -0
- package/dist/ui/navigation-focus.d.ts.map +1 -0
- package/dist/ui/navigation-focus.js +25 -0
- package/dist/ui/navigation-focus.js.map +1 -0
- package/dist/ui/navigation-focus.test.d.ts +2 -0
- package/dist/ui/navigation-focus.test.d.ts.map +1 -0
- package/dist/ui/navigation-focus.test.js +28 -0
- package/dist/ui/navigation-focus.test.js.map +1 -0
- package/dist/ui/open-in-cockpit-link.d.ts +28 -0
- package/dist/ui/open-in-cockpit-link.d.ts.map +1 -0
- package/dist/ui/open-in-cockpit-link.js +41 -0
- package/dist/ui/open-in-cockpit-link.js.map +1 -0
- package/dist/ui/paged-list-footer.test.d.ts +2 -0
- package/dist/ui/paged-list-footer.test.d.ts.map +1 -0
- package/dist/ui/paged-list-footer.test.js +128 -0
- package/dist/ui/paged-list-footer.test.js.map +1 -0
- package/dist/ui/paged-rows.d.ts +24 -0
- package/dist/ui/paged-rows.d.ts.map +1 -0
- package/dist/ui/paged-rows.js +25 -0
- package/dist/ui/paged-rows.js.map +1 -0
- package/dist/ui/parse-tool-result.test.d.ts +2 -0
- package/dist/ui/parse-tool-result.test.d.ts.map +1 -0
- package/dist/ui/parse-tool-result.test.js +88 -0
- package/dist/ui/parse-tool-result.test.js.map +1 -0
- package/dist/ui/profile-gate.d.ts +37 -0
- package/dist/ui/profile-gate.d.ts.map +1 -0
- package/dist/ui/profile-gate.js +126 -0
- package/dist/ui/profile-gate.js.map +1 -0
- package/dist/ui/profile-gate.test.d.ts +2 -0
- package/dist/ui/profile-gate.test.d.ts.map +1 -0
- package/dist/ui/profile-gate.test.js +246 -0
- package/dist/ui/profile-gate.test.js.map +1 -0
- package/dist/ui/query-fallback.d.ts +27 -0
- package/dist/ui/query-fallback.d.ts.map +1 -0
- package/dist/ui/query-fallback.js +30 -0
- package/dist/ui/query-fallback.js.map +1 -0
- package/dist/ui/query-fallback.test.d.ts +2 -0
- package/dist/ui/query-fallback.test.d.ts.map +1 -0
- package/dist/ui/query-fallback.test.js +49 -0
- package/dist/ui/query-fallback.test.js.map +1 -0
- package/dist/ui/row-card.d.ts +13 -0
- package/dist/ui/row-card.d.ts.map +1 -0
- package/dist/ui/row-card.js +11 -0
- package/dist/ui/row-card.js.map +1 -0
- package/dist/ui/section.d.ts +18 -0
- package/dist/ui/section.d.ts.map +1 -0
- package/dist/ui/section.js +14 -0
- package/dist/ui/section.js.map +1 -0
- package/dist/ui/segmented-control.d.ts +25 -0
- package/dist/ui/segmented-control.d.ts.map +1 -0
- package/dist/ui/segmented-control.js +22 -0
- package/dist/ui/segmented-control.js.map +1 -0
- package/dist/ui/settings-labels.d.ts +33 -0
- package/dist/ui/settings-labels.d.ts.map +1 -0
- package/dist/ui/settings-labels.js +50 -0
- package/dist/ui/settings-labels.js.map +1 -0
- package/dist/ui/settings-layout.d.ts +29 -0
- package/dist/ui/settings-layout.d.ts.map +1 -0
- package/dist/ui/settings-layout.js +49 -0
- package/dist/ui/settings-layout.js.map +1 -0
- package/dist/ui/settings-layout.test.d.ts +2 -0
- package/dist/ui/settings-layout.test.d.ts.map +1 -0
- package/dist/ui/settings-layout.test.js +73 -0
- package/dist/ui/settings-layout.test.js.map +1 -0
- package/dist/ui/settings.d.ts +47 -0
- package/dist/ui/settings.d.ts.map +1 -0
- package/dist/ui/settings.js +48 -0
- package/dist/ui/settings.js.map +1 -0
- package/dist/ui/settings.test.d.ts +2 -0
- package/dist/ui/settings.test.d.ts.map +1 -0
- package/dist/ui/settings.test.js +38 -0
- package/dist/ui/settings.test.js.map +1 -0
- package/dist/ui/shell-host.d.ts +46 -0
- package/dist/ui/shell-host.d.ts.map +1 -0
- package/dist/ui/shell-host.js +56 -0
- package/dist/ui/shell-host.js.map +1 -0
- package/dist/ui/shell-settings.d.ts +31 -0
- package/dist/ui/shell-settings.d.ts.map +1 -0
- package/dist/ui/shell-settings.js +97 -0
- package/dist/ui/shell-settings.js.map +1 -0
- package/dist/ui/shell-settings.test.d.ts +2 -0
- package/dist/ui/shell-settings.test.d.ts.map +1 -0
- package/dist/ui/shell-settings.test.js +108 -0
- package/dist/ui/shell-settings.test.js.map +1 -0
- package/dist/ui/shell-widgets.d.ts +14 -0
- package/dist/ui/shell-widgets.d.ts.map +1 -0
- package/dist/ui/shell-widgets.js +18 -0
- package/dist/ui/shell-widgets.js.map +1 -0
- package/dist/ui/table.d.ts +61 -0
- package/dist/ui/table.d.ts.map +1 -0
- package/dist/ui/table.js +43 -0
- package/dist/ui/table.js.map +1 -0
- package/dist/ui/tone-components.test.d.ts +2 -0
- package/dist/ui/tone-components.test.d.ts.map +1 -0
- package/dist/ui/tone-components.test.js +145 -0
- package/dist/ui/tone-components.test.js.map +1 -0
- package/dist/ui/tone-contrast.test.d.ts +2 -0
- package/dist/ui/tone-contrast.test.d.ts.map +1 -0
- package/dist/ui/tone-contrast.test.js +66 -0
- package/dist/ui/tone-contrast.test.js.map +1 -0
- package/dist/ui/toolkit-overlap.test.d.ts +2 -0
- package/dist/ui/toolkit-overlap.test.d.ts.map +1 -0
- package/dist/ui/toolkit-overlap.test.js +86 -0
- package/dist/ui/toolkit-overlap.test.js.map +1 -0
- package/dist/ui/use-apply-theme.d.ts +11 -0
- package/dist/ui/use-apply-theme.d.ts.map +1 -0
- package/dist/ui/use-apply-theme.js +37 -0
- package/dist/ui/use-apply-theme.js.map +1 -0
- package/dist/ui/use-apply-theme.test.d.ts +2 -0
- package/dist/ui/use-apply-theme.test.d.ts.map +1 -0
- package/dist/ui/use-apply-theme.test.js +102 -0
- package/dist/ui/use-apply-theme.test.js.map +1 -0
- package/dist/ui/use-bpmn-viewer.d.ts +135 -0
- package/dist/ui/use-bpmn-viewer.d.ts.map +1 -0
- package/dist/ui/use-bpmn-viewer.js +257 -0
- package/dist/ui/use-bpmn-viewer.js.map +1 -0
- package/dist/ui/use-bpmn-viewer.test.d.ts +2 -0
- package/dist/ui/use-bpmn-viewer.test.d.ts.map +1 -0
- package/dist/ui/use-bpmn-viewer.test.js +239 -0
- package/dist/ui/use-bpmn-viewer.test.js.map +1 -0
- package/dist/ui/use-detail-view.d.ts +49 -0
- package/dist/ui/use-detail-view.d.ts.map +1 -0
- package/dist/ui/use-detail-view.js +52 -0
- package/dist/ui/use-detail-view.js.map +1 -0
- package/dist/ui/use-detail-view.test.d.ts +2 -0
- package/dist/ui/use-detail-view.test.d.ts.map +1 -0
- package/dist/ui/use-detail-view.test.js +178 -0
- package/dist/ui/use-detail-view.test.js.map +1 -0
- package/dist/ui/use-paged-list-view.d.ts +48 -0
- package/dist/ui/use-paged-list-view.d.ts.map +1 -0
- package/dist/ui/use-paged-list-view.js +41 -0
- package/dist/ui/use-paged-list-view.js.map +1 -0
- package/dist/ui/use-paged-list-view.test.d.ts +2 -0
- package/dist/ui/use-paged-list-view.test.d.ts.map +1 -0
- package/dist/ui/use-paged-list-view.test.js +136 -0
- package/dist/ui/use-paged-list-view.test.js.map +1 -0
- package/dist/ui/use-paged-view-data.d.ts +103 -0
- package/dist/ui/use-paged-view-data.d.ts.map +1 -0
- package/dist/ui/use-paged-view-data.js +173 -0
- package/dist/ui/use-paged-view-data.js.map +1 -0
- package/dist/ui/use-paged-view-data.seeded.test.d.ts +2 -0
- package/dist/ui/use-paged-view-data.seeded.test.d.ts.map +1 -0
- package/dist/ui/use-paged-view-data.seeded.test.js +144 -0
- package/dist/ui/use-paged-view-data.seeded.test.js.map +1 -0
- package/dist/ui/use-paged-view-data.test.d.ts +2 -0
- package/dist/ui/use-paged-view-data.test.d.ts.map +1 -0
- package/dist/ui/use-paged-view-data.test.js +330 -0
- package/dist/ui/use-paged-view-data.test.js.map +1 -0
- package/dist/ui/use-reset-on-change.d.ts +22 -0
- package/dist/ui/use-reset-on-change.d.ts.map +1 -0
- package/dist/ui/use-reset-on-change.js +29 -0
- package/dist/ui/use-reset-on-change.js.map +1 -0
- package/dist/ui/use-reset-on-change.test.d.ts +2 -0
- package/dist/ui/use-reset-on-change.test.d.ts.map +1 -0
- package/dist/ui/use-reset-on-change.test.js +61 -0
- package/dist/ui/use-reset-on-change.test.js.map +1 -0
- package/dist/ui/use-view-data.seeded.test.d.ts +2 -0
- package/dist/ui/use-view-data.seeded.test.d.ts.map +1 -0
- package/dist/ui/use-view-data.seeded.test.js +168 -0
- package/dist/ui/use-view-data.seeded.test.js.map +1 -0
- package/dist/ui/view-data-state.d.ts +52 -0
- package/dist/ui/view-data-state.d.ts.map +1 -0
- package/dist/ui/view-data-state.js +54 -0
- package/dist/ui/view-data-state.js.map +1 -0
- package/dist/ui/view-data-state.test.d.ts +2 -0
- package/dist/ui/view-data-state.test.d.ts.map +1 -0
- package/dist/ui/view-data-state.test.js +62 -0
- package/dist/ui/view-data-state.test.js.map +1 -0
- package/dist/ui/view-meta.d.ts +70 -0
- package/dist/ui/view-meta.d.ts.map +1 -0
- package/dist/ui/view-meta.js +84 -0
- package/dist/ui/view-meta.js.map +1 -0
- package/dist/ui/view-meta.test.d.ts +2 -0
- package/dist/ui/view-meta.test.d.ts.map +1 -0
- package/dist/ui/view-meta.test.js +92 -0
- package/dist/ui/view-meta.test.js.map +1 -0
- package/dist/ui/view-refresh-state.d.ts +26 -0
- package/dist/ui/view-refresh-state.d.ts.map +1 -0
- package/dist/ui/view-refresh-state.js +15 -0
- package/dist/ui/view-refresh-state.js.map +1 -0
- package/dist/ui/widget-shell.d.ts +24 -0
- package/dist/ui/widget-shell.d.ts.map +1 -0
- package/dist/ui/widget-shell.js +50 -0
- package/dist/ui/widget-shell.js.map +1 -0
- package/dist/ui/widget-shell.test.d.ts +2 -0
- package/dist/ui/widget-shell.test.d.ts.map +1 -0
- package/dist/ui/widget-shell.test.js +41 -0
- package/dist/ui/widget-shell.test.js.map +1 -0
- package/dist/view-results.d.ts +42 -0
- package/dist/view-results.d.ts.map +1 -0
- package/dist/view-results.js +17 -0
- package/dist/view-results.js.map +1 -0
- package/dist/widget-meta-defaults.d.ts +48 -0
- package/dist/widget-meta-defaults.d.ts.map +1 -0
- package/dist/widget-meta-defaults.js +80 -0
- package/dist/widget-meta-defaults.js.map +1 -0
- package/dist/widget-meta-defaults.test.d.ts +2 -0
- package/dist/widget-meta-defaults.test.d.ts.map +1 -0
- package/dist/widget-meta-defaults.test.js +196 -0
- package/dist/widget-meta-defaults.test.js.map +1 -0
- package/dist/widget-tool-bindings.d.ts +71 -0
- package/dist/widget-tool-bindings.d.ts.map +1 -0
- package/dist/widget-tool-bindings.js +80 -0
- package/dist/widget-tool-bindings.js.map +1 -0
- package/dist/widget-tool-bindings.test.d.ts +2 -0
- package/dist/widget-tool-bindings.test.d.ts.map +1 -0
- package/dist/widget-tool-bindings.test.js +83 -0
- package/dist/widget-tool-bindings.test.js.map +1 -0
- package/dist/with-tool-errors.test.d.ts +2 -0
- package/dist/with-tool-errors.test.d.ts.map +1 -0
- package/dist/with-tool-errors.test.js +38 -0
- package/dist/with-tool-errors.test.js.map +1 -0
- package/package.json +113 -3
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { DEFAULT_MAX_BODY_BYTES, describeHttpEdgePolicy, edgeRejection, hostRejection, IN_FLIGHT_BODY_MULTIPLE, installHttpEdgeGuard, jsonRpcErrorBody, originRejection, resolveHttpEdgePolicy, } from "./http-edge.js";
|
|
3
|
+
const LOCAL = ["localhost", "127.0.0.1", "[::1]"];
|
|
4
|
+
describe("resolveHttpEdgePolicy", () => {
|
|
5
|
+
it("defaults to localhost-class only, a 4 MiB cap, a 16 MiB in-flight budget and an open /metrics", () => {
|
|
6
|
+
expect(resolveHttpEdgePolicy({})).toEqual({
|
|
7
|
+
allowedHosts: LOCAL,
|
|
8
|
+
allowedOrigins: LOCAL,
|
|
9
|
+
maxBodyBytes: 4 * 1024 * 1024,
|
|
10
|
+
maxInFlightBodyBytes: 16 * 1024 * 1024,
|
|
11
|
+
});
|
|
12
|
+
expect(DEFAULT_MAX_BODY_BYTES).toBe(4194304);
|
|
13
|
+
expect(IN_FLIGHT_BODY_MULTIPLE).toBe(4);
|
|
14
|
+
});
|
|
15
|
+
it("scales the in-flight budget with MCP_MAX_BODY_BYTES", () => {
|
|
16
|
+
expect(resolveHttpEdgePolicy({ MCP_MAX_BODY_BYTES: "1000" }).maxInFlightBodyBytes).toBe(4000);
|
|
17
|
+
});
|
|
18
|
+
it("derives the host and the origin from MCP_URL", () => {
|
|
19
|
+
const policy = resolveHttpEdgePolicy({ MCP_URL: "https://MCP.example.com:8443/base" });
|
|
20
|
+
expect(policy.allowedHosts).toEqual([...LOCAL, "mcp.example.com"]);
|
|
21
|
+
expect(policy.allowedOrigins).toEqual([...LOCAL, "https://mcp.example.com:8443"]);
|
|
22
|
+
});
|
|
23
|
+
it("adds the comma lists, normalized and de-duplicated", () => {
|
|
24
|
+
const policy = resolveHttpEdgePolicy({
|
|
25
|
+
MCP_URL: "https://mcp.example.com",
|
|
26
|
+
MCP_ALLOWED_HOSTS: " Internal.svc:8400 , mcp.example.com,,https://gw.example.com/x ",
|
|
27
|
+
MCP_ALLOWED_ORIGINS: "https://App.example.com/, app2.example.com",
|
|
28
|
+
});
|
|
29
|
+
expect(policy.allowedHosts).toEqual([
|
|
30
|
+
...LOCAL,
|
|
31
|
+
"mcp.example.com",
|
|
32
|
+
"internal.svc",
|
|
33
|
+
"gw.example.com",
|
|
34
|
+
]);
|
|
35
|
+
expect(policy.allowedOrigins).toEqual([
|
|
36
|
+
...LOCAL,
|
|
37
|
+
"https://mcp.example.com",
|
|
38
|
+
"https://app.example.com",
|
|
39
|
+
"app2.example.com",
|
|
40
|
+
]);
|
|
41
|
+
});
|
|
42
|
+
it("treats * as an explicit opt-out of that check", () => {
|
|
43
|
+
const policy = resolveHttpEdgePolicy({ MCP_ALLOWED_HOSTS: "*", MCP_ALLOWED_ORIGINS: "a.com,*" });
|
|
44
|
+
expect(policy.allowedHosts).toBe("*");
|
|
45
|
+
expect(policy.allowedOrigins).toBe("*");
|
|
46
|
+
});
|
|
47
|
+
it("reads the body cap and the metrics token", () => {
|
|
48
|
+
const policy = resolveHttpEdgePolicy({
|
|
49
|
+
MCP_MAX_BODY_BYTES: " 1024 ",
|
|
50
|
+
MCP_METRICS_TOKEN: " s3cret ",
|
|
51
|
+
});
|
|
52
|
+
expect(policy.maxBodyBytes).toBe(1024);
|
|
53
|
+
expect(policy.metricsToken).toBe("s3cret");
|
|
54
|
+
expect(resolveHttpEdgePolicy({ MCP_METRICS_TOKEN: " " })).not.toHaveProperty("metricsToken");
|
|
55
|
+
});
|
|
56
|
+
it.each([
|
|
57
|
+
[{ MCP_URL: "not a url" }, /MCP_URL "not a url" is not an absolute URL/],
|
|
58
|
+
[{ MCP_URL: "ftp://mcp.example.com" }, /must be an http\(s\) URL/],
|
|
59
|
+
[{ MCP_MAX_BODY_BYTES: "4MB" }, /MCP_MAX_BODY_BYTES "4MB" must be a positive integer/],
|
|
60
|
+
[{ MCP_MAX_BODY_BYTES: "0" }, /must be a positive integer/],
|
|
61
|
+
[{ MCP_MAX_BODY_BYTES: "1.5" }, /must be a positive integer/],
|
|
62
|
+
[{ MCP_ALLOWED_HOSTS: "bad host" }, /MCP_ALLOWED_HOSTS: "bad host" is not a hostname/],
|
|
63
|
+
[{ MCP_ALLOWED_ORIGINS: "https://" }, /MCP_ALLOWED_ORIGINS: "https:\/\/" is not an origin/],
|
|
64
|
+
[{ MCP_ALLOWED_ORIGINS: "data://x" }, /is not an origin/],
|
|
65
|
+
])("fails the boot on %j", (env, message) => {
|
|
66
|
+
expect(() => resolveHttpEdgePolicy(env)).toThrow(message);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe("describeHttpEdgePolicy", () => {
|
|
70
|
+
it("states hosts, origins, the cap and the metrics protection in one line", () => {
|
|
71
|
+
expect(describeHttpEdgePolicy(resolveHttpEdgePolicy({ MCP_URL: "https://mcp.example.com", MCP_METRICS_TOKEN: "t" }))).toBe("HTTP edge — hosts: localhost, 127.0.0.1, [::1], mcp.example.com; " +
|
|
72
|
+
"origins: localhost, 127.0.0.1, [::1], https://mcp.example.com; " +
|
|
73
|
+
"max body 4 MiB (16 MiB in flight); /metrics token-protected");
|
|
74
|
+
expect(describeHttpEdgePolicy(resolveHttpEdgePolicy({
|
|
75
|
+
MCP_ALLOWED_HOSTS: "*",
|
|
76
|
+
MCP_ALLOWED_ORIGINS: "*",
|
|
77
|
+
MCP_MAX_BODY_BYTES: "1572864",
|
|
78
|
+
}))).toBe("HTTP edge — hosts: any (validation off); origins: any (validation off); " +
|
|
79
|
+
"max body 1.5 MiB (6 MiB in flight); /metrics open");
|
|
80
|
+
});
|
|
81
|
+
it.each([
|
|
82
|
+
["1048576", "max body 1 MiB (4 MiB in flight);"],
|
|
83
|
+
["1024", "max body 1 KiB (4 KiB in flight);"],
|
|
84
|
+
["2560", "max body 2.5 KiB (10 KiB in flight);"],
|
|
85
|
+
["1023", "max body 1023 bytes (4 KiB in flight);"],
|
|
86
|
+
["640", "max body 640 bytes (2.5 KiB in flight);"],
|
|
87
|
+
["255", "max body 255 bytes (1020 bytes in flight);"],
|
|
88
|
+
])("formats a %s-byte cap readably", (bytes, expected) => {
|
|
89
|
+
expect(describeHttpEdgePolicy(resolveHttpEdgePolicy({ MCP_MAX_BODY_BYTES: bytes }))).toContain(expected);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
const policy = resolveHttpEdgePolicy({
|
|
93
|
+
MCP_URL: "https://mcp.example.com",
|
|
94
|
+
MCP_ALLOWED_ORIGINS: "https://app.example.com,tools.example.com",
|
|
95
|
+
});
|
|
96
|
+
describe("hostRejection", () => {
|
|
97
|
+
it.each([
|
|
98
|
+
"localhost",
|
|
99
|
+
"localhost:8400",
|
|
100
|
+
"127.0.0.1:1",
|
|
101
|
+
"[::1]:8400",
|
|
102
|
+
"mcp.example.com",
|
|
103
|
+
"MCP.EXAMPLE.COM:443",
|
|
104
|
+
])("admits %s", (host) => {
|
|
105
|
+
expect(hostRejection(host, policy)).toBeUndefined();
|
|
106
|
+
});
|
|
107
|
+
it("rejects a foreign host (port-agnostic) and points at the remedy", () => {
|
|
108
|
+
const reason = hostRejection("attacker.example:8400", policy);
|
|
109
|
+
expect(reason).toContain('Host "attacker.example" is not allowed');
|
|
110
|
+
expect(reason).toContain("MCP_URL");
|
|
111
|
+
expect(reason).toContain("MCP_ALLOWED_HOSTS");
|
|
112
|
+
// An IP that happens to reach the server is still not "ours".
|
|
113
|
+
expect(hostRejection("10.0.0.7:8400", policy)).toBeDefined();
|
|
114
|
+
});
|
|
115
|
+
it("rejects a missing or unparsable Host", () => {
|
|
116
|
+
expect(hostRejection(undefined, policy)).toBe("missing Host header");
|
|
117
|
+
expect(hostRejection("", policy)).toBe("missing Host header");
|
|
118
|
+
expect(hostRejection("a b", policy)).toBe('invalid Host header "a b"');
|
|
119
|
+
});
|
|
120
|
+
it("admits anything when Host validation is off", () => {
|
|
121
|
+
expect(hostRejection("attacker.example", { ...policy, allowedHosts: "*" })).toBeUndefined();
|
|
122
|
+
expect(hostRejection(undefined, { ...policy, allowedHosts: "*" })).toBeUndefined();
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
describe("originRejection", () => {
|
|
126
|
+
it("admits requests without an Origin (non-browser MCP clients)", () => {
|
|
127
|
+
expect(originRejection(undefined, "POST", policy)).toBeUndefined();
|
|
128
|
+
expect(originRejection("", "POST", policy)).toBeUndefined();
|
|
129
|
+
});
|
|
130
|
+
it("skips the safe methods, whatever the origin", () => {
|
|
131
|
+
expect(originRejection("https://attacker.example", "GET", policy)).toBeUndefined();
|
|
132
|
+
expect(originRejection("null", "HEAD", policy)).toBeUndefined();
|
|
133
|
+
});
|
|
134
|
+
it.each([
|
|
135
|
+
"http://localhost:6274",
|
|
136
|
+
"https://127.0.0.1",
|
|
137
|
+
"http://[::1]:3000",
|
|
138
|
+
"https://mcp.example.com",
|
|
139
|
+
"https://app.example.com",
|
|
140
|
+
"http://tools.example.com:9000",
|
|
141
|
+
])("admits %s", (origin) => {
|
|
142
|
+
expect(originRejection(origin, "POST", policy)).toBeUndefined();
|
|
143
|
+
});
|
|
144
|
+
it.each([
|
|
145
|
+
"https://attacker.example",
|
|
146
|
+
"http://app.example.com", // exact origin: scheme counts
|
|
147
|
+
"https://app.example.com:8443", // and so does the port
|
|
148
|
+
"https://mcp.example.com.attacker.example",
|
|
149
|
+
"null",
|
|
150
|
+
"not a url",
|
|
151
|
+
])("rejects %s on a POST", (origin) => {
|
|
152
|
+
const reason = originRejection(origin, "POST", policy);
|
|
153
|
+
expect(reason).toContain(`Origin "${origin}" is not allowed`);
|
|
154
|
+
expect(reason).toContain("MCP_ALLOWED_ORIGINS");
|
|
155
|
+
});
|
|
156
|
+
it("admits anything when Origin validation is off", () => {
|
|
157
|
+
expect(originRejection("https://attacker.example", "POST", { ...policy, allowedOrigins: "*" })).toBeUndefined();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
describe("edgeRejection", () => {
|
|
161
|
+
const request = (overrides = {}) => ({
|
|
162
|
+
method: "POST",
|
|
163
|
+
path: "/mcp",
|
|
164
|
+
host: "mcp.example.com",
|
|
165
|
+
origin: undefined,
|
|
166
|
+
...overrides,
|
|
167
|
+
});
|
|
168
|
+
it("passes a request whose Host and Origin are allowed", () => {
|
|
169
|
+
expect(edgeRejection(request({ origin: "https://app.example.com" }), policy)).toBeUndefined();
|
|
170
|
+
});
|
|
171
|
+
it("reports the Host before the Origin", () => {
|
|
172
|
+
const reason = edgeRejection(request({ host: "attacker.example", origin: "https://attacker.example" }), policy);
|
|
173
|
+
expect(reason).toMatch(/^Host "attacker\.example" is not allowed/);
|
|
174
|
+
});
|
|
175
|
+
it("reports a foreign Origin when the Host passes", () => {
|
|
176
|
+
const reason = edgeRejection(request({ origin: "https://attacker.example" }), policy);
|
|
177
|
+
expect(reason).toMatch(/^Origin "https:\/\/attacker\.example" is not allowed/);
|
|
178
|
+
});
|
|
179
|
+
it("passes the exempt path prefixes whatever their headers", () => {
|
|
180
|
+
const foreign = { host: "10.0.0.7", origin: "https://attacker.example" };
|
|
181
|
+
expect(edgeRejection(request({ path: "/metrics", ...foreign }), policy, ["/metrics"])).toBe(undefined);
|
|
182
|
+
expect(edgeRejection(request({ path: "/metrics2", ...foreign }), policy, ["/metrics"])).toBeDefined();
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
describe("jsonRpcErrorBody", () => {
|
|
186
|
+
it("is a JSON-RPC error with a null id", () => {
|
|
187
|
+
expect(JSON.parse(jsonRpcErrorBody("nope"))).toEqual({
|
|
188
|
+
jsonrpc: "2.0",
|
|
189
|
+
error: { code: -32000, message: "nope" },
|
|
190
|
+
id: null,
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
describe("installHttpEdgeGuard", () => {
|
|
195
|
+
function install(edge, exemptPaths) {
|
|
196
|
+
let middleware;
|
|
197
|
+
const host = {
|
|
198
|
+
use: (path, handler) => {
|
|
199
|
+
expect(path).toBe("*");
|
|
200
|
+
middleware = handler;
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
installHttpEdgeGuard(host, edge, exemptPaths ? { exemptPaths } : undefined);
|
|
204
|
+
return async (method, path, headers) => {
|
|
205
|
+
const ctx = {
|
|
206
|
+
req: { method, path, header: (name) => headers[name] },
|
|
207
|
+
};
|
|
208
|
+
let passed = false;
|
|
209
|
+
const response = await middleware(ctx, () => {
|
|
210
|
+
passed = true;
|
|
211
|
+
return Promise.resolve();
|
|
212
|
+
});
|
|
213
|
+
return { passed, response: response ?? undefined };
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
it("passes allowed requests through", async () => {
|
|
217
|
+
const run = install(policy);
|
|
218
|
+
const result = await run("POST", "/mcp", {
|
|
219
|
+
host: "mcp.example.com",
|
|
220
|
+
origin: "https://app.example.com",
|
|
221
|
+
});
|
|
222
|
+
expect(result).toEqual({ passed: true, response: undefined });
|
|
223
|
+
});
|
|
224
|
+
it("answers 403 with a JSON-RPC body for a foreign Host, before the route runs", async () => {
|
|
225
|
+
const run = install(policy);
|
|
226
|
+
const { passed, response } = await run("POST", "/mcp", { host: "attacker.example" });
|
|
227
|
+
expect(passed).toBe(false);
|
|
228
|
+
expect(response?.status).toBe(403);
|
|
229
|
+
expect(response?.headers.get("content-type")).toBe("application/json");
|
|
230
|
+
const body = (await response.json());
|
|
231
|
+
expect(body.error.message).toMatch(/^Forbidden: Host "attacker\.example" is not allowed/);
|
|
232
|
+
});
|
|
233
|
+
it("answers 403 for a foreign Origin even when the Host is fine", async () => {
|
|
234
|
+
const run = install(policy);
|
|
235
|
+
const { passed, response } = await run("POST", "/mcp", {
|
|
236
|
+
host: "localhost:8400",
|
|
237
|
+
origin: "https://attacker.example",
|
|
238
|
+
});
|
|
239
|
+
expect(passed).toBe(false);
|
|
240
|
+
expect(response?.status).toBe(403);
|
|
241
|
+
});
|
|
242
|
+
it("exempts the listed path prefixes (probes reach the container by IP)", async () => {
|
|
243
|
+
const run = install(policy, ["/health"]);
|
|
244
|
+
for (const path of ["/health", "/health/ready"]) {
|
|
245
|
+
expect((await run("GET", path, { host: "10.0.0.7:8400" })).passed, path).toBe(true);
|
|
246
|
+
}
|
|
247
|
+
expect((await run("GET", "/healthz", { host: "10.0.0.7:8400" })).passed).toBe(false);
|
|
248
|
+
expect((await run("GET", "/mcp", { host: "10.0.0.7:8400" })).passed).toBe(false);
|
|
249
|
+
});
|
|
250
|
+
it("guards every path when nothing is exempt", async () => {
|
|
251
|
+
const run = install(policy);
|
|
252
|
+
expect((await run("GET", "/health", { host: "10.0.0.7" })).passed).toBe(false);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
//# sourceMappingURL=http-edge.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-edge.test.js","sourceRoot":"","sources":["../src/http-edge.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Registry } from "prom-client";
|
|
2
|
+
import type { HttpRouteHost } from "./health.js";
|
|
3
|
+
import { type ToolCallMiddlewareHost } from "./host-boot.js";
|
|
4
|
+
/** The slice of hono's context the HTTP middleware reads — structural, like the other host ports. */
|
|
5
|
+
export interface HttpMiddlewareContext {
|
|
6
|
+
req: {
|
|
7
|
+
method: string;
|
|
8
|
+
path: string;
|
|
9
|
+
};
|
|
10
|
+
res: {
|
|
11
|
+
status: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** `server.use("*", middleware)` — hono's catch-all middleware registration. */
|
|
15
|
+
export interface HttpMiddlewareHost {
|
|
16
|
+
use(path: "*", handler: (ctx: HttpMiddlewareContext, next: () => Promise<void>) => Promise<void>): unknown;
|
|
17
|
+
}
|
|
18
|
+
export type MetricsHost = HttpRouteHost & HttpMiddlewareHost & ToolCallMiddlewareHost;
|
|
19
|
+
export interface MetricsOptions {
|
|
20
|
+
/** Scrape route (default `/metrics`). */
|
|
21
|
+
path?: string;
|
|
22
|
+
/** Name prefix for the server's own metrics (default `mcp_`). */
|
|
23
|
+
prefix?: string;
|
|
24
|
+
/** Collect prom-client's process/Node.js default metrics (default true). */
|
|
25
|
+
defaultMetrics?: boolean;
|
|
26
|
+
/** Routes kept verbatim in the `route` label; everything else is `other`. */
|
|
27
|
+
routes?: readonly string[];
|
|
28
|
+
/** Registry to populate (default: a fresh one — never the global registry, so hosts and tests stay isolated). */
|
|
29
|
+
registry?: Registry;
|
|
30
|
+
/** Bearer token the scrape requires (401 otherwise); unset = open. */
|
|
31
|
+
token?: string;
|
|
32
|
+
}
|
|
33
|
+
/** Constant-time `Authorization: Bearer <token>` check (hashing equalizes the lengths). */
|
|
34
|
+
export declare function bearerMatches(authorization: string | undefined, token: string): boolean;
|
|
35
|
+
/** Exact match or a sub-path of a known route keeps its label; anything else folds into `other`. */
|
|
36
|
+
export declare function routeLabel(path: string, routes?: readonly string[]): string;
|
|
37
|
+
/**
|
|
38
|
+
* Register the collectors and the scrape route. Returns the registry so a
|
|
39
|
+
* host can add its own instruments or serve it elsewhere.
|
|
40
|
+
*
|
|
41
|
+
* Call it BEFORE registering routes that should be counted — the health
|
|
42
|
+
* probes included: hono runs handlers in registration order and stops at the
|
|
43
|
+
* first response, so a route registered earlier never reaches the `*`
|
|
44
|
+
* middleware. The MCP transport and the OAuth discovery routes are mounted
|
|
45
|
+
* by `listen()`, i.e. always after this.
|
|
46
|
+
*/
|
|
47
|
+
export declare function installMetrics(server: MetricsHost, options?: MetricsOptions): Registry;
|
|
48
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAuBA,OAAO,EAA6C,QAAQ,EAAE,MAAM,aAAa,CAAA;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAA+B,KAAK,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAEzF,qGAAqG;AACrG,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACrC,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CACxB;AAED,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC,GAAG,CACD,IAAI,EAAE,GAAG,EACT,OAAO,EAAE,CAAC,GAAG,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAChF,OAAO,CAAA;CACX;AAED,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,kBAAkB,GAAG,sBAAsB,CAAA;AAErF,MAAM,WAAW,cAAc;IAC7B,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4EAA4E;IAC5E,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,iHAAiH;IACjH,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAOD,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAGvF;AAQD,oGAAoG;AACpG,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,SAAS,MAAM,EAAmB,GAAG,MAAM,CAE3F;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,cAAmB,GAAG,QAAQ,CAkF1F"}
|
package/dist/metrics.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prometheus metrics for composed-server hosts (server path only): a scrape
|
|
3
|
+
* endpoint (pull — a ServiceMonitor target, unlike the engine's OTLP push)
|
|
4
|
+
* fed by three sources:
|
|
5
|
+
*
|
|
6
|
+
* - `mcp:tools/call` middleware → per-tool call counter + duration histogram.
|
|
7
|
+
* Tool names are a finite catalogue, so the `tool` label stays bounded;
|
|
8
|
+
* arguments, users and sessions are never labels (cardinality + PII). It
|
|
9
|
+
* counts the calls that reached a tool's handler: the SDK refuses an unknown
|
|
10
|
+
* tool or arguments that fail the input schema before that, so those show
|
|
11
|
+
* only in mcp-use's request log (and as `/mcp` requests below).
|
|
12
|
+
* - hono `*` middleware → HTTP request counter + duration histogram. The
|
|
13
|
+
* `route` label is folded onto the known route set (`other` for the rest)
|
|
14
|
+
* because request paths are caller-controlled.
|
|
15
|
+
* - prom-client's default collectors → process/event-loop/heap gauges under
|
|
16
|
+
* their standard names (`process_*`, `nodejs_*`), which the stock Node.js
|
|
17
|
+
* Grafana dashboards expect — deliberately NOT prefixed.
|
|
18
|
+
*
|
|
19
|
+
* Outside mcp-use's OAuth gate like the health probes (scoped to the MCP base
|
|
20
|
+
* path): set `token` (the composed server's `MCP_METRICS_TOKEN`) to require
|
|
21
|
+
* `Authorization: Bearer <token>`, or front `/metrics` with network policy.
|
|
22
|
+
*/
|
|
23
|
+
import { createHash, timingSafeEqual } from "node:crypto";
|
|
24
|
+
import { collectDefaultMetrics, Counter, Histogram, Registry } from "prom-client";
|
|
25
|
+
import { toolCallOutcome, toolNameOf } from "./host-boot.js";
|
|
26
|
+
const DEFAULT_ROUTES = ["/mcp", "/health", "/metrics", "/.well-known", "/fonts"];
|
|
27
|
+
const DURATION_BUCKETS = [0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30];
|
|
28
|
+
const digest = (value) => createHash("sha256").update(value).digest();
|
|
29
|
+
/** Constant-time `Authorization: Bearer <token>` check (hashing equalizes the lengths). */
|
|
30
|
+
export function bearerMatches(authorization, token) {
|
|
31
|
+
const match = /^Bearer\s+(.+)$/i.exec(authorization?.trim() ?? "");
|
|
32
|
+
return match !== null && timingSafeEqual(digest(match[1]), digest(token));
|
|
33
|
+
}
|
|
34
|
+
/** The `Authorization` header from a hono-shaped route ctx (structural, like the other ports). */
|
|
35
|
+
const authorizationOf = (ctx) => ctx?.req?.header?.("authorization");
|
|
36
|
+
/** Exact match or a sub-path of a known route keeps its label; anything else folds into `other`. */
|
|
37
|
+
export function routeLabel(path, routes = DEFAULT_ROUTES) {
|
|
38
|
+
return routes.find((route) => path === route || path.startsWith(`${route}/`)) ?? "other";
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Register the collectors and the scrape route. Returns the registry so a
|
|
42
|
+
* host can add its own instruments or serve it elsewhere.
|
|
43
|
+
*
|
|
44
|
+
* Call it BEFORE registering routes that should be counted — the health
|
|
45
|
+
* probes included: hono runs handlers in registration order and stops at the
|
|
46
|
+
* first response, so a route registered earlier never reaches the `*`
|
|
47
|
+
* middleware. The MCP transport and the OAuth discovery routes are mounted
|
|
48
|
+
* by `listen()`, i.e. always after this.
|
|
49
|
+
*/
|
|
50
|
+
export function installMetrics(server, options = {}) {
|
|
51
|
+
const { path = "/metrics", prefix = "mcp_", defaultMetrics = true, routes = DEFAULT_ROUTES, registry = new Registry(), token, } = options;
|
|
52
|
+
if (defaultMetrics)
|
|
53
|
+
collectDefaultMetrics({ register: registry });
|
|
54
|
+
const toolCalls = new Counter({
|
|
55
|
+
name: `${prefix}tool_calls_total`,
|
|
56
|
+
help: "MCP tools/call invocations by tool and outcome (ok | error).",
|
|
57
|
+
labelNames: ["tool", "outcome"],
|
|
58
|
+
registers: [registry],
|
|
59
|
+
});
|
|
60
|
+
const toolDuration = new Histogram({
|
|
61
|
+
name: `${prefix}tool_call_duration_seconds`,
|
|
62
|
+
help: "MCP tools/call handler duration in seconds.",
|
|
63
|
+
labelNames: ["tool"],
|
|
64
|
+
buckets: DURATION_BUCKETS,
|
|
65
|
+
registers: [registry],
|
|
66
|
+
});
|
|
67
|
+
const httpRequests = new Counter({
|
|
68
|
+
name: `${prefix}http_requests_total`,
|
|
69
|
+
help: "HTTP requests by method, route and status code.",
|
|
70
|
+
labelNames: ["method", "route", "status"],
|
|
71
|
+
registers: [registry],
|
|
72
|
+
});
|
|
73
|
+
const httpDuration = new Histogram({
|
|
74
|
+
name: `${prefix}http_request_duration_seconds`,
|
|
75
|
+
help: "HTTP request duration in seconds by method and route.",
|
|
76
|
+
labelNames: ["method", "route"],
|
|
77
|
+
buckets: DURATION_BUCKETS,
|
|
78
|
+
registers: [registry],
|
|
79
|
+
});
|
|
80
|
+
server.use("mcp:tools/call", async (ctx, next) => {
|
|
81
|
+
const tool = toolNameOf(ctx);
|
|
82
|
+
const stop = toolDuration.startTimer({ tool });
|
|
83
|
+
// A throwing handler never reaches the assignment below — it stays `error`.
|
|
84
|
+
let outcome = "error";
|
|
85
|
+
try {
|
|
86
|
+
const result = await next();
|
|
87
|
+
outcome = toolCallOutcome(result);
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
stop();
|
|
92
|
+
toolCalls.inc({ tool, outcome });
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
server.use("*", async (ctx, next) => {
|
|
96
|
+
const method = ctx.req.method;
|
|
97
|
+
const route = routeLabel(ctx.req.path, routes);
|
|
98
|
+
const stop = httpDuration.startTimer({ method, route });
|
|
99
|
+
// hono routes handler errors through its error handler (c.res = 500), so
|
|
100
|
+
// `next()` normally resolves; the fallback covers an error escaping it.
|
|
101
|
+
let status = "500";
|
|
102
|
+
try {
|
|
103
|
+
await next();
|
|
104
|
+
status = String(ctx.res.status);
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
stop();
|
|
108
|
+
httpRequests.inc({ method, route, status });
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
server.get(path, async (ctx) => {
|
|
112
|
+
if (token !== undefined && !bearerMatches(authorizationOf(ctx), token)) {
|
|
113
|
+
return new Response("Unauthorized\n", {
|
|
114
|
+
status: 401,
|
|
115
|
+
headers: { "www-authenticate": 'Bearer realm="metrics"', "cache-control": "no-store" },
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return new Response(await registry.metrics(), {
|
|
119
|
+
headers: { "content-type": registry.contentType, "cache-control": "no-store" },
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
return registry;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.test.d.ts","sourceRoot":"","sources":["../src/metrics.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { Registry } from "prom-client";
|
|
3
|
+
import { bearerMatches, installMetrics, routeLabel, } from "./metrics.js";
|
|
4
|
+
function install(options) {
|
|
5
|
+
const routes = new Map();
|
|
6
|
+
let http;
|
|
7
|
+
let tool;
|
|
8
|
+
const server = {
|
|
9
|
+
get: (path, handler) => routes.set(path, handler),
|
|
10
|
+
use: (pattern, handler) => {
|
|
11
|
+
if (pattern === "*")
|
|
12
|
+
http = handler;
|
|
13
|
+
else
|
|
14
|
+
tool = handler;
|
|
15
|
+
return undefined;
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
const registry = installMetrics(server, { defaultMetrics: false, ...options });
|
|
19
|
+
if (!http || !tool)
|
|
20
|
+
throw new Error("middlewares were not registered");
|
|
21
|
+
const scrape = async (path = "/metrics", authorization) => {
|
|
22
|
+
const handler = routes.get(path);
|
|
23
|
+
if (!handler)
|
|
24
|
+
throw new Error(`no route registered for ${path}`);
|
|
25
|
+
const res = await handler({
|
|
26
|
+
req: { header: (name) => (name === "authorization" ? authorization : undefined) },
|
|
27
|
+
});
|
|
28
|
+
return { status: res.status, headers: res.headers, text: await res.text() };
|
|
29
|
+
};
|
|
30
|
+
const request = (method, path, status, next) => http({ req: { method, path }, res: { status } }, next ?? (async () => { }));
|
|
31
|
+
return { routes, registry, scrape, request, tool };
|
|
32
|
+
}
|
|
33
|
+
describe("bearerMatches", () => {
|
|
34
|
+
it("accepts exactly `Bearer <token>` (scheme case-insensitive)", () => {
|
|
35
|
+
expect(bearerMatches("Bearer s3cret", "s3cret")).toBe(true);
|
|
36
|
+
expect(bearerMatches("bearer s3cret ", "s3cret")).toBe(true);
|
|
37
|
+
expect(bearerMatches("Bearer s3cret2", "s3cret")).toBe(false);
|
|
38
|
+
expect(bearerMatches("Bearer s3cre", "s3cret")).toBe(false);
|
|
39
|
+
expect(bearerMatches("Basic s3cret", "s3cret")).toBe(false);
|
|
40
|
+
expect(bearerMatches("s3cret", "s3cret")).toBe(false);
|
|
41
|
+
expect(bearerMatches("Bearer ", "s3cret")).toBe(false);
|
|
42
|
+
expect(bearerMatches(undefined, "s3cret")).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
describe("routeLabel", () => {
|
|
46
|
+
it("keeps known routes and their sub-paths, folds everything else into other", () => {
|
|
47
|
+
expect(routeLabel("/mcp")).toBe("/mcp");
|
|
48
|
+
expect(routeLabel("/mcp/inspector")).toBe("/mcp");
|
|
49
|
+
expect(routeLabel("/health/ready")).toBe("/health");
|
|
50
|
+
expect(routeLabel("/.well-known/oauth-authorization-server")).toBe("/.well-known");
|
|
51
|
+
expect(routeLabel("/metrics")).toBe("/metrics");
|
|
52
|
+
expect(routeLabel("/mcpx")).toBe("other");
|
|
53
|
+
expect(routeLabel("/admin/../etc/passwd")).toBe("other");
|
|
54
|
+
expect(routeLabel("/")).toBe("other");
|
|
55
|
+
});
|
|
56
|
+
it("honors a custom route set", () => {
|
|
57
|
+
expect(routeLabel("/api/v1/x", ["/api"])).toBe("/api");
|
|
58
|
+
expect(routeLabel("/mcp", ["/api"])).toBe("other");
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe("installMetrics token", () => {
|
|
62
|
+
it("answers 401 with a Bearer challenge unless the scrape carries the token", async () => {
|
|
63
|
+
const { scrape } = install({ token: "s3cret" });
|
|
64
|
+
const anonymous = await scrape();
|
|
65
|
+
expect(anonymous.status).toBe(401);
|
|
66
|
+
expect(anonymous.headers.get("www-authenticate")).toBe('Bearer realm="metrics"');
|
|
67
|
+
expect(anonymous.text).not.toContain("mcp_tool_calls_total");
|
|
68
|
+
expect((await scrape("/metrics", "Bearer wrong")).status).toBe(401);
|
|
69
|
+
const authorized = await scrape("/metrics", "Bearer s3cret");
|
|
70
|
+
expect(authorized.status).toBe(200);
|
|
71
|
+
expect(authorized.text).toContain("mcp_tool_calls_total");
|
|
72
|
+
});
|
|
73
|
+
it("stays open without a token", async () => {
|
|
74
|
+
const { scrape } = install();
|
|
75
|
+
expect((await scrape()).status).toBe(200);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
describe("installMetrics", () => {
|
|
79
|
+
it("serves the registry as Prometheus text on the scrape route", async () => {
|
|
80
|
+
const { routes, scrape } = install();
|
|
81
|
+
expect([...routes.keys()]).toEqual(["/metrics"]);
|
|
82
|
+
const res = await scrape();
|
|
83
|
+
expect(res.status).toBe(200);
|
|
84
|
+
expect(res.headers.get("content-type")).toContain("text/plain");
|
|
85
|
+
expect(res.headers.get("cache-control")).toBe("no-store");
|
|
86
|
+
expect(res.text).toContain("# HELP mcp_tool_calls_total");
|
|
87
|
+
expect(res.text).toContain("# HELP mcp_http_requests_total");
|
|
88
|
+
});
|
|
89
|
+
it("honors a custom scrape path, prefix and registry", async () => {
|
|
90
|
+
const registry = new Registry();
|
|
91
|
+
const { routes, registry: returned, scrape, } = install({
|
|
92
|
+
path: "/internal/metrics",
|
|
93
|
+
prefix: "acme_",
|
|
94
|
+
registry,
|
|
95
|
+
});
|
|
96
|
+
expect(returned).toBe(registry);
|
|
97
|
+
expect([...routes.keys()]).toEqual(["/internal/metrics"]);
|
|
98
|
+
const { text } = await scrape("/internal/metrics");
|
|
99
|
+
expect(text).toContain("acme_tool_calls_total");
|
|
100
|
+
expect(text).not.toContain("mcp_tool_calls_total");
|
|
101
|
+
});
|
|
102
|
+
it("collects the default process metrics unless disabled", async () => {
|
|
103
|
+
const { scrape } = install({ defaultMetrics: true });
|
|
104
|
+
expect((await scrape()).text).toContain("process_cpu_user_seconds_total");
|
|
105
|
+
const { scrape: scrapeWithout } = install();
|
|
106
|
+
expect((await scrapeWithout()).text).not.toContain("process_cpu_user_seconds_total");
|
|
107
|
+
});
|
|
108
|
+
it("counts tool calls by name and outcome and observes their duration", async () => {
|
|
109
|
+
const { tool, scrape } = install();
|
|
110
|
+
const ok = { content: [] };
|
|
111
|
+
await expect(tool({ params: { name: "notes_list_notes" } }, async () => ok)).resolves.toBe(ok);
|
|
112
|
+
await tool({ params: { name: "notes_list_notes" } }, async () => ok);
|
|
113
|
+
await tool({ params: { name: "notes_show_notes" } }, async () => ({ isError: true }));
|
|
114
|
+
await tool({}, async () => ok);
|
|
115
|
+
const { text } = await scrape();
|
|
116
|
+
expect(text).toContain('mcp_tool_calls_total{tool="notes_list_notes",outcome="ok"} 2');
|
|
117
|
+
expect(text).toContain('mcp_tool_calls_total{tool="notes_show_notes",outcome="error"} 1');
|
|
118
|
+
expect(text).toContain('mcp_tool_calls_total{tool="unknown",outcome="ok"} 1');
|
|
119
|
+
expect(text).toContain('mcp_tool_call_duration_seconds_count{tool="notes_list_notes"} 2');
|
|
120
|
+
});
|
|
121
|
+
it("counts a throwing tool handler as error and rethrows", async () => {
|
|
122
|
+
const { tool, scrape } = install();
|
|
123
|
+
const boom = new Error("boom");
|
|
124
|
+
await expect(tool({ params: { name: "notes_list_notes" } }, async () => {
|
|
125
|
+
throw boom;
|
|
126
|
+
})).rejects.toBe(boom);
|
|
127
|
+
const { text } = await scrape();
|
|
128
|
+
expect(text).toContain('mcp_tool_calls_total{tool="notes_list_notes",outcome="error"} 1');
|
|
129
|
+
expect(text).toContain('mcp_tool_call_duration_seconds_count{tool="notes_list_notes"} 1');
|
|
130
|
+
});
|
|
131
|
+
it("counts HTTP requests by method, normalised route and status", async () => {
|
|
132
|
+
const { request, scrape } = install();
|
|
133
|
+
await request("GET", "/health/ready", 200);
|
|
134
|
+
await request("GET", "/health/live", 200);
|
|
135
|
+
await request("POST", "/mcp", 401);
|
|
136
|
+
await request("GET", "/does/not/exist", 404);
|
|
137
|
+
const { text } = await scrape();
|
|
138
|
+
expect(text).toContain('mcp_http_requests_total{method="GET",route="/health",status="200"} 2');
|
|
139
|
+
expect(text).toContain('mcp_http_requests_total{method="POST",route="/mcp",status="401"} 1');
|
|
140
|
+
expect(text).toContain('mcp_http_requests_total{method="GET",route="other",status="404"} 1');
|
|
141
|
+
expect(text).toContain('mcp_http_request_duration_seconds_count{method="GET",route="/health"} 2');
|
|
142
|
+
expect(text).not.toContain("/does/not/exist");
|
|
143
|
+
});
|
|
144
|
+
it("records 500 for an error escaping hono's error handler and rethrows", async () => {
|
|
145
|
+
const { request, scrape } = install();
|
|
146
|
+
const boom = new Error("boom");
|
|
147
|
+
await expect(request("POST", "/mcp", 200, async () => {
|
|
148
|
+
throw boom;
|
|
149
|
+
})).rejects.toBe(boom);
|
|
150
|
+
const { text } = await scrape();
|
|
151
|
+
expect(text).toContain('mcp_http_requests_total{method="POST",route="/mcp",status="500"} 1');
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
//# sourceMappingURL=metrics.test.js.map
|