@gpc-cli/cli 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/LICENSE +21 -0
  2. package/dist/apps-BBYNHB2H.js +83 -0
  3. package/dist/apps-BBYNHB2H.js.map +1 -0
  4. package/dist/auth-T7IDSMVX.js +129 -0
  5. package/dist/auth-T7IDSMVX.js.map +1 -0
  6. package/dist/bin.d.ts +2 -0
  7. package/dist/bin.js +36 -0
  8. package/dist/bin.js.map +1 -0
  9. package/dist/chunk-4QV4WD3F.js +103 -0
  10. package/dist/chunk-4QV4WD3F.js.map +1 -0
  11. package/dist/chunk-IVVT73IP.js +245 -0
  12. package/dist/chunk-IVVT73IP.js.map +1 -0
  13. package/dist/chunk-QMKZYXDJ.js +24 -0
  14. package/dist/chunk-QMKZYXDJ.js.map +1 -0
  15. package/dist/completion-U44CGHRH.js +145 -0
  16. package/dist/completion-U44CGHRH.js.map +1 -0
  17. package/dist/config-K7UJKIXT.js +44 -0
  18. package/dist/config-K7UJKIXT.js.map +1 -0
  19. package/dist/docs-CVTWIVMS.js +20 -0
  20. package/dist/docs-CVTWIVMS.js.map +1 -0
  21. package/dist/doctor-VDDUPTIM.js +59 -0
  22. package/dist/doctor-VDDUPTIM.js.map +1 -0
  23. package/dist/iap-QIV4CXKZ.js +158 -0
  24. package/dist/iap-QIV4CXKZ.js.map +1 -0
  25. package/dist/index.d.ts +6 -0
  26. package/dist/index.js +8 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/listings-PF5FDXKQ.js +261 -0
  29. package/dist/listings-PF5FDXKQ.js.map +1 -0
  30. package/dist/pricing-S4SB5FXJ.js +52 -0
  31. package/dist/pricing-S4SB5FXJ.js.map +1 -0
  32. package/dist/prompt-VP5LURRP.js +20 -0
  33. package/dist/prompt-VP5LURRP.js.map +1 -0
  34. package/dist/publish-3BAIN4NQ.js +114 -0
  35. package/dist/publish-3BAIN4NQ.js.map +1 -0
  36. package/dist/purchases-E6A2T5WQ.js +231 -0
  37. package/dist/purchases-E6A2T5WQ.js.map +1 -0
  38. package/dist/releases-464IMEEF.js +231 -0
  39. package/dist/releases-464IMEEF.js.map +1 -0
  40. package/dist/reports-3YAD4U4F.js +129 -0
  41. package/dist/reports-3YAD4U4F.js.map +1 -0
  42. package/dist/reviews-2CLM53E3.js +125 -0
  43. package/dist/reviews-2CLM53E3.js.map +1 -0
  44. package/dist/status-M7U3YNMU.js +32 -0
  45. package/dist/status-M7U3YNMU.js.map +1 -0
  46. package/dist/subscriptions-PUHH4FBB.js +376 -0
  47. package/dist/subscriptions-PUHH4FBB.js.map +1 -0
  48. package/dist/testers-WWZMLB7J.js +145 -0
  49. package/dist/testers-WWZMLB7J.js.map +1 -0
  50. package/dist/tracks-427E34S3.js +39 -0
  51. package/dist/tracks-427E34S3.js.map +1 -0
  52. package/dist/users-E5Y5HI6K.js +145 -0
  53. package/dist/users-E5Y5HI6K.js.map +1 -0
  54. package/dist/validate-TPKVSIMR.js +37 -0
  55. package/dist/validate-TPKVSIMR.js.map +1 -0
  56. package/dist/vitals-YMZMUPNA.js +166 -0
  57. package/dist/vitals-YMZMUPNA.js.map +1 -0
  58. package/package.json +48 -0
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ isDryRun,
4
+ printDryRun
5
+ } from "./chunk-QMKZYXDJ.js";
6
+ import {
7
+ requireConfirm
8
+ } from "./chunk-4QV4WD3F.js";
9
+
10
+ // src/commands/users.ts
11
+ import { loadConfig } from "@gpc-cli/config";
12
+ import { resolveAuth } from "@gpc-cli/auth";
13
+ import { createUsersClient } from "@gpc-cli/api";
14
+ import {
15
+ listUsers,
16
+ getUser,
17
+ inviteUser,
18
+ updateUser,
19
+ removeUser,
20
+ parseGrantArg,
21
+ PERMISSION_PROPAGATION_WARNING,
22
+ detectOutputFormat,
23
+ formatOutput
24
+ } from "@gpc-cli/core";
25
+ function resolveDeveloperId(devIdArg, config) {
26
+ const id = devIdArg || config.developerId;
27
+ if (!id) {
28
+ console.error("Error: No developer ID. Use --developer-id <id> or gpc config set developerId <id>");
29
+ process.exit(2);
30
+ }
31
+ return id;
32
+ }
33
+ async function getUsersClient(config) {
34
+ const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });
35
+ return createUsersClient({ auth });
36
+ }
37
+ function registerUsersCommands(program) {
38
+ const users = program.command("users").description("Manage developer account users and permissions").option("--developer-id <id>", "Developer account ID");
39
+ users.command("list").description("List all users in the developer account").option("--limit <n>", "Maximum total results", parseInt).option("--next-page <token>", "Resume from page token").action(async (options) => {
40
+ const config = await loadConfig();
41
+ const developerId = resolveDeveloperId(users.opts().developerId, config);
42
+ const client = await getUsersClient(config);
43
+ const format = detectOutputFormat();
44
+ try {
45
+ const result = await listUsers(client, developerId, {
46
+ limit: options.limit,
47
+ nextPage: options.nextPage
48
+ });
49
+ console.log(formatOutput(result, format));
50
+ } catch (error) {
51
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
52
+ process.exit(4);
53
+ }
54
+ });
55
+ users.command("get <email>").description("Get user details").action(async (email) => {
56
+ const config = await loadConfig();
57
+ const developerId = resolveDeveloperId(users.opts().developerId, config);
58
+ const client = await getUsersClient(config);
59
+ const format = detectOutputFormat();
60
+ try {
61
+ const result = await getUser(client, developerId, email);
62
+ console.log(formatOutput(result, format));
63
+ } catch (error) {
64
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
65
+ process.exit(4);
66
+ }
67
+ });
68
+ users.command("invite <email>").description("Invite a user to the developer account").option("--role <permissions...>", "Developer-level permissions").option("--grant <grants...>", "Per-app grants (format: com.example.app:PERMISSION1,PERMISSION2)").action(async (email, options) => {
69
+ const config = await loadConfig();
70
+ const developerId = resolveDeveloperId(users.opts().developerId, config);
71
+ const format = detectOutputFormat();
72
+ if (isDryRun(program)) {
73
+ printDryRun({
74
+ command: "users invite",
75
+ action: "invite",
76
+ target: email,
77
+ details: { role: options.role, grant: options.grant }
78
+ }, format, formatOutput);
79
+ return;
80
+ }
81
+ const client = await getUsersClient(config);
82
+ try {
83
+ const permissions = options.role;
84
+ const grants = options.grant?.map((g) => parseGrantArg(g));
85
+ const result = await inviteUser(client, developerId, email, permissions, grants);
86
+ console.log(formatOutput(result, format));
87
+ console.error(PERMISSION_PROPAGATION_WARNING);
88
+ } catch (error) {
89
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
90
+ process.exit(4);
91
+ }
92
+ });
93
+ users.command("update <email>").description("Update user permissions").option("--role <permissions...>", "Developer-level permissions").option("--grant <grants...>", "Per-app grants (format: com.example.app:PERMISSION1,PERMISSION2)").action(async (email, options) => {
94
+ const config = await loadConfig();
95
+ const developerId = resolveDeveloperId(users.opts().developerId, config);
96
+ const format = detectOutputFormat();
97
+ if (isDryRun(program)) {
98
+ printDryRun({
99
+ command: "users update",
100
+ action: "update",
101
+ target: email,
102
+ details: { role: options.role, grant: options.grant }
103
+ }, format, formatOutput);
104
+ return;
105
+ }
106
+ const client = await getUsersClient(config);
107
+ try {
108
+ const permissions = options.role;
109
+ const grants = options.grant?.map((g) => parseGrantArg(g));
110
+ const result = await updateUser(client, developerId, email, permissions, grants);
111
+ console.log(formatOutput(result, format));
112
+ console.error(PERMISSION_PROPAGATION_WARNING);
113
+ } catch (error) {
114
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
115
+ process.exit(4);
116
+ }
117
+ });
118
+ users.command("remove <email>").description("Remove a user from the developer account").action(async (email) => {
119
+ const config = await loadConfig();
120
+ const developerId = resolveDeveloperId(users.opts().developerId, config);
121
+ await requireConfirm(`Remove user "${email}" from developer account?`, program);
122
+ if (isDryRun(program)) {
123
+ const format = detectOutputFormat();
124
+ printDryRun({
125
+ command: "users remove",
126
+ action: "remove",
127
+ target: email
128
+ }, format, formatOutput);
129
+ return;
130
+ }
131
+ const client = await getUsersClient(config);
132
+ try {
133
+ await removeUser(client, developerId, email);
134
+ console.log(`User ${email} removed.`);
135
+ console.error(PERMISSION_PROPAGATION_WARNING);
136
+ } catch (error) {
137
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
138
+ process.exit(4);
139
+ }
140
+ });
141
+ }
142
+ export {
143
+ registerUsersCommands
144
+ };
145
+ //# sourceMappingURL=users-E5Y5HI6K.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/users.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createUsersClient } from \"@gpc-cli/api\";\nimport type { DeveloperPermission } from \"@gpc-cli/api\";\nimport {\n listUsers,\n getUser,\n inviteUser,\n updateUser,\n removeUser,\n parseGrantArg,\n PERMISSION_PROPAGATION_WARNING,\n detectOutputFormat,\n formatOutput,\n} from \"@gpc-cli/core\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { requireConfirm } from \"../prompt.js\";\n\nfunction resolveDeveloperId(devIdArg: string | undefined, config: any): string {\n const id = devIdArg || config.developerId;\n if (!id) {\n console.error(\"Error: No developer ID. Use --developer-id <id> or gpc config set developerId <id>\");\n process.exit(2);\n }\n return id;\n}\n\nasync function getUsersClient(config: any) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createUsersClient({ auth });\n}\n\nexport function registerUsersCommands(program: Command): void {\n const users = program\n .command(\"users\")\n .description(\"Manage developer account users and permissions\")\n .option(\"--developer-id <id>\", \"Developer account ID\");\n\n users\n .command(\"list\")\n .description(\"List all users in the developer account\")\n .option(\"--limit <n>\", \"Maximum total results\", parseInt)\n .option(\"--next-page <token>\", \"Resume from page token\")\n .action(async (options) => {\n const config = await loadConfig();\n const developerId = resolveDeveloperId(users.opts().developerId, config);\n const client = await getUsersClient(config);\n const format = detectOutputFormat();\n\n try {\n const result = await listUsers(client, developerId, {\n limit: options.limit,\n nextPage: options.nextPage,\n });\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n users\n .command(\"get <email>\")\n .description(\"Get user details\")\n .action(async (email: string) => {\n const config = await loadConfig();\n const developerId = resolveDeveloperId(users.opts().developerId, config);\n const client = await getUsersClient(config);\n const format = detectOutputFormat();\n\n try {\n const result = await getUser(client, developerId, email);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n users\n .command(\"invite <email>\")\n .description(\"Invite a user to the developer account\")\n .option(\"--role <permissions...>\", \"Developer-level permissions\")\n .option(\"--grant <grants...>\", \"Per-app grants (format: com.example.app:PERMISSION1,PERMISSION2)\")\n .action(async (email: string, options) => {\n const config = await loadConfig();\n const developerId = resolveDeveloperId(users.opts().developerId, config);\n const format = detectOutputFormat();\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"users invite\",\n action: \"invite\",\n target: email,\n details: { role: options.role, grant: options.grant },\n }, format, formatOutput);\n return;\n }\n\n const client = await getUsersClient(config);\n\n try {\n const permissions = options.role as DeveloperPermission[] | undefined;\n const grants = options.grant?.map((g: string) => parseGrantArg(g));\n const result = await inviteUser(client, developerId, email, permissions, grants);\n console.log(formatOutput(result, format));\n console.error(PERMISSION_PROPAGATION_WARNING);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n users\n .command(\"update <email>\")\n .description(\"Update user permissions\")\n .option(\"--role <permissions...>\", \"Developer-level permissions\")\n .option(\"--grant <grants...>\", \"Per-app grants (format: com.example.app:PERMISSION1,PERMISSION2)\")\n .action(async (email: string, options) => {\n const config = await loadConfig();\n const developerId = resolveDeveloperId(users.opts().developerId, config);\n const format = detectOutputFormat();\n\n if (isDryRun(program)) {\n printDryRun({\n command: \"users update\",\n action: \"update\",\n target: email,\n details: { role: options.role, grant: options.grant },\n }, format, formatOutput);\n return;\n }\n\n const client = await getUsersClient(config);\n\n try {\n const permissions = options.role as DeveloperPermission[] | undefined;\n const grants = options.grant?.map((g: string) => parseGrantArg(g));\n const result = await updateUser(client, developerId, email, permissions, grants);\n console.log(formatOutput(result, format));\n console.error(PERMISSION_PROPAGATION_WARNING);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n users\n .command(\"remove <email>\")\n .description(\"Remove a user from the developer account\")\n .action(async (email: string) => {\n const config = await loadConfig();\n const developerId = resolveDeveloperId(users.opts().developerId, config);\n\n await requireConfirm(`Remove user \"${email}\" from developer account?`, program);\n\n if (isDryRun(program)) {\n const format = detectOutputFormat();\n printDryRun({\n command: \"users remove\",\n action: \"remove\",\n target: email,\n }, format, formatOutput);\n return;\n }\n\n const client = await getUsersClient(config);\n\n try {\n await removeUser(client, developerId, email);\n console.log(`User ${email} removed.`);\n console.error(PERMISSION_PROPAGATION_WARNING);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/commands/validate.ts
4
+ import { validatePreSubmission, readReleaseNotesFromDir } from "@gpc-cli/core";
5
+ import { detectOutputFormat, formatOutput } from "@gpc-cli/core";
6
+ function registerValidateCommand(program) {
7
+ program.command("validate <file>").description("Pre-submission validation checks").option("--track <track>", "Target track to validate").option("--mapping <file>", "ProGuard/R8 mapping file").option("--notes <text>", "Release notes (en-US)").option("--notes-dir <dir>", "Read release notes from directory (<dir>/<lang>.txt)").action(async (file, options) => {
8
+ if (options.notes && options.notesDir) {
9
+ console.error("Error: Cannot use both --notes and --notes-dir");
10
+ process.exit(2);
11
+ }
12
+ const format = detectOutputFormat();
13
+ let notes;
14
+ if (options.notesDir) {
15
+ try {
16
+ notes = await readReleaseNotesFromDir(options.notesDir);
17
+ } catch (err) {
18
+ console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
19
+ process.exit(1);
20
+ }
21
+ } else if (options.notes) {
22
+ notes = [{ language: "en-US", text: options.notes }];
23
+ }
24
+ const result = await validatePreSubmission({
25
+ filePath: file,
26
+ mappingFile: options.mapping,
27
+ track: options.track,
28
+ notes
29
+ });
30
+ console.log(formatOutput(result, format));
31
+ process.exit(result.valid ? 0 : 1);
32
+ });
33
+ }
34
+ export {
35
+ registerValidateCommand
36
+ };
37
+ //# sourceMappingURL=validate-TPKVSIMR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/validate.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { validatePreSubmission, readReleaseNotesFromDir } from \"@gpc-cli/core\";\nimport { detectOutputFormat, formatOutput } from \"@gpc-cli/core\";\n\nexport function registerValidateCommand(program: Command): void {\n program\n .command(\"validate <file>\")\n .description(\"Pre-submission validation checks\")\n .option(\"--track <track>\", \"Target track to validate\")\n .option(\"--mapping <file>\", \"ProGuard/R8 mapping file\")\n .option(\"--notes <text>\", \"Release notes (en-US)\")\n .option(\"--notes-dir <dir>\", \"Read release notes from directory (<dir>/<lang>.txt)\")\n .action(async (file: string, options) => {\n if (options.notes && options.notesDir) {\n console.error(\"Error: Cannot use both --notes and --notes-dir\");\n process.exit(2);\n }\n\n const format = detectOutputFormat();\n\n let notes: { language: string; text: string }[] | undefined;\n if (options.notesDir) {\n try {\n notes = await readReleaseNotesFromDir(options.notesDir);\n } catch (err) {\n console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n } else if (options.notes) {\n notes = [{ language: \"en-US\", text: options.notes }];\n }\n\n const result = await validatePreSubmission({\n filePath: file,\n mappingFile: options.mapping,\n track: options.track,\n notes,\n });\n\n console.log(formatOutput(result, format));\n process.exit(result.valid ? 0 : 1);\n });\n}\n"],"mappings":";;;AACA,SAAS,uBAAuB,+BAA+B;AAC/D,SAAS,oBAAoB,oBAAoB;AAE1C,SAAS,wBAAwB,SAAwB;AAC9D,UACG,QAAQ,iBAAiB,EACzB,YAAY,kCAAkC,EAC9C,OAAO,mBAAmB,0BAA0B,EACpD,OAAO,oBAAoB,0BAA0B,EACrD,OAAO,kBAAkB,uBAAuB,EAChD,OAAO,qBAAqB,sDAAsD,EAClF,OAAO,OAAO,MAAc,YAAY;AACvC,QAAI,QAAQ,SAAS,QAAQ,UAAU;AACrC,cAAQ,MAAM,gDAAgD;AAC9D,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,SAAS,mBAAmB;AAElC,QAAI;AACJ,QAAI,QAAQ,UAAU;AACpB,UAAI;AACF,gBAAQ,MAAM,wBAAwB,QAAQ,QAAQ;AAAA,MACxD,SAAS,KAAK;AACZ,gBAAQ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAC1E,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,WAAW,QAAQ,OAAO;AACxB,cAAQ,CAAC,EAAE,UAAU,SAAS,MAAM,QAAQ,MAAM,CAAC;AAAA,IACrD;AAEA,UAAM,SAAS,MAAM,sBAAsB;AAAA,MACzC,UAAU;AAAA,MACV,aAAa,QAAQ;AAAA,MACrB,OAAO,QAAQ;AAAA,MACf;AAAA,IACF,CAAC;AAED,YAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AACxC,YAAQ,KAAK,OAAO,QAAQ,IAAI,CAAC;AAAA,EACnC,CAAC;AACL;","names":[]}
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/commands/vitals.ts
4
+ import { loadConfig } from "@gpc-cli/config";
5
+ import { resolveAuth } from "@gpc-cli/auth";
6
+ import { createReportingClient } from "@gpc-cli/api";
7
+ import {
8
+ getVitalsOverview,
9
+ getVitalsCrashes,
10
+ getVitalsAnr,
11
+ getVitalsStartup,
12
+ getVitalsRendering,
13
+ getVitalsBattery,
14
+ getVitalsMemory,
15
+ getVitalsAnomalies,
16
+ searchVitalsErrors,
17
+ compareVitalsTrend,
18
+ checkThreshold,
19
+ detectOutputFormat,
20
+ formatOutput
21
+ } from "@gpc-cli/core";
22
+ function resolvePackageName(packageArg, config) {
23
+ const name = packageArg || config.app;
24
+ if (!name) {
25
+ console.error("Error: No package name. Use --app <package> or gpc config set app <package>");
26
+ process.exit(2);
27
+ }
28
+ return name;
29
+ }
30
+ async function getReportingClient(config) {
31
+ const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });
32
+ return createReportingClient({ auth });
33
+ }
34
+ var VALID_DIMENSIONS = [
35
+ "apiLevel",
36
+ "versionCode",
37
+ "deviceModel",
38
+ "deviceType",
39
+ "countryCode",
40
+ "deviceRamBucket",
41
+ "deviceSocName",
42
+ "deviceCpuMakeModel",
43
+ "deviceGlEsVersion",
44
+ "deviceVulkanVersion",
45
+ "deviceOpenGlVersion",
46
+ "deviceBrand"
47
+ ];
48
+ function validateDimension(dim) {
49
+ if (!VALID_DIMENSIONS.includes(dim)) {
50
+ console.error(`Error: Invalid dimension "${dim}".`);
51
+ console.error(`Valid dimensions: ${VALID_DIMENSIONS.join(", ")}`);
52
+ process.exit(2);
53
+ }
54
+ return dim;
55
+ }
56
+ function registerMetricCommand(parent, name, description, fn, program) {
57
+ parent.command(name).description(description).option("--dim <dimension>", "Group by dimension").option("--days <n>", "Number of days to query", parseInt).option("--threshold <value>", "Threshold value for CI alerting", parseFloat).action(async (options) => {
58
+ const config = await loadConfig();
59
+ const packageName = resolvePackageName(program.opts().app, config);
60
+ const reporting = await getReportingClient(config);
61
+ const format = detectOutputFormat();
62
+ try {
63
+ const result = await fn(reporting, packageName, {
64
+ dimension: options.dim ? validateDimension(options.dim) : void 0,
65
+ days: options.days
66
+ });
67
+ console.log(formatOutput(result, format));
68
+ if (options.threshold !== void 0) {
69
+ const latestRow = result.rows?.[result.rows.length - 1];
70
+ const metricKeys = latestRow?.metrics ? Object.keys(latestRow.metrics) : [];
71
+ const firstMetric = metricKeys[0];
72
+ const value = firstMetric ? Number(latestRow?.metrics[firstMetric]?.decimalValue?.value) : void 0;
73
+ const check = checkThreshold(value, options.threshold);
74
+ if (check.breached) {
75
+ console.error(`Threshold breached: ${check.value} > ${check.threshold}`);
76
+ process.exit(6);
77
+ }
78
+ }
79
+ } catch (error) {
80
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
81
+ process.exit(4);
82
+ }
83
+ });
84
+ }
85
+ function registerVitalsCommands(program) {
86
+ const vitals = program.command("vitals").description("Monitor app vitals, crash rates, and performance metrics");
87
+ vitals.command("overview").description("Dashboard summary of all vital metrics").action(async () => {
88
+ const config = await loadConfig();
89
+ const packageName = resolvePackageName(program.opts().app, config);
90
+ const reporting = await getReportingClient(config);
91
+ const format = detectOutputFormat();
92
+ try {
93
+ const result = await getVitalsOverview(reporting, packageName);
94
+ console.log(formatOutput(result, format));
95
+ } catch (error) {
96
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
97
+ process.exit(4);
98
+ }
99
+ });
100
+ registerMetricCommand(vitals, "crashes", "Query crash rate metrics", getVitalsCrashes, program);
101
+ registerMetricCommand(vitals, "anr", "Query ANR rate metrics", getVitalsAnr, program);
102
+ registerMetricCommand(vitals, "startup", "Query slow startup metrics", getVitalsStartup, program);
103
+ registerMetricCommand(vitals, "rendering", "Query slow rendering metrics", getVitalsRendering, program);
104
+ registerMetricCommand(vitals, "battery", "Query excessive wakeup metrics", getVitalsBattery, program);
105
+ registerMetricCommand(vitals, "memory", "Query stuck wakelock metrics", getVitalsMemory, program);
106
+ vitals.command("anomalies").description("Detect anomalies in app vitals").action(async () => {
107
+ const config = await loadConfig();
108
+ const packageName = resolvePackageName(program.opts().app, config);
109
+ const reporting = await getReportingClient(config);
110
+ const format = detectOutputFormat();
111
+ try {
112
+ const result = await getVitalsAnomalies(reporting, packageName);
113
+ console.log(formatOutput(result, format));
114
+ } catch (error) {
115
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
116
+ process.exit(4);
117
+ }
118
+ });
119
+ const errors = vitals.command("errors").description("Search and view error issues");
120
+ errors.command("search").description("Search error issues").option("--filter <text>", "Filter expression").option("--max <n>", "Maximum results", parseInt).action(async (options) => {
121
+ const config = await loadConfig();
122
+ const packageName = resolvePackageName(program.opts().app, config);
123
+ const reporting = await getReportingClient(config);
124
+ const format = detectOutputFormat();
125
+ try {
126
+ const result = await searchVitalsErrors(reporting, packageName, {
127
+ filter: options.filter,
128
+ maxResults: options.max
129
+ });
130
+ console.log(formatOutput(result, format));
131
+ } catch (error) {
132
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
133
+ process.exit(4);
134
+ }
135
+ });
136
+ const METRIC_MAP = {
137
+ crashes: "vitals.crashrate",
138
+ anr: "vitals.anrrate",
139
+ startup: "vitals.slowstartrate",
140
+ rendering: "vitals.slowrenderingrate",
141
+ battery: "vitals.excessivewakeuprate",
142
+ memory: "vitals.stuckbackgroundwakelockrate"
143
+ };
144
+ vitals.command("compare <metric>").description("Compare metric trend: this period vs previous period").option("--days <n>", "Period length in days", parseInt, 7).action(async (metric, options) => {
145
+ const metricSet = METRIC_MAP[metric];
146
+ if (!metricSet) {
147
+ console.error(`Error: Unknown metric "${metric}". Use: ${Object.keys(METRIC_MAP).join(", ")}`);
148
+ process.exit(2);
149
+ }
150
+ const config = await loadConfig();
151
+ const packageName = resolvePackageName(program.opts().app, config);
152
+ const reporting = await getReportingClient(config);
153
+ const format = detectOutputFormat();
154
+ try {
155
+ const result = await compareVitalsTrend(reporting, packageName, metricSet, options.days);
156
+ console.log(formatOutput(result, format));
157
+ } catch (error) {
158
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
159
+ process.exit(4);
160
+ }
161
+ });
162
+ }
163
+ export {
164
+ registerVitalsCommands
165
+ };
166
+ //# sourceMappingURL=vitals-YMZMUPNA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/vitals.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createReportingClient } from \"@gpc-cli/api\";\nimport type { ReportingDimension } from \"@gpc-cli/api\";\nimport type { VitalsMetricSet } from \"@gpc-cli/api\";\nimport {\n getVitalsOverview,\n getVitalsCrashes,\n getVitalsAnr,\n getVitalsStartup,\n getVitalsRendering,\n getVitalsBattery,\n getVitalsMemory,\n getVitalsAnomalies,\n searchVitalsErrors,\n compareVitalsTrend,\n checkThreshold,\n detectOutputFormat,\n formatOutput,\n} from \"@gpc-cli/core\";\n\nfunction resolvePackageName(packageArg: string | undefined, config: any): string {\n const name = packageArg || config.app;\n if (!name) {\n console.error(\"Error: No package name. Use --app <package> or gpc config set app <package>\");\n process.exit(2);\n }\n return name;\n}\n\nasync function getReportingClient(config: any) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createReportingClient({ auth });\n}\n\nconst VALID_DIMENSIONS: ReportingDimension[] = [\n \"apiLevel\", \"versionCode\", \"deviceModel\", \"deviceType\",\n \"countryCode\", \"deviceRamBucket\", \"deviceSocName\",\n \"deviceCpuMakeModel\", \"deviceGlEsVersion\", \"deviceVulkanVersion\",\n \"deviceOpenGlVersion\", \"deviceBrand\",\n];\n\nfunction validateDimension(dim: string): ReportingDimension {\n if (!VALID_DIMENSIONS.includes(dim as ReportingDimension)) {\n console.error(`Error: Invalid dimension \"${dim}\".`);\n console.error(`Valid dimensions: ${VALID_DIMENSIONS.join(\", \")}`);\n process.exit(2);\n }\n return dim as ReportingDimension;\n}\n\ntype MetricFn = typeof getVitalsCrashes;\n\nfunction registerMetricCommand(\n parent: Command,\n name: string,\n description: string,\n fn: MetricFn,\n program: Command,\n): void {\n parent\n .command(name)\n .description(description)\n .option(\"--dim <dimension>\", \"Group by dimension\")\n .option(\"--days <n>\", \"Number of days to query\", parseInt)\n .option(\"--threshold <value>\", \"Threshold value for CI alerting\", parseFloat)\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const reporting = await getReportingClient(config);\n const format = detectOutputFormat();\n\n try {\n const result = await fn(reporting, packageName, {\n dimension: options.dim ? validateDimension(options.dim) : undefined,\n days: options.days,\n });\n console.log(formatOutput(result, format));\n\n if (options.threshold !== undefined) {\n const latestRow = result.rows?.[result.rows.length - 1];\n const metricKeys = latestRow?.metrics ? Object.keys(latestRow.metrics) : [];\n const firstMetric = metricKeys[0];\n const value = firstMetric\n ? Number(latestRow?.metrics[firstMetric]?.decimalValue?.value)\n : undefined;\n const check = checkThreshold(value, options.threshold);\n if (check.breached) {\n console.error(`Threshold breached: ${check.value} > ${check.threshold}`);\n process.exit(6);\n }\n }\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n}\n\nexport function registerVitalsCommands(program: Command): void {\n const vitals = program\n .command(\"vitals\")\n .description(\"Monitor app vitals, crash rates, and performance metrics\");\n\n vitals\n .command(\"overview\")\n .description(\"Dashboard summary of all vital metrics\")\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 = detectOutputFormat();\n\n try {\n const result = await getVitalsOverview(reporting, packageName);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n registerMetricCommand(vitals, \"crashes\", \"Query crash rate metrics\", getVitalsCrashes, program);\n registerMetricCommand(vitals, \"anr\", \"Query ANR rate metrics\", getVitalsAnr, program);\n registerMetricCommand(vitals, \"startup\", \"Query slow startup metrics\", getVitalsStartup, program);\n registerMetricCommand(vitals, \"rendering\", \"Query slow rendering metrics\", getVitalsRendering, program);\n registerMetricCommand(vitals, \"battery\", \"Query excessive wakeup metrics\", getVitalsBattery, program);\n registerMetricCommand(vitals, \"memory\", \"Query stuck wakelock metrics\", getVitalsMemory, program);\n\n vitals\n .command(\"anomalies\")\n .description(\"Detect anomalies in app vitals\")\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 = detectOutputFormat();\n\n try {\n const result = await getVitalsAnomalies(reporting, packageName);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n const errors = vitals\n .command(\"errors\")\n .description(\"Search and view error issues\");\n\n errors\n .command(\"search\")\n .description(\"Search error issues\")\n .option(\"--filter <text>\", \"Filter expression\")\n .option(\"--max <n>\", \"Maximum results\", parseInt)\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const reporting = await getReportingClient(config);\n const format = detectOutputFormat();\n\n try {\n const result = await searchVitalsErrors(reporting, packageName, {\n filter: options.filter,\n maxResults: options.max,\n });\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n const METRIC_MAP: Record<string, VitalsMetricSet> = {\n crashes: \"vitals.crashrate\",\n anr: \"vitals.anrrate\",\n startup: \"vitals.slowstartrate\",\n rendering: \"vitals.slowrenderingrate\",\n battery: \"vitals.excessivewakeuprate\",\n memory: \"vitals.stuckbackgroundwakelockrate\",\n };\n\n vitals\n .command(\"compare <metric>\")\n .description(\"Compare metric trend: this period vs previous period\")\n .option(\"--days <n>\", \"Period length in days\", parseInt, 7)\n .action(async (metric: string, options) => {\n const metricSet = METRIC_MAP[metric];\n if (!metricSet) {\n console.error(`Error: Unknown metric \"${metric}\". Use: ${Object.keys(METRIC_MAP).join(\", \")}`);\n process.exit(2);\n }\n\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts().app, config);\n const reporting = await getReportingClient(config);\n const format = detectOutputFormat();\n\n try {\n const result = await compareVitalsTrend(reporting, packageName, metricSet, options.days);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@gpc-cli/cli",
3
+ "version": "0.1.1",
4
+ "description": "The complete Google Play CLI",
5
+ "type": "module",
6
+ "bin": {
7
+ "gpc": "./dist/bin.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "dependencies": {
21
+ "commander": "^14.0.3",
22
+ "@gpc-cli/api": "1.0.0",
23
+ "@gpc-cli/auth": "^0.1.0",
24
+ "@gpc-cli/config": "0.1.0",
25
+ "@gpc-cli/core": "0.1.0",
26
+ "@gpc-cli/plugin-sdk": "0.1.0"
27
+ },
28
+ "keywords": [
29
+ "google-play",
30
+ "cli",
31
+ "android",
32
+ "play-store",
33
+ "play-console"
34
+ ],
35
+ "license": "MIT",
36
+ "devDependencies": {
37
+ "@types/node": "^25.3.5"
38
+ },
39
+ "scripts": {
40
+ "build": "tsup",
41
+ "dev": "tsup --watch",
42
+ "test": "vitest run",
43
+ "test:watch": "vitest",
44
+ "lint": "eslint src/",
45
+ "typecheck": "tsc --noEmit",
46
+ "clean": "rm -rf dist"
47
+ }
48
+ }