@mp3wizard/figma-console-mcp 1.14.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 +816 -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/base.js +5 -0
- package/dist/cloudflare/browser/cloudflare.js +156 -0
- package/dist/cloudflare/browser-manager.js +157 -0
- package/dist/cloudflare/core/cloud-websocket-connector.js +267 -0
- package/dist/cloudflare/core/cloud-websocket-relay.js +199 -0
- package/dist/cloudflare/core/comment-tools.js +292 -0
- package/dist/cloudflare/core/config.js +161 -0
- package/dist/cloudflare/core/console-monitor.js +427 -0
- package/dist/cloudflare/core/design-code-tools.js +2504 -0
- package/dist/cloudflare/core/design-system-manifest.js +260 -0
- package/dist/cloudflare/core/design-system-tools.js +863 -0
- package/dist/cloudflare/core/enrichment/enrichment-service.js +272 -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 +326 -0
- package/dist/cloudflare/core/figma-api.js +409 -0
- package/dist/cloudflare/core/figma-connector.js +7 -0
- package/dist/cloudflare/core/figma-desktop-connector.js +1184 -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 +2947 -0
- package/dist/cloudflare/core/logger.js +53 -0
- package/dist/cloudflare/core/port-discovery.js +282 -0
- package/dist/cloudflare/core/snippet-injector.js +96 -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/websocket-connector.js +256 -0
- package/dist/cloudflare/core/websocket-server.js +646 -0
- package/dist/cloudflare/core/write-tools.js +2091 -0
- package/dist/cloudflare/index.js +2899 -0
- package/dist/cloudflare/test-browser.js +88 -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 +162 -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/design-code-tools.d.ts +127 -0
- package/dist/core/design-code-tools.d.ts.map +1 -0
- package/dist/core/design-code-tools.js +2505 -0
- package/dist/core/design-code-tools.js.map +1 -0
- package/dist/core/design-system-manifest.d.ts +272 -0
- package/dist/core/design-system-manifest.d.ts.map +1 -0
- package/dist/core/design-system-manifest.js +261 -0
- package/dist/core/design-system-manifest.js.map +1 -0
- package/dist/core/design-system-tools.d.ts +17 -0
- package/dist/core/design-system-tools.d.ts.map +1 -0
- package/dist/core/design-system-tools.js +864 -0
- package/dist/core/design-system-tools.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 +273 -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 +80 -0
- package/dist/core/enrichment/style-resolver.d.ts.map +1 -0
- package/dist/core/enrichment/style-resolver.js +327 -0
- package/dist/core/enrichment/style-resolver.js.map +1 -0
- package/dist/core/figma-api.d.ts +201 -0
- package/dist/core/figma-api.d.ts.map +1 -0
- package/dist/core/figma-api.js +410 -0
- package/dist/core/figma-api.js.map +1 -0
- package/dist/core/figma-connector.d.ts +48 -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 +265 -0
- package/dist/core/figma-desktop-connector.d.ts.map +1 -0
- package/dist/core/figma-desktop-connector.js +1184 -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 +23 -0
- package/dist/core/figma-tools.d.ts.map +1 -0
- package/dist/core/figma-tools.js +2948 -0
- package/dist/core/figma-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 +110 -0
- package/dist/core/port-discovery.d.ts.map +1 -0
- package/dist/core/port-discovery.js +283 -0
- package/dist/core/port-discovery.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/types/design-code.d.ts +262 -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 +112 -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/websocket-connector.d.ts +55 -0
- package/dist/core/websocket-connector.d.ts.map +1 -0
- package/dist/core/websocket-connector.js +257 -0
- package/dist/core/websocket-connector.js.map +1 -0
- package/dist/core/websocket-server.d.ts +191 -0
- package/dist/core/websocket-server.d.ts.map +1 -0
- package/dist/core/websocket-server.js +647 -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 +2092 -0
- package/dist/core/write-tools.js.map +1 -0
- package/dist/local.d.ts +84 -0
- package/dist/local.d.ts.map +1 -0
- package/dist/local.js +5039 -0
- package/dist/local.js.map +1 -0
- package/figma-desktop-bridge/README.md +313 -0
- package/figma-desktop-bridge/code.js +2818 -0
- package/figma-desktop-bridge/manifest.json +67 -0
- package/figma-desktop-bridge/ui.html +1236 -0
- package/package.json +87 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consistency Scorer (weight: 0.15)
|
|
3
|
+
*
|
|
4
|
+
* Checks pattern uniformity across the design system.
|
|
5
|
+
* Evaluates naming delimiter consistency, casing consistency,
|
|
6
|
+
* size value consistency, and mode naming consistency.
|
|
7
|
+
*/
|
|
8
|
+
import { buildCollectionNameMap, clamp, getSeverity } from "./types.js";
|
|
9
|
+
/** Maximum examples to include in a finding. */
|
|
10
|
+
const MAX_EXAMPLES = 5;
|
|
11
|
+
const PASCAL_CASE_RE = /^[A-Z][a-zA-Z0-9]*$/;
|
|
12
|
+
const CAMEL_CASE_RE = /^[a-z][a-zA-Z0-9]*$/;
|
|
13
|
+
const KEBAB_CASE_RE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
14
|
+
const SNAKE_CASE_RE = /^[a-z][a-z0-9]*(_[a-z0-9]+)*$/;
|
|
15
|
+
/** Supported delimiters in variable names. */
|
|
16
|
+
const DELIMITERS = ["/", ".", "-", "_"];
|
|
17
|
+
/**
|
|
18
|
+
* Count delimiter occurrences across all variable names.
|
|
19
|
+
* Returns a map of delimiter to count of variables that use it.
|
|
20
|
+
*/
|
|
21
|
+
function countDelimiterUsage(names) {
|
|
22
|
+
const counts = new Map();
|
|
23
|
+
for (const delimiter of DELIMITERS) {
|
|
24
|
+
counts.set(delimiter, 0);
|
|
25
|
+
}
|
|
26
|
+
for (const name of names) {
|
|
27
|
+
for (const delimiter of DELIMITERS) {
|
|
28
|
+
if (name.includes(delimiter)) {
|
|
29
|
+
counts.set(delimiter, (counts.get(delimiter) ?? 0) + 1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return counts;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Score naming delimiter consistency.
|
|
37
|
+
* Variable names should consistently use the same delimiter (/, ., or -).
|
|
38
|
+
*/
|
|
39
|
+
function scoreDelimiterConsistency(data) {
|
|
40
|
+
const names = data.variables.map((v) => v.name);
|
|
41
|
+
if (names.length === 0) {
|
|
42
|
+
return {
|
|
43
|
+
id: "consistency-delimiter",
|
|
44
|
+
label: "Naming delimiter consistency",
|
|
45
|
+
score: 100,
|
|
46
|
+
severity: "info",
|
|
47
|
+
tooltip: "Variable names should use the same delimiter throughout (/ or . or -). Mixed delimiters make tokens harder to find and autocomplete.",
|
|
48
|
+
details: "No variables to evaluate.",
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const counts = countDelimiterUsage(names);
|
|
52
|
+
// Find variables that use any delimiter at all
|
|
53
|
+
const varsWithDelimiter = names.filter((name) => DELIMITERS.some((d) => name.includes(d)));
|
|
54
|
+
if (varsWithDelimiter.length === 0) {
|
|
55
|
+
return {
|
|
56
|
+
id: "consistency-delimiter",
|
|
57
|
+
label: "Naming delimiter consistency",
|
|
58
|
+
score: 100,
|
|
59
|
+
severity: "pass",
|
|
60
|
+
tooltip: "Variable names should use the same delimiter throughout (/ or . or -). Mixed delimiters make tokens harder to find and autocomplete.",
|
|
61
|
+
details: "No delimiters used in variable names (single-segment names).",
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// Find the dominant delimiter
|
|
65
|
+
let dominantDelimiter = "/";
|
|
66
|
+
let dominantCount = 0;
|
|
67
|
+
for (const [delimiter, count] of counts.entries()) {
|
|
68
|
+
if (count > dominantCount) {
|
|
69
|
+
dominantCount = count;
|
|
70
|
+
dominantDelimiter = delimiter;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const ratio = dominantCount / varsWithDelimiter.length;
|
|
74
|
+
const score = clamp(ratio * 100);
|
|
75
|
+
const collectionNames = buildCollectionNameMap(data.collections);
|
|
76
|
+
// Find variables using non-dominant delimiters
|
|
77
|
+
const nonDominantVars = data.variables.filter((v) => {
|
|
78
|
+
const name = v.name;
|
|
79
|
+
const usesDelimiter = DELIMITERS.some((d) => name.includes(d));
|
|
80
|
+
if (!usesDelimiter)
|
|
81
|
+
return false;
|
|
82
|
+
return !name.includes(dominantDelimiter);
|
|
83
|
+
});
|
|
84
|
+
return {
|
|
85
|
+
id: "consistency-delimiter",
|
|
86
|
+
label: "Naming delimiter consistency",
|
|
87
|
+
score,
|
|
88
|
+
severity: getSeverity(score),
|
|
89
|
+
tooltip: "Variable names should use the same delimiter throughout (/ or . or -). Mixed delimiters make tokens harder to find and autocomplete.",
|
|
90
|
+
details: `${Math.round(ratio * 100)}% of variables use "${dominantDelimiter}" as delimiter. Consistent delimiter usage improves navigability.`,
|
|
91
|
+
examples: nonDominantVars.length > 0
|
|
92
|
+
? nonDominantVars.slice(0, MAX_EXAMPLES).map((v) => v.name)
|
|
93
|
+
: undefined,
|
|
94
|
+
locations: nonDominantVars.length > 0
|
|
95
|
+
? nonDominantVars.slice(0, MAX_EXAMPLES).map((v) => ({
|
|
96
|
+
name: v.name,
|
|
97
|
+
collection: collectionNames.get(v.variableCollectionId),
|
|
98
|
+
type: "variable",
|
|
99
|
+
}))
|
|
100
|
+
: undefined,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Detect the casing pattern of a name segment.
|
|
105
|
+
*/
|
|
106
|
+
function detectCasing(segment) {
|
|
107
|
+
if (PASCAL_CASE_RE.test(segment))
|
|
108
|
+
return "PascalCase";
|
|
109
|
+
if (CAMEL_CASE_RE.test(segment))
|
|
110
|
+
return "camelCase";
|
|
111
|
+
if (KEBAB_CASE_RE.test(segment))
|
|
112
|
+
return "kebab-case";
|
|
113
|
+
if (SNAKE_CASE_RE.test(segment))
|
|
114
|
+
return "snake_case";
|
|
115
|
+
if (segment === segment.toUpperCase() && segment.length > 1)
|
|
116
|
+
return "UPPERCASE";
|
|
117
|
+
if (segment === segment.toLowerCase())
|
|
118
|
+
return "lowercase";
|
|
119
|
+
return "mixed";
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Score casing consistency across component and variable names.
|
|
123
|
+
*/
|
|
124
|
+
function scoreCasingConsistency(data) {
|
|
125
|
+
// Check component name casing
|
|
126
|
+
const componentSegments = [];
|
|
127
|
+
for (const comp of data.components) {
|
|
128
|
+
const segments = comp.name.split("/").map((s) => s.trim());
|
|
129
|
+
componentSegments.push(...segments);
|
|
130
|
+
}
|
|
131
|
+
// Check variable name leaf segments
|
|
132
|
+
const variableLeaves = [];
|
|
133
|
+
for (const v of data.variables) {
|
|
134
|
+
const segments = v.name.split(/[/.]/);
|
|
135
|
+
if (segments.length > 0) {
|
|
136
|
+
variableLeaves.push(...segments);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const allSegments = [...componentSegments, ...variableLeaves].filter((s) => s.length > 1);
|
|
140
|
+
if (allSegments.length === 0) {
|
|
141
|
+
return {
|
|
142
|
+
id: "consistency-casing",
|
|
143
|
+
label: "Casing consistency",
|
|
144
|
+
score: 100,
|
|
145
|
+
severity: "info",
|
|
146
|
+
tooltip: "Name segments should use a consistent casing convention (PascalCase, camelCase, etc.) across all components and variables.",
|
|
147
|
+
details: "No name segments to evaluate.",
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// Count casing patterns
|
|
151
|
+
const casingCounts = new Map();
|
|
152
|
+
for (const segment of allSegments) {
|
|
153
|
+
const casing = detectCasing(segment);
|
|
154
|
+
casingCounts.set(casing, (casingCounts.get(casing) ?? 0) + 1);
|
|
155
|
+
}
|
|
156
|
+
// Find dominant casing
|
|
157
|
+
let dominantCasing = "mixed";
|
|
158
|
+
let dominantCount = 0;
|
|
159
|
+
for (const [casing, count] of casingCounts.entries()) {
|
|
160
|
+
if (count > dominantCount) {
|
|
161
|
+
dominantCount = count;
|
|
162
|
+
dominantCasing = casing;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const ratio = dominantCount / allSegments.length;
|
|
166
|
+
const score = clamp(ratio * 100);
|
|
167
|
+
// Find segments using non-dominant casing
|
|
168
|
+
const nonDominantSegments = allSegments.filter((seg) => detectCasing(seg) !== dominantCasing);
|
|
169
|
+
return {
|
|
170
|
+
id: "consistency-casing",
|
|
171
|
+
label: "Casing consistency",
|
|
172
|
+
score,
|
|
173
|
+
severity: getSeverity(score),
|
|
174
|
+
tooltip: "Name segments should use a consistent casing convention (PascalCase, camelCase, etc.) across all components and variables.",
|
|
175
|
+
details: `${Math.round(ratio * 100)}% of name segments use ${dominantCasing}. Consistent casing improves readability.`,
|
|
176
|
+
examples: nonDominantSegments.length > 0
|
|
177
|
+
? nonDominantSegments.slice(0, MAX_EXAMPLES)
|
|
178
|
+
: undefined,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Check if numeric values follow a consistent scale pattern.
|
|
183
|
+
* Common patterns: multiples of 4, multiples of 8, powers of 2.
|
|
184
|
+
*/
|
|
185
|
+
function detectScalePattern(values) {
|
|
186
|
+
if (values.length === 0)
|
|
187
|
+
return { pattern: "none", matchRatio: 0 };
|
|
188
|
+
const positiveValues = values.filter((v) => v > 0);
|
|
189
|
+
if (positiveValues.length === 0)
|
|
190
|
+
return { pattern: "none", matchRatio: 0 };
|
|
191
|
+
const scales = [
|
|
192
|
+
{ name: "4px base", divisor: 4 },
|
|
193
|
+
{ name: "8px base", divisor: 8 },
|
|
194
|
+
{ name: "2px base", divisor: 2 },
|
|
195
|
+
];
|
|
196
|
+
let bestPattern = "none";
|
|
197
|
+
let bestRatio = 0;
|
|
198
|
+
for (const scale of scales) {
|
|
199
|
+
const matching = positiveValues.filter((v) => v % scale.divisor === 0).length;
|
|
200
|
+
const ratio = matching / positiveValues.length;
|
|
201
|
+
if (ratio > bestRatio) {
|
|
202
|
+
bestRatio = ratio;
|
|
203
|
+
bestPattern = scale.name;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return { pattern: bestPattern, matchRatio: bestRatio };
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Score size value consistency.
|
|
210
|
+
* Numeric (FLOAT) variables should follow a consistent scale.
|
|
211
|
+
*/
|
|
212
|
+
function scoreSizeValueConsistency(data) {
|
|
213
|
+
const floatVars = data.variables.filter((v) => v.resolvedType === "FLOAT");
|
|
214
|
+
if (floatVars.length === 0) {
|
|
215
|
+
return {
|
|
216
|
+
id: "consistency-size-values",
|
|
217
|
+
label: "Size value consistency",
|
|
218
|
+
score: 100,
|
|
219
|
+
severity: "info",
|
|
220
|
+
tooltip: "Numeric token values should follow a consistent scale (e.g. multiples of 4 or 8). Consistent scales create visual rhythm and predictable spacing.",
|
|
221
|
+
details: "No numeric variables to evaluate.",
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
// Extract numeric values (skip aliases)
|
|
225
|
+
const numericValues = [];
|
|
226
|
+
for (const v of floatVars) {
|
|
227
|
+
if (!v.valuesByMode)
|
|
228
|
+
continue;
|
|
229
|
+
for (const value of Object.values(v.valuesByMode)) {
|
|
230
|
+
if (typeof value === "number") {
|
|
231
|
+
numericValues.push(value);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (numericValues.length === 0) {
|
|
236
|
+
return {
|
|
237
|
+
id: "consistency-size-values",
|
|
238
|
+
label: "Size value consistency",
|
|
239
|
+
score: 50,
|
|
240
|
+
severity: "warning",
|
|
241
|
+
tooltip: "Numeric token values should follow a consistent scale (e.g. multiples of 4 or 8). Consistent scales create visual rhythm and predictable spacing.",
|
|
242
|
+
details: "No direct numeric values found (all aliases).",
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
const { pattern, matchRatio } = detectScalePattern(numericValues);
|
|
246
|
+
const score = clamp(matchRatio * 100);
|
|
247
|
+
return {
|
|
248
|
+
id: "consistency-size-values",
|
|
249
|
+
label: "Size value consistency",
|
|
250
|
+
score,
|
|
251
|
+
severity: getSeverity(score),
|
|
252
|
+
tooltip: "Numeric token values should follow a consistent scale (e.g. multiples of 4 or 8). Consistent scales create visual rhythm and predictable spacing.",
|
|
253
|
+
details: pattern !== "none"
|
|
254
|
+
? `${Math.round(matchRatio * 100)}% of numeric values follow a ${pattern} scale.`
|
|
255
|
+
: "No consistent scale pattern detected in numeric values.",
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Score mode naming consistency.
|
|
260
|
+
* All collections should use the same mode names.
|
|
261
|
+
*/
|
|
262
|
+
function scoreModeNamingConsistency(data) {
|
|
263
|
+
const collections = data.collections;
|
|
264
|
+
if (collections.length <= 1) {
|
|
265
|
+
return {
|
|
266
|
+
id: "consistency-mode-naming",
|
|
267
|
+
label: "Mode naming consistency",
|
|
268
|
+
score: 100,
|
|
269
|
+
severity: collections.length === 0 ? "info" : "pass",
|
|
270
|
+
tooltip: "All collections with multiple modes should use the same mode names (e.g. Light/Dark). Inconsistent mode names cause confusion.",
|
|
271
|
+
details: collections.length === 0
|
|
272
|
+
? "No collections to evaluate."
|
|
273
|
+
: "Only one collection; mode naming consistency is not applicable.",
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
// Collect mode name sets per collection
|
|
277
|
+
const modeNameSets = [];
|
|
278
|
+
for (const collection of collections) {
|
|
279
|
+
if (collection.modes && collection.modes.length > 0) {
|
|
280
|
+
const modeNames = collection.modes
|
|
281
|
+
.map((m) => m.name.toLowerCase())
|
|
282
|
+
.sort();
|
|
283
|
+
modeNameSets.push(modeNames);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (modeNameSets.length <= 1) {
|
|
287
|
+
return {
|
|
288
|
+
id: "consistency-mode-naming",
|
|
289
|
+
label: "Mode naming consistency",
|
|
290
|
+
score: 100,
|
|
291
|
+
severity: "pass",
|
|
292
|
+
tooltip: "All collections with multiple modes should use the same mode names (e.g. Light/Dark). Inconsistent mode names cause confusion.",
|
|
293
|
+
details: "Only one collection has modes; consistency is not applicable.",
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
// Compare mode name sets - check how many match the most common pattern
|
|
297
|
+
const serialized = modeNameSets.map((s) => s.join(","));
|
|
298
|
+
const patternCounts = new Map();
|
|
299
|
+
for (const s of serialized) {
|
|
300
|
+
patternCounts.set(s, (patternCounts.get(s) ?? 0) + 1);
|
|
301
|
+
}
|
|
302
|
+
let dominantCount = 0;
|
|
303
|
+
for (const count of patternCounts.values()) {
|
|
304
|
+
if (count > dominantCount) {
|
|
305
|
+
dominantCount = count;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
const ratio = dominantCount / modeNameSets.length;
|
|
309
|
+
const score = clamp(ratio * 100);
|
|
310
|
+
return {
|
|
311
|
+
id: "consistency-mode-naming",
|
|
312
|
+
label: "Mode naming consistency",
|
|
313
|
+
score,
|
|
314
|
+
severity: getSeverity(score),
|
|
315
|
+
tooltip: "All collections with multiple modes should use the same mode names (e.g. Light/Dark). Inconsistent mode names cause confusion.",
|
|
316
|
+
details: ratio < 1
|
|
317
|
+
? `${Math.round(ratio * 100)}% of collections share the same mode names. Align mode names across collections.`
|
|
318
|
+
: "All collections use consistent mode names.",
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Consistency category scorer.
|
|
323
|
+
* Returns the average score across all consistency checks.
|
|
324
|
+
*/
|
|
325
|
+
export function scoreConsistency(data) {
|
|
326
|
+
const findings = [
|
|
327
|
+
scoreDelimiterConsistency(data),
|
|
328
|
+
scoreCasingConsistency(data),
|
|
329
|
+
scoreSizeValueConsistency(data),
|
|
330
|
+
scoreModeNamingConsistency(data),
|
|
331
|
+
];
|
|
332
|
+
const score = clamp(findings.reduce((sum, f) => sum + f.score, 0) / findings.length);
|
|
333
|
+
return {
|
|
334
|
+
id: "consistency",
|
|
335
|
+
label: "Consistency",
|
|
336
|
+
shortLabel: "Consistency",
|
|
337
|
+
score,
|
|
338
|
+
weight: 0.15,
|
|
339
|
+
findings,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=consistency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consistency.js","sourceRoot":"","sources":["../../../../src/apps/design-system-dashboard/scoring/consistency.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage Scorer (weight: 0.10)
|
|
3
|
+
*
|
|
4
|
+
* Checks completeness of the design system.
|
|
5
|
+
* Evaluates token type coverage, core component presence,
|
|
6
|
+
* variable count health, and collection completeness.
|
|
7
|
+
*/
|
|
8
|
+
import type { CategoryScore, DesignSystemRawData } from "./types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Coverage category scorer.
|
|
11
|
+
* Returns the average score across all coverage checks.
|
|
12
|
+
*/
|
|
13
|
+
export declare function scoreCoverage(data: DesignSystemRawData): CategoryScore;
|
|
14
|
+
//# sourceMappingURL=coverage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../../../src/apps/design-system-dashboard/scoring/coverage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAW,MAAM,YAAY,CAAC;AA8O9E;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,mBAAmB,GAAG,aAAa,CAoBtE"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage Scorer (weight: 0.10)
|
|
3
|
+
*
|
|
4
|
+
* Checks completeness of the design system.
|
|
5
|
+
* Evaluates token type coverage, core component presence,
|
|
6
|
+
* variable count health, and collection completeness.
|
|
7
|
+
*/
|
|
8
|
+
import { clamp, getSeverity } from "./types.js";
|
|
9
|
+
/** All variable types that a complete token system should include. */
|
|
10
|
+
const ALL_VARIABLE_TYPES = ["COLOR", "FLOAT", "STRING", "BOOLEAN"];
|
|
11
|
+
/** Core component categories that a mature design system should have. */
|
|
12
|
+
const CORE_COMPONENT_PATTERNS = [
|
|
13
|
+
{ name: "button", pattern: /button/i },
|
|
14
|
+
{ name: "input", pattern: /input|text\s*field/i },
|
|
15
|
+
{ name: "card", pattern: /card/i },
|
|
16
|
+
{ name: "modal/dialog", pattern: /modal|dialog/i },
|
|
17
|
+
{ name: "navigation", pattern: /nav|navigation|menu|sidebar/i },
|
|
18
|
+
{ name: "alert/toast", pattern: /alert|toast|notification|snackbar/i },
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* Score token type coverage.
|
|
22
|
+
* A complete system should include COLOR, FLOAT, STRING, and BOOLEAN variables.
|
|
23
|
+
*/
|
|
24
|
+
function variableDataUnavailable(data) {
|
|
25
|
+
return (data.dataAvailability !== undefined && !data.dataAvailability.variables);
|
|
26
|
+
}
|
|
27
|
+
function variableUnavailableMessage(data) {
|
|
28
|
+
const reason = data.dataAvailability?.variableError ||
|
|
29
|
+
"Figma Enterprise plan or Desktop Bridge plugin required";
|
|
30
|
+
return `Variable data unavailable: ${reason}`;
|
|
31
|
+
}
|
|
32
|
+
function scoreTokenTypeCoverage(data) {
|
|
33
|
+
if (data.variables.length === 0) {
|
|
34
|
+
return {
|
|
35
|
+
id: "coverage-token-types",
|
|
36
|
+
label: "Token type coverage",
|
|
37
|
+
score: 0,
|
|
38
|
+
severity: variableDataUnavailable(data) ? "info" : "fail",
|
|
39
|
+
tooltip: "A complete design system should include all variable types: COLOR, FLOAT, STRING, and BOOLEAN. Missing types indicate gaps.",
|
|
40
|
+
details: variableDataUnavailable(data)
|
|
41
|
+
? variableUnavailableMessage(data)
|
|
42
|
+
: "No variables found in the design system.",
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const presentTypes = new Set(data.variables.map((v) => v.resolvedType));
|
|
46
|
+
const foundTypes = ALL_VARIABLE_TYPES.filter((t) => presentTypes.has(t));
|
|
47
|
+
let score;
|
|
48
|
+
switch (foundTypes.length) {
|
|
49
|
+
case 4:
|
|
50
|
+
score = 100;
|
|
51
|
+
break;
|
|
52
|
+
case 3:
|
|
53
|
+
score = 75;
|
|
54
|
+
break;
|
|
55
|
+
case 2:
|
|
56
|
+
score = 50;
|
|
57
|
+
break;
|
|
58
|
+
case 1:
|
|
59
|
+
score = 25;
|
|
60
|
+
break;
|
|
61
|
+
default:
|
|
62
|
+
score = 0;
|
|
63
|
+
}
|
|
64
|
+
const missingTypes = ALL_VARIABLE_TYPES.filter((t) => !presentTypes.has(t));
|
|
65
|
+
return {
|
|
66
|
+
id: "coverage-token-types",
|
|
67
|
+
label: "Token type coverage",
|
|
68
|
+
score: clamp(score),
|
|
69
|
+
severity: getSeverity(score),
|
|
70
|
+
tooltip: "A complete design system should include all variable types: COLOR, FLOAT, STRING, and BOOLEAN. Missing types indicate gaps.",
|
|
71
|
+
details: missingTypes.length > 0
|
|
72
|
+
? `${foundTypes.length} of ${ALL_VARIABLE_TYPES.length} variable types present. Missing: ${missingTypes.join(", ")}.`
|
|
73
|
+
: "All variable types (COLOR, FLOAT, STRING, BOOLEAN) are present.",
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Score core component presence.
|
|
78
|
+
* A mature design system should include button, input, card, modal, nav, and alert components.
|
|
79
|
+
*/
|
|
80
|
+
function scoreCoreComponentPresence(data) {
|
|
81
|
+
if (data.components.length === 0) {
|
|
82
|
+
return {
|
|
83
|
+
id: "coverage-core-components",
|
|
84
|
+
label: "Core component presence",
|
|
85
|
+
score: 0,
|
|
86
|
+
severity: "fail",
|
|
87
|
+
tooltip: "A mature design system should include core UI patterns: button, input, card, modal/dialog, navigation, and alert/toast.",
|
|
88
|
+
details: "No components found in the design system.",
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const foundCategories = [];
|
|
92
|
+
const missingCategories = [];
|
|
93
|
+
const matchExamples = [];
|
|
94
|
+
for (const category of CORE_COMPONENT_PATTERNS) {
|
|
95
|
+
const matching = data.components.filter((c) => category.pattern.test(c.name));
|
|
96
|
+
if (matching.length > 0) {
|
|
97
|
+
foundCategories.push(category.name);
|
|
98
|
+
matchExamples.push(`${category.name}: ${matching
|
|
99
|
+
.slice(0, 2)
|
|
100
|
+
.map((c) => c.name)
|
|
101
|
+
.join(", ")}`);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
missingCategories.push(category.name);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const ratio = foundCategories.length / CORE_COMPONENT_PATTERNS.length;
|
|
108
|
+
const score = clamp(ratio * 100);
|
|
109
|
+
return {
|
|
110
|
+
id: "coverage-core-components",
|
|
111
|
+
label: "Core component presence",
|
|
112
|
+
score,
|
|
113
|
+
severity: getSeverity(score),
|
|
114
|
+
tooltip: "A mature design system should include core UI patterns: button, input, card, modal/dialog, navigation, and alert/toast.",
|
|
115
|
+
details: missingCategories.length > 0
|
|
116
|
+
? `${foundCategories.length} of ${CORE_COMPONENT_PATTERNS.length} core component categories found. Missing: ${missingCategories.join(", ")}.`
|
|
117
|
+
: "All core component categories are represented.",
|
|
118
|
+
examples: matchExamples.length > 0 ? matchExamples : undefined,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Score variable count health.
|
|
123
|
+
* A healthy design system should have a meaningful number of tokens.
|
|
124
|
+
*/
|
|
125
|
+
function scoreVariableCountHealth(data) {
|
|
126
|
+
const count = data.variables.length;
|
|
127
|
+
let score;
|
|
128
|
+
let details;
|
|
129
|
+
if (count === 0 && variableDataUnavailable(data)) {
|
|
130
|
+
return {
|
|
131
|
+
id: "coverage-variable-count",
|
|
132
|
+
label: "Variable count health",
|
|
133
|
+
score: 0,
|
|
134
|
+
severity: "info",
|
|
135
|
+
tooltip: "A healthy token system typically has 50+ variables. Fewer tokens may indicate the system relies on hard-coded values.",
|
|
136
|
+
details: variableUnavailableMessage(data),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
if (count === 0) {
|
|
140
|
+
score = 0;
|
|
141
|
+
details =
|
|
142
|
+
"No variables found. A design system needs tokens for colors, spacing, and typography.";
|
|
143
|
+
}
|
|
144
|
+
else if (count <= 10) {
|
|
145
|
+
score = 50;
|
|
146
|
+
details = `${count} variables found. Consider expanding the token set for better coverage.`;
|
|
147
|
+
}
|
|
148
|
+
else if (count <= 50) {
|
|
149
|
+
score = 75;
|
|
150
|
+
details = `${count} variables found. Good foundation; consider adding more semantic layers.`;
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
score = 100;
|
|
154
|
+
details = `${count} variables found. Healthy token coverage.`;
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
id: "coverage-variable-count",
|
|
158
|
+
label: "Variable count health",
|
|
159
|
+
score: clamp(score),
|
|
160
|
+
severity: getSeverity(score),
|
|
161
|
+
tooltip: "A healthy token system typically has 50+ variables. Fewer tokens may indicate the system relies on hard-coded values.",
|
|
162
|
+
details,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Score collection completeness.
|
|
167
|
+
* Collections should cover different design concerns (color, spacing, typography, etc.).
|
|
168
|
+
*/
|
|
169
|
+
function scoreCollectionCompleteness(data) {
|
|
170
|
+
const count = data.collections.length;
|
|
171
|
+
let score;
|
|
172
|
+
let details;
|
|
173
|
+
if (count === 0 && variableDataUnavailable(data)) {
|
|
174
|
+
return {
|
|
175
|
+
id: "coverage-collection-completeness",
|
|
176
|
+
label: "Collection completeness",
|
|
177
|
+
score: 0,
|
|
178
|
+
severity: "info",
|
|
179
|
+
tooltip: "Multiple collections (3+) indicate good separation of concerns. Tokens should be organized by domain: colors, spacing, typography, etc.",
|
|
180
|
+
details: variableUnavailableMessage(data),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
if (count === 0) {
|
|
184
|
+
score = 0;
|
|
185
|
+
details =
|
|
186
|
+
"No variable collections found. Organize tokens into logical collections.";
|
|
187
|
+
}
|
|
188
|
+
else if (count === 1) {
|
|
189
|
+
score = 50;
|
|
190
|
+
details =
|
|
191
|
+
"1 collection found. Consider splitting tokens into multiple collections by concern (color, spacing, typography).";
|
|
192
|
+
}
|
|
193
|
+
else if (count === 2) {
|
|
194
|
+
score = 75;
|
|
195
|
+
details = `${count} collections found. Good separation of concerns.`;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
score = 100;
|
|
199
|
+
details = `${count} collections found. Well-organized token architecture.`;
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
id: "coverage-collection-completeness",
|
|
203
|
+
label: "Collection completeness",
|
|
204
|
+
score: clamp(score),
|
|
205
|
+
severity: getSeverity(score),
|
|
206
|
+
tooltip: "Multiple collections (3+) indicate good separation of concerns. Tokens should be organized by domain: colors, spacing, typography, etc.",
|
|
207
|
+
details,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Coverage category scorer.
|
|
212
|
+
* Returns the average score across all coverage checks.
|
|
213
|
+
*/
|
|
214
|
+
export function scoreCoverage(data) {
|
|
215
|
+
const findings = [
|
|
216
|
+
scoreTokenTypeCoverage(data),
|
|
217
|
+
scoreCoreComponentPresence(data),
|
|
218
|
+
scoreVariableCountHealth(data),
|
|
219
|
+
scoreCollectionCompleteness(data),
|
|
220
|
+
];
|
|
221
|
+
const score = clamp(findings.reduce((sum, f) => sum + f.score, 0) / findings.length);
|
|
222
|
+
return {
|
|
223
|
+
id: "coverage",
|
|
224
|
+
label: "Coverage",
|
|
225
|
+
shortLabel: "Coverage",
|
|
226
|
+
score,
|
|
227
|
+
weight: 0.1,
|
|
228
|
+
findings,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=coverage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../../../src/apps/design-system-dashboard/scoring/coverage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design System Health Dashboard — Scoring Engine
|
|
3
|
+
*
|
|
4
|
+
* Main orchestrator that runs all 6 category scorers against raw Figma data
|
|
5
|
+
* and produces a Lighthouse-style health score.
|
|
6
|
+
*
|
|
7
|
+
* Data flow:
|
|
8
|
+
* DesignSystemRawData → scoreDesignSystem() → DashboardData (JSON)
|
|
9
|
+
*/
|
|
10
|
+
import type { DashboardData, DesignSystemRawData } from "./types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Score a design system's health from raw Figma data.
|
|
13
|
+
*
|
|
14
|
+
* Runs all 6 category scorers and produces a weighted overall score.
|
|
15
|
+
* Category weights sum to 1.0:
|
|
16
|
+
* - Naming & Semantics: 0.20
|
|
17
|
+
* - Token Architecture: 0.20
|
|
18
|
+
* - Component Metadata: 0.20
|
|
19
|
+
* - Accessibility: 0.15
|
|
20
|
+
* - Consistency: 0.15
|
|
21
|
+
* - Coverage: 0.10
|
|
22
|
+
*
|
|
23
|
+
* @param data - Raw Figma data (variables, collections, components, styles)
|
|
24
|
+
* @returns Complete dashboard payload with overall score, categories, and summary
|
|
25
|
+
*/
|
|
26
|
+
export declare function scoreDesignSystem(data: DesignSystemRawData): DashboardData;
|
|
27
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../../src/apps/design-system-dashboard/scoring/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH,OAAO,KAAK,EAEX,aAAa,EACb,mBAAmB,EAEnB,MAAM,YAAY,CAAC;AAuCpB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,GAAG,aAAa,CAoC1E"}
|