metaobjects 0.15.11__tar.gz → 0.15.13__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 (383) hide show
  1. {metaobjects-0.15.11 → metaobjects-0.15.13}/PKG-INFO +1 -1
  2. {metaobjects-0.15.11 → metaobjects-0.15.13}/pyproject.toml +1 -1
  3. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/m2m_codegen.py +3 -3
  4. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/payload_vo_generator.py +19 -3
  5. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/render_helper_generator.py +43 -29
  6. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/router_generator.py +64 -26
  7. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/core_types.py +16 -0
  8. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/errors.py +7 -11
  9. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/registered_validation.py +36 -12
  10. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/validate_source_parameter_ref.py +7 -20
  11. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/validation_passes.py +67 -128
  12. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/persistence/origin/origin_constants.py +3 -2
  13. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/naming_refs.py +79 -52
  14. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/origin.json +1 -1
  15. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_generator_extension_seams.py +2 -2
  16. metaobjects-0.15.13/tests/codegen/test_router_generator.py +357 -0
  17. metaobjects-0.15.13/tests/integration/test_generated_router_uuid_pk.py +221 -0
  18. {metaobjects-0.15.11 → metaobjects-0.15.13}/uv.lock +1 -1
  19. metaobjects-0.15.11/tests/codegen/test_router_generator.py +0 -160
  20. {metaobjects-0.15.11 → metaobjects-0.15.13}/.gitignore +0 -0
  21. {metaobjects-0.15.11 → metaobjects-0.15.13}/LICENSE +0 -0
  22. {metaobjects-0.15.11 → metaobjects-0.15.13}/README.md +0 -0
  23. {metaobjects-0.15.11 → metaobjects-0.15.13}/hatch_build.py +0 -0
  24. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/__init__.py +0 -0
  25. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/agent_context/__init__.py +0 -0
  26. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/agent_context/scaffold.py +0 -0
  27. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/apidocs/__init__.py +0 -0
  28. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/apidocs/api_model.py +0 -0
  29. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/apidocs/builder.py +0 -0
  30. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/apidocs/naming.py +0 -0
  31. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/apidocs/paths.py +0 -0
  32. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/apidocs/renderer.py +0 -0
  33. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/attr_class_map.py +0 -0
  34. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/cli.py +0 -0
  35. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/KNOWN_GAPS.md +0 -0
  36. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/__init__.py +0 -0
  37. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/config.py +0 -0
  38. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/constants.py +0 -0
  39. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/extract_delegate_emitter.py +0 -0
  40. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/extract_schema_emitter.py +0 -0
  41. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/format.py +0 -0
  42. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/fr010_field_mapping.py +0 -0
  43. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generator.py +0 -0
  44. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generator_registry.py +0 -0
  45. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/__init__.py +0 -0
  46. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/entity_model.py +0 -0
  47. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/extractor_generator.py +0 -0
  48. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +0 -0
  49. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/fr019_shared_enum.py +0 -0
  50. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/output_parser_generator.py +0 -0
  51. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/output_prompt_generator.py +0 -0
  52. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/template_generator.py +0 -0
  53. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
  54. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/generators/trace_helper_generator.py +0 -0
  55. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/instance_artifacts.py +0 -0
  56. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/output_format_spec_emitter.py +0 -0
  57. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/overwrite_policy.py +0 -0
  58. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/runner.py +0 -0
  59. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/runtime/__init__.py +0 -0
  60. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
  61. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/template_codegen/__init__.py +0 -0
  62. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/template_codegen/output_pattern.py +0 -0
  63. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/template_codegen/template_data.py +0 -0
  64. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/template_codegen/template_spec.py +0 -0
  65. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/codegen/type_map.py +0 -0
  66. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/datatype.py +0 -0
  67. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/documentation/__init__.py +0 -0
  68. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/documentation/doc_constants.py +0 -0
  69. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/documentation/doc_provider.py +0 -0
  70. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/documentation/doc_schema.py +0 -0
  71. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/__init__.py +0 -0
  72. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/merge.py +0 -0
  73. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/meta_data_loader.py +0 -0
  74. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/sources/__init__.py +0 -0
  75. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/sources/directory_source.py +0 -0
  76. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/sources/file_source.py +0 -0
  77. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
  78. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/sources/uri_source.py +0 -0
  79. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/validate_discriminator.py +0 -0
  80. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/validate_field_readonly.py +0 -0
  81. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
  82. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/__init__.py +0 -0
  83. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/__init__.py +0 -0
  84. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/attr/__init__.py +0 -0
  85. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/attr/attr_constants.py +0 -0
  86. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/attr/meta_attr.py +0 -0
  87. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/field/__init__.py +0 -0
  88. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/field/field_constants.py +0 -0
  89. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/field/meta_field.py +0 -0
  90. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/identity/__init__.py +0 -0
  91. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
  92. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
  93. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/index/__init__.py +0 -0
  94. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/index/index_constants.py +0 -0
  95. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/index/meta_index.py +0 -0
  96. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/object/__init__.py +0 -0
  97. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/object/meta_object.py +0 -0
  98. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
  99. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
  100. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/object/object_constants.py +0 -0
  101. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/object/object_extract.py +0 -0
  102. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/object/value_object.py +0 -0
  103. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
  104. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -0
  105. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
  106. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
  107. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/validator/__init__.py +0 -0
  108. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/core/validator/validator_constants.py +0 -0
  109. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/meta_data.py +0 -0
  110. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/meta_root.py +0 -0
  111. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/persistence/__init__.py +0 -0
  112. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
  113. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/persistence/db/db_constants.py +0 -0
  114. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/persistence/db/db_provider.py +0 -0
  115. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
  116. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
  117. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
  118. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/persistence/source/meta_source.py +0 -0
  119. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/persistence/source/source_constants.py +0 -0
  120. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/presentation/__init__.py +0 -0
  121. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
  122. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
  123. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
  124. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
  125. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
  126. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
  127. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
  128. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
  129. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/provider_extends.py +0 -0
  130. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/template/__init__.py +0 -0
  131. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/template/meta_template.py +0 -0
  132. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/template/prompt_provider.py +0 -0
  133. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/meta/template/template_constants.py +0 -0
  134. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/parser.py +0 -0
  135. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/parser_yaml.py +0 -0
  136. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/provider.py +0 -0
  137. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/py.typed +0 -0
  138. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/registry.py +0 -0
  139. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/registry_manifest.py +0 -0
  140. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/__init__.py +0 -0
  141. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/email_document.py +0 -0
  142. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/escapers.py +0 -0
  143. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
  144. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/extract/__init__.py +0 -0
  145. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/extract/coerce.py +0 -0
  146. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/extract/extract.py +0 -0
  147. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/extract/extract_map.py +0 -0
  148. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
  149. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/extract/locate.py +0 -0
  150. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/extract/normalize.py +0 -0
  151. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/extract/strip.py +0 -0
  152. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/extract/types.py +0 -0
  153. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
  154. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/filesystem_provider.py +0 -0
  155. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/prompt/__init__.py +0 -0
  156. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
  157. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
  158. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/prompt/prompt_field.py +0 -0
  159. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
  160. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/prompt/prompt_style.py +0 -0
  161. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/renderer.py +0 -0
  162. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/render/verify.py +0 -0
  163. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/runtime/__init__.py +0 -0
  164. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/runtime/llm_recorder.py +0 -0
  165. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/runtime/n2m_resolver.py +0 -0
  166. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/runtime/object_manager.py +0 -0
  167. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/runtime/tph.py +0 -0
  168. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/serializer_json.py +0 -0
  169. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/shared/__init__.py +0 -0
  170. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/shared/base_types.py +0 -0
  171. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/shared/separators.py +0 -0
  172. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/shared/structural.py +0 -0
  173. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/source/__init__.py +0 -0
  174. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/source/error_source.py +0 -0
  175. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/source/json_path.py +0 -0
  176. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/source/semantic_diff.py +0 -0
  177. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/source/yaml_positions.py +0 -0
  178. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/__init__.py +0 -0
  179. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/attr.json +0 -0
  180. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/db.json +0 -0
  181. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/documentation.json +0 -0
  182. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/field.json +0 -0
  183. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/identity.json +0 -0
  184. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/index.json +0 -0
  185. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/layout.json +0 -0
  186. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/object.json +0 -0
  187. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/prompt.json +0 -0
  188. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/relationship.json +0 -0
  189. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/source.json +0 -0
  190. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/template.json +0 -0
  191. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/ui.json +0 -0
  192. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/validator.json +0 -0
  193. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/spec_metamodel/view.json +0 -0
  194. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/super_resolve.py +0 -0
  195. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/validation_types.py +0 -0
  196. {metaobjects-0.15.11 → metaobjects-0.15.13}/src/metaobjects/yaml_desugar.py +0 -0
  197. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/__init__.py +0 -0
  198. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/__init__.py +0 -0
  199. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/golden/extends/expected/BaseEntity.py +0 -0
  200. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/golden/extends/expected/Program.py +0 -0
  201. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/golden/extends/meta.json +0 -0
  202. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +0 -0
  203. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/golden/nested-array/expected/PostBrief.py +0 -0
  204. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/golden/nested-array/meta.json +0 -0
  205. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/golden/scalars/expected/Metric.py +0 -0
  206. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/golden/scalars/expected/Report.py +0 -0
  207. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/golden/scalars/meta.json +0 -0
  208. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/golden/vanilla/expected/Subscriber.py +0 -0
  209. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/golden/vanilla/meta.json +0 -0
  210. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_abstract_conformance.py +0 -0
  211. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_api_docs_builder.py +0 -0
  212. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_api_docs_paths.py +0 -0
  213. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_cli.py +0 -0
  214. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_cli_providers.py +0 -0
  215. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_cli_registry.py +0 -0
  216. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_cli_staleness_nudge.py +0 -0
  217. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_cli_verify_strict.py +0 -0
  218. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_cli_verify_subverbs.py +0 -0
  219. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_constants_config.py +0 -0
  220. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_entity_model.py +0 -0
  221. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_enum_conformance.py +0 -0
  222. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_extends_abstract_field_inheritance.py +0 -0
  223. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_extractor_generator.py +0 -0
  224. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_filter_allowlist_generator.py +0 -0
  225. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_format.py +0 -0
  226. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_fr010_nested_object_prompt.py +0 -0
  227. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_fr010_output_codegen.py +0 -0
  228. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
  229. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_generator.py +0 -0
  230. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_golden.py +0 -0
  231. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_inherit_without_restate_gate.py +0 -0
  232. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_inheritance_conformance.py +0 -0
  233. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_instance_artifacts.py +0 -0
  234. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_m2m_codegen.py +0 -0
  235. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_output_parser_generator.py +0 -0
  236. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_overwrite_policy.py +0 -0
  237. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_payload_vo_generator.py +0 -0
  238. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_projection_compile.py +0 -0
  239. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_render_helper_conformance.py +0 -0
  240. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_render_helper_generator.py +0 -0
  241. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_reverse_finders.py +0 -0
  242. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_runner.py +0 -0
  243. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_template_data.py +0 -0
  244. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_template_generator.py +0 -0
  245. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_template_output_pattern.py +0 -0
  246. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_template_scope_helpers.py +0 -0
  247. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_template_scope_walk.py +0 -0
  248. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_template_spec.py +0 -0
  249. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_tph_codegen.py +0 -0
  250. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_trace_helper_generator.py +0 -0
  251. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_type_map.py +0 -0
  252. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/codegen/test_validation_conformance.py +0 -0
  253. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/__init__.py +0 -0
  254. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/capabilities.py +0 -0
  255. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/conformance-expected-failures.json +0 -0
  256. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/conformance_adapter.py +0 -0
  257. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/corpus.py +0 -0
  258. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/expected_failures.py +0 -0
  259. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/fixture_discovery.py +0 -0
  260. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/navigator.py +0 -0
  261. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
  262. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_conformance.py +0 -0
  263. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_extract_conformance.py +0 -0
  264. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_extract_object_verdict.py +0 -0
  265. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_fr010_loader_attrs.py +0 -0
  266. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_fr011_attrs.py +0 -0
  267. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_generator_registry_conformance.py +0 -0
  268. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_object_model_conformance.py +0 -0
  269. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_provider_composition_conformance.py +0 -0
  270. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_registry_conformance.py +0 -0
  271. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_runner_hardfail.py +0 -0
  272. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_spec_metamodel_embed.py +0 -0
  273. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_strict_attr_load.py +0 -0
  274. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_template_codegen_conformance.py +0 -0
  275. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_template_generator_conformance.py +0 -0
  276. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/test_yaml_conformance.py +0 -0
  277. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
  278. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/__init__.py +0 -0
  279. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/api_contract_assertions.py +0 -0
  280. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/api_contract_jsonb_server.py +0 -0
  281. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/api_contract_m2m_server.py +0 -0
  282. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/api_contract_server.py +0 -0
  283. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/generated_jsonb_app.py +0 -0
  284. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/generated_m2m_app.py +0 -0
  285. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/generated_router_app.py +0 -0
  286. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/generated_tph_app.py +0 -0
  287. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/meta_ai_trace.yaml +0 -0
  288. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/normalization.py +0 -0
  289. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/postgres_container.py +0 -0
  290. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/query_runner.py +0 -0
  291. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/scenarios.py +0 -0
  292. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/test_api_contract.py +0 -0
  293. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/test_api_contract_generated.py +0 -0
  294. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/test_api_contract_jsonb.py +0 -0
  295. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/test_api_contract_m2m.py +0 -0
  296. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/test_api_contract_m2m_generated.py +0 -0
  297. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/test_api_contract_tph_generated.py +0 -0
  298. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/test_llm_call_trace.py +0 -0
  299. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/test_normalization.py +0 -0
  300. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/test_query_scenarios.py +0 -0
  301. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/integration/test_runtime_return_types.py +0 -0
  302. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/open_closed_proof_test.py +0 -0
  303. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/__init__.py +0 -0
  304. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/extract/__init__.py +0 -0
  305. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/extract/test_coerce.py +0 -0
  306. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/extract/test_extract.py +0 -0
  307. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/extract/test_extract_map.py +0 -0
  308. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/extract/test_json_forgiving_reader.py +0 -0
  309. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/extract/test_locate.py +0 -0
  310. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/extract/test_model.py +0 -0
  311. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/extract/test_normalize.py +0 -0
  312. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/extract/test_strip.py +0 -0
  313. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
  314. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/prompt/__init__.py +0 -0
  315. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/prompt/test_output_format_renderer.py +0 -0
  316. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/test_email_document.py +0 -0
  317. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/test_filesystem_provider.py +0 -0
  318. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/test_output_format_renderer_nested.py +0 -0
  319. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/test_output_prompt_conformance.py +0 -0
  320. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/test_render_conformance.py +0 -0
  321. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/test_render_max_chars.py +0 -0
  322. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/test_verify.py +0 -0
  323. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/render/test_verify_conformance.py +0 -0
  324. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/source/__init__.py +0 -0
  325. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/source/test_fr5c_merge_attribution.py +0 -0
  326. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/source/test_fr5d_reference_resolution.py +0 -0
  327. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/source/test_fr5e_database_source_shape.py +0 -0
  328. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/source/test_json_path.py +0 -0
  329. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/source/test_semantic_diff.py +0 -0
  330. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/source/test_source_on_node.py +0 -0
  331. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/source/test_yaml_positions.py +0 -0
  332. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/test_api_docs_accuracy.py +0 -0
  333. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/__init__.py +0 -0
  334. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_agent_context_staleness.py +0 -0
  335. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_capabilities.py +0 -0
  336. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_common_attrs.py +0 -0
  337. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_core_types.py +0 -0
  338. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_effective_package.py +0 -0
  339. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_errors.py +0 -0
  340. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_field_enum.py +0 -0
  341. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_field_map_validation.py +0 -0
  342. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
  343. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
  344. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_index_lookup.py +0 -0
  345. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_llm_recorder.py +0 -0
  346. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_loader.py +0 -0
  347. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_loader_bom.py +0 -0
  348. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_loader_class.py +0 -0
  349. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_merge.py +0 -0
  350. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_meta_attr.py +0 -0
  351. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_meta_data.py +0 -0
  352. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_meta_source.py +0 -0
  353. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_module_shortcuts.py +0 -0
  354. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_n2m_resolver.py +0 -0
  355. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_n2m_resolver_inherited.py +0 -0
  356. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
  357. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_one_primary_source.py +0 -0
  358. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_parser.py +0 -0
  359. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_parser_yaml.py +0 -0
  360. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_provider.py +0 -0
  361. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_provider_extension.py +0 -0
  362. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_registry.py +0 -0
  363. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_registry_completeness.py +0 -0
  364. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_registry_extend.py +0 -0
  365. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_registry_sealed.py +0 -0
  366. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_relationship_referential_actions.py +0 -0
  367. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_resolution_key.py +0 -0
  368. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
  369. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_serializer.py +0 -0
  370. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_shared_constants.py +0 -0
  371. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_smoke.py +0 -0
  372. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_sources.py +0 -0
  373. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_strict_child_placement.py +0 -0
  374. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_super_resolve.py +0 -0
  375. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_template_toolcall.py +0 -0
  376. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
  377. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_validation_attr_schema.py +0 -0
  378. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_validation_filter_values.py +0 -0
  379. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_validation_origin_paths.py +0 -0
  380. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_validation_sort_field.py +0 -0
  381. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_validation_warnings.py +0 -0
  382. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_write_coercion_arrays.py +0 -0
  383. {metaobjects-0.15.11 → metaobjects-0.15.13}/tests/unit/test_yaml_desugar.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metaobjects
