@gpc-cli/cli 0.9.8 → 0.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +18 -1
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-JVGSSJLY.js → chunk-ZXEA4KAA.js} +14 -8
- package/dist/chunk-ZXEA4KAA.js.map +1 -0
- package/dist/{completion-3UYUJD6S.js → completion-C3PPWNS7.js} +68 -1
- package/dist/completion-C3PPWNS7.js.map +1 -0
- package/dist/{iap-ZZS5NVFN.js → iap-2CV6SJUF.js} +7 -2
- package/dist/iap-2CV6SJUF.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/{internal-sharing-ZQUI3SDM.js → internal-sharing-TWMHLQLN.js} +7 -2
- package/dist/internal-sharing-TWMHLQLN.js.map +1 -0
- package/dist/{listings-LTVQHMX3.js → listings-4QCTOEWL.js} +34 -2
- package/dist/listings-4QCTOEWL.js.map +1 -0
- package/dist/migrate-5IA6WGMO.js +76 -0
- package/dist/migrate-5IA6WGMO.js.map +1 -0
- package/dist/purchase-options-2NUBLODI.js +145 -0
- package/dist/purchase-options-2NUBLODI.js.map +1 -0
- package/dist/{releases-GUMQZRFC.js → releases-HDCDARH5.js} +30 -3
- package/dist/releases-HDCDARH5.js.map +1 -0
- package/dist/tracks-D6FUNJ75.js +84 -0
- package/dist/tracks-D6FUNJ75.js.map +1 -0
- package/package.json +5 -5
- package/dist/chunk-JVGSSJLY.js.map +0 -1
- package/dist/completion-3UYUJD6S.js.map +0 -1
- package/dist/iap-ZZS5NVFN.js.map +0 -1
- package/dist/internal-sharing-ZQUI3SDM.js.map +0 -1
- package/dist/listings-LTVQHMX3.js.map +0 -1
- package/dist/releases-GUMQZRFC.js.map +0 -1
- package/dist/tracks-AJH5KP7J.js +0 -41
- package/dist/tracks-AJH5KP7J.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
createProgram,
|
|
4
4
|
handleCliError,
|
|
5
5
|
loadPlugins
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ZXEA4KAA.js";
|
|
7
7
|
|
|
8
8
|
// src/networking.ts
|
|
9
9
|
async function setupNetworking() {
|
|
@@ -110,6 +110,23 @@ await setupNetworking();
|
|
|
110
110
|
initAudit(getConfigDir());
|
|
111
111
|
var currentVersion = process.env["__GPC_VERSION"] || "0.0.0";
|
|
112
112
|
var updateCheckPromise = checkForUpdate(currentVersion);
|
|
113
|
+
if (process.argv.includes("--ci")) {
|
|
114
|
+
process.env["CI"] = "1";
|
|
115
|
+
if (!process.argv.some((a) => a.startsWith("--output") || a.startsWith("-o"))) {
|
|
116
|
+
process.argv.push("--output", "json");
|
|
117
|
+
}
|
|
118
|
+
if (!process.argv.includes("--no-interactive")) {
|
|
119
|
+
process.argv.push("--no-interactive");
|
|
120
|
+
}
|
|
121
|
+
if (!process.argv.includes("--no-color")) {
|
|
122
|
+
process.argv.push("--no-color");
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (process.argv.includes("--json") || process.argv.includes("-j")) {
|
|
126
|
+
if (!process.argv.some((a) => a.startsWith("--output") || a.startsWith("-o"))) {
|
|
127
|
+
process.argv.push("--output", "json");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
113
130
|
var pluginManager = await loadPlugins();
|
|
114
131
|
var program = await createProgram(pluginManager);
|
|
115
132
|
var startTime = Date.now();
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/networking.ts","../src/bin.ts","../src/update-check.ts"],"sourcesContent":["/**\n * Set up proxy and custom CA certificate support.\n * Must be called before any fetch() calls.\n */\nexport async function setupNetworking(): Promise<void> {\n // Map GPC_CA_CERT to NODE_EXTRA_CA_CERTS (works in both Node and Bun)\n const caCert = process.env[\"GPC_CA_CERT\"];\n if (caCert && !process.env[\"NODE_EXTRA_CA_CERTS\"]) {\n process.env[\"NODE_EXTRA_CA_CERTS\"] = caCert;\n }\n\n // In standalone binary mode, Bun handles HTTPS_PROXY/HTTP_PROXY natively\n if (process.env[\"__GPC_BINARY\"] === \"1\") return;\n\n const proxyUrl =\n process.env[\"HTTPS_PROXY\"] ||\n process.env[\"https_proxy\"] ||\n process.env[\"HTTP_PROXY\"] ||\n process.env[\"http_proxy\"];\n if (proxyUrl) {\n try {\n // @ts-expect-error undici types not available in all environments\n const { ProxyAgent, setGlobalDispatcher } = await import(\"undici\");\n setGlobalDispatcher(new ProxyAgent(proxyUrl));\n } catch {\n console.error(\"Warning: Proxy support requires Node.js 20+. HTTPS_PROXY will be ignored.\");\n }\n }\n}\n","import { setupNetworking } from \"./networking.js\";\nimport { createProgram } from \"./program.js\";\nimport { loadPlugins } from \"./plugins.js\";\nimport { handleCliError } from \"./error-handler.js\";\nimport { initAudit, sendWebhook } from \"@gpc-cli/core\";\nimport type { WebhookPayload } from \"@gpc-cli/core\";\nimport { getConfigDir, loadConfig } from \"@gpc-cli/config\";\nimport { checkForUpdate, formatUpdateNotification } from \"./update-check.js\";\n\nawait setupNetworking();\ninitAudit(getConfigDir());\n\nconst currentVersion = process.env[\"__GPC_VERSION\"] || \"0.0.0\";\n\n// Start update check before command execution (non-blocking)\nconst updateCheckPromise = checkForUpdate(currentVersion);\n\nconst pluginManager = await loadPlugins();\nconst program = await createProgram(pluginManager);\n\nconst startTime = Date.now();\nlet commandSuccess = true;\nlet commandError: string | undefined;\n\nawait program.parseAsync(process.argv).catch((error: unknown) => {\n commandSuccess = false;\n commandError = error instanceof Error ? error.message : String(error);\n const exitCode = handleCliError(error);\n process.exit(exitCode);\n});\n\n// Send webhook notification if --notify was set\nconst notifyOpt = program.opts()[\"notify\"] as string | boolean | undefined;\nif (notifyOpt !== undefined && notifyOpt !== false) {\n try {\n const config = await loadConfig();\n if (config.webhooks) {\n const commandName = process.argv.slice(2).filter((a) => !a.startsWith(\"--notify\")).join(\" \");\n const payload: WebhookPayload = {\n command: commandName || \"unknown\",\n success: commandSuccess,\n duration: Date.now() - startTime,\n app: program.opts()[\"app\"] as string | undefined,\n error: commandError,\n };\n\n const target = typeof notifyOpt === \"string\" ? notifyOpt : undefined;\n // Fire-and-forget — do not block exit\n sendWebhook(config.webhooks, payload, target).catch(() => {});\n }\n } catch {\n // Never let webhook logic break the CLI\n }\n}\n\n// After command completes, show update notification if available\ntry {\n const result = await Promise.race([\n updateCheckPromise,\n new Promise<null>((resolve) => setTimeout(() => resolve(null), 3000)),\n ]);\n\n if (\n result &&\n result.updateAvailable &&\n process.stdout.isTTY &&\n !process.argv.includes(\"--json\") &&\n program.opts()[\"output\"] !== \"json\"\n ) {\n process.stderr.write(`\\n${formatUpdateNotification(result)}\\n`);\n }\n} catch {\n // Silently ignore update check failures\n}\n","import { join } from \"node:path\";\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { getCacheDir } from \"@gpc-cli/config\";\n\nexport interface UpdateCheckResult {\n current: string;\n latest: string;\n updateAvailable: boolean;\n}\n\ninterface CacheData {\n latest: string;\n checkedAt: number;\n}\n\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\nconst FETCH_TIMEOUT_MS = 3000;\nconst REGISTRY_URL = \"https://registry.npmjs.org/@gpc-cli/cli/latest\";\n\nfunction getCacheFilePath(): string {\n return join(getCacheDir(), \"update-check.json\");\n}\n\n/**\n * Compare two semver strings numerically.\n * Returns true if `b` is newer than `a`.\n */\nexport function isNewerVersion(current: string, latest: string): boolean {\n const a = current.split(\".\").map(Number);\n const b = latest.split(\".\").map(Number);\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const av = a[i] ?? 0;\n const bv = b[i] ?? 0;\n if (bv > av) return true;\n if (bv < av) return false;\n }\n return false;\n}\n\nasync function readCache(): Promise<CacheData | null> {\n try {\n const raw = await readFile(getCacheFilePath(), \"utf-8\");\n const data = JSON.parse(raw) as CacheData;\n if (typeof data.latest === \"string\" && typeof data.checkedAt === \"number\") {\n return data;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction writeCache(data: CacheData): void {\n const filePath = getCacheFilePath();\n const dir = join(filePath, \"..\");\n // Fire-and-forget: ignore write errors\n mkdir(dir, { recursive: true })\n .then(() => writeFile(filePath, JSON.stringify(data), \"utf-8\"))\n .catch(() => {});\n}\n\nasync function fetchLatestVersion(): Promise<string | null> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n\n const response = await fetch(REGISTRY_URL, { signal: controller.signal });\n clearTimeout(timeout);\n\n if (!response.ok) return null;\n\n const body = (await response.json()) as { version?: string };\n if (typeof body.version !== \"string\") return null;\n\n return body.version;\n } catch {\n return null;\n }\n}\n\n/**\n * Check for a newer version of @gpc-cli/cli on npm.\n * Returns null if the check is skipped or fails.\n */\nexport async function checkForUpdate(currentVersion: string): Promise<UpdateCheckResult | null> {\n // Skip in non-interactive or CI environments\n if (process.env[\"GPC_NO_UPDATE_CHECK\"] === \"1\") return null;\n if (process.env[\"CI\"]) return null;\n if (!process.stdout.isTTY) return null;\n\n // Check cache first\n const cache = await readCache();\n if (cache && Date.now() - cache.checkedAt < CACHE_TTL_MS) {\n return {\n current: currentVersion,\n latest: cache.latest,\n updateAvailable: isNewerVersion(currentVersion, cache.latest),\n };\n }\n\n // Fetch from registry\n const latest = await fetchLatestVersion();\n if (!latest) return null;\n\n // Write cache (fire-and-forget)\n writeCache({ latest, checkedAt: Date.now() });\n\n return {\n current: currentVersion,\n latest,\n updateAvailable: isNewerVersion(currentVersion, latest),\n };\n}\n\n/**\n * Format a user-facing update notification string.\n */\nexport function formatUpdateNotification(result: UpdateCheckResult): string {\n return `Update available: ${result.current} \\u2192 ${result.latest} \\u2014 npm install -g @gpc-cli/cli`;\n}\n"],"mappings":"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","names":["currentVersion"]}
|
|
1
|
+
{"version":3,"sources":["../src/networking.ts","../src/bin.ts","../src/update-check.ts"],"sourcesContent":["/**\n * Set up proxy and custom CA certificate support.\n * Must be called before any fetch() calls.\n */\nexport async function setupNetworking(): Promise<void> {\n // Map GPC_CA_CERT to NODE_EXTRA_CA_CERTS (works in both Node and Bun)\n const caCert = process.env[\"GPC_CA_CERT\"];\n if (caCert && !process.env[\"NODE_EXTRA_CA_CERTS\"]) {\n process.env[\"NODE_EXTRA_CA_CERTS\"] = caCert;\n }\n\n // In standalone binary mode, Bun handles HTTPS_PROXY/HTTP_PROXY natively\n if (process.env[\"__GPC_BINARY\"] === \"1\") return;\n\n const proxyUrl =\n process.env[\"HTTPS_PROXY\"] ||\n process.env[\"https_proxy\"] ||\n process.env[\"HTTP_PROXY\"] ||\n process.env[\"http_proxy\"];\n if (proxyUrl) {\n try {\n // @ts-expect-error undici types not available in all environments\n const { ProxyAgent, setGlobalDispatcher } = await import(\"undici\");\n setGlobalDispatcher(new ProxyAgent(proxyUrl));\n } catch {\n console.error(\"Warning: Proxy support requires Node.js 20+. HTTPS_PROXY will be ignored.\");\n }\n }\n}\n","import { setupNetworking } from \"./networking.js\";\nimport { createProgram } from \"./program.js\";\nimport { loadPlugins } from \"./plugins.js\";\nimport { handleCliError } from \"./error-handler.js\";\nimport { initAudit, sendWebhook } from \"@gpc-cli/core\";\nimport type { WebhookPayload } from \"@gpc-cli/core\";\nimport { getConfigDir, loadConfig } from \"@gpc-cli/config\";\nimport { checkForUpdate, formatUpdateNotification } from \"./update-check.js\";\n\nawait setupNetworking();\ninitAudit(getConfigDir());\n\nconst currentVersion = process.env[\"__GPC_VERSION\"] || \"0.0.0\";\n\n// Start update check before command execution (non-blocking)\nconst updateCheckPromise = checkForUpdate(currentVersion);\n\n// Handle --ci and --json flags early (before command parsing)\nif (process.argv.includes(\"--ci\")) {\n process.env[\"CI\"] = \"1\";\n // --ci implies --output json --no-interactive --no-color\n if (!process.argv.some((a) => a.startsWith(\"--output\") || a.startsWith(\"-o\"))) {\n process.argv.push(\"--output\", \"json\");\n }\n if (!process.argv.includes(\"--no-interactive\")) {\n process.argv.push(\"--no-interactive\");\n }\n if (!process.argv.includes(\"--no-color\")) {\n process.argv.push(\"--no-color\");\n }\n}\nif (process.argv.includes(\"--json\") || process.argv.includes(\"-j\")) {\n if (!process.argv.some((a) => a.startsWith(\"--output\") || a.startsWith(\"-o\"))) {\n process.argv.push(\"--output\", \"json\");\n }\n}\n\nconst pluginManager = await loadPlugins();\nconst program = await createProgram(pluginManager);\n\nconst startTime = Date.now();\nlet commandSuccess = true;\nlet commandError: string | undefined;\n\nawait program.parseAsync(process.argv).catch((error: unknown) => {\n commandSuccess = false;\n commandError = error instanceof Error ? error.message : String(error);\n const exitCode = handleCliError(error);\n process.exit(exitCode);\n});\n\n// Send webhook notification if --notify was set\nconst notifyOpt = program.opts()[\"notify\"] as string | boolean | undefined;\nif (notifyOpt !== undefined && notifyOpt !== false) {\n try {\n const config = await loadConfig();\n if (config.webhooks) {\n const commandName = process.argv.slice(2).filter((a) => !a.startsWith(\"--notify\")).join(\" \");\n const payload: WebhookPayload = {\n command: commandName || \"unknown\",\n success: commandSuccess,\n duration: Date.now() - startTime,\n app: program.opts()[\"app\"] as string | undefined,\n error: commandError,\n };\n\n const target = typeof notifyOpt === \"string\" ? notifyOpt : undefined;\n // Fire-and-forget — do not block exit\n sendWebhook(config.webhooks, payload, target).catch(() => {});\n }\n } catch {\n // Never let webhook logic break the CLI\n }\n}\n\n// After command completes, show update notification if available\ntry {\n const result = await Promise.race([\n updateCheckPromise,\n new Promise<null>((resolve) => setTimeout(() => resolve(null), 3000)),\n ]);\n\n if (\n result &&\n result.updateAvailable &&\n process.stdout.isTTY &&\n !process.argv.includes(\"--json\") &&\n program.opts()[\"output\"] !== \"json\"\n ) {\n process.stderr.write(`\\n${formatUpdateNotification(result)}\\n`);\n }\n} catch {\n // Silently ignore update check failures\n}\n","import { join } from \"node:path\";\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { getCacheDir } from \"@gpc-cli/config\";\n\nexport interface UpdateCheckResult {\n current: string;\n latest: string;\n updateAvailable: boolean;\n}\n\ninterface CacheData {\n latest: string;\n checkedAt: number;\n}\n\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\nconst FETCH_TIMEOUT_MS = 3000;\nconst REGISTRY_URL = \"https://registry.npmjs.org/@gpc-cli/cli/latest\";\n\nfunction getCacheFilePath(): string {\n return join(getCacheDir(), \"update-check.json\");\n}\n\n/**\n * Compare two semver strings numerically.\n * Returns true if `b` is newer than `a`.\n */\nexport function isNewerVersion(current: string, latest: string): boolean {\n const a = current.split(\".\").map(Number);\n const b = latest.split(\".\").map(Number);\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const av = a[i] ?? 0;\n const bv = b[i] ?? 0;\n if (bv > av) return true;\n if (bv < av) return false;\n }\n return false;\n}\n\nasync function readCache(): Promise<CacheData | null> {\n try {\n const raw = await readFile(getCacheFilePath(), \"utf-8\");\n const data = JSON.parse(raw) as CacheData;\n if (typeof data.latest === \"string\" && typeof data.checkedAt === \"number\") {\n return data;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction writeCache(data: CacheData): void {\n const filePath = getCacheFilePath();\n const dir = join(filePath, \"..\");\n // Fire-and-forget: ignore write errors\n mkdir(dir, { recursive: true })\n .then(() => writeFile(filePath, JSON.stringify(data), \"utf-8\"))\n .catch(() => {});\n}\n\nasync function fetchLatestVersion(): Promise<string | null> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n\n const response = await fetch(REGISTRY_URL, { signal: controller.signal });\n clearTimeout(timeout);\n\n if (!response.ok) return null;\n\n const body = (await response.json()) as { version?: string };\n if (typeof body.version !== \"string\") return null;\n\n return body.version;\n } catch {\n return null;\n }\n}\n\n/**\n * Check for a newer version of @gpc-cli/cli on npm.\n * Returns null if the check is skipped or fails.\n */\nexport async function checkForUpdate(currentVersion: string): Promise<UpdateCheckResult | null> {\n // Skip in non-interactive or CI environments\n if (process.env[\"GPC_NO_UPDATE_CHECK\"] === \"1\") return null;\n if (process.env[\"CI\"]) return null;\n if (!process.stdout.isTTY) return null;\n\n // Check cache first\n const cache = await readCache();\n if (cache && Date.now() - cache.checkedAt < CACHE_TTL_MS) {\n return {\n current: currentVersion,\n latest: cache.latest,\n updateAvailable: isNewerVersion(currentVersion, cache.latest),\n };\n }\n\n // Fetch from registry\n const latest = await fetchLatestVersion();\n if (!latest) return null;\n\n // Write cache (fire-and-forget)\n writeCache({ latest, checkedAt: Date.now() });\n\n return {\n current: currentVersion,\n latest,\n updateAvailable: isNewerVersion(currentVersion, latest),\n };\n}\n\n/**\n * Format a user-facing update notification string.\n */\nexport function formatUpdateNotification(result: UpdateCheckResult): string {\n return `Update available: ${result.current} \\u2192 ${result.latest} \\u2014 npm install -g @gpc-cli/cli`;\n}\n"],"mappings":"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","names":["currentVersion"]}
|
|
@@ -67,7 +67,7 @@ function registerPluginCommands(program, manager) {
|
|
|
67
67
|
import { Command } from "commander";
|
|
68
68
|
async function createProgram(pluginManager) {
|
|
69
69
|
const program = new Command();
|
|
70
|
-
program.name("gpc").description("The complete Google Play CLI").version(process.env["__GPC_VERSION"] || "0.0.0", "-V, --version").option("-o, --output <format>", "Output format: table, json, yaml, markdown").option("-v, --verbose", "Enable debug logging").option("-q, --quiet", "Suppress non-essential output").option("-a, --app <package>", "App package name").option("-p, --profile <name>", "Auth profile name").option("--no-color", "Disable colored output").option("--no-interactive", "Disable interactive prompts").option("-y, --yes", "Skip confirmation prompts").option("--dry-run", "Preview changes without executing").option("--notify [target]", "Send webhook notification on completion (slack, discord, custom)");
|
|
70
|
+
program.name("gpc").description("The complete Google Play CLI").version(process.env["__GPC_VERSION"] || "0.0.0", "-V, --version").option("-o, --output <format>", "Output format: table, json, yaml, markdown, junit").option("-v, --verbose", "Enable debug logging").option("-q, --quiet", "Suppress non-essential output").option("-a, --app <package>", "App package name").option("-p, --profile <name>", "Auth profile name").option("--no-color", "Disable colored output").option("--no-interactive", "Disable interactive prompts").option("-y, --yes", "Skip confirmation prompts").option("--dry-run", "Preview changes without executing").option("--notify [target]", "Send webhook notification on completion (slack, discord, custom)").option("--ci", "Force CI mode (JSON output, no prompts, strict exit codes)").option("-j, --json", "Shorthand for --output json").showSuggestionAfterError(true);
|
|
71
71
|
const commandLoaders = {
|
|
72
72
|
auth: async () => {
|
|
73
73
|
(await import("./auth-CIITFC3C.js")).registerAuthCommands(program);
|
|
@@ -82,22 +82,22 @@ async function createProgram(pluginManager) {
|
|
|
82
82
|
(await import("./docs-CVTWIVMS.js")).registerDocsCommand(program);
|
|
83
83
|
},
|
|
84
84
|
completion: async () => {
|
|
85
|
-
(await import("./completion-
|
|
85
|
+
(await import("./completion-C3PPWNS7.js")).registerCompletionCommand(program);
|
|
86
86
|
},
|
|
87
87
|
apps: async () => {
|
|
88
88
|
(await import("./apps-5YQPQ3KB.js")).registerAppsCommands(program);
|
|
89
89
|
},
|
|
90
90
|
releases: async () => {
|
|
91
|
-
(await import("./releases-
|
|
91
|
+
(await import("./releases-HDCDARH5.js")).registerReleasesCommands(program);
|
|
92
92
|
},
|
|
93
93
|
tracks: async () => {
|
|
94
|
-
(await import("./tracks-
|
|
94
|
+
(await import("./tracks-D6FUNJ75.js")).registerTracksCommands(program);
|
|
95
95
|
},
|
|
96
96
|
status: async () => {
|
|
97
97
|
(await import("./status-TBPVS7YR.js")).registerStatusCommand(program);
|
|
98
98
|
},
|
|
99
99
|
listings: async () => {
|
|
100
|
-
(await import("./listings-
|
|
100
|
+
(await import("./listings-4QCTOEWL.js")).registerListingsCommands(program);
|
|
101
101
|
},
|
|
102
102
|
reviews: async () => {
|
|
103
103
|
(await import("./reviews-G3HZG3AS.js")).registerReviewsCommands(program);
|
|
@@ -109,7 +109,7 @@ async function createProgram(pluginManager) {
|
|
|
109
109
|
(await import("./subscriptions-CHQU5VXT.js")).registerSubscriptionsCommands(program);
|
|
110
110
|
},
|
|
111
111
|
iap: async () => {
|
|
112
|
-
(await import("./iap-
|
|
112
|
+
(await import("./iap-2CV6SJUF.js")).registerIapCommands(program);
|
|
113
113
|
},
|
|
114
114
|
purchases: async () => {
|
|
115
115
|
(await import("./purchases-KKSXVEWB.js")).registerPurchasesCommands(program);
|
|
@@ -150,11 +150,17 @@ async function createProgram(pluginManager) {
|
|
|
150
150
|
(await import("./one-time-products-BHE6WPZI.js")).registerOneTimeProductsCommands(program);
|
|
151
151
|
},
|
|
152
152
|
"internal-sharing": async () => {
|
|
153
|
-
(await import("./internal-sharing-
|
|
153
|
+
(await import("./internal-sharing-TWMHLQLN.js")).registerInternalSharingCommands(program);
|
|
154
154
|
},
|
|
155
155
|
"generated-apks": async () => {
|
|
156
156
|
(await import("./generated-apks-SUPM3NS3.js")).registerGeneratedApksCommands(program);
|
|
157
157
|
},
|
|
158
|
+
"purchase-options": async () => {
|
|
159
|
+
(await import("./purchase-options-2NUBLODI.js")).registerPurchaseOptionsCommands(program);
|
|
160
|
+
},
|
|
161
|
+
migrate: async () => {
|
|
162
|
+
(await import("./migrate-5IA6WGMO.js")).registerMigrateCommands(program);
|
|
163
|
+
},
|
|
158
164
|
plugins: async () => {
|
|
159
165
|
registerPluginsCommand(program, pluginManager);
|
|
160
166
|
}
|
|
@@ -293,4 +299,4 @@ export {
|
|
|
293
299
|
createProgram,
|
|
294
300
|
handleCliError
|
|
295
301
|
};
|
|
296
|
-
//# sourceMappingURL=chunk-
|
|
302
|
+
//# sourceMappingURL=chunk-ZXEA4KAA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugins.ts","../src/program.ts","../src/error-handler.ts"],"sourcesContent":["import { PluginManager, discoverPlugins } from \"@gpc-cli/core\";\nimport type { Command } from \"commander\";\n\n/**\n * Load and initialize all plugins.\n * First-party plugins (@gpc-cli/*) are auto-trusted.\n * Third-party plugins require prior approval stored in config.\n * Plugin loading is disabled in standalone binary mode.\n */\nexport async function loadPlugins(): Promise<PluginManager> {\n const manager = new PluginManager();\n\n // Standalone binary cannot resolve external npm packages at runtime\n if (process.env[\"__GPC_BINARY\"] === \"1\") {\n return manager;\n }\n\n try {\n const { loadConfig } = await import(\"@gpc-cli/config\");\n const config = await loadConfig();\n const plugins = await discoverPlugins({ configPlugins: config.plugins });\n const approved = new Set(config.approvedPlugins ?? []);\n\n for (const plugin of plugins) {\n const isTrusted = plugin.name.startsWith(\"@gpc-cli/\");\n\n if (!isTrusted && !approved.has(plugin.name)) {\n // Skip unapproved third-party plugins silently in non-interactive mode\n // In interactive mode, the user would run `gpc plugins approve <name>` first\n const isQuiet = process.argv.includes(\"--quiet\") || process.argv.includes(\"-q\");\n if (!isQuiet) {\n console.error(\n `Plugin \"${plugin.name}\" is not approved. Run: gpc plugins approve ${plugin.name}`,\n );\n }\n continue;\n }\n\n try {\n await manager.load(plugin);\n } catch {\n // Skip plugins that fail to load — don't block the CLI\n }\n }\n } catch {\n // Config loading failure shouldn't block plugin-free commands\n }\n\n return manager;\n}\n\n/**\n * Register plugin-defined commands with the Commander program.\n */\nexport function registerPluginCommands(program: Command, manager: PluginManager): void {\n for (const def of manager.getRegisteredCommands()) {\n const cmd = program.command(def.name).description(def.description);\n\n if (def.arguments) {\n for (const arg of def.arguments) {\n const syntax = arg.required ? `<${arg.name}>` : `[${arg.name}]`;\n cmd.argument(syntax, arg.description);\n }\n }\n\n if (def.options) {\n for (const opt of def.options) {\n cmd.option(\n opt.flags,\n opt.description,\n opt.defaultValue as string | boolean | string[] | undefined,\n );\n }\n }\n\n cmd.action(async (...rawArgs: unknown[]) => {\n const opts = rawArgs[rawArgs.length - 2] as Record<string, unknown>;\n const args: Record<string, unknown> = {};\n\n if (def.arguments) {\n def.arguments.forEach((argDef, i) => {\n args[argDef.name] = rawArgs[i];\n });\n }\n\n await def.action(args, opts);\n });\n }\n}\n","import { Command } from \"commander\";\nimport type { PluginManager } from \"@gpc-cli/core\";\nimport type { CommandEvent, CommandResult } from \"@gpc-cli/plugin-sdk\";\nimport { registerPluginCommands } from \"./plugins.js\";\n\nexport async function createProgram(pluginManager?: PluginManager): Promise<Command> {\n const program = new Command();\n\n program\n .name(\"gpc\")\n .description(\"The complete Google Play CLI\")\n .version(process.env[\"__GPC_VERSION\"] || \"0.0.0\", \"-V, --version\")\n .option(\"-o, --output <format>\", \"Output format: table, json, yaml, markdown, junit\")\n .option(\"-v, --verbose\", \"Enable debug logging\")\n .option(\"-q, --quiet\", \"Suppress non-essential output\")\n .option(\"-a, --app <package>\", \"App package name\")\n .option(\"-p, --profile <name>\", \"Auth profile name\")\n .option(\"--no-color\", \"Disable colored output\")\n .option(\"--no-interactive\", \"Disable interactive prompts\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"--dry-run\", \"Preview changes without executing\")\n .option(\"--notify [target]\", \"Send webhook notification on completion (slack, discord, custom)\")\n .option(\"--ci\", \"Force CI mode (JSON output, no prompts, strict exit codes)\")\n .option(\"-j, --json\", \"Shorthand for --output json\")\n .showSuggestionAfterError(true);\n\n const commandLoaders: Record<string, () => Promise<void>> = {\n auth: async () => {\n (await import(\"./commands/auth.js\")).registerAuthCommands(program);\n },\n config: async () => {\n (await import(\"./commands/config.js\")).registerConfigCommands(program);\n },\n doctor: async () => {\n (await import(\"./commands/doctor.js\")).registerDoctorCommand(program);\n },\n docs: async () => {\n (await import(\"./commands/docs.js\")).registerDocsCommand(program);\n },\n completion: async () => {\n (await import(\"./commands/completion.js\")).registerCompletionCommand(program);\n },\n apps: async () => {\n (await import(\"./commands/apps.js\")).registerAppsCommands(program);\n },\n releases: async () => {\n (await import(\"./commands/releases.js\")).registerReleasesCommands(program);\n },\n tracks: async () => {\n (await import(\"./commands/tracks.js\")).registerTracksCommands(program);\n },\n status: async () => {\n (await import(\"./commands/status.js\")).registerStatusCommand(program);\n },\n listings: async () => {\n (await import(\"./commands/listings.js\")).registerListingsCommands(program);\n },\n reviews: async () => {\n (await import(\"./commands/reviews.js\")).registerReviewsCommands(program);\n },\n vitals: async () => {\n (await import(\"./commands/vitals.js\")).registerVitalsCommands(program);\n },\n subscriptions: async () => {\n (await import(\"./commands/subscriptions.js\")).registerSubscriptionsCommands(program);\n },\n iap: async () => {\n (await import(\"./commands/iap.js\")).registerIapCommands(program);\n },\n purchases: async () => {\n (await import(\"./commands/purchases.js\")).registerPurchasesCommands(program);\n },\n pricing: async () => {\n (await import(\"./commands/pricing.js\")).registerPricingCommands(program);\n },\n reports: async () => {\n (await import(\"./commands/reports.js\")).registerReportsCommands(program);\n },\n users: async () => {\n (await import(\"./commands/users.js\")).registerUsersCommands(program);\n },\n testers: async () => {\n (await import(\"./commands/testers.js\")).registerTestersCommands(program);\n },\n validate: async () => {\n (await import(\"./commands/validate.js\")).registerValidateCommand(program);\n },\n publish: async () => {\n (await import(\"./commands/publish.js\")).registerPublishCommand(program);\n },\n recovery: async () => {\n (await import(\"./commands/recovery.js\")).registerRecoveryCommands(program);\n },\n \"data-safety\": async () => {\n (await import(\"./commands/data-safety.js\")).registerDataSafetyCommands(program);\n },\n \"external-transactions\": async () => {\n (await import(\"./commands/external-transactions.js\")).registerExternalTransactionsCommands(\n program,\n );\n },\n \"device-tiers\": async () => {\n (await import(\"./commands/device-tiers.js\")).registerDeviceTiersCommands(program);\n },\n \"one-time-products\": async () => {\n (await import(\"./commands/one-time-products.js\")).registerOneTimeProductsCommands(program);\n },\n \"internal-sharing\": async () => {\n (await import(\"./commands/internal-sharing.js\")).registerInternalSharingCommands(program);\n },\n \"generated-apks\": async () => {\n (await import(\"./commands/generated-apks.js\")).registerGeneratedApksCommands(program);\n },\n \"purchase-options\": async () => {\n (await import(\"./commands/purchase-options.js\")).registerPurchaseOptionsCommands(program);\n },\n migrate: async () => {\n (await import(\"./commands/migrate.js\")).registerMigrateCommands(program);\n },\n plugins: async () => {\n registerPluginsCommand(program, pluginManager);\n },\n };\n\n // Resolve command aliases for lazy loading\n const commandAliases: Record<string, string> = {\n \"ext-txn\": \"external-transactions\",\n otp: \"one-time-products\",\n };\n\n const rawTarget = process.argv[2];\n const target = rawTarget ? (commandAliases[rawTarget] ?? rawTarget) : undefined;\n\n const loader = target ? commandLoaders[target] : undefined;\n if (loader) {\n await loader();\n } else {\n await Promise.all(Object.values(commandLoaders).map((loader) => loader()));\n }\n\n // Register plugin-defined commands\n if (pluginManager) {\n registerPluginCommands(program, pluginManager);\n }\n\n // Wire plugin lifecycle hooks around command execution\n if (pluginManager) {\n wrapCommandHooks(program, pluginManager);\n }\n\n return program;\n}\n\n/**\n * `gpc plugins` — manage plugins.\n */\nfunction registerPluginsCommand(program: Command, manager?: PluginManager): void {\n const cmd = program.command(\"plugins\").description(\"Manage plugins\");\n\n cmd\n .command(\"list\")\n .description(\"List loaded plugins\")\n .action(() => {\n const plugins = manager?.getLoadedPlugins() ?? [];\n const opts = program.opts();\n\n if (opts[\"output\"] === \"json\") {\n console.log(JSON.stringify(plugins, null, 2));\n return;\n }\n\n if (plugins.length === 0) {\n console.log(\"No plugins loaded.\");\n console.log('\\nConfigure plugins in .gpcrc.json: { \"plugins\": [\"@gpc-cli/plugin-ci\"] }');\n return;\n }\n\n console.log(\"Loaded plugins:\\n\");\n for (const p of plugins) {\n const trust = p.trusted ? \"trusted\" : \"third-party\";\n console.log(` ${p.name}@${p.version} (${trust})`);\n }\n\n const commands = manager?.getRegisteredCommands() ?? [];\n if (commands.length > 0) {\n console.log(\"\\nPlugin commands:\\n\");\n for (const c of commands) {\n console.log(` gpc ${c.name} — ${c.description}`);\n }\n }\n });\n\n cmd\n .command(\"init <name>\")\n .description(\"Scaffold a new plugin project\")\n .option(\"-d, --dir <path>\", \"Output directory (defaults to ./gpc-plugin-<name>)\")\n .option(\"--description <text>\", \"Plugin description\")\n .action(async (name: string, opts: { dir?: string; description?: string }) => {\n const { scaffoldPlugin } = await import(\"@gpc-cli/core\");\n const pluginName = name.startsWith(\"gpc-plugin-\") ? name : `gpc-plugin-${name}`;\n const dir = opts.dir ?? `./${pluginName}`;\n\n const result = await scaffoldPlugin({ name, dir, description: opts.description });\n\n console.log(`Plugin scaffolded at ${result.dir}/\\n`);\n console.log(\"Files created:\");\n for (const f of result.files) {\n console.log(` ${f}`);\n }\n console.log(`\\nNext steps:`);\n console.log(` cd ${pluginName}`);\n console.log(` npm install`);\n console.log(` npm run build`);\n console.log(` npm test`);\n });\n\n cmd\n .command(\"approve <name>\")\n .description(\"Approve a third-party plugin for loading\")\n .action(async (name: string) => {\n const { approvePlugin } = await import(\"@gpc-cli/config\");\n await approvePlugin(name);\n console.log(`Plugin \"${name}\" approved. It will be loaded on next run.`);\n });\n\n cmd\n .command(\"revoke <name>\")\n .description(\"Revoke approval for a third-party plugin\")\n .action(async (name: string) => {\n const { revokePluginApproval } = await import(\"@gpc-cli/config\");\n const removed = await revokePluginApproval(name);\n if (removed) {\n console.log(`Plugin \"${name}\" approval revoked.`);\n } else {\n console.log(`Plugin \"${name}\" was not in the approved list.`);\n }\n });\n}\n\n/**\n * Wrap all registered commands so plugin hooks fire before/after each command.\n */\nfunction wrapCommandHooks(program: Command, manager: PluginManager): void {\n program.hook(\"preAction\", async (thisCommand) => {\n const event: CommandEvent = {\n command: getFullCommandName(thisCommand),\n args: thisCommand.opts(),\n app: program.opts()[\"app\"] as string | undefined,\n startedAt: new Date(),\n };\n\n // Store on the command for afterCommand/onError\n (thisCommand as unknown as Record<string, unknown>)[\"__pluginEvent\"] = event;\n\n await manager.runBeforeCommand(event);\n });\n\n program.hook(\"postAction\", async (thisCommand) => {\n const event: CommandEvent = (thisCommand as unknown as Record<string, unknown>)[\n \"__pluginEvent\"\n ] as CommandEvent;\n if (!event) return;\n\n const result: CommandResult = {\n success: true,\n durationMs: Date.now() - event.startedAt.getTime(),\n exitCode: 0,\n };\n\n await manager.runAfterCommand(event, result);\n });\n}\n\nfunction getFullCommandName(cmd: Command): string {\n const parts: string[] = [];\n let current: Command | null = cmd;\n while (current && current.name() !== \"gpc\") {\n parts.unshift(current.name());\n current = current.parent;\n }\n return parts.join(\" \");\n}\n","/**\n * Shared error formatting for CLI output.\n * Extracts error code, message, and suggestion from typed errors (GpcError, AuthError, ApiError, ConfigError).\n */\n\ninterface TypedError {\n message: string;\n code?: string;\n suggestion?: string;\n exitCode?: number;\n}\n\nfunction isTypedError(error: unknown): error is Error & TypedError {\n return error instanceof Error && \"code\" in error && typeof (error as TypedError).code === \"string\";\n}\n\n/**\n * Format an error for CLI output. Prints:\n * Error [CODE]: message\n * Suggestion: suggestion (if available)\n *\n * Returns the appropriate exit code.\n */\nexport function handleCliError(error: unknown): number {\n if (isTypedError(error)) {\n console.error(`Error [${error.code}]: ${error.message}`);\n if (error.suggestion) {\n console.error(`Suggestion: ${error.suggestion}`);\n }\n return error.exitCode ?? 1;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n console.error(`Error: ${message}`);\n return 1;\n}\n"],"mappings":"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","names":["loader"]}
|
|
@@ -207,6 +207,73 @@ function getCommandTree() {
|
|
|
207
207
|
import: { description: "Import testers from a CSV file" }
|
|
208
208
|
}
|
|
209
209
|
},
|
|
210
|
+
recovery: {
|
|
211
|
+
description: "Manage app recovery actions",
|
|
212
|
+
subcommands: {
|
|
213
|
+
list: { description: "List app recovery actions" },
|
|
214
|
+
cancel: { description: "Cancel a recovery action" },
|
|
215
|
+
deploy: { description: "Deploy a recovery action" },
|
|
216
|
+
create: { description: "Create a recovery action" },
|
|
217
|
+
"add-targeting": { description: "Add targeting to a recovery action" }
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
"data-safety": {
|
|
221
|
+
description: "Manage data safety declarations",
|
|
222
|
+
subcommands: {
|
|
223
|
+
get: { description: "Get data safety declaration" },
|
|
224
|
+
update: { description: "Update data safety declaration" },
|
|
225
|
+
export: { description: "Export data safety declaration" }
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
"external-transactions": {
|
|
229
|
+
description: "Manage external transactions",
|
|
230
|
+
subcommands: {
|
|
231
|
+
create: { description: "Create an external transaction" },
|
|
232
|
+
get: { description: "Get an external transaction" },
|
|
233
|
+
refund: { description: "Refund an external transaction" }
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
"device-tiers": {
|
|
237
|
+
description: "Manage device tier configurations",
|
|
238
|
+
subcommands: {
|
|
239
|
+
list: { description: "List device tier configurations" },
|
|
240
|
+
get: { description: "Get a device tier configuration" },
|
|
241
|
+
create: { description: "Create a device tier configuration" }
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
"one-time-products": {
|
|
245
|
+
description: "Manage one-time products",
|
|
246
|
+
subcommands: {
|
|
247
|
+
list: { description: "List one-time products" },
|
|
248
|
+
get: { description: "Get a one-time product" },
|
|
249
|
+
create: { description: "Create a one-time product" },
|
|
250
|
+
update: { description: "Update a one-time product" },
|
|
251
|
+
delete: { description: "Delete a one-time product" },
|
|
252
|
+
offers: {
|
|
253
|
+
description: "Manage one-time product offers",
|
|
254
|
+
subcommands: {
|
|
255
|
+
list: { description: "List offers for a one-time product" },
|
|
256
|
+
get: { description: "Get a one-time product offer" },
|
|
257
|
+
create: { description: "Create a one-time product offer" },
|
|
258
|
+
update: { description: "Update a one-time product offer" },
|
|
259
|
+
delete: { description: "Delete a one-time product offer" }
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
"internal-sharing": {
|
|
265
|
+
description: "Manage internal app sharing",
|
|
266
|
+
subcommands: {
|
|
267
|
+
upload: { description: "Upload an artifact for internal sharing" }
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
"generated-apks": {
|
|
271
|
+
description: "Manage generated APKs from app bundles",
|
|
272
|
+
subcommands: {
|
|
273
|
+
list: { description: "List generated APKs for a version" },
|
|
274
|
+
download: { description: "Download a generated APK" }
|
|
275
|
+
}
|
|
276
|
+
},
|
|
210
277
|
doctor: { description: "Verify setup and connectivity" },
|
|
211
278
|
docs: { description: "Open documentation in browser" },
|
|
212
279
|
validate: { description: "Pre-submission validation checks" },
|
|
@@ -492,4 +559,4 @@ export {
|
|
|
492
559
|
getCommandTree,
|
|
493
560
|
registerCompletionCommand
|
|
494
561
|
};
|
|
495
|
-
//# sourceMappingURL=completion-
|
|
562
|
+
//# sourceMappingURL=completion-C3PPWNS7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/completion.ts"],"sourcesContent":["import type { Command } from \"commander\";\n\nexport type ShellType = \"bash\" | \"zsh\" | \"fish\" | \"powershell\";\n\nexport const SUPPORTED_SHELLS: readonly ShellType[] = [\"bash\", \"zsh\", \"fish\", \"powershell\"] as const;\n\n/**\n * Full command tree for gpc CLI.\n * Each entry maps a command name to its description and optional subcommands.\n */\ninterface CommandDef {\n description: string;\n subcommands?: Record<string, CommandDef>;\n}\n\nexport function getCommandTree(): Record<string, CommandDef> {\n return {\n auth: {\n description: \"Manage authentication\",\n subcommands: {\n login: { description: \"Authenticate with Google Play Developer API\" },\n status: { description: \"Show current authentication status\" },\n logout: { description: \"Remove stored credentials\" },\n whoami: { description: \"Show the authenticated account\" },\n },\n },\n config: {\n description: \"Manage configuration\",\n subcommands: {\n init: { description: \"Create a configuration file\" },\n show: { description: \"Show current configuration\" },\n set: { description: \"Set a configuration value\" },\n path: { description: \"Show the configuration file path\" },\n },\n },\n apps: {\n description: \"Manage applications\",\n subcommands: {\n info: { description: \"Show app details\" },\n update: { description: \"Update app details\" },\n list: { description: \"List configured applications\" },\n },\n },\n releases: {\n description: \"Manage releases and rollouts\",\n subcommands: {\n upload: { description: \"Upload AAB/APK and assign to a track\" },\n status: { description: \"Show current release status across tracks\" },\n promote: { description: \"Promote a release from one track to another\" },\n rollout: {\n description: \"Manage staged rollouts\",\n subcommands: {\n increase: { description: \"Increase a staged rollout\" },\n halt: { description: \"Halt a staged rollout\" },\n resume: { description: \"Resume a staged rollout\" },\n complete: { description: \"Complete a staged rollout\" },\n },\n },\n notes: { description: \"Set release notes\" },\n },\n },\n tracks: {\n description: \"Manage tracks\",\n subcommands: {\n list: { description: \"List all tracks\" },\n },\n },\n status: { description: \"Cross-track release overview\" },\n listings: {\n description: \"Manage store listings and metadata\",\n subcommands: {\n get: { description: \"Get store listing(s)\" },\n update: { description: \"Update a store listing\" },\n delete: { description: \"Delete a store listing for a language\" },\n pull: { description: \"Download listings to Fastlane-format directory\" },\n push: { description: \"Upload listings from Fastlane-format directory\" },\n images: {\n description: \"Manage listing images\",\n subcommands: {\n list: { description: \"List images for a language and type\" },\n upload: { description: \"Upload an image\" },\n delete: { description: \"Delete an image\" },\n },\n },\n availability: { description: \"Get country availability for a track\" },\n },\n },\n reviews: {\n description: \"Manage user reviews and ratings\",\n subcommands: {\n list: { description: \"List user reviews\" },\n get: { description: \"Get a single review\" },\n reply: { description: \"Reply to a review\" },\n export: { description: \"Export reviews to JSON or CSV\" },\n },\n },\n vitals: {\n description: \"Monitor app vitals and performance metrics\",\n subcommands: {\n overview: { description: \"Dashboard summary of all vital metrics\" },\n crashes: { description: \"Query crash rate metrics\" },\n anr: { description: \"Query ANR rate metrics\" },\n startup: { description: \"Query slow startup metrics\" },\n rendering: { description: \"Query slow rendering metrics\" },\n battery: { description: \"Query excessive wakeup metrics\" },\n memory: { description: \"Query stuck wakelock metrics\" },\n anomalies: { description: \"Detect anomalies in app vitals\" },\n errors: {\n description: \"Search and view error issues\",\n subcommands: {\n search: { description: \"Search error issues\" },\n },\n },\n compare: { description: \"Compare metric trend between periods\" },\n },\n },\n subscriptions: {\n description: \"Manage subscriptions and base plans\",\n subcommands: {\n list: { description: \"List subscriptions\" },\n get: { description: \"Get a subscription\" },\n create: { description: \"Create a subscription from JSON file\" },\n update: { description: \"Update a subscription from JSON file\" },\n delete: { description: \"Delete a subscription\" },\n \"base-plans\": {\n description: \"Manage base plans\",\n subcommands: {\n activate: { description: \"Activate a base plan\" },\n deactivate: { description: \"Deactivate a base plan\" },\n delete: { description: \"Delete a base plan\" },\n \"migrate-prices\": { description: \"Migrate base plan prices\" },\n },\n },\n offers: {\n description: \"Manage subscription offers\",\n subcommands: {\n list: { description: \"List offers for a base plan\" },\n get: { description: \"Get an offer\" },\n create: { description: \"Create an offer from JSON file\" },\n update: { description: \"Update an offer from JSON file\" },\n delete: { description: \"Delete an offer\" },\n activate: { description: \"Activate an offer\" },\n deactivate: { description: \"Deactivate an offer\" },\n },\n },\n },\n },\n iap: {\n description: \"Manage in-app products\",\n subcommands: {\n list: { description: \"List in-app products\" },\n get: { description: \"Get an in-app product\" },\n create: { description: \"Create an in-app product from JSON file\" },\n update: { description: \"Update an in-app product from JSON file\" },\n delete: { description: \"Delete an in-app product\" },\n sync: { description: \"Sync in-app products from a directory\" },\n },\n },\n purchases: {\n description: \"Manage purchases and orders\",\n subcommands: {\n get: { description: \"Get a product purchase\" },\n acknowledge: { description: \"Acknowledge a product purchase\" },\n consume: { description: \"Consume a product purchase\" },\n subscription: {\n description: \"Manage subscription purchases\",\n subcommands: {\n get: { description: \"Get a subscription purchase\" },\n cancel: { description: \"Cancel a subscription\" },\n defer: { description: \"Defer a subscription expiry\" },\n revoke: { description: \"Revoke a subscription\" },\n },\n },\n voided: { description: \"List voided purchases\" },\n orders: {\n description: \"Manage orders\",\n subcommands: {\n refund: { description: \"Refund an order\" },\n },\n },\n },\n },\n pricing: {\n description: \"Pricing and regional price conversion\",\n subcommands: {\n convert: { description: \"Convert a price to all regional prices\" },\n },\n },\n reports: {\n description: \"Download financial and stats reports\",\n subcommands: {\n list: { description: \"List available report buckets\" },\n download: {\n description: \"Download a report\",\n subcommands: {\n financial: { description: \"Download a financial report\" },\n stats: { description: \"Download a stats report\" },\n },\n },\n },\n },\n users: {\n description: \"Manage developer account users and permissions\",\n subcommands: {\n list: { description: \"List all users in the developer account\" },\n get: { description: \"Get user details\" },\n invite: { description: \"Invite a user to the developer account\" },\n update: { description: \"Update user permissions\" },\n remove: { description: \"Remove a user from the developer account\" },\n },\n },\n testers: {\n description: \"Manage testers and tester groups\",\n subcommands: {\n list: { description: \"List testers for a track\" },\n add: { description: \"Add testers to a track\" },\n remove: { description: \"Remove testers from a track\" },\n import: { description: \"Import testers from a CSV file\" },\n },\n },\n recovery: {\n description: \"Manage app recovery actions\",\n subcommands: {\n list: { description: \"List app recovery actions\" },\n cancel: { description: \"Cancel a recovery action\" },\n deploy: { description: \"Deploy a recovery action\" },\n create: { description: \"Create a recovery action\" },\n \"add-targeting\": { description: \"Add targeting to a recovery action\" },\n },\n },\n \"data-safety\": {\n description: \"Manage data safety declarations\",\n subcommands: {\n get: { description: \"Get data safety declaration\" },\n update: { description: \"Update data safety declaration\" },\n export: { description: \"Export data safety declaration\" },\n },\n },\n \"external-transactions\": {\n description: \"Manage external transactions\",\n subcommands: {\n create: { description: \"Create an external transaction\" },\n get: { description: \"Get an external transaction\" },\n refund: { description: \"Refund an external transaction\" },\n },\n },\n \"device-tiers\": {\n description: \"Manage device tier configurations\",\n subcommands: {\n list: { description: \"List device tier configurations\" },\n get: { description: \"Get a device tier configuration\" },\n create: { description: \"Create a device tier configuration\" },\n },\n },\n \"one-time-products\": {\n description: \"Manage one-time products\",\n subcommands: {\n list: { description: \"List one-time products\" },\n get: { description: \"Get a one-time product\" },\n create: { description: \"Create a one-time product\" },\n update: { description: \"Update a one-time product\" },\n delete: { description: \"Delete a one-time product\" },\n offers: {\n description: \"Manage one-time product offers\",\n subcommands: {\n list: { description: \"List offers for a one-time product\" },\n get: { description: \"Get a one-time product offer\" },\n create: { description: \"Create a one-time product offer\" },\n update: { description: \"Update a one-time product offer\" },\n delete: { description: \"Delete a one-time product offer\" },\n },\n },\n },\n },\n \"internal-sharing\": {\n description: \"Manage internal app sharing\",\n subcommands: {\n upload: { description: \"Upload an artifact for internal sharing\" },\n },\n },\n \"generated-apks\": {\n description: \"Manage generated APKs from app bundles\",\n subcommands: {\n list: { description: \"List generated APKs for a version\" },\n download: { description: \"Download a generated APK\" },\n },\n },\n doctor: { description: \"Verify setup and connectivity\" },\n docs: { description: \"Open documentation in browser\" },\n validate: { description: \"Pre-submission validation checks\" },\n publish: { description: \"Validate, upload, and release in one step\" },\n completion: {\n description: \"Generate shell completions\",\n subcommands: {\n bash: { description: \"Generate bash completions\" },\n zsh: { description: \"Generate zsh completions\" },\n fish: { description: \"Generate fish completions\" },\n powershell: { description: \"Generate PowerShell completions\" },\n },\n },\n plugins: {\n description: \"Manage plugins\",\n subcommands: {\n list: { description: \"List loaded plugins\" },\n init: { description: \"Scaffold a new plugin project\" },\n approve: { description: \"Approve a third-party plugin for loading\" },\n revoke: { description: \"Revoke approval for a third-party plugin\" },\n },\n },\n };\n}\n\nexport function registerCompletionCommand(program: Command): void {\n const completion = program.command(\"completion\").description(\"Generate shell completions\");\n\n completion\n .command(\"bash\")\n .description(\"Generate bash completions\")\n .action(() => {\n console.log(generateBashCompletions());\n });\n\n completion\n .command(\"zsh\")\n .description(\"Generate zsh completions\")\n .action(() => {\n console.log(generateZshCompletions());\n });\n\n completion\n .command(\"fish\")\n .description(\"Generate fish completions\")\n .action(() => {\n console.log(generateFishCompletions());\n });\n\n completion\n .command(\"powershell\")\n .description(\"Generate PowerShell completions\")\n .action(() => {\n console.log(generatePowerShellCompletions());\n });\n}\n\nexport function generateBashCompletions(): string {\n const tree = getCommandTree();\n\n const topLevelNames = Object.keys(tree).join(\" \");\n\n // Build case entries for each command that has subcommands (up to 3 levels)\n const caseEntries: string[] = [];\n\n for (const [cmd, def] of Object.entries(tree)) {\n if (def.subcommands) {\n const subNames = Object.keys(def.subcommands).join(\" \");\n caseEntries.push(` ${cmd})\\n COMPREPLY=( $(compgen -W \"${subNames}\" -- \"\\${cur}\") )\\n return 0\\n ;;`);\n\n // Level 3: subcommands of subcommands\n for (const [sub, subDef] of Object.entries(def.subcommands)) {\n if (subDef.subcommands) {\n const subSubNames = Object.keys(subDef.subcommands).join(\" \");\n caseEntries.push(` ${sub})\\n COMPREPLY=( $(compgen -W \"${subSubNames}\" -- \"\\${cur}\") )\\n return 0\\n ;;`);\n }\n }\n }\n }\n\n return `# bash completion for gpc\n# Install: gpc completion bash >> ~/.bashrc\n_gpc() {\n local cur prev commands\n COMPREPLY=()\n cur=\"\\${COMP_WORDS[COMP_CWORD]}\"\n prev=\"\\${COMP_WORDS[COMP_CWORD-1]}\"\n\n commands=\"${topLevelNames}\"\n\n case \"\\${prev}\" in\n gpc)\n COMPREPLY=( $(compgen -W \"\\${commands}\" -- \"\\${cur}\") )\n return 0\n ;;\n${caseEntries.join(\"\\n\")}\n esac\n\n COMPREPLY=( $(compgen -W \"\\${commands}\" -- \"\\${cur}\") )\n return 0\n}\n\ncomplete -F _gpc gpc`;\n}\n\nexport function generateZshCompletions(): string {\n const tree = getCommandTree();\n\n // Build zsh arrays\n const arrayDefs: string[] = [];\n const caseBranches: string[] = [];\n\n // Top-level\n const topEntries = Object.entries(tree)\n .map(([name, def]) => ` '${name}:${escapeZsh(def.description)}'`)\n .join(\"\\n\");\n arrayDefs.push(` commands=(\\n${topEntries}\\n )`);\n\n // Build subcommand arrays and case branches for level 2\n for (const [cmd, def] of Object.entries(tree)) {\n if (def.subcommands) {\n const varName = `${cmd.replace(/-/g, \"_\")}_commands`;\n const entries = Object.entries(def.subcommands)\n .map(([name, sub]) => ` '${name}:${escapeZsh(sub.description)}'`)\n .join(\"\\n\");\n arrayDefs.push(` ${varName}=(\\n${entries}\\n )`);\n caseBranches.push(` ${cmd})\\n _describe -t ${varName} '${cmd} commands' ${varName}\\n ;;`);\n\n // Level 3\n for (const [sub, subDef] of Object.entries(def.subcommands)) {\n if (subDef.subcommands) {\n const subVarName = `${cmd.replace(/-/g, \"_\")}_${sub.replace(/-/g, \"_\")}_commands`;\n const subEntries = Object.entries(subDef.subcommands)\n .map(([name, s]) => ` '${name}:${escapeZsh(s.description)}'`)\n .join(\"\\n\");\n arrayDefs.push(` ${subVarName}=(\\n${subEntries}\\n )`);\n }\n }\n }\n }\n\n // Build level 3 case for subsubcommand state\n const level3Cases: string[] = [];\n for (const [cmd, def] of Object.entries(tree)) {\n if (!def.subcommands) continue;\n for (const [sub, subDef] of Object.entries(def.subcommands)) {\n if (subDef.subcommands) {\n const subVarName = `${cmd.replace(/-/g, \"_\")}_${sub.replace(/-/g, \"_\")}_commands`;\n level3Cases.push(` ${sub})\\n _describe -t ${subVarName} '${sub} commands' ${subVarName}\\n ;;`);\n }\n }\n }\n\n // Collect all variable names for local declarations\n const varNames: string[] = [\"commands\"];\n for (const [cmd, def] of Object.entries(tree)) {\n if (def.subcommands) {\n varNames.push(`${cmd.replace(/-/g, \"_\")}_commands`);\n for (const [sub, subDef] of Object.entries(def.subcommands)) {\n if (subDef.subcommands) {\n varNames.push(`${cmd.replace(/-/g, \"_\")}_${sub.replace(/-/g, \"_\")}_commands`);\n }\n }\n }\n }\n\n const localDecls = varNames.map((v) => ` local -a ${v}`).join(\"\\n\");\n\n return `#compdef gpc\n# Install: gpc completion zsh > ~/.zsh/completions/_gpc\n\n_gpc() {\n${localDecls}\n\n${arrayDefs.join(\"\\n\\n\")}\n\n _arguments -C \\\\\n '1: :->command' \\\\\n '2: :->subcommand' \\\\\n '3: :->subsubcommand' \\\\\n '*::arg:->args'\n\n case \"$state\" in\n command)\n _describe -t commands 'gpc commands' commands\n ;;\n subcommand)\n case \"$words[2]\" in\n${caseBranches.join(\"\\n\")}\n esac\n ;;\n subsubcommand)\n case \"$words[3]\" in\n${level3Cases.join(\"\\n\")}\n esac\n ;;\n esac\n}\n\n_gpc \"$@\"`;\n}\n\nexport function generateFishCompletions(): string {\n const tree = getCommandTree();\n const lines: string[] = [\n \"# fish completions for gpc\",\n \"# Install: gpc completion fish > ~/.config/fish/completions/gpc.fish\",\n \"\",\n \"# Disable file completions by default\",\n \"complete -c gpc -f\",\n \"\",\n \"# Top-level commands\",\n ];\n\n for (const [cmd, def] of Object.entries(tree)) {\n lines.push(\n `complete -c gpc -n '__fish_use_subcommand' -a ${cmd} -d '${escapeFish(def.description)}'`,\n );\n }\n\n // Level 2 subcommands\n for (const [cmd, def] of Object.entries(tree)) {\n if (!def.subcommands) continue;\n lines.push(\"\");\n lines.push(`# ${cmd} subcommands`);\n for (const [sub, subDef] of Object.entries(def.subcommands)) {\n lines.push(\n `complete -c gpc -n '__fish_seen_subcommand_from ${cmd}; and not __fish_seen_subcommand_from ${Object.keys(def.subcommands).join(\" \")}' -a ${sub} -d '${escapeFish(subDef.description)}'`,\n );\n }\n\n // Level 3 subcommands\n for (const [sub, subDef] of Object.entries(def.subcommands)) {\n if (!subDef.subcommands) continue;\n lines.push(\"\");\n lines.push(`# ${cmd} ${sub} subcommands`);\n for (const [subsub, subsubDef] of Object.entries(subDef.subcommands)) {\n lines.push(\n `complete -c gpc -n '__fish_seen_subcommand_from ${sub}; and not __fish_seen_subcommand_from ${Object.keys(subDef.subcommands).join(\" \")}' -a ${subsub} -d '${escapeFish(subsubDef.description)}'`,\n );\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function generatePowerShellCompletions(): string {\n const tree = getCommandTree();\n\n // Build the completion hashtable entries\n const completionEntries: string[] = [];\n\n // Top-level completions\n for (const [cmd, def] of Object.entries(tree)) {\n completionEntries.push(\n ` [CompletionResult]::new('${cmd}', '${cmd}', [CompletionResultType]::ParameterValue, '${escapePowerShell(def.description)}')`,\n );\n }\n\n // Subcommand completions (level 2)\n const subcommandCases: string[] = [];\n const level3Cases: string[] = [];\n\n for (const [cmd, def] of Object.entries(tree)) {\n if (!def.subcommands) continue;\n const subEntries = Object.entries(def.subcommands)\n .map(\n ([sub, subDef]) =>\n ` [CompletionResult]::new('${sub}', '${sub}', [CompletionResultType]::ParameterValue, '${escapePowerShell(subDef.description)}')`,\n )\n .join(\"\\n\");\n subcommandCases.push(` '${cmd}' {\\n${subEntries}\\n }`);\n\n // Level 3\n for (const [sub, subDef] of Object.entries(def.subcommands)) {\n if (!subDef.subcommands) continue;\n const subSubEntries = Object.entries(subDef.subcommands)\n .map(\n ([subsub, subsubDef]) =>\n ` [CompletionResult]::new('${subsub}', '${subsub}', [CompletionResultType]::ParameterValue, '${escapePowerShell(subsubDef.description)}')`,\n )\n .join(\"\\n\");\n level3Cases.push(` '${sub}' {\\n${subSubEntries}\\n }`);\n }\n }\n\n return `# PowerShell completions for gpc\n# Install: gpc completion powershell >> $PROFILE\n\nusing namespace System.Management.Automation\n\nRegister-ArgumentCompleter -CommandName gpc -Native -ScriptBlock {\n param($wordToComplete, $commandAst, $cursorPosition)\n\n $tokens = $commandAst.ToString().Substring(0, $cursorPosition).Trim() -split '\\\\s+'\n $tokenCount = $tokens.Count\n\n # Determine context\n if ($tokenCount -le 1 -or ($tokenCount -eq 2 -and $wordToComplete)) {\n # Top-level commands\n${completionEntries.join(\"\\n\")}\n } elseif ($tokenCount -eq 2 -or ($tokenCount -eq 3 -and $wordToComplete)) {\n # Subcommands\n $command = $tokens[1]\n switch ($command) {\n${subcommandCases.join(\"\\n\")}\n }\n } elseif ($tokenCount -eq 3 -or ($tokenCount -eq 4 -and $wordToComplete)) {\n # Sub-subcommands\n $subcommand = $tokens[2]\n switch ($subcommand) {\n${level3Cases.join(\"\\n\")}\n }\n }\n}`;\n}\n\nfunction escapeZsh(str: string): string {\n return str.replace(/'/g, \"'\\\\''\");\n}\n\nfunction escapeFish(str: string): string {\n return str.replace(/'/g, \"\\\\'\");\n}\n\nfunction escapePowerShell(str: string): string {\n return str.replace(/'/g, \"''\");\n}\n"],"mappings":"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","names":[]}
|
|
@@ -21,7 +21,8 @@ import {
|
|
|
21
21
|
syncInAppProducts,
|
|
22
22
|
detectOutputFormat,
|
|
23
23
|
formatOutput,
|
|
24
|
-
sortResults
|
|
24
|
+
sortResults,
|
|
25
|
+
createSpinner
|
|
25
26
|
} from "@gpc-cli/core";
|
|
26
27
|
function resolvePackageName(packageArg, config) {
|
|
27
28
|
const name = packageArg || config.app;
|
|
@@ -155,15 +156,19 @@ function registerIapCommands(program) {
|
|
|
155
156
|
const client = await getClient(config);
|
|
156
157
|
const format = detectOutputFormat();
|
|
157
158
|
const dryRun = isDryRun(program);
|
|
159
|
+
const spinner = createSpinner("Syncing in-app products...");
|
|
160
|
+
if (!program.opts()["quiet"] && process.stderr.isTTY) spinner.start();
|
|
158
161
|
try {
|
|
159
162
|
const result = await syncInAppProducts(client, packageName, options.dir, {
|
|
160
163
|
dryRun
|
|
161
164
|
});
|
|
165
|
+
spinner.stop("Sync complete");
|
|
162
166
|
if (dryRun) {
|
|
163
167
|
console.log(`[dry-run] Would create: ${result.created}, update: ${result.updated}`);
|
|
164
168
|
}
|
|
165
169
|
console.log(formatOutput(result, format));
|
|
166
170
|
} catch (error) {
|
|
171
|
+
spinner.fail("Sync failed");
|
|
167
172
|
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
168
173
|
process.exit(4);
|
|
169
174
|
}
|
|
@@ -172,4 +177,4 @@ function registerIapCommands(program) {
|
|
|
172
177
|
export {
|
|
173
178
|
registerIapCommands
|
|
174
179
|
};
|
|
175
|
-
//# sourceMappingURL=iap-
|
|
180
|
+
//# sourceMappingURL=iap-2CV6SJUF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/iap.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport type { GpcConfig } from \"@gpc-cli/config\";\nimport type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { createApiClient } from \"@gpc-cli/api\";\nimport {\n listInAppProducts,\n getInAppProduct,\n createInAppProduct,\n updateInAppProduct,\n deleteInAppProduct,\n syncInAppProducts,\n detectOutputFormat,\n formatOutput,\n sortResults,\n createSpinner,\n} from \"@gpc-cli/core\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { requireConfirm } from \"../prompt.js\";\n\nfunction resolvePackageName(packageArg: string | undefined, config: GpcConfig): string {\n const name = packageArg || config.app;\n if (!name) {\n console.error(\"Error: No package name. Use --app <package> or gpc config set app <package>\");\n process.exit(2);\n }\n return name;\n}\n\nasync function getClient(config: GpcConfig) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createApiClient({ auth });\n}\n\nexport function registerIapCommands(program: Command): void {\n const iap = program.command(\"iap\").description(\"Manage in-app products\");\n\n iap\n .command(\"list\")\n .description(\"List in-app products\")\n .option(\"--max <n>\", \"Maximum results 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 = detectOutputFormat();\n\n try {\n const result = await listInAppProducts(client, packageName, {\n maxResults: options.max,\n limit: options.limit,\n nextPage: options.nextPage,\n });\n if (options.sort) {\n result.inappproduct = sortResults(result.inappproduct, options.sort);\n }\n console.log(formatOutput(result, format));\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n iap\n .command(\"get <sku>\")\n .description(\"Get an in-app product\")\n .action(async (sku: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = detectOutputFormat();\n\n try {\n const result = await getInAppProduct(client, packageName, sku);\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 iap\n .command(\"create\")\n .description(\"Create an in-app product from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with product data\")\n .action(async (options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = detectOutputFormat();\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"iap create\",\n action: \"create\",\n target: `in-app product from ${options.file}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await createInAppProduct(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 iap\n .command(\"update <sku>\")\n .description(\"Update an in-app product from JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with product data\")\n .action(async (sku: string, options) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const format = detectOutputFormat();\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"iap update\",\n action: \"update\",\n target: sku,\n details: { file: options.file },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n const data = JSON.parse(await readFile(options.file, \"utf-8\"));\n const result = await updateInAppProduct(client, packageName, sku, 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 iap\n .command(\"delete <sku>\")\n .description(\"Delete an in-app product\")\n .action(async (sku: string) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n\n await requireConfirm(`Delete in-app product \"${sku}\"?`, program);\n\n if (isDryRun(program)) {\n const format = detectOutputFormat();\n printDryRun(\n {\n command: \"iap delete\",\n action: \"delete\",\n target: sku,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n try {\n await deleteInAppProduct(client, packageName, sku);\n console.log(`In-app product ${sku} deleted.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n iap\n .command(\"sync\")\n .description(\"Sync in-app products from a directory of JSON files\")\n .requiredOption(\"--dir <path>\", \"Directory containing product JSON files\")\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 = detectOutputFormat();\n const dryRun = isDryRun(program);\n\n const spinner = createSpinner(\"Syncing in-app products...\");\n if (!program.opts()[\"quiet\"] && process.stderr.isTTY) spinner.start();\n\n try {\n const result = await syncInAppProducts(client, packageName, options.dir, {\n dryRun,\n });\n spinner.stop(\"Sync complete\");\n if (dryRun) {\n console.log(`[dry-run] Would create: ${result.created}, update: ${result.updated}`);\n }\n console.log(formatOutput(result, format));\n } catch (error) {\n spinner.fail(\"Sync failed\");\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,8 @@ import { createApiClient } from "@gpc-cli/api";
|
|
|
7
7
|
import {
|
|
8
8
|
uploadInternalSharing,
|
|
9
9
|
detectOutputFormat,
|
|
10
|
-
formatOutput
|
|
10
|
+
formatOutput,
|
|
11
|
+
createSpinner
|
|
11
12
|
} from "@gpc-cli/core";
|
|
12
13
|
function resolvePackageName(packageArg, config) {
|
|
13
14
|
const name = packageArg || config.app;
|
|
@@ -29,10 +30,14 @@ function registerInternalSharingCommands(program) {
|
|
|
29
30
|
const client = await getClient(config);
|
|
30
31
|
const format = detectOutputFormat();
|
|
31
32
|
const fileType = opts.type;
|
|
33
|
+
const spinner = createSpinner("Uploading for internal sharing...");
|
|
34
|
+
if (!program.opts()["quiet"] && process.stderr.isTTY) spinner.start();
|
|
32
35
|
try {
|
|
33
36
|
const result = await uploadInternalSharing(client, packageName, file, fileType);
|
|
37
|
+
spinner.stop("Upload complete");
|
|
34
38
|
console.log(formatOutput(result, format));
|
|
35
39
|
} catch (error) {
|
|
40
|
+
spinner.fail("Upload failed");
|
|
36
41
|
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
37
42
|
process.exit(4);
|
|
38
43
|
}
|
|
@@ -41,4 +46,4 @@ function registerInternalSharingCommands(program) {
|
|
|
41
46
|
export {
|
|
42
47
|
registerInternalSharingCommands
|
|
43
48
|
};
|
|
44
|
-
//# sourceMappingURL=internal-sharing-
|
|
49
|
+
//# sourceMappingURL=internal-sharing-TWMHLQLN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/internal-sharing.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 uploadInternalSharing,\n detectOutputFormat,\n formatOutput,\n createSpinner,\n} from \"@gpc-cli/core\";\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 registerInternalSharingCommands(program: Command): void {\n const cmd = program\n .command(\"internal-sharing\")\n .description(\"Internal app sharing (upload bundles/APKs for instant sharing)\");\n\n cmd\n .command(\"upload <file>\")\n .description(\"Upload a bundle or APK for internal app sharing\")\n .option(\"--type <type>\", \"File type: bundle or apk (auto-detected from extension)\")\n .action(async (file: string, opts: { type?: string }) => {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n const format = detectOutputFormat();\n\n const fileType = opts.type as \"bundle\" | \"apk\" | undefined;\n\n const spinner = createSpinner(\"Uploading for internal sharing...\");\n if (!program.opts()[\"quiet\"] && process.stderr.isTTY) spinner.start();\n\n try {\n const result = await uploadInternalSharing(client, packageName, file, fileType);\n spinner.stop(\"Upload complete\");\n console.log(formatOutput(result, format));\n } catch (error) {\n spinner.fail(\"Upload failed\");\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,OACK;AAEP,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,gCAAgC,SAAwB;AACtE,QAAM,MAAM,QACT,QAAQ,kBAAkB,EAC1B,YAAY,gEAAgE;AAE/E,MACG,QAAQ,eAAe,EACvB,YAAY,iDAAiD,EAC7D,OAAO,iBAAiB,yDAAyD,EACjF,OAAO,OAAO,MAAc,SAA4B;AACvD,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AACpE,UAAM,SAAS,MAAM,UAAU,MAAM;AACrC,UAAM,SAAS,mBAAmB;AAElC,UAAM,WAAW,KAAK;AAEtB,UAAM,UAAU,cAAc,mCAAmC;AACjE,QAAI,CAAC,QAAQ,KAAK,EAAE,OAAO,KAAK,QAAQ,OAAO,MAAO,SAAQ,MAAM;AAEpE,QAAI;AACF,YAAM,SAAS,MAAM,sBAAsB,QAAQ,aAAa,MAAM,QAAQ;AAC9E,cAAQ,KAAK,iBAAiB;AAC9B,cAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,IAC1C,SAAS,OAAO;AACd,cAAQ,KAAK,eAAe;AAC5B,cAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAChF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AACL;","names":[]}
|
|
@@ -23,9 +23,11 @@ import {
|
|
|
23
23
|
listImages,
|
|
24
24
|
uploadImage,
|
|
25
25
|
deleteImage,
|
|
26
|
+
exportImages,
|
|
26
27
|
getCountryAvailability,
|
|
27
28
|
detectOutputFormat,
|
|
28
|
-
formatOutput
|
|
29
|
+
formatOutput,
|
|
30
|
+
createSpinner
|
|
29
31
|
} from "@gpc-cli/core";
|
|
30
32
|
function resolvePackageName(packageArg, config) {
|
|
31
33
|
const name = packageArg || config.app;
|
|
@@ -185,12 +187,16 @@ function registerListingsCommands(program) {
|
|
|
185
187
|
const packageName = resolvePackageName(program.opts()["app"], config);
|
|
186
188
|
const client = await getClient(config);
|
|
187
189
|
const format = detectOutputFormat();
|
|
190
|
+
const spinner = createSpinner("Pushing listings...");
|
|
191
|
+
if (!program.opts()["quiet"] && process.stderr.isTTY) spinner.start();
|
|
188
192
|
try {
|
|
189
193
|
const result = await pushListings(client, packageName, options.dir, {
|
|
190
194
|
dryRun: isDryRun(program)
|
|
191
195
|
});
|
|
196
|
+
spinner.stop("Listings pushed");
|
|
192
197
|
console.log(formatOutput(result, format));
|
|
193
198
|
} catch (error) {
|
|
199
|
+
spinner.fail("Push failed");
|
|
194
200
|
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
195
201
|
process.exit(4);
|
|
196
202
|
}
|
|
@@ -283,10 +289,14 @@ function registerListingsCommands(program) {
|
|
|
283
289
|
const client = await getClient(config);
|
|
284
290
|
const format = detectOutputFormat();
|
|
285
291
|
const imageType = validateImageType(options.type);
|
|
292
|
+
const spinner = createSpinner("Uploading image...");
|
|
293
|
+
if (!program.opts()["quiet"] && process.stderr.isTTY) spinner.start();
|
|
286
294
|
try {
|
|
287
295
|
const result = await uploadImage(client, packageName, options.lang, imageType, file);
|
|
296
|
+
spinner.stop("Image uploaded");
|
|
288
297
|
console.log(formatOutput(result, format));
|
|
289
298
|
} catch (error) {
|
|
299
|
+
spinner.fail("Image upload failed");
|
|
290
300
|
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
291
301
|
process.exit(4);
|
|
292
302
|
}
|
|
@@ -331,6 +341,28 @@ function registerListingsCommands(program) {
|
|
|
331
341
|
process.exit(4);
|
|
332
342
|
}
|
|
333
343
|
});
|
|
344
|
+
images.command("export").description("Export all images to a local directory").option("--dir <path>", "Output directory", "images").option("--lang <language>", "Language code (BCP 47) \u2014 export only this language").option("--type <type>", "Image type \u2014 export only this type").action(async (options) => {
|
|
345
|
+
const config = await loadConfig();
|
|
346
|
+
const packageName = resolvePackageName(program.opts()["app"], config);
|
|
347
|
+
const client = await getClient(config);
|
|
348
|
+
const format = detectOutputFormat();
|
|
349
|
+
const exportOpts = {};
|
|
350
|
+
if (options.lang) exportOpts.lang = options.lang;
|
|
351
|
+
if (options.type) {
|
|
352
|
+
exportOpts.type = validateImageType(options.type);
|
|
353
|
+
}
|
|
354
|
+
const spinner = createSpinner("Exporting images...");
|
|
355
|
+
if (!program.opts()["quiet"] && process.stderr.isTTY) spinner.start();
|
|
356
|
+
try {
|
|
357
|
+
const result = await exportImages(client, packageName, options.dir, exportOpts);
|
|
358
|
+
spinner.stop("Images exported");
|
|
359
|
+
console.log(formatOutput(result, format));
|
|
360
|
+
} catch (error) {
|
|
361
|
+
spinner.fail("Image export failed");
|
|
362
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
363
|
+
process.exit(4);
|
|
364
|
+
}
|
|
365
|
+
});
|
|
334
366
|
listings.command("availability").description("Get country availability for a track").option("--track <track>", "Track name", "production").action(async (options) => {
|
|
335
367
|
const config = await loadConfig();
|
|
336
368
|
const packageName = resolvePackageName(program.opts()["app"], config);
|
|
@@ -348,4 +380,4 @@ function registerListingsCommands(program) {
|
|
|
348
380
|
export {
|
|
349
381
|
registerListingsCommands
|
|
350
382
|
};
|
|
351
|
-
//# sourceMappingURL=listings-
|
|
383
|
+
//# sourceMappingURL=listings-4QCTOEWL.js.map
|