@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,204 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getOutputFormat
|
|
4
|
+
} from "./chunk-ELXAK7GI.js";
|
|
5
|
+
|
|
6
|
+
// src/commands/bundle.ts
|
|
7
|
+
import {
|
|
8
|
+
analyzeBundle,
|
|
9
|
+
compareBundles,
|
|
10
|
+
topFiles,
|
|
11
|
+
checkBundleSize,
|
|
12
|
+
formatOutput
|
|
13
|
+
} from "@gpc-cli/core";
|
|
14
|
+
function formatSize(bytes) {
|
|
15
|
+
const abs = Math.abs(bytes);
|
|
16
|
+
const sign = bytes < 0 ? "-" : "";
|
|
17
|
+
if (abs < 1024) return `${sign}${abs} B`;
|
|
18
|
+
if (abs < 1024 * 1024) return `${sign}${(abs / 1024).toFixed(1)} KB`;
|
|
19
|
+
return `${sign}${(abs / (1024 * 1024)).toFixed(2)} MB`;
|
|
20
|
+
}
|
|
21
|
+
function formatDelta(delta) {
|
|
22
|
+
const prefix = delta > 0 ? "+" : "";
|
|
23
|
+
return `${prefix}${formatSize(delta)}`;
|
|
24
|
+
}
|
|
25
|
+
function registerBundleCommands(program) {
|
|
26
|
+
const bundle = program.command("bundle").description("Analyze app bundles and APKs");
|
|
27
|
+
bundle.command("analyze <file>").description("Analyze size breakdown of an AAB or APK").option("--threshold <mb>", "Fail if compressed size exceeds threshold (MB)", parseFloat).option("--top <n>", "Show top N largest files", (v) => parseInt(v, 10)).option("--config <file>", "Check against .bundlesize.json thresholds").action(async (file, opts) => {
|
|
28
|
+
const format = getOutputFormat(program, await getConfig());
|
|
29
|
+
const analysis = await analyzeBundle(file);
|
|
30
|
+
if (format === "json") {
|
|
31
|
+
console.log(formatOutput(analysis, format));
|
|
32
|
+
} else if (format === "markdown") {
|
|
33
|
+
const moduleRows = analysis.modules.map((m) => ({
|
|
34
|
+
module: m.name,
|
|
35
|
+
compressed: formatSize(m.compressedSize),
|
|
36
|
+
uncompressed: formatSize(m.uncompressedSize),
|
|
37
|
+
entries: m.entries
|
|
38
|
+
}));
|
|
39
|
+
const categoryRows = analysis.categories.map((c) => ({
|
|
40
|
+
category: c.name,
|
|
41
|
+
compressed: formatSize(c.compressedSize),
|
|
42
|
+
uncompressed: formatSize(c.uncompressedSize),
|
|
43
|
+
entries: c.entries
|
|
44
|
+
}));
|
|
45
|
+
console.log(`## Bundle Analysis: \`${analysis.filePath}\``);
|
|
46
|
+
console.log();
|
|
47
|
+
console.log(`| Property | Value |`);
|
|
48
|
+
console.log(`| --- | --- |`);
|
|
49
|
+
console.log(`| Type | ${analysis.fileType.toUpperCase()} |`);
|
|
50
|
+
console.log(`| Total compressed | ${formatSize(analysis.totalCompressed)} |`);
|
|
51
|
+
console.log(`| Total uncompressed | ${formatSize(analysis.totalUncompressed)} |`);
|
|
52
|
+
console.log(`| Entries | ${analysis.entryCount} |`);
|
|
53
|
+
console.log();
|
|
54
|
+
console.log(`### Modules`);
|
|
55
|
+
console.log();
|
|
56
|
+
console.log(formatOutput(moduleRows, "markdown"));
|
|
57
|
+
console.log();
|
|
58
|
+
console.log(`### Categories`);
|
|
59
|
+
console.log();
|
|
60
|
+
console.log(formatOutput(categoryRows, "markdown"));
|
|
61
|
+
} else {
|
|
62
|
+
console.log(`
|
|
63
|
+
File: ${analysis.filePath}`);
|
|
64
|
+
console.log(`Type: ${analysis.fileType.toUpperCase()}`);
|
|
65
|
+
console.log(`Total compressed: ${formatSize(analysis.totalCompressed)}`);
|
|
66
|
+
console.log(`Total uncompressed: ${formatSize(analysis.totalUncompressed)}`);
|
|
67
|
+
console.log(`Entries: ${analysis.entryCount}
|
|
68
|
+
`);
|
|
69
|
+
const moduleRows = analysis.modules.map((m) => ({
|
|
70
|
+
module: m.name,
|
|
71
|
+
compressed: formatSize(m.compressedSize),
|
|
72
|
+
uncompressed: formatSize(m.uncompressedSize),
|
|
73
|
+
entries: m.entries
|
|
74
|
+
}));
|
|
75
|
+
console.log("Modules:");
|
|
76
|
+
console.log(formatOutput(moduleRows, "table"));
|
|
77
|
+
const categoryRows = analysis.categories.map((c) => ({
|
|
78
|
+
category: c.name,
|
|
79
|
+
compressed: formatSize(c.compressedSize),
|
|
80
|
+
uncompressed: formatSize(c.uncompressedSize),
|
|
81
|
+
entries: c.entries
|
|
82
|
+
}));
|
|
83
|
+
console.log("\nCategories:");
|
|
84
|
+
console.log(formatOutput(categoryRows, "table"));
|
|
85
|
+
}
|
|
86
|
+
if (opts.top !== void 0) {
|
|
87
|
+
const largest = topFiles(analysis, opts.top);
|
|
88
|
+
const topRows = largest.map((e) => ({
|
|
89
|
+
path: e.path,
|
|
90
|
+
compressed: formatSize(e.compressedSize),
|
|
91
|
+
uncompressed: formatSize(e.uncompressedSize),
|
|
92
|
+
category: e.category
|
|
93
|
+
}));
|
|
94
|
+
console.log(`
|
|
95
|
+
Top ${opts.top} files:`);
|
|
96
|
+
console.log(formatOutput(topRows, format === "json" ? "table" : format));
|
|
97
|
+
}
|
|
98
|
+
if (opts.config) {
|
|
99
|
+
const check = await checkBundleSize(analysis, opts.config);
|
|
100
|
+
if (!check.passed) {
|
|
101
|
+
const violations = check.violations.map((v) => `${v.subject}: ${formatSize(v.actual)} > max ${formatSize(v.max)}`).join("; ");
|
|
102
|
+
const err = new Error(`Bundle size check failed: ${violations}`);
|
|
103
|
+
Object.assign(err, { code: "THRESHOLD_BREACH", exitCode: 6 });
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (opts.threshold !== void 0) {
|
|
108
|
+
const thresholdBytes = opts.threshold * 1024 * 1024;
|
|
109
|
+
if (analysis.totalCompressed > thresholdBytes) {
|
|
110
|
+
const err = new Error(`Threshold breached: ${formatSize(analysis.totalCompressed)} > ${opts.threshold} MB`);
|
|
111
|
+
Object.assign(err, { code: "THRESHOLD_BREACH", exitCode: 6 });
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
bundle.command("compare <file1> <file2>").description("Compare size differences between two bundles or APKs").action(async (file1, file2) => {
|
|
117
|
+
const format = getOutputFormat(program, await getConfig());
|
|
118
|
+
const [before, after] = await Promise.all([analyzeBundle(file1), analyzeBundle(file2)]);
|
|
119
|
+
const comparison = compareBundles(before, after);
|
|
120
|
+
if (format === "json") {
|
|
121
|
+
console.log(formatOutput(comparison, format));
|
|
122
|
+
} else if (format === "markdown") {
|
|
123
|
+
const sign = comparison.sizeDelta >= 0 ? "+" : "";
|
|
124
|
+
const moduleRows = comparison.moduleDeltas.filter((m) => m.delta !== 0).map((m) => ({
|
|
125
|
+
module: m.module,
|
|
126
|
+
before: formatSize(m.before),
|
|
127
|
+
after: formatSize(m.after),
|
|
128
|
+
delta: formatDelta(m.delta)
|
|
129
|
+
}));
|
|
130
|
+
const categoryRows = comparison.categoryDeltas.filter((c) => c.delta !== 0).map((c) => ({
|
|
131
|
+
category: c.category,
|
|
132
|
+
before: formatSize(c.before),
|
|
133
|
+
after: formatSize(c.after),
|
|
134
|
+
delta: formatDelta(c.delta)
|
|
135
|
+
}));
|
|
136
|
+
console.log(`## Bundle Comparison`);
|
|
137
|
+
console.log();
|
|
138
|
+
console.log(`| | Path | Size |`);
|
|
139
|
+
console.log(`| --- | --- | --- |`);
|
|
140
|
+
console.log(
|
|
141
|
+
`| Before | \`${comparison.before.path}\` | ${formatSize(comparison.before.totalCompressed)} |`
|
|
142
|
+
);
|
|
143
|
+
console.log(
|
|
144
|
+
`| After | \`${comparison.after.path}\` | ${formatSize(comparison.after.totalCompressed)} |`
|
|
145
|
+
);
|
|
146
|
+
console.log(
|
|
147
|
+
`| **Delta** | | **${sign}${formatSize(comparison.sizeDelta)} (${sign}${comparison.sizeDeltaPercent}%)** |`
|
|
148
|
+
);
|
|
149
|
+
if (moduleRows.length > 0) {
|
|
150
|
+
console.log();
|
|
151
|
+
console.log(`### Module Changes`);
|
|
152
|
+
console.log();
|
|
153
|
+
console.log(formatOutput(moduleRows, "markdown"));
|
|
154
|
+
}
|
|
155
|
+
if (categoryRows.length > 0) {
|
|
156
|
+
console.log();
|
|
157
|
+
console.log(`### Category Changes`);
|
|
158
|
+
console.log();
|
|
159
|
+
console.log(formatOutput(categoryRows, "markdown"));
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
const sign = comparison.sizeDelta >= 0 ? "+" : "";
|
|
163
|
+
console.log(
|
|
164
|
+
`
|
|
165
|
+
Before: ${comparison.before.path} (${formatSize(comparison.before.totalCompressed)})`
|
|
166
|
+
);
|
|
167
|
+
console.log(
|
|
168
|
+
`After: ${comparison.after.path} (${formatSize(comparison.after.totalCompressed)})`
|
|
169
|
+
);
|
|
170
|
+
console.log(
|
|
171
|
+
`Delta: ${sign}${formatSize(comparison.sizeDelta)} (${sign}${comparison.sizeDeltaPercent}%)
|
|
172
|
+
`
|
|
173
|
+
);
|
|
174
|
+
const moduleRows = comparison.moduleDeltas.filter((m) => m.delta !== 0).map((m) => ({
|
|
175
|
+
module: m.module,
|
|
176
|
+
before: formatSize(m.before),
|
|
177
|
+
after: formatSize(m.after),
|
|
178
|
+
delta: formatDelta(m.delta)
|
|
179
|
+
}));
|
|
180
|
+
if (moduleRows.length > 0) {
|
|
181
|
+
console.log("Module changes:");
|
|
182
|
+
console.log(formatOutput(moduleRows, "table"));
|
|
183
|
+
}
|
|
184
|
+
const categoryRows = comparison.categoryDeltas.filter((c) => c.delta !== 0).map((c) => ({
|
|
185
|
+
category: c.category,
|
|
186
|
+
before: formatSize(c.before),
|
|
187
|
+
after: formatSize(c.after),
|
|
188
|
+
delta: formatDelta(c.delta)
|
|
189
|
+
}));
|
|
190
|
+
if (categoryRows.length > 0) {
|
|
191
|
+
console.log("\nCategory changes:");
|
|
192
|
+
console.log(formatOutput(categoryRows, "table"));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
async function getConfig() {
|
|
198
|
+
const { loadConfig } = await import("@gpc-cli/config");
|
|
199
|
+
return loadConfig();
|
|
200
|
+
}
|
|
201
|
+
export {
|
|
202
|
+
registerBundleCommands
|
|
203
|
+
};
|
|
204
|
+
//# sourceMappingURL=bundle-F7MUVC5J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/bundle.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport {\n analyzeBundle,\n compareBundles,\n topFiles,\n checkBundleSize,\n formatOutput,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\n\nfunction formatSize(bytes: number): string {\n const abs = Math.abs(bytes);\n const sign = bytes < 0 ? \"-\" : \"\";\n if (abs < 1024) return `${sign}${abs} B`;\n if (abs < 1024 * 1024) return `${sign}${(abs / 1024).toFixed(1)} KB`;\n return `${sign}${(abs / (1024 * 1024)).toFixed(2)} MB`;\n}\n\nfunction formatDelta(delta: number): string {\n const prefix = delta > 0 ? \"+\" : \"\";\n return `${prefix}${formatSize(delta)}`;\n}\n\nexport function registerBundleCommands(program: Command): void {\n const bundle = program.command(\"bundle\").description(\"Analyze app bundles and APKs\");\n\n bundle\n .command(\"analyze <file>\")\n .description(\"Analyze size breakdown of an AAB or APK\")\n .option(\"--threshold <mb>\", \"Fail if compressed size exceeds threshold (MB)\", parseFloat)\n .option(\"--top <n>\", \"Show top N largest files\", (v) => parseInt(v, 10))\n .option(\"--config <file>\", \"Check against .bundlesize.json thresholds\")\n .action(async (file: string, opts: { threshold?: number; top?: number; config?: string }) => {\n const format = getOutputFormat(program, await getConfig());\n\n const analysis = await analyzeBundle(file);\n\n if (format === \"json\") {\n console.log(formatOutput(analysis, format));\n } else if (format === \"markdown\") {\n const moduleRows = analysis.modules.map((m) => ({\n module: m.name,\n compressed: formatSize(m.compressedSize),\n uncompressed: formatSize(m.uncompressedSize),\n entries: m.entries,\n }));\n const categoryRows = analysis.categories.map((c) => ({\n category: c.name,\n compressed: formatSize(c.compressedSize),\n uncompressed: formatSize(c.uncompressedSize),\n entries: c.entries,\n }));\n console.log(`## Bundle Analysis: \\`${analysis.filePath}\\``);\n console.log();\n console.log(`| Property | Value |`);\n console.log(`| --- | --- |`);\n console.log(`| Type | ${analysis.fileType.toUpperCase()} |`);\n console.log(`| Total compressed | ${formatSize(analysis.totalCompressed)} |`);\n console.log(`| Total uncompressed | ${formatSize(analysis.totalUncompressed)} |`);\n console.log(`| Entries | ${analysis.entryCount} |`);\n console.log();\n console.log(`### Modules`);\n console.log();\n console.log(formatOutput(moduleRows, \"markdown\"));\n console.log();\n console.log(`### Categories`);\n console.log();\n console.log(formatOutput(categoryRows, \"markdown\"));\n } else {\n console.log(`\\nFile: ${analysis.filePath}`);\n console.log(`Type: ${analysis.fileType.toUpperCase()}`);\n console.log(`Total compressed: ${formatSize(analysis.totalCompressed)}`);\n console.log(`Total uncompressed: ${formatSize(analysis.totalUncompressed)}`);\n console.log(`Entries: ${analysis.entryCount}\\n`);\n\n // Modules table\n const moduleRows = analysis.modules.map((m) => ({\n module: m.name,\n compressed: formatSize(m.compressedSize),\n uncompressed: formatSize(m.uncompressedSize),\n entries: m.entries,\n }));\n console.log(\"Modules:\");\n console.log(formatOutput(moduleRows, \"table\"));\n\n // Categories table\n const categoryRows = analysis.categories.map((c) => ({\n category: c.name,\n compressed: formatSize(c.compressedSize),\n uncompressed: formatSize(c.uncompressedSize),\n entries: c.entries,\n }));\n console.log(\"\\nCategories:\");\n console.log(formatOutput(categoryRows, \"table\"));\n }\n\n // Top N files\n if (opts.top !== undefined) {\n const largest = topFiles(analysis, opts.top);\n const topRows = largest.map((e) => ({\n path: e.path,\n compressed: formatSize(e.compressedSize),\n uncompressed: formatSize(e.uncompressedSize),\n category: e.category,\n }));\n console.log(`\\nTop ${opts.top} files:`);\n console.log(formatOutput(topRows, format === \"json\" ? \"table\" : format));\n }\n\n // .bundlesize.json config check\n if (opts.config) {\n const check = await checkBundleSize(analysis, opts.config);\n if (!check.passed) {\n const violations = check.violations.map((v) => `${v.subject}: ${formatSize(v.actual)} > max ${formatSize(v.max)}`).join(\"; \");\n const err = new Error(`Bundle size check failed: ${violations}`);\n Object.assign(err, { code: \"THRESHOLD_BREACH\", exitCode: 6 });\n throw err;\n }\n }\n\n // Legacy --threshold check\n if (opts.threshold !== undefined) {\n const thresholdBytes = opts.threshold * 1024 * 1024;\n if (analysis.totalCompressed > thresholdBytes) {\n const err = new Error(`Threshold breached: ${formatSize(analysis.totalCompressed)} > ${opts.threshold} MB`);\n Object.assign(err, { code: \"THRESHOLD_BREACH\", exitCode: 6 });\n throw err;\n }\n }\n });\n\n bundle\n .command(\"compare <file1> <file2>\")\n .description(\"Compare size differences between two bundles or APKs\")\n .action(async (file1: string, file2: string) => {\n const format = getOutputFormat(program, await getConfig());\n\n const [before, after] = await Promise.all([analyzeBundle(file1), analyzeBundle(file2)]);\n const comparison = compareBundles(before, after);\n\n if (format === \"json\") {\n console.log(formatOutput(comparison, format));\n } else if (format === \"markdown\") {\n const sign = comparison.sizeDelta >= 0 ? \"+\" : \"\";\n const moduleRows = comparison.moduleDeltas\n .filter((m) => m.delta !== 0)\n .map((m) => ({\n module: m.module,\n before: formatSize(m.before),\n after: formatSize(m.after),\n delta: formatDelta(m.delta),\n }));\n const categoryRows = comparison.categoryDeltas\n .filter((c) => c.delta !== 0)\n .map((c) => ({\n category: c.category,\n before: formatSize(c.before),\n after: formatSize(c.after),\n delta: formatDelta(c.delta),\n }));\n console.log(`## Bundle Comparison`);\n console.log();\n console.log(`| | Path | Size |`);\n console.log(`| --- | --- | --- |`);\n console.log(\n `| Before | \\`${comparison.before.path}\\` | ${formatSize(comparison.before.totalCompressed)} |`,\n );\n console.log(\n `| After | \\`${comparison.after.path}\\` | ${formatSize(comparison.after.totalCompressed)} |`,\n );\n console.log(\n `| **Delta** | | **${sign}${formatSize(comparison.sizeDelta)} (${sign}${comparison.sizeDeltaPercent}%)** |`,\n );\n if (moduleRows.length > 0) {\n console.log();\n console.log(`### Module Changes`);\n console.log();\n console.log(formatOutput(moduleRows, \"markdown\"));\n }\n if (categoryRows.length > 0) {\n console.log();\n console.log(`### Category Changes`);\n console.log();\n console.log(formatOutput(categoryRows, \"markdown\"));\n }\n } else {\n const sign = comparison.sizeDelta >= 0 ? \"+\" : \"\";\n console.log(\n `\\nBefore: ${comparison.before.path} (${formatSize(comparison.before.totalCompressed)})`,\n );\n console.log(\n `After: ${comparison.after.path} (${formatSize(comparison.after.totalCompressed)})`,\n );\n console.log(\n `Delta: ${sign}${formatSize(comparison.sizeDelta)} (${sign}${comparison.sizeDeltaPercent}%)\\n`,\n );\n\n // Module deltas\n const moduleRows = comparison.moduleDeltas\n .filter((m) => m.delta !== 0)\n .map((m) => ({\n module: m.module,\n before: formatSize(m.before),\n after: formatSize(m.after),\n delta: formatDelta(m.delta),\n }));\n if (moduleRows.length > 0) {\n console.log(\"Module changes:\");\n console.log(formatOutput(moduleRows, \"table\"));\n }\n\n // Category deltas\n const categoryRows = comparison.categoryDeltas\n .filter((c) => c.delta !== 0)\n .map((c) => ({\n category: c.category,\n before: formatSize(c.before),\n after: formatSize(c.after),\n delta: formatDelta(c.delta),\n }));\n if (categoryRows.length > 0) {\n console.log(\"\\nCategory changes:\");\n console.log(formatOutput(categoryRows, \"table\"));\n }\n }\n });\n}\n\nasync function getConfig() {\n const { loadConfig } = await import(\"@gpc-cli/config\");\n return loadConfig();\n}\n"],"mappings":"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","names":[]}
|
|
@@ -74,10 +74,9 @@ function registerCacheCommand(program) {
|
|
|
74
74
|
if (opts.type) {
|
|
75
75
|
const matcher = FILE_TYPES[opts.type];
|
|
76
76
|
if (!matcher) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
process.exit(2);
|
|
77
|
+
const err = new Error(`Unknown cache type "${opts.type}".`);
|
|
78
|
+
Object.assign(err, { code: "USAGE_ERROR", exitCode: 2, suggestion: `Valid types: ${Object.keys(FILE_TYPES).join(", ")}` });
|
|
79
|
+
throw err;
|
|
81
80
|
}
|
|
82
81
|
toDelete = allFiles.filter((f) => matcher(f.name));
|
|
83
82
|
}
|
|
@@ -115,4 +114,4 @@ function registerCacheCommand(program) {
|
|
|
115
114
|
export {
|
|
116
115
|
registerCacheCommand
|
|
117
116
|
};
|
|
118
|
-
//# sourceMappingURL=cache-
|
|
117
|
+
//# sourceMappingURL=cache-XKPLZYEB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/cache.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { readdir, stat, unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { getCacheDir } from \"@gpc-cli/config\";\n\nconst FILE_TYPES: Record<string, (name: string) => boolean> = {\n status: (name) => name.startsWith(\"status-\") && name.endsWith(\".json\"),\n token: (name) => name === \"token-cache.json\",\n update: (name) => name === \"update-check.json\",\n};\n\nasync function getCacheFiles(\n cacheDir: string,\n): Promise<{ name: string; path: string; size: number; mtime: Date }[]> {\n let entries: string[];\n try {\n entries = await readdir(cacheDir);\n } catch {\n return [];\n }\n\n const files: { name: string; path: string; size: number; mtime: Date }[] = [];\n for (const entry of entries) {\n if (!entry.endsWith(\".json\")) continue;\n const filePath = join(cacheDir, entry);\n try {\n const info = await stat(filePath);\n if (info.isFile()) {\n files.push({ name: entry, path: filePath, size: info.size, mtime: info.mtime });\n }\n } catch {\n /* ignore */\n }\n }\n return files;\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction fileType(name: string): string {\n for (const [type, matcher] of Object.entries(FILE_TYPES)) {\n if (matcher(name)) return type;\n }\n return \"other\";\n}\n\nexport function registerCacheCommand(program: Command): void {\n const cache = program.command(\"cache\").description(\"Manage local cache files\");\n\n cache\n .command(\"info\")\n .description(\"Show cache directory and total size\")\n .action(async () => {\n const cacheDir = getCacheDir();\n const files = await getCacheFiles(cacheDir);\n const totalSize = files.reduce((sum, f) => sum + f.size, 0);\n console.log(`Cache directory: ${cacheDir}`);\n console.log(`Files: ${files.length}`);\n console.log(`Total size: ${formatBytes(totalSize)}`);\n });\n\n cache\n .command(\"list\")\n .description(\"List all cache files with size and age\")\n .action(async () => {\n const cacheDir = getCacheDir();\n const files = await getCacheFiles(cacheDir);\n if (files.length === 0) {\n console.log(\"No cache files found.\");\n return;\n }\n const now = Date.now();\n for (const f of files) {\n const ageMs = now - f.mtime.getTime();\n const ageMins = Math.floor(ageMs / 60000);\n const ageStr =\n ageMins < 60\n ? `${ageMins}m ago`\n : ageMins < 1440\n ? `${Math.floor(ageMins / 60)}h ago`\n : `${Math.floor(ageMins / 1440)}d ago`;\n const type = fileType(f.name);\n console.log(` ${f.name} [${type}] ${formatBytes(f.size)} ${ageStr}`);\n }\n });\n\n cache\n .command(\"clear\")\n .description(\"Remove cache files\")\n .option(\"--force\", \"Skip confirmation prompt\")\n .option(\"--type <type>\", \"Remove only files of this type (status|token|update)\")\n .action(async (opts) => {\n const cacheDir = getCacheDir();\n const allFiles = await getCacheFiles(cacheDir);\n\n let toDelete = allFiles;\n if (opts.type) {\n const matcher = FILE_TYPES[opts.type];\n if (!matcher) {\n const err = new Error(`Unknown cache type \"${opts.type}\".`);\n Object.assign(err, { code: \"USAGE_ERROR\", exitCode: 2, suggestion: `Valid types: ${Object.keys(FILE_TYPES).join(\", \")}` });\n throw err;\n }\n toDelete = allFiles.filter((f) => matcher(f.name));\n }\n\n if (toDelete.length === 0) {\n console.log(\"No cache files to remove.\");\n return;\n }\n\n if (!opts.force) {\n console.log(`About to remove ${toDelete.length} file(s) from ${cacheDir}:`);\n for (const f of toDelete) {\n console.log(` ${f.name} (${formatBytes(f.size)})`);\n }\n const { createInterface } = await import(\"node:readline\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((resolve) =>\n rl.question(\"Proceed? [y/N] \", resolve),\n );\n rl.close();\n if (answer.toLowerCase() !== \"y\") {\n console.log(\"Aborted.\");\n return;\n }\n }\n\n let removed = 0;\n for (const f of toDelete) {\n try {\n await unlink(f.path);\n removed++;\n } catch {\n /* ignore */\n }\n }\n console.log(`Removed ${removed} file(s).`);\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getOutputFormat
|
|
4
|
+
} from "./chunk-ELXAK7GI.js";
|
|
5
|
+
|
|
6
|
+
// src/commands/changelog.ts
|
|
7
|
+
import { fetchChangelog, formatChangelogEntry } from "@gpc-cli/core";
|
|
8
|
+
import { formatOutput } from "@gpc-cli/core";
|
|
9
|
+
import { loadConfig } from "@gpc-cli/config";
|
|
10
|
+
function registerChangelogCommand(program) {
|
|
11
|
+
program.command("changelog").description("Show release history").option("-n, --limit <count>", "Number of releases to show", parseInt, 5).option("--version <tag>", "Show a specific version (e.g., v0.9.43)").option("--all", "Show all releases").action(async (opts) => {
|
|
12
|
+
const config = await loadConfig();
|
|
13
|
+
const format = getOutputFormat(program, config);
|
|
14
|
+
const entries = await fetchChangelog({
|
|
15
|
+
limit: opts.all ? 100 : opts.limit,
|
|
16
|
+
version: opts.version
|
|
17
|
+
});
|
|
18
|
+
if (entries.length === 0) {
|
|
19
|
+
console.log("No releases found.");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (format === "json") {
|
|
23
|
+
console.log(formatOutput(entries, "json"));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (opts.version || entries.length === 1) {
|
|
27
|
+
console.log(formatChangelogEntry(entries[0]));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const header = "VERSION DATE TITLE";
|
|
31
|
+
const separator = "\u2500".repeat(header.length);
|
|
32
|
+
console.log(header);
|
|
33
|
+
console.log(separator);
|
|
34
|
+
for (const entry of entries) {
|
|
35
|
+
const version = entry.version.padEnd(12);
|
|
36
|
+
const date = entry.date.padEnd(12);
|
|
37
|
+
console.log(`${version} ${date} ${entry.title}`);
|
|
38
|
+
}
|
|
39
|
+
console.log("");
|
|
40
|
+
console.log(
|
|
41
|
+
`Showing ${entries.length} releases. Use --version <tag> for details, or --all for full history.`
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
registerChangelogCommand
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=changelog-7COFZO7Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/changelog.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { fetchChangelog, formatChangelogEntry } from \"@gpc-cli/core\";\nimport { formatOutput } from \"@gpc-cli/core\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { getOutputFormat } from \"../format.js\";\n\nexport function registerChangelogCommand(program: Command): void {\n program\n .command(\"changelog\")\n .description(\"Show release history\")\n .option(\"-n, --limit <count>\", \"Number of releases to show\", parseInt, 5)\n .option(\"--version <tag>\", \"Show a specific version (e.g., v0.9.43)\")\n .option(\"--all\", \"Show all releases\")\n .action(async (opts: { limit: number; version?: string; all?: boolean }) => {\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n\n const entries = await fetchChangelog({\n limit: opts.all ? 100 : opts.limit,\n version: opts.version,\n });\n\n if (entries.length === 0) {\n console.log(\"No releases found.\");\n return;\n }\n\n if (format === \"json\") {\n console.log(formatOutput(entries, \"json\"));\n return;\n }\n\n // Single version — show full details\n if (opts.version || entries.length === 1) {\n console.log(formatChangelogEntry(entries[0]!));\n return;\n }\n\n // Multiple versions — table summary\n const header = \"VERSION DATE TITLE\";\n const separator = \"─\".repeat(header.length);\n console.log(header);\n console.log(separator);\n for (const entry of entries) {\n const version = entry.version.padEnd(12);\n const date = entry.date.padEnd(12);\n console.log(`${version} ${date} ${entry.title}`);\n }\n console.log(\"\");\n console.log(\n `Showing ${entries.length} releases. Use --version <tag> for details, or --all for full history.`,\n );\n });\n}\n"],"mappings":";;;;;;AACA,SAAS,gBAAgB,4BAA4B;AACrD,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAGpB,SAAS,yBAAyB,SAAwB;AAC/D,UACG,QAAQ,WAAW,EACnB,YAAY,sBAAsB,EAClC,OAAO,uBAAuB,8BAA8B,UAAU,CAAC,EACvE,OAAO,mBAAmB,yCAAyC,EACnE,OAAO,SAAS,mBAAmB,EACnC,OAAO,OAAO,SAA6D;AAC1E,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAE9C,UAAM,UAAU,MAAM,eAAe;AAAA,MACnC,OAAO,KAAK,MAAM,MAAM,KAAK;AAAA,MAC7B,SAAS,KAAK;AAAA,IAChB,CAAC;AAED,QAAI,QAAQ,WAAW,GAAG;AACxB,cAAQ,IAAI,oBAAoB;AAChC;AAAA,IACF;AAEA,QAAI,WAAW,QAAQ;AACrB,cAAQ,IAAI,aAAa,SAAS,MAAM,CAAC;AACzC;AAAA,IACF;AAGA,QAAI,KAAK,WAAW,QAAQ,WAAW,GAAG;AACxC,cAAQ,IAAI,qBAAqB,QAAQ,CAAC,CAAE,CAAC;AAC7C;AAAA,IACF;AAGA,UAAM,SAAS;AACf,UAAM,YAAY,SAAI,OAAO,OAAO,MAAM;AAC1C,YAAQ,IAAI,MAAM;AAClB,YAAQ,IAAI,SAAS;AACrB,eAAW,SAAS,SAAS;AAC3B,YAAM,UAAU,MAAM,QAAQ,OAAO,EAAE;AACvC,YAAM,OAAO,MAAM,KAAK,OAAO,EAAE;AACjC,cAAQ,IAAI,GAAG,OAAO,IAAI,IAAI,IAAI,MAAM,KAAK,EAAE;AAAA,IACjD;AACA,YAAQ,IAAI,EAAE;AACd,YAAQ;AAAA,MACN,WAAW,QAAQ,MAAM;AAAA,IAC3B;AAAA,EACF,CAAC;AACL;","names":[]}
|
|
@@ -41,10 +41,9 @@ function writeCache(data) {
|
|
|
41
41
|
}
|
|
42
42
|
async function fetchLatestVersion() {
|
|
43
43
|
try {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
clearTimeout(timeout);
|
|
44
|
+
const response = await fetch(REGISTRY_URL, {
|
|
45
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
|
|
46
|
+
});
|
|
48
47
|
if (!response.ok) return null;
|
|
49
48
|
const body = await response.json();
|
|
50
49
|
if (typeof body.version !== "string") return null;
|
|
@@ -83,4 +82,4 @@ export {
|
|
|
83
82
|
checkForUpdate,
|
|
84
83
|
formatUpdateNotification
|
|
85
84
|
};
|
|
86
|
-
//# sourceMappingURL=chunk-
|
|
85
|
+
//# sourceMappingURL=chunk-3SJ6OXCZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/update-check.ts"],"sourcesContent":["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 response = await fetch(REGISTRY_URL, {\n signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n });\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 Run: gpc update`;\n}\n"],"mappings":";;;AAAA,SAAS,YAAY;AACrB,SAAS,UAAU,WAAW,aAAa;AAC3C,SAAS,mBAAmB;AAa5B,IAAM,eAAe,KAAK,KAAK,KAAK;AACpC,IAAM,mBAAmB;AACzB,IAAM,eAAe;AAErB,SAAS,mBAA2B;AAClC,SAAO,KAAK,YAAY,GAAG,mBAAmB;AAChD;AAMO,SAAS,eAAe,SAAiB,QAAyB;AACvE,QAAM,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,MAAM;AACvC,QAAM,IAAI,OAAO,MAAM,GAAG,EAAE,IAAI,MAAM;AACtC,WAAS,IAAI,GAAG,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK;AACrD,UAAM,KAAK,EAAE,CAAC,KAAK;AACnB,UAAM,KAAK,EAAE,CAAC,KAAK;AACnB,QAAI,KAAK,GAAI,QAAO;AACpB,QAAI,KAAK,GAAI,QAAO;AAAA,EACtB;AACA,SAAO;AACT;AAEA,eAAe,YAAuC;AACpD,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,iBAAiB,GAAG,OAAO;AACtD,UAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,QAAI,OAAO,KAAK,WAAW,YAAY,OAAO,KAAK,cAAc,UAAU;AACzE,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,WAAW,MAAuB;AACzC,QAAM,WAAW,iBAAiB;AAClC,QAAM,MAAM,KAAK,UAAU,IAAI;AAE/B,QAAM,KAAK,EAAE,WAAW,KAAK,CAAC,EAC3B,KAAK,MAAM,UAAU,UAAU,KAAK,UAAU,IAAI,GAAG,OAAO,CAAC,EAC7D,MAAM,MAAM;AAAA,EAAC,CAAC;AACnB;AAEA,eAAe,qBAA6C;AAC1D,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,cAAc;AAAA,MACzC,QAAQ,YAAY,QAAQ,gBAAgB;AAAA,IAC9C,CAAC;AAED,QAAI,CAAC,SAAS,GAAI,QAAO;AAEzB,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,QAAI,OAAO,KAAK,YAAY,SAAU,QAAO;AAE7C,WAAO,KAAK;AAAA,EACd,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMA,eAAsB,eAAe,gBAA2D;AAE9F,MAAI,QAAQ,IAAI,qBAAqB,MAAM,IAAK,QAAO;AACvD,MAAI,QAAQ,IAAI,IAAI,EAAG,QAAO;AAC9B,MAAI,CAAC,QAAQ,OAAO,MAAO,QAAO;AAGlC,QAAM,QAAQ,MAAM,UAAU;AAC9B,MAAI,SAAS,KAAK,IAAI,IAAI,MAAM,YAAY,cAAc;AACxD,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,MAAM;AAAA,MACd,iBAAiB,eAAe,gBAAgB,MAAM,MAAM;AAAA,IAC9D;AAAA,EACF;AAGA,QAAM,SAAS,MAAM,mBAAmB;AACxC,MAAI,CAAC,OAAQ,QAAO;AAGpB,aAAW,EAAE,QAAQ,WAAW,KAAK,IAAI,EAAE,CAAC;AAE5C,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,IACA,iBAAiB,eAAe,gBAAgB,MAAM;AAAA,EACxD;AACF;AAKO,SAAS,yBAAyB,QAAmC;AAC1E,SAAO,qBAAqB,OAAO,OAAO,WAAW,OAAO,MAAM;AACpE;","names":[]}
|
|
@@ -67,153 +67,153 @@ 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("GPC \u2014 Google Play Console CLI").version("0.9.
|
|
70
|
+
program.name("gpc").description("GPC \u2014 Google Play Console CLI").version("0.9.45", "-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").option("--apps <csv>", "Comma-separated package names for multi-app operations").showSuggestionAfterError(false);
|
|
71
71
|
const commandLoaders = {
|
|
72
72
|
auth: async () => {
|
|
73
|
-
(await import("./auth-
|
|
73
|
+
(await import("./auth-OTA3SV3J.js")).registerAuthCommands(program);
|
|
74
74
|
},
|
|
75
75
|
config: async () => {
|
|
76
|
-
(await import("./config-
|
|
76
|
+
(await import("./config-2FTCYEGD.js")).registerConfigCommands(program);
|
|
77
77
|
},
|
|
78
78
|
doctor: async () => {
|
|
79
|
-
(await import("./doctor-
|
|
79
|
+
(await import("./doctor-H4X7Q57B.js")).registerDoctorCommand(program);
|
|
80
80
|
},
|
|
81
81
|
update: async () => {
|
|
82
|
-
(await import("./update-
|
|
82
|
+
(await import("./update-OMALGIBR.js")).registerUpdateCommand(program);
|
|
83
83
|
},
|
|
84
84
|
docs: async () => {
|
|
85
|
-
(await import("./docs-
|
|
85
|
+
(await import("./docs-4D2SJ4LY.js")).registerDocsCommand(program);
|
|
86
86
|
},
|
|
87
87
|
changelog: async () => {
|
|
88
|
-
(await import("./changelog-
|
|
88
|
+
(await import("./changelog-7COFZO7Q.js")).registerChangelogCommand(program);
|
|
89
89
|
},
|
|
90
90
|
completion: async () => {
|
|
91
91
|
(await import("./completion-BCHRJSAT.js")).registerCompletionCommand(program);
|
|
92
92
|
},
|
|
93
93
|
apps: async () => {
|
|
94
|
-
(await import("./apps-
|
|
94
|
+
(await import("./apps-FKD3ZG5X.js")).registerAppsCommands(program);
|
|
95
95
|
},
|
|
96
96
|
releases: async () => {
|
|
97
|
-
(await import("./releases-
|
|
97
|
+
(await import("./releases-2I3WBULC.js")).registerReleasesCommands(program);
|
|
98
98
|
},
|
|
99
99
|
tracks: async () => {
|
|
100
|
-
(await import("./tracks-
|
|
100
|
+
(await import("./tracks-YHMO2A6B.js")).registerTracksCommands(program);
|
|
101
101
|
},
|
|
102
102
|
status: async () => {
|
|
103
|
-
(await import("./status-
|
|
103
|
+
(await import("./status-6LH5W4FU.js")).registerStatusCommand(program);
|
|
104
104
|
},
|
|
105
105
|
listings: async () => {
|
|
106
|
-
(await import("./listings-
|
|
106
|
+
(await import("./listings-7SGQ4SRX.js")).registerListingsCommands(program);
|
|
107
107
|
},
|
|
108
108
|
reviews: async () => {
|
|
109
|
-
(await import("./reviews-
|
|
109
|
+
(await import("./reviews-BCCXIQ6C.js")).registerReviewsCommands(program);
|
|
110
110
|
},
|
|
111
111
|
vitals: async () => {
|
|
112
|
-
(await import("./vitals-
|
|
112
|
+
(await import("./vitals-C23L2Y2E.js")).registerVitalsCommands(program);
|
|
113
113
|
},
|
|
114
114
|
subscriptions: async () => {
|
|
115
|
-
(await import("./subscriptions-
|
|
115
|
+
(await import("./subscriptions-DZP3Y7O7.js")).registerSubscriptionsCommands(program);
|
|
116
116
|
},
|
|
117
117
|
iap: async () => {
|
|
118
|
-
(await import("./iap-
|
|
118
|
+
(await import("./iap-OUI5YYN4.js")).registerIapCommands(program);
|
|
119
119
|
},
|
|
120
120
|
purchases: async () => {
|
|
121
|
-
(await import("./purchases-
|
|
121
|
+
(await import("./purchases-DAWTMXP6.js")).registerPurchasesCommands(program);
|
|
122
122
|
},
|
|
123
123
|
pricing: async () => {
|
|
124
|
-
(await import("./pricing-
|
|
124
|
+
(await import("./pricing-JJZFICFL.js")).registerPricingCommands(program);
|
|
125
125
|
},
|
|
126
126
|
reports: async () => {
|
|
127
|
-
(await import("./reports-
|
|
127
|
+
(await import("./reports-CIB2T3XT.js")).registerReportsCommands(program);
|
|
128
128
|
},
|
|
129
129
|
users: async () => {
|
|
130
|
-
(await import("./users-
|
|
130
|
+
(await import("./users-UKG7VIQH.js")).registerUsersCommands(program);
|
|
131
131
|
},
|
|
132
132
|
testers: async () => {
|
|
133
|
-
(await import("./testers-
|
|
133
|
+
(await import("./testers-LSMBXCA2.js")).registerTestersCommands(program);
|
|
134
134
|
},
|
|
135
135
|
validate: async () => {
|
|
136
|
-
(await import("./validate-
|
|
136
|
+
(await import("./validate-QIYSA3N7.js")).registerValidateCommand(program);
|
|
137
137
|
},
|
|
138
138
|
publish: async () => {
|
|
139
|
-
(await import("./publish-
|
|
139
|
+
(await import("./publish-JPTI4EBT.js")).registerPublishCommand(program);
|
|
140
140
|
},
|
|
141
141
|
recovery: async () => {
|
|
142
|
-
(await import("./recovery-
|
|
142
|
+
(await import("./recovery-YE3Z7NIN.js")).registerRecoveryCommands(program);
|
|
143
143
|
},
|
|
144
144
|
"data-safety": async () => {
|
|
145
|
-
(await import("./data-safety-
|
|
145
|
+
(await import("./data-safety-AFMD6MYI.js")).registerDataSafetyCommands(program);
|
|
146
146
|
},
|
|
147
147
|
"external-transactions": async () => {
|
|
148
|
-
(await import("./external-transactions-
|
|
148
|
+
(await import("./external-transactions-LCZALS3V.js")).registerExternalTransactionsCommands(
|
|
149
149
|
program
|
|
150
150
|
);
|
|
151
151
|
},
|
|
152
152
|
"device-tiers": async () => {
|
|
153
|
-
(await import("./device-tiers-
|
|
153
|
+
(await import("./device-tiers-AQAMUQXI.js")).registerDeviceTiersCommands(program);
|
|
154
154
|
},
|
|
155
155
|
"one-time-products": async () => {
|
|
156
|
-
(await import("./one-time-products-
|
|
156
|
+
(await import("./one-time-products-MGZTU7OM.js")).registerOneTimeProductsCommands(program);
|
|
157
157
|
},
|
|
158
158
|
"internal-sharing": async () => {
|
|
159
|
-
(await import("./internal-sharing-
|
|
159
|
+
(await import("./internal-sharing-ONNIWIAT.js")).registerInternalSharingCommands(program);
|
|
160
160
|
},
|
|
161
161
|
"generated-apks": async () => {
|
|
162
|
-
(await import("./generated-apks-
|
|
162
|
+
(await import("./generated-apks-RX2IUWSF.js")).registerGeneratedApksCommands(program);
|
|
163
163
|
},
|
|
164
164
|
"purchase-options": async () => {
|
|
165
|
-
(await import("./purchase-options-
|
|
165
|
+
(await import("./purchase-options-KFWW4JW2.js")).registerPurchaseOptionsCommands(program);
|
|
166
166
|
},
|
|
167
167
|
bundle: async () => {
|
|
168
|
-
(await import("./bundle-
|
|
168
|
+
(await import("./bundle-F7MUVC5J.js")).registerBundleCommands(program);
|
|
169
169
|
},
|
|
170
170
|
audit: async () => {
|
|
171
|
-
(await import("./audit-
|
|
171
|
+
(await import("./audit-JASSHRWN.js")).registerAuditCommands(program);
|
|
172
172
|
},
|
|
173
173
|
migrate: async () => {
|
|
174
|
-
(await import("./migrate-
|
|
174
|
+
(await import("./migrate-ZQCJGQQS.js")).registerMigrateCommands(program);
|
|
175
175
|
},
|
|
176
176
|
anomalies: async () => {
|
|
177
|
-
(await import("./anomalies-
|
|
177
|
+
(await import("./anomalies-UDE4NGHJ.js")).registerAnomaliesCommands(program);
|
|
178
178
|
},
|
|
179
179
|
"install-skills": async () => {
|
|
180
|
-
(await import("./install-skills-
|
|
180
|
+
(await import("./install-skills-6QDUXI5F.js")).registerInstallSkillsCommand(program);
|
|
181
181
|
},
|
|
182
182
|
version: async () => {
|
|
183
|
-
(await import("./version-
|
|
183
|
+
(await import("./version-NCSNXNVN.js")).registerVersionCommand(program);
|
|
184
184
|
},
|
|
185
185
|
cache: async () => {
|
|
186
|
-
(await import("./cache-
|
|
186
|
+
(await import("./cache-XKPLZYEB.js")).registerCacheCommand(program);
|
|
187
187
|
},
|
|
188
188
|
feedback: async () => {
|
|
189
|
-
(await import("./feedback-
|
|
189
|
+
(await import("./feedback-XP765TOO.js")).registerFeedbackCommand(program);
|
|
190
190
|
},
|
|
191
191
|
quickstart: async () => {
|
|
192
|
-
(await import("./quickstart-
|
|
192
|
+
(await import("./quickstart-Z5Y3FYJU.js")).registerQuickstartCommand(program);
|
|
193
193
|
},
|
|
194
194
|
grants: async () => {
|
|
195
|
-
(await import("./grants-
|
|
195
|
+
(await import("./grants-EBPECI26.js")).registerGrantsCommands(program);
|
|
196
196
|
},
|
|
197
197
|
train: async () => {
|
|
198
|
-
(await import("./train-
|
|
198
|
+
(await import("./train-MDD2EBHS.js")).registerTrainCommands(program);
|
|
199
199
|
},
|
|
200
200
|
quota: async () => {
|
|
201
|
-
(await import("./quota-
|
|
201
|
+
(await import("./quota-MZRWYJGR.js")).registerQuotaCommand(program);
|
|
202
202
|
},
|
|
203
203
|
games: async () => {
|
|
204
|
-
(await import("./games-
|
|
204
|
+
(await import("./games-ZSNGEI7A.js")).registerGamesCommands(program);
|
|
205
205
|
},
|
|
206
206
|
enterprise: async () => {
|
|
207
|
-
(await import("./enterprise-
|
|
207
|
+
(await import("./enterprise-7PWXMSUN.js")).registerEnterpriseCommands(program);
|
|
208
208
|
},
|
|
209
209
|
diff: async () => {
|
|
210
|
-
(await import("./diff-
|
|
210
|
+
(await import("./diff-6EO4ID6W.js")).registerDiffCommand(program);
|
|
211
211
|
},
|
|
212
212
|
init: async () => {
|
|
213
|
-
(await import("./init-
|
|
213
|
+
(await import("./init-WSTQTJOD.js")).registerInitCommand(program);
|
|
214
214
|
},
|
|
215
215
|
preflight: async () => {
|
|
216
|
-
(await import("./preflight-
|
|
216
|
+
(await import("./preflight-N7ZRG2JI.js")).registerPreflightCommand(program);
|
|
217
217
|
},
|
|
218
218
|
plugins: async () => {
|
|
219
219
|
registerPluginsCommand(program, pluginManager);
|
|
@@ -420,6 +420,7 @@ function isTypedError(error) {
|
|
|
420
420
|
var AUTH_KEYWORDS = ["AUTH", "UNAUTHENTICATED", "PERMISSION_DENIED", "401", "403"];
|
|
421
421
|
function isAuthRelatedError(error) {
|
|
422
422
|
if (isTypedError(error)) {
|
|
423
|
+
if (error.code?.startsWith("UPDATE_")) return false;
|
|
423
424
|
if (error.exitCode === 3) return true;
|
|
424
425
|
if (error.code && AUTH_KEYWORDS.some((k) => error.code?.includes(k))) return true;
|
|
425
426
|
}
|
|
@@ -427,6 +428,9 @@ function isAuthRelatedError(error) {
|
|
|
427
428
|
return AUTH_KEYWORDS.some((k) => msg.includes(k));
|
|
428
429
|
}
|
|
429
430
|
function handleCliError(error) {
|
|
431
|
+
if (isTypedError(error) && error.silent) {
|
|
432
|
+
return error.exitCode ?? 0;
|
|
433
|
+
}
|
|
430
434
|
const authHint = isAuthRelatedError(error) ? "\n\u2192 Run gpc doctor to diagnose your credentials." : "";
|
|
431
435
|
if (isTypedError(error)) {
|
|
432
436
|
console.error(`Error [${error.code}]: ${error.message}`);
|
|
@@ -447,4 +451,4 @@ export {
|
|
|
447
451
|
createProgram,
|
|
448
452
|
handleCliError
|
|
449
453
|
};
|
|
450
|
-
//# sourceMappingURL=chunk-
|
|
454
|
+
//# sourceMappingURL=chunk-6OWN6S6X.js.map
|