metaobjects 0.10.0__tar.gz → 0.11.0__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-0.10.0 → metaobjects-0.11.0}/PKG-INFO +1 -1
- {metaobjects-0.10.0 → metaobjects-0.11.0}/pyproject.toml +1 -1
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-authoring/SKILL.md +72 -1
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-codegen/references/typescript.md +30 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-prompts/SKILL.md +41 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-verify/references/migration.md +34 -1
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/extract_delegate_emitter.py +1 -1
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/extract_schema_emitter.py +1 -1
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/fr010_field_mapping.py +4 -4
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/entity_model.py +4 -4
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/filter_allowlist_generator.py +1 -1
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/m2m_codegen.py +1 -1
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/payload_vo_generator.py +2 -2
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/render_helper_generator.py +1 -1
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/output_format_spec_emitter.py +2 -2
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/type_map.py +2 -2
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/core_types.py +37 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/errors.py +5 -0
- metaobjects-0.11.0/src/metaobjects/loader/registered_validation.py +95 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/loader/validate_discriminator.py +1 -1
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/loader/validation_passes.py +53 -5
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/validator/validator_constants.py +13 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/persistence/db/db_constants.py +18 -0
- metaobjects-0.11.0/src/metaobjects/meta/persistence/db/db_provider.py +141 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/parser.py +5 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/registry.py +14 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/db.json +17 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/identity.json +2 -0
- metaobjects-0.11.0/src/metaobjects/spec_metamodel/validator.json +98 -0
- metaobjects-0.11.0/src/metaobjects/validation_types.py +39 -0
- metaobjects-0.11.0/tests/codegen/test_inherit_without_restate_gate.py +54 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_loader.py +3 -1
- {metaobjects-0.10.0 → metaobjects-0.11.0}/uv.lock +1 -1
- metaobjects-0.10.0/src/metaobjects/meta/persistence/db/db_provider.py +0 -60
- metaobjects-0.10.0/src/metaobjects/spec_metamodel/validator.json +0 -56
- {metaobjects-0.10.0 → metaobjects-0.11.0}/.gitignore +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/LICENSE +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/README.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/hatch_build.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/README.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/servers/csharp.meta.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/servers/java.meta.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/servers/kotlin.meta.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/servers/python.meta.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/servers/typescript.meta.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-codegen/SKILL.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-codegen/references/csharp.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-codegen/references/java.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-codegen/references/kotlin.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-prompts/references/csharp.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-prompts/references/java.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-prompts/references/kotlin.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-prompts/references/python.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-prompts/references/typescript.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-runtime-ui/SKILL.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-runtime-ui/references/java.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-runtime-ui/references/kotlin.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-runtime-ui/references/react.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-runtime-ui/references/tanstack.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-runtime-ui/references/typescript.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/skills/metaobjects-verify/SKILL.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/_content/templates/always-on.md.mustache +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/assemble.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/content_root.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/scaffold.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/agent_context/types.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/apidocs/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/apidocs/api_model.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/apidocs/builder.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/apidocs/naming.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/apidocs/paths.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/apidocs/renderer.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/attr_class_map.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/cli.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/KNOWN_GAPS.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/config.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/constants.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/format.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generator_registry.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/extractor_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/fr019_shared_enum.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/output_parser_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/output_prompt_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/router_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/template_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/tph_plan.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/trace_helper_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/instance_artifacts.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/overwrite_policy.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/runner.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/runtime/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/runtime/filter_parser.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/datatype.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/documentation/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/documentation/doc_constants.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/documentation/doc_provider.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/documentation/doc_schema.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/loader/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/loader/merge.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/loader/meta_data_loader.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/loader/sources/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/loader/sources/directory_source.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/loader/sources/file_source.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/loader/sources/meta_data_source.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/loader/sources/uri_source.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/loader/validate_field_readonly.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/loader/validate_source_parameter_ref.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/loader/validate_source_physical_names.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/attr/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/attr/attr_constants.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/attr/meta_attr.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/field/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/field/field_constants.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/field/meta_field.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/identity/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/identity/identity_constants.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/identity/meta_identity.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/object/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/object/meta_object.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/object/meta_object_aware.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/object/object_class_registry.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/object/object_constants.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/object/object_extract.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/object/value_object.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/relationship/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/relationship/derive_m2m_fields.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/relationship/meta_relationship.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/relationship/relationship_constants.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/core/validator/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/meta_data.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/meta_root.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/persistence/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/persistence/db/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/persistence/origin/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/persistence/origin/meta_origin.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/persistence/origin/origin_constants.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/persistence/source/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/persistence/source/meta_source.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/persistence/source/source_constants.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/presentation/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/presentation/layout/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/presentation/layout/layout_constants.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/presentation/layout/meta_layout.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/presentation/ui/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/presentation/ui/ui_provider.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/presentation/view/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/presentation/view/meta_view.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/presentation/view/view_constants.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/provider_extends.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/template/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/template/meta_template.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/template/prompt_provider.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/meta/template/template_constants.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/naming_refs.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/parser_yaml.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/provider.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/py.typed +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/registry_manifest.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/email_document.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/escapers.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/extract/KNOWN_GAPS.md +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/extract/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/extract/coerce.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/extract/extract.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/extract/extract_map.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/extract/json_forgiving_reader.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/extract/locate.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/extract/normalize.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/extract/strip.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/extract/types.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/extract/xml_forgiving_reader.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/filesystem_provider.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/prompt/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/prompt/output_format_renderer.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/prompt/output_format_spec.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/prompt/prompt_field.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/prompt/prompt_overrides.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/prompt/prompt_style.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/renderer.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/render/verify.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/runtime/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/runtime/llm_recorder.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/runtime/n2m_resolver.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/runtime/object_manager.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/runtime/tph.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/serializer_json.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/shared/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/shared/base_types.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/shared/separators.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/shared/structural.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/source/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/source/error_source.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/source/json_path.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/source/semantic_diff.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/source/yaml_positions.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/attr.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/documentation.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/field.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/layout.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/object.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/origin.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/prompt.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/relationship.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/source.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/template.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/ui.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/spec_metamodel/view.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/super_resolve.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/yaml_desugar.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/golden/extends/expected/BaseEntity.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/golden/extends/expected/Program.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/golden/extends/meta.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/golden/nested-array/expected/AuthorBrief.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/golden/nested-array/expected/PostBrief.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/golden/nested-array/meta.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/golden/scalars/expected/Metric.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/golden/scalars/expected/Report.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/golden/scalars/meta.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/golden/vanilla/expected/Subscriber.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/golden/vanilla/meta.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_abstract_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_api_docs_builder.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_api_docs_paths.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_cli.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_cli_registry.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_cli_staleness_nudge.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_cli_verify_subverbs.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_constants_config.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_entity_model.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_enum_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_extractor_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_filter_allowlist_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_format.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_fr010_output_codegen.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_fr019_shared_provided_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_generator_extension_seams.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_golden.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_inheritance_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_instance_artifacts.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_m2m_codegen.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_output_parser_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_overwrite_policy.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_payload_vo_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_render_helper_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_render_helper_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_router_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_runner.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_template_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_tph_codegen.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_trace_helper_generator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_type_map.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/codegen/test_validation_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/capabilities.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/conformance-expected-failures.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/conformance_adapter.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/corpus.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/expected_failures.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/fixture_discovery.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/navigator.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_agent_context_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_api_docs_cross_port_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_extract_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_extract_object_verdict.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_fr010_loader_attrs.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_fr011_attrs.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_generator_registry_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_object_model_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_registry_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_runner_hardfail.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_spec_metamodel_embed.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_strict_attr_load.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_template_generator_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/test_yaml_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/conformance/yaml-conformance-expected-failures.json +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/api_contract_assertions.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/api_contract_m2m_server.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/api_contract_server.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/generated_m2m_app.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/generated_router_app.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/generated_tph_app.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/meta_ai_trace.yaml +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/normalization.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/postgres_container.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/query_runner.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/scenarios.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/test_api_contract.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/test_api_contract_generated.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/test_api_contract_m2m.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/test_api_contract_m2m_generated.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/test_api_contract_tph_generated.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/test_llm_call_trace.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/test_normalization.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/test_query_scenarios.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/integration/test_runtime_return_types.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/open_closed_proof_test.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/extract/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/extract/test_coerce.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/extract/test_extract.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/extract/test_extract_map.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/extract/test_json_forgiving_reader.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/extract/test_locate.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/extract/test_model.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/extract/test_normalize.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/extract/test_strip.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/extract/test_xml_forgiving_reader.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/prompt/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/prompt/test_output_format_renderer.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/test_email_document.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/test_filesystem_provider.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/test_output_format_renderer_nested.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/test_output_prompt_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/test_render_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/test_render_max_chars.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/test_verify.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/render/test_verify_conformance.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/source/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/source/test_fr5c_merge_attribution.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/source/test_fr5d_reference_resolution.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/source/test_fr5e_database_source_shape.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/source/test_json_path.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/source/test_semantic_diff.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/source/test_source_on_node.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/source/test_yaml_positions.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/test_api_docs_accuracy.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/__init__.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_agent_context_staleness.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_capabilities.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_common_attrs.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_core_types.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_effective_package.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_errors.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_field_enum.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_field_uuid_dbcolumntype.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_fr016_source_name_and_kind_aliases.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_llm_recorder.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_loader_bom.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_loader_class.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_merge.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_meta_attr.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_meta_data.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_meta_source.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_module_shortcuts.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_n2m_resolver.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_object_manager_uuid_coercion.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_one_primary_source.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_parser.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_parser_yaml.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_provider.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_provider_extension.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_registry.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_registry_completeness.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_registry_extend.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_registry_sealed.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_relationship_referential_actions.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_resolution_key.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_runtime_resolution_key_binding.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_serializer.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_shared_constants.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_smoke.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_sources.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_strict_child_placement.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_super_resolve.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_template_toolcall.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_template_wrong_subtype_attrs.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_validation_attr_schema.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_validation_filter_values.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_validation_origin_paths.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_validation_sort_field.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/tests/unit/test_validation_warnings.py +0 -0
- {metaobjects-0.10.0 → metaobjects-0.11.0}/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.
|
|
3
|
+
Version: 0.11.0
|
|
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.
|
|
3
|
+
version = "0.11.0"
|
|
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"
|
|
@@ -165,6 +165,26 @@ Reuse a constraint set across entities with an abstract `field.enum` + `extends`
|
|
|
165
165
|
{ "field.object": { "name": "address", "@objectRef": "Address", "@storage": "flattened" } }
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
+
**Arrays of value objects** — set `isArray: true` with `@storage: jsonb`. The whole
|
|
169
|
+
array lives in **one** jsonb column (a JSON array), never a native `jsonb[]`. The
|
|
170
|
+
generated Postgres column is typed `.$type<VO[]>()` and the Zod schema is
|
|
171
|
+
`z.array(<VO>InsertSchema)`:
|
|
172
|
+
|
|
173
|
+
```json
|
|
174
|
+
{ "field.object": { "name": "triples", "@objectRef": "Triple",
|
|
175
|
+
"@storage": "jsonb", "isArray": true } }
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Opaque jsonb (no value object)** — when the payload has no fixed shape (freeform
|
|
179
|
+
config, passthrough metadata, an open-keyed map), do NOT use `field.object` (it
|
|
180
|
+
requires `@objectRef`, and a partial VO would let the generated Zod strip unknown
|
|
181
|
+
keys → data loss). Model it as a `field.string` with the physical-type override
|
|
182
|
+
`@dbColumnType: jsonb` — the logical type stays string-bound, the column is jsonb:
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
{ "field.string": { "name": "metadata", "@dbColumnType": "jsonb" } }
|
|
186
|
+
```
|
|
187
|
+
|
|
168
188
|
## YAML sigil-free authoring + the coercion footgun
|
|
169
189
|
|
|
170
190
|
In YAML, write the fused `type.subType` key with a **map body**, bare reserved
|
|
@@ -194,7 +214,7 @@ The `[]` key-suffix declares an array field: `field.long[]: weekIds` lowers to
|
|
|
194
214
|
| Subtype | Purpose | Key attrs |
|
|
195
215
|
|---|---|---|
|
|
196
216
|
| `identity.primary` | the PK field(s) | `@fields`, `@generation` |
|
|
197
|
-
| `identity.secondary` | a unique secondary index | `@fields` |
|
|
217
|
+
| `identity.secondary` | a unique secondary index | `@fields` (or `@expr` for a functional index) |
|
|
198
218
|
| `identity.reference` | an inbound FK from this entity to another | `@fields`, `@references`, `@enforce` |
|
|
199
219
|
|
|
200
220
|
`@generation` on a primary controls value generation (e.g. `increment`).
|
|
@@ -205,9 +225,27 @@ reference for navigation/typing/codegen only. Referential actions
|
|
|
205
225
|
(`@onDelete`/`@onUpdate`) are NOT on `identity.reference` — they live on the
|
|
206
226
|
`relationship.*` node (see Relationships below).
|
|
207
227
|
|
|
228
|
+
`@references` resolves cross-package by **fully-qualified name**
|
|
229
|
+
(`@references: "shared::billing::Account"`), the same rule as `extends`; a bare
|
|
230
|
+
name resolves within the current package. The FK target must be an entity with a
|
|
231
|
+
single-column primary key (the FK points at that PK); a target with a composite
|
|
232
|
+
PK needs the explicit dotted form `@references: "pkg::Target.fieldA,fieldB"`.
|
|
233
|
+
|
|
234
|
+
**A dangling reference fails the load (0.11.0+).** An unresolved
|
|
235
|
+
`identity.reference.@references` raises `ERR_INVALID_REFERENCE` and an unresolved
|
|
236
|
+
`relationship.@objectRef` raises `ERR_INVALID_RELATIONSHIP` — the target entity must
|
|
237
|
+
exist (previously such references loaded silently). So every `@references` /
|
|
238
|
+
`@objectRef` you author must name a real entity.
|
|
239
|
+
|
|
240
|
+
A `identity.secondary` can index an **expression** instead of plain columns: use
|
|
241
|
+
`@expr` (e.g. `"lower(email)"`) in place of `@fields`, optionally with `@using` (the
|
|
242
|
+
index method — `gin` / `gist` / `hash`; default `btree`) and `@where` (a partial-index
|
|
243
|
+
predicate).
|
|
244
|
+
|
|
208
245
|
```json
|
|
209
246
|
{ "identity.primary": { "name": "id", "@fields": ["id"], "@generation": "increment" } }
|
|
210
247
|
{ "identity.secondary": { "name": "byEmail", "@fields": ["email"] } }
|
|
248
|
+
{ "identity.secondary": { "name": "byEmailCI", "@expr": "lower(email)" } }
|
|
211
249
|
{ "identity.reference": { "name": "fkAuthor", "@fields": ["authorId"], "@references": "Author", "@enforce": true } }
|
|
212
250
|
```
|
|
213
251
|
|
|
@@ -229,6 +267,39 @@ the two halves of one FK.
|
|
|
229
267
|
"@cardinality": "many", "@onDelete": "cascade" } }
|
|
230
268
|
```
|
|
231
269
|
|
|
270
|
+
**Adoption footgun — pin BOTH actions.** `@onDelete` and `@onUpdate` each default to
|
|
271
|
+
`cascade` when omitted, but a plain SQL foreign key is `NO ACTION` on both. If you're
|
|
272
|
+
adopting an existing database (matching metadata to a live schema), omitting these
|
|
273
|
+
makes the metadata declare `CASCADE` where the DB has `NO ACTION` — a perpetual
|
|
274
|
+
`verify --db` drift. Pin **both** explicitly to the DB's real behavior:
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{ "relationship.composition": { "name": "author", "@objectRef": "User",
|
|
278
|
+
"@cardinality": "one", "@onDelete": "no-action", "@onUpdate": "no-action" } }
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Validators — cross-field rules
|
|
282
|
+
|
|
283
|
+
Entity-scoped `validator.*` children declare invariants that reference sibling fields
|
|
284
|
+
**by name** (the same name-reference pattern as `identity.*`). The backend derives the
|
|
285
|
+
enforcement (a CHECK constraint / cross-field assertion) — no raw expression is stored.
|
|
286
|
+
|
|
287
|
+
| Subtype | Rule | Key attrs |
|
|
288
|
+
|---|---|---|
|
|
289
|
+
| `validator.comparison` | two fields stand in a relational order (`@left @op @right`) | `@left`, `@op` (`gt`/`gte`/`lt`/`lte`/`ne`/`eq`), `@right` |
|
|
290
|
+
| `validator.requiredWhen` | `@field` is required when `@when` equals `@equals` | `@field`, `@when`, `@equals` |
|
|
291
|
+
| `validator.presentIff` | `@field` is present **iff** `@when` equals `@equals` (biconditional) | `@field`, `@when`, `@equals` |
|
|
292
|
+
| `validator.atLeastOne` | at least one of `@fields` (2+) is present | `@fields` |
|
|
293
|
+
|
|
294
|
+
```json
|
|
295
|
+
{ "validator.comparison": { "name": "hpInRange", "@left": "currentHp", "@op": "lte", "@right": "maxHp" } }
|
|
296
|
+
{ "validator.requiredWhen": { "name": "reasonIfRejected", "@field": "rejectReason", "@when": "status", "@equals": "rejected" } }
|
|
297
|
+
{ "validator.presentIff": { "name": "usedAtWhenUsed", "@field": "usedAt", "@when": "isUsed", "@equals": "true" } }
|
|
298
|
+
{ "validator.atLeastOne": { "name": "emailOrPhone", "@fields": ["email", "phone"] } }
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
These are children of `object.entity`, alongside its fields and identities.
|
|
302
|
+
|
|
232
303
|
## Sources — `source.rdb` + `@kind`
|
|
233
304
|
|
|
234
305
|
`source.rdb` declares where an entity's data lives. Read-only-ness derives from
|
|
@@ -41,6 +41,11 @@ export default defineConfig({
|
|
|
41
41
|
dialect: "postgres", // "postgres" | "sqlite" | "d1" (D1 is TS-only)
|
|
42
42
|
apiPrefix: "/api", // flows to routes AND client fetch URLs
|
|
43
43
|
columnNamingStrategy: "snake_case", // "snake_case" (default) | "literal" | "kebab-case"
|
|
44
|
+
timestampMode: "string", // "string" (default, ISO-8601 wire contract) | "date" (Drizzle native Date)
|
|
45
|
+
pluralizeCollections: true, // default; table VARS auto-pluralize (AgentConfig → agentConfigs)
|
|
46
|
+
collectionNameOverrides: { // per-entity escape hatch for names the rule gets wrong
|
|
47
|
+
AuditLog: "auditLog", LlmTierConfig: "llmTierConfig",
|
|
48
|
+
},
|
|
44
49
|
generators: [
|
|
45
50
|
entityFile(), queriesFile(), routesFile(), barrel(),
|
|
46
51
|
formFile(), tanstackQuery(), tanstackGrid(),
|
|
@@ -48,6 +53,13 @@ export default defineConfig({
|
|
|
48
53
|
});
|
|
49
54
|
```
|
|
50
55
|
|
|
56
|
+
Naming + timestamp knobs are **codegen config**, not metadata attributes — a
|
|
57
|
+
collection variable name and a Drizzle column mode are per-port rendering choices
|
|
58
|
+
with no meaning to the other language ports, so they carry no cross-port
|
|
59
|
+
conformance cost. `collectionNameOverrides` wins over `pluralizeCollections` and is
|
|
60
|
+
applied consistently to the table declaration, every FK reference, the `relations()`
|
|
61
|
+
block, and the inferred types.
|
|
62
|
+
|
|
51
63
|
A second file, `.metaobjects/config.json`, holds static project state parseable by
|
|
52
64
|
non-TS tooling; `meta init` scaffolds both plus the `metaobjects/` source dir.
|
|
53
65
|
|
|
@@ -133,3 +145,21 @@ Deterministic per dialect: `field.string` + `@maxLength` → `varchar(N)`,
|
|
|
133
145
|
(Postgres) + `gen_random_uuid()`, `field.enum` → `varchar` + `CHECK`. Override a
|
|
134
146
|
field's physical column name with `@column` on the field; the DB schema name lives
|
|
135
147
|
on `source.rdb` via `@schema`.
|
|
148
|
+
|
|
149
|
+
### Value-object jsonb columns
|
|
150
|
+
|
|
151
|
+
A `field.object` with `@storage: jsonb` (or the default `subdocument`) becomes a
|
|
152
|
+
single typed jsonb column — the referenced value-object's TS type is carried onto
|
|
153
|
+
the Drizzle column via `.$type<>()`, and its Zod schema is the VO's `InsertSchema`:
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
// field.object @objectRef=LlmConfig @storage=jsonb
|
|
157
|
+
llmConfigJson: jsonb("llm_config_json").$type<LlmConfig>(),
|
|
158
|
+
// field.object @objectRef=Triple @storage=jsonb isArray=true
|
|
159
|
+
triples: jsonb("triples").$type<Triple[]>(), // one jsonb column, NOT a native jsonb[]
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The VO type, its Zod `InsertSchema`, and this `.$type<>()` all import the VO from
|
|
163
|
+
the same module (layout/package/`extStyle`-aware resolution). An opaque jsonb column
|
|
164
|
+
(`field.string @dbColumnType: jsonb`) gets no `.$type<>()` — it stays `unknown`,
|
|
165
|
+
which is the correct shape for freeform payloads with no fixed VO.
|
|
@@ -123,6 +123,47 @@ For the `xml`-format example above with payload `{ displayName: "Ada", postCount
|
|
|
123
123
|
bytes. You render the prompt, call your LLM client (provider-agnostic — codegen
|
|
124
124
|
emits no provider-side schema), then parse the response.
|
|
125
125
|
|
|
126
|
+
## Conditional content: data and flags, never branched prose
|
|
127
|
+
|
|
128
|
+
When a prompt's wording varies along some dimension — audience, tier, mode,
|
|
129
|
+
locale, entitlement, a domain variant — do NOT branch the prose in code and
|
|
130
|
+
concatenate strings. Branching prompt text in a service is the anti-pattern this
|
|
131
|
+
pillar exists to remove: it scatters the same distinction across call sites, each
|
|
132
|
+
re-encoded and free to drift, and none of it snapshot-tested. The variation
|
|
133
|
+
belongs in exactly two places, with a third for the rare genuine divergence:
|
|
134
|
+
|
|
135
|
+
- **Vocabulary as payload data.** The words and values that differ become typed
|
|
136
|
+
payload fields, pre-computed once from the varying dimension — a noun, a label,
|
|
137
|
+
a set of verbs (a list), an example. The template stays single and references
|
|
138
|
+
`{{term}}` / `{{#items}}…{{/items}}`. The prose *structure* is identical across
|
|
139
|
+
variants; only the data differs, so there is nothing to branch.
|
|
140
|
+
- **Presence as boolean flags.** When a whole block exists-or-not for a variant,
|
|
141
|
+
gate it with a section flag the payload sets: `{{#showBlock}}…{{/showBlock}}`.
|
|
142
|
+
Reserve flags for entire blocks — never mid-sentence word swaps, which are
|
|
143
|
+
vocabulary.
|
|
144
|
+
- **Variant text only when prose truly diverges.** If a section's wording — not
|
|
145
|
+
just its vocabulary — genuinely differs, select a per-variant text through the
|
|
146
|
+
provider seam (a `@textRef` variant, or an included partial) so the shared
|
|
147
|
+
prose still lives in one place. Expect to need this rarely.
|
|
148
|
+
|
|
149
|
+
A single resolver maps the varying dimension to that payload (the flags + the
|
|
150
|
+
vocabulary), so the distinction is defined ONCE and every template that depends
|
|
151
|
+
on it stays consistent.
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
// WRONG — prose branched and concatenated in a service:
|
|
155
|
+
if (tier.isPremium()) sb.append("Your plan includes priority support.");
|
|
156
|
+
else sb.append("Upgrade any time for priority support.");
|
|
157
|
+
```
|
|
158
|
+
```mustache
|
|
159
|
+
{{! RIGHT — text in the template; the variant is data + a flag }}
|
|
160
|
+
{{supportLine}}
|
|
161
|
+
{{#isPremium}}(Priority queue enabled.){{/isPremium}}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
This stays deterministic and golden-testable per variant: render the template
|
|
165
|
+
against each value of the dimension and snapshot every variant.
|
|
166
|
+
|
|
126
167
|
## `verify` fails the build on prompt-drift
|
|
127
168
|
|
|
128
169
|
For every template, the verify step resolves the text, parses each `{{...}}`
|
|
@@ -66,7 +66,40 @@ A clean run is silent; a failure names the drifted table/column. Bias toward
|
|
|
66
66
|
trusting the tool — a drift failure almost always means the metadata changed and the
|
|
67
67
|
DB didn't follow.
|
|
68
68
|
|
|
69
|
+
## Index modeling (Postgres)
|
|
70
|
+
|
|
71
|
+
Secondary indexes carry physical-shape attributes contributed by the db provider
|
|
72
|
+
(they live on `identity.secondary`, not core):
|
|
73
|
+
|
|
74
|
+
- `@orders` — per-key sort direction, positional to `@fields` (`["asc", "desc"]`).
|
|
75
|
+
Omit for all-ascending; drives `DESC`-ordered index keys (e.g. a recency index).
|
|
76
|
+
- `@where` — a partial-index predicate (raw SQL, e.g. `"delivered_at IS NULL"`),
|
|
77
|
+
emitted as `WHERE (<pred>)`. The index then covers only matching rows.
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{ "identity.secondary": { "@fields": ["userId", "createdAt"],
|
|
81
|
+
"@orders": ["asc", "desc"], "@where": "archived_at IS NULL" } }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Adopting an existing database (non-destructive)
|
|
85
|
+
|
|
86
|
+
`meta verify --db` / `meta migrate` can reach **zero drift** against a hand-built
|
|
87
|
+
schema without a rewrite:
|
|
88
|
+
|
|
89
|
+
- **`meta migrate --from-db`** reverse-engineers a baseline from the live DB so the
|
|
90
|
+
first diff is empty.
|
|
91
|
+
- **Auto schema-scope** — the diff manages only the schemas the metadata *declares*
|
|
92
|
+
(via `source.rdb @schema`); tables in undeclared schemas belong to another owner
|
|
93
|
+
and are left untouched. This is what lets several apps share one database, each
|
|
94
|
+
owning its own schema, with a clean per-owner `verify --db` and no manual ignore
|
|
95
|
+
lists. A downstream app that extends the toolkit's DB declares its own `@schema`,
|
|
96
|
+
models only its tables, and runs its own migrate/verify against that scope.
|
|
97
|
+
- **`identity.reference @constraintName`** pins a foreign-key constraint name so the
|
|
98
|
+
metadata can match an existing DB's naming convention without a destructive
|
|
99
|
+
rename.
|
|
100
|
+
|
|
69
101
|
## Not yet shipped
|
|
70
102
|
|
|
71
|
-
Triggers, generated columns,
|
|
103
|
+
Triggers, generated columns, exclusion + CHECK constraints, MySQL, and data
|
|
72
104
|
migrations (column-type changes needing data transformation error out with a hint).
|
|
105
|
+
(Partial + descending **indexes** *are* supported — see Index modeling above.)
|
{metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/extract_delegate_emitter.py
RENAMED
|
@@ -47,7 +47,7 @@ def ref_vo(field: MetaData, root: MetaData) -> MetaData | None:
|
|
|
47
47
|
"""The ``@objectRef`` target VO for a nested-object field, or ``None`` when
|
|
48
48
|
unresolvable. Matches first on the full ref, then the trailing simple-name
|
|
49
49
|
segment (mirrors the runtime ``_resolve_object_ref`` short-name fallback)."""
|
|
50
|
-
ref = field.
|
|
50
|
+
ref = field.attrs().get(fc.FIELD_ATTR_OBJECT_REF)
|
|
51
51
|
if not isinstance(ref, str) or not ref:
|
|
52
52
|
return None
|
|
53
53
|
direct = _find_object(root, ref)
|
|
@@ -53,7 +53,7 @@ def _field_spec_literal(field: MetaData, owner: MetaData) -> str:
|
|
|
53
53
|
|
|
54
54
|
if field.sub_type == fc.FIELD_SUBTYPE_ENUM:
|
|
55
55
|
values_lit = fm.string_list_literal(fm.enum_values(field))
|
|
56
|
-
alias_lit = fm.properties_map_literal(field.
|
|
56
|
+
alias_lit = fm.properties_map_literal(field.attrs().get(fc.FIELD_ATTR_ENUM_ALIAS))
|
|
57
57
|
# FR-011: resolve the three new enum args (field → object.value → "strip" for
|
|
58
58
|
# normalize). Keep the back-compat 4-arg form when nothing is set; otherwise
|
|
59
59
|
# emit the 7-arg form (..., coerce_default, normalize, default_value).
|
|
@@ -34,12 +34,12 @@ def fields(vo: MetaData) -> list[MetaData]:
|
|
|
34
34
|
def is_array(field: MetaData) -> bool:
|
|
35
35
|
"""Array-ness from either form: the node property (programmatic build) or the
|
|
36
36
|
``@isArray`` attr (how metadata loads from JSON)."""
|
|
37
|
-
return bool(field.is_array) or field.
|
|
37
|
+
return bool(field.is_array) or field.attrs().get(KEY_IS_ARRAY) is True
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
def is_required(field: MetaData) -> bool:
|
|
41
41
|
"""``@required`` — accepts a bool ``True`` or the string ``"true"``."""
|
|
42
|
-
v = field.
|
|
42
|
+
v = field.attrs().get(fc.FIELD_ATTR_REQUIRED)
|
|
43
43
|
if v is True:
|
|
44
44
|
return True
|
|
45
45
|
return isinstance(v, str) and v.lower() == "true"
|
|
@@ -49,7 +49,7 @@ def xml_text(field: MetaData) -> bool:
|
|
|
49
49
|
"""``@xmlText`` — the XML text-content extract marker (accepts a bool ``True`` or the
|
|
50
50
|
string ``"true"``). When set, codegen bakes a ``FieldSpec.text_content_field(...)``.
|
|
51
51
|
Mirrors the TS ``xmlText(field)`` helper."""
|
|
52
|
-
v = field.
|
|
52
|
+
v = field.attrs().get(TEMPLATE_ATTR_XML_TEXT)
|
|
53
53
|
if v is True:
|
|
54
54
|
return True
|
|
55
55
|
return isinstance(v, str) and v.lower() == "true"
|
|
@@ -57,7 +57,7 @@ def xml_text(field: MetaData) -> bool:
|
|
|
57
57
|
|
|
58
58
|
def enum_values(field: MetaData) -> list[str]:
|
|
59
59
|
"""The string members of an enum field's ``@values`` attr (empty when absent)."""
|
|
60
|
-
v = field.
|
|
60
|
+
v = field.attrs().get(fc.FIELD_ATTR_VALUES)
|
|
61
61
|
if isinstance(v, (list, tuple)):
|
|
62
62
|
return [str(x) for x in v]
|
|
63
63
|
return []
|
{metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/entity_model.py
RENAMED
|
@@ -57,7 +57,7 @@ def _validator_constraints(field: MetaField) -> dict[str, object]:
|
|
|
57
57
|
# String length: validator.length @min/@max + field @maxLength (max wins per field attr).
|
|
58
58
|
min_len = _first_attr(field, vc.VALIDATOR_SUBTYPE_LENGTH, vc.VALIDATOR_ATTR_MIN)
|
|
59
59
|
max_len = _first_attr(field, vc.VALIDATOR_SUBTYPE_LENGTH, vc.VALIDATOR_ATTR_MAX)
|
|
60
|
-
field_max = field.
|
|
60
|
+
field_max = field.attrs().get(fc.FIELD_ATTR_MAX_LENGTH)
|
|
61
61
|
if _is_int(field_max):
|
|
62
62
|
max_len = field_max
|
|
63
63
|
if min_len is not None:
|
|
@@ -110,14 +110,14 @@ def _field_line(field: MetaField, imports: set[str], config: GenConfig) -> tuple
|
|
|
110
110
|
imports.update(pt.imports)
|
|
111
111
|
type_expr = pt.expr
|
|
112
112
|
if field.sub_type == fc.FIELD_SUBTYPE_OBJECT:
|
|
113
|
-
ref = field.
|
|
113
|
+
ref = field.attrs().get(fc.FIELD_ATTR_OBJECT_REF)
|
|
114
114
|
if ref:
|
|
115
115
|
# @objectRef is FQN-expanded at load time; the generated VOs live
|
|
116
116
|
# flat in one package, so import by the bare class name.
|
|
117
117
|
ref_name = str(ref).split("::")[-1]
|
|
118
118
|
imports.add(f"from .{ref_name} import {ref_name}")
|
|
119
|
-
required = field.
|
|
120
|
-
default_raw = field.
|
|
119
|
+
required = field.attrs().get(fc.FIELD_ATTR_REQUIRED) is True
|
|
120
|
+
default_raw = field.attrs().get(fc.FIELD_ATTR_DEFAULT)
|
|
121
121
|
has_default = default_raw is not None
|
|
122
122
|
enum_type_name = type_name if shared is not None else None
|
|
123
123
|
|
|
@@ -117,7 +117,7 @@ def _is_filterable(field: MetaField) -> bool:
|
|
|
117
117
|
matching the Java/Kotlin/C# tolerance for either YAML-bool or raw-string
|
|
118
118
|
value forms.
|
|
119
119
|
"""
|
|
120
|
-
raw = field.
|
|
120
|
+
raw = field.attrs().get(fc.FIELD_ATTR_FILTERABLE)
|
|
121
121
|
if raw is True:
|
|
122
122
|
return True
|
|
123
123
|
if isinstance(raw, str):
|
|
@@ -96,7 +96,7 @@ def _column_of(field: MetaField | None, fallback: str) -> str:
|
|
|
96
96
|
``@column`` overrides)."""
|
|
97
97
|
if field is None:
|
|
98
98
|
return fallback
|
|
99
|
-
col = field.
|
|
99
|
+
col = field.attrs().get(fc.FIELD_ATTR_COLUMN)
|
|
100
100
|
return col if isinstance(col, str) and col else field.name
|
|
101
101
|
|
|
102
102
|
|
{metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/generators/payload_vo_generator.py
RENAMED
|
@@ -172,7 +172,7 @@ def is_field_required(field: MetaField) -> bool:
|
|
|
172
172
|
additionally treat the string ``"true"`` as required. The payload type's optionality
|
|
173
173
|
and the extractor mapper's None-guarding are kept in lockstep by sharing THIS
|
|
174
174
|
predicate, so do not "reconcile" it with the runtime predicate."""
|
|
175
|
-
return field.
|
|
175
|
+
return field.attrs().get(fc.FIELD_ATTR_REQUIRED) is True
|
|
176
176
|
|
|
177
177
|
|
|
178
178
|
def _resolve_object_field_type(
|
|
@@ -186,7 +186,7 @@ def _resolve_object_field_type(
|
|
|
186
186
|
(array). The target VO is scheduled for in-file emission (per-file dedupe, same
|
|
187
187
|
mechanism as ``origin.collection``). Falls back to the bare type-map form when the
|
|
188
188
|
``@objectRef`` can't be resolved (defensive — loader validation gates it first)."""
|
|
189
|
-
ref = field.
|
|
189
|
+
ref = field.attrs().get(fc.FIELD_ATTR_OBJECT_REF)
|
|
190
190
|
if not isinstance(ref, str) or not ref:
|
|
191
191
|
return _fallback_type(field)
|
|
192
192
|
target = _resolve_object_by_short_or_fqn(root, ref)
|
|
@@ -114,7 +114,7 @@ def _derive_payload_field_tree(
|
|
|
114
114
|
if f.type != TYPE_FIELD or not isinstance(f, MetaField):
|
|
115
115
|
continue
|
|
116
116
|
if f.sub_type == fc.FIELD_SUBTYPE_OBJECT:
|
|
117
|
-
ref = f.
|
|
117
|
+
ref = f.attrs().get(fc.FIELD_ATTR_OBJECT_REF)
|
|
118
118
|
if isinstance(ref, str) and ref:
|
|
119
119
|
target = _resolve_nested_object_ref(root, ref)
|
|
120
120
|
if target is not None and target.sub_type == OBJECT_SUBTYPE_VALUE:
|
{metaobjects-0.10.0 → metaobjects-0.11.0}/src/metaobjects/codegen/output_format_spec_emitter.py
RENAMED
|
@@ -34,7 +34,7 @@ def _prompt_style_enum(template: MetaData) -> str:
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def _opt_string_attr(field: MetaData, attr_name: str) -> str:
|
|
37
|
-
v = field.
|
|
37
|
+
v = field.attrs().get(attr_name)
|
|
38
38
|
return fm.py_string_literal(v) if isinstance(v, str) else "None"
|
|
39
39
|
|
|
40
40
|
|
|
@@ -54,7 +54,7 @@ def _prompt_field_literal(field: MetaData) -> str:
|
|
|
54
54
|
|
|
55
55
|
if field.sub_type == fc.FIELD_SUBTYPE_ENUM:
|
|
56
56
|
values_lit = fm.string_list_literal(fm.enum_values(field))
|
|
57
|
-
enum_doc_lit = fm.properties_map_literal(field.
|
|
57
|
+
enum_doc_lit = fm.properties_map_literal(field.attrs().get(fc.FIELD_ATTR_ENUM_DOC))
|
|
58
58
|
return (
|
|
59
59
|
f'PromptField("{name}", FieldKind.ENUM, {req}, array={array}, '
|
|
60
60
|
f"enum_values={values_lit}, enum_doc={enum_doc_lit}, "
|
|
@@ -35,7 +35,7 @@ _SCALAR: dict[str, PyType] = {
|
|
|
35
35
|
def field_is_array(field: MetaField) -> bool:
|
|
36
36
|
"""Array-ness from either form: the node property (programmatic build) or the
|
|
37
37
|
`@isArray` attr (how metadata loads from JSON — the conformance-fixture form)."""
|
|
38
|
-
return field.is_array or field.
|
|
38
|
+
return field.is_array or field.attrs().get(KEY_IS_ARRAY) is True
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
def _py_str_literal(value: str) -> str:
|
|
@@ -66,7 +66,7 @@ def py_type_for(field: MetaField) -> PyType:
|
|
|
66
66
|
becomes ``list[Literal[...]]``. An enum WITHOUT declared values falls back to
|
|
67
67
|
``str``."""
|
|
68
68
|
if field.sub_type == fc.FIELD_SUBTYPE_OBJECT:
|
|
69
|
-
ref = field.
|
|
69
|
+
ref = field.attrs().get(fc.FIELD_ATTR_OBJECT_REF)
|
|
70
70
|
# @objectRef is expanded to a package-qualified FQN at load time
|
|
71
71
|
# (e.g. ``app::pkg::Thing``); the emitted VOs all live flat in one
|
|
72
72
|
# generated package, so type by the bare class name.
|
|
@@ -107,6 +107,7 @@ from .meta.presentation.view.view_constants import (
|
|
|
107
107
|
)
|
|
108
108
|
from .provider import Provider
|
|
109
109
|
from .registry import AttrSchema, ChildRule, NodeFactory, TypeDefinition, TypeRegistry
|
|
110
|
+
from .validation_types import ReferenceDescriptor
|
|
110
111
|
from .shared.base_types import (
|
|
111
112
|
SUBTYPE_BASE,
|
|
112
113
|
SUBTYPE_ROOT,
|
|
@@ -149,6 +150,7 @@ def _register_subtypes(
|
|
|
149
150
|
factory: NodeFactory,
|
|
150
151
|
child_rules: list[ChildRule] | None = None,
|
|
151
152
|
attrs: list[AttrSchema] | None = None,
|
|
153
|
+
references: list[ReferenceDescriptor] | None = None,
|
|
152
154
|
) -> None:
|
|
153
155
|
"""Register one TypeDefinition per subtype. Centralises loop boilerplate only —
|
|
154
156
|
all type knowledge (subtypes tuple, node class, child rules) stays with the caller."""
|
|
@@ -160,6 +162,7 @@ def _register_subtypes(
|
|
|
160
162
|
factory=factory,
|
|
161
163
|
child_rules=list(child_rules) if child_rules else [],
|
|
162
164
|
attrs=list(attrs) if attrs else [],
|
|
165
|
+
references=list(references) if references else [],
|
|
163
166
|
)
|
|
164
167
|
)
|
|
165
168
|
|
|
@@ -390,6 +393,12 @@ core_provider.add(
|
|
|
390
393
|
),
|
|
391
394
|
],
|
|
392
395
|
child_rules=[ChildRule(TYPE_ATTR, "*")],
|
|
396
|
+
# max_occurs/default_name are hardcoded here (matching the values in
|
|
397
|
+
# spec_metamodel/identity.json, which this port does NOT yet read). Sourcing them from
|
|
398
|
+
# that JSON — true single-source-of-truth across all ports — is the config-driven-
|
|
399
|
+
# validation work tracked in issue #51.
|
|
400
|
+
max_occurs=1,
|
|
401
|
+
default_name="primary",
|
|
393
402
|
)
|
|
394
403
|
)
|
|
395
404
|
|
|
@@ -420,6 +429,10 @@ core_provider.add(
|
|
|
420
429
|
AttrSchema(name=IDENTITY_REFERENCE_ATTR_ENFORCE, value_type=ATTR_SUBTYPE_BOOLEAN, required=False),
|
|
421
430
|
],
|
|
422
431
|
child_rules=[ChildRule(TYPE_ATTR, "*")],
|
|
432
|
+
# @references is a cross-reference to a real object (FK target) — the loader's
|
|
433
|
+
# registry-derived validation resolves it; "Entity.field" resolves the entity head.
|
|
434
|
+
references=[ReferenceDescriptor(
|
|
435
|
+
IDENTITY_REFERENCE_ATTR_REFERENCES, TYPE_OBJECT, None, True, "ERR_INVALID_REFERENCE")],
|
|
423
436
|
)
|
|
424
437
|
)
|
|
425
438
|
|
|
@@ -460,6 +473,10 @@ _register_subtypes(
|
|
|
460
473
|
factory=MetaRelationship,
|
|
461
474
|
child_rules=[ChildRule(TYPE_ATTR, "*")],
|
|
462
475
|
attrs=_RELATIONSHIP_ATTRS,
|
|
476
|
+
# @objectRef is a cross-reference to a real object (the relationship target); the
|
|
477
|
+
# loader's registry-derived validation resolves it (dangling target = load error).
|
|
478
|
+
references=[ReferenceDescriptor(
|
|
479
|
+
RELATIONSHIP_ATTR_OBJECT_REF, TYPE_OBJECT, None, False, "ERR_INVALID_RELATIONSHIP")],
|
|
463
480
|
)
|
|
464
481
|
|
|
465
482
|
# source.* — base (no attrs) + rdb (paradigm subtype with @table/@kind/@role/@schema).
|
|
@@ -628,6 +645,26 @@ _VALIDATOR_ATTRS_BY_SUBTYPE: dict[str, list[AttrSchema]] = {
|
|
|
628
645
|
],
|
|
629
646
|
vc.VALIDATOR_SUBTYPE_NUMERIC: list(_VALIDATOR_MIN_MAX_ATTRS),
|
|
630
647
|
vc.VALIDATOR_SUBTYPE_ARRAY: list(_VALIDATOR_MIN_MAX_ATTRS),
|
|
648
|
+
# Cross-field validators — entity-scoped, reference sibling fields by name.
|
|
649
|
+
vc.VALIDATOR_SUBTYPE_COMPARISON: [
|
|
650
|
+
AttrSchema(name=vc.VALIDATOR_ATTR_LEFT, value_type=ATTR_SUBTYPE_STRING, required=True),
|
|
651
|
+
AttrSchema(name=vc.VALIDATOR_ATTR_OP, value_type=ATTR_SUBTYPE_STRING, required=True,
|
|
652
|
+
allowed_values=("gt", "gte", "lt", "lte", "ne", "eq")),
|
|
653
|
+
AttrSchema(name=vc.VALIDATOR_ATTR_RIGHT, value_type=ATTR_SUBTYPE_STRING, required=True),
|
|
654
|
+
],
|
|
655
|
+
vc.VALIDATOR_SUBTYPE_REQUIRED_WHEN: [
|
|
656
|
+
AttrSchema(name=vc.VALIDATOR_ATTR_FIELD, value_type=ATTR_SUBTYPE_STRING, required=True),
|
|
657
|
+
AttrSchema(name=vc.VALIDATOR_ATTR_WHEN, value_type=ATTR_SUBTYPE_STRING, required=True),
|
|
658
|
+
AttrSchema(name=vc.VALIDATOR_ATTR_EQUALS, value_type=ATTR_SUBTYPE_STRING, required=True),
|
|
659
|
+
],
|
|
660
|
+
vc.VALIDATOR_SUBTYPE_PRESENT_IFF: [
|
|
661
|
+
AttrSchema(name=vc.VALIDATOR_ATTR_FIELD, value_type=ATTR_SUBTYPE_STRING, required=True),
|
|
662
|
+
AttrSchema(name=vc.VALIDATOR_ATTR_WHEN, value_type=ATTR_SUBTYPE_STRING, required=True),
|
|
663
|
+
AttrSchema(name=vc.VALIDATOR_ATTR_EQUALS, value_type=ATTR_SUBTYPE_STRING, required=True),
|
|
664
|
+
],
|
|
665
|
+
vc.VALIDATOR_SUBTYPE_AT_LEAST_ONE: [
|
|
666
|
+
AttrSchema(name=vc.VALIDATOR_ATTR_FIELDS, value_type=ATTR_SUBTYPE_STRING, required=True, is_array=True),
|
|
667
|
+
],
|
|
631
668
|
}
|
|
632
669
|
for _sub, _attrs in _VALIDATOR_ATTRS_BY_SUBTYPE.items():
|
|
633
670
|
core_provider.add(
|
|
@@ -23,6 +23,8 @@ class ErrorCode(str, Enum):
|
|
|
23
23
|
# Vocabulary-only here until FR-024 Phase E (the Python loader does not
|
|
24
24
|
# enforce these yet); the enum tracks the shared corpus codes.
|
|
25
25
|
ERR_IDENTITY_NAME_REQUIRED = "ERR_IDENTITY_NAME_REQUIRED"
|
|
26
|
+
# A type.subType declared with maxOccurs (e.g. identity.primary) appears more than allowed under one parent.
|
|
27
|
+
ERR_TOO_MANY_OCCURRENCES = "ERR_TOO_MANY_OCCURRENCES"
|
|
26
28
|
ERR_PROJECTION_IDENTITY_NOT_EXTENDED = "ERR_PROJECTION_IDENTITY_NOT_EXTENDED"
|
|
27
29
|
ERR_IDENTITY_KEY_MISMATCH = "ERR_IDENTITY_KEY_MISMATCH"
|
|
28
30
|
# FR-024 (ADR-0028): a source.* on an object.projection has a writable
|
|
@@ -76,6 +78,9 @@ class ErrorCode(str, Enum):
|
|
|
76
78
|
# references / sourceRefField-not-matching / M:N-attr-on-1:N). The symmetric-
|
|
77
79
|
# on-hetero + symmetric+sourceRefField rules emit ERR_BAD_ATTR_VALUE instead.
|
|
78
80
|
ERR_INVALID_RELATIONSHIP = "ERR_INVALID_RELATIONSHIP"
|
|
81
|
+
# identity.reference @references names an FK target object that does not resolve
|
|
82
|
+
# to any object in the loaded tree (a dangling cross-reference between metadata).
|
|
83
|
+
ERR_INVALID_REFERENCE = "ERR_INVALID_REFERENCE"
|
|
79
84
|
ERR_BAD_ATTR_FILTER = "ERR_BAD_ATTR_FILTER"
|
|
80
85
|
# Reserved structural body key authored as an @-attr (source-v2 / ADR-0007).
|
|
81
86
|
ERR_RESERVED_ATTR = "ERR_RESERVED_ATTR"
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""The recursive validation walk, DERIVED FROM THE TYPE REGISTRY.
|
|
2
|
+
|
|
3
|
+
Each node's TypeDefinition carries its reference descriptors + imperative validator, so a
|
|
4
|
+
downstream provider's type validates itself just by being registered. Per node: apply the
|
|
5
|
+
type's declared references (resolve against the symbol table), invoke its validator, recurse.
|
|
6
|
+
Mirrors the TS/Java/C# realization.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from ..errors import ErrorCode, MetaError
|
|
12
|
+
from ..meta.core.object.meta_object import MetaObject
|
|
13
|
+
from ..meta.meta_data import MetaData
|
|
14
|
+
from ..meta.meta_root import MetaRoot
|
|
15
|
+
from ..registry import TypeRegistry
|
|
16
|
+
from ..shared.base_types import TYPE_OBJECT
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class SymbolTable:
|
|
20
|
+
"""An index of every top-level object, built once per load (the binder analogue)."""
|
|
21
|
+
|
|
22
|
+
def __init__(self) -> None:
|
|
23
|
+
self._index: dict[str, MetaData] = {}
|
|
24
|
+
|
|
25
|
+
@classmethod
|
|
26
|
+
def build(cls, root: MetaData) -> "SymbolTable":
|
|
27
|
+
t = cls()
|
|
28
|
+
for child in root.own_children():
|
|
29
|
+
if child.type == TYPE_OBJECT and isinstance(child, MetaObject):
|
|
30
|
+
if child.name:
|
|
31
|
+
t._index[child.name] = child
|
|
32
|
+
t._index[child.fqn()] = child
|
|
33
|
+
t._index[child.resolution_key()] = child
|
|
34
|
+
return t
|
|
35
|
+
|
|
36
|
+
def resolve_object(self, reference: str) -> MetaData | None:
|
|
37
|
+
return self._index.get(reference)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ValidationContext:
|
|
41
|
+
def __init__(self, symbols: SymbolTable) -> None:
|
|
42
|
+
self.symbols = symbols
|
|
43
|
+
self.errors: list[MetaError] = []
|
|
44
|
+
|
|
45
|
+
def error(self, code: str, node: MetaData, message: str) -> None:
|
|
46
|
+
# Core descriptors use built-in codes; a downstream provider's custom code (not in
|
|
47
|
+
# the enum) maps to ERR_UNKNOWN for now (the message carries the detail).
|
|
48
|
+
try:
|
|
49
|
+
ec = ErrorCode(code)
|
|
50
|
+
except ValueError:
|
|
51
|
+
ec = ErrorCode.ERR_UNKNOWN
|
|
52
|
+
self.errors.append(MetaError(message, ec, envelope=node.source))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def run(root: MetaRoot, registry: TypeRegistry) -> list[MetaError]:
|
|
56
|
+
ctx = ValidationContext(SymbolTable.build(root))
|
|
57
|
+
_walk(root, registry, ctx)
|
|
58
|
+
return ctx.errors
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _walk(node: MetaData, registry: TypeRegistry, ctx: ValidationContext) -> None:
|
|
62
|
+
type_def = registry.find(node.type, node.sub_type)
|
|
63
|
+
if type_def is not None:
|
|
64
|
+
for desc in type_def.references:
|
|
65
|
+
raw = node.attr(desc.attr)
|
|
66
|
+
if not isinstance(raw, str) or raw == "":
|
|
67
|
+
continue # absence is the required-attr pass's job
|
|
68
|
+
entity_ref = raw.split(".", 1)[0] if desc.dotted_field_path else raw
|
|
69
|
+
target = ctx.symbols.resolve_object(entity_ref)
|
|
70
|
+
# Qualify the node name with its owning entity (e.g. "Order.items") so the error
|
|
71
|
+
# is locatable from the message alone, not just the source envelope.
|
|
72
|
+
qname = f"{node.parent.name}.{node.name}" if node.parent and node.parent.name else node.name
|
|
73
|
+
if target is None:
|
|
74
|
+
ctx.error(
|
|
75
|
+
desc.error_code, node,
|
|
76
|
+
f'{node.type}.{node.sub_type} "{qname}" @{desc.attr} "{raw}" '
|
|
77
|
+
f"does not resolve to an object.",
|
|
78
|
+
)
|
|
79
|
+
elif target.type != desc.target_type or (
|
|
80
|
+
desc.target_sub_type is not None and target.sub_type != desc.target_sub_type
|
|
81
|
+
):
|
|
82
|
+
want = (
|
|
83
|
+
f"{desc.target_type}.{desc.target_sub_type}"
|
|
84
|
+
if desc.target_sub_type
|
|
85
|
+
else desc.target_type
|
|
86
|
+
)
|
|
87
|
+
ctx.error(
|
|
88
|
+
desc.error_code, node,
|
|
89
|
+
f'{node.type}.{node.sub_type} "{qname}" @{desc.attr} "{raw}" '
|
|
90
|
+
f"resolves to {target.type}.{target.sub_type}, not a {want}.",
|
|
91
|
+
)
|
|
92
|
+
if type_def.validate is not None:
|
|
93
|
+
type_def.validate(node, ctx)
|
|
94
|
+
for child in node.own_children():
|
|
95
|
+
_walk(child, registry, ctx)
|
|
@@ -106,7 +106,7 @@ def validate_discriminator(root: MetaData, errors: list[MetaError]) -> None:
|
|
|
106
106
|
continue # root's own ERR_DISCRIMINATOR_FIELD_NOT_FOUND already fires
|
|
107
107
|
|
|
108
108
|
if field.sub_type == FIELD_SUBTYPE_ENUM:
|
|
109
|
-
enum_values = field.
|
|
109
|
+
enum_values = field.attrs().get(FIELD_ATTR_VALUES)
|
|
110
110
|
members = [str(v) for v in enum_values] if isinstance(enum_values, (list, tuple)) else []
|
|
111
111
|
if value not in members:
|
|
112
112
|
errors.append(
|