3
- Version: 0.15.11
3
+ Version: 0.15.13
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 = "0.15.11"
3
+ version = "0.15.13"
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"
@@ -110,7 +110,7 @@ def _field_named(entity: MetaObject, field_name: str) -> MetaField | None:
110
110
  return None
111
111
 
112
112
 
113
- def _pk_field_name(entity: MetaObject) -> str:
113
+ def pk_field_name(entity: MetaObject) -> str:
114
114
  """The single PK field name (``identity.primary @fields``), default ``id``."""
115
115
  for c in entity.children():
116
116
  if c.type == TYPE_IDENTITY and c.sub_type == IDENTITY_SUBTYPE_PRIMARY:
@@ -184,8 +184,8 @@ def resolve_m2m_descriptors(
184
184
  source_column=_column_of(source_fk, fields.source_field),
185
185
  target_column=_column_of(target_fk, fields.target_field),
186
186
  target_pk_column=_column_of(
187
- _field_named(target, _pk_field_name(target)),
188
- _pk_field_name(target),
187
+ _field_named(target, pk_field_name(target)),
188
+ pk_field_name(target),
189
189
  ),
190
190
  symmetric=rel.symmetric(),
191
191
  )
@@ -63,6 +63,7 @@ from metaobjects.meta.persistence.origin.origin_constants import (
63
63
  )
