Skip to content

Conversation

gianlukk994
Copy link
Contributor

@gianlukk994 gianlukk994 commented Oct 15, 2025

Description

This PR implements support for dumping Shopify Metaobject definitions and references in the schema files, enabling schema portability across different Shopify stores.

Key Enhancements

  • Metaobject Definitions Dump

    • Adds fetch_metaobject_definitions() to retrieve metaobject schemas.
    • Includes create_metaobject_definition calls in the schema dump output.
    • Orders metaobjects before metafields in the dump for clarity.
    • Handles metaobject field definitions, access controls, and capabilities.
    • Skips default values for cleaner output.
  • Portable References

    • Converts store-specific metaobject definition IDs (metaobject_definition_id) to portable metaobject types (metaobject_definition_type) in schema dumps.
    • Updates validations to use types instead of GIDs, making schema files cross-store compatible.
    • Enhances metafield creation and update logic to resolve types back to GIDs when needed.
    • Supports both single and array values for list.metaobject_reference fields.
    • Adds precise validation matching for metaobject reference fields.

Example Before

create_metafield :products, :color, :metaobject_reference,
  validations: [{name: "metaobject_definition_id", value: "gid://shopify/MetaobjectDefinition/123"}]

Example After

create_metafield :products, :color, :metaobject_reference,
  validations: [{name: "metaobject_definition_type", value: "color_pattern"}]

With this update, schema files can be shared between stores without manual ID changes, as long as the relevant metaobject types exist.

Convert metaobject definition IDs to types in schema dumps to make them
portable across different Shopify stores. Store-specific GIDs are now
replaced with metaobject types that can be resolved in any store.

Changes:
- Add get_metaobject_definition_type_by_gid() method to resolve GIDs to types
- Update schema dump to convert metaobject_definition_id validations to metaobject_definition_type
- Enhance create_metafield and update_metafield to resolve types back to GIDs
- Add precise validation matching for metaobject reference fields only
- Support both single and array values for list.metaobject_reference fields
- Include MetaobjectStatements in Schema module for type resolution

Before:
create_metafield :products, :color, :metaobject_reference,
  validations: [{name: "metaobject_definition_id", value: "gid://shopify/MetaobjectDefinition/123"}]

After:
create_metafield :products, :color, :metaobject_reference,
  validations: [{name: "metaobject_definition_type", value: "color_pattern"}]

This enables schema files to be shared between different Shopify stores
without manual ID updates, as long as the metaobject types exist.
Add support for dumping metaobject definitions in schema files with portable
cross-store references. Metaobjects are now included before metafields in
the schema dump output.

Changes:
- Add fetch_metaobject_definitions() method to retrieve metaobject schema
- Include create_metaobject_definition calls in schema dump output
- Convert metaobject references within metaobject fields to portable types
- Update schema dump header to mention metaobjects
- Order metaobjects before metafields in dump output
- Handle metaobject field definitions, access controls, and capabilities
- Skip default values (required: false, empty descriptions) for cleaner output

Schema now generates:
create_metaobject_definition :color_pattern,
  name: "Color Pattern",
  field_definitions: [{key: :name, type: :single_line_text_field, ...}],
  access: {admin: true, storefront: false}

create_metafield :products, :color, :metaobject_reference,
  validations: [{name: "metaobject_definition_type", value: "color_pattern"}]

This completes the portable schema dump feature by including both
metaobjects and metafields with cross-store compatible references.
@gianlukk994 gianlukk994 changed the title Gianlukk994/support metaobjects schema dump Add portable metaobject definitions and references to Shopify Toolkit schema dump Oct 15, 2025
@gianlukk994 gianlukk994 marked this pull request as ready for review October 15, 2025 13:42
@gianlukk994 gianlukk994 requested review from Copilot and elia October 15, 2025 13:42
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Adds support for including metaobject definitions and portable metaobject reference validations in the schema dump to enable cross-store portability.

  • Introduces dumping of metaobject definitions before metafields.
  • Converts metaobject definition GID-based validations to portable type-based validations in both dump and load paths.
  • Adds bidirectional conversion logic (GIDs <-> types) and associated tests for one direction.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
spec/shopify_toolkit/schema_spec.rb Adds test fixtures and specs for dumping metaobject definitions and converting validations from GIDs to types.
lib/shopify_toolkit/schema.rb Adds metaobject fetching, schema generation with metaobjects, validation conversion, and type detection helpers.
lib/shopify_toolkit/metaobject_statements.rb Adds helper to resolve a metaobject type from a GID for reverse validation conversion.
lib/shopify_toolkit/metafield_statements.rb Adds conversion from metaobject types back to GIDs when creating/updating metafields, plus duplicate type check logic.

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +251 to +258
expected_schema =
(
if RUBY_VERSION.to_f < 3.4
SCHEMA_FIXTURE_BEFORE_RUBY_3_4
else
SCHEMA_FIXTURE
end
)
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version comparison using RUBY_VERSION.to_f is unsafe for multi-digit minor versions (e.g. '3.10' becomes 3.1). Use Gem::Version: if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.4') instead.

Copilot uses AI. Check for mistakes.

Comment on lines +23 to 29
# Process validations to convert metaobject types to GIDs (only for metaobject reference fields)
if options[:validations] && is_metaobject_reference_type?(type)
options[:validations] = convert_validations_types_to_gids(options[:validations])
end

# Skip creation if metafield already exists
if get_metafield_gid(owner_type, key, namespace: namespace)
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validation conversion occurs before the existence check; if the metafield already exists and a referenced metaobject type is missing, this can raise unnecessarily. Move the conversion logic after the early-return existence check.

Copilot uses AI. Check for mistakes.

Comment on lines +153 to 159
# Process validations to convert metaobject types to GIDs (only for metaobject reference fields)
if options[:validations] && options[:type] && is_metaobject_reference_type?(options[:type])
options[:validations] = convert_validations_types_to_gids(options[:validations])
end

unless get_metafield_gid(owner_type, key, namespace: namespace)
say "Metafield #{namespace}:#{key} not found for #{owner_type}, skipping update"
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validation conversion (which can raise on missing types) is performed before confirming the metafield exists. Move the conversion inside the branch after the existence check to avoid unnecessary errors when skipping.

Copilot uses AI. Check for mistakes.

Comment on lines +105 to +109
def is_metaobject_reference_type?(type)
type_str = type.to_s
type_str == "metaobject_reference" || type_str == "list.metaobject_reference"
end

Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate implementation of is_metaobject_reference_type? also exists in metafield_statements.rb; consolidate into a single shared helper to avoid divergence.

Suggested change
def is_metaobject_reference_type?(type)
type_str = type.to_s
type_str == "metaobject_reference" || type_str == "list.metaobject_reference"
end

Copilot uses AI. Check for mistakes.

Comment on lines +58 to +61
def is_metaobject_reference_type?(type)
type_str = type.to_s
type_str == "metaobject_reference" || type_str == "list.metaobject_reference"
end
Copy link

Copilot AI Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This duplicates the same logic in schema.rb; extract to a shared module (e.g., SchemaUtils) to keep a single authoritative definition.

Copilot uses AI. Check for mistakes.

Copy link
Member

@elia elia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some of the copilot suggestions for extraction could make sense, but feel free to postpone them to the future

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants