@contractspec/bundle.workspace 0.0.0-canary-20260113162409
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +83 -0
- package/dist/_virtual/rolldown_runtime.mjs +20 -0
- package/dist/adapters/ai.d.mts +12 -0
- package/dist/adapters/ai.d.mts.map +1 -0
- package/dist/adapters/ai.mjs +83 -0
- package/dist/adapters/ai.mjs.map +1 -0
- package/dist/adapters/factory.d.mts +29 -0
- package/dist/adapters/factory.d.mts.map +1 -0
- package/dist/adapters/factory.mjs +37 -0
- package/dist/adapters/factory.mjs.map +1 -0
- package/dist/adapters/fs.d.mts +12 -0
- package/dist/adapters/fs.d.mts.map +1 -0
- package/dist/adapters/fs.mjs +133 -0
- package/dist/adapters/fs.mjs.map +1 -0
- package/dist/adapters/git.d.mts +11 -0
- package/dist/adapters/git.d.mts.map +1 -0
- package/dist/adapters/git.mjs +84 -0
- package/dist/adapters/git.mjs.map +1 -0
- package/dist/adapters/index.d.mts +7 -0
- package/dist/adapters/index.mjs +9 -0
- package/dist/adapters/logger.d.mts +18 -0
- package/dist/adapters/logger.d.mts.map +1 -0
- package/dist/adapters/logger.mjs +81 -0
- package/dist/adapters/logger.mjs.map +1 -0
- package/dist/adapters/watcher.d.mts +11 -0
- package/dist/adapters/watcher.d.mts.map +1 -0
- package/dist/adapters/watcher.mjs +74 -0
- package/dist/adapters/watcher.mjs.map +1 -0
- package/dist/adapters/workspace.d.mts +148 -0
- package/dist/adapters/workspace.d.mts.map +1 -0
- package/dist/adapters/workspace.mjs +275 -0
- package/dist/adapters/workspace.mjs.map +1 -0
- package/dist/ai/agents/claude-code-agent.d.mts +22 -0
- package/dist/ai/agents/claude-code-agent.d.mts.map +1 -0
- package/dist/ai/agents/claude-code-agent.mjs +182 -0
- package/dist/ai/agents/claude-code-agent.mjs.map +1 -0
- package/dist/ai/agents/cursor-agent.d.mts +68 -0
- package/dist/ai/agents/cursor-agent.d.mts.map +1 -0
- package/dist/ai/agents/cursor-agent.mjs +436 -0
- package/dist/ai/agents/cursor-agent.mjs.map +1 -0
- package/dist/ai/agents/index.mjs +7 -0
- package/dist/ai/agents/openai-codex-agent.d.mts +22 -0
- package/dist/ai/agents/openai-codex-agent.d.mts.map +1 -0
- package/dist/ai/agents/openai-codex-agent.mjs +167 -0
- package/dist/ai/agents/openai-codex-agent.mjs.map +1 -0
- package/dist/ai/agents/orchestrator.d.mts +50 -0
- package/dist/ai/agents/orchestrator.d.mts.map +1 -0
- package/dist/ai/agents/orchestrator.mjs +143 -0
- package/dist/ai/agents/orchestrator.mjs.map +1 -0
- package/dist/ai/agents/simple-agent.d.mts +17 -0
- package/dist/ai/agents/simple-agent.d.mts.map +1 -0
- package/dist/ai/agents/simple-agent.mjs +92 -0
- package/dist/ai/agents/simple-agent.mjs.map +1 -0
- package/dist/ai/agents/types.d.mts +36 -0
- package/dist/ai/agents/types.d.mts.map +1 -0
- package/dist/ai/client.d.mts +97 -0
- package/dist/ai/client.d.mts.map +1 -0
- package/dist/ai/client.mjs +189 -0
- package/dist/ai/client.mjs.map +1 -0
- package/dist/ai/index.d.mts +9 -0
- package/dist/ai/index.mjs +11 -0
- package/dist/ai/prompts/code-generation.d.mts +26 -0
- package/dist/ai/prompts/code-generation.d.mts.map +1 -0
- package/dist/ai/prompts/code-generation.mjs +143 -0
- package/dist/ai/prompts/code-generation.mjs.map +1 -0
- package/dist/ai/prompts/index.d.mts +10 -0
- package/dist/ai/prompts/index.d.mts.map +1 -0
- package/dist/ai/prompts/index.mjs +13 -0
- package/dist/ai/prompts/index.mjs.map +1 -0
- package/dist/ai/prompts/spec-creation.d.mts +29 -0
- package/dist/ai/prompts/spec-creation.d.mts.map +1 -0
- package/dist/ai/prompts/spec-creation.mjs +111 -0
- package/dist/ai/prompts/spec-creation.mjs.map +1 -0
- package/dist/ai/providers.d.mts +29 -0
- package/dist/ai/providers.d.mts.map +1 -0
- package/dist/ai/providers.mjs +39 -0
- package/dist/ai/providers.mjs.map +1 -0
- package/dist/formatters/index.d.mts +11 -0
- package/dist/formatters/index.d.mts.map +1 -0
- package/dist/formatters/index.mjs +17 -0
- package/dist/formatters/index.mjs.map +1 -0
- package/dist/formatters/json.d.mts +56 -0
- package/dist/formatters/json.d.mts.map +1 -0
- package/dist/formatters/json.mjs +43 -0
- package/dist/formatters/json.mjs.map +1 -0
- package/dist/formatters/sarif.d.mts +101 -0
- package/dist/formatters/sarif.d.mts.map +1 -0
- package/dist/formatters/sarif.mjs +163 -0
- package/dist/formatters/sarif.mjs.map +1 -0
- package/dist/formatters/text.d.mts +35 -0
- package/dist/formatters/text.d.mts.map +1 -0
- package/dist/formatters/text.mjs +209 -0
- package/dist/formatters/text.mjs.map +1 -0
- package/dist/index.d.mts +125 -0
- package/dist/index.mjs +110 -0
- package/dist/ports/ai.d.mts +59 -0
- package/dist/ports/ai.d.mts.map +1 -0
- package/dist/ports/fs.d.mts +81 -0
- package/dist/ports/fs.d.mts.map +1 -0
- package/dist/ports/git.d.mts +46 -0
- package/dist/ports/git.d.mts.map +1 -0
- package/dist/ports/index.d.mts +6 -0
- package/dist/ports/logger.d.mts +88 -0
- package/dist/ports/logger.d.mts.map +1 -0
- package/dist/ports/rulesync.d.mts +38 -0
- package/dist/ports/rulesync.d.mts.map +1 -0
- package/dist/ports/watcher.d.mts +52 -0
- package/dist/ports/watcher.d.mts.map +1 -0
- package/dist/services/agent-guide/adapters/claude-code.d.mts +35 -0
- package/dist/services/agent-guide/adapters/claude-code.d.mts.map +1 -0
- package/dist/services/agent-guide/adapters/claude-code.mjs +144 -0
- package/dist/services/agent-guide/adapters/claude-code.mjs.map +1 -0
- package/dist/services/agent-guide/adapters/cursor-cli.d.mts +39 -0
- package/dist/services/agent-guide/adapters/cursor-cli.d.mts.map +1 -0
- package/dist/services/agent-guide/adapters/cursor-cli.mjs +135 -0
- package/dist/services/agent-guide/adapters/cursor-cli.mjs.map +1 -0
- package/dist/services/agent-guide/adapters/generic-mcp.d.mts +53 -0
- package/dist/services/agent-guide/adapters/generic-mcp.d.mts.map +1 -0
- package/dist/services/agent-guide/adapters/generic-mcp.mjs +159 -0
- package/dist/services/agent-guide/adapters/generic-mcp.mjs.map +1 -0
- package/dist/services/agent-guide/adapters/index.d.mts +23 -0
- package/dist/services/agent-guide/adapters/index.d.mts.map +1 -0
- package/dist/services/agent-guide/adapters/index.mjs +31 -0
- package/dist/services/agent-guide/adapters/index.mjs.map +1 -0
- package/dist/services/agent-guide/agent-guide-service.d.mts +56 -0
- package/dist/services/agent-guide/agent-guide-service.d.mts.map +1 -0
- package/dist/services/agent-guide/agent-guide-service.mjs +147 -0
- package/dist/services/agent-guide/agent-guide-service.mjs.map +1 -0
- package/dist/services/agent-guide/index.d.mts +6 -0
- package/dist/services/agent-guide/index.mjs +7 -0
- package/dist/services/agent-guide/types.d.mts +58 -0
- package/dist/services/agent-guide/types.d.mts.map +1 -0
- package/dist/services/build.d.mts +61 -0
- package/dist/services/build.d.mts.map +1 -0
- package/dist/services/build.mjs +151 -0
- package/dist/services/build.mjs.map +1 -0
- package/dist/services/ci-check/checks/coverage.mjs +77 -0
- package/dist/services/ci-check/checks/coverage.mjs.map +1 -0
- package/dist/services/ci-check/checks/deps.mjs +32 -0
- package/dist/services/ci-check/checks/deps.mjs.map +1 -0
- package/dist/services/ci-check/checks/doctor.mjs +38 -0
- package/dist/services/ci-check/checks/doctor.mjs.map +1 -0
- package/dist/services/ci-check/checks/drift.mjs +40 -0
- package/dist/services/ci-check/checks/drift.mjs.map +1 -0
- package/dist/services/ci-check/checks/handlers.mjs +38 -0
- package/dist/services/ci-check/checks/handlers.mjs.map +1 -0
- package/dist/services/ci-check/checks/implementation.mjs +73 -0
- package/dist/services/ci-check/checks/implementation.mjs.map +1 -0
- package/dist/services/ci-check/checks/index.mjs +13 -0
- package/dist/services/ci-check/checks/integrity.mjs +31 -0
- package/dist/services/ci-check/checks/integrity.mjs.map +1 -0
- package/dist/services/ci-check/checks/layers.mjs +66 -0
- package/dist/services/ci-check/checks/layers.mjs.map +1 -0
- package/dist/services/ci-check/checks/structure.mjs +35 -0
- package/dist/services/ci-check/checks/structure.mjs.map +1 -0
- package/dist/services/ci-check/checks/test-refs.mjs +63 -0
- package/dist/services/ci-check/checks/test-refs.mjs.map +1 -0
- package/dist/services/ci-check/checks/tests.mjs +38 -0
- package/dist/services/ci-check/checks/tests.mjs.map +1 -0
- package/dist/services/ci-check/ci-check-service.d.mts +16 -0
- package/dist/services/ci-check/ci-check-service.d.mts.map +1 -0
- package/dist/services/ci-check/ci-check-service.mjs +129 -0
- package/dist/services/ci-check/ci-check-service.mjs.map +1 -0
- package/dist/services/ci-check/index.d.mts +2 -0
- package/dist/services/ci-check/index.mjs +4 -0
- package/dist/services/ci-check/types.d.mts +147 -0
- package/dist/services/ci-check/types.d.mts.map +1 -0
- package/dist/services/ci-check/types.mjs +37 -0
- package/dist/services/ci-check/types.mjs.map +1 -0
- package/dist/services/ci-check/utils.mjs +76 -0
- package/dist/services/ci-check/utils.mjs.map +1 -0
- package/dist/services/clean.d.mts +41 -0
- package/dist/services/clean.d.mts.map +1 -0
- package/dist/services/clean.mjs +72 -0
- package/dist/services/clean.mjs.map +1 -0
- package/dist/services/config.d.mts +16 -0
- package/dist/services/config.d.mts.map +1 -0
- package/dist/services/config.mjs +63 -0
- package/dist/services/config.mjs.map +1 -0
- package/dist/services/coverage/parsers/index.mjs +34 -0
- package/dist/services/coverage/parsers/index.mjs.map +1 -0
- package/dist/services/coverage/parsers/istanbul-parser.mjs +108 -0
- package/dist/services/coverage/parsers/istanbul-parser.mjs.map +1 -0
- package/dist/services/coverage/validator.mjs +55 -0
- package/dist/services/coverage/validator.mjs.map +1 -0
- package/dist/services/create/ai-generator.d.mts +84 -0
- package/dist/services/create/ai-generator.d.mts.map +1 -0
- package/dist/services/create/ai-generator.mjs +178 -0
- package/dist/services/create/ai-generator.mjs.map +1 -0
- package/dist/services/create/index.d.mts +28 -0
- package/dist/services/create/index.d.mts.map +1 -0
- package/dist/services/create/index.mjs +37 -0
- package/dist/services/create/index.mjs.map +1 -0
- package/dist/services/create/templates.d.mts +22 -0
- package/dist/services/create/templates.d.mts.map +1 -0
- package/dist/services/create/templates.mjs +39 -0
- package/dist/services/create/templates.mjs.map +1 -0
- package/dist/services/deps.d.mts +53 -0
- package/dist/services/deps.d.mts.map +1 -0
- package/dist/services/deps.mjs +62 -0
- package/dist/services/deps.mjs.map +1 -0
- package/dist/services/diff.d.mts +34 -0
- package/dist/services/diff.d.mts.map +1 -0
- package/dist/services/diff.mjs +34 -0
- package/dist/services/diff.mjs.map +1 -0
- package/dist/services/docs/docs-service.d.mts +20 -0
- package/dist/services/docs/docs-service.d.mts.map +1 -0
- package/dist/services/docs/docs-service.mjs +59 -0
- package/dist/services/docs/docs-service.mjs.map +1 -0
- package/dist/services/docs/index.d.mts +1 -0
- package/dist/services/docs/index.mjs +3 -0
- package/dist/services/doctor/checks/ai.mjs +119 -0
- package/dist/services/doctor/checks/ai.mjs.map +1 -0
- package/dist/services/doctor/checks/cli.mjs +156 -0
- package/dist/services/doctor/checks/cli.mjs.map +1 -0
- package/dist/services/doctor/checks/config.mjs +303 -0
- package/dist/services/doctor/checks/config.mjs.map +1 -0
- package/dist/services/doctor/checks/deps.mjs +267 -0
- package/dist/services/doctor/checks/deps.mjs.map +1 -0
- package/dist/services/doctor/checks/index.mjs +9 -0
- package/dist/services/doctor/checks/layers.mjs +139 -0
- package/dist/services/doctor/checks/layers.mjs.map +1 -0
- package/dist/services/doctor/checks/mcp.mjs +145 -0
- package/dist/services/doctor/checks/mcp.mjs.map +1 -0
- package/dist/services/doctor/checks/workspace.mjs +263 -0
- package/dist/services/doctor/checks/workspace.mjs.map +1 -0
- package/dist/services/doctor/doctor-service.d.mts +24 -0
- package/dist/services/doctor/doctor-service.d.mts.map +1 -0
- package/dist/services/doctor/doctor-service.mjs +118 -0
- package/dist/services/doctor/doctor-service.mjs.map +1 -0
- package/dist/services/doctor/index.d.mts +2 -0
- package/dist/services/doctor/index.mjs +4 -0
- package/dist/services/doctor/types.d.mts +118 -0
- package/dist/services/doctor/types.d.mts.map +1 -0
- package/dist/services/doctor/types.mjs +29 -0
- package/dist/services/doctor/types.mjs.map +1 -0
- package/dist/services/drift.mjs +73 -0
- package/dist/services/drift.mjs.map +1 -0
- package/dist/services/extract.d.mts +12 -0
- package/dist/services/extract.d.mts.map +1 -0
- package/dist/services/extract.mjs +33 -0
- package/dist/services/extract.mjs.map +1 -0
- package/dist/services/features/completion.d.mts +21 -0
- package/dist/services/features/completion.d.mts.map +1 -0
- package/dist/services/features/completion.mjs +70 -0
- package/dist/services/features/completion.mjs.map +1 -0
- package/dist/services/features/feature-editor.d.mts +27 -0
- package/dist/services/features/feature-editor.d.mts.map +1 -0
- package/dist/services/features/feature-editor.mjs +37 -0
- package/dist/services/features/feature-editor.mjs.map +1 -0
- package/dist/services/features/index.d.mts +11 -0
- package/dist/services/features/index.d.mts.map +1 -0
- package/dist/services/features/index.mjs +16 -0
- package/dist/services/features/index.mjs.map +1 -0
- package/dist/services/features/validation.d.mts +21 -0
- package/dist/services/features/validation.d.mts.map +1 -0
- package/dist/services/features/validation.mjs +27 -0
- package/dist/services/features/validation.mjs.map +1 -0
- package/dist/services/fix/fix-link-formatter.d.mts +12 -0
- package/dist/services/fix/fix-link-formatter.d.mts.map +1 -0
- package/dist/services/fix/fix-link-formatter.mjs +38 -0
- package/dist/services/fix/fix-link-formatter.mjs.map +1 -0
- package/dist/services/fix/fix-service.d.mts +74 -0
- package/dist/services/fix/fix-service.d.mts.map +1 -0
- package/dist/services/fix/fix-service.mjs +169 -0
- package/dist/services/fix/fix-service.mjs.map +1 -0
- package/dist/services/fix/index.d.mts +16 -0
- package/dist/services/fix/index.d.mts.map +1 -0
- package/dist/services/fix/index.mjs +24 -0
- package/dist/services/fix/index.mjs.map +1 -0
- package/dist/services/fix/path-resolver.mjs +83 -0
- package/dist/services/fix/path-resolver.mjs.map +1 -0
- package/dist/services/fix/schemas.d.mts +17 -0
- package/dist/services/fix/schemas.d.mts.map +1 -0
- package/dist/services/fix/schemas.mjs +12 -0
- package/dist/services/fix/schemas.mjs.map +1 -0
- package/dist/services/fix/strategies/implement-ai.d.mts +18 -0
- package/dist/services/fix/strategies/implement-ai.d.mts.map +1 -0
- package/dist/services/fix/strategies/implement-ai.mjs +139 -0
- package/dist/services/fix/strategies/implement-ai.mjs.map +1 -0
- package/dist/services/fix/strategies/implement-skeleton.d.mts +14 -0
- package/dist/services/fix/strategies/implement-skeleton.d.mts.map +1 -0
- package/dist/services/fix/strategies/implement-skeleton.mjs +77 -0
- package/dist/services/fix/strategies/implement-skeleton.mjs.map +1 -0
- package/dist/services/fix/strategies/index.d.mts +3 -0
- package/dist/services/fix/strategies/remove-reference.d.mts +17 -0
- package/dist/services/fix/strategies/remove-reference.d.mts.map +1 -0
- package/dist/services/fix/strategies/remove-reference.mjs +98 -0
- package/dist/services/fix/strategies/remove-reference.mjs.map +1 -0
- package/dist/services/fix/types.d.mts +207 -0
- package/dist/services/fix/types.d.mts.map +1 -0
- package/dist/services/fix/types.mjs +20 -0
- package/dist/services/fix/types.mjs.map +1 -0
- package/dist/services/formatter.d.mts +15 -0
- package/dist/services/formatter.d.mts.map +1 -0
- package/dist/services/formatter.mjs +26 -0
- package/dist/services/formatter.mjs.map +1 -0
- package/dist/services/gap.d.mts +18 -0
- package/dist/services/gap.d.mts.map +1 -0
- package/dist/services/gap.mjs +44 -0
- package/dist/services/gap.mjs.map +1 -0
- package/dist/services/generate-artifacts.d.mts +11 -0
- package/dist/services/generate-artifacts.d.mts.map +1 -0
- package/dist/services/generate-artifacts.mjs +27 -0
- package/dist/services/generate-artifacts.mjs.map +1 -0
- package/dist/services/hooks/hooks-service.d.mts +24 -0
- package/dist/services/hooks/hooks-service.d.mts.map +1 -0
- package/dist/services/hooks/hooks-service.mjs +126 -0
- package/dist/services/hooks/hooks-service.mjs.map +1 -0
- package/dist/services/hooks/index.d.mts +10 -0
- package/dist/services/hooks/index.d.mts.map +1 -0
- package/dist/services/hooks/index.mjs +12 -0
- package/dist/services/hooks/index.mjs.map +1 -0
- package/dist/services/hooks/types.d.mts +56 -0
- package/dist/services/hooks/types.d.mts.map +1 -0
- package/dist/services/impact/formatters.d.mts +27 -0
- package/dist/services/impact/formatters.d.mts.map +1 -0
- package/dist/services/impact/formatters.mjs +139 -0
- package/dist/services/impact/formatters.mjs.map +1 -0
- package/dist/services/impact/impact-detection-service.d.mts +22 -0
- package/dist/services/impact/impact-detection-service.d.mts.map +1 -0
- package/dist/services/impact/impact-detection-service.mjs +96 -0
- package/dist/services/impact/impact-detection-service.mjs.map +1 -0
- package/dist/services/impact/index.d.mts +11 -0
- package/dist/services/impact/index.d.mts.map +1 -0
- package/dist/services/impact/index.mjs +16 -0
- package/dist/services/impact/index.mjs.map +1 -0
- package/dist/services/impact/types.d.mts +63 -0
- package/dist/services/impact/types.d.mts.map +1 -0
- package/dist/services/implementation/discovery.d.mts +30 -0
- package/dist/services/implementation/discovery.d.mts.map +1 -0
- package/dist/services/implementation/discovery.mjs +144 -0
- package/dist/services/implementation/discovery.mjs.map +1 -0
- package/dist/services/implementation/index.d.mts +6 -0
- package/dist/services/implementation/index.mjs +7 -0
- package/dist/services/implementation/resolver/conventions.d.mts +18 -0
- package/dist/services/implementation/resolver/conventions.d.mts.map +1 -0
- package/dist/services/implementation/resolver/conventions.mjs +59 -0
- package/dist/services/implementation/resolver/conventions.mjs.map +1 -0
- package/dist/services/implementation/resolver/index.d.mts +24 -0
- package/dist/services/implementation/resolver/index.d.mts.map +1 -0
- package/dist/services/implementation/resolver/index.mjs +111 -0
- package/dist/services/implementation/resolver/index.mjs.map +1 -0
- package/dist/services/implementation/resolver/parsers.d.mts +16 -0
- package/dist/services/implementation/resolver/parsers.d.mts.map +1 -0
- package/dist/services/implementation/resolver/parsers.mjs +100 -0
- package/dist/services/implementation/resolver/parsers.mjs.map +1 -0
- package/dist/services/implementation/resolver/status.d.mts +21 -0
- package/dist/services/implementation/resolver/status.d.mts.map +1 -0
- package/dist/services/implementation/resolver/status.mjs +31 -0
- package/dist/services/implementation/resolver/status.mjs.map +1 -0
- package/dist/services/implementation/types.d.mts +89 -0
- package/dist/services/implementation/types.d.mts.map +1 -0
- package/dist/services/index.d.mts +103 -0
- package/dist/services/index.mjs +100 -0
- package/dist/services/integrity-diagram.d.mts +36 -0
- package/dist/services/integrity-diagram.d.mts.map +1 -0
- package/dist/services/integrity-diagram.mjs +275 -0
- package/dist/services/integrity-diagram.mjs.map +1 -0
- package/dist/services/integrity.d.mts +152 -0
- package/dist/services/integrity.d.mts.map +1 -0
- package/dist/services/integrity.mjs +361 -0
- package/dist/services/integrity.mjs.map +1 -0
- package/dist/services/layer-discovery.d.mts +77 -0
- package/dist/services/layer-discovery.d.mts.map +1 -0
- package/dist/services/layer-discovery.mjs +121 -0
- package/dist/services/layer-discovery.mjs.map +1 -0
- package/dist/services/list.d.mts +37 -0
- package/dist/services/list.d.mts.map +1 -0
- package/dist/services/list.mjs +46 -0
- package/dist/services/list.mjs.map +1 -0
- package/dist/services/llm/index.d.mts +28 -0
- package/dist/services/llm/index.d.mts.map +1 -0
- package/dist/services/llm/index.mjs +187 -0
- package/dist/services/llm/index.mjs.map +1 -0
- package/dist/services/llm/verify-static.d.mts +26 -0
- package/dist/services/llm/verify-static.d.mts.map +1 -0
- package/dist/services/llm/verify-static.mjs +82 -0
- package/dist/services/llm/verify-static.mjs.map +1 -0
- package/dist/services/modules/module-resolver.mjs +61 -0
- package/dist/services/modules/module-resolver.mjs.map +1 -0
- package/dist/services/openapi/export-service.d.mts +53 -0
- package/dist/services/openapi/export-service.d.mts.map +1 -0
- package/dist/services/openapi/export-service.mjs +50 -0
- package/dist/services/openapi/export-service.mjs.map +1 -0
- package/dist/services/openapi/import-service.d.mts +17 -0
- package/dist/services/openapi/import-service.d.mts.map +1 -0
- package/dist/services/openapi/import-service.mjs +168 -0
- package/dist/services/openapi/import-service.mjs.map +1 -0
- package/dist/services/openapi/index.d.mts +5 -0
- package/dist/services/openapi/index.mjs +6 -0
- package/dist/services/openapi/sync-service.d.mts +17 -0
- package/dist/services/openapi/sync-service.d.mts.map +1 -0
- package/dist/services/openapi/sync-service.mjs +120 -0
- package/dist/services/openapi/sync-service.mjs.map +1 -0
- package/dist/services/openapi/types.d.mts +162 -0
- package/dist/services/openapi/types.d.mts.map +1 -0
- package/dist/services/openapi/validate-service.d.mts +16 -0
- package/dist/services/openapi/validate-service.d.mts.map +1 -0
- package/dist/services/openapi/validate-service.mjs +130 -0
- package/dist/services/openapi/validate-service.mjs.map +1 -0
- package/dist/services/quickstart/dependencies.d.mts +31 -0
- package/dist/services/quickstart/dependencies.d.mts.map +1 -0
- package/dist/services/quickstart/dependencies.mjs +57 -0
- package/dist/services/quickstart/dependencies.mjs.map +1 -0
- package/dist/services/quickstart/index.mjs +4 -0
- package/dist/services/quickstart/quickstart-service.d.mts +20 -0
- package/dist/services/quickstart/quickstart-service.d.mts.map +1 -0
- package/dist/services/quickstart/quickstart-service.mjs +196 -0
- package/dist/services/quickstart/quickstart-service.mjs.map +1 -0
- package/dist/services/quickstart/types.d.mts +81 -0
- package/dist/services/quickstart/types.d.mts.map +1 -0
- package/dist/services/regenerator.d.mts +18 -0
- package/dist/services/regenerator.d.mts.map +1 -0
- package/dist/services/regenerator.mjs +23 -0
- package/dist/services/regenerator.mjs.map +1 -0
- package/dist/services/registry.d.mts +53 -0
- package/dist/services/registry.d.mts.map +1 -0
- package/dist/services/registry.mjs +74 -0
- package/dist/services/registry.mjs.map +1 -0
- package/dist/services/rulesync.d.mts +17 -0
- package/dist/services/rulesync.d.mts.map +1 -0
- package/dist/services/rulesync.mjs +71 -0
- package/dist/services/rulesync.mjs.map +1 -0
- package/dist/services/setup/config-generators.d.mts +42 -0
- package/dist/services/setup/config-generators.d.mts.map +1 -0
- package/dist/services/setup/config-generators.mjs +252 -0
- package/dist/services/setup/config-generators.mjs.map +1 -0
- package/dist/services/setup/file-merger.d.mts +27 -0
- package/dist/services/setup/file-merger.d.mts.map +1 -0
- package/dist/services/setup/file-merger.mjs +61 -0
- package/dist/services/setup/file-merger.mjs.map +1 -0
- package/dist/services/setup/setup-service.d.mts +12 -0
- package/dist/services/setup/setup-service.d.mts.map +1 -0
- package/dist/services/setup/setup-service.mjs +96 -0
- package/dist/services/setup/setup-service.mjs.map +1 -0
- package/dist/services/setup/targets/agents-md.mjs +47 -0
- package/dist/services/setup/targets/agents-md.mjs.map +1 -0
- package/dist/services/setup/targets/cli-config.mjs +60 -0
- package/dist/services/setup/targets/cli-config.mjs.map +1 -0
- package/dist/services/setup/targets/cursor-rules.mjs +48 -0
- package/dist/services/setup/targets/cursor-rules.mjs.map +1 -0
- package/dist/services/setup/targets/mcp-claude.mjs +60 -0
- package/dist/services/setup/targets/mcp-claude.mjs.map +1 -0
- package/dist/services/setup/targets/mcp-cursor.mjs +59 -0
- package/dist/services/setup/targets/mcp-cursor.mjs.map +1 -0
- package/dist/services/setup/targets/vscode-settings.mjs +63 -0
- package/dist/services/setup/targets/vscode-settings.mjs.map +1 -0
- package/dist/services/setup/types.d.mts +85 -0
- package/dist/services/setup/types.d.mts.map +1 -0
- package/dist/services/setup/types.mjs +27 -0
- package/dist/services/setup/types.mjs.map +1 -0
- package/dist/services/sync.d.mts +42 -0
- package/dist/services/sync.d.mts.map +1 -0
- package/dist/services/sync.mjs +64 -0
- package/dist/services/sync.mjs.map +1 -0
- package/dist/services/test/index.d.mts +2 -0
- package/dist/services/test/index.mjs +4 -0
- package/dist/services/test/test-generator-service.d.mts +24 -0
- package/dist/services/test/test-generator-service.d.mts.map +1 -0
- package/dist/services/test/test-generator-service.mjs +92 -0
- package/dist/services/test/test-generator-service.mjs.map +1 -0
- package/dist/services/test/test-service.d.mts +27 -0
- package/dist/services/test/test-service.d.mts.map +1 -0
- package/dist/services/test/test-service.mjs +94 -0
- package/dist/services/test/test-service.mjs.map +1 -0
- package/dist/services/test-link/index.d.mts +18 -0
- package/dist/services/test-link/index.d.mts.map +1 -0
- package/dist/services/test-link/index.mjs +60 -0
- package/dist/services/test-link/index.mjs.map +1 -0
- package/dist/services/test-link/test-ref-validator.d.mts +2 -0
- package/dist/services/test-link/test-ref-validator.mjs +50 -0
- package/dist/services/test-link/test-ref-validator.mjs.map +1 -0
- package/dist/services/upgrade/index.d.mts +10 -0
- package/dist/services/upgrade/index.d.mts.map +1 -0
- package/dist/services/upgrade/index.mjs +15 -0
- package/dist/services/upgrade/index.mjs.map +1 -0
- package/dist/services/upgrade/types.d.mts +78 -0
- package/dist/services/upgrade/types.d.mts.map +1 -0
- package/dist/services/upgrade/upgrade-service.d.mts +38 -0
- package/dist/services/upgrade/upgrade-service.d.mts.map +1 -0
- package/dist/services/upgrade/upgrade-service.mjs +201 -0
- package/dist/services/upgrade/upgrade-service.mjs.map +1 -0
- package/dist/services/validate/blueprint-validator.d.mts +23 -0
- package/dist/services/validate/blueprint-validator.d.mts.map +1 -0
- package/dist/services/validate/blueprint-validator.mjs +50 -0
- package/dist/services/validate/blueprint-validator.mjs.map +1 -0
- package/dist/services/validate/implementation-agent-validator.d.mts +20 -0
- package/dist/services/validate/implementation-agent-validator.d.mts.map +1 -0
- package/dist/services/validate/implementation-agent-validator.mjs +42 -0
- package/dist/services/validate/implementation-agent-validator.mjs.map +1 -0
- package/dist/services/validate/implementation-validator.d.mts +32 -0
- package/dist/services/validate/implementation-validator.d.mts.map +1 -0
- package/dist/services/validate/implementation-validator.mjs +64 -0
- package/dist/services/validate/implementation-validator.mjs.map +1 -0
- package/dist/services/validate/index.d.mts +5 -0
- package/dist/services/validate/index.mjs +7 -0
- package/dist/services/validate/spec-validator.d.mts +42 -0
- package/dist/services/validate/spec-validator.d.mts.map +1 -0
- package/dist/services/validate/spec-validator.mjs +49 -0
- package/dist/services/validate/spec-validator.mjs.map +1 -0
- package/dist/services/validate/tenant-validator.d.mts +21 -0
- package/dist/services/validate/tenant-validator.d.mts.map +1 -0
- package/dist/services/validate/tenant-validator.mjs +165 -0
- package/dist/services/validate/tenant-validator.mjs.map +1 -0
- package/dist/services/verification-cache/adapters/filesystem.d.mts +46 -0
- package/dist/services/verification-cache/adapters/filesystem.d.mts.map +1 -0
- package/dist/services/verification-cache/adapters/filesystem.mjs +120 -0
- package/dist/services/verification-cache/adapters/filesystem.mjs.map +1 -0
- package/dist/services/verification-cache/adapters/in-memory.d.mts +27 -0
- package/dist/services/verification-cache/adapters/in-memory.d.mts.map +1 -0
- package/dist/services/verification-cache/adapters/in-memory.mjs +46 -0
- package/dist/services/verification-cache/adapters/in-memory.mjs.map +1 -0
- package/dist/services/verification-cache/adapters/index.d.mts +3 -0
- package/dist/services/verification-cache/adapters/index.mjs +5 -0
- package/dist/services/verification-cache/adapters/workspace-state.d.mts +49 -0
- package/dist/services/verification-cache/adapters/workspace-state.d.mts.map +1 -0
- package/dist/services/verification-cache/adapters/workspace-state.mjs +91 -0
- package/dist/services/verification-cache/adapters/workspace-state.mjs.map +1 -0
- package/dist/services/verification-cache/cache-service.d.mts +70 -0
- package/dist/services/verification-cache/cache-service.d.mts.map +1 -0
- package/dist/services/verification-cache/cache-service.mjs +256 -0
- package/dist/services/verification-cache/cache-service.mjs.map +1 -0
- package/dist/services/verification-cache/index.d.mts +6 -0
- package/dist/services/verification-cache/index.mjs +8 -0
- package/dist/services/verification-cache/types.d.mts +124 -0
- package/dist/services/verification-cache/types.d.mts.map +1 -0
- package/dist/services/verification-cache/types.mjs +16 -0
- package/dist/services/verification-cache/types.mjs.map +1 -0
- package/dist/services/verify/ai-verifier.d.mts +25 -0
- package/dist/services/verify/ai-verifier.d.mts.map +1 -0
- package/dist/services/verify/ai-verifier.mjs +403 -0
- package/dist/services/verify/ai-verifier.mjs.map +1 -0
- package/dist/services/verify/behavior-verifier.d.mts +12 -0
- package/dist/services/verify/behavior-verifier.d.mts.map +1 -0
- package/dist/services/verify/behavior-verifier.mjs +186 -0
- package/dist/services/verify/behavior-verifier.mjs.map +1 -0
- package/dist/services/verify/index.d.mts +5 -0
- package/dist/services/verify/index.mjs +6 -0
- package/dist/services/verify/structure-verifier.d.mts +12 -0
- package/dist/services/verify/structure-verifier.d.mts.map +1 -0
- package/dist/services/verify/structure-verifier.mjs +196 -0
- package/dist/services/verify/structure-verifier.mjs.map +1 -0
- package/dist/services/verify/types.d.mts +137 -0
- package/dist/services/verify/types.d.mts.map +1 -0
- package/dist/services/verify/verify-service.d.mts +60 -0
- package/dist/services/verify/verify-service.d.mts.map +1 -0
- package/dist/services/verify/verify-service.mjs +204 -0
- package/dist/services/verify/verify-service.mjs.map +1 -0
- package/dist/services/versioning/changelog-formatter.d.mts +24 -0
- package/dist/services/versioning/changelog-formatter.d.mts.map +1 -0
- package/dist/services/versioning/changelog-formatter.mjs +155 -0
- package/dist/services/versioning/changelog-formatter.mjs.map +1 -0
- package/dist/services/versioning/conventional-commits.d.mts +95 -0
- package/dist/services/versioning/conventional-commits.d.mts.map +1 -0
- package/dist/services/versioning/conventional-commits.mjs +184 -0
- package/dist/services/versioning/conventional-commits.mjs.map +1 -0
- package/dist/services/versioning/index.d.mts +12 -0
- package/dist/services/versioning/index.d.mts.map +1 -0
- package/dist/services/versioning/index.mjs +28 -0
- package/dist/services/versioning/index.mjs.map +1 -0
- package/dist/services/versioning/types.d.mts +135 -0
- package/dist/services/versioning/types.d.mts.map +1 -0
- package/dist/services/versioning/versioning-service.d.mts +74 -0
- package/dist/services/versioning/versioning-service.d.mts.map +1 -0
- package/dist/services/versioning/versioning-service.mjs +501 -0
- package/dist/services/versioning/versioning-service.mjs.map +1 -0
- package/dist/services/vibe/config.d.mts +12 -0
- package/dist/services/vibe/config.d.mts.map +1 -0
- package/dist/services/vibe/config.mjs +43 -0
- package/dist/services/vibe/config.mjs.map +1 -0
- package/dist/services/vibe/context.d.mts +19 -0
- package/dist/services/vibe/context.d.mts.map +1 -0
- package/dist/services/vibe/context.mjs +92 -0
- package/dist/services/vibe/context.mjs.map +1 -0
- package/dist/services/vibe/definitions.d.mts +8 -0
- package/dist/services/vibe/definitions.d.mts.map +1 -0
- package/dist/services/vibe/definitions.mjs +129 -0
- package/dist/services/vibe/definitions.mjs.map +1 -0
- package/dist/services/vibe/engine.d.mts +44 -0
- package/dist/services/vibe/engine.d.mts.map +1 -0
- package/dist/services/vibe/engine.mjs +147 -0
- package/dist/services/vibe/engine.mjs.map +1 -0
- package/dist/services/vibe/index.d.mts +15 -0
- package/dist/services/vibe/index.d.mts.map +1 -0
- package/dist/services/vibe/index.mjs +26 -0
- package/dist/services/vibe/index.mjs.map +1 -0
- package/dist/services/vibe/loader.d.mts +15 -0
- package/dist/services/vibe/loader.d.mts.map +1 -0
- package/dist/services/vibe/loader.mjs +48 -0
- package/dist/services/vibe/loader.mjs.map +1 -0
- package/dist/services/vibe/pack.d.mts +19 -0
- package/dist/services/vibe/pack.d.mts.map +1 -0
- package/dist/services/vibe/pack.mjs +66 -0
- package/dist/services/vibe/pack.mjs.map +1 -0
- package/dist/services/vibe/types.d.mts +59 -0
- package/dist/services/vibe/types.d.mts.map +1 -0
- package/dist/services/vibe/types.mjs +12 -0
- package/dist/services/vibe/types.mjs.map +1 -0
- package/dist/services/view/index.d.mts +11 -0
- package/dist/services/view/index.d.mts.map +1 -0
- package/dist/services/view/index.mjs +119 -0
- package/dist/services/view/index.mjs.map +1 -0
- package/dist/services/watch.d.mts +25 -0
- package/dist/services/watch.d.mts.map +1 -0
- package/dist/services/watch.mjs +33 -0
- package/dist/services/watch.mjs.map +1 -0
- package/dist/services/workspace-info.d.mts +62 -0
- package/dist/services/workspace-info.d.mts.map +1 -0
- package/dist/services/workspace-info.mjs +103 -0
- package/dist/services/workspace-info.mjs.map +1 -0
- package/dist/templates/app-config.template.d.mts +7 -0
- package/dist/templates/app-config.template.d.mts.map +1 -0
- package/dist/templates/app-config.template.mjs +107 -0
- package/dist/templates/app-config.template.mjs.map +1 -0
- package/dist/templates/data-view.template.d.mts +7 -0
- package/dist/templates/data-view.template.d.mts.map +1 -0
- package/dist/templates/data-view.template.mjs +70 -0
- package/dist/templates/data-view.template.mjs.map +1 -0
- package/dist/templates/event.template.d.mts +11 -0
- package/dist/templates/event.template.d.mts.map +1 -0
- package/dist/templates/event.template.mjs +42 -0
- package/dist/templates/event.template.mjs.map +1 -0
- package/dist/templates/experiment.template.d.mts +7 -0
- package/dist/templates/experiment.template.d.mts.map +1 -0
- package/dist/templates/experiment.template.mjs +89 -0
- package/dist/templates/experiment.template.mjs.map +1 -0
- package/dist/templates/feature.template.d.mts +33 -0
- package/dist/templates/feature.template.d.mts.map +1 -0
- package/dist/templates/feature.template.mjs +52 -0
- package/dist/templates/feature.template.mjs.map +1 -0
- package/dist/templates/fix/skeleton-capability.mjs +49 -0
- package/dist/templates/fix/skeleton-capability.mjs.map +1 -0
- package/dist/templates/fix/skeleton-event.mjs +56 -0
- package/dist/templates/fix/skeleton-event.mjs.map +1 -0
- package/dist/templates/fix/skeleton-operation.mjs +122 -0
- package/dist/templates/fix/skeleton-operation.mjs.map +1 -0
- package/dist/templates/fix/skeleton-presentation.mjs +65 -0
- package/dist/templates/fix/skeleton-presentation.mjs.map +1 -0
- package/dist/templates/fix/utils.mjs +34 -0
- package/dist/templates/fix/utils.mjs.map +1 -0
- package/dist/templates/handler.template.d.mts +16 -0
- package/dist/templates/handler.template.d.mts.map +1 -0
- package/dist/templates/handler.template.mjs +100 -0
- package/dist/templates/handler.template.mjs.map +1 -0
- package/dist/templates/index.d.mts +22 -0
- package/dist/templates/index.d.mts.map +1 -0
- package/dist/templates/index.mjs +39 -0
- package/dist/templates/index.mjs.map +1 -0
- package/dist/templates/integration.template.d.mts +7 -0
- package/dist/templates/integration.template.d.mts.map +1 -0
- package/dist/templates/integration.template.mjs +160 -0
- package/dist/templates/integration.template.mjs.map +1 -0
- package/dist/templates/knowledge.template.d.mts +7 -0
- package/dist/templates/knowledge.template.d.mts.map +1 -0
- package/dist/templates/knowledge.template.mjs +75 -0
- package/dist/templates/knowledge.template.mjs.map +1 -0
- package/dist/templates/migration.template.d.mts +7 -0
- package/dist/templates/migration.template.d.mts.map +1 -0
- package/dist/templates/migration.template.mjs +62 -0
- package/dist/templates/migration.template.mjs.map +1 -0
- package/dist/templates/operation.template.d.mts +11 -0
- package/dist/templates/operation.template.d.mts.map +1 -0
- package/dist/templates/operation.template.mjs +107 -0
- package/dist/templates/operation.template.mjs.map +1 -0
- package/dist/templates/presentation.template.d.mts +11 -0
- package/dist/templates/presentation.template.d.mts.map +1 -0
- package/dist/templates/presentation.template.mjs +80 -0
- package/dist/templates/presentation.template.mjs.map +1 -0
- package/dist/templates/telemetry.template.d.mts +7 -0
- package/dist/templates/telemetry.template.d.mts.map +1 -0
- package/dist/templates/telemetry.template.mjs +91 -0
- package/dist/templates/telemetry.template.mjs.map +1 -0
- package/dist/templates/workflow-runner.template.d.mts +16 -0
- package/dist/templates/workflow-runner.template.d.mts.map +1 -0
- package/dist/templates/workflow-runner.template.mjs +50 -0
- package/dist/templates/workflow-runner.template.mjs.map +1 -0
- package/dist/templates/workflow.template.d.mts +7 -0
- package/dist/templates/workflow.template.d.mts.map +1 -0
- package/dist/templates/workflow.template.mjs +69 -0
- package/dist/templates/workflow.template.mjs.map +1 -0
- package/dist/types/config.d.mts +34 -0
- package/dist/types/config.d.mts.map +1 -0
- package/dist/types.d.mts +324 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/utils/filter.d.mts +16 -0
- package/dist/utils/filter.d.mts.map +1 -0
- package/dist/utils/filter.mjs +22 -0
- package/dist/utils/filter.mjs.map +1 -0
- package/dist/utils/index.d.mts +11 -0
- package/dist/utils/index.d.mts.map +1 -0
- package/dist/utils/index.mjs +20 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/utils/module-loader.d.mts +5 -0
- package/dist/utils/module-loader.d.mts.map +1 -0
- package/dist/utils/module-loader.mjs +41 -0
- package/dist/utils/module-loader.mjs.map +1 -0
- package/dist/utils/validation.d.mts +37 -0
- package/dist/utils/validation.d.mts.map +1 -0
- package/dist/utils/validation.mjs +43 -0
- package/dist/utils/validation.mjs.map +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"implementation-validator.mjs","names":[],"sources":["../../../src/services/validate/implementation-validator.ts"],"sourcesContent":["/**\n * Implementation validation service (handlers + tests).\n *\n * Deterministic, static checks intended for reuse across CLI/VSCode/web tooling.\n * This does NOT execute spec modules.\n */\n\nimport type { WorkspaceConfig } from '@contractspec/module.workspace';\nimport { scanSpecSource } from '@contractspec/module.workspace';\nimport type { FsAdapter } from '../../ports/fs';\n\nexport interface ValidateImplementationOptions {\n checkHandlers?: boolean;\n checkTests?: boolean;\n /**\n * Override workspace outputDir (defaults to config.outputDir).\n */\n outputDir?: string;\n}\n\nexport interface ValidateImplementationResult {\n valid: boolean;\n errors: string[];\n warnings: string[];\n expected: {\n handlerPath?: string;\n handlerTestPath?: string;\n componentPath?: string;\n componentTestPath?: string;\n formPath?: string;\n formTestPath?: string;\n };\n}\n\nfunction toKebabCase(value: string): string {\n return value\n .replace(/\\./g, '-')\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .toLowerCase();\n}\n\nfunction toPascalCase(value: string): string {\n return value\n .split(/[-_.]/)\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n}\n\nexport async function validateImplementationFiles(\n specFile: string,\n adapters: { fs: FsAdapter },\n config: WorkspaceConfig,\n options: ValidateImplementationOptions = {}\n): Promise<ValidateImplementationResult> {\n const { fs } = adapters;\n const errors: string[] = [];\n const warnings: string[] = [];\n\n const exists = await fs.exists(specFile);\n if (!exists) {\n return {\n valid: false,\n errors: [`Spec file not found: ${specFile}`],\n warnings: [],\n expected: {},\n };\n }\n\n const code = await fs.readFile(specFile);\n const scan = scanSpecSource(code, specFile);\n const specName = scan.key ?? fs.basename(specFile).replace(/\\.[jt]s$/, '');\n const outRoot = options.outputDir ?? config.outputDir ?? './src';\n const kebab = toKebabCase(specName);\n\n const expected: ValidateImplementationResult['expected'] = {};\n\n if (scan.specType === 'operation') {\n expected.handlerPath = fs.join(outRoot, 'handlers', `${kebab}.handler.ts`);\n expected.handlerTestPath = fs.join(\n outRoot,\n 'handlers',\n `${kebab}.handler.test.ts`\n );\n }\n if (scan.specType === 'presentation') {\n expected.componentPath = fs.join(outRoot, 'components', `${kebab}.tsx`);\n expected.componentTestPath = fs.join(\n outRoot,\n 'components',\n `${kebab}.test.tsx`\n );\n }\n if (scan.specType === 'form') {\n expected.formPath = fs.join(outRoot, 'forms', `${kebab}.form.tsx`);\n expected.formTestPath = fs.join(outRoot, 'forms', `${kebab}.form.test.tsx`);\n }\n\n if (options.checkHandlers && expected.handlerPath) {\n const handlerExists = await fs.exists(expected.handlerPath);\n if (!handlerExists) {\n errors.push(`Missing handler file: ${expected.handlerPath}`);\n } else {\n const handlerCode = await fs.readFile(expected.handlerPath);\n\n const expectedSpecVar = `${toPascalCase(specName.split('.').pop() ?? specName)}Spec`;\n const hasContractHandlerType = /ContractHandler<\\s*typeof\\s+\\w+\\s*>/.test(\n handlerCode\n );\n const referencesExpectedSpec = new RegExp(\n `typeof\\\\s+${expectedSpecVar}\\\\b`\n ).test(handlerCode);\n if (!hasContractHandlerType) {\n warnings.push(\n `Handler does not appear to type itself as ContractHandler<typeof Spec>: ${expected.handlerPath}`\n );\n } else if (!referencesExpectedSpec) {\n warnings.push(\n `Handler ContractHandler typing does not reference expected spec var (${expectedSpecVar}): ${expected.handlerPath}`\n );\n }\n }\n }\n\n if (options.checkTests) {\n const candidateTests = [\n expected.handlerTestPath,\n expected.componentTestPath,\n expected.formTestPath,\n ].filter((p): p is string => typeof p === 'string');\n\n for (const testPath of candidateTests) {\n const testExists = await fs.exists(testPath);\n if (!testExists) {\n errors.push(`Missing test file: ${testPath}`);\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n expected,\n };\n}\n"],"mappings":";;;AAkCA,SAAS,YAAY,OAAuB;AAC1C,QAAO,MACJ,QAAQ,OAAO,IAAI,CACnB,QAAQ,mBAAmB,QAAQ,CACnC,aAAa;;AAGlB,SAAS,aAAa,OAAuB;AAC3C,QAAO,MACJ,MAAM,QAAQ,CACd,OAAO,QAAQ,CACf,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,GAAG,KAAK,MAAM,EAAE,CAAC,CAC3D,KAAK,GAAG;;AAGb,eAAsB,4BACpB,UACA,UACA,QACA,UAAyC,EAAE,EACJ;CACvC,MAAM,EAAE,OAAO;CACf,MAAM,SAAmB,EAAE;CAC3B,MAAM,WAAqB,EAAE;AAG7B,KAAI,CADW,MAAM,GAAG,OAAO,SAAS,CAEtC,QAAO;EACL,OAAO;EACP,QAAQ,CAAC,wBAAwB,WAAW;EAC5C,UAAU,EAAE;EACZ,UAAU,EAAE;EACb;CAIH,MAAM,OAAO,eADA,MAAM,GAAG,SAAS,SAAS,EACN,SAAS;CAC3C,MAAM,WAAW,KAAK,OAAO,GAAG,SAAS,SAAS,CAAC,QAAQ,YAAY,GAAG;CAC1E,MAAM,UAAU,QAAQ,aAAa,OAAO,aAAa;CACzD,MAAM,QAAQ,YAAY,SAAS;CAEnC,MAAM,WAAqD,EAAE;AAE7D,KAAI,KAAK,aAAa,aAAa;AACjC,WAAS,cAAc,GAAG,KAAK,SAAS,YAAY,GAAG,MAAM,aAAa;AAC1E,WAAS,kBAAkB,GAAG,KAC5B,SACA,YACA,GAAG,MAAM,kBACV;;AAEH,KAAI,KAAK,aAAa,gBAAgB;AACpC,WAAS,gBAAgB,GAAG,KAAK,SAAS,cAAc,GAAG,MAAM,MAAM;AACvE,WAAS,oBAAoB,GAAG,KAC9B,SACA,cACA,GAAG,MAAM,WACV;;AAEH,KAAI,KAAK,aAAa,QAAQ;AAC5B,WAAS,WAAW,GAAG,KAAK,SAAS,SAAS,GAAG,MAAM,WAAW;AAClE,WAAS,eAAe,GAAG,KAAK,SAAS,SAAS,GAAG,MAAM,gBAAgB;;AAG7E,KAAI,QAAQ,iBAAiB,SAAS,YAEpC,KAAI,CADkB,MAAM,GAAG,OAAO,SAAS,YAAY,CAEzD,QAAO,KAAK,yBAAyB,SAAS,cAAc;MACvD;EACL,MAAM,cAAc,MAAM,GAAG,SAAS,SAAS,YAAY;EAE3D,MAAM,kBAAkB,GAAG,aAAa,SAAS,MAAM,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC;EAC/E,MAAM,yBAAyB,sCAAsC,KACnE,YACD;EACD,MAAM,0CAAyB,IAAI,OACjC,aAAa,gBAAgB,KAC9B,EAAC,KAAK,YAAY;AACnB,MAAI,CAAC,uBACH,UAAS,KACP,2EAA2E,SAAS,cACrF;WACQ,CAAC,uBACV,UAAS,KACP,wEAAwE,gBAAgB,KAAK,SAAS,cACvG;;AAKP,KAAI,QAAQ,YAAY;EACtB,MAAM,iBAAiB;GACrB,SAAS;GACT,SAAS;GACT,SAAS;GACV,CAAC,QAAQ,MAAmB,OAAO,MAAM,SAAS;AAEnD,OAAK,MAAM,YAAY,eAErB,KAAI,CADe,MAAM,GAAG,OAAO,SAAS,CAE1C,QAAO,KAAK,sBAAsB,WAAW;;AAKnD,QAAO;EACL,OAAO,OAAO,WAAW;EACzB;EACA;EACA;EACD"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ValidateSpecOptions, ValidateSpecResult, validateSpec, validateSpecs } from "./spec-validator.mjs";
|
|
2
|
+
import { ValidateImplementationOptions, ValidateImplementationResult, validateImplementationFiles } from "./implementation-validator.mjs";
|
|
3
|
+
import { BlueprintValidationResult, validateBlueprint } from "./blueprint-validator.mjs";
|
|
4
|
+
import { TenantValidationContext, TenantValidationResult, validateTenantConfig } from "./tenant-validator.mjs";
|
|
5
|
+
import { ImplementationValidationResult, ImplementationValidatorOptions, validateImplementationWithAgent } from "./implementation-agent-validator.mjs";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { validateSpec, validateSpecs } from "./spec-validator.mjs";
|
|
2
|
+
import { validateImplementationFiles } from "./implementation-validator.mjs";
|
|
3
|
+
import { validateBlueprint } from "./blueprint-validator.mjs";
|
|
4
|
+
import { validateTenantConfig } from "./tenant-validator.mjs";
|
|
5
|
+
import { validateImplementationWithAgent } from "./implementation-agent-validator.mjs";
|
|
6
|
+
|
|
7
|
+
export { };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { FsAdapter } from "../../ports/fs.mjs";
|
|
2
|
+
import { LoggerAdapter } from "../../ports/logger.mjs";
|
|
3
|
+
import { ValidationResult } from "@contractspec/module.workspace";
|
|
4
|
+
|
|
5
|
+
//#region src/services/validate/spec-validator.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options for spec validation.
|
|
9
|
+
*/
|
|
10
|
+
interface ValidateSpecOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Skip spec structure validation (e.g., for blueprint files).
|
|
13
|
+
*/
|
|
14
|
+
skipStructure?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Result of spec validation.
|
|
18
|
+
*/
|
|
19
|
+
interface ValidateSpecResult {
|
|
20
|
+
valid: boolean;
|
|
21
|
+
structureResult?: ValidationResult;
|
|
22
|
+
errors: string[];
|
|
23
|
+
warnings: string[];
|
|
24
|
+
code?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Validate a spec file.
|
|
28
|
+
*/
|
|
29
|
+
declare function validateSpec(specFile: string, adapters: {
|
|
30
|
+
fs: FsAdapter;
|
|
31
|
+
logger: LoggerAdapter;
|
|
32
|
+
}, options?: ValidateSpecOptions): Promise<ValidateSpecResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Validate multiple spec files.
|
|
35
|
+
*/
|
|
36
|
+
declare function validateSpecs(specFiles: string[], adapters: {
|
|
37
|
+
fs: FsAdapter;
|
|
38
|
+
logger: LoggerAdapter;
|
|
39
|
+
}, options?: ValidateSpecOptions): Promise<Map<string, ValidateSpecResult>>;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { ValidateSpecOptions, ValidateSpecResult, validateSpec, validateSpecs };
|
|
42
|
+
//# sourceMappingURL=spec-validator.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-validator.d.mts","names":[],"sources":["../../../src/services/validate/spec-validator.ts"],"sourcesContent":[],"mappings":";;;;;;AAwBA;AAWA;;AAEqC,UAvBpB,mBAAA,CAuBoB;EAC1B;;;EACD,aAAA,CAAA,EAAA,OAAA;AAqCV;;;;AAIuB,UAxDN,kBAAA,CAwDM;EAAZ,KAAA,EAAA,OAAA;EAAR,eAAA,CAAA,EAtDiB,gBAsDjB;EAAO,MAAA,EAAA,MAAA,EAAA;;;;;;;iBA7CY,YAAA;MAEJ;UAAmB;aAC1B,sBACR,QAAQ;;;;iBAqCW,aAAA;MAEJ;UAAmB;aAC1B,sBACR,QAAQ,YAAY"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { validateSpecStructure } from "@contractspec/module.workspace";
|
|
2
|
+
|
|
3
|
+
//#region src/services/validate/spec-validator.ts
|
|
4
|
+
/**
|
|
5
|
+
* Validation service.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Validate a spec file.
|
|
9
|
+
*/
|
|
10
|
+
async function validateSpec(specFile, adapters, options = {}) {
|
|
11
|
+
const { fs } = adapters;
|
|
12
|
+
if (!await fs.exists(specFile)) return {
|
|
13
|
+
valid: false,
|
|
14
|
+
errors: [`Spec file not found: ${specFile}`],
|
|
15
|
+
warnings: [],
|
|
16
|
+
code: void 0
|
|
17
|
+
};
|
|
18
|
+
const specCode = await fs.readFile(specFile);
|
|
19
|
+
const allErrors = [];
|
|
20
|
+
const allWarnings = [];
|
|
21
|
+
let structureResult;
|
|
22
|
+
if (!options.skipStructure) {
|
|
23
|
+
structureResult = validateSpecStructure(specCode, specFile);
|
|
24
|
+
allErrors.push(...structureResult.errors);
|
|
25
|
+
allWarnings.push(...structureResult.warnings);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
valid: allErrors.length === 0,
|
|
29
|
+
structureResult,
|
|
30
|
+
errors: allErrors,
|
|
31
|
+
warnings: allWarnings,
|
|
32
|
+
code: specCode
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Validate multiple spec files.
|
|
37
|
+
*/
|
|
38
|
+
async function validateSpecs(specFiles, adapters, options = {}) {
|
|
39
|
+
const results = /* @__PURE__ */ new Map();
|
|
40
|
+
for (const specFile of specFiles) {
|
|
41
|
+
const result = await validateSpec(specFile, adapters, options);
|
|
42
|
+
results.set(specFile, result);
|
|
43
|
+
}
|
|
44
|
+
return results;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
export { validateSpec, validateSpecs };
|
|
49
|
+
//# sourceMappingURL=spec-validator.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-validator.mjs","names":[],"sources":["../../../src/services/validate/spec-validator.ts"],"sourcesContent":["/**\n * Validation service.\n */\n\nimport {\n validateSpecStructure,\n type ValidationResult,\n} from '@contractspec/module.workspace';\nimport type { FsAdapter } from '../../ports/fs';\nimport type { LoggerAdapter } from '../../ports/logger';\n\n/**\n * Options for spec validation.\n */\nexport interface ValidateSpecOptions {\n /**\n * Skip spec structure validation (e.g., for blueprint files).\n */\n skipStructure?: boolean;\n}\n\n/**\n * Result of spec validation.\n */\nexport interface ValidateSpecResult {\n valid: boolean;\n structureResult?: ValidationResult;\n errors: string[];\n warnings: string[];\n code?: string;\n}\n\n/**\n * Validate a spec file.\n */\nexport async function validateSpec(\n specFile: string,\n adapters: { fs: FsAdapter; logger: LoggerAdapter },\n options: ValidateSpecOptions = {}\n): Promise<ValidateSpecResult> {\n const { fs } = adapters;\n\n const exists = await fs.exists(specFile);\n if (!exists) {\n return {\n valid: false,\n errors: [`Spec file not found: ${specFile}`],\n warnings: [],\n code: undefined,\n };\n }\n\n const specCode = await fs.readFile(specFile);\n\n const allErrors: string[] = [];\n const allWarnings: string[] = [];\n let structureResult: ValidationResult | undefined;\n\n if (!options.skipStructure) {\n structureResult = validateSpecStructure(specCode, specFile);\n allErrors.push(...structureResult.errors);\n allWarnings.push(...structureResult.warnings);\n }\n\n return {\n valid: allErrors.length === 0,\n structureResult,\n errors: allErrors,\n warnings: allWarnings,\n code: specCode,\n };\n}\n\n/**\n * Validate multiple spec files.\n */\nexport async function validateSpecs(\n specFiles: string[],\n adapters: { fs: FsAdapter; logger: LoggerAdapter },\n options: ValidateSpecOptions = {}\n): Promise<Map<string, ValidateSpecResult>> {\n const results = new Map<string, ValidateSpecResult>();\n\n for (const specFile of specFiles) {\n const result = await validateSpec(specFile, adapters, options);\n results.set(specFile, result);\n }\n\n return results;\n}\n"],"mappings":";;;;;;;;;AAmCA,eAAsB,aACpB,UACA,UACA,UAA+B,EAAE,EACJ;CAC7B,MAAM,EAAE,OAAO;AAGf,KAAI,CADW,MAAM,GAAG,OAAO,SAAS,CAEtC,QAAO;EACL,OAAO;EACP,QAAQ,CAAC,wBAAwB,WAAW;EAC5C,UAAU,EAAE;EACZ,MAAM;EACP;CAGH,MAAM,WAAW,MAAM,GAAG,SAAS,SAAS;CAE5C,MAAM,YAAsB,EAAE;CAC9B,MAAM,cAAwB,EAAE;CAChC,IAAI;AAEJ,KAAI,CAAC,QAAQ,eAAe;AAC1B,oBAAkB,sBAAsB,UAAU,SAAS;AAC3D,YAAU,KAAK,GAAG,gBAAgB,OAAO;AACzC,cAAY,KAAK,GAAG,gBAAgB,SAAS;;AAG/C,QAAO;EACL,OAAO,UAAU,WAAW;EAC5B;EACA,QAAQ;EACR,UAAU;EACV,MAAM;EACP;;;;;AAMH,eAAsB,cACpB,WACA,UACA,UAA+B,EAAE,EACS;CAC1C,MAAM,0BAAU,IAAI,KAAiC;AAErD,MAAK,MAAM,YAAY,WAAW;EAChC,MAAM,SAAS,MAAM,aAAa,UAAU,UAAU,QAAQ;AAC9D,UAAQ,IAAI,UAAU,OAAO;;AAG/B,QAAO"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { FsAdapter } from "../../ports/fs.mjs";
|
|
2
|
+
import { AppBlueprintSpec, TenantAppConfig, validateConfig } from "@contractspec/lib.contracts";
|
|
3
|
+
|
|
4
|
+
//#region src/services/validate/tenant-validator.d.ts
|
|
5
|
+
interface TenantValidationResult {
|
|
6
|
+
config?: TenantAppConfig;
|
|
7
|
+
report?: ReturnType<typeof validateConfig>;
|
|
8
|
+
valid: boolean;
|
|
9
|
+
errors: string[];
|
|
10
|
+
}
|
|
11
|
+
interface TenantValidationContext {
|
|
12
|
+
connections?: string[] | string;
|
|
13
|
+
integrationRegistrars?: string[] | string;
|
|
14
|
+
translationCatalog?: string;
|
|
15
|
+
}
|
|
16
|
+
declare function validateTenantConfig(blueprint: AppBlueprintSpec, tenantPath: string, contextOptions: TenantValidationContext, adapters: {
|
|
17
|
+
fs: FsAdapter;
|
|
18
|
+
}): Promise<TenantValidationResult>;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { TenantValidationContext, TenantValidationResult, validateTenantConfig };
|
|
21
|
+
//# sourceMappingURL=tenant-validator.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-validator.d.mts","names":[],"sources":["../../../src/services/validate/tenant-validator.ts"],"sourcesContent":[],"mappings":";;;;UAaiB,sBAAA;WACN;EADM,MAAA,CAAA,EAEN,UAFM,CAAA,OAEY,cAFU,CAAA;EAC5B,KAAA,EAAA,OAAA;EACkB,MAAA,EAAA,MAAA,EAAA;;AAAR,UAKJ,uBAAA,CALI;EAKJ,WAAA,CAAA,EAAA,MAAA,EAAA,GAAA,MAAuB;EAMlB,qBAAA,CAAA,EAAoB,MAAA,EAAA,GAAA,MAAA;EAC7B,kBAAA,CAAA,EAAA,MAAA;;AAGK,iBAJI,oBAAA,CAIJ,SAAA,EAHL,gBAGK,EAAA,UAAA,EAAA,MAAA,EAAA,cAAA,EADA,uBACA,EAAA,QAAA,EAAA;EACP,EAAA,EADO,SACP;CAAR,CAAA,EAAA,OAAA,CAAQ,sBAAR,CAAA"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { resolve } from "path";
|
|
2
|
+
import { pathToFileURL } from "url";
|
|
3
|
+
import { validateConfig } from "@contractspec/lib.contracts";
|
|
4
|
+
import { readFile } from "fs/promises";
|
|
5
|
+
|
|
6
|
+
//#region src/services/validate/tenant-validator.ts
|
|
7
|
+
async function validateTenantConfig(blueprint, tenantPath, contextOptions, adapters) {
|
|
8
|
+
const { fs } = adapters;
|
|
9
|
+
const resolvedPath = resolve(process.cwd(), tenantPath);
|
|
10
|
+
if (!await fs.exists(resolvedPath)) return {
|
|
11
|
+
valid: false,
|
|
12
|
+
errors: [`Tenant config file not found: ${resolvedPath}`]
|
|
13
|
+
};
|
|
14
|
+
try {
|
|
15
|
+
const tenant = await loadTenantConfig(resolvedPath);
|
|
16
|
+
const connections = await loadIntegrationConnections(contextOptions.connections, fs);
|
|
17
|
+
const catalog = await loadTranslationCatalog(contextOptions.translationCatalog, fs);
|
|
18
|
+
const integrationSpecs = await loadIntegrationRegistrars(contextOptions.integrationRegistrars);
|
|
19
|
+
const context = {};
|
|
20
|
+
if (connections.length > 0) context.tenantConnections = connections;
|
|
21
|
+
if (catalog) context.translationCatalogs = {
|
|
22
|
+
blueprint: [catalog],
|
|
23
|
+
platform: []
|
|
24
|
+
};
|
|
25
|
+
if (integrationSpecs) context.integrationSpecs = integrationSpecs;
|
|
26
|
+
const report = validateConfig(blueprint, tenant, context);
|
|
27
|
+
return {
|
|
28
|
+
config: tenant,
|
|
29
|
+
report,
|
|
30
|
+
valid: report.valid,
|
|
31
|
+
errors: report.errors.map((e) => `[${e.code}] ${e.path}: ${e.message}`)
|
|
32
|
+
};
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return {
|
|
35
|
+
valid: false,
|
|
36
|
+
errors: [error instanceof Error ? error.message : String(error)]
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function loadTenantConfig(tenantPath) {
|
|
41
|
+
if (tenantPath.endsWith(".json")) {
|
|
42
|
+
const raw = await readFile(tenantPath, "utf-8");
|
|
43
|
+
const json = JSON.parse(raw);
|
|
44
|
+
if (!isTenantConfig(json)) throw new Error("Tenant config JSON does not match the expected structure (missing meta).");
|
|
45
|
+
return json;
|
|
46
|
+
}
|
|
47
|
+
const mod = await loadModule(tenantPath);
|
|
48
|
+
const candidates = Object.values(mod).filter(isTenantConfig);
|
|
49
|
+
if (candidates.length === 0) throw new Error("Tenant config module does not export a TenantAppConfig.");
|
|
50
|
+
return candidates[0];
|
|
51
|
+
}
|
|
52
|
+
function isTenantConfig(value) {
|
|
53
|
+
return typeof value === "object" && value !== null && "meta" in value && typeof value.meta?.tenantId === "string";
|
|
54
|
+
}
|
|
55
|
+
async function loadModule(modulePath) {
|
|
56
|
+
try {
|
|
57
|
+
return await import(pathToFileURL(modulePath).href);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
throw new Error(`Failed to load module at ${modulePath}: ${error}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function normalizePathOption(value) {
|
|
63
|
+
if (!value) return [];
|
|
64
|
+
return (Array.isArray(value) ? value : value.split(",")).map((entry) => entry.trim()).filter(Boolean);
|
|
65
|
+
}
|
|
66
|
+
async function loadIntegrationConnections(value, fs) {
|
|
67
|
+
const paths = normalizePathOption(value);
|
|
68
|
+
if (!paths.length) return [];
|
|
69
|
+
const results = [];
|
|
70
|
+
for (const path$1 of paths) {
|
|
71
|
+
const resolved = resolve(process.cwd(), path$1);
|
|
72
|
+
if (!await fs.exists(resolved)) {
|
|
73
|
+
console.warn(`Warning: Connection file not found: ${resolved}`);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (resolved.endsWith(".json")) {
|
|
77
|
+
const raw = await readFile(resolved, "utf-8");
|
|
78
|
+
const parsed = JSON.parse(raw);
|
|
79
|
+
results.push(...collectConnections(parsed));
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const mod = await loadModule(resolved);
|
|
83
|
+
results.push(...collectConnections(mod));
|
|
84
|
+
}
|
|
85
|
+
return results;
|
|
86
|
+
}
|
|
87
|
+
function collectConnections(value) {
|
|
88
|
+
if (Array.isArray(value)) {
|
|
89
|
+
const connections = value.filter(isIntegrationConnection);
|
|
90
|
+
if (connections.length) return connections;
|
|
91
|
+
}
|
|
92
|
+
if (isIntegrationConnection(value)) return [value];
|
|
93
|
+
if (value && typeof value === "object") {
|
|
94
|
+
const collected = Object.values(value).flatMap((entry) => collectConnections(entry));
|
|
95
|
+
if (collected.length) return collected;
|
|
96
|
+
}
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
function isIntegrationConnection(value) {
|
|
100
|
+
return typeof value === "object" && value !== null && "meta" in value && typeof value.meta?.id === "string" && typeof value.secretRef === "string";
|
|
101
|
+
}
|
|
102
|
+
async function loadTranslationCatalog(path$1, fs) {
|
|
103
|
+
if (!path$1) return void 0;
|
|
104
|
+
const resolved = resolve(process.cwd(), path$1);
|
|
105
|
+
if (!await fs.exists(resolved)) return void 0;
|
|
106
|
+
if (resolved.endsWith(".json")) {
|
|
107
|
+
const raw = await readFile(resolved, "utf-8");
|
|
108
|
+
const parsed = JSON.parse(raw);
|
|
109
|
+
if (isBlueprintTranslationCatalog(parsed)) return normaliseTranslationCatalog(parsed);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const mod = await loadModule(resolved);
|
|
113
|
+
const catalogs = Object.values(mod).filter(isBlueprintTranslationCatalog);
|
|
114
|
+
if (catalogs.length === 0) return void 0;
|
|
115
|
+
return normaliseTranslationCatalog(catalogs[0]);
|
|
116
|
+
}
|
|
117
|
+
function isBlueprintTranslationCatalog(value) {
|
|
118
|
+
return typeof value === "object" && value !== null && "meta" in value && typeof value.meta?.key === "string" && typeof value.meta?.version === "string" && Array.isArray(value.entries);
|
|
119
|
+
}
|
|
120
|
+
function normaliseTranslationCatalog(catalog) {
|
|
121
|
+
const supportedLocales = catalog.supportedLocales && catalog.supportedLocales.length > 0 ? catalog.supportedLocales : [catalog.defaultLocale];
|
|
122
|
+
return {
|
|
123
|
+
...catalog,
|
|
124
|
+
supportedLocales
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async function loadIntegrationRegistrars(value) {
|
|
128
|
+
const entries = normalizePathOption(value);
|
|
129
|
+
if (!entries.length) return void 0;
|
|
130
|
+
const { IntegrationSpecRegistry } = await import("@contractspec/lib.contracts");
|
|
131
|
+
const registry = new IntegrationSpecRegistry();
|
|
132
|
+
for (const entry of entries) {
|
|
133
|
+
const { modulePath, exportName } = parseRegistrarEntry(entry);
|
|
134
|
+
if (!modulePath) continue;
|
|
135
|
+
const resolved = resolve(process.cwd(), modulePath);
|
|
136
|
+
try {
|
|
137
|
+
const registrar = pickRegistrar(await loadModule(resolved), exportName);
|
|
138
|
+
if (registrar) await registrar(registry);
|
|
139
|
+
} catch (e) {
|
|
140
|
+
console.warn(`Failed to load registrar from ${resolved}: ${e}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return registry;
|
|
144
|
+
}
|
|
145
|
+
function parseRegistrarEntry(entry) {
|
|
146
|
+
if (!entry) return { modulePath: null };
|
|
147
|
+
const [modulePathRaw, exportNameRaw] = entry.split("#");
|
|
148
|
+
return {
|
|
149
|
+
modulePath: modulePathRaw?.trim() ?? null,
|
|
150
|
+
exportName: exportNameRaw?.trim()
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function pickRegistrar(mod, exportName) {
|
|
154
|
+
if (exportName) {
|
|
155
|
+
const candidate = mod[exportName];
|
|
156
|
+
if (typeof candidate === "function") return candidate;
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (typeof mod.default === "function") return mod.default;
|
|
160
|
+
for (const value of Object.values(mod)) if (typeof value === "function") return value;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
//#endregion
|
|
164
|
+
export { validateTenantConfig };
|
|
165
|
+
//# sourceMappingURL=tenant-validator.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-validator.mjs","names":["validateTenantConfigSpecs","path"],"sources":["../../../src/services/validate/tenant-validator.ts"],"sourcesContent":["import { resolve } from 'path';\nimport { readFile } from 'fs/promises';\nimport { pathToFileURL } from 'url';\nimport {\n validateConfig as validateTenantConfigSpecs,\n type AppBlueprintSpec,\n type TenantAppConfig,\n type IntegrationSpecRegistry,\n type BlueprintTranslationCatalog,\n type IntegrationConnection,\n} from '@contractspec/lib.contracts';\nimport type { FsAdapter } from '../../ports/fs';\n\nexport interface TenantValidationResult {\n config?: TenantAppConfig;\n report?: ReturnType<typeof validateTenantConfigSpecs>;\n valid: boolean;\n errors: string[];\n}\n\nexport interface TenantValidationContext {\n connections?: string[] | string;\n integrationRegistrars?: string[] | string;\n translationCatalog?: string;\n}\n\nexport async function validateTenantConfig(\n blueprint: AppBlueprintSpec,\n tenantPath: string,\n contextOptions: TenantValidationContext,\n adapters: { fs: FsAdapter }\n): Promise<TenantValidationResult> {\n const { fs } = adapters;\n const resolvedPath = resolve(process.cwd(), tenantPath);\n\n if (!(await fs.exists(resolvedPath))) {\n return {\n valid: false,\n errors: [`Tenant config file not found: ${resolvedPath}`],\n };\n }\n\n try {\n const tenant = await loadTenantConfig(resolvedPath);\n const connections = await loadIntegrationConnections(\n contextOptions.connections,\n fs\n );\n const catalog = await loadTranslationCatalog(\n contextOptions.translationCatalog,\n fs\n );\n const integrationSpecs = await loadIntegrationRegistrars(\n contextOptions.integrationRegistrars\n );\n\n const context: Parameters<typeof validateTenantConfigSpecs>[2] = {};\n if (connections.length > 0) {\n context.tenantConnections = connections;\n }\n if (catalog) {\n context.translationCatalogs = {\n blueprint: [catalog],\n platform: [],\n };\n }\n if (integrationSpecs) {\n context.integrationSpecs = integrationSpecs;\n }\n\n const report = validateTenantConfigSpecs(blueprint, tenant, context);\n\n return {\n config: tenant,\n report,\n valid: report.valid,\n errors: report.errors.map((e) => `[${e.code}] ${e.path}: ${e.message}`),\n };\n } catch (error) {\n return {\n valid: false,\n errors: [error instanceof Error ? error.message : String(error)],\n };\n }\n}\n\n// Helpers\n\nasync function loadTenantConfig(tenantPath: string): Promise<TenantAppConfig> {\n if (tenantPath.endsWith('.json')) {\n const raw = await readFile(tenantPath, 'utf-8');\n const json = JSON.parse(raw);\n if (!isTenantConfig(json)) {\n throw new Error(\n 'Tenant config JSON does not match the expected structure (missing meta).'\n );\n }\n return json;\n }\n\n const mod = await loadModule(tenantPath);\n const candidates = Object.values(mod).filter(isTenantConfig);\n if (candidates.length === 0) {\n throw new Error('Tenant config module does not export a TenantAppConfig.');\n }\n return candidates[0] as TenantAppConfig;\n}\n\nfunction isTenantConfig(value: unknown): value is TenantAppConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'meta' in value &&\n typeof (value as TenantAppConfig).meta?.tenantId === 'string'\n );\n}\n\n// Basic module loader\nasync function loadModule(\n modulePath: string\n): Promise<Record<string, unknown>> {\n try {\n const url = pathToFileURL(modulePath).href;\n const mod = await import(url);\n return mod;\n } catch (error) {\n throw new Error(`Failed to load module at ${modulePath}: ${error}`);\n }\n}\n\n// --- Connection Loaders ---\n\nfunction normalizePathOption(value?: string | string[]): string[] {\n if (!value) return [];\n const values = Array.isArray(value) ? value : value.split(',');\n return values.map((entry) => entry.trim()).filter(Boolean);\n}\n\nasync function loadIntegrationConnections(\n value: string | string[] | undefined,\n fs: FsAdapter\n): Promise<IntegrationConnection[]> {\n const paths = normalizePathOption(value);\n if (!paths.length) return [];\n\n const results: IntegrationConnection[] = [];\n for (const path of paths) {\n const resolved = resolve(process.cwd(), path);\n if (!(await fs.exists(resolved))) {\n console.warn(`Warning: Connection file not found: ${resolved}`);\n continue;\n }\n\n if (resolved.endsWith('.json')) {\n const raw = await readFile(resolved, 'utf-8');\n const parsed = JSON.parse(raw);\n results.push(...collectConnections(parsed));\n continue;\n }\n\n const mod = await loadModule(resolved);\n results.push(...collectConnections(mod));\n }\n return results;\n}\n\nfunction collectConnections(value: unknown): IntegrationConnection[] {\n if (Array.isArray(value)) {\n const connections = value.filter(isIntegrationConnection);\n if (connections.length) return connections;\n }\n if (isIntegrationConnection(value)) {\n return [value];\n }\n if (value && typeof value === 'object') {\n const entries = Object.values(value as Record<string, unknown>);\n const collected = entries.flatMap((entry) => collectConnections(entry));\n if (collected.length) return collected;\n }\n return [];\n}\n\nfunction isIntegrationConnection(\n value: unknown\n): value is IntegrationConnection {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'meta' in value &&\n typeof (value as IntegrationConnection).meta?.id === 'string' &&\n typeof (value as IntegrationConnection).secretRef === 'string'\n );\n}\n\n// --- Translation Catalog Loaders ---\n\nasync function loadTranslationCatalog(\n path: string | undefined,\n fs: FsAdapter\n): Promise<BlueprintTranslationCatalog | undefined> {\n if (!path) return undefined;\n const resolved = resolve(process.cwd(), path);\n if (!(await fs.exists(resolved))) return undefined;\n\n if (resolved.endsWith('.json')) {\n const raw = await readFile(resolved, 'utf-8');\n const parsed = JSON.parse(raw);\n if (isBlueprintTranslationCatalog(parsed)) {\n return normaliseTranslationCatalog(parsed);\n }\n return undefined;\n }\n\n const mod = await loadModule(resolved);\n const catalogs = Object.values(mod).filter(isBlueprintTranslationCatalog);\n if (catalogs.length === 0) return undefined;\n return normaliseTranslationCatalog(\n catalogs[0] as BlueprintTranslationCatalog\n );\n}\n\nfunction isBlueprintTranslationCatalog(\n value: unknown\n): value is BlueprintTranslationCatalog {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'meta' in value &&\n typeof (value as BlueprintTranslationCatalog).meta?.key === 'string' &&\n typeof (value as BlueprintTranslationCatalog).meta?.version === 'string' &&\n Array.isArray((value as BlueprintTranslationCatalog).entries)\n );\n}\n\nfunction normaliseTranslationCatalog(\n catalog: BlueprintTranslationCatalog\n): BlueprintTranslationCatalog {\n const supportedLocales =\n catalog.supportedLocales && catalog.supportedLocales.length > 0\n ? catalog.supportedLocales\n : [catalog.defaultLocale];\n return {\n ...catalog,\n supportedLocales,\n };\n}\n\n// --- Registrar Loaders ---\n// Important: This needs IntegrationSpecRegistry which is a Class.\n// We only import type in signature, but need constructor.\n// Imports fixed at top.\n\nasync function loadIntegrationRegistrars(\n value?: string | string[]\n): Promise<IntegrationSpecRegistry | undefined> {\n const entries = normalizePathOption(value);\n if (!entries.length) return undefined;\n\n // We need to import the Class dynamically or have it available.\n // It is imported from @contractspec/lib.contracts\n const { IntegrationSpecRegistry } =\n await import('@contractspec/lib.contracts');\n const registry = new IntegrationSpecRegistry();\n\n for (const entry of entries) {\n const { modulePath, exportName } = parseRegistrarEntry(entry);\n if (!modulePath) continue;\n const resolved = resolve(process.cwd(), modulePath);\n // Logic simplified for brevity, assume module exists or handled by catch in loadModule\n try {\n const mod = await loadModule(resolved);\n const registrar = pickRegistrar(mod, exportName);\n if (registrar) {\n await registrar(registry);\n }\n } catch (e) {\n console.warn(`Failed to load registrar from ${resolved}: ${e}`);\n }\n }\n return registry;\n}\n\nfunction parseRegistrarEntry(entry: string): {\n modulePath: string | null;\n exportName?: string;\n} {\n if (!entry) return { modulePath: null };\n const [modulePathRaw, exportNameRaw] = entry.split('#');\n const modulePath = modulePathRaw?.trim() ?? null;\n const exportName = exportNameRaw?.trim();\n return { modulePath, exportName };\n}\n\nfunction pickRegistrar(\n mod: Record<string, unknown>,\n exportName?: string\n): ((registry: IntegrationSpecRegistry) => void | Promise<void>) | undefined {\n if (exportName) {\n const candidate = mod[exportName];\n if (typeof candidate === 'function') {\n return candidate as (\n registry: IntegrationSpecRegistry\n ) => void | Promise<void>;\n }\n return undefined;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (typeof (mod as any).default === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (mod as any).default;\n }\n for (const value of Object.values(mod)) {\n if (typeof value === 'function') {\n return value as (\n registry: IntegrationSpecRegistry\n ) => void | Promise<void>;\n }\n }\n return undefined;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { CacheKeyString, CacheStorageAdapter, VerificationCacheEntry } from "../types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/services/verification-cache/adapters/filesystem.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Filesystem storage adapter.
|
|
7
|
+
*/
|
|
8
|
+
declare class FileSystemCacheStorage implements CacheStorageAdapter {
|
|
9
|
+
private filePath;
|
|
10
|
+
private cache;
|
|
11
|
+
private isDirty;
|
|
12
|
+
constructor(filePath?: string, workspaceRoot?: string);
|
|
13
|
+
/**
|
|
14
|
+
* Load cache from disk synchronously.
|
|
15
|
+
*/
|
|
16
|
+
private loadSync;
|
|
17
|
+
/**
|
|
18
|
+
* Save cache to disk.
|
|
19
|
+
*/
|
|
20
|
+
private saveSync;
|
|
21
|
+
get(key: CacheKeyString): Promise<VerificationCacheEntry | null>;
|
|
22
|
+
set(key: CacheKeyString, entry: VerificationCacheEntry): Promise<void>;
|
|
23
|
+
delete(key: CacheKeyString): Promise<boolean>;
|
|
24
|
+
has(key: CacheKeyString): Promise<boolean>;
|
|
25
|
+
keys(): Promise<CacheKeyString[]>;
|
|
26
|
+
clear(): Promise<void>;
|
|
27
|
+
stats(): Promise<{
|
|
28
|
+
entryCount: number;
|
|
29
|
+
memoryUsage?: number;
|
|
30
|
+
}>;
|
|
31
|
+
/**
|
|
32
|
+
* Force save any pending changes.
|
|
33
|
+
*/
|
|
34
|
+
flush(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Reload cache from disk.
|
|
37
|
+
*/
|
|
38
|
+
reload(): void;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create a filesystem cache storage adapter.
|
|
42
|
+
*/
|
|
43
|
+
declare function createFileSystemCacheStorage(filePath?: string, workspaceRoot?: string): FileSystemCacheStorage;
|
|
44
|
+
//#endregion
|
|
45
|
+
export { FileSystemCacheStorage, createFileSystemCacheStorage };
|
|
46
|
+
//# sourceMappingURL=filesystem.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem.d.mts","names":[],"sources":["../../../../src/services/verification-cache/adapters/filesystem.ts"],"sourcesContent":[],"mappings":";;;;;;;AAwHoB,cAhFP,sBAAA,YAAkC,mBAgF3B,CAAA;EAAiB,QAAA,QAAA;EASpB,QAAA,KAAA;EAAiB,QAAA,OAAA;EAIV,WAAA,CAAA,QAAA,CAAA,EAAA,MAAA,EAAA,aAAA,CAAA,EAAA,MAAA;EAAR;;;EA7F+B,QAAA,QAAA;EAAmB;AA4IlE;;;WAtEiB,iBAAiB,QAAQ;WAIzB,uBAAuB,yBAAyB;cAM7C,iBAAiB;WASpB,iBAAiB;UAIlB,QAAQ;WAIP;WAMA;;;;;;;;;;;;;;;;iBAqCD,4BAAA,6CAGb"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { dirname, join } from "path";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from "fs";
|
|
3
|
+
|
|
4
|
+
//#region src/services/verification-cache/adapters/filesystem.ts
|
|
5
|
+
/**
|
|
6
|
+
* Filesystem cache storage adapter.
|
|
7
|
+
*
|
|
8
|
+
* Stores cache entries in a JSON file for CLI and CI environments.
|
|
9
|
+
* Uses atomic writes to prevent corruption.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Default cache file location.
|
|
13
|
+
*/
|
|
14
|
+
const DEFAULT_CACHE_FILE = ".contractspec/verification-cache.json";
|
|
15
|
+
const CURRENT_VERSION = 1;
|
|
16
|
+
/**
|
|
17
|
+
* Filesystem storage adapter.
|
|
18
|
+
*/
|
|
19
|
+
var FileSystemCacheStorage = class {
|
|
20
|
+
filePath;
|
|
21
|
+
cache;
|
|
22
|
+
isDirty = false;
|
|
23
|
+
constructor(filePath, workspaceRoot) {
|
|
24
|
+
const root = workspaceRoot ?? process.cwd();
|
|
25
|
+
this.filePath = filePath ?? join(root, DEFAULT_CACHE_FILE);
|
|
26
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
27
|
+
this.loadSync();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Load cache from disk synchronously.
|
|
31
|
+
*/
|
|
32
|
+
loadSync() {
|
|
33
|
+
try {
|
|
34
|
+
if (!existsSync(this.filePath)) return;
|
|
35
|
+
const content = readFileSync(this.filePath, "utf-8");
|
|
36
|
+
const data = JSON.parse(content);
|
|
37
|
+
if (data.version !== CURRENT_VERSION) return;
|
|
38
|
+
for (const [key, entry] of Object.entries(data.entries)) this.cache.set(key, entry);
|
|
39
|
+
} catch {}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Save cache to disk.
|
|
43
|
+
*/
|
|
44
|
+
saveSync() {
|
|
45
|
+
if (!this.isDirty) return;
|
|
46
|
+
try {
|
|
47
|
+
const dir = dirname(this.filePath);
|
|
48
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
49
|
+
const data = {
|
|
50
|
+
version: CURRENT_VERSION,
|
|
51
|
+
entries: Object.fromEntries(this.cache.entries())
|
|
52
|
+
};
|
|
53
|
+
const tempPath = `${this.filePath}.tmp`;
|
|
54
|
+
writeFileSync(tempPath, JSON.stringify(data, null, 2), "utf-8");
|
|
55
|
+
renameSync(tempPath, this.filePath);
|
|
56
|
+
this.isDirty = false;
|
|
57
|
+
} catch {}
|
|
58
|
+
}
|
|
59
|
+
async get(key) {
|
|
60
|
+
return this.cache.get(key) ?? null;
|
|
61
|
+
}
|
|
62
|
+
async set(key, entry) {
|
|
63
|
+
this.cache.set(key, entry);
|
|
64
|
+
this.isDirty = true;
|
|
65
|
+
this.saveSync();
|
|
66
|
+
}
|
|
67
|
+
async delete(key) {
|
|
68
|
+
const existed = this.cache.delete(key);
|
|
69
|
+
if (existed) {
|
|
70
|
+
this.isDirty = true;
|
|
71
|
+
this.saveSync();
|
|
72
|
+
}
|
|
73
|
+
return existed;
|
|
74
|
+
}
|
|
75
|
+
async has(key) {
|
|
76
|
+
return this.cache.has(key);
|
|
77
|
+
}
|
|
78
|
+
async keys() {
|
|
79
|
+
return Array.from(this.cache.keys());
|
|
80
|
+
}
|
|
81
|
+
async clear() {
|
|
82
|
+
this.cache.clear();
|
|
83
|
+
this.isDirty = true;
|
|
84
|
+
this.saveSync();
|
|
85
|
+
}
|
|
86
|
+
async stats() {
|
|
87
|
+
let fileSize = 0;
|
|
88
|
+
try {
|
|
89
|
+
if (existsSync(this.filePath)) fileSize = statSync(this.filePath).size;
|
|
90
|
+
} catch {}
|
|
91
|
+
return {
|
|
92
|
+
entryCount: this.cache.size,
|
|
93
|
+
memoryUsage: fileSize
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Force save any pending changes.
|
|
98
|
+
*/
|
|
99
|
+
flush() {
|
|
100
|
+
this.saveSync();
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Reload cache from disk.
|
|
104
|
+
*/
|
|
105
|
+
reload() {
|
|
106
|
+
this.cache.clear();
|
|
107
|
+
this.loadSync();
|
|
108
|
+
this.isDirty = false;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Create a filesystem cache storage adapter.
|
|
113
|
+
*/
|
|
114
|
+
function createFileSystemCacheStorage(filePath, workspaceRoot) {
|
|
115
|
+
return new FileSystemCacheStorage(filePath, workspaceRoot);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//#endregion
|
|
119
|
+
export { FileSystemCacheStorage, createFileSystemCacheStorage };
|
|
120
|
+
//# sourceMappingURL=filesystem.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem.mjs","names":[],"sources":["../../../../src/services/verification-cache/adapters/filesystem.ts"],"sourcesContent":["/**\n * Filesystem cache storage adapter.\n *\n * Stores cache entries in a JSON file for CLI and CI environments.\n * Uses atomic writes to prevent corruption.\n */\n\nimport {\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n statSync,\n renameSync,\n} from 'fs';\nimport { dirname, join } from 'path';\nimport type {\n CacheKeyString,\n CacheStorageAdapter,\n VerificationCacheEntry,\n} from '../types';\n\n/**\n * Default cache file location.\n */\nconst DEFAULT_CACHE_FILE = '.contractspec/verification-cache.json';\n\n/**\n * Cache file structure.\n */\ninterface CacheFileData {\n version: number;\n entries: Record<CacheKeyString, VerificationCacheEntry>;\n}\n\nconst CURRENT_VERSION = 1;\n\n/**\n * Filesystem storage adapter.\n */\nexport class FileSystemCacheStorage implements CacheStorageAdapter {\n private filePath: string;\n private cache: Map<CacheKeyString, VerificationCacheEntry>;\n private isDirty = false;\n\n constructor(filePath?: string, workspaceRoot?: string) {\n const root = workspaceRoot ?? process.cwd();\n this.filePath = filePath ?? join(root, DEFAULT_CACHE_FILE);\n this.cache = new Map();\n this.loadSync();\n }\n\n /**\n * Load cache from disk synchronously.\n */\n private loadSync(): void {\n try {\n if (!existsSync(this.filePath)) {\n return;\n }\n\n const content = readFileSync(this.filePath, 'utf-8');\n const data = JSON.parse(content) as CacheFileData;\n\n // Version check\n if (data.version !== CURRENT_VERSION) {\n // Incompatible version, start fresh\n return;\n }\n\n // Load entries\n for (const [key, entry] of Object.entries(data.entries)) {\n this.cache.set(key, entry);\n }\n } catch {\n // Ignore load errors, start with empty cache\n }\n }\n\n /**\n * Save cache to disk.\n */\n private saveSync(): void {\n if (!this.isDirty) return;\n\n try {\n // Ensure directory exists\n const dir = dirname(this.filePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n const data: CacheFileData = {\n version: CURRENT_VERSION,\n entries: Object.fromEntries(this.cache.entries()),\n };\n\n // Atomic write: write to temp file, then rename\n const tempPath = `${this.filePath}.tmp`;\n writeFileSync(tempPath, JSON.stringify(data, null, 2), 'utf-8');\n\n // Rename is atomic on most filesystems\n renameSync(tempPath, this.filePath);\n\n this.isDirty = false;\n } catch {\n // Ignore save errors\n }\n }\n\n async get(key: CacheKeyString): Promise<VerificationCacheEntry | null> {\n return this.cache.get(key) ?? null;\n }\n\n async set(key: CacheKeyString, entry: VerificationCacheEntry): Promise<void> {\n this.cache.set(key, entry);\n this.isDirty = true;\n this.saveSync();\n }\n\n async delete(key: CacheKeyString): Promise<boolean> {\n const existed = this.cache.delete(key);\n if (existed) {\n this.isDirty = true;\n this.saveSync();\n }\n return existed;\n }\n\n async has(key: CacheKeyString): Promise<boolean> {\n return this.cache.has(key);\n }\n\n async keys(): Promise<CacheKeyString[]> {\n return Array.from(this.cache.keys());\n }\n\n async clear(): Promise<void> {\n this.cache.clear();\n this.isDirty = true;\n this.saveSync();\n }\n\n async stats(): Promise<{ entryCount: number; memoryUsage?: number }> {\n let fileSize = 0;\n try {\n if (existsSync(this.filePath)) {\n const stat = statSync(this.filePath);\n fileSize = stat.size;\n }\n } catch {\n // Ignore\n }\n\n return {\n entryCount: this.cache.size,\n memoryUsage: fileSize,\n };\n }\n\n /**\n * Force save any pending changes.\n */\n flush(): void {\n this.saveSync();\n }\n\n /**\n * Reload cache from disk.\n */\n reload(): void {\n this.cache.clear();\n this.loadSync();\n this.isDirty = false;\n }\n}\n\n/**\n * Create a filesystem cache storage adapter.\n */\nexport function createFileSystemCacheStorage(\n filePath?: string,\n workspaceRoot?: string\n): FileSystemCacheStorage {\n return new FileSystemCacheStorage(filePath, workspaceRoot);\n}\n"],"mappings":";;;;;;;;;;;;;AAyBA,MAAM,qBAAqB;AAU3B,MAAM,kBAAkB;;;;AAKxB,IAAa,yBAAb,MAAmE;CACjE,AAAQ;CACR,AAAQ;CACR,AAAQ,UAAU;CAElB,YAAY,UAAmB,eAAwB;EACrD,MAAM,OAAO,iBAAiB,QAAQ,KAAK;AAC3C,OAAK,WAAW,YAAY,KAAK,MAAM,mBAAmB;AAC1D,OAAK,wBAAQ,IAAI,KAAK;AACtB,OAAK,UAAU;;;;;CAMjB,AAAQ,WAAiB;AACvB,MAAI;AACF,OAAI,CAAC,WAAW,KAAK,SAAS,CAC5B;GAGF,MAAM,UAAU,aAAa,KAAK,UAAU,QAAQ;GACpD,MAAM,OAAO,KAAK,MAAM,QAAQ;AAGhC,OAAI,KAAK,YAAY,gBAEnB;AAIF,QAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,QAAQ,CACrD,MAAK,MAAM,IAAI,KAAK,MAAM;UAEtB;;;;;CAQV,AAAQ,WAAiB;AACvB,MAAI,CAAC,KAAK,QAAS;AAEnB,MAAI;GAEF,MAAM,MAAM,QAAQ,KAAK,SAAS;AAClC,OAAI,CAAC,WAAW,IAAI,CAClB,WAAU,KAAK,EAAE,WAAW,MAAM,CAAC;GAGrC,MAAM,OAAsB;IAC1B,SAAS;IACT,SAAS,OAAO,YAAY,KAAK,MAAM,SAAS,CAAC;IAClD;GAGD,MAAM,WAAW,GAAG,KAAK,SAAS;AAClC,iBAAc,UAAU,KAAK,UAAU,MAAM,MAAM,EAAE,EAAE,QAAQ;AAG/D,cAAW,UAAU,KAAK,SAAS;AAEnC,QAAK,UAAU;UACT;;CAKV,MAAM,IAAI,KAA6D;AACrE,SAAO,KAAK,MAAM,IAAI,IAAI,IAAI;;CAGhC,MAAM,IAAI,KAAqB,OAA8C;AAC3E,OAAK,MAAM,IAAI,KAAK,MAAM;AAC1B,OAAK,UAAU;AACf,OAAK,UAAU;;CAGjB,MAAM,OAAO,KAAuC;EAClD,MAAM,UAAU,KAAK,MAAM,OAAO,IAAI;AACtC,MAAI,SAAS;AACX,QAAK,UAAU;AACf,QAAK,UAAU;;AAEjB,SAAO;;CAGT,MAAM,IAAI,KAAuC;AAC/C,SAAO,KAAK,MAAM,IAAI,IAAI;;CAG5B,MAAM,OAAkC;AACtC,SAAO,MAAM,KAAK,KAAK,MAAM,MAAM,CAAC;;CAGtC,MAAM,QAAuB;AAC3B,OAAK,MAAM,OAAO;AAClB,OAAK,UAAU;AACf,OAAK,UAAU;;CAGjB,MAAM,QAA+D;EACnE,IAAI,WAAW;AACf,MAAI;AACF,OAAI,WAAW,KAAK,SAAS,CAE3B,YADa,SAAS,KAAK,SAAS,CACpB;UAEZ;AAIR,SAAO;GACL,YAAY,KAAK,MAAM;GACvB,aAAa;GACd;;;;;CAMH,QAAc;AACZ,OAAK,UAAU;;;;;CAMjB,SAAe;AACb,OAAK,MAAM,OAAO;AAClB,OAAK,UAAU;AACf,OAAK,UAAU;;;;;;AAOnB,SAAgB,6BACd,UACA,eACwB;AACxB,QAAO,IAAI,uBAAuB,UAAU,cAAc"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CacheKeyString, CacheStorageAdapter, VerificationCacheEntry } from "../types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/services/verification-cache/adapters/in-memory.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* In-memory storage adapter using a Map.
|
|
7
|
+
*/
|
|
8
|
+
declare class InMemoryCacheStorage implements CacheStorageAdapter {
|
|
9
|
+
private cache;
|
|
10
|
+
get(key: CacheKeyString): Promise<VerificationCacheEntry | null>;
|
|
11
|
+
set(key: CacheKeyString, entry: VerificationCacheEntry): Promise<void>;
|
|
12
|
+
delete(key: CacheKeyString): Promise<boolean>;
|
|
13
|
+
has(key: CacheKeyString): Promise<boolean>;
|
|
14
|
+
keys(): Promise<CacheKeyString[]>;
|
|
15
|
+
clear(): Promise<void>;
|
|
16
|
+
stats(): Promise<{
|
|
17
|
+
entryCount: number;
|
|
18
|
+
memoryUsage?: number;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Create an in-memory cache storage adapter.
|
|
23
|
+
*/
|
|
24
|
+
declare function createInMemoryCacheStorage(): InMemoryCacheStorage;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { InMemoryCacheStorage, createInMemoryCacheStorage };
|
|
27
|
+
//# sourceMappingURL=in-memory.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory.d.mts","names":[],"sources":["../../../../src/services/verification-cache/adapters/in-memory.ts"],"sourcesContent":[],"mappings":";;;;;;;AA2BoB,cAXP,oBAAA,YAAgC,mBAWzB,CAAA;EAAiB,QAAA,KAAA;EAIpB,GAAA,CAAA,GAAA,EAZA,cAYA,CAAA,EAZiB,OAYjB,CAZyB,sBAYzB,GAAA,IAAA,CAAA;EAAiB,GAAA,CAAA,GAAA,EARjB,cAQiB,EAAA,KAAA,EARM,sBAQN,CAAA,EAR+B,OAQ/B,CAAA,IAAA,CAAA;EAIV,MAAA,CAAA,GAAA,EARJ,cAQI,CAAA,EARa,OAQb,CAAA,OAAA,CAAA;EAAR,GAAA,CAAA,GAAA,EAJC,cAID,CAAA,EAJkB,OAIlB,CAAA,OAAA,CAAA;EAIC,IAAA,CAAA,CAAA,EAJD,OAIC,CAJO,cAIP,EAAA,CAAA;EAIA,KAAA,CAAA,CAAA,EAJA,OAIA,CAAA,IAAA,CAAA;EA3B4B,KAAA,CAAA,CAAA,EA2B5B,OA3B4B,CAAA;IAAmB,UAAA,EAAA,MAAA;IA6ChD,WAAA,CAAA,EAAA,MAAA;;;;;;iBAAA,0BAAA,CAAA,GAA8B"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
//#region src/services/verification-cache/adapters/in-memory.ts
|
|
2
|
+
/**
|
|
3
|
+
* In-memory storage adapter using a Map.
|
|
4
|
+
*/
|
|
5
|
+
var InMemoryCacheStorage = class {
|
|
6
|
+
cache = /* @__PURE__ */ new Map();
|
|
7
|
+
async get(key) {
|
|
8
|
+
return this.cache.get(key) ?? null;
|
|
9
|
+
}
|
|
10
|
+
async set(key, entry) {
|
|
11
|
+
this.cache.set(key, entry);
|
|
12
|
+
}
|
|
13
|
+
async delete(key) {
|
|
14
|
+
return this.cache.delete(key);
|
|
15
|
+
}
|
|
16
|
+
async has(key) {
|
|
17
|
+
return this.cache.has(key);
|
|
18
|
+
}
|
|
19
|
+
async keys() {
|
|
20
|
+
return Array.from(this.cache.keys());
|
|
21
|
+
}
|
|
22
|
+
async clear() {
|
|
23
|
+
this.cache.clear();
|
|
24
|
+
}
|
|
25
|
+
async stats() {
|
|
26
|
+
let memoryUsage = 0;
|
|
27
|
+
for (const [key, value] of this.cache.entries()) {
|
|
28
|
+
memoryUsage += key.length * 2;
|
|
29
|
+
memoryUsage += JSON.stringify(value).length * 2;
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
entryCount: this.cache.size,
|
|
33
|
+
memoryUsage
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Create an in-memory cache storage adapter.
|
|
39
|
+
*/
|
|
40
|
+
function createInMemoryCacheStorage() {
|
|
41
|
+
return new InMemoryCacheStorage();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
export { InMemoryCacheStorage, createInMemoryCacheStorage };
|
|
46
|
+
//# sourceMappingURL=in-memory.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory.mjs","names":[],"sources":["../../../../src/services/verification-cache/adapters/in-memory.ts"],"sourcesContent":["/**\n * In-memory cache storage adapter.\n *\n * Suitable for tests and single-process environments.\n * Data is lost on process restart.\n */\n\nimport type {\n CacheKeyString,\n CacheStorageAdapter,\n VerificationCacheEntry,\n} from '../types';\n\n/**\n * In-memory storage adapter using a Map.\n */\nexport class InMemoryCacheStorage implements CacheStorageAdapter {\n private cache = new Map<CacheKeyString, VerificationCacheEntry>();\n\n async get(key: CacheKeyString): Promise<VerificationCacheEntry | null> {\n return this.cache.get(key) ?? null;\n }\n\n async set(key: CacheKeyString, entry: VerificationCacheEntry): Promise<void> {\n this.cache.set(key, entry);\n }\n\n async delete(key: CacheKeyString): Promise<boolean> {\n return this.cache.delete(key);\n }\n\n async has(key: CacheKeyString): Promise<boolean> {\n return this.cache.has(key);\n }\n\n async keys(): Promise<CacheKeyString[]> {\n return Array.from(this.cache.keys());\n }\n\n async clear(): Promise<void> {\n this.cache.clear();\n }\n\n async stats(): Promise<{ entryCount: number; memoryUsage?: number }> {\n // Estimate memory usage (rough approximation)\n let memoryUsage = 0;\n for (const [key, value] of this.cache.entries()) {\n memoryUsage += key.length * 2; // UTF-16 string\n memoryUsage += JSON.stringify(value).length * 2;\n }\n\n return {\n entryCount: this.cache.size,\n memoryUsage,\n };\n }\n}\n\n/**\n * Create an in-memory cache storage adapter.\n */\nexport function createInMemoryCacheStorage(): InMemoryCacheStorage {\n return new InMemoryCacheStorage();\n}\n"],"mappings":";;;;AAgBA,IAAa,uBAAb,MAAiE;CAC/D,AAAQ,wBAAQ,IAAI,KAA6C;CAEjE,MAAM,IAAI,KAA6D;AACrE,SAAO,KAAK,MAAM,IAAI,IAAI,IAAI;;CAGhC,MAAM,IAAI,KAAqB,OAA8C;AAC3E,OAAK,MAAM,IAAI,KAAK,MAAM;;CAG5B,MAAM,OAAO,KAAuC;AAClD,SAAO,KAAK,MAAM,OAAO,IAAI;;CAG/B,MAAM,IAAI,KAAuC;AAC/C,SAAO,KAAK,MAAM,IAAI,IAAI;;CAG5B,MAAM,OAAkC;AACtC,SAAO,MAAM,KAAK,KAAK,MAAM,MAAM,CAAC;;CAGtC,MAAM,QAAuB;AAC3B,OAAK,MAAM,OAAO;;CAGpB,MAAM,QAA+D;EAEnE,IAAI,cAAc;AAClB,OAAK,MAAM,CAAC,KAAK,UAAU,KAAK,MAAM,SAAS,EAAE;AAC/C,kBAAe,IAAI,SAAS;AAC5B,kBAAe,KAAK,UAAU,MAAM,CAAC,SAAS;;AAGhD,SAAO;GACL,YAAY,KAAK,MAAM;GACvB;GACD;;;;;;AAOL,SAAgB,6BAAmD;AACjE,QAAO,IAAI,sBAAsB"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { InMemoryCacheStorage, createInMemoryCacheStorage } from "./in-memory.mjs";
|
|
2
|
+
import { FileSystemCacheStorage, createFileSystemCacheStorage } from "./filesystem.mjs";
|
|
3
|
+
import { KeyValueStore, WorkspaceStateCacheStorage, createWorkspaceStateCacheStorage } from "./workspace-state.mjs";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { InMemoryCacheStorage, createInMemoryCacheStorage } from "./in-memory.mjs";
|
|
2
|
+
import { FileSystemCacheStorage, createFileSystemCacheStorage } from "./filesystem.mjs";
|
|
3
|
+
import { WorkspaceStateCacheStorage, createWorkspaceStateCacheStorage } from "./workspace-state.mjs";
|
|
4
|
+
|
|
5
|
+
export { };
|