@gpc-cli/cli 0.9.53 → 0.9.54

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 (148) hide show
  1. package/README.md +19 -19
  2. package/dist/{anomalies-V3AFS4LD.js → anomalies-I5P6QQAZ.js} +14 -5
  3. package/dist/anomalies-I5P6QQAZ.js.map +1 -0
  4. package/dist/{apps-4GP3FD7O.js → apps-WPUQOQLL.js} +2 -2
  5. package/dist/{audit-VTWXTXC6.js → audit-M7GYID74.js} +2 -2
  6. package/dist/{auth-BA4FE2PO.js → auth-4DRT7ZH2.js} +10 -4
  7. package/dist/auth-4DRT7ZH2.js.map +1 -0
  8. package/dist/bin.js +2 -2
  9. package/dist/{bundle-F7MUVC5J.js → bundle-PFTE7XMU.js} +4 -2
  10. package/dist/bundle-PFTE7XMU.js.map +1 -0
  11. package/dist/{cache-XKPLZYEB.js → cache-FGNP7Y37.js} +6 -2
  12. package/dist/cache-FGNP7Y37.js.map +1 -0
  13. package/dist/{chunk-SLNJEAMK.js → chunk-22XCOLZX.js} +4 -2
  14. package/dist/chunk-22XCOLZX.js.map +1 -0
  15. package/dist/{chunk-GQVZ2VCT.js → chunk-6HIY4IGM.js} +48 -45
  16. package/dist/chunk-6HIY4IGM.js.map +1 -0
  17. package/dist/{chunk-BCBXQC7J.js → chunk-E7SVZ7RF.js} +1 -1
  18. package/dist/chunk-E7SVZ7RF.js.map +1 -0
  19. package/dist/{chunk-NQH4G7BI.js → chunk-JDRY7HK5.js} +6 -9
  20. package/dist/chunk-JDRY7HK5.js.map +1 -0
  21. package/dist/{chunk-YFUBD2XB.js → chunk-RZQSEDKI.js} +6 -9
  22. package/dist/chunk-RZQSEDKI.js.map +1 -0
  23. package/dist/{chunk-A7VRCCNS.js → chunk-WSLFHX5X.js} +3 -3
  24. package/dist/chunk-WSLFHX5X.js.map +1 -0
  25. package/dist/{config-KT3PIL52.js → config-PUINDZON.js} +3 -3
  26. package/dist/{data-safety-AFMD6MYI.js → data-safety-46VY64OO.js} +12 -4
  27. package/dist/data-safety-46VY64OO.js.map +1 -0
  28. package/dist/{device-tiers-AQAMUQXI.js → device-tiers-MNZYMG3Y.js} +2 -2
  29. package/dist/device-tiers-MNZYMG3Y.js.map +1 -0
  30. package/dist/{diff-6EO4ID6W.js → diff-OBSHUSTL.js} +2 -2
  31. package/dist/diff-OBSHUSTL.js.map +1 -0
  32. package/dist/{docs-GMFN6V4K.js → docs-GP6AEX4N.js} +8 -4
  33. package/dist/docs-GP6AEX4N.js.map +1 -0
  34. package/dist/{doctor-GNI44SIP.js → doctor-T3QFYBRV.js} +5 -5
  35. package/dist/doctor-T3QFYBRV.js.map +1 -0
  36. package/dist/{external-transactions-LCZALS3V.js → external-transactions-JL3G4IG5.js} +11 -5
  37. package/dist/external-transactions-JL3G4IG5.js.map +1 -0
  38. package/dist/{feedback-XVTGMIBB.js → feedback-AULXQLJ7.js} +3 -3
  39. package/dist/feedback-AULXQLJ7.js.map +1 -0
  40. package/dist/{games-ZSNGEI7A.js → games-SVFN2YIS.js} +2 -2
  41. package/dist/games-SVFN2YIS.js.map +1 -0
  42. package/dist/{generated-apks-RX2IUWSF.js → generated-apks-TC33S2YN.js} +2 -2
  43. package/dist/generated-apks-TC33S2YN.js.map +1 -0
  44. package/dist/{grants-EBPECI26.js → grants-UHNBPIFD.js} +10 -3
  45. package/dist/grants-UHNBPIFD.js.map +1 -0
  46. package/dist/{iap-OUI5YYN4.js → iap-ETOL7OAC.js} +4 -4
  47. package/dist/iap-ETOL7OAC.js.map +1 -0
  48. package/dist/index.js +1 -1
  49. package/dist/{init-WSTQTJOD.js → init-6CCSVJC2.js} +7 -3
  50. package/dist/init-6CCSVJC2.js.map +1 -0
  51. package/dist/{install-skills-JKPYZHYS.js → install-skills-S342NJ7T.js} +7 -3
  52. package/dist/{install-skills-JKPYZHYS.js.map → install-skills-S342NJ7T.js.map} +1 -1
  53. package/dist/{internal-sharing-ONNIWIAT.js → internal-sharing-KW6YENDG.js} +2 -2
  54. package/dist/internal-sharing-KW6YENDG.js.map +1 -0
  55. package/dist/{listings-LNX6MQYN.js → listings-MOHHHNE6.js} +27 -7
  56. package/dist/listings-MOHHHNE6.js.map +1 -0
  57. package/dist/one-time-products-Y5RNIPV2.js +472 -0
  58. package/dist/one-time-products-Y5RNIPV2.js.map +1 -0
  59. package/dist/{preflight-W3JAJ4GO.js → preflight-KIWZPFTX.js} +4 -13
  60. package/dist/preflight-KIWZPFTX.js.map +1 -0
  61. package/dist/{pricing-JJZFICFL.js → pricing-HYQRXKNO.js} +3 -3
  62. package/dist/pricing-HYQRXKNO.js.map +1 -0
  63. package/dist/{prompt-GXC2JSLA.js → prompt-HJXNXXAR.js} +2 -2
  64. package/dist/{publish-P5KIGSLI.js → publish-26SSZ2W3.js} +11 -5
  65. package/dist/publish-26SSZ2W3.js.map +1 -0
  66. package/dist/{purchases-UBFLNYZC.js → purchases-AHWGLW6V.js} +35 -32
  67. package/dist/purchases-AHWGLW6V.js.map +1 -0
  68. package/dist/{quickstart-Z5Y3FYJU.js → quickstart-FOWM3OKT.js} +7 -2
  69. package/dist/quickstart-FOWM3OKT.js.map +1 -0
  70. package/dist/{recovery-YE3Z7NIN.js → recovery-B7DZQ6XG.js} +28 -12
  71. package/dist/recovery-B7DZQ6XG.js.map +1 -0
  72. package/dist/{releases-LUAHKIMY.js → releases-XY57V22L.js} +33 -8
  73. package/dist/releases-XY57V22L.js.map +1 -0
  74. package/dist/{reviews-YCBBM656.js → reviews-P4M6BEJI.js} +4 -6
  75. package/dist/reviews-P4M6BEJI.js.map +1 -0
  76. package/dist/{rtdn-LID2B7XZ.js → rtdn-YII4H6SD.js} +29 -21
  77. package/dist/rtdn-YII4H6SD.js.map +1 -0
  78. package/dist/{status-3HXBBXG6.js → status-32AJ7A6O.js} +13 -32
  79. package/dist/status-32AJ7A6O.js.map +1 -0
  80. package/dist/{subscriptions-LURZFPGJ.js → subscriptions-GTVJB4HX.js} +49 -12
  81. package/dist/subscriptions-GTVJB4HX.js.map +1 -0
  82. package/dist/system-apks-L6M7QYB3.js +111 -0
  83. package/dist/system-apks-L6M7QYB3.js.map +1 -0
  84. package/dist/{testers-6CQL4KQV.js → testers-QUWZHO6M.js} +25 -7
  85. package/dist/testers-QUWZHO6M.js.map +1 -0
  86. package/dist/{tracks-I4QZNZ3M.js → tracks-RH3RKVFB.js} +9 -3
  87. package/dist/{tracks-I4QZNZ3M.js.map → tracks-RH3RKVFB.js.map} +1 -1
  88. package/dist/{train-MDD2EBHS.js → train-D2NKUW3M.js} +3 -3
  89. package/dist/train-D2NKUW3M.js.map +1 -0
  90. package/dist/{update-QPPKXWI5.js → update-73YOR4GP.js} +8 -11
  91. package/dist/{update-QPPKXWI5.js.map → update-73YOR4GP.js.map} +1 -1
  92. package/dist/{users-UKG7VIQH.js → users-FOMAT7DY.js} +2 -2
  93. package/dist/{validate-QIYSA3N7.js → validate-RHWEZYD2.js} +6 -2
  94. package/dist/validate-RHWEZYD2.js.map +1 -0
  95. package/dist/{verify-UUQNQMPG.js → verify-H4ZUVHMZ.js} +5 -13
  96. package/dist/verify-H4ZUVHMZ.js.map +1 -0
  97. package/dist/{version-KUWLAZGT.js → version-RXLEX62V.js} +3 -3
  98. package/dist/{vitals-PJEQUUAK.js → vitals-PRBPNMVC.js} +26 -8
  99. package/dist/vitals-PRBPNMVC.js.map +1 -0
  100. package/package.json +5 -5
  101. package/dist/anomalies-V3AFS4LD.js.map +0 -1
  102. package/dist/auth-BA4FE2PO.js.map +0 -1
  103. package/dist/bundle-F7MUVC5J.js.map +0 -1
  104. package/dist/cache-XKPLZYEB.js.map +0 -1
  105. package/dist/chunk-A7VRCCNS.js.map +0 -1
  106. package/dist/chunk-BCBXQC7J.js.map +0 -1
  107. package/dist/chunk-GQVZ2VCT.js.map +0 -1
  108. package/dist/chunk-NQH4G7BI.js.map +0 -1
  109. package/dist/chunk-SLNJEAMK.js.map +0 -1
  110. package/dist/chunk-YFUBD2XB.js.map +0 -1
  111. package/dist/data-safety-AFMD6MYI.js.map +0 -1
  112. package/dist/device-tiers-AQAMUQXI.js.map +0 -1
  113. package/dist/diff-6EO4ID6W.js.map +0 -1
  114. package/dist/docs-GMFN6V4K.js.map +0 -1
  115. package/dist/doctor-GNI44SIP.js.map +0 -1
  116. package/dist/external-transactions-LCZALS3V.js.map +0 -1
  117. package/dist/feedback-XVTGMIBB.js.map +0 -1
  118. package/dist/games-ZSNGEI7A.js.map +0 -1
  119. package/dist/generated-apks-RX2IUWSF.js.map +0 -1
  120. package/dist/grants-EBPECI26.js.map +0 -1
  121. package/dist/iap-OUI5YYN4.js.map +0 -1
  122. package/dist/init-WSTQTJOD.js.map +0 -1
  123. package/dist/internal-sharing-ONNIWIAT.js.map +0 -1
  124. package/dist/listings-LNX6MQYN.js.map +0 -1
  125. package/dist/one-time-products-MGZTU7OM.js +0 -254
  126. package/dist/one-time-products-MGZTU7OM.js.map +0 -1
  127. package/dist/preflight-W3JAJ4GO.js.map +0 -1
  128. package/dist/pricing-JJZFICFL.js.map +0 -1
  129. package/dist/publish-P5KIGSLI.js.map +0 -1
  130. package/dist/purchases-UBFLNYZC.js.map +0 -1
  131. package/dist/quickstart-Z5Y3FYJU.js.map +0 -1
  132. package/dist/recovery-YE3Z7NIN.js.map +0 -1
  133. package/dist/releases-LUAHKIMY.js.map +0 -1
  134. package/dist/reviews-YCBBM656.js.map +0 -1
  135. package/dist/rtdn-LID2B7XZ.js.map +0 -1
  136. package/dist/status-3HXBBXG6.js.map +0 -1
  137. package/dist/subscriptions-LURZFPGJ.js.map +0 -1
  138. package/dist/testers-6CQL4KQV.js.map +0 -1
  139. package/dist/train-MDD2EBHS.js.map +0 -1
  140. package/dist/validate-QIYSA3N7.js.map +0 -1
  141. package/dist/verify-UUQNQMPG.js.map +0 -1
  142. package/dist/vitals-PJEQUUAK.js.map +0 -1
  143. /package/dist/{apps-4GP3FD7O.js.map → apps-WPUQOQLL.js.map} +0 -0
  144. /package/dist/{audit-VTWXTXC6.js.map → audit-M7GYID74.js.map} +0 -0
  145. /package/dist/{config-KT3PIL52.js.map → config-PUINDZON.js.map} +0 -0
  146. /package/dist/{prompt-GXC2JSLA.js.map → prompt-HJXNXXAR.js.map} +0 -0
  147. /package/dist/{users-UKG7VIQH.js.map → users-FOMAT7DY.js.map} +0 -0
  148. /package/dist/{version-KUWLAZGT.js.map → version-RXLEX62V.js.map} +0 -0
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Ship Android apps from your terminal.** The complete CLI for the Google Play Developer API.
4
4
 
