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.
Files changed (597) hide show
  1. {metaobjects-1.2.0 → metaobjects-1.2.1}/PKG-INFO +1 -1
  2. {metaobjects-1.2.0 → metaobjects-1.2.1}/pyproject.toml +1 -1
  3. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/KNOWN_GAPS.md +3 -3
  4. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/router_generator.py +70 -28
  5. metaobjects-1.2.1/tests/integration/test_generated_router_validated_input.py +272 -0
  6. {metaobjects-1.2.0 → metaobjects-1.2.1}/uv.lock +1 -1
  7. {metaobjects-1.2.0 → metaobjects-1.2.1}/.gitignore +0 -0
  8. {metaobjects-1.2.0 → metaobjects-1.2.1}/LICENSE +0 -0
  9. {metaobjects-1.2.0 → metaobjects-1.2.1}/README.md +0 -0
  10. {metaobjects-1.2.0 → metaobjects-1.2.1}/hatch_build.py +0 -0
  11. {metaobjects-1.2.0 → metaobjects-1.2.1}/scripts/generate_embedded_library.py +0 -0
  12. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/__init__.py +0 -0
  13. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/agent_context/__init__.py +0 -0
  14. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/agent_context/scaffold.py +0 -0
  15. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/apidocs/__init__.py +0 -0
  16. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/apidocs/api_model.py +0 -0
  17. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/apidocs/builder.py +0 -0
  18. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/apidocs/naming.py +0 -0
  19. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/apidocs/paths.py +0 -0
  20. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/apidocs/renderer.py +0 -0
  21. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/attr_class_map.py +0 -0
  22. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/cli.py +0 -0
  23. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/__init__.py +0 -0
  24. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/_moved.py +0 -0
  25. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/collection_name_collision.py +0 -0
  26. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/collision_names.py +0 -0
  27. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/config.py +0 -0
  28. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/constants.py +0 -0
  29. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/eject.py +0 -0
  30. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/extract_delegate_emitter.py +0 -0
  31. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/extract_schema_emitter.py +0 -0
  32. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/format.py +0 -0
  33. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/fr010_field_mapping.py +0 -0
  34. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generator.py +0 -0
  35. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generator_registry.py +0 -0
  36. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/__init__.py +0 -0
  37. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/api_docs_generator.py +0 -0
  38. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/entity_model.py +0 -0
  39. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/extractor_generator.py +0 -0
  40. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +0 -0
  41. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/find_inbound.py +0 -0
  42. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/fr019_shared_enum.py +0 -0
  43. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/m2m_codegen.py +0 -0
  44. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/names_generator.py +0 -0
  45. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/output_parser_generator.py +0 -0
  46. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/output_prompt_generator.py +0 -0
  47. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/render_helper_generator.py +0 -0
  48. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/report_export_generator.py +0 -0
  49. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/requirement_tests_generator.py +0 -0
  50. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/template_generator.py +0 -0
  51. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
  52. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/generators/trace_helper_generator.py +0 -0
  53. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/instance_artifacts.py +0 -0
  54. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/metaobjects-config.schema.json +0 -0
  55. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/model_walk.py +0 -0
  56. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/orphan_sweep.py +0 -0
  57. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/output_format_spec_emitter.py +0 -0
  58. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/overwrite_policy.py +0 -0
  59. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/project_config.py +0 -0
  60. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/project_import.py +0 -0
  61. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/requirement_hooks.py +0 -0
  62. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/requirement_walk.py +0 -0
  63. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runner.py +0 -0
  64. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/__init__.py +0 -0
  65. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/api_docs_builder.py +0 -0
  66. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/api_docs_model.py +0 -0
  67. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/api_docs_paths.py +0 -0
  68. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/api_docs_renderer.py +0 -0
  69. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/constraint_errors.py +0 -0
  70. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/decimal_wire.py +0 -0
  71. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/extract_delegate_emitter.py +0 -0
  72. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/extract_schema_emitter.py +0 -0
  73. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
  74. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/fr010_field_mapping.py +0 -0
  75. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/fr019_shared_enum.py +0 -0
  76. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/m2m_codegen.py +0 -0
  77. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/output_format_spec_emitter.py +0 -0
  78. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/report_export.py +0 -0
  79. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/runtime/shared_predicates.py +0 -0
  80. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/template_codegen/__init__.py +0 -0
  81. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/template_codegen/output_pattern.py +0 -0
  82. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/template_codegen/template_data.py +0 -0
  83. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/template_codegen/template_spec.py +0 -0
  84. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/type_map.py +0 -0
  85. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/codegen/value_objects.py +0 -0
  86. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/config/__init__.py +0 -0
  87. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/config/dependencies.py +0 -0
  88. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/config/neutral_config.py +0 -0
  89. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/config/source_resolver.py +0 -0
  90. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/core_types.py +0 -0
  91. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/datatype.py +0 -0
  92. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/documentation/__init__.py +0 -0
  93. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/documentation/doc_constants.py +0 -0
  94. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/documentation/doc_provider.py +0 -0
  95. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/documentation/doc_schema.py +0 -0
  96. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/errors.py +0 -0
  97. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/field_lint.py +0 -0
  98. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/fmt.py +0 -0
  99. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/library/__init__.py +0 -0
  100. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/library/embedded_library.py +0 -0
  101. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/library/library_sources.py +0 -0
  102. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/__init__.py +0 -0
  103. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/merge.py +0 -0
  104. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/meta_data_loader.py +0 -0
  105. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/registered_validation.py +0 -0
  106. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/resolve_references.py +0 -0
  107. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/sources/__init__.py +0 -0
  108. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/sources/directory_source.py +0 -0
  109. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/sources/file_source.py +0 -0
  110. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
  111. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/sources/uri_source.py +0 -0
  112. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_discriminator.py +0 -0
  113. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_enum_normalize_ambiguity.py +0 -0
  114. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_field_mutability.py +0 -0
  115. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_reporting.py +0 -0
  116. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_source_escapes.py +0 -0
  117. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_source_parameter_ref.py +0 -0
  118. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
  119. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/loader/validation_passes.py +0 -0
  120. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/__init__.py +0 -0
  121. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/__init__.py +0 -0
  122. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/attr/__init__.py +0 -0
  123. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/attr/attr_constants.py +0 -0
  124. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/attr/meta_attr.py +0 -0
  125. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/field/__init__.py +0 -0
  126. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/field/credential.py +0 -0
  127. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/field/field_constants.py +0 -0
  128. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/field/meta_field.py +0 -0
  129. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/identity/__init__.py +0 -0
  130. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
  131. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
  132. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/index/__init__.py +0 -0
  133. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/index/index_constants.py +0 -0
  134. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/index/meta_index.py +0 -0
  135. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/__init__.py +0 -0
  136. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/meta_object.py +0 -0
  137. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
  138. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
  139. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/object_constants.py +0 -0
  140. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/object_extract.py +0 -0
  141. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/object/value_object.py +0 -0
  142. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
  143. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -0
  144. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
  145. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
  146. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/relationship/relationship_references.py +0 -0
  147. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/__init__.py +0 -0
  148. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/meta_dimension.py +0 -0
  149. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/meta_measure.py +0 -0
  150. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/meta_segment.py +0 -0
  151. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/report_accessors.py +0 -0
  152. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/report_read_model.py +0 -0
  153. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/report_shape.py +0 -0
  154. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/reporting/reporting_constants.py +0 -0
  155. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/requirement/__init__.py +0 -0
  156. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/requirement/meta_requirement.py +0 -0
  157. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/requirement/requirement_constants.py +0 -0
  158. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/requirement/resolve_claim.py +0 -0
  159. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/validator/__init__.py +0 -0
  160. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/core/validator/validator_constants.py +0 -0
  161. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/meta_data.py +0 -0
  162. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/meta_root.py +0 -0
  163. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/__init__.py +0 -0
  164. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
  165. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/db/db_constants.py +0 -0
  166. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/db/db_provider.py +0 -0
  167. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
  168. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
  169. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/origin/origin_constants.py +0 -0
  170. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
  171. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/source/meta_source.py +0 -0
  172. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/persistence/source/source_constants.py +0 -0
  173. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/__init__.py +0 -0
  174. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
  175. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
  176. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
  177. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
  178. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
  179. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
  180. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
  181. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
  182. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/provider_extends.py +0 -0
  183. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/template/__init__.py +0 -0
  184. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/template/meta_template.py +0 -0
  185. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/template/prompt_provider.py +0 -0
  186. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta/template/template_constants.py +0 -0
  187. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/meta_endpoint.py +0 -0
  188. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/naming.py +0 -0
  189. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/naming_refs.py +0 -0
  190. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/parser.py +0 -0
  191. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/parser_yaml.py +0 -0
  192. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/provider.py +0 -0
  193. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/py.typed +0 -0
  194. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/registry.py +0 -0
  195. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/registry_manifest.py +0 -0
  196. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/__init__.py +0 -0
  197. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/email_document.py +0 -0
  198. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/engine.py +0 -0
  199. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/escapers.py +0 -0
  200. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
  201. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/__init__.py +0 -0
  202. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/coerce.py +0 -0
  203. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/extract.py +0 -0
  204. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/extract_map.py +0 -0
  205. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
  206. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/locate.py +0 -0
  207. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/normalize.py +0 -0
  208. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/strip.py +0 -0
  209. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/types.py +0 -0
  210. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
  211. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/filesystem_provider.py +0 -0
  212. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/jinja_render.py +0 -0
  213. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/jinja_verify.py +0 -0
  214. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/mustache_tags.py +0 -0
  215. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/payload_accessors.py +0 -0
  216. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/prompt/__init__.py +0 -0
  217. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
  218. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
  219. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/prompt/prompt_field.py +0 -0
  220. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
  221. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/prompt/prompt_style.py +0 -0
  222. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/renderer.py +0 -0
  223. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/render/verify.py +0 -0
  224. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/requirement_check.py +0 -0
  225. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/__init__.py +0 -0
  226. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/dialect.py +0 -0
  227. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/drivers.py +0 -0
  228. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/llm_recorder.py +0 -0
  229. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/n2m_resolver.py +0 -0
  230. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/object_manager.py +0 -0
  231. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/tph.py +0 -0
  232. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/runtime/validator_runner.py +0 -0
  233. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/scope.py +0 -0
  234. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/serializer_json.py +0 -0
  235. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/shared/__init__.py +0 -0
  236. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/shared/base_types.py +0 -0
  237. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/shared/separators.py +0 -0
  238. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/shared/structural.py +0 -0
  239. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source/__init__.py +0 -0
  240. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source/error_source.py +0 -0
  241. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source/json_path.py +0 -0
  242. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source/semantic_diff.py +0 -0
  243. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source/yaml_core_schema.py +0 -0
  244. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source/yaml_positions.py +0 -0
  245. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/source_resolution.py +0 -0
  246. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/__init__.py +0 -0
  247. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/attr.json +0 -0
  248. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/db.json +0 -0
  249. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/documentation.json +0 -0
  250. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/field.json +0 -0
  251. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/identity.json +0 -0
  252. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/index.json +0 -0
  253. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/layout.json +0 -0
  254. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/object.json +0 -0
  255. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/origin.json +0 -0
  256. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/prompt.json +0 -0
  257. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/relationship.json +0 -0
  258. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/reporting.json +0 -0
  259. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/requirement.json +0 -0
  260. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/source.json +0 -0
  261. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/template.json +0 -0
  262. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/ui-web.json +0 -0
  263. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/ui.json +0 -0
  264. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/validator.json +0 -0
  265. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/spec_metamodel/view.json +0 -0
  266. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/super_resolve.py +0 -0
  267. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/validation_types.py +0 -0
  268. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/wire.py +0 -0
  269. {metaobjects-1.2.0 → metaobjects-1.2.1}/src/metaobjects/yaml_desugar.py +0 -0
  270. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/__init__.py +0 -0
  271. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/__init__.py +0 -0
  272. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/config_helpers.py +0 -0
  273. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/gen_suite.py +0 -0
  274. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/extends/expected/BaseEntity.py +0 -0
  275. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/extends/expected/Program.py +0 -0
  276. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/extends/meta.json +0 -0
  277. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +0 -0
  278. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/nested-array/expected/PostBrief.py +0 -0
  279. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/nested-array/meta.json +0 -0
  280. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/scalars/expected/Metric.py +0 -0
  281. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/scalars/expected/Report.py +0 -0
  282. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/scalars/meta.json +0 -0
  283. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/vanilla/expected/Subscriber.py +0 -0
  284. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/golden/vanilla/meta.json +0 -0
  285. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_abstract_conformance.py +0 -0
  286. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_api_docs_builder.py +0 -0
  287. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_api_docs_paths.py +0 -0
  288. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli.py +0 -0
  289. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_config_gen.py +0 -0
  290. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_config_verify.py +0 -0
  291. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_dependencies.py +0 -0
  292. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_fmt.py +0 -0
  293. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_gen_unknown_attr.py +0 -0
  294. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_help_removed_flags.py +0 -0
  295. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_init.py +0 -0
  296. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_providers.py +0 -0
  297. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_registry.py +0 -0
  298. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_render_helper_template_root.py +0 -0
  299. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_staleness_nudge.py +0 -0
  300. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_surface.py +0 -0
  301. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_verify_field_lint.py +0 -0
  302. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_verify_requirements.py +0 -0
  303. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_verify_strict.py +0 -0
  304. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cli_verify_subverbs.py +0 -0
  305. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_codegen_compile_conformance.py +0 -0
  306. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_collection_name_collision.py +0 -0
  307. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_config_run_settings.py +0 -0
  308. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_constants_config.py +0 -0
  309. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_cross_package_binding_conformance.py +0 -0
  310. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_docs_generators.py +0 -0
  311. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_eject.py +0 -0
  312. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_eject_alone.py +0 -0
  313. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_eject_independence.py +0 -0
  314. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_eject_runtime.py +0 -0
  315. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_eject_undo.py +0 -0
  316. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_entity_model.py +0 -0
  317. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_enum_conformance.py +0 -0
  318. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_extends_abstract_field_inheritance.py +0 -0
  319. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_extract_tier_collision.py +0 -0
  320. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_extractor_generator.py +0 -0
  321. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_filter_allowlist_generator.py +0 -0
  322. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_fmt_format_file.py +0 -0
  323. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_format.py +0 -0
  324. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_fr010_nested_object_prompt.py +0 -0
  325. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_fr010_output_codegen.py +0 -0
  326. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
  327. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_gen_state_keying.py +0 -0
  328. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_generator.py +0 -0
  329. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_generator_extension_seams.py +0 -0
  330. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_golden.py +0 -0
  331. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_hand_edits.py +0 -0
  332. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_inherit_without_restate_gate.py +0 -0
  333. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_inheritance_conformance.py +0 -0
  334. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_instance_artifacts.py +0 -0
  335. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_m2m_codegen.py +0 -0
  336. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_moved_modules.py +0 -0
  337. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_names_extends_chain.py +0 -0
  338. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_names_generator.py +0 -0
  339. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_no_magic_physical_names.py +0 -0
  340. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_one_generator_list.py +0 -0
  341. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_origin_nullability.py +0 -0
  342. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_orphan_sweep.py +0 -0
  343. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_output_parser_generator.py +0 -0
  344. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_overwrite_policy.py +0 -0
  345. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_overwrite_policy_hash.py +0 -0
  346. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_pattern_ascii.py +0 -0
  347. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_project_config.py +0 -0
  348. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_project_import.py +0 -0
  349. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_projection_compile.py +0 -0
  350. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_projection_docs_routes.py +0 -0
  351. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_recipe_generators.py +0 -0
  352. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_render_helper_conformance.py +0 -0
  353. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_render_helper_generator.py +0 -0
  354. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_report_credential.py +0 -0
  355. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_report_export.py +0 -0
  356. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_report_router.py +0 -0
  357. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_requirement_tests_generator.py +0 -0
  358. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_reverse_finders.py +0 -0
  359. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_route_path_naming.py +0 -0
  360. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_autoset.py +0 -0
  361. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_generator.py +0 -0
  362. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_generator_m2m_target_tph.py +0 -0
  363. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_generator_tph_m2m.py +0 -0
  364. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_generator_tph_m2m_shadowed.py +0 -0
  365. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_mypy_strict.py +0 -0
  366. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_router_secret_fields.py +0 -0
  367. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_runner.py +0 -0
  368. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_source_resolution.py +0 -0
  369. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_sourceless_entity_surface.py +0 -0
  370. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_sourceless_projection.py +0 -0
  371. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_template_data.py +0 -0
  372. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_template_generator.py +0 -0
  373. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_template_output_pattern.py +0 -0
  374. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_template_scope_helpers.py +0 -0
  375. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_template_scope_walk.py +0 -0
  376. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_template_spec.py +0 -0
  377. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_tph_codegen.py +0 -0
  378. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_trace_helper_generator.py +0 -0
  379. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_type_map.py +0 -0
  380. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_validation_conformance.py +0 -0
  381. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_value_objects.py +0 -0
  382. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/codegen/test_write_through.py +0 -0
  383. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/config/__init__.py +0 -0
  384. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/config/test_dependencies.py +0 -0
  385. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/config/test_library_package_guard.py +0 -0
  386. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/config/test_neutral_config.py +0 -0
  387. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/config/test_neutral_config_unknown_key.py +0 -0
  388. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/config/test_source_resolver.py +0 -0
  389. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/__init__.py +0 -0
  390. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/capabilities.py +0 -0
  391. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/conformance-expected-failures.json +0 -0
  392. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/conformance_adapter.py +0 -0
  393. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/corpus.py +0 -0
  394. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/eject_contract.py +0 -0
  395. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/expected_failures.py +0 -0
  396. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/fixture_discovery.py +0 -0
  397. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/navigator.py +0 -0
  398. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
  399. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_conformance.py +0 -0
  400. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_conformance_twin_roundtrip.py +0 -0
  401. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_dependency_conformance.py +0 -0
  402. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_eject_contract.py +0 -0
  403. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_extract_conformance.py +0 -0
  404. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_extract_object_array_bounds.py +0 -0
  405. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_extract_object_verdict.py +0 -0
  406. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_field_lint_conformance.py +0 -0
  407. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_fmt_conformance.py +0 -0
  408. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_fr010_loader_attrs.py +0 -0
  409. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_fr011_attrs.py +0 -0
  410. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_generator_registry_conformance.py +0 -0
  411. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_naming_conformance.py +0 -0
  412. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_object_model_conformance.py +0 -0
  413. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_provider_composition_conformance.py +0 -0
  414. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_registry_conformance.py +0 -0
  415. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_requirement_check_conformance.py +0 -0
  416. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_requirement_test_identity_conformance.py +0 -0
  417. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_runner_hardfail.py +0 -0
  418. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_scope_conformance.py +0 -0
  419. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_shared_model_conformance.py +0 -0
  420. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_source_resolution_conformance.py +0 -0
  421. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_spec_metamodel_embed.py +0 -0
  422. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_strict_attr_load.py +0 -0
  423. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_template_codegen_conformance.py +0 -0
  424. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_template_generator_conformance.py +0 -0
  425. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_wire_conformance.py +0 -0
  426. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/test_yaml_conformance.py +0 -0
  427. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
  428. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/__init__.py +0 -0
  429. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/api_contract_assertions.py +0 -0
  430. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/api_contract_jsonb_server.py +0 -0
  431. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/api_contract_m2m_server.py +0 -0
  432. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/api_contract_server.py +0 -0
  433. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/conftest.py +0 -0
  434. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/corpus_config.py +0 -0
  435. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/engines.py +0 -0
  436. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_jsonb_app.py +0 -0
  437. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_m2m_app.py +0 -0
  438. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_projection_app.py +0 -0
  439. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_report_app.py +0 -0
  440. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_router_app.py +0 -0
  441. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_secret_fields_app.py +0 -0
  442. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/generated_tph_app.py +0 -0
  443. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/meta_ai_trace.yaml +0 -0
  444. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/mysql_container.py +0 -0
  445. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/normalization.py +0 -0
  446. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/postgres_container.py +0 -0
  447. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/query_runner.py +0 -0
  448. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/report_lane.py +0 -0
  449. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/scenarios.py +0 -0
  450. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract.py +0 -0
  451. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_decimal.py +0 -0
  452. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_generated.py +0 -0
  453. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_jsonb.py +0 -0
  454. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_m2m.py +0 -0
  455. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_m2m_generated.py +0 -0
  456. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_projection.py +0 -0
  457. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_report.py +0 -0
  458. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_secret_fields.py +0 -0
  459. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_api_contract_tph_generated.py +0 -0
  460. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_generated_decimal_wire.py +0 -0
  461. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_generated_router_uuid_pk.py +0 -0
  462. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_llm_call_trace.py +0 -0
  463. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_m2m_target_tph_generated.py +0 -0
  464. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_normalization.py +0 -0
  465. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_query_scenarios.py +0 -0
  466. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_runtime_return_types.py +0 -0
  467. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_tph_m2m_generated.py +0 -0
  468. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/integration/test_tph_m2m_shadowed_generated.py +0 -0
  469. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/__init__.py +0 -0
  470. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_abstract_subtype_authored.py +0 -0
  471. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_child_wrapper_body_shape.py +0 -0
  472. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_enum_extends_values_conflict.py +0 -0
  473. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_field_mutability_order.py +0 -0
  474. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_library_packages.py +0 -0
  475. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_naming_discovery.py +0 -0
  476. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_relative_package_multi_root.py +0 -0
  477. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_shipped_library_ai.py +0 -0
  478. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/loader/test_template_payload_target_210.py +0 -0
  479. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/open_closed_proof_test.py +0 -0
  480. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/__init__.py +0 -0
  481. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/__init__.py +0 -0
  482. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_coerce.py +0 -0
  483. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_extract.py +0 -0
  484. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_extract_map.py +0 -0
  485. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_json_forgiving_reader.py +0 -0
  486. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_locate.py +0 -0
  487. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_model.py +0 -0
  488. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_normalize.py +0 -0
  489. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_strip.py +0 -0
  490. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
  491. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/prompt/__init__.py +0 -0
  492. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/prompt/test_output_format_renderer.py +0 -0
  493. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_email_document.py +0 -0
  494. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_filesystem_provider.py +0 -0
  495. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_jinja_conformance.py +0 -0
  496. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_jinja_engine.py +0 -0
  497. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_output_format_renderer_nested.py +0 -0
  498. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_output_prompt_conformance.py +0 -0
  499. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_render_conformance.py +0 -0
  500. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_render_max_chars.py +0 -0
  501. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_render_model_payload.py +0 -0
  502. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_verify.py +0 -0
  503. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/render/test_verify_conformance.py +0 -0
  504. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_constraint_errors.py +0 -0
  505. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_decimal_wire.py +0 -0
  506. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_literal_naming_sqlite.py +0 -0
  507. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_object_manager_currency_read.py +0 -0
  508. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_object_manager_dialects.py +0 -0
  509. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_object_manager_enum_intvaluemap.py +0 -0
  510. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_object_manager_report.py +0 -0
  511. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_object_manager_table_name.py +0 -0
  512. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_validation_conformance_runtime.py +0 -0
  513. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/runtime/test_validator_runner.py +0 -0
  514. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/__init__.py +0 -0
  515. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_fr5c_merge_attribution.py +0 -0
  516. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_fr5d_reference_resolution.py +0 -0
  517. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_fr5e_database_source_shape.py +0 -0
  518. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_json_path.py +0 -0
  519. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_semantic_diff.py +0 -0
  520. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_source_on_node.py +0 -0
  521. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_yaml_core_schema.py +0 -0
  522. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/source/test_yaml_positions.py +0 -0
  523. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/test_api_docs_accuracy.py +0 -0
  524. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/test_api_docs_packages.py +0 -0
  525. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/test_meta_endpoint.py +0 -0
  526. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/test_report_read_model.py +0 -0
  527. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/test_report_shape.py +0 -0
  528. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/test_reporting_inert.py +0 -0
  529. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/__init__.py +0 -0
  530. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_agent_context_staleness.py +0 -0
  531. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_capabilities.py +0 -0
  532. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_column_naming_strategy.py +0 -0
  533. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_common_attrs.py +0 -0
  534. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_core_types.py +0 -0
  535. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_derive_m2m_declaring_entity.py +0 -0
  536. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_effective_children_sibling_shadowing.py +0 -0
  537. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_effective_package.py +0 -0
  538. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_errors.py +0 -0
  539. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_field_enum.py +0 -0
  540. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_field_enum_intvaluemap.py +0 -0
  541. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_field_map_validation.py +0 -0
  542. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
  543. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_file_source_id.py +0 -0
  544. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
  545. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_index_lookup.py +0 -0
  546. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_inherited_reference_binding.py +0 -0
  547. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_llm_recorder.py +0 -0
  548. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_loader.py +0 -0
  549. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_loader_bom.py +0 -0
  550. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_loader_class.py +0 -0
  551. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_merge.py +0 -0
  552. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_meta_attr.py +0 -0
  553. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_meta_data.py +0 -0
  554. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_meta_source.py +0 -0
  555. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_module_shortcuts.py +0 -0
  556. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_n2m_resolver.py +0 -0
  557. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_n2m_resolver_inherited.py +0 -0
  558. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_no_dead_config_fields.py +0 -0
  559. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_object_manager_autoset_stamping.py +0 -0
  560. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
  561. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_object_manager_write_through.py +0 -0
  562. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_one_primary_source.py +0 -0
  563. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_parser.py +0 -0
  564. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_parser_yaml.py +0 -0
  565. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_provider.py +0 -0
  566. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_provider_extension.py +0 -0
  567. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_registry.py +0 -0
  568. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_registry_completeness.py +0 -0
  569. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_registry_extend.py +0 -0
  570. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_registry_sealed.py +0 -0
  571. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_relationship_m2m_validation.py +0 -0
  572. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_relationship_references.py +0 -0
  573. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_relationship_referential_actions.py +0 -0
  574. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_relative_set_newlines.py +0 -0
  575. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_reporting_accessors.py +0 -0
  576. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_reporting_validation_spine_default.py +0 -0
  577. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_resolution_key.py +0 -0
  578. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_resolve_claim.py +0 -0
  579. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
  580. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_serializer.py +0 -0
  581. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_serializer_shared_document.py +0 -0
  582. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_shared_constants.py +0 -0
  583. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_smoke.py +0 -0
  584. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_source_escapes.py +0 -0
  585. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_sources.py +0 -0
  586. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_strict_child_placement.py +0 -0
  587. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_super_resolve.py +0 -0
  588. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_template_toolcall.py +0 -0
  589. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
  590. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_validation_attr_schema.py +0 -0
  591. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_validation_filter_values.py +0 -0
  592. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_validation_origin_195.py +0 -0
  593. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_validation_origin_paths.py +0 -0
  594. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_validation_sort_field.py +0 -0
  595. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_validation_warnings.py +0 -0
  596. {metaobjects-1.2.0 → metaobjects-1.2.1}/tests/unit/test_write_coercion_arrays.py +0 -0
  597. {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.0
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.0"
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 still receives the original `dict` (preserving the FR-035
40
- present-key tristate + wire values), so the strong-typing simplification below
41
- remains for the repo/response types; only the validation import was added.
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
@@ -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`` (the raw body as a dict) and passes THAT to the repository, so a
438
- field merely absent from the patch model still reaches the row. @autoSet gets
439
- away with it because the router OVERWRITES its key server-side; a writeOnce
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
- " # FR-036: run the generated field constraints (length / pattern /",
1087
- " # numeric bounds) before persisting; a violation is the cross-port 400.",
1088
- " try:",
1089
- f" {model_name}(**dto)",
1090
- " except ValidationError:",
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
- " # FR-036: validate PRESENT, non-null values with the create rules (the",
1118
- " # all-optional patch model never fires required-checks on ABSENT fields).",
1119
- " try:",
1120
- f" {patch_model}(**dto)",
1121
- " except ValidationError:",
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.append(" # FR-036: run the subtype's field constraints before persisting.")
1551
- parts.append(" try:")
1552
- parts.append(f" {sub}Create(**dto)")
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.append(" # FR-036: validate PRESENT, non-null values with the subtype's create rules.")
1588
- parts.append(" try:")
1589
- parts.append(f" {sub}Patch(**dto)")
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 RAW body dict and hands THAT to the
1896
- # repository), so the strip has to live here, not in <Entity>Patch.
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
@@ -399,7 +399,7 @@ wheels = [
399
399
 
400
400
  [[package]]
401
401
  name = "metaobjects"
402
- version = "1.2.0"
402
+ version = "1.2.1"
403
403
  source = { editable = "." }
404
404
  dependencies = [
405
405
  { name = "pyyaml" },
File without changes
File without changes
File without changes
File without changes