@gpc-cli/cli 0.9.44 → 0.9.46
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-NU2IN2GJ.js → anomalies-UDE4NGHJ.js} +19 -24
- package/dist/anomalies-UDE4NGHJ.js.map +1 -0
- package/dist/{apps-J2446UDA.js → apps-FKD3ZG5X.js} +31 -35
- package/dist/apps-FKD3ZG5X.js.map +1 -0
- package/dist/{audit-N2CRHWUN.js → audit-JASSHRWN.js} +47 -62
- package/dist/audit-JASSHRWN.js.map +1 -0
- package/dist/{auth-XGSTT5G5.js → auth-OTA3SV3J.js} +145 -103
- package/dist/auth-OTA3SV3J.js.map +1 -0
- package/dist/bin.js +6 -4
- package/dist/bin.js.map +1 -1
- package/dist/bundle-F7MUVC5J.js +204 -0
- package/dist/bundle-F7MUVC5J.js.map +1 -0
- package/dist/{cache-SLNFRTI2.js → cache-XKPLZYEB.js} +4 -5
- package/dist/cache-XKPLZYEB.js.map +1 -0
- package/dist/changelog-7COFZO7Q.js +48 -0
- package/dist/changelog-7COFZO7Q.js.map +1 -0
- package/dist/{chunk-4O4D5SGL.js → chunk-3SJ6OXCZ.js} +4 -5
- package/dist/chunk-3SJ6OXCZ.js.map +1 -0
- package/dist/{chunk-7LURVNQV.js → chunk-6OWN6S6X.js} +53 -49
- package/dist/{chunk-7LURVNQV.js.map → chunk-6OWN6S6X.js.map} +1 -1
- package/dist/{chunk-U6ZTQ34I.js → chunk-BCBXQC7J.js} +45 -11
- package/dist/chunk-BCBXQC7J.js.map +1 -0
- package/dist/{chunk-AA577WVQ.js → chunk-NQH4G7BI.js} +9 -3
- package/dist/chunk-NQH4G7BI.js.map +1 -0
- package/dist/chunk-SLNJEAMK.js +23 -0
- package/dist/chunk-SLNJEAMK.js.map +1 -0
- package/dist/{chunk-NV75I5VP.js → chunk-YFUBD2XB.js} +10 -8
- package/dist/chunk-YFUBD2XB.js.map +1 -0
- package/dist/{config-222P3MKK.js → config-2FTCYEGD.js} +8 -5
- package/dist/config-2FTCYEGD.js.map +1 -0
- package/dist/{data-safety-Q7FTCEWU.js → data-safety-AFMD6MYI.js} +12 -27
- package/dist/data-safety-AFMD6MYI.js.map +1 -0
- package/dist/{device-tiers-MIOQEXYY.js → device-tiers-AQAMUQXI.js} +23 -38
- package/dist/device-tiers-AQAMUQXI.js.map +1 -0
- package/dist/diff-6EO4ID6W.js +91 -0
- package/dist/diff-6EO4ID6W.js.map +1 -0
- package/dist/{docs-7DUXIKA3.js → docs-4D2SJ4LY.js} +4 -3
- package/dist/docs-4D2SJ4LY.js.map +1 -0
- package/dist/doctor-H4X7Q57B.js +691 -0
- package/dist/doctor-H4X7Q57B.js.map +1 -0
- package/dist/{enterprise-7THXNBTC.js → enterprise-7PWXMSUN.js} +11 -21
- package/dist/enterprise-7PWXMSUN.js.map +1 -0
- package/dist/{external-transactions-2GWIMUVM.js → external-transactions-LCZALS3V.js} +12 -28
- package/dist/external-transactions-LCZALS3V.js.map +1 -0
- package/dist/{feedback-2W2XJGZX.js → feedback-XP765TOO.js} +4 -4
- package/dist/{games-BT777WUO.js → games-ZSNGEI7A.js} +17 -32
- package/dist/games-ZSNGEI7A.js.map +1 -0
- package/dist/{generated-apks-RJWTIX7L.js → generated-apks-RX2IUWSF.js} +30 -38
- package/dist/generated-apks-RX2IUWSF.js.map +1 -0
- package/dist/{grants-TKQJ3IER.js → grants-EBPECI26.js} +22 -40
- package/dist/grants-EBPECI26.js.map +1 -0
- package/dist/{iap-ICAEQLK5.js → iap-OUI5YYN4.js} +30 -51
- package/dist/iap-OUI5YYN4.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/{init-JZ2THPMS.js → init-WSTQTJOD.js} +5 -4
- package/dist/init-WSTQTJOD.js.map +1 -0
- package/dist/{install-skills-OV4HVANW.js → install-skills-6QDUXI5F.js} +5 -6
- package/dist/{install-skills-OV4HVANW.js.map → install-skills-6QDUXI5F.js.map} +1 -1
- package/dist/{internal-sharing-3U2XFHA4.js → internal-sharing-ONNIWIAT.js} +3 -4
- package/dist/{internal-sharing-3U2XFHA4.js.map → internal-sharing-ONNIWIAT.js.map} +1 -1
- package/dist/{listings-77HZW4S5.js → listings-7SGQ4SRX.js} +118 -157
- package/dist/listings-7SGQ4SRX.js.map +1 -0
- package/dist/migrate-ZQCJGQQS.js +138 -0
- package/dist/migrate-ZQCJGQQS.js.map +1 -0
- package/dist/{one-time-products-LHZAXQES.js → one-time-products-MGZTU7OM.js} +65 -120
- package/dist/one-time-products-MGZTU7OM.js.map +1 -0
- package/dist/{preflight-H3HEBYQW.js → preflight-N7ZRG2JI.js} +58 -55
- package/dist/preflight-N7ZRG2JI.js.map +1 -0
- package/dist/{pricing-XQSDTTK5.js → pricing-JJZFICFL.js} +8 -8
- package/dist/{pricing-XQSDTTK5.js.map → pricing-JJZFICFL.js.map} +1 -1
- package/dist/{prompt-BSV22CQZ.js → prompt-GXC2JSLA.js} +2 -2
- package/dist/{publish-Q5ZKEKZ5.js → publish-JPTI4EBT.js} +34 -30
- package/dist/publish-JPTI4EBT.js.map +1 -0
- package/dist/{purchase-options-CKRN4VIW.js → purchase-options-KFWW4JW2.js} +16 -11
- package/dist/purchase-options-KFWW4JW2.js.map +1 -0
- package/dist/purchases-DAWTMXP6.js +383 -0
- package/dist/purchases-DAWTMXP6.js.map +1 -0
- package/dist/{quickstart-4HB62YEL.js → quickstart-Z5Y3FYJU.js} +5 -3
- package/dist/quickstart-Z5Y3FYJU.js.map +1 -0
- package/dist/{quota-UHIQQYOY.js → quota-MZRWYJGR.js} +5 -15
- package/dist/quota-MZRWYJGR.js.map +1 -0
- package/dist/{recovery-5EV2R476.js → recovery-YE3Z7NIN.js} +32 -61
- package/dist/recovery-YE3Z7NIN.js.map +1 -0
- package/dist/{releases-C2WC2K4E.js → releases-2I3WBULC.js} +184 -185
- package/dist/releases-2I3WBULC.js.map +1 -0
- package/dist/{reports-2YX3RDOS.js → reports-CIB2T3XT.js} +19 -21
- package/dist/reports-CIB2T3XT.js.map +1 -0
- package/dist/reviews-BCCXIQ6C.js +188 -0
- package/dist/reviews-BCCXIQ6C.js.map +1 -0
- package/dist/{status-WHGLODGV.js → status-6LH5W4FU.js} +105 -83
- package/dist/status-6LH5W4FU.js.map +1 -0
- package/dist/{subscriptions-CI3JH3VQ.js → subscriptions-DZP3Y7O7.js} +142 -232
- package/dist/subscriptions-DZP3Y7O7.js.map +1 -0
- package/dist/{testers-NZOFA3EF.js → testers-LSMBXCA2.js} +24 -44
- package/dist/testers-LSMBXCA2.js.map +1 -0
- package/dist/tracks-YHMO2A6B.js +98 -0
- package/dist/tracks-YHMO2A6B.js.map +1 -0
- package/dist/{train-XKE4JN3Y.js → train-MDD2EBHS.js} +35 -55
- package/dist/train-MDD2EBHS.js.map +1 -0
- package/dist/{update-QMPRL5Y6.js → update-OMALGIBR.js} +30 -15
- package/dist/update-OMALGIBR.js.map +1 -0
- package/dist/{users-2YTC4Q36.js → users-UKG7VIQH.js} +45 -67
- package/dist/users-UKG7VIQH.js.map +1 -0
- package/dist/{validate-UOVTM6L3.js → validate-QIYSA3N7.js} +8 -10
- package/dist/validate-QIYSA3N7.js.map +1 -0
- package/dist/{version-NK5SJLHJ.js → version-NCSNXNVN.js} +4 -4
- package/dist/{vitals-A4CS4MSS.js → vitals-C23L2Y2E.js} +153 -172
- package/dist/vitals-C23L2Y2E.js.map +1 -0
- package/package.json +6 -6
- package/dist/anomalies-NU2IN2GJ.js.map +0 -1
- package/dist/apps-J2446UDA.js.map +0 -1
- package/dist/audit-N2CRHWUN.js.map +0 -1
- package/dist/auth-XGSTT5G5.js.map +0 -1
- package/dist/bundle-F43TD2BQ.js +0 -218
- package/dist/bundle-F43TD2BQ.js.map +0 -1
- package/dist/cache-SLNFRTI2.js.map +0 -1
- package/dist/changelog-OYUZOCOL.js +0 -53
- package/dist/changelog-OYUZOCOL.js.map +0 -1
- package/dist/chunk-4O4D5SGL.js.map +0 -1
- package/dist/chunk-AA577WVQ.js.map +0 -1
- package/dist/chunk-FWKYRLKY.js +0 -19
- package/dist/chunk-FWKYRLKY.js.map +0 -1
- package/dist/chunk-NV75I5VP.js.map +0 -1
- package/dist/chunk-U6ZTQ34I.js.map +0 -1
- package/dist/config-222P3MKK.js.map +0 -1
- package/dist/data-safety-Q7FTCEWU.js.map +0 -1
- package/dist/device-tiers-MIOQEXYY.js.map +0 -1
- package/dist/diff-V77SMKAQ.js +0 -96
- package/dist/diff-V77SMKAQ.js.map +0 -1
- package/dist/docs-7DUXIKA3.js.map +0 -1
- package/dist/doctor-3Z4ARPM2.js +0 -372
- package/dist/doctor-3Z4ARPM2.js.map +0 -1
- package/dist/enterprise-7THXNBTC.js.map +0 -1
- package/dist/external-transactions-2GWIMUVM.js.map +0 -1
- package/dist/games-BT777WUO.js.map +0 -1
- package/dist/generated-apks-RJWTIX7L.js.map +0 -1
- package/dist/grants-TKQJ3IER.js.map +0 -1
- package/dist/iap-ICAEQLK5.js.map +0 -1
- package/dist/init-JZ2THPMS.js.map +0 -1
- package/dist/listings-77HZW4S5.js.map +0 -1
- package/dist/migrate-SQT6RD6T.js +0 -143
- package/dist/migrate-SQT6RD6T.js.map +0 -1
- package/dist/one-time-products-LHZAXQES.js.map +0 -1
- package/dist/preflight-H3HEBYQW.js.map +0 -1
- package/dist/publish-Q5ZKEKZ5.js.map +0 -1
- package/dist/purchase-options-CKRN4VIW.js.map +0 -1
- package/dist/purchases-HSMCOG4A.js +0 -330
- package/dist/purchases-HSMCOG4A.js.map +0 -1
- package/dist/quickstart-4HB62YEL.js.map +0 -1
- package/dist/quota-UHIQQYOY.js.map +0 -1
- package/dist/recovery-5EV2R476.js.map +0 -1
- package/dist/releases-C2WC2K4E.js.map +0 -1
- package/dist/reports-2YX3RDOS.js.map +0 -1
- package/dist/reviews-2CWOI5CV.js +0 -213
- package/dist/reviews-2CWOI5CV.js.map +0 -1
- package/dist/status-WHGLODGV.js.map +0 -1
- package/dist/subscriptions-CI3JH3VQ.js.map +0 -1
- package/dist/testers-NZOFA3EF.js.map +0 -1
- package/dist/tracks-NERFFEDT.js +0 -107
- package/dist/tracks-NERFFEDT.js.map +0 -1
- package/dist/train-XKE4JN3Y.js.map +0 -1
- package/dist/update-QMPRL5Y6.js.map +0 -1
- package/dist/users-2YTC4Q36.js.map +0 -1
- package/dist/validate-UOVTM6L3.js.map +0 -1
- package/dist/vitals-A4CS4MSS.js.map +0 -1
- /package/dist/{feedback-2W2XJGZX.js.map → feedback-XP765TOO.js.map} +0 -0
- /package/dist/{prompt-BSV22CQZ.js.map → prompt-GXC2JSLA.js.map} +0 -0
- /package/dist/{version-NK5SJLHJ.js.map → version-NCSNXNVN.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/grants.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 { createUsersClient } from \"@gpc-cli/api\";\nimport { listGrants, createGrant, updateGrant, deleteGrant, formatOutput, GpcError } from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { requireConfirm } from \"../prompt.js\";\n\nfunction resolveDeveloperId(devIdArg: string | undefined, config: GpcConfig): string {\n const id = devIdArg || config.developerId;\n if (!id) {\n throw new GpcError(\n \"No developer ID. Use --developer-id <id> or gpc config set developerId <id>\",\n \"MISSING_DEVELOPER_ID\",\n 2,\n \"gpc config set developerId <id>\",\n );\n }\n return id;\n}\n\nasync function getClient(config: GpcConfig) {\n const auth = await resolveAuth({ serviceAccountPath: config.auth?.serviceAccount });\n return createUsersClient({ auth });\n}\n\nexport function registerGrantsCommands(program: Command): void {\n const grants = program\n .command(\"grants\")\n .description(\"Manage per-app permission grants for developer account users\")\n .option(\"--developer-id <id>\", \"Developer account ID\");\n\n grants\n .command(\"list <email>\")\n .description(\"List all per-app grants for a user\")\n .action(async (email: string) => {\n const config = await loadConfig();\n const developerId = resolveDeveloperId(grants.opts()[\"developerId\"], config);\n const client = await getClient(config);\n const format = getOutputFormat(program, config);\n\n const result = await listGrants(client, developerId, email);\n if (result.length === 0) {\n if (format === \"json\") {\n console.log(formatOutput([], format));\n } else {\n console.log(`No grants found for ${email}.`);\n }\n return;\n }\n console.log(formatOutput(result, format));\n });\n\n grants\n .command(\"create <email>\")\n .description(\"Grant app-level permissions to a user\")\n .requiredOption(\"--package <packageName>\", \"App package name\")\n .requiredOption(\n \"--permissions <list>\",\n \"Comma-separated permissions (e.g. CAN_MANAGE_RELEASES,VIEW_APP_INFORMATION)\",\n )\n .action(async (email: string, options) => {\n const config = await loadConfig();\n const developerId = resolveDeveloperId(grants.opts()[\"developerId\"], config);\n const format = getOutputFormat(program, config);\n const perms = (options.permissions as string).split(\",\").map((p: string) => p.trim());\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"grants create\",\n action: \"grant permissions\",\n target: `${email}/${options.package}`,\n details: { permissions: perms },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n const result = await createGrant(client, developerId, email, options.package, perms);\n console.log(formatOutput(result, format));\n });\n\n grants\n .command(\"update <email>\")\n .description(\"Update app-level permissions for a user\")\n .requiredOption(\"--package <packageName>\", \"App package name\")\n .requiredOption(\"--permissions <list>\", \"New comma-separated permissions\")\n .action(async (email: string, options) => {\n const config = await loadConfig();\n const developerId = resolveDeveloperId(grants.opts()[\"developerId\"], config);\n const format = getOutputFormat(program, config);\n const perms = (options.permissions as string).split(\",\").map((p: string) => p.trim());\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"grants update\",\n action: \"update permissions\",\n target: `${email}/${options.package}`,\n details: { permissions: perms },\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n const result = await updateGrant(client, developerId, email, options.package, perms);\n console.log(formatOutput(result, format));\n });\n\n grants\n .command(\"delete <email>\")\n .description(\"Remove a per-app grant from a user\")\n .requiredOption(\"--package <packageName>\", \"App package name\")\n .action(async (email: string, options) => {\n const config = await loadConfig();\n const developerId = resolveDeveloperId(grants.opts()[\"developerId\"], config);\n const format = getOutputFormat(program, config);\n\n await requireConfirm(`Remove grant for \"${email}\" on ${options.package}?`, program);\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"grants delete\",\n action: \"remove grant\",\n target: `${email}/${options.package}`,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\n\n await deleteGrant(client, developerId, email, options.package);\n console.log(`Grant removed for ${email} on ${options.package}.`);\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
readJsonFile
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-SLNJEAMK.js";
|
|
5
5
|
import {
|
|
6
6
|
getClient,
|
|
7
7
|
resolvePackageName
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-NQH4G7BI.js";
|
|
9
9
|
import {
|
|
10
10
|
isDryRun,
|
|
11
11
|
printDryRun
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from "./chunk-ELXAK7GI.js";
|
|
16
16
|
import {
|
|
17
17
|
requireConfirm
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-YFUBD2XB.js";
|
|
19
19
|
|
|
20
20
|
// src/commands/iap.ts
|
|
21
21
|
import { loadConfig } from "@gpc-cli/config";
|
|
@@ -40,17 +40,12 @@ function registerIapCommands(program) {
|
|
|
40
40
|
console.error(
|
|
41
41
|
"Note: Using oneTimeProducts API (inappproducts endpoint is deprecated, shutdown Aug 2027)"
|
|
42
42
|
);
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
products = sortResults(products, options.sort);
|
|
48
|
-
}
|
|
49
|
-
console.log(formatOutput(products, format));
|
|
50
|
-
} catch (error) {
|
|
51
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
52
|
-
process.exit(4);
|
|
43
|
+
const result = await listOneTimeProducts(client, packageName);
|
|
44
|
+
let products = result.oneTimeProducts || [];
|
|
45
|
+
if (options.sort) {
|
|
46
|
+
products = sortResults(products, options.sort);
|
|
53
47
|
}
|
|
48
|
+
console.log(formatOutput(products, format));
|
|
54
49
|
});
|
|
55
50
|
iap.command("get <sku>").description("Get an in-app product").action(async (sku) => {
|
|
56
51
|
const config = await loadConfig();
|
|
@@ -60,13 +55,8 @@ function registerIapCommands(program) {
|
|
|
60
55
|
console.error(
|
|
61
56
|
"Note: Using oneTimeProducts API (inappproducts endpoint is deprecated, shutdown Aug 2027)"
|
|
62
57
|
);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
console.log(formatOutput(result, format));
|
|
66
|
-
} catch (error) {
|
|
67
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
68
|
-
process.exit(4);
|
|
69
|
-
}
|
|
58
|
+
const result = await getOneTimeProduct(client, packageName, sku);
|
|
59
|
+
console.log(formatOutput(result, format));
|
|
70
60
|
});
|
|
71
61
|
iap.command("create").description("Create an in-app product from JSON file").requiredOption("--file <path>", "JSON file with product data").action(async (options) => {
|
|
72
62
|
const config = await loadConfig();
|
|
@@ -85,14 +75,9 @@ function registerIapCommands(program) {
|
|
|
85
75
|
return;
|
|
86
76
|
}
|
|
87
77
|
const client = await getClient(config);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
console.log(formatOutput(result, format));
|
|
92
|
-
} catch (error) {
|
|
93
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
94
|
-
process.exit(4);
|
|
95
|
-
}
|
|
78
|
+
const data = await readJsonFile(options.file);
|
|
79
|
+
const result = await createInAppProduct(client, packageName, data);
|
|
80
|
+
console.log(formatOutput(result, format));
|
|
96
81
|
});
|
|
97
82
|
iap.command("update <sku>").description("Update an in-app product from JSON file").requiredOption("--file <path>", "JSON file with product data").action(async (sku, options) => {
|
|
98
83
|
const config = await loadConfig();
|
|
@@ -112,14 +97,9 @@ function registerIapCommands(program) {
|
|
|
112
97
|
return;
|
|
113
98
|
}
|
|
114
99
|
const client = await getClient(config);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
console.log(formatOutput(result, format));
|
|
119
|
-
} catch (error) {
|
|
120
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
121
|
-
process.exit(4);
|
|
122
|
-
}
|
|
100
|
+
const data = await readJsonFile(options.file);
|
|
101
|
+
const result = await updateInAppProduct(client, packageName, sku, data);
|
|
102
|
+
console.log(formatOutput(result, format));
|
|
123
103
|
});
|
|
124
104
|
iap.command("delete <sku>").description("Delete an in-app product").action(async (sku) => {
|
|
125
105
|
const config = await loadConfig();
|
|
@@ -139,13 +119,8 @@ function registerIapCommands(program) {
|
|
|
139
119
|
return;
|
|
140
120
|
}
|
|
141
121
|
const client = await getClient(config);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
console.log(`In-app product ${sku} deleted.`);
|
|
145
|
-
} catch (error) {
|
|
146
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
147
|
-
process.exit(4);
|
|
148
|
-
}
|
|
122
|
+
await deleteInAppProduct(client, packageName, sku);
|
|
123
|
+
console.log(`In-app product ${sku} deleted.`);
|
|
149
124
|
});
|
|
150
125
|
iap.command("sync").description("Sync in-app products from a directory of JSON files").requiredOption("--dir <path>", "Directory containing product JSON files").action(async (options) => {
|
|
151
126
|
const config = await loadConfig();
|
|
@@ -166,15 +141,20 @@ function registerIapCommands(program) {
|
|
|
166
141
|
console.log(formatOutput(result, format));
|
|
167
142
|
} catch (error) {
|
|
168
143
|
spinner.fail("Sync failed");
|
|
169
|
-
|
|
170
|
-
process.exit(4);
|
|
144
|
+
throw error;
|
|
171
145
|
}
|
|
172
146
|
});
|
|
173
147
|
iap.command("batch-get").description("Batch get multiple in-app products").option("--skus <skus>", "Comma-separated list of SKUs").option("--file <path>", "JSON file with array of SKUs").action(async (_options) => {
|
|
174
|
-
|
|
175
|
-
|
|
148
|
+
throw Object.assign(
|
|
149
|
+
new Error(
|
|
150
|
+
"The inappproducts batchGet endpoint is permanently blocked by Google Play (returns 403 PERMISSION_DENIED)."
|
|
151
|
+
),
|
|
152
|
+
{
|
|
153
|
+
code: "IAP_BATCH_GET_UNAVAILABLE",
|
|
154
|
+
exitCode: 1,
|
|
155
|
+
suggestion: "Use `gpc iap get <sku>` for a single product, or `gpc iap list` for all products."
|
|
156
|
+
}
|
|
176
157
|
);
|
|
177
|
-
process.exit(1);
|
|
178
158
|
});
|
|
179
159
|
iap.command("batch-update").description("Batch update multiple in-app products from a JSON file").requiredOption("--file <path>", "JSON file with array of product objects").option("--dry-run", "Preview changes without executing").action(async (options) => {
|
|
180
160
|
const config = await loadConfig();
|
|
@@ -214,12 +194,11 @@ function registerIapCommands(program) {
|
|
|
214
194
|
console.log(formatOutput(result, format));
|
|
215
195
|
} catch (error) {
|
|
216
196
|
spinner.fail("Batch update failed");
|
|
217
|
-
|
|
218
|
-
process.exit(4);
|
|
197
|
+
throw error;
|
|
219
198
|
}
|
|
220
199
|
});
|
|
221
200
|
}
|
|
222
201
|
export {
|
|
223
202
|
registerIapCommands
|
|
224
203
|
};
|
|
225
|
-
//# sourceMappingURL=iap-
|
|
204
|
+
//# sourceMappingURL=iap-OUI5YYN4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/iap.ts"],"sourcesContent":["import { resolvePackageName, getClient } from \"../resolve.js\";\nimport type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\n\nimport {\n listOneTimeProducts,\n getOneTimeProduct,\n createInAppProduct,\n updateInAppProduct,\n deleteInAppProduct,\n syncInAppProducts,\n formatOutput,\n sortResults,\n createSpinner,\n} from \"@gpc-cli/core\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\nimport { getOutputFormat } from \"../format.js\";\nimport { requireConfirm } from \"../prompt.js\";\nimport { readJsonFile } from \"../json.js\";\n\n\n\nexport function registerIapCommands(program: Command): void {\n const iap = program\n .command(\"iap\")\n .description(\"Manage in-app products (uses one-time products API)\");\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 = getOutputFormat(program, config);\n\n console.error(\n \"Note: Using oneTimeProducts API (inappproducts endpoint is deprecated, shutdown Aug 2027)\",\n );\n\n const result = await listOneTimeProducts(client, packageName);\n let products = result.oneTimeProducts || [];\n if (options.sort) {\n products = sortResults(products, options.sort);\n }\n console.log(formatOutput(products, format));\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 = getOutputFormat(program, config);\n\n console.error(\n \"Note: Using oneTimeProducts API (inappproducts endpoint is deprecated, shutdown Aug 2027)\",\n );\n\n const result = await getOneTimeProduct(client, packageName, sku);\n console.log(formatOutput(result, format));\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 = getOutputFormat(program, config);\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 const data = await readJsonFile(options.file);\n const result = await createInAppProduct(client, packageName, data as any);\n console.log(formatOutput(result, format));\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 = getOutputFormat(program, config);\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 const data = await readJsonFile(options.file);\n const result = await updateInAppProduct(client, packageName, sku, data as any);\n console.log(formatOutput(result, format));\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 = getOutputFormat(program, config);\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 await deleteInAppProduct(client, packageName, sku);\n console.log(`In-app product ${sku} deleted.`);\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 = getOutputFormat(program, config);\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 throw error;\n }\n });\n\n iap\n .command(\"batch-get\")\n .description(\"Batch get multiple in-app products\")\n .option(\"--skus <skus>\", \"Comma-separated list of SKUs\")\n .option(\"--file <path>\", \"JSON file with array of SKUs\")\n .action(async (_options) => {\n throw Object.assign(\n new Error(\n \"The inappproducts batchGet endpoint is permanently blocked by Google Play (returns 403 PERMISSION_DENIED).\",\n ),\n {\n code: \"IAP_BATCH_GET_UNAVAILABLE\",\n exitCode: 1,\n suggestion: \"Use `gpc iap get <sku>` for a single product, or `gpc iap list` for all products.\",\n },\n );\n });\n\n iap\n .command(\"batch-update\")\n .description(\"Batch update multiple in-app products from a JSON file\")\n .requiredOption(\"--file <path>\", \"JSON file with array of product objects\")\n .option(\"--dry-run\", \"Preview changes without executing\")\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 (options.dryRun || isDryRun(program)) {\n const data = await readJsonFile(options.file);\n const products = Array.isArray(data) ? data : [];\n console.log(`[dry-run] Would batch update ${products.length} product(s)`);\n if (format !== \"json\") {\n const rows = products.map((p: Record<string, unknown>) => ({\n sku: p[\"sku\"] || \"-\",\n action: \"update\",\n }));\n console.log(formatOutput(rows, format));\n } else {\n console.log(formatOutput(products, format));\n }\n return;\n }\n\n const client = await getClient(config);\n console.error(\"Note: Using inappproducts batch API\");\n\n const spinner = createSpinner(\"Batch updating products...\");\n if (!program.opts()[\"quiet\"] && process.stderr.isTTY) spinner.start();\n\n try {\n const data = await readJsonFile(options.file);\n const products = Array.isArray(data) ? data : [];\n const request = {\n requests: products.map((p: Record<string, unknown>) => ({\n inappproduct: p,\n packageName,\n sku: p[\"sku\"] as string,\n })),\n };\n const result = await client.inappproducts.batchUpdate(packageName, request as any);\n spinner.stop(\"Batch update complete\");\n console.log(formatOutput(result, format));\n } catch (error) {\n spinner.fail(\"Batch update failed\");\n throw error;\n }\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAEA,SAAS,kBAAkB;AAE3B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAQA,SAAS,oBAAoB,SAAwB;AAC1D,QAAM,MAAM,QACT,QAAQ,KAAK,EACb,YAAY,qDAAqD;AAEpE,MACG,QAAQ,MAAM,EACd,YAAY,sBAAsB,EAClC,OAAO,aAAa,4BAA4B,QAAQ,EACxD,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,YAAQ;AAAA,MACN;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,oBAAoB,QAAQ,WAAW;AAC1D,QAAI,WAAW,OAAO,mBAAmB,CAAC;AAC1C,QAAI,QAAQ,MAAM;AAChB,iBAAW,YAAY,UAAU,QAAQ,IAAI;AAAA,IAC/C;AACA,YAAQ,IAAI,aAAa,UAAU,MAAM,CAAC;AAAA,EAC9C,CAAC;AAEH,MACG,QAAQ,WAAW,EACnB,YAAY,uBAAuB,EACnC,OAAO,OAAO,QAAgB;AAC7B,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,YAAQ;AAAA,MACN;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,kBAAkB,QAAQ,aAAa,GAAG;AAC7D,YAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,EAC5C,CAAC;AAEH,MACG,QAAQ,QAAQ,EAChB,YAAY,yCAAyC,EACrD,eAAe,iBAAiB,6BAA6B,EAC7D,OAAO,OAAO,YAAY;AACzB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AACpE,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAE9C,QAAI,SAAS,OAAO,GAAG;AACrB;AAAA,QACE;AAAA,UACE,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,QAAQ,uBAAuB,QAAQ,IAAI;AAAA,QAC7C;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,UAAU,MAAM;AAErC,UAAM,OAAO,MAAM,aAAa,QAAQ,IAAI;AAC1C,UAAM,SAAS,MAAM,mBAAmB,QAAQ,aAAa,IAAW;AACxE,YAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,EAC5C,CAAC;AAEH,MACG,QAAQ,cAAc,EACtB,YAAY,yCAAyC,EACrD,eAAe,iBAAiB,6BAA6B,EAC7D,OAAO,OAAO,KAAa,YAAY;AACtC,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AACpE,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAE9C,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,UAAM,OAAO,MAAM,aAAa,QAAQ,IAAI;AAC1C,UAAM,SAAS,MAAM,mBAAmB,QAAQ,aAAa,KAAK,IAAW;AAC7E,YAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,EAC5C,CAAC;AAEH,MACG,QAAQ,cAAc,EACtB,YAAY,0BAA0B,EACtC,OAAO,OAAO,QAAgB;AAC7B,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AAEpE,UAAM,eAAe,0BAA0B,GAAG,MAAM,OAAO;AAE/D,QAAI,SAAS,OAAO,GAAG;AACrB,YAAM,SAAS,gBAAgB,SAAS,MAAM;AAC9C;AAAA,QACE;AAAA,UACE,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,UAAU,MAAM;AAErC,UAAM,mBAAmB,QAAQ,aAAa,GAAG;AAC/C,YAAQ,IAAI,kBAAkB,GAAG,WAAW;AAAA,EAChD,CAAC;AAEH,MACG,QAAQ,MAAM,EACd,YAAY,qDAAqD,EACjE,eAAe,gBAAgB,yCAAyC,EACxE,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;AAC9C,UAAM,SAAS,SAAS,OAAO;AAE/B,UAAM,UAAU,cAAc,4BAA4B;AAC1D,QAAI,CAAC,QAAQ,KAAK,EAAE,OAAO,KAAK,QAAQ,OAAO,MAAO,SAAQ,MAAM;AAEpE,QAAI;AACF,YAAM,SAAS,MAAM,kBAAkB,QAAQ,aAAa,QAAQ,KAAK;AAAA,QACvE;AAAA,MACF,CAAC;AACD,cAAQ,KAAK,eAAe;AAC5B,UAAI,QAAQ;AACV,gBAAQ,IAAI,2BAA2B,OAAO,OAAO,aAAa,OAAO,OAAO,EAAE;AAAA,MACpF;AACA,cAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,IAC1C,SAAS,OAAO;AACd,cAAQ,KAAK,aAAa;AAC1B,YAAM;AAAA,IACR;AAAA,EACF,CAAC;AAEH,MACG,QAAQ,WAAW,EACnB,YAAY,oCAAoC,EAChD,OAAO,iBAAiB,8BAA8B,EACtD,OAAO,iBAAiB,8BAA8B,EACtD,OAAO,OAAO,aAAa;AAC1B,UAAM,OAAO;AAAA,MACX,IAAI;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,UAAU;AAAA,QACV,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF,CAAC;AAEH,MACG,QAAQ,cAAc,EACtB,YAAY,wDAAwD,EACpE,eAAe,iBAAiB,yCAAyC,EACzE,OAAO,aAAa,mCAAmC,EACvD,OAAO,OAAO,YAAY;AACzB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,cAAc,mBAAmB,QAAQ,KAAK,EAAE,KAAK,GAAG,MAAM;AACpE,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAE9C,QAAI,QAAQ,UAAU,SAAS,OAAO,GAAG;AACvC,YAAM,OAAO,MAAM,aAAa,QAAQ,IAAI;AAC5C,YAAM,WAAW,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC;AAC/C,cAAQ,IAAI,gCAAgC,SAAS,MAAM,aAAa;AACxE,UAAI,WAAW,QAAQ;AACrB,cAAM,OAAO,SAAS,IAAI,CAAC,OAAgC;AAAA,UACzD,KAAK,EAAE,KAAK,KAAK;AAAA,UACjB,QAAQ;AAAA,QACV,EAAE;AACF,gBAAQ,IAAI,aAAa,MAAM,MAAM,CAAC;AAAA,MACxC,OAAO;AACL,gBAAQ,IAAI,aAAa,UAAU,MAAM,CAAC;AAAA,MAC5C;AACA;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,UAAU,MAAM;AACrC,YAAQ,MAAM,qCAAqC;AAEnD,UAAM,UAAU,cAAc,4BAA4B;AAC1D,QAAI,CAAC,QAAQ,KAAK,EAAE,OAAO,KAAK,QAAQ,OAAO,MAAO,SAAQ,MAAM;AAEpE,QAAI;AACF,YAAM,OAAO,MAAM,aAAa,QAAQ,IAAI;AAC5C,YAAM,WAAW,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC;AAC/C,YAAM,UAAU;AAAA,QACd,UAAU,SAAS,IAAI,CAAC,OAAgC;AAAA,UACtD,cAAc;AAAA,UACd;AAAA,UACA,KAAK,EAAE,KAAK;AAAA,QACd,EAAE;AAAA,MACJ;AACA,YAAM,SAAS,MAAM,OAAO,cAAc,YAAY,aAAa,OAAc;AACjF,cAAQ,KAAK,uBAAuB;AACpC,cAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,IAC1C,SAAS,OAAO;AACd,cAAQ,KAAK,qBAAqB;AAClC,YAAM;AAAA,IACR;AAAA,EACF,CAAC;AACL;","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
isInteractive,
|
|
9
9
|
promptInput,
|
|
10
10
|
promptSelect
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-YFUBD2XB.js";
|
|
12
12
|
|
|
13
13
|
// src/commands/init.ts
|
|
14
14
|
import { initProject } from "@gpc-cli/core";
|
|
@@ -25,8 +25,9 @@ function registerInitCommand(program) {
|
|
|
25
25
|
if (ciChoice !== "none") ci = ciChoice;
|
|
26
26
|
}
|
|
27
27
|
if (ci && ci !== "github" && ci !== "gitlab") {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
const err = new Error(`Invalid --ci-template value "${ci}".`);
|
|
29
|
+
Object.assign(err, { code: "USAGE_ERROR", exitCode: 2, suggestion: "Valid values: github, gitlab" });
|
|
30
|
+
throw err;
|
|
30
31
|
}
|
|
31
32
|
const result = await initProject({
|
|
32
33
|
dir: process.cwd(),
|
|
@@ -62,4 +63,4 @@ function registerInitCommand(program) {
|
|
|
62
63
|
export {
|
|
63
64
|
registerInitCommand
|
|
64
65
|
};
|
|
65
|
-
//# sourceMappingURL=init-
|
|
66
|
+
//# sourceMappingURL=init-WSTQTJOD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/init.ts"],"sourcesContent":["// Named exports only. No default export.\n\nimport type { Command } from \"commander\";\nimport { initProject } from \"@gpc-cli/core\";\nimport { isInteractive, promptInput, promptSelect } from \"../prompt.js\";\nimport { green, dim, yellow } from \"../colors.js\";\n\nexport function registerInitCommand(program: Command): void {\n program\n .command(\"init\")\n .description(\"Scaffold project config, metadata, and CI templates\")\n .option(\"--app <package>\", \"Android package name (e.g. com.example.app)\")\n .option(\"--ci-template <platform>\", \"Generate CI template: github, gitlab\")\n .option(\"--force\", \"Overwrite existing files\")\n .action(async (options) => {\n let app = options[\"app\"] as string | undefined;\n let ci = options[\"ciTemplate\"] as \"github\" | \"gitlab\" | undefined;\n\n // Interactive prompts when TTY\n if (isInteractive(program) && !app) {\n app = await promptInput(\"Package name (e.g. com.example.app)\");\n if (!app) app = undefined;\n }\n\n if (isInteractive(program) && !ci) {\n const ciChoice = await promptSelect(\"Generate CI template?\", [\"none\", \"github\", \"gitlab\"]);\n if (ciChoice !== \"none\") ci = ciChoice as \"github\" | \"gitlab\";\n }\n\n if (ci && ci !== \"github\" && ci !== \"gitlab\") {\n const err = new Error(`Invalid --ci-template value \"${ci}\".`);\n Object.assign(err, { code: \"USAGE_ERROR\", exitCode: 2, suggestion: \"Valid values: github, gitlab\" });\n throw err;\n }\n\n const result = await initProject({\n dir: process.cwd(),\n app: app || undefined,\n ci,\n skipExisting: !options[\"force\"],\n });\n\n if (result.created.length === 0 && result.skipped.length > 0) {\n console.log(yellow(\"⚠ All files already exist. Use --force to overwrite.\"));\n for (const f of result.skipped) {\n console.log(` ${dim(\"skip\")} ${f}`);\n }\n return;\n }\n\n for (const f of result.created) {\n console.log(` ${green(\"✓\")} ${f}`);\n }\n for (const f of result.skipped) {\n console.log(` ${dim(\"skip\")} ${f}`);\n }\n\n console.log(\"\");\n console.log(\n `${green(\"✓\")} Project initialized (${result.created.length} file${result.created.length === 1 ? \"\" : \"s\"} created)`,\n );\n\n if (result.created.some((f) => f.includes(\".gpcrc.json\"))) {\n console.log(dim(\"\\nNext steps:\"));\n console.log(dim(\" 1. gpc auth login --service-account path/to/key.json\"));\n console.log(dim(\" 2. gpc doctor\"));\n console.log(dim(\" 3. gpc status\"));\n }\n });\n}\n"],"mappings":";;;;;;;;;;;;;AAGA,SAAS,mBAAmB;AAIrB,SAAS,oBAAoB,SAAwB;AAC1D,UACG,QAAQ,MAAM,EACd,YAAY,qDAAqD,EACjE,OAAO,mBAAmB,6CAA6C,EACvE,OAAO,4BAA4B,sCAAsC,EACzE,OAAO,WAAW,0BAA0B,EAC5C,OAAO,OAAO,YAAY;AACzB,QAAI,MAAM,QAAQ,KAAK;AACvB,QAAI,KAAK,QAAQ,YAAY;AAG7B,QAAI,cAAc,OAAO,KAAK,CAAC,KAAK;AAClC,YAAM,MAAM,YAAY,qCAAqC;AAC7D,UAAI,CAAC,IAAK,OAAM;AAAA,IAClB;AAEA,QAAI,cAAc,OAAO,KAAK,CAAC,IAAI;AACjC,YAAM,WAAW,MAAM,aAAa,yBAAyB,CAAC,QAAQ,UAAU,QAAQ,CAAC;AACzF,UAAI,aAAa,OAAQ,MAAK;AAAA,IAChC;AAEA,QAAI,MAAM,OAAO,YAAY,OAAO,UAAU;AAC5C,YAAM,MAAM,IAAI,MAAM,gCAAgC,EAAE,IAAI;AAC5D,aAAO,OAAO,KAAK,EAAE,MAAM,eAAe,UAAU,GAAG,YAAY,+BAA+B,CAAC;AACnG,YAAM;AAAA,IACR;AAEA,UAAM,SAAS,MAAM,YAAY;AAAA,MAC/B,KAAK,QAAQ,IAAI;AAAA,MACjB,KAAK,OAAO;AAAA,MACZ;AAAA,MACA,cAAc,CAAC,QAAQ,OAAO;AAAA,IAChC,CAAC;AAED,QAAI,OAAO,QAAQ,WAAW,KAAK,OAAO,QAAQ,SAAS,GAAG;AAC5D,cAAQ,IAAI,OAAO,2DAAsD,CAAC;AAC1E,iBAAW,KAAK,OAAO,SAAS;AAC9B,gBAAQ,IAAI,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE;AAAA,MACrC;AACA;AAAA,IACF;AAEA,eAAW,KAAK,OAAO,SAAS;AAC9B,cAAQ,IAAI,KAAK,MAAM,QAAG,CAAC,IAAI,CAAC,EAAE;AAAA,IACpC;AACA,eAAW,KAAK,OAAO,SAAS;AAC9B,cAAQ,IAAI,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE;AAAA,IACrC;AAEA,YAAQ,IAAI,EAAE;AACd,YAAQ;AAAA,MACN,GAAG,MAAM,QAAG,CAAC,yBAAyB,OAAO,QAAQ,MAAM,QAAQ,OAAO,QAAQ,WAAW,IAAI,KAAK,GAAG;AAAA,IAC3G;AAEA,QAAI,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,aAAa,CAAC,GAAG;AACzD,cAAQ,IAAI,IAAI,eAAe,CAAC;AAChC,cAAQ,IAAI,IAAI,wDAAwD,CAAC;AACzE,cAAQ,IAAI,IAAI,iBAAiB,CAAC;AAClC,cAAQ,IAAI,IAAI,iBAAiB,CAAC;AAAA,IACpC;AAAA,EACF,CAAC;AACL;","names":[]}
|
|
@@ -36,11 +36,10 @@ function registerInstallSkillsCommand(program) {
|
|
|
36
36
|
} catch (err) {
|
|
37
37
|
const exitCode = err.status ?? 1;
|
|
38
38
|
if (exitCode !== 0) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
process.exit(exitCode);
|
|
39
|
+
const error = new Error("Skills installation failed.");
|
|
40
|
+
Object.assign(error, { code: "INSTALL_FAILED", exitCode, suggestion: `Make sure npx is available and you have internet access.
|
|
41
|
+
You can also install manually: npx skills add ${repo}` });
|
|
42
|
+
throw error;
|
|
44
43
|
}
|
|
45
44
|
}
|
|
46
45
|
});
|
|
@@ -48,4 +47,4 @@ You can also install manually: npx skills add ${repo}`);
|
|
|
48
47
|
export {
|
|
49
48
|
registerInstallSkillsCommand
|
|
50
49
|
};
|
|
51
|
-
//# sourceMappingURL=install-skills-
|
|
50
|
+
//# sourceMappingURL=install-skills-6QDUXI5F.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/install-skills.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { execFileSync } from \"node:child_process\";\n\nconst GPC_SKILLS_REPO = \"yasserstudio/gpc-skills\";\n\nconst BANNER = `\n ██████╗ ██████╗ ██████╗\n██╔════╝ ██╔══██╗██╔════╝ Agent Skills Installer\n██║ ███╗██████╔╝██║ 13 skills for AI-assisted\n██║ ██║██╔═══╝ ██║ Google Play workflows\n╚██████╔╝██║ ╚██████╗\n ╚═════╝ ╚═╝ ╚═════╝\n`;\n\nexport function registerInstallSkillsCommand(program: Command): void {\n program\n .command(\"install-skills\")\n .description(\"Install GPC agent skills for AI-assisted workflows\")\n .option(\"-l, --list\", \"List available skills without installing\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"-g, --global\", \"Install skills globally (user-level)\")\n .option(\"--all\", \"Install all skills to all agents without prompts\")\n .option(\"--repo <repo>\", \"Custom skills repository\", GPC_SKILLS_REPO)\n .action((opts: Record<string, unknown>) => {\n console.log(BANNER);\n\n const repo = (opts[\"repo\"] as string) || GPC_SKILLS_REPO;\n const args = [\"skills\", \"add\", repo];\n\n if (opts[\"list\"]) {\n args.push(\"--list\");\n }\n if (opts[\"yes\"]) {\n args.push(\"--yes\");\n }\n if (opts[\"global\"]) {\n args.push(\"--global\");\n }\n if (opts[\"all\"]) {\n args.push(\"--all\");\n }\n\n try {\n execFileSync(\"npx\", args, {\n stdio: \"inherit\",\n env: { ...process.env },\n });\n } catch (err: unknown) {\n const exitCode = (err as { status?: number }).status ?? 1;\n if (exitCode !== 0) {\n
|
|
1
|
+
{"version":3,"sources":["../src/commands/install-skills.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { execFileSync } from \"node:child_process\";\n\nconst GPC_SKILLS_REPO = \"yasserstudio/gpc-skills\";\n\nconst BANNER = `\n ██████╗ ██████╗ ██████╗\n██╔════╝ ██╔══██╗██╔════╝ Agent Skills Installer\n██║ ███╗██████╔╝██║ 13 skills for AI-assisted\n██║ ██║██╔═══╝ ██║ Google Play workflows\n╚██████╔╝██║ ╚██████╗\n ╚═════╝ ╚═╝ ╚═════╝\n`;\n\nexport function registerInstallSkillsCommand(program: Command): void {\n program\n .command(\"install-skills\")\n .description(\"Install GPC agent skills for AI-assisted workflows\")\n .option(\"-l, --list\", \"List available skills without installing\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"-g, --global\", \"Install skills globally (user-level)\")\n .option(\"--all\", \"Install all skills to all agents without prompts\")\n .option(\"--repo <repo>\", \"Custom skills repository\", GPC_SKILLS_REPO)\n .action((opts: Record<string, unknown>) => {\n console.log(BANNER);\n\n const repo = (opts[\"repo\"] as string) || GPC_SKILLS_REPO;\n const args = [\"skills\", \"add\", repo];\n\n if (opts[\"list\"]) {\n args.push(\"--list\");\n }\n if (opts[\"yes\"]) {\n args.push(\"--yes\");\n }\n if (opts[\"global\"]) {\n args.push(\"--global\");\n }\n if (opts[\"all\"]) {\n args.push(\"--all\");\n }\n\n try {\n execFileSync(\"npx\", args, {\n stdio: \"inherit\",\n env: { ...process.env },\n });\n } catch (err: unknown) {\n const exitCode = (err as { status?: number }).status ?? 1;\n if (exitCode !== 0) {\n const error = new Error(\"Skills installation failed.\");\n Object.assign(error, { code: \"INSTALL_FAILED\", exitCode, suggestion: `Make sure npx is available and you have internet access.\\nYou can also install manually: npx skills add ${repo}` });\n throw error;\n }\n }\n });\n}\n"],"mappings":";;;AACA,SAAS,oBAAoB;AAE7B,IAAM,kBAAkB;AAExB,IAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASR,SAAS,6BAA6B,SAAwB;AACnE,UACG,QAAQ,gBAAgB,EACxB,YAAY,oDAAoD,EAChE,OAAO,cAAc,0CAA0C,EAC/D,OAAO,aAAa,2BAA2B,EAC/C,OAAO,gBAAgB,sCAAsC,EAC7D,OAAO,SAAS,kDAAkD,EAClE,OAAO,iBAAiB,4BAA4B,eAAe,EACnE,OAAO,CAAC,SAAkC;AACzC,YAAQ,IAAI,MAAM;AAElB,UAAM,OAAQ,KAAK,MAAM,KAAgB;AACzC,UAAM,OAAO,CAAC,UAAU,OAAO,IAAI;AAEnC,QAAI,KAAK,MAAM,GAAG;AAChB,WAAK,KAAK,QAAQ;AAAA,IACpB;AACA,QAAI,KAAK,KAAK,GAAG;AACf,WAAK,KAAK,OAAO;AAAA,IACnB;AACA,QAAI,KAAK,QAAQ,GAAG;AAClB,WAAK,KAAK,UAAU;AAAA,IACtB;AACA,QAAI,KAAK,KAAK,GAAG;AACf,WAAK,KAAK,OAAO;AAAA,IACnB;AAEA,QAAI;AACF,mBAAa,OAAO,MAAM;AAAA,QACxB,OAAO;AAAA,QACP,KAAK,EAAE,GAAG,QAAQ,IAAI;AAAA,MACxB,CAAC;AAAA,IACH,SAAS,KAAc;AACrB,YAAM,WAAY,IAA4B,UAAU;AACxD,UAAI,aAAa,GAAG;AAClB,cAAM,QAAQ,IAAI,MAAM,6BAA6B;AACrD,eAAO,OAAO,OAAO,EAAE,MAAM,kBAAkB,UAAU,YAAY;AAAA,gDAA2G,IAAI,GAAG,CAAC;AACxL,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF,CAAC;AACL;","names":[]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
getClient,
|
|
4
4
|
resolvePackageName
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-NQH4G7BI.js";
|
|
6
6
|
import {
|
|
7
7
|
isDryRun,
|
|
8
8
|
printDryRun
|
|
@@ -42,12 +42,11 @@ function registerInternalSharingCommands(program) {
|
|
|
42
42
|
console.log(formatOutput(result, format));
|
|
43
43
|
} catch (error) {
|
|
44
44
|
spinner.fail("Upload failed");
|
|
45
|
-
|
|
46
|
-
process.exit(4);
|
|
45
|
+
throw error;
|
|
47
46
|
}
|
|
48
47
|
});
|
|
49
48
|
}
|
|
50
49
|
export {
|
|
51
50
|
registerInternalSharingCommands
|
|
52
51
|
};
|
|
53
|
-
//# sourceMappingURL=internal-sharing-
|
|
52
|
+
//# sourceMappingURL=internal-sharing-ONNIWIAT.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/internal-sharing.ts"],"sourcesContent":["import { resolvePackageName, getClient } from \"../resolve.js\";\nimport type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\n\nimport { uploadInternalSharing, formatOutput, createSpinner } from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\n\n\n\nexport function registerInternalSharingCommands(program: Command): void {\n const cmd = program\n .command(\"internal-sharing\")\n .description(\"Upload bundles or APKs for instant internal 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 format = getOutputFormat(program, config);\n\n const fileType = opts.type as \"bundle\" | \"apk\" | undefined;\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"internal-sharing upload\",\n action: \"upload for internal sharing\",\n target: file,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\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
|
|
1
|
+
{"version":3,"sources":["../src/commands/internal-sharing.ts"],"sourcesContent":["import { resolvePackageName, getClient } from \"../resolve.js\";\nimport type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\n\nimport { uploadInternalSharing, formatOutput, createSpinner } from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun, printDryRun } from \"../dry-run.js\";\n\n\n\nexport function registerInternalSharingCommands(program: Command): void {\n const cmd = program\n .command(\"internal-sharing\")\n .description(\"Upload bundles or APKs for instant internal 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 format = getOutputFormat(program, config);\n\n const fileType = opts.type as \"bundle\" | \"apk\" | undefined;\n\n if (isDryRun(program)) {\n printDryRun(\n {\n command: \"internal-sharing upload\",\n action: \"upload for internal sharing\",\n target: file,\n },\n format,\n formatOutput,\n );\n return;\n }\n\n const client = await getClient(config);\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 throw error;\n }\n });\n}\n"],"mappings":";;;;;;;;;;;;;;AAEA,SAAS,kBAAkB;AAE3B,SAAS,uBAAuB,cAAc,qBAAqB;AAM5D,SAAS,gCAAgC,SAAwB;AACtE,QAAM,MAAM,QACT,QAAQ,kBAAkB,EAC1B,YAAY,qDAAqD;AAEpE,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,gBAAgB,SAAS,MAAM;AAE9C,UAAM,WAAW,KAAK;AAEtB,QAAI,SAAS,OAAO,GAAG;AACrB;AAAA,QACE;AAAA,UACE,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,UAAU,MAAM;AACrC,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,YAAM;AAAA,IACR;AAAA,EACF,CAAC;AACL;","names":[]}
|