5
- 209 API endpoints. No Ruby. No browser. No ceremony.
5
+ 215 API endpoints. No Ruby. No browser. No ceremony.
6
6
 
7
7
  ```bash
8
8
  npm install -g @gpc-cli/cli
@@ -23,15 +23,15 @@ gpc doctor # 20 setup checks
23
23
 
24
24
  ## Why this over Fastlane?
25
25
 
26
- | | **GPC** | Fastlane supply |
27
- | ----------------- | ----------------- | ----------------- |
28
- | API coverage | **209 endpoints** | ~20 |
29
- | Runtime | Node.js or binary | Ruby + Bundler |
30
- | Cold start | <500ms | 2-3s |
31
- | Reviews & Vitals | Yes | No |
32
- | Subscriptions | Yes | No |
33
- | Preflight scanner | 9 offline checks | No |
34
- | CI/CD native | JSON + exit codes | Partial |
26
+ | | **GPC** | Fastlane supply |
27
+ | ----------------- | ----------------- | --------------- |
28
+ | API coverage | **215 endpoints** | ~20 |
29
+ | Runtime | Node.js or binary | Ruby + Bundler |
30
+ | Cold start | <500ms | 2-3s |
31
+ | Reviews & Vitals | Yes | No |
32
+ | Subscriptions | Yes | No |
33
+ | Preflight scanner | 9 offline checks | No |
34
+ | CI/CD native | JSON + exit codes | Partial |
35
35
 
36
36
  [Migration guide](https://yasserstudio.github.io/gpc/migration/from-fastlane) with one-to-one command mapping.
37
37
 
@@ -69,14 +69,14 @@ curl -fsSL https://raw.githubusercontent.com/yasserstudio/gpc/main/scripts/insta
69
69
 
70
70
  ## Related packages
71
71
 
72
- | Package | What it does |
73
- | ------- | ------------ |
74
- | [@gpc-cli/api](https://www.npmjs.com/package/@gpc-cli/api) | Typed Google Play API v3 client (standalone SDK) |
75
- | [@gpc-cli/auth](https://www.npmjs.com/package/@gpc-cli/auth) | Authentication (service account, OAuth, ADC) |
76
- | [@gpc-cli/core](https://www.npmjs.com/package/@gpc-cli/core) | Business logic and orchestration |
77
- | [@gpc-cli/config](https://www.npmjs.com/package/@gpc-cli/config) | Configuration and profiles |
78
- | [@gpc-cli/plugin-sdk](https://www.npmjs.com/package/@gpc-cli/plugin-sdk) | Plugin interface |
79
- | [@gpc-cli/plugin-ci](https://www.npmjs.com/package/@gpc-cli/plugin-ci) | CI/CD helpers |
72
+ | Package | What it does |
73
+ | ------------------------------------------------------------------------ | ------------------------------------------------ |
74
+ | [@gpc-cli/api](https://www.npmjs.com/package/@gpc-cli/api) | Typed Google Play API v3 client (standalone SDK) |
75
+ | [@gpc-cli/auth](https://www.npmjs.com/package/@gpc-cli/auth) | Authentication (service account, OAuth, ADC) |
76
+ | [@gpc-cli/core](https://www.npmjs.com/package/@gpc-cli/core) | Business logic and orchestration |
77
+ | [@gpc-cli/config](https://www.npmjs.com/package/@gpc-cli/config) | Configuration and profiles |
78
+ | [@gpc-cli/plugin-sdk](https://www.npmjs.com/package/@gpc-cli/plugin-sdk) | Plugin interface |
79
+ | [@gpc-cli/plugin-ci](https://www.npmjs.com/package/@gpc-cli/plugin-ci) | CI/CD helpers |
80
80
 
81
81
  ## Links
82
82
 
@@ -85,7 +85,7 @@ curl -fsSL https://raw.githubusercontent.com/yasserstudio/gpc/main/scripts/insta
85
85
  - [Commands reference](https://yasserstudio.github.io/gpc/commands/)
86
86
  - [CI/CD recipes](https://yasserstudio.github.io/gpc/ci-cd/)
87
87
 
88
- Free to use. 1,869 tests. 90%+ coverage. Every write operation supports `--dry-run`.
88
+ Free to use. 1,874 tests. 90%+ coverage. Every write operation supports `--dry-run`.
89
89
 
90
90
  ## License
91
91
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  resolvePackageName
4
- } from "./chunk-NQH4G7BI.js";
4
+ } from "./chunk-JDRY7HK5.js";
5
5
  import {
6
6
  yellow
7
7
  } from "./chunk-FAN4ZITI.js";
@@ -31,10 +31,19 @@ function registerAnomaliesCommands(program) {
31
31
  } catch (err) {
32
32
  if (err instanceof PlayApiError && err.statusCode === 403) {
33
33
  if (format === "json") {
34
- console.log(formatOutput({ anomalies: [], message: "Reporting API not enabled or insufficient permissions" }, format));
34
+ console.log(
35
+ formatOutput(
36
+ { anomalies: [], message: "Reporting API not enabled or insufficient permissions" },
37
+ format
38
+ )
39
+ );
35
40
  } else {
36
- console.log(`${yellow("\u26A0")} No anomaly data available. The Reporting API may not be enabled for this project.`);
37
- console.log(` Enable it at: https://console.cloud.google.com/apis/library/playdeveloperreporting.googleapis.com`);
41
+ console.log(
42
+ `${yellow("\u26A0")} No anomaly data available. The Reporting API may not be enabled for this project.`
43
+ );
44
+ console.log(
45
+ ` Enable it at: https://console.cloud.google.com/apis/library/playdeveloperreporting.googleapis.com`
46
+ );
38
47
  }
39
48
  return;
40
49
  }