64
64
  from metaobjects.meta.template import template_constants as tc
65
65
  from metaobjects.meta.template.meta_template import MetaTemplate
66
+ from metaobjects.naming_refs import resolve_object_ref
66
67
  from metaobjects.shared.base_types import TYPE_OBJECT, TYPE_TEMPLATE
67
68
  from metaobjects.shared.separators import PACKAGE_SEP
68
69
 
@@ -104,6 +105,16 @@ def payload_module_name(template_name: str) -> str:
104
105
  # ---------------------------------------------------------------------------
105
106
 
106
107
 
108
+ def _pkg_of(node: MetaData) -> str:
109
+ """The effective package of an object — its ``resolution_key()`` minus the
110
+ trailing ``::<name>`` ("" for a root-level object). Derived from the resolution
111
+ key so it is correct for BOTH loaded trees (file_default_package) and
112
+ programmatically-built trees (package only on the root)."""
113
+ key = node.resolution_key()
114
+ i = key.rfind(PACKAGE_SEP)
115
+ return "" if i == -1 else key[:i]
116
+
117
+
107
118
  def _resolve_object_by_short_or_fqn(root: MetaData, ref: str) -> MetaObject | None:
108
119
  """Find a ``MetaObject`` child satisfying an (already-expanded) object ref.
109
120
 
@@ -192,9 +203,14 @@ def _resolve_object_field_type(
192
203
  ref = field.attrs().get(fc.FIELD_ATTR_OBJECT_REF)
193
204
  if not isinstance(ref, str) or not ref:
194
205
  return _fallback_type(field)
195
- target = _resolve_object_by_short_or_fqn(root, ref)
196
- if target is None and PACKAGE_SEP in ref:
197
- target = _resolve_object_by_short_or_fqn(root, ref.rsplit(PACKAGE_SEP, 1)[-1])
206
+ # ADR-0042 a nested @objectRef resolves in the DECLARING field's package
207
+ # (correct for a field.object inherited via extends across packages); an FQN
208
+ # resolves exactly. NO bare-tail short-name fallback that would bind a same-named
209
+ # VO in the wrong package on a cross-package collision (#191). The declaring
210
+ # package is taken from the parent object's resolution key so it is correct for
211
+ # both loaded trees (file_default_package) and programmatic trees (root package).
212
+ referrer_pkg = _pkg_of(field.parent) if field.parent is not None else ""
213
+ target = resolve_object_ref(root, ref, referrer_pkg)
198
214
  if target is None:
199
215
  return _fallback_type(field)
200
216
  nested_class = payload_class_name(target.name)
@@ -62,7 +62,8 @@ from metaobjects.render.verify import (
62
62
  PayloadField,
63
63
  verify,
64
64
  )
65
- from metaobjects.shared.base_types import TYPE_FIELD, TYPE_OBJECT, TYPE_TEMPLATE
65
+ from metaobjects.naming_refs import resolve_object_ref
66
+ from metaobjects.shared.base_types import TYPE_FIELD, TYPE_TEMPLATE
66
67
  from metaobjects.shared.separators import PACKAGE_SEP
67
68
 
68
69
  _GENERATOR_NAME = "render-helper-generator"
@@ -81,30 +82,34 @@ def _py_str(s: str) -> str:
81
82
  # ---------------------------------------------------------------------------
82
83
 
83
84
 
84
- def _resolve_nested_object_ref(root: MetaData, reference: str) -> MetaObject | None:
85
+ def _pkg_of(node: MetaData) -> str:
86
+ """The effective package of an object — its ``resolution_key()`` minus the
87
+ trailing ``::<name>`` ("" for a root-level object). Derived from the resolution
88
+ key so it is correct for BOTH loaded trees (file_default_package) and
89
+ programmatically-built trees (package only on the root, folded via the ancestor
90
+ walk in ``resolution_key()``)."""
91
+ key = node.resolution_key()
92
+ i = key.rfind(PACKAGE_SEP)
93
+ return "" if i == -1 else key[:i]
94
+
95
+
96
+ def _resolve_nested_object_ref(
97
+ root: MetaData, reference: str, referrer_pkg: str
98
+ ) -> MetaObject | None:
85
99
  """Resolve a ``field.object``'s ``@objectRef`` to its target ``object.value``.
