@mytechtoday/augment-extensions 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/augment-extensions/coding-standards/c/CHANGELOG.md +55 -0
- package/augment-extensions/coding-standards/c/LICENSE +22 -0
- package/augment-extensions/coding-standards/c/README.md +167 -0
- package/augment-extensions/coding-standards/c/config/defaults.json +26 -0
- package/augment-extensions/coding-standards/c/config/examples/embedded.yaml +25 -0
- package/augment-extensions/coding-standards/c/config/examples/systems.json +31 -0
- package/augment-extensions/coding-standards/c/config/schema.json +244 -0
- package/augment-extensions/coding-standards/c/docs/API.md +613 -0
- package/augment-extensions/coding-standards/c/docs/CONFIGURATION.md +259 -0
- package/augment-extensions/coding-standards/c/docs/USER_GUIDE.md +567 -0
- package/augment-extensions/coding-standards/c/examples/drivers/Makefile +33 -0
- package/augment-extensions/coding-standards/c/examples/drivers/README.md +192 -0
- package/augment-extensions/coding-standards/c/examples/drivers/dma-example.c +224 -0
- package/augment-extensions/coding-standards/c/examples/drivers/example.dts +64 -0
- package/augment-extensions/coding-standards/c/examples/drivers/platform-driver.c +174 -0
- package/augment-extensions/coding-standards/c/examples/embedded/README.md +167 -0
- package/augment-extensions/coding-standards/c/examples/embedded/gpio-control.c +172 -0
- package/augment-extensions/coding-standards/c/examples/embedded/timer-isr.c +198 -0
- package/augment-extensions/coding-standards/c/examples/embedded/uart-communication.c +212 -0
- package/augment-extensions/coding-standards/c/examples/kernel/Makefile +82 -0
- package/augment-extensions/coding-standards/c/examples/kernel/README.md +168 -0
- package/augment-extensions/coding-standards/c/examples/kernel/char-device.c +198 -0
- package/augment-extensions/coding-standards/c/examples/kernel/proc-file.c +131 -0
- package/augment-extensions/coding-standards/c/examples/kernel/simple-module.c +111 -0
- package/augment-extensions/coding-standards/c/examples/legacy/Makefile +62 -0
- package/augment-extensions/coding-standards/c/examples/legacy/README.md +255 -0
- package/augment-extensions/coding-standards/c/examples/legacy/c89-to-c11-migration.c +268 -0
- package/augment-extensions/coding-standards/c/examples/legacy/compatibility-layer.c +239 -0
- package/augment-extensions/coding-standards/c/examples/networking/Makefile +35 -0
- package/augment-extensions/coding-standards/c/examples/networking/README.md +207 -0
- package/augment-extensions/coding-standards/c/examples/networking/protocol-parser.c +270 -0
- package/augment-extensions/coding-standards/c/examples/networking/tcp-server.c +197 -0
- package/augment-extensions/coding-standards/c/examples/networking/udp-multicast.c +220 -0
- package/augment-extensions/coding-standards/c/examples/realtime/Makefile +53 -0
- package/augment-extensions/coding-standards/c/examples/realtime/README.md +199 -0
- package/augment-extensions/coding-standards/c/examples/realtime/deadline-monitoring.c +260 -0
- package/augment-extensions/coding-standards/c/examples/realtime/priority-scheduling.c +258 -0
- package/augment-extensions/coding-standards/c/examples/systems/Makefile +34 -0
- package/augment-extensions/coding-standards/c/examples/systems/README.md +123 -0
- package/augment-extensions/coding-standards/c/examples/systems/ipc-pipes.c +181 -0
- package/augment-extensions/coding-standards/c/examples/systems/process-management.c +153 -0
- package/augment-extensions/coding-standards/c/examples/systems/signal-handling.c +162 -0
- package/augment-extensions/coding-standards/c/module.json +149 -0
- package/augment-extensions/coding-standards/c/rules/categories/drivers.md +635 -0
- package/augment-extensions/coding-standards/c/rules/categories/embedded.md +510 -0
- package/augment-extensions/coding-standards/c/rules/categories/kernel.md +653 -0
- package/augment-extensions/coding-standards/c/rules/categories/legacy.md +526 -0
- package/augment-extensions/coding-standards/c/rules/categories/networking.md +735 -0
- package/augment-extensions/coding-standards/c/rules/categories/realtime.md +631 -0
- package/augment-extensions/coding-standards/c/rules/categories/systems.md +586 -0
- package/augment-extensions/coding-standards/c/rules/universal/const-correctness.md +275 -0
- package/augment-extensions/coding-standards/c/rules/universal/documentation.md +251 -0
- package/augment-extensions/coding-standards/c/rules/universal/error-handling.md +250 -0
- package/augment-extensions/coding-standards/c/rules/universal/header-guards.md +254 -0
- package/augment-extensions/coding-standards/c/rules/universal/memory-safety.md +233 -0
- package/augment-extensions/coding-standards/c/rules/universal/naming.md +146 -0
- package/augment-extensions/coding-standards/c/src/conflict-detector.ts +461 -0
- package/augment-extensions/coding-standards/c/src/prompt-generator.ts +307 -0
- package/augment-extensions/coding-standards/c/src/rule-evaluator.ts +307 -0
- package/augment-extensions/coding-standards/c/src/rule-override.ts +427 -0
- package/augment-extensions/coding-standards/c/src/template-engine.ts +217 -0
- package/augment-extensions/coding-standards/c/templates/prompts/drivers.txt +191 -0
- package/augment-extensions/coding-standards/c/templates/prompts/embedded.txt +164 -0
- package/augment-extensions/coding-standards/c/templates/prompts/kernel.txt +175 -0
- package/augment-extensions/coding-standards/c/templates/prompts/legacy.txt +280 -0
- package/augment-extensions/coding-standards/c/templates/prompts/networking.txt +259 -0
- package/augment-extensions/coding-standards/c/templates/prompts/realtime.txt +219 -0
- package/augment-extensions/coding-standards/c/templates/prompts/systems.txt +147 -0
- package/augment-extensions/coding-standards/c/tests/integration/category-specific.test.ts +356 -0
- package/augment-extensions/coding-standards/c/tests/integration/end-to-end-workflow.test.ts +377 -0
- package/augment-extensions/coding-standards/c/tests/performance/benchmarks.test.ts +407 -0
- package/augment-extensions/coding-standards/c/tests/unit/config-manager.test.ts +345 -0
- package/augment-extensions/coding-standards/c/tests/unit/conflict-detector.test.ts +294 -0
- package/augment-extensions/coding-standards/c/tests/unit/prompt-generator.test.ts +174 -0
- package/augment-extensions/coding-standards/c/tests/unit/registry.test.ts +313 -0
- package/augment-extensions/coding-standards/c/tests/unit/rule-evaluator.test.ts +318 -0
- package/augment-extensions/coding-standards/c/tests/unit/rule-override.test.ts +326 -0
- package/augment-extensions/coding-standards/c/tests/unit/template-engine.test.ts +314 -0
- package/augment-extensions/coding-standards/go/CHARACTER-COUNT-REPORT.md +135 -0
- package/augment-extensions/coding-standards/go/PHASE1-COMPLETION.md +146 -0
- package/augment-extensions/coding-standards/go/PHASE4-COMPLETION.md +184 -0
- package/augment-extensions/coding-standards/go/README.md +200 -0
- package/augment-extensions/coding-standards/go/VALIDATION-CHECKLIST.md +154 -0
- package/augment-extensions/coding-standards/go/config/examples/example-cli.json +15 -0
- package/augment-extensions/coding-standards/go/config/examples/example-microservices.json +21 -0
- package/augment-extensions/coding-standards/go/config/examples/example-multi-category.yaml +24 -0
- package/augment-extensions/coding-standards/go/config/examples/example-web.json +15 -0
- package/augment-extensions/coding-standards/go/config/schema.json +110 -0
- package/augment-extensions/coding-standards/go/docs/CATEGORIES.md +221 -0
- package/augment-extensions/coding-standards/go/docs/CONFIGURATION.md +198 -0
- package/augment-extensions/coding-standards/go/docs/TROUBLESHOOTING.md +285 -0
- package/augment-extensions/coding-standards/go/examples/cli/cobra-app.go +287 -0
- package/augment-extensions/coding-standards/go/examples/cloud-native-app.go +217 -0
- package/augment-extensions/coding-standards/go/examples/devops-tool.go +250 -0
- package/augment-extensions/coding-standards/go/examples/distributed-system.go +247 -0
- package/augment-extensions/coding-standards/go/examples/microservices/grpc-service.go +253 -0
- package/augment-extensions/coding-standards/go/examples/rest-api.go +270 -0
- package/augment-extensions/coding-standards/go/examples/web/http-server.go +224 -0
- package/augment-extensions/coding-standards/go/module.json +139 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/api-versioning.md +149 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/rate-limiting.md +209 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/rest-api-design.md +183 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/cloud-config.md +193 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/health-checks.md +231 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/kubernetes.md +180 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/automation.md +179 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/ci-cd-integration.md +147 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/infrastructure-as-code.md +231 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/caching.md +150 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/consensus.md +187 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/event-sourcing.md +246 -0
- package/augment-extensions/coding-standards/go/rules/cli/command-parsing.md +264 -0
- package/augment-extensions/coding-standards/go/rules/cli/configuration.md +268 -0
- package/augment-extensions/coding-standards/go/rules/cli/cross-platform.md +324 -0
- package/augment-extensions/coding-standards/go/rules/microservices/distributed-tracing.md +253 -0
- package/augment-extensions/coding-standards/go/rules/microservices/grpc.md +257 -0
- package/augment-extensions/coding-standards/go/rules/microservices/metrics.md +278 -0
- package/augment-extensions/coding-standards/go/rules/microservices/service-discovery.md +249 -0
- package/augment-extensions/coding-standards/go/rules/universal/code-organization.md +221 -0
- package/augment-extensions/coding-standards/go/rules/universal/documentation.md +269 -0
- package/augment-extensions/coding-standards/go/rules/universal/performance.md +323 -0
- package/augment-extensions/coding-standards/go/rules/universal/testing.md +162 -0
- package/augment-extensions/coding-standards/go/rules/web/graceful-shutdown.md +249 -0
- package/augment-extensions/coding-standards/go/rules/web/http-handlers.md +164 -0
- package/augment-extensions/coding-standards/go/rules/web/middleware.md +234 -0
- package/augment-extensions/coding-standards/go/rules/web/routing.md +251 -0
- package/augment-extensions/coding-standards/go/templates/prompts/api.md +160 -0
- package/augment-extensions/coding-standards/go/templates/prompts/cli.md +225 -0
- package/augment-extensions/coding-standards/go/templates/prompts/cloud-native.md +121 -0
- package/augment-extensions/coding-standards/go/templates/prompts/devops.md +146 -0
- package/augment-extensions/coding-standards/go/templates/prompts/distributed.md +133 -0
- package/augment-extensions/coding-standards/go/templates/prompts/microservices.md +225 -0
- package/augment-extensions/coding-standards/go/templates/prompts/web.md +181 -0
- package/augment-extensions/coding-standards/go/tests/integration/module-integration.test.ts +164 -0
- package/augment-extensions/coding-standards/go/tests/unit/category-selection.test.ts +147 -0
- package/augment-extensions/coding-standards/go/tests/unit/module-structure.test.ts +154 -0
- package/augment-extensions/coding-standards/go/tests/validate-character-count.ps1 +13 -0
- package/augment-extensions/coding-standards/go/tests/validate-examples.ps1 +148 -0
- package/augment-extensions/coding-standards/go/tests/validate-examples.sh +135 -0
- package/cli/dist/analysis/ast-parser.d.ts +47 -0
- package/cli/dist/analysis/ast-parser.d.ts.map +1 -0
- package/cli/dist/analysis/ast-parser.js +161 -0
- package/cli/dist/analysis/ast-parser.js.map +1 -0
- package/cli/dist/analysis/complexity-analyzer.d.ts +27 -0
- package/cli/dist/analysis/complexity-analyzer.d.ts.map +1 -0
- package/cli/dist/analysis/complexity-analyzer.js +189 -0
- package/cli/dist/analysis/complexity-analyzer.js.map +1 -0
- package/cli/dist/analysis/dependency-analyzer.d.ts +23 -0
- package/cli/dist/analysis/dependency-analyzer.d.ts.map +1 -0
- package/cli/dist/analysis/dependency-analyzer.js +237 -0
- package/cli/dist/analysis/dependency-analyzer.js.map +1 -0
- package/cli/dist/analysis/index.d.ts +9 -0
- package/cli/dist/analysis/index.d.ts.map +1 -0
- package/cli/dist/analysis/index.js +25 -0
- package/cli/dist/analysis/index.js.map +1 -0
- package/cli/dist/analysis/security-scanner.d.ts +11 -0
- package/cli/dist/analysis/security-scanner.d.ts.map +1 -0
- package/cli/dist/analysis/security-scanner.js +294 -0
- package/cli/dist/analysis/security-scanner.js.map +1 -0
- package/cli/dist/analysis/types.d.ts +151 -0
- package/cli/dist/analysis/types.d.ts.map +1 -0
- package/cli/dist/analysis/types.js +6 -0
- package/cli/dist/analysis/types.js.map +1 -0
- package/cli/dist/cli.js +24 -0
- package/cli/dist/cli.js.map +1 -1
- package/cli/dist/commands/code-analysis.d.ts +11 -0
- package/cli/dist/commands/code-analysis.d.ts.map +1 -0
- package/cli/dist/commands/code-analysis.js +412 -0
- package/cli/dist/commands/code-analysis.js.map +1 -0
- package/modules.md +99 -3
- package/package.json +14 -2
- package/cli/dist/commands/agent.d.ts +0 -37
- package/cli/dist/commands/agent.d.ts.map +0 -1
- package/cli/dist/commands/agent.js +0 -222
- package/cli/dist/commands/agent.js.map +0 -1
- package/cli/dist/commands/beads.d.ts +0 -64
- package/cli/dist/commands/beads.d.ts.map +0 -1
- package/cli/dist/commands/beads.js +0 -377
- package/cli/dist/commands/beads.js.map +0 -1
- package/cli/dist/commands/change.d.ts +0 -54
- package/cli/dist/commands/change.d.ts.map +0 -1
- package/cli/dist/commands/change.js +0 -243
- package/cli/dist/commands/change.js.map +0 -1
- package/cli/dist/commands/clean.d.ts +0 -15
- package/cli/dist/commands/clean.d.ts.map +0 -1
- package/cli/dist/commands/clean.js +0 -63
- package/cli/dist/commands/clean.js.map +0 -1
- package/cli/dist/commands/clone.d.ts +0 -15
- package/cli/dist/commands/clone.d.ts.map +0 -1
- package/cli/dist/commands/clone.js +0 -49
- package/cli/dist/commands/clone.js.map +0 -1
- package/cli/dist/commands/config.d.ts +0 -33
- package/cli/dist/commands/config.d.ts.map +0 -1
- package/cli/dist/commands/config.js +0 -166
- package/cli/dist/commands/config.js.map +0 -1
- package/cli/dist/commands/context.d.ts +0 -38
- package/cli/dist/commands/context.d.ts.map +0 -1
- package/cli/dist/commands/context.js +0 -205
- package/cli/dist/commands/context.js.map +0 -1
- package/cli/dist/commands/create.d.ts +0 -18
- package/cli/dist/commands/create.d.ts.map +0 -1
- package/cli/dist/commands/create.js +0 -178
- package/cli/dist/commands/create.js.map +0 -1
- package/cli/dist/commands/diff.d.ts +0 -19
- package/cli/dist/commands/diff.d.ts.map +0 -1
- package/cli/dist/commands/diff.js +0 -104
- package/cli/dist/commands/diff.js.map +0 -1
- package/cli/dist/commands/doctor.d.ts +0 -14
- package/cli/dist/commands/doctor.d.ts.map +0 -1
- package/cli/dist/commands/doctor.js +0 -62
- package/cli/dist/commands/doctor.js.map +0 -1
- package/cli/dist/commands/export.d.ts +0 -28
- package/cli/dist/commands/export.d.ts.map +0 -1
- package/cli/dist/commands/export.js +0 -135
- package/cli/dist/commands/export.js.map +0 -1
- package/cli/dist/commands/import.d.ts +0 -23
- package/cli/dist/commands/import.d.ts.map +0 -1
- package/cli/dist/commands/import.js +0 -118
- package/cli/dist/commands/import.js.map +0 -1
- package/cli/dist/commands/prompt.d.ts +0 -45
- package/cli/dist/commands/prompt.d.ts.map +0 -1
- package/cli/dist/commands/prompt.js +0 -223
- package/cli/dist/commands/prompt.js.map +0 -1
- package/cli/dist/commands/spec.d.ts +0 -57
- package/cli/dist/commands/spec.d.ts.map +0 -1
- package/cli/dist/commands/spec.js +0 -279
- package/cli/dist/commands/spec.js.map +0 -1
- package/cli/dist/commands/stats.d.ts +0 -18
- package/cli/dist/commands/stats.d.ts.map +0 -1
- package/cli/dist/commands/stats.js +0 -85
- package/cli/dist/commands/stats.js.map +0 -1
- package/cli/dist/commands/task.d.ts +0 -65
- package/cli/dist/commands/task.d.ts.map +0 -1
- package/cli/dist/commands/task.js +0 -282
- package/cli/dist/commands/task.js.map +0 -1
- package/cli/dist/commands/template.d.ts +0 -17
- package/cli/dist/commands/template.d.ts.map +0 -1
- package/cli/dist/commands/template.js +0 -55
- package/cli/dist/commands/template.js.map +0 -1
- package/cli/dist/utils/agent-config.d.ts +0 -129
- package/cli/dist/utils/agent-config.d.ts.map +0 -1
- package/cli/dist/utils/agent-config.js +0 -297
- package/cli/dist/utils/agent-config.js.map +0 -1
- package/cli/dist/utils/beads-graph.d.ts +0 -17
- package/cli/dist/utils/beads-graph.d.ts.map +0 -1
- package/cli/dist/utils/beads-graph.js +0 -150
- package/cli/dist/utils/beads-graph.js.map +0 -1
- package/cli/dist/utils/beads-integration.d.ts +0 -112
- package/cli/dist/utils/beads-integration.d.ts.map +0 -1
- package/cli/dist/utils/beads-integration.js +0 -312
- package/cli/dist/utils/beads-integration.js.map +0 -1
- package/cli/dist/utils/beads-reporter.d.ts +0 -17
- package/cli/dist/utils/beads-reporter.d.ts.map +0 -1
- package/cli/dist/utils/beads-reporter.js +0 -160
- package/cli/dist/utils/beads-reporter.js.map +0 -1
- package/cli/dist/utils/cache-manager.d.ts +0 -55
- package/cli/dist/utils/cache-manager.d.ts.map +0 -1
- package/cli/dist/utils/cache-manager.js +0 -150
- package/cli/dist/utils/cache-manager.js.map +0 -1
- package/cli/dist/utils/change-manager.d.ts +0 -70
- package/cli/dist/utils/change-manager.d.ts.map +0 -1
- package/cli/dist/utils/change-manager.js +0 -412
- package/cli/dist/utils/change-manager.js.map +0 -1
- package/cli/dist/utils/config-manager-enhanced.d.ts +0 -66
- package/cli/dist/utils/config-manager-enhanced.d.ts.map +0 -1
- package/cli/dist/utils/config-manager-enhanced.js +0 -77
- package/cli/dist/utils/config-manager-enhanced.js.map +0 -1
- package/cli/dist/utils/context-manager.d.ts +0 -96
- package/cli/dist/utils/context-manager.d.ts.map +0 -1
- package/cli/dist/utils/context-manager.js +0 -258
- package/cli/dist/utils/context-manager.js.map +0 -1
- package/cli/dist/utils/diff-engine.d.ts +0 -78
- package/cli/dist/utils/diff-engine.d.ts.map +0 -1
- package/cli/dist/utils/diff-engine.js +0 -233
- package/cli/dist/utils/diff-engine.js.map +0 -1
- package/cli/dist/utils/export-system.d.ts +0 -101
- package/cli/dist/utils/export-system.d.ts.map +0 -1
- package/cli/dist/utils/export-system.js +0 -289
- package/cli/dist/utils/export-system.js.map +0 -1
- package/cli/dist/utils/health-checker.d.ts +0 -66
- package/cli/dist/utils/health-checker.d.ts.map +0 -1
- package/cli/dist/utils/health-checker.js +0 -285
- package/cli/dist/utils/health-checker.js.map +0 -1
- package/cli/dist/utils/import-system.d.ts +0 -74
- package/cli/dist/utils/import-system.d.ts.map +0 -1
- package/cli/dist/utils/import-system.js +0 -317
- package/cli/dist/utils/import-system.js.map +0 -1
- package/cli/dist/utils/module-cloner.d.ts +0 -40
- package/cli/dist/utils/module-cloner.d.ts.map +0 -1
- package/cli/dist/utils/module-cloner.js +0 -136
- package/cli/dist/utils/module-cloner.js.map +0 -1
- package/cli/dist/utils/prompt-manager.d.ts +0 -90
- package/cli/dist/utils/prompt-manager.d.ts.map +0 -1
- package/cli/dist/utils/prompt-manager.js +0 -302
- package/cli/dist/utils/prompt-manager.js.map +0 -1
- package/cli/dist/utils/spec-manager.d.ts +0 -65
- package/cli/dist/utils/spec-manager.d.ts.map +0 -1
- package/cli/dist/utils/spec-manager.js +0 -329
- package/cli/dist/utils/spec-manager.js.map +0 -1
- package/cli/dist/utils/stats-collector.d.ts +0 -74
- package/cli/dist/utils/stats-collector.d.ts.map +0 -1
- package/cli/dist/utils/stats-collector.js +0 -164
- package/cli/dist/utils/stats-collector.js.map +0 -1
- package/cli/dist/utils/template-engine.d.ts +0 -47
- package/cli/dist/utils/template-engine.d.ts.map +0 -1
- package/cli/dist/utils/template-engine.js +0 -204
- package/cli/dist/utils/template-engine.js.map +0 -1
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule Override System for C Coding Standards
|
|
3
|
+
*
|
|
4
|
+
* Implements rule override mechanism for category-specific exceptions.
|
|
5
|
+
* Supports configuration-based overrides and validates override consistency.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Rule, Category, Configuration, RuleSeverity } from './types';
|
|
9
|
+
import { RuleRegistry } from './registry';
|
|
10
|
+
import { ConfigurationManager } from './config-manager';
|
|
11
|
+
|
|
12
|
+
export interface RuleOverride {
|
|
13
|
+
ruleId: string;
|
|
14
|
+
category: Category;
|
|
15
|
+
action: 'disable' | 'enable' | 'change_severity';
|
|
16
|
+
newSeverity?: 'ERROR' | 'WARNING' | 'INFO';
|
|
17
|
+
reason: string;
|
|
18
|
+
appliedBy?: 'user' | 'category' | 'system';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface OverrideValidation {
|
|
22
|
+
valid: boolean;
|
|
23
|
+
errors: string[];
|
|
24
|
+
warnings: string[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface OverrideReport {
|
|
28
|
+
overrides: RuleOverride[];
|
|
29
|
+
applied: number;
|
|
30
|
+
failed: number;
|
|
31
|
+
warnings: string[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class RuleOverrideSystem {
|
|
35
|
+
private overrides: Map<string, RuleOverride[]> = new Map();
|
|
36
|
+
|
|
37
|
+
constructor(
|
|
38
|
+
private registry: RuleRegistry,
|
|
39
|
+
private configManager: ConfigurationManager
|
|
40
|
+
) {
|
|
41
|
+
this.loadConfigurationOverrides();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Load overrides from configuration
|
|
46
|
+
*/
|
|
47
|
+
private loadConfigurationOverrides(): void {
|
|
48
|
+
const config = this.configManager.getConfiguration();
|
|
49
|
+
|
|
50
|
+
// Load universal rule overrides
|
|
51
|
+
if (config.c_standards.universal_rules) {
|
|
52
|
+
for (const [ruleKey, severity] of Object.entries(config.c_standards.universal_rules)) {
|
|
53
|
+
const ruleId = `universal-${ruleKey}`;
|
|
54
|
+
|
|
55
|
+
if (severity === 'disabled') {
|
|
56
|
+
this.addOverride({
|
|
57
|
+
ruleId,
|
|
58
|
+
category: 'universal' as Category,
|
|
59
|
+
action: 'disable',
|
|
60
|
+
reason: 'Disabled in configuration',
|
|
61
|
+
appliedBy: 'user'
|
|
62
|
+
});
|
|
63
|
+
} else if (severity === 'warning') {
|
|
64
|
+
this.addOverride({
|
|
65
|
+
ruleId,
|
|
66
|
+
category: 'universal' as Category,
|
|
67
|
+
action: 'change_severity',
|
|
68
|
+
newSeverity: 'WARNING',
|
|
69
|
+
reason: 'Changed to warning in configuration',
|
|
70
|
+
appliedBy: 'user'
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Load category-specific overrides
|
|
77
|
+
if (config.c_standards.category_overrides) {
|
|
78
|
+
for (const [category, overrides] of Object.entries(config.c_standards.category_overrides)) {
|
|
79
|
+
this.loadCategoryOverrides(category as Category, overrides);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Load category-specific overrides
|
|
86
|
+
*/
|
|
87
|
+
private loadCategoryOverrides(category: Category, overrides: any): void {
|
|
88
|
+
// Example: embedded category disables dynamic allocation
|
|
89
|
+
if (category === 'embedded' && overrides.allow_dynamic_allocation === false) {
|
|
90
|
+
this.addOverride({
|
|
91
|
+
ruleId: 'universal-memory_safety',
|
|
92
|
+
category,
|
|
93
|
+
action: 'change_severity',
|
|
94
|
+
newSeverity: 'ERROR',
|
|
95
|
+
reason: 'Embedded systems forbid dynamic allocation',
|
|
96
|
+
appliedBy: 'category'
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Example: systems category requires POSIX compliance
|
|
101
|
+
if (category === 'systems' && overrides.require_posix_compliance === true) {
|
|
102
|
+
this.addOverride({
|
|
103
|
+
ruleId: 'systems-posix',
|
|
104
|
+
category,
|
|
105
|
+
action: 'enable',
|
|
106
|
+
reason: 'POSIX compliance required for systems programming',
|
|
107
|
+
appliedBy: 'category'
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Example: realtime category enforces determinism
|
|
112
|
+
if (category === 'realtime' && overrides.enforce_determinism === true) {
|
|
113
|
+
this.addOverride({
|
|
114
|
+
ruleId: 'realtime-determinism',
|
|
115
|
+
category,
|
|
116
|
+
action: 'change_severity',
|
|
117
|
+
newSeverity: 'ERROR',
|
|
118
|
+
reason: 'Determinism is critical for real-time systems',
|
|
119
|
+
appliedBy: 'category'
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Add a rule override
|
|
126
|
+
*/
|
|
127
|
+
addOverride(override: RuleOverride): void {
|
|
128
|
+
const key = `${override.ruleId}:${override.category}`;
|
|
129
|
+
|
|
130
|
+
if (!this.overrides.has(key)) {
|
|
131
|
+
this.overrides.set(key, []);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
this.overrides.get(key)!.push(override);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Get overrides for a specific rule and category
|
|
139
|
+
*/
|
|
140
|
+
getOverrides(ruleId: string, category: Category): RuleOverride[] {
|
|
141
|
+
const key = `${ruleId}:${category}`;
|
|
142
|
+
return this.overrides.get(key) || [];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Apply overrides to a rule
|
|
147
|
+
*/
|
|
148
|
+
applyOverrides(rule: Rule, category: Category): Rule {
|
|
149
|
+
const overrides = this.getOverrides(rule.id, category);
|
|
150
|
+
|
|
151
|
+
if (overrides.length === 0) {
|
|
152
|
+
return rule;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Create a copy of the rule
|
|
156
|
+
const modifiedRule = { ...rule };
|
|
157
|
+
|
|
158
|
+
// Apply each override in order
|
|
159
|
+
for (const override of overrides) {
|
|
160
|
+
switch (override.action) {
|
|
161
|
+
case 'disable':
|
|
162
|
+
modifiedRule.enabled = false;
|
|
163
|
+
break;
|
|
164
|
+
|
|
165
|
+
case 'enable':
|
|
166
|
+
modifiedRule.enabled = true;
|
|
167
|
+
break;
|
|
168
|
+
|
|
169
|
+
case 'change_severity':
|
|
170
|
+
if (override.newSeverity) {
|
|
171
|
+
modifiedRule.severity = override.newSeverity;
|
|
172
|
+
}
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return modifiedRule;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Validate override consistency
|
|
182
|
+
*/
|
|
183
|
+
validateOverrides(): OverrideValidation {
|
|
184
|
+
const errors: string[] = [];
|
|
185
|
+
const warnings: string[] = [];
|
|
186
|
+
|
|
187
|
+
// Check for conflicting overrides
|
|
188
|
+
for (const [key, overrideList] of this.overrides) {
|
|
189
|
+
if (overrideList.length > 1) {
|
|
190
|
+
// Multiple overrides for the same rule/category
|
|
191
|
+
const hasConflict = this.checkOverrideConflict(overrideList);
|
|
192
|
+
|
|
193
|
+
if (hasConflict) {
|
|
194
|
+
errors.push(`Conflicting overrides for ${key}: ${overrideList.map(o => o.action).join(', ')}`);
|
|
195
|
+
} else {
|
|
196
|
+
warnings.push(`Multiple overrides for ${key} (will be applied in order)`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Check if overridden rules exist
|
|
202
|
+
for (const [key, overrideList] of this.overrides) {
|
|
203
|
+
const ruleId = key.split(':')[0];
|
|
204
|
+
const rule = this.registry.getRule(ruleId);
|
|
205
|
+
|
|
206
|
+
if (!rule) {
|
|
207
|
+
warnings.push(`Override for non-existent rule: ${ruleId}`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Check for circular dependencies
|
|
212
|
+
const circular = this.detectCircularOverrides();
|
|
213
|
+
if (circular.length > 0) {
|
|
214
|
+
errors.push(`Circular override dependencies detected: ${circular.join(', ')}`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
valid: errors.length === 0,
|
|
219
|
+
errors,
|
|
220
|
+
warnings
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Check if override list has conflicts
|
|
226
|
+
*/
|
|
227
|
+
private checkOverrideConflict(overrides: RuleOverride[]): boolean {
|
|
228
|
+
// Check for enable/disable conflicts
|
|
229
|
+
const hasEnable = overrides.some(o => o.action === 'enable');
|
|
230
|
+
const hasDisable = overrides.some(o => o.action === 'disable');
|
|
231
|
+
|
|
232
|
+
if (hasEnable && hasDisable) {
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Check for severity conflicts
|
|
237
|
+
const severityChanges = overrides
|
|
238
|
+
.filter(o => o.action === 'change_severity')
|
|
239
|
+
.map(o => o.newSeverity);
|
|
240
|
+
|
|
241
|
+
const uniqueSeverities = new Set(severityChanges);
|
|
242
|
+
if (uniqueSeverities.size > 1) {
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Detect circular override dependencies
|
|
251
|
+
*/
|
|
252
|
+
private detectCircularOverrides(): string[] {
|
|
253
|
+
// Simplified implementation
|
|
254
|
+
// In production, use proper graph cycle detection
|
|
255
|
+
const circular: string[] = [];
|
|
256
|
+
|
|
257
|
+
// Check if any override creates a circular dependency
|
|
258
|
+
// This is a placeholder for demonstration
|
|
259
|
+
|
|
260
|
+
return circular;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Apply all overrides to rules for a category
|
|
265
|
+
*/
|
|
266
|
+
applyAllOverrides(rules: Rule[], category: Category): Rule[] {
|
|
267
|
+
return rules.map(rule => this.applyOverrides(rule, category));
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Get all overrides
|
|
272
|
+
*/
|
|
273
|
+
getAllOverrides(): RuleOverride[] {
|
|
274
|
+
const allOverrides: RuleOverride[] = [];
|
|
275
|
+
|
|
276
|
+
for (const overrideList of this.overrides.values()) {
|
|
277
|
+
allOverrides.push(...overrideList);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return allOverrides;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Clear all overrides
|
|
285
|
+
*/
|
|
286
|
+
clearOverrides(): void {
|
|
287
|
+
this.overrides.clear();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Remove overrides for a specific rule
|
|
292
|
+
*/
|
|
293
|
+
removeOverrides(ruleId: string, category?: Category): void {
|
|
294
|
+
if (category) {
|
|
295
|
+
const key = `${ruleId}:${category}`;
|
|
296
|
+
this.overrides.delete(key);
|
|
297
|
+
} else {
|
|
298
|
+
// Remove all overrides for this rule across all categories
|
|
299
|
+
const keysToDelete: string[] = [];
|
|
300
|
+
|
|
301
|
+
for (const key of this.overrides.keys()) {
|
|
302
|
+
if (key.startsWith(`${ruleId}:`)) {
|
|
303
|
+
keysToDelete.push(key);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
for (const key of keysToDelete) {
|
|
308
|
+
this.overrides.delete(key);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Generate override report
|
|
315
|
+
*/
|
|
316
|
+
generateReport(): OverrideReport {
|
|
317
|
+
const allOverrides = this.getAllOverrides();
|
|
318
|
+
const validation = this.validateOverrides();
|
|
319
|
+
|
|
320
|
+
return {
|
|
321
|
+
overrides: allOverrides,
|
|
322
|
+
applied: allOverrides.filter(o => o.appliedBy !== undefined).length,
|
|
323
|
+
failed: validation.errors.length,
|
|
324
|
+
warnings: validation.warnings
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Generate formatted override report
|
|
330
|
+
*/
|
|
331
|
+
generateFormattedReport(): string {
|
|
332
|
+
const report = this.generateReport();
|
|
333
|
+
let output = '# Rule Override Report\n\n';
|
|
334
|
+
|
|
335
|
+
output += `## Summary\n\n`;
|
|
336
|
+
output += `- Total overrides: ${report.overrides.length}\n`;
|
|
337
|
+
output += `- Applied: ${report.applied}\n`;
|
|
338
|
+
output += `- Failed: ${report.failed}\n`;
|
|
339
|
+
output += `- Warnings: ${report.warnings.length}\n\n`;
|
|
340
|
+
|
|
341
|
+
if (report.warnings.length > 0) {
|
|
342
|
+
output += `## Warnings\n\n`;
|
|
343
|
+
for (const warning of report.warnings) {
|
|
344
|
+
output += `- ${warning}\n`;
|
|
345
|
+
}
|
|
346
|
+
output += '\n';
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (report.overrides.length === 0) {
|
|
350
|
+
output += 'No overrides configured.\n';
|
|
351
|
+
return output;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
output += `## Overrides by Category\n\n`;
|
|
355
|
+
|
|
356
|
+
// Group by category
|
|
357
|
+
const byCategory = new Map<Category, RuleOverride[]>();
|
|
358
|
+
|
|
359
|
+
for (const override of report.overrides) {
|
|
360
|
+
if (!byCategory.has(override.category)) {
|
|
361
|
+
byCategory.set(override.category, []);
|
|
362
|
+
}
|
|
363
|
+
byCategory.get(override.category)!.push(override);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
for (const [category, overrides] of byCategory) {
|
|
367
|
+
output += `### ${category}\n\n`;
|
|
368
|
+
|
|
369
|
+
for (const override of overrides) {
|
|
370
|
+
output += `- **${override.ruleId}**: ${override.action}`;
|
|
371
|
+
|
|
372
|
+
if (override.newSeverity) {
|
|
373
|
+
output += ` (${override.newSeverity})`;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
output += `\n - Reason: ${override.reason}\n`;
|
|
377
|
+
|
|
378
|
+
if (override.appliedBy) {
|
|
379
|
+
output += ` - Applied by: ${override.appliedBy}\n`;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
output += '\n';
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return output;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Export overrides to configuration format
|
|
391
|
+
*/
|
|
392
|
+
exportToConfig(): any {
|
|
393
|
+
const config: any = {
|
|
394
|
+
universal_rules: {},
|
|
395
|
+
category_overrides: {}
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
for (const override of this.getAllOverrides()) {
|
|
399
|
+
if (override.category === 'universal') {
|
|
400
|
+
const ruleKey = override.ruleId.replace('universal-', '');
|
|
401
|
+
|
|
402
|
+
if (override.action === 'disable') {
|
|
403
|
+
config.universal_rules[ruleKey] = 'disabled';
|
|
404
|
+
} else if (override.action === 'change_severity' && override.newSeverity === 'WARNING') {
|
|
405
|
+
config.universal_rules[ruleKey] = 'warning';
|
|
406
|
+
} else {
|
|
407
|
+
config.universal_rules[ruleKey] = 'enabled';
|
|
408
|
+
}
|
|
409
|
+
} else {
|
|
410
|
+
if (!config.category_overrides[override.category]) {
|
|
411
|
+
config.category_overrides[override.category] = {};
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Map override to configuration property
|
|
415
|
+
// This is simplified; in production, use proper mapping
|
|
416
|
+
config.category_overrides[override.category][override.ruleId] = {
|
|
417
|
+
action: override.action,
|
|
418
|
+
severity: override.newSeverity,
|
|
419
|
+
reason: override.reason
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
return config;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Engine for C Coding Standards
|
|
3
|
+
*
|
|
4
|
+
* Provides template parsing with variable substitution and conditional sections.
|
|
5
|
+
* Supports {variable} syntax and {#if}/{#each} directives.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface TemplateContext {
|
|
9
|
+
[key: string]: any;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface TemplateDirective {
|
|
13
|
+
type: 'if' | 'each' | 'variable';
|
|
14
|
+
condition?: string;
|
|
15
|
+
variable?: string;
|
|
16
|
+
content?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class TemplateEngine {
|
|
20
|
+
/**
|
|
21
|
+
* Render a template with the given context
|
|
22
|
+
*/
|
|
23
|
+
render(template: string, context: TemplateContext): string {
|
|
24
|
+
let result = template;
|
|
25
|
+
|
|
26
|
+
// Process conditional blocks first ({#if condition}...{/if})
|
|
27
|
+
result = this.processConditionals(result, context);
|
|
28
|
+
|
|
29
|
+
// Process each blocks ({#each items}...{/each})
|
|
30
|
+
result = this.processEach(result, context);
|
|
31
|
+
|
|
32
|
+
// Process variable substitutions ({variable})
|
|
33
|
+
result = this.processVariables(result, context);
|
|
34
|
+
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Process conditional blocks
|
|
40
|
+
*/
|
|
41
|
+
private processConditionals(template: string, context: TemplateContext): string {
|
|
42
|
+
const ifRegex = /\{#if\s+([^}]+)\}([\s\S]*?)\{\/if\}/g;
|
|
43
|
+
|
|
44
|
+
return template.replace(ifRegex, (match, condition, content) => {
|
|
45
|
+
if (this.evaluateCondition(condition.trim(), context)) {
|
|
46
|
+
return content;
|
|
47
|
+
}
|
|
48
|
+
return '';
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Process each blocks
|
|
54
|
+
*/
|
|
55
|
+
private processEach(template: string, context: TemplateContext): string {
|
|
56
|
+
const eachRegex = /\{#each\s+([^}]+)\}([\s\S]*?)\{\/each\}/g;
|
|
57
|
+
|
|
58
|
+
return template.replace(eachRegex, (match, variable, content) => {
|
|
59
|
+
const varName = variable.trim();
|
|
60
|
+
const items = this.resolveVariable(varName, context);
|
|
61
|
+
|
|
62
|
+
if (!Array.isArray(items)) {
|
|
63
|
+
return '';
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return items.map((item, index) => {
|
|
67
|
+
const itemContext = {
|
|
68
|
+
...context,
|
|
69
|
+
[varName.split('.').pop() || 'item']: item,
|
|
70
|
+
'@index': index,
|
|
71
|
+
'@first': index === 0,
|
|
72
|
+
'@last': index === items.length - 1
|
|
73
|
+
};
|
|
74
|
+
return this.processVariables(content, itemContext);
|
|
75
|
+
}).join('');
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Process variable substitutions
|
|
81
|
+
*/
|
|
82
|
+
private processVariables(template: string, context: TemplateContext): string {
|
|
83
|
+
const varRegex = /\{([^#\/][^}]*)\}/g;
|
|
84
|
+
|
|
85
|
+
return template.replace(varRegex, (match, variable) => {
|
|
86
|
+
const varName = variable.trim();
|
|
87
|
+
const value = this.resolveVariable(varName, context);
|
|
88
|
+
|
|
89
|
+
if (value === undefined || value === null) {
|
|
90
|
+
return '';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return String(value);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Evaluate a condition
|
|
99
|
+
*/
|
|
100
|
+
private evaluateCondition(condition: string, context: TemplateContext): boolean {
|
|
101
|
+
// Handle negation
|
|
102
|
+
if (condition.startsWith('!')) {
|
|
103
|
+
return !this.evaluateCondition(condition.substring(1).trim(), context);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Handle equality checks
|
|
107
|
+
if (condition.includes('==')) {
|
|
108
|
+
const [left, right] = condition.split('==').map(s => s.trim());
|
|
109
|
+
const leftValue = this.resolveVariable(left, context);
|
|
110
|
+
const rightValue = right.startsWith('"') || right.startsWith("'")
|
|
111
|
+
? right.slice(1, -1)
|
|
112
|
+
: this.resolveVariable(right, context);
|
|
113
|
+
return leftValue == rightValue;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Handle inequality checks
|
|
117
|
+
if (condition.includes('!=')) {
|
|
118
|
+
const [left, right] = condition.split('!=').map(s => s.trim());
|
|
119
|
+
const leftValue = this.resolveVariable(left, context);
|
|
120
|
+
const rightValue = right.startsWith('"') || right.startsWith("'")
|
|
121
|
+
? right.slice(1, -1)
|
|
122
|
+
: this.resolveVariable(right, context);
|
|
123
|
+
return leftValue != rightValue;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Simple truthiness check
|
|
127
|
+
const value = this.resolveVariable(condition, context);
|
|
128
|
+
return Boolean(value);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Resolve a variable from context (supports dot notation)
|
|
133
|
+
*/
|
|
134
|
+
private resolveVariable(path: string, context: TemplateContext): any {
|
|
135
|
+
const parts = path.split('.');
|
|
136
|
+
let value: any = context;
|
|
137
|
+
|
|
138
|
+
for (const part of parts) {
|
|
139
|
+
if (value === undefined || value === null) {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
value = value[part];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return value;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Validate template syntax
|
|
150
|
+
*/
|
|
151
|
+
validate(template: string): { valid: boolean; errors: string[] } {
|
|
152
|
+
const errors: string[] = [];
|
|
153
|
+
|
|
154
|
+
// Check for balanced {#if}/{/if} blocks
|
|
155
|
+
const ifMatches = template.match(/\{#if\s+[^}]+\}/g) || [];
|
|
156
|
+
const ifEndMatches = template.match(/\{\/if\}/g) || [];
|
|
157
|
+
if (ifMatches.length !== ifEndMatches.length) {
|
|
158
|
+
errors.push(`Unbalanced {#if}/{/if} blocks: ${ifMatches.length} opening, ${ifEndMatches.length} closing`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Check for balanced {#each}/{/each} blocks
|
|
162
|
+
const eachMatches = template.match(/\{#each\s+[^}]+\}/g) || [];
|
|
163
|
+
const eachEndMatches = template.match(/\{\/each\}/g) || [];
|
|
164
|
+
if (eachMatches.length !== eachEndMatches.length) {
|
|
165
|
+
errors.push(`Unbalanced {#each}/{/each} blocks: ${eachMatches.length} opening, ${eachEndMatches.length} closing`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Check for invalid directive syntax
|
|
169
|
+
const invalidDirectives = template.match(/\{#[^iefl][^}]*\}/g);
|
|
170
|
+
if (invalidDirectives) {
|
|
171
|
+
errors.push(`Invalid directives found: ${invalidDirectives.join(', ')}`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
valid: errors.length === 0,
|
|
176
|
+
errors
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Extract variables used in template
|
|
182
|
+
*/
|
|
183
|
+
extractVariables(template: string): string[] {
|
|
184
|
+
const variables = new Set<string>();
|
|
185
|
+
|
|
186
|
+
// Extract from variable substitutions
|
|
187
|
+
const varMatches = template.matchAll(/\{([^#\/][^}]*)\}/g);
|
|
188
|
+
for (const match of varMatches) {
|
|
189
|
+
const varName = match[1].trim().split('.')[0];
|
|
190
|
+
if (varName && !varName.startsWith('@')) {
|
|
191
|
+
variables.add(varName);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Extract from conditionals
|
|
196
|
+
const ifMatches = template.matchAll(/\{#if\s+([^}]+)\}/g);
|
|
197
|
+
for (const match of ifMatches) {
|
|
198
|
+
const condition = match[1].trim();
|
|
199
|
+
const varName = condition.split(/[!=\s]/)[0].trim();
|
|
200
|
+
if (varName && !varName.startsWith('!')) {
|
|
201
|
+
variables.add(varName);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Extract from each blocks
|
|
206
|
+
const eachMatches = template.matchAll(/\{#each\s+([^}]+)\}/g);
|
|
207
|
+
for (const match of eachMatches) {
|
|
208
|
+
const varName = match[1].trim().split('.')[0];
|
|
209
|
+
if (varName) {
|
|
210
|
+
variables.add(varName);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return Array.from(variables);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|