@gpc-cli/cli 0.9.16 → 0.9.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  createProgram,
4
4
  handleCliError,
5
5
  loadPlugins
6
- } from "./chunk-NYGU5OUZ.js";
6
+ } from "./chunk-R3KI4HZ5.js";
7
7
 
8
8
  // src/networking.ts
9
9
  async function setupNetworking() {
@@ -97,16 +97,16 @@ async function createProgram(pluginManager) {
97
97
  (await import("./status-S3FAEXNH.js")).registerStatusCommand(program);
98
98
  },
99
99
  listings: async () => {
100
- (await import("./listings-AKOLKWLW.js")).registerListingsCommands(program);
100
+ (await import("./listings-S4CJ7EDX.js")).registerListingsCommands(program);
101
101
  },
102
102
  reviews: async () => {
103
- (await import("./reviews-6V3DO4NB.js")).registerReviewsCommands(program);
103
+ (await import("./reviews-PMUJVNVC.js")).registerReviewsCommands(program);
104
104
  },
105
105
  vitals: async () => {
106
- (await import("./vitals-I6FKKKPO.js")).registerVitalsCommands(program);
106
+ (await import("./vitals-EOHSUQJM.js")).registerVitalsCommands(program);
107
107
  },
108
108
  subscriptions: async () => {
109
- (await import("./subscriptions-L4YWMG3F.js")).registerSubscriptionsCommands(program);
109
+ (await import("./subscriptions-SF4LBZDJ.js")).registerSubscriptionsCommands(program);
110
110
  },
111
111
  iap: async () => {
112
112
  (await import("./iap-HDSHNFVG.js")).registerIapCommands(program);
@@ -302,4 +302,4 @@ export {
302
302
  createProgram,
303
303
  handleCliError
304
304
  };
305
- //# sourceMappingURL=chunk-NYGU5OUZ.js.map
305
+ //# sourceMappingURL=chunk-R3KI4HZ5.js.map
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  createProgram,
4
4
  handleCliError
5
- } from "./chunk-NYGU5OUZ.js";
5
+ } from "./chunk-R3KI4HZ5.js";
6
6
  export {
7
7
  createProgram,
8
8
  handleCliError
@@ -162,7 +162,7 @@ function registerListingsCommands(program) {
162
162
  process.exit(4);
163
163
  }
164
164
  });