@@ -63,4 +72,4 @@ function registerAnomaliesCommands(program) {
63
72
  export {
64
73
  registerAnomaliesCommands
65
74
  };
66
- //# sourceMappingURL=anomalies-V3AFS4LD.js.map
75
+ //# sourceMappingURL=anomalies-I5P6QQAZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/anomalies.ts"],"sourcesContent":["import { resolvePackageName } from \"../resolve.js\";\nimport type { Command } from \"commander\";\nimport type { GpcConfig } from \"@gpc-cli/config\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createReportingClient, PlayApiError } from \"@gpc-cli/api\";\nimport { getVitalsAnomalies, formatOutput } from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { yellow } from \"../colors.js\";\n\nasync function getReportingClient(config: GpcConfig) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createReportingClient({ auth });\n}\n\nexport function registerAnomaliesCommands(program: Command): void {\n const anomalies = program.command(\"anomalies\").description(\"Detect and list vitals anomalies\");\n\n anomalies\n .command(\"list\")\n .description(\"List detected vitals anomalies\")\n .action(async () => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const reporting = await getReportingClient(config);\n const format = getOutputFormat(program, config);\n\n let result;\n try {\n result = await getVitalsAnomalies(reporting, packageName);\n } catch (err) {\n if (err instanceof PlayApiError && err.statusCode === 403) {\n if (format === \"json\") {\n console.log(\n formatOutput(\n { anomalies: [], message: \"Reporting API not enabled or insufficient permissions\" },\n format,\n ),\n );\n } else {\n console.log(\n `${yellow(\"⚠\")} No anomaly data available. The Reporting API may not be enabled for this project.`,\n );\n console.log(\n ` Enable it at: https://console.cloud.google.com/apis/library/playdeveloperreporting.googleapis.com`,\n );\n }\n return;\n }\n throw err;\n }\n const items = (result as unknown as Record<string, unknown>)[\"anomalies\"] as\n | unknown[]\n | undefined;\n\n if (format !== \"json\") {\n if (!items || items.length === 0) {\n console.log(\"No anomalies detected.\");\n return;\n }\n const rows = items.map((item) => {\n const a = item as Record<string, unknown>;\n return {\n name: String(a[\"name\"] ?? \"-\"),\n metricSet: String(a[\"metricSet\"] ?? \"-\"),\n aggregationPeriod: String(a[\"aggregationPeriod\"] ?? \"-\"),\n };\n });\n console.log(formatOutput(rows, format));\n } else {\n console.log(formatOutput(result, format));\n }\n });\n}\n"],"mappings":";;;;;;;;;;;;AAGA,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB,oBAAoB;AACpD,SAAS,oBAAoB,oBAAoB;AAIjD,eAAe,mBAAmB,QAAmB;AACnD,QAAM,OAAO,MAAM,YAAY,EAAE,oBAAoB,OAAO,MAAM,eAAe,CAAC;AAClF,SAAO,sBAAsB,EAAE,KAAK,CAAC;AACvC;AAEO,SAAS,0BAA0B,SAAwB;AAChE,QAAM,YAAY,QAAQ,QAAQ,WAAW,EAAE,YAAY,kCAAkC;AAE7F,YACG,QAAQ,MAAM,EACd,YAAY,gCAAgC,EAC5C,OAAO,YAAY;AAClB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AACpE,UAAM,YAAY,MAAM,mBAAmB,MAAM;AACjD,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAE9C,QAAI;AACJ,QAAI;AACF,eAAS,MAAM,mBAAmB,WAAW,WAAW;AAAA,IAC1D,SAAS,KAAK;AACZ,UAAI,eAAe,gBAAgB,IAAI,eAAe,KAAK;AACzD,YAAI,WAAW,QAAQ;AACrB,kBAAQ;AAAA,YACN;AAAA,cACE,EAAE,WAAW,CAAC,GAAG,SAAS,wDAAwD;AAAA,cAClF;AAAA,YACF;AAAA,UACF;AAAA,QACF,OAAO;AACL,kBAAQ;AAAA,YACN,GAAG,OAAO,QAAG,CAAC;AAAA,UAChB;AACA,kBAAQ;AAAA,YACN;AAAA,UACF;AAAA,QACF;AACA;AAAA,MACF;AACA,YAAM;AAAA,IACR;AACA,UAAM,QAAS,OAA8C,WAAW;AAIxE,QAAI,WAAW,QAAQ;AACrB,UAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,gBAAQ,IAAI,wBAAwB;AACpC;AAAA,MACF;AACA,YAAM,OAAO,MAAM,IAAI,CAAC,SAAS;AAC/B,cAAM,IAAI;AACV,eAAO;AAAA,UACL,MAAM,OAAO,EAAE,MAAM,KAAK,GAAG;AAAA,UAC7B,WAAW,OAAO,EAAE,WAAW,KAAK,GAAG;AAAA,UACvC,mBAAmB,OAAO,EAAE,mBAAmB,KAAK,GAAG;AAAA,QACzD;AAAA,MACF,CAAC;AACD,cAAQ,IAAI,aAAa,MAAM,MAAM,CAAC;AAAA,IACxC,OAAO;AACL,cAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,IAC1C;AAAA,EACF,CAAC;AACL;","names":[]}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  buildCommitOptions
4
- } from "./chunk-A7VRCCNS.js";
4
+ } from "./chunk-WSLFHX5X.js";
5
5
  import {
6
6
  isDryRun,
7
7
  printDryRun
@@ -101,4 +101,4 @@ function registerAppsCommands(program) {
101
101
  export {
102
102
  registerAppsCommands
103
103
  };
104
- //# sourceMappingURL=apps-4GP3FD7O.js.map
104
+ //# sourceMappingURL=apps-WPUQOQLL.js.map
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-ELXAK7GI.js";
8
8
  import {
9
9
  requireConfirm
10
- } from "./chunk-YFUBD2XB.js";
10
+ } from "./chunk-RZQSEDKI.js";
11
11
 
12
12
  // src/commands/audit.ts
13
13
  import { loadConfig } from "@gpc-cli/config";
@@ -122,4 +122,4 @@ function registerAuditCommands(program) {
122
122
  export {
123
123
  registerAuditCommands
124
124
  };
125
- //# sourceMappingURL=audit-VTWXTXC6.js.map
125
+ //# sourceMappingURL=audit-M7GYID74.js.map
@@ -34,7 +34,9 @@ async function runLoginWizard(program) {
34
34
  const rl = createInterface({ input: process.stdin, output: process.stdout });
35
35
  try {
36
36
  console.log("\nGPC Authentication Setup");
37
- console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
37
+ console.log(
38
+ "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
39
+ );
38
40
  console.log("\nAuthentication methods:");
39
41
  console.log(" 1. Service account key file (recommended)");
40
42
  console.log(" 2. Application Default Credentials (ADC)");
@@ -258,7 +260,9 @@ function registerAuthCommands(program) {
258
260
  console.log("\nStep 3: Grant roles");
259
261
  console.log(" No GCP roles needed \u2014 permissions are managed in Google Play Console.");
260
262
  console.log("\nStep 4: Download the JSON key");
261
- console.log(" \u2022 Click your new service account \u2192 Keys \u2192 Add Key \u2192 Create new key \u2192 JSON");
263
+ console.log(
264
+ " \u2022 Click your new service account \u2192 Keys \u2192 Add Key \u2192 Create new key \u2192 JSON"
265
+ );
262
266
  console.log(" \u2022 Save as: ~/gpc-service-account.json");
263
267
  console.log("\nStep 5: Add to Google Play Console");
264
268
  console.log(" https://play.google.com/console/developers");
@@ -319,7 +323,9 @@ Step 6: Authenticating...`);
319
323
  await setConfigValue2("auth.serviceAccount", absPath);
320
324
  console.log(`\u2713 Authenticated and saved to config`);
321
325
  } catch (err) {
322
- console.error(`\u2717 Authentication failed: ${err instanceof Error ? err.message : String(err)}`);
326
+ console.error(
327
+ `\u2717 Authentication failed: ${err instanceof Error ? err.message : String(err)}`
328
+ );
323
329
  console.log(`
324
330
  Try manually: gpc auth login --service-account ${absPath}`);
325
331
  return;
@@ -349,4 +355,4 @@ Step 7: Verifying setup...`);
349
355
  export {
350
356
  registerAuthCommands
351
357
  };
352
- //# sourceMappingURL=auth-BA4FE2PO.js.map
358
+ //# sourceMappingURL=auth-4DRT7ZH2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/auth.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { createInterface } from \"node:readline\";\nimport { access } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { resolveAuth, loadServiceAccountKey, clearTokenCache, AuthError } from \"@gpc-cli/auth\";\nimport { loadConfig, getCacheDir, deleteConfigValue, setConfigValue } from \"@gpc-cli/config\";\nimport { formatOutput } from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nasync function askQuestion(\n rl: ReturnType<typeof createInterface>,\n question: string,\n): Promise<string> {\n return new Promise((resolve) => {\n rl.question(question, (answer) => resolve(answer.trim()));\n });\n}\n\n/** Resolve a path to absolute (prevents CWD-dependent config). */\nfunction toAbsolutePath(pathStr: string): string {\n return resolve(pathStr);\n}\n\n/** Verify that the saved credentials can acquire a token. */\nasync function verifyToken(\n serviceAccountPath?: string,\n): Promise<{ email: string; ok: boolean; error?: string }> {\n try {\n const client = await resolveAuth({ serviceAccountPath });\n const email = client.getClientEmail();\n await client.getAccessToken();\n return { email, ok: true };\n } catch (err) {\n const email = \"unknown\";\n const msg = err instanceof Error ? err.message : String(err);\n return { email, ok: false, error: msg };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Interactive login wizard\n// ---------------------------------------------------------------------------\n\nasync function runLoginWizard(program: Command): Promise<void> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n\n try {\n console.log(\"\\nGPC Authentication Setup\");\n console.log(\n \"\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\",\n );\n\n // Step 1: auth method\n console.log(\"\\nAuthentication methods:\");\n console.log(\" 1. Service account key file (recommended)\");\n console.log(\" 2. Application Default Credentials (ADC)\");\n const method = await askQuestion(rl, \"\\nSelect method [1]: \");\n const useAdc = method === \"2\";\n\n if (useAdc) {\n const client = await resolveAuth();\n const email = client.getClientEmail();\n // Verify token works\n await client.getAccessToken();\n outputLoginResult(program, { account: email, method: \"adc\", verified: true });\n return;\n }\n\n // Step 2: credentials path with validation loop\n let saPath = \"\";\n while (!saPath) {\n const input = await askQuestion(rl, \"\\nPath to service account JSON key: \");\n if (!input) {\n console.log(\" Path is required.\");\n continue;\n }\n try {\n await access(input);\n saPath = toAbsolutePath(input);\n } catch {\n console.log(` File not found: ${input}`);\n }\n }\n\n // Step 3: optional profile name\n const profileName = await askQuestion(rl, \"\\nProfile name (optional, press Enter to skip): \");\n\n // Step 4: default package name\n const packageName = await askQuestion(\n rl,\n \"Default package name (optional, e.g. com.example.app): \",\n );\n\n // Apply settings\n const key = await loadServiceAccountKey(saPath);\n\n if (profileName) {\n const { setProfileConfig } = await import(\"@gpc-cli/config\");\n await setProfileConfig(profileName, {\n auth: { serviceAccount: saPath },\n ...(packageName && { app: packageName }),\n });\n } else {\n await setConfigValue(\"auth.serviceAccount\", saPath);\n if (packageName) await setConfigValue(\"app\", packageName);\n }\n\n // Verify token\n const verification = await verifyToken(saPath);\n\n outputLoginResult(program, {\n account: key.client_email,\n project: key.project_id,\n method: \"service-account\",\n profile: profileName || undefined,\n verified: verification.ok,\n verifyError: verification.error,\n });\n } finally {\n rl.close();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Structured login output\n// ---------------------------------------------------------------------------\n\ninterface LoginResult {\n account: string;\n project?: string;\n method: string;\n profile?: string;\n verified: boolean;\n verifyError?: string;\n}\n\nfunction outputLoginResult(program: Command, result: LoginResult): void {\n const parentOpts = program.opts() ?? {};\n const jsonMode = !!(parentOpts[\"json\"] || parentOpts[\"output\"] === \"json\");\n\n if (jsonMode) {\n console.log(\n JSON.stringify({\n success: true,\n account: result.account,\n project: result.project,\n method: result.method,\n profile: result.profile,\n verified: result.verified,\n ...(result.verifyError && { verifyError: result.verifyError }),\n }),\n );\n return;\n }\n\n if (result.profile) {\n console.log(`\\nProfile \"${result.profile}\" configured with ${result.account}`);\n } else if (result.method === \"adc\") {\n console.log(`\\nAuthenticated via Application Default Credentials`);\n console.log(`Account: ${result.account}`);\n } else {\n console.log(`\\nAuthenticated as ${result.account}`);\n }\n if (result.project) console.log(`Project: ${result.project}`);\n\n if (result.verified) {\n console.log(\"Verified: token acquired successfully\");\n } else if (result.verifyError) {\n console.log(`Warning: token verification failed: ${result.verifyError}`);\n console.log(\"Credentials saved, but check your setup with: gpc doctor\");\n }\n\n if (!result.verifyError) {\n console.log(\"\\nRun 'gpc doctor' to verify your full setup.\");\n }\n}\n\n// ---------------------------------------------------------------------------\n// Command registration\n// ---------------------------------------------------------------------------\n\nexport function registerAuthCommands(program: Command): void {\n const auth = program.command(\"auth\").description(\"Manage authentication\");\n\n auth\n .command(\"login\")\n .description(\"Authenticate with Google Play Developer API\")\n .option(\"--service-account <path>\", \"Path to service account JSON key file\")\n .option(\"--adc\", \"Use Application Default Credentials\")\n .option(\"--profile <name>\", \"Store credentials under a named profile\")\n .action(async (options: { serviceAccount?: string; adc?: boolean; profile?: string }) => {\n if (options.serviceAccount) {\n const absolutePath = toAbsolutePath(options.serviceAccount);\n const key = await loadServiceAccountKey(absolutePath);\n\n if (options.profile) {\n const { setProfileConfig } = await import(\"@gpc-cli/config\");\n await setProfileConfig(options.profile, {\n auth: { serviceAccount: absolutePath },\n });\n } else {\n await setConfigValue(\"auth.serviceAccount\", absolutePath);\n }\n\n // Verify token works\n const verification = await verifyToken(absolutePath);\n\n outputLoginResult(program, {\n account: key.client_email,\n project: key.project_id,\n method: \"service-account\",\n profile: options.profile,\n verified: verification.ok,\n verifyError: verification.error,\n });\n } else if (options.adc) {\n const client = await resolveAuth();\n const email = client.getClientEmail();\n await client.getAccessToken();\n outputLoginResult(program, { account: email, method: \"adc\", verified: true });\n } else {\n // Interactive wizard when no flags provided and in interactive mode\n const opts = program.opts();\n const interactive =\n opts[\"interactive\"] !== false && opts[\"ci\"] !== true && process.stdin.isTTY;\n if (interactive) {\n await runLoginWizard(program);\n } else {\n console.log(\"Usage: gpc auth login --service-account <path>\");\n console.log(\"\");\n console.log(\"Authentication methods:\");\n console.log(\" --service-account <path> Service account JSON key file\");\n console.log(\" --adc Application Default Credentials\");\n console.log(\"\");\n console.log(\"Options:\");\n console.log(\" --profile <name> Store under a named profile\");\n }\n }\n });\n\n auth\n .command(\"status\")\n .description(\"Show current authentication status\")\n .action(async () => {\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n try {\n const client = await resolveAuth({\n serviceAccountPath: config.auth?.serviceAccount,\n cachePath: getCacheDir(),\n });\n const data = {\n authenticated: true,\n account: client.getClientEmail(),\n project: client.getProjectId(),\n ...(config.profile && { profile: config.profile }),\n };\n console.log(formatOutput(data, format));\n } catch (error) {\n if (error instanceof AuthError) {\n const data = {\n authenticated: false,\n error: error.message,\n suggestion: error.suggestion,\n };\n console.log(formatOutput(data, format));\n }\n throw error; // Let error handler set exit code 3\n }\n });\n\n auth\n .command(\"logout\")\n .description(\"Clear stored credentials and token cache\")\n .option(\"--profile <name>\", \"Clear credentials for a specific profile\")\n .action(async (options: { profile?: string }) => {\n if (options.profile) {\n const { deleteProfile } = await import(\"@gpc-cli/config\");\n const deleted = await deleteProfile(options.profile);\n if (deleted) {\n console.log(`Profile \"${options.profile}\" removed.`);\n } else {\n console.log(`Profile \"${options.profile}\" not found.`);\n }\n } else {\n await deleteConfigValue(\"auth.serviceAccount\");\n console.log(\"Credentials cleared.\");\n }\n await clearTokenCache(getCacheDir());\n console.log(\"Token cache cleared.\");\n });\n\n auth\n .command(\"whoami\")\n .description(\"Show current authenticated identity\")\n .action(async () => {\n const config = await loadConfig();\n const client = await resolveAuth({\n serviceAccountPath: config.auth?.serviceAccount,\n cachePath: getCacheDir(),\n });\n console.log(client.getClientEmail());\n });\n\n auth\n .command(\"switch <profile>\")\n .description(\"Switch to a named profile\")\n .action(async (profile: string) => {\n // loadConfig with the profile will throw ConfigError if profile doesn't exist\n const config = await loadConfig({ profile });\n await setConfigValue(\"profile\", profile);\n console.log(`Switched to profile \"${profile}\"`);\n if (config.auth?.serviceAccount) {\n console.log(`Service account: ${config.auth.serviceAccount}`);\n }\n });\n\n auth\n .command(\"token\")\n .description(\"Print the current access token (useful for manual API calls)\")\n .action(async () => {\n const config = await loadConfig();\n const authClient = await resolveAuth({\n serviceAccountPath: config.auth?.serviceAccount,\n cachePath: getCacheDir(),\n });\n const token = await authClient.getAccessToken();\n console.log(token);\n });\n\n auth\n .command(\"setup-gcp\")\n .description(\"Step-by-step guide to create a Google Cloud service account\")\n .option(\"--key <path>\", \"Path to an already-downloaded service account JSON key\")\n .action(async (options: { key?: string }) => {\n const { existsSync, readFileSync } = await import(\"node:fs\");\n const { resolve } = await import(\"node:path\");\n\n console.log(\"\\nGPC \\u2014 Google Cloud Service Account Setup\");\n console.log(\"\\u2550\".repeat(50));\n\n // If key path provided or user already has one, skip to validation\n let keyPath = options.key;\n\n if (!keyPath) {\n console.log(\"\\nStep 1: Open the Google Cloud Console\");\n console.log(\" https://console.cloud.google.com/iam-admin/serviceaccounts\");\n console.log(\"\\nStep 2: Create a service account\");\n console.log(\" \\u2022 Click 'Create Service Account'\");\n console.log(\" \\u2022 Name it: gpc-deploy (or any name you like)\");\n console.log(\" \\u2022 Description: GPC Google Play Console access\");\n console.log(\"\\nStep 3: Grant roles\");\n console.log(\" No GCP roles needed \\u2014 permissions are managed in Google Play Console.\");\n console.log(\"\\nStep 4: Download the JSON key\");\n console.log(\n \" \\u2022 Click your new service account \\u2192 Keys \\u2192 Add Key \\u2192 Create new key \\u2192 JSON\",\n );\n console.log(\" \\u2022 Save as: ~/gpc-service-account.json\");\n console.log(\"\\nStep 5: Add to Google Play Console\");\n console.log(\" https://play.google.com/console/developers\");\n console.log(\" \\u2022 Users and Permissions \\u2192 Invite new users\");\n console.log(\" \\u2022 Paste the service account email (ends with @...gserviceaccount.com)\");\n console.log(\" \\u2022 Grant: Release manager + View app info + Reply to reviews\");\n\n // Try to auto-detect a key file\n const commonPaths = [\n \"~/gpc-service-account.json\",\n \"./service-account.json\",\n \"./gpc-service-account.json\",\n \"~/.config/gpc/service-account.json\",\n ].map((p) => resolve(p.replace(\"~\", process.env[\"HOME\"] || \"\")));\n\n for (const p of commonPaths) {\n if (existsSync(p)) {\n console.log(`\\n\\u2713 Found key file: ${p}`);\n keyPath = p;\n break;\n }\n }\n\n if (!keyPath) {\n console.log(\"\\nOnce you've downloaded the key, run:\");\n console.log(\" gpc auth setup-gcp --key <path/to/key.json>\");\n console.log(\"\\nOr authenticate directly:\");\n console.log(\" gpc auth login --service-account <path/to/key.json>\");\n console.log(\"\\nSee full docs: https://yasserstudio.github.io/gpc/guide/authentication\");\n return;\n }\n }\n\n // Validate the key file\n const absPath = resolve(keyPath.replace(\"~\", process.env[\"HOME\"] || \"\"));\n if (!existsSync(absPath)) {\n console.error(`\\n\\u2717 File not found: ${absPath}`);\n return;\n }\n\n try {\n const content = JSON.parse(readFileSync(absPath, \"utf-8\"));\n if (content.type !== \"service_account\") {\n console.error(`\\n\\u2717 Not a service account key (type: ${content.type})`);\n return;\n }\n console.log(`\\n\\u2713 Valid service account key`);\n console.log(` Email: ${content.client_email}`);\n console.log(` Project: ${content.project_id}`);\n } catch {\n console.error(`\\n\\u2717 Invalid JSON file: ${absPath}`);\n return;\n }\n\n // Auto-login\n console.log(`\\nStep 6: Authenticating...`);\n try {\n const auth = await resolveAuth({ serviceAccountPath: absPath });\n await auth.getAccessToken();\n const { setConfigValue } = await import(\"@gpc-cli/config\");\n await setConfigValue(\"auth.serviceAccount\", absPath);\n console.log(`\\u2713 Authenticated and saved to config`);\n } catch (err) {\n console.error(\n `\\u2717 Authentication failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n console.log(`\\nTry manually: gpc auth login --service-account ${absPath}`);\n return;\n }\n\n // Auto-run doctor\n console.log(`\\nStep 7: Verifying setup...`);\n console.log(` Run: gpc doctor`);\n });\n\n auth\n .command(\"profiles\")\n .description(\"List configured profiles\")\n .action(async () => {\n const { listProfiles } = await import(\"@gpc-cli/config\");\n const config = await loadConfig();\n const profiles = await listProfiles();\n const format = getOutputFormat(program, config);\n\n if (profiles.length === 0) {\n console.log(\n \"No profiles configured. Use: gpc auth login --service-account <path> --profile <name>\",\n );\n return;\n }\n\n const data = profiles.map((name) => ({\n name,\n active: name === config.profile,\n }));\n console.log(formatOutput(data, format));\n });\n}\n"],"mappings":"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","names":["resolve","auth","setConfigValue"]}
package/dist/bin.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  createProgram,
4
4
  handleCliError,
5
5
  loadPlugins
6
- } from "./chunk-GQVZ2VCT.js";
6
+ } from "./chunk-6HIY4IGM.js";
7
7
  import {
8
8
  checkForUpdate,
9
9
  formatUpdateNotification
@@ -46,7 +46,7 @@ if (!_isJsonMode && !_isQuiet && !_isSetupCommand && !existsSync(getUserConfigPa
46
46
  }
47
47
  await setupNetworking();
48
48
  initAudit(getConfigDir());
49
- var currentVersion = "0.9.53";
49
+ var currentVersion = "0.9.54";
50
50
  var isUpdateCommand = process.argv[2] === "update";
51
51
  var updateCheckPromise = isUpdateCommand ? Promise.resolve(null) : checkForUpdate(currentVersion);
52
52
  if (process.argv.includes("--ci")) {
@@ -107,7 +107,9 @@ Top ${opts.top} files:`);
107
107
  if (opts.threshold !== void 0) {
108
108
  const thresholdBytes = opts.threshold * 1024 * 1024;
109
109
  if (analysis.totalCompressed > thresholdBytes) {
110
- const err = new Error(`Threshold breached: ${formatSize(analysis.totalCompressed)} > ${opts.threshold} MB`);
110
+ const err = new Error(
111
+ `Threshold breached: ${formatSize(analysis.totalCompressed)} > ${opts.threshold} MB`
112
+ );
111
113
  Object.assign(err, { code: "THRESHOLD_BREACH", exitCode: 6 });
112
114
  throw err;
113
115
  }
@@ -201,4 +203,4 @@ async function getConfig() {
201
203
  export {
202
204
  registerBundleCommands
203
205
  };
204
- //# sourceMappingURL=bundle-F7MUVC5J.js.map
206
+ //# sourceMappingURL=bundle-PFTE7XMU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/bundle.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport {\n analyzeBundle,\n compareBundles,\n topFiles,\n checkBundleSize,\n formatOutput,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\n\nfunction formatSize(bytes: number): string {\n const abs = Math.abs(bytes);\n const sign = bytes < 0 ? \"-\" : \"\";\n if (abs < 1024) return `${sign}${abs} B`;\n if (abs < 1024 * 1024) return `${sign}${(abs / 1024).toFixed(1)} KB`;\n return `${sign}${(abs / (1024 * 1024)).toFixed(2)} MB`;\n}\n\nfunction formatDelta(delta: number): string {\n const prefix = delta > 0 ? \"+\" : \"\";\n return `${prefix}${formatSize(delta)}`;\n}\n\nexport function registerBundleCommands(program: Command): void {\n const bundle = program.command(\"bundle\").description(\"Analyze app bundles and APKs\");\n\n bundle\n .command(\"analyze <file>\")\n .description(\"Analyze size breakdown of an AAB or APK\")\n .option(\"--threshold <mb>\", \"Fail if compressed size exceeds threshold (MB)\", parseFloat)\n .option(\"--top <n>\", \"Show top N largest files\", (v) => parseInt(v, 10))\n .option(\"--config <file>\", \"Check against .bundlesize.json thresholds\")\n .action(async (file: string, opts: { threshold?: number; top?: number; config?: string }) => {\n const format = getOutputFormat(program, await getConfig());\n\n const analysis = await analyzeBundle(file);\n\n if (format === \"json\") {\n console.log(formatOutput(analysis, format));\n } else if (format === \"markdown\") {\n const moduleRows = analysis.modules.map((m) => ({\n module: m.name,\n compressed: formatSize(m.compressedSize),\n uncompressed: formatSize(m.uncompressedSize),\n entries: m.entries,\n }));\n const categoryRows = analysis.categories.map((c) => ({\n category: c.name,\n compressed: formatSize(c.compressedSize),\n uncompressed: formatSize(c.uncompressedSize),\n entries: c.entries,\n }));\n console.log(`## Bundle Analysis: \\`${analysis.filePath}\\``);\n console.log();\n console.log(`| Property | Value |`);\n console.log(`| --- | --- |`);\n console.log(`| Type | ${analysis.fileType.toUpperCase()} |`);\n console.log(`| Total compressed | ${formatSize(analysis.totalCompressed)} |`);\n console.log(`| Total uncompressed | ${formatSize(analysis.totalUncompressed)} |`);\n console.log(`| Entries | ${analysis.entryCount} |`);\n console.log();\n console.log(`### Modules`);\n console.log();\n console.log(formatOutput(moduleRows, \"markdown\"));\n console.log();\n console.log(`### Categories`);\n console.log();\n console.log(formatOutput(categoryRows, \"markdown\"));\n } else {\n console.log(`\\nFile: ${analysis.filePath}`);\n console.log(`Type: ${analysis.fileType.toUpperCase()}`);\n console.log(`Total compressed: ${formatSize(analysis.totalCompressed)}`);\n console.log(`Total uncompressed: ${formatSize(analysis.totalUncompressed)}`);\n console.log(`Entries: ${analysis.entryCount}\\n`);\n\n // Modules table\n const moduleRows = analysis.modules.map((m) => ({\n module: m.name,\n compressed: formatSize(m.compressedSize),\n uncompressed: formatSize(m.uncompressedSize),\n entries: m.entries,\n }));\n console.log(\"Modules:\");\n console.log(formatOutput(moduleRows, \"table\"));\n\n // Categories table\n const categoryRows = analysis.categories.map((c) => ({\n category: c.name,\n compressed: formatSize(c.compressedSize),\n uncompressed: formatSize(c.uncompressedSize),\n entries: c.entries,\n }));\n console.log(\"\\nCategories:\");\n console.log(formatOutput(categoryRows, \"table\"));\n }\n\n // Top N files\n if (opts.top !== undefined) {\n const largest = topFiles(analysis, opts.top);\n const topRows = largest.map((e) => ({\n path: e.path,\n compressed: formatSize(e.compressedSize),\n uncompressed: formatSize(e.uncompressedSize),\n category: e.category,\n }));\n console.log(`\\nTop ${opts.top} files:`);\n console.log(formatOutput(topRows, format === \"json\" ? \"table\" : format));\n }\n\n // .bundlesize.json config check\n if (opts.config) {\n const check = await checkBundleSize(analysis, opts.config);\n if (!check.passed) {\n const violations = check.violations\n .map((v) => `${v.subject}: ${formatSize(v.actual)} > max ${formatSize(v.max)}`)\n .join(\"; \");\n const err = new Error(`Bundle size check failed: ${violations}`);\n Object.assign(err, { code: \"THRESHOLD_BREACH\", exitCode: 6 });\n throw err;\n }\n }\n\n // Legacy --threshold check\n if (opts.threshold !== undefined) {\n const thresholdBytes = opts.threshold * 1024 * 1024;\n if (analysis.totalCompressed > thresholdBytes) {\n const err = new Error(\n `Threshold breached: ${formatSize(analysis.totalCompressed)} > ${opts.threshold} MB`,\n );\n Object.assign(err, { code: \"THRESHOLD_BREACH\", exitCode: 6 });\n throw err;\n }\n }\n });\n\n bundle\n .command(\"compare <file1> <file2>\")\n .description(\"Compare size differences between two bundles or APKs\")\n .action(async (file1: string, file2: string) => {\n const format = getOutputFormat(program, await getConfig());\n\n const [before, after] = await Promise.all([analyzeBundle(file1), analyzeBundle(file2)]);\n const comparison = compareBundles(before, after);\n\n if (format === \"json\") {\n console.log(formatOutput(comparison, format));\n } else if (format === \"markdown\") {\n const sign = comparison.sizeDelta >= 0 ? \"+\" : \"\";\n const moduleRows = comparison.moduleDeltas\n .filter((m) => m.delta !== 0)\n .map((m) => ({\n module: m.module,\n before: formatSize(m.before),\n after: formatSize(m.after),\n delta: formatDelta(m.delta),\n }));\n const categoryRows = comparison.categoryDeltas\n .filter((c) => c.delta !== 0)\n .map((c) => ({\n category: c.category,\n before: formatSize(c.before),\n after: formatSize(c.after),\n delta: formatDelta(c.delta),\n }));\n console.log(`## Bundle Comparison`);\n console.log();\n console.log(`| | Path | Size |`);\n console.log(`| --- | --- | --- |`);\n console.log(\n `| Before | \\`${comparison.before.path}\\` | ${formatSize(comparison.before.totalCompressed)} |`,\n );\n console.log(\n `| After | \\`${comparison.after.path}\\` | ${formatSize(comparison.after.totalCompressed)} |`,\n );\n console.log(\n `| **Delta** | | **${sign}${formatSize(comparison.sizeDelta)} (${sign}${comparison.sizeDeltaPercent}%)** |`,\n );\n if (moduleRows.length > 0) {\n console.log();\n console.log(`### Module Changes`);\n console.log();\n console.log(formatOutput(moduleRows, \"markdown\"));\n }\n if (categoryRows.length > 0) {\n console.log();\n console.log(`### Category Changes`);\n console.log();\n console.log(formatOutput(categoryRows, \"markdown\"));\n }\n } else {\n const sign = comparison.sizeDelta >= 0 ? \"+\" : \"\";\n console.log(\n `\\nBefore: ${comparison.before.path} (${formatSize(comparison.before.totalCompressed)})`,\n );\n console.log(\n `After: ${comparison.after.path} (${formatSize(comparison.after.totalCompressed)})`,\n );\n console.log(\n `Delta: ${sign}${formatSize(comparison.sizeDelta)} (${sign}${comparison.sizeDeltaPercent}%)\\n`,\n );\n\n // Module deltas\n const moduleRows = comparison.moduleDeltas\n .filter((m) => m.delta !== 0)\n .map((m) => ({\n module: m.module,\n before: formatSize(m.before),\n after: formatSize(m.after),\n delta: formatDelta(m.delta),\n }));\n if (moduleRows.length > 0) {\n console.log(\"Module changes:\");\n console.log(formatOutput(moduleRows, \"table\"));\n }\n\n // Category deltas\n const categoryRows = comparison.categoryDeltas\n .filter((c) => c.delta !== 0)\n .map((c) => ({\n category: c.category,\n before: formatSize(c.before),\n after: formatSize(c.after),\n delta: formatDelta(c.delta),\n }));\n if (categoryRows.length > 0) {\n console.log(\"\\nCategory changes:\");\n console.log(formatOutput(categoryRows, \"table\"));\n }\n }\n });\n}\n\nasync function getConfig() {\n const { loadConfig } = await import(\"@gpc-cli/config\");\n return loadConfig();\n}\n"],"mappings":"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","names":[]}
@@ -75,7 +75,11 @@ function registerCacheCommand(program) {
75
75
  const matcher = FILE_TYPES[opts.type];
76
76
  if (!matcher) {
77
77
  const err = new Error(`Unknown cache type "${opts.type}".`);
78
- Object.assign(err, { code: "USAGE_ERROR", exitCode: 2, suggestion: `Valid types: ${Object.keys(FILE_TYPES).join(", ")}` });
78
+ Object.assign(err, {
79
+ code: "USAGE_ERROR",
80
+ exitCode: 2,
81
+ suggestion: `Valid types: ${Object.keys(FILE_TYPES).join(", ")}`
82
+ });
79
83
  throw err;
80
84
  }
81
85
  toDelete = allFiles.filter((f) => matcher(f.name));
@@ -114,4 +118,4 @@ function registerCacheCommand(program) {
114
118
  export {
115
119
  registerCacheCommand
116
120
  };
117
- //# sourceMappingURL=cache-XKPLZYEB.js.map
121
+ //# sourceMappingURL=cache-FGNP7Y37.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/cache.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { readdir, stat, unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { getCacheDir } from \"@gpc-cli/config\";\n\nconst FILE_TYPES: Record<string, (name: string) => boolean> = {\n status: (name) => name.startsWith(\"status-\") && name.endsWith(\".json\"),\n token: (name) => name === \"token-cache.json\",\n update: (name) => name === \"update-check.json\",\n};\n\nasync function getCacheFiles(\n cacheDir: string,\n): Promise<{ name: string; path: string; size: number; mtime: Date }[]> {\n let entries: string[];\n try {\n entries = await readdir(cacheDir);\n } catch {\n return [];\n }\n\n const files: { name: string; path: string; size: number; mtime: Date }[] = [];\n for (const entry of entries) {\n if (!entry.endsWith(\".json\")) continue;\n const filePath = join(cacheDir, entry);\n try {\n const info = await stat(filePath);\n if (info.isFile()) {\n files.push({ name: entry, path: filePath, size: info.size, mtime: info.mtime });\n }\n } catch {\n /* ignore */\n }\n }\n return files;\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction fileType(name: string): string {\n for (const [type, matcher] of Object.entries(FILE_TYPES)) {\n if (matcher(name)) return type;\n }\n return \"other\";\n}\n\nexport function registerCacheCommand(program: Command): void {\n const cache = program.command(\"cache\").description(\"Manage local cache files\");\n\n cache\n .command(\"info\")\n .description(\"Show cache directory and total size\")\n .action(async () => {\n const cacheDir = getCacheDir();\n const files = await getCacheFiles(cacheDir);\n const totalSize = files.reduce((sum, f) => sum + f.size, 0);\n console.log(`Cache directory: ${cacheDir}`);\n console.log(`Files: ${files.length}`);\n console.log(`Total size: ${formatBytes(totalSize)}`);\n });\n\n cache\n .command(\"list\")\n .description(\"List all cache files with size and age\")\n .action(async () => {\n const cacheDir = getCacheDir();\n const files = await getCacheFiles(cacheDir);\n if (files.length === 0) {\n console.log(\"No cache files found.\");\n return;\n }\n const now = Date.now();\n for (const f of files) {\n const ageMs = now - f.mtime.getTime();\n const ageMins = Math.floor(ageMs / 60000);\n const ageStr =\n ageMins < 60\n ? `${ageMins}m ago`\n : ageMins < 1440\n ? `${Math.floor(ageMins / 60)}h ago`\n : `${Math.floor(ageMins / 1440)}d ago`;\n const type = fileType(f.name);\n console.log(` ${f.name} [${type}] ${formatBytes(f.size)} ${ageStr}`);\n }\n });\n\n cache\n .command(\"clear\")\n .description(\"Remove cache files\")\n .option(\"--force\", \"Skip confirmation prompt\")\n .option(\"--type <type>\", \"Remove only files of this type (status|token|update)\")\n .action(async (opts) => {\n const cacheDir = getCacheDir();\n const allFiles = await getCacheFiles(cacheDir);\n\n let toDelete = allFiles;\n if (opts.type) {\n const matcher = FILE_TYPES[opts.type];\n if (!matcher) {\n const err = new Error(`Unknown cache type \"${opts.type}\".`);\n Object.assign(err, {\n code: \"USAGE_ERROR\",\n exitCode: 2,\n suggestion: `Valid types: ${Object.keys(FILE_TYPES).join(\", \")}`,\n });\n throw err;\n }\n toDelete = allFiles.filter((f) => matcher(f.name));\n }\n\n if (toDelete.length === 0) {\n console.log(\"No cache files to remove.\");\n return;\n }\n\n if (!opts.force) {\n console.log(`About to remove ${toDelete.length} file(s) from ${cacheDir}:`);\n for (const f of toDelete) {\n console.log(` ${f.name} (${formatBytes(f.size)})`);\n }\n const { createInterface } = await import(\"node:readline\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((resolve) =>\n rl.question(\"Proceed? [y/N] \", resolve),\n );\n rl.close();\n if (answer.toLowerCase() !== \"y\") {\n console.log(\"Aborted.\");\n return;\n }\n }\n\n let removed = 0;\n for (const f of toDelete) {\n try {\n await unlink(f.path);\n removed++;\n } catch {\n /* ignore */\n }\n }\n console.log(`Removed ${removed} file(s).`);\n });\n}\n"],"mappings":";;;AACA,SAAS,SAAS,MAAM,cAAc;AACtC,SAAS,YAAY;AACrB,SAAS,mBAAmB;AAE5B,IAAM,aAAwD;AAAA,EAC5D,QAAQ,CAAC,SAAS,KAAK,WAAW,SAAS,KAAK,KAAK,SAAS,OAAO;AAAA,EACrE,OAAO,CAAC,SAAS,SAAS;AAAA,EAC1B,QAAQ,CAAC,SAAS,SAAS;AAC7B;AAEA,eAAe,cACb,UACsE;AACtE,MAAI;AACJ,MAAI;AACF,cAAU,MAAM,QAAQ,QAAQ;AAAA,EAClC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,QAAqE,CAAC;AAC5E,aAAW,SAAS,SAAS;AAC3B,QAAI,CAAC,MAAM,SAAS,OAAO,EAAG;AAC9B,UAAM,WAAW,KAAK,UAAU,KAAK;AACrC,QAAI;AACF,YAAM,OAAO,MAAM,KAAK,QAAQ;AAChC,UAAI,KAAK,OAAO,GAAG;AACjB,cAAM,KAAK,EAAE,MAAM,OAAO,MAAM,UAAU,MAAM,KAAK,MAAM,OAAO,KAAK,MAAM,CAAC;AAAA,MAChF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,YAAY,OAAuB;AAC1C,MAAI,QAAQ,KAAM,QAAO,GAAG,KAAK;AACjC,MAAI,QAAQ,OAAO,KAAM,QAAO,IAAI,QAAQ,MAAM,QAAQ,CAAC,CAAC;AAC5D,SAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,CAAC,CAAC;AAC9C;AAEA,SAAS,SAAS,MAAsB;AACtC,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,UAAU,GAAG;AACxD,QAAI,QAAQ,IAAI,EAAG,QAAO;AAAA,EAC5B;AACA,SAAO;AACT;AAEO,SAAS,qBAAqB,SAAwB;AAC3D,QAAM,QAAQ,QAAQ,QAAQ,OAAO,EAAE,YAAY,0BAA0B;AAE7E,QACG,QAAQ,MAAM,EACd,YAAY,qCAAqC,EACjD,OAAO,YAAY;AAClB,UAAM,WAAW,YAAY;AAC7B,UAAM,QAAQ,MAAM,cAAc,QAAQ;AAC1C,UAAM,YAAY,MAAM,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,MAAM,CAAC;AAC1D,YAAQ,IAAI,oBAAoB,QAAQ,EAAE;AAC1C,YAAQ,IAAI,UAAU,MAAM,MAAM,EAAE;AACpC,YAAQ,IAAI,eAAe,YAAY,SAAS,CAAC,EAAE;AAAA,EACrD,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,wCAAwC,EACpD,OAAO,YAAY;AAClB,UAAM,WAAW,YAAY;AAC7B,UAAM,QAAQ,MAAM,cAAc,QAAQ;AAC1C,QAAI,MAAM,WAAW,GAAG;AACtB,cAAQ,IAAI,uBAAuB;AACnC;AAAA,IACF;AACA,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,KAAK,OAAO;AACrB,YAAM,QAAQ,MAAM,EAAE,MAAM,QAAQ;AACpC,YAAM,UAAU,KAAK,MAAM,QAAQ,GAAK;AACxC,YAAM,SACJ,UAAU,KACN,GAAG,OAAO,UACV,UAAU,OACR,GAAG,KAAK,MAAM,UAAU,EAAE,CAAC,UAC3B,GAAG,KAAK,MAAM,UAAU,IAAI,CAAC;AACrC,YAAM,OAAO,SAAS,EAAE,IAAI;AAC5B,cAAQ,IAAI,KAAK,EAAE,IAAI,MAAM,IAAI,MAAM,YAAY,EAAE,IAAI,CAAC,KAAK,MAAM,EAAE;AAAA,IACzE;AAAA,EACF,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,YAAY,oBAAoB,EAChC,OAAO,WAAW,0BAA0B,EAC5C,OAAO,iBAAiB,sDAAsD,EAC9E,OAAO,OAAO,SAAS;AACtB,UAAM,WAAW,YAAY;AAC7B,UAAM,WAAW,MAAM,cAAc,QAAQ;AAE7C,QAAI,WAAW;AACf,QAAI,KAAK,MAAM;AACb,YAAM,UAAU,WAAW,KAAK,IAAI;AACpC,UAAI,CAAC,SAAS;AACZ,cAAM,MAAM,IAAI,MAAM,uBAAuB,KAAK,IAAI,IAAI;AAC1D,eAAO,OAAO,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,YAAY,gBAAgB,OAAO,KAAK,UAAU,EAAE,KAAK,IAAI,CAAC;AAAA,QAChE,CAAC;AACD,cAAM;AAAA,MACR;AACA,iBAAW,SAAS,OAAO,CAAC,MAAM,QAAQ,EAAE,IAAI,CAAC;AAAA,IACnD;AAEA,QAAI,SAAS,WAAW,GAAG;AACzB,cAAQ,IAAI,2BAA2B;AACvC;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,OAAO;AACf,cAAQ,IAAI,mBAAmB,SAAS,MAAM,iBAAiB,QAAQ,GAAG;AAC1E,iBAAW,KAAK,UAAU;AACxB,gBAAQ,IAAI,KAAK,EAAE,IAAI,MAAM,YAAY,EAAE,IAAI,CAAC,GAAG;AAAA,MACrD;AACA,YAAM,EAAE,gBAAgB,IAAI,MAAM,OAAO,UAAe;AACxD,YAAM,KAAK,gBAAgB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO,CAAC;AAC3E,YAAM,SAAS,MAAM,IAAI;AAAA,QAAgB,CAAC,YACxC,GAAG,SAAS,mBAAmB,OAAO;AAAA,MACxC;AACA,SAAG,MAAM;AACT,UAAI,OAAO,YAAY,MAAM,KAAK;AAChC,gBAAQ,IAAI,UAAU;AACtB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,UAAU;AACd,eAAW,KAAK,UAAU;AACxB,UAAI;AACF,cAAM,OAAO,EAAE,IAAI;AACnB;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AACA,YAAQ,IAAI,WAAW,OAAO,WAAW;AAAA,EAC3C,CAAC;AACL;","names":[]}
@@ -7,7 +7,9 @@ async function readJsonFile(filePath) {
7
7
  return JSON.parse(await readFile(filePath, "utf-8"));
8
8
  } catch (err) {
9
9
  throw Object.assign(
10
- new Error(`Could not read JSON from ${filePath}: ${err instanceof Error ? err.message : String(err)}`),
10
+ new Error(
11
+ `Could not read JSON from ${filePath}: ${err instanceof Error ? err.message : String(err)}`
12
+ ),
11
13
  {
12
14
  code: "INVALID_JSON_FILE",
13
15
  exitCode: 2,
@@ -20,4 +22,4 @@ async function readJsonFile(filePath) {
20
22
  export {
21
23
  readJsonFile
22
24
  };
23
- //# sourceMappingURL=chunk-SLNJEAMK.js.map
25
+ //# sourceMappingURL=chunk-22XCOLZX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/json.ts"],"sourcesContent":["export async function readJsonFile(filePath: string): Promise<unknown> {\n const { readFile } = await import(\"node:fs/promises\");\n try {\n return JSON.parse(await readFile(filePath, \"utf-8\"));\n } catch (err) {\n throw Object.assign(\n new Error(\n `Could not read JSON from ${filePath}: ${err instanceof Error ? err.message : String(err)}`,\n ),\n {\n code: \"INVALID_JSON_FILE\",\n exitCode: 2,\n suggestion: `Check that ${filePath} exists and contains valid JSON`,\n },\n );\n }\n}\n"],"mappings":";;;AAAA,eAAsB,aAAa,UAAoC;AACrE,QAAM,EAAE,SAAS,IAAI,MAAM,OAAO,aAAkB;AACpD,MAAI;AACF,WAAO,KAAK,MAAM,MAAM,SAAS,UAAU,OAAO,CAAC;AAAA,EACrD,SAAS,KAAK;AACZ,UAAM,OAAO;AAAA,MACX,IAAI;AAAA,QACF,4BAA4B,QAAQ,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MAC3F;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,UAAU;AAAA,QACV,YAAY,cAAc,QAAQ;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -67,22 +67,22 @@ function registerPluginCommands(program, manager) {
67
67
  import { Command } from "commander";
68
68
  async function createProgram(pluginManager) {
69
69
  const program = new Command();
70
- program.name("gpc").description("GPC \u2014 Google Play Console CLI").version("0.9.53", "-V, --version").option("-o, --output <format>", "Output format: table, json, yaml, markdown, junit").option("-v, --verbose", "Enable debug logging").option("-q, --quiet", "Suppress non-essential output").option("-a, --app <package>", "App package name").option("-p, --profile <name>", "Auth profile name").option("--no-color", "Disable colored output").option("--no-interactive", "Disable interactive prompts").option("-y, --yes", "Skip confirmation prompts").option("--dry-run", "Preview changes without executing").option("--notify [target]", "Send webhook notification on completion (slack, discord, custom)").option("--ci", "Force CI mode (JSON output, no prompts, strict exit codes)").option("-j, --json", "Shorthand for --output json").option("--apps <csv>", "Comma-separated package names for multi-app operations").showSuggestionAfterError(false);
70
+ program.name("gpc").description("GPC \u2014 Google Play Console CLI").version("0.9.54", "-V, --version").option("-o, --output <format>", "Output format: table, json, yaml, markdown, junit").option("-v, --verbose", "Enable debug logging").option("-q, --quiet", "Suppress non-essential output").option("-a, --app <package>", "App package name").option("-p, --profile <name>", "Auth profile name").option("--no-color", "Disable colored output").option("--no-interactive", "Disable interactive prompts").option("-y, --yes", "Skip confirmation prompts").option("--dry-run", "Preview changes without executing").option("--notify [target]", "Send webhook notification on completion (slack, discord, custom)").option("--ci", "Force CI mode (JSON output, no prompts, strict exit codes)").option("-j, --json", "Shorthand for --output json").option("--apps <csv>", "Comma-separated package names for multi-app operations").showSuggestionAfterError(false);
71
71
  const commandLoaders = {
72
72
  auth: async () => {
73
- (await import("./auth-BA4FE2PO.js")).registerAuthCommands(program);
73
+ (await import("./auth-4DRT7ZH2.js")).registerAuthCommands(program);
74
74
  },
75
75
  config: async () => {
76
- (await import("./config-KT3PIL52.js")).registerConfigCommands(program);
76
+ (await import("./config-PUINDZON.js")).registerConfigCommands(program);
77
77
  },
78
78
  doctor: async () => {
79
- (await import("./doctor-GNI44SIP.js")).registerDoctorCommand(program);
79
+ (await import("./doctor-T3QFYBRV.js")).registerDoctorCommand(program);
80
80
  },
81
81
  update: async () => {
82
- (await import("./update-QPPKXWI5.js")).registerUpdateCommand(program);
82
+ (await import("./update-73YOR4GP.js")).registerUpdateCommand(program);
83
83
  },
84
84
  docs: async () => {
85
- (await import("./docs-GMFN6V4K.js")).registerDocsCommand(program);
85
+ (await import("./docs-GP6AEX4N.js")).registerDocsCommand(program);
86
86
  },
87
87
  changelog: async () => {
88
88
  (await import("./changelog-QLDFG5TV.js")).registerChangelogCommand(program);
@@ -91,138 +91,141 @@ async function createProgram(pluginManager) {
91
91
  (await import("./completion-BCHRJSAT.js")).registerCompletionCommand(program);
92
92
  },
93
93
  apps: async () => {
94
- (await import("./apps-4GP3FD7O.js")).registerAppsCommands(program);
94
+ (await import("./apps-WPUQOQLL.js")).registerAppsCommands(program);
95
95
  },
96
96
  releases: async () => {
97
- (await import("./releases-LUAHKIMY.js")).registerReleasesCommands(program);
97
+ (await import("./releases-XY57V22L.js")).registerReleasesCommands(program);
98
98
  },
99
99
  tracks: async () => {
100
- (await import("./tracks-I4QZNZ3M.js")).registerTracksCommands(program);
100
+ (await import("./tracks-RH3RKVFB.js")).registerTracksCommands(program);
101
101
  },
102
102
  status: async () => {
103
- (await import("./status-3HXBBXG6.js")).registerStatusCommand(program);
103
+ (await import("./status-32AJ7A6O.js")).registerStatusCommand(program);
104
104
  },
105
105
  listings: async () => {
106
- (await import("./listings-LNX6MQYN.js")).registerListingsCommands(program);
106
+ (await import("./listings-MOHHHNE6.js")).registerListingsCommands(program);
107
107
  },
108
108
  reviews: async () => {
109
- (await import("./reviews-YCBBM656.js")).registerReviewsCommands(program);
109
+ (await import("./reviews-P4M6BEJI.js")).registerReviewsCommands(program);
110
110
  },
111
111
  vitals: async () => {
112
- (await import("./vitals-PJEQUUAK.js")).registerVitalsCommands(program);
112
+ (await import("./vitals-PRBPNMVC.js")).registerVitalsCommands(program);
113
113
  },
114
114
  subscriptions: async () => {
115
- (await import("./subscriptions-LURZFPGJ.js")).registerSubscriptionsCommands(program);
115
+ (await import("./subscriptions-GTVJB4HX.js")).registerSubscriptionsCommands(program);
116
116
  },
117
117
  iap: async () => {
118
- (await import("./iap-OUI5YYN4.js")).registerIapCommands(program);
118
+ (await import("./iap-ETOL7OAC.js")).registerIapCommands(program);
119
119
  },
120
120
  purchases: async () => {
121
- (await import("./purchases-UBFLNYZC.js")).registerPurchasesCommands(program);
121
+ (await import("./purchases-AHWGLW6V.js")).registerPurchasesCommands(program);
122
122
  },
123
123
  pricing: async () => {
124
- (await import("./pricing-JJZFICFL.js")).registerPricingCommands(program);
124
+ (await import("./pricing-HYQRXKNO.js")).registerPricingCommands(program);
125
125
  },
126
126
  reports: async () => {
127
127
  (await import("./reports-CIB2T3XT.js")).registerReportsCommands(program);
128
128
  },
129
129
  users: async () => {
130
- (await import("./users-UKG7VIQH.js")).registerUsersCommands(program);
130
+ (await import("./users-FOMAT7DY.js")).registerUsersCommands(program);
131
131
  },
132
132
  testers: async () => {
133
- (await import("./testers-6CQL4KQV.js")).registerTestersCommands(program);
133
+ (await import("./testers-QUWZHO6M.js")).registerTestersCommands(program);
134
134
  },
135
135
  validate: async () => {
136
- (await import("./validate-QIYSA3N7.js")).registerValidateCommand(program);
136
+ (await import("./validate-RHWEZYD2.js")).registerValidateCommand(program);
137
137
  },
138
138
  publish: async () => {
139
- (await import("./publish-P5KIGSLI.js")).registerPublishCommand(program);
139
+ (await import("./publish-26SSZ2W3.js")).registerPublishCommand(program);
140
140
  },
141
141
  recovery: async () => {
142
- (await import("./recovery-YE3Z7NIN.js")).registerRecoveryCommands(program);
142
+ (await import("./recovery-B7DZQ6XG.js")).registerRecoveryCommands(program);
143
143
  },
144
144
  "data-safety": async () => {
145
- (await import("./data-safety-AFMD6MYI.js")).registerDataSafetyCommands(program);
145
+ (await import("./data-safety-46VY64OO.js")).registerDataSafetyCommands(program);
146
146
  },
147
147
  "external-transactions": async () => {
148
- (await import("./external-transactions-LCZALS3V.js")).registerExternalTransactionsCommands(
148
+ (await import("./external-transactions-JL3G4IG5.js")).registerExternalTransactionsCommands(
149
149
  program
150
150
  );
151
151
  },
152
152
  "device-tiers": async () => {
153
- (await import("./device-tiers-AQAMUQXI.js")).registerDeviceTiersCommands(program);
153
+ (await import("./device-tiers-MNZYMG3Y.js")).registerDeviceTiersCommands(program);
154
154
  },
155
155
  "one-time-products": async () => {
156
- (await import("./one-time-products-MGZTU7OM.js")).registerOneTimeProductsCommands(program);
156
+ (await import("./one-time-products-Y5RNIPV2.js")).registerOneTimeProductsCommands(program);
157
157
  },
158
158
  "internal-sharing": async () => {
159
- (await import("./internal-sharing-ONNIWIAT.js")).registerInternalSharingCommands(program);
159
+ (await import("./internal-sharing-KW6YENDG.js")).registerInternalSharingCommands(program);
160
160
  },
161
161
  "generated-apks": async () => {
162
- (await import("./generated-apks-RX2IUWSF.js")).registerGeneratedApksCommands(program);
162
+ (await import("./generated-apks-TC33S2YN.js")).registerGeneratedApksCommands(program);
163
+ },
164
+ "system-apks": async () => {
165
+ (await import("./system-apks-L6M7QYB3.js")).registerSystemApksCommands(program);
163
166
  },
164
167
  "purchase-options": async () => {
165
168
  (await import("./purchase-options-KFWW4JW2.js")).registerPurchaseOptionsCommands(program);
166
169
  },
167
170
  bundle: async () => {
168
- (await import("./bundle-F7MUVC5J.js")).registerBundleCommands(program);
171
+ (await import("./bundle-PFTE7XMU.js")).registerBundleCommands(program);
169
172
  },
170
173
  audit: async () => {
171
- (await import("./audit-VTWXTXC6.js")).registerAuditCommands(program);
174
+ (await import("./audit-M7GYID74.js")).registerAuditCommands(program);
172
175
  },
173
176
  migrate: async () => {
174
177
  (await import("./migrate-ZQCJGQQS.js")).registerMigrateCommands(program);
175
178
  },
176
179
  anomalies: async () => {
177
- (await import("./anomalies-V3AFS4LD.js")).registerAnomaliesCommands(program);
180
+ (await import("./anomalies-I5P6QQAZ.js")).registerAnomaliesCommands(program);
178
181
  },
179
182
  "install-skills": async () => {
180
- (await import("./install-skills-JKPYZHYS.js")).registerInstallSkillsCommand(program);
183
+ (await import("./install-skills-S342NJ7T.js")).registerInstallSkillsCommand(program);
181
184
  },
182
185
  verify: async () => {
183
- (await import("./verify-UUQNQMPG.js")).registerVerifyCommand(program);
186
+ (await import("./verify-H4ZUVHMZ.js")).registerVerifyCommand(program);
184
187
  },
185
188
  version: async () => {
186
- (await import("./version-KUWLAZGT.js")).registerVersionCommand(program);
189
+ (await import("./version-RXLEX62V.js")).registerVersionCommand(program);
187
190
  },
188
191
  cache: async () => {
189
- (await import("./cache-XKPLZYEB.js")).registerCacheCommand(program);
192
+ (await import("./cache-FGNP7Y37.js")).registerCacheCommand(program);
190
193
  },
191
194
  feedback: async () => {
192
- (await import("./feedback-XVTGMIBB.js")).registerFeedbackCommand(program);
195
+ (await import("./feedback-AULXQLJ7.js")).registerFeedbackCommand(program);
193
196
  },
194
197
  quickstart: async () => {
195
- (await import("./quickstart-Z5Y3FYJU.js")).registerQuickstartCommand(program);
198
+ (await import("./quickstart-FOWM3OKT.js")).registerQuickstartCommand(program);
196
199
  },
197
200
  grants: async () => {
198
- (await import("./grants-EBPECI26.js")).registerGrantsCommands(program);
201
+ (await import("./grants-UHNBPIFD.js")).registerGrantsCommands(program);
199
202
  },
200
203
  train: async () => {
201
- (await import("./train-MDD2EBHS.js")).registerTrainCommands(program);
204
+ (await import("./train-D2NKUW3M.js")).registerTrainCommands(program);
202
205
  },
203
206
  quota: async () => {
204
207
  (await import("./quota-MZRWYJGR.js")).registerQuotaCommand(program);
205
208
  },
206
209
  games: async () => {
207
- (await import("./games-ZSNGEI7A.js")).registerGamesCommands(program);
210
+ (await import("./games-SVFN2YIS.js")).registerGamesCommands(program);
208
211
  },
209
212
  enterprise: async () => {
210
213
  (await import("./enterprise-7PWXMSUN.js")).registerEnterpriseCommands(program);
211
214
  },
212
215
  diff: async () => {
213
- (await import("./diff-6EO4ID6W.js")).registerDiffCommand(program);
216
+ (await import("./diff-OBSHUSTL.js")).registerDiffCommand(program);
214
217
  },
215
218
  init: async () => {
216
- (await import("./init-WSTQTJOD.js")).registerInitCommand(program);
219
+ (await import("./init-6CCSVJC2.js")).registerInitCommand(program);
217
220
  },
218
221
  preflight: async () => {
219
- (await import("./preflight-W3JAJ4GO.js")).registerPreflightCommand(program);
222
+ (await import("./preflight-KIWZPFTX.js")).registerPreflightCommand(program);
220
223
  },
221
224
  plugins: async () => {
222
225
  registerPluginsCommand(program, pluginManager);
223
226
  },
224
227
  rtdn: async () => {
225
- (await import("./rtdn-LID2B7XZ.js")).registerRtdnCommands(program);
228
+ (await import("./rtdn-YII4H6SD.js")).registerRtdnCommands(program);
226
229
  }
227
230
  };
228
231
  function levenshtein(a, b) {
@@ -457,4 +460,4 @@ export {
457
460
  createProgram,
458
461
  handleCliError
459
462
  };
460
- //# sourceMappingURL=chunk-GQVZ2VCT.js.map
463
+ //# sourceMappingURL=chunk-6HIY4IGM.js.map