@frontmcp/ui 0.5.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 +201 -0
- package/README.md +438 -0
- package/package.json +147 -0
- package/src/adapters/index.d.ts +10 -0
- package/src/adapters/index.js +18 -0
- package/src/adapters/index.js.map +1 -0
- package/src/adapters/platform-meta.d.ts +165 -0
- package/src/adapters/platform-meta.js +310 -0
- package/src/adapters/platform-meta.js.map +1 -0
- package/src/base-template/bridge.d.ts +89 -0
- package/src/base-template/bridge.js +452 -0
- package/src/base-template/bridge.js.map +1 -0
- package/src/base-template/default-base-template.d.ts +91 -0
- package/src/base-template/default-base-template.js +435 -0
- package/src/base-template/default-base-template.js.map +1 -0
- package/src/base-template/index.d.ts +14 -0
- package/src/base-template/index.js +30 -0
- package/src/base-template/index.js.map +1 -0
- package/src/base-template/polyfills.d.ts +30 -0
- package/src/base-template/polyfills.js +190 -0
- package/src/base-template/polyfills.js.map +1 -0
- package/src/base-template/theme-styles.d.ts +73 -0
- package/src/base-template/theme-styles.js +95 -0
- package/src/base-template/theme-styles.js.map +1 -0
- package/src/bridge/adapters/base-adapter.d.ts +103 -0
- package/src/bridge/adapters/base-adapter.js +314 -0
- package/src/bridge/adapters/base-adapter.js.map +1 -0
- package/src/bridge/adapters/claude.adapter.d.ts +66 -0
- package/src/bridge/adapters/claude.adapter.js +145 -0
- package/src/bridge/adapters/claude.adapter.js.map +1 -0
- package/src/bridge/adapters/ext-apps.adapter.d.ts +142 -0
- package/src/bridge/adapters/ext-apps.adapter.js +416 -0
- package/src/bridge/adapters/ext-apps.adapter.js.map +1 -0
- package/src/bridge/adapters/gemini.adapter.d.ts +63 -0
- package/src/bridge/adapters/gemini.adapter.js +160 -0
- package/src/bridge/adapters/gemini.adapter.js.map +1 -0
- package/src/bridge/adapters/generic.adapter.d.ts +55 -0
- package/src/bridge/adapters/generic.adapter.js +108 -0
- package/src/bridge/adapters/generic.adapter.js.map +1 -0
- package/src/bridge/adapters/index.d.ts +25 -0
- package/src/bridge/adapters/index.js +65 -0
- package/src/bridge/adapters/index.js.map +1 -0
- package/src/bridge/adapters/openai.adapter.d.ts +64 -0
- package/src/bridge/adapters/openai.adapter.js +194 -0
- package/src/bridge/adapters/openai.adapter.js.map +1 -0
- package/src/bridge/core/adapter-registry.d.ts +121 -0
- package/src/bridge/core/adapter-registry.js +271 -0
- package/src/bridge/core/adapter-registry.js.map +1 -0
- package/src/bridge/core/bridge-factory.d.ts +198 -0
- package/src/bridge/core/bridge-factory.js +428 -0
- package/src/bridge/core/bridge-factory.js.map +1 -0
- package/src/bridge/core/index.d.ts +9 -0
- package/src/bridge/core/index.js +22 -0
- package/src/bridge/core/index.js.map +1 -0
- package/src/bridge/index.d.ts +61 -0
- package/src/bridge/index.js +94 -0
- package/src/bridge/index.js.map +1 -0
- package/src/bridge/runtime/iife-generator.d.ts +61 -0
- package/src/bridge/runtime/iife-generator.js +940 -0
- package/src/bridge/runtime/iife-generator.js.map +1 -0
- package/src/bridge/runtime/index.d.ts +8 -0
- package/src/bridge/runtime/index.js +16 -0
- package/src/bridge/runtime/index.js.map +1 -0
- package/src/bridge/types.d.ts +385 -0
- package/src/bridge/types.js +11 -0
- package/src/bridge/types.js.map +1 -0
- package/src/build/cdn-resources.d.ts +140 -0
- package/src/build/cdn-resources.js +314 -0
- package/src/build/cdn-resources.js.map +1 -0
- package/src/build/index.d.ts +294 -0
- package/src/build/index.js +325 -0
- package/src/build/index.js.map +1 -0
- package/src/build/widget-manifest.d.ts +212 -0
- package/src/build/widget-manifest.js +652 -0
- package/src/build/widget-manifest.js.map +1 -0
- package/src/bundler/bundler.d.ts +110 -0
- package/src/bundler/bundler.js +432 -0
- package/src/bundler/bundler.js.map +1 -0
- package/src/bundler/cache.d.ts +172 -0
- package/src/bundler/cache.js +250 -0
- package/src/bundler/cache.js.map +1 -0
- package/src/bundler/index.d.ts +41 -0
- package/src/bundler/index.js +73 -0
- package/src/bundler/index.js.map +1 -0
- package/src/bundler/sandbox/enclave-adapter.d.ts +120 -0
- package/src/bundler/sandbox/enclave-adapter.js +339 -0
- package/src/bundler/sandbox/enclave-adapter.js.map +1 -0
- package/src/bundler/sandbox/executor.d.ts +13 -0
- package/src/bundler/sandbox/executor.js +22 -0
- package/src/bundler/sandbox/executor.js.map +1 -0
- package/src/bundler/sandbox/policy.d.ts +61 -0
- package/src/bundler/sandbox/policy.js +238 -0
- package/src/bundler/sandbox/policy.js.map +1 -0
- package/src/bundler/types.d.ts +347 -0
- package/src/bundler/types.js +132 -0
- package/src/bundler/types.js.map +1 -0
- package/src/components/alert.d.ts +71 -0
- package/src/components/alert.js +189 -0
- package/src/components/alert.js.map +1 -0
- package/src/components/alert.schema.d.ts +114 -0
- package/src/components/alert.schema.js +105 -0
- package/src/components/alert.schema.js.map +1 -0
- package/src/components/avatar.d.ts +76 -0
- package/src/components/avatar.js +176 -0
- package/src/components/avatar.js.map +1 -0
- package/src/components/avatar.schema.d.ts +169 -0
- package/src/components/avatar.schema.js +103 -0
- package/src/components/avatar.schema.js.map +1 -0
- package/src/components/badge.d.ts +70 -0
- package/src/components/badge.js +149 -0
- package/src/components/badge.js.map +1 -0
- package/src/components/badge.schema.d.ts +109 -0
- package/src/components/badge.schema.js +96 -0
- package/src/components/badge.schema.js.map +1 -0
- package/src/components/button.d.ts +111 -0
- package/src/components/button.js +336 -0
- package/src/components/button.js.map +1 -0
- package/src/components/button.schema.d.ts +148 -0
- package/src/components/button.schema.js +121 -0
- package/src/components/button.schema.js.map +1 -0
- package/src/components/card.d.ts +60 -0
- package/src/components/card.js +117 -0
- package/src/components/card.js.map +1 -0
- package/src/components/card.schema.d.ts +113 -0
- package/src/components/card.schema.js +98 -0
- package/src/components/card.schema.js.map +1 -0
- package/src/components/form.d.ts +239 -0
- package/src/components/form.js +420 -0
- package/src/components/form.js.map +1 -0
- package/src/components/form.schema.d.ts +441 -0
- package/src/components/form.schema.js +406 -0
- package/src/components/form.schema.js.map +1 -0
- package/src/components/index.d.ts +29 -0
- package/src/components/index.js +98 -0
- package/src/components/index.js.map +1 -0
- package/src/components/list.d.ts +127 -0
- package/src/components/list.js +279 -0
- package/src/components/list.js.map +1 -0
- package/src/components/list.schema.d.ts +134 -0
- package/src/components/list.schema.js +168 -0
- package/src/components/list.schema.js.map +1 -0
- package/src/components/modal.d.ts +111 -0
- package/src/components/modal.js +260 -0
- package/src/components/modal.js.map +1 -0
- package/src/components/modal.schema.d.ts +186 -0
- package/src/components/modal.schema.js +167 -0
- package/src/components/modal.schema.js.map +1 -0
- package/src/components/table.d.ts +105 -0
- package/src/components/table.js +283 -0
- package/src/components/table.js.map +1 -0
- package/src/components/table.schema.d.ts +159 -0
- package/src/components/table.schema.js +173 -0
- package/src/components/table.schema.js.map +1 -0
- package/src/handlebars/helpers.d.ts +348 -0
- package/src/handlebars/helpers.js +605 -0
- package/src/handlebars/helpers.js.map +1 -0
- package/src/handlebars/index.d.ts +193 -0
- package/src/handlebars/index.js +350 -0
- package/src/handlebars/index.js.map +1 -0
- package/src/index.d.ts +50 -0
- package/src/index.js +192 -0
- package/src/index.js.map +1 -0
- package/src/layouts/base.d.ts +88 -0
- package/src/layouts/base.js +227 -0
- package/src/layouts/base.js.map +1 -0
- package/src/layouts/index.d.ts +7 -0
- package/src/layouts/index.js +25 -0
- package/src/layouts/index.js.map +1 -0
- package/src/layouts/presets.d.ts +133 -0
- package/src/layouts/presets.js +277 -0
- package/src/layouts/presets.js.map +1 -0
- package/src/pages/consent.d.ts +116 -0
- package/src/pages/consent.js +218 -0
- package/src/pages/consent.js.map +1 -0
- package/src/pages/error.d.ts +100 -0
- package/src/pages/error.js +263 -0
- package/src/pages/error.js.map +1 -0
- package/src/pages/index.d.ts +8 -0
- package/src/pages/index.js +27 -0
- package/src/pages/index.js.map +1 -0
- package/src/react/Alert.d.ts +101 -0
- package/src/react/Alert.js +51 -0
- package/src/react/Alert.js.map +1 -0
- package/src/react/Badge.d.ts +100 -0
- package/src/react/Badge.js +55 -0
- package/src/react/Badge.js.map +1 -0
- package/src/react/Button.d.ts +108 -0
- package/src/react/Button.js +52 -0
- package/src/react/Button.js.map +1 -0
- package/src/react/Card.d.ts +103 -0
- package/src/react/Card.js +55 -0
- package/src/react/Card.js.map +1 -0
- package/src/react/hooks/context.d.ts +178 -0
- package/src/react/hooks/context.js +287 -0
- package/src/react/hooks/context.js.map +1 -0
- package/src/react/hooks/index.d.ts +41 -0
- package/src/react/hooks/index.js +61 -0
- package/src/react/hooks/index.js.map +1 -0
- package/src/react/hooks/tools.d.ts +283 -0
- package/src/react/hooks/tools.js +465 -0
- package/src/react/hooks/tools.js.map +1 -0
- package/src/react/index.d.ts +80 -0
- package/src/react/index.js +113 -0
- package/src/react/index.js.map +1 -0
- package/src/react/types.d.ts +105 -0
- package/src/react/types.js +12 -0
- package/src/react/types.js.map +1 -0
- package/src/react/utils.d.ts +42 -0
- package/src/react/utils.js +99 -0
- package/src/react/utils.js.map +1 -0
- package/src/registry/index.d.ts +45 -0
- package/src/registry/index.js +67 -0
- package/src/registry/index.js.map +1 -0
- package/src/registry/render-template.d.ts +86 -0
- package/src/registry/render-template.js +239 -0
- package/src/registry/render-template.js.map +1 -0
- package/src/registry/tool-ui.registry.d.ts +260 -0
- package/src/registry/tool-ui.registry.js +438 -0
- package/src/registry/tool-ui.registry.js.map +1 -0
- package/src/registry/uri-utils.d.ts +55 -0
- package/src/registry/uri-utils.js +97 -0
- package/src/registry/uri-utils.js.map +1 -0
- package/src/render/index.d.ts +7 -0
- package/src/render/index.js +14 -0
- package/src/render/index.js.map +1 -0
- package/src/render/prerender.d.ts +56 -0
- package/src/render/prerender.js +98 -0
- package/src/render/prerender.js.map +1 -0
- package/src/renderers/cache.d.ts +144 -0
- package/src/renderers/cache.js +240 -0
- package/src/renderers/cache.js.map +1 -0
- package/src/renderers/html.renderer.d.ts +122 -0
- package/src/renderers/html.renderer.js +204 -0
- package/src/renderers/html.renderer.js.map +1 -0
- package/src/renderers/index.d.ts +35 -0
- package/src/renderers/index.js +70 -0
- package/src/renderers/index.js.map +1 -0
- package/src/renderers/mdx.renderer.d.ts +119 -0
- package/src/renderers/mdx.renderer.js +305 -0
- package/src/renderers/mdx.renderer.js.map +1 -0
- package/src/renderers/react.renderer.d.ts +95 -0
- package/src/renderers/react.renderer.js +260 -0
- package/src/renderers/react.renderer.js.map +1 -0
- package/src/renderers/registry.d.ts +133 -0
- package/src/renderers/registry.js +232 -0
- package/src/renderers/registry.js.map +1 -0
- package/src/renderers/types.d.ts +341 -0
- package/src/renderers/types.js +9 -0
- package/src/renderers/types.js.map +1 -0
- package/src/renderers/utils/detect.d.ts +106 -0
- package/src/renderers/utils/detect.js +267 -0
- package/src/renderers/utils/detect.js.map +1 -0
- package/src/renderers/utils/hash.d.ts +39 -0
- package/src/renderers/utils/hash.js +75 -0
- package/src/renderers/utils/hash.js.map +1 -0
- package/src/renderers/utils/index.d.ts +8 -0
- package/src/renderers/utils/index.js +28 -0
- package/src/renderers/utils/index.js.map +1 -0
- package/src/renderers/utils/transpiler.d.ts +88 -0
- package/src/renderers/utils/transpiler.js +215 -0
- package/src/renderers/utils/transpiler.js.map +1 -0
- package/src/runtime/adapters/html.adapter.d.ts +58 -0
- package/src/runtime/adapters/html.adapter.js +131 -0
- package/src/runtime/adapters/html.adapter.js.map +1 -0
- package/src/runtime/adapters/index.d.ts +25 -0
- package/src/runtime/adapters/index.js +54 -0
- package/src/runtime/adapters/index.js.map +1 -0
- package/src/runtime/adapters/mdx.adapter.d.ts +72 -0
- package/src/runtime/adapters/mdx.adapter.js +241 -0
- package/src/runtime/adapters/mdx.adapter.js.map +1 -0
- package/src/runtime/adapters/react.adapter.d.ts +69 -0
- package/src/runtime/adapters/react.adapter.js +245 -0
- package/src/runtime/adapters/react.adapter.js.map +1 -0
- package/src/runtime/adapters/types.d.ts +94 -0
- package/src/runtime/adapters/types.js +11 -0
- package/src/runtime/adapters/types.js.map +1 -0
- package/src/runtime/csp.d.ts +37 -0
- package/src/runtime/csp.js +140 -0
- package/src/runtime/csp.js.map +1 -0
- package/src/runtime/index.d.ts +16 -0
- package/src/runtime/index.js +72 -0
- package/src/runtime/index.js.map +1 -0
- package/src/runtime/mcp-bridge.d.ts +100 -0
- package/src/runtime/mcp-bridge.js +581 -0
- package/src/runtime/mcp-bridge.js.map +1 -0
- package/src/runtime/renderer-runtime.d.ts +132 -0
- package/src/runtime/renderer-runtime.js +389 -0
- package/src/runtime/renderer-runtime.js.map +1 -0
- package/src/runtime/sanitizer.d.ts +171 -0
- package/src/runtime/sanitizer.js +318 -0
- package/src/runtime/sanitizer.js.map +1 -0
- package/src/runtime/types.d.ts +414 -0
- package/src/runtime/types.js +12 -0
- package/src/runtime/types.js.map +1 -0
- package/src/runtime/wrapper.d.ts +375 -0
- package/src/runtime/wrapper.js +1793 -0
- package/src/runtime/wrapper.js.map +1 -0
- package/src/styles/index.d.ts +7 -0
- package/src/styles/index.js +11 -0
- package/src/styles/index.js.map +1 -0
- package/src/styles/variants.d.ts +50 -0
- package/src/styles/variants.js +175 -0
- package/src/styles/variants.js.map +1 -0
- package/src/theme/cdn.d.ts +194 -0
- package/src/theme/cdn.js +375 -0
- package/src/theme/cdn.js.map +1 -0
- package/src/theme/index.d.ts +17 -0
- package/src/theme/index.js +57 -0
- package/src/theme/index.js.map +1 -0
- package/src/theme/platforms.d.ts +106 -0
- package/src/theme/platforms.js +161 -0
- package/src/theme/platforms.js.map +1 -0
- package/src/theme/presets/github-openai.d.ts +49 -0
- package/src/theme/presets/github-openai.js +189 -0
- package/src/theme/presets/github-openai.js.map +1 -0
- package/src/theme/presets/index.d.ts +10 -0
- package/src/theme/presets/index.js +17 -0
- package/src/theme/presets/index.js.map +1 -0
- package/src/theme/theme.d.ts +395 -0
- package/src/theme/theme.js +332 -0
- package/src/theme/theme.js.map +1 -0
- package/src/tool-template/builder.d.ts +212 -0
- package/src/tool-template/builder.js +397 -0
- package/src/tool-template/builder.js.map +1 -0
- package/src/tool-template/index.d.ts +15 -0
- package/src/tool-template/index.js +38 -0
- package/src/tool-template/index.js.map +1 -0
- package/src/types/index.d.ts +13 -0
- package/src/types/index.js +26 -0
- package/src/types/index.js.map +1 -0
- package/src/types/ui-config.d.ts +357 -0
- package/src/types/ui-config.js +12 -0
- package/src/types/ui-config.js.map +1 -0
- package/src/types/ui-runtime.d.ts +965 -0
- package/src/types/ui-runtime.js +117 -0
- package/src/types/ui-runtime.js.map +1 -0
- package/src/validation/error-box.d.ts +55 -0
- package/src/validation/error-box.js +75 -0
- package/src/validation/error-box.js.map +1 -0
- package/src/validation/index.d.ts +12 -0
- package/src/validation/index.js +21 -0
- package/src/validation/index.js.map +1 -0
- package/src/validation/wrapper.d.ts +96 -0
- package/src/validation/wrapper.js +117 -0
- package/src/validation/wrapper.js.map +1 -0
- package/src/web-components/core/attribute-parser.d.ts +85 -0
- package/src/web-components/core/attribute-parser.js +189 -0
- package/src/web-components/core/attribute-parser.js.map +1 -0
- package/src/web-components/core/base-element.d.ts +197 -0
- package/src/web-components/core/base-element.js +289 -0
- package/src/web-components/core/base-element.js.map +1 -0
- package/src/web-components/core/index.d.ts +8 -0
- package/src/web-components/core/index.js +18 -0
- package/src/web-components/core/index.js.map +1 -0
- package/src/web-components/elements/fmcp-alert.d.ts +45 -0
- package/src/web-components/elements/fmcp-alert.js +93 -0
- package/src/web-components/elements/fmcp-alert.js.map +1 -0
- package/src/web-components/elements/fmcp-badge.d.ts +46 -0
- package/src/web-components/elements/fmcp-badge.js +99 -0
- package/src/web-components/elements/fmcp-badge.js.map +1 -0
- package/src/web-components/elements/fmcp-button.d.ts +124 -0
- package/src/web-components/elements/fmcp-button.js +233 -0
- package/src/web-components/elements/fmcp-button.js.map +1 -0
- package/src/web-components/elements/fmcp-card.d.ts +52 -0
- package/src/web-components/elements/fmcp-card.js +115 -0
- package/src/web-components/elements/fmcp-card.js.map +1 -0
- package/src/web-components/elements/fmcp-input.d.ts +95 -0
- package/src/web-components/elements/fmcp-input.js +248 -0
- package/src/web-components/elements/fmcp-input.js.map +1 -0
- package/src/web-components/elements/fmcp-select.d.ts +99 -0
- package/src/web-components/elements/fmcp-select.js +243 -0
- package/src/web-components/elements/fmcp-select.js.map +1 -0
- package/src/web-components/elements/index.d.ts +12 -0
- package/src/web-components/elements/index.js +34 -0
- package/src/web-components/elements/index.js.map +1 -0
- package/src/web-components/index.d.ts +49 -0
- package/src/web-components/index.js +75 -0
- package/src/web-components/index.js.map +1 -0
- package/src/web-components/register.d.ts +56 -0
- package/src/web-components/register.js +80 -0
- package/src/web-components/register.js.map +1 -0
- package/src/web-components/types.d.ts +121 -0
- package/src/web-components/types.js +25 -0
- package/src/web-components/types.js.map +1 -0
- package/src/widgets/index.d.ts +7 -0
- package/src/widgets/index.js +24 -0
- package/src/widgets/index.js.map +1 -0
- package/src/widgets/progress.d.ts +132 -0
- package/src/widgets/progress.js +303 -0
- package/src/widgets/progress.js.map +1 -0
- package/src/widgets/resource.d.ts +162 -0
- package/src/widgets/resource.js +340 -0
- package/src/widgets/resource.js.map +1 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file cdn.ts
|
|
3
|
+
* @description CDN Configuration for FrontMCP UI.
|
|
4
|
+
*
|
|
5
|
+
* Centralized configuration for all CDN resources used by FrontMCP UI.
|
|
6
|
+
* All resources are loaded at runtime - no build step required.
|
|
7
|
+
*
|
|
8
|
+
* For platforms with blocked network (e.g., Claude Artifacts),
|
|
9
|
+
* scripts can be fetched once and cached for inline injection.
|
|
10
|
+
*
|
|
11
|
+
* CDN URLs can be customized via theme configuration for:
|
|
12
|
+
* - Using private CDN mirrors
|
|
13
|
+
* - Self-hosting resources
|
|
14
|
+
* - Compliance with CSP policies
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { buildCdnScriptsFromTheme, DEFAULT_THEME } from '@frontmcp/ui';
|
|
19
|
+
*
|
|
20
|
+
* // Use default CDN URLs
|
|
21
|
+
* const scripts = buildCdnScripts();
|
|
22
|
+
*
|
|
23
|
+
* // Use theme-configured CDN URLs
|
|
24
|
+
* const themedScripts = buildCdnScriptsFromTheme(DEFAULT_THEME);
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @module @frontmcp/ui/theme/cdn
|
|
28
|
+
*/
|
|
29
|
+
import type { ThemeConfig } from './theme';
|
|
30
|
+
/**
|
|
31
|
+
* CDN resource configuration
|
|
32
|
+
*/
|
|
33
|
+
export declare const CDN: {
|
|
34
|
+
/**
|
|
35
|
+
* Tailwind CSS v4 Browser CDN
|
|
36
|
+
* Generates styles on-the-fly with @theme support
|
|
37
|
+
* @see https://tailwindcss.com/docs/installation/play-cdn
|
|
38
|
+
*/
|
|
39
|
+
readonly tailwind: "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4";
|
|
40
|
+
/**
|
|
41
|
+
* HTMX 2.x - High power tools for HTML
|
|
42
|
+
* Enables AJAX, WebSockets, Server Sent Events directly in HTML
|
|
43
|
+
* @see https://htmx.org
|
|
44
|
+
*/
|
|
45
|
+
readonly htmx: {
|
|
46
|
+
readonly url: "https://cdnjs.cloudflare.com/ajax/libs/htmx/2.0.7/htmx.min.js";
|
|
47
|
+
readonly integrity: "sha512-T6VLg/MJYMbLTmQ8VLvonbWg8VOvmDhXcOvHzCwo6ShdGuUU5SEcp1IAPXL4k9lVoMi8gRXl5K/S/zh43Y9rJA==";
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Alpine.js - Lightweight reactive framework
|
|
51
|
+
* Used for more complex client-side interactions
|
|
52
|
+
* @see https://alpinejs.dev
|
|
53
|
+
*/
|
|
54
|
+
readonly alpine: {
|
|
55
|
+
readonly url: "https://cdn.jsdelivr.net/npm/alpinejs@3.14.3/dist/cdn.min.js";
|
|
56
|
+
readonly integrity: "sha384-6zY8MFQJ/EqS1r4RJl+7j8rvZPuBWpT0RzWf+IFcKhxqUzQNmJzA1X1VEVZhYaEz";
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Google Fonts - Inter for modern UI typography
|
|
60
|
+
*/
|
|
61
|
+
readonly fonts: {
|
|
62
|
+
readonly preconnect: readonly ["https://fonts.googleapis.com", "https://fonts.gstatic.com"];
|
|
63
|
+
readonly inter: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";
|
|
64
|
+
readonly mono: "https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&display=swap";
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Lucide Icons - Beautiful & consistent icons
|
|
68
|
+
* @see https://lucide.dev
|
|
69
|
+
*/
|
|
70
|
+
readonly icons: {
|
|
71
|
+
readonly url: "https://cdn.jsdelivr.net/npm/lucide@0.294.0/dist/umd/lucide.min.js";
|
|
72
|
+
readonly integrity: "sha384-wpLmHb7v7V1LsEuTmPQ9tXqWZvTtRWWVqJuE+Yz6X0I6O2T6bHJVeXH1lVWqF4qE";
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Fetch a script and cache its content
|
|
77
|
+
*/
|
|
78
|
+
export declare function fetchScript(url: string): Promise<string>;
|
|
79
|
+
/**
|
|
80
|
+
* Fetch and cache all required scripts for offline use
|
|
81
|
+
* Call this at startup to prepare for blocked-network platforms
|
|
82
|
+
*/
|
|
83
|
+
export declare function fetchAndCacheScripts(options?: {
|
|
84
|
+
tailwind?: boolean;
|
|
85
|
+
htmx?: boolean;
|
|
86
|
+
alpine?: boolean;
|
|
87
|
+
icons?: boolean;
|
|
88
|
+
}): Promise<Map<string, string>>;
|
|
89
|
+
/**
|
|
90
|
+
* Get cached script content
|
|
91
|
+
*/
|
|
92
|
+
export declare function getCachedScript(url: string): string | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Check if a script is cached
|
|
95
|
+
*/
|
|
96
|
+
export declare function isScriptCached(url: string): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Clear the script cache
|
|
99
|
+
*/
|
|
100
|
+
export declare function clearScriptCache(): void;
|
|
101
|
+
/**
|
|
102
|
+
* Options for building CDN script tags
|
|
103
|
+
*/
|
|
104
|
+
export interface CdnScriptOptions {
|
|
105
|
+
/** Include Tailwind CSS (default: true) */
|
|
106
|
+
tailwind?: boolean;
|
|
107
|
+
/** Include HTMX (default: true) */
|
|
108
|
+
htmx?: boolean;
|
|
109
|
+
/** Include Alpine.js (default: false) */
|
|
110
|
+
alpine?: boolean;
|
|
111
|
+
/** Include Lucide icons (default: false) */
|
|
112
|
+
icons?: boolean;
|
|
113
|
+
/** Include Inter font (default: true) */
|
|
114
|
+
interFont?: boolean;
|
|
115
|
+
/** Include JetBrains Mono font (default: false) */
|
|
116
|
+
monoFont?: boolean;
|
|
117
|
+
/** Use inline scripts from cache (for blocked network) */
|
|
118
|
+
inline?: boolean;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Build font preconnect links
|
|
122
|
+
*/
|
|
123
|
+
export declare function buildFontPreconnect(): string;
|
|
124
|
+
/**
|
|
125
|
+
* Build font stylesheet links
|
|
126
|
+
*/
|
|
127
|
+
export declare function buildFontStylesheets(options?: {
|
|
128
|
+
inter?: boolean;
|
|
129
|
+
mono?: boolean;
|
|
130
|
+
}): string;
|
|
131
|
+
/**
|
|
132
|
+
* Build all CDN script tags based on options
|
|
133
|
+
*
|
|
134
|
+
* @remarks
|
|
135
|
+
* When `inline: true` is specified, scripts must be pre-cached via `fetchAndCacheScripts()`.
|
|
136
|
+
* Uncached scripts will be silently skipped with a console warning.
|
|
137
|
+
*/
|
|
138
|
+
export declare function buildCdnScripts(options?: CdnScriptOptions): string;
|
|
139
|
+
/**
|
|
140
|
+
* Options for theme-aware CDN script building
|
|
141
|
+
*/
|
|
142
|
+
export interface ThemeCdnScriptOptions {
|
|
143
|
+
/** Include Tailwind CSS (default: true) */
|
|
144
|
+
tailwind?: boolean;
|
|
145
|
+
/** Include HTMX (default: true) */
|
|
146
|
+
htmx?: boolean;
|
|
147
|
+
/** Include Alpine.js (default: false) */
|
|
148
|
+
alpine?: boolean;
|
|
149
|
+
/** Include icon library (default: false) */
|
|
150
|
+
icons?: boolean;
|
|
151
|
+
/** Use inline scripts from cache (for blocked network) */
|
|
152
|
+
inline?: boolean;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Build font preconnect links from theme CDN configuration
|
|
156
|
+
*
|
|
157
|
+
* @param theme - Theme configuration with CDN settings
|
|
158
|
+
* @returns HTML preconnect link tags
|
|
159
|
+
*/
|
|
160
|
+
export declare function buildFontPreconnectFromTheme(theme: ThemeConfig): string;
|
|
161
|
+
/**
|
|
162
|
+
* Build font stylesheet links from theme CDN configuration
|
|
163
|
+
*
|
|
164
|
+
* @param theme - Theme configuration with CDN settings
|
|
165
|
+
* @returns HTML stylesheet link tags
|
|
166
|
+
*/
|
|
167
|
+
export declare function buildFontStylesheetsFromTheme(theme: ThemeConfig): string;
|
|
168
|
+
/**
|
|
169
|
+
* Build all CDN script tags from theme configuration
|
|
170
|
+
*
|
|
171
|
+
* Uses theme.cdn configuration if available, falls back to global CDN defaults.
|
|
172
|
+
*
|
|
173
|
+
* @remarks
|
|
174
|
+
* When `inline: true` is specified, scripts must be pre-cached via `fetchAndCacheScriptsFromTheme()`.
|
|
175
|
+
* Uncached scripts will be silently skipped with a console warning.
|
|
176
|
+
*
|
|
177
|
+
* @param theme - Theme configuration with CDN settings
|
|
178
|
+
* @param options - Script inclusion options
|
|
179
|
+
* @returns HTML script tags
|
|
180
|
+
*/
|
|
181
|
+
export declare function buildCdnScriptsFromTheme(theme: ThemeConfig, options?: ThemeCdnScriptOptions): string;
|
|
182
|
+
/**
|
|
183
|
+
* Fetch and cache scripts based on theme CDN configuration
|
|
184
|
+
*
|
|
185
|
+
* @param theme - Theme configuration with CDN settings
|
|
186
|
+
* @param options - Which scripts to cache
|
|
187
|
+
* @returns Map of cached script URLs to content
|
|
188
|
+
*/
|
|
189
|
+
export declare function fetchAndCacheScriptsFromTheme(theme: ThemeConfig, options?: {
|
|
190
|
+
tailwind?: boolean;
|
|
191
|
+
htmx?: boolean;
|
|
192
|
+
alpine?: boolean;
|
|
193
|
+
icons?: boolean;
|
|
194
|
+
}): Promise<Map<string, string>>;
|
package/src/theme/cdn.js
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file cdn.ts
|
|
4
|
+
* @description CDN Configuration for FrontMCP UI.
|
|
5
|
+
*
|
|
6
|
+
* Centralized configuration for all CDN resources used by FrontMCP UI.
|
|
7
|
+
* All resources are loaded at runtime - no build step required.
|
|
8
|
+
*
|
|
9
|
+
* For platforms with blocked network (e.g., Claude Artifacts),
|
|
10
|
+
* scripts can be fetched once and cached for inline injection.
|
|
11
|
+
*
|
|
12
|
+
* CDN URLs can be customized via theme configuration for:
|
|
13
|
+
* - Using private CDN mirrors
|
|
14
|
+
* - Self-hosting resources
|
|
15
|
+
* - Compliance with CSP policies
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { buildCdnScriptsFromTheme, DEFAULT_THEME } from '@frontmcp/ui';
|
|
20
|
+
*
|
|
21
|
+
* // Use default CDN URLs
|
|
22
|
+
* const scripts = buildCdnScripts();
|
|
23
|
+
*
|
|
24
|
+
* // Use theme-configured CDN URLs
|
|
25
|
+
* const themedScripts = buildCdnScriptsFromTheme(DEFAULT_THEME);
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @module @frontmcp/ui/theme/cdn
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.CDN = void 0;
|
|
32
|
+
exports.fetchScript = fetchScript;
|
|
33
|
+
exports.fetchAndCacheScripts = fetchAndCacheScripts;
|
|
34
|
+
exports.getCachedScript = getCachedScript;
|
|
35
|
+
exports.isScriptCached = isScriptCached;
|
|
36
|
+
exports.clearScriptCache = clearScriptCache;
|
|
37
|
+
exports.buildFontPreconnect = buildFontPreconnect;
|
|
38
|
+
exports.buildFontStylesheets = buildFontStylesheets;
|
|
39
|
+
exports.buildCdnScripts = buildCdnScripts;
|
|
40
|
+
exports.buildFontPreconnectFromTheme = buildFontPreconnectFromTheme;
|
|
41
|
+
exports.buildFontStylesheetsFromTheme = buildFontStylesheetsFromTheme;
|
|
42
|
+
exports.buildCdnScriptsFromTheme = buildCdnScriptsFromTheme;
|
|
43
|
+
exports.fetchAndCacheScriptsFromTheme = fetchAndCacheScriptsFromTheme;
|
|
44
|
+
// ============================================
|
|
45
|
+
// CDN URLs
|
|
46
|
+
// ============================================
|
|
47
|
+
/**
|
|
48
|
+
* CDN resource configuration
|
|
49
|
+
*/
|
|
50
|
+
exports.CDN = {
|
|
51
|
+
/**
|
|
52
|
+
* Tailwind CSS v4 Browser CDN
|
|
53
|
+
* Generates styles on-the-fly with @theme support
|
|
54
|
+
* @see https://tailwindcss.com/docs/installation/play-cdn
|
|
55
|
+
*/
|
|
56
|
+
tailwind: 'https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4',
|
|
57
|
+
/**
|
|
58
|
+
* HTMX 2.x - High power tools for HTML
|
|
59
|
+
* Enables AJAX, WebSockets, Server Sent Events directly in HTML
|
|
60
|
+
* @see https://htmx.org
|
|
61
|
+
*/
|
|
62
|
+
htmx: {
|
|
63
|
+
url: 'https://cdnjs.cloudflare.com/ajax/libs/htmx/2.0.7/htmx.min.js',
|
|
64
|
+
integrity: 'sha512-T6VLg/MJYMbLTmQ8VLvonbWg8VOvmDhXcOvHzCwo6ShdGuUU5SEcp1IAPXL4k9lVoMi8gRXl5K/S/zh43Y9rJA==',
|
|
65
|
+
},
|
|
66
|
+
/**
|
|
67
|
+
* Alpine.js - Lightweight reactive framework
|
|
68
|
+
* Used for more complex client-side interactions
|
|
69
|
+
* @see https://alpinejs.dev
|
|
70
|
+
*/
|
|
71
|
+
alpine: {
|
|
72
|
+
url: 'https://cdn.jsdelivr.net/npm/alpinejs@3.14.3/dist/cdn.min.js',
|
|
73
|
+
integrity: 'sha384-6zY8MFQJ/EqS1r4RJl+7j8rvZPuBWpT0RzWf+IFcKhxqUzQNmJzA1X1VEVZhYaEz',
|
|
74
|
+
},
|
|
75
|
+
/**
|
|
76
|
+
* Google Fonts - Inter for modern UI typography
|
|
77
|
+
*/
|
|
78
|
+
fonts: {
|
|
79
|
+
preconnect: ['https://fonts.googleapis.com', 'https://fonts.gstatic.com'],
|
|
80
|
+
inter: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap',
|
|
81
|
+
mono: 'https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&display=swap',
|
|
82
|
+
},
|
|
83
|
+
/**
|
|
84
|
+
* Lucide Icons - Beautiful & consistent icons
|
|
85
|
+
* @see https://lucide.dev
|
|
86
|
+
*/
|
|
87
|
+
icons: {
|
|
88
|
+
url: 'https://cdn.jsdelivr.net/npm/lucide@0.294.0/dist/umd/lucide.min.js',
|
|
89
|
+
integrity: 'sha384-wpLmHb7v7V1LsEuTmPQ9tXqWZvTtRWWVqJuE+Yz6X0I6O2T6bHJVeXH1lVWqF4qE',
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
// ============================================
|
|
93
|
+
// Script Cache for Offline/Blocked Platforms
|
|
94
|
+
// ============================================
|
|
95
|
+
/**
|
|
96
|
+
* Cached script content for platforms with blocked network
|
|
97
|
+
* These are populated by fetchAndCacheScripts()
|
|
98
|
+
*/
|
|
99
|
+
const scriptCache = new Map();
|
|
100
|
+
/**
|
|
101
|
+
* Fetch a script and cache its content
|
|
102
|
+
*/
|
|
103
|
+
async function fetchScript(url) {
|
|
104
|
+
if (scriptCache.has(url)) {
|
|
105
|
+
return scriptCache.get(url);
|
|
106
|
+
}
|
|
107
|
+
const response = await fetch(url);
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
throw new Error(`Failed to fetch script: ${url} (${response.status})`);
|
|
110
|
+
}
|
|
111
|
+
const content = await response.text();
|
|
112
|
+
scriptCache.set(url, content);
|
|
113
|
+
return content;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Fetch and cache all required scripts for offline use
|
|
117
|
+
* Call this at startup to prepare for blocked-network platforms
|
|
118
|
+
*/
|
|
119
|
+
async function fetchAndCacheScripts(options = {}) {
|
|
120
|
+
const { tailwind = true, htmx = true, alpine = false, icons = false } = options;
|
|
121
|
+
const urls = [];
|
|
122
|
+
if (tailwind)
|
|
123
|
+
urls.push(exports.CDN.tailwind);
|
|
124
|
+
if (htmx)
|
|
125
|
+
urls.push(exports.CDN.htmx.url);
|
|
126
|
+
if (alpine)
|
|
127
|
+
urls.push(exports.CDN.alpine.url);
|
|
128
|
+
if (icons)
|
|
129
|
+
urls.push(exports.CDN.icons.url);
|
|
130
|
+
await Promise.all(urls.map(fetchScript));
|
|
131
|
+
return scriptCache;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get cached script content
|
|
135
|
+
*/
|
|
136
|
+
function getCachedScript(url) {
|
|
137
|
+
return scriptCache.get(url);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Check if a script is cached
|
|
141
|
+
*/
|
|
142
|
+
function isScriptCached(url) {
|
|
143
|
+
return scriptCache.has(url);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Clear the script cache
|
|
147
|
+
*/
|
|
148
|
+
function clearScriptCache() {
|
|
149
|
+
scriptCache.clear();
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Build font preconnect links
|
|
153
|
+
*/
|
|
154
|
+
function buildFontPreconnect() {
|
|
155
|
+
return exports.CDN.fonts.preconnect
|
|
156
|
+
.map((url, i) => `<link rel="preconnect" href="${url}"${i > 0 ? ' crossorigin' : ''}>`)
|
|
157
|
+
.join('\n ');
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Build font stylesheet links
|
|
161
|
+
*/
|
|
162
|
+
function buildFontStylesheets(options = {}) {
|
|
163
|
+
const { inter = true, mono = false } = options;
|
|
164
|
+
const links = [];
|
|
165
|
+
if (inter) {
|
|
166
|
+
links.push(`<link href="${exports.CDN.fonts.inter}" rel="stylesheet">`);
|
|
167
|
+
}
|
|
168
|
+
if (mono) {
|
|
169
|
+
links.push(`<link href="${exports.CDN.fonts.mono}" rel="stylesheet">`);
|
|
170
|
+
}
|
|
171
|
+
return links.join('\n ');
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Build script tag with optional integrity
|
|
175
|
+
*/
|
|
176
|
+
function buildScriptTag(url, integrity, options = {}) {
|
|
177
|
+
const attrs = [`src="${url}"`];
|
|
178
|
+
if (integrity) {
|
|
179
|
+
attrs.push(`integrity="${integrity}"`);
|
|
180
|
+
attrs.push('crossorigin="anonymous"');
|
|
181
|
+
}
|
|
182
|
+
if (options.defer)
|
|
183
|
+
attrs.push('defer');
|
|
184
|
+
if (options.async)
|
|
185
|
+
attrs.push('async');
|
|
186
|
+
return `<script ${attrs.join(' ')}></script>`;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Build inline script tag from cached content
|
|
190
|
+
*/
|
|
191
|
+
function buildInlineScriptTag(content) {
|
|
192
|
+
return `<script>${content}</script>`;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Build all CDN script tags based on options
|
|
196
|
+
*
|
|
197
|
+
* @remarks
|
|
198
|
+
* When `inline: true` is specified, scripts must be pre-cached via `fetchAndCacheScripts()`.
|
|
199
|
+
* Uncached scripts will be silently skipped with a console warning.
|
|
200
|
+
*/
|
|
201
|
+
function buildCdnScripts(options = {}) {
|
|
202
|
+
const { tailwind = true, htmx = true, alpine = false, icons = false, inline = false } = options;
|
|
203
|
+
const scripts = [];
|
|
204
|
+
if (inline) {
|
|
205
|
+
// Use cached inline scripts - warn if not cached
|
|
206
|
+
if (tailwind) {
|
|
207
|
+
if (isScriptCached(exports.CDN.tailwind)) {
|
|
208
|
+
scripts.push(buildInlineScriptTag(getCachedScript(exports.CDN.tailwind)));
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
console.warn('[frontmcp/ui] Inline mode requested but Tailwind script not cached. Call fetchAndCacheScripts() first.');
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (htmx) {
|
|
215
|
+
if (isScriptCached(exports.CDN.htmx.url)) {
|
|
216
|
+
scripts.push(buildInlineScriptTag(getCachedScript(exports.CDN.htmx.url)));
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
console.warn('[frontmcp/ui] Inline mode requested but HTMX script not cached. Call fetchAndCacheScripts() first.');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (alpine) {
|
|
223
|
+
if (isScriptCached(exports.CDN.alpine.url)) {
|
|
224
|
+
scripts.push(buildInlineScriptTag(getCachedScript(exports.CDN.alpine.url)));
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
console.warn('[frontmcp/ui] Inline mode requested but Alpine.js script not cached. Call fetchAndCacheScripts() first.');
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (icons) {
|
|
231
|
+
if (isScriptCached(exports.CDN.icons.url)) {
|
|
232
|
+
scripts.push(buildInlineScriptTag(getCachedScript(exports.CDN.icons.url)));
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
console.warn('[frontmcp/ui] Inline mode requested but Lucide icons script not cached. Call fetchAndCacheScripts() first.');
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
// Use CDN URLs
|
|
241
|
+
if (tailwind) {
|
|
242
|
+
scripts.push(buildScriptTag(exports.CDN.tailwind));
|
|
243
|
+
}
|
|
244
|
+
if (htmx) {
|
|
245
|
+
scripts.push(buildScriptTag(exports.CDN.htmx.url, exports.CDN.htmx.integrity));
|
|
246
|
+
}
|
|
247
|
+
if (alpine) {
|
|
248
|
+
scripts.push(buildScriptTag(exports.CDN.alpine.url, exports.CDN.alpine.integrity, { defer: true }));
|
|
249
|
+
}
|
|
250
|
+
if (icons) {
|
|
251
|
+
scripts.push(buildScriptTag(exports.CDN.icons.url, exports.CDN.icons.integrity));
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return scripts.join('\n ');
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Build font preconnect links from theme CDN configuration
|
|
258
|
+
*
|
|
259
|
+
* @param theme - Theme configuration with CDN settings
|
|
260
|
+
* @returns HTML preconnect link tags
|
|
261
|
+
*/
|
|
262
|
+
function buildFontPreconnectFromTheme(theme) {
|
|
263
|
+
const preconnect = theme.cdn?.fonts?.preconnect ?? exports.CDN.fonts.preconnect;
|
|
264
|
+
return preconnect.map((url, i) => `<link rel="preconnect" href="${url}"${i > 0 ? ' crossorigin' : ''}>`).join('\n ');
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Build font stylesheet links from theme CDN configuration
|
|
268
|
+
*
|
|
269
|
+
* @param theme - Theme configuration with CDN settings
|
|
270
|
+
* @returns HTML stylesheet link tags
|
|
271
|
+
*/
|
|
272
|
+
function buildFontStylesheetsFromTheme(theme) {
|
|
273
|
+
const stylesheets = theme.cdn?.fonts?.stylesheets ?? [exports.CDN.fonts.inter];
|
|
274
|
+
return stylesheets.map((url) => `<link href="${url}" rel="stylesheet">`).join('\n ');
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Build all CDN script tags from theme configuration
|
|
278
|
+
*
|
|
279
|
+
* Uses theme.cdn configuration if available, falls back to global CDN defaults.
|
|
280
|
+
*
|
|
281
|
+
* @remarks
|
|
282
|
+
* When `inline: true` is specified, scripts must be pre-cached via `fetchAndCacheScriptsFromTheme()`.
|
|
283
|
+
* Uncached scripts will be silently skipped with a console warning.
|
|
284
|
+
*
|
|
285
|
+
* @param theme - Theme configuration with CDN settings
|
|
286
|
+
* @param options - Script inclusion options
|
|
287
|
+
* @returns HTML script tags
|
|
288
|
+
*/
|
|
289
|
+
function buildCdnScriptsFromTheme(theme, options = {}) {
|
|
290
|
+
const { tailwind = true, htmx = true, alpine = false, icons = false, inline = false } = options;
|
|
291
|
+
const scripts = [];
|
|
292
|
+
// Get URLs from theme or fallback to defaults
|
|
293
|
+
const tailwindUrl = theme.cdn?.scripts?.tailwind ?? exports.CDN.tailwind;
|
|
294
|
+
const htmxConfig = theme.cdn?.scripts?.htmx ?? exports.CDN.htmx;
|
|
295
|
+
const alpineConfig = theme.cdn?.scripts?.alpine ?? exports.CDN.alpine;
|
|
296
|
+
const iconsConfig = theme.cdn?.icons?.script ?? exports.CDN.icons;
|
|
297
|
+
if (inline) {
|
|
298
|
+
// Use cached inline scripts - warn if not cached
|
|
299
|
+
if (tailwind) {
|
|
300
|
+
if (isScriptCached(tailwindUrl)) {
|
|
301
|
+
scripts.push(buildInlineScriptTag(getCachedScript(tailwindUrl)));
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
console.warn('[frontmcp/ui] Inline mode requested but Tailwind script not cached. Call fetchAndCacheScriptsFromTheme() first.');
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (htmx) {
|
|
308
|
+
if (isScriptCached(htmxConfig.url)) {
|
|
309
|
+
scripts.push(buildInlineScriptTag(getCachedScript(htmxConfig.url)));
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
console.warn('[frontmcp/ui] Inline mode requested but HTMX script not cached. Call fetchAndCacheScriptsFromTheme() first.');
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (alpine) {
|
|
316
|
+
if (isScriptCached(alpineConfig.url)) {
|
|
317
|
+
scripts.push(buildInlineScriptTag(getCachedScript(alpineConfig.url)));
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
console.warn('[frontmcp/ui] Inline mode requested but Alpine.js script not cached. Call fetchAndCacheScriptsFromTheme() first.');
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (icons) {
|
|
324
|
+
if (isScriptCached(iconsConfig.url)) {
|
|
325
|
+
scripts.push(buildInlineScriptTag(getCachedScript(iconsConfig.url)));
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
console.warn('[frontmcp/ui] Inline mode requested but icons script not cached. Call fetchAndCacheScriptsFromTheme() first.');
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
// Use CDN URLs from theme
|
|
334
|
+
if (tailwind) {
|
|
335
|
+
scripts.push(buildScriptTag(tailwindUrl));
|
|
336
|
+
}
|
|
337
|
+
if (htmx) {
|
|
338
|
+
scripts.push(buildScriptTag(htmxConfig.url, htmxConfig.integrity));
|
|
339
|
+
}
|
|
340
|
+
if (alpine) {
|
|
341
|
+
scripts.push(buildScriptTag(alpineConfig.url, alpineConfig.integrity, { defer: true }));
|
|
342
|
+
}
|
|
343
|
+
if (icons) {
|
|
344
|
+
scripts.push(buildScriptTag(iconsConfig.url, iconsConfig.integrity));
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return scripts.join('\n ');
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Fetch and cache scripts based on theme CDN configuration
|
|
351
|
+
*
|
|
352
|
+
* @param theme - Theme configuration with CDN settings
|
|
353
|
+
* @param options - Which scripts to cache
|
|
354
|
+
* @returns Map of cached script URLs to content
|
|
355
|
+
*/
|
|
356
|
+
async function fetchAndCacheScriptsFromTheme(theme, options = {}) {
|
|
357
|
+
const { tailwind = true, htmx = true, alpine = false, icons = false } = options;
|
|
358
|
+
const urls = [];
|
|
359
|
+
// Get URLs from theme or fallback to defaults
|
|
360
|
+
const tailwindUrl = theme.cdn?.scripts?.tailwind ?? exports.CDN.tailwind;
|
|
361
|
+
const htmxConfig = theme.cdn?.scripts?.htmx ?? exports.CDN.htmx;
|
|
362
|
+
const alpineConfig = theme.cdn?.scripts?.alpine ?? exports.CDN.alpine;
|
|
363
|
+
const iconsConfig = theme.cdn?.icons?.script ?? exports.CDN.icons;
|
|
364
|
+
if (tailwind)
|
|
365
|
+
urls.push(tailwindUrl);
|
|
366
|
+
if (htmx)
|
|
367
|
+
urls.push(htmxConfig.url);
|
|
368
|
+
if (alpine)
|
|
369
|
+
urls.push(alpineConfig.url);
|
|
370
|
+
if (icons)
|
|
371
|
+
urls.push(iconsConfig.url);
|
|
372
|
+
await Promise.all(urls.map(fetchScript));
|
|
373
|
+
return scriptCache;
|
|
374
|
+
}
|
|
375
|
+
//# sourceMappingURL=cdn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdn.js","sourceRoot":"","sources":["../../../src/theme/cdn.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @file cdn.ts\n * @description CDN Configuration for FrontMCP UI.\n *\n * Centralized configuration for all CDN resources used by FrontMCP UI.\n * All resources are loaded at runtime - no build step required.\n *\n * For platforms with blocked network (e.g., Claude Artifacts),\n * scripts can be fetched once and cached for inline injection.\n *\n * CDN URLs can be customized via theme configuration for:\n * - Using private CDN mirrors\n * - Self-hosting resources\n * - Compliance with CSP policies\n *\n * @example\n * ```typescript\n * import { buildCdnScriptsFromTheme, DEFAULT_THEME } from '@frontmcp/ui';\n *\n * // Use default CDN URLs\n * const scripts = buildCdnScripts();\n *\n * // Use theme-configured CDN URLs\n * const themedScripts = buildCdnScriptsFromTheme(DEFAULT_THEME);\n * ```\n *\n * @module @frontmcp/ui/theme/cdn\n */\n\nimport type { ThemeConfig } from './theme';\n\n// ============================================\n// CDN URLs\n// ============================================\n\n/**\n * CDN resource configuration\n */\nexport const CDN = {\n /**\n * Tailwind CSS v4 Browser CDN\n * Generates styles on-the-fly with @theme support\n * @see https://tailwindcss.com/docs/installation/play-cdn\n */\n tailwind: 'https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4',\n\n /**\n * HTMX 2.x - High power tools for HTML\n * Enables AJAX, WebSockets, Server Sent Events directly in HTML\n * @see https://htmx.org\n */\n htmx: {\n url: 'https://cdnjs.cloudflare.com/ajax/libs/htmx/2.0.7/htmx.min.js',\n integrity: 'sha512-T6VLg/MJYMbLTmQ8VLvonbWg8VOvmDhXcOvHzCwo6ShdGuUU5SEcp1IAPXL4k9lVoMi8gRXl5K/S/zh43Y9rJA==',\n },\n\n /**\n * Alpine.js - Lightweight reactive framework\n * Used for more complex client-side interactions\n * @see https://alpinejs.dev\n */\n alpine: {\n url: 'https://cdn.jsdelivr.net/npm/alpinejs@3.14.3/dist/cdn.min.js',\n integrity: 'sha384-6zY8MFQJ/EqS1r4RJl+7j8rvZPuBWpT0RzWf+IFcKhxqUzQNmJzA1X1VEVZhYaEz',\n },\n\n /**\n * Google Fonts - Inter for modern UI typography\n */\n fonts: {\n preconnect: ['https://fonts.googleapis.com', 'https://fonts.gstatic.com'],\n inter: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap',\n mono: 'https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&display=swap',\n },\n\n /**\n * Lucide Icons - Beautiful & consistent icons\n * @see https://lucide.dev\n */\n icons: {\n url: 'https://cdn.jsdelivr.net/npm/lucide@0.294.0/dist/umd/lucide.min.js',\n integrity: 'sha384-wpLmHb7v7V1LsEuTmPQ9tXqWZvTtRWWVqJuE+Yz6X0I6O2T6bHJVeXH1lVWqF4qE',\n },\n} as const;\n\n// ============================================\n// Script Cache for Offline/Blocked Platforms\n// ============================================\n\n/**\n * Cached script content for platforms with blocked network\n * These are populated by fetchAndCacheScripts()\n */\nconst scriptCache: Map<string, string> = new Map();\n\n/**\n * Fetch a script and cache its content\n */\nexport async function fetchScript(url: string): Promise<string> {\n if (scriptCache.has(url)) {\n return scriptCache.get(url)!;\n }\n\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch script: ${url} (${response.status})`);\n }\n\n const content = await response.text();\n scriptCache.set(url, content);\n return content;\n}\n\n/**\n * Fetch and cache all required scripts for offline use\n * Call this at startup to prepare for blocked-network platforms\n */\nexport async function fetchAndCacheScripts(\n options: {\n tailwind?: boolean;\n htmx?: boolean;\n alpine?: boolean;\n icons?: boolean;\n } = {},\n): Promise<Map<string, string>> {\n const { tailwind = true, htmx = true, alpine = false, icons = false } = options;\n const urls: string[] = [];\n\n if (tailwind) urls.push(CDN.tailwind);\n if (htmx) urls.push(CDN.htmx.url);\n if (alpine) urls.push(CDN.alpine.url);\n if (icons) urls.push(CDN.icons.url);\n\n await Promise.all(urls.map(fetchScript));\n return scriptCache;\n}\n\n/**\n * Get cached script content\n */\nexport function getCachedScript(url: string): string | undefined {\n return scriptCache.get(url);\n}\n\n/**\n * Check if a script is cached\n */\nexport function isScriptCached(url: string): boolean {\n return scriptCache.has(url);\n}\n\n/**\n * Clear the script cache\n */\nexport function clearScriptCache(): void {\n scriptCache.clear();\n}\n\n// ============================================\n// CDN Builder Utilities\n// ============================================\n\n/**\n * Options for building CDN script tags\n */\nexport interface CdnScriptOptions {\n /** Include Tailwind CSS (default: true) */\n tailwind?: boolean;\n /** Include HTMX (default: true) */\n htmx?: boolean;\n /** Include Alpine.js (default: false) */\n alpine?: boolean;\n /** Include Lucide icons (default: false) */\n icons?: boolean;\n /** Include Inter font (default: true) */\n interFont?: boolean;\n /** Include JetBrains Mono font (default: false) */\n monoFont?: boolean;\n /** Use inline scripts from cache (for blocked network) */\n inline?: boolean;\n}\n\n/**\n * Build font preconnect links\n */\nexport function buildFontPreconnect(): string {\n return CDN.fonts.preconnect\n .map((url, i) => `<link rel=\"preconnect\" href=\"${url}\"${i > 0 ? ' crossorigin' : ''}>`)\n .join('\\n ');\n}\n\n/**\n * Build font stylesheet links\n */\nexport function buildFontStylesheets(options: { inter?: boolean; mono?: boolean } = {}): string {\n const { inter = true, mono = false } = options;\n const links: string[] = [];\n\n if (inter) {\n links.push(`<link href=\"${CDN.fonts.inter}\" rel=\"stylesheet\">`);\n }\n if (mono) {\n links.push(`<link href=\"${CDN.fonts.mono}\" rel=\"stylesheet\">`);\n }\n\n return links.join('\\n ');\n}\n\n/**\n * Build script tag with optional integrity\n */\nfunction buildScriptTag(url: string, integrity?: string, options: { defer?: boolean; async?: boolean } = {}): string {\n const attrs: string[] = [`src=\"${url}\"`];\n\n if (integrity) {\n attrs.push(`integrity=\"${integrity}\"`);\n attrs.push('crossorigin=\"anonymous\"');\n }\n if (options.defer) attrs.push('defer');\n if (options.async) attrs.push('async');\n\n return `<script ${attrs.join(' ')}></script>`;\n}\n\n/**\n * Build inline script tag from cached content\n */\nfunction buildInlineScriptTag(content: string): string {\n return `<script>${content}</script>`;\n}\n\n/**\n * Build all CDN script tags based on options\n *\n * @remarks\n * When `inline: true` is specified, scripts must be pre-cached via `fetchAndCacheScripts()`.\n * Uncached scripts will be silently skipped with a console warning.\n */\nexport function buildCdnScripts(options: CdnScriptOptions = {}): string {\n const { tailwind = true, htmx = true, alpine = false, icons = false, inline = false } = options;\n\n const scripts: string[] = [];\n\n if (inline) {\n // Use cached inline scripts - warn if not cached\n if (tailwind) {\n if (isScriptCached(CDN.tailwind)) {\n scripts.push(buildInlineScriptTag(getCachedScript(CDN.tailwind)!));\n } else {\n console.warn(\n '[frontmcp/ui] Inline mode requested but Tailwind script not cached. Call fetchAndCacheScripts() first.',\n );\n }\n }\n if (htmx) {\n if (isScriptCached(CDN.htmx.url)) {\n scripts.push(buildInlineScriptTag(getCachedScript(CDN.htmx.url)!));\n } else {\n console.warn(\n '[frontmcp/ui] Inline mode requested but HTMX script not cached. Call fetchAndCacheScripts() first.',\n );\n }\n }\n if (alpine) {\n if (isScriptCached(CDN.alpine.url)) {\n scripts.push(buildInlineScriptTag(getCachedScript(CDN.alpine.url)!));\n } else {\n console.warn(\n '[frontmcp/ui] Inline mode requested but Alpine.js script not cached. Call fetchAndCacheScripts() first.',\n );\n }\n }\n if (icons) {\n if (isScriptCached(CDN.icons.url)) {\n scripts.push(buildInlineScriptTag(getCachedScript(CDN.icons.url)!));\n } else {\n console.warn(\n '[frontmcp/ui] Inline mode requested but Lucide icons script not cached. Call fetchAndCacheScripts() first.',\n );\n }\n }\n } else {\n // Use CDN URLs\n if (tailwind) {\n scripts.push(buildScriptTag(CDN.tailwind));\n }\n if (htmx) {\n scripts.push(buildScriptTag(CDN.htmx.url, CDN.htmx.integrity));\n }\n if (alpine) {\n scripts.push(buildScriptTag(CDN.alpine.url, CDN.alpine.integrity, { defer: true }));\n }\n if (icons) {\n scripts.push(buildScriptTag(CDN.icons.url, CDN.icons.integrity));\n }\n }\n\n return scripts.join('\\n ');\n}\n\n// ============================================\n// Theme-Aware CDN Builders\n// ============================================\n\n/**\n * Options for theme-aware CDN script building\n */\nexport interface ThemeCdnScriptOptions {\n /** Include Tailwind CSS (default: true) */\n tailwind?: boolean;\n /** Include HTMX (default: true) */\n htmx?: boolean;\n /** Include Alpine.js (default: false) */\n alpine?: boolean;\n /** Include icon library (default: false) */\n icons?: boolean;\n /** Use inline scripts from cache (for blocked network) */\n inline?: boolean;\n}\n\n/**\n * Build font preconnect links from theme CDN configuration\n *\n * @param theme - Theme configuration with CDN settings\n * @returns HTML preconnect link tags\n */\nexport function buildFontPreconnectFromTheme(theme: ThemeConfig): string {\n const preconnect = theme.cdn?.fonts?.preconnect ?? CDN.fonts.preconnect;\n return preconnect.map((url, i) => `<link rel=\"preconnect\" href=\"${url}\"${i > 0 ? ' crossorigin' : ''}>`).join('\\n ');\n}\n\n/**\n * Build font stylesheet links from theme CDN configuration\n *\n * @param theme - Theme configuration with CDN settings\n * @returns HTML stylesheet link tags\n */\nexport function buildFontStylesheetsFromTheme(theme: ThemeConfig): string {\n const stylesheets = theme.cdn?.fonts?.stylesheets ?? [CDN.fonts.inter];\n return stylesheets.map((url) => `<link href=\"${url}\" rel=\"stylesheet\">`).join('\\n ');\n}\n\n/**\n * Build all CDN script tags from theme configuration\n *\n * Uses theme.cdn configuration if available, falls back to global CDN defaults.\n *\n * @remarks\n * When `inline: true` is specified, scripts must be pre-cached via `fetchAndCacheScriptsFromTheme()`.\n * Uncached scripts will be silently skipped with a console warning.\n *\n * @param theme - Theme configuration with CDN settings\n * @param options - Script inclusion options\n * @returns HTML script tags\n */\nexport function buildCdnScriptsFromTheme(theme: ThemeConfig, options: ThemeCdnScriptOptions = {}): string {\n const { tailwind = true, htmx = true, alpine = false, icons = false, inline = false } = options;\n\n const scripts: string[] = [];\n\n // Get URLs from theme or fallback to defaults\n const tailwindUrl = theme.cdn?.scripts?.tailwind ?? CDN.tailwind;\n const htmxConfig = theme.cdn?.scripts?.htmx ?? CDN.htmx;\n const alpineConfig = theme.cdn?.scripts?.alpine ?? CDN.alpine;\n const iconsConfig = theme.cdn?.icons?.script ?? CDN.icons;\n\n if (inline) {\n // Use cached inline scripts - warn if not cached\n if (tailwind) {\n if (isScriptCached(tailwindUrl)) {\n scripts.push(buildInlineScriptTag(getCachedScript(tailwindUrl)!));\n } else {\n console.warn(\n '[frontmcp/ui] Inline mode requested but Tailwind script not cached. Call fetchAndCacheScriptsFromTheme() first.',\n );\n }\n }\n if (htmx) {\n if (isScriptCached(htmxConfig.url)) {\n scripts.push(buildInlineScriptTag(getCachedScript(htmxConfig.url)!));\n } else {\n console.warn(\n '[frontmcp/ui] Inline mode requested but HTMX script not cached. Call fetchAndCacheScriptsFromTheme() first.',\n );\n }\n }\n if (alpine) {\n if (isScriptCached(alpineConfig.url)) {\n scripts.push(buildInlineScriptTag(getCachedScript(alpineConfig.url)!));\n } else {\n console.warn(\n '[frontmcp/ui] Inline mode requested but Alpine.js script not cached. Call fetchAndCacheScriptsFromTheme() first.',\n );\n }\n }\n if (icons) {\n if (isScriptCached(iconsConfig.url)) {\n scripts.push(buildInlineScriptTag(getCachedScript(iconsConfig.url)!));\n } else {\n console.warn(\n '[frontmcp/ui] Inline mode requested but icons script not cached. Call fetchAndCacheScriptsFromTheme() first.',\n );\n }\n }\n } else {\n // Use CDN URLs from theme\n if (tailwind) {\n scripts.push(buildScriptTag(tailwindUrl));\n }\n if (htmx) {\n scripts.push(buildScriptTag(htmxConfig.url, htmxConfig.integrity));\n }\n if (alpine) {\n scripts.push(buildScriptTag(alpineConfig.url, alpineConfig.integrity, { defer: true }));\n }\n if (icons) {\n scripts.push(buildScriptTag(iconsConfig.url, iconsConfig.integrity));\n }\n }\n\n return scripts.join('\\n ');\n}\n\n/**\n * Fetch and cache scripts based on theme CDN configuration\n *\n * @param theme - Theme configuration with CDN settings\n * @param options - Which scripts to cache\n * @returns Map of cached script URLs to content\n */\nexport async function fetchAndCacheScriptsFromTheme(\n theme: ThemeConfig,\n options: {\n tailwind?: boolean;\n htmx?: boolean;\n alpine?: boolean;\n icons?: boolean;\n } = {},\n): Promise<Map<string, string>> {\n const { tailwind = true, htmx = true, alpine = false, icons = false } = options;\n const urls: string[] = [];\n\n // Get URLs from theme or fallback to defaults\n const tailwindUrl = theme.cdn?.scripts?.tailwind ?? CDN.tailwind;\n const htmxConfig = theme.cdn?.scripts?.htmx ?? CDN.htmx;\n const alpineConfig = theme.cdn?.scripts?.alpine ?? CDN.alpine;\n const iconsConfig = theme.cdn?.icons?.script ?? CDN.icons;\n\n if (tailwind) urls.push(tailwindUrl);\n if (htmx) urls.push(htmxConfig.url);\n if (alpine) urls.push(alpineConfig.url);\n if (icons) urls.push(iconsConfig.url);\n\n await Promise.all(urls.map(fetchScript));\n return scriptCache;\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file index.ts
|
|
3
|
+
* @description Theme Module for FrontMCP UI.
|
|
4
|
+
*
|
|
5
|
+
* Provides comprehensive theming capabilities including:
|
|
6
|
+
* - Color palettes and semantic tokens
|
|
7
|
+
* - Typography and spacing configuration
|
|
8
|
+
* - CDN resource customization
|
|
9
|
+
* - Platform-specific configurations
|
|
10
|
+
* - Theme presets (GitHub/OpenAI default)
|
|
11
|
+
*
|
|
12
|
+
* @module @frontmcp/ui/theme
|
|
13
|
+
*/
|
|
14
|
+
export { CDN, type CdnScriptOptions, type ThemeCdnScriptOptions, fetchScript, fetchAndCacheScripts, fetchAndCacheScriptsFromTheme, getCachedScript, isScriptCached, clearScriptCache, buildFontPreconnect, buildFontPreconnectFromTheme, buildFontStylesheets, buildFontStylesheetsFromTheme, buildCdnScripts, buildCdnScriptsFromTheme, } from './cdn';
|
|
15
|
+
export { type PlatformId, type NetworkMode, type ScriptStrategy, type PlatformCapabilities, OPENAI_PLATFORM, CLAUDE_PLATFORM, GEMINI_PLATFORM, NGROK_PLATFORM, CUSTOM_PLATFORM, PLATFORM_PRESETS, getPlatform, createPlatform, canUseCdn, needsInlineScripts, supportsFullInteractivity, getFallbackMode, } from './platforms';
|
|
16
|
+
export { type DeepPartial, type ColorScale, type SemanticColors, type SurfaceColors, type TextColors, type BorderColors, type ThemeColors, type FontFamilies, type FontSizes, type FontWeights, type ThemeTypography, type ThemeSpacing, type ThemeRadius, type ThemeShadows, type ButtonTokens, type CardTokens, type InputTokens, type ComponentTokens, type CdnScriptResource, type ThemeCdnFonts, type ThemeCdnIcons, type ThemeCdnScripts, type ThemeCdnConfig, type ThemeConfig, mergeThemes, createTheme, buildThemeCss, buildStyleBlock, } from './theme';
|
|
17
|
+
export { GITHUB_OPENAI_THEME, DEFAULT_THEME } from './presets';
|