86
100
 
87
- ADR-0041: a FULLY-QUALIFIED ref (contains ``::``) resolves EXACTLY on the
88
- package-qualified name (``resolution_key()``/``fqn()``) never a bare-tail
89
- fallback that would bind a same-named ``object.value`` in the WRONG package on a
90
- cross-package short-name collision. A bare ref still matches by short name
91
- (first-wins). Mirrors the Java/Kotlin ``resolveNestedObjectRef`` + TS
92
- ``refMatchesObject``."""
101
+ ADR-0042: package-local — an FQN ref (contains ``::``) resolves EXACTLY on the
102
+ package-qualified name; a bare ref resolves in the referrer's package FIRST
103
+ (else a root-level object), never a same-named ``object.value`` in another
104
+ package via a bare-tail fallback. *referrer_pkg* is the DECLARING field's
105
+ package (which differs from the VO's when the field is inherited via extends
106
+ from an abstract VO in another package). Shares the single ``resolve_object_ref``
107
+ matcher. Mirrors the TS ``findObject`` in payload-field-tree.ts."""
93
108
  if not reference:
94
109
  return None
95
- fqn = PACKAGE_SEP in reference
96
- ref_short = reference.rsplit(PACKAGE_SEP, 1)[-1]
97
- # ADR-0039 sanctioned own: top-level scan on the loader ROOT (never extended, own == effective)
98
- for child in root.own_children():
99
- if child.type != TYPE_OBJECT or not isinstance(child, MetaObject):
100
- continue
101
- if child.sub_type != OBJECT_SUBTYPE_VALUE:
102
- continue
103
- if fqn:
104
- if child.resolution_key() == reference or child.fqn() == reference:
105
- return child
106
- elif child.name.rsplit(PACKAGE_SEP, 1)[-1] == ref_short:
107
- return child
110
+ target = resolve_object_ref(root, reference, referrer_pkg)
111
+ if target is not None and target.sub_type == OBJECT_SUBTYPE_VALUE:
112
+ return target # type: ignore[return-value]
108
113
  return None
109
114
 
110
115
 
