@muloka/figma-console-mcp 0.1.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 +898 -0
- package/dist/apps/design-system-dashboard/scoring/accessibility.d.ts +14 -0
- package/dist/apps/design-system-dashboard/scoring/accessibility.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/accessibility.js +278 -0
- package/dist/apps/design-system-dashboard/scoring/accessibility.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/component-metadata.d.ts +29 -0
- package/dist/apps/design-system-dashboard/scoring/component-metadata.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/component-metadata.js +358 -0
- package/dist/apps/design-system-dashboard/scoring/component-metadata.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/consistency.d.ts +14 -0
- package/dist/apps/design-system-dashboard/scoring/consistency.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/consistency.js +342 -0
- package/dist/apps/design-system-dashboard/scoring/consistency.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/coverage.d.ts +14 -0
- package/dist/apps/design-system-dashboard/scoring/coverage.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/coverage.js +231 -0
- package/dist/apps/design-system-dashboard/scoring/coverage.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/engine.d.ts +27 -0
- package/dist/apps/design-system-dashboard/scoring/engine.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/engine.js +93 -0
- package/dist/apps/design-system-dashboard/scoring/engine.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/naming-semantics.d.ts +14 -0
- package/dist/apps/design-system-dashboard/scoring/naming-semantics.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/naming-semantics.js +309 -0
- package/dist/apps/design-system-dashboard/scoring/naming-semantics.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/token-architecture.d.ts +14 -0
- package/dist/apps/design-system-dashboard/scoring/token-architecture.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/token-architecture.js +350 -0
- package/dist/apps/design-system-dashboard/scoring/token-architecture.js.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/types.d.ts +89 -0
- package/dist/apps/design-system-dashboard/scoring/types.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/scoring/types.js +41 -0
- package/dist/apps/design-system-dashboard/scoring/types.js.map +1 -0
- package/dist/apps/design-system-dashboard/server.d.ts +24 -0
- package/dist/apps/design-system-dashboard/server.d.ts.map +1 -0
- package/dist/apps/design-system-dashboard/server.js +160 -0
- package/dist/apps/design-system-dashboard/server.js.map +1 -0
- package/dist/apps/token-browser/server.d.ts +26 -0
- package/dist/apps/token-browser/server.d.ts.map +1 -0
- package/dist/apps/token-browser/server.js +137 -0
- package/dist/apps/token-browser/server.js.map +1 -0
- package/dist/browser/base.d.ts +58 -0
- package/dist/browser/base.d.ts.map +1 -0
- package/dist/browser/base.js +6 -0
- package/dist/browser/base.js.map +1 -0
- package/dist/browser/local.d.ts +87 -0
- package/dist/browser/local.d.ts.map +1 -0
- package/dist/browser/local.js +318 -0
- package/dist/browser/local.js.map +1 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/accessibility.js +277 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/component-metadata.js +357 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/consistency.js +341 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/coverage.js +230 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/engine.js +92 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/naming-semantics.js +308 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/token-architecture.js +349 -0
- package/dist/cloudflare/apps/design-system-dashboard/scoring/types.js +40 -0
- package/dist/cloudflare/apps/design-system-dashboard/server.js +159 -0
- package/dist/cloudflare/apps/token-browser/server.js +136 -0
- package/dist/cloudflare/browser-manager.js +157 -0
- package/dist/cloudflare/core/accessibility-tools.js +361 -0
- package/dist/cloudflare/core/annotation-tools.js +230 -0
- package/dist/cloudflare/core/cloud-websocket-connector.js +419 -0
- package/dist/cloudflare/core/cloud-websocket-relay.js +198 -0
- package/dist/cloudflare/core/comment-tools.js +292 -0
- package/dist/cloudflare/core/config.js +153 -0
- package/dist/cloudflare/core/console-monitor.js +427 -0
- package/dist/cloudflare/core/deep-component-tools.js +128 -0
- package/dist/cloudflare/core/design-code-tools.js +2793 -0
- package/dist/cloudflare/core/design-system-manifest.js +265 -0
- package/dist/cloudflare/core/design-system-tools.js +882 -0
- package/dist/cloudflare/core/diagnose-tool.js +100 -0
- package/dist/cloudflare/core/diff/changelog-formatter.js +275 -0
- package/dist/cloudflare/core/diff/diff-engine.js +334 -0
- package/dist/cloudflare/core/diff/property-compare.js +36 -0
- package/dist/cloudflare/core/diff/version-cache.js +74 -0
- package/dist/cloudflare/core/enrichment/enrichment-service.js +374 -0
- package/dist/cloudflare/core/enrichment/index.js +7 -0
- package/dist/cloudflare/core/enrichment/relationship-mapper.js +351 -0
- package/dist/cloudflare/core/enrichment/style-resolver.js +346 -0
- package/dist/cloudflare/core/figjam-tools.js +547 -0
- package/dist/cloudflare/core/figma-api.js +509 -0
- package/dist/cloudflare/core/figma-connector.js +7 -0
- package/dist/cloudflare/core/figma-reconstruction-spec.js +402 -0
- package/dist/cloudflare/core/figma-style-extractor.js +311 -0
- package/dist/cloudflare/core/figma-tools.js +3302 -0
- package/dist/cloudflare/core/identity.js +96 -0
- package/dist/cloudflare/core/library-tools.js +580 -0
- package/dist/cloudflare/core/logger.js +53 -0
- package/dist/cloudflare/core/port-discovery.js +935 -0
- package/dist/cloudflare/core/resolve-package-root.js +11 -0
- package/dist/cloudflare/core/slides-tools.js +714 -0
- package/dist/cloudflare/core/slot-tools.js +334 -0
- package/dist/cloudflare/core/snippet-injector.js +96 -0
- package/dist/cloudflare/core/tokens/alias-resolver.js +205 -0
- package/dist/cloudflare/core/tokens/config.js +294 -0
- package/dist/cloudflare/core/tokens/dialect.js +232 -0
- package/dist/cloudflare/core/tokens/figma-converter.js +323 -0
- package/dist/cloudflare/core/tokens/formatters/css-vars.js +338 -0
- package/dist/cloudflare/core/tokens/formatters/dtcg.js +376 -0
- package/dist/cloudflare/core/tokens/formatters/index.js +45 -0
- package/dist/cloudflare/core/tokens/formatters/json.js +205 -0
- package/dist/cloudflare/core/tokens/formatters/less.js +4 -0
- package/dist/cloudflare/core/tokens/formatters/scss.js +258 -0
- package/dist/cloudflare/core/tokens/formatters/stubs.js +13 -0
- package/dist/cloudflare/core/tokens/formatters/style-dictionary-v3.js +213 -0
- package/dist/cloudflare/core/tokens/formatters/tailwind-v3.js +237 -0
- package/dist/cloudflare/core/tokens/formatters/tailwind-v4.js +335 -0
- package/dist/cloudflare/core/tokens/formatters/tokens-studio.js +256 -0
- package/dist/cloudflare/core/tokens/formatters/ts-module.js +198 -0
- package/dist/cloudflare/core/tokens/index.js +16 -0
- package/dist/cloudflare/core/tokens/parsers/css-vars.js +4 -0
- package/dist/cloudflare/core/tokens/parsers/dtcg.js +280 -0
- package/dist/cloudflare/core/tokens/parsers/index.js +138 -0
- package/dist/cloudflare/core/tokens/parsers/json.js +7 -0
- package/dist/cloudflare/core/tokens/parsers/scss.js +4 -0
- package/dist/cloudflare/core/tokens/parsers/stubs.js +20 -0
- package/dist/cloudflare/core/tokens/parsers/style-dictionary-v3.js +4 -0
- package/dist/cloudflare/core/tokens/parsers/tailwind-v3.js +4 -0
- package/dist/cloudflare/core/tokens/parsers/tailwind-v4.js +4 -0
- package/dist/cloudflare/core/tokens/parsers/tokens-studio.js +4 -0
- package/dist/cloudflare/core/tokens/schemas.js +152 -0
- package/dist/cloudflare/core/tokens/transforms/color.js +12 -0
- package/dist/cloudflare/core/tokens/transforms/index.js +29 -0
- package/dist/cloudflare/core/tokens/transforms/size.js +7 -0
- package/dist/cloudflare/core/tokens/types.js +18 -0
- package/dist/cloudflare/core/tokens-tools.js +1788 -0
- package/dist/cloudflare/core/types/design-code.js +4 -0
- package/dist/cloudflare/core/types/enriched.js +5 -0
- package/dist/cloudflare/core/types/index.js +4 -0
- package/dist/cloudflare/core/variable-resolver.js +85 -0
- package/dist/cloudflare/core/version-tools.js +1199 -0
- package/dist/cloudflare/core/websocket-connector.js +436 -0
- package/dist/cloudflare/core/websocket-server.js +956 -0
- package/dist/cloudflare/core/write-tools.js +2506 -0
- package/dist/cloudflare/index.js +3010 -0
- package/dist/core/accessibility-tools.d.ts +21 -0
- package/dist/core/accessibility-tools.d.ts.map +1 -0
- package/dist/core/accessibility-tools.js +362 -0
- package/dist/core/accessibility-tools.js.map +1 -0
- package/dist/core/annotation-tools.d.ts +14 -0
- package/dist/core/annotation-tools.d.ts.map +1 -0
- package/dist/core/annotation-tools.js +231 -0
- package/dist/core/annotation-tools.js.map +1 -0
- package/dist/core/comment-tools.d.ts +11 -0
- package/dist/core/comment-tools.d.ts.map +1 -0
- package/dist/core/comment-tools.js +293 -0
- package/dist/core/comment-tools.js.map +1 -0
- package/dist/core/config.d.ts +17 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +154 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/console-monitor.d.ts +82 -0
- package/dist/core/console-monitor.d.ts.map +1 -0
- package/dist/core/console-monitor.js +428 -0
- package/dist/core/console-monitor.js.map +1 -0
- package/dist/core/deep-component-tools.d.ts +14 -0
- package/dist/core/deep-component-tools.d.ts.map +1 -0
- package/dist/core/deep-component-tools.js +129 -0
- package/dist/core/deep-component-tools.js.map +1 -0
- package/dist/core/design-code-tools.d.ts +116 -0
- package/dist/core/design-code-tools.d.ts.map +1 -0
- package/dist/core/design-code-tools.js +2794 -0
- package/dist/core/design-code-tools.js.map +1 -0
- package/dist/core/design-system-manifest.d.ts +273 -0
- package/dist/core/design-system-manifest.d.ts.map +1 -0
- package/dist/core/design-system-manifest.js +266 -0
- package/dist/core/design-system-manifest.js.map +1 -0
- package/dist/core/design-system-tools.d.ts +67 -0
- package/dist/core/design-system-tools.d.ts.map +1 -0
- package/dist/core/design-system-tools.js +883 -0
- package/dist/core/design-system-tools.js.map +1 -0
- package/dist/core/diagnose-tool.d.ts +41 -0
- package/dist/core/diagnose-tool.d.ts.map +1 -0
- package/dist/core/diagnose-tool.js +101 -0
- package/dist/core/diagnose-tool.js.map +1 -0
- package/dist/core/diff/changelog-formatter.d.ts +35 -0
- package/dist/core/diff/changelog-formatter.d.ts.map +1 -0
- package/dist/core/diff/changelog-formatter.js +276 -0
- package/dist/core/diff/changelog-formatter.js.map +1 -0
- package/dist/core/diff/diff-engine.d.ts +127 -0
- package/dist/core/diff/diff-engine.d.ts.map +1 -0
- package/dist/core/diff/diff-engine.js +335 -0
- package/dist/core/diff/diff-engine.js.map +1 -0
- package/dist/core/diff/property-compare.d.ts +19 -0
- package/dist/core/diff/property-compare.d.ts.map +1 -0
- package/dist/core/diff/property-compare.js +37 -0
- package/dist/core/diff/property-compare.js.map +1 -0
- package/dist/core/diff/version-cache.d.ts +40 -0
- package/dist/core/diff/version-cache.d.ts.map +1 -0
- package/dist/core/diff/version-cache.js +75 -0
- package/dist/core/diff/version-cache.js.map +1 -0
- package/dist/core/enrichment/enrichment-service.d.ts +52 -0
- package/dist/core/enrichment/enrichment-service.d.ts.map +1 -0
- package/dist/core/enrichment/enrichment-service.js +375 -0
- package/dist/core/enrichment/enrichment-service.js.map +1 -0
- package/dist/core/enrichment/index.d.ts +8 -0
- package/dist/core/enrichment/index.d.ts.map +1 -0
- package/dist/core/enrichment/index.js +8 -0
- package/dist/core/enrichment/index.js.map +1 -0
- package/dist/core/enrichment/relationship-mapper.d.ts +106 -0
- package/dist/core/enrichment/relationship-mapper.d.ts.map +1 -0
- package/dist/core/enrichment/relationship-mapper.js +352 -0
- package/dist/core/enrichment/relationship-mapper.js.map +1 -0
- package/dist/core/enrichment/style-resolver.d.ts +85 -0
- package/dist/core/enrichment/style-resolver.d.ts.map +1 -0
- package/dist/core/enrichment/style-resolver.js +347 -0
- package/dist/core/enrichment/style-resolver.js.map +1 -0
- package/dist/core/figjam-tools.d.ts +8 -0
- package/dist/core/figjam-tools.d.ts.map +1 -0
- package/dist/core/figjam-tools.js +548 -0
- package/dist/core/figjam-tools.js.map +1 -0
- package/dist/core/figma-api.d.ts +254 -0
- package/dist/core/figma-api.d.ts.map +1 -0
- package/dist/core/figma-api.js +510 -0
- package/dist/core/figma-api.js.map +1 -0
- package/dist/core/figma-connector.d.ts +214 -0
- package/dist/core/figma-connector.d.ts.map +1 -0
- package/dist/core/figma-connector.js +8 -0
- package/dist/core/figma-connector.js.map +1 -0
- package/dist/core/figma-desktop-connector.d.ts +312 -0
- package/dist/core/figma-desktop-connector.d.ts.map +1 -0
- package/dist/core/figma-desktop-connector.js +1298 -0
- package/dist/core/figma-desktop-connector.js.map +1 -0
- package/dist/core/figma-reconstruction-spec.d.ts +166 -0
- package/dist/core/figma-reconstruction-spec.d.ts.map +1 -0
- package/dist/core/figma-reconstruction-spec.js +403 -0
- package/dist/core/figma-reconstruction-spec.js.map +1 -0
- package/dist/core/figma-style-extractor.d.ts +76 -0
- package/dist/core/figma-style-extractor.d.ts.map +1 -0
- package/dist/core/figma-style-extractor.js +312 -0
- package/dist/core/figma-style-extractor.js.map +1 -0
- package/dist/core/figma-tools.d.ts +22 -0
- package/dist/core/figma-tools.d.ts.map +1 -0
- package/dist/core/figma-tools.js +3303 -0
- package/dist/core/figma-tools.js.map +1 -0
- package/dist/core/identity.d.ts +41 -0
- package/dist/core/identity.d.ts.map +1 -0
- package/dist/core/identity.js +97 -0
- package/dist/core/identity.js.map +1 -0
- package/dist/core/library-tools.d.ts +17 -0
- package/dist/core/library-tools.d.ts.map +1 -0
- package/dist/core/library-tools.js +581 -0
- package/dist/core/library-tools.js.map +1 -0
- package/dist/core/logger.d.ts +22 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +54 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/port-discovery.d.ts +211 -0
- package/dist/core/port-discovery.d.ts.map +1 -0
- package/dist/core/port-discovery.js +936 -0
- package/dist/core/port-discovery.js.map +1 -0
- package/dist/core/resolve-package-root.d.ts +2 -0
- package/dist/core/resolve-package-root.d.ts.map +1 -0
- package/dist/core/resolve-package-root.js +12 -0
- package/dist/core/resolve-package-root.js.map +1 -0
- package/dist/core/slides-tools.d.ts +8 -0
- package/dist/core/slides-tools.d.ts.map +1 -0
- package/dist/core/slides-tools.js +715 -0
- package/dist/core/slides-tools.js.map +1 -0
- package/dist/core/slot-tools.d.ts +7 -0
- package/dist/core/slot-tools.d.ts.map +1 -0
- package/dist/core/slot-tools.js +335 -0
- package/dist/core/slot-tools.js.map +1 -0
- package/dist/core/snippet-injector.d.ts +24 -0
- package/dist/core/snippet-injector.d.ts.map +1 -0
- package/dist/core/snippet-injector.js +97 -0
- package/dist/core/snippet-injector.js.map +1 -0
- package/dist/core/tokens/alias-resolver.d.ts +97 -0
- package/dist/core/tokens/alias-resolver.d.ts.map +1 -0
- package/dist/core/tokens/alias-resolver.js +206 -0
- package/dist/core/tokens/alias-resolver.js.map +1 -0
- package/dist/core/tokens/config.d.ts +380 -0
- package/dist/core/tokens/config.d.ts.map +1 -0
- package/dist/core/tokens/config.js +295 -0
- package/dist/core/tokens/config.js.map +1 -0
- package/dist/core/tokens/dialect.d.ts +107 -0
- package/dist/core/tokens/dialect.d.ts.map +1 -0
- package/dist/core/tokens/dialect.js +233 -0
- package/dist/core/tokens/dialect.js.map +1 -0
- package/dist/core/tokens/figma-converter.d.ts +102 -0
- package/dist/core/tokens/figma-converter.d.ts.map +1 -0
- package/dist/core/tokens/figma-converter.js +324 -0
- package/dist/core/tokens/figma-converter.js.map +1 -0
- package/dist/core/tokens/formatters/css-vars.d.ts +24 -0
- package/dist/core/tokens/formatters/css-vars.d.ts.map +1 -0
- package/dist/core/tokens/formatters/css-vars.js +339 -0
- package/dist/core/tokens/formatters/css-vars.js.map +1 -0
- package/dist/core/tokens/formatters/dtcg.d.ts +28 -0
- package/dist/core/tokens/formatters/dtcg.d.ts.map +1 -0
- package/dist/core/tokens/formatters/dtcg.js +377 -0
- package/dist/core/tokens/formatters/dtcg.js.map +1 -0
- package/dist/core/tokens/formatters/index.d.ts +30 -0
- package/dist/core/tokens/formatters/index.d.ts.map +1 -0
- package/dist/core/tokens/formatters/index.js +46 -0
- package/dist/core/tokens/formatters/index.js.map +1 -0
- package/dist/core/tokens/formatters/json.d.ts +37 -0
- package/dist/core/tokens/formatters/json.d.ts.map +1 -0
- package/dist/core/tokens/formatters/json.js +206 -0
- package/dist/core/tokens/formatters/json.js.map +1 -0
- package/dist/core/tokens/formatters/less.d.ts +4 -0
- package/dist/core/tokens/formatters/less.d.ts.map +1 -0
- package/dist/core/tokens/formatters/less.js +5 -0
- package/dist/core/tokens/formatters/less.js.map +1 -0
- package/dist/core/tokens/formatters/scss.d.ts +26 -0
- package/dist/core/tokens/formatters/scss.d.ts.map +1 -0
- package/dist/core/tokens/formatters/scss.js +259 -0
- package/dist/core/tokens/formatters/scss.js.map +1 -0
- package/dist/core/tokens/formatters/stubs.d.ts +9 -0
- package/dist/core/tokens/formatters/stubs.d.ts.map +1 -0
- package/dist/core/tokens/formatters/stubs.js +14 -0
- package/dist/core/tokens/formatters/stubs.js.map +1 -0
- package/dist/core/tokens/formatters/style-dictionary-v3.d.ts +45 -0
- package/dist/core/tokens/formatters/style-dictionary-v3.d.ts.map +1 -0
- package/dist/core/tokens/formatters/style-dictionary-v3.js +214 -0
- package/dist/core/tokens/formatters/style-dictionary-v3.js.map +1 -0
- package/dist/core/tokens/formatters/tailwind-v3.d.ts +37 -0
- package/dist/core/tokens/formatters/tailwind-v3.d.ts.map +1 -0
- package/dist/core/tokens/formatters/tailwind-v3.js +238 -0
- package/dist/core/tokens/formatters/tailwind-v3.js.map +1 -0
- package/dist/core/tokens/formatters/tailwind-v4.d.ts +41 -0
- package/dist/core/tokens/formatters/tailwind-v4.d.ts.map +1 -0
- package/dist/core/tokens/formatters/tailwind-v4.js +336 -0
- package/dist/core/tokens/formatters/tailwind-v4.js.map +1 -0
- package/dist/core/tokens/formatters/tokens-studio.d.ts +44 -0
- package/dist/core/tokens/formatters/tokens-studio.d.ts.map +1 -0
- package/dist/core/tokens/formatters/tokens-studio.js +257 -0
- package/dist/core/tokens/formatters/tokens-studio.js.map +1 -0
- package/dist/core/tokens/formatters/ts-module.d.ts +35 -0
- package/dist/core/tokens/formatters/ts-module.d.ts.map +1 -0
- package/dist/core/tokens/formatters/ts-module.js +199 -0
- package/dist/core/tokens/formatters/ts-module.js.map +1 -0
- package/dist/core/tokens/index.d.ts +18 -0
- package/dist/core/tokens/index.d.ts.map +1 -0
- package/dist/core/tokens/index.js +17 -0
- package/dist/core/tokens/index.js.map +1 -0
- package/dist/core/tokens/parsers/css-vars.d.ts +3 -0
- package/dist/core/tokens/parsers/css-vars.d.ts.map +1 -0
- package/dist/core/tokens/parsers/css-vars.js +5 -0
- package/dist/core/tokens/parsers/css-vars.js.map +1 -0
- package/dist/core/tokens/parsers/dtcg.d.ts +21 -0
- package/dist/core/tokens/parsers/dtcg.d.ts.map +1 -0
- package/dist/core/tokens/parsers/dtcg.js +281 -0
- package/dist/core/tokens/parsers/dtcg.js.map +1 -0
- package/dist/core/tokens/parsers/index.d.ts +37 -0
- package/dist/core/tokens/parsers/index.d.ts.map +1 -0
- package/dist/core/tokens/parsers/index.js +139 -0
- package/dist/core/tokens/parsers/index.js.map +1 -0
- package/dist/core/tokens/parsers/json.d.ts +4 -0
- package/dist/core/tokens/parsers/json.d.ts.map +1 -0
- package/dist/core/tokens/parsers/json.js +8 -0
- package/dist/core/tokens/parsers/json.js.map +1 -0
- package/dist/core/tokens/parsers/scss.d.ts +3 -0
- package/dist/core/tokens/parsers/scss.d.ts.map +1 -0
- package/dist/core/tokens/parsers/scss.js +5 -0
- package/dist/core/tokens/parsers/scss.js.map +1 -0
- package/dist/core/tokens/parsers/stubs.d.ts +15 -0
- package/dist/core/tokens/parsers/stubs.d.ts.map +1 -0
- package/dist/core/tokens/parsers/stubs.js +21 -0
- package/dist/core/tokens/parsers/stubs.js.map +1 -0
- package/dist/core/tokens/parsers/style-dictionary-v3.d.ts +3 -0
- package/dist/core/tokens/parsers/style-dictionary-v3.d.ts.map +1 -0
- package/dist/core/tokens/parsers/style-dictionary-v3.js +5 -0
- package/dist/core/tokens/parsers/style-dictionary-v3.js.map +1 -0
- package/dist/core/tokens/parsers/tailwind-v3.d.ts +3 -0
- package/dist/core/tokens/parsers/tailwind-v3.d.ts.map +1 -0
- package/dist/core/tokens/parsers/tailwind-v3.js +5 -0
- package/dist/core/tokens/parsers/tailwind-v3.js.map +1 -0
- package/dist/core/tokens/parsers/tailwind-v4.d.ts +3 -0
- package/dist/core/tokens/parsers/tailwind-v4.d.ts.map +1 -0
- package/dist/core/tokens/parsers/tailwind-v4.js +5 -0
- package/dist/core/tokens/parsers/tailwind-v4.js.map +1 -0
- package/dist/core/tokens/parsers/tokens-studio.d.ts +3 -0
- package/dist/core/tokens/parsers/tokens-studio.d.ts.map +1 -0
- package/dist/core/tokens/parsers/tokens-studio.js +5 -0
- package/dist/core/tokens/parsers/tokens-studio.js.map +1 -0
- package/dist/core/tokens/schemas.d.ts +155 -0
- package/dist/core/tokens/schemas.d.ts.map +1 -0
- package/dist/core/tokens/schemas.js +153 -0
- package/dist/core/tokens/schemas.js.map +1 -0
- package/dist/core/tokens/transforms/color.d.ts +9 -0
- package/dist/core/tokens/transforms/color.d.ts.map +1 -0
- package/dist/core/tokens/transforms/color.js +13 -0
- package/dist/core/tokens/transforms/color.js.map +1 -0
- package/dist/core/tokens/transforms/index.d.ts +36 -0
- package/dist/core/tokens/transforms/index.d.ts.map +1 -0
- package/dist/core/tokens/transforms/index.js +30 -0
- package/dist/core/tokens/transforms/index.js.map +1 -0
- package/dist/core/tokens/transforms/size.d.ts +7 -0
- package/dist/core/tokens/transforms/size.d.ts.map +1 -0
- package/dist/core/tokens/transforms/size.js +8 -0
- package/dist/core/tokens/transforms/size.js.map +1 -0
- package/dist/core/tokens/types.d.ts +284 -0
- package/dist/core/tokens/types.d.ts.map +1 -0
- package/dist/core/tokens/types.js +19 -0
- package/dist/core/tokens/types.js.map +1 -0
- package/dist/core/tokens-tools.d.ts +285 -0
- package/dist/core/tokens-tools.d.ts.map +1 -0
- package/dist/core/tokens-tools.js +1789 -0
- package/dist/core/tokens-tools.js.map +1 -0
- package/dist/core/types/design-code.d.ts +271 -0
- package/dist/core/types/design-code.d.ts.map +1 -0
- package/dist/core/types/design-code.js +5 -0
- package/dist/core/types/design-code.js.map +1 -0
- package/dist/core/types/enriched.d.ts +213 -0
- package/dist/core/types/enriched.d.ts.map +1 -0
- package/dist/core/types/enriched.js +6 -0
- package/dist/core/types/enriched.js.map +1 -0
- package/dist/core/types/index.d.ts +104 -0
- package/dist/core/types/index.d.ts.map +1 -0
- package/dist/core/types/index.js +5 -0
- package/dist/core/types/index.js.map +1 -0
- package/dist/core/variable-resolver.d.ts +45 -0
- package/dist/core/variable-resolver.d.ts.map +1 -0
- package/dist/core/variable-resolver.js +86 -0
- package/dist/core/variable-resolver.js.map +1 -0
- package/dist/core/version-tools.d.ts +59 -0
- package/dist/core/version-tools.d.ts.map +1 -0
- package/dist/core/version-tools.js +1200 -0
- package/dist/core/version-tools.js.map +1 -0
- package/dist/core/websocket-connector.d.ts +247 -0
- package/dist/core/websocket-connector.d.ts.map +1 -0
- package/dist/core/websocket-connector.js +437 -0
- package/dist/core/websocket-connector.js.map +1 -0
- package/dist/core/websocket-server.d.ts +290 -0
- package/dist/core/websocket-server.d.ts.map +1 -0
- package/dist/core/websocket-server.js +957 -0
- package/dist/core/websocket-server.js.map +1 -0
- package/dist/core/write-tools.d.ts +7 -0
- package/dist/core/write-tools.d.ts.map +1 -0
- package/dist/core/write-tools.js +2507 -0
- package/dist/core/write-tools.js.map +1 -0
- package/dist/local.d.ts +105 -0
- package/dist/local.d.ts.map +1 -0
- package/dist/local.js +3314 -0
- package/dist/local.js.map +1 -0
- package/figma-desktop-bridge/README.md +365 -0
- package/figma-desktop-bridge/code.js +7359 -0
- package/figma-desktop-bridge/icon.png +0 -0
- package/figma-desktop-bridge/manifest.json +67 -0
- package/figma-desktop-bridge/ui.html +2783 -0
- package/package.json +103 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Relationship Mapper
|
|
3
|
+
* Maps relationships between styles, variables, and components
|
|
4
|
+
* Tracks usage counts and builds reverse lookup indexes
|
|
5
|
+
*/
|
|
6
|
+
export class RelationshipMapper {
|
|
7
|
+
constructor(logger) {
|
|
8
|
+
// Relationship indexes
|
|
9
|
+
this.componentsByStyle = new Map();
|
|
10
|
+
this.componentsByVariable = new Map();
|
|
11
|
+
this.stylesByVariable = new Map();
|
|
12
|
+
this.variableDependencies = new Map();
|
|
13
|
+
// Usage counters
|
|
14
|
+
this.styleUsageCount = new Map();
|
|
15
|
+
this.variableUsageCount = new Map();
|
|
16
|
+
this.logger = logger;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build all relationship indexes from file data
|
|
20
|
+
*/
|
|
21
|
+
async buildRelationships(fileData) {
|
|
22
|
+
this.logger.info("Building relationship indexes");
|
|
23
|
+
try {
|
|
24
|
+
// Clear existing indexes
|
|
25
|
+
this.clear();
|
|
26
|
+
// Build variable dependencies first
|
|
27
|
+
if (fileData.variables) {
|
|
28
|
+
await this.buildVariableDependencies(fileData.variables);
|
|
29
|
+
}
|
|
30
|
+
// Build style-variable relationships
|
|
31
|
+
if (fileData.styles && fileData.variables) {
|
|
32
|
+
await this.buildStyleVariableRelationships(fileData.styles, fileData.variables);
|
|
33
|
+
}
|
|
34
|
+
// Build component relationships
|
|
35
|
+
if (fileData.document) {
|
|
36
|
+
await this.buildComponentRelationships(fileData.document);
|
|
37
|
+
}
|
|
38
|
+
this.logger.info({
|
|
39
|
+
styles: this.componentsByStyle.size,
|
|
40
|
+
variables: this.componentsByVariable.size,
|
|
41
|
+
}, "Relationship indexes built successfully");
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
this.logger.error({ error }, "Error building relationships");
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get components that use a specific style
|
|
50
|
+
*/
|
|
51
|
+
getComponentsByStyle(styleId) {
|
|
52
|
+
return this.componentsByStyle.get(styleId) || [];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get components that use a specific variable
|
|
56
|
+
*/
|
|
57
|
+
getComponentsByVariable(variableId) {
|
|
58
|
+
return this.componentsByVariable.get(variableId) || [];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get styles that use a specific variable
|
|
62
|
+
*/
|
|
63
|
+
getStylesByVariable(variableId) {
|
|
64
|
+
return this.stylesByVariable.get(variableId) || [];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get variable dependencies (what variables this variable references)
|
|
68
|
+
*/
|
|
69
|
+
getVariableDependencies(variableId) {
|
|
70
|
+
return this.variableDependencies.get(variableId) || [];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get usage count for a style
|
|
74
|
+
*/
|
|
75
|
+
getStyleUsageCount(styleId) {
|
|
76
|
+
return this.styleUsageCount.get(styleId) || 0;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get usage count for a variable
|
|
80
|
+
*/
|
|
81
|
+
getVariableUsageCount(variableId) {
|
|
82
|
+
return this.variableUsageCount.get(variableId) || 0;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Find unused styles (styles with zero usage)
|
|
86
|
+
*/
|
|
87
|
+
getUnusedStyles(allStyles) {
|
|
88
|
+
const unused = [];
|
|
89
|
+
for (const style of allStyles) {
|
|
90
|
+
const usageCount = this.getStyleUsageCount(style.node_id || style.key || style.id);
|
|
91
|
+
if (usageCount === 0) {
|
|
92
|
+
unused.push({
|
|
93
|
+
id: style.id || style.key,
|
|
94
|
+
name: style.name,
|
|
95
|
+
type: style.style_type || style.styleType,
|
|
96
|
+
node_id: style.node_id || style.key,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return unused;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Find unused variables (variables with zero usage)
|
|
104
|
+
*/
|
|
105
|
+
getUnusedVariables(allVariables) {
|
|
106
|
+
const unused = [];
|
|
107
|
+
for (const variable of allVariables) {
|
|
108
|
+
const usageCount = this.getVariableUsageCount(variable.id);
|
|
109
|
+
if (usageCount === 0) {
|
|
110
|
+
unused.push({
|
|
111
|
+
id: variable.id,
|
|
112
|
+
name: variable.name,
|
|
113
|
+
collection: variable.variableCollectionId,
|
|
114
|
+
resolvedType: variable.resolvedType,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return unused;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Build variable dependency graph (which variables reference which)
|
|
122
|
+
*/
|
|
123
|
+
async buildVariableDependencies(variables) {
|
|
124
|
+
for (const [variableId, variable] of variables.entries()) {
|
|
125
|
+
const dependencies = this.extractVariableDependencies(variable, variables);
|
|
126
|
+
if (dependencies.length > 0) {
|
|
127
|
+
this.variableDependencies.set(variableId, dependencies);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Extract dependencies from a single variable
|
|
133
|
+
*/
|
|
134
|
+
extractVariableDependencies(variable, allVariables, depth = 0) {
|
|
135
|
+
const dependencies = [];
|
|
136
|
+
// Check all modes for variable aliases
|
|
137
|
+
for (const [modeId, value] of Object.entries(variable.valuesByMode || {})) {
|
|
138
|
+
if (typeof value === "object" &&
|
|
139
|
+
value !== null &&
|
|
140
|
+
value.type === "VARIABLE_ALIAS") {
|
|
141
|
+
const targetId = value.id;
|
|
142
|
+
const targetVariable = allVariables.get(targetId);
|
|
143
|
+
if (targetVariable) {
|
|
144
|
+
dependencies.push({
|
|
145
|
+
id: targetId,
|
|
146
|
+
name: targetVariable.name,
|
|
147
|
+
type: "alias",
|
|
148
|
+
depth,
|
|
149
|
+
});
|
|
150
|
+
// Increment usage count for the referenced variable
|
|
151
|
+
const currentCount = this.variableUsageCount.get(targetId) || 0;
|
|
152
|
+
this.variableUsageCount.set(targetId, currentCount + 1);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return dependencies;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Build relationships between styles and variables
|
|
160
|
+
*/
|
|
161
|
+
async buildStyleVariableRelationships(styles, variables) {
|
|
162
|
+
for (const style of styles) {
|
|
163
|
+
const variableRefs = this.extractStyleVariableReferences(style);
|
|
164
|
+
for (const varRef of variableRefs) {
|
|
165
|
+
// Track which styles use this variable
|
|
166
|
+
if (!this.stylesByVariable.has(varRef)) {
|
|
167
|
+
this.stylesByVariable.set(varRef, []);
|
|
168
|
+
}
|
|
169
|
+
this.stylesByVariable.get(varRef)?.push({
|
|
170
|
+
id: style.id || style.key,
|
|
171
|
+
name: style.name,
|
|
172
|
+
type: style.style_type || style.styleType,
|
|
173
|
+
node_id: style.node_id || style.key,
|
|
174
|
+
});
|
|
175
|
+
// Increment variable usage count
|
|
176
|
+
const currentCount = this.variableUsageCount.get(varRef) || 0;
|
|
177
|
+
this.variableUsageCount.set(varRef, currentCount + 1);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Extract variable references from a style
|
|
183
|
+
*/
|
|
184
|
+
extractStyleVariableReferences(style) {
|
|
185
|
+
const refs = [];
|
|
186
|
+
// Check boundVariables
|
|
187
|
+
if (style.boundVariables) {
|
|
188
|
+
const props = ["fills", "strokes", "effects", "text"];
|
|
189
|
+
for (const prop of props) {
|
|
190
|
+
if (style.boundVariables[prop]) {
|
|
191
|
+
const binding = style.boundVariables[prop];
|
|
192
|
+
if (Array.isArray(binding)) {
|
|
193
|
+
for (const b of binding) {
|
|
194
|
+
if (b.id)
|
|
195
|
+
refs.push(b.id);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
else if (binding.id) {
|
|
199
|
+
refs.push(binding.id);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return refs;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Build component relationships by traversing the document tree
|
|
208
|
+
*/
|
|
209
|
+
async buildComponentRelationships(document) {
|
|
210
|
+
// Traverse all pages
|
|
211
|
+
if (document.children) {
|
|
212
|
+
for (const page of document.children) {
|
|
213
|
+
await this.traverseNode(page, page.name);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Recursively traverse nodes to find component instances and their style/variable usage
|
|
219
|
+
*/
|
|
220
|
+
async traverseNode(node, pageName, path = []) {
|
|
221
|
+
const currentPath = [...path, node.name];
|
|
222
|
+
// Check if this node uses any styles
|
|
223
|
+
if (node.styles) {
|
|
224
|
+
this.trackNodeStyleUsage(node, pageName, currentPath);
|
|
225
|
+
}
|
|
226
|
+
// Check if this node uses any variables (via boundVariables)
|
|
227
|
+
if (node.boundVariables) {
|
|
228
|
+
this.trackNodeVariableUsage(node, pageName, currentPath);
|
|
229
|
+
}
|
|
230
|
+
// Recurse into children
|
|
231
|
+
if (node.children) {
|
|
232
|
+
for (const child of node.children) {
|
|
233
|
+
await this.traverseNode(child, pageName, currentPath);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Track which styles a node uses
|
|
239
|
+
*/
|
|
240
|
+
trackNodeStyleUsage(node, pageName, path) {
|
|
241
|
+
const componentUsage = {
|
|
242
|
+
id: node.id,
|
|
243
|
+
name: node.name,
|
|
244
|
+
type: node.type,
|
|
245
|
+
page: pageName,
|
|
246
|
+
};
|
|
247
|
+
// Check all style properties (fill, stroke, text, effect, grid)
|
|
248
|
+
const styleProps = ["fill", "stroke", "text", "effect", "grid"];
|
|
249
|
+
for (const prop of styleProps) {
|
|
250
|
+
const styleId = node.styles?.[prop];
|
|
251
|
+
if (styleId) {
|
|
252
|
+
// Add to componentsByStyle index
|
|
253
|
+
if (!this.componentsByStyle.has(styleId)) {
|
|
254
|
+
this.componentsByStyle.set(styleId, []);
|
|
255
|
+
}
|
|
256
|
+
this.componentsByStyle.get(styleId)?.push(componentUsage);
|
|
257
|
+
// Increment style usage count
|
|
258
|
+
const currentCount = this.styleUsageCount.get(styleId) || 0;
|
|
259
|
+
this.styleUsageCount.set(styleId, currentCount + 1);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Track which variables a node uses
|
|
265
|
+
*/
|
|
266
|
+
trackNodeVariableUsage(node, pageName, path) {
|
|
267
|
+
const componentUsage = {
|
|
268
|
+
id: node.id,
|
|
269
|
+
name: node.name,
|
|
270
|
+
type: node.type,
|
|
271
|
+
page: pageName,
|
|
272
|
+
};
|
|
273
|
+
// Extract all variable IDs from boundVariables
|
|
274
|
+
const variableIds = this.extractNodeVariableReferences(node);
|
|
275
|
+
for (const varId of variableIds) {
|
|
276
|
+
// Add to componentsByVariable index
|
|
277
|
+
if (!this.componentsByVariable.has(varId)) {
|
|
278
|
+
this.componentsByVariable.set(varId, []);
|
|
279
|
+
}
|
|
280
|
+
this.componentsByVariable.get(varId)?.push(componentUsage);
|
|
281
|
+
// Increment variable usage count
|
|
282
|
+
const currentCount = this.variableUsageCount.get(varId) || 0;
|
|
283
|
+
this.variableUsageCount.set(varId, currentCount + 1);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Extract all variable references from a node's boundVariables
|
|
288
|
+
*/
|
|
289
|
+
extractNodeVariableReferences(node) {
|
|
290
|
+
const refs = [];
|
|
291
|
+
if (!node.boundVariables)
|
|
292
|
+
return refs;
|
|
293
|
+
// boundVariables can have many properties (fills, strokes, etc.)
|
|
294
|
+
for (const [prop, binding] of Object.entries(node.boundVariables)) {
|
|
295
|
+
if (Array.isArray(binding)) {
|
|
296
|
+
for (const b of binding) {
|
|
297
|
+
if (b.id)
|
|
298
|
+
refs.push(b.id);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
else if (binding && typeof binding === "object" && binding.id) {
|
|
302
|
+
refs.push(binding.id);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return refs;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Detect circular variable references
|
|
309
|
+
*/
|
|
310
|
+
detectCircularReferences() {
|
|
311
|
+
const circular = [];
|
|
312
|
+
const visited = new Set();
|
|
313
|
+
const currentPath = [];
|
|
314
|
+
for (const [variableId] of this.variableDependencies) {
|
|
315
|
+
this.detectCircularDFS(variableId, visited, currentPath, circular);
|
|
316
|
+
}
|
|
317
|
+
return circular;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* DFS helper for detecting circular references
|
|
321
|
+
*/
|
|
322
|
+
detectCircularDFS(variableId, visited, currentPath, circular) {
|
|
323
|
+
if (currentPath.includes(variableId)) {
|
|
324
|
+
// Found a cycle
|
|
325
|
+
const cycleStart = currentPath.indexOf(variableId);
|
|
326
|
+
const cycle = currentPath.slice(cycleStart).concat(variableId);
|
|
327
|
+
circular.push({ chain: cycle });
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
if (visited.has(variableId))
|
|
331
|
+
return;
|
|
332
|
+
visited.add(variableId);
|
|
333
|
+
currentPath.push(variableId);
|
|
334
|
+
const dependencies = this.variableDependencies.get(variableId) || [];
|
|
335
|
+
for (const dep of dependencies) {
|
|
336
|
+
this.detectCircularDFS(dep.id, visited, currentPath, circular);
|
|
337
|
+
}
|
|
338
|
+
currentPath.pop();
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Clear all indexes and caches
|
|
342
|
+
*/
|
|
343
|
+
clear() {
|
|
344
|
+
this.componentsByStyle.clear();
|
|
345
|
+
this.componentsByVariable.clear();
|
|
346
|
+
this.stylesByVariable.clear();
|
|
347
|
+
this.variableDependencies.clear();
|
|
348
|
+
this.styleUsageCount.clear();
|
|
349
|
+
this.variableUsageCount.clear();
|
|
350
|
+
}
|
|
351
|
+
}
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Style Value Resolver
|
|
3
|
+
* Resolves style values from variable references and provides formatted outputs
|
|
4
|
+
*/
|
|
5
|
+
export class StyleValueResolver {
|
|
6
|
+
constructor(logger) {
|
|
7
|
+
this.cache = new Map();
|
|
8
|
+
this.variableCache = new Map();
|
|
9
|
+
this.logger = logger;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Resolve a style's value, handling variable references
|
|
13
|
+
*/
|
|
14
|
+
async resolveStyleValue(style, variables, maxDepth = 10) {
|
|
15
|
+
const cacheKey = `style:${style.key || style.node_id}`;
|
|
16
|
+
// Check cache
|
|
17
|
+
if (this.cache.has(cacheKey)) {
|
|
18
|
+
return this.cache.get(cacheKey);
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
// Get the actual style node data
|
|
22
|
+
const styleData = await this.getStyleData(style);
|
|
23
|
+
if (!styleData) {
|
|
24
|
+
return { value: null };
|
|
25
|
+
}
|
|
26
|
+
// Check if this style uses a variable
|
|
27
|
+
const variableRef = this.findVariableReference(styleData);
|
|
28
|
+
if (variableRef && variables.has(variableRef.id)) {
|
|
29
|
+
// Resolve the variable value
|
|
30
|
+
const variable = variables.get(variableRef.id);
|
|
31
|
+
const resolvedValue = await this.resolveVariableValue(variable, variables, maxDepth);
|
|
32
|
+
const result = {
|
|
33
|
+
value: resolvedValue,
|
|
34
|
+
variableRef: {
|
|
35
|
+
id: variableRef.id,
|
|
36
|
+
name: variable.name,
|
|
37
|
+
collection: variable.variableCollectionId,
|
|
38
|
+
resolvedType: variable.resolvedType,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
this.cache.set(cacheKey, result);
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
// No variable reference, return direct value
|
|
45
|
+
const directValue = this.extractDirectValue(styleData, style.style_type);
|
|
46
|
+
const result = { value: directValue };
|
|
47
|
+
this.cache.set(cacheKey, result);
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
this.logger.error({
|
|
52
|
+
error,
|
|
53
|
+
style: style.name,
|
|
54
|
+
}, "Error resolving style value");
|
|
55
|
+
return { value: null };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Resolve a variable's value, handling alias chains.
|
|
60
|
+
*
|
|
61
|
+
* `modeId` selects which mode's value to resolve; omitted, it falls back
|
|
62
|
+
* to the variable's first mode (legacy behavior for callers that don't
|
|
63
|
+
* care about modes). The cache is keyed per (variable, mode) so
|
|
64
|
+
* multi-mode variables don't all resolve to the first mode's value.
|
|
65
|
+
*/
|
|
66
|
+
async resolveVariableValue(variable, allVariables, maxDepth = 10, currentDepth = 0, modeId) {
|
|
67
|
+
if (currentDepth >= maxDepth) {
|
|
68
|
+
this.logger.warn({
|
|
69
|
+
variable: variable.name,
|
|
70
|
+
}, "Max resolution depth reached");
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
// Pick the mode to resolve: the requested modeId when this variable
|
|
74
|
+
// has a value for it, otherwise the first available mode (alias
|
|
75
|
+
// targets in other collections have different modeIds).
|
|
76
|
+
const modes = Object.keys(variable.valuesByMode || {});
|
|
77
|
+
if (modes.length === 0) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
const effectiveMode = modeId !== undefined && variable.valuesByMode[modeId] !== undefined
|
|
81
|
+
? modeId
|
|
82
|
+
: modes[0];
|
|
83
|
+
const cacheKey = `var:${variable.id}:${effectiveMode}`;
|
|
84
|
+
if (this.variableCache.has(cacheKey)) {
|
|
85
|
+
return this.variableCache.get(cacheKey);
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const value = variable.valuesByMode[effectiveMode];
|
|
89
|
+
// Check if this is an alias (reference to another variable)
|
|
90
|
+
if (value !== null && typeof value === "object" && value.type === "VARIABLE_ALIAS") {
|
|
91
|
+
const targetVariable = allVariables.get(value.id);
|
|
92
|
+
if (!targetVariable) {
|
|
93
|
+
this.logger.warn({
|
|
94
|
+
source: variable.name,
|
|
95
|
+
targetId: value.id,
|
|
96
|
+
}, "Variable alias target not found");
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
// Recursively resolve the alias, carrying the requested modeId
|
|
100
|
+
// through so same-collection targets resolve the same mode.
|
|
101
|
+
const resolvedValue = await this.resolveVariableValue(targetVariable, allVariables, maxDepth, currentDepth + 1, modeId);
|
|
102
|
+
this.variableCache.set(cacheKey, resolvedValue);
|
|
103
|
+
return resolvedValue;
|
|
104
|
+
}
|
|
105
|
+
// Direct value - format based on type
|
|
106
|
+
const formattedValue = this.formatVariableValue(value, variable.resolvedType);
|
|
107
|
+
this.variableCache.set(cacheKey, formattedValue);
|
|
108
|
+
return formattedValue;
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
this.logger.error({
|
|
112
|
+
error,
|
|
113
|
+
variable: variable.name,
|
|
114
|
+
}, "Error resolving variable value");
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Format a variable value based on its type
|
|
120
|
+
*/
|
|
121
|
+
formatVariableValue(value, type) {
|
|
122
|
+
// Guard only null/undefined — 0, false, and "" are legitimate
|
|
123
|
+
// variable values (opacity 0, boolean flags off, empty strings).
|
|
124
|
+
if (value === null || value === undefined)
|
|
125
|
+
return null;
|
|
126
|
+
switch (type) {
|
|
127
|
+
case "COLOR":
|
|
128
|
+
return this.formatColor(value);
|
|
129
|
+
case "FLOAT":
|
|
130
|
+
case "NUMBER":
|
|
131
|
+
return value;
|
|
132
|
+
case "STRING":
|
|
133
|
+
return value;
|
|
134
|
+
case "BOOLEAN":
|
|
135
|
+
return Boolean(value);
|
|
136
|
+
default:
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Format a color value to hex string
|
|
142
|
+
*/
|
|
143
|
+
formatColor(color) {
|
|
144
|
+
if (typeof color === "string") {
|
|
145
|
+
return color;
|
|
146
|
+
}
|
|
147
|
+
if (color.r !== undefined && color.g !== undefined && color.b !== undefined) {
|
|
148
|
+
const clampByte = (f) => Math.max(0, Math.min(255, Math.round(f * 255)));
|
|
149
|
+
const toHex = (byte) => byte.toString(16).padStart(2, "0");
|
|
150
|
+
const r = clampByte(color.r);
|
|
151
|
+
const g = clampByte(color.g);
|
|
152
|
+
const b = clampByte(color.b);
|
|
153
|
+
let hex = `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
154
|
+
// Preserve alpha: append the alpha byte for semi-transparent colors
|
|
155
|
+
// (mirrors rgbaToHex in tokens/figma-converter.ts).
|
|
156
|
+
if (color.a !== undefined && color.a < 1) {
|
|
157
|
+
hex += toHex(clampByte(color.a));
|
|
158
|
+
}
|
|
159
|
+
return hex.toUpperCase();
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Generate export formats for a resolved value
|
|
165
|
+
*/
|
|
166
|
+
generateExportFormats(name, value, type, formats = ["css", "sass", "tailwind", "typescript", "json"]) {
|
|
167
|
+
const result = {};
|
|
168
|
+
// Sanitize name for different formats
|
|
169
|
+
const cssName = this.toCSSVariableName(name);
|
|
170
|
+
const sassName = this.toSassVariableName(name);
|
|
171
|
+
const tailwindName = this.toTailwindClassName(name);
|
|
172
|
+
const tsName = this.toTypeScriptPath(name);
|
|
173
|
+
const jsonPath = this.toJSONPath(name);
|
|
174
|
+
for (const format of formats) {
|
|
175
|
+
switch (format) {
|
|
176
|
+
case "css":
|
|
177
|
+
result.css = `var(${cssName})`;
|
|
178
|
+
break;
|
|
179
|
+
case "sass":
|
|
180
|
+
result.sass = sassName;
|
|
181
|
+
break;
|
|
182
|
+
case "tailwind":
|
|
183
|
+
result.tailwind = tailwindName;
|
|
184
|
+
break;
|
|
185
|
+
case "typescript":
|
|
186
|
+
result.typescript = tsName;
|
|
187
|
+
break;
|
|
188
|
+
case "json":
|
|
189
|
+
result.json = jsonPath;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Convert token name to CSS variable format
|
|
197
|
+
* Example: "color/background/primary-default" -> "--color-background-primary-default"
|
|
198
|
+
*/
|
|
199
|
+
toCSSVariableName(name) {
|
|
200
|
+
return `--${name.replace(/\//g, "-").toLowerCase()}`;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Convert token name to Sass variable format
|
|
204
|
+
* Example: "color/background/primary-default" -> "$color-background-primary-default"
|
|
205
|
+
*/
|
|
206
|
+
toSassVariableName(name) {
|
|
207
|
+
return `$${name.replace(/\//g, "-").toLowerCase()}`;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Convert token name to Tailwind class format
|
|
211
|
+
* Example: "color/background/primary-default" -> "bg-primary"
|
|
212
|
+
*/
|
|
213
|
+
toTailwindClassName(name) {
|
|
214
|
+
const parts = name.split("/");
|
|
215
|
+
// Try to infer Tailwind utility class
|
|
216
|
+
if (parts[0] === "color") {
|
|
217
|
+
if (parts[1] === "background") {
|
|
218
|
+
return `bg-${parts[parts.length - 1].toLowerCase()}`;
|
|
219
|
+
}
|
|
220
|
+
if (parts[1] === "text") {
|
|
221
|
+
return `text-${parts[parts.length - 1].toLowerCase()}`;
|
|
222
|
+
}
|
|
223
|
+
if (parts[1] === "border") {
|
|
224
|
+
return `border-${parts[parts.length - 1].toLowerCase()}`;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (parts[0] === "spacing") {
|
|
228
|
+
return `space-${parts[parts.length - 1].toLowerCase()}`;
|
|
229
|
+
}
|
|
230
|
+
// Fallback: use last part
|
|
231
|
+
return parts[parts.length - 1].toLowerCase();
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Convert token name to TypeScript path format
|
|
235
|
+
* Example: "color/background/primary-default" -> "tokens.color.background.primaryDefault"
|
|
236
|
+
*/
|
|
237
|
+
toTypeScriptPath(name) {
|
|
238
|
+
const parts = name.split("/");
|
|
239
|
+
const camelCaseParts = parts.map((part, index) => {
|
|
240
|
+
if (index === 0)
|
|
241
|
+
return part.toLowerCase();
|
|
242
|
+
return part
|
|
243
|
+
.split("-")
|
|
244
|
+
.map((word, i) => i === 0
|
|
245
|
+
? word.toLowerCase()
|
|
246
|
+
: word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
247
|
+
.join("");
|
|
248
|
+
});
|
|
249
|
+
return `tokens.${camelCaseParts.join(".")}`;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Convert token name to nested JSON path
|
|
253
|
+
* Example: "color/background/primary-default" -> { color: { background: { primaryDefault: value } } }
|
|
254
|
+
*/
|
|
255
|
+
toJSONPath(name) {
|
|
256
|
+
const parts = name.split("/");
|
|
257
|
+
const result = {};
|
|
258
|
+
let current = result;
|
|
259
|
+
for (let i = 0; i < parts.length; i++) {
|
|
260
|
+
const key = parts[i]
|
|
261
|
+
.split("-")
|
|
262
|
+
.map((word, j) => j === 0
|
|
263
|
+
? word.toLowerCase()
|
|
264
|
+
: word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
265
|
+
.join("");
|
|
266
|
+
if (i === parts.length - 1) {
|
|
267
|
+
current[key] = "[VALUE]"; // Placeholder
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
current[key] = {};
|
|
271
|
+
current = current[key];
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return result;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Get style data from Figma API
|
|
278
|
+
* This would be called via the Figma API client
|
|
279
|
+
*/
|
|
280
|
+
async getStyleData(style) {
|
|
281
|
+
// TODO: Implement actual Figma API call
|
|
282
|
+
// For now, return the style object itself
|
|
283
|
+
return style;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Find variable reference in style data
|
|
287
|
+
*/
|
|
288
|
+
findVariableReference(styleData) {
|
|
289
|
+
// Check for boundVariables (new variables API)
|
|
290
|
+
if (styleData.boundVariables) {
|
|
291
|
+
// Check common properties that can be bound to variables
|
|
292
|
+
const props = ["fills", "strokes", "effects", "text"];
|
|
293
|
+
for (const prop of props) {
|
|
294
|
+
if (styleData.boundVariables[prop]) {
|
|
295
|
+
const binding = styleData.boundVariables[prop];
|
|
296
|
+
if (Array.isArray(binding) && binding.length > 0) {
|
|
297
|
+
return { id: binding[0].id };
|
|
298
|
+
}
|
|
299
|
+
if (binding.id) {
|
|
300
|
+
return { id: binding.id };
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Extract direct value from style (no variable)
|
|
309
|
+
*/
|
|
310
|
+
extractDirectValue(styleData, styleType) {
|
|
311
|
+
switch (styleType) {
|
|
312
|
+
case "FILL":
|
|
313
|
+
if (styleData.fills && styleData.fills.length > 0) {
|
|
314
|
+
const fill = styleData.fills[0];
|
|
315
|
+
if (fill.type === "SOLID") {
|
|
316
|
+
return this.formatColor(fill.color);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return null;
|
|
320
|
+
case "TEXT":
|
|
321
|
+
if (styleData.fontFamily) {
|
|
322
|
+
return {
|
|
323
|
+
fontFamily: styleData.fontFamily,
|
|
324
|
+
fontSize: styleData.fontSize,
|
|
325
|
+
fontWeight: styleData.fontWeight,
|
|
326
|
+
lineHeight: styleData.lineHeight,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
return null;
|
|
330
|
+
case "EFFECT":
|
|
331
|
+
if (styleData.effects && styleData.effects.length > 0) {
|
|
332
|
+
return styleData.effects;
|
|
333
|
+
}
|
|
334
|
+
return null;
|
|
335
|
+
default:
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Clear the cache
|
|
341
|
+
*/
|
|
342
|
+
clearCache() {
|
|
343
|
+
this.cache.clear();
|
|
344
|
+
this.variableCache.clear();
|
|
345
|
+
}
|
|
346
|
+
}
|