@gpc-cli/cli 0.9.45 → 0.9.46

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.
Files changed (167) hide show
  1. package/dist/{anomalies-NU2IN2GJ.js → anomalies-UDE4NGHJ.js} +19 -24
  2. package/dist/anomalies-UDE4NGHJ.js.map +1 -0
  3. package/dist/{apps-J2446UDA.js → apps-FKD3ZG5X.js} +31 -35
  4. package/dist/apps-FKD3ZG5X.js.map +1 -0
  5. package/dist/{audit-N2CRHWUN.js → audit-JASSHRWN.js} +47 -62
  6. package/dist/audit-JASSHRWN.js.map +1 -0
  7. package/dist/{auth-XGSTT5G5.js → auth-OTA3SV3J.js} +145 -103
  8. package/dist/auth-OTA3SV3J.js.map +1 -0
  9. package/dist/bin.js +5 -3
  10. package/dist/bin.js.map +1 -1
  11. package/dist/bundle-F7MUVC5J.js +204 -0
  12. package/dist/bundle-F7MUVC5J.js.map +1 -0
  13. package/dist/{cache-SLNFRTI2.js → cache-XKPLZYEB.js} +4 -5
  14. package/dist/cache-XKPLZYEB.js.map +1 -0
  15. package/dist/changelog-7COFZO7Q.js +48 -0
  16. package/dist/changelog-7COFZO7Q.js.map +1 -0
  17. package/dist/{chunk-4O4D5SGL.js → chunk-3SJ6OXCZ.js} +4 -5
  18. package/dist/chunk-3SJ6OXCZ.js.map +1 -0
  19. package/dist/{chunk-SEVX56VN.js → chunk-6OWN6S6X.js} +52 -48
  20. package/dist/{chunk-SEVX56VN.js.map → chunk-6OWN6S6X.js.map} +1 -1
  21. package/dist/{chunk-U6ZTQ34I.js → chunk-BCBXQC7J.js} +45 -11
  22. package/dist/chunk-BCBXQC7J.js.map +1 -0
  23. package/dist/{chunk-AA577WVQ.js → chunk-NQH4G7BI.js} +9 -3
  24. package/dist/chunk-NQH4G7BI.js.map +1 -0
  25. package/dist/chunk-SLNJEAMK.js +23 -0
  26. package/dist/chunk-SLNJEAMK.js.map +1 -0
  27. package/dist/{chunk-NV75I5VP.js → chunk-YFUBD2XB.js} +10 -8
  28. package/dist/chunk-YFUBD2XB.js.map +1 -0
  29. package/dist/{config-BUXPDN7N.js → config-2FTCYEGD.js} +8 -5
  30. package/dist/config-2FTCYEGD.js.map +1 -0
  31. package/dist/{data-safety-Q7FTCEWU.js → data-safety-AFMD6MYI.js} +12 -27
  32. package/dist/data-safety-AFMD6MYI.js.map +1 -0
  33. package/dist/{device-tiers-MIOQEXYY.js → device-tiers-AQAMUQXI.js} +23 -38
  34. package/dist/device-tiers-AQAMUQXI.js.map +1 -0
  35. package/dist/diff-6EO4ID6W.js +91 -0
  36. package/dist/diff-6EO4ID6W.js.map +1 -0
  37. package/dist/{docs-7DUXIKA3.js → docs-4D2SJ4LY.js} +4 -3
  38. package/dist/docs-4D2SJ4LY.js.map +1 -0
  39. package/dist/doctor-H4X7Q57B.js +691 -0
  40. package/dist/doctor-H4X7Q57B.js.map +1 -0
  41. package/dist/{enterprise-7THXNBTC.js → enterprise-7PWXMSUN.js} +11 -21
  42. package/dist/enterprise-7PWXMSUN.js.map +1 -0
  43. package/dist/{external-transactions-2GWIMUVM.js → external-transactions-LCZALS3V.js} +12 -28
  44. package/dist/external-transactions-LCZALS3V.js.map +1 -0
  45. package/dist/{feedback-DPTO6DUT.js → feedback-XP765TOO.js} +3 -3
  46. package/dist/{games-BT777WUO.js → games-ZSNGEI7A.js} +17 -32
  47. package/dist/games-ZSNGEI7A.js.map +1 -0
  48. package/dist/{generated-apks-RJWTIX7L.js → generated-apks-RX2IUWSF.js} +30 -38
  49. package/dist/generated-apks-RX2IUWSF.js.map +1 -0
  50. package/dist/{grants-TKQJ3IER.js → grants-EBPECI26.js} +22 -40
  51. package/dist/grants-EBPECI26.js.map +1 -0
  52. package/dist/{iap-ICAEQLK5.js → iap-OUI5YYN4.js} +30 -51
  53. package/dist/iap-OUI5YYN4.js.map +1 -0
  54. package/dist/index.js +1 -1
  55. package/dist/{init-JZ2THPMS.js → init-WSTQTJOD.js} +5 -4
  56. package/dist/init-WSTQTJOD.js.map +1 -0
  57. package/dist/{install-skills-OV4HVANW.js → install-skills-6QDUXI5F.js} +5 -6
  58. package/dist/{install-skills-OV4HVANW.js.map → install-skills-6QDUXI5F.js.map} +1 -1
  59. package/dist/{internal-sharing-3U2XFHA4.js → internal-sharing-ONNIWIAT.js} +3 -4
  60. package/dist/{internal-sharing-3U2XFHA4.js.map → internal-sharing-ONNIWIAT.js.map} +1 -1
  61. package/dist/{listings-77HZW4S5.js → listings-7SGQ4SRX.js} +118 -157
  62. package/dist/listings-7SGQ4SRX.js.map +1 -0
  63. package/dist/migrate-ZQCJGQQS.js +138 -0
  64. package/dist/migrate-ZQCJGQQS.js.map +1 -0
  65. package/dist/{one-time-products-LHZAXQES.js → one-time-products-MGZTU7OM.js} +65 -120
  66. package/dist/one-time-products-MGZTU7OM.js.map +1 -0
  67. package/dist/{preflight-H3HEBYQW.js → preflight-N7ZRG2JI.js} +58 -55
  68. package/dist/preflight-N7ZRG2JI.js.map +1 -0
  69. package/dist/{pricing-XQSDTTK5.js → pricing-JJZFICFL.js} +8 -8
  70. package/dist/{pricing-XQSDTTK5.js.map → pricing-JJZFICFL.js.map} +1 -1
  71. package/dist/{prompt-BSV22CQZ.js → prompt-GXC2JSLA.js} +2 -2
  72. package/dist/{publish-Q5ZKEKZ5.js → publish-JPTI4EBT.js} +34 -30
  73. package/dist/publish-JPTI4EBT.js.map +1 -0
  74. package/dist/{purchase-options-CKRN4VIW.js → purchase-options-KFWW4JW2.js} +16 -11
  75. package/dist/purchase-options-KFWW4JW2.js.map +1 -0
  76. package/dist/{purchases-43AKV6HG.js → purchases-DAWTMXP6.js} +118 -193
  77. package/dist/purchases-DAWTMXP6.js.map +1 -0
  78. package/dist/{quickstart-4HB62YEL.js → quickstart-Z5Y3FYJU.js} +5 -3
  79. package/dist/quickstart-Z5Y3FYJU.js.map +1 -0
  80. package/dist/{quota-UHIQQYOY.js → quota-MZRWYJGR.js} +5 -15
  81. package/dist/quota-MZRWYJGR.js.map +1 -0
  82. package/dist/{recovery-5EV2R476.js → recovery-YE3Z7NIN.js} +32 -61
  83. package/dist/recovery-YE3Z7NIN.js.map +1 -0
  84. package/dist/{releases-C2WC2K4E.js → releases-2I3WBULC.js} +184 -185
  85. package/dist/releases-2I3WBULC.js.map +1 -0
  86. package/dist/{reports-2YX3RDOS.js → reports-CIB2T3XT.js} +19 -21
  87. package/dist/reports-CIB2T3XT.js.map +1 -0
  88. package/dist/reviews-BCCXIQ6C.js +188 -0
  89. package/dist/reviews-BCCXIQ6C.js.map +1 -0
  90. package/dist/{status-WHGLODGV.js → status-6LH5W4FU.js} +105 -83
  91. package/dist/status-6LH5W4FU.js.map +1 -0
  92. package/dist/{subscriptions-CI3JH3VQ.js → subscriptions-DZP3Y7O7.js} +142 -232
  93. package/dist/subscriptions-DZP3Y7O7.js.map +1 -0
  94. package/dist/{testers-NZOFA3EF.js → testers-LSMBXCA2.js} +24 -44
  95. package/dist/testers-LSMBXCA2.js.map +1 -0
  96. package/dist/tracks-YHMO2A6B.js +98 -0
  97. package/dist/tracks-YHMO2A6B.js.map +1 -0
  98. package/dist/{train-CJJVLY4B.js → train-MDD2EBHS.js} +35 -55
  99. package/dist/train-MDD2EBHS.js.map +1 -0
  100. package/dist/{update-NAK6CMUX.js → update-OMALGIBR.js} +29 -14
  101. package/dist/update-OMALGIBR.js.map +1 -0
  102. package/dist/{users-2YTC4Q36.js → users-UKG7VIQH.js} +45 -67
  103. package/dist/users-UKG7VIQH.js.map +1 -0
  104. package/dist/{validate-UOVTM6L3.js → validate-QIYSA3N7.js} +8 -10
  105. package/dist/validate-QIYSA3N7.js.map +1 -0
  106. package/dist/{version-N64UBW7A.js → version-NCSNXNVN.js} +3 -3
  107. package/dist/{vitals-A4CS4MSS.js → vitals-C23L2Y2E.js} +153 -172
  108. package/dist/vitals-C23L2Y2E.js.map +1 -0
  109. package/package.json +6 -6
  110. package/dist/anomalies-NU2IN2GJ.js.map +0 -1
  111. package/dist/apps-J2446UDA.js.map +0 -1
  112. package/dist/audit-N2CRHWUN.js.map +0 -1
  113. package/dist/auth-XGSTT5G5.js.map +0 -1
  114. package/dist/bundle-F43TD2BQ.js +0 -218
  115. package/dist/bundle-F43TD2BQ.js.map +0 -1
  116. package/dist/cache-SLNFRTI2.js.map +0 -1
  117. package/dist/changelog-ZYD6W5IV.js +0 -53
  118. package/dist/changelog-ZYD6W5IV.js.map +0 -1
  119. package/dist/chunk-4O4D5SGL.js.map +0 -1
  120. package/dist/chunk-AA577WVQ.js.map +0 -1
  121. package/dist/chunk-FWKYRLKY.js +0 -19
  122. package/dist/chunk-FWKYRLKY.js.map +0 -1
  123. package/dist/chunk-NV75I5VP.js.map +0 -1
  124. package/dist/chunk-U6ZTQ34I.js.map +0 -1
  125. package/dist/config-BUXPDN7N.js.map +0 -1
  126. package/dist/data-safety-Q7FTCEWU.js.map +0 -1
  127. package/dist/device-tiers-MIOQEXYY.js.map +0 -1
  128. package/dist/diff-V77SMKAQ.js +0 -96
  129. package/dist/diff-V77SMKAQ.js.map +0 -1
  130. package/dist/docs-7DUXIKA3.js.map +0 -1
  131. package/dist/doctor-3Z4ARPM2.js +0 -372
  132. package/dist/doctor-3Z4ARPM2.js.map +0 -1
  133. package/dist/enterprise-7THXNBTC.js.map +0 -1
  134. package/dist/external-transactions-2GWIMUVM.js.map +0 -1
  135. package/dist/games-BT777WUO.js.map +0 -1
  136. package/dist/generated-apks-RJWTIX7L.js.map +0 -1
  137. package/dist/grants-TKQJ3IER.js.map +0 -1
  138. package/dist/iap-ICAEQLK5.js.map +0 -1
  139. package/dist/init-JZ2THPMS.js.map +0 -1
  140. package/dist/listings-77HZW4S5.js.map +0 -1
  141. package/dist/migrate-SQT6RD6T.js +0 -143
  142. package/dist/migrate-SQT6RD6T.js.map +0 -1
  143. package/dist/one-time-products-LHZAXQES.js.map +0 -1
  144. package/dist/preflight-H3HEBYQW.js.map +0 -1
  145. package/dist/publish-Q5ZKEKZ5.js.map +0 -1
  146. package/dist/purchase-options-CKRN4VIW.js.map +0 -1
  147. package/dist/purchases-43AKV6HG.js.map +0 -1
  148. package/dist/quickstart-4HB62YEL.js.map +0 -1
  149. package/dist/quota-UHIQQYOY.js.map +0 -1
  150. package/dist/recovery-5EV2R476.js.map +0 -1
  151. package/dist/releases-C2WC2K4E.js.map +0 -1
  152. package/dist/reports-2YX3RDOS.js.map +0 -1
  153. package/dist/reviews-2CWOI5CV.js +0 -213
  154. package/dist/reviews-2CWOI5CV.js.map +0 -1
  155. package/dist/status-WHGLODGV.js.map +0 -1
  156. package/dist/subscriptions-CI3JH3VQ.js.map +0 -1
  157. package/dist/testers-NZOFA3EF.js.map +0 -1
  158. package/dist/tracks-NERFFEDT.js +0 -107
  159. package/dist/tracks-NERFFEDT.js.map +0 -1
  160. package/dist/train-CJJVLY4B.js.map +0 -1
  161. package/dist/update-NAK6CMUX.js.map +0 -1
  162. package/dist/users-2YTC4Q36.js.map +0 -1
  163. package/dist/validate-UOVTM6L3.js.map +0 -1
  164. package/dist/vitals-A4CS4MSS.js.map +0 -1
  165. /package/dist/{feedback-DPTO6DUT.js.map → feedback-XP765TOO.js.map} +0 -0
  166. /package/dist/{prompt-BSV22CQZ.js.map → prompt-GXC2JSLA.js.map} +0 -0
  167. /package/dist/{version-N64UBW7A.js.map → version-NCSNXNVN.js.map} +0 -0
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  readJsonFile
4
- } from "./chunk-FWKYRLKY.js";
4
+ } from "./chunk-SLNJEAMK.js";
5
5
  import {
6
6
  getClient,
7
7
  resolvePackageName
8
- } from "./chunk-AA577WVQ.js";
8
+ } from "./chunk-NQH4G7BI.js";
9
9
  import {
10
10
  isDryRun,
11
11
  printDryRun
@@ -15,7 +15,7 @@ import {
15
15
  } from "./chunk-ELXAK7GI.js";
16
16
  import {
17
17
  requireConfirm
18
- } from "./chunk-NV75I5VP.js";
18
+ } from "./chunk-YFUBD2XB.js";
19
19
 
