@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 +109 -4
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2238
|
+
sanitized,
|
|
2134
2239
|
updateMask
|
|
2135
2240
|
);
|
|
2136
2241
|
}
|