Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ data:
connectorSubtype: api
connectorType: source
definitionId: 9da77001-af33-4bcd-be46-6252bf9342b9
dockerImageTag: 3.5.1
dockerImageTag: 3.5.2
dockerRepository: airbyte/source-shopify
documentationUrl: https://docs.airbyte.com/integrations/sources/shopify
erdUrl: https://dbdocs.io/airbyteio/source-shopify?view=relationships
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
version = "3.5.1"
version = "3.5.2"
name = "source-shopify"
description = "Source CDK implementation for Shopify."
authors = [ "Airbyte <contact@airbyte.io>",]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,8 @@
},
"accepts_marketing_updated_at": {
"description": "Timestamp when marketing acceptance was last updated",
"type": ["null", "string"]
"type": ["null", "string"],
"format": "date-time"
},
"marketing_opt_in_level": {
"description": "Level of marketing opt-in for the customer",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
},
"processed_at": {
"description": "Date and time when the refund was processed",
"type": ["null", "string"]
"type": ["null", "string"],
"format": "date-time"
},
"user_id": {
"description": "ID of the user who initiated the refund",
Expand Down Expand Up @@ -548,7 +549,8 @@
},
"created_at": {
"description": "Date and time when the transaction was created",
"type": ["null", "string"]
"type": ["null", "string"],
"format": "date-time"
},
"currency": {
"description": "Currency used for the transaction",
Expand Down Expand Up @@ -588,7 +590,8 @@
},
"processed_at": {
"description": "Date and time when the transaction was processed",
"type": ["null", "string"]
"type": ["null", "string"],
"format": "date-time"
},
"receipt": {
"description": "Details of the receipt for the transaction",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,8 @@
},
"processed_at": {
"description": "The date and time when the order was processed",
"type": ["null", "string"]
"type": ["null", "string"],
"format": "date-time"
},
"po_number": {
"description": "The purchase order number",
Expand Down Expand Up @@ -893,7 +894,8 @@
"type": ["null", "string"]
},
"accepts_marketing_updated_at": {
"type": ["null", "string"]
"type": ["null", "string"],
"format": "date-time"
},
"marketing_opt_in_level": {
"type": ["null", "string"]
Expand Down Expand Up @@ -2181,7 +2183,8 @@
},
"created_at": {
"description": "Timestamp for when the transaction was created",
"type": ["null", "string"]
"type": ["null", "string"],
"format": "date-time"
},
"currency": {
"description": "Currency of the transaction",
Expand Down Expand Up @@ -2221,7 +2224,8 @@
},
"processed_at": {
"description": "Timestamp for when the transaction was processed",
"type": ["null", "string"]
"type": ["null", "string"],
"format": "date-time"
},
"receipt": {
"description": "Receipt information for the transaction",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
#

import json
from pathlib import Path

import pytest


SCHEMAS_DIR = Path(__file__).parent.parent / "source_shopify" / "schemas"


def _collect_fields_at_path(schema_obj, path=""):
"""Walk a JSON schema and yield (dotted_path, field_def) for every leaf property."""
if not isinstance(schema_obj, dict):
return
for key, definition in schema_obj.get("properties", {}).items():
field_path = f"{path}.{key}" if path else key
yield field_path, definition
# Recurse into nested objects
if "properties" in definition:
yield from _collect_fields_at_path(definition, field_path)
# Recurse into array items
items = definition.get("items", {})
if isinstance(items, dict) and "properties" in items:
yield from _collect_fields_at_path(items, f"{field_path}[]")


@pytest.mark.parametrize(
"schema_file, field_path",
[
pytest.param("orders.json", "processed_at", id="orders-processed_at"),
pytest.param("orders.json", "customer.accepts_marketing_updated_at", id="orders-customer-accepts_marketing_updated_at"),
pytest.param("orders.json", "refunds[].transactions[].created_at", id="orders-refunds-transactions-created_at"),
pytest.param("orders.json", "refunds[].transactions[].processed_at", id="orders-refunds-transactions-processed_at"),
pytest.param("order_refunds.json", "processed_at", id="order_refunds-processed_at"),
pytest.param("order_refunds.json", "transactions[].created_at", id="order_refunds-transactions-created_at"),
pytest.param("order_refunds.json", "transactions[].processed_at", id="order_refunds-transactions-processed_at"),
pytest.param("draft_orders.json", "customer.accepts_marketing_updated_at", id="draft_orders-customer-accepts_marketing_updated_at"),
],
)
def test_datetime_fields_have_format_annotation(schema_file, field_path):
schema = json.loads((SCHEMAS_DIR / schema_file).read_text())
fields = dict(_collect_fields_at_path(schema))
assert field_path in fields, f"Field {field_path} not found in {schema_file}"
field_def = fields[field_path]
assert field_def.get("format") == "date-time", f'{schema_file}: {field_path} is missing \'"format": "date-time"\'. Got: {field_def}'
1 change: 1 addition & 0 deletions docs/integrations/sources/shopify.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ If you synced one of these streams on an earlier connector version and suspect m

| Version | Date | Pull Request | Subject |
|:-----------|:-----------|:---------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 3.5.2 | 2026-06-30 | [81339](https://github.com/airbytehq/airbyte/pull/81339) | Add missing `format: date-time` annotations to datetime fields in `orders`, `order_refunds`, and `draft_orders` schemas so typed destinations map them correctly |
| 3.5.1 | 2026-06-24 | [80787](https://github.com/airbytehq/airbyte/pull/80787) | Validate and normalize the `shop` config value: accept a bare subdomain or full myshopify URL, and reject malformed input with a clear config error. The normalized handle is also written to the `shop_url` record field, so previously-malformed configs now emit a clean value. |
| 3.5.0 | 2026-06-11 | [79624](https://github.com/airbytehq/airbyte/pull/79624) | Add new synchronous cursor-paginated `discount_codes_sync` stream with support for >100 redeem codes per discount |
| 3.4.1 | 2026-06-10 | [78513](https://github.com/airbytehq/airbyte/pull/78513) | Enable `groupObjects: true` on the `discount_codes` bulk query to preserve grouped output for stores with many redeem codes per discount. |
Expand Down
Loading