20
20
  // src/commands/one-time-products.ts
21
21
  import { loadConfig } from "@gpc-cli/config";
@@ -41,30 +41,25 @@ function registerOneTimeProductsCommands(program) {
41
41
  const packageName = resolvePackageName(program.opts()["app"], config);
42
42
  const client = await getClient(config);
43
43
  const format = getOutputFormat(program, config);
44
- try {
45
- const result = await listOneTimeProducts(client, packageName);
46
- if (options.sort) {
47
- result.oneTimeProducts = sortResults(result.oneTimeProducts, options.sort);
48
- }
49
- const products = result.oneTimeProducts || [];
50
- if (format !== "json") {
51
- if (products.length === 0) {
52
- console.log("No one-time products found.");
53
- return;
54
- }
55
- const summary = products.map((p) => ({
56
- productId: p.productId,
57
- purchaseType: p["purchaseType"] || "-",
58
- listings: p.listings ? Object.keys(p.listings).length : 0,
59
- firstTitle: p.listings ? Object.values(p.listings)[0]?.title || "-" : "-"
60
- }));
61
- console.log(formatOutput(summary, format));
62
- } else {
63
- console.log(formatOutput(result, format));
44
+ const result = await listOneTimeProducts(client, packageName);
45
+ if (options.sort) {
46
+ result.oneTimeProducts = sortResults(result.oneTimeProducts, options.sort);
47
+ }
48
+ const products = result.oneTimeProducts || [];
49
+ if (format !== "json") {
50
+ if (products.length === 0) {
51
+ console.log("No one-time products found.");
52
+ return;
64
53
  }
65
- } catch (error) {
66
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
67
- process.exit(4);
54
+ const summary = products.map((p) => ({
55
+ productId: p.productId,
56
+ purchaseType: p["purchaseType"] || "-",
57
+ listings: p.listings ? Object.keys(p.listings).length : 0,
58
+ firstTitle: p.listings ? Object.values(p.listings)[0]?.title || "-" : "-"
59
+ }));
60
+ console.log(formatOutput(summary, format));
61
+ } else {
62
+ console.log(formatOutput(result, format));
68
63
  }
69
64
  });
70
65
  otp.command("get <product-id>").description("Get a one-time product").action(async (productId) => {
@@ -72,13 +67,8 @@ function registerOneTimeProductsCommands(program) {
72
67
  const packageName = resolvePackageName(program.opts()["app"], config);
73
68
  const client = await getClient(config);
74
69
  const format = getOutputFormat(program, config);
75
- try {
76
- const result = await getOneTimeProduct(client, packageName, productId);
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
- }
70
+ const result = await getOneTimeProduct(client, packageName, productId);
71
+ console.log(formatOutput(result, format));
82
72
  });
83
73
  otp.command("create").description("Create a one-time product from JSON file").requiredOption("--file <path>", "JSON file with product data").action(async (options) => {
84
74
  const config = await loadConfig();
@@ -97,14 +87,9 @@ function registerOneTimeProductsCommands(program) {
97
87
  return;
98
88
  }
99
89
  const client = await getClient(config);
100
- try {
101
- const data = await readJsonFile(options.file);
102
- const result = await createOneTimeProduct(client, packageName, data);
103
- console.log(formatOutput(result, format));
104
- } catch (error) {
105
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
106
- process.exit(4);
107
- }
90
+ const data = await readJsonFile(options.file);
91
+ const result = await createOneTimeProduct(client, packageName, data);
92
+ console.log(formatOutput(result, format));
108
93
  });
109
94
  otp.command("update <product-id>").description("Update a one-time product from JSON file").requiredOption("--file <path>", "JSON file with product data").option("--update-mask <fields>", "Comma-separated field mask").action(async (productId, options) => {
110
95
  const config = await loadConfig();
@@ -124,20 +109,15 @@ function registerOneTimeProductsCommands(program) {
124
109
  return;
125
110
  }
126
111
  const client = await getClient(config);
127
- try {
128
- const data = await readJsonFile(options.file);
129
- const result = await updateOneTimeProduct(
130
- client,
131
- packageName,
132
- productId,
133
- data,
134
- options.updateMask
135
- );
136
- console.log(formatOutput(result, format));
137
- } catch (error) {
138
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
139
- process.exit(4);
140
- }
112
+ const data = await readJsonFile(options.file);
113
+ const result = await updateOneTimeProduct(
114
+ client,
115
+ packageName,
116
+ productId,
117
+ data,
118
+ options.updateMask
119
+ );
120
+ console.log(formatOutput(result, format));
141
121
  });
142
122
  otp.command("delete <product-id>").description("Delete a one-time product").action(async (productId) => {
143
123
  const config = await loadConfig();
@@ -157,13 +137,8 @@ function registerOneTimeProductsCommands(program) {
157
137
  return;
158
138
  }
159
139
  const client = await getClient(config);
160
- try {
161
- await deleteOneTimeProduct(client, packageName, productId);
162
- console.log(`One-time product ${productId} deleted.`);
163
- } catch (error) {
164
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
165
- process.exit(4);
166
- }
140
+ await deleteOneTimeProduct(client, packageName, productId);
141
+ console.log(`One-time product ${productId} deleted.`);
167
142
  });
168
143
  const offers = otp.command("offers").description("Manage one-time product offers");
169
144
  offers.command("list <product-id>").description("List offers for a one-time product").option("--sort <field>", "Sort by field (prefix with - for descending)").action(async (productId, options) => {
@@ -171,29 +146,19 @@ function registerOneTimeProductsCommands(program) {
171
146
  const packageName = resolvePackageName(program.opts()["app"], config);
172
147
  const client = await getClient(config);
173
148
  const format = getOutputFormat(program, config);
174
- try {
175
- const result = await listOneTimeOffers(client, packageName, productId);
176
- if (options.sort) {
177
- result.oneTimeOffers = sortResults(result.oneTimeOffers, options.sort);
178
- }
179
- console.log(formatOutput(result, format));
180
- } catch (error) {
181
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
182
- process.exit(4);
149
+ const result = await listOneTimeOffers(client, packageName, productId);
150
+ if (options.sort) {
151
+ result.oneTimeOffers = sortResults(result.oneTimeOffers, options.sort);
183
152
  }
153
+ console.log(formatOutput(result, format));
184
154
  });
185
155
  offers.command("get <product-id> <offer-id>").description("Get an offer for a one-time product").action(async (productId, offerId) => {
186
156
  const config = await loadConfig();
187
157
  const packageName = resolvePackageName(program.opts()["app"], config);
188
158
  const client = await getClient(config);
189
159
  const format = getOutputFormat(program, config);
190
- try {
191
- const result = await getOneTimeOffer(client, packageName, productId, offerId);
192
- console.log(formatOutput(result, format));
193
- } catch (error) {
194
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
195
- process.exit(4);
196
- }
160
+ const result = await getOneTimeOffer(client, packageName, productId, offerId);
161
+ console.log(formatOutput(result, format));
197
162
  });
198
163
  offers.command("create <product-id>").description("Create an offer from JSON file").requiredOption("--file <path>", "JSON file with offer data").action(async (productId, options) => {
199
164
  const config = await loadConfig();
@@ -213,14 +178,9 @@ function registerOneTimeProductsCommands(program) {
213
178
  return;
214
179
  }
215
180
  const client = await getClient(config);
216
- try {
217
- const data = await readJsonFile(options.file);
218
- const result = await createOneTimeOffer(client, packageName, productId, data);
219
- console.log(formatOutput(result, format));
220
- } catch (error) {
221
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
222
- process.exit(4);
223
- }
181
+ const data = await readJsonFile(options.file);
182
+ const result = await createOneTimeOffer(client, packageName, productId, data);
183
+ console.log(formatOutput(result, format));
224
184
  });
225
185
  offers.command("update <product-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(
226
186
  async (productId, offerId, options) => {
@@ -241,21 +201,16 @@ function registerOneTimeProductsCommands(program) {
241
201
  return;
242
202
  }
243
203
  const client = await getClient(config);
244
- try {
245
- const data = await readJsonFile(options.file);
246
- const result = await updateOneTimeOffer(
247
- client,
248
- packageName,
249
- productId,
250
- offerId,
251
- data,
252
- options.updateMask
253
- );
254
- console.log(formatOutput(result, format));
255
- } catch (error) {
256
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
257
- process.exit(4);
258
- }
204
+ const data = await readJsonFile(options.file);
205
+ const result = await updateOneTimeOffer(
206
+ client,
207
+ packageName,
208
+ productId,
209
+ offerId,
210
+ data,
211
+ options.updateMask
212
+ );
213
+ console.log(formatOutput(result, format));
259
214
  }
260
215
  );
261
216
  offers.command("delete <product-id> <offer-id>").description("Delete an offer").action(async (productId, offerId) => {
@@ -276,34 +231,24 @@ function registerOneTimeProductsCommands(program) {
276
231
  return;
277
232
  }
278
233
  const client = await getClient(config);
279
- try {
280
- await deleteOneTimeOffer(client, packageName, productId, offerId);
281
- console.log(`Offer ${offerId} deleted.`);
282
- } catch (error) {
283
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
284
- process.exit(4);
285
- }
234
+ await deleteOneTimeOffer(client, packageName, productId, offerId);
235
+ console.log(`Offer ${offerId} deleted.`);
286
236
  });
287
237
  otp.command("diff <product-id>").description("Compare local JSON file against remote one-time product").requiredOption("--file <path>", "Local JSON file to compare against remote").action(async (productId, options) => {
288
238
  const config = await loadConfig();
289
239
  const packageName = resolvePackageName(program.opts()["app"], config);
290
240
  const client = await getClient(config);
291
241
  const format = getOutputFormat(program, config);
292
- try {
293
- const localData = await readJsonFile(options.file);
294
- const diffs = await diffOneTimeProduct(client, packageName, productId, localData);
295
- if (diffs.length === 0) {
296
- console.log("No differences found.");
297
- } else {
298
- console.log(formatOutput(diffs, format));
299
- }
300
- } catch (error) {
301
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
302
- process.exit(4);
242
+ const localData = await readJsonFile(options.file);
243
+ const diffs = await diffOneTimeProduct(client, packageName, productId, localData);
244
+ if (diffs.length === 0) {
245
+ console.log("No differences found.");
246
+ } else {
247
+ console.log(formatOutput(diffs, format));
303
248
  }
304
249
  });
305
250
  }
306
251
  export {
307
252
  registerOneTimeProductsCommands
308
253
  };
309
- //# sourceMappingURL=one-time-products-LHZAXQES.js.map
254
+ //# sourceMappingURL=one-time-products-MGZTU7OM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/one-time-products.ts"],"sourcesContent":["import { resolvePackageName, getClient } from \"../resolve.js\";\nimport type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\n\nimport type { OneTimeProduct } from \"@gpc-cli/api\";\nimport {\n listOneTimeProducts,\n getOneTimeProduct,\n createOneTimeProduct,\n updateOneTimeProduct,\n deleteOneTimeProduct,\n listOneTimeOffers,\n getOneTimeOffer,\n createOneTimeOffer,\n updateOneTimeOffer,\n deleteOneTimeOffer,\n diffOneTimeProduct,\n formatOutput,\n sortResults,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { requireConfirm } from \"../prompt.js\";\nimport { readJsonFile } from \"../json.js\";\n\n\n\nexport function registerOneTimeProductsCommands(program: Command): void {\n const otp = program\n .command(\"one-time-products\")\n .alias(\"otp\")\n .description(\"Manage one-time products and offers (modern OTP API)\");\n\n otp\n .command(\"list\")\n .description(\"List one-time products\")\n .option(\"--sort <field>\", \"Sort by field (prefix with - for descending)\")\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 listOneTimeProducts(client, packageName);\n if (options.sort) {\n result.oneTimeProducts = sortResults(result.oneTimeProducts, options.sort);\n }\n const products = result.oneTimeProducts || [];\n if (format !== \"json\") {\n if (products.length === 0) {\n console.log(\"No one-time products found.\");\n return;\n }\n const summary = products.map((p: OneTimeProduct) => ({\n productId: p.productId,\n purchaseType: (p as unknown as Record<string, unknown>)[\"purchaseType\"] || \"-\",\n listings: p.listings ? Object.keys(p.listings).length : 0,\n firstTitle: p.listings ? Object.values(p.listings)[0]?.title || \"-\" : \"-\",\n }));\n console.log(formatOutput(summary, format));\n } else {\n console.log(formatOutput(result, format));\n }\n });\n\n otp\n .command(\"get <product-id>\")\n .description(\"Get a one-time product\")\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 = getOutputFormat(program, config);\n\n const result = await getOneTimeProduct(client, packageName, productId);\n console.log(formatOutput(result, format));\n });\n\n otp\n .command(\"create\")\n .description(\"Create a one-time product from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with product data\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"one-time-products create\",\n action: \"create\",\n target: `one-time product from ${options.file}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n const data = await readJsonFile(options.file);\n const result = await createOneTimeProduct(client, packageName, data as any);\n console.log(formatOutput(result, format));\n });\n\n otp\n .command(\"update <product-id>\")\n .description(\"Update a one-time product from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with product 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 = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"one-time-products update\",\n action: \"update\",\n target: productId,\n details: { file: options.file },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n const data = await readJsonFile(options.file);\n const result = await updateOneTimeProduct(\n client,\n packageName,\n productId,\n data as any,\n options.updateMask,\n );\n console.log(formatOutput(result, format));\n });\n\n otp\n .command(\"delete <product-id>\")\n .description(\"Delete a one-time product\")\n .action(async (productId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Delete one-time product \"${productId}\"?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"one-time-products delete\",\n action: \"delete\",\n target: productId,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n await deleteOneTimeProduct(client, packageName, productId);\n console.log(`One-time product ${productId} deleted.`);\n });\n\n // --- Offers ---\n const offers = otp.command(\"offers\").description(\"Manage one-time product offers\");\n\n offers\n .command(\"list <product-id>\")\n .description(\"List offers for a one-time product\")\n .option(\"--sort <field>\", \"Sort by field (prefix with - for descending)\")\n .action(async (productId: string, 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 listOneTimeOffers(client, packageName, productId);\n if (options.sort) {\n result.oneTimeOffers = sortResults(result.oneTimeOffers, options.sort);\n }\n console.log(formatOutput(result, format));\n });\n\n offers\n .command(\"get <product-id> <offer-id>\")\n .description(\"Get an offer for a one-time product\")\n .action(async (productId: 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 = getOutputFormat(program, config);\n\n const result = await getOneTimeOffer(client, packageName, productId, offerId);\n console.log(formatOutput(result, format));\n });\n\n offers\n .command(\"create <product-id>\")\n .description(\"Create an offer from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with offer data\")\n .action(async (productId: string, options: { file: string }) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"one-time-products offers create\",\n action: \"create offer for\",\n target: productId,\n details: { file: options.file },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n const data = await readJsonFile(options.file);\n const result = await createOneTimeOffer(client, packageName, productId, data as any);\n console.log(formatOutput(result, format));\n });\n\n offers\n .command(\"update <product-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(\n async (\n productId: string,\n offerId: string,\n options: { file: string; updateMask?: string },\n ) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"one-time-products offers update\",\n action: \"update offer\",\n target: `${productId}/${offerId}`,\n details: { file: options.file },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n const data = await readJsonFile(options.file);\n const result = await updateOneTimeOffer(\n client,\n packageName,\n productId,\n offerId,\n data as any,\n options.updateMask,\n );\n console.log(formatOutput(result, format));\n },\n );\n\n offers\n .command(\"delete <product-id> <offer-id>\")\n .description(\"Delete an offer\")\n .action(async (productId: string, offerId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Delete offer \"${offerId}\" for product \"${productId}\"?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"one-time-products offers delete\",\n action: \"delete offer\",\n target: `${productId}/${offerId}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n await deleteOneTimeOffer(client, packageName, productId, offerId);\n console.log(`Offer ${offerId} deleted.`);\n });\n\n // --- Diff ---\n otp\n .command(\"diff <product-id>\")\n .description(\"Compare local JSON file against remote one-time product\")\n .requiredOption(\"--file <path>\", \"Local JSON file to compare against remote\")\n .action(async (productId: string, options: { file: 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 localData = (await readJsonFile(options.file)) as OneTimeProduct;\n const diffs = await diffOneTimeProduct(client, packageName, productId, localData);\n if (diffs.length === 0) {\n console.log(\"No differences found.\");\n } else {\n console.log(formatOutput(diffs, format));\n }\n });\n}\n"],"mappings":"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","names":[]}
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-ELXAK7GI.js";
12
12
 
13
13
  // src/commands/preflight.ts
14
- import { runPreflight, getAllScannerNames, formatOutput } from "@gpc-cli/core";
14
+ import { runPreflight, getAllScannerNames, formatOutput, GpcError } from "@gpc-cli/core";
15
15
  import { loadConfig } from "@gpc-cli/config";
16
16
  var SEVERITY_ICONS = {
17
17
  critical: "\u2717",
@@ -62,82 +62,85 @@ function registerPreflightCommand(program) {
62
62
  }
63
63
  async function runPreflightAction(program, file, options) {
64
64
  if (!file && !options["metadata"] && !options["source"]) {
65
- console.error("Error: Provide an AAB file, --metadata <dir>, or --source <dir>");
66
- process.exit(2);
65
+ throw new GpcError(
66
+ "Provide an AAB file, --metadata <dir>, or --source <dir>",
67
+ "MISSING_INPUT",
68
+ 2,
69
+ "gpc preflight app.aab"
70
+ );
67
71
  }
68
72
  const failOn = options["failOn"];
69
73
  const validSeverities = /* @__PURE__ */ new Set(["critical", "error", "warning", "info"]);
70
74
  if (failOn && !validSeverities.has(failOn)) {
71
- console.error(
72
- `Error: Invalid --fail-on value "${failOn}". Use: critical, error, warning, info`
75
+ throw new GpcError(
76
+ `Invalid --fail-on value "${failOn}". Use: critical, error, warning, info`,
77
+ "INVALID_OPTION",
78
+ 2
73
79
  );
74
- process.exit(2);
75
80
  }
76
81
  const scannerNames = options["scanners"]?.split(",").map((s) => s.trim());
77
82
  if (scannerNames) {
78
83
  const known = new Set(getAllScannerNames());
79
84
  const unknown = scannerNames.filter((s) => !known.has(s));
80
85
  if (unknown.length > 0) {
81
- console.error(
82
- `Error: Unknown scanner(s): ${unknown.join(", ")}. Available: ${getAllScannerNames().join(", ")}`
86
+ throw new GpcError(
87
+ `Unknown scanner(s): ${unknown.join(", ")}. Available: ${getAllScannerNames().join(", ")}`,
88
+ "UNKNOWN_SCANNER",
89
+ 2
83
90
  );
84
- process.exit(2);
85
91
  }
86
92
  }
87
93
  const config = await loadConfig();
88
94
  const format = getOutputFormat(program, config);
89
- try {
90
- const result = await runPreflight({
91
- aabPath: file,
92
- metadataDir: options["metadata"],
93
- sourceDir: options["source"],
94
- scanners: scannerNames,
95
- failOn,
96
- configPath: options["config"]
97
- });
98
- if (format === "json") {
99
- console.log(formatOutput(result, format));
95
+ const result = await runPreflight({
96
+ aabPath: file,
97
+ metadataDir: options["metadata"],
98
+ sourceDir: options["source"],
99
+ scanners: scannerNames,
100
+ failOn,
101
+ configPath: options["config"]
102
+ });
103
+ if (format === "json") {
104
+ console.log(formatOutput(result, format));
105
+ } else {
106
+ console.log(bold("GPC Preflight Scanner"));
107
+ if (file) console.log(dim(`File: ${file}`));
108
+ console.log(dim(`Scanners: ${result.scanners.join(", ")}`));
109
+ console.log("");
110
+ if (result.findings.length === 0) {
111
+ console.log(green("\u2713 No issues found"));
100
112
  } else {
101
- console.log(bold("GPC Preflight Scanner"));
102
- if (file) console.log(dim(`File: ${file}`));
103
- console.log(dim(`Scanners: ${result.scanners.join(", ")}`));
104
- console.log("");
105
- if (result.findings.length === 0) {
106
- console.log(green("\u2713 No issues found"));
107
- } else {
108
- for (const finding of result.findings) {
109
- const icon = SEVERITY_ICONS[finding.severity];
110
- const label = severityColor(
111
- finding.severity,
112
- `${icon} ${finding.severity.toUpperCase()}`
113
- );
114
- console.log(`${label} ${finding.title}`);
115
- console.log(` ${dim(finding.message)}`);
116
- if (finding.suggestion) {
117
- console.log(` ${dim("\u2192")} ${finding.suggestion}`);
118
- }
119
- if (finding.policyUrl) {
120
- console.log(` ${dim(finding.policyUrl)}`);
121
- }
122
- console.log("");
113
+ for (const finding of result.findings) {
114
+ const icon = SEVERITY_ICONS[finding.severity];
115
+ const label = severityColor(
116
+ finding.severity,
117
+ `${icon} ${finding.severity.toUpperCase()}`
118
+ );
119
+ console.log(`${label} ${finding.title}`);
120
+ console.log(` ${dim(finding.message)}`);
121
+ if (finding.suggestion) {
122
+ console.log(` ${dim("\u2192")} ${finding.suggestion}`);
123
123
  }
124
+ if (finding.policyUrl) {
125
+ console.log(` ${dim(finding.policyUrl)}`);
126
+ }
127
+ console.log("");
124
128
  }
125
- const parts = [];
126
- if (result.summary.critical > 0) parts.push(bold(red(`${result.summary.critical} critical`)));
127
- if (result.summary.error > 0) parts.push(red(`${result.summary.error} error`));
128
- if (result.summary.warning > 0) parts.push(yellow(`${result.summary.warning} warning`));
129
- if (result.summary.info > 0) parts.push(dim(`${result.summary.info} info`));
130
- const summaryLine = parts.length > 0 ? parts.join(", ") : green("0 issues");
131
- const passedLabel = result.passed ? green("\u2713 PASSED") : red("\u2717 FAILED");
132
- console.log(`${passedLabel} ${summaryLine} ${dim(`(${result.durationMs}ms)`)}`);
133
129
  }
134
- process.exit(result.passed ? 0 : 6);
135
- } catch (err) {
136
- console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
137
- process.exit(1);
130
+ const parts = [];
131
+ if (result.summary.critical > 0) parts.push(bold(red(`${result.summary.critical} critical`)));
132
+ if (result.summary.error > 0) parts.push(red(`${result.summary.error} error`));
133
+ if (result.summary.warning > 0) parts.push(yellow(`${result.summary.warning} warning`));
134
+ if (result.summary.info > 0) parts.push(dim(`${result.summary.info} info`));
135
+ const summaryLine = parts.length > 0 ? parts.join(", ") : green("0 issues");
136
+ const passedLabel = result.passed ? green("\u2713 PASSED") : red("\u2717 FAILED");
137
+ console.log(`${passedLabel} ${summaryLine} ${dim(`(${result.durationMs}ms)`)}`);
138
+ }
139
+ if (!result.passed) {
140
+ process.exitCode = 6;
138
141
  }
139
142
  }
140
143
  export {
141
144
  registerPreflightCommand
142
145
  };
143
- //# sourceMappingURL=preflight-H3HEBYQW.js.map
146
+ //# sourceMappingURL=preflight-N7ZRG2JI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/preflight.ts"],"sourcesContent":["// Named exports only. No default export.\n\nimport type { Command } from \"commander\";\nimport { runPreflight, getAllScannerNames, formatOutput, GpcError } from \"@gpc-cli/core\";\nimport type { FindingSeverity } from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { green, red, yellow, dim, bold } from \"../colors.js\";\n\nconst SEVERITY_ICONS: Record<FindingSeverity, string> = {\n critical: \"✗\",\n error: \"✗\",\n warning: \"⚠\",\n info: \"ℹ\",\n};\n\nfunction severityColor(severity: FindingSeverity, text: string): string {\n switch (severity) {\n case \"critical\":\n return bold(red(text));\n case \"error\":\n return red(text);\n case \"warning\":\n return yellow(text);\n case \"info\":\n return dim(text);\n }\n}\n\nexport function registerPreflightCommand(program: Command): void {\n const cmd = program\n .command(\"preflight [file]\")\n .description(\"Pre-submission compliance scanner for AAB files (offline)\")\n .option(\n \"--fail-on <severity>\",\n \"Fail if any finding meets or exceeds severity: critical, error, warning, info\",\n \"error\",\n )\n .option(\"--scanners <names>\", \"Comma-separated scanner names to run (default: all)\")\n .option(\"--metadata <dir>\", \"Path to metadata directory (Fastlane format) for listing checks\")\n .option(\"--source <dir>\", \"Path to source directory for code scanning\")\n .option(\"--config <path>\", \"Path to .preflightrc.json config file\")\n .action(async (file: string | undefined, options) => {\n await runPreflightAction(program, file, options);\n });\n\n // Subcommand: preflight manifest\n cmd\n .command(\"manifest <file>\")\n .description(\"Run manifest scanner only\")\n .option(\"--fail-on <severity>\", \"Fail threshold\", \"error\")\n .action(async (file: string, options) => {\n await runPreflightAction(program, file, { ...options, scanners: \"manifest\" });\n });\n\n // Subcommand: preflight permissions\n cmd\n .command(\"permissions <file>\")\n .description(\"Run permissions scanner only\")\n .option(\"--fail-on <severity>\", \"Fail threshold\", \"error\")\n .action(async (file: string, options) => {\n await runPreflightAction(program, file, { ...options, scanners: \"permissions\" });\n });\n\n // Subcommand: preflight metadata\n cmd\n .command(\"metadata <dir>\")\n .description(\"Run metadata scanner on a listings directory\")\n .option(\"--fail-on <severity>\", \"Fail threshold\", \"error\")\n .action(async (dir: string, options) => {\n await runPreflightAction(program, undefined, {\n ...options,\n metadata: dir,\n scanners: \"metadata\",\n });\n });\n\n // Subcommand: preflight codescan\n cmd\n .command(\"codescan <dir>\")\n .description(\"Run code scanners (secrets, billing, privacy) on source directory\")\n .option(\"--fail-on <severity>\", \"Fail threshold\", \"error\")\n .action(async (dir: string, options) => {\n await runPreflightAction(program, undefined, {\n ...options,\n source: dir,\n scanners: \"secrets,billing,privacy\",\n });\n });\n}\n\nasync function runPreflightAction(\n program: Command,\n file: string | undefined,\n options: Record<string, string | undefined>,\n): Promise<void> {\n if (!file && !options[\"metadata\"] && !options[\"source\"]) {\n throw new GpcError(\n \"Provide an AAB file, --metadata <dir>, or --source <dir>\",\n \"MISSING_INPUT\",\n 2,\n \"gpc preflight app.aab\",\n );\n }\n\n const failOn = options[\"failOn\"] as FindingSeverity | undefined;\n const validSeverities = new Set([\"critical\", \"error\", \"warning\", \"info\"]);\n if (failOn && !validSeverities.has(failOn)) {\n throw new GpcError(\n `Invalid --fail-on value \"${failOn}\". Use: critical, error, warning, info`,\n \"INVALID_OPTION\",\n 2,\n );\n }\n\n const scannerNames = options[\"scanners\"]?.split(\",\").map((s) => s.trim());\n if (scannerNames) {\n const known = new Set(getAllScannerNames());\n const unknown = scannerNames.filter((s) => !known.has(s));\n if (unknown.length > 0) {\n throw new GpcError(\n `Unknown scanner(s): ${unknown.join(\", \")}. Available: ${getAllScannerNames().join(\", \")}`,\n \"UNKNOWN_SCANNER\",\n 2,\n );\n }\n }\n\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n\n const result = await runPreflight({\n aabPath: file,\n metadataDir: options[\"metadata\"],\n sourceDir: options[\"source\"],\n scanners: scannerNames,\n failOn,\n configPath: options[\"config\"],\n });\n\n if (format === \"json\") {\n console.log(formatOutput(result, format));\n } else {\n // Header\n console.log(bold(\"GPC Preflight Scanner\"));\n if (file) console.log(dim(`File: ${file}`));\n console.log(dim(`Scanners: ${result.scanners.join(\", \")}`));\n console.log(\"\");\n\n if (result.findings.length === 0) {\n console.log(green(\"✓ No issues found\"));\n } else {\n // Group by severity\n for (const finding of result.findings) {\n const icon = SEVERITY_ICONS[finding.severity];\n const label = severityColor(\n finding.severity,\n `${icon} ${finding.severity.toUpperCase()}`,\n );\n console.log(`${label} ${finding.title}`);\n console.log(` ${dim(finding.message)}`);\n if (finding.suggestion) {\n console.log(` ${dim(\"→\")} ${finding.suggestion}`);\n }\n if (finding.policyUrl) {\n console.log(` ${dim(finding.policyUrl)}`);\n }\n console.log(\"\");\n }\n }\n\n // Summary line\n const parts: string[] = [];\n if (result.summary.critical > 0) parts.push(bold(red(`${result.summary.critical} critical`)));\n if (result.summary.error > 0) parts.push(red(`${result.summary.error} error`));\n if (result.summary.warning > 0) parts.push(yellow(`${result.summary.warning} warning`));\n if (result.summary.info > 0) parts.push(dim(`${result.summary.info} info`));\n\n const summaryLine = parts.length > 0 ? parts.join(\", \") : green(\"0 issues\");\n const passedLabel = result.passed ? green(\"✓ PASSED\") : red(\"✗ FAILED\");\n console.log(`${passedLabel} ${summaryLine} ${dim(`(${result.durationMs}ms)`)}`);\n }\n\n if (!result.passed) {\n process.exitCode = 6;\n }\n}\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  getClient,
4
4
  resolvePackageName
5
- } from "./chunk-AA577WVQ.js";
5
+ } from "./chunk-NQH4G7BI.js";
6
6
  import {
7
7
  getOutputFormat
8
8
  } from "./chunk-ELXAK7GI.js";
@@ -15,7 +15,7 @@ function registerPricingCommands(program) {
15
15
  pricing.command("convert").description("Convert a price to all regional prices").option("--from <currency>", "Source currency code (e.g. USD)").option("--amount <number>", "Price amount (e.g. 4.99)").action(async (options) => {
16
16
  const config = await loadConfig();
17
17
  const packageName = resolvePackageName(program.opts()["app"], config);
18
- const { isInteractive, requireOption } = await import("./prompt-BSV22CQZ.js");
18
+ const { isInteractive, requireOption } = await import("./prompt-GXC2JSLA.js");
19
19
  const interactive = isInteractive(program);
20
20
  options.from = await requireOption(
21
21
  "from",
@@ -61,17 +61,17 @@ function registerPricingCommands(program) {
61
61
  } catch (error) {
62
62
  const { PlayApiError } = await import("@gpc-cli/api");
63
63
  if (error instanceof PlayApiError && (error.code === "API_HTTP_400" || error.code === "API_EDIT_EXPIRED")) {
64
- console.error(
65
- "Error: Price conversion is not available for this app. Ensure the app has monetization configured in Google Play Console (at least one paid product or subscription)."
64
+ const err = new Error(
65
+ "Price conversion is not available for this app. Ensure the app has monetization configured in Google Play Console (at least one paid product or subscription)."
66
66
  );
67
- } else {
68
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
67
+ Object.assign(err, { code: "API_PRICING_UNAVAILABLE", exitCode: 4 });
68
+ throw err;
69
69
  }
70
- process.exit(4);
70
+ throw error;
71
71
  }
72
72
  });
73
73
  }
74
74
  export {
75
75
  registerPricingCommands
76
76
  };
77
- //# sourceMappingURL=pricing-XQSDTTK5.js.map
77
+ //# sourceMappingURL=pricing-JJZFICFL.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/pricing.ts"],"sourcesContent":["import { resolvePackageName, getClient } from \"../resolve.js\";\nimport type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\n\nimport { convertRegionPrices, formatOutput } from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\n\n\n\nexport function registerPricingCommands(program: Command): void {\n const pricing = program.command(\"pricing\").description(\"Pricing and regional price conversion\");\n\n pricing\n .command(\"convert\")\n .description(\"Convert a price to all regional prices\")\n .option(\"--from <currency>\", \"Source currency code (e.g. USD)\")\n .option(\"--amount <number>\", \"Price amount (e.g. 4.99)\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const { isInteractive, requireOption } = await import(\"../prompt.js\");\n const interactive = isInteractive(program);\n\n options.from = await requireOption(\n \"from\",\n options.from,\n {\n message: \"Source currency code (e.g. USD):\",\n default: \"USD\",\n },\n interactive,\n );\n\n options.amount = await requireOption(\n \"amount\",\n options.amount,\n {\n message: \"Price amount (e.g. 4.99):\",\n },\n interactive,\n );\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await convertRegionPrices(client, packageName, options.from, options.amount);\n if (format !== \"json\") {\n const prices = (result as unknown as Record<string, unknown>)[\"convertedRegionPrices\"] as\n | Record<string, Record<string, unknown>>\n | undefined;\n if (prices) {\n const rows = Object.entries(prices).map(([region, data]) => {\n const money = data[\"price\"] as Record<string, unknown> | undefined;\n const units = money?.[\"units\"] || \"0\";\n const nanos = String(money?.[\"nanos\"] || 0)\n .padStart(9, \"0\")\n .slice(0, 2);\n return {\n region,\n price: money\n ? `${units}.${nanos}`\n : data[\"priceMicros\"]\n ? String(Number(data[\"priceMicros\"]) / 1_000_000)\n : \"-\",\n currencyCode: (money?.[\"currencyCode\"] || data[\"currencyCode\"] || \"-\") as string,\n };\n });\n console.log(formatOutput(rows, format));\n } else {\n console.log(formatOutput(result, format));\n }\n } else {\n console.log(formatOutput(result, format));\n }\n } catch (error) {\n const { PlayApiError } = await import(\"@gpc-cli/api\");\n if (\n error instanceof PlayApiError &&\n (error.code === \"API_HTTP_400\" || error.code === \"API_EDIT_EXPIRED\")\n ) {\n console.error(\n \"Error: Price conversion is not available for this app. \" +\n \"Ensure the app has monetization configured in Google Play Console (at least one paid product or subscription).\",\n );\n } else {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n }\n process.exit(4);\n }\n });\n}\n"],"mappings":";;;;;;;;;;AAEA,SAAS,kBAAkB;AAE3B,SAAS,qBAAqB,oBAAoB;AAK3C,SAAS,wBAAwB,SAAwB;AAC9D,QAAM,UAAU,QAAQ,QAAQ,SAAS,EAAE,YAAY,uCAAuC;AAE9F,UACG,QAAQ,SAAS,EACjB,YAAY,wCAAwC,EACpD,OAAO,qBAAqB,iCAAiC,EAC7D,OAAO,qBAAqB,0BAA0B,EACtD,OAAO,OAAO,YAAY;AACzB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AACpE,UAAM,EAAE,eAAe,cAAc,IAAI,MAAM,OAAO,sBAAc;AACpE,UAAM,cAAc,cAAc,OAAO;AAEzC,YAAQ,OAAO,MAAM;AAAA,MACnB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,QACE,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,MACA;AAAA,IACF;AAEA,YAAQ,SAAS,MAAM;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,QACE,SAAS;AAAA,MACX;AAAA,MACA;AAAA,IACF;AACA,UAAM,SAAS,MAAM,UAAU,MAAM;AACrC,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAE9C,QAAI;AACF,YAAM,SAAS,MAAM,oBAAoB,QAAQ,aAAa,QAAQ,MAAM,QAAQ,MAAM;AAC1F,UAAI,WAAW,QAAQ;AACrB,cAAM,SAAU,OAA8C,uBAAuB;AAGrF,YAAI,QAAQ;AACV,gBAAM,OAAO,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,QAAQ,IAAI,MAAM;AAC1D,kBAAM,QAAQ,KAAK,OAAO;AAC1B,kBAAM,QAAQ,QAAQ,OAAO,KAAK;AAClC,kBAAM,QAAQ,OAAO,QAAQ,OAAO,KAAK,CAAC,EACvC,SAAS,GAAG,GAAG,EACf,MAAM,GAAG,CAAC;AACb,mBAAO;AAAA,cACL;AAAA,cACA,OAAO,QACH,GAAG,KAAK,IAAI,KAAK,KACjB,KAAK,aAAa,IAChB,OAAO,OAAO,KAAK,aAAa,CAAC,IAAI,GAAS,IAC9C;AAAA,cACN,cAAe,QAAQ,cAAc,KAAK,KAAK,cAAc,KAAK;AAAA,YACpE;AAAA,UACF,CAAC;AACD,kBAAQ,IAAI,aAAa,MAAM,MAAM,CAAC;AAAA,QACxC,OAAO;AACL,kBAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,QAC1C;AAAA,MACF,OAAO;AACL,gBAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,MAC1C;AAAA,IACF,SAAS,OAAO;AACd,YAAM,EAAE,aAAa,IAAI,MAAM,OAAO,cAAc;AACpD,UACE,iBAAiB,iBAChB,MAAM,SAAS,kBAAkB,MAAM,SAAS,qBACjD;AACA,gBAAQ;AAAA,UACN;AAAA,QAEF;AAAA,MACF,OAAO;AACL,gBAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,MAClF;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;","names":[]}
1
+ {"version":3,"sources":["../src/commands/pricing.ts"],"sourcesContent":["import { resolvePackageName, getClient } from \"../resolve.js\";\nimport type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\n\nimport { convertRegionPrices, formatOutput } from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\n\n\n\nexport function registerPricingCommands(program: Command): void {\n const pricing = program.command(\"pricing\").description(\"Pricing and regional price conversion\");\n\n pricing\n .command(\"convert\")\n .description(\"Convert a price to all regional prices\")\n .option(\"--from <currency>\", \"Source currency code (e.g. USD)\")\n .option(\"--amount <number>\", \"Price amount (e.g. 4.99)\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const { isInteractive, requireOption } = await import(\"../prompt.js\");\n const interactive = isInteractive(program);\n\n options.from = await requireOption(\n \"from\",\n options.from,\n {\n message: \"Source currency code (e.g. USD):\",\n default: \"USD\",\n },\n interactive,\n );\n\n options.amount = await requireOption(\n \"amount\",\n options.amount,\n {\n message: \"Price amount (e.g. 4.99):\",\n },\n interactive,\n );\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await convertRegionPrices(client, packageName, options.from, options.amount);\n if (format !== \"json\") {\n const prices = (result as unknown as Record<string, unknown>)[\"convertedRegionPrices\"] as\n | Record<string, Record<string, unknown>>\n | undefined;\n if (prices) {\n const rows = Object.entries(prices).map(([region, data]) => {\n const money = data[\"price\"] as Record<string, unknown> | undefined;\n const units = money?.[\"units\"] || \"0\";\n const nanos = String(money?.[\"nanos\"] || 0)\n .padStart(9, \"0\")\n .slice(0, 2);\n return {\n region,\n price: money\n ? `${units}.${nanos}`\n : data[\"priceMicros\"]\n ? String(Number(data[\"priceMicros\"]) / 1_000_000)\n : \"-\",\n currencyCode: (money?.[\"currencyCode\"] || data[\"currencyCode\"] || \"-\") as string,\n };\n });\n console.log(formatOutput(rows, format));\n } else {\n console.log(formatOutput(result, format));\n }\n } else {\n console.log(formatOutput(result, format));\n }\n } catch (error) {\n const { PlayApiError } = await import(\"@gpc-cli/api\");\n if (\n error instanceof PlayApiError &&\n (error.code === \"API_HTTP_400\" || error.code === \"API_EDIT_EXPIRED\")\n ) {\n const err = new Error(\n \"Price conversion is not available for this app. \" +\n \"Ensure the app has monetization configured in Google Play Console (at least one paid product or subscription).\",\n );\n Object.assign(err, { code: \"API_PRICING_UNAVAILABLE\", exitCode: 4 });\n throw err;\n }\n throw error;\n }\n });\n}\n"],"mappings":";;;;;;;;;;AAEA,SAAS,kBAAkB;AAE3B,SAAS,qBAAqB,oBAAoB;AAK3C,SAAS,wBAAwB,SAAwB;AAC9D,QAAM,UAAU,QAAQ,QAAQ,SAAS,EAAE,YAAY,uCAAuC;AAE9F,UACG,QAAQ,SAAS,EACjB,YAAY,wCAAwC,EACpD,OAAO,qBAAqB,iCAAiC,EAC7D,OAAO,qBAAqB,0BAA0B,EACtD,OAAO,OAAO,YAAY;AACzB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AACpE,UAAM,EAAE,eAAe,cAAc,IAAI,MAAM,OAAO,sBAAc;AACpE,UAAM,cAAc,cAAc,OAAO;AAEzC,YAAQ,OAAO,MAAM;AAAA,MACnB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,QACE,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,MACA;AAAA,IACF;AAEA,YAAQ,SAAS,MAAM;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,QACE,SAAS;AAAA,MACX;AAAA,MACA;AAAA,IACF;AACA,UAAM,SAAS,MAAM,UAAU,MAAM;AACrC,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAE9C,QAAI;AACF,YAAM,SAAS,MAAM,oBAAoB,QAAQ,aAAa,QAAQ,MAAM,QAAQ,MAAM;AAC1F,UAAI,WAAW,QAAQ;AACrB,cAAM,SAAU,OAA8C,uBAAuB;AAGrF,YAAI,QAAQ;AACV,gBAAM,OAAO,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,QAAQ,IAAI,MAAM;AAC1D,kBAAM,QAAQ,KAAK,OAAO;AAC1B,kBAAM,QAAQ,QAAQ,OAAO,KAAK;AAClC,kBAAM,QAAQ,OAAO,QAAQ,OAAO,KAAK,CAAC,EACvC,SAAS,GAAG,GAAG,EACf,MAAM,GAAG,CAAC;AACb,mBAAO;AAAA,cACL;AAAA,cACA,OAAO,QACH,GAAG,KAAK,IAAI,KAAK,KACjB,KAAK,aAAa,IAChB,OAAO,OAAO,KAAK,aAAa,CAAC,IAAI,GAAS,IAC9C;AAAA,cACN,cAAe,QAAQ,cAAc,KAAK,KAAK,cAAc,KAAK;AAAA,YACpE;AAAA,UACF,CAAC;AACD,kBAAQ,IAAI,aAAa,MAAM,MAAM,CAAC;AAAA,QACxC,OAAO;AACL,kBAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,QAC1C;AAAA,MACF,OAAO;AACL,gBAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,MAC1C;AAAA,IACF,SAAS,OAAO;AACd,YAAM,EAAE,aAAa,IAAI,MAAM,OAAO,cAAc;AACpD,UACE,iBAAiB,iBAChB,MAAM,SAAS,kBAAkB,MAAM,SAAS,qBACjD;AACA,cAAM,MAAM,IAAI;AAAA,UACd;AAAA,QAEF;AACA,eAAO,OAAO,KAAK,EAAE,MAAM,2BAA2B,UAAU,EAAE,CAAC;AACnE,cAAM;AAAA,MACR;AACA,YAAM;AAAA,IACR;AAAA,EACF,CAAC;AACL;","names":[]}
@@ -7,7 +7,7 @@ import {
7
7
  requireConfirm,
8
8
  requireOption,
9
9
  skipConfirm
10
- } from "./chunk-NV75I5VP.js";
10
+ } from "./chunk-YFUBD2XB.js";
11
11
  export {
12
12
  isInteractive,
13
13
  promptConfirm,
@@ -17,4 +17,4 @@ export {
17
17
  requireOption,
18
18
  skipConfirm
19
19
  };
20
- //# sourceMappingURL=prompt-BSV22CQZ.js.map
20
+ //# sourceMappingURL=prompt-GXC2JSLA.js.map