metaobjects 1.2.0__tar.gz → 1.2.1__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.2.0 → metaobjects-1.2.1}/PKG-INFO +1 -1
- {metaobjects-1.2.0 → metaobjects-1.2.1}/pyproject.toml +1 -1
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/KNOWN_GAPS.md +3 -3
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/router_generator.py +70 -28
- metaobjects-1.2.1/tests/integration/test_generated_router_validated_input.py +272 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/uv.lock +1 -1
- {metaobjects-1.2.0 → metaobjects-1.2.1}/.gitignore +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/LICENSE +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/README.md +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/hatch_build.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/scripts/generate_embedded_library.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/agent_context/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/agent_context/scaffold.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/apidocs/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/apidocs/api_model.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/apidocs/builder.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/apidocs/naming.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/apidocs/paths.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/apidocs/renderer.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/attr_class_map.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/cli.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/_moved.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/collection_name_collision.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/collision_names.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/config.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/eject.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/extract_delegate_emitter.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/extract_schema_emitter.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/format.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/fr010_field_mapping.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generator_registry.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/api_docs_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/entity_model.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/extractor_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/find_inbound.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/fr019_shared_enum.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/m2m_codegen.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/names_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/output_parser_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/output_prompt_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/render_helper_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/report_export_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/requirement_tests_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/template_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/trace_helper_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/instance_artifacts.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/metaobjects-config.schema.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/model_walk.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/orphan_sweep.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/output_format_spec_emitter.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/overwrite_policy.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/project_config.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/project_import.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/requirement_hooks.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/requirement_walk.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runner.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/api_docs_builder.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/api_docs_model.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/api_docs_paths.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/api_docs_renderer.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/constraint_errors.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/decimal_wire.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/extract_delegate_emitter.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/extract_schema_emitter.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/fr010_field_mapping.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/fr019_shared_enum.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/m2m_codegen.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/output_format_spec_emitter.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/report_export.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/shared_predicates.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/template_codegen/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/template_codegen/output_pattern.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/template_codegen/template_data.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/template_codegen/template_spec.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/type_map.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/value_objects.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/config/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/config/dependencies.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/config/neutral_config.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/config/source_resolver.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/core_types.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/datatype.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/documentation/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/documentation/doc_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/documentation/doc_provider.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/documentation/doc_schema.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/errors.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/field_lint.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/fmt.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/library/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/library/embedded_library.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/library/library_sources.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/merge.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/meta_data_loader.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/registered_validation.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/resolve_references.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/sources/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/sources/directory_source.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/sources/file_source.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/sources/uri_source.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_discriminator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_enum_normalize_ambiguity.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_field_mutability.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_reporting.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_source_escapes.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_source_parameter_ref.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validation_passes.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/attr/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/attr/attr_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/attr/meta_attr.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/field/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/field/credential.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/field/field_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/field/meta_field.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/identity/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/index/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/index/index_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/index/meta_index.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/meta_object.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/object_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/object_extract.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/value_object.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/relationship/relationship_references.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/meta_dimension.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/meta_measure.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/meta_segment.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/report_accessors.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/report_read_model.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/report_shape.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/reporting_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/requirement/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/requirement/meta_requirement.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/requirement/requirement_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/requirement/resolve_claim.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/validator/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/validator/validator_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/meta_data.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/meta_root.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/db/db_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/db/db_provider.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/origin/origin_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/source/meta_source.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/source/source_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/provider_extends.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/template/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/template/meta_template.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/template/prompt_provider.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/template/template_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta_endpoint.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/naming.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/naming_refs.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/parser.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/parser_yaml.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/provider.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/py.typed +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/registry.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/registry_manifest.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/email_document.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/engine.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/escapers.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/coerce.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/extract.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/extract_map.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/locate.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/normalize.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/strip.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/types.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/filesystem_provider.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/jinja_render.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/jinja_verify.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/mustache_tags.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/payload_accessors.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/prompt/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/prompt/prompt_field.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/prompt/prompt_style.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/renderer.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/verify.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/requirement_check.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/dialect.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/drivers.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/llm_recorder.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/n2m_resolver.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/object_manager.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/tph.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/validator_runner.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/scope.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/serializer_json.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/shared/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/shared/base_types.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/shared/separators.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/shared/structural.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source/error_source.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source/json_path.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source/semantic_diff.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source/yaml_core_schema.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source/yaml_positions.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source_resolution.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/attr.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/db.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/documentation.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/field.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/identity.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/index.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/layout.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/object.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/origin.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/prompt.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/relationship.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/reporting.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/requirement.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/source.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/template.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/ui-web.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/ui.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/validator.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/view.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/super_resolve.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/validation_types.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/wire.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/yaml_desugar.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/config_helpers.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/gen_suite.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/extends/expected/BaseEntity.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/extends/expected/Program.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/extends/meta.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/nested-array/expected/PostBrief.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/nested-array/meta.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/scalars/expected/Metric.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/scalars/expected/Report.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/scalars/meta.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/vanilla/expected/Subscriber.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/vanilla/meta.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_abstract_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_api_docs_builder.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_api_docs_paths.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_config_gen.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_config_verify.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_dependencies.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_fmt.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_gen_unknown_attr.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_help_removed_flags.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_init.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_providers.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_registry.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_render_helper_template_root.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_staleness_nudge.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_surface.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_verify_field_lint.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_verify_requirements.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_verify_strict.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_verify_subverbs.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_codegen_compile_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_collection_name_collision.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_config_run_settings.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_constants_config.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cross_package_binding_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_docs_generators.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_eject.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_eject_alone.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_eject_independence.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_eject_runtime.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_eject_undo.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_entity_model.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_enum_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_extends_abstract_field_inheritance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_extract_tier_collision.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_extractor_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_filter_allowlist_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_fmt_format_file.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_format.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_fr010_nested_object_prompt.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_fr010_output_codegen.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_gen_state_keying.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_generator_extension_seams.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_golden.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_hand_edits.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_inherit_without_restate_gate.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_inheritance_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_instance_artifacts.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_m2m_codegen.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_moved_modules.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_names_extends_chain.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_names_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_no_magic_physical_names.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_one_generator_list.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_origin_nullability.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_orphan_sweep.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_output_parser_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_overwrite_policy.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_overwrite_policy_hash.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_pattern_ascii.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_project_config.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_project_import.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_projection_compile.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_projection_docs_routes.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_recipe_generators.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_render_helper_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_render_helper_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_report_credential.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_report_export.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_report_router.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_requirement_tests_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_reverse_finders.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_route_path_naming.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_autoset.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_generator_m2m_target_tph.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_generator_tph_m2m.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_generator_tph_m2m_shadowed.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_mypy_strict.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_secret_fields.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_runner.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_source_resolution.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_sourceless_entity_surface.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_sourceless_projection.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_template_data.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_template_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_template_output_pattern.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_template_scope_helpers.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_template_scope_walk.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_template_spec.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_tph_codegen.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_trace_helper_generator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_type_map.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_validation_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_value_objects.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_write_through.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/config/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/config/test_dependencies.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/config/test_library_package_guard.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/config/test_neutral_config.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/config/test_neutral_config_unknown_key.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/config/test_source_resolver.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/capabilities.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/conformance-expected-failures.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/conformance_adapter.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/corpus.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/eject_contract.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/expected_failures.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/fixture_discovery.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/navigator.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_conformance_twin_roundtrip.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_dependency_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_eject_contract.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_extract_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_extract_object_array_bounds.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_extract_object_verdict.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_field_lint_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_fmt_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_fr010_loader_attrs.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_fr011_attrs.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_generator_registry_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_naming_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_object_model_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_provider_composition_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_registry_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_requirement_check_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_requirement_test_identity_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_runner_hardfail.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_scope_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_shared_model_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_source_resolution_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_spec_metamodel_embed.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_strict_attr_load.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_template_codegen_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_template_generator_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_wire_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_yaml_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/api_contract_assertions.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/api_contract_jsonb_server.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/api_contract_m2m_server.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/api_contract_server.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/conftest.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/corpus_config.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/engines.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_jsonb_app.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_m2m_app.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_projection_app.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_report_app.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_router_app.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_secret_fields_app.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_tph_app.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/meta_ai_trace.yaml +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/mysql_container.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/normalization.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/postgres_container.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/query_runner.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/report_lane.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/scenarios.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_decimal.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_generated.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_jsonb.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_m2m.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_m2m_generated.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_projection.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_report.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_secret_fields.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_tph_generated.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_generated_decimal_wire.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_generated_router_uuid_pk.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_llm_call_trace.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_m2m_target_tph_generated.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_normalization.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_query_scenarios.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_runtime_return_types.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_tph_m2m_generated.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_tph_m2m_shadowed_generated.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_abstract_subtype_authored.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_child_wrapper_body_shape.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_enum_extends_values_conflict.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_field_mutability_order.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_library_packages.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_naming_discovery.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_relative_package_multi_root.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_shipped_library_ai.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_template_payload_target_210.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/open_closed_proof_test.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_coerce.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_extract.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_extract_map.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_json_forgiving_reader.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_locate.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_model.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_normalize.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_strip.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/prompt/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/prompt/test_output_format_renderer.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_email_document.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_filesystem_provider.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_jinja_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_jinja_engine.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_output_format_renderer_nested.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_output_prompt_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_render_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_render_max_chars.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_render_model_payload.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_verify.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_verify_conformance.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_constraint_errors.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_decimal_wire.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_literal_naming_sqlite.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_object_manager_currency_read.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_object_manager_dialects.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_object_manager_enum_intvaluemap.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_object_manager_report.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_object_manager_table_name.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_validation_conformance_runtime.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_validator_runner.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_fr5c_merge_attribution.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_fr5d_reference_resolution.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_fr5e_database_source_shape.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_json_path.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_semantic_diff.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_source_on_node.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_yaml_core_schema.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_yaml_positions.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/test_api_docs_accuracy.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/test_api_docs_packages.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/test_meta_endpoint.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/test_report_read_model.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/test_report_shape.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/test_reporting_inert.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/__init__.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_agent_context_staleness.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_capabilities.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_column_naming_strategy.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_common_attrs.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_core_types.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_derive_m2m_declaring_entity.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_effective_children_sibling_shadowing.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_effective_package.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_errors.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_field_enum.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_field_enum_intvaluemap.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_field_map_validation.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_file_source_id.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_index_lookup.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_inherited_reference_binding.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_llm_recorder.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_loader.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_loader_bom.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_loader_class.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_merge.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_meta_attr.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_meta_data.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_meta_source.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_module_shortcuts.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_n2m_resolver.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_n2m_resolver_inherited.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_no_dead_config_fields.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_object_manager_autoset_stamping.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_object_manager_write_through.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_one_primary_source.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_parser.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_parser_yaml.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_provider.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_provider_extension.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_registry.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_registry_completeness.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_registry_extend.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_registry_sealed.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_relationship_m2m_validation.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_relationship_references.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_relationship_referential_actions.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_relative_set_newlines.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_reporting_accessors.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_reporting_validation_spine_default.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_resolution_key.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_resolve_claim.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_serializer.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_serializer_shared_document.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_shared_constants.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_smoke.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_source_escapes.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_sources.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_strict_child_placement.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_super_resolve.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_template_toolcall.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_validation_attr_schema.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_validation_filter_values.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_validation_origin_195.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_validation_origin_paths.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_validation_sort_field.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_validation_warnings.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_write_coercion_arrays.py +0 -0
- {metaobjects-1.2.0 → metaobjects-1.2.1}/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.2.
|
|
3
|
+
Version: 1.2.1
|
|
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.2.
|
|
3
|
+
version = "1.2.1"
|
|
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"
|
|
@@ -36,9 +36,9 @@ The generated router takes `dto: dict[str, Any]` for `POST` / `PATCH` /
|
|
|
36
36
|
(`from .<Entity> import <Entity>, <Entity>Patch`) and constructs them to enforce
|
|
37
37
|
field constraints over HTTP — POST validates `<Entity>(**dto)`, PATCH validates
|
|
38
38
|
the all-optional `<Entity>Patch(**dto)` (present values only) → `400 {"error":"validation"}`.
|
|
39
|
-
The repository seam
|
|
40
|
-
present-key tristate + wire values), so the strong-typing
|
|
41
|
-
remains for the repo/response types
|
|
39
|
+
The repository seam receives only the keys the input model validated, as a `dict`
|
|
40
|
+
(the FR-035 present-key tristate + wire values are kept), so the strong-typing
|
|
41
|
+
simplification below remains for the repo/response types.
|
|
42
42
|
|
|
43
43
|
This keeps the router module decoupled from sibling generated files
|
|
44
44
|
(the entity-model generator emits one `@dataclass`/Pydantic model per
|
{metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/router_generator.py
RENAMED
|
@@ -434,10 +434,9 @@ def _frozen_names(entity: MetaObject) -> list[str]:
|
|
|
434
434
|
|
|
435
435
|
ADR-0045: the OUTERMOST generated write artifact enforces the mode, and for
|
|
436
436
|
FastAPI that is the ROUTER, not the ``<Entity>Patch`` model — the handler binds
|
|
437
|
-
``dto``
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
field has no server value to overwrite, so it must be popped explicitly."""
|
|
437
|
+
``dto`` as a dict. Since 1.2.1 the router hands the repository only the keys the
|
|
438
|
+
patch model validated (:func:`_validated_input_lines`), which already drops these;
|
|
439
|
+
the explicit pop stays as the FR-037 seam an owned router edits."""
|
|
441
440
|
return [
|
|
442
441
|
f.name
|
|
443
442
|
for f in entity.fields()
|
|
@@ -461,6 +460,49 @@ def _frozen_strip_lines(entity: MetaObject, indent: str = " ") -> list[str]:
|
|
|
461
460
|
]
|
|
462
461
|
|
|
463
462
|
|
|
463
|
+
#: 1.2.1 security fix. The request body cut down to what the input model validated, emitted
|
|
464
|
+
#: once per writable router. 1.2.0 validated the body and then handed the RAW body to the
|
|
465
|
+
#: repository, so a client-sent server-generated id, a ``readOnly`` field or a name the entity
|
|
466
|
+
#: does not declare (an ``isAdmin``) reached the write. Pydantic ignores a key a model does not
|
|
467
|
+
#: declare, and the input models leave out every field a client may not set, so keeping only
|
|
468
|
+
#: the keys the model validated (at every depth: a nested value object included) drops all of
|
|
469
|
+
#: them silently, as the TypeScript routes do. The values stay the body's own (decimal-exact)
|
|
470
|
+
#: values, so a repository receives the same value types as in 1.2.0.
|
|
471
|
+
_VALIDATED_INPUT_LINES: list[str] = [
|
|
472
|
+
"def _validated_input(valid: BaseModel, raw: dict[str, Any]) -> dict[str, Any]:",
|
|
473
|
+
' """GENERATED — *raw* cut down to the keys *valid* validated, at every depth. A key the',
|
|
474
|
+
" input model does not declare (an undeclared name, a server-generated id, a readOnly field)",
|
|
475
|
+
' is dropped silently and never reaches the repository; values stay the body\'s own."""',
|
|
476
|
+
" return {_k: _validated_value(getattr(valid, _k), raw[_k]) for _k in valid.model_fields_set}",
|
|
477
|
+
"",
|
|
478
|
+
"",
|
|
479
|
+
"def _validated_value(valid: Any, raw: Any) -> Any:",
|
|
480
|
+
" if isinstance(valid, BaseModel) and isinstance(raw, dict):",
|
|
481
|
+
" return _validated_input(valid, raw)",
|
|
482
|
+
" if isinstance(valid, list) and isinstance(raw, list):",
|
|
483
|
+
" return [_validated_value(v, r) for v, r in zip(valid, raw)]",
|
|
484
|
+
" if isinstance(valid, dict) and isinstance(raw, dict):",
|
|
485
|
+
" return {k: _validated_value(v, raw[k]) for k, v in valid.items() if k in raw}",
|
|
486
|
+
" return raw",
|
|
487
|
+
]
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
def _validated_input_lines(model: str, *comment: str) -> list[str]:
|
|
491
|
+
"""Validate ``dto`` against the input *model*, then rebind it to what the model validated
|
|
492
|
+
(see :data:`_VALIDATED_INPUT_LINES`): the repository never sees any other key."""
|
|
493
|
+
return [
|
|
494
|
+
*(f" # {line}" for line in comment),
|
|
495
|
+
" try:",
|
|
496
|
+
f" _valid = {model}(**dto)",
|
|
497
|
+
" except ValidationError:",
|
|
498
|
+
' return JSONResponse(status_code=400, content={"error": "validation"})',
|
|
499
|
+
" # SECURITY (1.2.1): only what the input model validated reaches the repository. A key",
|
|
500
|
+
" # it does not declare (an undeclared name, a server-generated id, a readOnly or derived",
|
|
501
|
+
" # field, a frozen one on update) is dropped silently, never 400'd.",
|
|
502
|
+
" dto = _validated_input(_valid, dto)",
|
|
503
|
+
]
|
|
504
|
+
|
|
505
|
+
|
|
464
506
|
def _auto_set_split(entity: MetaObject) -> tuple[list[MetaField], list[MetaField]]:
|
|
465
507
|
"""The entity's ``@autoSet`` temporal fields split into ``(onCreate, onUpdate)``.
|
|
466
508
|
|
|
@@ -1083,12 +1125,11 @@ class RouterGenerator:
|
|
|
1083
1125
|
") -> Any:",
|
|
1084
1126
|
*_DECIMAL_COERCE,
|
|
1085
1127
|
*denied_strip,
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
' return JSONResponse(status_code=400, content={"error": "validation"})',
|
|
1128
|
+
*_validated_input_lines(
|
|
1129
|
+
model_name,
|
|
1130
|
+
"FR-036: run the generated field constraints (length / pattern /",
|
|
1131
|
+
"numeric bounds) before persisting; a violation is the cross-port 400.",
|
|
1132
|
+
),
|
|
1092
1133
|
# #203/ADR-0045: the generated router (the API surface) stamps @autoSet columns
|
|
1093
1134
|
# ABOVE the consumer repo seam — onCreate + onUpdate both stamped from one instant
|
|
1094
1135
|
# (a fresh row's createdAt == updatedAt), ignoring any caller-supplied value.
|
|
@@ -1114,12 +1155,11 @@ class RouterGenerator:
|
|
|
1114
1155
|
" for _k in _REQUIRED_FIELDS:",
|
|
1115
1156
|
" if _k in dto and dto[_k] is None:",
|
|
1116
1157
|
' return JSONResponse(status_code=400, content={"error": "validation"})',
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
' return JSONResponse(status_code=400, content={"error": "validation"})',
|
|
1158
|
+
*_validated_input_lines(
|
|
1159
|
+
patch_model,
|
|
1160
|
+
"FR-036: validate PRESENT, non-null values with the create rules (the",
|
|
1161
|
+
"all-optional patch model never fires required-checks on ABSENT fields).",
|
|
1162
|
+
),
|
|
1123
1163
|
# #203/ADR-0045: bump onUpdate @autoSet columns (server-owned) on EVERY patch,
|
|
1124
1164
|
# above the repo seam — a server-inserted present key (compatible with the PATCH
|
|
1125
1165
|
# present-key tristate); onCreate columns are never touched here.
|
|
@@ -1468,6 +1508,9 @@ class RouterGenerator:
|
|
|
1468
1508
|
parts.extend(_JSON_BODY_LINES)
|
|
1469
1509
|
parts.append("")
|
|
1470
1510
|
parts.append("")
|
|
1511
|
+
parts.extend(_VALIDATED_INPUT_LINES)
|
|
1512
|
+
parts.append("")
|
|
1513
|
+
parts.append("")
|
|
1471
1514
|
# FR-037 R1 — the names a PATCH must never write. Emitted even when EMPTY so
|
|
1472
1515
|
# the generated module always carries the seam (an entity that later gains a
|
|
1473
1516
|
# writeOnce field changes one literal, not the module's shape).
|
|
@@ -1547,11 +1590,9 @@ class RouterGenerator:
|
|
|
1547
1590
|
parts.append(") -> Any:")
|
|
1548
1591
|
parts.extend(_DECIMAL_COERCE)
|
|
1549
1592
|
parts.extend(denied_strip_tph)
|
|
1550
|
-
parts.
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
parts.append(" except ValidationError:")
|
|
1554
|
-
parts.append(' return JSONResponse(status_code=400, content={"error": "validation"})')
|
|
1593
|
+
parts.extend(_validated_input_lines(
|
|
1594
|
+
f"{sub}Create", "FR-036: run the subtype's field constraints before persisting."
|
|
1595
|
+
))
|
|
1555
1596
|
# #203/ADR-0045: stamp @autoSet columns ABOVE the repo seam (empty for a
|
|
1556
1597
|
# non-@autoSet hierarchy — byte-identical output).
|
|
1557
1598
|
parts.extend(create_autoset)
|
|
@@ -1584,11 +1625,9 @@ class RouterGenerator:
|
|
|
1584
1625
|
parts.append(" for _k in _REQUIRED_FIELDS:")
|
|
1585
1626
|
parts.append(" if _k in dto and dto[_k] is None:")
|
|
1586
1627
|
parts.append(' return JSONResponse(status_code=400, content={"error": "validation"})')
|
|
1587
|
-
parts.
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
parts.append(" except ValidationError:")
|
|
1591
|
-
parts.append(' return JSONResponse(status_code=400, content={"error": "validation"})')
|
|
1628
|
+
parts.extend(_validated_input_lines(
|
|
1629
|
+
f"{sub}Patch", "FR-036: validate PRESENT, non-null values with the subtype's create rules."
|
|
1630
|
+
))
|
|
1592
1631
|
# #203/ADR-0045: pop the write-once onCreate column(s), bump onUpdate — ABOVE
|
|
1593
1632
|
# the repo seam (empty for a non-@autoSet hierarchy — byte-identical output).
|
|
1594
1633
|
parts.extend(update_autoset)
|
|
@@ -1857,6 +1896,9 @@ class RouterGenerator:
|
|
|
1857
1896
|
parts.extend(_JSON_BODY_LINES)
|
|
1858
1897
|
parts.append("")
|
|
1859
1898
|
parts.append("")
|
|
1899
|
+
parts.extend(_VALIDATED_INPUT_LINES)
|
|
1900
|
+
parts.append("")
|
|
1901
|
+
parts.append("")
|
|
1860
1902
|
# FR-037 R1 — the names a PATCH must never write. Emitted even when EMPTY so
|
|
1861
1903
|
# the generated module always carries the seam (an entity that later gains a
|
|
1862
1904
|
# writeOnce field changes one literal, not the module's shape).
|
|
@@ -1892,8 +1934,8 @@ class RouterGenerator:
|
|
|
1892
1934
|
create_autoset=create_autoset,
|
|
1893
1935
|
update_autoset=update_autoset,
|
|
1894
1936
|
# FR-037 R1 — ADR-0045: the ROUTER is the outermost write artifact for
|
|
1895
|
-
# FastAPI (the handler binds the
|
|
1896
|
-
#
|
|
1937
|
+
# FastAPI (the handler binds the body as a dict), so the strip lives here,
|
|
1938
|
+
# not in <Entity>Patch.
|
|
1897
1939
|
frozen_strip=_frozen_strip_lines(entity),
|
|
1898
1940
|
denied_strip=_denied_strip_lines(denied_names),
|
|
1899
1941
|
)
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"""1.2.1 security fix: a generated create / update hands the repository ONLY the validated input.
|
|
2
|
+
|
|
3
|
+
The 1.2.0 router validated the request body against ``<Entity>Create`` / ``<Entity>Patch`` and
|
|
4
|
+
then passed the RAW body to the repository. Pydantic ignores a key a model does not declare, and
|
|
5
|
+
the input models leave out the server-owned fields, so a client-sent ``id``, a ``readOnly`` field
|
|
6
|
+
and a made-up ``isAdmin`` all reached the write. Now the repository receives only what the input
|
|
7
|
+
model validated, at every depth, as with the TypeScript routes: a name the entity does not
|
|
8
|
+
declare, a server-generated id, a ``readOnly`` field and the id on update are all dropped
|
|
9
|
+
silently. None of them is a 400: a client that sends an extra harmless field keeps working.
|
|
10
|
+
|
|
11
|
+
The model is generated with the real Python codegen (``run_gen``: entity + filter-allowlist +
|
|
12
|
+
routes), the emitted package is imported unmodified, and the only hand-written piece is a
|
|
13
|
+
repository that records what it was handed. No database: the router is the artifact, as in the
|
|
14
|
+
other generated-router lanes.
|
|
15
|
+
"""
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import importlib
|
|
19
|
+
import json
|
|
20
|
+
import sys
|
|
21
|
+
import tempfile
|
|
22
|
+
import uuid
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
from typing import Any
|
|
25
|
+
|
|
26
|
+
import pytest
|
|
27
|
+
from fastapi import FastAPI
|
|
28
|
+
from fastapi.testclient import TestClient
|
|
29
|
+
|
|
30
|
+
from metaobjects import MetaDataLoader
|
|
31
|
+
from metaobjects.codegen.config import GenConfig
|
|
32
|
+
from metaobjects.codegen.generators.entity_model import entity_model
|
|
33
|
+
from metaobjects.codegen.generators.filter_allowlist_generator import filter_allowlist_generator
|
|
34
|
+
from metaobjects.codegen.generators.router_generator import router_generator
|
|
35
|
+
from metaobjects.codegen.runner import run_gen
|
|
36
|
+
|
|
37
|
+
from .generated_tph_app import build_generated_tph_app
|
|
38
|
+
|
|
39
|
+
_META = {
|
|
40
|
+
"metadata.root": {
|
|
41
|
+
"package": "acme::secfix",
|
|
42
|
+
"children": [
|
|
43
|
+
{"object.value": {
|
|
44
|
+
"name": "Address",
|
|
45
|
+
"children": [
|
|
46
|
+
{"field.string": {"name": "city", "@maxLength": 40}},
|
|
47
|
+
],
|
|
48
|
+
}},
|
|
49
|
+
{"object.entity": {
|
|
50
|
+
"name": "Member",
|
|
51
|
+
"children": [
|
|
52
|
+
{"source.rdb": {"@table": "members"}},
|
|
53
|
+
{"field.long": {"name": "id"}},
|
|
54
|
+
{"field.string": {"name": "name", "@required": True, "@maxLength": 80}},
|
|
55
|
+
{"field.string": {"name": "role", "@maxLength": 20, "@mutability": "readOnly"}},
|
|
56
|
+
{"field.string": {"name": "tenant", "@maxLength": 20, "@mutability": "writeOnce"}},
|
|
57
|
+
{"field.object": {"name": "address", "@objectRef": "Address", "@storage": "jsonb"}},
|
|
58
|
+
{"field.timestamp": {"name": "createdAt", "@autoSet": "onCreate"}},
|
|
59
|
+
{"identity.primary": {"name": "id", "@fields": "id", "@generation": "increment"}},
|
|
60
|
+
],
|
|
61
|
+
}},
|
|
62
|
+
{"object.entity": {
|
|
63
|
+
"name": "Account",
|
|
64
|
+
"children": [
|
|
65
|
+
{"source.rdb": {"@table": "accounts"}},
|
|
66
|
+
{"field.string": {"name": "code", "@maxLength": 20}},
|
|
67
|
+
{"field.string": {"name": "label", "@maxLength": 80}},
|
|
68
|
+
{"identity.primary": {"name": "code", "@fields": "code"}},
|
|
69
|
+
],
|
|
70
|
+
}},
|
|
71
|
+
],
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class _RecordingRepo:
|
|
77
|
+
"""The generated repository seam, recording every write it is handed."""
|
|
78
|
+
|
|
79
|
+
def __init__(self, pk: str) -> None:
|
|
80
|
+
self.pk = pk
|
|
81
|
+
self.writes: list[tuple[str, dict[str, Any]]] = []
|
|
82
|
+
|
|
83
|
+
def create(self, dto: Any) -> Any:
|
|
84
|
+
self.writes.append(("create", dict(dto)))
|
|
85
|
+
return {self.pk: 1, **dto}
|
|
86
|
+
|
|
87
|
+
def update(self, id: Any, dto: Any) -> Any | None:
|
|
88
|
+
self.writes.append(("update", dict(dto)))
|
|
89
|
+
return {self.pk: id, **dto}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _generate_package() -> str:
|
|
93
|
+
"""Run the real Python codegen for ``_META`` into a temp package; return its name."""
|
|
94
|
+
meta_dir = Path(tempfile.mkdtemp(prefix="secfix-meta-"))
|
|
95
|
+
(meta_dir / "meta.json").write_text(json.dumps(_META))
|
|
96
|
+
loaded = MetaDataLoader.from_directory(str(meta_dir))
|
|
97
|
+
assert not loaded.errors, "; ".join(f"{e.code}: {e.message}" for e in loaded.errors)
|
|
98
|
+
pkg = f"secfix_{uuid.uuid4().hex[:8]}"
|
|
99
|
+
root = Path(tempfile.mkdtemp(prefix="secfix-gen-"))
|
|
100
|
+
run_gen(
|
|
101
|
+
GenConfig(out_dir=str(root / pkg)),
|
|
102
|
+
loaded.root,
|
|
103
|
+
generators=[entity_model(), filter_allowlist_generator(), router_generator()],
|
|
104
|
+
)
|
|
105
|
+
sys.path.insert(0, str(root))
|
|
106
|
+
return pkg
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
_PKG = _generate_package()
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _client(router_module: str, pk: str) -> tuple[TestClient, _RecordingRepo, str]:
|
|
113
|
+
mod = importlib.import_module(f"{_PKG}.{router_module}")
|
|
114
|
+
repo = _RecordingRepo(pk)
|
|
115
|
+
app = FastAPI()
|
|
116
|
+
app.include_router(mod.router)
|
|
117
|
+
app.dependency_overrides[mod.get_repository] = lambda: repo
|
|
118
|
+
return TestClient(app), repo, mod.router.prefix
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@pytest.fixture()
|
|
122
|
+
def member() -> tuple[TestClient, _RecordingRepo, str]:
|
|
123
|
+
return _client("member_router", "id")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@pytest.fixture()
|
|
127
|
+
def account() -> tuple[TestClient, _RecordingRepo, str]:
|
|
128
|
+
return _client("account_router", "code")
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# --- the reported defect: a client-sent id and a made-up isAdmin reach the repository -------
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def test_create_never_hands_the_repository_a_client_id_or_an_undeclared_field(member) -> None:
|
|
135
|
+
client, repo, base = member
|
|
136
|
+
resp = client.post(base, json={"id": 999, "name": "Mallory", "isAdmin": True})
|
|
137
|
+
assert resp.status_code == 201, resp.text
|
|
138
|
+
[(op, written)] = repo.writes
|
|
139
|
+
assert op == "create"
|
|
140
|
+
assert set(written) == {"name", "createdAt"} # createdAt is the router's own stamp
|
|
141
|
+
assert written["name"] == "Mallory"
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@pytest.mark.parametrize("method", ["PATCH", "PUT"])
|
|
145
|
+
def test_update_never_hands_the_repository_an_undeclared_field(member, method: str) -> None:
|
|
146
|
+
client, repo, base = member
|
|
147
|
+
resp = client.request(method, f"{base}/1", json={"name": "M", "isAdmin": True})
|
|
148
|
+
assert resp.status_code == 200, resp.text
|
|
149
|
+
assert repo.writes == [("update", {"name": "M"})]
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def test_an_undeclared_key_inside_a_value_object_never_reaches_the_repository(member) -> None:
|
|
153
|
+
client, repo, base = member
|
|
154
|
+
resp = client.post(base, json={"name": "Mallory", "address": {"city": "Oslo", "isAdmin": True}})
|
|
155
|
+
assert resp.status_code == 201, resp.text
|
|
156
|
+
[(_op, written)] = repo.writes
|
|
157
|
+
assert written["address"] == {"city": "Oslo"}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def test_a_malformed_value_on_a_settable_field_is_still_a_400(member) -> None:
|
|
161
|
+
client, repo, base = member
|
|
162
|
+
resp = client.post(base, json={"name": "x" * 81, "isAdmin": True})
|
|
163
|
+
assert resp.status_code == 400, resp.text
|
|
164
|
+
assert resp.json() == {"error": "validation"}
|
|
165
|
+
assert repo.writes == []
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
# --- declared but not settable: dropped, never 400'd, and never handed to the repository ----
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def test_create_strips_the_client_id_and_a_read_only_field(member) -> None:
|
|
172
|
+
client, repo, base = member
|
|
173
|
+
resp = client.post(
|
|
174
|
+
base,
|
|
175
|
+
json={"id": 999, "name": "Mallory", "role": "admin", "tenant": "t1",
|
|
176
|
+
"address": {"city": "Oslo"}},
|
|
177
|
+
)
|
|
178
|
+
assert resp.status_code == 201, resp.text
|
|
179
|
+
[(op, written)] = repo.writes
|
|
180
|
+
assert op == "create"
|
|
181
|
+
# The server generates the id and owns `role`; `createdAt` is the router's own stamp.
|
|
182
|
+
assert set(written) == {"name", "tenant", "address", "createdAt"}
|
|
183
|
+
assert written["name"] == "Mallory"
|
|
184
|
+
assert written["tenant"] == "t1" # writeOnce is settable on create
|
|
185
|
+
assert written["address"] == {"city": "Oslo"}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
@pytest.mark.parametrize("method", ["PATCH", "PUT"])
|
|
189
|
+
def test_update_never_hands_the_repository_the_id_or_a_frozen_field(member, method: str) -> None:
|
|
190
|
+
client, repo, base = member
|
|
191
|
+
resp = client.request(
|
|
192
|
+
method,
|
|
193
|
+
f"{base}/1",
|
|
194
|
+
json={"id": 999, "name": "M2", "role": "admin", "tenant": "t2", "createdAt": "2000-01-01T00:00:00Z"},
|
|
195
|
+
)
|
|
196
|
+
assert resp.status_code == 200, resp.text
|
|
197
|
+
assert repo.writes == [("update", {"name": "M2"})]
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def test_update_passes_a_present_null_through_as_a_clear(member) -> None:
|
|
201
|
+
"""The PATCH present-key tristate is unchanged: an explicit null on a nullable field clears it."""
|
|
202
|
+
client, repo, base = member
|
|
203
|
+
resp = client.patch(f"{base}/1", json={"address": None})
|
|
204
|
+
assert resp.status_code == 200, resp.text
|
|
205
|
+
assert repo.writes == [("update", {"address": None})]
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def test_an_assigned_key_is_still_the_callers_on_create_and_route_owned_on_update(account) -> None:
|
|
209
|
+
client, repo, base = account
|
|
210
|
+
created = client.post(base, json={"code": "ACME", "label": "Acme"})
|
|
211
|
+
assert created.status_code == 201, created.text
|
|
212
|
+
updated = client.patch(f"{base}/ACME", json={"code": "EVIL", "label": "Acme 2"})
|
|
213
|
+
assert updated.status_code == 200, updated.text
|
|
214
|
+
assert repo.writes == [
|
|
215
|
+
("create", {"code": "ACME", "label": "Acme"}),
|
|
216
|
+
("update", {"label": "Acme 2"}),
|
|
217
|
+
]
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
# --- TPH: the per-subtype create / update handlers are a separate code path -----------------
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def _find_tph_dir() -> Path:
|
|
224
|
+
cur = Path(__file__).resolve()
|
|
225
|
+
while cur != cur.parent:
|
|
226
|
+
candidate = cur / "fixtures" / "api-contract-conformance" / "tph"
|
|
227
|
+
if candidate.is_dir():
|
|
228
|
+
return candidate
|
|
229
|
+
cur = cur.parent
|
|
230
|
+
raise RuntimeError("fixtures/api-contract-conformance/tph not found")
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
@pytest.fixture()
|
|
234
|
+
def tph() -> tuple[TestClient, list[tuple[str, str, dict[str, Any]]]]:
|
|
235
|
+
app, repo = build_generated_tph_app(_find_tph_dir())
|
|
236
|
+
writes: list[tuple[str, str, dict[str, Any]]] = []
|
|
237
|
+
create, update = repo.create, repo.update
|
|
238
|
+
|
|
239
|
+
def recording_create(subtype: str, dto: Any) -> Any:
|
|
240
|
+
writes.append(("create", subtype, dict(dto)))
|
|
241
|
+
return create(subtype, dto)
|
|
242
|
+
|
|
243
|
+
def recording_update(subtype: str, id: int, dto: Any) -> Any:
|
|
244
|
+
writes.append(("update", subtype, dict(dto)))
|
|
245
|
+
return update(subtype, id, dto)
|
|
246
|
+
|
|
247
|
+
repo.create, repo.update = recording_create, recording_update
|
|
248
|
+
return TestClient(app), writes
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def test_tph_subtype_create_drops_the_client_id_and_an_undeclared_field(tph) -> None:
|
|
252
|
+
client, writes = tph
|
|
253
|
+
resp = client.post(
|
|
254
|
+
"/api/auths/bridge", json={"id": 999, "reference": "R-1", "quantity": 2, "isAdmin": True}
|
|
255
|
+
)
|
|
256
|
+
assert resp.status_code == 201, resp.text
|
|
257
|
+
[(op, subtype, written)] = writes
|
|
258
|
+
assert (op, subtype) == ("create", "Bridge")
|
|
259
|
+
assert "id" not in written
|
|
260
|
+
assert "isAdmin" not in written
|
|
261
|
+
assert {"reference", "quantity"} <= set(written)
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def test_tph_subtype_update_drops_the_id_and_an_undeclared_field(tph) -> None:
|
|
265
|
+
client, writes = tph
|
|
266
|
+
# The store is unseeded, so the answer is a 404; what matters is what the write was handed.
|
|
267
|
+
client.patch("/api/auths/bridge/1", json={"id": 999, "quantity": 3, "isAdmin": True})
|
|
268
|
+
[(op, subtype, written)] = writes
|
|
269
|
+
assert (op, subtype) == ("update", "Bridge")
|
|
270
|
+
assert "id" not in written
|
|
271
|
+
assert "isAdmin" not in written
|
|
272
|
+
assert written["quantity"] == 3
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/collection_name_collision.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/api_docs_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
{metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/extractor_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/fr019_shared_enum.py
RENAMED
|
File without changes
|
|
File without changes
|
{metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/names_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/template_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
{metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/trace_helper_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
{metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/metaobjects-config.schema.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/output_format_spec_emitter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/api_docs_renderer.py
RENAMED
|
File without changes
|
{metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/constraint_errors.py
RENAMED
|
File without changes
|