165
- listings.command("pull").description("Download listings to Fastlane-format directory").option("--dir <path>", "Output directory", "metadata").action(async (options) => {
165
+ listings.command("pull").description("Download listings to Fastlane-format directory").option("--dir <path>", "Target directory (default: metadata)", "metadata").action(async (options) => {
166
166
  const config = await loadConfig();
167
167
  const packageName = resolvePackageName(program.opts()["app"], config);
168
168
  const client = await getClient(config);
@@ -184,7 +184,7 @@ function registerListingsCommands(program) {
184
184
  process.exit(4);
185
185
  }
186
186
  });
187
- listings.command("push").description("Upload listings from Fastlane-format directory").option("--dir <path>", "Source directory", "metadata").action(async (options) => {
187
+ listings.command("push").description("Upload listings from Fastlane-format directory").option("--dir <path>", "Source directory (default: metadata)", "metadata").action(async (options) => {
188
188
  const config = await loadConfig();
189
189
  const packageName = resolvePackageName(program.opts()["app"], config);
190
190
  const client = await getClient(config);
@@ -382,4 +382,4 @@ function registerListingsCommands(program) {
382
382
  export {
383
383
  registerListingsCommands
384
384
  };
385
- //# sourceMappingURL=listings-AKOLKWLW.js.map
385
+ //# sourceMappingURL=listings-S4CJ7EDX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/listings.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport type { GpcConfig } from \"@gpc-cli/config\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createApiClient } from \"@gpc-cli/api\";\nimport type { ImageType } from \"@gpc-cli/api\";\nimport {\n getListings,\n updateListing,\n deleteListing,\n pullListings,\n pushListings,\n diffListingsCommand,\n listImages,\n uploadImage,\n deleteImage,\n exportImages,\n getCountryAvailability,\n formatOutput,\n createSpinner,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { isInteractive, requireOption, requireConfirm } from \"../prompt.js\";\n\nfunction resolvePackageName(packageArg: string | undefined, config: GpcConfig): string {\n const name = packageArg || config.app;\n if (!name) {\n console.error(\"Error: No package name. Use --app <package> or gpc config set app <package>\");\n process.exit(2);\n }\n return name;\n}\n\nasync function getClient(config: GpcConfig) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createApiClient({ auth });\n}\n\nconst VALID_IMAGE_TYPES: ImageType[] = [\n \"phoneScreenshots\",\n \"sevenInchScreenshots\",\n \"tenInchScreenshots\",\n \"tvScreenshots\",\n \"wearScreenshots\",\n \"icon\",\n \"featureGraphic\",\n \"tvBanner\",\n];\n\nfunction validateImageType(type: string): ImageType {\n if (!VALID_IMAGE_TYPES.includes(type as ImageType)) {\n console.error(`Error: Invalid image type \"${type}\".`);\n console.error(`Valid types: ${VALID_IMAGE_TYPES.join(\", \")}`);\n process.exit(2);\n }\n return type as ImageType;\n}\n\nexport function registerListingsCommands(program: Command): void {\n const listings = program.command(\"listings\").description(\"Manage store listings and metadata\");\n\n // Get\n listings\n .command(\"get\")\n .description(\"Get store listing(s)\")\n .option(\"--lang <language>\", \"Language code (BCP 47)\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await getListings(client, packageName, options.lang);\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 // Update\n listings\n .command(\"update\")\n .description(\"Update a store listing\")\n .option(\"--lang <language>\", \"Language code (BCP 47)\")\n .option(\"--title <text>\", \"App title\")\n .option(\"--short <text>\", \"Short description\")\n .option(\"--full <text>\", \"Full description\")\n .option(\"--full-file <path>\", \"Read full description from file\")\n .option(\"--video <url>\", \"Video URL\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const interactive = isInteractive(program);\n\n options.lang = await requireOption(\n \"lang\",\n options.lang,\n {\n message: \"Language code (BCP 47):\",\n default: \"en-US\",\n },\n interactive,\n );\n const format = getOutputFormat(program, config);\n\n try {\n const data: Record<string, string> = {};\n if (options[\"title\"]) data[\"title\"] = options[\"title\"];\n if (options[\"short\"]) data[\"shortDescription\"] = options[\"short\"];\n if (options[\"full\"]) data[\"fullDescription\"] = options[\"full\"];\n if (options[\"fullFile\"]) {\n const { readFile } = await import(\"node:fs/promises\");\n data[\"fullDescription\"] = (await readFile(options[\"fullFile\"], \"utf-8\")).trimEnd();\n }\n if (options[\"video\"]) data[\"video\"] = options[\"video\"];\n\n if (Object.keys(data).length === 0) {\n console.error(\n \"Error: Provide at least one field to update (--title, --short, --full, --full-file, --video).\",\n );\n process.exit(2);\n }\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"listings update\",\n action: \"update listing for\",\n target: options.lang,\n details: data,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n const result = await updateListing(client, packageName, options.lang, data);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Delete\n listings\n .command(\"delete\")\n .description(\"Delete a store listing for a language\")\n .option(\"--lang <language>\", \"Language code (BCP 47)\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const interactive = isInteractive(program);\n\n options.lang = await requireOption(\n \"lang\",\n options.lang,\n {\n message: \"Language code (BCP 47):\",\n },\n interactive,\n );\n\n await requireConfirm(`Delete listing for \"${options.lang}\"?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"listings delete\",\n action: \"delete listing for\",\n target: options.lang,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await deleteListing(client, packageName, options.lang);\n console.log(`Listing for \"${options.lang}\" deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Pull\n listings\n .command(\"pull\")\n .description(\"Download listings to Fastlane-format directory\")\n .option(\"--dir <path>\", \"Target directory (default: metadata)\", \"metadata\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await pullListings(client, packageName, options.dir);\n console.log(\n formatOutput(\n {\n directory: options.dir,\n languages: result.listings.map((l) => l.language),\n count: result.listings.length,\n },\n format,\n ),\n );\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Push\n listings\n .command(\"push\")\n .description(\"Upload listings from Fastlane-format directory\")\n .option(\"--dir <path>\", \"Source directory (default: metadata)\", \"metadata\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n const spinner = createSpinner(\"Pushing listings...\");\n if (!program.opts()[\"quiet\"] && process.stderr.isTTY) spinner.start();\n\n try {\n const result = await pushListings(client, packageName, options.dir, {\n dryRun: isDryRun(program),\n });\n spinner.stop(\"Listings pushed\");\n console.log(formatOutput(result, format));\n } catch (error) {\n spinner.fail(\"Push failed\");\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Diff\n listings\n .command(\"diff\")\n .description(\"Compare local Fastlane-format metadata against remote listings\")\n .option(\"--dir <path>\", \"Local metadata directory\", \"metadata\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const diffs = await diffListingsCommand(client, packageName, options.dir);\n\n if (diffs.length === 0) {\n if (format === \"json\") {\n console.log(formatOutput([], format));\n } else {\n console.log(\"No differences found.\");\n }\n return;\n }\n\n if (format === \"json\") {\n console.log(formatOutput(diffs, format));\n } else {\n for (const diff of diffs) {\n console.log(`[${diff.language}] ${diff.field}:`);\n console.log(` local: ${diff.local || \"(empty)\"}`);\n console.log(` remote: ${diff.remote || \"(empty)\"}`);\n }\n }\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Images subcommand\n const images = listings.command(\"images\").description(\"Manage listing images\");\n\n // Images list\n images\n .command(\"list\")\n .description(\"List images for a language and type\")\n .option(\"--lang <language>\", \"Language code (BCP 47)\")\n .option(\"--type <type>\", \"Image type\")\n .option(\"--limit <n>\", \"Maximum results to return\")\n .option(\"--next-page <token>\", \"Pagination token for next page\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const interactive = isInteractive(program);\n\n options.lang = await requireOption(\n \"lang\",\n options.lang,\n {\n message: \"Language code (BCP 47):\",\n default: \"en-US\",\n },\n interactive,\n );\n\n options.type = await requireOption(\n \"type\",\n options.type,\n {\n message: \"Image type:\",\n choices: VALID_IMAGE_TYPES as unknown as string[],\n },\n interactive,\n );\n\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n const imageType = validateImageType(options.type);\n\n try {\n const result = await listImages(client, packageName, options.lang, imageType);\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 // Images upload\n images\n .command(\"upload <file>\")\n .description(\"Upload an image\")\n .option(\"--lang <language>\", \"Language code (BCP 47)\")\n .option(\"--type <type>\", \"Image type\")\n .action(async (file: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const interactive = isInteractive(program);\n\n options.lang = await requireOption(\n \"lang\",\n options.lang,\n {\n message: \"Language code (BCP 47):\",\n default: \"en-US\",\n },\n interactive,\n );\n\n options.type = await requireOption(\n \"type\",\n options.type,\n {\n message: \"Image type:\",\n choices: VALID_IMAGE_TYPES as unknown as string[],\n },\n interactive,\n );\n\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n const imageType = validateImageType(options.type);\n\n const spinner = createSpinner(\"Uploading image...\");\n if (!program.opts()[\"quiet\"] && process.stderr.isTTY) spinner.start();\n\n try {\n const result = await uploadImage(client, packageName, options.lang, imageType, file);\n spinner.stop(\"Image uploaded\");\n console.log(formatOutput(result, format));\n } catch (error) {\n spinner.fail(\"Image upload failed\");\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Images delete\n images\n .command(\"delete\")\n .description(\"Delete an image\")\n .option(\"--lang <language>\", \"Language code (BCP 47)\")\n .option(\"--type <type>\", \"Image type\")\n .option(\"--id <imageId>\", \"Image ID to delete\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const interactive = isInteractive(program);\n\n options.lang = await requireOption(\n \"lang\",\n options.lang,\n {\n message: \"Language code (BCP 47):\",\n },\n interactive,\n );\n\n options.type = await requireOption(\n \"type\",\n options.type,\n {\n message: \"Image type:\",\n choices: VALID_IMAGE_TYPES as unknown as string[],\n },\n interactive,\n );\n\n options.id = await requireOption(\n \"id\",\n options.id,\n {\n message: \"Image ID to delete:\",\n },\n interactive,\n );\n\n await requireConfirm(`Delete image \"${options.id}\"?`, program);\n\n const client = await getClient(config);\n const imageType = validateImageType(options.type);\n\n try {\n await deleteImage(client, packageName, options.lang, imageType, options.id);\n console.log(`Image \"${options.id}\" deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Images export\n images\n .command(\"export\")\n .description(\"Export all images to a local directory\")\n .option(\"--dir <path>\", \"Output directory\", \"images\")\n .option(\"--lang <language>\", \"Language code (BCP 47) — export only this language\")\n .option(\"--type <type>\", \"Image type — export only this type\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n const exportOpts: { lang?: string; type?: ImageType } = {};\n if (options.lang) exportOpts.lang = options.lang;\n if (options.type) {\n exportOpts.type = validateImageType(options.type);\n }\n\n const spinner = createSpinner(\"Exporting images...\");\n if (!program.opts()[\"quiet\"] && process.stderr.isTTY) spinner.start();\n\n try {\n const result = await exportImages(client, packageName, options.dir, exportOpts);\n spinner.stop(\"Images exported\");\n console.log(formatOutput(result, format));\n } catch (error) {\n spinner.fail(\"Image export failed\");\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Availability\n listings\n .command(\"availability\")\n .description(\"Get country availability for a track\")\n .option(\"--track <track>\", \"Track name\", \"production\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await getCountryAvailability(client, packageName, options.track);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n}\n"],"mappings":"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","names":[]}
@@ -52,6 +52,10 @@ function registerReviewsCommands(program) {
52
52
  limit: options.limit,
53
53
  nextPage: options.nextPage
54
54
  });
55
+ if (Array.isArray(result) && result.length === 0 && format !== "json") {
56
+ console.log("No reviews found.");
57
+ return;
58
+ }
55
59
  const sorted = sortResults(result, options.sort);
56
60
  console.log(formatOutput(sorted, format));
57
61
  } catch (error) {
@@ -135,4 +139,4 @@ function registerReviewsCommands(program) {
135
139
  export {
136
140
  registerReviewsCommands
137
141
  };
138
- //# sourceMappingURL=reviews-6V3DO4NB.js.map
142
+ //# sourceMappingURL=reviews-PMUJVNVC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/reviews.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport type { GpcConfig } from \"@gpc-cli/config\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createApiClient } from \"@gpc-cli/api\";\nimport {\n listReviews,\n getReview,\n replyToReview,\n exportReviews,\n formatOutput,\n sortResults,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { isInteractive, requireOption } from \"../prompt.js\";\n\nfunction resolvePackageName(packageArg: string | undefined, config: GpcConfig): string {\n const name = packageArg || config.app;\n if (!name) {\n console.error(\"Error: No package name. Use --app <package> or gpc config set app <package>\");\n process.exit(2);\n }\n return name;\n}\n\nasync function getClient(config: GpcConfig) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createApiClient({ auth });\n}\n\nexport function registerReviewsCommands(program: Command): void {\n const reviews = program.command(\"reviews\").description(\"Manage user reviews and ratings\");\n\n reviews\n .command(\"list\")\n .description(\"List user reviews\")\n .option(\"--stars <n>\", \"Filter by star rating (1-5)\", parseInt)\n .option(\"--lang <code>\", \"Filter by reviewer language\")\n .option(\"--since <date>\", \"Filter reviews after date (ISO 8601)\")\n .option(\"--translate-to <lang>\", \"Translate reviews to language\")\n .option(\"--max <n>\", \"Maximum number of reviews per page\", parseInt)\n .option(\"--limit <n>\", \"Maximum total results\", parseInt)\n .option(\"--next-page <token>\", \"Resume from page token\")\n .option(\"--sort <field>\", \"Sort by field (prefix with - for descending)\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await listReviews(client, packageName, {\n stars: options.stars,\n language: options.lang,\n since: options.since,\n translationLanguage: options.translateTo,\n maxResults: options.max,\n limit: options.limit,\n nextPage: options.nextPage,\n });\n if (Array.isArray(result) && result.length === 0 && format !== \"json\") {\n console.log(\"No reviews found.\");\n return;\n }\n const sorted = sortResults(result, options.sort);\n console.log(formatOutput(sorted, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n reviews\n .command(\"get <review-id>\")\n .description(\"Get a single review\")\n .option(\"--translate-to <lang>\", \"Translate review to language\")\n .action(async (reviewId: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await getReview(client, packageName, reviewId, options.translateTo);\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 reviews\n .command(\"reply <review-id>\")\n .description(\"Reply to a review\")\n .option(\"--text <text>\", \"Reply text (max 350 chars)\")\n .action(async (reviewId: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n const interactive = isInteractive(program);\n\n options.text = await requireOption(\n \"text\",\n options.text,\n {\n message: \"Reply text (max 350 chars):\",\n },\n interactive,\n );\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"reviews reply\",\n action: \"reply to\",\n target: reviewId,\n details: { text: options.text },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await replyToReview(client, packageName, reviewId, options.text);\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 reviews\n .command(\"export\")\n .description(\"Export reviews to JSON or CSV\")\n .option(\"--format <type>\", \"Output format: json or csv\", \"json\")\n .option(\"--stars <n>\", \"Filter by star rating (1-5)\", parseInt)\n .option(\"--lang <code>\", \"Filter by reviewer language\")\n .option(\"--since <date>\", \"Filter reviews after date (ISO 8601)\")\n .option(\"--translate-to <lang>\", \"Translate reviews to language\")\n .option(\"--output <file>\", \"Write output to file instead of stdout\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n\n try {\n const result = await exportReviews(client, packageName, {\n format: options.format as \"json\" | \"csv\",\n stars: options.stars,\n language: options.lang,\n since: options.since,\n translationLanguage: options.translateTo,\n });\n\n if (options.output) {\n const { writeFile } = await import(\"node:fs/promises\");\n await writeFile(options.output, result, \"utf-8\");\n console.log(`Reviews exported to ${options.output}`);\n } else {\n console.log(result);\n }\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":[]}
@@ -84,7 +84,7 @@ function registerSubscriptionsCommands(program) {
84
84
  process.exit(4);
85
85
  }
86
86
  });
87
- subs.command("create").description("Create a subscription from JSON file").requiredOption("--file <path>", "JSON file with subscription data").action(async (options) => {
87
+ subs.command("create").description("Create a subscription from JSON file").requiredOption("--file <path>", "JSON file with subscription data").option("--activate", "Activate all base plans after creation").action(async (options) => {
88
88
  const config = await loadConfig();
89
89
  const packageName = resolvePackageName(program.opts()["app"], config);
90
90
  const format = getOutputFormat(program, config);
@@ -93,7 +93,8 @@ function registerSubscriptionsCommands(program) {
93
93
  {
94
94
  command: "subscriptions create",
95
95
  action: "create",
96
- target: `subscription from ${options.file}`
96
+ target: `subscription from ${options.file}`,
97
+ details: options.activate ? { activate: true } : void 0
97
98
  },
98
99
  format,
99
100
  formatOutput
@@ -104,7 +105,18 @@ function registerSubscriptionsCommands(program) {
104
105
  try {
105
106
  const data = JSON.parse(await readFile(options.file, "utf-8"));
106
107
  const result = await createSubscription(client, packageName, data);
107
- console.log(formatOutput(result, format));
108
+ if (options.activate && result.basePlans) {
109
+ for (const bp of result.basePlans) {
110
+ if (bp.state === "DRAFT") {
111
+ await activateBasePlan(client, packageName, result.productId, bp.basePlanId);
112
+ console.error(`Activated base plan: ${bp.basePlanId}`);
113
+ }
114
+ }
115
+ const updated = await getSubscription(client, packageName, result.productId);
116
+ console.log(formatOutput(updated, format));
117
+ } else {
118
+ console.log(formatOutput(result, format));
119
+ }
108
120
  } catch (error) {
109
121
  console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
110
122
  process.exit(4);
@@ -451,4 +463,4 @@ function registerSubscriptionsCommands(program) {
451
463
  export {
452
464
  registerSubscriptionsCommands
453
465
  };
454
- //# sourceMappingURL=subscriptions-L4YWMG3F.js.map
466
+ //# sourceMappingURL=subscriptions-SF4LBZDJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/subscriptions.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport type { GpcConfig } from \"@gpc-cli/config\";\nimport type { Command } from \"commander\";\nimport { Option } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createApiClient } from \"@gpc-cli/api\";\nimport {\n listSubscriptions,\n getSubscription,\n createSubscription,\n updateSubscription,\n deleteSubscription,\n activateBasePlan,\n deactivateBasePlan,\n deleteBasePlan,\n migratePrices,\n listOffers,\n getOffer,\n createOffer,\n updateOffer,\n deleteOffer,\n activateOffer,\n deactivateOffer,\n formatOutput,\n sortResults,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { requireConfirm } from \"../prompt.js\";\n\nfunction resolvePackageName(packageArg: string | undefined, config: GpcConfig): string {\n const name = packageArg || config.app;\n if (!name) {\n console.error(\"Error: No package name. Use --app <package> or gpc config set app <package>\");\n process.exit(2);\n }\n return name;\n}\n\nasync function getClient(config: GpcConfig) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createApiClient({ auth });\n}\n\nexport function registerSubscriptionsCommands(program: Command): void {\n const subs = program.command(\"subscriptions\").description(\"Manage subscriptions and base plans\");\n\n subs\n .command(\"list\")\n .description(\"List subscriptions\")\n .addOption(new Option(\"--page-size <n>\", \"Results per page\").argParser(parseInt).hideHelp())\n .addOption(new Option(\"--page-token <token>\", \"Page token\").hideHelp())\n .option(\"--limit <n>\", \"Maximum total results\", parseInt)\n .option(\"--next-page <token>\", \"Resume from page token\")\n .option(\"--sort <field>\", \"Sort by field (prefix with - for descending)\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await listSubscriptions(client, packageName, {\n pageSize: options.pageSize,\n pageToken: options.pageToken,\n limit: options.limit,\n nextPage: options.nextPage,\n });\n if (options.sort) {\n result.subscriptions = sortResults(result.subscriptions, options.sort);\n }\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n subs\n .command(\"get <product-id>\")\n .description(\"Get a subscription\")\n .action(async (productId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await getSubscription(client, packageName, productId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n subs\n .command(\"create\")\n .description(\"Create a subscription from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with subscription data\")\n .option(\"--activate\", \"Activate all base plans after creation\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions create\",\n action: \"create\",\n target: `subscription from ${options.file}`,\n details: options.activate ? { activate: true } : undefined,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await createSubscription(client, packageName, data);\n\n if (options.activate && result.basePlans) {\n for (const bp of result.basePlans) {\n if (bp.state === \"DRAFT\") {\n await activateBasePlan(client, packageName, result.productId, bp.basePlanId);\n console.error(`Activated base plan: ${bp.basePlanId}`);\n }\n }\n // Re-fetch to get updated state\n const updated = await getSubscription(client, packageName, result.productId);\n console.log(formatOutput(updated, format));\n } else {\n console.log(formatOutput(result, format));\n }\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n subs\n .command(\"update <product-id>\")\n .description(\"Update a subscription from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with subscription data\")\n .option(\"--update-mask <fields>\", \"Comma-separated field mask\")\n .action(async (productId: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions update\",\n action: \"update\",\n target: productId,\n details: { file: options.file, updateMask: options.updateMask },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await updateSubscription(\n client,\n packageName,\n productId,\n data,\n options.updateMask,\n );\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n subs\n .command(\"delete <product-id>\")\n .description(\"Delete a subscription\")\n .action(async (productId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Delete subscription \"${productId}\"?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"subscriptions delete\",\n action: \"delete\",\n target: productId,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await deleteSubscription(client, packageName, productId);\n console.log(`Subscription ${productId} deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // --- Base Plans ---\n const basePlans = subs.command(\"base-plans\").description(\"Manage base plans\");\n\n basePlans\n .command(\"activate <product-id> <base-plan-id>\")\n .description(\"Activate a base plan\")\n .action(async (productId: string, basePlanId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions base-plans activate\",\n action: \"activate\",\n target: `${productId}/${basePlanId}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await activateBasePlan(client, packageName, productId, basePlanId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n basePlans\n .command(\"deactivate <product-id> <base-plan-id>\")\n .description(\"Deactivate a base plan\")\n .action(async (productId: string, basePlanId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions base-plans deactivate\",\n action: \"deactivate\",\n target: `${productId}/${basePlanId}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await deactivateBasePlan(client, packageName, productId, basePlanId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n basePlans\n .command(\"delete <product-id> <base-plan-id>\")\n .description(\"Delete a base plan\")\n .action(async (productId: string, basePlanId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(\n `Delete base plan \"${basePlanId}\" from subscription \"${productId}\"?`,\n program,\n );\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"subscriptions base-plans delete\",\n action: \"delete\",\n target: `${productId}/${basePlanId}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await deleteBasePlan(client, packageName, productId, basePlanId);\n console.log(`Base plan ${basePlanId} deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n basePlans\n .command(\"migrate-prices <product-id> <base-plan-id>\")\n .description(\"Migrate base plan prices\")\n .requiredOption(\"--file <path>\", \"JSON file with migration data\")\n .action(\n async (\n productId: string,\n basePlanId: string,\n options: { file: string; updateMask?: string },\n ) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions base-plans migrate-prices\",\n action: \"migrate prices for\",\n target: `${productId}/${basePlanId}`,\n details: { file: options.file },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await migratePrices(client, packageName, productId, basePlanId, data);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n },\n );\n\n // --- Offers ---\n const offers = subs.command(\"offers\").description(\"Manage subscription offers\");\n\n offers\n .command(\"list <product-id> <base-plan-id>\")\n .description(\"List offers for a base plan\")\n .action(async (productId: string, basePlanId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await listOffers(client, packageName, productId, basePlanId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"get <product-id> <base-plan-id> <offer-id>\")\n .description(\"Get an offer\")\n .action(async (productId: string, basePlanId: string, offerId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await getOffer(client, packageName, productId, basePlanId, offerId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"create <product-id> <base-plan-id>\")\n .description(\"Create an offer from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with offer data\")\n .action(\n async (\n productId: string,\n basePlanId: string,\n options: { file: string; updateMask?: string },\n ) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions offers create\",\n action: \"create offer for\",\n target: `${productId}/${basePlanId}`,\n details: { file: options.file },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await createOffer(client, packageName, productId, basePlanId, data);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n },\n );\n\n offers\n .command(\"update <product-id> <base-plan-id> <offer-id>\")\n .description(\"Update an offer from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with offer data\")\n .option(\"--update-mask <fields>\", \"Comma-separated field mask\")\n .action(\n async (\n productId: string,\n basePlanId: string,\n offerId: string,\n options: { file: string; updateMask?: string },\n ) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions offers update\",\n action: \"update offer\",\n target: `${productId}/${basePlanId}/${offerId}`,\n details: { file: options.file, updateMask: options.updateMask },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await updateOffer(\n client,\n packageName,\n productId,\n basePlanId,\n offerId,\n data,\n options.updateMask,\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\n offers\n .command(\"delete <product-id> <base-plan-id> <offer-id>\")\n .description(\"Delete an offer\")\n .action(async (productId: string, basePlanId: string, offerId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Delete offer \"${offerId}\"?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"subscriptions offers delete\",\n action: \"delete offer\",\n target: `${productId}/${basePlanId}/${offerId}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await deleteOffer(client, packageName, productId, basePlanId, offerId);\n console.log(`Offer ${offerId} deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"activate <product-id> <base-plan-id> <offer-id>\")\n .description(\"Activate an offer\")\n .action(async (productId: string, basePlanId: string, offerId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions offers activate\",\n action: \"activate offer\",\n target: `${productId}/${basePlanId}/${offerId}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await activateOffer(client, packageName, productId, basePlanId, offerId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"deactivate <product-id> <base-plan-id> <offer-id>\")\n .description(\"Deactivate an offer\")\n .action(async (productId: string, basePlanId: string, offerId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions offers deactivate\",\n action: \"deactivate offer\",\n target: `${productId}/${basePlanId}/${offerId}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await deactivateOffer(client, packageName, productId, basePlanId, offerId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n}\n"],"mappings":"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","names":[]}
@@ -93,6 +93,10 @@ function registerVitalsCommands(program) {
93
93
  const format = getOutputFormat(program, config);
94
94
  try {
95
95
  const result = await getVitalsOverview(reporting, packageName);
96
+ if (format !== "json" && Object.keys(result).length === 0) {
97
+ console.log("No vitals data available.");
98
+ return;
99
+ }
96
100
  console.log(formatOutput(result, format));
97
101
  } catch (error) {
98
102
  console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
@@ -179,4 +183,4 @@ function registerVitalsCommands(program) {
179
183
  export {
180
184
  registerVitalsCommands
181
185
  };
182
- //# sourceMappingURL=vitals-I6FKKKPO.js.map
186
+ //# sourceMappingURL=vitals-EOHSUQJM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/vitals.ts"],"sourcesContent":["import 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 } 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 formatOutput,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\n\nfunction resolvePackageName(packageArg: string | undefined, config: GpcConfig): 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: GpcConfig) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createReportingClient({ auth });\n}\n\nconst VALID_DIMENSIONS: ReportingDimension[] = [\n \"apiLevel\",\n \"versionCode\",\n \"deviceModel\",\n \"deviceType\",\n \"countryCode\",\n \"deviceRamBucket\",\n \"deviceSocName\",\n \"deviceCpuMakeModel\",\n \"deviceGlEsVersion\",\n \"deviceVulkanVersion\",\n \"deviceOpenGlVersion\",\n \"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 = getOutputFormat(program, config);\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 = getOutputFormat(program, config);\n\n try {\n const result = await getVitalsOverview(reporting, packageName);\n if (format !== \"json\" && Object.keys(result).length === 0) {\n console.log(\"No vitals data available.\");\n return;\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 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(\n vitals,\n \"rendering\",\n \"Query slow rendering metrics\",\n getVitalsRendering,\n program,\n );\n registerMetricCommand(\n vitals,\n \"battery\",\n \"Query excessive wakeup metrics\",\n getVitalsBattery,\n program,\n );\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 = getOutputFormat(program, config);\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.command(\"errors\").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 = getOutputFormat(program, config);\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(\n `Error: Unknown metric \"${metric}\". Use: ${Object.keys(METRIC_MAP).join(\", \")}`,\n );\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 = getOutputFormat(program, config);\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":";;;;;;AAEA,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,6BAA6B;AAGtC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,mBAAmB,YAAgC,QAA2B;AACrF,QAAM,OAAO,cAAc,OAAO;AAClC,MAAI,CAAC,MAAM;AACT,YAAQ,MAAM,6EAA6E;AAC3F,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,SAAO;AACT;AAEA,eAAe,mBAAmB,QAAmB;AACnD,QAAM,OAAO,MAAM,YAAY,EAAE,oBAAoB,OAAO,MAAM,eAAe,CAAC;AAClF,SAAO,sBAAsB,EAAE,KAAK,CAAC;AACvC;AAEA,IAAM,mBAAyC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,kBAAkB,KAAiC;AAC1D,MAAI,CAAC,iBAAiB,SAAS,GAAyB,GAAG;AACzD,YAAQ,MAAM,6BAA6B,GAAG,IAAI;AAClD,YAAQ,MAAM,qBAAqB,iBAAiB,KAAK,IAAI,CAAC,EAAE;AAChE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,SAAO;AACT;AAIA,SAAS,sBACP,QACA,MACA,aACA,IACA,SACM;AACN,SACG,QAAQ,IAAI,EACZ,YAAY,WAAW,EACvB,OAAO,qBAAqB,oBAAoB,EAChD,OAAO,cAAc,2BAA2B,QAAQ,EACxD,OAAO,uBAAuB,mCAAmC,UAAU,EAC3E,OAAO,OAAO,YAAY;AACzB,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;AACF,YAAM,SAAS,MAAM,GAAG,WAAW,aAAa;AAAA,QAC9C,WAAW,QAAQ,MAAM,kBAAkB,QAAQ,GAAG,IAAI;AAAA,QAC1D,MAAM,QAAQ;AAAA,MAChB,CAAC;AACD,cAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAExC,UAAI,QAAQ,cAAc,QAAW;AACnC,cAAM,YAAY,OAAO,OAAO,OAAO,KAAK,SAAS,CAAC;AACtD,cAAM,aAAa,WAAW,UAAU,OAAO,KAAK,UAAU,OAAO,IAAI,CAAC;AAC1E,cAAM,cAAc,WAAW,CAAC;AAChC,cAAM,QAAQ,cACV,OAAO,WAAW,QAAQ,WAAW,GAAG,cAAc,KAAK,IAC3D;AACJ,cAAM,QAAQ,eAAe,OAAO,QAAQ,SAAS;AACrD,YAAI,MAAM,UAAU;AAClB,kBAAQ,MAAM,uBAAuB,MAAM,KAAK,MAAM,MAAM,SAAS,EAAE;AACvE,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAChF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;AAEO,SAAS,uBAAuB,SAAwB;AAC7D,QAAM,SAAS,QACZ,QAAQ,QAAQ,EAChB,YAAY,0DAA0D;AAEzE,SACG,QAAQ,UAAU,EAClB,YAAY,wCAAwC,EACpD,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;AACF,YAAM,SAAS,MAAM,kBAAkB,WAAW,WAAW;AAC7D,UAAI,WAAW,UAAU,OAAO,KAAK,MAAM,EAAE,WAAW,GAAG;AACzD,gBAAQ,IAAI,2BAA2B;AACvC;AAAA,MACF;AACA,cAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,IAC1C,SAAS,OAAO;AACd,cAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAChF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,wBAAsB,QAAQ,WAAW,4BAA4B,kBAAkB,OAAO;AAC9F,wBAAsB,QAAQ,OAAO,0BAA0B,cAAc,OAAO;AACpF,wBAAsB,QAAQ,WAAW,8BAA8B,kBAAkB,OAAO;AAChG;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,wBAAsB,QAAQ,UAAU,gCAAgC,iBAAiB,OAAO;AAEhG,SACG,QAAQ,WAAW,EACnB,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;AACF,YAAM,SAAS,MAAM,mBAAmB,WAAW,WAAW;AAC9D,cAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,IAC1C,SAAS,OAAO;AACd,cAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAChF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,QAAM,SAAS,OAAO,QAAQ,QAAQ,EAAE,YAAY,8BAA8B;AAElF,SACG,QAAQ,QAAQ,EAChB,YAAY,qBAAqB,EACjC,OAAO,mBAAmB,mBAAmB,EAC7C,OAAO,aAAa,mBAAmB,QAAQ,EAC/C,OAAO,OAAO,YAAY;AACzB,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;AACF,YAAM,SAAS,MAAM,mBAAmB,WAAW,aAAa;AAAA,QAC9D,QAAQ,QAAQ;AAAA,QAChB,YAAY,QAAQ;AAAA,MACtB,CAAC;AACD,cAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,IAC1C,SAAS,OAAO;AACd,cAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAChF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,QAAM,aAA8C;AAAA,IAClD,SAAS;AAAA,IACT,KAAK;AAAA,IACL,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;AAEA,SACG,QAAQ,kBAAkB,EAC1B,YAAY,sDAAsD,EAClE,OAAO,cAAc,yBAAyB,UAAU,CAAC,EACzD,OAAO,OAAO,QAAgB,YAAY;AACzC,UAAM,YAAY,WAAW,MAAM;AACnC,QAAI,CAAC,WAAW;AACd,cAAQ;AAAA,QACN,0BAA0B,MAAM,WAAW,OAAO,KAAK,UAAU,EAAE,KAAK,IAAI,CAAC;AAAA,MAC/E;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,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;AACF,YAAM,SAAS,MAAM,mBAAmB,WAAW,aAAa,WAAW,QAAQ,IAAI;AACvF,cAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,IAC1C,SAAS,OAAO;AACd,cAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAChF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gpc-cli/cli",
3
- "version": "0.9.16",
3
+ "version": "0.9.18",
4
4
  "description": "The complete Google Play CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,11 +19,11 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "commander": "^14.0.3",
22
- "@gpc-cli/auth": "^0.9.9",
23
- "@gpc-cli/api": "1.0.12",
24
- "@gpc-cli/config": "0.9.8",
22
+ "@gpc-cli/api": "1.0.14",
23
+ "@gpc-cli/core": "0.9.16",
25
24
  "@gpc-cli/plugin-sdk": "0.9.6",
26
- "@gpc-cli/core": "0.9.14"
25
+ "@gpc-cli/auth": "^0.9.9",
26
+ "@gpc-cli/config": "0.9.8"
27
27
  },
28
28
  "keywords": [
29
29
  "google-play",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/listings.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport type { GpcConfig } from \"@gpc-cli/config\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createApiClient } from \"@gpc-cli/api\";\nimport type { ImageType } from \"@gpc-cli/api\";\nimport {\n getListings,\n updateListing,\n deleteListing,\n pullListings,\n pushListings,\n diffListingsCommand,\n listImages,\n uploadImage,\n deleteImage,\n exportImages,\n getCountryAvailability,\n formatOutput,\n createSpinner,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { isInteractive, requireOption, requireConfirm } from \"../prompt.js\";\n\nfunction resolvePackageName(packageArg: string | undefined, config: GpcConfig): string {\n const name = packageArg || config.app;\n if (!name) {\n console.error(\"Error: No package name. Use --app <package> or gpc config set app <package>\");\n process.exit(2);\n }\n return name;\n}\n\nasync function getClient(config: GpcConfig) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createApiClient({ auth });\n}\n\nconst VALID_IMAGE_TYPES: ImageType[] = [\n \"phoneScreenshots\",\n \"sevenInchScreenshots\",\n \"tenInchScreenshots\",\n \"tvScreenshots\",\n \"wearScreenshots\",\n \"icon\",\n \"featureGraphic\",\n \"tvBanner\",\n];\n\nfunction validateImageType(type: string): ImageType {\n if (!VALID_IMAGE_TYPES.includes(type as ImageType)) {\n console.error(`Error: Invalid image type \"${type}\".`);\n console.error(`Valid types: ${VALID_IMAGE_TYPES.join(\", \")}`);\n process.exit(2);\n }\n return type as ImageType;\n}\n\nexport function registerListingsCommands(program: Command): void {\n const listings = program.command(\"listings\").description(\"Manage store listings and metadata\");\n\n // Get\n listings\n .command(\"get\")\n .description(\"Get store listing(s)\")\n .option(\"--lang <language>\", \"Language code (BCP 47)\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await getListings(client, packageName, options.lang);\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 // Update\n listings\n .command(\"update\")\n .description(\"Update a store listing\")\n .option(\"--lang <language>\", \"Language code (BCP 47)\")\n .option(\"--title <text>\", \"App title\")\n .option(\"--short <text>\", \"Short description\")\n .option(\"--full <text>\", \"Full description\")\n .option(\"--full-file <path>\", \"Read full description from file\")\n .option(\"--video <url>\", \"Video URL\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const interactive = isInteractive(program);\n\n options.lang = await requireOption(\n \"lang\",\n options.lang,\n {\n message: \"Language code (BCP 47):\",\n default: \"en-US\",\n },\n interactive,\n );\n const format = getOutputFormat(program, config);\n\n try {\n const data: Record<string, string> = {};\n if (options[\"title\"]) data[\"title\"] = options[\"title\"];\n if (options[\"short\"]) data[\"shortDescription\"] = options[\"short\"];\n if (options[\"full\"]) data[\"fullDescription\"] = options[\"full\"];\n if (options[\"fullFile\"]) {\n const { readFile } = await import(\"node:fs/promises\");\n data[\"fullDescription\"] = (await readFile(options[\"fullFile\"], \"utf-8\")).trimEnd();\n }\n if (options[\"video\"]) data[\"video\"] = options[\"video\"];\n\n if (Object.keys(data).length === 0) {\n console.error(\n \"Error: Provide at least one field to update (--title, --short, --full, --full-file, --video).\",\n );\n process.exit(2);\n }\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"listings update\",\n action: \"update listing for\",\n target: options.lang,\n details: data,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n const result = await updateListing(client, packageName, options.lang, data);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Delete\n listings\n .command(\"delete\")\n .description(\"Delete a store listing for a language\")\n .option(\"--lang <language>\", \"Language code (BCP 47)\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const interactive = isInteractive(program);\n\n options.lang = await requireOption(\n \"lang\",\n options.lang,\n {\n message: \"Language code (BCP 47):\",\n },\n interactive,\n );\n\n await requireConfirm(`Delete listing for \"${options.lang}\"?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"listings delete\",\n action: \"delete listing for\",\n target: options.lang,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await deleteListing(client, packageName, options.lang);\n console.log(`Listing for \"${options.lang}\" deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Pull\n listings\n .command(\"pull\")\n .description(\"Download listings to Fastlane-format directory\")\n .option(\"--dir <path>\", \"Output directory\", \"metadata\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await pullListings(client, packageName, options.dir);\n console.log(\n formatOutput(\n {\n directory: options.dir,\n languages: result.listings.map((l) => l.language),\n count: result.listings.length,\n },\n format,\n ),\n );\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Push\n listings\n .command(\"push\")\n .description(\"Upload listings from Fastlane-format directory\")\n .option(\"--dir <path>\", \"Source directory\", \"metadata\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n const spinner = createSpinner(\"Pushing listings...\");\n if (!program.opts()[\"quiet\"] && process.stderr.isTTY) spinner.start();\n\n try {\n const result = await pushListings(client, packageName, options.dir, {\n dryRun: isDryRun(program),\n });\n spinner.stop(\"Listings pushed\");\n console.log(formatOutput(result, format));\n } catch (error) {\n spinner.fail(\"Push failed\");\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Diff\n listings\n .command(\"diff\")\n .description(\"Compare local Fastlane-format metadata against remote listings\")\n .option(\"--dir <path>\", \"Local metadata directory\", \"metadata\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const diffs = await diffListingsCommand(client, packageName, options.dir);\n\n if (diffs.length === 0) {\n if (format === \"json\") {\n console.log(formatOutput([], format));\n } else {\n console.log(\"No differences found.\");\n }\n return;\n }\n\n if (format === \"json\") {\n console.log(formatOutput(diffs, format));\n } else {\n for (const diff of diffs) {\n console.log(`[${diff.language}] ${diff.field}:`);\n console.log(` local: ${diff.local || \"(empty)\"}`);\n console.log(` remote: ${diff.remote || \"(empty)\"}`);\n }\n }\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Images subcommand\n const images = listings.command(\"images\").description(\"Manage listing images\");\n\n // Images list\n images\n .command(\"list\")\n .description(\"List images for a language and type\")\n .option(\"--lang <language>\", \"Language code (BCP 47)\")\n .option(\"--type <type>\", \"Image type\")\n .option(\"--limit <n>\", \"Maximum results to return\")\n .option(\"--next-page <token>\", \"Pagination token for next page\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const interactive = isInteractive(program);\n\n options.lang = await requireOption(\n \"lang\",\n options.lang,\n {\n message: \"Language code (BCP 47):\",\n default: \"en-US\",\n },\n interactive,\n );\n\n options.type = await requireOption(\n \"type\",\n options.type,\n {\n message: \"Image type:\",\n choices: VALID_IMAGE_TYPES as unknown as string[],\n },\n interactive,\n );\n\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n const imageType = validateImageType(options.type);\n\n try {\n const result = await listImages(client, packageName, options.lang, imageType);\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 // Images upload\n images\n .command(\"upload <file>\")\n .description(\"Upload an image\")\n .option(\"--lang <language>\", \"Language code (BCP 47)\")\n .option(\"--type <type>\", \"Image type\")\n .action(async (file: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const interactive = isInteractive(program);\n\n options.lang = await requireOption(\n \"lang\",\n options.lang,\n {\n message: \"Language code (BCP 47):\",\n default: \"en-US\",\n },\n interactive,\n );\n\n options.type = await requireOption(\n \"type\",\n options.type,\n {\n message: \"Image type:\",\n choices: VALID_IMAGE_TYPES as unknown as string[],\n },\n interactive,\n );\n\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n const imageType = validateImageType(options.type);\n\n const spinner = createSpinner(\"Uploading image...\");\n if (!program.opts()[\"quiet\"] && process.stderr.isTTY) spinner.start();\n\n try {\n const result = await uploadImage(client, packageName, options.lang, imageType, file);\n spinner.stop(\"Image uploaded\");\n console.log(formatOutput(result, format));\n } catch (error) {\n spinner.fail(\"Image upload failed\");\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Images delete\n images\n .command(\"delete\")\n .description(\"Delete an image\")\n .option(\"--lang <language>\", \"Language code (BCP 47)\")\n .option(\"--type <type>\", \"Image type\")\n .option(\"--id <imageId>\", \"Image ID to delete\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const interactive = isInteractive(program);\n\n options.lang = await requireOption(\n \"lang\",\n options.lang,\n {\n message: \"Language code (BCP 47):\",\n },\n interactive,\n );\n\n options.type = await requireOption(\n \"type\",\n options.type,\n {\n message: \"Image type:\",\n choices: VALID_IMAGE_TYPES as unknown as string[],\n },\n interactive,\n );\n\n options.id = await requireOption(\n \"id\",\n options.id,\n {\n message: \"Image ID to delete:\",\n },\n interactive,\n );\n\n await requireConfirm(`Delete image \"${options.id}\"?`, program);\n\n const client = await getClient(config);\n const imageType = validateImageType(options.type);\n\n try {\n await deleteImage(client, packageName, options.lang, imageType, options.id);\n console.log(`Image \"${options.id}\" deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Images export\n images\n .command(\"export\")\n .description(\"Export all images to a local directory\")\n .option(\"--dir <path>\", \"Output directory\", \"images\")\n .option(\"--lang <language>\", \"Language code (BCP 47) — export only this language\")\n .option(\"--type <type>\", \"Image type — export only this type\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n const exportOpts: { lang?: string; type?: ImageType } = {};\n if (options.lang) exportOpts.lang = options.lang;\n if (options.type) {\n exportOpts.type = validateImageType(options.type);\n }\n\n const spinner = createSpinner(\"Exporting images...\");\n if (!program.opts()[\"quiet\"] && process.stderr.isTTY) spinner.start();\n\n try {\n const result = await exportImages(client, packageName, options.dir, exportOpts);\n spinner.stop(\"Images exported\");\n console.log(formatOutput(result, format));\n } catch (error) {\n spinner.fail(\"Image export failed\");\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // Availability\n listings\n .command(\"availability\")\n .description(\"Get country availability for a track\")\n .option(\"--track <track>\", \"Track name\", \"production\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await getCountryAvailability(client, packageName, options.track);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/reviews.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport type { GpcConfig } from \"@gpc-cli/config\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createApiClient } from \"@gpc-cli/api\";\nimport {\n listReviews,\n getReview,\n replyToReview,\n exportReviews,\n formatOutput,\n sortResults,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { isInteractive, requireOption } from \"../prompt.js\";\n\nfunction resolvePackageName(packageArg: string | undefined, config: GpcConfig): string {\n const name = packageArg || config.app;\n if (!name) {\n console.error(\"Error: No package name. Use --app <package> or gpc config set app <package>\");\n process.exit(2);\n }\n return name;\n}\n\nasync function getClient(config: GpcConfig) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createApiClient({ auth });\n}\n\nexport function registerReviewsCommands(program: Command): void {\n const reviews = program.command(\"reviews\").description(\"Manage user reviews and ratings\");\n\n reviews\n .command(\"list\")\n .description(\"List user reviews\")\n .option(\"--stars <n>\", \"Filter by star rating (1-5)\", parseInt)\n .option(\"--lang <code>\", \"Filter by reviewer language\")\n .option(\"--since <date>\", \"Filter reviews after date (ISO 8601)\")\n .option(\"--translate-to <lang>\", \"Translate reviews to language\")\n .option(\"--max <n>\", \"Maximum number of reviews per page\", parseInt)\n .option(\"--limit <n>\", \"Maximum total results\", parseInt)\n .option(\"--next-page <token>\", \"Resume from page token\")\n .option(\"--sort <field>\", \"Sort by field (prefix with - for descending)\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await listReviews(client, packageName, {\n stars: options.stars,\n language: options.lang,\n since: options.since,\n translationLanguage: options.translateTo,\n maxResults: options.max,\n limit: options.limit,\n nextPage: options.nextPage,\n });\n const sorted = sortResults(result, options.sort);\n console.log(formatOutput(sorted, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n reviews\n .command(\"get <review-id>\")\n .description(\"Get a single review\")\n .option(\"--translate-to <lang>\", \"Translate review to language\")\n .action(async (reviewId: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await getReview(client, packageName, reviewId, options.translateTo);\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 reviews\n .command(\"reply <review-id>\")\n .description(\"Reply to a review\")\n .option(\"--text <text>\", \"Reply text (max 350 chars)\")\n .action(async (reviewId: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n const interactive = isInteractive(program);\n\n options.text = await requireOption(\n \"text\",\n options.text,\n {\n message: \"Reply text (max 350 chars):\",\n },\n interactive,\n );\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"reviews reply\",\n action: \"reply to\",\n target: reviewId,\n details: { text: options.text },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await replyToReview(client, packageName, reviewId, options.text);\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 reviews\n .command(\"export\")\n .description(\"Export reviews to JSON or CSV\")\n .option(\"--format <type>\", \"Output format: json or csv\", \"json\")\n .option(\"--stars <n>\", \"Filter by star rating (1-5)\", parseInt)\n .option(\"--lang <code>\", \"Filter by reviewer language\")\n .option(\"--since <date>\", \"Filter reviews after date (ISO 8601)\")\n .option(\"--translate-to <lang>\", \"Translate reviews to language\")\n .option(\"--output <file>\", \"Write output to file instead of stdout\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n\n try {\n const result = await exportReviews(client, packageName, {\n format: options.format as \"json\" | \"csv\",\n stars: options.stars,\n language: options.lang,\n since: options.since,\n translationLanguage: options.translateTo,\n });\n\n if (options.output) {\n const { writeFile } = await import(\"node:fs/promises\");\n await writeFile(options.output, result, \"utf-8\");\n console.log(`Reviews exported to ${options.output}`);\n } else {\n console.log(result);\n }\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":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/subscriptions.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport type { GpcConfig } from \"@gpc-cli/config\";\nimport type { Command } from \"commander\";\nimport { Option } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createApiClient } from \"@gpc-cli/api\";\nimport {\n listSubscriptions,\n getSubscription,\n createSubscription,\n updateSubscription,\n deleteSubscription,\n activateBasePlan,\n deactivateBasePlan,\n deleteBasePlan,\n migratePrices,\n listOffers,\n getOffer,\n createOffer,\n updateOffer,\n deleteOffer,\n activateOffer,\n deactivateOffer,\n formatOutput,\n sortResults,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { requireConfirm } from \"../prompt.js\";\n\nfunction resolvePackageName(packageArg: string | undefined, config: GpcConfig): string {\n const name = packageArg || config.app;\n if (!name) {\n console.error(\"Error: No package name. Use --app <package> or gpc config set app <package>\");\n process.exit(2);\n }\n return name;\n}\n\nasync function getClient(config: GpcConfig) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createApiClient({ auth });\n}\n\nexport function registerSubscriptionsCommands(program: Command): void {\n const subs = program.command(\"subscriptions\").description(\"Manage subscriptions and base plans\");\n\n subs\n .command(\"list\")\n .description(\"List subscriptions\")\n .addOption(new Option(\"--page-size <n>\", \"Results per page\").argParser(parseInt).hideHelp())\n .addOption(new Option(\"--page-token <token>\", \"Page token\").hideHelp())\n .option(\"--limit <n>\", \"Maximum total results\", parseInt)\n .option(\"--next-page <token>\", \"Resume from page token\")\n .option(\"--sort <field>\", \"Sort by field (prefix with - for descending)\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await listSubscriptions(client, packageName, {\n pageSize: options.pageSize,\n pageToken: options.pageToken,\n limit: options.limit,\n nextPage: options.nextPage,\n });\n if (options.sort) {\n result.subscriptions = sortResults(result.subscriptions, options.sort);\n }\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n subs\n .command(\"get <product-id>\")\n .description(\"Get a subscription\")\n .action(async (productId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await getSubscription(client, packageName, productId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n subs\n .command(\"create\")\n .description(\"Create a subscription from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with subscription data\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions create\",\n action: \"create\",\n target: `subscription from ${options.file}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await createSubscription(client, packageName, data);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n subs\n .command(\"update <product-id>\")\n .description(\"Update a subscription from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with subscription data\")\n .option(\"--update-mask <fields>\", \"Comma-separated field mask\")\n .action(async (productId: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions update\",\n action: \"update\",\n target: productId,\n details: { file: options.file, updateMask: options.updateMask },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await updateSubscription(\n client,\n packageName,\n productId,\n data,\n options.updateMask,\n );\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n subs\n .command(\"delete <product-id>\")\n .description(\"Delete a subscription\")\n .action(async (productId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Delete subscription \"${productId}\"?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"subscriptions delete\",\n action: \"delete\",\n target: productId,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await deleteSubscription(client, packageName, productId);\n console.log(`Subscription ${productId} deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // --- Base Plans ---\n const basePlans = subs.command(\"base-plans\").description(\"Manage base plans\");\n\n basePlans\n .command(\"activate <product-id> <base-plan-id>\")\n .description(\"Activate a base plan\")\n .action(async (productId: string, basePlanId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions base-plans activate\",\n action: \"activate\",\n target: `${productId}/${basePlanId}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await activateBasePlan(client, packageName, productId, basePlanId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n basePlans\n .command(\"deactivate <product-id> <base-plan-id>\")\n .description(\"Deactivate a base plan\")\n .action(async (productId: string, basePlanId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions base-plans deactivate\",\n action: \"deactivate\",\n target: `${productId}/${basePlanId}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await deactivateBasePlan(client, packageName, productId, basePlanId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n basePlans\n .command(\"delete <product-id> <base-plan-id>\")\n .description(\"Delete a base plan\")\n .action(async (productId: string, basePlanId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(\n `Delete base plan \"${basePlanId}\" from subscription \"${productId}\"?`,\n program,\n );\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"subscriptions base-plans delete\",\n action: \"delete\",\n target: `${productId}/${basePlanId}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await deleteBasePlan(client, packageName, productId, basePlanId);\n console.log(`Base plan ${basePlanId} deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n basePlans\n .command(\"migrate-prices <product-id> <base-plan-id>\")\n .description(\"Migrate base plan prices\")\n .requiredOption(\"--file <path>\", \"JSON file with migration data\")\n .action(\n async (\n productId: string,\n basePlanId: string,\n options: { file: string; updateMask?: string },\n ) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions base-plans migrate-prices\",\n action: \"migrate prices for\",\n target: `${productId}/${basePlanId}`,\n details: { file: options.file },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await migratePrices(client, packageName, productId, basePlanId, data);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n },\n );\n\n // --- Offers ---\n const offers = subs.command(\"offers\").description(\"Manage subscription offers\");\n\n offers\n .command(\"list <product-id> <base-plan-id>\")\n .description(\"List offers for a base plan\")\n .action(async (productId: string, basePlanId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await listOffers(client, packageName, productId, basePlanId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"get <product-id> <base-plan-id> <offer-id>\")\n .description(\"Get an offer\")\n .action(async (productId: string, basePlanId: string, offerId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await getOffer(client, packageName, productId, basePlanId, offerId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"create <product-id> <base-plan-id>\")\n .description(\"Create an offer from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with offer data\")\n .action(\n async (\n productId: string,\n basePlanId: string,\n options: { file: string; updateMask?: string },\n ) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions offers create\",\n action: \"create offer for\",\n target: `${productId}/${basePlanId}`,\n details: { file: options.file },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await createOffer(client, packageName, productId, basePlanId, data);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n },\n );\n\n offers\n .command(\"update <product-id> <base-plan-id> <offer-id>\")\n .description(\"Update an offer from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with offer data\")\n .option(\"--update-mask <fields>\", \"Comma-separated field mask\")\n .action(\n async (\n productId: string,\n basePlanId: string,\n offerId: string,\n options: { file: string; updateMask?: string },\n ) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions offers update\",\n action: \"update offer\",\n target: `${productId}/${basePlanId}/${offerId}`,\n details: { file: options.file, updateMask: options.updateMask },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await updateOffer(\n client,\n packageName,\n productId,\n basePlanId,\n offerId,\n data,\n options.updateMask,\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\n offers\n .command(\"delete <product-id> <base-plan-id> <offer-id>\")\n .description(\"Delete an offer\")\n .action(async (productId: string, basePlanId: string, offerId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Delete offer \"${offerId}\"?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"subscriptions offers delete\",\n action: \"delete offer\",\n target: `${productId}/${basePlanId}/${offerId}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await deleteOffer(client, packageName, productId, basePlanId, offerId);\n console.log(`Offer ${offerId} deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"activate <product-id> <base-plan-id> <offer-id>\")\n .description(\"Activate an offer\")\n .action(async (productId: string, basePlanId: string, offerId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions offers activate\",\n action: \"activate offer\",\n target: `${productId}/${basePlanId}/${offerId}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await activateOffer(client, packageName, productId, basePlanId, offerId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n offers\n .command(\"deactivate <product-id> <base-plan-id> <offer-id>\")\n .description(\"Deactivate an offer\")\n .action(async (productId: string, basePlanId: string, offerId: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"subscriptions offers deactivate\",\n action: \"deactivate offer\",\n target: `${productId}/${basePlanId}/${offerId}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await deactivateOffer(client, packageName, productId, basePlanId, offerId);\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/vitals.ts"],"sourcesContent":["import 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 } 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 formatOutput,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\n\nfunction resolvePackageName(packageArg: string | undefined, config: GpcConfig): 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: GpcConfig) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createReportingClient({ auth });\n}\n\nconst VALID_DIMENSIONS: ReportingDimension[] = [\n \"apiLevel\",\n \"versionCode\",\n \"deviceModel\",\n \"deviceType\",\n \"countryCode\",\n \"deviceRamBucket\",\n \"deviceSocName\",\n \"deviceCpuMakeModel\",\n \"deviceGlEsVersion\",\n \"deviceVulkanVersion\",\n \"deviceOpenGlVersion\",\n \"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 = getOutputFormat(program, config);\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 = getOutputFormat(program, config);\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(\n vitals,\n \"rendering\",\n \"Query slow rendering metrics\",\n getVitalsRendering,\n program,\n );\n registerMetricCommand(\n vitals,\n \"battery\",\n \"Query excessive wakeup metrics\",\n getVitalsBattery,\n program,\n );\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 = getOutputFormat(program, config);\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.command(\"errors\").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 = getOutputFormat(program, config);\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(\n `Error: Unknown metric \"${metric}\". Use: ${Object.keys(METRIC_MAP).join(\", \")}`,\n );\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 = getOutputFormat(program, config);\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":[]}