@gpc-cli/core 0.9.52 → 0.9.54
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/README.md +1 -0
- package/dist/index.d.ts +66 -3
- package/dist/index.js +348 -6
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -60,6 +60,7 @@ const analysis = await analyzeBundle("./app.aab");
|
|
|
60
60
|
| **Testers** | `listTesters`, `addTesters`, `removeTesters`, `importTestersFromCsv` |
|
|
61
61
|
| **Bundle** | `analyzeBundle`, `compareBundles` (zero-dependency AAB/APK size analysis) |
|
|
62
62
|
| **Publishing** | `publish` (end-to-end: upload + track + notes + commit) |
|
|
63
|
+
| **Changelog** | `generateChangelog`, `fetchChangelog`, `formatChangelogEntry`, `buildLocaleBundle`, `renderPlayStore`, `renderMarkdown`, `renderJson`, `renderPrompt`, `translateBundle`, `resolveLocales` |
|
|
63
64
|
| **Validation** | `validateUploadFile`, `validateImage`, `validatePreSubmission` |
|
|
64
65
|
|
|
65
66
|
## Utilities
|
package/dist/index.d.ts
CHANGED
|
@@ -109,6 +109,7 @@ interface AppInfo {
|
|
|
109
109
|
}
|
|
110
110
|
declare function getAppInfo(client: PlayApiClient, packageName: string): Promise<AppInfo>;
|
|
111
111
|
|
|
112
|
+
declare function waitForBundleProcessing(client: PlayApiClient, packageName: string, editId: string, versionCode: number, backoff?: number[]): Promise<void>;
|
|
112
113
|
interface UploadResult {
|
|
113
114
|
versionCode: number;
|
|
114
115
|
track: string;
|
|
@@ -183,6 +184,19 @@ declare function fetchReleaseNotes(client: PlayApiClient, packageName: string, t
|
|
|
183
184
|
language: string;
|
|
184
185
|
text: string;
|
|
185
186
|
}[]>;
|
|
187
|
+
interface ApplyReleaseNotesResult {
|
|
188
|
+
track: string;
|
|
189
|
+
versionCodes: string[];
|
|
190
|
+
localeCount: number;
|
|
191
|
+
releaseNotes: {
|
|
192
|
+
language: string;
|
|
193
|
+
text: string;
|
|
194
|
+
}[];
|
|
195
|
+
}
|
|
196
|
+
declare function applyReleaseNotes(client: PlayApiClient, packageName: string, track: string, releaseNotes: {
|
|
197
|
+
language: string;
|
|
198
|
+
text: string;
|
|
199
|
+
}[], commitOptions?: EditCommitOptions): Promise<ApplyReleaseNotesResult>;
|
|
186
200
|
interface ReleaseDiff {
|
|
187
201
|
field: string;
|
|
188
202
|
track1Value: string;
|
|
@@ -1323,15 +1337,43 @@ declare function renderJson(g: GeneratedChangelog): string;
|
|
|
1323
1337
|
|
|
1324
1338
|
declare function renderPrompt(g: GeneratedChangelog): string;
|
|
1325
1339
|
|
|
1340
|
+
type Provider = "anthropic" | "openai" | "google";
|
|
1341
|
+
type TranslationPath = "gateway" | "direct";
|
|
1342
|
+
type ErrorReason = "rate_limited" | "auth" | "safety_blocked" | "timeout" | "network" | "no_source" | "unknown";
|
|
1343
|
+
interface TranslationResult {
|
|
1344
|
+
text: string;
|
|
1345
|
+
tokensIn: number;
|
|
1346
|
+
tokensOut: number;
|
|
1347
|
+
}
|
|
1348
|
+
type Translator = (locale: string, sourceText: string) => Promise<TranslationResult>;
|
|
1349
|
+
interface TranslatorConfig {
|
|
1350
|
+
path: TranslationPath;
|
|
1351
|
+
provider: Provider;
|
|
1352
|
+
model: string;
|
|
1353
|
+
runId: string;
|
|
1354
|
+
}
|
|
1355
|
+
interface ResolveAiConfigOptions {
|
|
1356
|
+
provider?: string;
|
|
1357
|
+
model?: string;
|
|
1358
|
+
env?: NodeJS.ProcessEnv;
|
|
1359
|
+
}
|
|
1360
|
+
declare const PROVIDER_WHITELIST: readonly Provider[];
|
|
1361
|
+
declare const DEFAULT_MODELS: Record<Provider, string>;
|
|
1362
|
+
declare function resolveAiConfig(opts?: ResolveAiConfigOptions): TranslatorConfig;
|
|
1363
|
+
declare function classifyError(err: unknown): ErrorReason;
|
|
1364
|
+
declare function createTranslator(config: TranslatorConfig): Promise<Translator>;
|
|
1365
|
+
declare function fetchAggregateCost(runId: string): Promise<number | undefined>;
|
|
1366
|
+
declare function formatPathLabel(config: TranslatorConfig): string;
|
|
1367
|
+
|
|
1326
1368
|
declare const PLAY_STORE_LIMIT = 500;
|
|
1327
|
-
declare const PLACEHOLDER_TEXT = "[needs translation \u2014 pass --ai
|
|
1369
|
+
declare const PLACEHOLDER_TEXT = "[needs translation \u2014 pass --ai, or paste the prompt emitted by --format prompt]";
|
|
1328
1370
|
type PlayStoreFormat = "md" | "json" | "prompt";
|
|
1329
1371
|
interface LocaleEntry {
|
|
1330
1372
|
language: string;
|
|
1331
1373
|
text: string;
|
|
1332
1374
|
chars: number;
|
|
1333
1375
|
limit: number;
|
|
1334
|
-
status: "ok" | "over" | "placeholder" | "empty";
|
|
1376
|
+
status: "ok" | "over" | "placeholder" | "empty" | "failed";
|
|
1335
1377
|
}
|
|
1336
1378
|
interface LocaleBundle {
|
|
1337
1379
|
from: string;
|
|
@@ -1354,6 +1396,27 @@ declare function renderPlayStore(g: GeneratedChangelog, opts: PlayStoreRenderOpt
|
|
|
1354
1396
|
output: string;
|
|
1355
1397
|
bundle: LocaleBundle;
|
|
1356
1398
|
};
|
|
1399
|
+
interface TranslationFailure {
|
|
1400
|
+
language: string;
|
|
1401
|
+
reason: ErrorReason;
|
|
1402
|
+
}
|
|
1403
|
+
interface TranslateBundleOptions {
|
|
1404
|
+
translator: Translator;
|
|
1405
|
+
strict?: boolean;
|
|
1406
|
+
onError?: (failure: TranslationFailure, err: unknown) => void;
|
|
1407
|
+
onTranslated?: (entry: LocaleEntry) => void;
|
|
1408
|
+
}
|
|
1409
|
+
interface TranslatedBundle extends LocaleBundle {
|
|
1410
|
+
tokensIn: number;
|
|
1411
|
+
tokensOut: number;
|
|
1412
|
+
failures: TranslationFailure[];
|
|
1413
|
+
}
|
|
1414
|
+
declare function translateBundle(bundle: LocaleBundle, options: TranslateBundleOptions): Promise<TranslatedBundle>;
|
|
1415
|
+
declare function validateBundleForApply(bundle: LocaleBundle): string[];
|
|
1416
|
+
declare function bundleToReleaseNotes(bundle: LocaleBundle): {
|
|
1417
|
+
language: string;
|
|
1418
|
+
text: string;
|
|
1419
|
+
}[];
|
|
1357
1420
|
|
|
1358
1421
|
type Renderer = (g: GeneratedChangelog) => string;
|
|
1359
1422
|
declare const RENDERERS: Record<OutputMode, Renderer>;
|
|
@@ -1409,4 +1472,4 @@ declare function decodeNotification(base64Payload: string): DecodedNotification;
|
|
|
1409
1472
|
*/
|
|
1410
1473
|
declare function formatNotification(notification: DecodedNotification): Record<string, unknown>;
|
|
1411
1474
|
|
|
1412
|
-
export { ApiError, type AppInfo, type AppStatus, type AuditEntry, type BatchSyncResult, type BundleAnalysis, type BundleComparison, type BundleEntry, type BundleSizeCheckResult, type BundleSizeConfig, type ChangelogEntry, type CommandContext, type CommitCluster, ConfigError, type CreateEnterpriseAppParams, DEFAULT_LIMITS, DEFAULT_PREFLIGHT_CONFIG, type DecodedNotification, type DiffToken, type DiscoverPluginsOptions, type DryRunPublishResult, type DryRunResult, type DryRunUploadResult, type ExportImagesOptions, type ExportImagesSummary, type FastlaneDetection, type FastlaneLane, type FetchChangelogOptions, type FieldLintResult, type FileValidationResult, type FindingSeverity, GOOGLE_PLAY_LANGUAGES, type GenerateOptions, type GeneratedChangelog, type GetAppStatusOptions, type GitNotesOptions, type GitReleaseNotes, type GitRunner, GpcError, type ImageValidationResult, type InitOptions, type InitResult, type InternalSharingUploadResult, type ListIapOptions, type ListSubscriptionsOptions, type ListUsersOptions, type ListVoidedOptions, type ListingDiff, type ListingFieldLimits, type ListingLintResult, type ListingsResult, type LoadedPlugin, type LocaleBundle, type LocaleEntry, type MigrationResult, NetworkError, type OneTimeProductDiff, type OutputMode, PERMISSION_PROPAGATION_WARNING, PLACEHOLDER_TEXT, PLAY_STORE_LIMIT, type ParsedCommit, type ParsedManifest, type ParsedMonth, type PlayStoreFormat, type PlayStoreRenderOptions, PluginManager, type PreflightConfig, type PreflightFinding, type PreflightOptions, type PreflightResult, type PreflightScanner, type PublishOptions, type PublishResult, type PushResult, type QuotaUsage, RENDERERS, type RawCommit, type ReleaseDiff, type ReleaseNotesValidation, type ReleaseStatusResult, type Renderer, type ResolveLocalesOptions, type ReviewAnalysis, type ReviewExportOptions, type ReviewsFilterOptions, type RtdnStatus, SECTION_ORDER, SENSITIVE_ARG_KEYS, SENSITIVE_KEYS, SEVERITY_ORDER, type ScaffoldOptions, type ScaffoldResult, type Spinner, type StatusDiff, type StatusRelease, type StatusReviews, type StatusVitalMetric, type SubscriptionAnalytics, type SubscriptionDiff, type SyncResult, type ThresholdResult, type TrainConfig, type TrainState, type UploadResult, type ValidateCheck, type ValidateOptions, type ValidateResult, type VersionVitalsComparison, type VersionVitalsRow, type VitalsOverview, type VitalsQueryOptions, type VitalsTrendComparison, type WatchOptions, type WatchVitalsOptions, type WebhookPayload, abortTrain, acknowledgeProductPurchase, activateBasePlan, activateOffer, addRecoveryTargeting, addTesters, advanceTrain, analyzeBundle, analyzeRemoteListings, analyzeReviews, batchGetOrders, batchSyncInAppProducts, buildLocaleBundle, cancelRecoveryAction, cancelSubscriptionPurchase, cancelSubscriptionV2, checkBundleSize, checkThreshold, clearAuditLog, compareBundles, compareVersionVitals, compareVitalsTrend, computeStatusDiff, consumeProductPurchase, convertRegionPrices, createAuditEntry, createDeviceTier, createEnterpriseApp, createExternalTransaction, createGrant, createInAppProduct, createOffer, createOneTimeOffer, createOneTimeProduct, createRecoveryAction, createSpinner, createSubscription, createTrack, deactivateBasePlan, deactivateOffer, decodeNotification, defaultGitRunner, deferSubscriptionPurchase, deferSubscriptionV2, deleteBasePlan, deleteGrant, deleteImage, deleteInAppProduct, deleteListing, deleteOffer, deleteOneTimeOffer, deleteOneTimeProduct, deleteSubscription, deployRecoveryAction, detectFastlane, detectOutputFormat, diffListings, diffListingsCommand, diffListingsEnhanced, diffOneTimeProduct, diffReleases, diffSubscription, discoverPlugins, downloadGeneratedApk, downloadReport, exportImages, exportReviews, fetchChangelog, fetchReleaseNotes, formatChangelogEntry, formatCustomPayload, formatDiscordPayload, formatJunit, formatNotification, formatOutput, formatSlackPayload, formatStatusDiff, formatStatusSummary, formatStatusTable, formatWordDiff, generateChangelog, generateMigrationPlan, generateNotesFromGit, getAllScannerNames, getAppInfo, getAppStatus, getCountryAvailability, getDeviceTier, getExternalTransaction, getInAppProduct, getListings, getOffer, getOneTimeOffer, getOneTimeProduct, getOrderDetails, getProductPurchase, getProductPurchaseV2, getQuotaUsage, getReleasesStatus, getReview, getRtdnStatus, getSubscription, getSubscriptionAnalytics, getSubscriptionPurchase, getTrainStatus, getUser, getVitalsAnomalies, getVitalsAnr, getVitalsBattery, getVitalsCrashes, getVitalsErrorCount, getVitalsLmk, getVitalsMemory, getVitalsOverview, getVitalsRendering, getVitalsStartup, importDataSafety, importTestersFromCsv, initAudit, initProject, inviteUser, isFinancialReportType, isStatsReportType, isValidBcp47, isValidReportType, isValidStatsDimension, lintListing, lintListings, lintLocalListings, listAchievements, listAuditEvents, listDeviceTiers, listEvents, listGeneratedApks, listGrants, listImages, listInAppProducts, listLeaderboards, listOffers, listOneTimeOffers, listOneTimeProducts, listRecoveryActions, listReports, listReviews, listSubscriptions, listTesters, listTracks, listUsers, listVoidedPurchases, loadPreflightConfig, loadStatusCache, maybePaginate, migratePrices, parseAppfile, parseCommit, parseFastfile, parseGrantArg, parseMonth, parseRemoteUrl, pauseTrain, promoteRelease, publish, publishEnterpriseApp, pullListings, pushListings, readListingsFromDir, readReleaseNotesFromDir, redactAuditArgs, redactSensitive, refundExternalTransaction, refundOrder, relativeTime, removeTesters, removeUser, renderJson, renderMarkdown, renderPlayStore, renderPlayStoreJson, renderPlayStoreMd, renderPlayStorePrompt, renderPrompt, replyToReview, resolveLocales, revokeSubscriptionPurchase, runPreflight, runWatchLoop, safePath, safePathWithin, saveStatusCache, scaffoldPlugin, searchAuditEvents, searchVitalsErrors, sendNotification, sendWebhook, sortResults, startTrain, statusHasBreach, syncInAppProducts, topFiles, trackBreachState, updateAppDetails, updateDataSafety, updateGrant, updateInAppProduct, updateListing, updateOffer, updateOneTimeOffer, updateOneTimeProduct, updateRollout, updateSubscription, updateTrackConfig, updateUser, uploadExternallyHosted, uploadImage, uploadInternalSharing, uploadRelease, validateImage, validateLanguageCode, validatePackageName, validatePreSubmission, validateReleaseNotes, validateSku, validateTrackName, validateUploadFile, validateVersionCode, watchVitalsWithAutoHalt, wordDiff, writeAuditLog, writeListingsToDir, writeMigrationOutput };
|
|
1475
|
+
export { ApiError, type AppInfo, type AppStatus, type ApplyReleaseNotesResult, type AuditEntry, type BatchSyncResult, type BundleAnalysis, type BundleComparison, type BundleEntry, type BundleSizeCheckResult, type BundleSizeConfig, type ChangelogEntry, type CommandContext, type CommitCluster, ConfigError, type CreateEnterpriseAppParams, DEFAULT_LIMITS, DEFAULT_MODELS, DEFAULT_PREFLIGHT_CONFIG, type DecodedNotification, type DiffToken, type DiscoverPluginsOptions, type DryRunPublishResult, type DryRunResult, type DryRunUploadResult, type ErrorReason, type ExportImagesOptions, type ExportImagesSummary, type FastlaneDetection, type FastlaneLane, type FetchChangelogOptions, type FieldLintResult, type FileValidationResult, type FindingSeverity, GOOGLE_PLAY_LANGUAGES, type GenerateOptions, type GeneratedChangelog, type GetAppStatusOptions, type GitNotesOptions, type GitReleaseNotes, type GitRunner, GpcError, type ImageValidationResult, type InitOptions, type InitResult, type InternalSharingUploadResult, type ListIapOptions, type ListSubscriptionsOptions, type ListUsersOptions, type ListVoidedOptions, type ListingDiff, type ListingFieldLimits, type ListingLintResult, type ListingsResult, type LoadedPlugin, type LocaleBundle, type LocaleEntry, type MigrationResult, NetworkError, type OneTimeProductDiff, type OutputMode, PERMISSION_PROPAGATION_WARNING, PLACEHOLDER_TEXT, PLAY_STORE_LIMIT, PROVIDER_WHITELIST, type ParsedCommit, type ParsedManifest, type ParsedMonth, type PlayStoreFormat, type PlayStoreRenderOptions, PluginManager, type PreflightConfig, type PreflightFinding, type PreflightOptions, type PreflightResult, type PreflightScanner, type Provider, type PublishOptions, type PublishResult, type PushResult, type QuotaUsage, RENDERERS, type RawCommit, type ReleaseDiff, type ReleaseNotesValidation, type ReleaseStatusResult, type Renderer, type ResolveAiConfigOptions, type ResolveLocalesOptions, type ReviewAnalysis, type ReviewExportOptions, type ReviewsFilterOptions, type RtdnStatus, SECTION_ORDER, SENSITIVE_ARG_KEYS, SENSITIVE_KEYS, SEVERITY_ORDER, type ScaffoldOptions, type ScaffoldResult, type Spinner, type StatusDiff, type StatusRelease, type StatusReviews, type StatusVitalMetric, type SubscriptionAnalytics, type SubscriptionDiff, type SyncResult, type ThresholdResult, type TrainConfig, type TrainState, type TranslateBundleOptions, type TranslatedBundle, type TranslationFailure, type TranslationPath, type TranslationResult, type Translator, type TranslatorConfig, type UploadResult, type ValidateCheck, type ValidateOptions, type ValidateResult, type VersionVitalsComparison, type VersionVitalsRow, type VitalsOverview, type VitalsQueryOptions, type VitalsTrendComparison, type WatchOptions, type WatchVitalsOptions, type WebhookPayload, abortTrain, acknowledgeProductPurchase, activateBasePlan, activateOffer, addRecoveryTargeting, addTesters, advanceTrain, analyzeBundle, analyzeRemoteListings, analyzeReviews, applyReleaseNotes, batchGetOrders, batchSyncInAppProducts, buildLocaleBundle, bundleToReleaseNotes, cancelRecoveryAction, cancelSubscriptionPurchase, cancelSubscriptionV2, checkBundleSize, checkThreshold, classifyError, clearAuditLog, compareBundles, compareVersionVitals, compareVitalsTrend, computeStatusDiff, consumeProductPurchase, convertRegionPrices, createAuditEntry, createDeviceTier, createEnterpriseApp, createExternalTransaction, createGrant, createInAppProduct, createOffer, createOneTimeOffer, createOneTimeProduct, createRecoveryAction, createSpinner, createSubscription, createTrack, createTranslator, deactivateBasePlan, deactivateOffer, decodeNotification, defaultGitRunner, deferSubscriptionPurchase, deferSubscriptionV2, deleteBasePlan, deleteGrant, deleteImage, deleteInAppProduct, deleteListing, deleteOffer, deleteOneTimeOffer, deleteOneTimeProduct, deleteSubscription, deployRecoveryAction, detectFastlane, detectOutputFormat, diffListings, diffListingsCommand, diffListingsEnhanced, diffOneTimeProduct, diffReleases, diffSubscription, discoverPlugins, downloadGeneratedApk, downloadReport, exportImages, exportReviews, fetchAggregateCost, fetchChangelog, fetchReleaseNotes, formatChangelogEntry, formatCustomPayload, formatDiscordPayload, formatJunit, formatNotification, formatOutput, formatPathLabel, formatSlackPayload, formatStatusDiff, formatStatusSummary, formatStatusTable, formatWordDiff, generateChangelog, generateMigrationPlan, generateNotesFromGit, getAllScannerNames, getAppInfo, getAppStatus, getCountryAvailability, getDeviceTier, getExternalTransaction, getInAppProduct, getListings, getOffer, getOneTimeOffer, getOneTimeProduct, getOrderDetails, getProductPurchase, getProductPurchaseV2, getQuotaUsage, getReleasesStatus, getReview, getRtdnStatus, getSubscription, getSubscriptionAnalytics, getSubscriptionPurchase, getTrainStatus, getUser, getVitalsAnomalies, getVitalsAnr, getVitalsBattery, getVitalsCrashes, getVitalsErrorCount, getVitalsLmk, getVitalsMemory, getVitalsOverview, getVitalsRendering, getVitalsStartup, importDataSafety, importTestersFromCsv, initAudit, initProject, inviteUser, isFinancialReportType, isStatsReportType, isValidBcp47, isValidReportType, isValidStatsDimension, lintListing, lintListings, lintLocalListings, listAchievements, listAuditEvents, listDeviceTiers, listEvents, listGeneratedApks, listGrants, listImages, listInAppProducts, listLeaderboards, listOffers, listOneTimeOffers, listOneTimeProducts, listRecoveryActions, listReports, listReviews, listSubscriptions, listTesters, listTracks, listUsers, listVoidedPurchases, loadPreflightConfig, loadStatusCache, maybePaginate, migratePrices, parseAppfile, parseCommit, parseFastfile, parseGrantArg, parseMonth, parseRemoteUrl, pauseTrain, promoteRelease, publish, publishEnterpriseApp, pullListings, pushListings, readListingsFromDir, readReleaseNotesFromDir, redactAuditArgs, redactSensitive, refundExternalTransaction, refundOrder, relativeTime, removeTesters, removeUser, renderJson, renderMarkdown, renderPlayStore, renderPlayStoreJson, renderPlayStoreMd, renderPlayStorePrompt, renderPrompt, replyToReview, resolveAiConfig, resolveLocales, revokeSubscriptionPurchase, runPreflight, runWatchLoop, safePath, safePathWithin, saveStatusCache, scaffoldPlugin, searchAuditEvents, searchVitalsErrors, sendNotification, sendWebhook, sortResults, startTrain, statusHasBreach, syncInAppProducts, topFiles, trackBreachState, translateBundle, updateAppDetails, updateDataSafety, updateGrant, updateInAppProduct, updateListing, updateOffer, updateOneTimeOffer, updateOneTimeProduct, updateRollout, updateSubscription, updateTrackConfig, updateUser, uploadExternallyHosted, uploadImage, uploadInternalSharing, uploadRelease, validateBundleForApply, validateImage, validateLanguageCode, validatePackageName, validatePreSubmission, validateReleaseNotes, validateSku, validateTrackName, validateUploadFile, validateVersionCode, waitForBundleProcessing, watchVitalsWithAutoHalt, wordDiff, writeAuditLog, writeListingsToDir, writeMigrationOutput };
|
package/dist/index.js
CHANGED
|
@@ -650,6 +650,20 @@ function formatSize(bytes) {
|
|
|
650
650
|
}
|
|
651
651
|
|
|
652
652
|
// src/commands/releases.ts
|
|
653
|
+
var BUNDLE_POLL_BACKOFF = [2e3, 3e3, 5e3, 8e3, 13e3];
|
|
654
|
+
async function waitForBundleProcessing(client, packageName, editId, versionCode, backoff = BUNDLE_POLL_BACKOFF) {
|
|
655
|
+
for (let i = 0; i < backoff.length; i++) {
|
|
656
|
+
const bundles = await client.bundles.list(packageName, editId);
|
|
657
|
+
if (bundles.some((b) => b.versionCode === versionCode)) return;
|
|
658
|
+
await new Promise((r) => setTimeout(r, backoff[i]));
|
|
659
|
+
}
|
|
660
|
+
throw new GpcError(
|
|
661
|
+
`Bundle versionCode ${versionCode} not ready after ${backoff.length} poll attempts (~${Math.round(backoff.reduce((a, b) => a + b, 0) / 1e3)}s)`,
|
|
662
|
+
"BUNDLE_PROCESSING_TIMEOUT",
|
|
663
|
+
4,
|
|
664
|
+
"The AAB is still being processed by Google. Retry the upload, or use --status draft and commit later."
|
|
665
|
+
);
|
|
666
|
+
}
|
|
653
667
|
async function withRetryOnConflict(client, packageName, operation) {
|
|
654
668
|
const edit = await client.edits.insert(packageName);
|
|
655
669
|
try {
|
|
@@ -763,6 +777,9 @@ ${validation.errors.join("\n")}`,
|
|
|
763
777
|
uploadOpts,
|
|
764
778
|
options.deviceTierConfigId
|
|
765
779
|
);
|
|
780
|
+
if (!isApk) {
|
|
781
|
+
await waitForBundleProcessing(client, packageName, edit.id, bundle.versionCode);
|
|
782
|
+
}
|
|
766
783
|
if (options.mappingFile) {
|
|
767
784
|
await client.deobfuscation.upload(
|
|
768
785
|
packageName,
|
|
@@ -1023,6 +1040,35 @@ async function fetchReleaseNotes(client, packageName, track) {
|
|
|
1023
1040
|
});
|
|
1024
1041
|
}
|
|
1025
1042
|
}
|
|
1043
|
+
async function applyReleaseNotes(client, packageName, track, releaseNotes, commitOptions) {
|
|
1044
|
+
return withRetryOnConflict(client, packageName, async (edit) => {
|
|
1045
|
+
const trackData = await client.tracks.get(packageName, edit.id, track);
|
|
1046
|
+
const draft = trackData.releases?.find((r) => r.status === "draft");
|
|
1047
|
+
if (!draft) {
|
|
1048
|
+
throw new GpcError(
|
|
1049
|
+
`No draft release found on track "${track}"`,
|
|
1050
|
+
"RELEASE_NO_DRAFT",
|
|
1051
|
+
1,
|
|
1052
|
+
`Upload an AAB/APK first to create a draft, or check the --track value. Current track: "${track}".`
|
|
1053
|
+
);
|
|
1054
|
+
}
|
|
1055
|
+
const patched = {
|
|
1056
|
+
...draft,
|
|
1057
|
+
releaseNotes
|
|
1058
|
+
};
|
|
1059
|
+
await client.tracks.update(packageName, edit.id, track, patched);
|
|
1060
|
+
if (!commitOptions?.changesNotSentForReview) {
|
|
1061
|
+
await client.edits.validate(packageName, edit.id);
|
|
1062
|
+
}
|
|
1063
|
+
await client.edits.commit(packageName, edit.id, commitOptions);
|
|
1064
|
+
return {
|
|
1065
|
+
track,
|
|
1066
|
+
versionCodes: draft.versionCodes || [],
|
|
1067
|
+
localeCount: releaseNotes.length,
|
|
1068
|
+
releaseNotes
|
|
1069
|
+
};
|
|
1070
|
+
});
|
|
1071
|
+
}
|
|
1026
1072
|
async function diffReleases(client, packageName, fromTrack, toTrack) {
|
|
1027
1073
|
const edit = await client.edits.insert(packageName);
|
|
1028
1074
|
try {
|
|
@@ -7377,7 +7423,16 @@ var KNOWN_TYPES = /* @__PURE__ */ new Set([
|
|
|
7377
7423
|
"release"
|
|
7378
7424
|
]);
|
|
7379
7425
|
var FILTERED_TYPES = /* @__PURE__ */ new Set(["chore", "refactor", "test", "build", "style", "merge"]);
|
|
7380
|
-
var SECTION_ORDER = [
|
|
7426
|
+
var SECTION_ORDER = [
|
|
7427
|
+
"breaking",
|
|
7428
|
+
"feat",
|
|
7429
|
+
"fix",
|
|
7430
|
+
"perf",
|
|
7431
|
+
"docs",
|
|
7432
|
+
"ci",
|
|
7433
|
+
"release",
|
|
7434
|
+
"other"
|
|
7435
|
+
];
|
|
7381
7436
|
var FIXUP_PATTERNS = [
|
|
7382
7437
|
/^wip\b/i,
|
|
7383
7438
|
/^fix\s+typo\b/i,
|
|
@@ -7841,14 +7896,18 @@ function renderPrompt(g) {
|
|
|
7841
7896
|
if (g.headlineCandidates.length > 0) {
|
|
7842
7897
|
lines.push("HEADLINE CANDIDATES (largest first):");
|
|
7843
7898
|
for (const c of g.headlineCandidates) {
|
|
7844
|
-
lines.push(
|
|
7899
|
+
lines.push(
|
|
7900
|
+
` ${c.label} (weight ${c.weight}, ${c.commits.length} commits, primary ${c.primaryType})`
|
|
7901
|
+
);
|
|
7845
7902
|
}
|
|
7846
7903
|
lines.push("");
|
|
7847
7904
|
}
|
|
7848
7905
|
lines.push("CLUSTERED COMMITS:");
|
|
7849
7906
|
lines.push("");
|
|
7850
7907
|
for (const cluster of g.clusters) {
|
|
7851
|
-
lines.push(
|
|
7908
|
+
lines.push(
|
|
7909
|
+
`[cluster: ${cluster.label}, weight ${cluster.weight}, ${cluster.commits.length} commits, primary ${cluster.primaryType}]`
|
|
7910
|
+
);
|
|
7852
7911
|
for (const commit of cluster.commits) {
|
|
7853
7912
|
lines.push(`- ${commit.type}: ${safeLine(commit.subject)} (${commit.sha.slice(0, 7)})`);
|
|
7854
7913
|
if (commit.files.length > 0) {
|
|
@@ -7881,9 +7940,179 @@ function renderPrompt(g) {
|
|
|
7881
7940
|
return lines.join("\n");
|
|
7882
7941
|
}
|
|
7883
7942
|
|
|
7943
|
+
// src/commands/changelog-ai.ts
|
|
7944
|
+
import { randomUUID } from "crypto";
|
|
7945
|
+
var PROVIDER_WHITELIST = ["anthropic", "openai", "google"];
|
|
7946
|
+
var DEFAULT_MODELS = {
|
|
7947
|
+
anthropic: "claude-sonnet-4-6",
|
|
7948
|
+
openai: "gpt-4o-mini",
|
|
7949
|
+
google: "gemini-2.5-flash"
|
|
7950
|
+
};
|
|
7951
|
+
function resolveAiConfig(opts = {}) {
|
|
7952
|
+
const env = opts.env ?? process.env;
|
|
7953
|
+
const hasGateway = typeof env["AI_GATEWAY_API_KEY"] === "string" && env["AI_GATEWAY_API_KEY"].length > 0;
|
|
7954
|
+
let provider;
|
|
7955
|
+
if (opts.provider) {
|
|
7956
|
+
const normalized = opts.provider.toLowerCase();
|
|
7957
|
+
if (!PROVIDER_WHITELIST.includes(normalized)) {
|
|
7958
|
+
throw new GpcError(
|
|
7959
|
+
`Unknown --provider "${opts.provider}"`,
|
|
7960
|
+
"CHANGELOG_AI_UNKNOWN_PROVIDER",
|
|
7961
|
+
2,
|
|
7962
|
+
`Valid providers: ${PROVIDER_WHITELIST.join(", ")}`
|
|
7963
|
+
);
|
|
7964
|
+
}
|
|
7965
|
+
provider = normalized;
|
|
7966
|
+
} else if (hasGateway || env["ANTHROPIC_API_KEY"]) {
|
|
7967
|
+
provider = "anthropic";
|
|
7968
|
+
} else if (env["OPENAI_API_KEY"]) {
|
|
7969
|
+
provider = "openai";
|
|
7970
|
+
} else if (env["GOOGLE_GENERATIVE_AI_API_KEY"]) {
|
|
7971
|
+
provider = "google";
|
|
7972
|
+
} else {
|
|
7973
|
+
throw new GpcError(
|
|
7974
|
+
"No AI provider credentials found in env",
|
|
7975
|
+
"CHANGELOG_AI_NO_CREDENTIALS",
|
|
7976
|
+
3,
|
|
7977
|
+
"Set one of: AI_GATEWAY_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY."
|
|
7978
|
+
);
|
|
7979
|
+
}
|
|
7980
|
+
const model = opts.model ?? DEFAULT_MODELS[provider];
|
|
7981
|
+
const path = hasGateway ? "gateway" : "direct";
|
|
7982
|
+
const runId = randomUUID();
|
|
7983
|
+
return { path, provider, model, runId };
|
|
7984
|
+
}
|
|
7985
|
+
function classifyError(err) {
|
|
7986
|
+
if (!err || typeof err !== "object") return "unknown";
|
|
7987
|
+
const e = err;
|
|
7988
|
+
const name = typeof e["name"] === "string" ? e["name"] : "";
|
|
7989
|
+
const statusCode = typeof e["statusCode"] === "number" ? e["statusCode"] : typeof e["status"] === "number" ? e["status"] : 0;
|
|
7990
|
+
const message = typeof e["message"] === "string" ? e["message"].toLowerCase() : "";
|
|
7991
|
+
const finishReason = typeof e["finishReason"] === "string" ? e["finishReason"] : "";
|
|
7992
|
+
if (name === "RateLimitError" || statusCode === 429 || statusCode === 529) return "rate_limited";
|
|
7993
|
+
if (statusCode === 401 || statusCode === 403) return "auth";
|
|
7994
|
+
if (message.includes("api key invalid") || message.includes("invalid api key")) return "auth";
|
|
7995
|
+
if (finishReason === "SAFETY") return "safety_blocked";
|
|
7996
|
+
if (statusCode === 400 && (message.includes("content_policy") || message.includes("content policy") || message.includes("safety"))) {
|
|
7997
|
+
return "safety_blocked";
|
|
7998
|
+
}
|
|
7999
|
+
if (name === "AbortError" || name === "TimeoutError") return "timeout";
|
|
8000
|
+
if (message.includes("timeout") || message.includes("timed out")) return "timeout";
|
|
8001
|
+
if (message.includes("econnrefused") || message.includes("enotfound") || message.includes("etimedout") || message.includes("network") || name === "TypeError" && message.includes("fetch")) {
|
|
8002
|
+
return "network";
|
|
8003
|
+
}
|
|
8004
|
+
return "unknown";
|
|
8005
|
+
}
|
|
8006
|
+
function buildSystemPrompt() {
|
|
8007
|
+
return [
|
|
8008
|
+
`You translate Play Store "What's new" release notes for Android apps.`,
|
|
8009
|
+
"Rules:",
|
|
8010
|
+
"- Translation MUST be at most 500 Unicode code points.",
|
|
8011
|
+
'- Preserve bullet format (one item per line, starts with "- ").',
|
|
8012
|
+
"- User-facing tone. Avoid internal jargon.",
|
|
8013
|
+
'- Do not translate technical names (package names, CLI flags, "GPC").',
|
|
8014
|
+
"- Drop the conventional-commit prefix (feat:/fix:/docs:) if it feels unnatural in the target language.",
|
|
8015
|
+
"Respond with the translated text only. No explanations, no markdown headings."
|
|
8016
|
+
].join("\n");
|
|
8017
|
+
}
|
|
8018
|
+
function buildUserPrompt(locale, sourceText) {
|
|
8019
|
+
return `Translate the following release notes into ${locale}:
|
|
8020
|
+
|
|
8021
|
+
${sourceText}`;
|
|
8022
|
+
}
|
|
8023
|
+
function providerSpecificOptions(provider) {
|
|
8024
|
+
if (provider === "google") {
|
|
8025
|
+
return { google: { thinkingConfig: { thinkingBudget: 0 } } };
|
|
8026
|
+
}
|
|
8027
|
+
return {};
|
|
8028
|
+
}
|
|
8029
|
+
function readUsage(usage) {
|
|
8030
|
+
if (!usage || typeof usage !== "object") return { tokensIn: 0, tokensOut: 0 };
|
|
8031
|
+
const u = usage;
|
|
8032
|
+
const tokensIn = typeof u["inputTokens"] === "number" ? u["inputTokens"] : typeof u["promptTokens"] === "number" ? u["promptTokens"] : 0;
|
|
8033
|
+
const tokensOut = typeof u["outputTokens"] === "number" ? u["outputTokens"] : typeof u["completionTokens"] === "number" ? u["completionTokens"] : 0;
|
|
8034
|
+
return { tokensIn, tokensOut };
|
|
8035
|
+
}
|
|
8036
|
+
async function createTranslator(config) {
|
|
8037
|
+
const ai = await import("ai");
|
|
8038
|
+
const generateText = ai.generateText;
|
|
8039
|
+
if (config.path === "gateway") {
|
|
8040
|
+
const modelString = `${config.provider}/${config.model}`;
|
|
8041
|
+
return async (locale, sourceText) => {
|
|
8042
|
+
const result = await generateText({
|
|
8043
|
+
model: ai.gateway(modelString),
|
|
8044
|
+
system: buildSystemPrompt(),
|
|
8045
|
+
prompt: buildUserPrompt(locale, sourceText),
|
|
8046
|
+
temperature: 0.2,
|
|
8047
|
+
providerOptions: {
|
|
8048
|
+
gateway: { tags: [`gpc-changelog-${config.runId}`] },
|
|
8049
|
+
...providerSpecificOptions(config.provider)
|
|
8050
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8051
|
+
}
|
|
8052
|
+
});
|
|
8053
|
+
const { tokensIn, tokensOut } = readUsage(result.usage);
|
|
8054
|
+
return { text: result.text, tokensIn, tokensOut };
|
|
8055
|
+
};
|
|
8056
|
+
}
|
|
8057
|
+
let modelFactory;
|
|
8058
|
+
if (config.provider === "anthropic") {
|
|
8059
|
+
const mod = await import("@ai-sdk/anthropic");
|
|
8060
|
+
modelFactory = (id) => mod.anthropic(id);
|
|
8061
|
+
} else if (config.provider === "openai") {
|
|
8062
|
+
const mod = await import("@ai-sdk/openai");
|
|
8063
|
+
modelFactory = (id) => mod.openai(id);
|
|
8064
|
+
} else {
|
|
8065
|
+
const mod = await import("@ai-sdk/google");
|
|
8066
|
+
modelFactory = (id) => mod.google(id);
|
|
8067
|
+
}
|
|
8068
|
+
return async (locale, sourceText) => {
|
|
8069
|
+
const result = await generateText({
|
|
8070
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8071
|
+
model: modelFactory(config.model),
|
|
8072
|
+
system: buildSystemPrompt(),
|
|
8073
|
+
prompt: buildUserPrompt(locale, sourceText),
|
|
8074
|
+
temperature: 0.2,
|
|
8075
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8076
|
+
providerOptions: providerSpecificOptions(config.provider)
|
|
8077
|
+
});
|
|
8078
|
+
const { tokensIn, tokensOut } = readUsage(result.usage);
|
|
8079
|
+
return { text: result.text, tokensIn, tokensOut };
|
|
8080
|
+
};
|
|
8081
|
+
}
|
|
8082
|
+
async function fetchAggregateCost(runId) {
|
|
8083
|
+
try {
|
|
8084
|
+
const { gateway } = await import("ai");
|
|
8085
|
+
const now = /* @__PURE__ */ new Date();
|
|
8086
|
+
const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1e3);
|
|
8087
|
+
const today = now.toISOString().slice(0, 10);
|
|
8088
|
+
const startDate = yesterday.toISOString().slice(0, 10);
|
|
8089
|
+
const report = await gateway.getSpendReport({
|
|
8090
|
+
startDate,
|
|
8091
|
+
endDate: today,
|
|
8092
|
+
groupBy: "tag",
|
|
8093
|
+
tags: [`gpc-changelog-${runId}`]
|
|
8094
|
+
});
|
|
8095
|
+
const results = report.results ?? [];
|
|
8096
|
+
return results.reduce((sum, row) => sum + (row.totalCost ?? 0), 0);
|
|
8097
|
+
} catch {
|
|
8098
|
+
return void 0;
|
|
8099
|
+
}
|
|
8100
|
+
}
|
|
8101
|
+
var PROVIDER_BRAND = {
|
|
8102
|
+
anthropic: "Anthropic",
|
|
8103
|
+
openai: "OpenAI",
|
|
8104
|
+
google: "Google"
|
|
8105
|
+
};
|
|
8106
|
+
function formatPathLabel(config) {
|
|
8107
|
+
if (config.path === "gateway") {
|
|
8108
|
+
return `routing via AI Gateway (${config.provider}/${config.model})`;
|
|
8109
|
+
}
|
|
8110
|
+
return `direct ${PROVIDER_BRAND[config.provider]} SDK (${config.model})`;
|
|
8111
|
+
}
|
|
8112
|
+
|
|
7884
8113
|
// src/commands/changelog-renderers/play-store.ts
|
|
7885
8114
|
var PLAY_STORE_LIMIT = 500;
|
|
7886
|
-
var PLACEHOLDER_TEXT = "[needs translation \u2014 pass --ai
|
|
8115
|
+
var PLACEHOLDER_TEXT = "[needs translation \u2014 pass --ai, or paste the prompt emitted by --format prompt]";
|
|
7887
8116
|
function safeLine2(s) {
|
|
7888
8117
|
return s.replace(/[\r\n]+/g, " ").trim();
|
|
7889
8118
|
}
|
|
@@ -7989,7 +8218,9 @@ function renderPlayStorePrompt(bundle, g) {
|
|
|
7989
8218
|
const source = bundle.locales.find((e) => e.language === bundle.sourceLanguage);
|
|
7990
8219
|
const targets = bundle.locales.filter((e) => e.language !== bundle.sourceLanguage);
|
|
7991
8220
|
const lines = [];
|
|
7992
|
-
lines.push(
|
|
8221
|
+
lines.push(
|
|
8222
|
+
`You are translating Play Store "What's new" release notes from ${bundle.sourceLanguage}.`
|
|
8223
|
+
);
|
|
7993
8224
|
lines.push("");
|
|
7994
8225
|
lines.push("TARGETS:");
|
|
7995
8226
|
for (const t of targets) lines.push(` - ${t.language}`);
|
|
@@ -8000,7 +8231,9 @@ function renderPlayStorePrompt(bundle, g) {
|
|
|
8000
8231
|
lines.push('- Preserve the bullet format (one item per line, starts with "- ")');
|
|
8001
8232
|
lines.push("- Keep a user-facing tone (no internal jargon)");
|
|
8002
8233
|
lines.push('- Do not translate technical names (package names, CLI flags, "GPC")');
|
|
8003
|
-
lines.push(
|
|
8234
|
+
lines.push(
|
|
8235
|
+
"- Drop the conventional-commit prefix (feat:/fix:) if it feels unnatural in the target language"
|
|
8236
|
+
);
|
|
8004
8237
|
lines.push("");
|
|
8005
8238
|
lines.push(`SOURCE (${bundle.sourceLanguage}, ${source?.chars ?? 0}/${bundle.limit} chars):`);
|
|
8006
8239
|
lines.push("```");
|
|
@@ -8038,6 +8271,103 @@ function renderPlayStore(g, opts) {
|
|
|
8038
8271
|
return { output: renderPlayStorePrompt(bundle, g), bundle };
|
|
8039
8272
|
}
|
|
8040
8273
|
}
|
|
8274
|
+
async function translateBundle(bundle, options) {
|
|
8275
|
+
const source = bundle.locales.find((e) => e.language === bundle.sourceLanguage);
|
|
8276
|
+
const sourceText = source?.text ?? "";
|
|
8277
|
+
const hasSource = source !== void 0 && sourceText.trim().length > 0;
|
|
8278
|
+
let tokensIn = 0;
|
|
8279
|
+
let tokensOut = 0;
|
|
8280
|
+
const failures = [];
|
|
8281
|
+
const newLocales = [];
|
|
8282
|
+
for (const entry of bundle.locales) {
|
|
8283
|
+
if (entry.status !== "placeholder") {
|
|
8284
|
+
newLocales.push(entry);
|
|
8285
|
+
continue;
|
|
8286
|
+
}
|
|
8287
|
+
if (!hasSource) {
|
|
8288
|
+
const failure = { language: entry.language, reason: "no_source" };
|
|
8289
|
+
failures.push(failure);
|
|
8290
|
+
options.onError?.(failure, new Error("source locale missing or empty"));
|
|
8291
|
+
const failedText = `[translation failed: no_source]`;
|
|
8292
|
+
newLocales.push({
|
|
8293
|
+
language: entry.language,
|
|
8294
|
+
text: failedText,
|
|
8295
|
+
chars: countChars(failedText),
|
|
8296
|
+
limit: PLAY_STORE_LIMIT,
|
|
8297
|
+
status: "failed"
|
|
8298
|
+
});
|
|
8299
|
+
continue;
|
|
8300
|
+
}
|
|
8301
|
+
try {
|
|
8302
|
+
const result = await options.translator(entry.language, sourceText);
|
|
8303
|
+
tokensIn += result.tokensIn;
|
|
8304
|
+
tokensOut += result.tokensOut;
|
|
8305
|
+
let text = result.text.trim();
|
|
8306
|
+
let chars = countChars(text);
|
|
8307
|
+
let status = "ok";
|
|
8308
|
+
if (chars > PLAY_STORE_LIMIT) {
|
|
8309
|
+
text = truncateToLimit(text, PLAY_STORE_LIMIT);
|
|
8310
|
+
chars = countChars(text);
|
|
8311
|
+
status = "over";
|
|
8312
|
+
}
|
|
8313
|
+
const translated2 = {
|
|
8314
|
+
language: entry.language,
|
|
8315
|
+
text,
|
|
8316
|
+
chars,
|
|
8317
|
+
limit: PLAY_STORE_LIMIT,
|
|
8318
|
+
status
|
|
8319
|
+
};
|
|
8320
|
+
newLocales.push(translated2);
|
|
8321
|
+
options.onTranslated?.(translated2);
|
|
8322
|
+
} catch (err) {
|
|
8323
|
+
const reason = classifyError(err);
|
|
8324
|
+
const failure = { language: entry.language, reason };
|
|
8325
|
+
failures.push(failure);
|
|
8326
|
+
options.onError?.(failure, err);
|
|
8327
|
+
const failedText = `[translation failed: ${reason}]`;
|
|
8328
|
+
newLocales.push({
|
|
8329
|
+
language: entry.language,
|
|
8330
|
+
text: failedText,
|
|
8331
|
+
chars: countChars(failedText),
|
|
8332
|
+
limit: PLAY_STORE_LIMIT,
|
|
8333
|
+
status: "failed"
|
|
8334
|
+
});
|
|
8335
|
+
}
|
|
8336
|
+
}
|
|
8337
|
+
const overflows = newLocales.filter((e) => e.status === "over").map((e) => e.language);
|
|
8338
|
+
const translated = {
|
|
8339
|
+
...bundle,
|
|
8340
|
+
locales: newLocales,
|
|
8341
|
+
overflows,
|
|
8342
|
+
tokensIn,
|
|
8343
|
+
tokensOut,
|
|
8344
|
+
failures
|
|
8345
|
+
};
|
|
8346
|
+
if (options.strict && failures.length > 0) {
|
|
8347
|
+
throw new GpcError(
|
|
8348
|
+
`${failures.length} locale${failures.length === 1 ? "" : "s"} failed to translate: ${failures.map((f) => `${f.language}=${f.reason}`).join(", ")}`,
|
|
8349
|
+
"CHANGELOG_AI_TRANSLATION_FAILED",
|
|
8350
|
+
1,
|
|
8351
|
+
"Remove --strict to continue on errors, or check credentials and retry."
|
|
8352
|
+
);
|
|
8353
|
+
}
|
|
8354
|
+
return translated;
|
|
8355
|
+
}
|
|
8356
|
+
function validateBundleForApply(bundle) {
|
|
8357
|
+
const errors = [];
|
|
8358
|
+
for (const entry of bundle.locales) {
|
|
8359
|
+
if (entry.status === "placeholder") {
|
|
8360
|
+
errors.push(`${entry.language}: untranslated placeholder \u2014 use --ai or remove this locale`);
|
|
8361
|
+
}
|
|
8362
|
+
if (entry.status === "failed") {
|
|
8363
|
+
errors.push(`${entry.language}: translation failed \u2014 retry or remove this locale`);
|
|
8364
|
+
}
|
|
8365
|
+
}
|
|
8366
|
+
return errors;
|
|
8367
|
+
}
|
|
8368
|
+
function bundleToReleaseNotes(bundle) {
|
|
8369
|
+
return bundle.locales.filter((e) => e.status !== "placeholder" && e.status !== "failed").map((e) => ({ language: e.language, text: e.text }));
|
|
8370
|
+
}
|
|
8041
8371
|
|
|
8042
8372
|
// src/commands/changelog-renderers/index.ts
|
|
8043
8373
|
var RENDERERS = {
|
|
@@ -8204,6 +8534,7 @@ export {
|
|
|
8204
8534
|
ApiError,
|
|
8205
8535
|
ConfigError,
|
|
8206
8536
|
DEFAULT_LIMITS,
|
|
8537
|
+
DEFAULT_MODELS,
|
|
8207
8538
|
DEFAULT_PREFLIGHT_CONFIG,
|
|
8208
8539
|
GOOGLE_PLAY_LANGUAGES,
|
|
8209
8540
|
GpcError,
|
|
@@ -8211,6 +8542,7 @@ export {
|
|
|
8211
8542
|
PERMISSION_PROPAGATION_WARNING,
|
|
8212
8543
|
PLACEHOLDER_TEXT,
|
|
8213
8544
|
PLAY_STORE_LIMIT,
|
|
8545
|
+
PROVIDER_WHITELIST,
|
|
8214
8546
|
PluginManager,
|
|
8215
8547
|
RENDERERS,
|
|
8216
8548
|
SECTION_ORDER,
|
|
@@ -8227,14 +8559,17 @@ export {
|
|
|
8227
8559
|
analyzeBundle,
|
|
8228
8560
|
analyzeRemoteListings,
|
|
8229
8561
|
analyzeReviews2 as analyzeReviews,
|
|
8562
|
+
applyReleaseNotes,
|
|
8230
8563
|
batchGetOrders,
|
|
8231
8564
|
batchSyncInAppProducts,
|
|
8232
8565
|
buildLocaleBundle,
|
|
8566
|
+
bundleToReleaseNotes,
|
|
8233
8567
|
cancelRecoveryAction,
|
|
8234
8568
|
cancelSubscriptionPurchase,
|
|
8235
8569
|
cancelSubscriptionV2,
|
|
8236
8570
|
checkBundleSize,
|
|
8237
8571
|
checkThreshold,
|
|
8572
|
+
classifyError,
|
|
8238
8573
|
clearAuditLog,
|
|
8239
8574
|
compareBundles,
|
|
8240
8575
|
compareVersionVitals,
|
|
@@ -8255,6 +8590,7 @@ export {
|
|
|
8255
8590
|
createSpinner,
|
|
8256
8591
|
createSubscription,
|
|
8257
8592
|
createTrack,
|
|
8593
|
+
createTranslator,
|
|
8258
8594
|
deactivateBasePlan,
|
|
8259
8595
|
deactivateOffer,
|
|
8260
8596
|
decodeNotification,
|
|
@@ -8284,6 +8620,7 @@ export {
|
|
|
8284
8620
|
downloadReport,
|
|
8285
8621
|
exportImages,
|
|
8286
8622
|
exportReviews,
|
|
8623
|
+
fetchAggregateCost,
|
|
8287
8624
|
fetchChangelog,
|
|
8288
8625
|
fetchReleaseNotes,
|
|
8289
8626
|
formatChangelogEntry,
|
|
@@ -8292,6 +8629,7 @@ export {
|
|
|
8292
8629
|
formatJunit,
|
|
8293
8630
|
formatNotification,
|
|
8294
8631
|
formatOutput,
|
|
8632
|
+
formatPathLabel,
|
|
8295
8633
|
formatSlackPayload,
|
|
8296
8634
|
formatStatusDiff,
|
|
8297
8635
|
formatStatusSummary,
|
|
@@ -8399,6 +8737,7 @@ export {
|
|
|
8399
8737
|
renderPlayStorePrompt,
|
|
8400
8738
|
renderPrompt,
|
|
8401
8739
|
replyToReview,
|
|
8740
|
+
resolveAiConfig,
|
|
8402
8741
|
resolveLocales,
|
|
8403
8742
|
revokeSubscriptionPurchase,
|
|
8404
8743
|
runPreflight,
|
|
@@ -8417,6 +8756,7 @@ export {
|
|
|
8417
8756
|
syncInAppProducts,
|
|
8418
8757
|
topFiles,
|
|
8419
8758
|
trackBreachState,
|
|
8759
|
+
translateBundle,
|
|
8420
8760
|
updateAppDetails,
|
|
8421
8761
|
updateDataSafety,
|
|
8422
8762
|
updateGrant,
|
|
@@ -8433,6 +8773,7 @@ export {
|
|
|
8433
8773
|
uploadImage,
|
|
8434
8774
|
uploadInternalSharing,
|
|
8435
8775
|
uploadRelease,
|
|
8776
|
+
validateBundleForApply,
|
|
8436
8777
|
validateImage,
|
|
8437
8778
|
validateLanguageCode,
|
|
8438
8779
|
validatePackageName,
|
|
@@ -8442,6 +8783,7 @@ export {
|
|
|
8442
8783
|
validateTrackName,
|
|
8443
8784
|
validateUploadFile,
|
|
8444
8785
|
validateVersionCode,
|
|
8786
|
+
waitForBundleProcessing,
|
|
8445
8787
|
watchVitalsWithAutoHalt,
|
|
8446
8788
|
wordDiff,
|
|
8447
8789
|
writeAuditLog,
|