@documentation-robotics/cli 0.2.0 → 0.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/README.md +46 -16
- package/dist/analysis/relationship-classifier.js +2 -9
- package/dist/analysis/relationship-classifier.js.map +2 -2
- package/dist/analyzers/active-analyzer.js +62 -0
- package/dist/analyzers/active-analyzer.js.map +7 -0
- package/dist/analyzers/call-graph-utils.js +2 -2
- package/dist/analyzers/call-graph-utils.js.map +2 -2
- package/dist/analyzers/cards/build.js +191 -0
- package/dist/analyzers/cards/build.js.map +7 -0
- package/dist/analyzers/cards/classify.js +42 -0
- package/dist/analyzers/cards/classify.js.map +7 -0
- package/dist/analyzers/cards/edge-index.js +44 -0
- package/dist/analyzers/cards/edge-index.js.map +7 -0
- package/dist/analyzers/cards/extract.js +138 -0
- package/dist/analyzers/cards/extract.js.map +7 -0
- package/dist/analyzers/cards/facts.js +46 -0
- package/dist/analyzers/cards/facts.js.map +7 -0
- package/dist/analyzers/cards/graph.js +42 -0
- package/dist/analyzers/cards/graph.js.map +7 -0
- package/dist/analyzers/cards/index.js +8 -0
- package/dist/analyzers/cards/index.js.map +7 -0
- package/dist/analyzers/cards/routes.js +96 -0
- package/dist/analyzers/cards/routes.js.map +7 -0
- package/dist/analyzers/cards/tier0.js +18 -0
- package/dist/analyzers/cards/tier0.js.map +7 -0
- package/dist/analyzers/cards/types.js +1 -0
- package/dist/analyzers/cards/types.js.map +7 -0
- package/dist/analyzers/cbm-analyzer.js +270 -174
- package/dist/analyzers/cbm-analyzer.js.map +2 -2
- package/dist/analyzers/cbm-responses.js +342 -0
- package/dist/analyzers/cbm-responses.js.map +7 -0
- package/dist/analyzers/code-changes.js +159 -0
- package/dist/analyzers/code-changes.js.map +7 -0
- package/dist/analyzers/edge-relationships.js +49 -0
- package/dist/analyzers/edge-relationships.js.map +7 -0
- package/dist/analyzers/extraction-plan.js +541 -0
- package/dist/analyzers/extraction-plan.js.map +7 -0
- package/dist/analyzers/index-job.js +229 -0
- package/dist/analyzers/index-job.js.map +7 -0
- package/dist/analyzers/mapping-loader.js +9 -0
- package/dist/analyzers/mapping-loader.js.map +2 -2
- package/dist/analyzers/tier0-rules.js +153 -0
- package/dist/analyzers/tier0-rules.js.map +7 -0
- package/dist/analyzers/types.js.map +1 -1
- package/dist/audit/relationships/ai/prompts.js +10 -10
- package/dist/audit/relationships/ai/prompts.js.map +2 -2
- package/dist/audit/relationships/analysis/layer-templates.js +52 -52
- package/dist/audit/relationships/analysis/layer-templates.js.map +1 -1
- package/dist/cli.js +23 -11
- package/dist/cli.js.map +2 -2
- package/dist/coding-agents/default-permissions.js +31 -1
- package/dist/coding-agents/default-permissions.js.map +2 -2
- package/dist/coding-agents/drbot-mcp.js +269 -0
- package/dist/coding-agents/drbot-mcp.js.map +7 -0
- package/dist/commands/add.js +7 -4
- package/dist/commands/add.js.map +2 -2
- package/dist/commands/analyzer.js +143 -40
- package/dist/commands/analyzer.js.map +2 -2
- package/dist/commands/changeset-verify.js +63 -0
- package/dist/commands/changeset-verify.js.map +7 -0
- package/dist/commands/changeset.js +80 -29
- package/dist/commands/changeset.js.map +2 -2
- package/dist/commands/delete.js +10 -4
- package/dist/commands/delete.js.map +2 -2
- package/dist/commands/farm.js +176 -60
- package/dist/commands/farm.js.map +2 -2
- package/dist/commands/init.js +9 -26
- package/dist/commands/init.js.map +2 -2
- package/dist/commands/mcp.js +40 -21
- package/dist/commands/mcp.js.map +3 -3
- package/dist/commands/relationship.js +208 -37
- package/dist/commands/relationship.js.map +2 -2
- package/dist/commands/reports.js +3 -3
- package/dist/commands/reports.js.map +2 -2
- package/dist/commands/update.js +52 -32
- package/dist/commands/update.js.map +2 -2
- package/dist/commands/upgrade.js +99 -103
- package/dist/commands/upgrade.js.map +3 -3
- package/dist/commands/validate.js +19 -3
- package/dist/commands/validate.js.map +2 -2
- package/dist/commands/version.js +1 -1
- package/dist/commands/visualize.js +34 -15
- package/dist/commands/visualize.js.map +2 -2
- package/dist/core/annotation-store.js +15 -5
- package/dist/core/annotation-store.js.map +2 -2
- package/dist/core/catalog-migration.js +34 -0
- package/dist/core/catalog-migration.js.map +7 -0
- package/dist/core/changeset-analysis.js +421 -0
- package/dist/core/changeset-analysis.js.map +7 -0
- package/dist/core/changeset-base-index.js +160 -0
- package/dist/core/changeset-base-index.js.map +7 -0
- package/dist/core/changeset-brief-compact.js +256 -0
- package/dist/core/changeset-brief-compact.js.map +7 -0
- package/dist/core/changeset-brief-delta.js +102 -0
- package/dist/core/changeset-brief-delta.js.map +7 -0
- package/dist/core/changeset-graph.js +281 -0
- package/dist/core/changeset-graph.js.map +7 -0
- package/dist/core/changeset-only-guard.js +32 -0
- package/dist/core/changeset-only-guard.js.map +7 -0
- package/dist/core/changeset-summary.js +68 -0
- package/dist/core/changeset-summary.js.map +7 -0
- package/dist/core/changeset-validator.js +66 -20
- package/dist/core/changeset-validator.js.map +2 -2
- package/dist/core/changeset-verify.js +848 -0
- package/dist/core/changeset-verify.js.map +7 -0
- package/dist/core/changeset.js +56 -9
- package/dist/core/changeset.js.map +2 -2
- package/dist/core/element-type-migration.js +145 -0
- package/dist/core/element-type-migration.js.map +7 -0
- package/dist/core/extraction-observability.js +161 -0
- package/dist/core/extraction-observability.js.map +7 -0
- package/dist/core/farm-manifest.js +12 -6
- package/dist/core/farm-manifest.js.map +2 -2
- package/dist/core/farm-sync-engine.js +1 -1
- package/dist/core/farm-sync-engine.js.map +2 -2
- package/dist/core/farm-sync-state.js +10 -2
- package/dist/core/farm-sync-state.js.map +2 -2
- package/dist/core/migration-registry.js +88 -47
- package/dist/core/migration-registry.js.map +2 -2
- package/dist/core/model-upgrade.js +102 -0
- package/dist/core/model-upgrade.js.map +7 -0
- package/dist/core/model.js +82 -30
- package/dist/core/model.js.map +2 -2
- package/dist/core/mutation-handler.js +71 -6
- package/dist/core/mutation-handler.js.map +2 -2
- package/dist/core/project-init.js +53 -0
- package/dist/core/project-init.js.map +7 -0
- package/dist/core/relationship-migration-table.js +6639 -0
- package/dist/core/relationship-migration-table.js.map +7 -0
- package/dist/core/relationship-migration.js +272 -0
- package/dist/core/relationship-migration.js.map +7 -0
- package/dist/core/relationship-prune.js +49 -0
- package/dist/core/relationship-prune.js.map +7 -0
- package/dist/core/relationship-staging.js +161 -0
- package/dist/core/relationship-staging.js.map +7 -0
- package/dist/core/relationships.js +26 -4
- package/dist/core/relationships.js.map +2 -2
- package/dist/core/report-data-model.js +7 -13
- package/dist/core/report-data-model.js.map +2 -2
- package/dist/core/staged-changeset-storage.js +145 -18
- package/dist/core/staged-changeset-storage.js.map +2 -2
- package/dist/core/staged-source-reference.js +28 -0
- package/dist/core/staged-source-reference.js.map +7 -0
- package/dist/core/staging-area.js +166 -24
- package/dist/core/staging-area.js.map +2 -2
- package/dist/core/upgrade-plan.js +117 -0
- package/dist/core/upgrade-plan.js.map +7 -0
- package/dist/core/virtual-projection.js +13 -5
- package/dist/core/virtual-projection.js.map +2 -2
- package/dist/export/archimate-exporter.js +1 -0
- package/dist/export/archimate-exporter.js.map +2 -2
- package/dist/generated/compiled-validators.js +2 -2
- package/dist/generated/compiled-validators.js.map +2 -2
- package/dist/generated/layer-registry.js +16 -16
- package/dist/generated/layer-registry.js.map +2 -2
- package/dist/generated/node-types.js +186 -168
- package/dist/generated/node-types.js.map +2 -2
- package/dist/generated/relationship-index.js +2468 -7913
- package/dist/generated/relationship-index.js.map +2 -2
- package/dist/integrations/claude_code/.claude-plugin/plugin.json +24 -0
- package/dist/integrations/claude_code/agents/dr-architect.md +30 -3
- package/dist/integrations/claude_code/agents/dr-extractor.md +8 -2
- package/dist/integrations/claude_code/commands/dr-analyzer.md +565 -0
- package/dist/integrations/claude_code/commands/dr-changeset.md +2 -1
- package/dist/integrations/claude_code/commands/dr-map.md +20 -1
- package/dist/integrations/claude_code/commands/dr-plan.md +66 -0
- package/dist/integrations/claude_code/commands/dr-relate.md +106 -96
- package/dist/integrations/claude_code/commands/dr-verify.md +45 -2
- package/dist/integrations/claude_code/docs/END_TO_END_WALKTHROUGH.md +14 -0
- package/dist/integrations/claude_code/docs/MCP_SERVER.md +47 -26
- package/dist/integrations/claude_code/docs/QUICK_START.md +37 -8
- package/dist/integrations/claude_code/docs/README.md +68 -2
- package/dist/integrations/claude_code/plugin-agents/dr-advisor.md +255 -0
- package/dist/integrations/claude_code/plugin-agents/dr-architect.md +306 -0
- package/dist/integrations/claude_code/skills/dr_01_motivation_layer/SKILL.md +93 -72
- package/dist/integrations/claude_code/skills/dr_02_business_layer/SKILL.md +163 -126
- package/dist/integrations/claude_code/skills/dr_03_product_layer/SKILL.md +161 -126
- package/dist/integrations/claude_code/skills/dr_04_security_layer/SKILL.md +153 -133
- package/dist/integrations/claude_code/skills/dr_05_application_layer/SKILL.md +129 -100
- package/dist/integrations/claude_code/skills/dr_06_technology_layer/SKILL.md +111 -94
- package/dist/integrations/claude_code/skills/dr_07_api_layer/SKILL.md +143 -157
- package/dist/integrations/claude_code/skills/dr_08_data_model_layer/SKILL.md +117 -33
- package/dist/integrations/claude_code/skills/dr_09_dataset_layer/SKILL.md +74 -25
- package/dist/integrations/claude_code/skills/dr_10_ux_layer/SKILL.md +88 -12
- package/dist/integrations/claude_code/skills/dr_11_navigation_layer/SKILL.md +83 -24
- package/dist/integrations/claude_code/skills/dr_12_apm_layer/SKILL.md +57 -12
- package/dist/integrations/claude_code/skills/dr_13_testing_layer/SKILL.md +95 -15
- package/dist/integrations/claude_code/skills/dr_change_planning/SKILL.md +178 -0
- package/dist/integrations/claude_code/skills/dr_changeset_reviewer/SKILL.md +8 -0
- package/dist/integrations/claude_code/skills/dr_engineering_guide/SKILL.md +6 -1
- package/dist/integrations/github_copilot/agents/dr-architect.md +3 -1
- package/dist/integrations/github_copilot/skills/dr_01_motivation_layer/SKILL.md +182 -102
- package/dist/integrations/github_copilot/skills/dr_02_business_layer/SKILL.md +266 -148
- package/dist/integrations/github_copilot/skills/dr_03_product_layer/SKILL.md +547 -86
- package/dist/integrations/github_copilot/skills/dr_04_security_layer/SKILL.md +164 -169
- package/dist/integrations/github_copilot/skills/dr_05_application_layer/SKILL.md +420 -150
- package/dist/integrations/github_copilot/skills/dr_06_technology_layer/SKILL.md +331 -138
- package/dist/integrations/github_copilot/skills/dr_07_api_layer/SKILL.md +265 -201
- package/dist/integrations/github_copilot/skills/dr_08_data_model_layer/SKILL.md +181 -58
- package/dist/integrations/github_copilot/skills/dr_09_dataset_layer/SKILL.md +209 -57
- package/dist/integrations/github_copilot/skills/dr_10_ux_layer/SKILL.md +277 -112
- package/dist/integrations/github_copilot/skills/dr_11_navigation_layer/SKILL.md +219 -70
- package/dist/integrations/github_copilot/skills/dr_12_apm_layer/SKILL.md +189 -105
- package/dist/integrations/github_copilot/skills/dr_13_testing_layer/SKILL.md +225 -102
- package/dist/integrations/github_copilot/skills/dr_change_planning/SKILL.md +177 -0
- package/dist/integrations/github_copilot/skills/dr_changeset_reviewer/SKILL.md +3 -0
- package/dist/integrations/hash-utils.js.map +2 -2
- package/dist/mcp/api-key-manager.js +14 -1
- package/dist/mcp/api-key-manager.js.map +2 -2
- package/dist/mcp/changeset-only.js +45 -0
- package/dist/mcp/changeset-only.js.map +7 -0
- package/dist/mcp/project-root.js +85 -0
- package/dist/mcp/project-root.js.map +7 -0
- package/dist/mcp/server-instructions.js +27 -0
- package/dist/mcp/server-instructions.js.map +7 -0
- package/dist/mcp/strict-schema.js +52 -0
- package/dist/mcp/strict-schema.js.map +7 -0
- package/dist/mcp/tool-registry.js +55 -5
- package/dist/mcp/tool-registry.js.map +2 -2
- package/dist/mcp/tools/changeset-analysis-tools.js +98 -0
- package/dist/mcp/tools/changeset-analysis-tools.js.map +7 -0
- package/dist/mcp/tools/changeset-commit.js +224 -0
- package/dist/mcp/tools/changeset-commit.js.map +7 -0
- package/dist/mcp/tools/changeset-editing.js +260 -0
- package/dist/mcp/tools/changeset-editing.js.map +7 -0
- package/dist/mcp/tools/changeset-lifecycle.js +83 -0
- package/dist/mcp/tools/changeset-lifecycle.js.map +7 -0
- package/dist/mcp/tools/changeset-shared.js +31 -0
- package/dist/mcp/tools/changeset-shared.js.map +7 -0
- package/dist/mcp/tools/changeset-show.js +17 -1
- package/dist/mcp/tools/changeset-show.js.map +2 -2
- package/dist/mcp/tools/changeset-verify.js +49 -0
- package/dist/mcp/tools/changeset-verify.js.map +7 -0
- package/dist/mcp/tools/codebase-extract.js +836 -0
- package/dist/mcp/tools/codebase-extract.js.map +7 -0
- package/dist/mcp/tools/codebase-index.js +125 -0
- package/dist/mcp/tools/codebase-index.js.map +7 -0
- package/dist/mcp/tools/codebase-shared.js +265 -0
- package/dist/mcp/tools/codebase-shared.js.map +7 -0
- package/dist/mcp/tools/codebase-verify.js +48 -0
- package/dist/mcp/tools/codebase-verify.js.map +7 -0
- package/dist/mcp/tools/index.js +34 -1
- package/dist/mcp/tools/index.js.map +2 -2
- package/dist/mcp/tools/model-add.js +191 -74
- package/dist/mcp/tools/model-add.js.map +2 -2
- package/dist/mcp/tools/model-delete.js +2 -2
- package/dist/mcp/tools/model-delete.js.map +2 -2
- package/dist/mcp/tools/model-search.js +14 -0
- package/dist/mcp/tools/model-search.js.map +2 -2
- package/dist/mcp/tools/model-show.js +29 -2
- package/dist/mcp/tools/model-show.js.map +2 -2
- package/dist/mcp/tools/model-trace.js +93 -30
- package/dist/mcp/tools/model-trace.js.map +2 -2
- package/dist/mcp/tools/model-update.js +46 -26
- package/dist/mcp/tools/model-update.js.map +2 -2
- package/dist/mcp/tools/model-validate.js +46 -4
- package/dist/mcp/tools/model-validate.js.map +2 -2
- package/dist/mcp/tools/project-status-collectors.js +381 -0
- package/dist/mcp/tools/project-status-collectors.js.map +7 -0
- package/dist/mcp/tools/project-status.js +237 -0
- package/dist/mcp/tools/project-status.js.map +7 -0
- package/dist/mcp/tools/project-tools.js +505 -0
- package/dist/mcp/tools/project-tools.js.map +7 -0
- package/dist/mcp/tools/relationship-tools.js +167 -0
- package/dist/mcp/tools/relationship-tools.js.map +7 -0
- package/dist/mcp/tools/review-open.js +210 -0
- package/dist/mcp/tools/review-open.js.map +7 -0
- package/dist/mcp/tools/shared.js +35 -4
- package/dist/mcp/tools/shared.js.map +2 -2
- package/dist/mcp/tools/spec-type.js +90 -0
- package/dist/mcp/tools/spec-type.js.map +7 -0
- package/dist/reports/model-report-orchestrator.js +31 -2
- package/dist/reports/model-report-orchestrator.js.map +2 -2
- package/dist/schemas/bundled/analyzers/cbm.json +1200 -70
- package/dist/schemas/bundled/analyzers/manifest.json +2 -2
- package/dist/schemas/bundled/api.json +1029 -1658
- package/dist/schemas/bundled/apm.json +499 -734
- package/dist/schemas/bundled/application.json +735 -371
- package/dist/schemas/bundled/base.json +3 -220
- package/dist/schemas/bundled/business.json +452 -366
- package/dist/schemas/bundled/data-model.json +395 -411
- package/dist/schemas/bundled/data-store.json +334 -558
- package/dist/schemas/bundled/manifest.json +18 -18
- package/dist/schemas/bundled/motivation.json +349 -368
- package/dist/schemas/bundled/navigation.json +415 -731
- package/dist/schemas/bundled/product.json +325 -159
- package/dist/schemas/bundled/security.json +864 -1232
- package/dist/schemas/bundled/technology.json +574 -703
- package/dist/schemas/bundled/testing.json +865 -1646
- package/dist/schemas/bundled/ux.json +739 -1352
- package/dist/server/schemas.js +8 -0
- package/dist/server/schemas.js.map +2 -2
- package/dist/server/server.js +686 -231
- package/dist/server/server.js.map +3 -3
- package/dist/server/viewer-registry.js +264 -0
- package/dist/server/viewer-registry.js.map +7 -0
- package/dist/server-entry.js +2 -1
- package/dist/server-entry.js.map +2 -2
- package/dist/telemetry/index.js +1 -1
- package/dist/utils/ansi-suppressor.js +6 -8
- package/dist/utils/ansi-suppressor.js.map +2 -2
- package/dist/utils/attribute-patch.js +41 -0
- package/dist/utils/attribute-patch.js.map +7 -0
- package/dist/utils/error-hints.js +29 -0
- package/dist/utils/error-hints.js.map +7 -0
- package/dist/utils/errors.js +9 -3
- package/dist/utils/errors.js.map +2 -2
- package/dist/utils/id-generator.js +5 -2
- package/dist/utils/id-generator.js.map +2 -2
- package/dist/utils/project-paths.js +26 -1
- package/dist/utils/project-paths.js.map +2 -2
- package/dist/utils/source-reference.js +64 -31
- package/dist/utils/source-reference.js.map +2 -2
- package/dist/utils/spec-version.js +2 -2
- package/dist/utils/spec-version.js.map +1 -1
- package/dist/validators/composed-reference-validator.js +5 -27
- package/dist/validators/composed-reference-validator.js.map +2 -2
- package/dist/validators/model-warnings.js +28 -0
- package/dist/validators/model-warnings.js.map +7 -0
- package/dist/validators/reference-validator.js +0 -7
- package/dist/validators/reference-validator.js.map +2 -2
- package/dist/validators/relationship-schema-validator.js +3 -3
- package/dist/validators/relationship-schema-validator.js.map +2 -2
- package/dist/validators/schema-validator.js +27 -9
- package/dist/validators/schema-validator.js.map +2 -2
- package/dist/validators/types.js.map +1 -1
- package/dist/viewer/README.md +6 -6
- package/dist/viewer/assets/main-CUOQGGRA.css +1 -0
- package/dist/viewer/assets/main-DvH3gYrI.js +84 -0
- package/dist/viewer/index.html +2 -2
- package/dist/viewer/manifest.json +10 -10
- package/dist/viewer/version.json +1 -1
- package/package.json +2 -1
- package/dist/viewer/assets/main-B7AOQXXX.js +0 -81
- package/dist/viewer/assets/main-vdrFrG7q.css +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/validators/schema-validator.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Schema validation using AJV\n *\n * Validates model elements against their corresponding spec node schemas.\n * Each element type has a dedicated schema in spec/schemas/nodes/{layer}/{type}.node.schema.json\n */\n\nimport Ajv, { ValidateFunction, ErrorObject } from \"ajv\";\nimport addFormats from \"ajv-formats\";\nimport { ValidationResult } from \"./types.js\";\nimport type { Layer } from \"../core/layer.js\";\nimport type { Element } from \"../core/element.js\";\nimport { fileURLToPath } from \"url\";\nimport path from \"path\";\nimport { readFile } from \"../utils/file-io.js\";\nimport { startActiveSpan } from \"../telemetry/index.js\";\nimport { existsSync } from \"fs\";\nimport {\n validateSpecNode,\n validateSpecNodeRelationship,\n validateSourceReference,\n validateAttributeSpec,\n} from \"../generated/compiled-validators.js\";\n\n// Fallback for runtime environments where TELEMETRY_ENABLED is not defined by esbuild\ndeclare const TELEMETRY_ENABLED: boolean | undefined;\nconst isTelemetryEnabled = typeof TELEMETRY_ENABLED !== \"undefined\" ? TELEMETRY_ENABLED : false;\n\n/**\n * Validator for JSON Schema compliance\n *\n * Validates model elements against spec node schemas. Each element is validated\n * against its type-specific schema (e.g., motivation.goal elements validate against\n * spec/schemas/nodes/motivation/goal.node.schema.json).\n */\nexport class SchemaValidator {\n // Static shared AJV instance to avoid schema registry conflicts\n // When multiple SchemaValidator instances are created, they all use the same\n // AJV instance which maintains a single schema registry. This prevents\n // \"schema with key or id already exists\" errors when loading the same schemas.\n private static sharedAjv: Ajv | null = null;\n private static baseSchemaLoadedInSharedInstance: boolean = false;\n // Track schema IDs already registered in the shared AJV instance to avoid re-registering\n private static registeredSchemaIds: Set<string> = new Set();\n // Layer-level cache: layer ID \u2192 nodeSchemas map (avoids re-reading layer dist files)\n private static layerCache: Map<string, Record<string, unknown>> = new Map();\n\n private ajv: Ajv;\n private compiledSchemas: Map<string, ValidateFunction> = new Map(); // Key: layer.type\n private bundledDir: string;\n\n constructor() {\n // Initialize shared AJV instance once\n if (!SchemaValidator.sharedAjv) {\n SchemaValidator.sharedAjv = new Ajv({\n allErrors: true,\n strict: false,\n validateFormats: true,\n verbose: true,\n });\n addFormats(SchemaValidator.sharedAjv);\n }\n this.ajv = SchemaValidator.sharedAjv;\n\n // Determine bundled directory (compiled spec dist files)\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n this.bundledDir = path.join(__dirname, \"..\", \"schemas\", \"bundled\");\n }\n\n /**\n * Extract error message from unknown error type with proper type checking\n */\n private static getErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n const msg = (error as Record<string, unknown>).message;\n if (typeof msg === \"string\") {\n return msg;\n }\n }\n return \"Unknown error\";\n }\n\n /**\n * Ensure base schemas are pre-compiled validators are initialized\n * Loads base schemas from base.json and registers them with AJV for reference resolution.\n * This allows per-type schemas to resolve $ref to base schemas during compilation.\n */\n private async ensureBaseSchemaLoaded(): Promise<void> {\n // Check if already loaded in the shared AJV instance (applies to all instances)\n if (SchemaValidator.baseSchemaLoadedInSharedInstance) {\n return;\n }\n\n // Register pre-compiled validators with AJV\n this.compiledSchemas.set(\"spec-node\", validateSpecNode);\n this.compiledSchemas.set(\"spec-node-relationship\", validateSpecNodeRelationship);\n this.compiledSchemas.set(\"source-references\", validateSourceReference);\n this.compiledSchemas.set(\"attribute-spec\", validateAttributeSpec);\n\n // Load base.json and register all schemas with AJV for $ref resolution\n // Schemas use URN-style $ids like \"urn:dr:spec:base:spec-node\" after compilation\n const baseJsonPath = path.join(this.bundledDir, \"base.json\");\n try {\n const baseContent = await readFile(baseJsonPath);\n const baseData = JSON.parse(baseContent) as {\n specVersion: string;\n schemas: Record<string, unknown>;\n predicates: unknown;\n };\n\n for (const [key, schema] of Object.entries(baseData.schemas)) {\n const s = schema as Record<string, unknown>;\n const schemaId = (s.$id as string) || `urn:dr:spec:base:${key}`;\n\n // Skip if already registered\n if (SchemaValidator.registeredSchemaIds.has(schemaId)) {\n continue;\n }\n\n try {\n this.ajv.addSchema(s, schemaId);\n SchemaValidator.registeredSchemaIds.add(schemaId);\n } catch (error: unknown) {\n const errorMsg = SchemaValidator.getErrorMessage(error);\n const isDuplicateSchemaError = /schema with key or id [^ ]+ already exists/.test(errorMsg);\n if (isDuplicateSchemaError) {\n SchemaValidator.registeredSchemaIds.add(schemaId);\n } else {\n console.warn(`[SCHEMA-LOAD-001] Failed to register base schema '${key}': ${errorMsg}`);\n }\n }\n }\n } catch (error: unknown) {\n console.warn(\n `[SCHEMA-LOAD-001] Failed to load base.json from ${baseJsonPath}: ${SchemaValidator.getErrorMessage(error)}`\n );\n }\n\n // Mark base schemas as loaded in shared instance (applies to all instances)\n SchemaValidator.baseSchemaLoadedInSharedInstance = true;\n }\n\n /**\n * Load the nodeSchemas map for a layer, using a static layer-level cache.\n * Reads bundled/{layer}.json once per layer and caches the nodeSchemas object.\n */\n private async loadLayerNodeSchemas(layer: string): Promise<Record<string, unknown> | null> {\n // Return cached layer schemas if available\n if (SchemaValidator.layerCache.has(layer)) {\n return SchemaValidator.layerCache.get(layer)!;\n }\n\n const layerPath = path.join(this.bundledDir, `${layer}.json`);\n if (!existsSync(layerPath)) {\n return null;\n }\n\n try {\n const content = await readFile(layerPath);\n const layerData = JSON.parse(content) as { nodeSchemas: Record<string, unknown> };\n const nodeSchemas = layerData.nodeSchemas || {};\n SchemaValidator.layerCache.set(layer, nodeSchemas);\n return nodeSchemas;\n } catch (error: unknown) {\n console.warn(\n `[SCHEMA-LOAD-002] Failed to load layer file for '${layer}': ${SchemaValidator.getErrorMessage(error)}`\n );\n return null;\n }\n }\n\n /**\n * Load and compile a spec node schema for a specific element type\n */\n private async loadSpecNodeSchema(layer: string, type: string): Promise<ValidateFunction | null> {\n const cacheKey = `${layer}.${type}`;\n\n // Check compiled schema cache first\n if (this.compiledSchemas.has(cacheKey)) {\n return this.compiledSchemas.get(cacheKey)!;\n }\n\n // Ensure base schemas are loaded first (required for reference resolution)\n await this.ensureBaseSchemaLoaded();\n\n try {\n // Load node schemas from layer dist file (layer-level cache)\n const nodeSchemas = await this.loadLayerNodeSchemas(layer);\n if (!nodeSchemas || !nodeSchemas[type]) {\n // No schema for this type - acceptable for custom types\n return null;\n }\n\n const schema = nodeSchemas[type] as Record<string, unknown>;\n const schemaId = (schema.$id as string) || `urn:dr:spec:node:${layer}.${type}`;\n\n // Check if schema with this $id is already registered to avoid duplicate compilation\n if (SchemaValidator.registeredSchemaIds.has(schemaId)) {\n // Schema already registered \u2014 return from compiled cache or null (fallback to base)\n return this.compiledSchemas.get(cacheKey) || null;\n }\n\n try {\n const validate = this.ajv.compile(schema);\n this.compiledSchemas.set(cacheKey, validate);\n SchemaValidator.registeredSchemaIds.add(schemaId);\n return validate;\n } catch (registrationError: unknown) {\n const errorMsg = SchemaValidator.getErrorMessage(registrationError);\n if (errorMsg.includes(\"already exists\")) {\n SchemaValidator.registeredSchemaIds.add(schemaId);\n return null;\n }\n throw registrationError;\n }\n } catch (error: unknown) {\n const errorMsg = SchemaValidator.getErrorMessage(error);\n if (errorMsg.includes(\"can't resolve reference\")) {\n return null;\n }\n console.warn(`[SCHEMA-LOAD-002] Failed to load spec node schema for ${layer}.${type}: ${errorMsg}`);\n return null;\n }\n }\n\n /**\n * Validate a layer against its spec node schemas\n *\n * This validates each element in the layer against its corresponding spec node schema.\n */\n async validateLayer(layer: Layer): Promise<ValidationResult> {\n return startActiveSpan(\n \"schema.validate\",\n async (span) => {\n const result = new ValidationResult();\n let validatedCount = 0;\n let skippedCount = 0;\n\n // Validate each element individually\n for (const element of layer.elements.values()) {\n const elementResult = await this.validateElement(element, layer.name);\n\n if (elementResult.hasErrors) {\n // Add element-specific errors to layer result\n for (const error of elementResult.errors) {\n result.addError({\n layer: layer.name,\n elementId: element.path || element.id,\n message: error.message,\n location: error.location,\n fixSuggestion: error.fixSuggestion,\n });\n }\n }\n\n if (elementResult.validated) {\n validatedCount++;\n } else {\n skippedCount++;\n }\n }\n\n if (isTelemetryEnabled) {\n span.setAttribute(\"schema.valid\", result.isValid());\n span.setAttribute(\"schema.error_count\", result.errors.length);\n span.setAttribute(\"schema.validated_count\", validatedCount);\n span.setAttribute(\"schema.skipped_count\", skippedCount);\n }\n\n return result;\n },\n { \"schema.layer\": layer.name }\n );\n }\n\n /**\n * Validate a single element against its spec node schema\n */\n private async validateElement(element: Element, layerName: string): Promise<{\n validated: boolean;\n hasErrors: boolean;\n errors: Array<{ message: string; location: string; fixSuggestion?: string }>;\n }> {\n const result = {\n validated: false,\n hasErrors: false,\n errors: [] as Array<{ message: string; location: string; fixSuggestion?: string }>,\n };\n\n const specNode = element.toSpecNode();\n\n // First: Validate against base spec-node schema using pre-compiled validator\n // This ensures all elements conform to the base structure before type-specific validation\n await this.ensureBaseSchemaLoaded();\n const baseValid = validateSpecNode(specNode);\n\n if (!baseValid && validateSpecNode.errors) {\n result.hasErrors = true;\n result.validated = true;\n for (const error of validateSpecNode.errors) {\n result.errors.push({\n message: `Element '${element.path || element.id}': ${this.formatAjvError(error)}`,\n location: error.instancePath || \"/\",\n fixSuggestion: this.generateFixSuggestion(error),\n });\n }\n return result; // Fail fast on base schema violation\n }\n\n // Second: Load and validate against type-specific schema (lazy-loaded)\n const validate = await this.loadSpecNodeSchema(layerName, element.type);\n\n if (!validate) {\n // No type-specific schema found - base schema validation passed\n // This is acceptable for custom types or types without schemas yet\n result.validated = true;\n return result;\n }\n\n result.validated = true;\n\n // Validate element against type-specific schema\n const typeValid = validate(specNode);\n\n if (!typeValid && validate.errors) {\n result.hasErrors = true;\n for (const error of validate.errors) {\n result.errors.push({\n message: `Element '${element.path || element.id}': ${this.formatAjvError(error)}`,\n location: error.instancePath || \"/\",\n fixSuggestion: this.generateFixSuggestion(error),\n });\n }\n }\n\n return result;\n }\n\n /**\n * Format AJV error message\n */\n private formatAjvError(error: ErrorObject): string {\n const keyword = error.keyword;\n const dataPath = error.instancePath || \"/\";\n\n switch (keyword) {\n case \"type\":\n return `At ${dataPath}: expected ${error.params?.type}, got ${error.data === null ? \"null\" : typeof error.data}`;\n case \"required\":\n return `At ${dataPath}: missing required property '${error.params?.missingProperty}'`;\n case \"enum\":\n return `At ${dataPath}: value must be one of [${error.params?.allowedValues?.join(\", \")}]`;\n case \"pattern\":\n return `At ${dataPath}: value must match pattern ${error.params?.pattern}`;\n case \"minLength\":\n return `At ${dataPath}: string must be at least ${error.params?.limit} characters`;\n case \"maxLength\":\n return `At ${dataPath}: string must be at most ${error.params?.limit} characters`;\n case \"minimum\":\n return `At ${dataPath}: value must be >= ${error.params?.limit}`;\n case \"maximum\":\n return `At ${dataPath}: value must be <= ${error.params?.limit}`;\n case \"additionalProperties\":\n return `At ${dataPath}: unexpected property '${error.params?.additionalProperty}'`;\n case \"const\":\n return `At ${dataPath}: value must be ${JSON.stringify(error.params?.allowedValue)}`;\n default:\n return error.message || `Validation failed`;\n }\n }\n\n /**\n * Generate a fix suggestion based on the error\n */\n private generateFixSuggestion(error: ErrorObject): string | undefined {\n const keyword = error.keyword;\n\n switch (keyword) {\n case \"required\":\n return `Add required field: ${error.params?.missingProperty}`;\n case \"type\":\n return `Expected type ${error.params?.type}`;\n case \"enum\":\n return `Use one of: ${error.params?.allowedValues?.join(\", \")}`;\n case \"pattern\":\n return `Value must match pattern: ${error.params?.pattern}`;\n case \"additionalProperties\":\n return `Remove unexpected property: ${error.params?.additionalProperty}`;\n case \"const\":\n return `Value must be exactly: ${JSON.stringify(error.params?.allowedValue)}`;\n default:\n return undefined;\n }\n }\n\n /**\n * Reset static state for test isolation\n *\n * Clears the shared AJV instance and schema registry, allowing tests\n * to load schemas from a clean state without conflicts.\n *\n * Usage (in test setup):\n * beforeEach(() => {\n * SchemaValidator.reset();\n * });\n */\n static reset(): void {\n SchemaValidator.sharedAjv = null;\n SchemaValidator.baseSchemaLoadedInSharedInstance = false;\n SchemaValidator.registeredSchemaIds.clear();\n SchemaValidator.layerCache.clear();\n }\n}\n"],
|
|
5
|
-
"mappings": "AAOA,OAAO,SAA4C;AACnD,OAAO,gBAAgB;AACvB,SAAS,wBAAwB;AAGjC,SAAS,qBAAqB;AAC9B,OAAO,UAAU;AACjB,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAChC,SAAS,kBAAkB;AAC3B,SACE,kBACA,8BACA,yBACA,6BACK;
|
|
4
|
+
"sourcesContent": ["/**\n * Schema validation using AJV\n *\n * Validates model elements against their corresponding spec node schemas.\n * Each element type has a dedicated schema in spec/schemas/nodes/{layer}/{type}.node.schema.json\n */\n\nimport Ajv, { ValidateFunction, ErrorObject } from \"ajv\";\nimport addFormats from \"ajv-formats\";\nimport { ValidationResult } from \"./types.js\";\nimport type { Layer } from \"../core/layer.js\";\nimport type { Element } from \"../core/element.js\";\nimport { fileURLToPath } from \"url\";\nimport path from \"path\";\nimport { readFile } from \"../utils/file-io.js\";\nimport { startActiveSpan } from \"../telemetry/index.js\";\nimport { existsSync } from \"fs\";\nimport {\n validateSpecNode,\n validateSpecNodeRelationship,\n validateSourceReference,\n validateAttributeSpec,\n} from \"../generated/compiled-validators.js\";\nimport { isValidLayer } from \"../generated/layer-registry.js\";\nimport { getNodeTypesForLayer, isValidNodeType } from \"../generated/node-types.js\";\nimport { findSimilar } from \"../utils/errors.js\";\n\n/**\n * Types in `layer` that `type` may have meant: close spellings, and names that contain it or that\n * it contains (an obsolete `capability` \u2192 `softwarecapability`).\n */\nexport function suggestNodeTypes(layer: string, type: string): string[] {\n const names = getNodeTypesForLayer(layer).map((t) => t.type);\n const lower = type.toLowerCase();\n const containing =\n lower.length >= 4\n ? names.filter((name) => name !== lower && (name.includes(lower) || lower.includes(name)))\n : [];\n return Array.from(new Set([...findSimilar(type, names, 3), ...containing])).slice(0, 3);\n}\n\n// Fallback for runtime environments where TELEMETRY_ENABLED is not defined by esbuild\ndeclare const TELEMETRY_ENABLED: boolean | undefined;\nconst isTelemetryEnabled = typeof TELEMETRY_ENABLED !== \"undefined\" ? TELEMETRY_ENABLED : false;\n\n/**\n * Validator for JSON Schema compliance\n *\n * Validates model elements against spec node schemas. Each element is validated\n * against its type-specific schema (e.g., motivation.goal elements validate against\n * spec/schemas/nodes/motivation/goal.node.schema.json).\n */\nexport class SchemaValidator {\n // Static shared AJV instance to avoid schema registry conflicts\n // When multiple SchemaValidator instances are created, they all use the same\n // AJV instance which maintains a single schema registry. This prevents\n // \"schema with key or id already exists\" errors when loading the same schemas.\n private static sharedAjv: Ajv | null = null;\n private static baseSchemaLoadedInSharedInstance: boolean = false;\n // Track schema IDs already registered in the shared AJV instance to avoid re-registering\n private static registeredSchemaIds: Set<string> = new Set();\n // Layer-level cache: layer ID \u2192 nodeSchemas map (avoids re-reading layer dist files)\n private static layerCache: Map<string, Record<string, unknown>> = new Map();\n\n // Compiled node schemas, keyed by layer.type. Shared like the AJV instance they were compiled\n // in: registeredSchemaIds is static, so a per-instance cache would leave every later instance\n // with a registered id and no validator, and it would silently fall back to the base schema.\n private static compiledSchemas: Map<string, ValidateFunction> = new Map();\n\n private ajv: Ajv;\n private bundledDir: string;\n\n constructor() {\n // Initialize shared AJV instance once\n if (!SchemaValidator.sharedAjv) {\n SchemaValidator.sharedAjv = new Ajv({\n allErrors: true,\n strict: false,\n validateFormats: true,\n verbose: true,\n });\n addFormats(SchemaValidator.sharedAjv);\n }\n this.ajv = SchemaValidator.sharedAjv;\n\n // Determine bundled directory (compiled spec dist files)\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n this.bundledDir = path.join(__dirname, \"..\", \"schemas\", \"bundled\");\n }\n\n /**\n * Extract error message from unknown error type with proper type checking\n */\n private static getErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n const msg = (error as Record<string, unknown>).message;\n if (typeof msg === \"string\") {\n return msg;\n }\n }\n return \"Unknown error\";\n }\n\n /**\n * Ensure base schemas are pre-compiled validators are initialized\n * Loads base schemas from base.json and registers them with AJV for reference resolution.\n * This allows per-type schemas to resolve $ref to base schemas during compilation.\n */\n private async ensureBaseSchemaLoaded(): Promise<void> {\n // Check if already loaded in the shared AJV instance (applies to all instances)\n if (SchemaValidator.baseSchemaLoadedInSharedInstance) {\n return;\n }\n\n // Register pre-compiled validators with AJV\n SchemaValidator.compiledSchemas.set(\"spec-node\", validateSpecNode);\n SchemaValidator.compiledSchemas.set(\"spec-node-relationship\", validateSpecNodeRelationship);\n SchemaValidator.compiledSchemas.set(\"source-references\", validateSourceReference);\n SchemaValidator.compiledSchemas.set(\"attribute-spec\", validateAttributeSpec);\n\n // Load base.json and register all schemas with AJV for $ref resolution\n // Schemas use URN-style $ids like \"urn:dr:spec:base:spec-node\" after compilation\n const baseJsonPath = path.join(this.bundledDir, \"base.json\");\n try {\n const baseContent = await readFile(baseJsonPath);\n const baseData = JSON.parse(baseContent) as {\n specVersion: string;\n schemas: Record<string, unknown>;\n predicates: unknown;\n };\n\n for (const [key, schema] of Object.entries(baseData.schemas)) {\n const s = schema as Record<string, unknown>;\n const schemaId = (s.$id as string) || `urn:dr:spec:base:${key}`;\n\n // Skip if already registered\n if (SchemaValidator.registeredSchemaIds.has(schemaId)) {\n continue;\n }\n\n try {\n this.ajv.addSchema(s, schemaId);\n SchemaValidator.registeredSchemaIds.add(schemaId);\n } catch (error: unknown) {\n const errorMsg = SchemaValidator.getErrorMessage(error);\n const isDuplicateSchemaError = /schema with key or id [^ ]+ already exists/.test(errorMsg);\n if (isDuplicateSchemaError) {\n SchemaValidator.registeredSchemaIds.add(schemaId);\n } else {\n console.warn(`[SCHEMA-LOAD-001] Failed to register base schema '${key}': ${errorMsg}`);\n }\n }\n }\n } catch (error: unknown) {\n console.warn(\n `[SCHEMA-LOAD-001] Failed to load base.json from ${baseJsonPath}: ${SchemaValidator.getErrorMessage(error)}`\n );\n }\n\n // Mark base schemas as loaded in shared instance (applies to all instances)\n SchemaValidator.baseSchemaLoadedInSharedInstance = true;\n }\n\n /**\n * Load the nodeSchemas map for a layer, using a static layer-level cache.\n * Reads bundled/{layer}.json once per layer and caches the nodeSchemas object.\n */\n private async loadLayerNodeSchemas(layer: string): Promise<Record<string, unknown> | null> {\n // Return cached layer schemas if available\n if (SchemaValidator.layerCache.has(layer)) {\n return SchemaValidator.layerCache.get(layer)!;\n }\n\n const layerPath = path.join(this.bundledDir, `${layer}.json`);\n if (!existsSync(layerPath)) {\n return null;\n }\n\n try {\n const content = await readFile(layerPath);\n const layerData = JSON.parse(content) as { nodeSchemas: Record<string, unknown> };\n const nodeSchemas = layerData.nodeSchemas || {};\n SchemaValidator.layerCache.set(layer, nodeSchemas);\n return nodeSchemas;\n } catch (error: unknown) {\n console.warn(\n `[SCHEMA-LOAD-002] Failed to load layer file for '${layer}': ${SchemaValidator.getErrorMessage(error)}`\n );\n return null;\n }\n }\n\n /**\n * Load and compile a spec node schema for a specific element type\n */\n private async loadSpecNodeSchema(layer: string, type: string): Promise<ValidateFunction | null> {\n const cacheKey = `${layer}.${type}`;\n\n // Check compiled schema cache first\n if (SchemaValidator.compiledSchemas.has(cacheKey)) {\n return SchemaValidator.compiledSchemas.get(cacheKey)!;\n }\n\n // Ensure base schemas are loaded first (required for reference resolution)\n await this.ensureBaseSchemaLoaded();\n\n try {\n // Load node schemas from layer dist file (layer-level cache)\n const nodeSchemas = await this.loadLayerNodeSchemas(layer);\n if (!nodeSchemas || !nodeSchemas[type]) {\n // No schema for this type - acceptable for custom types\n return null;\n }\n\n const schema = nodeSchemas[type] as Record<string, unknown>;\n const schemaId = (schema.$id as string) || `urn:dr:spec:node:${layer}.${type}`;\n\n // Check if schema with this $id is already registered to avoid duplicate compilation\n if (SchemaValidator.registeredSchemaIds.has(schemaId)) {\n // Schema already registered \u2014 return from compiled cache or null (fallback to base)\n return SchemaValidator.compiledSchemas.get(cacheKey) || null;\n }\n\n try {\n const validate = this.ajv.compile(schema);\n SchemaValidator.compiledSchemas.set(cacheKey, validate);\n SchemaValidator.registeredSchemaIds.add(schemaId);\n return validate;\n } catch (registrationError: unknown) {\n const errorMsg = SchemaValidator.getErrorMessage(registrationError);\n if (errorMsg.includes(\"already exists\")) {\n SchemaValidator.registeredSchemaIds.add(schemaId);\n return null;\n }\n throw registrationError;\n }\n } catch (error: unknown) {\n const errorMsg = SchemaValidator.getErrorMessage(error);\n if (errorMsg.includes(\"can't resolve reference\")) {\n return null;\n }\n console.warn(`[SCHEMA-LOAD-002] Failed to load spec node schema for ${layer}.${type}: ${errorMsg}`);\n return null;\n }\n }\n\n /**\n * Validate a layer against its spec node schemas\n *\n * This validates each element in the layer against its corresponding spec node schema.\n */\n async validateLayer(layer: Layer): Promise<ValidationResult> {\n return startActiveSpan(\n \"schema.validate\",\n async (span) => {\n const result = new ValidationResult();\n let validatedCount = 0;\n let skippedCount = 0;\n\n // Validate each element individually\n for (const element of layer.elements.values()) {\n const elementResult = await this.validateElement(element, layer.name);\n\n if (elementResult.hasErrors) {\n // Add element-specific errors to layer result\n for (const error of elementResult.errors) {\n result.addError({\n layer: layer.name,\n elementId: element.path || element.id,\n message: error.message,\n location: error.location,\n fixSuggestion: error.fixSuggestion,\n });\n }\n }\n\n if (elementResult.validated) {\n validatedCount++;\n } else {\n skippedCount++;\n }\n }\n\n if (isTelemetryEnabled) {\n span.setAttribute(\"schema.valid\", result.isValid());\n span.setAttribute(\"schema.error_count\", result.errors.length);\n span.setAttribute(\"schema.validated_count\", validatedCount);\n span.setAttribute(\"schema.skipped_count\", skippedCount);\n }\n\n return result;\n },\n { \"schema.layer\": layer.name }\n );\n }\n\n /**\n * Validate a single element against its spec node schema\n */\n private async validateElement(element: Element, layerName: string): Promise<{\n validated: boolean;\n hasErrors: boolean;\n errors: Array<{ message: string; location: string; fixSuggestion?: string }>;\n }> {\n const result = {\n validated: false,\n hasErrors: false,\n errors: [] as Array<{ message: string; location: string; fixSuggestion?: string }>,\n };\n\n const specNode = element.toSpecNode();\n\n // First: Validate against base spec-node schema using pre-compiled validator\n // This ensures all elements conform to the base structure before type-specific validation\n await this.ensureBaseSchemaLoaded();\n const baseValid = validateSpecNode(specNode);\n\n if (!baseValid && validateSpecNode.errors) {\n result.hasErrors = true;\n result.validated = true;\n for (const error of validateSpecNode.errors) {\n result.errors.push({\n message: `Element '${element.path || element.id}': ${this.formatAjvError(error)}`,\n location: error.instancePath || \"/\",\n fixSuggestion: this.generateFixSuggestion(error),\n });\n }\n return result; // Fail fast on base schema violation\n }\n\n // An element whose type the spec doesn't define (often one the spec has since dropped or\n // renamed) has no type schema to check, so report it rather than letting it pass unchecked.\n if (isValidLayer(layerName) && !isValidNodeType(layerName, element.type)) {\n const elementId = element.path || element.id;\n const similar = suggestNodeTypes(layerName, element.type);\n result.validated = true;\n result.hasErrors = true;\n result.errors.push({\n message:\n `Element '${elementId}' has type '${element.type}', which the spec does not define for the ${layerName} layer` +\n (similar.length > 0 ? ` (did you mean ${similar.map((s) => `'${s}'`).join(\" or \")}?)` : \"\"),\n location: \"/type\",\n fixSuggestion:\n similar.length > 0\n ? `Change the element's type to '${similar[0]}', or remove the element`\n : `Change the element's type to one the ${layerName} layer defines, or remove the element`,\n });\n return result;\n }\n\n // Second: Load and validate against type-specific schema (lazy-loaded)\n const validate = await this.loadSpecNodeSchema(layerName, element.type);\n\n if (!validate) {\n // No type-specific schema found - base schema validation passed\n // This is acceptable for custom types or types without schemas yet\n result.validated = true;\n return result;\n }\n\n result.validated = true;\n\n // Validate element against type-specific schema\n const typeValid = validate(specNode);\n\n if (!typeValid && validate.errors) {\n result.hasErrors = true;\n for (const error of validate.errors) {\n result.errors.push({\n message: `Element '${element.path || element.id}': ${this.formatAjvError(error)}`,\n location: error.instancePath || \"/\",\n fixSuggestion: this.generateFixSuggestion(error),\n });\n }\n }\n\n return result;\n }\n\n /**\n * Format AJV error message\n */\n private formatAjvError(error: ErrorObject): string {\n const keyword = error.keyword;\n const dataPath = error.instancePath || \"/\";\n\n switch (keyword) {\n case \"type\":\n return `At ${dataPath}: expected ${error.params?.type}, got ${error.data === null ? \"null\" : typeof error.data}`;\n case \"required\":\n return `At ${dataPath}: missing required property '${error.params?.missingProperty}'`;\n case \"enum\":\n return `At ${dataPath}: value must be one of [${error.params?.allowedValues?.join(\", \")}]`;\n case \"pattern\":\n return `At ${dataPath}: value must match pattern ${error.params?.pattern}`;\n case \"minLength\":\n return `At ${dataPath}: string must be at least ${error.params?.limit} characters`;\n case \"maxLength\":\n return `At ${dataPath}: string must be at most ${error.params?.limit} characters`;\n case \"minimum\":\n return `At ${dataPath}: value must be >= ${error.params?.limit}`;\n case \"maximum\":\n return `At ${dataPath}: value must be <= ${error.params?.limit}`;\n case \"additionalProperties\":\n return `At ${dataPath}: unexpected property '${error.params?.additionalProperty}'`;\n case \"const\":\n return `At ${dataPath}: value must be ${JSON.stringify(error.params?.allowedValue)}`;\n default:\n return error.message || `Validation failed`;\n }\n }\n\n /**\n * Generate a fix suggestion based on the error\n */\n private generateFixSuggestion(error: ErrorObject): string | undefined {\n const keyword = error.keyword;\n\n switch (keyword) {\n case \"required\":\n return `Add required field: ${error.params?.missingProperty}`;\n case \"type\":\n return `Expected type ${error.params?.type}`;\n case \"enum\":\n return `Use one of: ${error.params?.allowedValues?.join(\", \")}`;\n case \"pattern\":\n return `Value must match pattern: ${error.params?.pattern}`;\n case \"additionalProperties\":\n return `Remove unexpected property: ${error.params?.additionalProperty}`;\n case \"const\":\n return `Value must be exactly: ${JSON.stringify(error.params?.allowedValue)}`;\n default:\n return undefined;\n }\n }\n\n /**\n * Reset static state for test isolation\n *\n * Clears the shared AJV instance and schema registry, allowing tests\n * to load schemas from a clean state without conflicts.\n *\n * Usage (in test setup):\n * beforeEach(() => {\n * SchemaValidator.reset();\n * });\n */\n static reset(): void {\n SchemaValidator.sharedAjv = null;\n SchemaValidator.baseSchemaLoadedInSharedInstance = false;\n SchemaValidator.registeredSchemaIds.clear();\n SchemaValidator.layerCache.clear();\n SchemaValidator.compiledSchemas.clear();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/validators/types.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Validation result types and classes\n */\n\n/**\n * A single validation issue\n */\nexport interface ValidationIssue {\n layer: string;\n elementId?: string;\n message: string;\n severity: \"error\" | \"warning\";\n category?: \"orphan\" | \"schema\" | \"semantic\" | \"reference\";\n location?: string;\n fixSuggestion?: string;\n}\n\n/**\n * Result of a validation operation\n */\nexport class ValidationResult {\n errors: ValidationIssue[] = [];\n warnings: ValidationIssue[] = [];\n\n /**\n * Check if validation passed (no errors)\n */\n isValid(): boolean {\n return this.errors.length === 0;\n }\n\n /**\n * Add an error to the result\n */\n addError(issue: Omit<ValidationIssue, \"severity\">): void {\n this.errors.push({ ...issue, severity: \"error\" });\n }\n\n /**\n * Add a warning to the result\n */\n addWarning(issue: Omit<ValidationIssue, \"severity\">): void {\n this.warnings.push({ ...issue, severity: \"warning\" });\n }\n\n /**\n * Merge another validation result into this one\n */\n merge(other: ValidationResult, prefix?: string): void {\n const addPrefix = (issue: ValidationIssue): ValidationIssue => ({\n ...issue,\n message: prefix ? `${prefix}: ${issue.message}` : issue.message,\n });\n\n this.errors.push(...other.errors.map(addPrefix));\n this.warnings.push(...other.warnings.map(addPrefix));\n }\n\n /**\n * Convert to dictionary representation\n */\n toDict(): Record<string, unknown> {\n return {\n valid: this.isValid(),\n errors: this.errors,\n warnings: this.warnings,\n errorCount: this.errors.length,\n warningCount: this.warnings.length,\n };\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * Validation result types and classes\n */\n\n/**\n * A single validation issue\n */\nexport interface ValidationIssue {\n layer: string;\n elementId?: string;\n message: string;\n severity: \"error\" | \"warning\";\n category?: \"orphan\" | \"schema\" | \"semantic\" | \"reference\" | \"expected\";\n location?: string;\n fixSuggestion?: string;\n}\n\n/**\n * Result of a validation operation\n */\nexport class ValidationResult {\n errors: ValidationIssue[] = [];\n warnings: ValidationIssue[] = [];\n\n /**\n * Check if validation passed (no errors)\n */\n isValid(): boolean {\n return this.errors.length === 0;\n }\n\n /**\n * Add an error to the result\n */\n addError(issue: Omit<ValidationIssue, \"severity\">): void {\n this.errors.push({ ...issue, severity: \"error\" });\n }\n\n /**\n * Add a warning to the result\n */\n addWarning(issue: Omit<ValidationIssue, \"severity\">): void {\n this.warnings.push({ ...issue, severity: \"warning\" });\n }\n\n /**\n * Merge another validation result into this one\n */\n merge(other: ValidationResult, prefix?: string): void {\n const addPrefix = (issue: ValidationIssue): ValidationIssue => ({\n ...issue,\n message: prefix ? `${prefix}: ${issue.message}` : issue.message,\n });\n\n this.errors.push(...other.errors.map(addPrefix));\n this.warnings.push(...other.warnings.map(addPrefix));\n }\n\n /**\n * Convert to dictionary representation\n */\n toDict(): Record<string, unknown> {\n return {\n valid: this.isValid(),\n errors: this.errors,\n warnings: this.warnings,\n errorCount: this.errors.length,\n warningCount: this.warnings.length,\n };\n }\n}\n"],
|
|
5
5
|
"mappings": "AAoBM,MAAO,iBAAgB;EAC3B,SAA4B,CAAA;EAC5B,WAA8B,CAAA;;;;EAK9B,UAAO;AACL,WAAO,KAAK,OAAO,WAAW;EAChC;;;;EAKA,SAAS,OAAwC;AAC/C,SAAK,OAAO,KAAK,EAAE,GAAG,OAAO,UAAU,QAAO,CAAE;EAClD;;;;EAKA,WAAW,OAAwC;AACjD,SAAK,SAAS,KAAK,EAAE,GAAG,OAAO,UAAU,UAAS,CAAE;EACtD;;;;EAKA,MAAM,OAAyB,QAAe;AAC5C,UAAM,YAAY,CAAC,WAA6C;MAC9D,GAAG;MACH,SAAS,SAAS,GAAG,MAAM,KAAK,MAAM,OAAO,KAAK,MAAM;;AAG1D,SAAK,OAAO,KAAK,GAAG,MAAM,OAAO,IAAI,SAAS,CAAC,GAC/C,KAAK,SAAS,KAAK,GAAG,MAAM,SAAS,IAAI,SAAS,CAAC;EACrD;;;;EAKA,SAAM;AACJ,WAAO;MACL,OAAO,KAAK,QAAO;MACnB,QAAQ,KAAK;MACb,UAAU,KAAK;MACf,YAAY,KAAK,OAAO;MACxB,cAAc,KAAK,SAAS;;EAEhC;;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/viewer/README.md
CHANGED
|
@@ -4,15 +4,15 @@ This directory contains the pre-built embedded viewer for the Documentation Robo
|
|
|
4
4
|
|
|
5
5
|
## Bundle Information
|
|
6
6
|
|
|
7
|
-
- **Version:** 0.
|
|
8
|
-
- **Build Date:** 2026-
|
|
9
|
-
- **Total Size:** 1.
|
|
10
|
-
- **Estimated Gzip:**
|
|
7
|
+
- **Version:** 0.9.0
|
|
8
|
+
- **Build Date:** 2026-11-11T14:01:29.591Z
|
|
9
|
+
- **Total Size:** 1.53 MB
|
|
10
|
+
- **Estimated Gzip:** 484.51 KB
|
|
11
11
|
|
|
12
12
|
## Files
|
|
13
13
|
|
|
14
|
-
- `assets/main-
|
|
15
|
-
- `assets/main-
|
|
14
|
+
- `assets/main-DvH3gYrI.js` (1.07 MB)
|
|
15
|
+
- `assets/main-CUOQGGRA.css` (225.52 KB)
|
|
16
16
|
- `fonts/inter/Inter-SemiBold.woff2` (23.88 KB)
|
|
17
17
|
- `fonts/inter/Inter-ExtraBold.woff2` (23.83 KB)
|
|
18
18
|
- `fonts/inter/Inter-Bold.woff2` (23.79 KB)
|