domainforge 0.13.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/.cargo/config.toml +6 -0
- package/.claude/settings.local.json +18 -0
- package/.coderabbit.yml +43 -0
- package/.codex/skills/release-management/SKILL.md +151 -0
- package/.codex/skills/release-management/agents/openai.yaml +4 -0
- package/.github/actions/decrypt-secrets/action.yml +121 -0
- package/.github/agents/Coder.agent.md +97 -0
- package/.github/agents/DeepResearch.agent.md +61 -0
- package/.github/chatmodes/tdd.vibepro.chatmode.md +1183 -0
- package/.github/copilot-instructions.md +13 -0
- package/.github/dependabot.yml +68 -0
- package/.github/workflows/README.md +165 -0
- package/.github/workflows/ci.yml +335 -0
- package/.github/workflows/dependabot-automerge.yml +114 -0
- package/.github/workflows/dependency-review.yml +27 -0
- package/.github/workflows/deploy.yml +87 -0
- package/.github/workflows/prepare-release.yml +168 -0
- package/.github/workflows/release-crates.yml +42 -0
- package/.github/workflows/release-npm.yml +137 -0
- package/.github/workflows/release-please.yml +29 -0
- package/.github/workflows/release-pypi.yml +96 -0
- package/.gitkeep +1 -0
- package/.release-please-manifest.json +5 -0
- package/.sea-registry.toml +10 -0
- package/.serena/project.yml +133 -0
- package/.sops.yaml +10 -0
- package/AGENTS.md +216 -0
- package/CHANGELOG.md +400 -0
- package/CLAUDE.md +62 -0
- package/CONTRIBUTING.md +323 -0
- package/Cargo.lock +3612 -0
- package/Cargo.toml +12 -0
- package/LICENSE +201 -0
- package/README.md +660 -0
- package/README_PYTHON.md +256 -0
- package/README_TYPESCRIPT.md +305 -0
- package/README_WASM.md +329 -0
- package/RELEASE_NOTES.md +41 -0
- package/bun.lock +378 -0
- package/bunfig.toml +11 -0
- package/check_output.txt +83 -0
- package/clippy_output.txt +80 -0
- package/commitlint.config.cjs +8 -0
- package/deny.toml +42 -0
- package/devbox.json +14 -0
- package/devbox.lock +76 -0
- package/docs/RELEASE_PROCESS.md +360 -0
- package/docs/diagnostics.md +161 -0
- package/docs/doc_guidelines.md +53 -0
- package/docs/explanations/README.md +21 -0
- package/docs/explanations/architecture-overview.md +109 -0
- package/docs/explanations/cross-language-binding-strategy.md +68 -0
- package/docs/explanations/graph-store-design.md +47 -0
- package/docs/explanations/performance-benchmarks.md +63 -0
- package/docs/explanations/policy-evaluation-logic.md +106 -0
- package/docs/explanations/semantic-modeling-concepts.md +109 -0
- package/docs/explanations/three-valued-logic.md +66 -0
- package/docs/explanations/versioning-strategy.md +45 -0
- package/docs/governance.md +168 -0
- package/docs/how-tos/README.md +46 -0
- package/docs/how-tos/ci-cd-validation.md +93 -0
- package/docs/how-tos/create-custom-units.md +125 -0
- package/docs/how-tos/define-policies.md +119 -0
- package/docs/how-tos/export-to-calm.md +110 -0
- package/docs/how-tos/export-to-protobuf.md +312 -0
- package/docs/how-tos/extend-grammar.md +133 -0
- package/docs/how-tos/generate-rdf-turtle.md +106 -0
- package/docs/how-tos/import-from-calm.md +114 -0
- package/docs/how-tos/import-from-sbvr.md +249 -0
- package/docs/how-tos/install-cli.md +126 -0
- package/docs/how-tos/parse-sea-files.md +132 -0
- package/docs/how-tos/policy-evaluation-modes.md +30 -0
- package/docs/how-tos/run-cross-language-tests.md +115 -0
- package/docs/how-tos/troubleshoot-napi-builds.md +55 -0
- package/docs/how-tos/use-modules-imports.md +285 -0
- package/docs/index.md +13 -0
- package/docs/plans/canonical-normalizer.md +121 -0
- package/docs/plans/cd_improvement.md +112 -0
- package/docs/plans/cli-ast.md +29 -0
- package/docs/plans/expression-bindings-and-normalizer-integration.md +174 -0
- package/docs/plans/protobuf_advanced_features_plan.md +597 -0
- package/docs/plans/protobuf_plan.yml +525 -0
- package/docs/plans/refactor_dsl_architecture.md +131 -0
- package/docs/plans/release-plan.md +163 -0
- package/docs/plans/sea_fmt_implementation_plan.md +516 -0
- package/docs/playbooks/README.md +18 -0
- package/docs/playbooks/adding-new-primitive.md +68 -0
- package/docs/playbooks/debugging-parser-failures.md +42 -0
- package/docs/playbooks/local-release-preparation.md +139 -0
- package/docs/playbooks/migrating-schema-versions.md +43 -0
- package/docs/playbooks/onboarding-contributors.md +64 -0
- package/docs/playbooks/releasing-beta.md +86 -0
- package/docs/playbooks/secret-management.md +64 -0
- package/docs/reference/README.md +199 -0
- package/docs/reference/ast-json-api.md +427 -0
- package/docs/reference/calm-mapping.md +519 -0
- package/docs/reference/cli-commands.md +588 -0
- package/docs/reference/configuration.md +202 -0
- package/docs/reference/error-codes.md +664 -0
- package/docs/reference/generated-artifacts-policy.md +53 -0
- package/docs/reference/grammar-spec.md +255 -0
- package/docs/reference/primitives-api.md +317 -0
- package/docs/reference/protobuf-api.md +426 -0
- package/docs/reference/python-api.md +485 -0
- package/docs/reference/registry.md +50 -0
- package/docs/reference/sea-dsl-ai-cheatsheet.yaml +913 -0
- package/docs/reference/security-model.md +74 -0
- package/docs/reference/typescript-api.md +508 -0
- package/docs/reference/wasm-api.md +420 -0
- package/docs/semantic-pack-review.md +144 -0
- package/docs/semantic-pack-signing.md +234 -0
- package/docs/semantic-packs.md +284 -0
- package/docs/specs/ADR-001-sea-dsl-semantic-source-of-truth.md +33 -0
- package/docs/specs/ADR-002-projection-first-class-construct.md +50 -0
- package/docs/specs/ADR-003-protobuf-projection-target.md +51 -0
- package/docs/specs/ADR-004-projection-compatibility-semantics.md +57 -0
- package/docs/specs/ADR-005-multi-language-support-strategy.md +112 -0
- package/docs/specs/ADR-006-error-handling-strategy.md +115 -0
- package/docs/specs/ADR-007-policy-evaluation-engine.md +95 -0
- package/docs/specs/ADR-008-knowledge-graph-integration.md +90 -0
- package/docs/specs/ADR-009-module-resolution-strategy.md +115 -0
- package/docs/specs/ADR-010-unit-system.md +106 -0
- package/docs/specs/PRD-001-sea-projection-framework.md +155 -0
- package/docs/specs/PRD-002-sea-cli-tooling.md +169 -0
- package/docs/specs/PRD-003-dsl-core-capabilities.md +275 -0
- package/docs/specs/README.md +62 -0
- package/docs/specs/SDS-001-protobuf-projection-engine.md +451 -0
- package/docs/specs/SDS-002-sea-core-architecture.md +268 -0
- package/docs/specs/SDS-003-parser-semantic-graph.md +377 -0
- package/docs/specs/SDS-004-policy-engine-design.md +362 -0
- package/docs/specs/SDS-005-knowledge-graph-module.md +364 -0
- package/docs/specs/SDS-006-calm-integration.md +367 -0
- package/docs/specs/SDS-007-sbvr-import.md +347 -0
- package/docs/templates/template_explanation.md +14 -0
- package/docs/templates/template_howto.md +21 -0
- package/docs/templates/template_playbook.md +21 -0
- package/docs/templates/template_reference.md +17 -0
- package/docs/templates/template_tutorial.md +24 -0
- package/docs/tutorials/README.md +12 -0
- package/docs/tutorials/first-sea-model.md +85 -0
- package/docs/tutorials/getting-started.md +98 -0
- package/docs/tutorials/python-binding-quickstart.md +107 -0
- package/docs/tutorials/typescript-binding-quickstart.md +91 -0
- package/docs/tutorials/wasm-in-browser.md +75 -0
- package/domainforge-core/CHANGELOG.md +138 -0
- package/domainforge-core/Cargo.toml +101 -0
- package/domainforge-core/MIGRATING.md +32 -0
- package/domainforge-core/README.md +197 -0
- package/domainforge-core/benchmark_results.txt +51 -0
- package/domainforge-core/build.rs +6 -0
- package/domainforge-core/deny.toml +31 -0
- package/domainforge-core/docs/specs/projections/sbvr_kg_mapping.md +43 -0
- package/domainforge-core/examples/basic.sea +7 -0
- package/domainforge-core/examples/cli/import_export_workflow.sh +38 -0
- package/domainforge-core/examples/cli/validate_example.sh +30 -0
- package/domainforge-core/examples/evolution_semantics.sea +31 -0
- package/domainforge-core/examples/parser_demo.rs +203 -0
- package/domainforge-core/grammar/sea.pest +408 -0
- package/domainforge-core/schemas/calm-v1.schema.json +170 -0
- package/domainforge-core/schemas/shacl/sea_shapes.ttl +19 -0
- package/domainforge-core/src/authority/compiler.rs +309 -0
- package/domainforge-core/src/authority/environment.rs +203 -0
- package/domainforge-core/src/authority/error.rs +164 -0
- package/domainforge-core/src/authority/fact_resolver.rs +224 -0
- package/domainforge-core/src/authority/mod.rs +25 -0
- package/domainforge-core/src/authority/pack.rs +133 -0
- package/domainforge-core/src/authority/policy.rs +224 -0
- package/domainforge-core/src/authority/resolver.rs +446 -0
- package/domainforge-core/src/authority/trace.rs +217 -0
- package/domainforge-core/src/authority/transform.rs +168 -0
- package/domainforge-core/src/authority/types.rs +617 -0
- package/domainforge-core/src/bin/domainforge.rs +25 -0
- package/domainforge-core/src/calm/export.rs +538 -0
- package/domainforge-core/src/calm/import.rs +1220 -0
- package/domainforge-core/src/calm/mod.rs +9 -0
- package/domainforge-core/src/calm/models.rs +108 -0
- package/domainforge-core/src/calm/sbvr_import.rs +9 -0
- package/domainforge-core/src/cli/authority.rs +149 -0
- package/domainforge-core/src/cli/format.rs +85 -0
- package/domainforge-core/src/cli/import.rs +133 -0
- package/domainforge-core/src/cli/mod.rs +64 -0
- package/domainforge-core/src/cli/normalize.rs +180 -0
- package/domainforge-core/src/cli/pack.rs +904 -0
- package/domainforge-core/src/cli/parse.rs +112 -0
- package/domainforge-core/src/cli/project.rs +294 -0
- package/domainforge-core/src/cli/registry.rs +41 -0
- package/domainforge-core/src/cli/test.rs +12 -0
- package/domainforge-core/src/cli/validate.rs +195 -0
- package/domainforge-core/src/cli/validate_kg.rs +80 -0
- package/domainforge-core/src/concept_id.rs +89 -0
- package/domainforge-core/src/error/diagnostics.rs +426 -0
- package/domainforge-core/src/error/fuzzy.rs +253 -0
- package/domainforge-core/src/error/mod.rs +13 -0
- package/domainforge-core/src/formatter/comments.rs +223 -0
- package/domainforge-core/src/formatter/config.rs +114 -0
- package/domainforge-core/src/formatter/mod.rs +22 -0
- package/domainforge-core/src/formatter/printer.rs +906 -0
- package/domainforge-core/src/graph/mod.rs +858 -0
- package/domainforge-core/src/graph/to_ast.rs +66 -0
- package/domainforge-core/src/kg.rs +1476 -0
- package/domainforge-core/src/kg_import.rs +251 -0
- package/domainforge-core/src/lib.rs +203 -0
- package/domainforge-core/src/module/mod.rs +1 -0
- package/domainforge-core/src/module/resolver.rs +260 -0
- package/domainforge-core/src/parser/ast.rs +2919 -0
- package/domainforge-core/src/parser/ast_convert.rs +494 -0
- package/domainforge-core/src/parser/ast_schema.rs +491 -0
- package/domainforge-core/src/parser/error.rs +291 -0
- package/domainforge-core/src/parser/lint.rs +39 -0
- package/domainforge-core/src/parser/mod.rs +193 -0
- package/domainforge-core/src/parser/printer.rs +702 -0
- package/domainforge-core/src/parser/profiles.rs +71 -0
- package/domainforge-core/src/parser/string_utils.rs +138 -0
- package/domainforge-core/src/patterns.rs +68 -0
- package/domainforge-core/src/policy/core.rs +1148 -0
- package/domainforge-core/src/policy/expression.rs +399 -0
- package/domainforge-core/src/policy/mod.rs +18 -0
- package/domainforge-core/src/policy/normalize.rs +1028 -0
- package/domainforge-core/src/policy/quantifier.rs +940 -0
- package/domainforge-core/src/policy/three_valued.rs +140 -0
- package/domainforge-core/src/policy/three_valued_microbench.rs +104 -0
- package/domainforge-core/src/policy/type_inference.rs +67 -0
- package/domainforge-core/src/policy/violation.rs +36 -0
- package/domainforge-core/src/primitives/concept_change.rs +61 -0
- package/domainforge-core/src/primitives/entity.rs +224 -0
- package/domainforge-core/src/primitives/flow.rs +111 -0
- package/domainforge-core/src/primitives/instance.rs +93 -0
- package/domainforge-core/src/primitives/mapping_contract.rs +50 -0
- package/domainforge-core/src/primitives/metric.rs +79 -0
- package/domainforge-core/src/primitives/mod.rs +25 -0
- package/domainforge-core/src/primitives/projection_contract.rs +50 -0
- package/domainforge-core/src/primitives/quantity.rs +56 -0
- package/domainforge-core/src/primitives/relation.rs +68 -0
- package/domainforge-core/src/primitives/resource.rs +237 -0
- package/domainforge-core/src/primitives/resource_instance.rs +88 -0
- package/domainforge-core/src/primitives/role.rs +49 -0
- package/domainforge-core/src/projection/buf.rs +404 -0
- package/domainforge-core/src/projection/contracts.rs +22 -0
- package/domainforge-core/src/projection/engine.rs +19 -0
- package/domainforge-core/src/projection/mod.rs +16 -0
- package/domainforge-core/src/projection/protobuf.rs +3331 -0
- package/domainforge-core/src/projection/registry.rs +43 -0
- package/domainforge-core/src/python/authority.rs +253 -0
- package/domainforge-core/src/python/error.rs +227 -0
- package/domainforge-core/src/python/formatter.rs +86 -0
- package/domainforge-core/src/python/graph.rs +366 -0
- package/domainforge-core/src/python/mod.rs +9 -0
- package/domainforge-core/src/python/policy.rs +651 -0
- package/domainforge-core/src/python/primitives.rs +796 -0
- package/domainforge-core/src/python/registry.rs +98 -0
- package/domainforge-core/src/python/semantic_pack.rs +619 -0
- package/domainforge-core/src/python/units.rs +96 -0
- package/domainforge-core/src/registry/mod.rs +432 -0
- package/domainforge-core/src/registry/tests.rs +210 -0
- package/domainforge-core/src/sbvr.rs +744 -0
- package/domainforge-core/src/semantic_pack/builder.rs +470 -0
- package/domainforge-core/src/semantic_pack/canonical_json.rs +184 -0
- package/domainforge-core/src/semantic_pack/diagnostics.rs +214 -0
- package/domainforge-core/src/semantic_pack/diff.rs +216 -0
- package/domainforge-core/src/semantic_pack/mod.rs +31 -0
- package/domainforge-core/src/semantic_pack/pack_set.rs +240 -0
- package/domainforge-core/src/semantic_pack/resolver.rs +437 -0
- package/domainforge-core/src/semantic_pack/review.rs +125 -0
- package/domainforge-core/src/semantic_pack/schema.rs +342 -0
- package/domainforge-core/src/semantic_pack/signing.rs +105 -0
- package/domainforge-core/src/semantic_pack/validator.rs +368 -0
- package/domainforge-core/src/semantic_version.rs +140 -0
- package/domainforge-core/src/test_utils.rs +12 -0
- package/domainforge-core/src/typescript/authority.rs +184 -0
- package/domainforge-core/src/typescript/error.rs +146 -0
- package/domainforge-core/src/typescript/formatter.rs +76 -0
- package/domainforge-core/src/typescript/graph.rs +391 -0
- package/domainforge-core/src/typescript/mod.rs +9 -0
- package/domainforge-core/src/typescript/policy.rs +564 -0
- package/domainforge-core/src/typescript/primitives.rs +784 -0
- package/domainforge-core/src/typescript/registry.rs +88 -0
- package/domainforge-core/src/typescript/semantic_pack.rs +470 -0
- package/domainforge-core/src/typescript/units.rs +76 -0
- package/domainforge-core/src/units/mod.rs +462 -0
- package/domainforge-core/src/uuid_module.rs +42 -0
- package/domainforge-core/src/validation_error.rs +818 -0
- package/domainforge-core/src/validation_result.rs +30 -0
- package/domainforge-core/src/wasm/authority.rs +192 -0
- package/domainforge-core/src/wasm/error.rs +145 -0
- package/domainforge-core/src/wasm/formatter.rs +69 -0
- package/domainforge-core/src/wasm/graph.rs +471 -0
- package/domainforge-core/src/wasm/mod.rs +16 -0
- package/domainforge-core/src/wasm/policy.rs +607 -0
- package/domainforge-core/src/wasm/primitives.rs +295 -0
- package/domainforge-core/src/wasm/semantic_pack.rs +471 -0
- package/domainforge-core/src/wasm/units.rs +62 -0
- package/domainforge-core/std/aws.sea +6 -0
- package/domainforge-core/std/core.sea +6 -0
- package/domainforge-core/std/http.sea +27 -0
- package/domainforge-core/tests/aggregation_enhanced_tests.rs +162 -0
- package/domainforge-core/tests/aggregation_eval_tests.rs +248 -0
- package/domainforge-core/tests/aggregation_integration_tests.rs +379 -0
- package/domainforge-core/tests/aggregation_parser_tests.rs +92 -0
- package/domainforge-core/tests/aggregation_tests.rs +102 -0
- package/domainforge-core/tests/authority_conformance_tests.rs +1173 -0
- package/domainforge-core/tests/calm_round_trip_tests.rs +283 -0
- package/domainforge-core/tests/calm_schema_validation_tests.rs +137 -0
- package/domainforge-core/tests/cast_operator_tests.rs +85 -0
- package/domainforge-core/tests/cli_binary_check.rs +37 -0
- package/domainforge-core/tests/cli_import_tests.rs +291 -0
- package/domainforge-core/tests/cli_path_traversal_tests.rs +124 -0
- package/domainforge-core/tests/cli_tests.rs +63 -0
- package/domainforge-core/tests/diagnostics_tests.rs +203 -0
- package/domainforge-core/tests/dimension_unit_tests.rs +80 -0
- package/domainforge-core/tests/entity_tests.rs +69 -0
- package/domainforge-core/tests/evolution_semantics_tests.rs +157 -0
- package/domainforge-core/tests/flow_tests.rs +78 -0
- package/domainforge-core/tests/flow_unit_validation_tests.rs +31 -0
- package/domainforge-core/tests/graph_integration_tests.rs +218 -0
- package/domainforge-core/tests/graph_tests.rs +626 -0
- package/domainforge-core/tests/import_parsing_tests.rs +23 -0
- package/domainforge-core/tests/instance_integration_tests.rs +98 -0
- package/domainforge-core/tests/instance_parsing_tests.rs +58 -0
- package/domainforge-core/tests/instance_tests.rs +61 -0
- package/domainforge-core/tests/kg_uri_encoding_tests.rs +53 -0
- package/domainforge-core/tests/lint_tests.rs +19 -0
- package/domainforge-core/tests/metric_tests.rs +143 -0
- package/domainforge-core/tests/module_resolution_tests.rs +100 -0
- package/domainforge-core/tests/namespace_registry_tests.rs +247 -0
- package/domainforge-core/tests/null_handling_tests.rs +26 -0
- package/domainforge-core/tests/parser_ast_v3.rs +53 -0
- package/domainforge-core/tests/parser_dimension_registry_tests.rs +20 -0
- package/domainforge-core/tests/parser_integration_tests.rs +294 -0
- package/domainforge-core/tests/parser_metadata_tests.rs +97 -0
- package/domainforge-core/tests/parser_resource_domain_only_graph_test.rs +21 -0
- package/domainforge-core/tests/parser_resource_limits_tests.rs +122 -0
- package/domainforge-core/tests/parser_tests.rs +512 -0
- package/domainforge-core/tests/pattern_semantics_tests.rs +87 -0
- package/domainforge-core/tests/phase_14_determinism_tests.rs +166 -0
- package/domainforge-core/tests/phase_15_validation_error_tests.rs +136 -0
- package/domainforge-core/tests/phase_16_unicode_tests.rs +248 -0
- package/domainforge-core/tests/phase_17_export_tests.rs +285 -0
- package/domainforge-core/tests/phase_17_round_trip_tests.rs +264 -0
- package/domainforge-core/tests/policy_tests.rs +635 -0
- package/domainforge-core/tests/primitives_integration_tests.rs +151 -0
- package/domainforge-core/tests/print_rdf_xml.rs +14 -0
- package/domainforge-core/tests/printer_tests.rs +204 -0
- package/domainforge-core/tests/profile_tests.rs +35 -0
- package/domainforge-core/tests/projection_contracts_tests.rs +154 -0
- package/domainforge-core/tests/protobuf_projection_tests.rs +199 -0
- package/domainforge-core/tests/quantity_tests.rs +41 -0
- package/domainforge-core/tests/rdf_xml_typed_literal_tests.rs +105 -0
- package/domainforge-core/tests/registry_schema_tests.rs +33 -0
- package/domainforge-core/tests/resource_tests.rs +50 -0
- package/domainforge-core/tests/resource_unit_tests.rs +24 -0
- package/domainforge-core/tests/roles_relations_tests.rs +61 -0
- package/domainforge-core/tests/round_trip_tests.rs +34 -0
- package/domainforge-core/tests/runtime_toggle_tests.rs +70 -0
- package/domainforge-core/tests/sbvr_fact_schema_tests.rs +60 -0
- package/domainforge-core/tests/sbvr_flow_facts_tests.rs +55 -0
- package/domainforge-core/tests/sbvr_parsing_tests.rs +53 -0
- package/domainforge-core/tests/semantic_pack_alias_resolution.rs +197 -0
- package/domainforge-core/tests/semantic_pack_build.rs +302 -0
- package/domainforge-core/tests/semantic_pack_consumer_smoke.rs +150 -0
- package/domainforge-core/tests/semantic_pack_pack_set.rs +160 -0
- package/domainforge-core/tests/semantic_pack_signing.rs +157 -0
- package/domainforge-core/tests/semantic_pack_three_valued.rs +250 -0
- package/domainforge-core/tests/semantic_pack_validate.rs +196 -0
- package/domainforge-core/tests/std_lib_tests.rs +37 -0
- package/domainforge-core/tests/temporal_evaluation_tests.rs +159 -0
- package/domainforge-core/tests/temporal_semantics_tests.rs +214 -0
- package/domainforge-core/tests/three_valued_quantifiers_tests.rs +164 -0
- package/domainforge-core/tests/turtle_entity_export_tests.rs +38 -0
- package/domainforge-core/tests/turtle_escaping_tests.rs +53 -0
- package/domainforge-core/tests/turtle_resource_export_tests.rs +34 -0
- package/domainforge-core/tests/type_inference_tests.rs +40 -0
- package/domainforge-core/tests/unicode_validation_tests.rs +169 -0
- package/domainforge-core/tests/unit_tests.rs +81 -0
- package/domainforge-core/tests/validate_tests.rs +38 -0
- package/domainforge-core/tests/validation_unit_mismatch_tests.rs +83 -0
- package/domainforge-core/tests/wasm_tests.rs +229 -0
- package/domainforge-python/CHANGELOG-python.md +12 -0
- package/domainforge-python/MIGRATING.md +24 -0
- package/domainforge-python/README.md +256 -0
- package/domainforge-python/domainforge/__init__.py +95 -0
- package/domainforge-python/domainforge/domainforge.pyi +519 -0
- package/domainforge-python/pyproject.toml +36 -0
- package/domainforge-typescript/CHANGELOG-typescript.md +12 -0
- package/domainforge-typescript/LICENSE +201 -0
- package/domainforge-typescript/MIGRATING.md +24 -0
- package/domainforge-typescript/README.md +305 -0
- package/domainforge-typescript/index.d.ts +452 -0
- package/domainforge-typescript/index.js +361 -0
- package/domainforge-typescript/package.json +60 -0
- package/example.js +61 -0
- package/examples/browser.html +366 -0
- package/examples/namespaces/finance/cashflow.sea +5 -0
- package/examples/namespaces/logistics/core.sea +7 -0
- package/examples/observability_metrics.sea +38 -0
- package/fixtures/semantic_packs/acme_procurement/domain/entities.sea +39 -0
- package/fixtures/semantic_packs/acme_procurement/domain/metrics.sea +11 -0
- package/fixtures/semantic_packs/acme_procurement/domain/relations.sea +7 -0
- package/fixtures/semantic_packs/acme_procurement/domain/resources.sea +9 -0
- package/fixtures/semantic_packs/acme_procurement/review/acme.procurement.semantic-review.jsonl +7 -0
- package/fixtures/semantic_packs/acme_procurement/tests/ambiguous_vendor_alias.sea +8 -0
- package/fixtures/semantic_packs/acme_procurement/tests/deprecated_vendor_alias.sea +8 -0
- package/fixtures/semantic_packs/acme_procurement/tests/invalid_relation.sea +3 -0
- package/fixtures/semantic_packs/acme_procurement/tests/proposed_concept.sea +8 -0
- package/fixtures/semantic_packs/acme_procurement/tests/rejected_concept.sea +8 -0
- package/fixtures/semantic_packs/acme_procurement/tests/unit_mismatch.sea +7 -0
- package/fixtures/semantic_packs/acme_procurement/tests/unknown_vendor_policy.sea +8 -0
- package/fixtures/semantic_packs/acme_procurement/tests/valid_purchase_policy.sea +8 -0
- package/index.d.ts +2 -0
- package/index.js +8 -0
- package/justfile +200 -0
- package/lefthook.yml +13 -0
- package/lib/validate_native_exports.d.ts +4 -0
- package/lib/validate_native_exports.js +12 -0
- package/package.json +22 -0
- package/pytest.ini +5 -0
- package/python/tests/test_registry.py +75 -0
- package/python/tests/test_units.py +18 -0
- package/release-please-config.json +49 -0
- package/requirements-dev.txt +3 -0
- package/requirements.txt +3 -0
- package/rust-toolchain.toml +3 -0
- package/schemas/ast-v1.schema.json +72 -0
- package/schemas/ast-v2.schema.json +1200 -0
- package/schemas/ast-v3.schema.json +1200 -0
- package/schemas/sea-registry.schema.json +45 -0
- package/scripts/build-python.sh +37 -0
- package/scripts/build-release.sh +279 -0
- package/scripts/build-typescript.sh +13 -0
- package/scripts/build-wasm.sh +113 -0
- package/scripts/bump-version.sh +245 -0
- package/scripts/check_unused_test_imports.py +85 -0
- package/scripts/ci_tasks.py +379 -0
- package/scripts/clear_debug_test.sh +10 -0
- package/scripts/create-github-release.sh +262 -0
- package/scripts/create-tag.sh +203 -0
- package/scripts/find_and_link_test_binary.sh +70 -0
- package/scripts/generate-changelog.sh +271 -0
- package/scripts/generate-release-notes.sh +205 -0
- package/scripts/lint_release_security.py +96 -0
- package/scripts/lint_release_workflows.py +82 -0
- package/scripts/lint_workflow_gates.py +113 -0
- package/scripts/optimized-wasm-build.sh +61 -0
- package/scripts/patch_napi_types.py +62 -0
- package/scripts/pre-release-check.sh +289 -0
- package/scripts/prepare_rust_debug.sh +52 -0
- package/scripts/release.sh +373 -0
- package/scripts/resolve_rust_binary.py +230 -0
- package/scripts/run_commitlint.sh +29 -0
- package/scripts/test-all.sh +77 -0
- package/scripts/update_launch_program.py +93 -0
- package/secrets/README.md +27 -0
- package/secrets/secrets.yaml +21 -0
- package/test_integration.py +67 -0
- package/tests/test_authority.py +328 -0
- package/tests/test_ci_tasks.py +143 -0
- package/tests/test_expression.py +256 -0
- package/tests/test_golden_payment_flow.py +42 -0
- package/tests/test_graph.py +127 -0
- package/tests/test_instance.py +136 -0
- package/tests/test_parser.py +82 -0
- package/tests/test_primitives.py +68 -0
- package/tests/test_role_relation_parity.py +56 -0
- package/tests/test_runtime_toggle.py +156 -0
- package/tests/test_semantic_pack.py +639 -0
- package/tests/test_three_valued_eval.py +159 -0
- package/tsconfig.json +30 -0
- package/typescript-tests/advanced.test.ts +165 -0
- package/typescript-tests/authority.test.ts +216 -0
- package/typescript-tests/expression.test.ts +228 -0
- package/typescript-tests/golden-payment-flow.test.ts +51 -0
- package/typescript-tests/graph.test.ts +142 -0
- package/typescript-tests/native-binding.test.ts +20 -0
- package/typescript-tests/primitives.test.ts +88 -0
- package/typescript-tests/registry.test.ts +122 -0
- package/typescript-tests/role_relation.test.ts +63 -0
- package/typescript-tests/runtime_toggle.test.ts +141 -0
- package/typescript-tests/semantic-pack.test.ts +556 -0
- package/typescript-tests/three_valued_eval.test.ts +135 -0
- package/typescript-tests/units.test.ts +36 -0
- package/vitest.config.ts +13 -0
- package/wasm_demo.html +225 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
//! Parse SEA files and output AST or Graph JSON.
|
|
2
|
+
//!
|
|
3
|
+
//! This command parses a SEA DSL file and outputs the result in the specified format.
|
|
4
|
+
//! Use `--format json` to get structured JSON output suitable for tooling.
|
|
5
|
+
|
|
6
|
+
use anyhow::{Context, Result};
|
|
7
|
+
use clap::{Args, ValueEnum};
|
|
8
|
+
use std::fs;
|
|
9
|
+
use std::path::PathBuf;
|
|
10
|
+
|
|
11
|
+
#[derive(Args)]
|
|
12
|
+
pub struct ParseArgs {
|
|
13
|
+
/// Input SEA file to parse
|
|
14
|
+
#[arg(required = true)]
|
|
15
|
+
pub input: PathBuf,
|
|
16
|
+
|
|
17
|
+
/// Output format
|
|
18
|
+
#[arg(long, value_enum, default_value_t = ParseFormat::Human)]
|
|
19
|
+
pub format: ParseFormat,
|
|
20
|
+
|
|
21
|
+
/// Output file (stdout if not specified)
|
|
22
|
+
#[arg(long, short)]
|
|
23
|
+
pub out: Option<PathBuf>,
|
|
24
|
+
|
|
25
|
+
/// Output AST instead of Graph (preserves source structure and line numbers)
|
|
26
|
+
#[arg(long)]
|
|
27
|
+
pub ast: bool,
|
|
28
|
+
|
|
29
|
+
/// Output AST v3 (alias for --ast)
|
|
30
|
+
#[arg(long)]
|
|
31
|
+
pub ast_v3: bool,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#[derive(ValueEnum, Clone, Debug, Copy, Default)]
|
|
35
|
+
pub enum ParseFormat {
|
|
36
|
+
/// Human-readable summary
|
|
37
|
+
#[default]
|
|
38
|
+
Human,
|
|
39
|
+
/// JSON output
|
|
40
|
+
Json,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
pub fn run(args: ParseArgs) -> Result<()> {
|
|
44
|
+
let source = fs::read_to_string(&args.input)
|
|
45
|
+
.with_context(|| format!("Failed to read file: {}", args.input.display()))?;
|
|
46
|
+
|
|
47
|
+
let output = match (args.ast || args.ast_v3, args.format) {
|
|
48
|
+
// AST output (uses schema types for stable JSON format)
|
|
49
|
+
(true, ParseFormat::Json) => {
|
|
50
|
+
let internal_ast =
|
|
51
|
+
crate::parser::parse(&source).map_err(|e| anyhow::anyhow!("Parse error: {}", e))?;
|
|
52
|
+
let schema_ast: crate::parser::ast_schema::Ast = internal_ast.into();
|
|
53
|
+
serde_json::to_string_pretty(&schema_ast).context("Failed to serialize AST to JSON")?
|
|
54
|
+
}
|
|
55
|
+
(true, ParseFormat::Human) => {
|
|
56
|
+
let ast =
|
|
57
|
+
crate::parser::parse(&source).map_err(|e| anyhow::anyhow!("Parse error: {}", e))?;
|
|
58
|
+
format!(
|
|
59
|
+
"AST parsed successfully: {}\n\
|
|
60
|
+
Namespace: {}\n\
|
|
61
|
+
Version: {}\n\
|
|
62
|
+
Declarations: {}",
|
|
63
|
+
args.input.display(),
|
|
64
|
+
ast.metadata.namespace.as_deref().unwrap_or("(none)"),
|
|
65
|
+
ast.metadata.version.as_deref().unwrap_or("(none)"),
|
|
66
|
+
ast.declarations.len()
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
// Graph output (default)
|
|
70
|
+
(false, ParseFormat::Json) => {
|
|
71
|
+
let graph = crate::parser::parse_to_graph(&source)
|
|
72
|
+
.map_err(|e| anyhow::anyhow!("Parse error: {}", e))?;
|
|
73
|
+
serde_json::to_string_pretty(&graph).context("Failed to serialize Graph to JSON")?
|
|
74
|
+
}
|
|
75
|
+
(false, ParseFormat::Human) => {
|
|
76
|
+
let graph = crate::parser::parse_to_graph(&source)
|
|
77
|
+
.map_err(|e| anyhow::anyhow!("Parse error: {}", e))?;
|
|
78
|
+
format!(
|
|
79
|
+
"Graph parsed successfully: {}\n\
|
|
80
|
+
Entities: {}\n\
|
|
81
|
+
Resources: {}\n\
|
|
82
|
+
Flows: {}\n\
|
|
83
|
+
Roles: {}\n\
|
|
84
|
+
Relations: {}\n\
|
|
85
|
+
Instances: {}\n\
|
|
86
|
+
Policies: {}",
|
|
87
|
+
args.input.display(),
|
|
88
|
+
graph.entity_count(),
|
|
89
|
+
graph.resource_count(),
|
|
90
|
+
graph.flow_count(),
|
|
91
|
+
graph.role_count(),
|
|
92
|
+
graph.relation_count(),
|
|
93
|
+
graph.instance_count(),
|
|
94
|
+
graph.pattern_count()
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// Write output
|
|
100
|
+
match args.out {
|
|
101
|
+
Some(path) => {
|
|
102
|
+
fs::write(&path, &output)
|
|
103
|
+
.with_context(|| format!("Failed to write to: {}", path.display()))?;
|
|
104
|
+
eprintln!("Wrote output to: {}", path.display());
|
|
105
|
+
}
|
|
106
|
+
None => {
|
|
107
|
+
println!("{}", output);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
Ok(())
|
|
112
|
+
}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
use crate::parser::{parse_to_graph_with_options, ParseOptions};
|
|
2
|
+
use crate::projection::protobuf::{CompatibilityMode, SchemaHistory};
|
|
3
|
+
use crate::projection::ProtobufEngine;
|
|
4
|
+
use crate::NamespaceRegistry;
|
|
5
|
+
use anyhow::{Context, Result};
|
|
6
|
+
use clap::{Parser, ValueEnum};
|
|
7
|
+
use std::fs::{read_to_string, write};
|
|
8
|
+
use std::path::{Path, PathBuf};
|
|
9
|
+
|
|
10
|
+
#[derive(Parser)]
|
|
11
|
+
pub struct ProjectArgs {
|
|
12
|
+
#[arg(long, value_enum)]
|
|
13
|
+
pub format: ProjectFormat,
|
|
14
|
+
|
|
15
|
+
/// Optional namespace filter (project only entities from this namespace)
|
|
16
|
+
#[arg(long)]
|
|
17
|
+
pub namespace: Option<String>,
|
|
18
|
+
|
|
19
|
+
/// Protobuf package name (for protobuf format)
|
|
20
|
+
#[arg(long, default_value = "sea.generated")]
|
|
21
|
+
pub package: String,
|
|
22
|
+
|
|
23
|
+
/// Include governance messages (for protobuf format)
|
|
24
|
+
#[arg(long)]
|
|
25
|
+
pub include_governance: bool,
|
|
26
|
+
|
|
27
|
+
/// Generate gRPC service definitions from Flow patterns (protobuf only)
|
|
28
|
+
#[arg(long)]
|
|
29
|
+
pub include_services: bool,
|
|
30
|
+
|
|
31
|
+
/// Schema compatibility mode: additive, backward, or breaking (protobuf only)
|
|
32
|
+
#[arg(long, value_enum, default_value = "backward")]
|
|
33
|
+
pub compatibility: CliCompatibilityMode,
|
|
34
|
+
|
|
35
|
+
/// Directory to store schema history for compatibility checking (protobuf only)
|
|
36
|
+
#[arg(long)]
|
|
37
|
+
pub schema_history: Option<PathBuf>,
|
|
38
|
+
|
|
39
|
+
/// Automatically apply fixes (add reserved fields) for backward compatibility
|
|
40
|
+
#[arg(long)]
|
|
41
|
+
pub apply_fixes: bool,
|
|
42
|
+
|
|
43
|
+
/// Run 'buf lint' on the generated output
|
|
44
|
+
#[arg(long)]
|
|
45
|
+
pub buf_lint: bool,
|
|
46
|
+
|
|
47
|
+
/// Run 'buf breaking' check against previous version
|
|
48
|
+
#[arg(long)]
|
|
49
|
+
pub buf_breaking: bool,
|
|
50
|
+
|
|
51
|
+
/// Run 'buf generate' to build code artifacts
|
|
52
|
+
#[arg(long)]
|
|
53
|
+
pub buf_generate: bool,
|
|
54
|
+
|
|
55
|
+
/// Generate multiple files (one per namespace) instead of a single file
|
|
56
|
+
#[arg(long)]
|
|
57
|
+
pub multi_file: bool,
|
|
58
|
+
|
|
59
|
+
pub input: PathBuf,
|
|
60
|
+
pub output: PathBuf,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
#[derive(ValueEnum, Clone, Debug, Copy)]
|
|
64
|
+
pub enum ProjectFormat {
|
|
65
|
+
Calm,
|
|
66
|
+
Kg,
|
|
67
|
+
Protobuf,
|
|
68
|
+
Proto, // alias for protobuf
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
#[derive(ValueEnum, Clone, Debug, Copy, Default)]
|
|
72
|
+
pub enum CliCompatibilityMode {
|
|
73
|
+
/// Only additions allowed - strictest mode for public APIs
|
|
74
|
+
Additive,
|
|
75
|
+
/// Removals become reserved fields - default for internal APIs
|
|
76
|
+
#[default]
|
|
77
|
+
Backward,
|
|
78
|
+
/// All changes allowed - for breaking releases
|
|
79
|
+
Breaking,
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
impl From<CliCompatibilityMode> for CompatibilityMode {
|
|
83
|
+
fn from(mode: CliCompatibilityMode) -> Self {
|
|
84
|
+
match mode {
|
|
85
|
+
CliCompatibilityMode::Additive => CompatibilityMode::Additive,
|
|
86
|
+
CliCompatibilityMode::Backward => CompatibilityMode::Backward,
|
|
87
|
+
CliCompatibilityMode::Breaking => CompatibilityMode::Breaking,
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
pub fn run(args: ProjectArgs) -> Result<()> {
|
|
93
|
+
let source = read_to_string(&args.input)
|
|
94
|
+
.with_context(|| format!("Failed to read input file {}", args.input.display()))?;
|
|
95
|
+
|
|
96
|
+
// Parse input
|
|
97
|
+
let registry =
|
|
98
|
+
NamespaceRegistry::discover(&args.input).context("discovering namespace registry")?;
|
|
99
|
+
let default_namespace = registry
|
|
100
|
+
.as_ref()
|
|
101
|
+
.and_then(|reg| reg.namespace_for(&args.input).map(|ns| ns.to_string()));
|
|
102
|
+
let options = ParseOptions {
|
|
103
|
+
default_namespace: default_namespace.clone(),
|
|
104
|
+
namespace_registry: registry.clone(),
|
|
105
|
+
entry_path: Some(args.input.clone()),
|
|
106
|
+
..Default::default()
|
|
107
|
+
};
|
|
108
|
+
let graph = parse_to_graph_with_options(&source, &options)
|
|
109
|
+
.map_err(|e| anyhow::anyhow!("Parse failed for {}: {}", args.input.display(), e))?;
|
|
110
|
+
|
|
111
|
+
match args.format {
|
|
112
|
+
ProjectFormat::Calm => {
|
|
113
|
+
let value = crate::calm::export(&graph)
|
|
114
|
+
.map_err(|e| anyhow::anyhow!("Failed to export to CALM: {}", e))?;
|
|
115
|
+
let json =
|
|
116
|
+
serde_json::to_string_pretty(&value).context("Failed to serialize CALM JSON")?;
|
|
117
|
+
write(&args.output, json)
|
|
118
|
+
.with_context(|| format!("Failed to write output to {}", args.output.display()))?;
|
|
119
|
+
println!("Projected to CALM: {}", args.output.display());
|
|
120
|
+
}
|
|
121
|
+
ProjectFormat::Kg => {
|
|
122
|
+
let kg = crate::KnowledgeGraph::from_graph(&graph)
|
|
123
|
+
.map_err(|e| anyhow::anyhow!("Failed to convert to Knowledge Graph: {}", e))?;
|
|
124
|
+
|
|
125
|
+
let output_str = if args
|
|
126
|
+
.output
|
|
127
|
+
.extension()
|
|
128
|
+
.and_then(|ext| ext.to_str())
|
|
129
|
+
.is_some_and(|ext| {
|
|
130
|
+
ext.eq_ignore_ascii_case("xml") || ext.eq_ignore_ascii_case("rdf")
|
|
131
|
+
}) {
|
|
132
|
+
kg.to_rdf_xml()
|
|
133
|
+
} else {
|
|
134
|
+
kg.to_turtle()
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
write(&args.output, output_str)
|
|
138
|
+
.with_context(|| format!("Failed to write output to {}", args.output.display()))?;
|
|
139
|
+
println!("Projected to KG: {}", args.output.display());
|
|
140
|
+
}
|
|
141
|
+
ProjectFormat::Protobuf | ProjectFormat::Proto => {
|
|
142
|
+
let namespace_filter = args.namespace.as_deref().unwrap_or("");
|
|
143
|
+
let projection_name = args
|
|
144
|
+
.input
|
|
145
|
+
.file_stem()
|
|
146
|
+
.and_then(|s| s.to_str())
|
|
147
|
+
.unwrap_or("projection");
|
|
148
|
+
|
|
149
|
+
if args.multi_file {
|
|
150
|
+
if args.schema_history.is_some() {
|
|
151
|
+
eprintln!(
|
|
152
|
+
"Warning: --schema-history is currently ignored in --multi-file mode."
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if !args.output.exists() {
|
|
157
|
+
std::fs::create_dir_all(&args.output).with_context(|| {
|
|
158
|
+
format!(
|
|
159
|
+
"Failed to create output directory {}",
|
|
160
|
+
args.output.display()
|
|
161
|
+
)
|
|
162
|
+
})?;
|
|
163
|
+
} else if !args.output.is_dir() {
|
|
164
|
+
return Err(anyhow::anyhow!(
|
|
165
|
+
"Output path must be a directory for --multi-file projection"
|
|
166
|
+
));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
let files = ProtobufEngine::project_multi_file(
|
|
170
|
+
&graph,
|
|
171
|
+
&args.package,
|
|
172
|
+
args.include_governance,
|
|
173
|
+
args.include_services,
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
for (rel_path, proto) in &files {
|
|
177
|
+
let abs_path = args.output.join(rel_path);
|
|
178
|
+
crate::projection::protobuf::validate_output_path(&args.output, &abs_path)
|
|
179
|
+
.map_err(|e| anyhow::anyhow!("{}", e))?;
|
|
180
|
+
if let Some(parent) = abs_path.parent() {
|
|
181
|
+
std::fs::create_dir_all(parent)?;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
let content = proto.to_proto_string();
|
|
185
|
+
write(&abs_path, content)
|
|
186
|
+
.with_context(|| format!("Failed to write {}", abs_path.display()))?;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
println!(
|
|
190
|
+
"Projected to Protobuf (Multi-file): {}",
|
|
191
|
+
args.output.display()
|
|
192
|
+
);
|
|
193
|
+
println!(" Files: {}", files.len());
|
|
194
|
+
println!(" Base Package: {}", args.package);
|
|
195
|
+
} else {
|
|
196
|
+
let mut proto_file = ProtobufEngine::project_with_full_options(
|
|
197
|
+
&graph,
|
|
198
|
+
namespace_filter,
|
|
199
|
+
&args.package,
|
|
200
|
+
projection_name,
|
|
201
|
+
args.include_governance,
|
|
202
|
+
args.include_services,
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
// Handle compatibility checking if schema history is provided
|
|
206
|
+
if let Some(ref history_dir) = args.schema_history {
|
|
207
|
+
let history = SchemaHistory::new(history_dir);
|
|
208
|
+
let mode: CompatibilityMode = args.compatibility.into();
|
|
209
|
+
|
|
210
|
+
let result = history
|
|
211
|
+
.check_and_update(&mut proto_file, mode, args.apply_fixes)
|
|
212
|
+
.map_err(|e| anyhow::anyhow!("Compatibility check failed: {}", e))?;
|
|
213
|
+
|
|
214
|
+
// Print compatibility report
|
|
215
|
+
if result.has_violations() {
|
|
216
|
+
eprintln!("\n{}", result.to_report());
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Fail if not compatible (unless in breaking mode)
|
|
220
|
+
if !result.is_compatible {
|
|
221
|
+
return Err(anyhow::anyhow!(
|
|
222
|
+
"Schema evolution is not compatible in {} mode. Use --compatibility breaking to force, or --apply-fixes to auto-fix.",
|
|
223
|
+
mode
|
|
224
|
+
));
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if result.has_violations() {
|
|
228
|
+
println!(
|
|
229
|
+
" Compatibility: {} (with {} warnings)",
|
|
230
|
+
mode,
|
|
231
|
+
result.violations.len()
|
|
232
|
+
);
|
|
233
|
+
} else {
|
|
234
|
+
println!(" Compatibility: {} (clean)", mode);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
let proto_string = proto_file.to_proto_string();
|
|
239
|
+
write(&args.output, &proto_string).with_context(|| {
|
|
240
|
+
format!("Failed to write output to {}", args.output.display())
|
|
241
|
+
})?;
|
|
242
|
+
println!("Projected to Protobuf: {}", args.output.display());
|
|
243
|
+
println!(" Package: {}", args.package);
|
|
244
|
+
println!(" Messages: {}", proto_file.messages.len());
|
|
245
|
+
if !proto_file.services.is_empty() {
|
|
246
|
+
println!(
|
|
247
|
+
" Services: {} ({} methods)",
|
|
248
|
+
proto_file.services.len(),
|
|
249
|
+
proto_file
|
|
250
|
+
.services
|
|
251
|
+
.iter()
|
|
252
|
+
.map(|s| s.methods.len())
|
|
253
|
+
.sum::<usize>()
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Buf integration
|
|
259
|
+
if args.buf_lint || args.buf_breaking || args.buf_generate {
|
|
260
|
+
use crate::projection::buf::BufIntegration;
|
|
261
|
+
let buf = BufIntegration::new();
|
|
262
|
+
let output_dir = if args.multi_file {
|
|
263
|
+
&args.output
|
|
264
|
+
} else {
|
|
265
|
+
args.output.parent().unwrap_or(Path::new("."))
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
if args.buf_lint {
|
|
269
|
+
print!(" Running buf lint... ");
|
|
270
|
+
match buf.lint(output_dir) {
|
|
271
|
+
Ok(result) => {
|
|
272
|
+
if result.success {
|
|
273
|
+
println!("clean");
|
|
274
|
+
} else {
|
|
275
|
+
println!("issues found:");
|
|
276
|
+
println!("{}", result.raw_output);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
Err(e) => println!("failed: {}", e),
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if args.buf_breaking {
|
|
284
|
+
if let Some(history) = args.schema_history {
|
|
285
|
+
print!(" Running buf breaking check... ");
|
|
286
|
+
println!("(checking against {})", history.display());
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
Ok(())
|
|
294
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
use crate::registry::NamespaceRegistry;
|
|
2
|
+
use clap::{Args, Subcommand};
|
|
3
|
+
use std::path::PathBuf;
|
|
4
|
+
|
|
5
|
+
#[derive(Debug, Args)]
|
|
6
|
+
pub struct RegistryArgs {
|
|
7
|
+
#[command(subcommand)]
|
|
8
|
+
pub command: RegistryCommands,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
#[derive(Debug, Subcommand)]
|
|
12
|
+
pub enum RegistryCommands {
|
|
13
|
+
/// Resolve the namespace for a file
|
|
14
|
+
Resolve(ResolveArgs),
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
#[derive(Debug, Args)]
|
|
18
|
+
pub struct ResolveArgs {
|
|
19
|
+
/// Fail if multiple namespaces match with equal specificity
|
|
20
|
+
#[arg(long)]
|
|
21
|
+
pub fail_on_ambiguity: bool,
|
|
22
|
+
|
|
23
|
+
/// The file path to resolve
|
|
24
|
+
pub file: PathBuf,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
pub fn run(args: RegistryArgs) -> anyhow::Result<()> {
|
|
28
|
+
match args.command {
|
|
29
|
+
RegistryCommands::Resolve(resolve_args) => run_resolve(resolve_args),
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
fn run_resolve(args: ResolveArgs) -> anyhow::Result<()> {
|
|
34
|
+
let path = args.file;
|
|
35
|
+
let registry = NamespaceRegistry::discover(&path)?
|
|
36
|
+
.ok_or_else(|| anyhow::anyhow!("No .sea-registry.toml found"))?;
|
|
37
|
+
|
|
38
|
+
let namespace = registry.namespace_for_with_options(&path, args.fail_on_ambiguity)?;
|
|
39
|
+
println!("{}", namespace);
|
|
40
|
+
Ok(())
|
|
41
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
use crate::parser::{parse_to_graph_with_options, ParseOptions};
|
|
2
|
+
use crate::{Graph, NamespaceRegistry};
|
|
3
|
+
use anyhow::{Context, Result};
|
|
4
|
+
use clap::{Parser, ValueEnum};
|
|
5
|
+
use std::fs::read_to_string;
|
|
6
|
+
use std::path::{Path, PathBuf};
|
|
7
|
+
|
|
8
|
+
#[derive(Parser)]
|
|
9
|
+
pub struct ValidateArgs {
|
|
10
|
+
#[arg(long, value_enum, default_value_t = OutputFormat::Human)]
|
|
11
|
+
pub format: OutputFormat,
|
|
12
|
+
|
|
13
|
+
#[arg(long)]
|
|
14
|
+
pub no_color: bool,
|
|
15
|
+
|
|
16
|
+
#[arg(long)]
|
|
17
|
+
pub show_source: bool,
|
|
18
|
+
|
|
19
|
+
#[arg(required = true)]
|
|
20
|
+
pub target: PathBuf,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
#[derive(ValueEnum, Clone, Debug, Copy)]
|
|
24
|
+
pub enum OutputFormat {
|
|
25
|
+
Json,
|
|
26
|
+
Human,
|
|
27
|
+
Lsp,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
pub fn run(args: ValidateArgs) -> Result<()> {
|
|
31
|
+
let use_color = !args.no_color;
|
|
32
|
+
|
|
33
|
+
if args.target.is_dir() {
|
|
34
|
+
validate_directory(&args.target, args.format, use_color, args.show_source)
|
|
35
|
+
} else {
|
|
36
|
+
validate_file(&args.target, args.format, use_color, args.show_source)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
fn validate_file(
|
|
41
|
+
path: &Path,
|
|
42
|
+
format: OutputFormat,
|
|
43
|
+
use_color: bool,
|
|
44
|
+
show_source: bool,
|
|
45
|
+
) -> Result<()> {
|
|
46
|
+
let source =
|
|
47
|
+
read_to_string(path).with_context(|| format!("Failed to read file {}", path.display()))?;
|
|
48
|
+
let registry = NamespaceRegistry::discover(path).map_err(|e| anyhow::anyhow!(e.to_string()))?;
|
|
49
|
+
let default_namespace = registry
|
|
50
|
+
.as_ref()
|
|
51
|
+
.and_then(|reg| reg.namespace_for(path).map(|ns| ns.to_string()));
|
|
52
|
+
let options = ParseOptions {
|
|
53
|
+
default_namespace,
|
|
54
|
+
namespace_registry: registry.clone(),
|
|
55
|
+
entry_path: Some(path.to_path_buf()),
|
|
56
|
+
..Default::default()
|
|
57
|
+
};
|
|
58
|
+
let graph = parse_to_graph_with_options(&source, &options)
|
|
59
|
+
.map_err(|e| anyhow::anyhow!("Parse failed for {}: {}", path.display(), e))?;
|
|
60
|
+
report_validation(graph, format, use_color, show_source, Some(&source))
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
fn validate_directory(
|
|
64
|
+
path: &Path,
|
|
65
|
+
format: OutputFormat,
|
|
66
|
+
use_color: bool,
|
|
67
|
+
show_source: bool,
|
|
68
|
+
) -> Result<()> {
|
|
69
|
+
let registry = NamespaceRegistry::discover(path)
|
|
70
|
+
.map_err(|e| anyhow::anyhow!("Failed to load registry near {}: {}", path.display(), e))?
|
|
71
|
+
.ok_or_else(|| {
|
|
72
|
+
anyhow::anyhow!(
|
|
73
|
+
"No .sea-registry.toml found for {}. Run inside a workspace with a registry file.",
|
|
74
|
+
path.display()
|
|
75
|
+
)
|
|
76
|
+
})?;
|
|
77
|
+
|
|
78
|
+
let files = registry
|
|
79
|
+
.resolve_files()
|
|
80
|
+
.map_err(|e| anyhow::anyhow!("Failed to expand registry: {}", e))?;
|
|
81
|
+
|
|
82
|
+
if files.is_empty() {
|
|
83
|
+
return Err(anyhow::anyhow!(
|
|
84
|
+
"Registry at '{}' did not match any .sea files",
|
|
85
|
+
registry.root().display()
|
|
86
|
+
));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let mut graph = Graph::new();
|
|
90
|
+
for binding in files {
|
|
91
|
+
let source = read_to_string(&binding.path)
|
|
92
|
+
.with_context(|| format!("Failed to read {}", binding.path.display()))?;
|
|
93
|
+
let options = ParseOptions {
|
|
94
|
+
default_namespace: Some(binding.namespace.clone()),
|
|
95
|
+
namespace_registry: Some(registry.clone()),
|
|
96
|
+
entry_path: Some(binding.path.clone()),
|
|
97
|
+
..Default::default()
|
|
98
|
+
};
|
|
99
|
+
let file_graph = parse_to_graph_with_options(&source, &options)
|
|
100
|
+
.map_err(|e| anyhow::anyhow!("Parse failed for {}: {}", binding.path.display(), e))?;
|
|
101
|
+
graph
|
|
102
|
+
.extend(file_graph)
|
|
103
|
+
.map_err(|e| anyhow::anyhow!("Failed to merge {}: {}", binding.path.display(), e))?;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// For directory validation, we don't pass source code for now as errors could be from any file
|
|
107
|
+
// TODO: Map errors back to specific files in directory mode
|
|
108
|
+
report_validation(graph, format, use_color, show_source, None)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
fn report_validation(
|
|
112
|
+
graph: Graph,
|
|
113
|
+
format: OutputFormat,
|
|
114
|
+
use_color: bool,
|
|
115
|
+
show_source: bool,
|
|
116
|
+
source: Option<&str>,
|
|
117
|
+
) -> Result<()> {
|
|
118
|
+
// Note: show_source and source are currently unused because validation violations
|
|
119
|
+
// don't yet include source range information. These parameters are kept for future
|
|
120
|
+
// implementation when source snippets can be displayed.
|
|
121
|
+
let _ = (show_source, source); // Acknowledge parameters for future use
|
|
122
|
+
|
|
123
|
+
let result = graph.validate();
|
|
124
|
+
|
|
125
|
+
match format {
|
|
126
|
+
OutputFormat::Json => {
|
|
127
|
+
let json_output = serde_json::json!({
|
|
128
|
+
"error_count": result.error_count,
|
|
129
|
+
"violations": result.violations.iter().map(|v| {
|
|
130
|
+
serde_json::json!({
|
|
131
|
+
"severity": match v.severity {
|
|
132
|
+
crate::policy::Severity::Error => "error",
|
|
133
|
+
crate::policy::Severity::Warning => "warning",
|
|
134
|
+
crate::policy::Severity::Info => "info",
|
|
135
|
+
},
|
|
136
|
+
"policy_name": v.policy_name,
|
|
137
|
+
"message": v.message,
|
|
138
|
+
"context": v.context,
|
|
139
|
+
})
|
|
140
|
+
}).collect::<Vec<_>>(),
|
|
141
|
+
});
|
|
142
|
+
println!(
|
|
143
|
+
"{}",
|
|
144
|
+
serde_json::to_string_pretty(&json_output).context("Failed to serialize output")?
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
OutputFormat::Human | OutputFormat::Lsp => {
|
|
148
|
+
if result.error_count > 0 {
|
|
149
|
+
let msg = format!("Validation failed: {} errors", result.error_count);
|
|
150
|
+
if use_color {
|
|
151
|
+
use colored::Colorize;
|
|
152
|
+
println!("{}", msg.red());
|
|
153
|
+
} else {
|
|
154
|
+
println!("{}", msg);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
for v in &result.violations {
|
|
158
|
+
let severity = match v.severity {
|
|
159
|
+
crate::policy::Severity::Error => "ERROR",
|
|
160
|
+
crate::policy::Severity::Warning => "WARN",
|
|
161
|
+
crate::policy::Severity::Info => "INFO",
|
|
162
|
+
};
|
|
163
|
+
let severity_colored = if use_color {
|
|
164
|
+
use colored::Colorize;
|
|
165
|
+
match v.severity {
|
|
166
|
+
crate::policy::Severity::Error => severity.red().to_string(),
|
|
167
|
+
crate::policy::Severity::Warning => severity.yellow().to_string(),
|
|
168
|
+
crate::policy::Severity::Info => severity.blue().to_string(),
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
severity.to_string()
|
|
172
|
+
};
|
|
173
|
+
println!("- [{}] {}: {}", severity_colored, v.policy_name, v.message);
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
let msg = format!(
|
|
177
|
+
"Validation succeeded: {} violations total",
|
|
178
|
+
result.violations.len()
|
|
179
|
+
);
|
|
180
|
+
if use_color {
|
|
181
|
+
use colored::Colorize;
|
|
182
|
+
println!("{}", msg.green());
|
|
183
|
+
} else {
|
|
184
|
+
println!("{}", msg);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if result.error_count > 0 {
|
|
191
|
+
Err(anyhow::anyhow!("Validation errors detected"))
|
|
192
|
+
} else {
|
|
193
|
+
Ok(())
|
|
194
|
+
}
|
|
195
|
+
}
|