@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,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  resolvePackageName
4
- } from "./chunk-AA577WVQ.js";
4
+ } from "./chunk-NQH4G7BI.js";
5
5
  import {
6
6
  isDryRun
7
7
  } from "./chunk-Y3QZDAKS.js";
@@ -12,7 +12,7 @@ import {
12
12
  isInteractive,
13
13
  promptInput,
14
14
  promptSelect
15
- } from "./chunk-NV75I5VP.js";
15
+ } from "./chunk-YFUBD2XB.js";
16
16
 
17
17
  // src/commands/publish.ts
18
18
  import { appendFile, stat } from "fs/promises";
@@ -24,7 +24,8 @@ import {
24
24
  generateNotesFromGit,
25
25
  writeAuditLog,
26
26
  createAuditEntry,
27
- formatOutput
27
+ formatOutput,
28
+ GpcError
28
29
  } from "@gpc-cli/core";
29
30
  var PASS = "\u2713";
30
31
  var FAIL = "\u2717";
@@ -83,15 +84,21 @@ function registerPublishCommand(program) {
83
84
  try {
84
85
  await stat(file);
85
86
  } catch {
86
- console.error(`Error: File not found: ${file}`);
87
- process.exit(2);
87
+ throw new GpcError(
88
+ `File not found: ${file}`,
89
+ "PUBLISH_USAGE_ERROR",
90
+ 2,
91
+ "Check the file path and try again."
92
+ );
88
93
  }
89
94
  const noteSources = [options.notes, options.notesDir, options.notesFromGit].filter(Boolean);
90
95
  if (noteSources.length > 1) {
91
- console.error(
92
- "Error: Cannot combine --notes, --notes-dir, and --notes-from-git. Use only one."
96
+ throw new GpcError(
97
+ "Cannot combine --notes, --notes-dir, and --notes-from-git. Use only one.",
98
+ "PUBLISH_USAGE_ERROR",
99
+ 2,
100
+ "Pick one release notes source."
93
101
  );
94
- process.exit(2);
95
102
  }
96
103
  const config = await loadConfig();
97
104
  const packageName = resolvePackageName(program.opts()["app"], config);
@@ -118,10 +125,12 @@ function registerPublishCommand(program) {
118
125
  if (options.rollout !== void 0) {
119
126
  const rollout = Number(options.rollout);
120
127
  if (!Number.isFinite(rollout) || rollout < 1 || rollout > 100) {
121
- console.error(
122
- `Error: --rollout must be a number between 1 and 100 (got: ${options.rollout})`
128
+ throw new GpcError(
129
+ `--rollout must be a number between 1 and 100 (got: ${options.rollout})`,
130
+ "PUBLISH_USAGE_ERROR",
131
+ 2,
132
+ "Use a percentage between 1 and 100."
123
133
  );
124
- process.exit(2);
125
134
  }
126
135
  }
127
136
  if (options.notesFromGit) {
@@ -146,21 +155,16 @@ function registerPublishCommand(program) {
146
155
  });
147
156
  const client = createApiClient({ auth, onRetry });
148
157
  if (isDryRun(program)) {
149
- try {
150
- const result = await publish(client, packageName, file, {
151
- track: options.track,
152
- rolloutPercent: options.rollout ? Number(options.rollout) : void 0,
153
- notes: options.notes,
154
- notesDir: options.notesDir,
155
- releaseName: options.name,
156
- mappingFile: options.mapping,
157
- dryRun: true
158
- });
159
- console.log(formatDryRunOutput(result, format));
160
- } catch (error) {
161
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
162
- process.exit(4);
163
- }
158
+ const result = await publish(client, packageName, file, {
159
+ track: options.track,
160
+ rolloutPercent: options.rollout ? Number(options.rollout) : void 0,
161
+ notes: options.notes,
162
+ notesDir: options.notesDir,
163
+ releaseName: options.name,
164
+ mappingFile: options.mapping,
165
+ dryRun: true
166
+ });
167
+ console.log(formatDryRunOutput(result, format));
164
168
  return;
165
169
  }
166
170
  const auditEntry = createAuditEntry(
@@ -181,15 +185,15 @@ function registerPublishCommand(program) {
181
185
  console.log(formatValidationOutput(result, format));
182
186
  auditEntry.success = false;
183
187
  auditEntry.error = "Validation failed";
184
- process.exit(1);
188
+ process.exitCode = 1;
189
+ return;
185
190
  }
186
191
  console.log(formatPublishOutput(result, format));
187
192
  auditEntry.success = true;
188
193
  } catch (error) {
189
194
  auditEntry.success = false;
190
195
  auditEntry.error = error instanceof Error ? error.message : String(error);
191
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
192
- process.exit(4);
196
+ throw error;
193
197
  } finally {
194
198
  auditEntry.durationMs = Date.now() - new Date(auditEntry.timestamp).getTime();
195
199
  writeAuditLog(auditEntry).catch(() => {
@@ -200,4 +204,4 @@ function registerPublishCommand(program) {
200
204
  export {
201
205
  registerPublishCommand
202
206
  };
203
- //# sourceMappingURL=publish-Q5ZKEKZ5.js.map
207
+ //# sourceMappingURL=publish-JPTI4EBT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/publish.ts"],"sourcesContent":["import { resolvePackageName } from \"../resolve.js\";\nimport { appendFile, stat } from \"node:fs/promises\";\nimport type { OutputFormat } from \"@gpc-cli/config\";\nimport type { Command } from \"commander\";\nimport { loadConfig, getCacheDir } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createApiClient } from \"@gpc-cli/api\";\nimport type { RetryLogEntry } from \"@gpc-cli/api\";\nimport {\n publish,\n generateNotesFromGit,\n writeAuditLog,\n createAuditEntry,\n formatOutput,\n GpcError,\n} from \"@gpc-cli/core\";\nimport type { PublishResult, DryRunPublishResult } from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun } from \"../dry-run.js\";\nimport { isInteractive, promptSelect, promptInput } from \"../prompt.js\";\n\nconst PASS = \"\\u2713\";\nconst FAIL = \"\\u2717\";\nconst WARN = \"\\u26A0\";\n\n\n// ---------------------------------------------------------------------------\n// Output formatters\n// ---------------------------------------------------------------------------\n\nfunction formatChecks(checks: { name: string; passed: boolean; message: string }[]): string[] {\n return checks.map((c) => ` ${c.passed ? PASS : FAIL} ${c.message}`);\n}\n\nfunction formatValidationOutput(result: PublishResult, format: OutputFormat): string {\n if (format !== \"table\") {\n return formatOutput({ success: false, validation: result.validation }, format);\n }\n const lines = [\"Validation failed:\\n\", ...formatChecks(result.validation.checks)];\n for (const w of result.validation.warnings) {\n lines.push(` ${WARN} ${w}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction formatPublishOutput(result: PublishResult, format: OutputFormat): string {\n if (format !== \"table\") return formatOutput(result, format);\n\n const upload = result.upload;\n if (!upload) return formatOutput(result, format);\n const rollout =\n upload.status === \"inProgress\" && \"userFraction\" in upload\n ? ` (${Math.round(Number((upload as Record<string, unknown>)[\"userFraction\"]) * 100)}% rollout)`\n : \"\";\n\n const lines = [\"Published successfully\\n\", ...formatChecks(result.validation.checks)];\n for (const w of result.validation.warnings) {\n lines.push(` ${WARN} ${w}`);\n }\n lines.push(\"\");\n lines.push(` versionCode ${upload.versionCode}`);\n lines.push(` track ${upload.track}`);\n lines.push(` status ${upload.status}${rollout}`);\n return lines.join(\"\\n\");\n}\n\nfunction formatDryRunOutput(result: DryRunPublishResult, format: OutputFormat): string {\n if (format !== \"table\") return formatOutput(result, format);\n\n const lines = [\"Dry run — no changes made\\n\", ...formatChecks(result.validation.checks)];\n for (const w of result.validation.warnings) {\n lines.push(` ${WARN} ${w}`);\n }\n\n const u = result.upload;\n lines.push(\"\");\n lines.push(` Track ${u.track}`);\n\n if (u.currentReleases.length === 0) {\n lines.push(` Current (no releases on this track)`);\n } else {\n for (const r of u.currentReleases) {\n const fraction =\n r.userFraction !== undefined ? ` (${Math.round(r.userFraction * 100)}%)` : \"\";\n lines.push(` Current ${r.versionCodes.join(\", \")} · ${r.status}${fraction}`);\n }\n }\n const plannedFraction =\n u.plannedRelease.userFraction !== undefined\n ? ` (${Math.round(u.plannedRelease.userFraction * 100)}%)`\n : \"\";\n lines.push(` Would be (new bundle) · ${u.plannedRelease.status}${plannedFraction}`);\n return lines.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Command\n// ---------------------------------------------------------------------------\n\nexport function registerPublishCommand(program: Command): void {\n program\n .command(\"publish <file>\")\n .description(\"Validate, upload, and release in one step\")\n .option(\"--track <track>\", \"Target track\", \"internal\")\n .option(\"--rollout <percent>\", \"Staged rollout percentage (1-100)\")\n .option(\"--notes <text>\", \"Release notes (en-US)\")\n .option(\"--notes-dir <dir>\", \"Read release notes from directory (<dir>/<lang>.txt)\")\n .option(\"--notes-from-git\", \"Generate release notes from git commit history\")\n .option(\"--since <ref>\", \"Git ref to start from (tag, SHA) — used with --notes-from-git\")\n .option(\"--name <name>\", \"Release name\")\n .option(\"--mapping <file>\", \"ProGuard/R8 mapping file for deobfuscation\")\n .option(\"--retry-log <path>\", \"Write retry log entries to file (JSONL)\")\n .action(async (file: string, options) => {\n try {\n await stat(file);\n } catch {\n throw new GpcError(\n `File not found: ${file}`,\n \"PUBLISH_USAGE_ERROR\",\n 2,\n \"Check the file path and try again.\",\n );\n }\n\n const noteSources = [options.notes, options.notesDir, options.notesFromGit].filter(Boolean);\n if (noteSources.length > 1) {\n throw new GpcError(\n \"Cannot combine --notes, --notes-dir, and --notes-from-git. Use only one.\",\n \"PUBLISH_USAGE_ERROR\",\n 2,\n \"Pick one release notes source.\",\n );\n }\n\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n // Interactive mode: prompt for missing options\n if (isInteractive(program)) {\n if (!options.track || options.track === \"internal\") {\n const tracks = [\"internal\", \"alpha\", \"beta\", \"production\"];\n options.track = await promptSelect(\"Select track:\", tracks, \"internal\");\n }\n\n if (!options.rollout && options.track === \"production\") {\n const rolloutStr = await promptInput(\n \"Staged rollout percentage (1-100, blank for full)\",\n \"100\",\n );\n if (rolloutStr && rolloutStr !== \"100\") {\n options.rollout = rolloutStr;\n }\n }\n\n if (!options.notes && !options.notesDir && !options.notesFromGit) {\n const notes = await promptInput(\"Release notes (en-US, blank to skip)\");\n if (notes) options.notes = notes;\n }\n }\n\n // Rollout range guard\n if (options.rollout !== undefined) {\n const rollout = Number(options.rollout);\n if (!Number.isFinite(rollout) || rollout < 1 || rollout > 100) {\n throw new GpcError(\n `--rollout must be a number between 1 and 100 (got: ${options.rollout})`,\n \"PUBLISH_USAGE_ERROR\",\n 2,\n \"Use a percentage between 1 and 100.\",\n );\n }\n }\n\n // Resolve git-based release notes before calling publish\n if (options.notesFromGit) {\n const gitNotes = await generateNotesFromGit({ since: options.since });\n options.notes = gitNotes.text;\n if (gitNotes.truncated) {\n console.error(\n `${WARN} Release notes truncated to 500 characters (${gitNotes.commitCount} commits from ${gitNotes.since}).`,\n );\n }\n }\n\n let onRetry: ((entry: RetryLogEntry) => void) | undefined;\n if (options.retryLog) {\n onRetry = (entry: RetryLogEntry) => {\n appendFile(options.retryLog, JSON.stringify(entry) + \"\\n\").catch(() => {});\n };\n }\n\n const auth = await resolveAuth({\n serviceAccountPath: config.auth?.serviceAccount,\n cachePath: getCacheDir(),\n });\n const client = createApiClient({ auth, onRetry });\n\n if (isDryRun(program)) {\n const result = await publish(client, packageName, file, {\n track: options.track,\n rolloutPercent: options.rollout ? Number(options.rollout) : undefined,\n notes: options.notes,\n notesDir: options.notesDir,\n releaseName: options.name,\n mappingFile: options.mapping,\n dryRun: true,\n });\n console.log(formatDryRunOutput(result as DryRunPublishResult, format));\n return;\n }\n\n const auditEntry = createAuditEntry(\n \"publish\",\n { file, track: options.track, rollout: options.rollout },\n packageName,\n );\n\n try {\n const result = await publish(client, packageName, file, {\n track: options.track,\n rolloutPercent: options.rollout ? Number(options.rollout) : undefined,\n notes: options.notes,\n notesDir: options.notesDir,\n releaseName: options.name,\n mappingFile: options.mapping,\n });\n\n if (!result.upload) {\n console.log(formatValidationOutput(result as PublishResult, format));\n auditEntry.success = false;\n auditEntry.error = \"Validation failed\";\n process.exitCode = 1;\n return;\n }\n\n console.log(formatPublishOutput(result as PublishResult, format));\n auditEntry.success = true;\n } catch (error) {\n auditEntry.success = false;\n auditEntry.error = error instanceof Error ? error.message : String(error);\n throw error;\n } finally {\n auditEntry.durationMs = Date.now() - new Date(auditEntry.timestamp).getTime();\n writeAuditLog(auditEntry).catch(() => {});\n }\n });\n}\n"],"mappings":"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","names":[]}
@@ -14,27 +14,32 @@ See: gpc otp offers --help`;
14
14
  function registerPurchaseOptionsCommands(program) {
15
15
  const po = program.command("purchase-options").description("Manage purchase options (use 'otp offers' commands)");
16
16
  po.command("list").description("List purchase options").option("--sort <field>", "Sort by field").action(async () => {
17
- console.log(REDIRECT_MESSAGE);
18
- process.exit(2);
17
+ const err = new Error(REDIRECT_MESSAGE);
18
+ Object.assign(err, { code: "USAGE_ERROR", exitCode: 2 });
19
+ throw err;
19
20
  });
20
21
  po.command("get <id>").description("Get a purchase option").action(async () => {
21
- console.log(REDIRECT_MESSAGE);
22
- process.exit(2);
22
+ const err = new Error(REDIRECT_MESSAGE);
23
+ Object.assign(err, { code: "USAGE_ERROR", exitCode: 2 });
24
+ throw err;
23
25
  });
24
26
  po.command("create").description("Create a purchase option").option("--file <path>", "JSON file with purchase option data").action(async () => {
25
- console.log(REDIRECT_MESSAGE);
26
- process.exit(2);
27
+ const err = new Error(REDIRECT_MESSAGE);
28
+ Object.assign(err, { code: "USAGE_ERROR", exitCode: 2 });
29
+ throw err;
27
30
  });
28
31
  po.command("activate <id>").description("Activate a purchase option").action(async () => {
29
- console.log(REDIRECT_MESSAGE);
30
- process.exit(2);
32
+ const err = new Error(REDIRECT_MESSAGE);
33
+ Object.assign(err, { code: "USAGE_ERROR", exitCode: 2 });
34
+ throw err;
31
35
  });
32
36
  po.command("deactivate <id>").description("Deactivate a purchase option").action(async () => {
33
- console.log(REDIRECT_MESSAGE);
34
- process.exit(2);
37
+ const err = new Error(REDIRECT_MESSAGE);
38
+ Object.assign(err, { code: "USAGE_ERROR", exitCode: 2 });
39
+ throw err;
35
40
  });
36
41
  }
37
42
  export {
38
43
  registerPurchaseOptionsCommands
39
44
  };
40
- //# sourceMappingURL=purchase-options-CKRN4VIW.js.map
45
+ //# sourceMappingURL=purchase-options-KFWW4JW2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/purchase-options.ts"],"sourcesContent":["import type { Command } from \"commander\";\n\nconst REDIRECT_MESSAGE = `Purchase options are managed through one-time product offers.\n\nUse the following commands instead:\n gpc otp offers list <product-id> List purchase options for a product\n gpc otp offers get <product-id> <id> Get a specific purchase option\n gpc otp offers create <product-id> Create a purchase option\n gpc otp offers activate <product-id> <id>\n gpc otp offers deactivate <product-id> <id>\n\nSee: gpc otp offers --help`;\n\nexport function registerPurchaseOptionsCommands(program: Command): void {\n const po = program\n .command(\"purchase-options\")\n .description(\"Manage purchase options (use 'otp offers' commands)\");\n\n po.command(\"list\")\n .description(\"List purchase options\")\n .option(\"--sort <field>\", \"Sort by field\")\n .action(async () => {\n const err = new Error(REDIRECT_MESSAGE);\n Object.assign(err, { code: \"USAGE_ERROR\", exitCode: 2 });\n throw err;\n });\n\n po.command(\"get <id>\")\n .description(\"Get a purchase option\")\n .action(async () => {\n const err = new Error(REDIRECT_MESSAGE);\n Object.assign(err, { code: \"USAGE_ERROR\", exitCode: 2 });\n throw err;\n });\n\n po.command(\"create\")\n .description(\"Create a purchase option\")\n .option(\"--file <path>\", \"JSON file with purchase option data\")\n .action(async () => {\n const err = new Error(REDIRECT_MESSAGE);\n Object.assign(err, { code: \"USAGE_ERROR\", exitCode: 2 });\n throw err;\n });\n\n po.command(\"activate <id>\")\n .description(\"Activate a purchase option\")\n .action(async () => {\n const err = new Error(REDIRECT_MESSAGE);\n Object.assign(err, { code: \"USAGE_ERROR\", exitCode: 2 });\n throw err;\n });\n\n po.command(\"deactivate <id>\")\n .description(\"Deactivate a purchase option\")\n .action(async () => {\n const err = new Error(REDIRECT_MESSAGE);\n Object.assign(err, { code: \"USAGE_ERROR\", exitCode: 2 });\n throw err;\n });\n}\n"],"mappings":";;;AAEA,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWlB,SAAS,gCAAgC,SAAwB;AACtE,QAAM,KAAK,QACR,QAAQ,kBAAkB,EAC1B,YAAY,qDAAqD;AAEpE,KAAG,QAAQ,MAAM,EACd,YAAY,uBAAuB,EACnC,OAAO,kBAAkB,eAAe,EACxC,OAAO,YAAY;AAClB,UAAM,MAAM,IAAI,MAAM,gBAAgB;AACtC,WAAO,OAAO,KAAK,EAAE,MAAM,eAAe,UAAU,EAAE,CAAC;AACvD,UAAM;AAAA,EACR,CAAC;AAEH,KAAG,QAAQ,UAAU,EAClB,YAAY,uBAAuB,EACnC,OAAO,YAAY;AAClB,UAAM,MAAM,IAAI,MAAM,gBAAgB;AACtC,WAAO,OAAO,KAAK,EAAE,MAAM,eAAe,UAAU,EAAE,CAAC;AACvD,UAAM;AAAA,EACR,CAAC;AAEH,KAAG,QAAQ,QAAQ,EAChB,YAAY,0BAA0B,EACtC,OAAO,iBAAiB,qCAAqC,EAC7D,OAAO,YAAY;AAClB,UAAM,MAAM,IAAI,MAAM,gBAAgB;AACtC,WAAO,OAAO,KAAK,EAAE,MAAM,eAAe,UAAU,EAAE,CAAC;AACvD,UAAM;AAAA,EACR,CAAC;AAEH,KAAG,QAAQ,eAAe,EACvB,YAAY,4BAA4B,EACxC,OAAO,YAAY;AAClB,UAAM,MAAM,IAAI,MAAM,gBAAgB;AACtC,WAAO,OAAO,KAAK,EAAE,MAAM,eAAe,UAAU,EAAE,CAAC;AACvD,UAAM;AAAA,EACR,CAAC;AAEH,KAAG,QAAQ,iBAAiB,EACzB,YAAY,8BAA8B,EAC1C,OAAO,YAAY;AAClB,UAAM,MAAM,IAAI,MAAM,gBAAgB;AACtC,WAAO,OAAO,KAAK,EAAE,MAAM,eAAe,UAAU,EAAE,CAAC;AACvD,UAAM;AAAA,EACR,CAAC;AACL;","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
  isDryRun,
8
8
  printDryRun
@@ -14,7 +14,7 @@ import {
14
14
  isInteractive,
15
15
  requireConfirm,
16
16
  requireOption
17
- } from "./chunk-NV75I5VP.js";
17
+ } from "./chunk-YFUBD2XB.js";
18
18
 
19
19
  // src/commands/purchases.ts
20
20
  import { Option } from "commander";
@@ -44,24 +44,19 @@ function registerPurchasesCommands(program) {
44
44
  const packageName = resolvePackageName(program.opts()["app"], config);
45
45
  const client = await getClient(config);
46
46
  const format = getOutputFormat(program, config);
47
- try {
48
- const result = await getProductPurchase(client, packageName, productId, token);
49
- if (format !== "json") {
50
- const r = result;
51
- const row = {
52
- orderId: r["orderId"] || "-",
53
- purchaseState: r["purchaseState"] ?? "-",
54
- consumptionState: r["consumptionState"] ?? "-",
55
- purchaseTime: r["purchaseTimeMillis"] ? new Date(Number(r["purchaseTimeMillis"])).toISOString() : "-",
56
- acknowledged: r["acknowledgementState"] ?? "-"
57
- };
58
- console.log(formatOutput(row, format));
59
- } else {
60
- console.log(formatOutput(result, format));
61
- }
62
- } catch (error) {
63
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
64
- process.exit(4);
47
+ const result = await getProductPurchase(client, packageName, productId, token);
48
+ if (format !== "json") {
49
+ const r = result;
50
+ const row = {
51
+ orderId: r["orderId"] || "-",
52
+ purchaseState: r["purchaseState"] ?? "-",
53
+ consumptionState: r["consumptionState"] ?? "-",
54
+ purchaseTime: r["purchaseTimeMillis"] ? new Date(Number(r["purchaseTimeMillis"])).toISOString() : "-",
55
+ acknowledged: r["acknowledgementState"] ?? "-"
56
+ };
57
+ console.log(formatOutput(row, format));
58
+ } else {
59
+ console.log(formatOutput(result, format));
65
60
  }
66
61
  });
67
62
  purchases.command("acknowledge <product-id> <token>").description("Acknowledge a product purchase").option("--payload <text>", "Developer payload").action(async (productId, token, options) => {
@@ -82,13 +77,8 @@ function registerPurchasesCommands(program) {
82
77
  return;
83
78
  }
84
79
  const client = await getClient(config);
85
- try {
86
- await acknowledgeProductPurchase(client, packageName, productId, token, options.payload);
87
- console.log(`Purchase acknowledged.`);
88
- } catch (error) {
89
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
90
- process.exit(4);
91
- }
80
+ await acknowledgeProductPurchase(client, packageName, productId, token, options.payload);
81
+ console.log(`Purchase acknowledged.`);
92
82
  });
93
83
  purchases.command("consume <product-id> <token>").description("Consume a product purchase").action(async (productId, token) => {
94
84
  const config = await loadConfig();
@@ -107,13 +97,8 @@ function registerPurchasesCommands(program) {
107
97
  return;
108
98
  }
109
99
  const client = await getClient(config);
110
- try {
111
- await consumeProductPurchase(client, packageName, productId, token);
112
- console.log(`Purchase consumed.`);
113
- } catch (error) {
114
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
115
- process.exit(4);
116
- }
100
+ await consumeProductPurchase(client, packageName, productId, token);
101
+ console.log(`Purchase consumed.`);
117
102
  });
118
103
  const sub = purchases.command("subscription").description("Manage subscription purchases");
119
104
  sub.command("get <token>").description("Get a subscription purchase (v2)").action(async (token) => {
@@ -121,26 +106,21 @@ function registerPurchasesCommands(program) {
121
106
  const packageName = resolvePackageName(program.opts()["app"], config);
122
107
  const client = await getClient(config);
123
108
  const format = getOutputFormat(program, config);
124
- try {
125
- const result = await getSubscriptionPurchase(client, packageName, token);
126
- if (format !== "json") {
127
- const r = result;
128
- const lineItems = r["lineItems"];
129
- const row = {
130
- subscriptionState: r["subscriptionState"] || "-",
131
- startTime: r["startTime"] || "-",
132
- expiryTime: r["expiryTime"] || "-",
133
- linkedPurchaseToken: r["linkedPurchaseToken"] ? "yes" : "no",
134
- lineItems: lineItems?.length || 0,
135
- acknowledgement: r["acknowledgementState"] || "-"
136
- };
137
- console.log(formatOutput(row, format));
138
- } else {
139
- console.log(formatOutput(result, format));
140
- }
141
- } catch (error) {
142
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
143
- process.exit(4);
109
+ const result = await getSubscriptionPurchase(client, packageName, token);
110
+ if (format !== "json") {
111
+ const r = result;
112
+ const lineItems = r["lineItems"];
113
+ const row = {
114
+ subscriptionState: r["subscriptionState"] || "-",
115
+ startTime: r["startTime"] || "-",
116
+ expiryTime: r["expiryTime"] || "-",
117
+ linkedPurchaseToken: r["linkedPurchaseToken"] ? "yes" : "no",
118
+ lineItems: lineItems?.length || 0,
119
+ acknowledgement: r["acknowledgementState"] || "-"
120
+ };
121
+ console.log(formatOutput(row, format));
122
+ } else {
123
+ console.log(formatOutput(result, format));
144
124
  }
145
125
  });
146
126
  sub.command("cancel <subscription-id> <token>").description("Cancel a subscription (v1)").action(async (subscriptionId, token) => {
@@ -160,13 +140,8 @@ function registerPurchasesCommands(program) {
160
140
  return;
161
141
  }
162
142
  const client = await getClient(config);
163
- try {
164
- await cancelSubscriptionPurchase(client, packageName, subscriptionId, token);
165
- console.log(`Subscription cancelled.`);
166
- } catch (error) {
167
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
168
- process.exit(4);
169
- }
143
+ await cancelSubscriptionPurchase(client, packageName, subscriptionId, token);
144
+ console.log(`Subscription cancelled.`);
170
145
  });
171
146
  sub.command("defer <subscription-id> <token>").description("Defer a subscription expiry").option("--expiry <iso-date>", "Desired new expiry date (ISO 8601)").action(async (subscriptionId, token, options) => {
172
147
  const config = await loadConfig();
@@ -195,19 +170,14 @@ function registerPurchasesCommands(program) {
195
170
  return;
196
171
  }
197
172
  const client = await getClient(config);
198
- try {
199
- const result = await deferSubscriptionPurchase(
200
- client,
201
- packageName,
202
- subscriptionId,
203
- token,
204
- options.expiry
205
- );
206
- console.log(formatOutput(result, format));
207
- } catch (error) {
208
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
209
- process.exit(4);
210
- }
173
+ const result = await deferSubscriptionPurchase(
174
+ client,
175
+ packageName,
176
+ subscriptionId,
177
+ token,
178
+ options.expiry
179
+ );
180
+ console.log(formatOutput(result, format));
211
181
  });
212
182
  sub.command("refund <token>").description("Refund a subscription purchase (v2)").action(async (token) => {
213
183
  const config = await loadConfig();
@@ -227,13 +197,8 @@ function registerPurchasesCommands(program) {
227
197
  return;
228
198
  }
229
199
  const client = await getClient(config);
230
- try {
231
- await refundSubscriptionV2(client, packageName, token);
232
- console.log(`Subscription refunded.`);
233
- } catch (error) {
234
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
235
- process.exit(4);
236
- }
200
+ await refundSubscriptionV2(client, packageName, token);
201
+ console.log(`Subscription refunded.`);
237
202
  });
238
203
  sub.command("revoke <token>").description("Revoke a subscription (v2)").action(async (token) => {
239
204
  const config = await loadConfig();
@@ -252,13 +217,8 @@ function registerPurchasesCommands(program) {
252
217
  return;
253
218
  }
254
219
  const client = await getClient(config);
255
- try {
256
- await revokeSubscriptionPurchase(client, packageName, token);
257
- console.log(`Subscription revoked.`);
258
- } catch (error) {
259
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
260
- process.exit(4);
261
- }
220
+ await revokeSubscriptionPurchase(client, packageName, token);
221
+ console.log(`Subscription revoked.`);
262
222
  });
263
223
  purchases.command("voided").description("List voided purchases").option("--start-time <time>", "Start time (milliseconds)").option("--end-time <time>", "End time (milliseconds)").addOption(
264
224
  new Option("--max-results <n>", "Maximum results per page").argParser(parseInt).hideHelp()
@@ -267,34 +227,29 @@ function registerPurchasesCommands(program) {
267
227
  const packageName = resolvePackageName(program.opts()["app"], config);
268
228
  const client = await getClient(config);
269
229
  const format = getOutputFormat(program, config);
270
- try {
271
- const result = await listVoidedPurchases(client, packageName, {
272
- startTime: options.startTime,
273
- endTime: options.endTime,
274
- maxResults: options.maxResults,
275
- limit: options.limit,
276
- nextPage: options.nextPage
277
- });
278
- if (format !== "json") {
279
- const purchases2 = result["voidedPurchases"];
280
- if (purchases2 && purchases2.length > 0) {
281
- const rows = purchases2.map((p) => ({
282
- orderId: p["orderId"] || "-",
283
- purchaseToken: String(p["purchaseToken"] || "-").slice(0, 16) + "...",
284
- voidedTime: p["voidedTimeMillis"] ? new Date(Number(p["voidedTimeMillis"])).toISOString() : "-",
285
- voidedSource: p["voidedSource"] ?? "-",
286
- voidedReason: p["voidedReason"] ?? "-"
287
- }));
288
- console.log(formatOutput(rows, format));
289
- } else {
290
- console.log("No voided purchases found.");
291
- }
230
+ const result = await listVoidedPurchases(client, packageName, {
231
+ startTime: options.startTime,
232
+ endTime: options.endTime,
233
+ maxResults: options.maxResults,
234
+ limit: options.limit,
235
+ nextPage: options.nextPage
236
+ });
237
+ if (format !== "json") {
238
+ const purchases2 = result["voidedPurchases"];
239
+ if (purchases2 && purchases2.length > 0) {
240
+ const rows = purchases2.map((p) => ({
241
+ orderId: p["orderId"] || "-",
242
+ purchaseToken: String(p["purchaseToken"] || "-").slice(0, 16) + "...",
243
+ voidedTime: p["voidedTimeMillis"] ? new Date(Number(p["voidedTimeMillis"])).toISOString() : "-",
244
+ voidedSource: p["voidedSource"] ?? "-",
245
+ voidedReason: p["voidedReason"] ?? "-"
246
+ }));
247
+ console.log(formatOutput(rows, format));
292
248
  } else {
293
- console.log(formatOutput(result, format));
249
+ console.log("No voided purchases found.");
294
250
  }
295
- } catch (error) {
296
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
297
- process.exit(4);
251
+ } else {
252
+ console.log(formatOutput(result, format));
298
253
  }
299
254
  });
300
255
  const orders = purchases.command("orders").description("Manage orders");
@@ -317,40 +272,30 @@ function registerPurchasesCommands(program) {
317
272
  return;
318
273
  }
319
274
  const client = await getClient(config);
320
- try {
321
- await refundOrder(client, packageName, orderId, {
322
- fullRefund: options.fullRefund,
323
- proratedRefund: options.proratedRefund
324
- });
325
- console.log(`Order ${orderId} refunded.`);
326
- } catch (error) {
327
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
328
- process.exit(4);
329
- }
275
+ await refundOrder(client, packageName, orderId, {
276
+ fullRefund: options.fullRefund,
277
+ proratedRefund: options.proratedRefund
278
+ });
279
+ console.log(`Order ${orderId} refunded.`);
330
280
  });
331
281
  orders.command("get <order-id>").description("Get order details").action(async (orderId) => {
332
282
  const config = await loadConfig();
333
283
  const packageName = resolvePackageName(program.opts()["app"], config);
334
284
  const client = await getClient(config);
335
285
  const format = getOutputFormat(program, config);
336
- try {
337
- const result = await getOrderDetails(client, packageName, orderId);
338
- if (format !== "json") {
339
- const row = {
340
- orderId: result.orderId,
341
- state: result.state,
342
- purchaseToken: result.purchaseToken ? result.purchaseToken.slice(0, 16) + "..." : "-",
343
- createTime: result.createTime || "-",
344
- total: result.total ? `${result.total.units || "0"}.${String(result.total.nanos || 0).padStart(9, "0").slice(0, 2)} ${result.total.currencyCode}` : "-",
345
- lineItems: result.lineItems?.length || 0
346
- };
347
- console.log(formatOutput(row, format));
348
- } else {
349
- console.log(formatOutput(result, format));
350
- }
351
- } catch (error) {
352
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
353
- process.exit(4);
286
+ const result = await getOrderDetails(client, packageName, orderId);
287
+ if (format !== "json") {
288
+ const row = {
289
+ orderId: result.orderId,
290
+ state: result.state,
291
+ purchaseToken: result.purchaseToken ? result.purchaseToken.slice(0, 16) + "..." : "-",
292
+ createTime: result.createTime || "-",
293
+ total: result.total ? `${result.total.units || "0"}.${String(result.total.nanos || 0).padStart(9, "0").slice(0, 2)} ${result.total.currencyCode}` : "-",
294
+ lineItems: result.lineItems?.length || 0
295
+ };
296
+ console.log(formatOutput(row, format));
297
+ } else {
298
+ console.log(formatOutput(result, format));
354
299
  }
355
300
  });
356
301
  orders.command("batch-get").description("Get multiple orders at once").requiredOption("--ids <order-ids>", "Comma-separated order IDs (max 1000)").action(async (options) => {
@@ -359,26 +304,21 @@ function registerPurchasesCommands(program) {
359
304
  const client = await getClient(config);
360
305
  const format = getOutputFormat(program, config);
361
306
  const orderIds = options.ids.split(",").map((id) => id.trim()).filter(Boolean);
362
- try {
363
- const result = await batchGetOrders(client, packageName, orderIds);
364
- if (format !== "json") {
365
- if (result.length === 0) {
366
- console.log("No orders found.");
367
- } else {
368
- const rows = result.map((o) => ({
369
- orderId: o.orderId,
370
- state: o.state,
371
- createTime: o.createTime || "-",
372
- lineItems: o.lineItems?.length || 0
373
- }));
374
- console.log(formatOutput(rows, format));
375
- }
307
+ const result = await batchGetOrders(client, packageName, orderIds);
308
+ if (format !== "json") {
309
+ if (result.length === 0) {
310
+ console.log("No orders found.");
376
311
  } else {
377
- console.log(formatOutput(result, format));
312
+ const rows = result.map((o) => ({
313
+ orderId: o.orderId,
314
+ state: o.state,
315
+ createTime: o.createTime || "-",
316
+ lineItems: o.lineItems?.length || 0
317
+ }));
318
+ console.log(formatOutput(rows, format));
378
319
  }
379
- } catch (error) {
380
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
381
- process.exit(4);
320
+ } else {
321
+ console.log(formatOutput(result, format));
382
322
  }
383
323
  });
384
324
  const product = purchases.command("product").description("Product purchase operations");
@@ -387,24 +327,19 @@ function registerPurchasesCommands(program) {
387
327
  const packageName = resolvePackageName(program.opts()["app"], config);
388
328
  const client = await getClient(config);
389
329
  const format = getOutputFormat(program, config);
390
- try {
391
- const result = await getProductPurchaseV2(client, packageName, token);
392
- if (format !== "json") {
393
- const row = {
394
- orderId: result.orderId || "-",
395
- state: result.purchaseStateContext?.state || "-",
396
- regionCode: result.regionCode || "-",
397
- completionTime: result.purchaseCompletionTime || "-",
398
- acknowledgement: result.acknowledgementState || "-",
399
- lineItems: result.productLineItem?.length || 0
400
- };
401
- console.log(formatOutput(row, format));
402
- } else {
403
- console.log(formatOutput(result, format));
404
- }
405
- } catch (error) {
406
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
407
- process.exit(4);
330
+ const result = await getProductPurchaseV2(client, packageName, token);
331
+ if (format !== "json") {
332
+ const row = {
333
+ orderId: result.orderId || "-",
334
+ state: result.purchaseStateContext?.state || "-",
335
+ regionCode: result.regionCode || "-",
336
+ completionTime: result.purchaseCompletionTime || "-",
337
+ acknowledgement: result.acknowledgementState || "-",
338
+ lineItems: result.productLineItem?.length || 0
339
+ };
340
+ console.log(formatOutput(row, format));
341
+ } else {
342
+ console.log(formatOutput(result, format));
408
343
  }
409
344
  });
410
345
  sub.command("cancel-v2 <token>").description("Cancel a subscription (v2 \u2014 supports cancellation types)").option("--type <cancellationType>", "Cancellation type (e.g., USER_CANCELED, SYSTEM_CANCELED, DEVELOPER_CANCELED, REPLACED)").action(async (token, options) => {
@@ -421,13 +356,8 @@ function registerPurchasesCommands(program) {
421
356
  return;
422
357
  }
423
358
  const client = await getClient(config);
424
- try {
425
- await cancelSubscriptionV2(client, packageName, token, options.type);
426
- console.log("Subscription cancelled.");
427
- } catch (error) {
428
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
429
- process.exit(4);
430
- }
359
+ await cancelSubscriptionV2(client, packageName, token, options.type);
360
+ console.log("Subscription cancelled.");
431
361
  });
432
362
  sub.command("defer-v2 <token>").description("Defer a subscription renewal (v2 \u2014 supports add-on subscriptions)").requiredOption("--until <date>", "Desired expiry time (ISO 8601 date)").action(async (token, options) => {
433
363
  const config = await loadConfig();
@@ -443,16 +373,11 @@ function registerPurchasesCommands(program) {
443
373
  return;
444
374
  }
445
375
  const client = await getClient(config);
446
- try {
447
- const result = await deferSubscriptionV2(client, packageName, token, options.until);
448
- console.log(`Subscription deferred. New expiry: ${result.newExpiryTime}`);
449
- } catch (error) {
450
- console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
451
- process.exit(4);
452
- }
376
+ const result = await deferSubscriptionV2(client, packageName, token, options.until);
377
+ console.log(`Subscription deferred. New expiry: ${result.newExpiryTime}`);
453
378
  });
454
379
  }
455
380
  export {
456
381
  registerPurchasesCommands
457
382
  };
458
- //# sourceMappingURL=purchases-43AKV6HG.js.map
383
+ //# sourceMappingURL=purchases-DAWTMXP6.js.map