metaobjects 1.1.1__tar.gz → 1.1.3__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.3}/PKG-INFO +1 -1
- {metaobjects-1.1.1 → metaobjects-1.1.3}/pyproject.toml +1 -1
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/cli.py +31 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/router_generator.py +193 -25
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/decimal_wire.py +75 -9
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/config/dependencies.py +5 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/config/neutral_config.py +42 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/config/source_resolver.py +3 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/meta_data_loader.py +2 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/meta_root.py +5 -0
- metaobjects-1.1.3/src/metaobjects/wire.py +70 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_config_run_settings.py +90 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_router_generator.py +2 -2
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_router_generator_m2m_target_tph.py +1 -1
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_router_generator_tph_m2m.py +13 -3
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_router_generator_tph_m2m_shadowed.py +3 -3
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_tph_codegen.py +1 -1
- metaobjects-1.1.3/tests/conformance/test_wire_conformance.py +54 -0
- metaobjects-1.1.3/tests/integration/corpus_config.py +18 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/generated_jsonb_app.py +2 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/generated_m2m_app.py +2 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/generated_projection_app.py +2 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/generated_report_app.py +10 -1
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/generated_router_app.py +2 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/generated_tph_app.py +2 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_api_contract_report.py +1 -1
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_generated_decimal_wire.py +234 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/runtime/test_decimal_wire.py +12 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/uv.lock +1 -1
- {metaobjects-1.1.1 → metaobjects-1.1.3}/.gitignore +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/LICENSE +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/README.md +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/hatch_build.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/scripts/generate_embedded_library.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/agent_context/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/agent_context/scaffold.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/apidocs/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/apidocs/api_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/apidocs/builder.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/apidocs/naming.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/apidocs/paths.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/apidocs/renderer.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/attr_class_map.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/KNOWN_GAPS.md +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/_moved.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/collection_name_collision.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/collision_names.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/config.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/eject.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/extract_delegate_emitter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/extract_schema_emitter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/format.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/fr010_field_mapping.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generator_registry.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/api_docs_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/entity_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/extractor_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/find_inbound.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/fr019_shared_enum.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/m2m_codegen.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/names_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/output_parser_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/output_prompt_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/render_helper_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/requirement_tests_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/template_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/generators/trace_helper_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/instance_artifacts.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/metaobjects-config.schema.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/model_walk.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/orphan_sweep.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/output_format_spec_emitter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/overwrite_policy.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/project_config.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/project_import.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/requirement_hooks.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/requirement_walk.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runner.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/api_docs_builder.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/api_docs_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/api_docs_paths.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/api_docs_renderer.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/constraint_errors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/extract_delegate_emitter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/extract_schema_emitter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/fr010_field_mapping.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/fr019_shared_enum.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/m2m_codegen.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/output_format_spec_emitter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/runtime/shared_predicates.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/template_codegen/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/template_codegen/output_pattern.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/template_codegen/template_data.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/template_codegen/template_spec.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/type_map.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/codegen/value_objects.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/config/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/core_types.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/datatype.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/documentation/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/documentation/doc_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/documentation/doc_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/documentation/doc_schema.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/errors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/field_lint.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/fmt.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/library/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/library/embedded_library.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/library/library_sources.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/merge.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/registered_validation.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/resolve_references.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/sources/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/sources/directory_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/sources/file_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/sources/uri_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/validate_discriminator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/validate_enum_normalize_ambiguity.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/validate_field_mutability.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/validate_reporting.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/validate_source_escapes.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/validate_source_parameter_ref.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/loader/validation_passes.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/attr/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/attr/attr_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/attr/meta_attr.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/field/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/field/field_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/field/meta_field.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/identity/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/index/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/index/index_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/index/meta_index.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/object/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/object/meta_object.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/object/object_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/object/object_extract.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/object/value_object.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/relationship/relationship_references.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/reporting/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/reporting/meta_dimension.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/reporting/meta_measure.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/reporting/meta_segment.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/reporting/report_accessors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/reporting/report_read_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/reporting/report_shape.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/reporting/reporting_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/requirement/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/requirement/meta_requirement.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/requirement/requirement_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/requirement/resolve_claim.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/validator/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/core/validator/validator_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/meta_data.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/persistence/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/persistence/db/db_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/persistence/db/db_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/persistence/origin/origin_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/persistence/source/meta_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/persistence/source/source_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/presentation/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/provider_extends.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/template/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/template/meta_template.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/template/prompt_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta/template/template_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/meta_endpoint.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/naming.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/naming_refs.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/parser.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/parser_yaml.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/py.typed +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/registry.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/registry_manifest.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/email_document.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/escapers.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/extract/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/extract/coerce.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/extract/extract.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/extract/extract_map.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/extract/locate.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/extract/normalize.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/extract/strip.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/extract/types.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/filesystem_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/payload_accessors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/prompt/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/prompt/prompt_field.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/prompt/prompt_style.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/renderer.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/render/verify.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/requirement_check.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/runtime/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/runtime/dialect.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/runtime/drivers.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/runtime/llm_recorder.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/runtime/n2m_resolver.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/runtime/object_manager.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/runtime/tph.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/runtime/validator_runner.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/scope.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/serializer_json.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/shared/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/shared/base_types.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/shared/separators.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/shared/structural.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/source/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/source/error_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/source/json_path.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/source/semantic_diff.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/source/yaml_positions.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/source_resolution.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/attr.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/db.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/documentation.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/field.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/identity.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/index.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/layout.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/object.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/origin.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/prompt.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/relationship.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/reporting.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/requirement.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/source.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/template.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/ui-web.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/ui.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/validator.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/spec_metamodel/view.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/super_resolve.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/validation_types.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/src/metaobjects/yaml_desugar.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/config_helpers.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/gen_suite.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/golden/extends/expected/BaseEntity.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/golden/extends/expected/Program.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/golden/extends/meta.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/golden/nested-array/expected/PostBrief.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/golden/nested-array/meta.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/golden/scalars/expected/Metric.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/golden/scalars/expected/Report.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/golden/scalars/meta.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/golden/vanilla/expected/Subscriber.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/golden/vanilla/meta.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_abstract_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_api_docs_builder.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_api_docs_paths.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_config_gen.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_config_verify.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_dependencies.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_fmt.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_gen_unknown_attr.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_help_removed_flags.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_providers.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_registry.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_render_helper_template_root.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_staleness_nudge.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_surface.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_verify_field_lint.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_verify_requirements.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_verify_strict.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cli_verify_subverbs.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_codegen_compile_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_collection_name_collision.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_constants_config.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_cross_package_binding_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_docs_generators.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_eject.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_eject_alone.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_eject_independence.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_eject_runtime.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_entity_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_enum_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_extends_abstract_field_inheritance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_extract_tier_collision.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_extractor_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_filter_allowlist_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_fmt_format_file.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_format.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_fr010_nested_object_prompt.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_fr010_output_codegen.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_gen_state_keying.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_generator_extension_seams.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_golden.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_hand_edits.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_inherit_without_restate_gate.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_inheritance_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_instance_artifacts.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_m2m_codegen.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_moved_modules.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_names_extends_chain.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_names_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_no_magic_physical_names.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_one_generator_list.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_origin_nullability.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_orphan_sweep.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_output_parser_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_overwrite_policy.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_overwrite_policy_hash.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_project_config.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_project_import.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_projection_compile.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_projection_docs_routes.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_recipe_generators.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_render_helper_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_render_helper_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_report_router.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_requirement_tests_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_reverse_finders.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_route_path_naming.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_router_autoset.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_runner.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_source_resolution.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_sourceless_entity_surface.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_sourceless_projection.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_template_data.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_template_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_template_output_pattern.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_template_scope_helpers.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_template_scope_walk.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_template_spec.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_trace_helper_generator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_type_map.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_validation_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_value_objects.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/codegen/test_write_through.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/config/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/config/test_dependencies.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/config/test_library_package_guard.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/config/test_neutral_config.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/config/test_neutral_config_unknown_key.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/config/test_source_resolver.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/capabilities.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/conformance-expected-failures.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/conformance_adapter.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/corpus.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/eject_contract.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/expected_failures.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/fixture_discovery.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/navigator.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_conformance_twin_roundtrip.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_dependency_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_eject_contract.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_extract_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_extract_object_array_bounds.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_extract_object_verdict.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_field_lint_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_fmt_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_fr010_loader_attrs.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_fr011_attrs.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_generator_registry_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_naming_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_object_model_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_provider_composition_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_registry_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_requirement_check_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_requirement_test_identity_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_runner_hardfail.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_scope_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_source_resolution_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_spec_metamodel_embed.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_strict_attr_load.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_template_codegen_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_template_generator_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/test_yaml_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/api_contract_assertions.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/api_contract_jsonb_server.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/api_contract_m2m_server.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/api_contract_server.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/conftest.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/engines.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/meta_ai_trace.yaml +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/mysql_container.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/normalization.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/postgres_container.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/query_runner.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/report_lane.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/scenarios.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_api_contract.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_api_contract_decimal.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_api_contract_generated.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_api_contract_jsonb.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_api_contract_m2m.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_api_contract_m2m_generated.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_api_contract_projection.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_api_contract_tph_generated.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_generated_router_uuid_pk.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_llm_call_trace.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_m2m_target_tph_generated.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_normalization.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_query_scenarios.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_runtime_return_types.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_tph_m2m_generated.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/integration/test_tph_m2m_shadowed_generated.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/loader/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/loader/test_abstract_subtype_authored.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/loader/test_child_wrapper_body_shape.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/loader/test_enum_extends_values_conflict.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/loader/test_field_mutability_order.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/loader/test_library_packages.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/loader/test_naming_discovery.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/loader/test_relative_package_multi_root.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/loader/test_shipped_library_ai.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/loader/test_template_payload_target_210.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/open_closed_proof_test.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/extract/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/extract/test_coerce.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/extract/test_extract.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/extract/test_extract_map.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/extract/test_json_forgiving_reader.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/extract/test_locate.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/extract/test_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/extract/test_normalize.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/extract/test_strip.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/prompt/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/prompt/test_output_format_renderer.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/test_email_document.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/test_filesystem_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/test_output_format_renderer_nested.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/test_output_prompt_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/test_render_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/test_render_max_chars.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/test_render_model_payload.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/test_verify.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/render/test_verify_conformance.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/runtime/test_constraint_errors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/runtime/test_literal_naming_sqlite.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/runtime/test_object_manager_currency_read.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/runtime/test_object_manager_dialects.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/runtime/test_object_manager_enum_intvaluemap.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/runtime/test_object_manager_report.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/runtime/test_object_manager_table_name.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/runtime/test_validation_conformance_runtime.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/runtime/test_validator_runner.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/source/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/source/test_fr5c_merge_attribution.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/source/test_fr5d_reference_resolution.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/source/test_fr5e_database_source_shape.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/source/test_json_path.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/source/test_semantic_diff.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/source/test_source_on_node.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/source/test_yaml_positions.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/test_api_docs_accuracy.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/test_api_docs_packages.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/test_meta_endpoint.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/test_report_read_model.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/test_report_shape.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/test_reporting_inert.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/__init__.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_agent_context_staleness.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_capabilities.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_column_naming_strategy.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_common_attrs.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_core_types.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_derive_m2m_declaring_entity.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_effective_children_sibling_shadowing.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_effective_package.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_errors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_field_enum.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_field_enum_intvaluemap.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_field_map_validation.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_file_source_id.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_index_lookup.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_inherited_reference_binding.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_llm_recorder.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_loader.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_loader_bom.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_loader_class.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_merge.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_meta_attr.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_meta_data.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_meta_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_module_shortcuts.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_n2m_resolver.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_n2m_resolver_inherited.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_no_dead_config_fields.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_object_manager_autoset_stamping.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_object_manager_write_through.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_one_primary_source.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_parser.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_parser_yaml.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_provider.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_provider_extension.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_registry.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_registry_completeness.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_registry_extend.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_registry_sealed.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_relationship_m2m_validation.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_relationship_references.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_relationship_referential_actions.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_reporting_accessors.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_reporting_validation_spine_default.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_resolution_key.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_resolve_claim.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_serializer.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_serializer_shared_document.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_shared_constants.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_smoke.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_source_escapes.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_sources.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_strict_child_placement.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_super_resolve.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_template_toolcall.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_validation_attr_schema.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_validation_filter_values.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_validation_origin_195.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_validation_origin_paths.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_validation_sort_field.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_validation_warnings.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/tests/unit/test_write_coercion_arrays.py +0 -0
- {metaobjects-1.1.1 → metaobjects-1.1.3}/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.3
|
|
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.3"
|
|
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.3}/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()) + "}"
|
|
@@ -599,6 +658,12 @@ def _auth_docstring_paragraph(*, read_only: bool) -> str:
|
|
|
599
658
|
)
|
|
600
659
|
|
|
601
660
|
|
|
661
|
+
#: The most rows a report list answers when no cap is configured, the same default in every
|
|
662
|
+
#: port. With no ``limit`` a report answers every row up to the cap and is refused above it,
|
|
663
|
+
#: never truncated.
|
|
664
|
+
DEFAULT_REPORT_MAX_ROWS = 10_000
|
|
665
|
+
|
|
666
|
+
|
|
602
667
|
class RouterGenerator:
|
|
603
668
|
"""One ``<entity_snake>_router.py`` per routed object (FastAPI ``APIRouter``):
|
|
604
669
|
full CRUD for a writable source, read-only for a view-backed one.
|
|
@@ -630,6 +695,13 @@ class RouterGenerator:
|
|
|
630
695
|
|
|
631
696
|
name = "router-generator"
|
|
632
697
|
|
|
698
|
+
def __init__(self, report_max_rows: int = DEFAULT_REPORT_MAX_ROWS) -> None:
|
|
699
|
+
"""*report_max_rows* is the row cap of a served report's list route: with no ``limit``
|
|
700
|
+
the route answers every row up to it, and one more row (or a ``limit`` above it) is
|
|
701
|
+
``400 {"error": "report_too_large", "maxRows": N}``. Reports only; an entity's list
|
|
702
|
+
keeps its paging."""
|
|
703
|
+
self.report_max_rows = report_max_rows
|
|
704
|
+
|
|
633
705
|
def _emit_repository_protocol(
|
|
634
706
|
self, repo_class: str, m2m: list[M2mDescriptor], pk_type: str
|
|
635
707
|
) -> list[str]:
|
|
@@ -699,12 +771,81 @@ class RouterGenerator:
|
|
|
699
771
|
create_autoset: list[str] = (),
|
|
700
772
|
update_autoset: list[str] = (),
|
|
701
773
|
frozen_strip: list[str] = (),
|
|
774
|
+
report_max_rows: int | None = None,
|
|
702
775
|
) -> list[str]:
|
|
703
776
|
"""One CRUD route handler block, dispatched by *name*
|
|
704
777
|
(``list`` / ``get`` / ``create`` / ``update`` / ``delete``). Override to
|
|
705
778
|
change a handler's body / decorators / response shape. *model_name* /
|
|
706
779
|
*patch_model* are the generated create + all-optional PATCH Pydantic models
|
|
707
|
-
used to run field constraints on POST / PATCH (FR-036).
|
|
780
|
+
used to run field constraints on POST / PATCH (FR-036). *report_max_rows* is
|
|
781
|
+
passed only for a served report's ``list``: every row up to that cap, refused above it."""
|
|
782
|
+
if name == "list" and report_max_rows is not None:
|
|
783
|
+
return [
|
|
784
|
+
'@router.get("")',
|
|
785
|
+
f"def list_{plural}(",
|
|
786
|
+
" request: Request,",
|
|
787
|
+
f" repo: Annotated[{repo_class}, Depends(get_repository)],",
|
|
788
|
+
" limit: str | None = Query(None),",
|
|
789
|
+
" offset: str | None = Query(None),",
|
|
790
|
+
" sort: str | None = Query(None),",
|
|
791
|
+
' with_count: int | None = Query(None, alias="withCount"),',
|
|
792
|
+
") -> Any:",
|
|
793
|
+
f" max_rows = {report_max_rows}",
|
|
794
|
+
" too_large = JSONResponse(",
|
|
795
|
+
' status_code=400, content={"error": "report_too_large", "maxRows": max_rows}',
|
|
796
|
+
" )",
|
|
797
|
+
" requested_limit: int | None = None",
|
|
798
|
+
" if limit is not None:",
|
|
799
|
+
" if not (limit.isascii() and limit.isdigit()) or int(limit) < 1:",
|
|
800
|
+
" return JSONResponse(",
|
|
801
|
+
" status_code=400,",
|
|
802
|
+
" content={",
|
|
803
|
+
' "error": "pagination.invalid_value",',
|
|
804
|
+
' "param": "limit",',
|
|
805
|
+
' "value": limit,',
|
|
806
|
+
' "expected": f"an integer from 1 to {max_rows}",',
|
|
807
|
+
" },",
|
|
808
|
+
" )",
|
|
809
|
+
" requested_limit = int(limit)",
|
|
810
|
+
" if requested_limit > max_rows:",
|
|
811
|
+
" return too_large",
|
|
812
|
+
" actual_offset = 0",
|
|
813
|
+
" if offset is not None:",
|
|
814
|
+
" if not (offset.isascii() and offset.isdigit()):",
|
|
815
|
+
" return JSONResponse(",
|
|
816
|
+
" status_code=400,",
|
|
817
|
+
" content={",
|
|
818
|
+
' "error": "pagination.invalid_value",',
|
|
819
|
+
' "param": "offset",',
|
|
820
|
+
' "value": offset,',
|
|
821
|
+
' "expected": "a non-negative integer (0 or more)",',
|
|
822
|
+
" },",
|
|
823
|
+
" )",
|
|
824
|
+
" actual_offset = int(offset)",
|
|
825
|
+
" sort_clause: _SortClause | None = None",
|
|
826
|
+
" if sort is not None:",
|
|
827
|
+
" sort_clause = _parse_sort(sort)",
|
|
828
|
+
" if sort_clause is None:",
|
|
829
|
+
' return JSONResponse(status_code=400, content={"error": "invalid_sort", "field": sort.split(":", 1)[0]})',
|
|
830
|
+
f" filter_result = parse_filter(request.query_params, {fields_const}, {ops_const})",
|
|
831
|
+
" if filter_result.error_envelope is not None:",
|
|
832
|
+
" return JSONResponse(status_code=400, content=filter_result.error_envelope)",
|
|
833
|
+
" predicates, decimal_error = coerce_decimal_predicates(",
|
|
834
|
+
" filter_result.predicates, _DECIMAL_FIELDS",
|
|
835
|
+
" )",
|
|
836
|
+
" if decimal_error is not None:",
|
|
837
|
+
" return JSONResponse(status_code=400, content=decimal_error)",
|
|
838
|
+
" # With no limit the repository is asked for one row past the cap, so the",
|
|
839
|
+
" # refusal comes before any body is written.",
|
|
840
|
+
" fetch_limit = requested_limit if requested_limit is not None else max_rows + 1",
|
|
841
|
+
" rows = repo.list(fetch_limit, actual_offset, sort_clause, predicates)",
|
|
842
|
+
" if requested_limit is None and len(rows) > max_rows:",
|
|
843
|
+
" return too_large",
|
|
844
|
+
" if with_count == 1:",
|
|
845
|
+
" total = repo.count(predicates)",
|
|
846
|
+
' return {"rows": render_wire(rows, _WIRE), "total": total}',
|
|
847
|
+
" return render_wire(rows, _WIRE)",
|
|
848
|
+
]
|
|
708
849
|
if name == "list":
|
|
709
850
|
return [
|
|
710
851
|
'@router.get("")',
|
|
@@ -734,8 +875,8 @@ class RouterGenerator:
|
|
|
734
875
|
" rows = repo.list(actual_limit, actual_offset, sort_clause, predicates)",
|
|
735
876
|
" if with_count == 1:",
|
|
736
877
|
" total = repo.count(predicates)",
|
|
737
|
-
' return {"rows":
|
|
738
|
-
" return
|
|
878
|
+
' return {"rows": render_wire(rows, _WIRE), "total": total}',
|
|
879
|
+
" return render_wire(rows, _WIRE)",
|
|
739
880
|
]
|
|
740
881
|
if name == "get":
|
|
741
882
|
return [
|
|
@@ -747,7 +888,7 @@ class RouterGenerator:
|
|
|
747
888
|
f" row = repo.find_by_id({pk_param})",
|
|
748
889
|
" if row is None:",
|
|
749
890
|
' return JSONResponse(status_code=404, content={"error": "not_found"})',
|
|
750
|
-
" return
|
|
891
|
+
" return render_wire(row, _WIRE)",
|
|
751
892
|
]
|
|
752
893
|
if name == "create":
|
|
753
894
|
return [
|
|
@@ -768,7 +909,7 @@ class RouterGenerator:
|
|
|
768
909
|
# (a fresh row's createdAt == updatedAt), ignoring any caller-supplied value.
|
|
769
910
|
*create_autoset,
|
|
770
911
|
" try:",
|
|
771
|
-
" return
|
|
912
|
+
" return render_wire(repo.create(dto), _WIRE)",
|
|
772
913
|
*_CONSTRAINT_EXCEPT,
|
|
773
914
|
]
|
|
774
915
|
if name == "update":
|
|
@@ -803,7 +944,7 @@ class RouterGenerator:
|
|
|
803
944
|
*_CONSTRAINT_EXCEPT,
|
|
804
945
|
" if saved is None:",
|
|
805
946
|
' return JSONResponse(status_code=404, content={"error": "not_found"})',
|
|
806
|
-
" return
|
|
947
|
+
" return render_wire(saved, _WIRE)",
|
|
807
948
|
]
|
|
808
949
|
if name == "delete":
|
|
809
950
|
return [
|
|
@@ -836,8 +977,9 @@ class RouterGenerator:
|
|
|
836
977
|
f" {pk_param}: {pk_type},",
|
|
837
978
|
f" repo: Annotated[{repo_class}, Depends(get_repository)],",
|
|
838
979
|
") -> list[Any]:",
|
|
839
|
-
f" return
|
|
840
|
-
f"({pk_param}{_target_subtype_arg(d, {d.target_discriminator})})
|
|
980
|
+
f" return render_wire(repo.find_related_{d.relation_name}"
|
|
981
|
+
f"({pk_param}{_target_subtype_arg(d, {d.target_discriminator})}), "
|
|
982
|
+
f"{_m2m_wire_name(d.target_entity)})",
|
|
841
983
|
]
|
|
842
984
|
|
|
843
985
|
def _emit_tph_m2m_route(
|
|
@@ -893,8 +1035,9 @@ class RouterGenerator:
|
|
|
893
1035
|
" return []",
|
|
894
1036
|
]
|
|
895
1037
|
lines.append(
|
|
896
|
-
f" return
|
|
897
|
-
f"({subtype_expr}, {pk_param}{_target_subtype_arg(d, target_discs)})
|
|
1038
|
+
f" return render_wire(repo.find_related_{d.relation_name}"
|
|
1039
|
+
f"({subtype_expr}, {pk_param}{_target_subtype_arg(d, target_discs)}), "
|
|
1040
|
+
f"{_m2m_wire_name(d.target_entity)})"
|
|
898
1041
|
)
|
|
899
1042
|
return lines
|
|
900
1043
|
|
|
@@ -923,8 +1066,8 @@ class RouterGenerator:
|
|
|
923
1066
|
f" rows = {repo_var}.list({subtype_expr}, actual_limit, actual_offset, sort_clause, predicates)",
|
|
924
1067
|
" if with_count == 1:",
|
|
925
1068
|
f" total = {repo_var}.count({subtype_expr}, predicates)",
|
|
926
|
-
' return {"rows":
|
|
927
|
-
" return
|
|
1069
|
+
' return {"rows": render_wire(rows, _WIRE), "total": total}',
|
|
1070
|
+
" return render_wire(rows, _WIRE)",
|
|
928
1071
|
]
|
|
929
1072
|
|
|
930
1073
|
def _render_tph_router(
|
|
@@ -933,6 +1076,7 @@ class RouterGenerator:
|
|
|
933
1076
|
plan: TphPlan,
|
|
934
1077
|
object_index: dict[str, MetaObject],
|
|
935
1078
|
column_naming: str = DEFAULT_COLUMN_NAMING,
|
|
1079
|
+
wire: WireFormat = WireFormat(),
|
|
936
1080
|
) -> str:
|
|
937
1081
|
"""FR-017 TPH: emit the discriminator base's router — a polymorphic collection
|
|
938
1082
|
at the base path + a full per-subtype CRUD set at /<base>/<segment>. The repo
|
|
@@ -1090,7 +1234,8 @@ class RouterGenerator:
|
|
|
1090
1234
|
parts.append(" coerce_decimal_fields,")
|
|
1091
1235
|
parts.append(" coerce_decimal_predicates,")
|
|
1092
1236
|
parts.append(" parse_json_object,")
|
|
1093
|
-
parts.append("
|
|
1237
|
+
parts.append(" WireOutput,")
|
|
1238
|
+
parts.append(" render_wire,")
|
|
1094
1239
|
parts.append(")")
|
|
1095
1240
|
parts.append(f"from {_runtime_module('filter_parser')} import (")
|
|
1096
1241
|
parts.append(" FilterPredicate,")
|
|
@@ -1116,6 +1261,12 @@ class RouterGenerator:
|
|
|
1116
1261
|
parts.append("")
|
|
1117
1262
|
parts.append(f"_DECIMAL_FIELDS: frozenset[str] = {decimal_set_body}")
|
|
1118
1263
|
parts.extend(_decimal_limits_lines([entity, *(st.entity for st in plan.subtypes)]))
|
|
1264
|
+
parts.extend(_wire_lines([entity, *(st.entity for st in plan.subtypes)], wire))
|
|
1265
|
+
parts.extend(_m2m_wire_lines(
|
|
1266
|
+
[*base_m2m, *(d for st in plan.subtypes for d in sub_m2m[st.entity.name])],
|
|
1267
|
+
object_index,
|
|
1268
|
+
wire,
|
|
1269
|
+
))
|
|
1119
1270
|
parts.append("")
|
|
1120
1271
|
parts.append("")
|
|
1121
1272
|
parts.extend(_JSON_BODY_LINES)
|
|
@@ -1207,7 +1358,7 @@ class RouterGenerator:
|
|
|
1207
1358
|
# non-@autoSet hierarchy — byte-identical output).
|
|
1208
1359
|
parts.extend(create_autoset)
|
|
1209
1360
|
parts.append(" try:")
|
|
1210
|
-
parts.append(f' return
|
|
1361
|
+
parts.append(f' return render_wire(repo.create("{val}", dto), _WIRE)')
|
|
1211
1362
|
parts.extend(_CONSTRAINT_EXCEPT)
|
|
1212
1363
|
parts.append("")
|
|
1213
1364
|
parts.append("")
|
|
@@ -1219,7 +1370,7 @@ class RouterGenerator:
|
|
|
1219
1370
|
parts.append(f' row = repo.find_by_id("{val}", {pk_param})')
|
|
1220
1371
|
parts.append(" if row is None:")
|
|
1221
1372
|
parts.append(' return JSONResponse(status_code=404, content={"error": "not_found"})')
|
|
1222
|
-
parts.append(" return
|
|
1373
|
+
parts.append(" return render_wire(row, _WIRE)")
|
|
1223
1374
|
parts.append("")
|
|
1224
1375
|
parts.append("")
|
|
1225
1376
|
parts.append(f'@router.patch("/{seg}/{{{pk_param}}}")')
|
|
@@ -1248,7 +1399,7 @@ class RouterGenerator:
|
|
|
1248
1399
|
parts.extend(_CONSTRAINT_EXCEPT)
|
|
1249
1400
|
parts.append(" if saved is None:")
|
|
1250
1401
|
parts.append(' return JSONResponse(status_code=404, content={"error": "not_found"})')
|
|
1251
|
-
parts.append(" return
|
|
1402
|
+
parts.append(" return render_wire(saved, _WIRE)")
|
|
1252
1403
|
parts.append("")
|
|
1253
1404
|
parts.append("")
|
|
1254
1405
|
parts.append(f'@router.delete("/{seg}/{{{pk_param}}}", status_code=status.HTTP_204_NO_CONTENT)')
|
|
@@ -1298,7 +1449,7 @@ class RouterGenerator:
|
|
|
1298
1449
|
parts.append(f" row = repo.find_by_id(None, {pk_param})")
|
|
1299
1450
|
parts.append(" if row is None:")
|
|
1300
1451
|
parts.append(' return JSONResponse(status_code=404, content={"error": "not_found"})')
|
|
1301
|
-
parts.append(" return
|
|
1452
|
+
parts.append(" return render_wire(row, _WIRE)")
|
|
1302
1453
|
parts.append("")
|
|
1303
1454
|
|
|
1304
1455
|
# FW-8 rule (a): every relationship the BASE resolves — every row of the
|
|
@@ -1326,6 +1477,7 @@ class RouterGenerator:
|
|
|
1326
1477
|
entity: MetaObject,
|
|
1327
1478
|
object_index: dict[str, MetaObject] | None = None,
|
|
1328
1479
|
column_naming: str = DEFAULT_COLUMN_NAMING,
|
|
1480
|
+
wire: WireFormat | None = None,
|
|
1329
1481
|
) -> str | None:
|
|
1330
1482
|
"""Render an entity as a FastAPI ``APIRouter`` module.
|
|
1331
1483
|
|
|
@@ -1342,6 +1494,8 @@ class RouterGenerator:
|
|
|
1342
1494
|
source URL segment is the ENTITY name pluralized (cross-port grammar), NOT
|
|
1343
1495
|
the physical ``@table``. Without an index, only CRUD is emitted (back-compat).
|
|
1344
1496
|
|
|
1497
|
+
*wire* is the run's ``wire`` setting; omitted, it is read from the loaded root.
|
|
1498
|
+
|
|
1345
1499
|
*column_naming* is ``GenConfig.column_naming`` for this run — passed through
|
|
1346
1500
|
to :func:`resolve_m2m_descriptors` so the M:N descriptor's physical junction
|
|
1347
1501
|
columns are resolved by the SAME strategy the ``names`` generator applies to
|
|
@@ -1353,6 +1507,9 @@ class RouterGenerator:
|
|
|
1353
1507
|
"""
|
|
1354
1508
|
if not emits_router(entity):
|
|
1355
1509
|
return None
|
|
1510
|
+
# ADR-0019 Amendment 2: the project's `wire` setting, from the loaded root. A caller
|
|
1511
|
+
# that holds an object detached from the root (a report's read model) passes it.
|
|
1512
|
+
wire = wire if wire is not None else wire_of(entity)
|
|
1356
1513
|
# FR-017 TPH: a concrete subtype is folded into its base's single table — it
|
|
1357
1514
|
# emits no standalone router (its CRUD lives under the base's per-subtype segment).
|
|
1358
1515
|
if object_index is not None and is_tph_subtype(entity):
|
|
@@ -1371,7 +1528,7 @@ class RouterGenerator:
|
|
|
1371
1528
|
# answering the cross-port 405 envelope. Gated by
|
|
1372
1529
|
# fixtures/api-contract-conformance/projection/.
|
|
1373
1530
|
if is_read_only_routed(entity):
|
|
1374
|
-
return self._render_readonly_router(entity, column_naming)
|
|
1531
|
+
return self._render_readonly_router(entity, column_naming, wire)
|
|
1375
1532
|
return None
|
|
1376
1533
|
|
|
1377
1534
|
# FR-017 TPH: a discriminator base emits a polymorphic collection at the base
|
|
@@ -1379,7 +1536,7 @@ class RouterGenerator:
|
|
|
1379
1536
|
if object_index is not None:
|
|
1380
1537
|
plan = tph_plan_for(entity, object_index)
|
|
1381
1538
|
if plan is not None:
|
|
1382
|
-
return self._render_tph_router(entity, plan, object_index, column_naming)
|
|
1539
|
+
return self._render_tph_router(entity, plan, object_index, column_naming, wire)
|
|
1383
1540
|
|
|
1384
1541
|
m2m: list[M2mDescriptor] = (
|
|
1385
1542
|
resolve_m2m_descriptors(entity, object_index, column_naming)
|
|
@@ -1458,7 +1615,8 @@ class RouterGenerator:
|
|
|
1458
1615
|
parts.append(" coerce_decimal_fields,")
|
|
1459
1616
|
parts.append(" coerce_decimal_predicates,")
|
|
1460
1617
|
parts.append(" parse_json_object,")
|
|
1461
|
-
parts.append("
|
|
1618
|
+
parts.append(" WireOutput,")
|
|
1619
|
+
parts.append(" render_wire,")
|
|
1462
1620
|
parts.append(")")
|
|
1463
1621
|
parts.append(f"from {_runtime_module('filter_parser')} import (")
|
|
1464
1622
|
parts.append(" FilterPredicate,")
|
|
@@ -1485,6 +1643,8 @@ class RouterGenerator:
|
|
|
1485
1643
|
parts.append("")
|
|
1486
1644
|
parts.append(f"_DECIMAL_FIELDS: frozenset[str] = {decimal_set_body}")
|
|
1487
1645
|
parts.extend(_decimal_limits_lines([entity]))
|
|
1646
|
+
parts.extend(_wire_lines([entity], wire))
|
|
1647
|
+
parts.extend(_m2m_wire_lines(m2m, object_index or {}, wire))
|
|
1488
1648
|
parts.append("")
|
|
1489
1649
|
parts.append("")
|
|
1490
1650
|
parts.extend(_JSON_BODY_LINES)
|
|
@@ -1599,6 +1759,7 @@ class RouterGenerator:
|
|
|
1599
1759
|
self,
|
|
1600
1760
|
entity: MetaObject,
|
|
1601
1761
|
column_naming: str = DEFAULT_COLUMN_NAMING,
|
|
1762
|
+
wire: WireFormat = WireFormat(),
|
|
1602
1763
|
) -> str:
|
|
1603
1764
|
"""Render a read-only (`@kind: view` / `materializedView`) object as a FastAPI
|
|
1604
1765
|
``APIRouter``: GET list + GET by id, and the four write verbs answering 405. An
|
|
@@ -1663,7 +1824,8 @@ class RouterGenerator:
|
|
|
1663
1824
|
parts.append("")
|
|
1664
1825
|
parts.append(f"from {_runtime_module('decimal_wire')} import (")
|
|
1665
1826
|
parts.append(" coerce_decimal_predicates,")
|
|
1666
|
-
parts.append("
|
|
1827
|
+
parts.append(" WireOutput,")
|
|
1828
|
+
parts.append(" render_wire,")
|
|
1667
1829
|
parts.append(")")
|
|
1668
1830
|
parts.append(f"from {_runtime_module('filter_parser')} import (")
|
|
1669
1831
|
parts.append(" FilterPredicate,")
|
|
@@ -1682,6 +1844,7 @@ class RouterGenerator:
|
|
|
1682
1844
|
"_DECIMAL_FIELDS: frozenset[str] = "
|
|
1683
1845
|
+ _py_set_literal(_decimal_field_names([entity]), frozen=True)
|
|
1684
1846
|
)
|
|
1847
|
+
parts.extend(_wire_lines([entity], wire))
|
|
1685
1848
|
parts.append("")
|
|
1686
1849
|
parts.append("")
|
|
1687
1850
|
parts.extend(_sort_parse_fn_lines())
|
|
@@ -1722,6 +1885,9 @@ class RouterGenerator:
|
|
|
1722
1885
|
# handlers do not read these; they are required by the shared signature.
|
|
1723
1886
|
model_name="",
|
|
1724
1887
|
patch_model="",
|
|
1888
|
+
# Only a report is capped; passed for it alone so an adopter's `_emit_route_handler`
|
|
1889
|
+
# override that does not take the keyword keeps working for a projection.
|
|
1890
|
+
**({"report_max_rows": self.report_max_rows} if is_report else {}),
|
|
1725
1891
|
)
|
|
1726
1892
|
for i, hname in enumerate(("list", "get") if item_route else ("list",)):
|
|
1727
1893
|
if i > 0:
|
|
@@ -1746,7 +1912,8 @@ class RouterGenerator:
|
|
|
1746
1912
|
# reads (`c.config.column_naming`) — so the M:N descriptor built here
|
|
1747
1913
|
# and the per-field constants built there can't disagree about a
|
|
1748
1914
|
# column name within one run.
|
|
1749
|
-
|
|
1915
|
+
wire = wire_of(c.loaded_root) if c.loaded_root is not None else None
|
|
1916
|
+
source = self.render_router(entity, index, c.config.column_naming, wire)
|
|
1750
1917
|
if source is None:
|
|
1751
1918
|
return []
|
|
1752
1919
|
snake = _snake_case(entity.name)
|
|
@@ -1774,11 +1941,12 @@ def render_router(
|
|
|
1774
1941
|
return RouterGenerator().render_router(entity, object_index, column_naming)
|
|
1775
1942
|
|
|
1776
1943
|
|
|
1777
|
-
def router_generator() -> Generator:
|
|
1944
|
+
def router_generator(report_max_rows: int = DEFAULT_REPORT_MAX_ROWS) -> Generator:
|
|
1778
1945
|
"""Generator factory: one ``<entity_snake>_router.py`` per routed object —
|
|
1779
|
-
full CRUD for a writable source, read-only for a view-backed one.
|
|
1946
|
+
full CRUD for a writable source, read-only for a view-backed one. *report_max_rows*
|
|
1947
|
+
is the row cap of a served report's list route (default 10000).
|
|
1780
1948
|
|
|
1781
1949
|
Returns a :class:`RouterGenerator` (subclassable extension seam). Skips objects
|
|
1782
1950
|
without a ``source.rdb`` child and the non-collection read-only kinds
|
|
1783
1951
|
(storedProc / tableFunction)."""
|
|
1784
|
-
return RouterGenerator()
|
|
1952
|
+
return RouterGenerator(report_max_rows)
|
|
@@ -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
|