@polymorphism-tech/morph-spec 2.2.0 → 2.4.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/CLAUDE.md +314 -1673
- package/LICENSE +72 -72
- package/README.md +515 -516
- package/bin/detect-agents.js +225 -225
- package/bin/morph-spec.js +358 -173
- package/bin/render-template.js +302 -302
- package/bin/semantic-detect-agents.js +246 -246
- package/bin/task-manager.js +429 -0
- package/bin/validate-agents-skills.js +251 -251
- package/bin/validate-agents.js +69 -69
- package/bin/validate-phase.js +263 -263
- package/bin/validate.js +369 -0
- package/content/.azure/README.md +293 -293
- package/content/.azure/docs/azure-devops-setup.md +454 -454
- package/content/.azure/docs/branch-strategy.md +398 -398
- package/content/.azure/docs/local-development.md +515 -515
- package/content/.azure/pipelines/pipeline-variables.yml +34 -34
- package/content/.azure/pipelines/prod-pipeline.yml +319 -319
- package/content/.azure/pipelines/staging-pipeline.yml +234 -234
- package/content/.azure/pipelines/templates/build-dotnet.yml +75 -75
- package/content/.azure/pipelines/templates/deploy-app-service.yml +94 -94
- package/content/.azure/pipelines/templates/deploy-container-app.yml +120 -120
- package/content/.azure/pipelines/templates/infra-deploy.yml +90 -90
- package/content/.claude/commands/morph-apply.md +221 -158
- package/content/.claude/commands/morph-archive.md +79 -79
- package/content/.claude/commands/morph-infra.md +209 -209
- package/content/.claude/commands/morph-preflight.md +227 -0
- package/content/.claude/commands/morph-proposal.md +122 -101
- package/content/.claude/commands/morph-status.md +86 -86
- package/content/.claude/commands/morph-troubleshoot.md +122 -0
- package/content/.claude/settings.local.json +15 -15
- package/content/.claude/skills/checklists/code-review.md +226 -0
- package/content/.claude/skills/checklists/morph-checklist.md +117 -0
- package/content/.claude/skills/checklists/simulation-checklist.md +77 -0
- package/content/.claude/skills/infra/bicep-architect.md +126 -419
- package/content/.claude/skills/infra/container-specialist.md +131 -437
- package/content/.claude/skills/infra/devops-engineer.md +119 -405
- package/content/.claude/skills/integrations/asaas-financial.md +130 -333
- package/content/.claude/skills/integrations/azure-identity.md +142 -309
- package/content/.claude/skills/integrations/clerk-auth.md +108 -290
- package/content/.claude/skills/integrations/resend-email.md +119 -0
- package/content/.claude/skills/specialists/ai-system-architect.md +192 -604
- package/content/.claude/skills/specialists/azure-architect.md +142 -142
- package/content/.claude/skills/specialists/code-analyzer.md +235 -0
- package/content/.claude/skills/specialists/dotnet-senior.md +287 -0
- package/content/.claude/skills/specialists/ef-modeler.md +113 -200
- package/content/.claude/skills/specialists/hangfire-orchestrator.md +126 -245
- package/content/.claude/skills/specialists/ms-agent-expert.md +109 -263
- package/content/.claude/skills/specialists/po-pm-advisor.md +197 -197
- package/content/.claude/skills/specialists/standards-architect.md +156 -78
- package/content/.claude/skills/specialists/testing-specialist.md +126 -0
- package/content/.claude/skills/specialists/ui-ux-designer.md +191 -1060
- package/content/.claude/skills/stacks/dotnet-blazor.md +210 -588
- package/content/.claude/skills/stacks/dotnet-nextjs.md +154 -402
- package/content/.claude/skills/workflows/morph-replicate.md +213 -0
- package/content/.claude/{commands/morph-clarify.md → skills/workflows/phase-clarify.md} +5 -58
- package/content/.claude/{commands/morph-design.md → skills/workflows/phase-design.md} +16 -86
- package/content/.claude/{commands/morph-setup.md → skills/workflows/phase-setup.md} +9 -17
- package/content/.claude/skills/workflows/phase-tasks.md +164 -0
- package/content/.claude/{commands/morph-uiux.md → skills/workflows/phase-uiux.md} +15 -88
- package/content/.morph/.morphversion +5 -5
- package/content/.morph/archive/.gitkeep +25 -25
- package/content/.morph/config/agents.json +378 -242
- package/content/.morph/config/config.template.json +89 -108
- package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
- package/content/.morph/docs/workflows/design-impl.md +37 -0
- package/content/.morph/docs/workflows/fast-track.md +29 -0
- package/content/.morph/docs/workflows/full-morph.md +76 -0
- package/content/.morph/docs/workflows/standard.md +44 -0
- package/content/.morph/docs/workflows/ui-refresh.md +39 -0
- package/content/.morph/examples/api-nextjs/README.md +241 -241
- package/content/.morph/examples/api-nextjs/contracts.ts +307 -307
- package/content/.morph/examples/api-nextjs/spec.md +399 -399
- package/content/.morph/examples/api-nextjs/tasks.md +168 -168
- package/content/.morph/examples/micro-saas/README.md +125 -125
- package/content/.morph/examples/micro-saas/contracts.cs +358 -358
- package/content/.morph/examples/micro-saas/decisions.md +246 -246
- package/content/.morph/examples/micro-saas/spec.md +236 -236
- package/content/.morph/examples/micro-saas/tasks.md +150 -150
- package/content/.morph/examples/multi-agent/README.md +309 -309
- package/content/.morph/examples/multi-agent/contracts.cs +433 -433
- package/content/.morph/examples/multi-agent/spec.md +479 -479
- package/content/.morph/examples/multi-agent/tasks.md +185 -185
- package/content/.morph/examples/scheduled-reports/decisions.md +158 -0
- package/content/.morph/examples/scheduled-reports/proposal.md +95 -0
- package/content/.morph/examples/scheduled-reports/spec.md +267 -0
- package/content/.morph/examples/state-v3.json +188 -0
- package/content/.morph/features/.gitkeep +25 -25
- package/content/.morph/hooks/README.md +190 -239
- package/content/.morph/hooks/pre-commit-agents.sh +24 -24
- package/content/.morph/hooks/pre-commit-all.sh +48 -48
- package/content/.morph/hooks/pre-commit-specs.sh +49 -49
- package/content/.morph/hooks/pre-commit-tests.sh +60 -60
- package/content/.morph/project.md +160 -160
- package/content/.morph/schemas/agent.schema.json +296 -296
- package/content/.morph/schemas/tasks.schema.json +220 -0
- package/content/.morph/specs/.gitkeep +20 -20
- package/content/.morph/standards/agent-framework-blazor-ui.md +359 -0
- package/content/.morph/standards/agent-framework-production.md +410 -0
- package/content/.morph/standards/agent-framework-setup.md +413 -453
- package/content/.morph/standards/agent-framework-workflows.md +349 -0
- package/content/.morph/standards/architecture.md +325 -325
- package/content/.morph/standards/azure.md +605 -379
- package/content/.morph/standards/coding.md +377 -377
- package/content/.morph/standards/dotnet10-migration.md +520 -494
- package/content/.morph/standards/fluent-ui-setup.md +590 -590
- package/content/.morph/standards/migration-guide.md +514 -514
- package/content/.morph/standards/passkeys-auth.md +423 -423
- package/content/.morph/standards/vector-search-rag.md +536 -536
- package/content/.morph/state.json +17 -17
- package/content/.morph/templates/FluentDesignTheme.cs +149 -149
- package/content/.morph/templates/MudTheme.cs +281 -281
- package/content/.morph/templates/agent.cs +163 -172
- package/content/.morph/templates/clarify-questions.md +159 -0
- package/content/.morph/templates/component.razor +239 -239
- package/content/.morph/templates/contracts/Commands.cs +74 -0
- package/content/.morph/templates/contracts/Entities.cs +25 -0
- package/content/.morph/templates/contracts/Queries.cs +74 -0
- package/content/.morph/templates/contracts/README.md +74 -0
- package/content/.morph/templates/contracts.cs +217 -217
- package/content/.morph/templates/decisions.md +123 -106
- package/content/.morph/templates/design-system.css +226 -226
- package/content/.morph/templates/infra/.dockerignore.example +89 -89
- package/content/.morph/templates/infra/Dockerfile.example +82 -82
- package/content/.morph/templates/infra/README.md +286 -286
- package/content/.morph/templates/infra/app-insights.bicep +63 -63
- package/content/.morph/templates/infra/app-service.bicep +164 -164
- package/content/.morph/templates/infra/container-app-env.bicep +49 -49
- package/content/.morph/templates/infra/container-app.bicep +156 -156
- package/content/.morph/templates/infra/deploy-checklist.md +426 -0
- package/content/.morph/templates/infra/deploy.ps1 +229 -229
- package/content/.morph/templates/infra/deploy.sh +208 -208
- package/content/.morph/templates/infra/key-vault.bicep +91 -91
- package/content/.morph/templates/infra/main.bicep +189 -189
- package/content/.morph/templates/infra/parameters.dev.json +29 -29
- package/content/.morph/templates/infra/parameters.prod.json +29 -29
- package/content/.morph/templates/infra/parameters.staging.json +29 -29
- package/content/.morph/templates/infra/sql-database.bicep +103 -103
- package/content/.morph/templates/infra/storage.bicep +106 -106
- package/content/.morph/templates/integrations/asaas-client.cs +387 -387
- package/content/.morph/templates/integrations/asaas-webhook.cs +351 -351
- package/content/.morph/templates/integrations/azure-identity-config.cs +288 -288
- package/content/.morph/templates/integrations/clerk-config.cs +258 -258
- package/content/.morph/templates/job.cs +171 -171
- package/content/.morph/templates/migration.cs +83 -83
- package/content/.morph/templates/proposal.md +141 -155
- package/content/.morph/templates/recap.md +94 -105
- package/content/.morph/templates/repository.cs +141 -141
- package/content/.morph/templates/saas/subscription.cs +347 -347
- package/content/.morph/templates/saas/tenant.cs +338 -338
- package/content/.morph/templates/service.cs +139 -139
- package/content/.morph/templates/simulation.md +353 -0
- package/content/.morph/templates/spec.md +149 -148
- package/content/.morph/templates/sprint-status.yaml +68 -68
- package/content/.morph/templates/state.template.json +222 -222
- package/content/.morph/templates/story.md +143 -143
- package/content/.morph/templates/tasks.md +257 -235
- package/content/.morph/templates/test.cs +239 -239
- package/content/.morph/templates/ui-components.md +362 -276
- package/content/.morph/templates/ui-design-system.md +286 -286
- package/content/.morph/templates/ui-flows.md +336 -336
- package/content/.morph/templates/ui-mockups.md +133 -133
- package/content/.morph/test-infra/example.bicep +59 -59
- package/content/CLAUDE.md +150 -442
- package/content/README.md +79 -79
- package/detectors/config-detector.js +223 -223
- package/detectors/conversation-analyzer.js +163 -163
- package/detectors/index.js +84 -84
- package/detectors/standards-generator.js +275 -275
- package/detectors/structure-detector.js +245 -250
- package/docs/README.md +144 -149
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +977 -977
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1048 -1048
- package/docs/api/scripts/collapse.js +38 -38
- package/docs/api/scripts/commonNav.js +28 -28
- package/docs/api/scripts/linenumber.js +25 -25
- package/docs/api/scripts/nav.js +12 -12
- package/docs/api/scripts/polyfill.js +3 -3
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -202
- package/docs/api/scripts/prettify/lang-css.js +2 -2
- package/docs/api/scripts/prettify/prettify.js +28 -28
- package/docs/api/scripts/search.js +98 -98
- package/docs/api/styles/jsdoc.css +776 -776
- package/docs/api/styles/prettify.css +80 -80
- package/docs/examples.md +328 -328
- package/docs/getting-started.md +301 -302
- package/docs/installation.md +361 -361
- package/docs/templates.md +418 -418
- package/docs/validation-checklist.md +265 -266
- package/package.json +80 -80
- package/scripts/postinstall.js +132 -132
- package/src/commands/advance-phase.js +183 -0
- package/src/commands/analyze-blazor-concurrency.js +193 -0
- package/src/commands/create-story.js +351 -351
- package/src/commands/detect-agents.js +139 -0
- package/src/commands/detect.js +104 -104
- package/src/commands/doctor.js +356 -280
- package/src/commands/generate.js +149 -149
- package/src/commands/init.js +258 -245
- package/src/commands/lint-fluent.js +352 -0
- package/src/commands/rollback-phase.js +185 -0
- package/src/commands/session-summary.js +291 -0
- package/src/commands/shard-spec.js +224 -224
- package/src/commands/sprint-status.js +250 -250
- package/src/commands/state.js +333 -333
- package/src/commands/sync.js +167 -167
- package/src/commands/task.js +78 -0
- package/src/commands/troubleshoot.js +222 -0
- package/src/commands/update.js +192 -159
- package/src/commands/validate-blazor-state.js +210 -0
- package/src/commands/validate-blazor.js +156 -0
- package/src/commands/validate-css.js +84 -0
- package/src/commands/validate-phase.js +221 -0
- package/src/lib/blazor-concurrency-analyzer.js +288 -0
- package/src/lib/blazor-state-validator.js +291 -0
- package/src/lib/blazor-validator.js +374 -0
- package/src/lib/complexity-analyzer.js +441 -292
- package/src/lib/continuous-validator.js +421 -0
- package/src/lib/css-validator.js +352 -0
- package/src/lib/decision-constraint-loader.js +109 -0
- package/src/lib/design-system-generator.js +298 -298
- package/src/lib/learning-system.js +520 -0
- package/src/lib/mockup-generator.js +366 -0
- package/src/lib/recap-generator.js +205 -0
- package/src/lib/state-manager.js +397 -340
- package/src/lib/troubleshoot-grep.js +194 -0
- package/src/lib/troubleshoot-index.js +144 -0
- package/src/lib/ui-detector.js +350 -0
- package/src/lib/validation-runner.js +231 -0
- package/src/lib/validators/architecture-validator.js +387 -0
- package/src/lib/validators/contract-compliance-validator.js +273 -0
- package/src/lib/validators/package-validator.js +360 -0
- package/src/lib/validators/ui-contrast-validator.js +422 -0
- package/src/utils/file-copier.js +179 -139
- package/src/utils/logger.js +32 -32
- package/src/utils/version-checker.js +175 -175
- package/content/.claude/commands/morph-costs.md +0 -206
- package/content/.claude/commands/morph-tasks.md +0 -319
- package/content/.claude/skills/specialists/cost-guardian.md +0 -110
- package/content/.claude/skills/stacks/shopify.md +0 -445
- package/content/.morph/config/azure-pricing.json +0 -70
- package/content/.morph/config/azure-pricing.schema.json +0 -50
- package/content/.morph/hooks/pre-commit-costs.sh +0 -91
- package/docs/api/cost-calculator.js.html +0 -513
- package/docs/api/design-system-generator.js.html +0 -382
- package/docs/api/global.html +0 -5263
- package/docs/api/index.html +0 -96
- package/docs/api/state-manager.js.html +0 -423
- package/src/commands/cost.js +0 -181
- package/src/commands/update-pricing.js +0 -206
- package/src/lib/cost-calculator.js +0 -429
|
@@ -1,298 +1,298 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MORPH-SPEC Design System Generator Library
|
|
3
|
-
*
|
|
4
|
-
* Reads ui-design-system.md and generates:
|
|
5
|
-
* - wwwroot/css/design-system.css (CSS variables)
|
|
6
|
-
* - Themes/FluentDesignTheme.cs (Fluent UI theme)
|
|
7
|
-
* - Themes/MudTheme.cs (MudBlazor theme)
|
|
8
|
-
*
|
|
9
|
-
* Used both by CLI commands and internal automation.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { readFileSync, existsSync } from 'fs';
|
|
13
|
-
|
|
14
|
-
// ============================================================================
|
|
15
|
-
// Parsing Functions
|
|
16
|
-
// ============================================================================
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Parse colors from markdown
|
|
20
|
-
* @param {string} markdown - Markdown content
|
|
21
|
-
* @returns {Object} Colors object with primary, secondary, neutral, semantic
|
|
22
|
-
*/
|
|
23
|
-
export function parseColors(markdown) {
|
|
24
|
-
const colors = { primary: {}, secondary: {}, neutral: {}, semantic: {} };
|
|
25
|
-
|
|
26
|
-
// Match color definitions like: - **Primary 500** (`#...`) - ...
|
|
27
|
-
const colorRegex = /(?:^|\n)[-*]\s+\*\*([^*]+)\*\*[^\(]*\(`(#[0-9A-Fa-f]{6})`\)/gm;
|
|
28
|
-
|
|
29
|
-
let match;
|
|
30
|
-
while ((match = colorRegex.exec(markdown)) !== null) {
|
|
31
|
-
const [, name, hex] = match;
|
|
32
|
-
const cleanName = name.trim().toLowerCase().replace(/\s+/g, '-');
|
|
33
|
-
|
|
34
|
-
if (name.includes('Primary')) {
|
|
35
|
-
const variant = name.match(/\d+/)?.[0] || 'default';
|
|
36
|
-
colors.primary[variant] = hex;
|
|
37
|
-
} else if (name.includes('Secondary')) {
|
|
38
|
-
const variant = name.match(/\d+/)?.[0] || 'default';
|
|
39
|
-
colors.secondary[variant] = hex;
|
|
40
|
-
} else if (name.includes('Neutral') || name.includes('Gray')) {
|
|
41
|
-
const variant = name.match(/\d+/)?.[0] || 'default';
|
|
42
|
-
colors.neutral[variant] = hex;
|
|
43
|
-
} else if (name.includes('Success') || name.includes('Error') || name.includes('Warning') || name.includes('Info')) {
|
|
44
|
-
const type = name.toLowerCase().replace(/\s+/g, '-');
|
|
45
|
-
colors.semantic[type] = hex;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return colors;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Parse typography from markdown
|
|
54
|
-
* @param {string} markdown - Markdown content
|
|
55
|
-
* @returns {Object} Typography object with fontFamily, fontSize, fontWeight, lineHeight
|
|
56
|
-
*/
|
|
57
|
-
export function parseTypography(markdown) {
|
|
58
|
-
const typography = { fontFamily: {}, fontSize: {}, fontWeight: {}, lineHeight: {} };
|
|
59
|
-
|
|
60
|
-
// Match font family
|
|
61
|
-
const fontFamilyRegex = /(?:font[- ]?family|typeface)[:\s]+([^\n]+)/gi;
|
|
62
|
-
const fontMatch = fontFamilyRegex.exec(markdown);
|
|
63
|
-
if (fontMatch) {
|
|
64
|
-
typography.fontFamily.primary = fontMatch[1].trim();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Match font sizes (but exclude spacing-related)
|
|
68
|
-
const fontSizeRegex = /(?:^|\n)[-*]\s+\*\*([^*]+)\*\*[^:]*:\s*(\d+(?:\.\d+)?(?:rem|px|em))/gm;
|
|
69
|
-
let match;
|
|
70
|
-
while ((match = fontSizeRegex.exec(markdown)) !== null) {
|
|
71
|
-
const [, name, size] = match;
|
|
72
|
-
const lowerName = name.toLowerCase();
|
|
73
|
-
// Skip if it's spacing-related
|
|
74
|
-
if (lowerName.includes('spacing') || lowerName.includes('gap') || lowerName.includes('margin') || lowerName.includes('padding')) {
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
const cleanName = name.trim().toLowerCase().replace(/\s+/g, '-');
|
|
78
|
-
typography.fontSize[cleanName] = size;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return typography;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Parse spacing from markdown
|
|
86
|
-
* @param {string} markdown - Markdown content
|
|
87
|
-
* @returns {Object} Spacing object with spacing values
|
|
88
|
-
*/
|
|
89
|
-
export function parseSpacing(markdown) {
|
|
90
|
-
const spacing = {};
|
|
91
|
-
|
|
92
|
-
// Match spacing definitions
|
|
93
|
-
const spacingRegex = /(?:^|\n)[-*]\s+\*\*([^*]+)\*\*[^:]*:\s*(\d+(?:\.\d+)?(?:rem|px|em))/gm;
|
|
94
|
-
let match;
|
|
95
|
-
while ((match = spacingRegex.exec(markdown)) !== null) {
|
|
96
|
-
const [, name, value] = match;
|
|
97
|
-
if (name.toLowerCase().includes('spacing') || name.toLowerCase().includes('gap') || name.toLowerCase().includes('margin') || name.toLowerCase().includes('padding')) {
|
|
98
|
-
const cleanName = name.trim().toLowerCase().replace(/\s+/g, '-');
|
|
99
|
-
spacing[cleanName] = value;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return spacing;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Parse all design system properties from markdown
|
|
108
|
-
* @param {string} markdownPath - Path to ui-design-system.md file
|
|
109
|
-
* @returns {Object} Parsed design system with colors, typography, spacing
|
|
110
|
-
*/
|
|
111
|
-
export function parseDesignSystem(markdownPath) {
|
|
112
|
-
if (!existsSync(markdownPath)) {
|
|
113
|
-
throw new Error(`File not found: ${markdownPath}`);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const markdown = readFileSync(markdownPath, 'utf-8');
|
|
117
|
-
|
|
118
|
-
return {
|
|
119
|
-
colors: parseColors(markdown),
|
|
120
|
-
typography: parseTypography(markdown),
|
|
121
|
-
spacing: parseSpacing(markdown)
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// ============================================================================
|
|
126
|
-
// Generation Functions
|
|
127
|
-
// ============================================================================
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Generate CSS variables file
|
|
131
|
-
* @param {Object} colors - Colors object
|
|
132
|
-
* @param {Object} typography - Typography object
|
|
133
|
-
* @param {Object} spacing - Spacing object
|
|
134
|
-
* @returns {string} CSS content
|
|
135
|
-
*/
|
|
136
|
-
export function generateCSS(colors, typography, spacing) {
|
|
137
|
-
let css = `/* Auto-generated by MORPH-SPEC Design System Generator */\n`;
|
|
138
|
-
css += `/* Do not edit manually - regenerate from ui-design-system.md */\n\n`;
|
|
139
|
-
css += `:root {\n`;
|
|
140
|
-
|
|
141
|
-
// Colors
|
|
142
|
-
if (Object.keys(colors.primary).length > 0) {
|
|
143
|
-
css += ` /* Primary Colors */\n`;
|
|
144
|
-
Object.entries(colors.primary).forEach(([variant, hex]) => {
|
|
145
|
-
css += ` --color-primary-${variant}: ${hex};\n`;
|
|
146
|
-
});
|
|
147
|
-
css += `\n`;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (Object.keys(colors.secondary).length > 0) {
|
|
151
|
-
css += ` /* Secondary Colors */\n`;
|
|
152
|
-
Object.entries(colors.secondary).forEach(([variant, hex]) => {
|
|
153
|
-
css += ` --color-secondary-${variant}: ${hex};\n`;
|
|
154
|
-
});
|
|
155
|
-
css += `\n`;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (Object.keys(colors.neutral).length > 0) {
|
|
159
|
-
css += ` /* Neutral Colors */\n`;
|
|
160
|
-
Object.entries(colors.neutral).forEach(([variant, hex]) => {
|
|
161
|
-
css += ` --color-neutral-${variant}: ${hex};\n`;
|
|
162
|
-
});
|
|
163
|
-
css += `\n`;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (Object.keys(colors.semantic).length > 0) {
|
|
167
|
-
css += ` /* Semantic Colors */\n`;
|
|
168
|
-
Object.entries(colors.semantic).forEach(([type, hex]) => {
|
|
169
|
-
css += ` --color-${type}: ${hex};\n`;
|
|
170
|
-
});
|
|
171
|
-
css += `\n`;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Typography
|
|
175
|
-
if (typography.fontFamily.primary) {
|
|
176
|
-
css += ` /* Typography */\n`;
|
|
177
|
-
css += ` --font-family-primary: ${typography.fontFamily.primary};\n`;
|
|
178
|
-
css += `\n`;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (Object.keys(typography.fontSize).length > 0) {
|
|
182
|
-
css += ` /* Font Sizes */\n`;
|
|
183
|
-
Object.entries(typography.fontSize).forEach(([name, size]) => {
|
|
184
|
-
css += ` --font-size-${name}: ${size};\n`;
|
|
185
|
-
});
|
|
186
|
-
css += `\n`;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Spacing
|
|
190
|
-
if (Object.keys(spacing).length > 0) {
|
|
191
|
-
css += ` /* Spacing */\n`;
|
|
192
|
-
Object.entries(spacing).forEach(([name, value]) => {
|
|
193
|
-
css += ` --${name}: ${value};\n`;
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
css += `}\n`;
|
|
198
|
-
|
|
199
|
-
return css;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Generate Fluent UI theme (C#)
|
|
204
|
-
* @param {Object} colors - Colors object
|
|
205
|
-
* @param {Object} typography - Typography object
|
|
206
|
-
* @param {string} namespace - C# namespace (default: YourProject.Themes)
|
|
207
|
-
* @returns {string} C# code
|
|
208
|
-
*/
|
|
209
|
-
export function generateFluentTheme(colors, typography, namespace = 'YourProject.Themes') {
|
|
210
|
-
const primary500 = colors.primary['500'] || '#0078d4';
|
|
211
|
-
|
|
212
|
-
let csharp = `// Auto-generated by MORPH-SPEC Design System Generator\n`;
|
|
213
|
-
csharp += `// Do not edit manually - regenerate from ui-design-system.md\n\n`;
|
|
214
|
-
csharp += `using Microsoft.FluentUI.AspNetCore.Components;\n\n`;
|
|
215
|
-
csharp += `namespace ${namespace};\n\n`;
|
|
216
|
-
csharp += `public static class FluentDesignTheme\n{\n`;
|
|
217
|
-
csharp += ` public static DesignThemePalette GetPalette()\n`;
|
|
218
|
-
csharp += ` {\n`;
|
|
219
|
-
csharp += ` return new DesignThemePalette\n`;
|
|
220
|
-
csharp += ` {\n`;
|
|
221
|
-
csharp += ` Accent = "${primary500}",\n`;
|
|
222
|
-
csharp += ` // Add more theme properties as needed\n`;
|
|
223
|
-
csharp += ` };\n`;
|
|
224
|
-
csharp += ` }\n`;
|
|
225
|
-
csharp += `}\n`;
|
|
226
|
-
|
|
227
|
-
return csharp;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Generate MudBlazor theme (C#)
|
|
232
|
-
* @param {Object} colors - Colors object
|
|
233
|
-
* @param {Object} typography - Typography object
|
|
234
|
-
* @param {string} namespace - C# namespace (default: YourProject.Themes)
|
|
235
|
-
* @returns {string} C# code
|
|
236
|
-
*/
|
|
237
|
-
export function generateMudTheme(colors, typography, namespace = 'YourProject.Themes') {
|
|
238
|
-
const primary500 = colors.primary['500'] || '#594ae2';
|
|
239
|
-
const secondary500 = colors.secondary['500'] || '#ff4081';
|
|
240
|
-
|
|
241
|
-
let csharp = `// Auto-generated by MORPH-SPEC Design System Generator\n`;
|
|
242
|
-
csharp += `// Do not edit manually - regenerate from ui-design-system.md\n\n`;
|
|
243
|
-
csharp += `using MudBlazor;\n\n`;
|
|
244
|
-
csharp += `namespace ${namespace};\n\n`;
|
|
245
|
-
csharp += `public static class MudDesignTheme\n{\n`;
|
|
246
|
-
csharp += ` public static MudTheme GetTheme()\n`;
|
|
247
|
-
csharp += ` {\n`;
|
|
248
|
-
csharp += ` return new MudTheme\n`;
|
|
249
|
-
csharp += ` {\n`;
|
|
250
|
-
csharp += ` Palette = new PaletteLight\n`;
|
|
251
|
-
csharp += ` {\n`;
|
|
252
|
-
csharp += ` Primary = "${primary500}",\n`;
|
|
253
|
-
csharp += ` Secondary = "${secondary500}",\n`;
|
|
254
|
-
csharp += ` // Add more palette colors as needed\n`;
|
|
255
|
-
csharp += ` }\n`;
|
|
256
|
-
csharp += ` };\n`;
|
|
257
|
-
csharp += ` }\n`;
|
|
258
|
-
csharp += `}\n`;
|
|
259
|
-
|
|
260
|
-
return csharp;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Generate all design system files
|
|
265
|
-
* @param {string} designSystemPath - Path to ui-design-system.md
|
|
266
|
-
* @param {Object} options - Generation options
|
|
267
|
-
* @param {string} options.mode - Generation mode: 'fluent', 'mud', or 'both'
|
|
268
|
-
* @param {string} options.namespace - C# namespace
|
|
269
|
-
* @returns {Object} Generated files content
|
|
270
|
-
*/
|
|
271
|
-
export function generateDesignSystem(designSystemPath, options = {}) {
|
|
272
|
-
const { mode = 'both', namespace = 'YourProject.Themes' } = options;
|
|
273
|
-
|
|
274
|
-
// Parse design system
|
|
275
|
-
const { colors, typography, spacing } = parseDesignSystem(designSystemPath);
|
|
276
|
-
|
|
277
|
-
const generated = {
|
|
278
|
-
css: generateCSS(colors, typography, spacing),
|
|
279
|
-
stats: {
|
|
280
|
-
primaryColors: Object.keys(colors.primary).length,
|
|
281
|
-
neutralColors: Object.keys(colors.neutral).length,
|
|
282
|
-
semanticColors: Object.keys(colors.semantic).length,
|
|
283
|
-
fontSizes: Object.keys(typography.fontSize).length,
|
|
284
|
-
spacingValues: Object.keys(spacing).length
|
|
285
|
-
}
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
// Generate themes based on mode
|
|
289
|
-
if (mode === 'fluent' || mode === 'both') {
|
|
290
|
-
generated.fluentTheme = generateFluentTheme(colors, typography, namespace);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
if (mode === 'mud' || mode === 'both') {
|
|
294
|
-
generated.mudTheme = generateMudTheme(colors, typography, namespace);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
return generated;
|
|
298
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* MORPH-SPEC Design System Generator Library
|
|
3
|
+
*
|
|
4
|
+
* Reads ui-design-system.md and generates:
|
|
5
|
+
* - wwwroot/css/design-system.css (CSS variables)
|
|
6
|
+
* - Themes/FluentDesignTheme.cs (Fluent UI theme)
|
|
7
|
+
* - Themes/MudTheme.cs (MudBlazor theme)
|
|
8
|
+
*
|
|
9
|
+
* Used both by CLI commands and internal automation.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { readFileSync, existsSync } from 'fs';
|
|
13
|
+
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Parsing Functions
|
|
16
|
+
// ============================================================================
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Parse colors from markdown
|
|
20
|
+
* @param {string} markdown - Markdown content
|
|
21
|
+
* @returns {Object} Colors object with primary, secondary, neutral, semantic
|
|
22
|
+
*/
|
|
23
|
+
export function parseColors(markdown) {
|
|
24
|
+
const colors = { primary: {}, secondary: {}, neutral: {}, semantic: {} };
|
|
25
|
+
|
|
26
|
+
// Match color definitions like: - **Primary 500** (`#...`) - ...
|
|
27
|
+
const colorRegex = /(?:^|\n)[-*]\s+\*\*([^*]+)\*\*[^\(]*\(`(#[0-9A-Fa-f]{6})`\)/gm;
|
|
28
|
+
|
|
29
|
+
let match;
|
|
30
|
+
while ((match = colorRegex.exec(markdown)) !== null) {
|
|
31
|
+
const [, name, hex] = match;
|
|
32
|
+
const cleanName = name.trim().toLowerCase().replace(/\s+/g, '-');
|
|
33
|
+
|
|
34
|
+
if (name.includes('Primary')) {
|
|
35
|
+
const variant = name.match(/\d+/)?.[0] || 'default';
|
|
36
|
+
colors.primary[variant] = hex;
|
|
37
|
+
} else if (name.includes('Secondary')) {
|
|
38
|
+
const variant = name.match(/\d+/)?.[0] || 'default';
|
|
39
|
+
colors.secondary[variant] = hex;
|
|
40
|
+
} else if (name.includes('Neutral') || name.includes('Gray')) {
|
|
41
|
+
const variant = name.match(/\d+/)?.[0] || 'default';
|
|
42
|
+
colors.neutral[variant] = hex;
|
|
43
|
+
} else if (name.includes('Success') || name.includes('Error') || name.includes('Warning') || name.includes('Info')) {
|
|
44
|
+
const type = name.toLowerCase().replace(/\s+/g, '-');
|
|
45
|
+
colors.semantic[type] = hex;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return colors;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Parse typography from markdown
|
|
54
|
+
* @param {string} markdown - Markdown content
|
|
55
|
+
* @returns {Object} Typography object with fontFamily, fontSize, fontWeight, lineHeight
|
|
56
|
+
*/
|
|
57
|
+
export function parseTypography(markdown) {
|
|
58
|
+
const typography = { fontFamily: {}, fontSize: {}, fontWeight: {}, lineHeight: {} };
|
|
59
|
+
|
|
60
|
+
// Match font family
|
|
61
|
+
const fontFamilyRegex = /(?:font[- ]?family|typeface)[:\s]+([^\n]+)/gi;
|
|
62
|
+
const fontMatch = fontFamilyRegex.exec(markdown);
|
|
63
|
+
if (fontMatch) {
|
|
64
|
+
typography.fontFamily.primary = fontMatch[1].trim();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Match font sizes (but exclude spacing-related)
|
|
68
|
+
const fontSizeRegex = /(?:^|\n)[-*]\s+\*\*([^*]+)\*\*[^:]*:\s*(\d+(?:\.\d+)?(?:rem|px|em))/gm;
|
|
69
|
+
let match;
|
|
70
|
+
while ((match = fontSizeRegex.exec(markdown)) !== null) {
|
|
71
|
+
const [, name, size] = match;
|
|
72
|
+
const lowerName = name.toLowerCase();
|
|
73
|
+
// Skip if it's spacing-related
|
|
74
|
+
if (lowerName.includes('spacing') || lowerName.includes('gap') || lowerName.includes('margin') || lowerName.includes('padding')) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const cleanName = name.trim().toLowerCase().replace(/\s+/g, '-');
|
|
78
|
+
typography.fontSize[cleanName] = size;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return typography;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Parse spacing from markdown
|
|
86
|
+
* @param {string} markdown - Markdown content
|
|
87
|
+
* @returns {Object} Spacing object with spacing values
|
|
88
|
+
*/
|
|
89
|
+
export function parseSpacing(markdown) {
|
|
90
|
+
const spacing = {};
|
|
91
|
+
|
|
92
|
+
// Match spacing definitions
|
|
93
|
+
const spacingRegex = /(?:^|\n)[-*]\s+\*\*([^*]+)\*\*[^:]*:\s*(\d+(?:\.\d+)?(?:rem|px|em))/gm;
|
|
94
|
+
let match;
|
|
95
|
+
while ((match = spacingRegex.exec(markdown)) !== null) {
|
|
96
|
+
const [, name, value] = match;
|
|
97
|
+
if (name.toLowerCase().includes('spacing') || name.toLowerCase().includes('gap') || name.toLowerCase().includes('margin') || name.toLowerCase().includes('padding')) {
|
|
98
|
+
const cleanName = name.trim().toLowerCase().replace(/\s+/g, '-');
|
|
99
|
+
spacing[cleanName] = value;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return spacing;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Parse all design system properties from markdown
|
|
108
|
+
* @param {string} markdownPath - Path to ui-design-system.md file
|
|
109
|
+
* @returns {Object} Parsed design system with colors, typography, spacing
|
|
110
|
+
*/
|
|
111
|
+
export function parseDesignSystem(markdownPath) {
|
|
112
|
+
if (!existsSync(markdownPath)) {
|
|
113
|
+
throw new Error(`File not found: ${markdownPath}`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const markdown = readFileSync(markdownPath, 'utf-8');
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
colors: parseColors(markdown),
|
|
120
|
+
typography: parseTypography(markdown),
|
|
121
|
+
spacing: parseSpacing(markdown)
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ============================================================================
|
|
126
|
+
// Generation Functions
|
|
127
|
+
// ============================================================================
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Generate CSS variables file
|
|
131
|
+
* @param {Object} colors - Colors object
|
|
132
|
+
* @param {Object} typography - Typography object
|
|
133
|
+
* @param {Object} spacing - Spacing object
|
|
134
|
+
* @returns {string} CSS content
|
|
135
|
+
*/
|
|
136
|
+
export function generateCSS(colors, typography, spacing) {
|
|
137
|
+
let css = `/* Auto-generated by MORPH-SPEC Design System Generator */\n`;
|
|
138
|
+
css += `/* Do not edit manually - regenerate from ui-design-system.md */\n\n`;
|
|
139
|
+
css += `:root {\n`;
|
|
140
|
+
|
|
141
|
+
// Colors
|
|
142
|
+
if (Object.keys(colors.primary).length > 0) {
|
|
143
|
+
css += ` /* Primary Colors */\n`;
|
|
144
|
+
Object.entries(colors.primary).forEach(([variant, hex]) => {
|
|
145
|
+
css += ` --color-primary-${variant}: ${hex};\n`;
|
|
146
|
+
});
|
|
147
|
+
css += `\n`;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (Object.keys(colors.secondary).length > 0) {
|
|
151
|
+
css += ` /* Secondary Colors */\n`;
|
|
152
|
+
Object.entries(colors.secondary).forEach(([variant, hex]) => {
|
|
153
|
+
css += ` --color-secondary-${variant}: ${hex};\n`;
|
|
154
|
+
});
|
|
155
|
+
css += `\n`;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (Object.keys(colors.neutral).length > 0) {
|
|
159
|
+
css += ` /* Neutral Colors */\n`;
|
|
160
|
+
Object.entries(colors.neutral).forEach(([variant, hex]) => {
|
|
161
|
+
css += ` --color-neutral-${variant}: ${hex};\n`;
|
|
162
|
+
});
|
|
163
|
+
css += `\n`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (Object.keys(colors.semantic).length > 0) {
|
|
167
|
+
css += ` /* Semantic Colors */\n`;
|
|
168
|
+
Object.entries(colors.semantic).forEach(([type, hex]) => {
|
|
169
|
+
css += ` --color-${type}: ${hex};\n`;
|
|
170
|
+
});
|
|
171
|
+
css += `\n`;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Typography
|
|
175
|
+
if (typography.fontFamily.primary) {
|
|
176
|
+
css += ` /* Typography */\n`;
|
|
177
|
+
css += ` --font-family-primary: ${typography.fontFamily.primary};\n`;
|
|
178
|
+
css += `\n`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (Object.keys(typography.fontSize).length > 0) {
|
|
182
|
+
css += ` /* Font Sizes */\n`;
|
|
183
|
+
Object.entries(typography.fontSize).forEach(([name, size]) => {
|
|
184
|
+
css += ` --font-size-${name}: ${size};\n`;
|
|
185
|
+
});
|
|
186
|
+
css += `\n`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Spacing
|
|
190
|
+
if (Object.keys(spacing).length > 0) {
|
|
191
|
+
css += ` /* Spacing */\n`;
|
|
192
|
+
Object.entries(spacing).forEach(([name, value]) => {
|
|
193
|
+
css += ` --${name}: ${value};\n`;
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
css += `}\n`;
|
|
198
|
+
|
|
199
|
+
return css;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Generate Fluent UI theme (C#)
|
|
204
|
+
* @param {Object} colors - Colors object
|
|
205
|
+
* @param {Object} typography - Typography object
|
|
206
|
+
* @param {string} namespace - C# namespace (default: YourProject.Themes)
|
|
207
|
+
* @returns {string} C# code
|
|
208
|
+
*/
|
|
209
|
+
export function generateFluentTheme(colors, typography, namespace = 'YourProject.Themes') {
|
|
210
|
+
const primary500 = colors.primary['500'] || '#0078d4';
|
|
211
|
+
|
|
212
|
+
let csharp = `// Auto-generated by MORPH-SPEC Design System Generator\n`;
|
|
213
|
+
csharp += `// Do not edit manually - regenerate from ui-design-system.md\n\n`;
|
|
214
|
+
csharp += `using Microsoft.FluentUI.AspNetCore.Components;\n\n`;
|
|
215
|
+
csharp += `namespace ${namespace};\n\n`;
|
|
216
|
+
csharp += `public static class FluentDesignTheme\n{\n`;
|
|
217
|
+
csharp += ` public static DesignThemePalette GetPalette()\n`;
|
|
218
|
+
csharp += ` {\n`;
|
|
219
|
+
csharp += ` return new DesignThemePalette\n`;
|
|
220
|
+
csharp += ` {\n`;
|
|
221
|
+
csharp += ` Accent = "${primary500}",\n`;
|
|
222
|
+
csharp += ` // Add more theme properties as needed\n`;
|
|
223
|
+
csharp += ` };\n`;
|
|
224
|
+
csharp += ` }\n`;
|
|
225
|
+
csharp += `}\n`;
|
|
226
|
+
|
|
227
|
+
return csharp;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Generate MudBlazor theme (C#)
|
|
232
|
+
* @param {Object} colors - Colors object
|
|
233
|
+
* @param {Object} typography - Typography object
|
|
234
|
+
* @param {string} namespace - C# namespace (default: YourProject.Themes)
|
|
235
|
+
* @returns {string} C# code
|
|
236
|
+
*/
|
|
237
|
+
export function generateMudTheme(colors, typography, namespace = 'YourProject.Themes') {
|
|
238
|
+
const primary500 = colors.primary['500'] || '#594ae2';
|
|
239
|
+
const secondary500 = colors.secondary['500'] || '#ff4081';
|
|
240
|
+
|
|
241
|
+
let csharp = `// Auto-generated by MORPH-SPEC Design System Generator\n`;
|
|
242
|
+
csharp += `// Do not edit manually - regenerate from ui-design-system.md\n\n`;
|
|
243
|
+
csharp += `using MudBlazor;\n\n`;
|
|
244
|
+
csharp += `namespace ${namespace};\n\n`;
|
|
245
|
+
csharp += `public static class MudDesignTheme\n{\n`;
|
|
246
|
+
csharp += ` public static MudTheme GetTheme()\n`;
|
|
247
|
+
csharp += ` {\n`;
|
|
248
|
+
csharp += ` return new MudTheme\n`;
|
|
249
|
+
csharp += ` {\n`;
|
|
250
|
+
csharp += ` Palette = new PaletteLight\n`;
|
|
251
|
+
csharp += ` {\n`;
|
|
252
|
+
csharp += ` Primary = "${primary500}",\n`;
|
|
253
|
+
csharp += ` Secondary = "${secondary500}",\n`;
|
|
254
|
+
csharp += ` // Add more palette colors as needed\n`;
|
|
255
|
+
csharp += ` }\n`;
|
|
256
|
+
csharp += ` };\n`;
|
|
257
|
+
csharp += ` }\n`;
|
|
258
|
+
csharp += `}\n`;
|
|
259
|
+
|
|
260
|
+
return csharp;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Generate all design system files
|
|
265
|
+
* @param {string} designSystemPath - Path to ui-design-system.md
|
|
266
|
+
* @param {Object} options - Generation options
|
|
267
|
+
* @param {string} options.mode - Generation mode: 'fluent', 'mud', or 'both'
|
|
268
|
+
* @param {string} options.namespace - C# namespace
|
|
269
|
+
* @returns {Object} Generated files content
|
|
270
|
+
*/
|
|
271
|
+
export function generateDesignSystem(designSystemPath, options = {}) {
|
|
272
|
+
const { mode = 'both', namespace = 'YourProject.Themes' } = options;
|
|
273
|
+
|
|
274
|
+
// Parse design system
|
|
275
|
+
const { colors, typography, spacing } = parseDesignSystem(designSystemPath);
|
|
276
|
+
|
|
277
|
+
const generated = {
|
|
278
|
+
css: generateCSS(colors, typography, spacing),
|
|
279
|
+
stats: {
|
|
280
|
+
primaryColors: Object.keys(colors.primary).length,
|
|
281
|
+
neutralColors: Object.keys(colors.neutral).length,
|
|
282
|
+
semanticColors: Object.keys(colors.semantic).length,
|
|
283
|
+
fontSizes: Object.keys(typography.fontSize).length,
|
|
284
|
+
spacingValues: Object.keys(spacing).length
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
// Generate themes based on mode
|
|
289
|
+
if (mode === 'fluent' || mode === 'both') {
|
|
290
|
+
generated.fluentTheme = generateFluentTheme(colors, typography, namespace);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (mode === 'mud' || mode === 'both') {
|
|
294
|
+
generated.mudTheme = generateMudTheme(colors, typography, namespace);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return generated;
|
|
298
|
+
}
|