metaobjects 1.1.1__tar.gz → 1.1.2__tar.gz
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.
- {metaobjects-1.1.1 → metaobjects-1.1.2}/PKG-INFO +1 -1
- {metaobjects-1.1.1 → metaobjects-1.1.2}/pyproject.toml +1 -1
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/cli.py +31 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/router_generator.py +103 -21
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/decimal_wire.py +75 -9
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/config/dependencies.py +5 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/config/neutral_config.py +42 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/config/source_resolver.py +3 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/meta_data_loader.py +2 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/meta_root.py +5 -0
- metaobjects-1.1.2/src/metaobjects/wire.py +70 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_config_run_settings.py +90 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_router_generator.py +2 -2
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_router_generator_m2m_target_tph.py +1 -1
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_router_generator_tph_m2m.py +13 -3
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_router_generator_tph_m2m_shadowed.py +3 -3
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_tph_codegen.py +1 -1
- metaobjects-1.1.2/tests/conformance/test_wire_conformance.py +54 -0
- metaobjects-1.1.2/tests/integration/corpus_config.py +18 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/generated_jsonb_app.py +2 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/generated_m2m_app.py +2 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/generated_projection_app.py +2 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/generated_report_app.py +2 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/generated_router_app.py +2 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/generated_tph_app.py +2 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_generated_decimal_wire.py +234 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/runtime/test_decimal_wire.py +12 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/uv.lock +1 -1
- {metaobjects-1.1.1 → metaobjects-1.1.2}/.gitignore +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/LICENSE +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/README.md +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/hatch_build.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/scripts/generate_embedded_library.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/agent_context/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/agent_context/scaffold.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/apidocs/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/apidocs/api_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/apidocs/builder.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/apidocs/naming.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/apidocs/paths.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/apidocs/renderer.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/attr_class_map.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/KNOWN_GAPS.md +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/_moved.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/collection_name_collision.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/collision_names.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/config.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/eject.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/extract_delegate_emitter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/extract_schema_emitter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/format.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/fr010_field_mapping.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generator_registry.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/api_docs_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/entity_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/extractor_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/find_inbound.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/fr019_shared_enum.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/m2m_codegen.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/names_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/output_parser_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/output_prompt_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/render_helper_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/requirement_tests_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/template_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/trace_helper_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/instance_artifacts.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/metaobjects-config.schema.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/model_walk.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/orphan_sweep.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/output_format_spec_emitter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/overwrite_policy.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/project_config.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/project_import.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/requirement_hooks.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/requirement_walk.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runner.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/api_docs_builder.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/api_docs_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/api_docs_paths.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/api_docs_renderer.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/constraint_errors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/extract_delegate_emitter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/extract_schema_emitter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/fr010_field_mapping.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/fr019_shared_enum.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/m2m_codegen.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/output_format_spec_emitter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/runtime/shared_predicates.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/template_codegen/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/template_codegen/output_pattern.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/template_codegen/template_data.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/template_codegen/template_spec.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/type_map.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/value_objects.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/config/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/core_types.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/datatype.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/documentation/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/documentation/doc_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/documentation/doc_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/documentation/doc_schema.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/errors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/field_lint.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/fmt.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/library/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/library/embedded_library.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/library/library_sources.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/merge.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/registered_validation.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/resolve_references.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/sources/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/sources/directory_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/sources/file_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/sources/uri_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/validate_discriminator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/validate_enum_normalize_ambiguity.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/validate_field_mutability.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/validate_reporting.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/validate_source_escapes.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/validate_source_parameter_ref.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/loader/validation_passes.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/attr/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/attr/attr_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/attr/meta_attr.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/field/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/field/field_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/field/meta_field.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/identity/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/index/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/index/index_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/index/meta_index.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/object/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/object/meta_object.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/object/object_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/object/object_extract.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/object/value_object.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/relationship/relationship_references.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/reporting/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/reporting/meta_dimension.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/reporting/meta_measure.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/reporting/meta_segment.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/reporting/report_accessors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/reporting/report_read_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/reporting/report_shape.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/reporting/reporting_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/requirement/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/requirement/meta_requirement.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/requirement/requirement_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/requirement/resolve_claim.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/validator/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/core/validator/validator_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/meta_data.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/persistence/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/persistence/db/db_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/persistence/db/db_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/persistence/origin/origin_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/persistence/source/meta_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/persistence/source/source_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/presentation/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/provider_extends.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/template/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/template/meta_template.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/template/prompt_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta/template/template_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/meta_endpoint.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/naming.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/naming_refs.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/parser.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/parser_yaml.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/py.typed +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/registry.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/registry_manifest.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/email_document.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/escapers.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/extract/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/extract/coerce.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/extract/extract.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/extract/extract_map.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/extract/locate.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/extract/normalize.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/extract/strip.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/extract/types.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/filesystem_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/payload_accessors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/prompt/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/prompt/prompt_field.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/prompt/prompt_style.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/renderer.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/render/verify.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/requirement_check.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/runtime/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/runtime/dialect.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/runtime/drivers.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/runtime/llm_recorder.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/runtime/n2m_resolver.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/runtime/object_manager.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/runtime/tph.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/runtime/validator_runner.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/scope.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/serializer_json.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/shared/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/shared/base_types.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/shared/separators.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/shared/structural.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/source/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/source/error_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/source/json_path.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/source/semantic_diff.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/source/yaml_positions.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/source_resolution.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/attr.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/db.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/documentation.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/field.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/identity.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/index.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/layout.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/object.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/origin.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/prompt.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/relationship.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/reporting.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/requirement.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/source.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/template.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/ui-web.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/ui.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/validator.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/spec_metamodel/view.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/super_resolve.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/validation_types.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/yaml_desugar.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/config_helpers.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/gen_suite.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/golden/extends/expected/BaseEntity.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/golden/extends/expected/Program.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/golden/extends/meta.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/golden/nested-array/expected/PostBrief.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/golden/nested-array/meta.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/golden/scalars/expected/Metric.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/golden/scalars/expected/Report.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/golden/scalars/meta.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/golden/vanilla/expected/Subscriber.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/golden/vanilla/meta.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_abstract_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_api_docs_builder.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_api_docs_paths.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_config_gen.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_config_verify.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_dependencies.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_fmt.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_gen_unknown_attr.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_help_removed_flags.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_providers.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_registry.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_render_helper_template_root.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_staleness_nudge.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_surface.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_verify_field_lint.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_verify_requirements.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_verify_strict.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cli_verify_subverbs.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_codegen_compile_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_collection_name_collision.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_constants_config.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_cross_package_binding_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_docs_generators.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_eject.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_eject_alone.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_eject_independence.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_eject_runtime.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_entity_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_enum_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_extends_abstract_field_inheritance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_extract_tier_collision.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_extractor_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_filter_allowlist_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_fmt_format_file.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_format.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_fr010_nested_object_prompt.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_fr010_output_codegen.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_gen_state_keying.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_generator_extension_seams.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_golden.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_hand_edits.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_inherit_without_restate_gate.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_inheritance_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_instance_artifacts.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_m2m_codegen.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_moved_modules.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_names_extends_chain.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_names_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_no_magic_physical_names.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_one_generator_list.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_origin_nullability.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_orphan_sweep.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_output_parser_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_overwrite_policy.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_overwrite_policy_hash.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_project_config.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_project_import.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_projection_compile.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_projection_docs_routes.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_recipe_generators.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_render_helper_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_render_helper_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_report_router.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_requirement_tests_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_reverse_finders.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_route_path_naming.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_router_autoset.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_runner.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_source_resolution.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_sourceless_entity_surface.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_sourceless_projection.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_template_data.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_template_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_template_output_pattern.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_template_scope_helpers.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_template_scope_walk.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_template_spec.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_trace_helper_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_type_map.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_validation_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_value_objects.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/codegen/test_write_through.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/config/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/config/test_dependencies.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/config/test_library_package_guard.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/config/test_neutral_config.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/config/test_neutral_config_unknown_key.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/config/test_source_resolver.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/capabilities.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/conformance-expected-failures.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/conformance_adapter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/corpus.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/eject_contract.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/expected_failures.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/fixture_discovery.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/navigator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_conformance_twin_roundtrip.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_dependency_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_eject_contract.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_extract_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_extract_object_array_bounds.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_extract_object_verdict.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_field_lint_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_fmt_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_fr010_loader_attrs.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_fr011_attrs.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_generator_registry_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_naming_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_object_model_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_provider_composition_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_registry_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_requirement_check_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_requirement_test_identity_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_runner_hardfail.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_scope_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_source_resolution_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_spec_metamodel_embed.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_strict_attr_load.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_template_codegen_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_template_generator_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/test_yaml_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/api_contract_assertions.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/api_contract_jsonb_server.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/api_contract_m2m_server.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/api_contract_server.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/conftest.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/engines.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/meta_ai_trace.yaml +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/mysql_container.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/normalization.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/postgres_container.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/query_runner.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/report_lane.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/scenarios.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_api_contract.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_api_contract_decimal.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_api_contract_generated.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_api_contract_jsonb.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_api_contract_m2m.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_api_contract_m2m_generated.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_api_contract_projection.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_api_contract_report.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_api_contract_tph_generated.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_generated_router_uuid_pk.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_llm_call_trace.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_m2m_target_tph_generated.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_normalization.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_query_scenarios.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_runtime_return_types.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_tph_m2m_generated.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/integration/test_tph_m2m_shadowed_generated.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/loader/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/loader/test_abstract_subtype_authored.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/loader/test_child_wrapper_body_shape.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/loader/test_enum_extends_values_conflict.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/loader/test_field_mutability_order.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/loader/test_library_packages.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/loader/test_naming_discovery.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/loader/test_relative_package_multi_root.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/loader/test_shipped_library_ai.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/loader/test_template_payload_target_210.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/open_closed_proof_test.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/extract/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/extract/test_coerce.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/extract/test_extract.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/extract/test_extract_map.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/extract/test_json_forgiving_reader.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/extract/test_locate.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/extract/test_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/extract/test_normalize.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/extract/test_strip.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/prompt/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/prompt/test_output_format_renderer.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/test_email_document.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/test_filesystem_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/test_output_format_renderer_nested.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/test_output_prompt_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/test_render_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/test_render_max_chars.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/test_render_model_payload.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/test_verify.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/render/test_verify_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/runtime/test_constraint_errors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/runtime/test_literal_naming_sqlite.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/runtime/test_object_manager_currency_read.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/runtime/test_object_manager_dialects.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/runtime/test_object_manager_enum_intvaluemap.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/runtime/test_object_manager_report.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/runtime/test_object_manager_table_name.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/runtime/test_validation_conformance_runtime.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/runtime/test_validator_runner.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/source/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/source/test_fr5c_merge_attribution.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/source/test_fr5d_reference_resolution.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/source/test_fr5e_database_source_shape.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/source/test_json_path.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/source/test_semantic_diff.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/source/test_source_on_node.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/source/test_yaml_positions.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/test_api_docs_accuracy.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/test_api_docs_packages.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/test_meta_endpoint.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/test_report_read_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/test_report_shape.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/test_reporting_inert.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_agent_context_staleness.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_capabilities.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_column_naming_strategy.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_common_attrs.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_core_types.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_derive_m2m_declaring_entity.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_effective_children_sibling_shadowing.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_effective_package.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_errors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_field_enum.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_field_enum_intvaluemap.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_field_map_validation.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_file_source_id.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_index_lookup.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_inherited_reference_binding.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_llm_recorder.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_loader.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_loader_bom.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_loader_class.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_merge.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_meta_attr.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_meta_data.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_meta_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_module_shortcuts.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_n2m_resolver.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_n2m_resolver_inherited.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_no_dead_config_fields.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_object_manager_autoset_stamping.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_object_manager_write_through.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_one_primary_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_parser.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_parser_yaml.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_provider_extension.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_registry.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_registry_completeness.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_registry_extend.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_registry_sealed.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_relationship_m2m_validation.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_relationship_references.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_relationship_referential_actions.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_reporting_accessors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_reporting_validation_spine_default.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_resolution_key.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_resolve_claim.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_serializer.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_serializer_shared_document.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_shared_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_smoke.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_source_escapes.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_sources.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_strict_child_placement.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_super_resolve.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_template_toolcall.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_validation_attr_schema.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_validation_filter_values.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_validation_origin_195.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_validation_origin_paths.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_validation_sort_field.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_validation_warnings.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_write_coercion_arrays.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.2}/tests/unit/test_yaml_desugar.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: metaobjects
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: Cross-language metadata standard: declare typed entities once, generate idiomatic drift-checked code across languages — Python port.
|
|
5
5
|
Project-URL: Homepage, https://metaobjects.dev
|
|
6
6
|
Project-URL: Repository, https://github.com/metaobjectsdev/metaobjects
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "metaobjects"
|
|
3
|
-
version = "1.1.
|
|
3
|
+
version = "1.1.2"
|
|
4
4
|
description = "Cross-language metadata standard: declare typed entities once, generate idiomatic drift-checked code across languages — Python port."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -148,6 +148,7 @@ from metaobjects.render.verify import (
|
|
|
148
148
|
verify as render_verify,
|
|
149
149
|
)
|
|
150
150
|
from metaobjects.shared.base_types import TYPE_OBJECT, TYPE_TEMPLATE
|
|
151
|
+
from metaobjects.wire import WireFormat, wire_block, wire_candidates
|
|
151
152
|
|
|
152
153
|
|
|
153
154
|
#: The error a run with no generator selection reports.
|
|
@@ -505,6 +506,7 @@ def _load_root(
|
|
|
505
506
|
# so codegen and the runtime (both reached from an explicit-`metadata_dir` CLI
|
|
506
507
|
# invocation) read the same values `gen`/`verify --codegen` would.
|
|
507
508
|
result.root.naming = neutral.naming if neutral is not None else NamingRules()
|
|
509
|
+
result.root.wire = neutral.wire if neutral is not None else WireFormat()
|
|
508
510
|
return result.root, []
|
|
509
511
|
|
|
510
512
|
|
|
@@ -567,6 +569,7 @@ def _load_collection_result(
|
|
|
567
569
|
# project's ONE naming setting (read at the same rung as `libraries`); attach
|
|
568
570
|
# it to the loaded root so codegen, the runtime and `verify` agree.
|
|
569
571
|
result.root.naming = collection.naming
|
|
572
|
+
result.root.wire = collection.wire
|
|
570
573
|
return result
|
|
571
574
|
|
|
572
575
|
|
|
@@ -2151,6 +2154,20 @@ def _verify_codegen_config(args: argparse.Namespace) -> int:
|
|
|
2151
2154
|
):
|
|
2152
2155
|
print(naming_differs_message(candidate, used), file=sys.stderr)
|
|
2153
2156
|
return 1
|
|
2157
|
+
# The same question for the `wire` setting: it reaches the JSON every generated route
|
|
2158
|
+
# writes, so "regenerate" would change the contract existing clients read.
|
|
2159
|
+
used_wire = root.wire
|
|
2160
|
+
for wire_candidate in wire_candidates(used_wire):
|
|
2161
|
+
root.wire = wire_candidate
|
|
2162
|
+
try:
|
|
2163
|
+
other_errors, other_reports = compare(column_naming)
|
|
2164
|
+
finally:
|
|
2165
|
+
root.wire = used_wire
|
|
2166
|
+
if not other_errors and all(
|
|
2167
|
+
_report_clean(rep.changed, rep.missing, rep.extra) for rep in other_reports
|
|
2168
|
+
):
|
|
2169
|
+
print(wire_differs_message(wire_candidate, used_wire), file=sys.stderr)
|
|
2170
|
+
return 1
|
|
2154
2171
|
if regenerable:
|
|
2155
2172
|
print("regenerate (metaobjects gen) and commit the result.", file=sys.stderr)
|
|
2156
2173
|
if edited_orphans:
|
|
@@ -2204,6 +2221,20 @@ def naming_differs_message(committed: NamingRules, used: NamingRules) -> str:
|
|
|
2204
2221
|
)
|
|
2205
2222
|
|
|
2206
2223
|
|
|
2224
|
+
def wire_differs_message(committed: WireFormat, used: WireFormat) -> str:
|
|
2225
|
+
"""What ``verify --codegen`` says, in place of "regenerate", when the committed output was
|
|
2226
|
+
generated with the ``committed`` wire format and this run's loaded root resolved ``used``
|
|
2227
|
+
(ADR-0019 Amendment 2: the ``wire`` block of ``.metaobjects/config.json``)."""
|
|
2228
|
+
return (
|
|
2229
|
+
f"The committed output was generated with {wire_block(committed)}; this run used "
|
|
2230
|
+
f"{wire_block(used)} (the wire block of .metaobjects/config.json; each key defaults to "
|
|
2231
|
+
f"native). Do not regenerate: that changes the JSON the generated routes write "
|
|
2232
|
+
f"(decimals, value-object null members) for clients already reading it. "
|
|
2233
|
+
f"Declare {wire_block(committed)} in .metaobjects/config.json, and gen and verify "
|
|
2234
|
+
f"--codegen both read it."
|
|
2235
|
+
)
|
|
2236
|
+
|
|
2237
|
+
|
|
2207
2238
|
#: The text-ref attrs a ``template.*`` node may carry. Each is resolved through
|
|
2208
2239
|
#: the filesystem provider and run through the render ``verify()`` gate. A prompt
|
|
2209
2240
|
#: / document uses ``@textRef``; an email uses subject / html / (optional) text
|
{metaobjects-1.1.1 → metaobjects-1.1.2}/src/metaobjects/codegen/generators/router_generator.py
RENAMED
|
@@ -72,6 +72,7 @@ from metaobjects.meta.persistence.source.source_constants import (
|
|
|
72
72
|
)
|
|
73
73
|
from metaobjects.naming import DEFAULT_COLUMN_NAMING
|
|
74
74
|
from metaobjects.naming_refs import ref_target
|
|
75
|
+
from metaobjects.wire import WIRE_NATIVE, WireFormat, wire_of
|
|
75
76
|
from metaobjects.shared.base_types import TYPE_IDENTITY
|
|
76
77
|
|
|
77
78
|
from ..runtime.fr010_field_mapping import is_required
|
|
@@ -261,6 +262,64 @@ def _nested_decimals(entities: list[MetaObject]) -> dict[str, Any]:
|
|
|
261
262
|
return out
|
|
262
263
|
|
|
263
264
|
|
|
265
|
+
def _vo_shape(vo: MetaObject, seen: frozenset[str]) -> dict[str, Any]:
|
|
266
|
+
"""The declared members of the value object *vo*, as ``{"f": [member, ...], "o": {member:
|
|
267
|
+
shape}}`` (``o`` for the members that are themselves value objects or maps of them). What
|
|
268
|
+
``nullMembers: emit`` fills in; ``omit`` walks it to reach nested value objects."""
|
|
269
|
+
seen = seen | {vo.name}
|
|
270
|
+
shape: dict[str, Any] = {"f": [f.name for f in vo.fields()], "o": {}}
|
|
271
|
+
for f in vo.fields():
|
|
272
|
+
inner = _field_shape(f, seen)
|
|
273
|
+
if inner is not None:
|
|
274
|
+
shape["o"][f.name] = inner
|
|
275
|
+
return shape
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def _field_shape(f: MetaField, seen: frozenset[str]) -> dict[str, Any] | None:
|
|
279
|
+
if f.sub_type not in (fc.FIELD_SUBTYPE_OBJECT, fc.FIELD_SUBTYPE_MAP):
|
|
280
|
+
return None
|
|
281
|
+
target = object_ref_target(f)
|
|
282
|
+
if target is None or target.name in seen:
|
|
283
|
+
return None
|
|
284
|
+
shape = _vo_shape(target, seen)
|
|
285
|
+
return {"m": shape} if f.sub_type == fc.FIELD_SUBTYPE_MAP else shape
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def _wire_lines(entities: list[MetaObject], wire: WireFormat, name: str = "_WIRE") -> list[str]:
|
|
289
|
+
"""The *name* constant a response of *entities* is written through: the project's ``wire``
|
|
290
|
+
setting (ADR-0019 Amendment 2) and, when ``nullMembers`` is not ``native``, the declared
|
|
291
|
+
members of each value-object field of *entities* (the first declaration of a name wins)."""
|
|
292
|
+
shapes: dict[str, Any] = {}
|
|
293
|
+
if wire.null_members != WIRE_NATIVE:
|
|
294
|
+
for entity in entities:
|
|
295
|
+
for f in entity.fields():
|
|
296
|
+
if f.name not in shapes and (shape := _field_shape(f, frozenset())) is not None:
|
|
297
|
+
shapes[f.name] = shape
|
|
298
|
+
args = f'decimals="{wire.decimals}", null_members="{wire.null_members}"'
|
|
299
|
+
if shapes:
|
|
300
|
+
args += f", shapes={shapes!r}"
|
|
301
|
+
return ["", "", f"{name} = WireOutput({args})"]
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def _m2m_wire_name(target: str) -> str:
|
|
305
|
+
"""The wire constant an M:N traversal onto *target* writes the target's rows through."""
|
|
306
|
+
return f"_WIRE_{_snake_case(target).upper()}"
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def _m2m_wire_lines(
|
|
310
|
+
descriptors: list[M2mDescriptor], object_index: dict[str, MetaObject], wire: WireFormat
|
|
311
|
+
) -> list[str]:
|
|
312
|
+
"""One :func:`_m2m_wire_name` constant per distinct M:N target, shaped by the TARGET's
|
|
313
|
+
value-object fields (and its TPH subtypes' when the target is a discriminator base)."""
|
|
314
|
+
lines: list[str] = []
|
|
315
|
+
for name in dict.fromkeys(d.target_entity for d in descriptors):
|
|
316
|
+
target = next(o for o in object_index.values() if o.name == name)
|
|
317
|
+
plan = tph_plan_for(target, object_index)
|
|
318
|
+
entities = [target, *(st.entity for st in plan.subtypes)] if plan is not None else [target]
|
|
319
|
+
lines.extend(_wire_lines(entities, wire, _m2m_wire_name(name)))
|
|
320
|
+
return lines
|
|
321
|
+
|
|
322
|
+
|
|
264
323
|
def _decimal_limits_lines(entities: list[MetaObject]) -> list[str]:
|
|
265
324
|
limits = _decimal_limits(entities)
|
|
266
325
|
body = "{" + ", ".join(f'"{n}": ({p}, {sc})' for n, (p, sc) in limits.items()) + "}"
|
|
@@ -734,8 +793,8 @@ class RouterGenerator:
|
|
|
734
793
|
" rows = repo.list(actual_limit, actual_offset, sort_clause, predicates)",
|
|
735
794
|
" if with_count == 1:",
|
|
736
795
|
" total = repo.count(predicates)",
|
|
737
|
-
' return {"rows":
|
|
738
|
-
" return
|
|
796
|
+
' return {"rows": render_wire(rows, _WIRE), "total": total}',
|
|
797
|
+
" return render_wire(rows, _WIRE)",
|
|
739
798
|
]
|
|
740
799
|
if name == "get":
|
|
741
800
|
return [
|
|
@@ -747,7 +806,7 @@ class RouterGenerator:
|
|
|
747
806
|
f" row = repo.find_by_id({pk_param})",
|
|
748
807
|
" if row is None:",
|
|
749
808
|
' return JSONResponse(status_code=404, content={"error": "not_found"})',
|
|
750
|
-
" return
|
|
809
|
+
" return render_wire(row, _WIRE)",
|
|
751
810
|
]
|
|
752
811
|
if name == "create":
|
|
753
812
|
return [
|
|
@@ -768,7 +827,7 @@ class RouterGenerator:
|
|
|
768
827
|
# (a fresh row's createdAt == updatedAt), ignoring any caller-supplied value.
|
|
769
828
|
*create_autoset,
|
|
770
829
|
" try:",
|
|
771
|
-
" return
|
|
830
|
+
" return render_wire(repo.create(dto), _WIRE)",
|
|
772
831
|
*_CONSTRAINT_EXCEPT,
|
|
773
832
|
]
|
|
774
833
|
if name == "update":
|
|
@@ -803,7 +862,7 @@ class RouterGenerator:
|
|
|
803
862
|
*_CONSTRAINT_EXCEPT,
|
|
804
863
|
" if saved is None:",
|
|
805
864
|
' return JSONResponse(status_code=404, content={"error": "not_found"})',
|
|
806
|
-
" return
|
|
865
|
+
" return render_wire(saved, _WIRE)",
|
|
807
866
|
]
|
|
808
867
|
if name == "delete":
|
|
809
868
|
return [
|
|
@@ -836,8 +895,9 @@ class RouterGenerator:
|
|
|
836
895
|
f" {pk_param}: {pk_type},",
|
|
837
896
|
f" repo: Annotated[{repo_class}, Depends(get_repository)],",
|
|
838
897
|
") -> list[Any]:",
|
|
839
|
-
f" return
|
|
840
|
-
f"({pk_param}{_target_subtype_arg(d, {d.target_discriminator})})
|
|
898
|
+
f" return render_wire(repo.find_related_{d.relation_name}"
|
|
899
|
+
f"({pk_param}{_target_subtype_arg(d, {d.target_discriminator})}), "
|
|
900
|
+
f"{_m2m_wire_name(d.target_entity)})",
|
|
841
901
|
]
|
|
842
902
|
|
|
843
903
|
def _emit_tph_m2m_route(
|
|
@@ -893,8 +953,9 @@ class RouterGenerator:
|
|
|
893
953
|
" return []",
|
|
894
954
|
]
|
|
895
955
|
lines.append(
|
|
896
|
-
f" return
|
|
897
|
-
f"({subtype_expr}, {pk_param}{_target_subtype_arg(d, target_discs)})
|
|
956
|
+
f" return render_wire(repo.find_related_{d.relation_name}"
|
|
957
|
+
f"({subtype_expr}, {pk_param}{_target_subtype_arg(d, target_discs)}), "
|
|
958
|
+
f"{_m2m_wire_name(d.target_entity)})"
|
|
898
959
|
)
|
|
899
960
|
return lines
|
|
900
961
|
|
|
@@ -923,8 +984,8 @@ class RouterGenerator:
|
|
|
923
984
|
f" rows = {repo_var}.list({subtype_expr}, actual_limit, actual_offset, sort_clause, predicates)",
|
|
924
985
|
" if with_count == 1:",
|
|
925
986
|
f" total = {repo_var}.count({subtype_expr}, predicates)",
|
|
926
|
-
' return {"rows":
|
|
927
|
-
" return
|
|
987
|
+
' return {"rows": render_wire(rows, _WIRE), "total": total}',
|
|
988
|
+
" return render_wire(rows, _WIRE)",
|
|
928
989
|
]
|
|
929
990
|
|
|
930
991
|
def _render_tph_router(
|
|
@@ -933,6 +994,7 @@ class RouterGenerator:
|
|
|
933
994
|
plan: TphPlan,
|
|
934
995
|
object_index: dict[str, MetaObject],
|
|
935
996
|
column_naming: str = DEFAULT_COLUMN_NAMING,
|
|
997
|
+
wire: WireFormat = WireFormat(),
|
|
936
998
|
) -> str:
|
|
937
999
|
"""FR-017 TPH: emit the discriminator base's router — a polymorphic collection
|
|
938
1000
|
at the base path + a full per-subtype CRUD set at /<base>/<segment>. The repo
|
|
@@ -1090,7 +1152,8 @@ class RouterGenerator:
|
|
|
1090
1152
|
parts.append(" coerce_decimal_fields,")
|
|
1091
1153
|
parts.append(" coerce_decimal_predicates,")
|
|
1092
1154
|
parts.append(" parse_json_object,")
|
|
1093
|
-
parts.append("
|
|
1155
|
+
parts.append(" WireOutput,")
|
|
1156
|
+
parts.append(" render_wire,")
|
|
1094
1157
|
parts.append(")")
|
|
1095
1158
|
parts.append(f"from {_runtime_module('filter_parser')} import (")
|
|
1096
1159
|
parts.append(" FilterPredicate,")
|
|
@@ -1116,6 +1179,12 @@ class RouterGenerator:
|
|
|
1116
1179
|
parts.append("")
|
|
1117
1180
|
parts.append(f"_DECIMAL_FIELDS: frozenset[str] = {decimal_set_body}")
|
|
1118
1181
|
parts.extend(_decimal_limits_lines([entity, *(st.entity for st in plan.subtypes)]))
|
|
1182
|
+
parts.extend(_wire_lines([entity, *(st.entity for st in plan.subtypes)], wire))
|
|
1183
|
+
parts.extend(_m2m_wire_lines(
|
|
1184
|
+
[*base_m2m, *(d for st in plan.subtypes for d in sub_m2m[st.entity.name])],
|
|
1185
|
+
object_index,
|
|
1186
|
+
wire,
|
|
1187
|
+
))
|
|
1119
1188
|
parts.append("")
|
|
1120
1189
|
parts.append("")
|
|
1121
1190
|
parts.extend(_JSON_BODY_LINES)
|
|
@@ -1207,7 +1276,7 @@ class RouterGenerator:
|
|
|
1207
1276
|
# non-@autoSet hierarchy — byte-identical output).
|
|
1208
1277
|
parts.extend(create_autoset)
|
|
1209
1278
|
parts.append(" try:")
|
|
1210
|
-
parts.append(f' return
|
|
1279
|
+
parts.append(f' return render_wire(repo.create("{val}", dto), _WIRE)')
|
|
1211
1280
|
parts.extend(_CONSTRAINT_EXCEPT)
|
|
1212
1281
|
parts.append("")
|
|
1213
1282
|
parts.append("")
|
|
@@ -1219,7 +1288,7 @@ class RouterGenerator:
|
|
|
1219
1288
|
parts.append(f' row = repo.find_by_id("{val}", {pk_param})')
|
|
1220
1289
|
parts.append(" if row is None:")
|
|
1221
1290
|
parts.append(' return JSONResponse(status_code=404, content={"error": "not_found"})')
|
|
1222
|
-
parts.append(" return
|
|
1291
|
+
parts.append(" return render_wire(row, _WIRE)")
|
|
1223
1292
|
parts.append("")
|
|
1224
1293
|
parts.append("")
|
|
1225
1294
|
parts.append(f'@router.patch("/{seg}/{{{pk_param}}}")')
|
|
@@ -1248,7 +1317,7 @@ class RouterGenerator:
|
|
|
1248
1317
|
parts.extend(_CONSTRAINT_EXCEPT)
|
|
1249
1318
|
parts.append(" if saved is None:")
|
|
1250
1319
|
parts.append(' return JSONResponse(status_code=404, content={"error": "not_found"})')
|
|
1251
|
-
parts.append(" return
|
|
1320
|
+
parts.append(" return render_wire(saved, _WIRE)")
|
|
1252
1321
|
parts.append("")
|
|
1253
1322
|
parts.append("")
|
|
1254
1323
|
parts.append(f'@router.delete("/{seg}/{{{pk_param}}}", status_code=status.HTTP_204_NO_CONTENT)')
|
|
@@ -1298,7 +1367,7 @@ class RouterGenerator:
|
|
|
1298
1367
|
parts.append(f" row = repo.find_by_id(None, {pk_param})")
|
|
1299
1368
|
parts.append(" if row is None:")
|
|
1300
1369
|
parts.append(' return JSONResponse(status_code=404, content={"error": "not_found"})')
|
|
1301
|
-
parts.append(" return
|
|
1370
|
+
parts.append(" return render_wire(row, _WIRE)")
|
|
1302
1371
|
parts.append("")
|
|
1303
1372
|
|
|
1304
1373
|
# FW-8 rule (a): every relationship the BASE resolves — every row of the
|
|
@@ -1326,6 +1395,7 @@ class RouterGenerator:
|
|
|
1326
1395
|
entity: MetaObject,
|
|
1327
1396
|
object_index: dict[str, MetaObject] | None = None,
|
|
1328
1397
|
column_naming: str = DEFAULT_COLUMN_NAMING,
|
|
1398
|
+
wire: WireFormat | None = None,
|
|
1329
1399
|
) -> str | None:
|
|
1330
1400
|
"""Render an entity as a FastAPI ``APIRouter`` module.
|
|
1331
1401
|
|
|
@@ -1342,6 +1412,8 @@ class RouterGenerator:
|
|
|
1342
1412
|
source URL segment is the ENTITY name pluralized (cross-port grammar), NOT
|
|
1343
1413
|
the physical ``@table``. Without an index, only CRUD is emitted (back-compat).
|
|
1344
1414
|
|
|
1415
|
+
*wire* is the run's ``wire`` setting; omitted, it is read from the loaded root.
|
|
1416
|
+
|
|
1345
1417
|
*column_naming* is ``GenConfig.column_naming`` for this run — passed through
|
|
1346
1418
|
to :func:`resolve_m2m_descriptors` so the M:N descriptor's physical junction
|
|
1347
1419
|
columns are resolved by the SAME strategy the ``names`` generator applies to
|
|
@@ -1353,6 +1425,9 @@ class RouterGenerator:
|
|
|
1353
1425
|
"""
|
|
1354
1426
|
if not emits_router(entity):
|
|
1355
1427
|
return None
|
|
1428
|
+
# ADR-0019 Amendment 2: the project's `wire` setting, from the loaded root. A caller
|
|
1429
|
+
# that holds an object detached from the root (a report's read model) passes it.
|
|
1430
|
+
wire = wire if wire is not None else wire_of(entity)
|
|
1356
1431
|
# FR-017 TPH: a concrete subtype is folded into its base's single table — it
|
|
1357
1432
|
# emits no standalone router (its CRUD lives under the base's per-subtype segment).
|
|
1358
1433
|
if object_index is not None and is_tph_subtype(entity):
|
|
@@ -1371,7 +1446,7 @@ class RouterGenerator:
|
|
|
1371
1446
|
# answering the cross-port 405 envelope. Gated by
|
|
1372
1447
|
# fixtures/api-contract-conformance/projection/.
|
|
1373
1448
|
if is_read_only_routed(entity):
|
|
1374
|
-
return self._render_readonly_router(entity, column_naming)
|
|
1449
|
+
return self._render_readonly_router(entity, column_naming, wire)
|
|
1375
1450
|
return None
|
|
1376
1451
|
|
|
1377
1452
|
# FR-017 TPH: a discriminator base emits a polymorphic collection at the base
|
|
@@ -1379,7 +1454,7 @@ class RouterGenerator:
|
|
|
1379
1454
|
if object_index is not None:
|
|
1380
1455
|
plan = tph_plan_for(entity, object_index)
|
|
1381
1456
|
if plan is not None:
|
|
1382
|
-
return self._render_tph_router(entity, plan, object_index, column_naming)
|
|
1457
|
+
return self._render_tph_router(entity, plan, object_index, column_naming, wire)
|
|
1383
1458
|
|
|
1384
1459
|
m2m: list[M2mDescriptor] = (
|
|
1385
1460
|
resolve_m2m_descriptors(entity, object_index, column_naming)
|
|
@@ -1458,7 +1533,8 @@ class RouterGenerator:
|
|
|
1458
1533
|
parts.append(" coerce_decimal_fields,")
|
|
1459
1534
|
parts.append(" coerce_decimal_predicates,")
|
|
1460
1535
|
parts.append(" parse_json_object,")
|
|
1461
|
-
parts.append("
|
|
1536
|
+
parts.append(" WireOutput,")
|
|
1537
|
+
parts.append(" render_wire,")
|
|
1462
1538
|
parts.append(")")
|
|
1463
1539
|
parts.append(f"from {_runtime_module('filter_parser')} import (")
|
|
1464
1540
|
parts.append(" FilterPredicate,")
|
|
@@ -1485,6 +1561,8 @@ class RouterGenerator:
|
|
|
1485
1561
|
parts.append("")
|
|
1486
1562
|
parts.append(f"_DECIMAL_FIELDS: frozenset[str] = {decimal_set_body}")
|
|
1487
1563
|
parts.extend(_decimal_limits_lines([entity]))
|
|
1564
|
+
parts.extend(_wire_lines([entity], wire))
|
|
1565
|
+
parts.extend(_m2m_wire_lines(m2m, object_index or {}, wire))
|
|
1488
1566
|
parts.append("")
|
|
1489
1567
|
parts.append("")
|
|
1490
1568
|
parts.extend(_JSON_BODY_LINES)
|
|
@@ -1599,6 +1677,7 @@ class RouterGenerator:
|
|
|
1599
1677
|
self,
|
|
1600
1678
|
entity: MetaObject,
|
|
1601
1679
|
column_naming: str = DEFAULT_COLUMN_NAMING,
|
|
1680
|
+
wire: WireFormat = WireFormat(),
|
|
1602
1681
|
) -> str:
|
|
1603
1682
|
"""Render a read-only (`@kind: view` / `materializedView`) object as a FastAPI
|
|
1604
1683
|
``APIRouter``: GET list + GET by id, and the four write verbs answering 405. An
|
|
@@ -1663,7 +1742,8 @@ class RouterGenerator:
|
|
|
1663
1742
|
parts.append("")
|
|
1664
1743
|
parts.append(f"from {_runtime_module('decimal_wire')} import (")
|
|
1665
1744
|
parts.append(" coerce_decimal_predicates,")
|
|
1666
|
-
parts.append("
|
|
1745
|
+
parts.append(" WireOutput,")
|
|
1746
|
+
parts.append(" render_wire,")
|
|
1667
1747
|
parts.append(")")
|
|
1668
1748
|
parts.append(f"from {_runtime_module('filter_parser')} import (")
|
|
1669
1749
|
parts.append(" FilterPredicate,")
|
|
@@ -1682,6 +1762,7 @@ class RouterGenerator:
|
|
|
1682
1762
|
"_DECIMAL_FIELDS: frozenset[str] = "
|
|
1683
1763
|
+ _py_set_literal(_decimal_field_names([entity]), frozen=True)
|
|
1684
1764
|
)
|
|
1765
|
+
parts.extend(_wire_lines([entity], wire))
|
|
1685
1766
|
parts.append("")
|
|
1686
1767
|
parts.append("")
|
|
1687
1768
|
parts.extend(_sort_parse_fn_lines())
|
|
@@ -1746,7 +1827,8 @@ class RouterGenerator:
|
|
|
1746
1827
|
# reads (`c.config.column_naming`) — so the M:N descriptor built here
|
|
1747
1828
|
# and the per-field constants built there can't disagree about a
|
|
1748
1829
|
# column name within one run.
|
|
1749
|
-
|
|
1830
|
+
wire = wire_of(c.loaded_root) if c.loaded_root is not None else None
|
|
1831
|
+
source = self.render_router(entity, index, c.config.column_naming, wire)
|
|
1750
1832
|
if source is None:
|
|
1751
1833
|
return []
|
|
1752
1834
|
snake = _snake_case(entity.name)
|
|
@@ -6,6 +6,8 @@ One production helper, used by the generated routers and tested against the shar
|
|
|
6
6
|
* **W1, emit** -- :func:`format_decimal` / :func:`to_wire`: every ``Decimal`` leaves as a JSON
|
|
7
7
|
string in canonical form (plain notation, no exponent, no trailing fractional zeros, zero is
|
|
8
8
|
``"0"``).
|
|
9
|
+
Which form leaves is the project's ``wire`` setting (:func:`render_wire`): ``string`` is W1,
|
|
10
|
+
``native`` is :func:`to_native`.
|
|
9
11
|
* **W2, accept** -- :func:`parse_decimal` (a request-body value) and :func:`parse_decimal_operand`
|
|
10
12
|
(a filter operand): a string in the JSON-number grammar, or a JSON number; anything else is a
|
|
11
13
|
``ValueError``. Nothing goes through a ``float``: :func:`parse_json_object` reads a body with
|
|
@@ -20,7 +22,7 @@ import dataclasses
|
|
|
20
22
|
import json
|
|
21
23
|
import re
|
|
22
24
|
from decimal import Context, Decimal, InvalidOperation
|
|
23
|
-
from typing import Any, Iterable
|
|
25
|
+
from typing import Any, Callable, Iterable
|
|
24
26
|
|
|
25
27
|
#: A string body value and a filter operand: the JSON-number grammar. An exponent is allowed on
|
|
26
28
|
#: input only. No sign other than ``-``, no leading zeros, no bare point, no whitespace.
|
|
@@ -245,17 +247,81 @@ def coerce_decimal_predicates(
|
|
|
245
247
|
return out, None
|
|
246
248
|
|
|
247
249
|
|
|
248
|
-
def
|
|
249
|
-
"""
|
|
250
|
-
|
|
251
|
-
is left for the framework's encoder."""
|
|
250
|
+
def _render(value: Any, decimal: Callable[[Decimal], str]) -> Any:
|
|
251
|
+
"""*value* with every ``Decimal`` (at any depth of a dict, list or Pydantic model) as the
|
|
252
|
+
string *decimal* makes of it; everything else is left for the framework's encoder."""
|
|
252
253
|
if isinstance(value, Decimal):
|
|
253
|
-
return
|
|
254
|
+
return decimal(value)
|
|
254
255
|
if isinstance(value, dict):
|
|
255
|
-
return {k:
|
|
256
|
+
return {k: _render(v, decimal) for k, v in value.items()}
|
|
256
257
|
if isinstance(value, (list, tuple)):
|
|
257
|
-
return [
|
|
258
|
+
return [_render(v, decimal) for v in value]
|
|
258
259
|
dump = getattr(value, "model_dump", None)
|
|
259
260
|
if callable(dump):
|
|
260
|
-
return
|
|
261
|
+
return _render(dump(), decimal)
|
|
261
262
|
return value
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def to_wire(value: Any) -> Any:
|
|
266
|
+
"""W1 over a whole response: every ``Decimal`` in *value* (a row, a list of rows, the
|
|
267
|
+
``{"rows", "total"}`` envelope, a Pydantic model) as its canonical string."""
|
|
268
|
+
return _render(value, format_decimal)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def to_native(value: Any) -> Any:
|
|
272
|
+
"""The ``native`` decimal form over a whole response: every ``Decimal`` as ``str(value)``,
|
|
273
|
+
which is what Pydantic v2 writes for one and keeps the value's scale (``Decimal("12.50")``
|
|
274
|
+
is ``"12.50"``). FastAPI's own encoder would turn a ``Decimal`` in a plain dict row into a
|
|
275
|
+
``float``, which is lossy; a string is the exact form."""
|
|
276
|
+
return _render(value, str)
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
@dataclasses.dataclass(frozen=True)
|
|
280
|
+
class WireOutput:
|
|
281
|
+
"""The ``wire`` project setting (ADR-0019 Amendment 2) a generated router writes with.
|
|
282
|
+
|
|
283
|
+
*decimals* is ``native`` or ``string``; *null_members* is ``native``, ``emit`` or ``omit``.
|
|
284
|
+
*shapes* names, per value-object field of the entity, its declared members:
|
|
285
|
+
``{"f": [member, ...], "o": {member: shape}}``, or ``{"m": shape}`` for a ``field.map`` of
|
|
286
|
+
value objects (the shape applies to each value)."""
|
|
287
|
+
|
|
288
|
+
decimals: str = "native"
|
|
289
|
+
null_members: str = "native"
|
|
290
|
+
shapes: dict[str, Any] = dataclasses.field(default_factory=dict)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def render_wire(value: Any, wire: WireOutput) -> Any:
|
|
294
|
+
"""A response *value* (a row, a list of rows, a Pydantic model) in the form *wire* asks
|
|
295
|
+
for. Input rules do not depend on *wire*."""
|
|
296
|
+
if wire.null_members != "native" and wire.shapes:
|
|
297
|
+
value = _shape_members(value, wire)
|
|
298
|
+
return to_wire(value) if wire.decimals == "string" else to_native(value)
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def _shape_members(value: Any, wire: WireOutput) -> Any:
|
|
302
|
+
"""Apply ``omit`` / ``emit`` to the value-object fields of every row in *value*. A row's
|
|
303
|
+
other fields (a top-level ``null`` among them) are untouched."""
|
|
304
|
+
if isinstance(value, (list, tuple)):
|
|
305
|
+
return [_shape_members(v, wire) for v in value]
|
|
306
|
+
dump = getattr(value, "model_dump", None)
|
|
307
|
+
if callable(dump):
|
|
308
|
+
value = dump()
|
|
309
|
+
if not isinstance(value, dict):
|
|
310
|
+
return value
|
|
311
|
+
out: dict[str, Any] = {}
|
|
312
|
+
for k, v in value.items():
|
|
313
|
+
out[k] = _shape_vo(v, wire.shapes[k], wire.null_members) if k in wire.shapes else v
|
|
314
|
+
return out
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def _shape_vo(value: Any, shape: dict[str, Any], mode: str) -> Any:
|
|
318
|
+
if isinstance(value, list):
|
|
319
|
+
return [_shape_vo(v, shape, mode) for v in value]
|
|
320
|
+
if not isinstance(value, dict):
|
|
321
|
+
return value
|
|
322
|
+
if "m" in shape:
|
|
323
|
+
return {k: _shape_vo(v, shape["m"], mode) for k, v in value.items()}
|
|
324
|
+
members = {k: _shape_vo(v, shape["o"][k], mode) if k in shape["o"] else v for k, v in value.items()}
|
|
325
|
+
if mode == "omit":
|
|
326
|
+
return {k: v for k, v in members.items() if v is not None}
|
|
327
|
+
return {**{name: None for name in shape["f"]}, **members}
|
|
@@ -17,6 +17,7 @@ from typing import Any, Callable, Sequence
|
|
|
17
17
|
from metaobjects.errors import ErrorCode, ParseError
|
|
18
18
|
from metaobjects.meta.meta_data import MetaData
|
|
19
19
|
from metaobjects.naming import NamingRules, package_of_resolution_key
|
|
20
|
+
from metaobjects.wire import WireFormat
|
|
20
21
|
from metaobjects.registry_manifest import METAMODEL_VERSION
|
|
21
22
|
from metaobjects.shared.base_types import TYPE_OBJECT
|
|
22
23
|
|
|
@@ -659,6 +660,10 @@ class Collection:
|
|
|
659
660
|
#: codegen, the runtime and `verify` all read the same values.
|
|
660
661
|
naming: NamingRules
|
|
661
662
|
|
|
663
|
+
#: ADR-0019 Amendment 2 — this project's `wire` setting, read at the same rung;
|
|
664
|
+
#: attached to the loaded root beside `naming`.
|
|
665
|
+
wire: WireFormat = WireFormat()
|
|
666
|
+
|
|
662
667
|
def imported(self, fqn: str) -> bool:
|
|
663
668
|
"""Is `fqn` in a package one of this project's dependencies owns?"""
|
|
664
669
|
return package_of_resolution_key(fqn) in self.imported_packages
|
|
@@ -7,6 +7,7 @@ from pathlib import Path
|
|
|
7
7
|
|
|
8
8
|
from metaobjects.errors import ErrorCode, ParseError
|
|
9
9
|
from metaobjects.naming import COLUMN_NAMING_STRATEGIES, TABLE_NAMING_RULES, NamingRules
|
|
10
|
+
from metaobjects.wire import WIRE_DECIMALS, WIRE_NULL_MEMBERS, WireFormat
|
|
10
11
|
|
|
11
12
|
#: The DEFAULT value of `sources` when the key is absent or empty — never a
|
|
12
13
|
#: requirement, and never assumed to exist by any other code path.
|
|
@@ -75,6 +76,12 @@ class NeutralConfig:
|
|
|
75
76
|
#: every column.
|
|
76
77
|
naming: NamingRules
|
|
77
78
|
|
|
79
|
+
#: ADR-0019 Amendment 2 — the `wire` block: the OUTPUT form of a generated REST
|
|
80
|
+
#: surface (decimals, value-object null members). Absent or `{}` ⇒ `native` for both.
|
|
81
|
+
#: Attached to the loaded root (`MetaRoot.wire`) beside `naming`; validated HERE
|
|
82
|
+
#: for the same reason `naming` is.
|
|
83
|
+
wire: WireFormat = WireFormat()
|
|
84
|
+
|
|
78
85
|
|
|
79
86
|
def find_project_dir(start: Path) -> Path | None:
|
|
80
87
|
"""The nearest directory at or above *start* that holds ``.metaobjects/config.json``,
|
|
@@ -167,6 +174,7 @@ def read_neutral_config(config_dir: Path) -> NeutralConfig | None:
|
|
|
167
174
|
migrate_scope = _read_migrate_scope(raw, path)
|
|
168
175
|
libraries = _read_libraries(raw, path)
|
|
169
176
|
naming = _read_naming(raw, path)
|
|
177
|
+
wire = _read_wire(raw, path)
|
|
170
178
|
|
|
171
179
|
# Unknown top-level keys are IGNORED by design — see the module docstring.
|
|
172
180
|
return NeutralConfig(
|
|
@@ -176,6 +184,7 @@ def read_neutral_config(config_dir: Path) -> NeutralConfig | None:
|
|
|
176
184
|
migrate_scope=migrate_scope,
|
|
177
185
|
libraries=libraries,
|
|
178
186
|
naming=naming,
|
|
187
|
+
wire=wire,
|
|
179
188
|
)
|
|
180
189
|
|
|
181
190
|
|
|
@@ -296,6 +305,39 @@ def _read_naming(raw: dict[str, object], path: Path) -> NamingRules:
|
|
|
296
305
|
return NamingRules(columns=columns, tables=tables)
|
|
297
306
|
|
|
298
307
|
|
|
308
|
+
#: Every key the `wire` block accepts, and the ONLY ones it accepts (refused, not ignored, like `naming`).
|
|
309
|
+
_WIRE_KEYS = ("decimals", "nullMembers")
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def _read_wire(raw: dict[str, object], path: Path) -> WireFormat:
|
|
313
|
+
"""ADR-0019 Amendment 2 — the `wire` block. Absent or `{}` ⇒ `native` for both keys.
|
|
314
|
+
Refuses a non-object `wire`, an unknown key, or a value outside the closed set a key
|
|
315
|
+
accepts: a mistake must not silently fall back to the default and change the JSON an
|
|
316
|
+
API writes."""
|
|
317
|
+
if "wire" not in raw:
|
|
318
|
+
return WireFormat()
|
|
319
|
+
wire = raw["wire"]
|
|
320
|
+
if not isinstance(wire, dict):
|
|
321
|
+
raise ParseError(f'{path}: "wire" must be an object', code=ErrorCode.ERR_COLLECTION_NOT_FOUND)
|
|
322
|
+
for key in wire:
|
|
323
|
+
if key not in _WIRE_KEYS:
|
|
324
|
+
raise ParseError(
|
|
325
|
+
f'{path}: "wire" has an unknown key "{key}" (expected "decimals" and/or "nullMembers")',
|
|
326
|
+
code=ErrorCode.ERR_COLLECTION_NOT_FOUND,
|
|
327
|
+
)
|
|
328
|
+
values: dict[str, str] = {}
|
|
329
|
+
for key, allowed in (("decimals", WIRE_DECIMALS), ("nullMembers", WIRE_NULL_MEMBERS)):
|
|
330
|
+
value = wire.get(key, allowed[0])
|
|
331
|
+
if not isinstance(value, str) or value not in allowed:
|
|
332
|
+
choices = ", ".join(f'"{a}"' for a in allowed)
|
|
333
|
+
raise ParseError(
|
|
334
|
+
f'{path}: "wire.{key}" must be one of {choices}, got {json.dumps(value)}',
|
|
335
|
+
code=ErrorCode.ERR_COLLECTION_NOT_FOUND,
|
|
336
|
+
)
|
|
337
|
+
values[key] = value
|
|
338
|
+
return WireFormat(decimals=values["decimals"], null_members=values["nullMembers"])
|
|
339
|
+
|
|
340
|
+
|
|
299
341
|
def _validate_dependency_spec(dep: object, path: Path) -> dict[str, str]:
|
|
300
342
|
"""Validate one entry of `dependencies` (DESIGN §3.1) and return it
|
|
301
343
|
normalized. Mirrors the TS `DependencySpecSchema` union in
|
|
@@ -7,6 +7,7 @@ from typing import Callable
|
|
|
7
7
|
from metaobjects.errors import ErrorCode, ParseError
|
|
8
8
|
from metaobjects.loader.sources import DirectorySource
|
|
9
9
|
from metaobjects.naming import NamingRules, package_of_resolution_key
|
|
10
|
+
from metaobjects.wire import WireFormat
|
|
10
11
|
from metaobjects.scope import compile_scope, matches_scope
|
|
11
12
|
|
|
12
13
|
from .dependencies import (
|
|
@@ -155,6 +156,7 @@ def _collection_from_own_files(
|
|
|
155
156
|
migrate_scope: list[str] | None = cfg.migrate_scope if cfg is not None else None
|
|
156
157
|
libraries: list[str] = cfg.libraries if cfg is not None else []
|
|
157
158
|
naming: NamingRules = cfg.naming if cfg is not None else NamingRules()
|
|
159
|
+
wire: WireFormat = cfg.wire if cfg is not None else WireFormat()
|
|
158
160
|
|
|
159
161
|
lock = read_lock(root)
|
|
160
162
|
dependencies: list[ResolvedDependency] = (
|
|
@@ -185,6 +187,7 @@ def _collection_from_own_files(
|
|
|
185
187
|
),
|
|
186
188
|
libraries=tuple(libraries),
|
|
187
189
|
naming=naming,
|
|
190
|
+
wire=wire,
|
|
188
191
|
)
|
|
189
192
|
|
|
190
193
|
|
|
@@ -59,10 +59,12 @@ def _apply_discovered_naming(result: "LoadResult", start: Path) -> None:
|
|
|
59
59
|
*start*) to the loaded root; warn once when there is none and the default applies."""
|
|
60
60
|
from ..config.neutral_config import find_project_dir
|
|
61
61
|
from ..naming import attach_naming
|
|
62
|
+
from ..wire import attach_wire
|
|
62
63
|
|
|
63
64
|
project = find_project_dir(start if start.is_dir() else start.parent)
|
|
64
65
|
if project is not None:
|
|
65
66
|
attach_naming(result.root, project)
|
|
67
|
+
attach_wire(result.root, project)
|
|
66
68
|
return
|
|
67
69
|
warnings.warn(
|
|
68
70
|
f"no .metaobjects/config.json found at or above {start}: physical names use the "
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
from ..naming import NamingRules
|
|
5
|
+
from ..wire import WireFormat
|
|
5
6
|
from .meta_data import MetaData
|
|
6
7
|
|
|
7
8
|
|
|
@@ -16,3 +17,7 @@ class MetaRoot(MetaData):
|
|
|
16
17
|
# after loading — never during construction, since the loader seeds an empty
|
|
17
18
|
# root before any file is read.
|
|
18
19
|
self.naming: NamingRules = NamingRules()
|
|
20
|
+
# ADR-0019 Amendment 2 — the project `wire` setting (output form of the generated
|
|
21
|
+
# REST surface), attached by the same project-aware loads as `naming`; read with
|
|
22
|
+
# `wire_of()`. `native` for both keys until a load attaches the project's own.
|
|
23
|
+
self.wire: WireFormat = WireFormat()
|