@@ -118,6 +123,10 @@ def _derive_payload_field_tree(
118
123
  if vo is None or vo.resolution_key() in seen:
119
124
  return []
120
125
  next_seen = seen | {vo.resolution_key()}
126
+ # A nested @objectRef resolves in the FIELD's own declaring package (below),
127
+ # which differs from this VO's when the field is inherited via extends from an
128
+ # abstract VO in another package (the bare ref was authored there).
129
+ vo_pkg = _pkg_of(vo)
121
130
  fields: list[PayloadField] = []
122
131
  for f in vo.children():
123
132
  if f.type != TYPE_FIELD or not isinstance(f, MetaField):
@@ -125,7 +134,8 @@ def _derive_payload_field_tree(
125
134
  if f.sub_type == fc.FIELD_SUBTYPE_OBJECT:
126
135
  ref = f.attrs().get(fc.FIELD_ATTR_OBJECT_REF)
127
136
  if isinstance(ref, str) and ref:
128
- target = _resolve_nested_object_ref(root, ref)
137
+ field_pkg = _pkg_of(f.parent) if f.parent is not None else vo_pkg
138
+ target = _resolve_nested_object_ref(root, ref, field_pkg)
129
139
  if target is not None and target.sub_type == OBJECT_SUBTYPE_VALUE:
130
140
  children = _derive_payload_field_tree(root, target, next_seen)
131
141
  fields.append(PayloadField(f.name, children))
@@ -152,16 +162,20 @@ def _field_tree_literal(fields: list[PayloadField]) -> str:
152
162
 
153
163
 
154
164
  def _resolve_payload_vo(root: MetaData, payload_ref: str) -> MetaObject | None:
155
- """``@payloadRef`` must resolve to an ``object.value`` (same contract as the
156
- parser/prompt generators). Matches a value-object child by short name OR by the
157
- last segment of a fully-qualified ``a::b::Name`` ref (FR-026 expands refs to FQN,
158
- while the child node still carries the short ``name``)."""
159
- ref_short = payload_ref.rsplit("::", 1)[-1]
165
+ """``@payloadRef`` must resolve to an ``object.value``. Package-local (ADR-0042):
166
+ the referrer's own package first (else a root-level object), FQN exact. The
167
+ referrer package is derived from the resolved match's own resolution key, so this
168
+ keeps the same behavior for the single-package + FQN codegen fixtures while never
169
+ binding a same-named VO in the wrong package (the nested @objectRef path is the
170
+ one #191 named — see _resolve_nested_object_ref). Matches a value-object child by
171
+ the package-folded resolution key OR the bare short name (FR-026 expands refs to
172
+ FQN, while the child node still carries the short ``name``)."""
173
+ ref_short = payload_ref.rsplit(PACKAGE_SEP, 1)[-1]
160
174
  # ADR-0039 sanctioned own: top-level scan on the loader ROOT (never extended, own == effective)
161
175
  for child in root.own_children():
162
- if child.type != TYPE_OBJECT or not isinstance(child, MetaObject):
176
+ if not isinstance(child, MetaObject) or child.sub_type != OBJECT_SUBTYPE_VALUE:
163
177
  continue
164
- if child.sub_type == OBJECT_SUBTYPE_VALUE and child.name in (payload_ref, ref_short):
178
+ if child.resolution_key() == payload_ref or child.name == ref_short:
165
179
  return child
166
180
  return None
167
181
 
@@ -43,10 +43,12 @@ from metaobjects.codegen.generator import EmittedFile, GenContext, Generator, pe
43
43
  from metaobjects.codegen.generators.m2m_codegen import (
44
44
  M2mDescriptor,
45
45
  build_object_index,
46
+ pk_field_name,
46
47
  resolve_m2m_descriptors,
47
48
  )
48
49
  from metaobjects.codegen.generators.tph_plan import TphPlan, is_tph_subtype, tph_plan_for
49
50
  from metaobjects.codegen.instance_artifacts import emits_instance_artifacts
51
+ from metaobjects.codegen.type_map import PyType, py_type_for
50
52
  from metaobjects.meta.core.field import field_constants as fc
51
53
  from metaobjects.meta.core.field.meta_field import MetaField
52
54
  from metaobjects.meta.core.identity.identity_constants import (
@@ -87,6 +89,23 @@ def _scalar_fields(entity: MetaObject) -> list[MetaField]:
87
89
  return [f for f in entity.fields() if f.sub_type != fc.FIELD_SUBTYPE_OBJECT]
88
90
 
89
91
 
92
+ def _pk_py_type(entity: MetaObject) -> PyType:
93
+ """The Python type of the entity's primary-key path/id parameter, derived
94
+ from the PK field's declared subtype via ``type_map.py_type_for`` — the same
95
+ mapper the Pydantic entity model uses, so ``field.uuid`` binds ``uuid.UUID``
96
+ on the route exactly as it does on the model (mirrors the C#
97
+ RoutesGenerator's ``CSharpNaming.ScalarFor(pkField.SubType)``).
98
+
99
+ Composite PK → ``@fields[0]`` (the TS ``getPkInfo`` behavior); no primary
100
+ identity / unresolvable field → ``int`` (the ``field.long`` default).
101
+ """
102
+ name = pk_field_name(entity)
103
+ pk_field = next((f for f in entity.fields() if f.name == name), None)
104
+ if pk_field is None:
105
+ return PyType("int")
106
+ return py_type_for(pk_field)
107
+
108
+
90
109
  @dataclass(frozen=True)
91
110
  class ReverseFk:
92
111
  """One FK an entity ``E`` holds (ADR-0038): the FK FIELD name on ``E`` and the
@@ -140,13 +159,15 @@ class RouterGenerator:
140
159
 
141
160
  Override points:
142
161
 
143
- * ``_emit_repository_protocol(repo_class, m2m)`` — the consumer-implemented
144
- ``Repository`` ``Protocol`` block (CRUD finders + M:N ``find_related_*``).
162
+ * ``_emit_repository_protocol(repo_class, m2m, pk_type)`` — the consumer-
163
+ implemented ``Repository`` ``Protocol`` block (CRUD finders + M:N
164
+ ``find_related_*``); ``pk_type`` is the PK's Python annotation text.
145
165
  * ``_emit_reverse_finders(entity)`` — the ADR-0038 reverse-FK finder pair
146
166
  (``find_<e_plural>_by_<fk_segment>`` + ``…_in``) appended to the ``Protocol``.
147
167
  * ``_emit_route_handler(name, ...)`` — the CRUD route handlers (list / get /
148
168
  create / update / delete), keyed by ``name``.
149
- * ``_emit_m2m_route(d, snake, pk_param, repo_class)`` — one M:N traversal route.
169
+ * ``_emit_m2m_route(d, snake, pk_param, pk_type, repo_class)`` — one M:N
170
+ traversal route.
150
171
  * ``render_router(entity, object_index)`` — the whole module (last resort).
151
172
 
152
173
  Skips entities without a ``source.rdb`` child and read-only kinds
@@ -156,11 +177,12 @@ class RouterGenerator:
156
177
  name = "router-generator"
157
178
 
158
179
  def _emit_repository_protocol(
159
- self, repo_class: str, m2m: list[M2mDescriptor]
180
+ self, repo_class: str, m2m: list[M2mDescriptor], pk_type: str
160
181
  ) -> list[str]:
161
182
  """The repository ``Protocol`` block. Returns/accepts ``Any`` so this module
162
- stays decoupled from the entity-model import. Override to add custom finder
163
- signatures or change the seam shape."""
183
+ stays decoupled from the entity-model import; *pk_type* is the PK's Python
184
+ annotation text (metadata-derived e.g. ``uuid.UUID`` / ``int`` / ``str``).
185
+ Override to add custom finder signatures or change the seam shape."""
164
186
  lines: list[str] = [
165
187
  f"class {repo_class}(Protocol):",
166
188
  ' """GENERATED — consumer implements with their preferred persistence layer."""',
@@ -172,14 +194,14 @@ class RouterGenerator:
172
194
  " filters: list[FilterPredicate],",
173
195
  " ) -> list[Any]: ...",
174
196
  " def count(self, filters: list[FilterPredicate]) -> int: ...",
175
- " def find_by_id(self, id: int) -> Any | None: ...",
197
+ f" def find_by_id(self, id: {pk_type}) -> Any | None: ...",
176
198
  " def create(self, dto: Any) -> Any: ...",
177
- " def update(self, id: int, dto: Any) -> Any | None: ...",
178
- " def delete(self, id: int) -> bool: ...",
199
+ f" def update(self, id: {pk_type}, dto: Any) -> Any | None: ...",
200
+ f" def delete(self, id: {pk_type}) -> bool: ...",
179
201
  ]
180
202
  for d in m2m:
181
203
  lines.append(
182
- f" def find_related_{d.relation_name}(self, id: int) -> list[Any]: ..."
204
+ f" def find_related_{d.relation_name}(self, id: {pk_type}) -> list[Any]: ..."
183
205
  )
184
206
  return lines
185
207
 
@@ -212,6 +234,7 @@ class RouterGenerator:
212
234
  snake: str,
213
235
  plural: str,
214
236
  pk_param: str,
237
+ pk_type: str,
215
238
  repo_class: str,
216
239
  fields_const: str,
217
240
  ops_const: str,
@@ -251,7 +274,7 @@ class RouterGenerator:
251
274
  return [
252
275
  f'@router.get("/{{{pk_param}}}")',
253
276
  f"def get_{snake}(",
254
- f" {pk_param}: int,",
277
+ f" {pk_param}: {pk_type},",
255
278
  f" repo: Annotated[{repo_class}, Depends(get_repository)],",
256
279
  ") -> Any:",
257
280
  f" row = repo.find_by_id({pk_param})",
@@ -273,7 +296,7 @@ class RouterGenerator:
273
296
  f'@router.patch("/{{{pk_param}}}")',
274
297
  f'@router.put("/{{{pk_param}}}")',
275
298
  f"def update_{snake}(",
276
- f" {pk_param}: int,",
299
+ f" {pk_param}: {pk_type},",
277
300
  " dto: dict[str, Any],",
278
301
  f" repo: Annotated[{repo_class}, Depends(get_repository)],",
279
302
  ") -> Any:",
@@ -286,7 +309,7 @@ class RouterGenerator:
286
309
  return [
287
310
  f'@router.delete("/{{{pk_param}}}", status_code=status.HTTP_204_NO_CONTENT)',
288
311
  f"def delete_{snake}(",
289
- f" {pk_param}: int,",
312
+ f" {pk_param}: {pk_type},",
290
313
  f" repo: Annotated[{repo_class}, Depends(get_repository)],",
291
314
  ") -> None:",
292
315
  f" if not repo.delete({pk_param}):",
@@ -295,7 +318,7 @@ class RouterGenerator:
295
318
  raise ValueError(f"unknown route handler '{name}'")
296
319
 
297
320
  def _emit_m2m_route(
298
- self, d: M2mDescriptor, snake: str, pk_param: str, repo_class: str
321
+ self, d: M2mDescriptor, snake: str, pk_param: str, pk_type: str, repo_class: str
299
322
  ) -> list[str]:
300
323
  """One M:N traversal route ``GET /{id}/<relationName>`` — a thin pass-through
301
324
  to the repository's ``find_related_*`` finder. Override to add filtering /
@@ -303,7 +326,7 @@ class RouterGenerator:
303
326
  return [
304
327
  f'@router.get("/{{{pk_param}}}/{d.relation_name}")',
305
328
  f"def list_{snake}_{d.relation_name}(",
306
- f" {pk_param}: int,",
329
+ f" {pk_param}: {pk_type},",
307
330
  f" repo: Annotated[{repo_class}, Depends(get_repository)],",
308
331
  ") -> list[Any]:",
309
332
  f" return repo.find_related_{d.relation_name}({pk_param})",
@@ -343,6 +366,10 @@ class RouterGenerator:
343
366
  snake = _snake_case(short_name)
344
367
  plural = _plural_lowercase(short_name)
345
368
  pk_param = f"{snake}_id"
369
+ # PK type from the BASE's declared primary key (subtypes share the
370
+ # base's single table — mirrors the C# TPH pkType threading).
371
+ pk = _pk_py_type(entity)
372
+ pk_type = pk.expr
346
373
  repo_class = f"{short_name}Repository"
347
374
  upper = short_name.upper()
348
375
  fields_const = f"{upper}_FILTER_FIELDS"
@@ -371,6 +398,10 @@ class RouterGenerator:
371
398
  )
372
399
  parts.append("from __future__ import annotations")
373
400
  parts.append("")
401
+ for import_line in sorted(pk.imports):
402
+ parts.append(import_line)
403
+ if pk.imports:
404
+ parts.append("")
374
405
  parts.append("from typing import Annotated, Any, Protocol")
375
406
  parts.append("")
376
407
  parts.append("from fastapi import APIRouter, Depends, Query, Request, status")
@@ -420,10 +451,10 @@ class RouterGenerator:
420
451
  parts.append(" filters: list[FilterPredicate],")
421
452
  parts.append(" ) -> list[Any]: ...")
422
453
  parts.append(" def count(self, subtype: str | None, filters: list[FilterPredicate]) -> int: ...")
423
- parts.append(" def find_by_id(self, subtype: str | None, id: int) -> Any | None: ...")
454
+ parts.append(f" def find_by_id(self, subtype: str | None, id: {pk_type}) -> Any | None: ...")
424
455
  parts.append(" def create(self, subtype: str, dto: Any) -> Any: ...")
425
- parts.append(" def update(self, subtype: str, id: int, dto: Any) -> Any | None: ...")
426
- parts.append(" def delete(self, subtype: str, id: int) -> bool: ...")
456
+ parts.append(f" def update(self, subtype: str, id: {pk_type}, dto: Any) -> Any | None: ...")
457
+ parts.append(f" def delete(self, subtype: str, id: {pk_type}) -> bool: ...")
427
458
  parts.append("")
428
459
  parts.append("")
429
460
  parts.append(f"def get_repository() -> {repo_class}:")
@@ -445,7 +476,7 @@ class RouterGenerator:
445
476
  ") -> Any:",
446
477
  ]
447
478
 
448
- # --- Per-subtype routes FIRST (literal segments match before /{id:int}). ---
479
+ # --- Per-subtype routes FIRST (literal segments match before /{id}). ---
449
480
  for st in plan.subtypes:
450
481
  seg = st.route_segment
451
482
  val = st.value
@@ -464,7 +495,7 @@ class RouterGenerator:
464
495
  parts.append("")
465
496
  parts.append(f'@router.get("/{seg}/{{{pk_param}}}")')
466
497
  parts.append(f"def get_{plural}_{sfx}(")
467
- parts.append(f" {pk_param}: int,")
498
+ parts.append(f" {pk_param}: {pk_type},")
468
499
  parts.append(f" repo: Annotated[{repo_class}, Depends(get_repository)],")
469
500
  parts.append(") -> Any:")
470
501
  parts.append(f' row = repo.find_by_id("{val}", {pk_param})')
@@ -476,7 +507,7 @@ class RouterGenerator:
476
507
  parts.append(f'@router.patch("/{seg}/{{{pk_param}}}")')
477
508
  parts.append(f'@router.put("/{seg}/{{{pk_param}}}")')
478
509
  parts.append(f"def update_{plural}_{sfx}(")
479
- parts.append(f" {pk_param}: int,")
510
+ parts.append(f" {pk_param}: {pk_type},")
480
511
  parts.append(" dto: dict[str, Any],")
481
512
  parts.append(f" repo: Annotated[{repo_class}, Depends(get_repository)],")
482
513
  parts.append(") -> Any:")
@@ -488,7 +519,7 @@ class RouterGenerator:
488
519
  parts.append("")
489
520
  parts.append(f'@router.delete("/{seg}/{{{pk_param}}}", status_code=status.HTTP_204_NO_CONTENT)')
490
521
  parts.append(f"def delete_{plural}_{sfx}(")
491
- parts.append(f" {pk_param}: int,")
522
+ parts.append(f" {pk_param}: {pk_type},")
492
523
  parts.append(f" repo: Annotated[{repo_class}, Depends(get_repository)],")
493
524
  parts.append(") -> None:")
494
525
  parts.append(f' if not repo.delete("{val}", {pk_param}):')
@@ -496,14 +527,14 @@ class RouterGenerator:
496
527
  parts.append("")
497
528
  parts.append("")
498
529
 
499
- # --- Polymorphic base routes LAST (so /{id:int} doesn't shadow /<segment>). ---
530
+ # --- Polymorphic base routes LAST (so /{id} doesn't shadow /<segment>). ---
500
531
  parts.extend(list_sig(f"list_{plural}", ""))
501
532
  parts.extend(self._emit_tph_list_body("None", fields_const, ops_const))
502
533
  parts.append("")
503
534
  parts.append("")
504
535
  parts.append(f'@router.get("/{{{pk_param}}}")')
505
536
  parts.append(f"def get_{snake}(")
506
- parts.append(f" {pk_param}: int,")
537
+ parts.append(f" {pk_param}: {pk_type},")
507
538
  parts.append(f" repo: Annotated[{repo_class}, Depends(get_repository)],")
508
539
  parts.append(") -> Any:")
509
540
  parts.append(f" row = repo.find_by_id(None, {pk_param})")
@@ -560,6 +591,8 @@ class RouterGenerator:
560
591
  snake = _snake_case(short_name)
561
592
  plural = _plural_lowercase(short_name)
562
593
  pk_param = f"{snake}_id"
594
+ pk = _pk_py_type(entity)
595
+ pk_type = pk.expr
563
596
  repo_class = f"{short_name}Repository"
564
597
  sort_fields = [f.name for f in _scalar_fields(entity)]
565
598
  upper = short_name.upper()
@@ -578,6 +611,10 @@ class RouterGenerator:
578
611
  )
579
612
  parts.append("from __future__ import annotations")
580
613
  parts.append("")
614
+ for import_line in sorted(pk.imports):
615
+ parts.append(import_line)
616
+ if pk.imports:
617
+ parts.append("")
581
618
  parts.append("from typing import Annotated, Any, Protocol")
582
619
  parts.append("")
583
620
  parts.append("from fastapi import APIRouter, Depends, Query, Request, status")
@@ -616,7 +653,7 @@ class RouterGenerator:
616
653
  parts.append(" return _SortClause(field=parts[0], direction=direction)")
617
654
  parts.append("")
618
655
  parts.append("")
619
- proto_lines = self._emit_repository_protocol(repo_class, m2m)
656
+ proto_lines = self._emit_repository_protocol(repo_class, m2m, pk_type)
620
657
  proto_lines.extend(self._emit_reverse_finders(entity))
621
658
  parts.extend(proto_lines)
622
659
  parts.append("")
@@ -631,6 +668,7 @@ class RouterGenerator:
631
668
  snake=snake,
632
669
  plural=plural,
633
670
  pk_param=pk_param,
671
+ pk_type=pk_type,
634
672
  repo_class=repo_class,
635
673
  fields_const=fields_const,
636
674
  ops_const=ops_const,
@@ -649,7 +687,7 @@ class RouterGenerator:
649
687
  # array for an orphan source — never a 404).
650
688
  for d in m2m:
651
689
  parts.append("")
652
- parts.extend(self._emit_m2m_route(d, snake, pk_param, repo_class))
690
+ parts.extend(self._emit_m2m_route(d, snake, pk_param, pk_type, repo_class))
653
691
  parts.append("")
654
692
 
655
693
  return "\n".join(parts)
@@ -374,6 +374,22 @@ for _def in core_provider._defs: # noqa: SLF001 (provider build-time enrichment
374
374
  )
375
375
  break
376
376
 
377
+ # ADR-0042 — a field.object / field.map @objectRef must RESOLVE (a dangling target
378
+ # fails the load, closing the gap #191 surfaced as a misleading downstream error).
379
+ # The required-attr pass owns absence (ERR_OBJECT_FIELD_WITHOUT_OBJECT_REF); this
380
+ # reference descriptor fires only when @objectRef is present but resolves to nothing
381
+ # → ERR_UNRESOLVED_OBJECT_REF. Mirrors the TS core-types.ts registerCoreTypeDefs.
382
+ for _def in core_provider._defs: # noqa: SLF001 (provider build-time enrichment)
383
+ if _def.type == TYPE_FIELD and _def.sub_type in (
384
+ fc.FIELD_SUBTYPE_OBJECT,
385
+ fc.FIELD_SUBTYPE_MAP,
386
+ ):
387
+ _def.references.append(
388
+ ReferenceDescriptor(
389
+ FIELD_ATTR_OBJECT_REF, TYPE_OBJECT, None, False, "ERR_UNRESOLVED_OBJECT_REF"
390
+ )
391
+ )
392
+
377
393
  # field.enum — dedicated registration with required @values attr.
378
394
  # Inherits every common field attr (column / required / unique / default /
379
395
  # maxLength / filterable / sortable / etc.) so the D2 type-coercion guard
@@ -138,17 +138,13 @@ class ErrorCode(str, Enum):
138
138
  # emit this yet (the T6 guard is deferred — like TS, it belongs in the parser);
139
139
  # the enum tracks the shared corpus code so resolution/desugar stay aligned.
140
140
  ERR_RELATIVE_REF_IN_CANONICAL = "ERR_RELATIVE_REF_IN_CANONICAL"
141
- # ADR-0041cross-package reference resolution contract. A BARE object
142
- # reference (no ``::``) that names an object present in MORE THAN ONE package,
143
- # with NO match in the referrer's own package, is ambiguous the author must
144
- # qualify it with the package (FQN). Applies to every object-ref-bearing attr
145
- # (@objectRef / @references / @from / @of / @via heads / @parameterRef /
146
- # @payloadRef / @responseRef). An FQN ref resolves exactly and is never
147
- # ambiguous; a bare ref that matches the referrer's own package, or exactly one
148
- # package anywhere, resolves fine. ``extends`` is intentionally NOT covered
149
- # (its same-package/root-strict super-resolver yields ERR_UNRESOLVED_SUPER on a
150
- # bare cross-package miss, not ambiguity).
151
- ERR_AMBIGUOUS_REF = "ERR_AMBIGUOUS_REF"
141
+ # ADR-0042a field.object / field.map @objectRef does not resolve to any
142
+ # object in the loaded tree (a dangling target). Bare refs resolve
143
+ # package-locally (referrer's package, else root-level); FQN refs resolve
144
+ # exactly a bare cross-package ref no longer binds elsewhere. Supersedes the
145
+ # retired ADR-0041 ERR_AMBIGUOUS_REF (bare = package-local ambiguity is
146
+ # unreachable, so every unresolved ref fails closed with its per-attr code).
147
+ ERR_UNRESOLVED_OBJECT_REF = "ERR_UNRESOLVED_OBJECT_REF"
152
148
  # FR-033 — strict structural-placement vocabulary. ERR_CHILD_NOT_ALLOWED: a
153
149
  # structural child (field/identity/source/validator/… — not an attr) is placed
154
150
  # under a parent whose registered childRules do not admit it (the structural
@@ -12,8 +12,10 @@ from ..errors import ErrorCode, MetaError
12
12
  from ..meta.core.object.meta_object import MetaObject
13
13
  from ..meta.meta_data import MetaData
14
14
  from ..meta.meta_root import MetaRoot
15
+ from ..naming_refs import did_you_mean_hint
15
16
  from ..registry import TypeRegistry
16
17
  from ..shared.base_types import TYPE_OBJECT
18
+ from ..shared.separators import PACKAGE_SEP
17
19
 
18
20
 
19
21
  class SymbolTable:
@@ -29,19 +31,29 @@ class SymbolTable:
29
31
  # extended, own == effective) — mirrors the TS validation-registry.
30
32
  for child in root.own_children():
31
33
  if child.type == TYPE_OBJECT and isinstance(child, MetaObject):
32
- if child.name:
33
- t._index[child.name] = child
34
- t._index[child.fqn()] = child
34
+ # ADR-0042: key by the canonical resolution key ONLY (the FQN, or
35
+ # the bare name for a root-level/empty-package object) — NO bare-name
36
+ # fallback, so a bare ref never binds a same-named object in another
37
+ # package. Mirrors the TS validation-registry symbol table.
35
38
  t._index[child.resolution_key()] = child
36
39
  return t
37
40
 
38
- def resolve_object(self, reference: str) -> MetaData | None:
39
- return self._index.get(reference)
41
+ def resolve_object(self, reference: str, referrer_pkg: str) -> MetaData | None:
42
+ """ADR-0042 package-local resolution: FQN → exact resolution-key match;
43
+ bare → the referrer's own package (``<referrer_pkg>::<ref>``), else a
44
+ root-level object. Mirrors the TS ``resolveObject``."""
45
+ if PACKAGE_SEP in reference:
46
+ return self._index.get(reference)
47
+ local_key = (
48
+ f"{referrer_pkg}{PACKAGE_SEP}{reference}" if referrer_pkg else reference
49
+ )
50
+ return self._index.get(local_key) or self._index.get(reference)
40
51
 
41
52
 
42
53
  class ValidationContext:
43
- def __init__(self, symbols: SymbolTable) -> None:
54
+ def __init__(self, symbols: SymbolTable, root: MetaData) -> None:
44
55
  self.symbols = symbols
56
+ self.root = root
45
57
  self.errors: list[MetaError] = []
46
58
 
47
59
  def error(self, code: str, node: MetaData, message: str) -> None:
@@ -55,12 +67,23 @@ class ValidationContext:
55
67
 
56
68
 
57
69
  def run(root: MetaRoot, registry: TypeRegistry) -> list[MetaError]:
58
- ctx = ValidationContext(SymbolTable.build(root))
59
- _walk(root, registry, ctx)
70
+ ctx = ValidationContext(SymbolTable.build(root), root)
71
+ _walk(root, registry, ctx, "")
60
72
  return ctx.errors
61
73
 
62
74
 
63
- def _walk(node: MetaData, registry: TypeRegistry, ctx: ValidationContext) -> None:
75
+ def _walk(
76
+ node: MetaData, registry: TypeRegistry, ctx: ValidationContext, referrer_pkg: str
77
+ ) -> None:
78
+ # ADR-0042: a top-level object establishes the package context for its subtree;
79
+ # nested ref-bearing nodes (relationship/field.object/identity.reference) resolve
80
+ # BARE refs against it. Nested nodes carry no `package`, so they inherit the
81
+ # enclosing object's (via file_default_package, else the threaded context).
82
+ pkg = (
83
+ (node.package or node.file_default_package or referrer_pkg)
84
+ if node.type == TYPE_OBJECT
85
+ else referrer_pkg
86
+ )
64
87
  type_def = registry.find(node.type, node.sub_type)
65
88
  if type_def is not None:
66
89
  for desc in type_def.references:
@@ -72,7 +95,8 @@ def _walk(node: MetaData, registry: TypeRegistry, ctx: ValidationContext) -> Non
72
95
  if not isinstance(raw, str) or raw == "":
73
96
  continue # absence is the required-attr pass's job
74
97
  entity_ref = raw.split(".", 1)[0] if desc.dotted_field_path else raw
75
- target = ctx.symbols.resolve_object(entity_ref)
98
+ # ADR-0042: bare refs resolve package-local against the enclosing object.
99
+ target = ctx.symbols.resolve_object(entity_ref, pkg)
76
100
  # Qualify the node name with its owning entity (e.g. "Order.items") so the error
77
101
  # is locatable from the message alone, not just the source envelope.
78
102
  qname = f"{node.parent.name}.{node.name}" if node.parent and node.parent.name else node.name
@@ -80,7 +104,7 @@ def _walk(node: MetaData, registry: TypeRegistry, ctx: ValidationContext) -> Non
80
104
  ctx.error(
81
105
  desc.error_code, node,
82
106
  f'{node.type}.{node.sub_type} "{qname}" @{desc.attr} "{raw}" '
83
- f"does not resolve to an object.",
107
+ f"does not resolve to an object.{did_you_mean_hint(ctx.root, entity_ref)}",
84
108
  )
85
109
  elif target.type != desc.target_type or (
86
110
  desc.target_sub_type is not None and target.sub_type != desc.target_sub_type
@@ -101,4 +125,4 @@ def _walk(node: MetaData, registry: TypeRegistry, ctx: ValidationContext) -> Non
101
125
  # node once at its declaration site (own children); inherited nodes are
102
126
  # validated where they are declared. Mirrors the TS ``node.ownChildren()`` walk.
103
127
  for child in node.own_children():
104
- _walk(child, registry, ctx)
128
+ _walk(child, registry, ctx, pkg)