@polymorphism-tech/morph-spec 2.4.0 → 3.0.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 +158 -26
- package/LICENSE +72 -72
- package/bin/detect-agents.js +225 -225
- package/bin/morph-spec.js +8 -0
- package/bin/render-template.js +302 -302
- package/bin/semantic-detect-agents.js +246 -246
- package/bin/validate-agents-skills.js +251 -251
- package/bin/validate-agents.js +69 -69
- package/bin/validate-phase.js +263 -263
- 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-archive.md +79 -79
- package/content/.claude/commands/morph-deploy.md +529 -0
- package/content/.claude/commands/morph-infra.md +209 -209
- package/content/.claude/commands/morph-preflight.md +227 -227
- package/content/.claude/commands/morph-troubleshoot.md +122 -122
- package/content/.claude/settings.local.json +15 -15
- package/content/.claude/skills/infra/azure-deploy-specialist.md +699 -0
- package/content/.claude/skills/level-0-meta/README.md +7 -0
- package/content/.claude/skills/{checklists → level-0-meta}/morph-checklist.md +117 -117
- package/content/.claude/skills/level-1-workflows/README.md +7 -0
- package/content/.claude/skills/{workflows → level-1-workflows}/morph-replicate.md +213 -213
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-clarify.md +131 -131
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-design.md +213 -205
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-setup.md +106 -92
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-tasks.md +164 -164
- package/content/.claude/skills/{workflows → level-1-workflows}/phase-uiux.md +169 -138
- package/content/.claude/skills/level-2-domains/README.md +14 -0
- package/content/.claude/skills/{specialists → level-2-domains/quality}/testing-specialist.md +126 -126
- package/content/.claude/skills/level-3-technologies/README.md +7 -0
- package/content/.claude/skills/level-4-patterns/README.md +7 -0
- package/content/.claude/skills/specialists/prompt-engineer.md +189 -0
- package/content/.claude/skills/specialists/seo-growth-hacker.md +320 -0
- package/content/.morph/.morphversion +5 -5
- package/content/.morph/archive/.gitkeep +25 -25
- package/content/.morph/config/agents.json +742 -358
- package/content/.morph/config/config.template.json +33 -0
- package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
- package/content/.morph/docs/workflows/enforcement-pipeline.md +668 -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 -158
- package/content/.morph/examples/scheduled-reports/proposal.md +95 -95
- package/content/.morph/examples/scheduled-reports/spec.md +267 -267
- package/content/.morph/examples/state-v3.json +188 -188
- package/content/.morph/features/.gitkeep +25 -25
- package/content/.morph/hooks/README.md +158 -0
- 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/hooks/task-completed.js +73 -0
- package/content/.morph/hooks/teammate-idle.js +68 -0
- package/content/.morph/project.md +160 -160
- package/content/.morph/schemas/agent.schema.json +296 -296
- package/content/.morph/schemas/tasks.schema.json +220 -220
- package/content/.morph/specs/.gitkeep +20 -20
- package/content/.morph/standards/agent-teams-workflow.md +474 -0
- package/content/.morph/standards/coding.md +377 -377
- 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/CONTEXT-FEATURE.md +276 -0
- package/content/.morph/templates/CONTEXT.md +170 -0
- package/content/.morph/templates/FluentDesignTheme.cs +149 -149
- package/content/.morph/templates/MudTheme.cs +281 -281
- package/content/.morph/templates/clarify-questions.md +159 -159
- package/content/.morph/templates/component.razor +239 -239
- package/content/.morph/templates/contracts/Commands.cs +74 -74
- package/content/.morph/templates/contracts/Entities.cs +25 -25
- package/content/.morph/templates/contracts/Queries.cs +74 -74
- package/content/.morph/templates/contracts/README.md +74 -74
- package/content/.morph/templates/contracts.cs +217 -217
- 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/azure-pipelines-deploy.yml +480 -0
- 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 -426
- 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/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/sprint-status.yaml +68 -68
- package/content/.morph/templates/story.md +143 -143
- package/content/.morph/templates/test.cs +239 -239
- 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/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/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/templates.md +418 -418
- package/package.json +1 -1
- package/scripts/postinstall.js +132 -132
- package/src/commands/advance-phase.js +83 -0
- package/src/commands/analyze-blazor-concurrency.js +193 -193
- package/src/commands/create-story.js +351 -351
- package/src/commands/deploy.js +780 -0
- package/src/commands/detect-agents.js +34 -6
- package/src/commands/detect.js +104 -104
- package/src/commands/generate-context.js +40 -0
- package/src/commands/generate.js +149 -149
- package/src/commands/lint-fluent.js +352 -352
- package/src/commands/rollback-phase.js +185 -185
- package/src/commands/session-summary.js +291 -291
- 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/troubleshoot.js +222 -222
- package/src/commands/validate-blazor-state.js +210 -210
- package/src/commands/validate-blazor.js +156 -156
- package/src/commands/validate-css.js +84 -84
- package/src/commands/validate-phase.js +221 -221
- package/src/lib/blazor-concurrency-analyzer.js +288 -288
- package/src/lib/blazor-state-validator.js +291 -291
- package/src/lib/blazor-validator.js +374 -374
- package/src/lib/context-generator.js +513 -0
- package/src/lib/css-validator.js +352 -352
- package/src/lib/design-system-detector.js +187 -0
- package/src/lib/design-system-generator.js +298 -298
- package/src/lib/design-system-scaffolder.js +299 -0
- package/src/lib/hook-executor.js +256 -0
- package/src/lib/learning-system.js +520 -520
- package/src/lib/mockup-generator.js +366 -366
- package/src/lib/spec-validator.js +258 -0
- package/src/lib/standards-context-injector.js +287 -0
- package/src/lib/team-orchestrator.js +322 -0
- package/src/lib/troubleshoot-grep.js +194 -194
- package/src/lib/troubleshoot-index.js +144 -144
- package/src/lib/ui-detector.js +350 -350
- package/src/lib/validation-runner.js +65 -13
- package/src/lib/validators/architecture-validator.js +387 -387
- package/src/lib/validators/design-system-validator.js +231 -0
- package/src/lib/validators/package-validator.js +360 -360
- package/src/lib/validators/ui-contrast-validator.js +422 -422
- package/src/utils/file-copier.js +9 -1
- package/src/utils/logger.js +32 -32
- package/src/utils/version-checker.js +175 -175
- /package/content/.claude/skills/{checklists → level-0-meta}/code-review.md +0 -0
- /package/content/.claude/skills/{checklists → level-0-meta}/simulation-checklist.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/ai-agents}/ai-system-architect.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/architecture}/po-pm-advisor.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/architecture}/standards-architect.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/backend}/dotnet-senior.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/backend}/ef-modeler.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/backend}/hangfire-orchestrator.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/backend}/ms-agent-expert.md +0 -0
- /package/content/.claude/skills/{stacks/dotnet-blazor.md → level-2-domains/frontend/blazor-builder.md} +0 -0
- /package/content/.claude/skills/{stacks/dotnet-nextjs.md → level-2-domains/frontend/nextjs-expert.md} +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/frontend}/ui-ux-designer.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/infrastructure}/azure-architect.md +0 -0
- /package/content/.claude/skills/{infra → level-2-domains/infrastructure}/bicep-architect.md +0 -0
- /package/content/.claude/skills/{infra → level-2-domains/infrastructure}/container-specialist.md +0 -0
- /package/content/.claude/skills/{infra → level-2-domains/infrastructure}/devops-engineer.md +0 -0
- /package/content/.claude/skills/{integrations → level-2-domains/integrations}/asaas-financial.md +0 -0
- /package/content/.claude/skills/{integrations → level-2-domains/integrations}/azure-identity.md +0 -0
- /package/content/.claude/skills/{integrations → level-2-domains/integrations}/clerk-auth.md +0 -0
- /package/content/.claude/skills/{integrations → level-2-domains/integrations}/resend-email.md +0 -0
- /package/content/.claude/skills/{specialists → level-2-domains/quality}/code-analyzer.md +0 -0
|
@@ -1,156 +1,156 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* validate-blazor command
|
|
3
|
-
*
|
|
4
|
-
* Validates Fluent UI Blazor patterns and icons in Razor files.
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* morph-spec validate-blazor [path]
|
|
8
|
-
* morph-spec validate-blazor src/Components --verbose
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { glob } from 'glob';
|
|
12
|
-
import { readFileSync, existsSync, statSync } from 'fs';
|
|
13
|
-
import { join, resolve } from 'path';
|
|
14
|
-
import chalk from 'chalk';
|
|
15
|
-
import ora from 'ora';
|
|
16
|
-
|
|
17
|
-
import {
|
|
18
|
-
validateBlazorFile,
|
|
19
|
-
formatIssues,
|
|
20
|
-
countIssues,
|
|
21
|
-
} from '../lib/blazor-validator.js';
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Main command handler for validate-blazor.
|
|
25
|
-
*
|
|
26
|
-
* @param {string} [targetPath] - Path to validate (file or directory)
|
|
27
|
-
* @param {Object} options - Command options
|
|
28
|
-
* @param {boolean} [options.verbose] - Show detailed output
|
|
29
|
-
* @param {boolean} [options.fix] - Auto-fix issues where possible
|
|
30
|
-
*/
|
|
31
|
-
export async function validateBlazorCommand(targetPath, options = {}) {
|
|
32
|
-
const { verbose = false } = options;
|
|
33
|
-
|
|
34
|
-
console.log('');
|
|
35
|
-
console.log(
|
|
36
|
-
chalk.cyan('\uD83D\uDD0D Validating Fluent UI Blazor patterns...')
|
|
37
|
-
);
|
|
38
|
-
console.log('');
|
|
39
|
-
|
|
40
|
-
// Determine target path
|
|
41
|
-
const basePath = targetPath ? resolve(targetPath) : process.cwd();
|
|
42
|
-
|
|
43
|
-
if (!existsSync(basePath)) {
|
|
44
|
-
console.log(chalk.red(`\u274C Path not found: ${basePath}`));
|
|
45
|
-
process.exit(1);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const spinner = ora('Scanning for Razor files...').start();
|
|
49
|
-
|
|
50
|
-
let files = [];
|
|
51
|
-
|
|
52
|
-
try {
|
|
53
|
-
const stats = statSync(basePath);
|
|
54
|
-
|
|
55
|
-
if (stats.isFile()) {
|
|
56
|
-
// Single file
|
|
57
|
-
if (
|
|
58
|
-
basePath.endsWith('.razor') ||
|
|
59
|
-
basePath.endsWith('.razor.cs') ||
|
|
60
|
-
basePath.endsWith('.cs')
|
|
61
|
-
) {
|
|
62
|
-
files = [basePath];
|
|
63
|
-
} else {
|
|
64
|
-
spinner.fail('File must be .razor or .cs');
|
|
65
|
-
process.exit(1);
|
|
66
|
-
}
|
|
67
|
-
} else {
|
|
68
|
-
// Directory - find all Razor files
|
|
69
|
-
const pattern = join(basePath, '**/*.{razor,razor.cs}');
|
|
70
|
-
files = await glob(pattern, {
|
|
71
|
-
ignore: ['**/node_modules/**', '**/bin/**', '**/obj/**'],
|
|
72
|
-
windowsPathsNoEscape: true,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
spinner.succeed(`Found ${files.length} Razor file(s)`);
|
|
77
|
-
} catch (error) {
|
|
78
|
-
spinner.fail(`Error scanning files: ${error.message}`);
|
|
79
|
-
process.exit(1);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (files.length === 0) {
|
|
83
|
-
console.log(chalk.yellow('\n\u26A0\uFE0F No Razor files found to validate'));
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Validate each file
|
|
88
|
-
const allIssues = [];
|
|
89
|
-
const fileResults = [];
|
|
90
|
-
|
|
91
|
-
for (const file of files) {
|
|
92
|
-
try {
|
|
93
|
-
const content = readFileSync(file, 'utf-8');
|
|
94
|
-
const issues = validateBlazorFile(content, file);
|
|
95
|
-
|
|
96
|
-
if (issues.length > 0) {
|
|
97
|
-
allIssues.push(...issues);
|
|
98
|
-
fileResults.push({ file, issues });
|
|
99
|
-
}
|
|
100
|
-
} catch (error) {
|
|
101
|
-
console.log(chalk.red(`\u274C Error reading ${file}: ${error.message}`));
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Output results
|
|
106
|
-
console.log('');
|
|
107
|
-
|
|
108
|
-
if (allIssues.length === 0) {
|
|
109
|
-
console.log(
|
|
110
|
-
chalk.green('\u2705 No issues found! All patterns look correct.')
|
|
111
|
-
);
|
|
112
|
-
console.log('');
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Group and display issues
|
|
117
|
-
if (verbose) {
|
|
118
|
-
// Verbose: show all issues with details
|
|
119
|
-
fileResults.forEach(({ file, issues }) => {
|
|
120
|
-
console.log(chalk.white.bold(`\n${file}`));
|
|
121
|
-
console.log(chalk.gray('-'.repeat(60)));
|
|
122
|
-
console.log(formatIssues(issues));
|
|
123
|
-
});
|
|
124
|
-
} else {
|
|
125
|
-
// Compact: just list issues
|
|
126
|
-
allIssues.forEach((issue) => {
|
|
127
|
-
const icon = issue.type === 'error' ? '\u274C' : '\u26A0\uFE0F';
|
|
128
|
-
const location = issue.line ? `${issue.file}:${issue.line}` : issue.file;
|
|
129
|
-
|
|
130
|
-
console.log(`${icon} ${issue.message}`);
|
|
131
|
-
if (issue.suggestion) {
|
|
132
|
-
console.log(chalk.gray(` \u2192 ${issue.suggestion}`));
|
|
133
|
-
}
|
|
134
|
-
console.log(chalk.dim(` ${location}`));
|
|
135
|
-
console.log('');
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Summary
|
|
140
|
-
const { errors, warnings } = countIssues(allIssues);
|
|
141
|
-
const summaryColor = errors > 0 ? chalk.red : chalk.yellow;
|
|
142
|
-
|
|
143
|
-
console.log(chalk.gray('-'.repeat(60)));
|
|
144
|
-
console.log(
|
|
145
|
-
summaryColor(
|
|
146
|
-
`\n${files.length} arquivo(s) validado(s) | ${errors} erro(s) | ${warnings} warning(s)\n`
|
|
147
|
-
)
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
// Exit with error code if there are errors
|
|
151
|
-
if (errors > 0) {
|
|
152
|
-
process.exit(1);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export default validateBlazorCommand;
|
|
1
|
+
/**
|
|
2
|
+
* validate-blazor command
|
|
3
|
+
*
|
|
4
|
+
* Validates Fluent UI Blazor patterns and icons in Razor files.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* morph-spec validate-blazor [path]
|
|
8
|
+
* morph-spec validate-blazor src/Components --verbose
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { glob } from 'glob';
|
|
12
|
+
import { readFileSync, existsSync, statSync } from 'fs';
|
|
13
|
+
import { join, resolve } from 'path';
|
|
14
|
+
import chalk from 'chalk';
|
|
15
|
+
import ora from 'ora';
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
validateBlazorFile,
|
|
19
|
+
formatIssues,
|
|
20
|
+
countIssues,
|
|
21
|
+
} from '../lib/blazor-validator.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Main command handler for validate-blazor.
|
|
25
|
+
*
|
|
26
|
+
* @param {string} [targetPath] - Path to validate (file or directory)
|
|
27
|
+
* @param {Object} options - Command options
|
|
28
|
+
* @param {boolean} [options.verbose] - Show detailed output
|
|
29
|
+
* @param {boolean} [options.fix] - Auto-fix issues where possible
|
|
30
|
+
*/
|
|
31
|
+
export async function validateBlazorCommand(targetPath, options = {}) {
|
|
32
|
+
const { verbose = false } = options;
|
|
33
|
+
|
|
34
|
+
console.log('');
|
|
35
|
+
console.log(
|
|
36
|
+
chalk.cyan('\uD83D\uDD0D Validating Fluent UI Blazor patterns...')
|
|
37
|
+
);
|
|
38
|
+
console.log('');
|
|
39
|
+
|
|
40
|
+
// Determine target path
|
|
41
|
+
const basePath = targetPath ? resolve(targetPath) : process.cwd();
|
|
42
|
+
|
|
43
|
+
if (!existsSync(basePath)) {
|
|
44
|
+
console.log(chalk.red(`\u274C Path not found: ${basePath}`));
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const spinner = ora('Scanning for Razor files...').start();
|
|
49
|
+
|
|
50
|
+
let files = [];
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const stats = statSync(basePath);
|
|
54
|
+
|
|
55
|
+
if (stats.isFile()) {
|
|
56
|
+
// Single file
|
|
57
|
+
if (
|
|
58
|
+
basePath.endsWith('.razor') ||
|
|
59
|
+
basePath.endsWith('.razor.cs') ||
|
|
60
|
+
basePath.endsWith('.cs')
|
|
61
|
+
) {
|
|
62
|
+
files = [basePath];
|
|
63
|
+
} else {
|
|
64
|
+
spinner.fail('File must be .razor or .cs');
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
// Directory - find all Razor files
|
|
69
|
+
const pattern = join(basePath, '**/*.{razor,razor.cs}');
|
|
70
|
+
files = await glob(pattern, {
|
|
71
|
+
ignore: ['**/node_modules/**', '**/bin/**', '**/obj/**'],
|
|
72
|
+
windowsPathsNoEscape: true,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
spinner.succeed(`Found ${files.length} Razor file(s)`);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
spinner.fail(`Error scanning files: ${error.message}`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (files.length === 0) {
|
|
83
|
+
console.log(chalk.yellow('\n\u26A0\uFE0F No Razor files found to validate'));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Validate each file
|
|
88
|
+
const allIssues = [];
|
|
89
|
+
const fileResults = [];
|
|
90
|
+
|
|
91
|
+
for (const file of files) {
|
|
92
|
+
try {
|
|
93
|
+
const content = readFileSync(file, 'utf-8');
|
|
94
|
+
const issues = validateBlazorFile(content, file);
|
|
95
|
+
|
|
96
|
+
if (issues.length > 0) {
|
|
97
|
+
allIssues.push(...issues);
|
|
98
|
+
fileResults.push({ file, issues });
|
|
99
|
+
}
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.log(chalk.red(`\u274C Error reading ${file}: ${error.message}`));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Output results
|
|
106
|
+
console.log('');
|
|
107
|
+
|
|
108
|
+
if (allIssues.length === 0) {
|
|
109
|
+
console.log(
|
|
110
|
+
chalk.green('\u2705 No issues found! All patterns look correct.')
|
|
111
|
+
);
|
|
112
|
+
console.log('');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Group and display issues
|
|
117
|
+
if (verbose) {
|
|
118
|
+
// Verbose: show all issues with details
|
|
119
|
+
fileResults.forEach(({ file, issues }) => {
|
|
120
|
+
console.log(chalk.white.bold(`\n${file}`));
|
|
121
|
+
console.log(chalk.gray('-'.repeat(60)));
|
|
122
|
+
console.log(formatIssues(issues));
|
|
123
|
+
});
|
|
124
|
+
} else {
|
|
125
|
+
// Compact: just list issues
|
|
126
|
+
allIssues.forEach((issue) => {
|
|
127
|
+
const icon = issue.type === 'error' ? '\u274C' : '\u26A0\uFE0F';
|
|
128
|
+
const location = issue.line ? `${issue.file}:${issue.line}` : issue.file;
|
|
129
|
+
|
|
130
|
+
console.log(`${icon} ${issue.message}`);
|
|
131
|
+
if (issue.suggestion) {
|
|
132
|
+
console.log(chalk.gray(` \u2192 ${issue.suggestion}`));
|
|
133
|
+
}
|
|
134
|
+
console.log(chalk.dim(` ${location}`));
|
|
135
|
+
console.log('');
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Summary
|
|
140
|
+
const { errors, warnings } = countIssues(allIssues);
|
|
141
|
+
const summaryColor = errors > 0 ? chalk.red : chalk.yellow;
|
|
142
|
+
|
|
143
|
+
console.log(chalk.gray('-'.repeat(60)));
|
|
144
|
+
console.log(
|
|
145
|
+
summaryColor(
|
|
146
|
+
`\n${files.length} arquivo(s) validado(s) | ${errors} erro(s) | ${warnings} warning(s)\n`
|
|
147
|
+
)
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
// Exit with error code if there are errors
|
|
151
|
+
if (errors > 0) {
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export default validateBlazorCommand;
|
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MORPH-SPEC validate-css Command
|
|
3
|
-
*
|
|
4
|
-
* Validates that all CSS classes used in Razor files are defined in CSS files.
|
|
5
|
-
* Helps catch missing CSS definitions before runtime.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* morph-spec validate-css [path]
|
|
9
|
-
* morph-spec validate-css src/MyApp.Web
|
|
10
|
-
* morph-spec validate-css --verbose
|
|
11
|
-
* morph-spec validate-css --generate-stub
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import chalk from 'chalk';
|
|
15
|
-
import { existsSync, writeFileSync } from 'fs';
|
|
16
|
-
import { resolve, join } from 'path';
|
|
17
|
-
import {
|
|
18
|
-
validateCssClasses,
|
|
19
|
-
formatValidationResults,
|
|
20
|
-
generateCssStub
|
|
21
|
-
} from '../lib/css-validator.js';
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Execute the validate-css command
|
|
25
|
-
* @param {string} path - Project path to validate
|
|
26
|
-
* @param {Object} options - Command options
|
|
27
|
-
*/
|
|
28
|
-
export async function validateCssCommand(path, options = {}) {
|
|
29
|
-
const projectPath = resolve(path || '.');
|
|
30
|
-
const { verbose, generateStub, includeUtilities } = options;
|
|
31
|
-
|
|
32
|
-
// Validate path exists
|
|
33
|
-
if (!existsSync(projectPath)) {
|
|
34
|
-
console.error(chalk.red(`\n Error: Path does not exist: ${projectPath}\n`));
|
|
35
|
-
process.exit(1);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
console.log(chalk.cyan('\n Validating CSS classes...\n'));
|
|
39
|
-
console.log(chalk.gray(` Path: ${projectPath}`));
|
|
40
|
-
console.log('');
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
// Run validation
|
|
44
|
-
const results = await validateCssClasses(projectPath, {
|
|
45
|
-
verbose,
|
|
46
|
-
includeUtilities
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
// Output results
|
|
50
|
-
const formatted = formatValidationResults(results, verbose);
|
|
51
|
-
console.log(formatted);
|
|
52
|
-
|
|
53
|
-
// Generate stub if requested
|
|
54
|
-
if (generateStub && !results.valid) {
|
|
55
|
-
const stubContent = generateCssStub(results);
|
|
56
|
-
const stubPath = join(projectPath, 'missing-classes.css');
|
|
57
|
-
|
|
58
|
-
writeFileSync(stubPath, stubContent, 'utf8');
|
|
59
|
-
console.log(chalk.green(`\n Generated stub file: ${stubPath}\n`));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Summary with colors
|
|
63
|
-
if (results.valid) {
|
|
64
|
-
console.log(chalk.green('\n All CSS classes are properly defined!\n'));
|
|
65
|
-
process.exit(0);
|
|
66
|
-
} else {
|
|
67
|
-
console.log(chalk.yellow(`\n Found ${results.missingClasses.length} missing CSS class(es)\n`));
|
|
68
|
-
|
|
69
|
-
// Suggestions
|
|
70
|
-
console.log(chalk.cyan('Suggestions:'));
|
|
71
|
-
console.log(chalk.gray(' 1. Add the missing classes to your design-system.css'));
|
|
72
|
-
console.log(chalk.gray(' 2. Run with --generate-stub to create a template file'));
|
|
73
|
-
console.log(chalk.gray(' 3. If using utility frameworks (Tailwind), add --include-utilities\n'));
|
|
74
|
-
|
|
75
|
-
process.exit(1);
|
|
76
|
-
}
|
|
77
|
-
} catch (error) {
|
|
78
|
-
console.error(chalk.red(`\n Error: ${error.message}\n`));
|
|
79
|
-
if (verbose) {
|
|
80
|
-
console.error(error.stack);
|
|
81
|
-
}
|
|
82
|
-
process.exit(1);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* MORPH-SPEC validate-css Command
|
|
3
|
+
*
|
|
4
|
+
* Validates that all CSS classes used in Razor files are defined in CSS files.
|
|
5
|
+
* Helps catch missing CSS definitions before runtime.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* morph-spec validate-css [path]
|
|
9
|
+
* morph-spec validate-css src/MyApp.Web
|
|
10
|
+
* morph-spec validate-css --verbose
|
|
11
|
+
* morph-spec validate-css --generate-stub
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import chalk from 'chalk';
|
|
15
|
+
import { existsSync, writeFileSync } from 'fs';
|
|
16
|
+
import { resolve, join } from 'path';
|
|
17
|
+
import {
|
|
18
|
+
validateCssClasses,
|
|
19
|
+
formatValidationResults,
|
|
20
|
+
generateCssStub
|
|
21
|
+
} from '../lib/css-validator.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Execute the validate-css command
|
|
25
|
+
* @param {string} path - Project path to validate
|
|
26
|
+
* @param {Object} options - Command options
|
|
27
|
+
*/
|
|
28
|
+
export async function validateCssCommand(path, options = {}) {
|
|
29
|
+
const projectPath = resolve(path || '.');
|
|
30
|
+
const { verbose, generateStub, includeUtilities } = options;
|
|
31
|
+
|
|
32
|
+
// Validate path exists
|
|
33
|
+
if (!existsSync(projectPath)) {
|
|
34
|
+
console.error(chalk.red(`\n Error: Path does not exist: ${projectPath}\n`));
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
console.log(chalk.cyan('\n Validating CSS classes...\n'));
|
|
39
|
+
console.log(chalk.gray(` Path: ${projectPath}`));
|
|
40
|
+
console.log('');
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
// Run validation
|
|
44
|
+
const results = await validateCssClasses(projectPath, {
|
|
45
|
+
verbose,
|
|
46
|
+
includeUtilities
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Output results
|
|
50
|
+
const formatted = formatValidationResults(results, verbose);
|
|
51
|
+
console.log(formatted);
|
|
52
|
+
|
|
53
|
+
// Generate stub if requested
|
|
54
|
+
if (generateStub && !results.valid) {
|
|
55
|
+
const stubContent = generateCssStub(results);
|
|
56
|
+
const stubPath = join(projectPath, 'missing-classes.css');
|
|
57
|
+
|
|
58
|
+
writeFileSync(stubPath, stubContent, 'utf8');
|
|
59
|
+
console.log(chalk.green(`\n Generated stub file: ${stubPath}\n`));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Summary with colors
|
|
63
|
+
if (results.valid) {
|
|
64
|
+
console.log(chalk.green('\n All CSS classes are properly defined!\n'));
|
|
65
|
+
process.exit(0);
|
|
66
|
+
} else {
|
|
67
|
+
console.log(chalk.yellow(`\n Found ${results.missingClasses.length} missing CSS class(es)\n`));
|
|
68
|
+
|
|
69
|
+
// Suggestions
|
|
70
|
+
console.log(chalk.cyan('Suggestions:'));
|
|
71
|
+
console.log(chalk.gray(' 1. Add the missing classes to your design-system.css'));
|
|
72
|
+
console.log(chalk.gray(' 2. Run with --generate-stub to create a template file'));
|
|
73
|
+
console.log(chalk.gray(' 3. If using utility frameworks (Tailwind), add --include-utilities\n'));
|
|
74
|
+
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error(chalk.red(`\n Error: ${error.message}\n`));
|
|
79
|
+
if (verbose) {
|
|
80
|
+
console.error(error.stack);
|
|
81
|
+
}
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
}
|