metaobjects 1.0.3__tar.gz → 1.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {metaobjects-1.0.3 → metaobjects-1.0.4}/PKG-INFO +1 -1
- {metaobjects-1.0.3 → metaobjects-1.0.4}/pyproject.toml +1 -1
- {metaobjects-1.0.3 → metaobjects-1.0.4}/scripts/generate_embedded_library.py +36 -3
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/cli.py +99 -25
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/constants.py +11 -2
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generator_registry.py +38 -5
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/router_generator.py +12 -8
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/trace_helper_generator.py +31 -10
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/config/dependencies.py +82 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/errors.py +9 -0
- metaobjects-1.0.4/src/metaobjects/library/embedded_library.py +22 -0
- metaobjects-1.0.4/src/metaobjects/library/library_sources.py +191 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/merge.py +17 -2
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validation_passes.py +186 -24
- metaobjects-1.0.4/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +347 -0
- metaobjects-1.0.4/src/metaobjects/meta/core/relationship/relationship_references.py +166 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/meta_data.py +6 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/naming_refs.py +11 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/relationship.json +8 -8
- metaobjects-1.0.4/tests/codegen/gen_suite.py +16 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/extends/expected/BaseEntity.py +1 -1
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/extends/expected/Program.py +1 -1
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +1 -1
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/nested-array/expected/PostBrief.py +1 -1
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/scalars/expected/Metric.py +1 -1
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/scalars/expected/Report.py +1 -1
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/vanilla/expected/Subscriber.py +1 -1
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli.py +43 -42
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_config_gen.py +11 -10
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_config_verify.py +35 -34
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_dependencies.py +11 -10
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_providers.py +7 -5
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_registry.py +3 -2
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_staleness_nudge.py +6 -5
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_verify_strict.py +8 -7
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_cli_verify_subverbs.py +21 -20
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_gen_state_keying.py +3 -2
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_m2m_codegen.py +41 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_names_generator.py +7 -6
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_reverse_finders.py +89 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_trace_helper_generator.py +47 -4
- metaobjects-1.0.4/tests/config/test_library_package_guard.py +112 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_generator_registry_conformance.py +31 -1
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_llm_call_trace.py +3 -2
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/loader/test_shipped_library_ai.py +13 -2
- metaobjects-1.0.4/tests/unit/test_derive_m2m_declaring_entity.py +358 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_llm_recorder.py +6 -3
- metaobjects-1.0.4/tests/unit/test_relationship_m2m_validation.py +557 -0
- metaobjects-1.0.4/tests/unit/test_relationship_references.py +203 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/uv.lock +1 -1
- metaobjects-1.0.3/src/metaobjects/library/embedded_library.py +0 -11
- metaobjects-1.0.3/src/metaobjects/library/library_sources.py +0 -99
- metaobjects-1.0.3/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -185
- {metaobjects-1.0.3 → metaobjects-1.0.4}/.gitignore +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/LICENSE +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/README.md +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/hatch_build.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/agent_context/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/agent_context/scaffold.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/apidocs/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/apidocs/api_model.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/apidocs/builder.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/apidocs/naming.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/apidocs/paths.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/apidocs/renderer.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/attr_class_map.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/KNOWN_GAPS.md +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/collision_names.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/config.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/extract_delegate_emitter.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/extract_schema_emitter.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/format.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/fr010_field_mapping.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/entity_model.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/extractor_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/find_inbound.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/fr019_shared_enum.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/m2m_codegen.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/names_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/output_parser_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/output_prompt_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/payload_vo_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/render_helper_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/template_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/instance_artifacts.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/metaobjects-config.schema.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/output_format_spec_emitter.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/overwrite_policy.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/project_config.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/runner.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/runtime/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/template_codegen/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/template_codegen/output_pattern.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/template_codegen/template_data.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/template_codegen/template_spec.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/type_map.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/config/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/config/neutral_config.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/config/source_resolver.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/core_types.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/datatype.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/documentation/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/documentation/doc_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/documentation/doc_provider.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/documentation/doc_schema.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/library/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/meta_data_loader.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/registered_validation.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/sources/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/sources/directory_source.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/sources/file_source.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/sources/uri_source.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validate_discriminator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validate_enum_normalize_ambiguity.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validate_field_mutability.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validate_source_escapes.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validate_source_parameter_ref.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/attr/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/attr/attr_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/attr/meta_attr.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/field/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/field/field_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/field/meta_field.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/identity/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/index/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/index/index_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/index/meta_index.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/meta_object.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/object_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/object_extract.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/object/value_object.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/requirement/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/requirement/meta_requirement.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/requirement/requirement_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/validator/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/core/validator/validator_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/meta_root.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/db/db_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/db/db_provider.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/origin/origin_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/source/meta_source.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/persistence/source/source_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/provider_extends.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/template/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/template/meta_template.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/template/prompt_provider.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/meta/template/template_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/naming.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/parser.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/parser_yaml.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/provider.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/py.typed +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/registry.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/registry_manifest.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/email_document.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/escapers.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/coerce.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/extract.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/extract_map.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/locate.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/normalize.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/strip.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/types.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/filesystem_provider.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/payload_accessors.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/prompt/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/prompt/prompt_field.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/prompt/prompt_style.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/renderer.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/render/verify.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/runtime/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/runtime/llm_recorder.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/runtime/n2m_resolver.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/runtime/object_manager.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/runtime/tph.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/scope.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/serializer_json.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/shared/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/shared/base_types.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/shared/separators.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/shared/structural.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/source/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/source/error_source.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/source/json_path.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/source/semantic_diff.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/source/yaml_positions.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/source_resolution.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/attr.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/db.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/documentation.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/field.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/identity.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/index.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/layout.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/object.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/origin.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/prompt.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/requirement.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/source.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/template.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/ui-web.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/ui.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/validator.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/spec_metamodel/view.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/super_resolve.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/validation_types.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/yaml_desugar.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/extends/meta.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/nested-array/meta.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/scalars/meta.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/golden/vanilla/meta.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_abstract_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_api_docs_builder.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_api_docs_paths.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_constants_config.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_entity_model.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_enum_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_extends_abstract_field_inheritance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_extract_tier_collision.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_extractor_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_filter_allowlist_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_format.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_fr010_nested_object_prompt.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_fr010_output_codegen.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_generator_extension_seams.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_golden.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_inherit_without_restate_gate.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_inheritance_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_instance_artifacts.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_names_extends_chain.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_no_magic_physical_names.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_origin_nullability.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_output_parser_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_overwrite_policy.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_overwrite_policy_hash.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_payload_vo_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_project_config.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_projection_compile.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_render_helper_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_render_helper_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_router_autoset.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_router_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_runner.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_source_resolution.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_sourceless_projection.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_template_data.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_template_generator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_template_output_pattern.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_template_scope_helpers.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_template_scope_walk.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_template_spec.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_tph_codegen.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_type_map.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_validation_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/codegen/test_write_through.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/config/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/config/test_dependencies.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/config/test_neutral_config.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/config/test_source_resolver.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/capabilities.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/conformance-expected-failures.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/conformance_adapter.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/corpus.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/expected_failures.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/fixture_discovery.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/navigator.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_dependency_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_extract_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_extract_object_verdict.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_fr010_loader_attrs.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_fr011_attrs.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_object_model_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_provider_composition_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_registry_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_runner_hardfail.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_scope_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_source_resolution_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_spec_metamodel_embed.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_strict_attr_load.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_template_codegen_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_template_generator_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/test_yaml_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/api_contract_assertions.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/api_contract_jsonb_server.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/api_contract_m2m_server.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/api_contract_server.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/generated_jsonb_app.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/generated_m2m_app.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/generated_router_app.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/generated_tph_app.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/meta_ai_trace.yaml +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/normalization.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/postgres_container.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/query_runner.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/scenarios.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_api_contract.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_api_contract_generated.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_api_contract_jsonb.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_api_contract_m2m.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_api_contract_m2m_generated.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_api_contract_tph_generated.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_generated_router_uuid_pk.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_normalization.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_query_scenarios.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/integration/test_runtime_return_types.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/loader/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/loader/test_abstract_subtype_authored.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/loader/test_enum_extends_values_conflict.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/loader/test_field_mutability_order.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/loader/test_template_payload_target_210.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/open_closed_proof_test.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_coerce.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_extract.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_extract_map.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_json_forgiving_reader.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_locate.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_model.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_normalize.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_strip.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/prompt/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/prompt/test_output_format_renderer.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_email_document.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_filesystem_provider.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_output_format_renderer_nested.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_output_prompt_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_render_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_render_max_chars.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_verify.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/render/test_verify_conformance.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/runtime/test_object_manager_enum_intvaluemap.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/runtime/test_object_manager_table_name.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_fr5c_merge_attribution.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_fr5d_reference_resolution.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_fr5e_database_source_shape.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_json_path.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_semantic_diff.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_source_on_node.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/source/test_yaml_positions.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/test_api_docs_accuracy.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/__init__.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_agent_context_staleness.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_capabilities.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_column_naming_strategy.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_common_attrs.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_core_types.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_effective_children_sibling_shadowing.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_effective_package.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_errors.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_field_enum.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_field_enum_intvaluemap.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_field_map_validation.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_file_source_id.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_index_lookup.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_loader.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_loader_bom.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_loader_class.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_merge.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_meta_attr.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_meta_data.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_meta_source.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_module_shortcuts.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_n2m_resolver.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_n2m_resolver_inherited.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_no_dead_config_fields.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_object_manager_autoset_stamping.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_object_manager_write_through.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_one_primary_source.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_parser.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_parser_yaml.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_provider.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_provider_extension.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_registry.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_registry_completeness.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_registry_extend.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_registry_sealed.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_relationship_referential_actions.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_resolution_key.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_serializer.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_serializer_shared_document.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_shared_constants.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_smoke.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_source_escapes.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_sources.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_strict_child_placement.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_super_resolve.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_template_toolcall.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_validation_attr_schema.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_validation_filter_values.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_validation_origin_195.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_validation_origin_paths.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_validation_sort_field.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_validation_warnings.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/tests/unit/test_write_coercion_arrays.py +0 -0
- {metaobjects-1.0.3 → metaobjects-1.0.4}/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.0.
|
|
3
|
+
Version: 1.0.4
|
|
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.0.
|
|
3
|
+
version = "1.0.4"
|
|
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"
|
|
@@ -52,10 +52,43 @@ def main() -> int:
|
|
|
52
52
|
if not entries:
|
|
53
53
|
raise SystemExit(f"no *.yaml found under {library_dir} — refusing to emit an empty library")
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
# The MANIFESTS ride the same embed, in their own map keyed by library NAME.
|
|
56
|
+
#
|
|
57
|
+
# Their own map rather than another entry in the ref map, because a ref is
|
|
58
|
+
# "path under library/ minus .yaml" and every reader appends ``.yaml`` back. Folding
|
|
59
|
+
# a ``.json`` into that would mean a special case at every call site in four ports.
|
|
60
|
+
manifests = []
|
|
61
|
+
missing = []
|
|
62
|
+
for d in sorted(p for p in library_dir.iterdir() if p.is_dir()):
|
|
63
|
+
manifest = d / "library.json"
|
|
64
|
+
if manifest.is_file():
|
|
65
|
+
manifests.append((d.name, manifest.read_text(encoding="utf-8")))
|
|
66
|
+
else:
|
|
67
|
+
missing.append(d.name)
|
|
68
|
+
|
|
69
|
+
# A library directory with no manifest is a build error, not a silently-skipped one:
|
|
70
|
+
# the manifest declares the library's LAYERS, and without it ``libraries: ["iam/db"]``
|
|
71
|
+
# resolves to nothing and the adopter gets an empty tree with no explanation.
|
|
72
|
+
if missing:
|
|
73
|
+
raise SystemExit(f"library director{'y' if len(missing) == 1 else 'ies'} with no library.json: {', '.join(missing)}")
|
|
57
74
|
|
|
58
|
-
|
|
75
|
+
body = "".join(f" {ref!r}: {text!r},\n" for ref, text in entries)
|
|
76
|
+
manifest_body = "".join(f" {name!r}: {text!r},\n" for name, text in manifests)
|
|
77
|
+
out_path.write_text(
|
|
78
|
+
HEADER
|
|
79
|
+
+ body
|
|
80
|
+
+ "}\n\n"
|
|
81
|
+
+ "#: Library NAME -> the exact text of its ``library.json`` manifest.\n"
|
|
82
|
+
+ "EMBEDDED_LIBRARY_MANIFESTS: dict[str, str] = {\n"
|
|
83
|
+
+ manifest_body
|
|
84
|
+
+ "}\n",
|
|
85
|
+
encoding="utf-8",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
print(
|
|
89
|
+
f"wrote {out_path.relative_to(root)} ({len(entries)} ref(s): "
|
|
90
|
+
f"{', '.join(r for r, _ in entries)}; {len(manifests)} manifest(s))"
|
|
91
|
+
)
|
|
59
92
|
return 0
|
|
60
93
|
|
|
61
94
|
|
|
@@ -53,7 +53,12 @@ from typing import Callable
|
|
|
53
53
|
|
|
54
54
|
from metaobjects import MetaDataLoader
|
|
55
55
|
from metaobjects.errors import ParseError
|
|
56
|
-
from metaobjects.config.dependencies import
|
|
56
|
+
from metaobjects.config.dependencies import (
|
|
57
|
+
Collection,
|
|
58
|
+
imported_from,
|
|
59
|
+
refuse_library_package_misuse,
|
|
60
|
+
refuse_unowned_packages,
|
|
61
|
+
)
|
|
57
62
|
from metaobjects.loader.meta_data_loader import LoadResult
|
|
58
63
|
from metaobjects.loader.sources import FileSource
|
|
59
64
|
from metaobjects.meta.core.object.meta_object import MetaObject
|
|
@@ -119,22 +124,29 @@ def _pkg_of(node: MetaData) -> str:
|
|
|
119
124
|
return "" if i == -1 else key[:i]
|
|
120
125
|
|
|
121
126
|
|
|
122
|
-
|
|
123
|
-
|
|
127
|
+
#: The error a run with no generator selection reports.
|
|
128
|
+
#:
|
|
129
|
+
#: There is no default suite. This port used to run EIGHT generators for a caller who
|
|
130
|
+
#: named none — entity, router, filter-allowlist, names, payload, output-parser,
|
|
131
|
+
#: output-prompt, extractor — which is a shape nobody chose. Java has never had a
|
|
132
|
+
#: default set and has been right all along; TypeScript and C# dropped theirs in the
|
|
133
|
+
#: same change.
|
|
134
|
+
#:
|
|
135
|
+
#: Deciding WHICH code an application needs belongs to whoever is building it —
|
|
136
|
+
#: increasingly an LLM working in the repo, which is well able to make that call given a
|
|
137
|
+
#: truthful catalog and is badly served by a default that pre-empts it. ``--list`` is
|
|
138
|
+
#: that catalog.
|
|
139
|
+
NO_GENERATORS_SELECTED = (
|
|
140
|
+
"gen: no generators selected. Nothing is generated until you choose it — "
|
|
141
|
+
"pass --generators <a,b,c>. See the catalog: metaobjects gen --list"
|
|
142
|
+
)
|
|
124
143
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
"""
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
filter_allowlist_generator(),
|
|
132
|
-
names_generator(),
|
|
133
|
-
payload_vo_generator(),
|
|
134
|
-
output_parser_generator(),
|
|
135
|
-
output_prompt_generator(),
|
|
136
|
-
extractor_generator(),
|
|
137
|
-
]
|
|
144
|
+
|
|
145
|
+
class NoGeneratorsSelectedError(ValueError):
|
|
146
|
+
"""Raised when a codegen run names no generator. Carries the usage message."""
|
|
147
|
+
|
|
148
|
+
def __init__(self) -> None:
|
|
149
|
+
super().__init__(NO_GENERATORS_SELECTED)
|
|
138
150
|
|
|
139
151
|
|
|
140
152
|
def _resolve_providers(specs: list[str] | None) -> tuple[list[object], list[str]]:
|
|
@@ -338,6 +350,11 @@ def _load_collection_result(
|
|
|
338
350
|
result = loader.load([*lib_sources, *sources])
|
|
339
351
|
if not result.errors:
|
|
340
352
|
refuse_unowned_packages(result.root, collection.imported_packages, collection.imported_nodes)
|
|
353
|
+
# FR-043 §3.4 / §3.5 — the same rule for a shipped LIBRARY's package, where the
|
|
354
|
+
# two ways to get it wrong are opposite: a node the library also declares (an
|
|
355
|
+
# ejected copy, still opted in) and one it does not (a new node in someone
|
|
356
|
+
# else's package).
|
|
357
|
+
refuse_library_package_misuse(result.root, libraries)
|
|
341
358
|
return result
|
|
342
359
|
|
|
343
360
|
|
|
@@ -507,7 +524,11 @@ def _run_suite(
|
|
|
507
524
|
# verify path (those pass gen_state_dir=None and record nothing at all).
|
|
508
525
|
baseline=baseline,
|
|
509
526
|
)
|
|
510
|
-
suite
|
|
527
|
+
# No default suite — see NO_GENERATORS_SELECTED. A caller that names none gets a
|
|
528
|
+
# usage error and an empty out dir, never a shape this CLI picked.
|
|
529
|
+
if not generators:
|
|
530
|
+
raise NoGeneratorsSelectedError
|
|
531
|
+
suite = generators
|
|
511
532
|
result = run_gen(config, root, generators=suite, entity_filter=entity_filter, select=select)
|
|
512
533
|
for warning in result.warnings:
|
|
513
534
|
print(f"warning: {warning}")
|
|
@@ -885,6 +906,11 @@ def _cmd_gen(args: argparse.Namespace) -> int:
|
|
|
885
906
|
for msg in gen_errors:
|
|
886
907
|
print(f" {msg}", file=sys.stderr)
|
|
887
908
|
return 1
|
|
909
|
+
else:
|
|
910
|
+
# Codegen is opt-in: refuse here, at the door, rather than letting the run reach
|
|
911
|
+
# the generator loop and fail with an empty out dir half-created.
|
|
912
|
+
print(f"error: {NO_GENERATORS_SELECTED}", file=sys.stderr)
|
|
913
|
+
return 2
|
|
888
914
|
|
|
889
915
|
# SP-1: declarative Mustache generators from a JSON template-spec. Their output
|
|
890
916
|
# is format-agnostic (text/markdown/csv/json/xml/html), so they run as a SECOND,
|
|
@@ -1380,12 +1406,35 @@ def _verify_codegen(args: argparse.Namespace) -> int:
|
|
|
1380
1406
|
print(spec_err, file=sys.stderr)
|
|
1381
1407
|
return 1
|
|
1382
1408
|
|
|
1409
|
+
# `verify --codegen` re-runs the SELECTION and compares. Codegen is opt-in, so the
|
|
1410
|
+
# selection has to be named — with none, there is no generated output to check, and
|
|
1411
|
+
# saying so beats silently regenerating a suite this project never asked for and
|
|
1412
|
+
# convicting every file of being missing.
|
|
1413
|
+
selection: list[Generator] | None = None
|
|
1414
|
+
if getattr(args, "generators", None):
|
|
1415
|
+
selection, gen_errors = _resolve_generators(args.generators)
|
|
1416
|
+
if gen_errors:
|
|
1417
|
+
print("error: invalid --generators selection:", file=sys.stderr)
|
|
1418
|
+
for msg in gen_errors:
|
|
1419
|
+
print(f" {msg}", file=sys.stderr)
|
|
1420
|
+
return 1
|
|
1421
|
+
elif not spec_gens:
|
|
1422
|
+
print(
|
|
1423
|
+
"verify --codegen: no generators selected, so there is no generated output "
|
|
1424
|
+
"to check. Pass --generators <a,b,c> naming the same suite `gen` ran "
|
|
1425
|
+
"(metaobjects gen --list is the catalog).",
|
|
1426
|
+
)
|
|
1427
|
+
return 0
|
|
1428
|
+
|
|
1383
1429
|
with tempfile.TemporaryDirectory() as tmp:
|
|
1384
1430
|
entities = _parse_entities(getattr(args, "entities", None))
|
|
1385
|
-
written
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1431
|
+
written: list[str] = []
|
|
1432
|
+
errors: list[str] = []
|
|
1433
|
+
if selection is not None:
|
|
1434
|
+
written, errors = _generate(
|
|
1435
|
+
args.metadata_dir, tmp, selection, entities, strict=strict,
|
|
1436
|
+
providers=providers, column_naming=column_naming,
|
|
1437
|
+
)
|
|
1389
1438
|
if errors:
|
|
1390
1439
|
print("error: failed to load metadata:", file=sys.stderr)
|
|
1391
1440
|
for msg in errors:
|
|
@@ -1458,6 +1507,22 @@ def _verify_codegen_neutral_fallback(args: argparse.Namespace) -> int:
|
|
|
1458
1507
|
if not providers_ok:
|
|
1459
1508
|
return 1
|
|
1460
1509
|
|
|
1510
|
+
# Same rule as _verify_codegen: the selection must be named, because there is no
|
|
1511
|
+
# default suite to regenerate and diff against.
|
|
1512
|
+
if not getattr(args, "generators", None):
|
|
1513
|
+
print(
|
|
1514
|
+
"verify --codegen: no generators selected, so there is no generated output "
|
|
1515
|
+
"to check. Pass --generators <a,b,c> naming the same suite `gen` ran "
|
|
1516
|
+
"(metaobjects gen --list is the catalog).",
|
|
1517
|
+
)
|
|
1518
|
+
return 0
|
|
1519
|
+
selection, gen_errors = _resolve_generators(args.generators)
|
|
1520
|
+
if gen_errors:
|
|
1521
|
+
print("error: invalid --generators selection:", file=sys.stderr)
|
|
1522
|
+
for msg in gen_errors:
|
|
1523
|
+
print(f" {msg}", file=sys.stderr)
|
|
1524
|
+
return 1
|
|
1525
|
+
|
|
1461
1526
|
with tempfile.TemporaryDirectory() as tmp:
|
|
1462
1527
|
entities = _parse_entities(getattr(args, "entities", None))
|
|
1463
1528
|
root, load_errors = _load_root_from_collection(collection, strict=strict, providers=providers)
|
|
@@ -1475,7 +1540,7 @@ def _verify_codegen_neutral_fallback(args: argparse.Namespace) -> int:
|
|
|
1475
1540
|
return 2
|
|
1476
1541
|
|
|
1477
1542
|
_run_suite(
|
|
1478
|
-
root, tmp,
|
|
1543
|
+
root, tmp, selection, entities, gen_state_dir=None, column_naming=column_naming,
|
|
1479
1544
|
select=collection.in_scope,
|
|
1480
1545
|
)
|
|
1481
1546
|
expected = _relative_set(Path(tmp))
|
|
@@ -1903,9 +1968,9 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
1903
1968
|
"--generators",
|
|
1904
1969
|
default=None,
|
|
1905
1970
|
help=(
|
|
1906
|
-
"comma-separated STABLE generator names to run
|
|
1907
|
-
"
|
|
1908
|
-
"See `gen --list
|
|
1971
|
+
"REQUIRED — comma-separated STABLE generator names to run "
|
|
1972
|
+
"(e.g. entity,routes). Codegen is opt-in: there is no default suite, so a "
|
|
1973
|
+
"run that names none is a usage error. See `gen --list` for the catalog."
|
|
1909
1974
|
),
|
|
1910
1975
|
)
|
|
1911
1976
|
gen.add_argument(
|
|
@@ -2134,6 +2199,15 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
2134
2199
|
default=None,
|
|
2135
2200
|
help="verify only this named target from the config (default: every target)",
|
|
2136
2201
|
)
|
|
2202
|
+
verify.add_argument(
|
|
2203
|
+
"--generators",
|
|
2204
|
+
default=None,
|
|
2205
|
+
help=(
|
|
2206
|
+
"comma-separated STABLE generator names — must MATCH the `gen` that "
|
|
2207
|
+
"produced --out. `verify --codegen` re-runs the selection and diffs; with "
|
|
2208
|
+
"none named there is nothing to check and it says so."
|
|
2209
|
+
),
|
|
2210
|
+
)
|
|
2137
2211
|
verify.set_defaults(func=_cmd_verify)
|
|
2138
2212
|
|
|
2139
2213
|
agent_docs = sub.add_parser(
|
|
@@ -5,11 +5,20 @@ GENERATED_MARKER = "@generated by metaobjects"
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def generated_header(entity_name: str, fqn: str) -> str:
|
|
8
|
-
"""Line-1 header for every emitted module. Detected by the overwrite policy.
|
|
8
|
+
"""Line-1 header for every emitted module. Detected by the overwrite policy.
|
|
9
|
+
|
|
10
|
+
Line 3 used to read ``Customize via <name>_extra.py in this directory``, the exact
|
|
11
|
+
wording the TypeScript emitters carried. It asserted a plugin point no port has: a
|
|
12
|
+
sibling module is safe because codegen only writes the paths it records, never
|
|
13
|
+
because of its name, and nothing imports it for you. See #367 for what the TS
|
|
14
|
+
spelling cost in a real build, and ``docs/features/own-your-codegen.md`` for the
|
|
15
|
+
convention as it actually works. Keep this line and
|
|
16
|
+
``codegen-ts/src/constants.ts``'s ``sidecarLine`` saying the same thing.
|
|
17
|
+
"""
|
|
9
18
|
return (
|
|
10
19
|
f"# {GENERATED_MARKER} — DO NOT EDIT.\n"
|
|
11
20
|
f"# Source metadata: {entity_name} ({fqn})\n"
|
|
12
|
-
f"#
|
|
21
|
+
f"# Extend in your own module (e.g. {entity_name}_extra.py) — nothing imports it for you.\n"
|
|
13
22
|
)
|
|
14
23
|
|
|
15
24
|
|
|
@@ -6,9 +6,11 @@ the cross-port contract: the same logical generator carries the same stable name
|
|
|
6
6
|
in every port. This module is the discoverability + identity surface behind
|
|
7
7
|
``metaobjects gen --list`` and the ``--generators a,b`` selection path.
|
|
8
8
|
|
|
9
|
-
It is
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
It is the ONLY name-based door. ADR-0034 Amendment 2 made codegen opt-in and DELETED
|
|
10
|
+
the default suite this note used to name (``cli._default_generators``): a run that
|
|
11
|
+
selects no generator generates nothing and raises ``NoGeneratorsSelectedError``. The
|
|
12
|
+
``run_gen(..., generators=[...])`` factory-array path remains for in-process callers,
|
|
13
|
+
where ``generators`` is likewise required.
|
|
12
14
|
|
|
13
15
|
The registry's name set is conformance-tested for SET EQUALITY against the Python
|
|
14
16
|
slice of the canonical manifest
|
|
@@ -45,10 +47,27 @@ from metaobjects.render.verify import InMemoryProvider
|
|
|
45
47
|
|
|
46
48
|
GeneratorTier = str # "native" | "neutral"
|
|
47
49
|
|
|
50
|
+
#: The six layers a generator can belong to — the axis an adopter SELECTS BY, gated
|
|
51
|
+
#: cross-port against the manifest exactly as ``tier`` is. Six, not ten: an earlier
|
|
52
|
+
#: draft split ``capability`` four ways, each with ONE member, and a layer with one
|
|
53
|
+
#: member does no grouping work. ``capability`` holds the generators the MODEL has
|
|
54
|
+
#: already chosen (you declared a ``template.prompt``), which is why they are found
|
|
55
|
+
#: by probing a real model rather than by browsing a taxonomy.
|
|
56
|
+
GENERATOR_LAYERS: tuple[str, ...] = (
|
|
57
|
+
"model",
|
|
58
|
+
"persistence",
|
|
59
|
+
"api",
|
|
60
|
+
"client",
|
|
61
|
+
"docs",
|
|
62
|
+
"capability",
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
GeneratorLayer = str # one of GENERATOR_LAYERS
|
|
66
|
+
|
|
48
67
|
|
|
49
68
|
@dataclass(frozen=True)
|
|
50
69
|
class GeneratorEntry:
|
|
51
|
-
"""A registry entry: stable name + one-line description + tier + factory."""
|
|
70
|
+
"""A registry entry: stable name + one-line description + tier + layer + factory."""
|
|
52
71
|
|
|
53
72
|
#: Stable, cross-port-consistent id. Equals the registry map key.
|
|
54
73
|
name: str
|
|
@@ -56,6 +75,8 @@ class GeneratorEntry:
|
|
|
56
75
|
description: str
|
|
57
76
|
#: "native" = recommended ``metaobjects gen`` suite; "neutral" = ``meta docs``-owned.
|
|
58
77
|
tier: GeneratorTier
|
|
78
|
+
#: The selection axis — one of :data:`GENERATOR_LAYERS`. Gated cross-port.
|
|
79
|
+
layer: GeneratorLayer
|
|
59
80
|
#: Constructs the generator with sensible defaults. Calling it must not throw.
|
|
60
81
|
factory: Callable[[], Generator]
|
|
61
82
|
|
|
@@ -89,72 +110,84 @@ def _render_helper_default() -> Generator:
|
|
|
89
110
|
|
|
90
111
|
|
|
91
112
|
#: Stable name -> GeneratorEntry. The 11 native generators whose manifest `ports`
|
|
92
|
-
#: include `python` (ADR-0021 D3). Set
|
|
113
|
+
#: include `python` (ADR-0021 D3). Set equality, tier AND layer are conformance-tested
|
|
114
|
+
#: against the manifest.
|
|
93
115
|
GENERATOR_REGISTRY: dict[str, GeneratorEntry] = {
|
|
94
116
|
"entity": GeneratorEntry(
|
|
95
117
|
name="entity",
|
|
96
118
|
description="Per-entity model/class — the entity module (table-backed or value object).",
|
|
97
119
|
tier="native",
|
|
120
|
+
layer="model",
|
|
98
121
|
factory=entity_model,
|
|
99
122
|
),
|
|
100
123
|
"routes": GeneratorEntry(
|
|
101
124
|
name="routes",
|
|
102
125
|
description="Per-entity REST endpoint surface (controllers / routes / router).",
|
|
103
126
|
tier="native",
|
|
127
|
+
layer="api",
|
|
104
128
|
factory=router_generator,
|
|
105
129
|
),
|
|
106
130
|
"output-parser": GeneratorEntry(
|
|
107
131
|
name="output-parser",
|
|
108
132
|
description="Per-template tolerant output parser (recover-on-receipt).",
|
|
109
133
|
tier="native",
|
|
134
|
+
layer="capability",
|
|
110
135
|
factory=output_parser_generator,
|
|
111
136
|
),
|
|
112
137
|
"output-prompt": GeneratorEntry(
|
|
113
138
|
name="output-prompt",
|
|
114
139
|
description="Per-template output-format prompt fragment generator.",
|
|
115
140
|
tier="native",
|
|
141
|
+
layer="capability",
|
|
116
142
|
factory=output_prompt_generator,
|
|
117
143
|
),
|
|
118
144
|
"render-helper": GeneratorEntry(
|
|
119
145
|
name="render-helper",
|
|
120
146
|
description="Per-template.output render helper (document/email typed wrappers).",
|
|
121
147
|
tier="native",
|
|
148
|
+
layer="capability",
|
|
122
149
|
factory=_render_helper_default,
|
|
123
150
|
),
|
|
124
151
|
"extractor": GeneratorEntry(
|
|
125
152
|
name="extractor",
|
|
126
153
|
description="Per-template strict typed extract<Name> helper (strict payload extraction).",
|
|
127
154
|
tier="native",
|
|
155
|
+
layer="capability",
|
|
128
156
|
factory=extractor_generator,
|
|
129
157
|
),
|
|
130
158
|
"template": GeneratorEntry(
|
|
131
159
|
name="template",
|
|
132
160
|
description="Generic Mustache template primitive (walk + template -> files).",
|
|
133
161
|
tier="native",
|
|
162
|
+
layer="capability",
|
|
134
163
|
factory=_template_primitive,
|
|
135
164
|
),
|
|
136
165
|
"filter-allowlist": GeneratorEntry(
|
|
137
166
|
name="filter-allowlist",
|
|
138
167
|
description="Per-entity REST filter allowlist (queryable-field guard).",
|
|
139
168
|
tier="native",
|
|
169
|
+
layer="api",
|
|
140
170
|
factory=filter_allowlist_generator,
|
|
141
171
|
),
|
|
142
172
|
"names": GeneratorEntry(
|
|
143
173
|
name="names",
|
|
144
174
|
description="Per-entity physical database name constants (table/view name, schema, column names).",
|
|
145
175
|
tier="native",
|
|
176
|
+
layer="model",
|
|
146
177
|
factory=names_generator,
|
|
147
178
|
),
|
|
148
179
|
"payload": GeneratorEntry(
|
|
149
180
|
name="payload",
|
|
150
181
|
description="Per-template payload value object (the strict payload type).",
|
|
151
182
|
tier="native",
|
|
183
|
+
layer="capability",
|
|
152
184
|
factory=payload_vo_generator,
|
|
153
185
|
),
|
|
154
186
|
"trace-helper": GeneratorEntry(
|
|
155
187
|
name="trace-helper",
|
|
156
188
|
description="Per-entity typed record<Entity> LLM-trace helper (extract + buildLlmCallRow + persist).",
|
|
157
189
|
tier="native",
|
|
190
|
+
layer="capability",
|
|
158
191
|
factory=trace_helper_generator,
|
|
159
192
|
),
|
|
160
193
|
}
|
{metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/router_generator.py
RENAMED
|
@@ -60,10 +60,12 @@ from metaobjects.meta.core.field.meta_field import MetaField
|
|
|
60
60
|
from metaobjects.meta.persistence.db import db_constants as dbc
|
|
61
61
|
from metaobjects.meta.core.identity.identity_constants import (
|
|
62
62
|
IDENTITY_ATTR_FIELDS,
|
|
63
|
-
IDENTITY_REFERENCE_ATTR_REFERENCES,
|
|
64
63
|
IDENTITY_SUBTYPE_REFERENCE,
|
|
65
64
|
)
|
|
66
65
|
from metaobjects.meta.core.object.meta_object import MetaObject
|
|
66
|
+
from metaobjects.meta.core.relationship.relationship_references import (
|
|
67
|
+
reference_target_entity,
|
|
68
|
+
)
|
|
67
69
|
from metaobjects.meta.persistence.source.source_constants import SOURCE_KIND_TABLE
|
|
68
70
|
from metaobjects.naming import DEFAULT_COLUMN_NAMING
|
|
69
71
|
from metaobjects.shared.base_types import TYPE_IDENTITY
|
|
@@ -269,13 +271,15 @@ def reverse_fks_for(entity: MetaObject) -> list[ReverseFk]:
|
|
|
269
271
|
fk_field = fields[0]
|
|
270
272
|
elif isinstance(fields, str) and fields:
|
|
271
273
|
fk_field = fields.split(",")[0].strip() or None
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
)
|
|
278
|
-
if
|
|
274
|
+
# #368 fallout: @references may be the dotted `Entity.field` /
|
|
275
|
+
# `Entity.fieldA,fieldB` explicit-fields form (e.g. "acme::sport::Team.id"),
|
|
276
|
+
# not just a bare/qualified entity name. reference_target_entity() already
|
|
277
|
+
# drops that dotted tail (ADR-0039: resolving); strip_package here then bares
|
|
278
|
+
# the remaining qualified entity name, same as the pre-existing package strip.
|
|
279
|
+
target = reference_target_entity(c)
|
|
280
|
+
if isinstance(target, str) and PACKAGE_SEP in target:
|
|
281
|
+
target = target[target.rfind(PACKAGE_SEP) + len(PACKAGE_SEP):]
|
|
282
|
+
if not fk_field or not target:
|
|
279
283
|
continue
|
|
280
284
|
out.append(ReverseFk(fk_field=fk_field, target_entity=target))
|
|
281
285
|
return out
|
{metaobjects-1.0.3 → metaobjects-1.0.4}/src/metaobjects/codegen/generators/trace_helper_generator.py
RENAMED
|
@@ -54,13 +54,31 @@ from metaobjects.meta.meta_data import MetaData
|
|
|
54
54
|
from metaobjects.meta.template import template_constants as tc
|
|
55
55
|
from metaobjects.meta.template.meta_template import MetaTemplate
|
|
56
56
|
from metaobjects.shared.base_types import TYPE_TEMPLATE
|
|
57
|
+
from metaobjects.library.library_sources import LIBRARY_MANIFESTS
|
|
57
58
|
from metaobjects.shared.separators import PACKAGE_SEP
|
|
58
59
|
|
|
59
60
|
_GENERATOR_NAME = "trace-helper"
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
def _anchor_fqns() -> frozenset[str]:
|
|
63
|
+
"""FQNs of the library nodes this generator keys on, read from the shipped
|
|
64
|
+
``library.json`` manifests (FR-043 §6) rather than hard-coded here.
|
|
65
|
+
|
|
66
|
+
What it replaces: ``LLM_CALL_BASE = "LlmCallBase"``, compared against
|
|
67
|
+
``MetaData.name`` (the SHORT name) anywhere in the super chain — so any adopter
|
|
68
|
+
entity of that name, in any package, triggered a helper that writes the shipped
|
|
69
|
+
base's columns. An anchor is fully qualified and is resolved to a node below.
|
|
70
|
+
"""
|
|
71
|
+
out: set[str] = set()
|
|
72
|
+
for manifest in LIBRARY_MANIFESTS.values():
|
|
73
|
+
for gen in manifest.get("generators", []):
|
|
74
|
+
if gen.get("name") == _GENERATOR_NAME and gen.get("anchor"):
|
|
75
|
+
out.add(gen["anchor"])
|
|
76
|
+
return frozenset(out)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
#: The anchor FQNs, resolved once per process from the embedded manifests.
|
|
80
|
+
#: Mirrors TS ``anchorFqns()`` / Java ``LlmTraceHelperGenerator.ANCHOR_FQNS``.
|
|
81
|
+
ANCHOR_FQNS = _anchor_fqns()
|
|
64
82
|
|
|
65
83
|
|
|
66
84
|
def _pkg_of(node: MetaData) -> str:
|
|
@@ -88,15 +106,18 @@ def _snake_case(name: str) -> str:
|
|
|
88
106
|
|
|
89
107
|
|
|
90
108
|
def _extends_base(entity: MetaObject) -> bool:
|
|
91
|
-
"""Walk the resolved super chain looking for
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
109
|
+
"""Walk the resolved super chain looking for one of :data:`ANCHOR_FQNS`.
|
|
110
|
+
|
|
111
|
+
The FULLY-QUALIFIED name, via ``resolution_key()``: within one loaded root an FQN
|
|
112
|
+
identifies exactly one node (a same-name redeclaration merges), so this is the
|
|
113
|
+
node-identity compare the TypeScript port makes against the resolved anchor node,
|
|
114
|
+
and the Java port makes against ``getName()``."""
|
|
115
|
+
if not ANCHOR_FQNS:
|
|
116
|
+
return False
|
|
96
117
|
cur = entity.super_data
|
|
97
118
|
visited: set[int] = set()
|
|
98
119
|
while cur is not None and id(cur) not in visited:
|
|
99
|
-
if cur.
|
|
120
|
+
if cur.resolution_key() in ANCHOR_FQNS:
|
|
100
121
|
return True
|
|
101
122
|
visited.add(id(cur))
|
|
102
123
|
cur = cur.super_data
|
|
@@ -125,7 +146,7 @@ def render_trace_helper(entity: MetaObject, root: MetaData) -> str | None:
|
|
|
125
146
|
"""Render one ``record_<entity>.py`` for a concrete trace ``object.entity``.
|
|
126
147
|
|
|
127
148
|
Returns ``None`` when the entity is not a trace-helper target (abstract, not
|
|
128
|
-
|
|
149
|
+
derived from a library anchor, no nested ``template.prompt``, or that prompt carries
|
|
129
150
|
neither ``@responseRef`` nor ``@payloadRef``).
|
|
130
151
|
|
|
131
152
|
Raises ``ValueError`` when the prompt's ``@responseRef`` does not resolve to an
|
|
@@ -515,6 +515,88 @@ def refuse_unowned_packages(
|
|
|
515
515
|
)
|
|
516
516
|
|
|
517
517
|
|
|
518
|
+
def refuse_library_package_misuse(
|
|
519
|
+
root: MetaData,
|
|
520
|
+
selection: Sequence[str] | None,
|
|
521
|
+
) -> None:
|
|
522
|
+
"""FR-043 §3.4 / §3.5 — refuse the two ways an adopter's own file lands in a
|
|
523
|
+
shipped library's package while that library is opted in.
|
|
524
|
+
|
|
525
|
+
Both are SILENT otherwise, and they fail in opposite directions:
|
|
526
|
+
|
|
527
|
+
the EJECTED COPY
|
|
528
|
+
``meta eject <lib>`` hands you the library's YAML to own, and the next step it
|
|
529
|
+
prints is to remove the library from ``libraries``. Skip that and both trees
|
|
530
|
+
load: the copy merges into the shipped node, so ADDITIONS take and DELETIONS do
|
|
531
|
+
not, because the library still declares what you removed
|
|
532
|
+
(``ERR_LIBRARY_PACKAGE_COLLISION``).
|
|
533
|
+
|
|
534
|
+
the NEW NODE
|
|
535
|
+
something of your own declared into ``metaobjects::<lib>``, where a later
|
|
536
|
+
release of the library may ship a node of that name and merge into it
|
|
537
|
+
(``ERR_LIBRARY_PACKAGE_NOT_OWNED``).
|
|
538
|
+
|
|
539
|
+
An ``overlay: true`` redeclaration is the documented adaptation door (§3.4) and is
|
|
540
|
+
deliberately untouched — ``is_merge`` is the loader's own record that the flag was
|
|
541
|
+
honoured, so this cannot mistake the two. Mirrors the TS
|
|
542
|
+
``refuseLibraryPackageMisuse`` (``sdk/src/memory.ts``); called AFTER the loader's
|
|
543
|
+
own errors for the same reason its sibling above is.
|
|
544
|
+
|
|
545
|
+
No-op for a project that opts into no library.
|
|
546
|
+
"""
|
|
547
|
+
if not selection:
|
|
548
|
+
return
|
|
549
|
+
from metaobjects.library.library_sources import (
|
|
550
|
+
LIBRARY_MANIFESTS,
|
|
551
|
+
is_library_file_id,
|
|
552
|
+
split_layer_token,
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
owner: dict[str, str] = {}
|
|
556
|
+
for token in selection:
|
|
557
|
+
library = split_layer_token(token)[0]
|
|
558
|
+
for pkg in LIBRARY_MANIFESTS.get(library, {}).get("packages", []):
|
|
559
|
+
owner[pkg] = library
|
|
560
|
+
if not owner:
|
|
561
|
+
return
|
|
562
|
+
|
|
563
|
+
# ADR-0039 SANCTIONED own-accessor case: a root-level scan, exactly as the
|
|
564
|
+
# dependency refusal above — `MetaRoot` has no super, and the question is "what did
|
|
565
|
+
# this tree declare at the top level".
|
|
566
|
+
for node in root.own_children():
|
|
567
|
+
key = node.resolution_key()
|
|
568
|
+
library = owner.get(package_of_resolution_key(key))
|
|
569
|
+
if library is None:
|
|
570
|
+
continue
|
|
571
|
+
files = getattr(node.source, "files", None) or []
|
|
572
|
+
if not any(not is_library_file_id(f) for f in files):
|
|
573
|
+
continue # the library's own node, untouched
|
|
574
|
+
if getattr(node, "is_merge", False):
|
|
575
|
+
continue # a marked overlay — the documented door
|
|
576
|
+
if any(is_library_file_id(f) for f in files):
|
|
577
|
+
raise ParseError(
|
|
578
|
+
f'"{key}" is declared by your own metadata AND by the shipped library '
|
|
579
|
+
f'"{library}", which this project opts into. The two merge silently and '
|
|
580
|
+
"asymmetrically: additions in your copy take effect and DELETIONS do not, "
|
|
581
|
+
"because the library still declares what you removed. Remove "
|
|
582
|
+
f'"{library}" from \'libraries\' in .metaobjects/config.json — you own the '
|
|
583
|
+
"metadata now — or delete your copy and amend the library with "
|
|
584
|
+
"'overlay: true' on the nodes you want to change.",
|
|
585
|
+
code=ErrorCode.ERR_LIBRARY_PACKAGE_COLLISION,
|
|
586
|
+
)
|
|
587
|
+
raise ParseError(
|
|
588
|
+
f'"{key}" is declared here, but the package '
|
|
589
|
+
f'"{package_of_resolution_key(key)}" belongs to the shipped library '
|
|
590
|
+
f'"{library}", which this project opts into. A later release of that library '
|
|
591
|
+
"may ship a node of this name and merge into yours. Declare it in a package "
|
|
592
|
+
"this project owns and 'extends' the library's node if it needs its shape; if "
|
|
593
|
+
"it was meant to AMEND a library node, give it that node's name and "
|
|
594
|
+
f"'overlay: true'; if you want this design outright, run 'meta eject {library}' "
|
|
595
|
+
f'and remove "{library}" from \'libraries\'.',
|
|
596
|
+
code=ErrorCode.ERR_LIBRARY_PACKAGE_NOT_OWNED,
|
|
597
|
+
)
|
|
598
|
+
|
|
599
|
+
|
|
518
600
|
@dataclass(frozen=True)
|
|
519
601
|
class Collection:
|
|
520
602
|
"""Everything the FR-023-aware source ladder resolved for one project:
|
|
@@ -127,6 +127,15 @@ class ErrorCode(str, Enum):
|
|
|
127
127
|
ERR_COLLECTION_NOT_FOUND = "ERR_COLLECTION_NOT_FOUND"
|
|
128
128
|
# FR-023 — a declared dependency's transport could not locate a directory holding
|
|
129
129
|
# metaobjects.pkg.json.
|
|
130
|
+
# FR-043: .metaobjects/config.json's `libraries` names a shipped library or layer
|
|
131
|
+
# this build does not have. Refused with the available tokens rather than skipped —
|
|
132
|
+
# skipped, it resurfaces as ERR_UNRESOLVED_SUPER against the adopter's own metadata.
|
|
133
|
+
ERR_UNKNOWN_LIBRARY = "ERR_UNKNOWN_LIBRARY"
|
|
134
|
+
# FR-043: a node is declared by BOTH an adopter's own metadata and a shipped library the project opts into — the `meta eject <lib>` copy with the library still in `libraries`. The two merge silently and ASYMMETRICALLY: additions take, deletions do not, because the library still declares what was removed.
|
|
135
|
+
# Raised by the TypeScript SDK's load path; registered in every port so the shared corpus list stays one set.
|
|
136
|
+
ERR_LIBRARY_PACKAGE_COLLISION = "ERR_LIBRARY_PACKAGE_COLLISION"
|
|
137
|
+
# FR-043: a NEW top-level node is declared into a package a shipped library owns while that library is opted in — a later release of the library may ship a node of that name and merge into it. `overlay: true` on one of the library's OWN nodes is the documented amendment door and is untouched.
|
|
138
|
+
ERR_LIBRARY_PACKAGE_NOT_OWNED = "ERR_LIBRARY_PACKAGE_NOT_OWNED"
|
|
130
139
|
ERR_DEPENDENCY_UNRESOLVED = "ERR_DEPENDENCY_UNRESOLVED"
|
|
131
140
|
# FR-023 — a dependency's metaobjects.pkg.json fails its schema, names a different
|
|
132
141
|
# dependency, points at a missing/hash-mismatched artifact, or the artifact does not
|