@gpc-cli/core 0.9.13 → 0.9.15

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.
package/dist/index.js CHANGED
@@ -2048,6 +2048,105 @@ function checkThreshold(value, threshold) {
2048
2048
 
2049
2049
  // src/commands/subscriptions.ts
2050
2050
  import { paginateAll as paginateAll2 } from "@gpc-cli/api";
2051
+ function coerceMoneyUnits(money) {
2052
+ if (money.units !== void 0 && typeof money.units !== "string") {
2053
+ return { ...money, units: String(money.units) };
2054
+ }
2055
+ return money;
2056
+ }
2057
+ function sanitizeSubscription(data) {
2058
+ const { ...cleaned } = data;
2059
+ delete cleaned["state"];
2060
+ delete cleaned["archived"];
2061
+ if (cleaned.basePlans) {
2062
+ cleaned.basePlans = cleaned.basePlans.map((bp) => {
2063
+ const { state: _s, archived: _a, ...cleanBp } = bp;
2064
+ if (cleanBp.regionalConfigs) {
2065
+ cleanBp.regionalConfigs = cleanBp.regionalConfigs.map((rc) => ({
2066
+ ...rc,
2067
+ price: coerceMoneyUnits(rc.price)
2068
+ }));
2069
+ }
2070
+ return cleanBp;
2071
+ });
2072
+ }
2073
+ return cleaned;
2074
+ }
2075
+ function sanitizeOffer(data) {
2076
+ const { state: _s, ...cleaned } = data;
2077
+ delete cleaned["archived"];
2078
+ return cleaned;
2079
+ }
2080
+ function parseDuration(iso) {
2081
+ const match = iso.match(/^P(\d+)D$/);
2082
+ return match?.[1] ? parseInt(match[1], 10) : 0;
2083
+ }
2084
+ var PRORATION_MODE_PREFIX = "SUBSCRIPTION_PRORATION_MODE_";
2085
+ var VALID_PRORATION_MODES = [
2086
+ "SUBSCRIPTION_PRORATION_MODE_CHARGE_ON_NEXT_BILLING_DATE",
2087
+ "SUBSCRIPTION_PRORATION_MODE_CHARGE_FULL_PRICE_IMMEDIATELY"
2088
+ ];
2089
+ function autoFixProrationMode(data) {
2090
+ if (!data.basePlans) return;
2091
+ for (const bp of data.basePlans) {
2092
+ const mode = bp.autoRenewingBasePlanType?.prorationMode;
2093
+ if (mode && !mode.startsWith(PRORATION_MODE_PREFIX)) {
2094
+ bp.autoRenewingBasePlanType.prorationMode = `${PRORATION_MODE_PREFIX}${mode}`;
2095
+ }
2096
+ if (bp.autoRenewingBasePlanType?.prorationMode) {
2097
+ const fullMode = bp.autoRenewingBasePlanType.prorationMode;
2098
+ if (!VALID_PRORATION_MODES.includes(fullMode)) {
2099
+ throw new GpcError(
2100
+ `Invalid prorationMode: "${fullMode}"`,
2101
+ "INVALID_SUBSCRIPTION_DATA",
2102
+ 2,
2103
+ `Valid values: ${VALID_PRORATION_MODES.join(", ")}`
2104
+ );
2105
+ }
2106
+ }
2107
+ }
2108
+ }
2109
+ function validateSubscriptionData(data) {
2110
+ autoFixProrationMode(data);
2111
+ if (data.listings) {
2112
+ for (const [lang, listing] of Object.entries(data.listings)) {
2113
+ if (listing.benefits && listing.benefits.length > 4) {
2114
+ throw new GpcError(
2115
+ `Listing "${lang}" has ${listing.benefits.length} benefits (max 4)`,
2116
+ "INVALID_SUBSCRIPTION_DATA",
2117
+ 2,
2118
+ "Google Play allows a maximum of 4 benefits per subscription listing"
2119
+ );
2120
+ }
2121
+ if (listing.description && listing.description.length > 80) {
2122
+ throw new GpcError(
2123
+ `Listing "${lang}" description is ${listing.description.length} chars (max 80)`,
2124
+ "INVALID_SUBSCRIPTION_DATA",
2125
+ 2,
2126
+ "Google Play limits subscription descriptions to 80 characters"
2127
+ );
2128
+ }
2129
+ }
2130
+ }
2131
+ if (data.basePlans) {
2132
+ for (const bp of data.basePlans) {
2133
+ const autoType = bp.autoRenewingBasePlanType;
2134
+ if (autoType?.gracePeriodDuration && autoType?.accountHoldDuration) {
2135
+ const grace = parseDuration(autoType.gracePeriodDuration);
2136
+ const hold = parseDuration(autoType.accountHoldDuration);
2137
+ const sum = grace + hold;
2138
+ if (sum < 30 || sum > 60) {
2139
+ throw new GpcError(
2140
+ `Base plan "${bp.basePlanId}": gracePeriodDuration (${grace}d) + accountHoldDuration (${hold}d) = ${sum}d (must be 30-60)`,
2141
+ "INVALID_SUBSCRIPTION_DATA",
2142
+ 2,
2143
+ "gracePeriodDuration + accountHoldDuration must sum to between P30D and P60D"
2144
+ );
2145
+ }
2146
+ }
2147
+ }
2148
+ }
2149
+ }
2051
2150
  async function listSubscriptions(client, packageName, options) {
2052
2151
  validatePackageName(packageName);
2053
2152
  if (options?.limit || options?.nextPage) {
@@ -2075,12 +2174,16 @@ async function getSubscription(client, packageName, productId) {
2075
2174
  }
2076
2175
  async function createSubscription(client, packageName, data) {
2077
2176
  validatePackageName(packageName);
2078
- return client.subscriptions.create(packageName, data);
2177
+ validateSubscriptionData(data);
2178
+ const sanitized = sanitizeSubscription(data);
2179
+ return client.subscriptions.create(packageName, sanitized, data.productId);
2079
2180
  }
2080
2181
  async function updateSubscription(client, packageName, productId, data, updateMask) {
2081
2182
  validatePackageName(packageName);
2082
2183
  validateSku(productId);
2083
- return client.subscriptions.update(packageName, productId, data, updateMask);
2184
+ validateSubscriptionData(data);
2185
+ const sanitized = sanitizeSubscription(data);
2186
+ return client.subscriptions.update(packageName, productId, sanitized, updateMask);
2084
2187
  }
2085
2188
  async function deleteSubscription(client, packageName, productId) {
2086
2189
  validatePackageName(packageName);
@@ -2120,17 +2223,19 @@ async function getOffer(client, packageName, productId, basePlanId, offerId) {
2120
2223
  async function createOffer(client, packageName, productId, basePlanId, data) {
2121
2224
  validatePackageName(packageName);
2122
2225
  validateSku(productId);
2123
- return client.subscriptions.createOffer(packageName, productId, basePlanId, data);
2226
+ const sanitized = sanitizeOffer(data);
2227
+ return client.subscriptions.createOffer(packageName, productId, basePlanId, sanitized, data.offerId);
2124
2228
  }
2125
2229
  async function updateOffer(client, packageName, productId, basePlanId, offerId, data, updateMask) {
2126
2230
  validatePackageName(packageName);
2127
2231
  validateSku(productId);
2232
+ const sanitized = sanitizeOffer(data);
2128
2233
  return client.subscriptions.updateOffer(
2129
2234
  packageName,
2130
2235
  productId,
2131
2236
  basePlanId,
2132
2237
  offerId,
2133
- data,
2238
+ sanitized,
2134
2239
  updateMask
2135
2240
  );
2136
2241
  }