@daemux/store-automator 0.10.24 → 0.10.26

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.
@@ -5,14 +5,14 @@
5
5
  },
6
6
  "metadata": {
7
7
  "description": "App Store & Google Play automation for Flutter apps",
8
- "version": "0.10.24"
8
+ "version": "0.10.26"
9
9
  },
10
10
  "plugins": [
11
11
  {
12
12
  "name": "store-automator",
13
13
  "source": "./plugins/store-automator",
14
14
  "description": "3 agents for app store publishing: reviewer, meta-creator, media-designer",
15
- "version": "0.10.24",
15
+ "version": "0.10.26",
16
16
  "keywords": [
17
17
  "flutter",
18
18
  "app-store",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daemux/store-automator",
3
- "version": "0.10.24",
3
+ "version": "0.10.26",
4
4
  "description": "Full App Store & Google Play automation for Flutter apps with Claude Code agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "store-automator",
3
- "version": "0.10.24",
3
+ "version": "0.10.26",
4
4
  "description": "App Store & Google Play automation agents for Flutter app publishing",
5
5
  "author": {
6
6
  "name": "Daemux"
@@ -97,30 +97,48 @@ def get_subscription_prices(headers: dict, sub_id: str) -> list:
97
97
  def get_price_points_for_territory(
98
98
  headers: dict, sub_id: str, territory: str,
99
99
  ) -> list:
100
- """Get available price points for a subscription in a given territory."""
101
- resp = requests.get(
102
- f"{BASE_URL}/subscriptions/{sub_id}/pricePoints",
103
- params={
104
- "filter[territory]": territory,
105
- "include": "territory",
106
- },
107
- headers=headers,
108
- timeout=TIMEOUT,
109
- )
110
- if not resp.ok:
111
- print_api_errors(resp, f"get price points for {territory}")
112
- return []
113
- return resp.json().get("data", [])
100
+ """Get all available price points for a subscription in a given territory.
101
+
102
+ Uses limit=200 (ASC API max) and follows pagination links to ensure
103
+ higher price tiers (e.g. $9.99, $69.99) beyond the first page are included.
104
+ """
105
+ url: str | None = f"{BASE_URL}/subscriptions/{sub_id}/pricePoints"
106
+ params: dict | None = {
107
+ "filter[territory]": territory,
108
+ "include": "territory",
109
+ "limit": 200,
110
+ }
111
+ all_points: list = []
112
+ while url:
113
+ resp = requests.get(url, headers=headers, params=params, timeout=TIMEOUT)
114
+ if not resp.ok:
115
+ print_api_errors(resp, f"get price points for {territory}")
116
+ return all_points
117
+ data = resp.json()
118
+ all_points.extend(data.get("data", []))
119
+ url = data.get("links", {}).get("next")
120
+ params = None # next URL already contains query parameters
121
+ return all_points
114
122
 
115
123
 
116
124
  def find_price_point_by_amount(
117
125
  price_points: list, amount_str: str,
118
126
  ) -> dict | None:
119
- """Find a price point matching the given customer price string."""
127
+ """Find a price point matching the given customer price (numeric comparison).
128
+
129
+ Apple's API may return prices with trailing zeros (e.g. "9.990" instead
130
+ of "9.99"), so we compare as floats with a small tolerance rather than
131
+ doing an exact string match.
132
+ """
120
133
  for pp in price_points:
121
134
  customer_price = pp.get("attributes", {}).get("customerPrice", "")
122
- if customer_price == amount_str:
123
- return pp
135
+ try:
136
+ api_price = float(customer_price)
137
+ target_price = float(amount_str)
138
+ if abs(api_price - target_price) < 0.01:
139
+ return pp
140
+ except (ValueError, TypeError):
141
+ continue
124
142
  return None
125
143
 
126
144
 
@@ -158,7 +158,15 @@ def _sync_pricing(headers: dict, sub_id: str, sub_config: dict) -> None:
158
158
  price_points = get_price_points_for_territory(headers, sub_id, territory)
159
159
  point = find_price_point_by_amount(price_points, amount)
160
160
  if not point:
161
- print(f" WARNING: No price point matching {amount} for {territory}", file=sys.stderr)
161
+ sample = [
162
+ pp.get("attributes", {}).get("customerPrice", "?")
163
+ for pp in price_points[:5]
164
+ ]
165
+ print(
166
+ f" WARNING: No price point matching {amount} for {territory}"
167
+ f" (API returned {len(price_points)} points, first prices: {sample})",
168
+ file=sys.stderr,
169
+ )
162
170
  continue
163
171
  result = create_subscription_price(headers, sub_id, point["id"])
164
172
  if result: