@gpc-cli/cli 0.1.1
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/LICENSE +21 -0
- package/dist/apps-BBYNHB2H.js +83 -0
- package/dist/apps-BBYNHB2H.js.map +1 -0
- package/dist/auth-T7IDSMVX.js +129 -0
- package/dist/auth-T7IDSMVX.js.map +1 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +36 -0
- package/dist/bin.js.map +1 -0
- package/dist/chunk-4QV4WD3F.js +103 -0
- package/dist/chunk-4QV4WD3F.js.map +1 -0
- package/dist/chunk-IVVT73IP.js +245 -0
- package/dist/chunk-IVVT73IP.js.map +1 -0
- package/dist/chunk-QMKZYXDJ.js +24 -0
- package/dist/chunk-QMKZYXDJ.js.map +1 -0
- package/dist/completion-U44CGHRH.js +145 -0
- package/dist/completion-U44CGHRH.js.map +1 -0
- package/dist/config-K7UJKIXT.js +44 -0
- package/dist/config-K7UJKIXT.js.map +1 -0
- package/dist/docs-CVTWIVMS.js +20 -0
- package/dist/docs-CVTWIVMS.js.map +1 -0
- package/dist/doctor-VDDUPTIM.js +59 -0
- package/dist/doctor-VDDUPTIM.js.map +1 -0
- package/dist/iap-QIV4CXKZ.js +158 -0
- package/dist/iap-QIV4CXKZ.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/listings-PF5FDXKQ.js +261 -0
- package/dist/listings-PF5FDXKQ.js.map +1 -0
- package/dist/pricing-S4SB5FXJ.js +52 -0
- package/dist/pricing-S4SB5FXJ.js.map +1 -0
- package/dist/prompt-VP5LURRP.js +20 -0
- package/dist/prompt-VP5LURRP.js.map +1 -0
- package/dist/publish-3BAIN4NQ.js +114 -0
- package/dist/publish-3BAIN4NQ.js.map +1 -0
- package/dist/purchases-E6A2T5WQ.js +231 -0
- package/dist/purchases-E6A2T5WQ.js.map +1 -0
- package/dist/releases-464IMEEF.js +231 -0
- package/dist/releases-464IMEEF.js.map +1 -0
- package/dist/reports-3YAD4U4F.js +129 -0
- package/dist/reports-3YAD4U4F.js.map +1 -0
- package/dist/reviews-2CLM53E3.js +125 -0
- package/dist/reviews-2CLM53E3.js.map +1 -0
- package/dist/status-M7U3YNMU.js +32 -0
- package/dist/status-M7U3YNMU.js.map +1 -0
- package/dist/subscriptions-PUHH4FBB.js +376 -0
- package/dist/subscriptions-PUHH4FBB.js.map +1 -0
- package/dist/testers-WWZMLB7J.js +145 -0
- package/dist/testers-WWZMLB7J.js.map +1 -0
- package/dist/tracks-427E34S3.js +39 -0
- package/dist/tracks-427E34S3.js.map +1 -0
- package/dist/users-E5Y5HI6K.js +145 -0
- package/dist/users-E5Y5HI6K.js.map +1 -0
- package/dist/validate-TPKVSIMR.js +37 -0
- package/dist/validate-TPKVSIMR.js.map +1 -0
- package/dist/vitals-YMZMUPNA.js +166 -0
- package/dist/vitals-YMZMUPNA.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
isDryRun,
|
|
4
|
+
printDryRun
|
|
5
|
+
} from "./chunk-QMKZYXDJ.js";
|
|
6
|
+
import {
|
|
7
|
+
requireConfirm
|
|
8
|
+
} from "./chunk-4QV4WD3F.js";
|
|
9
|
+
|
|
10
|
+
// src/commands/subscriptions.ts
|
|
11
|
+
import { readFile } from "fs/promises";
|
|
12
|
+
import { loadConfig } from "@gpc-cli/config";
|
|
13
|
+
import { resolveAuth } from "@gpc-cli/auth";
|
|
14
|
+
import { createApiClient } from "@gpc-cli/api";
|
|
15
|
+
import {
|
|
16
|
+
listSubscriptions,
|
|
17
|
+
getSubscription,
|
|
18
|
+
createSubscription,
|
|
19
|
+
updateSubscription,
|
|
20
|
+
deleteSubscription,
|
|
21
|
+
activateBasePlan,
|
|
22
|
+
deactivateBasePlan,
|
|
23
|
+
deleteBasePlan,
|
|
24
|
+
migratePrices,
|
|
25
|
+
listOffers,
|
|
26
|
+
getOffer,
|
|
27
|
+
createOffer,
|
|
28
|
+
updateOffer,
|
|
29
|
+
deleteOffer,
|
|
30
|
+
activateOffer,
|
|
31
|
+
deactivateOffer,
|
|
32
|
+
detectOutputFormat,
|
|
33
|
+
formatOutput
|
|
34
|
+
} from "@gpc-cli/core";
|
|
35
|
+
function resolvePackageName(packageArg, config) {
|
|
36
|
+
const name = packageArg || config.app;
|
|
37
|
+
if (!name) {
|
|
38
|
+
console.error("Error: No package name. Use --app <package> or gpc config set app <package>");
|
|
39
|
+
process.exit(2);
|
|
40
|
+
}
|
|
41
|
+
return name;
|
|
42
|
+
}
|
|
43
|
+
async function getClient(config) {
|
|
44
|
+
const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });
|
|
45
|
+
return createApiClient({ auth });
|
|
46
|
+
}
|
|
47
|
+
function registerSubscriptionsCommands(program) {
|
|
48
|
+
const subs = program.command("subscriptions").description("Manage subscriptions and base plans");
|
|
49
|
+
subs.command("list").description("List subscriptions").option("--page-size <n>", "Results per page", parseInt).option("--page-token <token>", "Page token").option("--limit <n>", "Maximum total results", parseInt).option("--next-page <token>", "Resume from page token").action(async (options) => {
|
|
50
|
+
const config = await loadConfig();
|
|
51
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
52
|
+
const client = await getClient(config);
|
|
53
|
+
const format = detectOutputFormat();
|
|
54
|
+
try {
|
|
55
|
+
const result = await listSubscriptions(client, packageName, {
|
|
56
|
+
pageSize: options.pageSize,
|
|
57
|
+
pageToken: options.pageToken,
|
|
58
|
+
limit: options.limit,
|
|
59
|
+
nextPage: options.nextPage
|
|
60
|
+
});
|
|
61
|
+
console.log(formatOutput(result, format));
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
64
|
+
process.exit(4);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
subs.command("get <product-id>").description("Get a subscription").action(async (productId) => {
|
|
68
|
+
const config = await loadConfig();
|
|
69
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
70
|
+
const client = await getClient(config);
|
|
71
|
+
const format = detectOutputFormat();
|
|
72
|
+
try {
|
|
73
|
+
const result = await getSubscription(client, packageName, productId);
|
|
74
|
+
console.log(formatOutput(result, format));
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
77
|
+
process.exit(4);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
subs.command("create").description("Create a subscription from JSON file").requiredOption("--file <path>", "JSON file with subscription data").action(async (options) => {
|
|
81
|
+
const config = await loadConfig();
|
|
82
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
83
|
+
const format = detectOutputFormat();
|
|
84
|
+
if (isDryRun(program)) {
|
|
85
|
+
printDryRun({
|
|
86
|
+
command: "subscriptions create",
|
|
87
|
+
action: "create",
|
|
88
|
+
target: `subscription from ${options.file}`
|
|
89
|
+
}, format, formatOutput);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const client = await getClient(config);
|
|
93
|
+
try {
|
|
94
|
+
const data = JSON.parse(await readFile(options.file, "utf-8"));
|
|
95
|
+
const result = await createSubscription(client, packageName, data);
|
|
96
|
+
console.log(formatOutput(result, format));
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
99
|
+
process.exit(4);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
subs.command("update <product-id>").description("Update a subscription from JSON file").requiredOption("--file <path>", "JSON file with subscription data").option("--update-mask <fields>", "Comma-separated field mask").action(async (productId, options) => {
|
|
103
|
+
const config = await loadConfig();
|
|
104
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
105
|
+
const format = detectOutputFormat();
|
|
106
|
+
if (isDryRun(program)) {
|
|
107
|
+
printDryRun({
|
|
108
|
+
command: "subscriptions update",
|
|
109
|
+
action: "update",
|
|
110
|
+
target: productId,
|
|
111
|
+
details: { file: options.file, updateMask: options.updateMask }
|
|
112
|
+
}, format, formatOutput);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const client = await getClient(config);
|
|
116
|
+
try {
|
|
117
|
+
const data = JSON.parse(await readFile(options.file, "utf-8"));
|
|
118
|
+
const result = await updateSubscription(client, packageName, productId, data, options.updateMask);
|
|
119
|
+
console.log(formatOutput(result, format));
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
122
|
+
process.exit(4);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
subs.command("delete <product-id>").description("Delete a subscription").action(async (productId) => {
|
|
126
|
+
const config = await loadConfig();
|
|
127
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
128
|
+
await requireConfirm(`Delete subscription "${productId}"?`, program);
|
|
129
|
+
if (isDryRun(program)) {
|
|
130
|
+
const format = detectOutputFormat();
|
|
131
|
+
printDryRun({
|
|
132
|
+
command: "subscriptions delete",
|
|
133
|
+
action: "delete",
|
|
134
|
+
target: productId
|
|
135
|
+
}, format, formatOutput);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const client = await getClient(config);
|
|
139
|
+
try {
|
|
140
|
+
await deleteSubscription(client, packageName, productId);
|
|
141
|
+
console.log(`Subscription ${productId} deleted.`);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
144
|
+
process.exit(4);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
const basePlans = subs.command("base-plans").description("Manage base plans");
|
|
148
|
+
basePlans.command("activate <product-id> <base-plan-id>").description("Activate a base plan").action(async (productId, basePlanId) => {
|
|
149
|
+
const config = await loadConfig();
|
|
150
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
151
|
+
const format = detectOutputFormat();
|
|
152
|
+
if (isDryRun(program)) {
|
|
153
|
+
printDryRun({
|
|
154
|
+
command: "subscriptions base-plans activate",
|
|
155
|
+
action: "activate",
|
|
156
|
+
target: `${productId}/${basePlanId}`
|
|
157
|
+
}, format, formatOutput);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const client = await getClient(config);
|
|
161
|
+
try {
|
|
162
|
+
const result = await activateBasePlan(client, packageName, productId, basePlanId);
|
|
163
|
+
console.log(formatOutput(result, format));
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
166
|
+
process.exit(4);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
basePlans.command("deactivate <product-id> <base-plan-id>").description("Deactivate a base plan").action(async (productId, basePlanId) => {
|
|
170
|
+
const config = await loadConfig();
|
|
171
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
172
|
+
const format = detectOutputFormat();
|
|
173
|
+
if (isDryRun(program)) {
|
|
174
|
+
printDryRun({
|
|
175
|
+
command: "subscriptions base-plans deactivate",
|
|
176
|
+
action: "deactivate",
|
|
177
|
+
target: `${productId}/${basePlanId}`
|
|
178
|
+
}, format, formatOutput);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const client = await getClient(config);
|
|
182
|
+
try {
|
|
183
|
+
const result = await deactivateBasePlan(client, packageName, productId, basePlanId);
|
|
184
|
+
console.log(formatOutput(result, format));
|
|
185
|
+
} catch (error) {
|
|
186
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
187
|
+
process.exit(4);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
basePlans.command("delete <product-id> <base-plan-id>").description("Delete a base plan").action(async (productId, basePlanId) => {
|
|
191
|
+
const config = await loadConfig();
|
|
192
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
193
|
+
await requireConfirm(`Delete base plan "${basePlanId}" from subscription "${productId}"?`, program);
|
|
194
|
+
if (isDryRun(program)) {
|
|
195
|
+
const format = detectOutputFormat();
|
|
196
|
+
printDryRun({
|
|
197
|
+
command: "subscriptions base-plans delete",
|
|
198
|
+
action: "delete",
|
|
199
|
+
target: `${productId}/${basePlanId}`
|
|
200
|
+
}, format, formatOutput);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const client = await getClient(config);
|
|
204
|
+
try {
|
|
205
|
+
await deleteBasePlan(client, packageName, productId, basePlanId);
|
|
206
|
+
console.log(`Base plan ${basePlanId} deleted.`);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
209
|
+
process.exit(4);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
basePlans.command("migrate-prices <product-id> <base-plan-id>").description("Migrate base plan prices").requiredOption("--file <path>", "JSON file with migration data").action(async (productId, basePlanId, options) => {
|
|
213
|
+
const config = await loadConfig();
|
|
214
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
215
|
+
const format = detectOutputFormat();
|
|
216
|
+
if (isDryRun(program)) {
|
|
217
|
+
printDryRun({
|
|
218
|
+
command: "subscriptions base-plans migrate-prices",
|
|
219
|
+
action: "migrate prices for",
|
|
220
|
+
target: `${productId}/${basePlanId}`,
|
|
221
|
+
details: { file: options.file }
|
|
222
|
+
}, format, formatOutput);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const client = await getClient(config);
|
|
226
|
+
try {
|
|
227
|
+
const data = JSON.parse(await readFile(options.file, "utf-8"));
|
|
228
|
+
const result = await migratePrices(client, packageName, productId, basePlanId, data);
|
|
229
|
+
console.log(formatOutput(result, format));
|
|
230
|
+
} catch (error) {
|
|
231
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
232
|
+
process.exit(4);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
const offers = subs.command("offers").description("Manage subscription offers");
|
|
236
|
+
offers.command("list <product-id> <base-plan-id>").description("List offers for a base plan").action(async (productId, basePlanId) => {
|
|
237
|
+
const config = await loadConfig();
|
|
238
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
239
|
+
const client = await getClient(config);
|
|
240
|
+
const format = detectOutputFormat();
|
|
241
|
+
try {
|
|
242
|
+
const result = await listOffers(client, packageName, productId, basePlanId);
|
|
243
|
+
console.log(formatOutput(result, format));
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
246
|
+
process.exit(4);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
offers.command("get <product-id> <base-plan-id> <offer-id>").description("Get an offer").action(async (productId, basePlanId, offerId) => {
|
|
250
|
+
const config = await loadConfig();
|
|
251
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
252
|
+
const client = await getClient(config);
|
|
253
|
+
const format = detectOutputFormat();
|
|
254
|
+
try {
|
|
255
|
+
const result = await getOffer(client, packageName, productId, basePlanId, offerId);
|
|
256
|
+
console.log(formatOutput(result, format));
|
|
257
|
+
} catch (error) {
|
|
258
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
259
|
+
process.exit(4);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
offers.command("create <product-id> <base-plan-id>").description("Create an offer from JSON file").requiredOption("--file <path>", "JSON file with offer data").action(async (productId, basePlanId, options) => {
|
|
263
|
+
const config = await loadConfig();
|
|
264
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
265
|
+
const format = detectOutputFormat();
|
|
266
|
+
if (isDryRun(program)) {
|
|
267
|
+
printDryRun({
|
|
268
|
+
command: "subscriptions offers create",
|
|
269
|
+
action: "create offer for",
|
|
270
|
+
target: `${productId}/${basePlanId}`,
|
|
271
|
+
details: { file: options.file }
|
|
272
|
+
}, format, formatOutput);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const client = await getClient(config);
|
|
276
|
+
try {
|
|
277
|
+
const data = JSON.parse(await readFile(options.file, "utf-8"));
|
|
278
|
+
const result = await createOffer(client, packageName, productId, basePlanId, data);
|
|
279
|
+
console.log(formatOutput(result, format));
|
|
280
|
+
} catch (error) {
|
|
281
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
282
|
+
process.exit(4);
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
offers.command("update <product-id> <base-plan-id> <offer-id>").description("Update an offer from JSON file").requiredOption("--file <path>", "JSON file with offer data").option("--update-mask <fields>", "Comma-separated field mask").action(async (productId, basePlanId, offerId, options) => {
|
|
286
|
+
const config = await loadConfig();
|
|
287
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
288
|
+
const format = detectOutputFormat();
|
|
289
|
+
if (isDryRun(program)) {
|
|
290
|
+
printDryRun({
|
|
291
|
+
command: "subscriptions offers update",
|
|
292
|
+
action: "update offer",
|
|
293
|
+
target: `${productId}/${basePlanId}/${offerId}`,
|
|
294
|
+
details: { file: options.file, updateMask: options.updateMask }
|
|
295
|
+
}, format, formatOutput);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
const client = await getClient(config);
|
|
299
|
+
try {
|
|
300
|
+
const data = JSON.parse(await readFile(options.file, "utf-8"));
|
|
301
|
+
const result = await updateOffer(client, packageName, productId, basePlanId, offerId, data, options.updateMask);
|
|
302
|
+
console.log(formatOutput(result, format));
|
|
303
|
+
} catch (error) {
|
|
304
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
305
|
+
process.exit(4);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
offers.command("delete <product-id> <base-plan-id> <offer-id>").description("Delete an offer").action(async (productId, basePlanId, offerId) => {
|
|
309
|
+
const config = await loadConfig();
|
|
310
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
311
|
+
await requireConfirm(`Delete offer "${offerId}"?`, program);
|
|
312
|
+
if (isDryRun(program)) {
|
|
313
|
+
const format = detectOutputFormat();
|
|
314
|
+
printDryRun({
|
|
315
|
+
command: "subscriptions offers delete",
|
|
316
|
+
action: "delete offer",
|
|
317
|
+
target: `${productId}/${basePlanId}/${offerId}`
|
|
318
|
+
}, format, formatOutput);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const client = await getClient(config);
|
|
322
|
+
try {
|
|
323
|
+
await deleteOffer(client, packageName, productId, basePlanId, offerId);
|
|
324
|
+
console.log(`Offer ${offerId} deleted.`);
|
|
325
|
+
} catch (error) {
|
|
326
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
327
|
+
process.exit(4);
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
offers.command("activate <product-id> <base-plan-id> <offer-id>").description("Activate an offer").action(async (productId, basePlanId, offerId) => {
|
|
331
|
+
const config = await loadConfig();
|
|
332
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
333
|
+
const format = detectOutputFormat();
|
|
334
|
+
if (isDryRun(program)) {
|
|
335
|
+
printDryRun({
|
|
336
|
+
command: "subscriptions offers activate",
|
|
337
|
+
action: "activate offer",
|
|
338
|
+
target: `${productId}/${basePlanId}/${offerId}`
|
|
339
|
+
}, format, formatOutput);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
const client = await getClient(config);
|
|
343
|
+
try {
|
|
344
|
+
const result = await activateOffer(client, packageName, productId, basePlanId, offerId);
|
|
345
|
+
console.log(formatOutput(result, format));
|
|
346
|
+
} catch (error) {
|
|
347
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
348
|
+
process.exit(4);
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
offers.command("deactivate <product-id> <base-plan-id> <offer-id>").description("Deactivate an offer").action(async (productId, basePlanId, offerId) => {
|
|
352
|
+
const config = await loadConfig();
|
|
353
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
354
|
+
const format = detectOutputFormat();
|
|
355
|
+
if (isDryRun(program)) {
|
|
356
|
+
printDryRun({
|
|
357
|
+
command: "subscriptions offers deactivate",
|
|
358
|
+
action: "deactivate offer",
|
|
359
|
+
target: `${productId}/${basePlanId}/${offerId}`
|
|
360
|
+
}, format, formatOutput);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
const client = await getClient(config);
|
|
364
|
+
try {
|
|
365
|
+
const result = await deactivateOffer(client, packageName, productId, basePlanId, offerId);
|
|
366
|
+
console.log(formatOutput(result, format));
|
|
367
|
+
} catch (error) {
|
|
368
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
369
|
+
process.exit(4);
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
export {
|
|
374
|
+
registerSubscriptionsCommands
|
|
375
|
+
};
|
|
376
|
+
//# sourceMappingURL=subscriptions-PUHH4FBB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/subscriptions.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createApiClient } from \"@gpc-cli/api\";\nimport {\n listSubscriptions,\n getSubscription,\n createSubscription,\n updateSubscription,\n deleteSubscription,\n activateBasePlan,\n deactivateBasePlan,\n deleteBasePlan,\n migratePrices,\n listOffers,\n getOffer,\n createOffer,\n updateOffer,\n deleteOffer,\n activateOffer,\n deactivateOffer,\n detectOutputFormat,\n formatOutput,\n} from \"@gpc-cli/core\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { requireConfirm } from \"../prompt.js\";\n\nfunction resolvePackageName(packageArg: string | undefined, config: any): string {\n const name = packageArg || config.app;\n if (!name) {\n console.error(\"Error: No package name. Use --app <package> or gpc config set app <package>\");\n process.exit(2);\n }\n return name;\n}\n\nasync function getClient(config: any) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createApiClient({ auth });\n}\n\nexport function registerSubscriptionsCommands(program: Command): void {\n const subs = program\n .command(\"subscriptions\")\n .description(\"Manage subscriptions and base plans\");\n\n subs\n .command(\"list\")\n .description(\"List subscriptions\")\n .option(\"--page-size <n>\", \"Results per page\", parseInt)\n .option(\"--page-token <token>\", \"Page token\")\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 = detectOutputFormat();\n\n try {\n const result = await listSubscriptions(client, packageName, {\n pageSize: options.pageSize,\n pageToken: options.pageToken,\n limit: options.limit,\n nextPage: options.nextPage,\n });\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n subs\n .command(\"get <product-id>\")\n .description(\"Get a subscription\")\n .action(async (productId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const client = await getClient(config);\n const format = detectOutputFormat();\n\n try {\n const result = await getSubscription(client, packageName, productId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n subs\n .command(\"create\")\n .description(\"Create a subscription from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with subscription data\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const format = detectOutputFormat();\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"subscriptions create\",\n action: \"create\",\n target: `subscription from ${options.file}`,\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await createSubscription(client, packageName, data);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n subs\n .command(\"update <product-id>\")\n .description(\"Update a subscription from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with subscription data\")\n .option(\"--update-mask <fields>\", \"Comma-separated field mask\")\n .action(async (productId: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const format = detectOutputFormat();\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"subscriptions update\",\n action: \"update\",\n target: productId,\n details: { file: options.file, updateMask: options.updateMask },\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await updateSubscription(client, packageName, productId, data, options.updateMask);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n subs\n .command(\"delete <product-id>\")\n .description(\"Delete a subscription\")\n .action(async (productId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n\n await requireConfirm(`Delete subscription \"${productId}\"?`, program);\n\n if (isDryRun(program)) {\n const format = detectOutputFormat();\n printDryRun({\n command: \"subscriptions delete\",\n action: \"delete\",\n target: productId,\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await deleteSubscription(client, packageName, productId);\n console.log(`Subscription ${productId} deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // --- Base Plans ---\n const basePlans = subs\n .command(\"base-plans\")\n .description(\"Manage base plans\");\n\n basePlans\n .command(\"activate <product-id> <base-plan-id>\")\n .description(\"Activate a base plan\")\n .action(async (productId: string, basePlanId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const format = detectOutputFormat();\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"subscriptions base-plans activate\",\n action: \"activate\",\n target: `${productId}/${basePlanId}`,\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await activateBasePlan(client, packageName, productId, basePlanId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n basePlans\n .command(\"deactivate <product-id> <base-plan-id>\")\n .description(\"Deactivate a base plan\")\n .action(async (productId: string, basePlanId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const format = detectOutputFormat();\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"subscriptions base-plans deactivate\",\n action: \"deactivate\",\n target: `${productId}/${basePlanId}`,\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await deactivateBasePlan(client, packageName, productId, basePlanId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n basePlans\n .command(\"delete <product-id> <base-plan-id>\")\n .description(\"Delete a base plan\")\n .action(async (productId: string, basePlanId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n\n await requireConfirm(`Delete base plan \"${basePlanId}\" from subscription \"${productId}\"?`, program);\n\n if (isDryRun(program)) {\n const format = detectOutputFormat();\n printDryRun({\n command: \"subscriptions base-plans delete\",\n action: \"delete\",\n target: `${productId}/${basePlanId}`,\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await deleteBasePlan(client, packageName, productId, basePlanId);\n console.log(`Base plan ${basePlanId} deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n basePlans\n .command(\"migrate-prices <product-id> <base-plan-id>\")\n .description(\"Migrate base plan prices\")\n .requiredOption(\"--file <path>\", \"JSON file with migration data\")\n .action(async (productId: string, basePlanId: string, options: any) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const format = detectOutputFormat();\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"subscriptions base-plans migrate-prices\",\n action: \"migrate prices for\",\n target: `${productId}/${basePlanId}`,\n details: { file: options.file },\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await migratePrices(client, packageName, productId, basePlanId, data);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // --- Offers ---\n const offers = subs\n .command(\"offers\")\n .description(\"Manage subscription offers\");\n\n offers\n .command(\"list <product-id> <base-plan-id>\")\n .description(\"List offers for a base plan\")\n .action(async (productId: string, basePlanId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const client = await getClient(config);\n const format = detectOutputFormat();\n\n try {\n const result = await listOffers(client, packageName, productId, basePlanId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"get <product-id> <base-plan-id> <offer-id>\")\n .description(\"Get an offer\")\n .action(async (productId: string, basePlanId: string, offerId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const client = await getClient(config);\n const format = detectOutputFormat();\n\n try {\n const result = await getOffer(client, packageName, productId, basePlanId, offerId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"create <product-id> <base-plan-id>\")\n .description(\"Create an offer from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with offer data\")\n .action(async (productId: string, basePlanId: string, options: any) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const format = detectOutputFormat();\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"subscriptions offers create\",\n action: \"create offer for\",\n target: `${productId}/${basePlanId}`,\n details: { file: options.file },\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await createOffer(client, packageName, productId, basePlanId, data);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"update <product-id> <base-plan-id> <offer-id>\")\n .description(\"Update an offer from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with offer data\")\n .option(\"--update-mask <fields>\", \"Comma-separated field mask\")\n .action(async (productId: string, basePlanId: string, offerId: string, options: any) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const format = detectOutputFormat();\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"subscriptions offers update\",\n action: \"update offer\",\n target: `${productId}/${basePlanId}/${offerId}`,\n details: { file: options.file, updateMask: options.updateMask },\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await updateOffer(client, packageName, productId, basePlanId, offerId, data, options.updateMask);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"delete <product-id> <base-plan-id> <offer-id>\")\n .description(\"Delete an offer\")\n .action(async (productId: string, basePlanId: string, offerId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n\n await requireConfirm(`Delete offer \"${offerId}\"?`, program);\n\n if (isDryRun(program)) {\n const format = detectOutputFormat();\n printDryRun({\n command: \"subscriptions offers delete\",\n action: \"delete offer\",\n target: `${productId}/${basePlanId}/${offerId}`,\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await deleteOffer(client, packageName, productId, basePlanId, offerId);\n console.log(`Offer ${offerId} deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"activate <product-id> <base-plan-id> <offer-id>\")\n .description(\"Activate an offer\")\n .action(async (productId: string, basePlanId: string, offerId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const format = detectOutputFormat();\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"subscriptions offers activate\",\n action: \"activate offer\",\n target: `${productId}/${basePlanId}/${offerId}`,\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await activateOffer(client, packageName, productId, basePlanId, offerId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"deactivate <product-id> <base-plan-id> <offer-id>\")\n .description(\"Deactivate an offer\")\n .action(async (productId: string, basePlanId: string, offerId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const format = detectOutputFormat();\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"subscriptions offers deactivate\",\n action: \"deactivate offer\",\n target: `${productId}/${basePlanId}/${offerId}`,\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await deactivateOffer(client, packageName, productId, basePlanId, offerId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
isDryRun,
|
|
4
|
+
printDryRun
|
|
5
|
+
} from "./chunk-QMKZYXDJ.js";
|
|
6
|
+
import {
|
|
7
|
+
isInteractive,
|
|
8
|
+
requireConfirm,
|
|
9
|
+
requireOption
|
|
10
|
+
} from "./chunk-4QV4WD3F.js";
|
|
11
|
+
|
|
12
|
+
// src/commands/testers.ts
|
|
13
|
+
import { loadConfig } from "@gpc-cli/config";
|
|
14
|
+
import { resolveAuth } from "@gpc-cli/auth";
|
|
15
|
+
import { createApiClient } from "@gpc-cli/api";
|
|
16
|
+
import {
|
|
17
|
+
listTesters,
|
|
18
|
+
addTesters,
|
|
19
|
+
removeTesters,
|
|
20
|
+
importTestersFromCsv,
|
|
21
|
+
detectOutputFormat,
|
|
22
|
+
formatOutput
|
|
23
|
+
} from "@gpc-cli/core";
|
|
24
|
+
function resolvePackageName(packageArg, config) {
|
|
25
|
+
const name = packageArg || config.app;
|
|
26
|
+
if (!name) {
|
|
27
|
+
console.error("Error: No package name. Use --app <package> or gpc config set app <package>");
|
|
28
|
+
process.exit(2);
|
|
29
|
+
}
|
|
30
|
+
return name;
|
|
31
|
+
}
|
|
32
|
+
async function getClient(config) {
|
|
33
|
+
const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });
|
|
34
|
+
return createApiClient({ auth });
|
|
35
|
+
}
|
|
36
|
+
function registerTestersCommands(program) {
|
|
37
|
+
const testers = program.command("testers").description("Manage testers and tester groups");
|
|
38
|
+
testers.command("list").description("List testers for a track").option("--track <track>", "Track name (e.g., internal, alpha, beta)").action(async (options) => {
|
|
39
|
+
const config = await loadConfig();
|
|
40
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
41
|
+
const interactive = isInteractive(program);
|
|
42
|
+
options.track = await requireOption("track", options.track, {
|
|
43
|
+
message: "Track:",
|
|
44
|
+
choices: ["internal", "alpha", "beta"]
|
|
45
|
+
}, interactive);
|
|
46
|
+
const client = await getClient(config);
|
|
47
|
+
const format = detectOutputFormat();
|
|
48
|
+
try {
|
|
49
|
+
const result = await listTesters(client, packageName, options.track);
|
|
50
|
+
console.log(formatOutput(result, format));
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
53
|
+
process.exit(4);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
testers.command("add <emails...>").description("Add testers (Google Group emails) to a track").option("--track <track>", "Track name (e.g., internal, alpha, beta)").action(async (emails, options) => {
|
|
57
|
+
const config = await loadConfig();
|
|
58
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
59
|
+
const format = detectOutputFormat();
|
|
60
|
+
const interactive = isInteractive(program);
|
|
61
|
+
options.track = await requireOption("track", options.track, {
|
|
62
|
+
message: "Track:",
|
|
63
|
+
choices: ["internal", "alpha", "beta"]
|
|
64
|
+
}, interactive);
|
|
65
|
+
if (isDryRun(program)) {
|
|
66
|
+
printDryRun({
|
|
67
|
+
command: "testers add",
|
|
68
|
+
action: "add testers to",
|
|
69
|
+
target: options.track,
|
|
70
|
+
details: { emails }
|
|
71
|
+
}, format, formatOutput);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const client = await getClient(config);
|
|
75
|
+
try {
|
|
76
|
+
const result = await addTesters(client, packageName, options.track, emails);
|
|
77
|
+
console.log(formatOutput(result, format));
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
80
|
+
process.exit(4);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
testers.command("remove <emails...>").description("Remove testers (Google Group emails) from a track").option("--track <track>", "Track name (e.g., internal, alpha, beta)").action(async (emails, options) => {
|
|
84
|
+
const config = await loadConfig();
|
|
85
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
86
|
+
const format = detectOutputFormat();
|
|
87
|
+
const interactive = isInteractive(program);
|
|
88
|
+
options.track = await requireOption("track", options.track, {
|
|
89
|
+
message: "Track:",
|
|
90
|
+
choices: ["internal", "alpha", "beta"]
|
|
91
|
+
}, interactive);
|
|
92
|
+
await requireConfirm(`Remove ${emails.length} tester(s) from ${options.track}?`, program);
|
|
93
|
+
if (isDryRun(program)) {
|
|
94
|
+
printDryRun({
|
|
95
|
+
command: "testers remove",
|
|
96
|
+
action: "remove testers from",
|
|
97
|
+
target: options.track,
|
|
98
|
+
details: { emails }
|
|
99
|
+
}, format, formatOutput);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const client = await getClient(config);
|
|
103
|
+
try {
|
|
104
|
+
const result = await removeTesters(client, packageName, options.track, emails);
|
|
105
|
+
console.log(formatOutput(result, format));
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
108
|
+
process.exit(4);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
testers.command("import").description("Import testers from a CSV file").option("--track <track>", "Track name (e.g., internal, alpha, beta)").option("--file <path>", "CSV file with email addresses").action(async (options) => {
|
|
112
|
+
const config = await loadConfig();
|
|
113
|
+
const packageName = resolvePackageName(program.opts().app, config);
|
|
114
|
+
const format = detectOutputFormat();
|
|
115
|
+
const interactive = isInteractive(program);
|
|
116
|
+
options.track = await requireOption("track", options.track, {
|
|
117
|
+
message: "Track:",
|
|
118
|
+
choices: ["internal", "alpha", "beta"]
|
|
119
|
+
}, interactive);
|
|
120
|
+
options.file = await requireOption("file", options.file, {
|
|
121
|
+
message: "CSV file path:"
|
|
122
|
+
}, interactive);
|
|
123
|
+
if (isDryRun(program)) {
|
|
124
|
+
printDryRun({
|
|
125
|
+
command: "testers import",
|
|
126
|
+
action: "import testers to",
|
|
127
|
+
target: options.track,
|
|
128
|
+
details: { file: options.file }
|
|
129
|
+
}, format, formatOutput);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const client = await getClient(config);
|
|
133
|
+
try {
|
|
134
|
+
const result = await importTestersFromCsv(client, packageName, options.track, options.file);
|
|
135
|
+
console.log(formatOutput({ added: result.added, testers: result.testers }, format));
|
|
136
|
+
} catch (error) {
|
|
137
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
138
|
+
process.exit(4);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
export {
|
|
143
|
+
registerTestersCommands
|
|
144
|
+
};
|
|
145
|
+
//# sourceMappingURL=testers-WWZMLB7J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/testers.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createApiClient } from \"@gpc-cli/api\";\nimport {\n listTesters,\n addTesters,\n removeTesters,\n importTestersFromCsv,\n detectOutputFormat,\n formatOutput,\n} from \"@gpc-cli/core\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { isInteractive, requireOption, requireConfirm } from \"../prompt.js\";\n\nfunction resolvePackageName(packageArg: string | undefined, config: any): string {\n const name = packageArg || config.app;\n if (!name) {\n console.error(\"Error: No package name. Use --app <package> or gpc config set app <package>\");\n process.exit(2);\n }\n return name;\n}\n\nasync function getClient(config: any) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createApiClient({ auth });\n}\n\nexport function registerTestersCommands(program: Command): void {\n const testers = program\n .command(\"testers\")\n .description(\"Manage testers and tester groups\");\n\n testers\n .command(\"list\")\n .description(\"List testers for a track\")\n .option(\"--track <track>\", \"Track name (e.g., internal, alpha, beta)\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const interactive = isInteractive(program);\n\n options.track = await requireOption(\"track\", options.track, {\n message: \"Track:\",\n choices: [\"internal\", \"alpha\", \"beta\"],\n }, interactive);\n\n const client = await getClient(config);\n const format = detectOutputFormat();\n\n try {\n const result = await listTesters(client, packageName, options.track);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n testers\n .command(\"add <emails...>\")\n .description(\"Add testers (Google Group emails) to a track\")\n .option(\"--track <track>\", \"Track name (e.g., internal, alpha, beta)\")\n .action(async (emails: string[], options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const format = detectOutputFormat();\n const interactive = isInteractive(program);\n\n options.track = await requireOption(\"track\", options.track, {\n message: \"Track:\",\n choices: [\"internal\", \"alpha\", \"beta\"],\n }, interactive);\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"testers add\",\n action: \"add testers to\",\n target: options.track,\n details: { emails },\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await addTesters(client, packageName, options.track, emails);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n testers\n .command(\"remove <emails...>\")\n .description(\"Remove testers (Google Group emails) from a track\")\n .option(\"--track <track>\", \"Track name (e.g., internal, alpha, beta)\")\n .action(async (emails: string[], options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const format = detectOutputFormat();\n const interactive = isInteractive(program);\n\n options.track = await requireOption(\"track\", options.track, {\n message: \"Track:\",\n choices: [\"internal\", \"alpha\", \"beta\"],\n }, interactive);\n\n await requireConfirm(`Remove ${emails.length} tester(s) from ${options.track}?`, program);\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"testers remove\",\n action: \"remove testers from\",\n target: options.track,\n details: { emails },\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await removeTesters(client, packageName, options.track, emails);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n testers\n .command(\"import\")\n .description(\"Import testers from a CSV file\")\n .option(\"--track <track>\", \"Track name (e.g., internal, alpha, beta)\")\n .option(\"--file <path>\", \"CSV file with email addresses\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const format = detectOutputFormat();\n const interactive = isInteractive(program);\n\n options.track = await requireOption(\"track\", options.track, {\n message: \"Track:\",\n choices: [\"internal\", \"alpha\", \"beta\"],\n }, interactive);\n\n options.file = await requireOption(\"file\", options.file, {\n message: \"CSV file path:\",\n }, interactive);\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"testers import\",\n action: \"import testers to\",\n target: options.track,\n details: { file: options.file },\n }, format, formatOutput);\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await importTestersFromCsv(client, packageName, options.track, options.file);\n console.log(formatOutput({ added: result.added, testers: result.testers }, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/commands/tracks.ts
|
|
4
|
+
import { loadConfig } from "@gpc-cli/config";
|
|
5
|
+
import { resolveAuth } from "@gpc-cli/auth";
|
|
6
|
+
import { createApiClient } from "@gpc-cli/api";
|
|
7
|
+
import { listTracks } from "@gpc-cli/core";
|
|
8
|
+
import { detectOutputFormat, formatOutput } from "@gpc-cli/core";
|
|
9
|
+
function registerTracksCommands(program) {
|
|
10
|
+
const tracks = program.command("tracks").description("Manage tracks");
|
|
11
|
+
tracks.command("list").description("List all tracks").action(async () => {
|
|
12
|
+
const config = await loadConfig();
|
|
13
|
+
const packageName = program.opts().app || config.app;
|
|
14
|
+
if (!packageName) {
|
|
15
|
+
console.error("Error: No package name. Use --app <package> or gpc config set app <package>");
|
|
16
|
+
process.exit(2);
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });
|
|
20
|
+
const client = createApiClient({ auth });
|
|
21
|
+
const trackList = await listTracks(client, packageName);
|
|
22
|
+
const format = detectOutputFormat();
|
|
23
|
+
const summary = trackList.map((t) => ({
|
|
24
|
+
track: t.track,
|
|
25
|
+
releases: t.releases?.length || 0,
|
|
26
|
+
latestStatus: t.releases?.[0]?.status || "none",
|
|
27
|
+
latestVersion: t.releases?.[0]?.versionCodes?.[0] || "-"
|
|
28
|
+
}));
|
|
29
|
+
console.log(formatOutput(summary, format));
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
32
|
+
process.exit(4);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
registerTracksCommands
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=tracks-427E34S3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/tracks.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createApiClient } from \"@gpc-cli/api\";\nimport { listTracks } from \"@gpc-cli/core\";\nimport { detectOutputFormat, formatOutput } from \"@gpc-cli/core\";\n\nexport function registerTracksCommands(program: Command): void {\n const tracks = program\n .command(\"tracks\")\n .description(\"Manage tracks\");\n\n tracks\n .command(\"list\")\n .description(\"List all tracks\")\n .action(async () => {\n const config = await loadConfig();\n const packageName = program.opts().app || config.app;\n if (!packageName) {\n console.error(\"Error: No package name. Use --app <package> or gpc config set app <package>\");\n process.exit(2);\n }\n\n try {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n const client = createApiClient({ auth });\n const trackList = await listTracks(client, packageName);\n const format = detectOutputFormat();\n\n const summary = trackList.map((t) => ({\n track: t.track,\n releases: t.releases?.length || 0,\n latestStatus: t.releases?.[0]?.status || \"none\",\n latestVersion: t.releases?.[0]?.versionCodes?.[0] || \"-\",\n }));\n\n console.log(formatOutput(summary, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n}\n"],"mappings":";;;AACA,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAChC,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB,oBAAoB;AAE1C,SAAS,uBAAuB,SAAwB;AAC7D,QAAM,SAAS,QACZ,QAAQ,QAAQ,EAChB,YAAY,eAAe;AAE9B,SACG,QAAQ,MAAM,EACd,YAAY,iBAAiB,EAC7B,OAAO,YAAY;AAClB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,QAAQ,KAAK,EAAE,OAAO,OAAO;AACjD,QAAI,CAAC,aAAa;AAChB,cAAQ,MAAM,6EAA6E;AAC3F,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI;AACF,YAAM,OAAO,MAAM,YAAY,EAAE,oBAAoB,OAAO,MAAM,eAAe,CAAC;AAClF,YAAM,SAAS,gBAAgB,EAAE,KAAK,CAAC;AACvC,YAAM,YAAY,MAAM,WAAW,QAAQ,WAAW;AACtD,YAAM,SAAS,mBAAmB;AAElC,YAAM,UAAU,UAAU,IAAI,CAAC,OAAO;AAAA,QACpC,OAAO,EAAE;AAAA,QACT,UAAU,EAAE,UAAU,UAAU;AAAA,QAChC,cAAc,EAAE,WAAW,CAAC,GAAG,UAAU;AAAA,QACzC,eAAe,EAAE,WAAW,CAAC,GAAG,eAAe,CAAC,KAAK;AAAA,MACvD,EAAE;AAEF,cAAQ,IAAI,aAAa,SAAS,MAAM,CAAC;AAAA,IAC3C,SAAS,OAAO;AACd,cAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAChF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;","names":[]}
|