@gpc-cli/core 0.9.61 → 0.9.62
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/LICENSE +21 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +35 -18
- package/dist/index.js.map +1 -1
- package/package.json +16 -16
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 GPC Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { OutputFormat, ResolvedConfig, WebhookConfig } from '@gpc-cli/config';
|
|
2
2
|
import { AuthClient } from '@gpc-cli/auth';
|
|
3
3
|
import { GpcPlugin, PluginManifest, CommandEvent, CommandResult, PluginError, RequestEvent, ResponseEvent, PluginCommand } from '@gpc-cli/plugin-sdk';
|
|
4
|
-
import { PlayApiClient, EditCommitOptions, Track, ExternallyHostedApk, ExternallyHostedApkResponse, DeobfuscationFileType, UploadProgressEvent, ResumableUploadOptions, Listing, ImageType, CountryAvailability, Image, AppDetails, Review, ReviewReplyResponse, Subscription, SubscriptionOffer, OffersListResponse, BasePlanMigratePricesRequest, InAppProduct, Order, SubscriptionDeferResponse, SubscriptionsV2DeferResponse, ProductPurchase, ProductPurchaseV2, SubscriptionPurchaseV2, VoidedPurchase, UsersApiClient, User, DeveloperLevelPermission, Grant, MetricRow, ReportingDimension, ReportingAggregation, VitalsMetricSet, ReportingApiClient, AnomalyDetectionResponse, MetricSetResponse, ErrorIssuesResponse, ConvertRegionPricesResponse, ReportType, StatsDimension, ReportBucket, Testers, AppRecoveryTargeting, AppRecoveryAction, CreateAppRecoveryActionRequest,
|
|
4
|
+
import { PlayApiClient, EditCommitOptions, Track, ExternallyHostedApk, ExternallyHostedApkResponse, DeobfuscationFileType, UploadProgressEvent, ResumableUploadOptions, Listing, ImageType, CountryAvailability, Image, AppDetails, Review, ReviewReplyResponse, Subscription, SubscriptionOffer, OffersListResponse, BasePlanMigratePricesRequest, InAppProduct, Order, SubscriptionDeferResponse, SubscriptionsV2DeferResponse, ProductPurchase, ProductPurchaseV2, SubscriptionPurchaseV2, VoidedPurchase, UsersApiClient, User, DeveloperLevelPermission, Grant, MetricRow, ReportingDimension, ReportingAggregation, VitalsMetricSet, ReportingApiClient, AnomalyDetectionResponse, MetricSetResponse, ErrorIssuesResponse, ConvertRegionPricesResponse, ReportType, StatsDimension, ReportBucket, Testers, AppRecoveryTargeting, AppRecoveryAction, CreateAppRecoveryActionRequest, DataSafetyResponse, DataSafetyRequest, ExternalTransaction, ExternalTransactionRefund, DeviceTierConfig, OneTimeOffer, OneTimeProduct, OneTimeOffersListResponse, OneTimeProductsListResponse, GamesApiClient, Achievement, GameEvent, Leaderboard, EnterpriseApiClient, CustomApp, GeneratedApk, Bundle } from '@gpc-cli/api';
|
|
5
5
|
|
|
6
6
|
declare class GpcError extends Error {
|
|
7
7
|
readonly code: string;
|
|
@@ -779,8 +779,8 @@ declare function deployRecoveryAction(client: PlayApiClient, packageName: string
|
|
|
779
779
|
declare function createRecoveryAction(client: PlayApiClient, packageName: string, request: CreateAppRecoveryActionRequest): Promise<AppRecoveryAction>;
|
|
780
780
|
declare function addRecoveryTargeting(client: PlayApiClient, packageName: string, actionId: string, targeting: AppRecoveryTargeting): Promise<AppRecoveryAction>;
|
|
781
781
|
|
|
782
|
-
declare function updateDataSafety(client: PlayApiClient, packageName: string, data:
|
|
783
|
-
declare function importDataSafety(client: PlayApiClient, packageName: string, filePath: string): Promise<
|
|
782
|
+
declare function updateDataSafety(client: PlayApiClient, packageName: string, data: DataSafetyRequest): Promise<DataSafetyResponse>;
|
|
783
|
+
declare function importDataSafety(client: PlayApiClient, packageName: string, filePath: string): Promise<DataSafetyResponse>;
|
|
784
784
|
|
|
785
785
|
declare function createExternalTransaction(client: PlayApiClient, packageName: string, data: ExternalTransaction): Promise<ExternalTransaction>;
|
|
786
786
|
declare function getExternalTransaction(client: PlayApiClient, packageName: string, transactionId: string): Promise<ExternalTransaction>;
|
package/dist/index.js
CHANGED
|
@@ -3975,24 +3975,41 @@ async function addRecoveryTargeting(client, packageName, actionId, targeting) {
|
|
|
3975
3975
|
}
|
|
3976
3976
|
|
|
3977
3977
|
// src/commands/data-safety.ts
|
|
3978
|
-
import { readFile as readFile6 } from "fs/promises";
|
|
3978
|
+
import { readFile as readFile6, stat as stat4 } from "fs/promises";
|
|
3979
|
+
var MAX_CSV_BYTES = 1 * 1024 * 1024;
|
|
3979
3980
|
async function updateDataSafety(client, packageName, data) {
|
|
3980
3981
|
return client.dataSafety.update(packageName, data);
|
|
3981
3982
|
}
|
|
3982
3983
|
async function importDataSafety(client, packageName, filePath) {
|
|
3983
|
-
|
|
3984
|
-
let data;
|
|
3984
|
+
let fileStat;
|
|
3985
3985
|
try {
|
|
3986
|
-
|
|
3986
|
+
fileStat = await stat4(filePath);
|
|
3987
3987
|
} catch {
|
|
3988
3988
|
throw new GpcError(
|
|
3989
|
-
`
|
|
3990
|
-
"
|
|
3989
|
+
`Cannot read data safety CSV: "${filePath}"`,
|
|
3990
|
+
"FILE_NOT_FOUND",
|
|
3991
3991
|
1,
|
|
3992
|
-
"
|
|
3992
|
+
"Check the file path and ensure the file exists."
|
|
3993
3993
|
);
|
|
3994
3994
|
}
|
|
3995
|
-
|
|
3995
|
+
if (fileStat.size === 0) {
|
|
3996
|
+
throw new GpcError(
|
|
3997
|
+
`Data safety CSV is empty: "${filePath}"`,
|
|
3998
|
+
"INVALID_INPUT",
|
|
3999
|
+
1,
|
|
4000
|
+
"Export your data safety form from Play Console and provide the CSV."
|
|
4001
|
+
);
|
|
4002
|
+
}
|
|
4003
|
+
if (fileStat.size > MAX_CSV_BYTES) {
|
|
4004
|
+
throw new GpcError(
|
|
4005
|
+
`Data safety CSV exceeds 1 MB (${fileStat.size} bytes): "${filePath}"`,
|
|
4006
|
+
"FILE_TOO_LARGE",
|
|
4007
|
+
1,
|
|
4008
|
+
"The CSV should be a few KB. Check that you are passing the correct file."
|
|
4009
|
+
);
|
|
4010
|
+
}
|
|
4011
|
+
const csvContent = await readFile6(filePath, "utf-8");
|
|
4012
|
+
return updateDataSafety(client, packageName, { safetyLabels: csvContent });
|
|
3996
4013
|
}
|
|
3997
4014
|
|
|
3998
4015
|
// src/commands/external-transactions.ts
|
|
@@ -4667,11 +4684,11 @@ function safePathWithin(userPath, baseDir) {
|
|
|
4667
4684
|
}
|
|
4668
4685
|
|
|
4669
4686
|
// src/commands/init.ts
|
|
4670
|
-
import { mkdir as mkdir6, writeFile as writeFile6, stat as
|
|
4687
|
+
import { mkdir as mkdir6, writeFile as writeFile6, stat as stat5 } from "fs/promises";
|
|
4671
4688
|
import { join as join7 } from "path";
|
|
4672
4689
|
async function exists2(path) {
|
|
4673
4690
|
try {
|
|
4674
|
-
await
|
|
4691
|
+
await stat5(path);
|
|
4675
4692
|
return true;
|
|
4676
4693
|
} catch {
|
|
4677
4694
|
return false;
|
|
@@ -5756,7 +5773,7 @@ ${fileList}` + (hasPageSizeCompat ? "\nandroid:pageSizeCompat is set, so the app
|
|
|
5756
5773
|
}
|
|
5757
5774
|
|
|
5758
5775
|
// src/preflight/scanners/metadata-scanner.ts
|
|
5759
|
-
import { readdir as readdir4, stat as
|
|
5776
|
+
import { readdir as readdir4, stat as stat6, readFile as readFile10 } from "fs/promises";
|
|
5760
5777
|
import { join as join8 } from "path";
|
|
5761
5778
|
var SAFE_LANG = /^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$/;
|
|
5762
5779
|
var FILE_MAP2 = {
|
|
@@ -5809,7 +5826,7 @@ var metadataScanner = {
|
|
|
5809
5826
|
}
|
|
5810
5827
|
for (const lang of locales) {
|
|
5811
5828
|
const langDir = join8(dir, lang);
|
|
5812
|
-
const langStat = await
|
|
5829
|
+
const langStat = await stat6(langDir).catch(() => null);
|
|
5813
5830
|
if (!langStat?.isDirectory()) continue;
|
|
5814
5831
|
const fields = {};
|
|
5815
5832
|
for (const [fileName, field] of Object.entries(FILE_MAP2)) {
|
|
@@ -5916,7 +5933,7 @@ var metadataScanner = {
|
|
|
5916
5933
|
import { readFile as readFile11 } from "fs/promises";
|
|
5917
5934
|
|
|
5918
5935
|
// src/preflight/scan-files.ts
|
|
5919
|
-
import { readdir as readdir5, stat as
|
|
5936
|
+
import { readdir as readdir5, stat as stat7 } from "fs/promises";
|
|
5920
5937
|
import { join as join9, extname as extname2 } from "path";
|
|
5921
5938
|
var DEFAULT_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
5922
5939
|
".git",
|
|
@@ -5941,7 +5958,7 @@ async function collectSourceFiles(dir, extensions, skipDirs = DEFAULT_SKIP_DIRS,
|
|
|
5941
5958
|
for (const entry of entries) {
|
|
5942
5959
|
if (skipDirs.has(entry)) continue;
|
|
5943
5960
|
const fullPath = join9(dir, entry);
|
|
5944
|
-
const s = await
|
|
5961
|
+
const s = await stat7(fullPath).catch(() => null);
|
|
5945
5962
|
if (!s) continue;
|
|
5946
5963
|
if (s.isDirectory()) {
|
|
5947
5964
|
const sub = await collectSourceFiles(fullPath, extensions, skipDirs, maxDepth - 1);
|
|
@@ -6863,7 +6880,7 @@ async function downloadGeneratedApk(client, packageName, versionCode, apkId, out
|
|
|
6863
6880
|
}
|
|
6864
6881
|
|
|
6865
6882
|
// src/commands/bundle-analysis.ts
|
|
6866
|
-
import { readFile as readFile14, stat as
|
|
6883
|
+
import { readFile as readFile14, stat as stat8 } from "fs/promises";
|
|
6867
6884
|
var EOCD_SIGNATURE = 101010256;
|
|
6868
6885
|
var CD_SIGNATURE = 33639248;
|
|
6869
6886
|
var MODULE_SUBDIRS = /* @__PURE__ */ new Set(["dex", "manifest", "res", "assets", "lib", "resources.pb", "root"]);
|
|
@@ -6939,7 +6956,7 @@ function detectFileType2(filePath) {
|
|
|
6939
6956
|
return "apk";
|
|
6940
6957
|
}
|
|
6941
6958
|
async function analyzeBundle(filePath) {
|
|
6942
|
-
const fileInfo = await
|
|
6959
|
+
const fileInfo = await stat8(filePath).catch(() => null);
|
|
6943
6960
|
if (!fileInfo || !fileInfo.isFile()) {
|
|
6944
6961
|
throw new Error(`File not found: ${filePath}`);
|
|
6945
6962
|
}
|
|
@@ -8359,10 +8376,10 @@ function compareFingerprints(a, b) {
|
|
|
8359
8376
|
|
|
8360
8377
|
// src/utils/hash.ts
|
|
8361
8378
|
import { createHash } from "crypto";
|
|
8362
|
-
import { stat as
|
|
8379
|
+
import { stat as stat9 } from "fs/promises";
|
|
8363
8380
|
async function sha256File(filePath) {
|
|
8364
8381
|
const hash = createHash("sha256");
|
|
8365
|
-
const { size } = await
|
|
8382
|
+
const { size } = await stat9(filePath);
|
|
8366
8383
|
if (size === 0) return hash.digest("hex");
|
|
8367
8384
|
const { createReadStream } = await import("fs");
|
|
8368
8385
|
const stream = createReadStream(filePath);
|