@gpc-cli/cli 0.9.45 → 0.9.47
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/README.md +36 -15
- package/dist/anomalies-V3AFS4LD.js +66 -0
- package/dist/anomalies-V3AFS4LD.js.map +1 -0
- package/dist/{apps-J2446UDA.js → apps-FKD3ZG5X.js} +31 -35
- package/dist/apps-FKD3ZG5X.js.map +1 -0
- package/dist/{audit-N2CRHWUN.js → audit-JASSHRWN.js} +47 -62
- package/dist/audit-JASSHRWN.js.map +1 -0
- package/dist/{auth-XGSTT5G5.js → auth-OTA3SV3J.js} +145 -103
- package/dist/auth-OTA3SV3J.js.map +1 -0
- package/dist/bin.js +6 -4
- package/dist/bin.js.map +1 -1
- package/dist/bundle-F7MUVC5J.js +204 -0
- package/dist/bundle-F7MUVC5J.js.map +1 -0
- package/dist/{cache-SLNFRTI2.js → cache-XKPLZYEB.js} +4 -5
- package/dist/cache-XKPLZYEB.js.map +1 -0
- package/dist/changelog-QLDFG5TV.js +48 -0
- package/dist/changelog-QLDFG5TV.js.map +1 -0
- package/dist/{chunk-4O4D5SGL.js → chunk-3SJ6OXCZ.js} +4 -5
- package/dist/chunk-3SJ6OXCZ.js.map +1 -0
- package/dist/{chunk-U6ZTQ34I.js → chunk-BCBXQC7J.js} +45 -11
- package/dist/chunk-BCBXQC7J.js.map +1 -0
- package/dist/{chunk-AA577WVQ.js → chunk-NQH4G7BI.js} +9 -3
- package/dist/chunk-NQH4G7BI.js.map +1 -0
- package/dist/chunk-SLNJEAMK.js +23 -0
- package/dist/chunk-SLNJEAMK.js.map +1 -0
- package/dist/{chunk-SEVX56VN.js → chunk-WWVURXVO.js} +56 -49
- package/dist/chunk-WWVURXVO.js.map +1 -0
- package/dist/{chunk-NV75I5VP.js → chunk-YFUBD2XB.js} +10 -8
- package/dist/chunk-YFUBD2XB.js.map +1 -0
- package/dist/{config-BUXPDN7N.js → config-NY3TZGVS.js} +8 -5
- package/dist/config-NY3TZGVS.js.map +1 -0
- package/dist/{data-safety-Q7FTCEWU.js → data-safety-AFMD6MYI.js} +12 -27
- package/dist/data-safety-AFMD6MYI.js.map +1 -0
- package/dist/{device-tiers-MIOQEXYY.js → device-tiers-AQAMUQXI.js} +23 -38
- package/dist/device-tiers-AQAMUQXI.js.map +1 -0
- package/dist/diff-6EO4ID6W.js +91 -0
- package/dist/diff-6EO4ID6W.js.map +1 -0
- package/dist/{docs-7DUXIKA3.js → docs-4D2SJ4LY.js} +4 -3
- package/dist/docs-4D2SJ4LY.js.map +1 -0
- package/dist/doctor-QCCWG6Y3.js +708 -0
- package/dist/doctor-QCCWG6Y3.js.map +1 -0
- package/dist/{enterprise-7THXNBTC.js → enterprise-7PWXMSUN.js} +11 -21
- package/dist/enterprise-7PWXMSUN.js.map +1 -0
- package/dist/{external-transactions-2GWIMUVM.js → external-transactions-LCZALS3V.js} +12 -28
- package/dist/external-transactions-LCZALS3V.js.map +1 -0
- package/dist/{feedback-DPTO6DUT.js → feedback-CET2X67K.js} +4 -4
- package/dist/{games-BT777WUO.js → games-ZSNGEI7A.js} +17 -32
- package/dist/games-ZSNGEI7A.js.map +1 -0
- package/dist/{generated-apks-RJWTIX7L.js → generated-apks-RX2IUWSF.js} +30 -38
- package/dist/generated-apks-RX2IUWSF.js.map +1 -0
- package/dist/{grants-TKQJ3IER.js → grants-EBPECI26.js} +22 -40
- package/dist/grants-EBPECI26.js.map +1 -0
- package/dist/{iap-ICAEQLK5.js → iap-OUI5YYN4.js} +30 -51
- package/dist/iap-OUI5YYN4.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/{init-JZ2THPMS.js → init-WSTQTJOD.js} +5 -4
- package/dist/init-WSTQTJOD.js.map +1 -0
- package/dist/{install-skills-OV4HVANW.js → install-skills-6QDUXI5F.js} +5 -6
- package/dist/{install-skills-OV4HVANW.js.map → install-skills-6QDUXI5F.js.map} +1 -1
- package/dist/{internal-sharing-3U2XFHA4.js → internal-sharing-ONNIWIAT.js} +3 -4
- package/dist/{internal-sharing-3U2XFHA4.js.map → internal-sharing-ONNIWIAT.js.map} +1 -1
- package/dist/{listings-77HZW4S5.js → listings-7SGQ4SRX.js} +118 -157
- package/dist/listings-7SGQ4SRX.js.map +1 -0
- package/dist/migrate-ZQCJGQQS.js +138 -0
- package/dist/migrate-ZQCJGQQS.js.map +1 -0
- package/dist/{one-time-products-LHZAXQES.js → one-time-products-MGZTU7OM.js} +65 -120
- package/dist/one-time-products-MGZTU7OM.js.map +1 -0
- package/dist/{preflight-H3HEBYQW.js → preflight-N7ZRG2JI.js} +58 -55
- package/dist/preflight-N7ZRG2JI.js.map +1 -0
- package/dist/{pricing-XQSDTTK5.js → pricing-JJZFICFL.js} +8 -8
- package/dist/{pricing-XQSDTTK5.js.map → pricing-JJZFICFL.js.map} +1 -1
- package/dist/{prompt-BSV22CQZ.js → prompt-GXC2JSLA.js} +2 -2
- package/dist/{publish-Q5ZKEKZ5.js → publish-JPTI4EBT.js} +34 -30
- package/dist/publish-JPTI4EBT.js.map +1 -0
- package/dist/{purchase-options-CKRN4VIW.js → purchase-options-KFWW4JW2.js} +16 -11
- package/dist/purchase-options-KFWW4JW2.js.map +1 -0
- package/dist/{purchases-43AKV6HG.js → purchases-Z3QBM3UO.js} +121 -194
- package/dist/purchases-Z3QBM3UO.js.map +1 -0
- package/dist/{quickstart-4HB62YEL.js → quickstart-Z5Y3FYJU.js} +5 -3
- package/dist/quickstart-Z5Y3FYJU.js.map +1 -0
- package/dist/{quota-UHIQQYOY.js → quota-MZRWYJGR.js} +5 -15
- package/dist/quota-MZRWYJGR.js.map +1 -0
- package/dist/{recovery-5EV2R476.js → recovery-YE3Z7NIN.js} +32 -61
- package/dist/recovery-YE3Z7NIN.js.map +1 -0
- package/dist/{releases-C2WC2K4E.js → releases-276W3BR7.js} +188 -187
- package/dist/releases-276W3BR7.js.map +1 -0
- package/dist/{reports-2YX3RDOS.js → reports-CIB2T3XT.js} +19 -21
- package/dist/reports-CIB2T3XT.js.map +1 -0
- package/dist/reviews-YCBBM656.js +199 -0
- package/dist/reviews-YCBBM656.js.map +1 -0
- package/dist/rtdn-LID2B7XZ.js +87 -0
- package/dist/rtdn-LID2B7XZ.js.map +1 -0
- package/dist/{status-WHGLODGV.js → status-6LH5W4FU.js} +105 -83
- package/dist/status-6LH5W4FU.js.map +1 -0
- package/dist/{subscriptions-CI3JH3VQ.js → subscriptions-DZP3Y7O7.js} +142 -232
- package/dist/subscriptions-DZP3Y7O7.js.map +1 -0
- package/dist/{testers-NZOFA3EF.js → testers-LSMBXCA2.js} +24 -44
- package/dist/testers-LSMBXCA2.js.map +1 -0
- package/dist/tracks-YHMO2A6B.js +98 -0
- package/dist/tracks-YHMO2A6B.js.map +1 -0
- package/dist/{train-CJJVLY4B.js → train-MDD2EBHS.js} +35 -55
- package/dist/train-MDD2EBHS.js.map +1 -0
- package/dist/{update-NAK6CMUX.js → update-XAO5EZHC.js} +30 -15
- package/dist/update-XAO5EZHC.js.map +1 -0
- package/dist/{users-2YTC4Q36.js → users-UKG7VIQH.js} +45 -67
- package/dist/users-UKG7VIQH.js.map +1 -0
- package/dist/{validate-UOVTM6L3.js → validate-QIYSA3N7.js} +8 -10
- package/dist/validate-QIYSA3N7.js.map +1 -0
- package/dist/{version-N64UBW7A.js → version-R3P4NHCF.js} +4 -4
- package/dist/{vitals-A4CS4MSS.js → vitals-PJEQUUAK.js} +174 -165
- package/dist/vitals-PJEQUUAK.js.map +1 -0
- package/package.json +6 -6
- package/dist/anomalies-NU2IN2GJ.js +0 -54
- package/dist/anomalies-NU2IN2GJ.js.map +0 -1
- package/dist/apps-J2446UDA.js.map +0 -1
- package/dist/audit-N2CRHWUN.js.map +0 -1
- package/dist/auth-XGSTT5G5.js.map +0 -1
- package/dist/bundle-F43TD2BQ.js +0 -218
- package/dist/bundle-F43TD2BQ.js.map +0 -1
- package/dist/cache-SLNFRTI2.js.map +0 -1
- package/dist/changelog-ZYD6W5IV.js +0 -53
- package/dist/changelog-ZYD6W5IV.js.map +0 -1
- package/dist/chunk-4O4D5SGL.js.map +0 -1
- package/dist/chunk-AA577WVQ.js.map +0 -1
- package/dist/chunk-FWKYRLKY.js +0 -19
- package/dist/chunk-FWKYRLKY.js.map +0 -1
- package/dist/chunk-NV75I5VP.js.map +0 -1
- package/dist/chunk-SEVX56VN.js.map +0 -1
- package/dist/chunk-U6ZTQ34I.js.map +0 -1
- package/dist/config-BUXPDN7N.js.map +0 -1
- package/dist/data-safety-Q7FTCEWU.js.map +0 -1
- package/dist/device-tiers-MIOQEXYY.js.map +0 -1
- package/dist/diff-V77SMKAQ.js +0 -96
- package/dist/diff-V77SMKAQ.js.map +0 -1
- package/dist/docs-7DUXIKA3.js.map +0 -1
- package/dist/doctor-3Z4ARPM2.js +0 -372
- package/dist/doctor-3Z4ARPM2.js.map +0 -1
- package/dist/enterprise-7THXNBTC.js.map +0 -1
- package/dist/external-transactions-2GWIMUVM.js.map +0 -1
- package/dist/games-BT777WUO.js.map +0 -1
- package/dist/generated-apks-RJWTIX7L.js.map +0 -1
- package/dist/grants-TKQJ3IER.js.map +0 -1
- package/dist/iap-ICAEQLK5.js.map +0 -1
- package/dist/init-JZ2THPMS.js.map +0 -1
- package/dist/listings-77HZW4S5.js.map +0 -1
- package/dist/migrate-SQT6RD6T.js +0 -143
- package/dist/migrate-SQT6RD6T.js.map +0 -1
- package/dist/one-time-products-LHZAXQES.js.map +0 -1
- package/dist/preflight-H3HEBYQW.js.map +0 -1
- package/dist/publish-Q5ZKEKZ5.js.map +0 -1
- package/dist/purchase-options-CKRN4VIW.js.map +0 -1
- package/dist/purchases-43AKV6HG.js.map +0 -1
- package/dist/quickstart-4HB62YEL.js.map +0 -1
- package/dist/quota-UHIQQYOY.js.map +0 -1
- package/dist/recovery-5EV2R476.js.map +0 -1
- package/dist/releases-C2WC2K4E.js.map +0 -1
- package/dist/reports-2YX3RDOS.js.map +0 -1
- package/dist/reviews-2CWOI5CV.js +0 -213
- package/dist/reviews-2CWOI5CV.js.map +0 -1
- package/dist/status-WHGLODGV.js.map +0 -1
- package/dist/subscriptions-CI3JH3VQ.js.map +0 -1
- package/dist/testers-NZOFA3EF.js.map +0 -1
- package/dist/tracks-NERFFEDT.js +0 -107
- package/dist/tracks-NERFFEDT.js.map +0 -1
- package/dist/train-CJJVLY4B.js.map +0 -1
- package/dist/update-NAK6CMUX.js.map +0 -1
- package/dist/users-2YTC4Q36.js.map +0 -1
- package/dist/validate-UOVTM6L3.js.map +0 -1
- package/dist/vitals-A4CS4MSS.js.map +0 -1
- /package/dist/{feedback-DPTO6DUT.js.map → feedback-CET2X67K.js.map} +0 -0
- /package/dist/{prompt-BSV22CQZ.js.map → prompt-GXC2JSLA.js.map} +0 -0
- /package/dist/{version-N64UBW7A.js.map → version-R3P4NHCF.js.map} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
getClient,
|
|
4
4
|
resolvePackageName
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-NQH4G7BI.js";
|
|
6
6
|
import {
|
|
7
7
|
isDryRun,
|
|
8
8
|
printDryRun
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
isInteractive,
|
|
15
15
|
requireConfirm,
|
|
16
16
|
requireOption
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-YFUBD2XB.js";
|
|
18
18
|
|
|
19
19
|
// src/commands/purchases.ts
|
|
20
20
|
import { Option } from "commander";
|
|
@@ -44,24 +44,19 @@ function registerPurchasesCommands(program) {
|
|
|
44
44
|
const packageName = resolvePackageName(program.opts()["app"], config);
|
|
45
45
|
const client = await getClient(config);
|
|
46
46
|
const format = getOutputFormat(program, config);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
console.log(formatOutput(result, format));
|
|
61
|
-
}
|
|
62
|
-
} catch (error) {
|
|
63
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
64
|
-
process.exit(4);
|
|
47
|
+
const result = await getProductPurchase(client, packageName, productId, token);
|
|
48
|
+
if (format !== "json") {
|
|
49
|
+
const r = result;
|
|
50
|
+
const row = {
|
|
51
|
+
orderId: r["orderId"] || "-",
|
|
52
|
+
purchaseState: r["purchaseState"] ?? "-",
|
|
53
|
+
consumptionState: r["consumptionState"] ?? "-",
|
|
54
|
+
purchaseTime: r["purchaseTimeMillis"] ? new Date(Number(r["purchaseTimeMillis"])).toISOString() : "-",
|
|
55
|
+
acknowledged: r["acknowledgementState"] ?? "-"
|
|
56
|
+
};
|
|
57
|
+
console.log(formatOutput(row, format));
|
|
58
|
+
} else {
|
|
59
|
+
console.log(formatOutput(result, format));
|
|
65
60
|
}
|
|
66
61
|
});
|
|
67
62
|
purchases.command("acknowledge <product-id> <token>").description("Acknowledge a product purchase").option("--payload <text>", "Developer payload").action(async (productId, token, options) => {
|
|
@@ -82,13 +77,8 @@ function registerPurchasesCommands(program) {
|
|
|
82
77
|
return;
|
|
83
78
|
}
|
|
84
79
|
const client = await getClient(config);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
console.log(`Purchase acknowledged.`);
|
|
88
|
-
} catch (error) {
|
|
89
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
90
|
-
process.exit(4);
|
|
91
|
-
}
|
|
80
|
+
await acknowledgeProductPurchase(client, packageName, productId, token, options.payload);
|
|
81
|
+
console.log(`Purchase acknowledged.`);
|
|
92
82
|
});
|
|
93
83
|
purchases.command("consume <product-id> <token>").description("Consume a product purchase").action(async (productId, token) => {
|
|
94
84
|
const config = await loadConfig();
|
|
@@ -107,13 +97,8 @@ function registerPurchasesCommands(program) {
|
|
|
107
97
|
return;
|
|
108
98
|
}
|
|
109
99
|
const client = await getClient(config);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
console.log(`Purchase consumed.`);
|
|
113
|
-
} catch (error) {
|
|
114
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
115
|
-
process.exit(4);
|
|
116
|
-
}
|
|
100
|
+
await consumeProductPurchase(client, packageName, productId, token);
|
|
101
|
+
console.log(`Purchase consumed.`);
|
|
117
102
|
});
|
|
118
103
|
const sub = purchases.command("subscription").description("Manage subscription purchases");
|
|
119
104
|
sub.command("get <token>").description("Get a subscription purchase (v2)").action(async (token) => {
|
|
@@ -121,26 +106,21 @@ function registerPurchasesCommands(program) {
|
|
|
121
106
|
const packageName = resolvePackageName(program.opts()["app"], config);
|
|
122
107
|
const client = await getClient(config);
|
|
123
108
|
const format = getOutputFormat(program, config);
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
console.log(formatOutput(result, format));
|
|
140
|
-
}
|
|
141
|
-
} catch (error) {
|
|
142
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
143
|
-
process.exit(4);
|
|
109
|
+
const result = await getSubscriptionPurchase(client, packageName, token);
|
|
110
|
+
if (format !== "json") {
|
|
111
|
+
const r = result;
|
|
112
|
+
const lineItems = r["lineItems"];
|
|
113
|
+
const row = {
|
|
114
|
+
subscriptionState: r["subscriptionState"] || "-",
|
|
115
|
+
startTime: r["startTime"] || "-",
|
|
116
|
+
expiryTime: r["expiryTime"] || "-",
|
|
117
|
+
linkedPurchaseToken: r["linkedPurchaseToken"] ? "yes" : "no",
|
|
118
|
+
lineItems: lineItems?.length || 0,
|
|
119
|
+
acknowledgement: r["acknowledgementState"] || "-"
|
|
120
|
+
};
|
|
121
|
+
console.log(formatOutput(row, format));
|
|
122
|
+
} else {
|
|
123
|
+
console.log(formatOutput(result, format));
|
|
144
124
|
}
|
|
145
125
|
});
|
|
146
126
|
sub.command("cancel <subscription-id> <token>").description("Cancel a subscription (v1)").action(async (subscriptionId, token) => {
|
|
@@ -160,13 +140,8 @@ function registerPurchasesCommands(program) {
|
|
|
160
140
|
return;
|
|
161
141
|
}
|
|
162
142
|
const client = await getClient(config);
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
console.log(`Subscription cancelled.`);
|
|
166
|
-
} catch (error) {
|
|
167
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
168
|
-
process.exit(4);
|
|
169
|
-
}
|
|
143
|
+
await cancelSubscriptionPurchase(client, packageName, subscriptionId, token);
|
|
144
|
+
console.log(`Subscription cancelled.`);
|
|
170
145
|
});
|
|
171
146
|
sub.command("defer <subscription-id> <token>").description("Defer a subscription expiry").option("--expiry <iso-date>", "Desired new expiry date (ISO 8601)").action(async (subscriptionId, token, options) => {
|
|
172
147
|
const config = await loadConfig();
|
|
@@ -195,19 +170,14 @@ function registerPurchasesCommands(program) {
|
|
|
195
170
|
return;
|
|
196
171
|
}
|
|
197
172
|
const client = await getClient(config);
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
console.log(formatOutput(result, format));
|
|
207
|
-
} catch (error) {
|
|
208
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
209
|
-
process.exit(4);
|
|
210
|
-
}
|
|
173
|
+
const result = await deferSubscriptionPurchase(
|
|
174
|
+
client,
|
|
175
|
+
packageName,
|
|
176
|
+
subscriptionId,
|
|
177
|
+
token,
|
|
178
|
+
options.expiry
|
|
179
|
+
);
|
|
180
|
+
console.log(formatOutput(result, format));
|
|
211
181
|
});
|
|
212
182
|
sub.command("refund <token>").description("Refund a subscription purchase (v2)").action(async (token) => {
|
|
213
183
|
const config = await loadConfig();
|
|
@@ -227,13 +197,8 @@ function registerPurchasesCommands(program) {
|
|
|
227
197
|
return;
|
|
228
198
|
}
|
|
229
199
|
const client = await getClient(config);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
console.log(`Subscription refunded.`);
|
|
233
|
-
} catch (error) {
|
|
234
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
235
|
-
process.exit(4);
|
|
236
|
-
}
|
|
200
|
+
await refundSubscriptionV2(client, packageName, token);
|
|
201
|
+
console.log(`Subscription refunded.`);
|
|
237
202
|
});
|
|
238
203
|
sub.command("revoke <token>").description("Revoke a subscription (v2)").action(async (token) => {
|
|
239
204
|
const config = await loadConfig();
|
|
@@ -252,49 +217,41 @@ function registerPurchasesCommands(program) {
|
|
|
252
217
|
return;
|
|
253
218
|
}
|
|
254
219
|
const client = await getClient(config);
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
console.log(`Subscription revoked.`);
|
|
258
|
-
} catch (error) {
|
|
259
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
260
|
-
process.exit(4);
|
|
261
|
-
}
|
|
220
|
+
await revokeSubscriptionPurchase(client, packageName, token);
|
|
221
|
+
console.log(`Subscription revoked.`);
|
|
262
222
|
});
|
|
263
|
-
purchases.command("voided").description("List voided purchases").option("--start-time <time>", "Start time (milliseconds)").option("--end-time <time>", "End time (milliseconds)").addOption(
|
|
223
|
+
purchases.command("voided").description("List voided purchases").option("--start-time <time>", "Start time (milliseconds)").option("--end-time <time>", "End time (milliseconds)").option("--type <n>", "Purchase type: 0=in-app only (default), 1=in-app + subscriptions", parseInt).option("--include-partial-refunds", "Include quantity-based partial refunds").addOption(
|
|
264
224
|
new Option("--max-results <n>", "Maximum results per page").argParser(parseInt).hideHelp()
|
|
265
225
|
).option("--limit <n>", "Maximum total results", parseInt).option("--next-page <token>", "Resume from page token").action(async (options) => {
|
|
266
226
|
const config = await loadConfig();
|
|
267
227
|
const packageName = resolvePackageName(program.opts()["app"], config);
|
|
268
228
|
const client = await getClient(config);
|
|
269
229
|
const format = getOutputFormat(program, config);
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
console.log("No voided purchases found.");
|
|
291
|
-
}
|
|
230
|
+
const result = await listVoidedPurchases(client, packageName, {
|
|
231
|
+
startTime: options.startTime,
|
|
232
|
+
endTime: options.endTime,
|
|
233
|
+
type: options.type,
|
|
234
|
+
includeQuantityBasedPartialRefund: options.includePartialRefunds,
|
|
235
|
+
maxResults: options.maxResults,
|
|
236
|
+
limit: options.limit,
|
|
237
|
+
nextPage: options.nextPage
|
|
238
|
+
});
|
|
239
|
+
if (format !== "json") {
|
|
240
|
+
const purchases2 = result["voidedPurchases"];
|
|
241
|
+
if (purchases2 && purchases2.length > 0) {
|
|
242
|
+
const rows = purchases2.map((p) => ({
|
|
243
|
+
orderId: p["orderId"] || "-",
|
|
244
|
+
purchaseToken: String(p["purchaseToken"] || "-").slice(0, 16) + "...",
|
|
245
|
+
voidedTime: p["voidedTimeMillis"] ? new Date(Number(p["voidedTimeMillis"])).toISOString() : "-",
|
|
246
|
+
voidedSource: p["voidedSource"] ?? "-",
|
|
247
|
+
voidedReason: p["voidedReason"] ?? "-"
|
|
248
|
+
}));
|
|
249
|
+
console.log(formatOutput(rows, format));
|
|
292
250
|
} else {
|
|
293
|
-
console.log(
|
|
251
|
+
console.log("No voided purchases found.");
|
|
294
252
|
}
|
|
295
|
-
}
|
|
296
|
-
console.
|
|
297
|
-
process.exit(4);
|
|
253
|
+
} else {
|
|
254
|
+
console.log(formatOutput(result, format));
|
|
298
255
|
}
|
|
299
256
|
});
|
|
300
257
|
const orders = purchases.command("orders").description("Manage orders");
|
|
@@ -317,40 +274,30 @@ function registerPurchasesCommands(program) {
|
|
|
317
274
|
return;
|
|
318
275
|
}
|
|
319
276
|
const client = await getClient(config);
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
console.log(`Order ${orderId} refunded.`);
|
|
326
|
-
} catch (error) {
|
|
327
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
328
|
-
process.exit(4);
|
|
329
|
-
}
|
|
277
|
+
await refundOrder(client, packageName, orderId, {
|
|
278
|
+
fullRefund: options.fullRefund,
|
|
279
|
+
proratedRefund: options.proratedRefund
|
|
280
|
+
});
|
|
281
|
+
console.log(`Order ${orderId} refunded.`);
|
|
330
282
|
});
|
|
331
283
|
orders.command("get <order-id>").description("Get order details").action(async (orderId) => {
|
|
332
284
|
const config = await loadConfig();
|
|
333
285
|
const packageName = resolvePackageName(program.opts()["app"], config);
|
|
334
286
|
const client = await getClient(config);
|
|
335
287
|
const format = getOutputFormat(program, config);
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
console.log(formatOutput(result, format));
|
|
350
|
-
}
|
|
351
|
-
} catch (error) {
|
|
352
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
353
|
-
process.exit(4);
|
|
288
|
+
const result = await getOrderDetails(client, packageName, orderId);
|
|
289
|
+
if (format !== "json") {
|
|
290
|
+
const row = {
|
|
291
|
+
orderId: result.orderId,
|
|
292
|
+
state: result.state,
|
|
293
|
+
purchaseToken: result.purchaseToken ? result.purchaseToken.slice(0, 16) + "..." : "-",
|
|
294
|
+
createTime: result.createTime || "-",
|
|
295
|
+
total: result.total ? `${result.total.units || "0"}.${String(result.total.nanos || 0).padStart(9, "0").slice(0, 2)} ${result.total.currencyCode}` : "-",
|
|
296
|
+
lineItems: result.lineItems?.length || 0
|
|
297
|
+
};
|
|
298
|
+
console.log(formatOutput(row, format));
|
|
299
|
+
} else {
|
|
300
|
+
console.log(formatOutput(result, format));
|
|
354
301
|
}
|
|
355
302
|
});
|
|
356
303
|
orders.command("batch-get").description("Get multiple orders at once").requiredOption("--ids <order-ids>", "Comma-separated order IDs (max 1000)").action(async (options) => {
|
|
@@ -359,26 +306,21 @@ function registerPurchasesCommands(program) {
|
|
|
359
306
|
const client = await getClient(config);
|
|
360
307
|
const format = getOutputFormat(program, config);
|
|
361
308
|
const orderIds = options.ids.split(",").map((id) => id.trim()).filter(Boolean);
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
if (
|
|
365
|
-
|
|
366
|
-
console.log("No orders found.");
|
|
367
|
-
} else {
|
|
368
|
-
const rows = result.map((o) => ({
|
|
369
|
-
orderId: o.orderId,
|
|
370
|
-
state: o.state,
|
|
371
|
-
createTime: o.createTime || "-",
|
|
372
|
-
lineItems: o.lineItems?.length || 0
|
|
373
|
-
}));
|
|
374
|
-
console.log(formatOutput(rows, format));
|
|
375
|
-
}
|
|
309
|
+
const result = await batchGetOrders(client, packageName, orderIds);
|
|
310
|
+
if (format !== "json") {
|
|
311
|
+
if (result.length === 0) {
|
|
312
|
+
console.log("No orders found.");
|
|
376
313
|
} else {
|
|
377
|
-
|
|
314
|
+
const rows = result.map((o) => ({
|
|
315
|
+
orderId: o.orderId,
|
|
316
|
+
state: o.state,
|
|
317
|
+
createTime: o.createTime || "-",
|
|
318
|
+
lineItems: o.lineItems?.length || 0
|
|
319
|
+
}));
|
|
320
|
+
console.log(formatOutput(rows, format));
|
|
378
321
|
}
|
|
379
|
-
}
|
|
380
|
-
console.
|
|
381
|
-
process.exit(4);
|
|
322
|
+
} else {
|
|
323
|
+
console.log(formatOutput(result, format));
|
|
382
324
|
}
|
|
383
325
|
});
|
|
384
326
|
const product = purchases.command("product").description("Product purchase operations");
|
|
@@ -387,24 +329,19 @@ function registerPurchasesCommands(program) {
|
|
|
387
329
|
const packageName = resolvePackageName(program.opts()["app"], config);
|
|
388
330
|
const client = await getClient(config);
|
|
389
331
|
const format = getOutputFormat(program, config);
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
console.log(formatOutput(result, format));
|
|
404
|
-
}
|
|
405
|
-
} catch (error) {
|
|
406
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
407
|
-
process.exit(4);
|
|
332
|
+
const result = await getProductPurchaseV2(client, packageName, token);
|
|
333
|
+
if (format !== "json") {
|
|
334
|
+
const row = {
|
|
335
|
+
orderId: result.orderId || "-",
|
|
336
|
+
state: result.purchaseStateContext?.state || "-",
|
|
337
|
+
regionCode: result.regionCode || "-",
|
|
338
|
+
completionTime: result.purchaseCompletionTime || "-",
|
|
339
|
+
acknowledgement: result.acknowledgementState || "-",
|
|
340
|
+
lineItems: result.productLineItem?.length || 0
|
|
341
|
+
};
|
|
342
|
+
console.log(formatOutput(row, format));
|
|
343
|
+
} else {
|
|
344
|
+
console.log(formatOutput(result, format));
|
|
408
345
|
}
|
|
409
346
|
});
|
|
410
347
|
sub.command("cancel-v2 <token>").description("Cancel a subscription (v2 \u2014 supports cancellation types)").option("--type <cancellationType>", "Cancellation type (e.g., USER_CANCELED, SYSTEM_CANCELED, DEVELOPER_CANCELED, REPLACED)").action(async (token, options) => {
|
|
@@ -421,13 +358,8 @@ function registerPurchasesCommands(program) {
|
|
|
421
358
|
return;
|
|
422
359
|
}
|
|
423
360
|
const client = await getClient(config);
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
console.log("Subscription cancelled.");
|
|
427
|
-
} catch (error) {
|
|
428
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
429
|
-
process.exit(4);
|
|
430
|
-
}
|
|
361
|
+
await cancelSubscriptionV2(client, packageName, token, options.type);
|
|
362
|
+
console.log("Subscription cancelled.");
|
|
431
363
|
});
|
|
432
364
|
sub.command("defer-v2 <token>").description("Defer a subscription renewal (v2 \u2014 supports add-on subscriptions)").requiredOption("--until <date>", "Desired expiry time (ISO 8601 date)").action(async (token, options) => {
|
|
433
365
|
const config = await loadConfig();
|
|
@@ -443,16 +375,11 @@ function registerPurchasesCommands(program) {
|
|
|
443
375
|
return;
|
|
444
376
|
}
|
|
445
377
|
const client = await getClient(config);
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
console.log(`Subscription deferred. New expiry: ${result.newExpiryTime}`);
|
|
449
|
-
} catch (error) {
|
|
450
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
451
|
-
process.exit(4);
|
|
452
|
-
}
|
|
378
|
+
const result = await deferSubscriptionV2(client, packageName, token, options.until);
|
|
379
|
+
console.log(`Subscription deferred. New expiry: ${result.newExpiryTime}`);
|
|
453
380
|
});
|
|
454
381
|
}
|
|
455
382
|
export {
|
|
456
383
|
registerPurchasesCommands
|
|
457
384
|
};
|
|
458
|
-
//# sourceMappingURL=purchases-
|
|
385
|
+
//# sourceMappingURL=purchases-Z3QBM3UO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/purchases.ts"],"sourcesContent":["import { resolvePackageName, getClient } from \"../resolve.js\";\nimport type { Command } from \"commander\";\nimport { Option } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\n\nimport {\n getProductPurchase,\n getProductPurchaseV2,\n acknowledgeProductPurchase,\n consumeProductPurchase,\n getSubscriptionPurchase,\n cancelSubscriptionPurchase,\n cancelSubscriptionV2,\n deferSubscriptionPurchase,\n deferSubscriptionV2,\n revokeSubscriptionPurchase,\n refundSubscriptionV2,\n listVoidedPurchases,\n refundOrder,\n getOrderDetails,\n batchGetOrders,\n formatOutput,\n} from \"@gpc-cli/core\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isInteractive, requireOption, requireConfirm } from \"../prompt.js\";\n\n\n\nexport function registerPurchasesCommands(program: Command): void {\n const purchases = program.command(\"purchases\").description(\"Manage purchases and orders\");\n\n purchases\n .command(\"get <product-id> <token>\")\n .description(\"Get a product purchase\")\n .action(async (productId: string, token: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n const result = await getProductPurchase(client, packageName, productId, token);\n if (format !== \"json\") {\n const r = result as unknown as Record<string, unknown>;\n const row = {\n orderId: r[\"orderId\"] || \"-\",\n purchaseState: r[\"purchaseState\"] ?? \"-\",\n consumptionState: r[\"consumptionState\"] ?? \"-\",\n purchaseTime: r[\"purchaseTimeMillis\"]\n ? new Date(Number(r[\"purchaseTimeMillis\"])).toISOString()\n : \"-\",\n acknowledged: r[\"acknowledgementState\"] ?? \"-\",\n };\n console.log(formatOutput(row, format));\n } else {\n console.log(formatOutput(result, format));\n }\n });\n\n purchases\n .command(\"acknowledge <product-id> <token>\")\n .description(\"Acknowledge a product purchase\")\n .option(\"--payload <text>\", \"Developer payload\")\n .action(async (productId: string, token: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"purchases acknowledge\",\n action: \"acknowledge\",\n target: `${productId}/${token}`,\n details: { payload: options.payload },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n await acknowledgeProductPurchase(client, packageName, productId, token, options.payload);\n console.log(`Purchase acknowledged.`);\n });\n\n purchases\n .command(\"consume <product-id> <token>\")\n .description(\"Consume a product purchase\")\n .action(async (productId: string, token: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"purchases consume\",\n action: \"consume\",\n target: `${productId}/${token}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n await consumeProductPurchase(client, packageName, productId, token);\n console.log(`Purchase consumed.`);\n });\n\n // --- Subscription purchases ---\n const sub = purchases.command(\"subscription\").description(\"Manage subscription purchases\");\n\n sub\n .command(\"get <token>\")\n .description(\"Get a subscription purchase (v2)\")\n .action(async (token: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n const result = await getSubscriptionPurchase(client, packageName, token);\n if (format !== \"json\") {\n const r = result as unknown as Record<string, unknown>;\n const lineItems = r[\"lineItems\"] as Record<string, unknown>[] | undefined;\n const row = {\n subscriptionState: r[\"subscriptionState\"] || \"-\",\n startTime: r[\"startTime\"] || \"-\",\n expiryTime: r[\"expiryTime\"] || \"-\",\n linkedPurchaseToken: r[\"linkedPurchaseToken\"] ? \"yes\" : \"no\",\n lineItems: lineItems?.length || 0,\n acknowledgement: r[\"acknowledgementState\"] || \"-\",\n };\n console.log(formatOutput(row, format));\n } else {\n console.log(formatOutput(result, format));\n }\n });\n\n sub\n .command(\"cancel <subscription-id> <token>\")\n .description(\"Cancel a subscription (v1)\")\n .action(async (subscriptionId: string, token: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"purchases subscription cancel\",\n action: \"cancel subscription\",\n target: `${subscriptionId}/${token}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n await cancelSubscriptionPurchase(client, packageName, subscriptionId, token);\n console.log(`Subscription cancelled.`);\n });\n\n sub\n .command(\"defer <subscription-id> <token>\")\n .description(\"Defer a subscription expiry\")\n .option(\"--expiry <iso-date>\", \"Desired new expiry date (ISO 8601)\")\n .action(async (subscriptionId: string, token: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n const interactive = isInteractive(program);\n\n options.expiry = await requireOption(\n \"expiry\",\n options.expiry,\n {\n message: \"New expiry date (ISO 8601, e.g. 2026-12-31T23:59:59Z):\",\n },\n interactive,\n );\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"purchases subscription defer\",\n action: \"defer subscription\",\n target: `${subscriptionId}/${token}`,\n details: { expiry: options.expiry },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n const result = await deferSubscriptionPurchase(\n client,\n packageName,\n subscriptionId,\n token,\n options.expiry,\n );\n console.log(formatOutput(result, format));\n });\n\n sub\n .command(\"refund <token>\")\n .description(\"Refund a subscription purchase (v2)\")\n .action(async (token: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Refund subscription for token \"${token.slice(0, 16)}...\"?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"purchases subscription refund\",\n action: \"refund subscription\",\n target: token,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n await refundSubscriptionV2(client, packageName, token);\n console.log(`Subscription refunded.`);\n });\n\n sub\n .command(\"revoke <token>\")\n .description(\"Revoke a subscription (v2)\")\n .action(async (token: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"purchases subscription revoke\",\n action: \"revoke subscription\",\n target: token,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n await revokeSubscriptionPurchase(client, packageName, token);\n console.log(`Subscription revoked.`);\n });\n\n // --- Voided purchases ---\n purchases\n .command(\"voided\")\n .description(\"List voided purchases\")\n .option(\"--start-time <time>\", \"Start time (milliseconds)\")\n .option(\"--end-time <time>\", \"End time (milliseconds)\")\n .option(\"--type <n>\", \"Purchase type: 0=in-app only (default), 1=in-app + subscriptions\", parseInt)\n .option(\"--include-partial-refunds\", \"Include quantity-based partial refunds\")\n .addOption(\n new Option(\"--max-results <n>\", \"Maximum results per page\").argParser(parseInt).hideHelp(),\n )\n .option(\"--limit <n>\", \"Maximum total results\", parseInt)\n .option(\"--next-page <token>\", \"Resume from page token\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n const result = await listVoidedPurchases(client, packageName, {\n startTime: options.startTime,\n endTime: options.endTime,\n type: options.type,\n includeQuantityBasedPartialRefund: options.includePartialRefunds,\n maxResults: options.maxResults,\n limit: options.limit,\n nextPage: options.nextPage,\n });\n if (format !== \"json\") {\n const purchases = (result as Record<string, unknown>)[\"voidedPurchases\"] as\n | Record<string, unknown>[]\n | undefined;\n if (purchases && purchases.length > 0) {\n const rows = purchases.map((p) => ({\n orderId: p[\"orderId\"] || \"-\",\n purchaseToken: String(p[\"purchaseToken\"] || \"-\").slice(0, 16) + \"...\",\n voidedTime: p[\"voidedTimeMillis\"]\n ? new Date(Number(p[\"voidedTimeMillis\"])).toISOString()\n : \"-\",\n voidedSource: p[\"voidedSource\"] ?? \"-\",\n voidedReason: p[\"voidedReason\"] ?? \"-\",\n }));\n console.log(formatOutput(rows, format));\n } else {\n console.log(\"No voided purchases found.\");\n }\n } else {\n console.log(formatOutput(result, format));\n }\n });\n\n // --- Orders ---\n const orders = purchases.command(\"orders\").description(\"Manage orders\");\n\n orders\n .command(\"refund <order-id>\")\n .description(\"Refund an order\")\n .option(\"--full-refund\", \"Full refund\")\n .option(\"--prorated-refund\", \"Prorated refund\")\n .action(async (orderId: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Refund order \"${orderId}\"?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"purchases orders refund\",\n action: \"refund\",\n target: orderId,\n details: { fullRefund: options.fullRefund, proratedRefund: options.proratedRefund },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n await refundOrder(client, packageName, orderId, {\n fullRefund: options.fullRefund,\n proratedRefund: options.proratedRefund,\n });\n console.log(`Order ${orderId} refunded.`);\n });\n\n orders\n .command(\"get <order-id>\")\n .description(\"Get order details\")\n .action(async (orderId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n const result = await getOrderDetails(client, packageName, orderId);\n if (format !== \"json\") {\n const row = {\n orderId: result.orderId,\n state: result.state,\n purchaseToken: result.purchaseToken ? result.purchaseToken.slice(0, 16) + \"...\" : \"-\",\n createTime: result.createTime || \"-\",\n total: result.total ? `${result.total.units || \"0\"}.${String(result.total.nanos || 0).padStart(9, \"0\").slice(0, 2)} ${result.total.currencyCode}` : \"-\",\n lineItems: result.lineItems?.length || 0,\n };\n console.log(formatOutput(row, format));\n } else {\n console.log(formatOutput(result, format));\n }\n });\n\n orders\n .command(\"batch-get\")\n .description(\"Get multiple orders at once\")\n .requiredOption(\"--ids <order-ids>\", \"Comma-separated order IDs (max 1000)\")\n .action(async (options: { ids: string }) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n const orderIds = options.ids.split(\",\").map((id) => id.trim()).filter(Boolean);\n\n const result = await batchGetOrders(client, packageName, orderIds);\n if (format !== \"json\") {\n if (result.length === 0) {\n console.log(\"No orders found.\");\n } else {\n const rows = result.map((o) => ({\n orderId: o.orderId,\n state: o.state,\n createTime: o.createTime || \"-\",\n lineItems: o.lineItems?.length || 0,\n }));\n console.log(formatOutput(rows, format));\n }\n } else {\n console.log(formatOutput(result, format));\n }\n });\n\n // --- Product purchases V2 (Jun 2025) ---\n const product = purchases.command(\"product\").description(\"Product purchase operations\");\n\n product\n .command(\"get-v2 <token>\")\n .description(\"Get product purchase details (v2 — supports multi-offer OTPs)\")\n .action(async (token: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n const result = await getProductPurchaseV2(client, packageName, token);\n if (format !== \"json\") {\n const row = {\n orderId: result.orderId || \"-\",\n state: result.purchaseStateContext?.state || \"-\",\n regionCode: result.regionCode || \"-\",\n completionTime: result.purchaseCompletionTime || \"-\",\n acknowledgement: result.acknowledgementState || \"-\",\n lineItems: result.productLineItem?.length || 0,\n };\n console.log(formatOutput(row, format));\n } else {\n console.log(formatOutput(result, format));\n }\n });\n\n // --- Subscription V2 cancel/defer (Sep 2025 / Jan 2026) ---\n // Added to existing `sub` group alongside v1 cancel/defer\n\n sub\n .command(\"cancel-v2 <token>\")\n .description(\"Cancel a subscription (v2 — supports cancellation types)\")\n .option(\"--type <cancellationType>\", \"Cancellation type (e.g., USER_CANCELED, SYSTEM_CANCELED, DEVELOPER_CANCELED, REPLACED)\")\n .action(async (token: string, options: { type?: string }) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Cancel subscription (token: ${token.slice(0, 16)}...)?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n { command: \"purchases subscription cancel-v2\", action: \"cancel\", target: token.slice(0, 16) + \"...\", details: { cancellationType: options.type } },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n await cancelSubscriptionV2(client, packageName, token, options.type);\n console.log(\"Subscription cancelled.\");\n });\n\n sub\n .command(\"defer-v2 <token>\")\n .description(\"Defer a subscription renewal (v2 — supports add-on subscriptions)\")\n .requiredOption(\"--until <date>\", \"Desired expiry time (ISO 8601 date)\")\n .action(async (token: string, options: { until: string }) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Defer subscription renewal to ${options.until}?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n { command: \"purchases subscription defer-v2\", action: \"defer\", target: token.slice(0, 16) + \"...\", details: { desiredExpiryTime: options.until } },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n const result = await deferSubscriptionV2(client, packageName, token, options.until);\n console.log(`Subscription deferred. New expiry: ${result.newExpiryTime}`);\n });\n}\n"],"mappings":"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","names":["purchases"]}
|
|
@@ -51,7 +51,9 @@ function registerQuickstartCommand(program) {
|
|
|
51
51
|
stdio: "pipe",
|
|
52
52
|
encoding: "utf-8"
|
|
53
53
|
});
|
|
54
|
-
if (result.
|
|
54
|
+
if (result.error) {
|
|
55
|
+
step(4, total, "Running doctor...", "\u2014 could not find gpc in PATH. Run: gpc doctor");
|
|
56
|
+
} else if (result.status === 0) {
|
|
55
57
|
step(4, total, "Running doctor...", "\u2713 All checks passed");
|
|
56
58
|
} else {
|
|
57
59
|
step(4, total, "Running doctor...", "\u26A0 Some checks failed \u2014 run: gpc doctor");
|
|
@@ -77,11 +79,11 @@ function registerQuickstartCommand(program) {
|
|
|
77
79
|
} else {
|
|
78
80
|
console.log("Fix the issues above, then run 'gpc quickstart' again.");
|
|
79
81
|
console.log("Need help? Run 'gpc doctor' for detailed diagnostics.");
|
|
80
|
-
process.
|
|
82
|
+
process.exitCode = 1;
|
|
81
83
|
}
|
|
82
84
|
});
|
|
83
85
|
}
|
|
84
86
|
export {
|
|
85
87
|
registerQuickstartCommand
|
|
86
88
|
};
|
|
87
|
-
//# sourceMappingURL=quickstart-
|
|
89
|
+
//# sourceMappingURL=quickstart-Z5Y3FYJU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/quickstart.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\n\nfunction step(n: number, total: number, label: string, status: string): void {\n const padded = `Step ${n}/${total} ${label}`.padEnd(48);\n console.log(`${padded}${status}`);\n}\n\nexport function registerQuickstartCommand(program: Command): void {\n program\n .command(\"quickstart\")\n .description(\"Guided setup: verify credentials, config, and show next steps\")\n .action(async () => {\n console.log(\"\\nGPC — Quick Start Setup\");\n console.log(\"══════════════════════════════════════════════════════\");\n\n const total = 4;\n let allPassed = true;\n\n // Step 1: Check for existing config\n let config: Awaited<ReturnType<typeof loadConfig>> | null = null;\n try {\n config = await loadConfig();\n const profileInfo = config.profile ? `profile \"${config.profile}\"` : \"default config\";\n step(1, total, \"Checking for existing config...\", `✓ Found ${profileInfo}`);\n } catch {\n step(1, total, \"Checking for existing config...\", \"⚠ No config found\");\n console.log(\"\\n Run: gpc config init\");\n console.log(\" Or: gpc auth login (runs interactive setup)\");\n allPassed = false;\n }\n\n // Step 2: Verify credentials\n if (config) {\n try {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n const email = auth.getClientEmail();\n step(2, total, \"Verifying credentials...\", `✓ ${email}`);\n } catch {\n step(2, total, \"Verifying credentials...\", \"✗ Auth failed — run: gpc auth login\");\n allPassed = false;\n }\n } else {\n step(2, total, \"Verifying credentials...\", \"— skipped (no config)\");\n allPassed = false;\n }\n\n // Step 3: Check package name\n const packageName = config?.app ?? (program.opts()[\"app\"] as string | undefined);\n if (packageName) {\n step(3, total, \"Checking package name...\", `✓ ${packageName}`);\n } else {\n step(3, total, \"Checking package name...\", \"⚠ Not set — run: gpc config set app <package>\");\n allPassed = false;\n }\n\n // Step 4: Run doctor inline\n if (allPassed) {\n try {\n const { spawnSync } = await import(\"node:child_process\");\n // Use \"gpc\" directly — process.execPath + process.argv[1] fails when\n // installed via Homebrew (Bun-compiled binary can't be re-run under Node)\n const result = spawnSync(\"gpc\", [\"doctor\"], {\n stdio: \"pipe\",\n encoding: \"utf-8\",\n });\n if (result.error) {\n // gpc not found in PATH (ENOENT) or other spawn error\n step(4, total, \"Running doctor...\", \"\\u2014 could not find gpc in PATH. Run: gpc doctor\");\n } else if (result.status === 0) {\n step(4, total, \"Running doctor...\", \"\\u2713 All checks passed\");\n } else {\n step(4, total, \"Running doctor...\", \"\\u26A0 Some checks failed \\u2014 run: gpc doctor\");\n allPassed = false;\n }\n } catch {\n step(4, total, \"Running doctor...\", \"\\u2014 run: gpc doctor\");\n }\n } else {\n step(4, total, \"Running doctor...\", \"\\u2014 skipped\");\n }\n\n console.log(\"\");\n\n if (allPassed) {\n console.log(\"Ready. Here's what you can do next:\");\n console.log(\"\");\n console.log(\" gpc status → app health snapshot\");\n console.log(\" gpc releases list → current tracks and versions\");\n console.log(\" gpc reviews list → recent user reviews\");\n console.log(\" gpc vitals overview → crash and ANR rates\");\n console.log(\" gpc publish app.aab → end-to-end upload and release\");\n console.log(\"\");\n console.log(\"Docs: https://yasserstudio.github.io/gpc/\");\n } else {\n console.log(\"Fix the issues above, then run 'gpc quickstart' again.\");\n console.log(\"Need help? Run 'gpc doctor' for detailed diagnostics.\");\n process.exitCode = 1;\n }\n });\n}\n"],"mappings":";;;AACA,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAE5B,SAAS,KAAK,GAAW,OAAe,OAAe,QAAsB;AAC3E,QAAM,SAAS,QAAQ,CAAC,IAAI,KAAK,KAAK,KAAK,GAAG,OAAO,EAAE;AACvD,UAAQ,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE;AAClC;AAEO,SAAS,0BAA0B,SAAwB;AAChE,UACG,QAAQ,YAAY,EACpB,YAAY,+DAA+D,EAC3E,OAAO,YAAY;AAClB,YAAQ,IAAI,gCAA2B;AACvC,YAAQ,IAAI,sUAAwD;AAEpE,UAAM,QAAQ;AACd,QAAI,YAAY;AAGhB,QAAI,SAAwD;AAC5D,QAAI;AACF,eAAS,MAAM,WAAW;AAC1B,YAAM,cAAc,OAAO,UAAU,YAAY,OAAO,OAAO,MAAM;AACrE,WAAK,GAAG,OAAO,mCAAmC,gBAAW,WAAW,EAAE;AAAA,IAC5E,QAAQ;AACN,WAAK,GAAG,OAAO,mCAAmC,wBAAmB;AACrE,cAAQ,IAAI,0BAA0B;AACtC,cAAQ,IAAI,iDAAiD;AAC7D,kBAAY;AAAA,IACd;AAGA,QAAI,QAAQ;AACV,UAAI;AACF,cAAM,OAAO,MAAM,YAAY,EAAE,oBAAoB,OAAO,MAAM,eAAe,CAAC;AAClF,cAAM,QAAQ,KAAK,eAAe;AAClC,aAAK,GAAG,OAAO,4BAA4B,UAAK,KAAK,EAAE;AAAA,MACzD,QAAQ;AACN,aAAK,GAAG,OAAO,4BAA4B,+CAAqC;AAChF,oBAAY;AAAA,MACd;AAAA,IACF,OAAO;AACL,WAAK,GAAG,OAAO,4BAA4B,4BAAuB;AAClE,kBAAY;AAAA,IACd;AAGA,UAAM,cAAc,QAAQ,OAAQ,QAAQ,KAAK,EAAE,KAAK;AACxD,QAAI,aAAa;AACf,WAAK,GAAG,OAAO,4BAA4B,UAAK,WAAW,EAAE;AAAA,IAC/D,OAAO;AACL,WAAK,GAAG,OAAO,4BAA4B,yDAA+C;AAC1F,kBAAY;AAAA,IACd;AAGA,QAAI,WAAW;AACb,UAAI;AACF,cAAM,EAAE,UAAU,IAAI,MAAM,OAAO,eAAoB;AAGvD,cAAM,SAAS,UAAU,OAAO,CAAC,QAAQ,GAAG;AAAA,UAC1C,OAAO;AAAA,UACP,UAAU;AAAA,QACZ,CAAC;AACD,YAAI,OAAO,OAAO;AAEhB,eAAK,GAAG,OAAO,qBAAqB,oDAAoD;AAAA,QAC1F,WAAW,OAAO,WAAW,GAAG;AAC9B,eAAK,GAAG,OAAO,qBAAqB,0BAA0B;AAAA,QAChE,OAAO;AACL,eAAK,GAAG,OAAO,qBAAqB,kDAAkD;AACtF,sBAAY;AAAA,QACd;AAAA,MACF,QAAQ;AACN,aAAK,GAAG,OAAO,qBAAqB,wBAAwB;AAAA,MAC9D;AAAA,IACF,OAAO;AACL,WAAK,GAAG,OAAO,qBAAqB,gBAAgB;AAAA,IACtD;AAEA,YAAQ,IAAI,EAAE;AAEd,QAAI,WAAW;AACb,cAAQ,IAAI,qCAAqC;AACjD,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,sDAAiD;AAC7D,cAAQ,IAAI,8DAAyD;AACrE,cAAQ,IAAI,sDAAiD;AAC7D,cAAQ,IAAI,sDAAiD;AAC7D,cAAQ,IAAI,gEAA2D;AACvE,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,2CAA2C;AAAA,IACzD,OAAO;AACL,cAAQ,IAAI,wDAAwD;AACpE,cAAQ,IAAI,uDAAuD;AACnE,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF,CAAC;AACL;","names":[]}
|
|
@@ -33,26 +33,16 @@ function registerQuotaCommand(program) {
|
|
|
33
33
|
const quota = program.command("quota").description("View Google Play API quota usage tracked from local audit log");
|
|
34
34
|
quota.command("status").description("Show daily and per-minute API call counts").action(async () => {
|
|
35
35
|
const format = getOutputFormat(program, {});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
printQuotaTable(usage, format);
|
|
39
|
-
} catch (error) {
|
|
40
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
41
|
-
process.exit(1);
|
|
42
|
-
}
|
|
36
|
+
const usage = await getQuotaUsage();
|
|
37
|
+
printQuotaTable(usage, format);
|
|
43
38
|
});
|
|
44
39
|
quota.command("usage").description("Show API quota usage breakdown (alias for quota status)").action(async () => {
|
|
45
40
|
const format = getOutputFormat(program, {});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
printQuotaTable(usage, format);
|
|
49
|
-
} catch (error) {
|
|
50
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
51
|
-
process.exit(1);
|
|
52
|
-
}
|
|
41
|
+
const usage = await getQuotaUsage();
|
|
42
|
+
printQuotaTable(usage, format);
|
|
53
43
|
});
|
|
54
44
|
}
|
|
55
45
|
export {
|
|
56
46
|
registerQuotaCommand
|
|
57
47
|
};
|
|
58
|
-
//# sourceMappingURL=quota-
|
|
48
|
+
//# sourceMappingURL=quota-MZRWYJGR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/quota.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { getQuotaUsage, formatOutput } from \"@gpc-cli/core\";\nimport type { QuotaUsage } from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\n\nfunction printQuotaTable(usage: QuotaUsage, format: string): void {\n if (format === \"json\") {\n console.log(formatOutput(usage, format));\n return;\n }\n\n const dailyPct = ((usage.dailyCallsUsed / usage.dailyCallsLimit) * 100).toFixed(1);\n const minPct = ((usage.minuteCallsUsed / usage.minuteCallsLimit) * 100).toFixed(1);\n\n console.log(`\\nAPI Quota Usage`);\n console.log(`${\"─\".repeat(45)}`);\n console.log(\n `Daily: ${usage.dailyCallsUsed.toLocaleString()} / ${usage.dailyCallsLimit.toLocaleString()} (${dailyPct}%)`,\n );\n console.log(` Remaining: ${usage.dailyCallsRemaining.toLocaleString()}`);\n console.log(`Minute: ${usage.minuteCallsUsed} / ${usage.minuteCallsLimit} (${minPct}%)`);\n console.log(` Remaining: ${usage.minuteCallsRemaining}`);\n\n if (usage.topCommands.length > 0) {\n console.log(`\\nTop commands today:`);\n for (const { command, count } of usage.topCommands) {\n console.log(` ${command.padEnd(30)} ${count}`);\n }\n }\n}\n\nexport function registerQuotaCommand(program: Command): void {\n const quota = program\n .command(\"quota\")\n .description(\"View Google Play API quota usage tracked from local audit log\");\n\n quota\n .command(\"status\")\n .description(\"Show daily and per-minute API call counts\")\n .action(async () => {\n const format = getOutputFormat(program, {});\n const usage = await getQuotaUsage();\n printQuotaTable(usage, format);\n });\n\n quota\n .command(\"usage\")\n .description(\"Show API quota usage breakdown (alias for quota status)\")\n .action(async () => {\n const format = getOutputFormat(program, {});\n const usage = await getQuotaUsage();\n printQuotaTable(usage, format);\n });\n}\n"],"mappings":";;;;;;AACA,SAAS,eAAe,oBAAoB;AAI5C,SAAS,gBAAgB,OAAmB,QAAsB;AAChE,MAAI,WAAW,QAAQ;AACrB,YAAQ,IAAI,aAAa,OAAO,MAAM,CAAC;AACvC;AAAA,EACF;AAEA,QAAM,YAAa,MAAM,iBAAiB,MAAM,kBAAmB,KAAK,QAAQ,CAAC;AACjF,QAAM,UAAW,MAAM,kBAAkB,MAAM,mBAAoB,KAAK,QAAQ,CAAC;AAEjF,UAAQ,IAAI;AAAA,gBAAmB;AAC/B,UAAQ,IAAI,GAAG,SAAI,OAAO,EAAE,CAAC,EAAE;AAC/B,UAAQ;AAAA,IACN,YAAY,MAAM,eAAe,eAAe,CAAC,MAAM,MAAM,gBAAgB,eAAe,CAAC,KAAK,QAAQ;AAAA,EAC5G;AACA,UAAQ,IAAI,uBAAuB,MAAM,oBAAoB,eAAe,CAAC,EAAE;AAC/E,UAAQ,IAAI,YAAY,MAAM,eAAe,MAAM,MAAM,gBAAgB,KAAK,MAAM,IAAI;AACxF,UAAQ,IAAI,uBAAuB,MAAM,oBAAoB,EAAE;AAE/D,MAAI,MAAM,YAAY,SAAS,GAAG;AAChC,YAAQ,IAAI;AAAA,oBAAuB;AACnC,eAAW,EAAE,SAAS,MAAM,KAAK,MAAM,aAAa;AAClD,cAAQ,IAAI,KAAK,QAAQ,OAAO,EAAE,CAAC,IAAI,KAAK,EAAE;AAAA,IAChD;AAAA,EACF;AACF;AAEO,SAAS,qBAAqB,SAAwB;AAC3D,QAAM,QAAQ,QACX,QAAQ,OAAO,EACf,YAAY,+DAA+D;AAE9E,QACG,QAAQ,QAAQ,EAChB,YAAY,2CAA2C,EACvD,OAAO,YAAY;AAClB,UAAM,SAAS,gBAAgB,SAAS,CAAC,CAAC;AAC1C,UAAM,QAAQ,MAAM,cAAc;AAClC,oBAAgB,OAAO,MAAM;AAAA,EAC/B,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,YAAY,yDAAyD,EACrE,OAAO,YAAY;AAClB,UAAM,SAAS,gBAAgB,SAAS,CAAC,CAAC;AAC1C,UAAM,QAAQ,MAAM,cAAc;AAClC,oBAAgB,OAAO,MAAM;AAAA,EAC/B,CAAC;AACL;","names":[]}
|