@gpc-cli/cli 0.9.40 → 0.9.41
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/{anomalies-KRRA75MJ.js → anomalies-NU2IN2GJ.js} +4 -9
- package/dist/anomalies-NU2IN2GJ.js.map +1 -0
- package/dist/bin.js +2 -2
- package/dist/{chunk-FIW4GLGP.js → chunk-25HYD4WO.js} +27 -27
- package/dist/chunk-AA577WVQ.js +23 -0
- package/dist/chunk-AA577WVQ.js.map +1 -0
- package/dist/{config-36GIPNWX.js → config-222P3MKK.js} +1 -1
- package/dist/config-222P3MKK.js.map +1 -0
- package/dist/{data-safety-JR6PZ2BD.js → data-safety-L64D6ZZX.js} +5 -15
- package/dist/data-safety-L64D6ZZX.js.map +1 -0
- package/dist/{device-tiers-5SGJPSYG.js → device-tiers-UZVKC726.js} +5 -15
- package/dist/device-tiers-UZVKC726.js.map +1 -0
- package/dist/{diff-EQOPWX3M.js → diff-V77SMKAQ.js} +4 -9
- package/dist/diff-V77SMKAQ.js.map +1 -0
- package/dist/{external-transactions-O5P4QBIT.js → external-transactions-6DWF5U3Q.js} +5 -15
- package/dist/external-transactions-6DWF5U3Q.js.map +1 -0
- package/dist/{feedback-2V6MLXZH.js → feedback-YIFDVXST.js} +2 -2
- package/dist/{games-X57AGM3E.js → games-BT777WUO.js} +8 -13
- package/dist/games-BT777WUO.js.map +1 -0
- package/dist/{generated-apks-KB2PLWDI.js → generated-apks-RJWTIX7L.js} +5 -15
- package/dist/generated-apks-RJWTIX7L.js.map +1 -0
- package/dist/{iap-BNIAHBDN.js → iap-QTO5Q6SN.js} +5 -15
- package/dist/iap-QTO5Q6SN.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/{internal-sharing-M74VNIQ2.js → internal-sharing-DEOI3ENH.js} +5 -15
- package/dist/internal-sharing-DEOI3ENH.js.map +1 -0
- package/dist/{listings-JOFAZBKU.js → listings-NJWIKN4J.js} +5 -15
- package/dist/listings-NJWIKN4J.js.map +1 -0
- package/dist/{one-time-products-3WNXDKE3.js → one-time-products-6CQNNTBX.js} +5 -15
- package/dist/one-time-products-6CQNNTBX.js.map +1 -0
- package/dist/{pricing-OZO66DVL.js → pricing-XQSDTTK5.js} +5 -15
- package/dist/pricing-XQSDTTK5.js.map +1 -0
- package/dist/{publish-EPZXLGKZ.js → publish-OJJFPDRM.js} +4 -9
- package/dist/publish-OJJFPDRM.js.map +1 -0
- package/dist/{purchases-7ZPVCN6D.js → purchases-745IKIG5.js} +5 -15
- package/dist/purchases-745IKIG5.js.map +1 -0
- package/dist/{recovery-YGPOVUFD.js → recovery-BBF6NQ4C.js} +5 -15
- package/dist/recovery-BBF6NQ4C.js.map +1 -0
- package/dist/{releases-FXVNP6VK.js → releases-C2WC2K4E.js} +8 -9
- package/dist/{releases-FXVNP6VK.js.map → releases-C2WC2K4E.js.map} +1 -1
- package/dist/{reviews-MOVGATUI.js → reviews-2B5SKNXW.js} +5 -15
- package/dist/reviews-2B5SKNXW.js.map +1 -0
- package/dist/{subscriptions-LSOJID6H.js → subscriptions-4XKNTOOL.js} +12 -17
- package/dist/subscriptions-4XKNTOOL.js.map +1 -0
- package/dist/{testers-SDLVWQ2Z.js → testers-3Y753PFW.js} +5 -15
- package/dist/testers-3Y753PFW.js.map +1 -0
- package/dist/{train-PX5Z26PQ.js → train-YA4KGVGZ.js} +4 -9
- package/dist/train-YA4KGVGZ.js.map +1 -0
- package/dist/{update-EXLKAKOD.js → update-ISG6JXID.js} +2 -2
- package/dist/{version-3O6R66WZ.js → version-BN45CRWB.js} +2 -2
- package/dist/{vitals-6EYDCGQK.js → vitals-A4CS4MSS.js} +4 -9
- package/dist/vitals-A4CS4MSS.js.map +1 -0
- package/package.json +4 -4
- package/dist/anomalies-KRRA75MJ.js.map +0 -1
- package/dist/config-36GIPNWX.js.map +0 -1
- package/dist/data-safety-JR6PZ2BD.js.map +0 -1
- package/dist/device-tiers-5SGJPSYG.js.map +0 -1
- package/dist/diff-EQOPWX3M.js.map +0 -1
- package/dist/external-transactions-O5P4QBIT.js.map +0 -1
- package/dist/games-X57AGM3E.js.map +0 -1
- package/dist/generated-apks-KB2PLWDI.js.map +0 -1
- package/dist/iap-BNIAHBDN.js.map +0 -1
- package/dist/internal-sharing-M74VNIQ2.js.map +0 -1
- package/dist/listings-JOFAZBKU.js.map +0 -1
- package/dist/one-time-products-3WNXDKE3.js.map +0 -1
- package/dist/pricing-OZO66DVL.js.map +0 -1
- package/dist/publish-EPZXLGKZ.js.map +0 -1
- package/dist/purchases-7ZPVCN6D.js.map +0 -1
- package/dist/recovery-YGPOVUFD.js.map +0 -1
- package/dist/reviews-MOVGATUI.js.map +0 -1
- package/dist/subscriptions-LSOJID6H.js.map +0 -1
- package/dist/testers-SDLVWQ2Z.js.map +0 -1
- package/dist/train-PX5Z26PQ.js.map +0 -1
- package/dist/vitals-6EYDCGQK.js.map +0 -1
- /package/dist/{chunk-FIW4GLGP.js.map → chunk-25HYD4WO.js.map} +0 -0
- /package/dist/{feedback-2V6MLXZH.js.map → feedback-YIFDVXST.js.map} +0 -0
- /package/dist/{update-EXLKAKOD.js.map → update-ISG6JXID.js.map} +0 -0
- /package/dist/{version-3O6R66WZ.js.map → version-BN45CRWB.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/pricing.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 { convertRegionPrices, formatOutput } 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 getClient(config: GpcConfig) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createApiClient({ auth });\n}\n\nexport function registerPricingCommands(program: Command): void {\n const pricing = program.command(\"pricing\").description(\"Pricing and regional price conversion\");\n\n pricing\n .command(\"convert\")\n .description(\"Convert a price to all regional prices\")\n .option(\"--from <currency>\", \"Source currency code (e.g. USD)\")\n .option(\"--amount <number>\", \"Price amount (e.g. 4.99)\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const { isInteractive, requireOption } = await import(\"../prompt.js\");\n const interactive = isInteractive(program);\n\n options.from = await requireOption(\n \"from\",\n options.from,\n {\n message: \"Source currency code (e.g. USD):\",\n default: \"USD\",\n },\n interactive,\n );\n\n options.amount = await requireOption(\n \"amount\",\n options.amount,\n {\n message: \"Price amount (e.g. 4.99):\",\n },\n interactive,\n );\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await convertRegionPrices(client, packageName, options.from, options.amount);\n if (format !== \"json\") {\n const prices = (result as unknown as Record<string, unknown>)[\"convertedRegionPrices\"] as\n | Record<string, Record<string, unknown>>\n | undefined;\n if (prices) {\n const rows = Object.entries(prices).map(([region, data]) => {\n const money = data[\"price\"] as Record<string, unknown> | undefined;\n const units = money?.[\"units\"] || \"0\";\n const nanos = String(money?.[\"nanos\"] || 0)\n .padStart(9, \"0\")\n .slice(0, 2);\n return {\n region,\n price: money\n ? `${units}.${nanos}`\n : data[\"priceMicros\"]\n ? String(Number(data[\"priceMicros\"]) / 1_000_000)\n : \"-\",\n currencyCode: (money?.[\"currencyCode\"] || data[\"currencyCode\"] || \"-\") as string,\n };\n });\n console.log(formatOutput(rows, format));\n } else {\n console.log(formatOutput(result, format));\n }\n } else {\n console.log(formatOutput(result, format));\n }\n } catch (error) {\n const { PlayApiError } = await import(\"@gpc-cli/api\");\n if (\n error instanceof PlayApiError &&\n (error.code === \"API_HTTP_400\" || error.code === \"API_EDIT_EXPIRED\")\n ) {\n console.error(\n \"Error: Price conversion is not available for this app. \" +\n \"Ensure the app has monetization configured in Google Play Console (at least one paid product or subscription).\",\n );\n } else {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n }\n process.exit(4);\n }\n });\n}\n"],"mappings":";;;;;;AAEA,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAChC,SAAS,qBAAqB,oBAAoB;AAGlD,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,UAAU,QAAmB;AAC1C,QAAM,OAAO,MAAM,YAAY,EAAE,oBAAoB,OAAO,MAAM,eAAe,CAAC;AAClF,SAAO,gBAAgB,EAAE,KAAK,CAAC;AACjC;AAEO,SAAS,wBAAwB,SAAwB;AAC9D,QAAM,UAAU,QAAQ,QAAQ,SAAS,EAAE,YAAY,uCAAuC;AAE9F,UACG,QAAQ,SAAS,EACjB,YAAY,wCAAwC,EACpD,OAAO,qBAAqB,iCAAiC,EAC7D,OAAO,qBAAqB,0BAA0B,EACtD,OAAO,OAAO,YAAY;AACzB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AACpE,UAAM,EAAE,eAAe,cAAc,IAAI,MAAM,OAAO,sBAAc;AACpE,UAAM,cAAc,cAAc,OAAO;AAEzC,YAAQ,OAAO,MAAM;AAAA,MACnB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,QACE,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,MACA;AAAA,IACF;AAEA,YAAQ,SAAS,MAAM;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,QACE,SAAS;AAAA,MACX;AAAA,MACA;AAAA,IACF;AACA,UAAM,SAAS,MAAM,UAAU,MAAM;AACrC,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAE9C,QAAI;AACF,YAAM,SAAS,MAAM,oBAAoB,QAAQ,aAAa,QAAQ,MAAM,QAAQ,MAAM;AAC1F,UAAI,WAAW,QAAQ;AACrB,cAAM,SAAU,OAA8C,uBAAuB;AAGrF,YAAI,QAAQ;AACV,gBAAM,OAAO,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,QAAQ,IAAI,MAAM;AAC1D,kBAAM,QAAQ,KAAK,OAAO;AAC1B,kBAAM,QAAQ,QAAQ,OAAO,KAAK;AAClC,kBAAM,QAAQ,OAAO,QAAQ,OAAO,KAAK,CAAC,EACvC,SAAS,GAAG,GAAG,EACf,MAAM,GAAG,CAAC;AACb,mBAAO;AAAA,cACL;AAAA,cACA,OAAO,QACH,GAAG,KAAK,IAAI,KAAK,KACjB,KAAK,aAAa,IAChB,OAAO,OAAO,KAAK,aAAa,CAAC,IAAI,GAAS,IAC9C;AAAA,cACN,cAAe,QAAQ,cAAc,KAAK,KAAK,cAAc,KAAK;AAAA,YACpE;AAAA,UACF,CAAC;AACD,kBAAQ,IAAI,aAAa,MAAM,MAAM,CAAC;AAAA,QACxC,OAAO;AACL,kBAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,QAC1C;AAAA,MACF,OAAO;AACL,gBAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,MAC1C;AAAA,IACF,SAAS,OAAO;AACd,YAAM,EAAE,aAAa,IAAI,MAAM,OAAO,cAAc;AACpD,UACE,iBAAiB,iBAChB,MAAM,SAAS,kBAAkB,MAAM,SAAS,qBACjD;AACA,gBAAQ;AAAA,UACN;AAAA,QAEF;AAAA,MACF,OAAO;AACL,gBAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,MAClF;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/publish.ts"],"sourcesContent":["import { appendFile, stat } from \"node:fs/promises\";\nimport type { GpcConfig, OutputFormat } from \"@gpc-cli/config\";\nimport type { Command } from \"commander\";\nimport { loadConfig, getCacheDir } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createApiClient } from \"@gpc-cli/api\";\nimport type { RetryLogEntry } from \"@gpc-cli/api\";\nimport {\n publish,\n generateNotesFromGit,\n writeAuditLog,\n createAuditEntry,\n formatOutput,\n} from \"@gpc-cli/core\";\nimport type { PublishResult, DryRunPublishResult } from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun } from \"../dry-run.js\";\nimport { isInteractive, promptSelect, promptInput } from \"../prompt.js\";\n\nconst PASS = \"\\u2713\";\nconst FAIL = \"\\u2717\";\nconst WARN = \"\\u26A0\";\n\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\n// ---------------------------------------------------------------------------\n// Output formatters\n// ---------------------------------------------------------------------------\n\nfunction formatChecks(checks: { name: string; passed: boolean; message: string }[]): string[] {\n return checks.map((c) => ` ${c.passed ? PASS : FAIL} ${c.message}`);\n}\n\nfunction formatValidationOutput(result: PublishResult, format: OutputFormat): string {\n if (format !== \"table\") {\n return formatOutput({ success: false, validation: result.validation }, format);\n }\n const lines = [\"Validation failed:\\n\", ...formatChecks(result.validation.checks)];\n for (const w of result.validation.warnings) {\n lines.push(` ${WARN} ${w}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction formatPublishOutput(result: PublishResult, format: OutputFormat): string {\n if (format !== \"table\") return formatOutput(result, format);\n\n const upload = result.upload;\n if (!upload) return formatOutput(result, format);\n const rollout =\n upload.status === \"inProgress\" && \"userFraction\" in upload\n ? ` (${Math.round(Number((upload as Record<string, unknown>)[\"userFraction\"]) * 100)}% rollout)`\n : \"\";\n\n const lines = [\"Published successfully\\n\", ...formatChecks(result.validation.checks)];\n for (const w of result.validation.warnings) {\n lines.push(` ${WARN} ${w}`);\n }\n lines.push(\"\");\n lines.push(` versionCode ${upload.versionCode}`);\n lines.push(` track ${upload.track}`);\n lines.push(` status ${upload.status}${rollout}`);\n return lines.join(\"\\n\");\n}\n\nfunction formatDryRunOutput(result: DryRunPublishResult, format: OutputFormat): string {\n if (format !== \"table\") return formatOutput(result, format);\n\n const lines = [\"Dry run — no changes made\\n\", ...formatChecks(result.validation.checks)];\n for (const w of result.validation.warnings) {\n lines.push(` ${WARN} ${w}`);\n }\n\n const u = result.upload;\n lines.push(\"\");\n lines.push(` Track ${u.track}`);\n\n if (u.currentReleases.length === 0) {\n lines.push(` Current (no releases on this track)`);\n } else {\n for (const r of u.currentReleases) {\n const fraction =\n r.userFraction !== undefined ? ` (${Math.round(r.userFraction * 100)}%)` : \"\";\n lines.push(` Current ${r.versionCodes.join(\", \")} · ${r.status}${fraction}`);\n }\n }\n const plannedFraction =\n u.plannedRelease.userFraction !== undefined\n ? ` (${Math.round(u.plannedRelease.userFraction * 100)}%)`\n : \"\";\n lines.push(` Would be (new bundle) · ${u.plannedRelease.status}${plannedFraction}`);\n return lines.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Command\n// ---------------------------------------------------------------------------\n\nexport function registerPublishCommand(program: Command): void {\n program\n .command(\"publish <file>\")\n .description(\"Validate, upload, and release in one step\")\n .option(\"--track <track>\", \"Target track\", \"internal\")\n .option(\"--rollout <percent>\", \"Staged rollout percentage (1-100)\")\n .option(\"--notes <text>\", \"Release notes (en-US)\")\n .option(\"--notes-dir <dir>\", \"Read release notes from directory (<dir>/<lang>.txt)\")\n .option(\"--notes-from-git\", \"Generate release notes from git commit history\")\n .option(\"--since <ref>\", \"Git ref to start from (tag, SHA) — used with --notes-from-git\")\n .option(\"--name <name>\", \"Release name\")\n .option(\"--mapping <file>\", \"ProGuard/R8 mapping file for deobfuscation\")\n .option(\"--retry-log <path>\", \"Write retry log entries to file (JSONL)\")\n .action(async (file: string, options) => {\n try {\n await stat(file);\n } catch {\n console.error(`Error: File not found: ${file}`);\n process.exit(2);\n }\n\n const noteSources = [options.notes, options.notesDir, options.notesFromGit].filter(Boolean);\n if (noteSources.length > 1) {\n console.error(\n \"Error: Cannot combine --notes, --notes-dir, and --notes-from-git. Use only one.\",\n );\n process.exit(2);\n }\n\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n // Interactive mode: prompt for missing options\n if (isInteractive(program)) {\n if (!options.track || options.track === \"internal\") {\n const tracks = [\"internal\", \"alpha\", \"beta\", \"production\"];\n options.track = await promptSelect(\"Select track:\", tracks, \"internal\");\n }\n\n if (!options.rollout && options.track === \"production\") {\n const rolloutStr = await promptInput(\n \"Staged rollout percentage (1-100, blank for full)\",\n \"100\",\n );\n if (rolloutStr && rolloutStr !== \"100\") {\n options.rollout = rolloutStr;\n }\n }\n\n if (!options.notes && !options.notesDir && !options.notesFromGit) {\n const notes = await promptInput(\"Release notes (en-US, blank to skip)\");\n if (notes) options.notes = notes;\n }\n }\n\n // Rollout range guard\n if (options.rollout !== undefined) {\n const rollout = Number(options.rollout);\n if (!Number.isFinite(rollout) || rollout < 1 || rollout > 100) {\n console.error(\n `Error: --rollout must be a number between 1 and 100 (got: ${options.rollout})`,\n );\n process.exit(2);\n }\n }\n\n // Resolve git-based release notes before calling publish\n if (options.notesFromGit) {\n const gitNotes = await generateNotesFromGit({ since: options.since });\n options.notes = gitNotes.text;\n if (gitNotes.truncated) {\n console.error(\n `${WARN} Release notes truncated to 500 characters (${gitNotes.commitCount} commits from ${gitNotes.since}).`,\n );\n }\n }\n\n let onRetry: ((entry: RetryLogEntry) => void) | undefined;\n if (options.retryLog) {\n onRetry = (entry: RetryLogEntry) => {\n appendFile(options.retryLog, JSON.stringify(entry) + \"\\n\").catch(() => {});\n };\n }\n\n const auth = await resolveAuth({\n serviceAccountPath: config.auth?.serviceAccount,\n cachePath: getCacheDir(),\n });\n const client = createApiClient({ auth, onRetry });\n\n if (isDryRun(program)) {\n try {\n const result = await publish(client, packageName, file, {\n track: options.track,\n rolloutPercent: options.rollout ? Number(options.rollout) : undefined,\n notes: options.notes,\n notesDir: options.notesDir,\n releaseName: options.name,\n mappingFile: options.mapping,\n dryRun: true,\n });\n console.log(formatDryRunOutput(result as DryRunPublishResult, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n return;\n }\n\n const auditEntry = createAuditEntry(\n \"publish\",\n { file, track: options.track, rollout: options.rollout },\n packageName,\n );\n\n try {\n const result = await publish(client, packageName, file, {\n track: options.track,\n rolloutPercent: options.rollout ? Number(options.rollout) : undefined,\n notes: options.notes,\n notesDir: options.notesDir,\n releaseName: options.name,\n mappingFile: options.mapping,\n });\n\n if (!result.upload) {\n console.log(formatValidationOutput(result as PublishResult, format));\n auditEntry.success = false;\n auditEntry.error = \"Validation failed\";\n process.exit(1);\n }\n\n console.log(formatPublishOutput(result as PublishResult, format));\n auditEntry.success = true;\n } catch (error) {\n auditEntry.success = false;\n auditEntry.error = error instanceof Error ? error.message : String(error);\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n } finally {\n auditEntry.durationMs = Date.now() - new Date(auditEntry.timestamp).getTime();\n writeAuditLog(auditEntry).catch(() => {});\n }\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/purchases.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { Option } 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 getProductPurchase,\n acknowledgeProductPurchase,\n consumeProductPurchase,\n getSubscriptionPurchase,\n cancelSubscriptionPurchase,\n deferSubscriptionPurchase,\n revokeSubscriptionPurchase,\n refundSubscriptionV2,\n listVoidedPurchases,\n refundOrder,\n formatOutput,\n} from \"@gpc-cli/core\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { getOutputFormat } from \"../format.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\nexport function registerPurchasesCommands(program: Command): void {\n const purchases = program.command(\"purchases\").description(\"Manage purchases and orders\");\n\n purchases\n .command(\"get <product-id> <token>\")\n .description(\"Get a product purchase\")\n .action(async (productId: string, token: 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 getProductPurchase(client, packageName, productId, token);\n if (format !== \"json\") {\n const r = result as unknown as Record<string, unknown>;\n const row = {\n orderId: r[\"orderId\"] || \"-\",\n purchaseState: r[\"purchaseState\"] ?? \"-\",\n consumptionState: r[\"consumptionState\"] ?? \"-\",\n purchaseTime: r[\"purchaseTimeMillis\"]\n ? new Date(Number(r[\"purchaseTimeMillis\"])).toISOString()\n : \"-\",\n acknowledged: r[\"acknowledgementState\"] ?? \"-\",\n };\n console.log(formatOutput(row, 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 purchases\n .command(\"acknowledge <product-id> <token>\")\n .description(\"Acknowledge a product purchase\")\n .option(\"--payload <text>\", \"Developer payload\")\n .action(async (productId: string, token: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"purchases acknowledge\",\n action: \"acknowledge\",\n target: `${productId}/${token}`,\n details: { payload: options.payload },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await acknowledgeProductPurchase(client, packageName, productId, token, options.payload);\n console.log(`Purchase acknowledged.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n purchases\n .command(\"consume <product-id> <token>\")\n .description(\"Consume a product purchase\")\n .action(async (productId: string, token: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"purchases consume\",\n action: \"consume\",\n target: `${productId}/${token}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await consumeProductPurchase(client, packageName, productId, token);\n console.log(`Purchase consumed.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // --- Subscription purchases ---\n const sub = purchases.command(\"subscription\").description(\"Manage subscription purchases\");\n\n sub\n .command(\"get <token>\")\n .description(\"Get a subscription purchase (v2)\")\n .action(async (token: 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 getSubscriptionPurchase(client, packageName, token);\n if (format !== \"json\") {\n const r = result as unknown as Record<string, unknown>;\n const lineItems = r[\"lineItems\"] as Record<string, unknown>[] | undefined;\n const row = {\n subscriptionState: r[\"subscriptionState\"] || \"-\",\n startTime: r[\"startTime\"] || \"-\",\n expiryTime: r[\"expiryTime\"] || \"-\",\n linkedPurchaseToken: r[\"linkedPurchaseToken\"] ? \"yes\" : \"no\",\n lineItems: lineItems?.length || 0,\n acknowledgement: r[\"acknowledgementState\"] || \"-\",\n };\n console.log(formatOutput(row, 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 sub\n .command(\"cancel <subscription-id> <token>\")\n .description(\"Cancel a subscription (v1)\")\n .action(async (subscriptionId: string, token: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"purchases subscription cancel\",\n action: \"cancel subscription\",\n target: `${subscriptionId}/${token}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await cancelSubscriptionPurchase(client, packageName, subscriptionId, token);\n console.log(`Subscription cancelled.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n sub\n .command(\"defer <subscription-id> <token>\")\n .description(\"Defer a subscription expiry\")\n .option(\"--expiry <iso-date>\", \"Desired new expiry date (ISO 8601)\")\n .action(async (subscriptionId: string, token: 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.expiry = await requireOption(\n \"expiry\",\n options.expiry,\n {\n message: \"New expiry date (ISO 8601, e.g. 2026-12-31T23:59:59Z):\",\n },\n interactive,\n );\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"purchases subscription defer\",\n action: \"defer subscription\",\n target: `${subscriptionId}/${token}`,\n details: { expiry: options.expiry },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await deferSubscriptionPurchase(\n client,\n packageName,\n subscriptionId,\n token,\n options.expiry,\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 sub\n .command(\"refund <token>\")\n .description(\"Refund a subscription purchase (v2)\")\n .action(async (token: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Refund subscription for token \"${token.slice(0, 16)}...\"?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"purchases subscription refund\",\n action: \"refund subscription\",\n target: token,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await refundSubscriptionV2(client, packageName, token);\n console.log(`Subscription refunded.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n sub\n .command(\"revoke <token>\")\n .description(\"Revoke a subscription (v2)\")\n .action(async (token: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"purchases subscription revoke\",\n action: \"revoke subscription\",\n target: token,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await revokeSubscriptionPurchase(client, packageName, token);\n console.log(`Subscription revoked.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n // --- Voided purchases ---\n purchases\n .command(\"voided\")\n .description(\"List voided purchases\")\n .option(\"--start-time <time>\", \"Start time (milliseconds)\")\n .option(\"--end-time <time>\", \"End time (milliseconds)\")\n .addOption(\n new Option(\"--max-results <n>\", \"Maximum results per page\").argParser(parseInt).hideHelp(),\n )\n .option(\"--limit <n>\", \"Maximum total results\", parseInt)\n .option(\"--next-page <token>\", \"Resume from page token\")\n .action(async (options) => {\n const config = await loadConfig();\n const 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 listVoidedPurchases(client, packageName, {\n startTime: options.startTime,\n endTime: options.endTime,\n maxResults: options.maxResults,\n limit: options.limit,\n nextPage: options.nextPage,\n });\n if (format !== \"json\") {\n const purchases = (result as Record<string, unknown>)[\"voidedPurchases\"] as\n | Record<string, unknown>[]\n | undefined;\n if (purchases && purchases.length > 0) {\n const rows = purchases.map((p) => ({\n orderId: p[\"orderId\"] || \"-\",\n purchaseToken: String(p[\"purchaseToken\"] || \"-\").slice(0, 16) + \"...\",\n voidedTime: p[\"voidedTimeMillis\"]\n ? new Date(Number(p[\"voidedTimeMillis\"])).toISOString()\n : \"-\",\n voidedSource: p[\"voidedSource\"] ?? \"-\",\n voidedReason: p[\"voidedReason\"] ?? \"-\",\n }));\n console.log(formatOutput(rows, format));\n } else {\n console.log(\"No voided purchases found.\");\n }\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 // --- Orders ---\n const orders = purchases.command(\"orders\").description(\"Manage orders\");\n\n orders\n .command(\"refund <order-id>\")\n .description(\"Refund an order\")\n .option(\"--full-refund\", \"Full refund\")\n .option(\"--prorated-refund\", \"Prorated refund\")\n .action(async (orderId: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Refund order \"${orderId}\"?`, program);\n\n if (isDryRun(program)) {\n const format = getOutputFormat(program, config);\n printDryRun(\n {\n command: \"purchases orders refund\",\n action: \"refund\",\n target: orderId,\n details: { fullRefund: options.fullRefund, proratedRefund: options.proratedRefund },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await refundOrder(client, packageName, orderId, {\n fullRefund: options.fullRefund,\n proratedRefund: options.proratedRefund,\n });\n console.log(`Order ${orderId} refunded.`);\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":["purchases"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/recovery.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 listRecoveryActions,\n cancelRecoveryAction,\n deployRecoveryAction,\n createRecoveryAction,\n addRecoveryTargeting,\n formatOutput,\n} from \"@gpc-cli/core\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { getOutputFormat } from \"../format.js\";\nimport { requireConfirm } from \"../prompt.js\";\nimport { readFileSync } from \"node:fs\";\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 registerRecoveryCommands(program: Command): void {\n const recovery = program.command(\"recovery\").description(\"Manage app recovery actions\");\n\n recovery\n .command(\"list\")\n .description(\"List app recovery actions\")\n .option(\"--version-code <code>\", \"Filter by version code\", parseInt)\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 client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n if (options.versionCode === undefined) {\n console.error(\n \"Error: --version-code is required. The API requires a version code to filter recovery actions.\",\n );\n console.error(\"Usage: gpc recovery list --version-code <code>\");\n process.exit(2);\n }\n const result = await listRecoveryActions(client, packageName, options.versionCode);\n if (Array.isArray(result) && result.length === 0) {\n if (format === \"json\") {\n console.log(formatOutput([], format));\n } else {\n console.log(\"No recovery actions found.\");\n }\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 recovery\n .command(\"cancel <id>\")\n .description(\"Cancel a recovery action\")\n .action(async (id: 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: \"recovery cancel\",\n action: \"cancel\",\n target: id,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n await requireConfirm(`Cancel recovery action ${id}?`, program);\n\n const client = await getClient(config);\n\n try {\n await cancelRecoveryAction(client, packageName, id);\n console.log(\n formatOutput({ success: true, appRecoveryId: id, action: \"cancelled\" }, format),\n );\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n recovery\n .command(\"deploy <id>\")\n .description(\"Deploy a recovery action\")\n .action(async (id: 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: \"recovery deploy\",\n action: \"deploy\",\n target: id,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n await requireConfirm(`Deploy recovery action ${id}?`, program);\n\n const client = await getClient(config);\n\n try {\n await deployRecoveryAction(client, packageName, id);\n console.log(formatOutput({ success: true, appRecoveryId: id, action: \"deployed\" }, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n recovery\n .command(\"create\")\n .description(\"Create a new app recovery action\")\n .requiredOption(\"--file <path>\", \"Path to JSON file with recovery action 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 let data: Record<string, unknown>;\n try {\n data = JSON.parse(readFileSync(options.file, \"utf-8\"));\n } catch (err) {\n console.error(\n `Error: Could not read recovery action data from ${options.file}: ${err instanceof Error ? err.message : String(err)}`,\n );\n process.exit(2);\n }\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"recovery create\",\n action: \"create recovery action\",\n target: packageName,\n details: data,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await createRecoveryAction(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 recovery\n .command(\"add-targeting <action-id>\")\n .description(\"Add targeting rules to an existing recovery action\")\n .requiredOption(\"--file <path>\", \"Path to JSON file with targeting data\")\n .action(async (actionId: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n let targeting: Record<string, unknown>;\n try {\n targeting = JSON.parse(readFileSync(options.file, \"utf-8\"));\n } catch (err) {\n console.error(\n `Error: Could not read targeting data from ${options.file}: ${err instanceof Error ? err.message : String(err)}`,\n );\n process.exit(2);\n }\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"recovery add-targeting\",\n action: \"add targeting to recovery action\",\n target: actionId,\n details: targeting,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await addRecoveryTargeting(client, packageName, actionId, targeting);\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 analyzeReviews,\n formatOutput,\n maybePaginate,\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 if (format !== \"json\" && Array.isArray(sorted)) {\n const rows = sorted.map((r: unknown) => {\n const rv = r as Record<string, unknown>;\n const comments = rv[\"comments\"] as Record<string, unknown>[] | undefined;\n const userComment = comments?.[0]?.[\"userComment\"] as\n | Record<string, unknown>\n | undefined;\n return {\n reviewId: rv[\"reviewId\"] || \"-\",\n author: rv[\"authorName\"] || \"-\",\n stars: userComment?.[\"starRating\"] || \"-\",\n text: String(userComment?.[\"text\"] || \"-\").slice(0, 80),\n lastModified: userComment?.[\"lastModified\"]\n ? String(\n (userComment[\"lastModified\"] as Record<string, unknown>)?.[\"seconds\"] || \"-\",\n )\n : \"-\",\n thumbsUp: userComment?.[\"thumbsUpCount\"] || 0,\n };\n });\n await maybePaginate(formatOutput(rows, format));\n } else {\n await maybePaginate(formatOutput(sorted, format));\n }\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 if (format !== \"json\") {\n const charCount = options.text.length;\n console.log(`Reply sent (${charCount}/350 chars)`);\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 reviews\n .command(\"analyze\")\n .description(\"Analyze reviews: sentiment, topics, keywords, rating distribution\")\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(\"--max <n>\", \"Maximum number of reviews to analyze\", parseInt)\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 analyzeReviews(client, packageName, {\n stars: options.stars,\n language: options.lang,\n since: options.since,\n maxResults: options.max,\n });\n\n if (format === \"json\") {\n console.log(formatOutput(result, format));\n return;\n }\n\n console.log(`\\nReview Analysis — ${packageName}`);\n console.log(`${\"─\".repeat(50)}`);\n console.log(`Total reviews: ${result.totalReviews}`);\n console.log(\n `Average rating: ${result.avgRating > 0 ? result.avgRating.toFixed(2) + \" ★\" : \"N/A\"}`,\n );\n console.log(`\\nSentiment:`);\n console.log(\n ` Positive: ${result.sentiment.positive} Negative: ${result.sentiment.negative} Neutral: ${result.sentiment.neutral}`,\n );\n console.log(` Avg score: ${result.sentiment.avgScore} (range -1 to +1)`);\n\n if (result.topics.length > 0) {\n console.log(`\\nTop topics:`);\n for (const t of result.topics.slice(0, 8)) {\n const bar = t.avgScore > 0.1 ? \"+\" : t.avgScore < -0.1 ? \"-\" : \"~\";\n console.log(` [${bar}] ${t.topic.padEnd(20)} ${t.count} reviews`);\n }\n }\n\n if (result.keywords.length > 0) {\n console.log(\n `\\nTop keywords: ${result.keywords\n .slice(0, 10)\n .map((k) => k.word)\n .join(\", \")}`,\n );\n }\n\n if (Object.keys(result.ratingDistribution).length > 0) {\n console.log(`\\nRating distribution:`);\n for (let star = 5; star >= 1; star--) {\n const count = result.ratingDistribution[star] ?? 0;\n if (count > 0) console.log(` ${star}★ ${count}`);\n }\n }\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":";;;;;;;;;;;;;;AAEA,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAKP,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,UAAU,QAAmB;AAC1C,QAAM,OAAO,MAAM,YAAY,EAAE,oBAAoB,OAAO,MAAM,eAAe,CAAC;AAClF,SAAO,gBAAgB,EAAE,KAAK,CAAC;AACjC;AAEO,SAAS,wBAAwB,SAAwB;AAC9D,QAAM,UAAU,QAAQ,QAAQ,SAAS,EAAE,YAAY,iCAAiC;AAExF,UACG,QAAQ,MAAM,EACd,YAAY,mBAAmB,EAC/B,OAAO,eAAe,+BAA+B,QAAQ,EAC7D,OAAO,iBAAiB,6BAA6B,EACrD,OAAO,kBAAkB,sCAAsC,EAC/D,OAAO,yBAAyB,+BAA+B,EAC/D,OAAO,aAAa,sCAAsC,QAAQ,EAClE,OAAO,eAAe,yBAAyB,QAAQ,EACvD,OAAO,uBAAuB,wBAAwB,EACtD,OAAO,kBAAkB,8CAA8C,EACvE,OAAO,OAAO,YAAY;AACzB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AACpE,UAAM,SAAS,MAAM,UAAU,MAAM;AACrC,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAE9C,QAAI;AACF,YAAM,SAAS,MAAM,YAAY,QAAQ,aAAa;AAAA,QACpD,OAAO,QAAQ;AAAA,QACf,UAAU,QAAQ;AAAA,QAClB,OAAO,QAAQ;AAAA,QACf,qBAAqB,QAAQ;AAAA,QAC7B,YAAY,QAAQ;AAAA,QACpB,OAAO,QAAQ;AAAA,QACf,UAAU,QAAQ;AAAA,MACpB,CAAC;AACD,UAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW,KAAK,WAAW,QAAQ;AACrE,gBAAQ,IAAI,mBAAmB;AAC/B;AAAA,MACF;AACA,YAAM,SAAS,YAAY,QAAQ,QAAQ,IAAI;AAC/C,UAAI,WAAW,UAAU,MAAM,QAAQ,MAAM,GAAG;AAC9C,cAAM,OAAO,OAAO,IAAI,CAAC,MAAe;AACtC,gBAAM,KAAK;AACX,gBAAM,WAAW,GAAG,UAAU;AAC9B,gBAAM,cAAc,WAAW,CAAC,IAAI,aAAa;AAGjD,iBAAO;AAAA,YACL,UAAU,GAAG,UAAU,KAAK;AAAA,YAC5B,QAAQ,GAAG,YAAY,KAAK;AAAA,YAC5B,OAAO,cAAc,YAAY,KAAK;AAAA,YACtC,MAAM,OAAO,cAAc,MAAM,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE;AAAA,YACtD,cAAc,cAAc,cAAc,IACtC;AAAA,cACG,YAAY,cAAc,IAAgC,SAAS,KAAK;AAAA,YAC3E,IACA;AAAA,YACJ,UAAU,cAAc,eAAe,KAAK;AAAA,UAC9C;AAAA,QACF,CAAC;AACD,cAAM,cAAc,aAAa,MAAM,MAAM,CAAC;AAAA,MAChD,OAAO;AACL,cAAM,cAAc,aAAa,QAAQ,MAAM,CAAC;AAAA,MAClD;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;AAEH,UACG,QAAQ,iBAAiB,EACzB,YAAY,qBAAqB,EACjC,OAAO,yBAAyB,8BAA8B,EAC9D,OAAO,OAAO,UAAkB,YAAY;AAC3C,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AACpE,UAAM,SAAS,MAAM,UAAU,MAAM;AACrC,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAE9C,QAAI;AACF,YAAM,SAAS,MAAM,UAAU,QAAQ,aAAa,UAAU,QAAQ,WAAW;AACjF,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,UACG,QAAQ,mBAAmB,EAC3B,YAAY,mBAAmB,EAC/B,OAAO,iBAAiB,4BAA4B,EACpD,OAAO,OAAO,UAAkB,YAAY;AAC3C,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AACpE,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAC9C,UAAM,cAAc,cAAc,OAAO;AAEzC,YAAQ,OAAO,MAAM;AAAA,MACnB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,QACE,SAAS;AAAA,MACX;AAAA,MACA;AAAA,IACF;AAEA,QAAI,SAAS,OAAO,GAAG;AACrB;AAAA,QACE;AAAA,UACE,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,SAAS,EAAE,MAAM,QAAQ,KAAK;AAAA,QAChC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,UAAU,MAAM;AAErC,QAAI;AACF,YAAM,SAAS,MAAM,cAAc,QAAQ,aAAa,UAAU,QAAQ,IAAI;AAC9E,UAAI,WAAW,QAAQ;AACrB,cAAM,YAAY,QAAQ,KAAK;AAC/B,gBAAQ,IAAI,eAAe,SAAS,aAAa;AAAA,MACnD;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,UACG,QAAQ,SAAS,EACjB,YAAY,mEAAmE,EAC/E,OAAO,eAAe,+BAA+B,QAAQ,EAC7D,OAAO,iBAAiB,6BAA6B,EACrD,OAAO,kBAAkB,sCAAsC,EAC/D,OAAO,aAAa,wCAAwC,QAAQ,EACpE,OAAO,OAAO,YAAY;AACzB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AACpE,UAAM,SAAS,MAAM,UAAU,MAAM;AACrC,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAE9C,QAAI;AACF,YAAM,SAAS,MAAM,eAAe,QAAQ,aAAa;AAAA,QACvD,OAAO,QAAQ;AAAA,QACf,UAAU,QAAQ;AAAA,QAClB,OAAO,QAAQ;AAAA,QACf,YAAY,QAAQ;AAAA,MACtB,CAAC;AAED,UAAI,WAAW,QAAQ;AACrB,gBAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AACxC;AAAA,MACF;AAEA,cAAQ,IAAI;AAAA,yBAAuB,WAAW,EAAE;AAChD,cAAQ,IAAI,GAAG,SAAI,OAAO,EAAE,CAAC,EAAE;AAC/B,cAAQ,IAAI,oBAAoB,OAAO,YAAY,EAAE;AACrD,cAAQ;AAAA,QACN,oBAAoB,OAAO,YAAY,IAAI,OAAO,UAAU,QAAQ,CAAC,IAAI,YAAO,KAAK;AAAA,MACvF;AACA,cAAQ,IAAI;AAAA,WAAc;AAC1B,cAAQ;AAAA,QACN,eAAe,OAAO,UAAU,QAAQ,eAAe,OAAO,UAAU,QAAQ,cAAc,OAAO,UAAU,OAAO;AAAA,MACxH;AACA,cAAQ,IAAI,gBAAgB,OAAO,UAAU,QAAQ,mBAAmB;AAExE,UAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,gBAAQ,IAAI;AAAA,YAAe;AAC3B,mBAAW,KAAK,OAAO,OAAO,MAAM,GAAG,CAAC,GAAG;AACzC,gBAAM,MAAM,EAAE,WAAW,MAAM,MAAM,EAAE,WAAW,OAAO,MAAM;AAC/D,kBAAQ,IAAI,MAAM,GAAG,KAAK,EAAE,MAAM,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,UAAU;AAAA,QACnE;AAAA,MACF;AAEA,UAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,gBAAQ;AAAA,UACN;AAAA,gBAAmB,OAAO,SACvB,MAAM,GAAG,EAAE,EACX,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI,CAAC;AAAA,QACf;AAAA,MACF;AAEA,UAAI,OAAO,KAAK,OAAO,kBAAkB,EAAE,SAAS,GAAG;AACrD,gBAAQ,IAAI;AAAA,qBAAwB;AACpC,iBAAS,OAAO,GAAG,QAAQ,GAAG,QAAQ;AACpC,gBAAM,QAAQ,OAAO,mBAAmB,IAAI,KAAK;AACjD,cAAI,QAAQ,EAAG,SAAQ,IAAI,KAAK,IAAI,WAAM,KAAK,EAAE;AAAA,QACnD;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;AAEH,UACG,QAAQ,QAAQ,EAChB,YAAY,+BAA+B,EAC3C,OAAO,mBAAmB,8BAA8B,MAAM,EAC9D,OAAO,eAAe,+BAA+B,QAAQ,EAC7D,OAAO,iBAAiB,6BAA6B,EACrD,OAAO,kBAAkB,sCAAsC,EAC/D,OAAO,yBAAyB,+BAA+B,EAC/D,OAAO,mBAAmB,wCAAwC,EAClE,OAAO,OAAO,YAAY;AACzB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AACpE,UAAM,SAAS,MAAM,UAAU,MAAM;AAErC,QAAI;AACF,YAAM,SAAS,MAAM,cAAc,QAAQ,aAAa;AAAA,QACtD,QAAQ,QAAQ;AAAA,QAChB,OAAO,QAAQ;AAAA,QACf,UAAU,QAAQ;AAAA,QAClB,OAAO,QAAQ;AAAA,QACf,qBAAqB,QAAQ;AAAA,MAC/B,CAAC;AAED,UAAI,QAAQ,QAAQ;AAClB,cAAM,EAAE,UAAU,IAAI,MAAM,OAAO,aAAkB;AACrD,cAAM,UAAU,QAAQ,QAAQ,QAAQ,OAAO;AAC/C,gBAAQ,IAAI,uBAAuB,QAAQ,MAAM,EAAE;AAAA,MACrD,OAAO;AACL,gBAAQ,IAAI,MAAM;AAAA,MACpB;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;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/subscriptions.ts"],"sourcesContent":["import 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 type { Subscription } 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 diffSubscription,\n getSubscriptionAnalytics,\n formatOutput,\n sortResults,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { requireConfirm } from \"../prompt.js\";\nimport { readJsonFile } from \"../json.js\";\n\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 if (format !== \"json\") {\n const summary = (result.subscriptions || []).map((s: Subscription) => ({\n productId: s.productId,\n basePlans: s.basePlans?.length || 0,\n listings: s.listings ? Object.keys(s.listings).length : 0,\n firstBasePlanState: s.basePlans?.[0]?.state || \"-\",\n }));\n console.log(formatOutput(summary, 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(\"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 if (format !== \"json\") {\n const s = result as unknown as Record<string, unknown>;\n const basePlans = s[\"basePlans\"] as Array<Record<string, unknown>> | undefined;\n const listings = s[\"listings\"] as\n | Record<string, unknown>\n | Array<Record<string, unknown>>\n | undefined;\n const listingLanguages = listings\n ? Array.isArray(listings)\n ? listings.map((l) => l[\"languageCode\"] || l[\"language\"] || \"?\").join(\", \")\n : Object.keys(listings).join(\", \")\n : \"-\";\n const listingCount = listings\n ? Array.isArray(listings)\n ? listings.length\n : Object.keys(listings).length\n : 0;\n const summary = {\n productId: s[\"productId\"],\n basePlans: basePlans?.length || 0,\n basePlanIds: basePlans?.map((bp) => bp[\"basePlanId\"]).join(\", \") || \"-\",\n listings: listingCount,\n listingLanguages,\n taxCategory: (s[\"taxAndComplianceSettings\"] as Record<string, unknown>)?.[\n \"taxRateInfoByRegionCode\"\n ]\n ? \"configured\"\n : \"-\",\n };\n console.log(formatOutput(summary, 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(\"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 = await readJsonFile(options.file);\n const result = await createSubscription(client, packageName, data as any);\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 = await readJsonFile(options.file);\n const result = await updateSubscription(\n client,\n packageName,\n productId,\n data as any,\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 = await readJsonFile(options.file);\n const result = await migratePrices(\n client,\n packageName,\n productId,\n basePlanId,\n data as any,\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 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 const offers_list = (result as unknown as Record<string, unknown>)[\"subscriptionOffers\"] as\n | Array<Record<string, unknown>>\n | undefined;\n if (format !== \"json\") {\n if (!offers_list || offers_list.length === 0) {\n console.log(\"No offers found.\");\n return;\n }\n const summary = offers_list.map((o) => ({\n offerId: o[\"offerId\"],\n basePlanId: o[\"basePlanId\"],\n state: o[\"state\"] || \"-\",\n phases: (o[\"phases\"] as unknown[])?.length || 0,\n regionalConfigs: (o[\"regionalConfigs\"] as unknown[])?.length || 0,\n }));\n console.log(formatOutput(summary, 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 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 = await readJsonFile(options.file);\n const result = await createOffer(client, packageName, productId, basePlanId, data as any);\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 = await readJsonFile(options.file);\n const result = await updateOffer(\n client,\n packageName,\n productId,\n basePlanId,\n offerId,\n data as any,\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 // --- Diff ---\n subs\n .command(\"diff <product-id>\")\n .description(\"Compare local JSON file against remote subscription\")\n .requiredOption(\"--file <path>\", \"Local JSON file to compare against remote\")\n .action(async (productId: string, options: { file: string }) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const localData = (await readJsonFile(options.file)) as Subscription;\n const diffs = await diffSubscription(client, packageName, productId, localData);\n if (diffs.length === 0) {\n console.log(\"No differences found.\");\n } else {\n console.log(formatOutput(diffs, format));\n }\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n subs\n .command(\"analytics\")\n .description(\"Subscription catalog analytics: active plans, offer counts, state breakdown\")\n .action(async () => {\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 getSubscriptionAnalytics(client, packageName);\n\n if (format === \"json\") {\n console.log(formatOutput(result, format));\n return;\n }\n\n console.log(`\\nSubscription Analytics — ${packageName}`);\n console.log(`${\"─\".repeat(50)}`);\n console.log(`Total subscriptions: ${result.totalSubscriptions}`);\n console.log(`Active subscriptions: ${result.activeCount}`);\n console.log(`Active base plans: ${result.activeBasePlans}`);\n console.log(`Draft base plans: ${result.trialBasePlans}`);\n console.log(`Inactive base plans: ${result.pausedBasePlans}`);\n console.log(`Total offers: ${result.offerCount}`);\n\n if (result.byProductId.length > 0) {\n console.log(`\\nBy product:`);\n console.log(formatOutput(result.byProductId, format));\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":["basePlans"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/testers.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 listTesters,\n addTesters,\n removeTesters,\n importTestersFromCsv,\n formatOutput,\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\nexport function registerTestersCommands(program: Command): void {\n const testers = program.command(\"testers\").description(\"Manage testers and tester groups\");\n\n testers\n .command(\"list\")\n .description(\"List testers for a track\")\n .option(\"--track <track>\", \"Track name (e.g., internal, alpha, beta)\")\n .option(\"--sort <field>\", \"Sort by field (prefix with - for descending, e.g., email or -email)\")\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.track = await requireOption(\n \"track\",\n options.track,\n {\n message: \"Track:\",\n choices: [\"internal\", \"alpha\", \"beta\"],\n },\n interactive,\n );\n\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n try {\n const result = await listTesters(client, packageName, options.track);\n if (options.sort && result.googleGroups) {\n const descending = options.sort.startsWith(\"-\");\n result.googleGroups = [...result.googleGroups].sort((a: string, b: string) =>\n descending ? b.localeCompare(a) : a.localeCompare(b),\n );\n }\n if (format !== \"json\") {\n const groups = (result.googleGroups || []) as string[];\n const rows = groups.map((g: string) => ({ googleGroup: g }));\n if (rows.length > 0) {\n console.log(formatOutput(rows, format));\n } else {\n console.log(\"No testers found.\");\n }\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 testers\n .command(\"add <emails...>\")\n .description(\"Add testers (Google Group emails) to a track\")\n .option(\"--track <track>\", \"Track name (e.g., internal, alpha, beta)\")\n .action(async (emails: 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.track = await requireOption(\n \"track\",\n options.track,\n {\n message: \"Track:\",\n choices: [\"internal\", \"alpha\", \"beta\"],\n },\n interactive,\n );\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"testers add\",\n action: \"add testers to\",\n target: options.track,\n details: { emails },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await addTesters(client, packageName, options.track, emails);\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 testers\n .command(\"remove <emails...>\")\n .description(\"Remove testers (Google Group emails) from a track\")\n .option(\"--track <track>\", \"Track name (e.g., internal, alpha, beta)\")\n .action(async (emails: 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.track = await requireOption(\n \"track\",\n options.track,\n {\n message: \"Track:\",\n choices: [\"internal\", \"alpha\", \"beta\"],\n },\n interactive,\n );\n\n await requireConfirm(`Remove ${emails.length} tester(s) from ${options.track}?`, program);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"testers remove\",\n action: \"remove testers from\",\n target: options.track,\n details: { emails },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const result = await removeTesters(client, packageName, options.track, emails);\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 testers\n .command(\"import\")\n .description(\"Import testers from a CSV file\")\n .option(\"--track <track>\", \"Track name (e.g., internal, alpha, beta)\")\n .option(\"--file <path>\", \"CSV file with email addresses\")\n .action(async (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.track = await requireOption(\n \"track\",\n options.track,\n {\n message: \"Track:\",\n choices: [\"internal\", \"alpha\", \"beta\"],\n },\n interactive,\n );\n\n options.file = await requireOption(\n \"file\",\n options.file,\n {\n message: \"CSV file path:\",\n },\n interactive,\n );\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"testers import\",\n action: \"import testers to\",\n target: options.track,\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 result = await importTestersFromCsv(client, packageName, options.track, options.file);\n console.log(formatOutput({ added: result.added, testers: result.testers }, 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/train.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, createReportingClient } from \"@gpc-cli/api\";\nimport {\n startTrain,\n getTrainStatus,\n pauseTrain,\n abortTrain,\n advanceTrain,\n formatOutput,\n} from \"@gpc-cli/core\";\nimport type { TrainConfig } 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 getClients(config: GpcConfig) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return {\n apiClient: createApiClient({ auth }),\n reportingClient: createReportingClient({ auth }),\n };\n}\n\nasync function loadTrainConfig(file: string): Promise<TrainConfig> {\n const { readFile } = await import(\"node:fs/promises\");\n try {\n const raw = await readFile(file, \"utf-8\");\n return JSON.parse(raw) as TrainConfig;\n } catch {\n console.error(`Error: Could not read train config from \"${file}\"`);\n process.exit(2);\n }\n}\n\nexport function registerTrainCommands(program: Command): void {\n const train = program\n .command(\"train\")\n .description(\"Manage config-driven staged rollout release trains\");\n\n train\n .command(\"start\")\n .description(\"Start a release train from a config file\")\n .option(\"--config <file>\", \"Train config file (JSON)\", \".gpcrc-train.json\")\n .option(\"--force\", \"Restart even if a train is already running\")\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 const trainConfig = await loadTrainConfig(options.config as string);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"train start\",\n action: \"start release train\",\n target: packageName,\n details: { stages: trainConfig.stages.length, gates: trainConfig.gates },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const { apiClient } = await getClients(config);\n\n try {\n const state = await startTrain(apiClient, packageName, trainConfig, {\n force: options.force as boolean,\n });\n console.log(formatOutput(state, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n train\n .command(\"status\")\n .description(\"Show current release train state\")\n .action(async () => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n try {\n const state = await getTrainStatus(packageName);\n if (!state) {\n if (format === \"json\") {\n console.log(formatOutput(null, format));\n } else {\n console.log(`No active release train for ${packageName}.`);\n }\n return;\n }\n console.log(formatOutput(state, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n train\n .command(\"advance\")\n .description(\"Advance the train to the next stage (after delay and gate checks pass)\")\n .action(async () => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n const { apiClient, reportingClient } = await getClients(config);\n\n try {\n const state = await advanceTrain(apiClient, reportingClient, packageName);\n if (!state) {\n console.log(`No active release train for ${packageName}.`);\n return;\n }\n console.log(formatOutput(state, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n train\n .command(\"pause\")\n .description(\"Pause the release train\")\n .action(async () => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = getOutputFormat(program, config);\n\n try {\n const state = await pauseTrain(packageName);\n if (!state) {\n console.log(`No active release train for ${packageName}.`);\n return;\n }\n console.log(formatOutput(state, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n train\n .command(\"abort\")\n .description(\"Abort and clear the release train state\")\n .action(async () => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Abort release train for ${packageName}?`, program);\n\n try {\n await abortTrain(packageName);\n console.log(`Release train aborted for ${packageName}.`);\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 getVitalsLmk,\n getVitalsAnomalies,\n searchVitalsErrors,\n compareVitalsTrend,\n compareVersionVitals,\n watchVitalsWithAutoHalt,\n checkThreshold,\n formatOutput,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { red, yellow, green } from \"../colors.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 \"startType\", // Required dimension for slowStartRateMetricSet\n];\n\nconst THRESHOLD_CONFIG_KEYS: Record<string, string> = {\n crashes: \"crashRate\",\n anr: \"anrRate\",\n startup: \"slowStartRate\",\n rendering: \"slowRenderingRate\",\n battery: \"excessiveWakeupRate\",\n memory: \"stuckWakelockRate\",\n wakeup: \"excessiveWakeupRate\",\n lmk: \"stuckWakelockRate\",\n};\n\nfunction validateDimension(dim: string): ReportingDimension {\n if (!(VALID_DIMENSIONS as readonly string[]).includes(dim)) {\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 if (format !== \"json\" && (!result.rows || result.rows.length === 0)) {\n console.log(`${yellow(\"⚠\")} No vitals data available.`);\n return;\n }\n if (format !== \"json\" && result.rows) {\n const rows = result.rows.map((row: unknown) => {\n const rowR = row as Record<string, unknown>;\n const startTime = rowR[\"startTime\"] as Record<string, unknown> | undefined;\n const metrics = rowR[\"metrics\"] as\n | Record<string, Record<string, unknown>>\n | unknown[]\n | undefined;\n const flat: Record<string, unknown> = {\n date: startTime\n ? `${startTime[\"year\"]}-${String(startTime[\"month\"]).padStart(2, \"0\")}-${String(startTime[\"day\"]).padStart(2, \"0\")}`\n : \"-\",\n };\n if (metrics && !Array.isArray(metrics)) {\n for (const [key, val] of Object.entries(metrics)) {\n flat[key] =\n (val as Record<string, unknown>)?.[\"decimalValue\"] !== undefined\n ? ((val as Record<string, Record<string, unknown>>)?.[\"decimalValue\"]?.[\n \"value\"\n ] ?? \"-\")\n : \"-\";\n }\n } else if (Array.isArray(metrics)) {\n // Fallback: if API returns metrics as array, use metric names from config\n for (let i = 0; i < metrics.length; i++) {\n const val = metrics[i] as Record<string, unknown> | undefined;\n const metricName = val?.[\"metric\"] as string | undefined;\n const key = metricName ?? `metric${i}`;\n flat[key] =\n (val as Record<string, unknown>)?.[\"decimalValue\"] !== undefined\n ? ((val as Record<string, Record<string, unknown>>)?.[\"decimalValue\"]?.[\n \"value\"\n ] ?? \"-\")\n : \"-\";\n }\n }\n const dims = rowR[\"dimensions\"] as Record<string, unknown> | unknown[] | undefined;\n if (dims && !Array.isArray(dims)) {\n for (const [key, val] of Object.entries(dims)) {\n flat[key] = (val as Record<string, unknown>)?.[\"stringValue\"] ?? \"-\";\n }\n } else if (Array.isArray(dims)) {\n // Fallback: if API returns dimensions as array\n for (let i = 0; i < dims.length; i++) {\n const val = dims[i] as Record<string, unknown> | undefined;\n const dimName = val?.[\"dimension\"] as string | undefined;\n flat[dimName ?? `dim${i}`] = val?.[\"stringValue\"] ?? val?.[\"int64Value\"] ?? \"-\";\n }\n }\n return flat;\n });\n console.log(formatOutput(rows, format));\n } else {\n console.log(formatOutput(result, format));\n }\n\n // Check threshold from flag or config\n const configKey = THRESHOLD_CONFIG_KEYS[name];\n const configThreshold = configKey\n ? (config as unknown as Record<string, unknown>)[\"vitals\"]\n ? ((config as unknown as Record<string, unknown>)[\"vitals\"] as Record<string, unknown>)[\n \"thresholds\"\n ]\n ? (\n (\n (config as unknown as Record<string, unknown>)[\"vitals\"] as Record<\n string,\n unknown\n >\n )[\"thresholds\"] as Record<string, unknown>\n )[configKey]\n : undefined\n : undefined\n : undefined;\n const threshold =\n options.threshold ??\n (configThreshold !== undefined ? Number(configThreshold) : undefined);\n if (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, threshold);\n if (check.breached) {\n console.error(`${red(\"✗\")} 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 (Object.keys(result).length === 0) {\n if (format === \"json\") {\n console.log(formatOutput({ vitals: [], message: \"No vitals data available\" }, format));\n } else {\n console.log(\"No vitals data available.\");\n }\n return;\n }\n if (format !== \"json\") {\n const overview = result as Record<string, unknown>;\n const rows = Object.entries(overview).map(([metric, data]) => {\n const metricRows = data as Record<string, unknown>[] | undefined;\n const latest = metricRows?.[metricRows.length - 1];\n const metrics = latest?.[\"metrics\"] as\n | Record<string, Record<string, unknown>>\n | undefined;\n const firstKey = metrics ? Object.keys(metrics)[0] : undefined;\n const value = firstKey\n ? (metrics?.[firstKey]?.[\"decimalValue\"] as Record<string, unknown> | undefined)?.[\n \"value\"\n ]\n : undefined;\n return {\n metric,\n dataPoints: metricRows?.length || 0,\n latestValue: value ?? \"-\",\n };\n });\n console.log(formatOutput(rows, 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 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 registerMetricCommand(\n vitals,\n \"wakeup\",\n \"Query excessive wakeup rate metrics\",\n getVitalsBattery,\n program,\n );\n registerMetricCommand(\n vitals,\n \"lmk\",\n \"Query low-memory kill (stuck wakelock) metrics\",\n getVitalsLmk,\n program,\n );\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 const issues = (result as unknown as Record<string, unknown>)[\"errorIssues\"] as\n | unknown[]\n | undefined;\n if (format !== \"json\" && (!issues || issues.length === 0)) {\n console.log(\"No error issues found.\");\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 const METRIC_MAP: Record<string, VitalsMetricSet> = {\n crashes: \"crashRateMetricSet\",\n anr: \"anrRateMetricSet\",\n startup: \"slowStartRateMetricSet\",\n rendering: \"slowRenderingRateMetricSet\",\n battery: \"excessiveWakeupRateMetricSet\",\n memory: \"stuckBackgroundWakelockRateMetricSet\",\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\", (v) => parseInt(v, 10), 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 vitals\n .command(\"compare-versions <v1> <v2>\")\n .description(\"Compare vitals side-by-side for two version codes\")\n .option(\"--days <n>\", \"Number of days to query\", (v) => parseInt(v, 10), 30)\n .action(async (v1: string, v2: string, 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 compareVersionVitals(reporting, packageName, v1, v2, {\n days: options.days,\n });\n\n if (format === \"json\") {\n console.log(formatOutput(result, format));\n return;\n }\n\n const metrics: [keyof typeof result.v1, string][] = [\n [\"crashRate\", \"Crash Rate\"],\n [\"anrRate\", \"ANR Rate\"],\n [\"slowStartRate\", \"Slow Start Rate\"],\n [\"slowRenderingRate\", \"Slow Rendering Rate\"],\n ];\n\n console.log(`\\nVersion Comparison — ${packageName}`);\n console.log(`${\"─\".repeat(60)}`);\n console.log(`${\"Metric\".padEnd(22)} ${\"v\" + v1.padEnd(14)} ${\"v\" + v2.padEnd(14)} Change`);\n console.log(`${\"─\".repeat(60)}`);\n\n for (const [key, label] of metrics) {\n const val1 = result.v1[key] as number | undefined;\n const val2 = result.v2[key] as number | undefined;\n const s1 = val1 !== undefined ? (val1 * 100).toFixed(3) + \"%\" : \"N/A\";\n const s2 = val2 !== undefined ? (val2 * 100).toFixed(3) + \"%\" : \"N/A\";\n const isRegression = result.regressions.includes(key as string);\n const change =\n val1 !== undefined && val2 !== undefined ? ((val2 - val1) / val1) * 100 : undefined;\n const changeStr =\n change !== undefined ? (change > 0 ? \"+\" : \"\") + change.toFixed(1) + \"%\" : \"N/A\";\n const colorFn = isRegression\n ? red\n : change !== undefined && change < -1\n ? green\n : (s: string) => s;\n console.log(\n `${label.padEnd(22)} ${s1.padEnd(15)} ${colorFn(s2.padEnd(15))} ${colorFn(changeStr)}`,\n );\n }\n\n if (result.regressions.length > 0) {\n console.log(`\\n${red(\"✗\")} Regressions detected: ${result.regressions.join(\", \")}`);\n } else {\n console.log(`\\n${green(\"✓\")} No regressions detected.`);\n }\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n vitals\n .command(\"watch\")\n .description(\"Monitor vitals continuously and optionally auto-halt rollout on breach\")\n .requiredOption(\"--threshold <value>\", \"Breach threshold value\", parseFloat)\n .option(\n \"--metric <name>\",\n \"Metric to monitor (crashes, anr, startup, rendering, battery, memory)\",\n \"crashes\",\n )\n .option(\"--interval <seconds>\", \"Polling interval in seconds\", (v) => parseInt(v, 10), 300)\n .option(\"--auto-halt-rollout\", \"Automatically halt rollout if threshold is breached\")\n .option(\"--track <name>\", \"Track to halt rollout on (required with --auto-halt-rollout)\")\n .action(async (options) => {\n const metricSet = METRIC_MAP[options.metric as string];\n if (!metricSet) {\n console.error(\n `Error: Unknown metric \"${options.metric}\". Use: ${Object.keys(METRIC_MAP).join(\", \")}`,\n );\n process.exit(2);\n }\n\n if (options.autoHaltRollout && !options.track) {\n console.error(\"Error: --track <name> is required when using --auto-halt-rollout\");\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 intervalMs = (options.interval as number) * 1000;\n\n console.log(`Watching ${options.metric} for ${packageName}`);\n console.log(`Threshold: ${options.threshold} Interval: ${options.interval}s`);\n if (options.autoHaltRollout) {\n console.log(`Auto-halt enabled on track: ${options.track}`);\n }\n console.log(\"Press Ctrl+C to stop.\\n\");\n\n const stop = watchVitalsWithAutoHalt(reporting, packageName, {\n intervalMs,\n threshold: options.threshold as number,\n metricSet,\n onPoll: (value, breached) => {\n const ts = new Date().toISOString();\n const valStr = value !== undefined ? (value * 100).toFixed(3) + \"%\" : \"N/A\";\n const indicator = breached ? red(\"✗ BREACH\") : green(\"✓ OK\");\n console.log(`[${ts}] ${options.metric}: ${valStr} — ${indicator}`);\n },\n onHalt: options.autoHaltRollout\n ? async (value: number) => {\n console.error(\n `\\n${red(\"✗\")} Threshold breached (${(value * 100).toFixed(3)}% > ${options.threshold}%). Halting rollout on track \"${options.track}\"...`,\n );\n try {\n const { resolveAuth } = await import(\"@gpc-cli/auth\");\n const { createApiClient } = await import(\"@gpc-cli/api\");\n const { updateRollout } = await import(\"@gpc-cli/core\");\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n const apiClient = createApiClient({ auth });\n await updateRollout(apiClient, packageName, options.track as string, \"halt\");\n console.error(`${red(\"⚠\")} Rollout halted on track \"${options.track}\".`);\n } catch (err) {\n console.error(\n `Failed to halt rollout: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n stop();\n process.exit(6);\n }\n : undefined,\n });\n\n process.on(\"SIGINT\", () => {\n stop();\n console.log(\"\\nWatch stopped.\");\n process.exit(0);\n });\n });\n}\n"],"mappings":"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","names":["resolveAuth"]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|