@gpc-cli/core 0.10.7 → 0.11.0
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/index.d.ts +9 -1
- package/dist/index.js +185 -16
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1368,6 +1368,8 @@ interface ParsedManifest {
|
|
|
1368
1368
|
services: ManifestComponent[];
|
|
1369
1369
|
receivers: ManifestComponent[];
|
|
1370
1370
|
providers: ManifestComponent[];
|
|
1371
|
+
/** `<meta-data>` entries of `<application>`, name to value. Entries without a value are omitted. */
|
|
1372
|
+
metaData: Record<string, string>;
|
|
1371
1373
|
/** Android 16+ compat shim for non-16KB-aligned native libs. */
|
|
1372
1374
|
pageSizeCompat?: boolean;
|
|
1373
1375
|
/** Set when the manifest could not be fully parsed -- manifest-dependent scanners should skip. */
|
|
@@ -1668,6 +1670,12 @@ declare function runWatchLoop(opts: WatchOptions): Promise<void>;
|
|
|
1668
1670
|
/** Returns true if breach state changed (breach started or cleared). */
|
|
1669
1671
|
declare function trackBreachState(packageName: string, isBreaching: boolean): Promise<boolean>;
|
|
1670
1672
|
declare function sendNotification(title: string, body: string): void;
|
|
1673
|
+
/**
|
|
1674
|
+
* Re-rates a saved status against the thresholds of the current run. A cached
|
|
1675
|
+
* status keeps the thresholds of the run that fetched it, so serving it as-is
|
|
1676
|
+
* would gate on values the caller never asked for.
|
|
1677
|
+
*/
|
|
1678
|
+
declare function applyVitalThresholds(status: AppStatus, vitalThresholds: GetAppStatusOptions["vitalThresholds"]): AppStatus;
|
|
1671
1679
|
declare function statusHasBreach(status: AppStatus): boolean;
|
|
1672
1680
|
|
|
1673
1681
|
interface ChangelogEntry {
|
|
@@ -2052,4 +2060,4 @@ declare function readinessBadgeColor(grade: ReadinessGrade): string;
|
|
|
2052
2060
|
declare function readinessBadgeUrl(score: ReadinessScore): string;
|
|
2053
2061
|
declare function readinessBadgeMarkdown(score: ReadinessScore): string;
|
|
2054
2062
|
|
|
2055
|
-
export { ApiError, type ApiSigningFingerprint, type AppInfo, type AppStatus, type ApplyReleaseNotesResult, type AuditEntry, type BatchSyncResult, type BundleAnalysis, type BundleComparison, type BundleEntry, type BundleSizeCheckResult, type BundleSizeConfig, type BundlesWaitOptions, type ChangelogEntry, type ChecklistInput, type ChecklistItem, type ChecklistResult, type CommandContext, type CommitCluster, type CommitResult, ConfigError, type CreateEnterpriseAppParams, DEFAULT_LIMITS, DEFAULT_MODELS, DEFAULT_PREFLIGHT_CONFIG, DEFAULT_WATCH_THRESHOLDS, type DecodedNotification, type DiffToken, type DiscoverPluginsOptions, type DiscoveredPlugin, type DryRunPublishResult, type DryRunResult, type DryRunUploadResult, type ErrorReason, type ExportImagesOptions, type ExportImagesSummary, type ExternalTransactionRefundOptions, type FastlaneDetection, type FastlaneLane, type FetchChangelogOptions, type FieldLintResult, type FileValidationResult, type FinancialReportDownload, type FindingSeverity, GOOGLE_PLAY_LANGUAGES, type GameConfigDiff, type GamesPushOptions, type GamesSyncResult, type GenerateOptions, type GeneratedChangelog, type GetAppStatusOptions, type GitNotesOptions, type GitReleaseNotes, type GitRunner, GpcError, type ImageSyncDetail, type ImageSyncOptions, type ImageSyncResult, type ImageValidationResult, type InitOptions, type InitResult, type InternalSharingUploadResult, type KeystoreFingerprint, type ListGamesConfigOptions, type ListIapOptions, type ListReportsResult, 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, REVIEW_SORT_PRESETS, type RawCommit, type ReadinessBreakdownEntry, type ReadinessGrade, type ReadinessScore, type ReadinessSignal, type ReadinessSignalStatus, type RefundReviewPreference, type ReleaseDiff, type ReleaseNotesValidation, type ReleaseStatusResult, type Renderer, type ReportObject, type ReportsAuth, type ResolveAiConfigOptions, type ResolveLocalesOptions, type ReviewAnalysis, type ReviewExportOptions, type ReviewOrderRefundOptions, type ReviewOrderRefundResult, type ReviewSortPreset, type ReviewsFilterOptions, type RevocationRefundType, type RtdnStatus, SECTION_ORDER, SENSITIVE_ARG_KEYS, SENSITIVE_KEYS, SEVERITY_ORDER, type ScaffoldOptions, type ScaffoldResult, type SigningConsistencyResult, type SigningKeyComparison, type Spinner, type StatsReportDownload, 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, VALID_WATCH_METRICS, type ValidateCheck, type ValidateOptions, type ValidateResult, type ValidatedPluginApproval, type VersionVitalsComparison, type VersionVitalsRow, type VitalsOverview, type VitalsQueryOptions, type VitalsTrendComparison, type WatchAction, type WatchCallbacks, type WatchConfig, type WatchEvent, type WatchMetric, type WatchOptions, type WatchRollout, type WatchSummary, type WatchVitalReading, type WatchVitalsOptions, type WebhookPayload, type ZipCsvEntry, abortTrain, acknowledgeProductPurchase, activateBasePlan, activateOffer, addRecoveryTargeting, addTesters, advanceTrain, analyzeBundle, analyzeRemoteListings, analyzeReviews, annotateListResult, applyReleaseNotes, assertRateThreshold, assignRelease, batchGetOrders, batchSyncInAppProducts, buildChecklist, buildExternalTransactionRefund, buildLocaleBundle, bundleToReleaseNotes, cancelRecoveryAction, cancelSubscriptionPurchase, cancelSubscriptionV2, checkBundleSize, checkSigningConsistency, checkThreshold, classifyError, clearAuditLog, commitWithRescue, compareBundles, compareFingerprints, compareVersionVitals, compareVitalsTrend, computeStatusDiff, consumeProductPurchase, convertRegionPrices, createAchievementConfig, createAuditEntry, createDeviceTier, createEnterpriseApp, createExternalTransaction, createGrant, createInAppProduct, createLeaderboardConfig, createOffer, createOneTimeOffer, createOneTimeProduct, createRecoveryAction, createSpinner, createSubscription, createTrack, createTranslator, deactivateBasePlan, deactivateOffer, decodeCsvText, decodeNotification, decodeStatsCsv, defaultGitRunner, deferSubscriptionPurchase, deferSubscriptionV2, deleteAchievementConfig, deleteBasePlan, deleteGrant, deleteImage, deleteInAppProduct, deleteLeaderboardConfig, deleteListing, deleteOffer, deleteOneTimeOffer, deleteOneTimeProduct, deleteSubscription, deployRecoveryAction, detectFastlane, detectOutputFormat, diffAchievementConfig, diffLeaderboardConfig, diffListings, diffListingsCommand, diffListingsEnhanced, diffOneTimeProduct, diffReleases, diffSubscription, discoverPluginEntries, discoverPlugins, dispatchWebhook, downloadFinancialReport, downloadGeneratedApk, downloadReportObject, downloadStatsReport, exportImages, exportReviews, extractCsvEntriesFromZip, fetchAggregateCost, fetchChangelog, fetchReleaseNotes, findBundle, formatChangelogEntry, formatCustomPayload, formatDiscordPayload, formatJunit, formatMoney, formatNotification, formatOutput, formatPathLabel, formatSlackPayload, formatStatusDiff, formatStatusSummary, formatStatusTable, formatWordDiff, generateChangelog, generateMigrationPlan, generateNotesFromGit, getAchievementConfig, getAllScannerNames, getApiSigningFingerprint, getAppInfo, getAppStatus, getCountryAvailability, getDeviceTier, getExternalTransaction, getInAppProduct, getKeystoreFingerprint, getLeaderboardConfig, getListings, getOffer, getOneTimeOffer, getOneTimeProduct, getOrderDetails, getProductPurchase, getProductPurchaseV2, getQuotaUsage, getReleasesStatus, getReview, getRtdnStatus, getSubscription, getSubscriptionAnalytics, getSubscriptionPurchase, getTrainStatus, getUser, getVitalsAnomalies, getVitalsAnr, getVitalsBattery, getVitalsCrashes, getVitalsErrorCount, getVitalsLmk, getVitalsMemory, getVitalsMemoryBitmap, getVitalsMemoryRss, getVitalsOverview, getVitalsRendering, getVitalsStartup, gradeFromPercent, gunzipIfNeeded, handleBreach, importDataSafety, importTestersFromCsv, initAudit, initProject, inviteUser, isFinancialReportType, isGzip, isStatsReportType, isValidBcp47, isValidReportType, isValidStatsDimension, isVersionedNotesDir, isZip, latestWorstValue, lintListing, lintListings, lintLocalListings, listAchievementConfigs, listAchievements, listAuditEvents, listBundles, listDeviceTiers, listGeneratedApks, listGrants, listImages, listInAppProducts, listLeaderboardConfigs, listLeaderboards, listOffers, listOneTimeOffers, listOneTimeProducts, listRecoveryActions, listReportObjects, listReports, listReviews, listSubscriptions, listTesters, listTracks, listUsers, listVoidedPurchases, loadPreflightConfig, loadStatusCache, maybePaginate, migratePrices, monthToken, moreResultsFooter, normalizeFingerprint, parseAppfile, parseCommit, parseFastfile, parseGrantArg, parseKeytoolOutput, parseMonth, parseRemoteUrl, pauseTrain, promoteRelease, publish, publishEnterpriseApp, pullAchievementConfigs, pullLeaderboardConfigs, pullListings, pushAchievementConfigs, pushLeaderboardConfigs, pushListings, readListingsFromDir, readMetricValue, readReleaseNotesForVersion, readReleaseNotesFromDir, readinessBadgeColor, readinessBadgeMarkdown, readinessBadgeUrl, redactAuditArgs, redactSensitive, refundExternalTransaction, refundOrder, relativeTime, removeTesters, removeUser, renderChecklistMarkdown, renderJson, renderMarkdown, renderPlayStore, renderPlayStoreJson, renderPlayStoreMd, renderPlayStorePrompt, renderPrompt, replyToReview, reportAccessDeniedError, reportBucketNotFoundError, reportObjectNotFoundError, reportPrefix, resolveAiConfig, resolveLocales, resolveReportsBucket, retryOnUploadNotComplete, reviewOrderRefund, revokeSubscriptionPurchase, runPreflight, runWatch, runWatchLoop, safePath, safePathWithin, saveStatusCache, scaffoldPlugin, scoreReadiness, searchAuditEvents, searchVitalsErrors, sendNotification, sendWebhook, setAchievementIcon, setLeaderboardIcon, sha256File, sortResults, sortReviews, startTrain, statusHasBreach, syncImages, syncInAppProducts, topFiles, trackBreachState, translateBundle, updateAchievementConfig, updateAppDetails, updateDataSafety, updateGrant, updateInAppProduct, updateLeaderboardConfig, updateListing, updateOffer, updateOneTimeOffer, updateOneTimeProduct, updateRollout, updateSubscription, updateTrackConfig, updateUser, uploadExternallyHosted, uploadImage, uploadInternalSharing, uploadRelease, validateAndCommit, validateBundleForApply, validateImage, validateLanguageCode, validatePackageName, validatePluginForApproval, validatePreSubmission, validateReleaseNotes, validateSku, validateTrackName, validateUploadFile, validateVersionCode, waitForBundle, waitForBundleProcessing, watchVitalsWithAutoHalt, wordDiff, worstSliceAverage, writeAuditLog, writeListingsToDir, writeMigrationOutput };
|
|
2063
|
+
export { ApiError, type ApiSigningFingerprint, type AppInfo, type AppStatus, type ApplyReleaseNotesResult, type AuditEntry, type BatchSyncResult, type BundleAnalysis, type BundleComparison, type BundleEntry, type BundleSizeCheckResult, type BundleSizeConfig, type BundlesWaitOptions, type ChangelogEntry, type ChecklistInput, type ChecklistItem, type ChecklistResult, type CommandContext, type CommitCluster, type CommitResult, ConfigError, type CreateEnterpriseAppParams, DEFAULT_LIMITS, DEFAULT_MODELS, DEFAULT_PREFLIGHT_CONFIG, DEFAULT_WATCH_THRESHOLDS, type DecodedNotification, type DiffToken, type DiscoverPluginsOptions, type DiscoveredPlugin, type DryRunPublishResult, type DryRunResult, type DryRunUploadResult, type ErrorReason, type ExportImagesOptions, type ExportImagesSummary, type ExternalTransactionRefundOptions, type FastlaneDetection, type FastlaneLane, type FetchChangelogOptions, type FieldLintResult, type FileValidationResult, type FinancialReportDownload, type FindingSeverity, GOOGLE_PLAY_LANGUAGES, type GameConfigDiff, type GamesPushOptions, type GamesSyncResult, type GenerateOptions, type GeneratedChangelog, type GetAppStatusOptions, type GitNotesOptions, type GitReleaseNotes, type GitRunner, GpcError, type ImageSyncDetail, type ImageSyncOptions, type ImageSyncResult, type ImageValidationResult, type InitOptions, type InitResult, type InternalSharingUploadResult, type KeystoreFingerprint, type ListGamesConfigOptions, type ListIapOptions, type ListReportsResult, 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, REVIEW_SORT_PRESETS, type RawCommit, type ReadinessBreakdownEntry, type ReadinessGrade, type ReadinessScore, type ReadinessSignal, type ReadinessSignalStatus, type RefundReviewPreference, type ReleaseDiff, type ReleaseNotesValidation, type ReleaseStatusResult, type Renderer, type ReportObject, type ReportsAuth, type ResolveAiConfigOptions, type ResolveLocalesOptions, type ReviewAnalysis, type ReviewExportOptions, type ReviewOrderRefundOptions, type ReviewOrderRefundResult, type ReviewSortPreset, type ReviewsFilterOptions, type RevocationRefundType, type RtdnStatus, SECTION_ORDER, SENSITIVE_ARG_KEYS, SENSITIVE_KEYS, SEVERITY_ORDER, type ScaffoldOptions, type ScaffoldResult, type SigningConsistencyResult, type SigningKeyComparison, type Spinner, type StatsReportDownload, 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, VALID_WATCH_METRICS, type ValidateCheck, type ValidateOptions, type ValidateResult, type ValidatedPluginApproval, type VersionVitalsComparison, type VersionVitalsRow, type VitalsOverview, type VitalsQueryOptions, type VitalsTrendComparison, type WatchAction, type WatchCallbacks, type WatchConfig, type WatchEvent, type WatchMetric, type WatchOptions, type WatchRollout, type WatchSummary, type WatchVitalReading, type WatchVitalsOptions, type WebhookPayload, type ZipCsvEntry, abortTrain, acknowledgeProductPurchase, activateBasePlan, activateOffer, addRecoveryTargeting, addTesters, advanceTrain, analyzeBundle, analyzeRemoteListings, analyzeReviews, annotateListResult, applyReleaseNotes, applyVitalThresholds, assertRateThreshold, assignRelease, batchGetOrders, batchSyncInAppProducts, buildChecklist, buildExternalTransactionRefund, buildLocaleBundle, bundleToReleaseNotes, cancelRecoveryAction, cancelSubscriptionPurchase, cancelSubscriptionV2, checkBundleSize, checkSigningConsistency, checkThreshold, classifyError, clearAuditLog, commitWithRescue, compareBundles, compareFingerprints, compareVersionVitals, compareVitalsTrend, computeStatusDiff, consumeProductPurchase, convertRegionPrices, createAchievementConfig, createAuditEntry, createDeviceTier, createEnterpriseApp, createExternalTransaction, createGrant, createInAppProduct, createLeaderboardConfig, createOffer, createOneTimeOffer, createOneTimeProduct, createRecoveryAction, createSpinner, createSubscription, createTrack, createTranslator, deactivateBasePlan, deactivateOffer, decodeCsvText, decodeNotification, decodeStatsCsv, defaultGitRunner, deferSubscriptionPurchase, deferSubscriptionV2, deleteAchievementConfig, deleteBasePlan, deleteGrant, deleteImage, deleteInAppProduct, deleteLeaderboardConfig, deleteListing, deleteOffer, deleteOneTimeOffer, deleteOneTimeProduct, deleteSubscription, deployRecoveryAction, detectFastlane, detectOutputFormat, diffAchievementConfig, diffLeaderboardConfig, diffListings, diffListingsCommand, diffListingsEnhanced, diffOneTimeProduct, diffReleases, diffSubscription, discoverPluginEntries, discoverPlugins, dispatchWebhook, downloadFinancialReport, downloadGeneratedApk, downloadReportObject, downloadStatsReport, exportImages, exportReviews, extractCsvEntriesFromZip, fetchAggregateCost, fetchChangelog, fetchReleaseNotes, findBundle, formatChangelogEntry, formatCustomPayload, formatDiscordPayload, formatJunit, formatMoney, formatNotification, formatOutput, formatPathLabel, formatSlackPayload, formatStatusDiff, formatStatusSummary, formatStatusTable, formatWordDiff, generateChangelog, generateMigrationPlan, generateNotesFromGit, getAchievementConfig, getAllScannerNames, getApiSigningFingerprint, getAppInfo, getAppStatus, getCountryAvailability, getDeviceTier, getExternalTransaction, getInAppProduct, getKeystoreFingerprint, getLeaderboardConfig, getListings, getOffer, getOneTimeOffer, getOneTimeProduct, getOrderDetails, getProductPurchase, getProductPurchaseV2, getQuotaUsage, getReleasesStatus, getReview, getRtdnStatus, getSubscription, getSubscriptionAnalytics, getSubscriptionPurchase, getTrainStatus, getUser, getVitalsAnomalies, getVitalsAnr, getVitalsBattery, getVitalsCrashes, getVitalsErrorCount, getVitalsLmk, getVitalsMemory, getVitalsMemoryBitmap, getVitalsMemoryRss, getVitalsOverview, getVitalsRendering, getVitalsStartup, gradeFromPercent, gunzipIfNeeded, handleBreach, importDataSafety, importTestersFromCsv, initAudit, initProject, inviteUser, isFinancialReportType, isGzip, isStatsReportType, isValidBcp47, isValidReportType, isValidStatsDimension, isVersionedNotesDir, isZip, latestWorstValue, lintListing, lintListings, lintLocalListings, listAchievementConfigs, listAchievements, listAuditEvents, listBundles, listDeviceTiers, listGeneratedApks, listGrants, listImages, listInAppProducts, listLeaderboardConfigs, listLeaderboards, listOffers, listOneTimeOffers, listOneTimeProducts, listRecoveryActions, listReportObjects, listReports, listReviews, listSubscriptions, listTesters, listTracks, listUsers, listVoidedPurchases, loadPreflightConfig, loadStatusCache, maybePaginate, migratePrices, monthToken, moreResultsFooter, normalizeFingerprint, parseAppfile, parseCommit, parseFastfile, parseGrantArg, parseKeytoolOutput, parseMonth, parseRemoteUrl, pauseTrain, promoteRelease, publish, publishEnterpriseApp, pullAchievementConfigs, pullLeaderboardConfigs, pullListings, pushAchievementConfigs, pushLeaderboardConfigs, pushListings, readListingsFromDir, readMetricValue, readReleaseNotesForVersion, readReleaseNotesFromDir, readinessBadgeColor, readinessBadgeMarkdown, readinessBadgeUrl, redactAuditArgs, redactSensitive, refundExternalTransaction, refundOrder, relativeTime, removeTesters, removeUser, renderChecklistMarkdown, renderJson, renderMarkdown, renderPlayStore, renderPlayStoreJson, renderPlayStoreMd, renderPlayStorePrompt, renderPrompt, replyToReview, reportAccessDeniedError, reportBucketNotFoundError, reportObjectNotFoundError, reportPrefix, resolveAiConfig, resolveLocales, resolveReportsBucket, retryOnUploadNotComplete, reviewOrderRefund, revokeSubscriptionPurchase, runPreflight, runWatch, runWatchLoop, safePath, safePathWithin, saveStatusCache, scaffoldPlugin, scoreReadiness, searchAuditEvents, searchVitalsErrors, sendNotification, sendWebhook, setAchievementIcon, setLeaderboardIcon, sha256File, sortResults, sortReviews, startTrain, statusHasBreach, syncImages, syncInAppProducts, topFiles, trackBreachState, translateBundle, updateAchievementConfig, updateAppDetails, updateDataSafety, updateGrant, updateInAppProduct, updateLeaderboardConfig, updateListing, updateOffer, updateOneTimeOffer, updateOneTimeProduct, updateRollout, updateSubscription, updateTrackConfig, updateUser, uploadExternallyHosted, uploadImage, uploadInternalSharing, uploadRelease, validateAndCommit, validateBundleForApply, validateImage, validateLanguageCode, validatePackageName, validatePluginForApproval, validatePreSubmission, validateReleaseNotes, validateSku, validateTrackName, validateUploadFile, validateVersionCode, waitForBundle, waitForBundleProcessing, watchVitalsWithAutoHalt, wordDiff, worstSliceAverage, writeAuditLog, writeListingsToDir, writeMigrationOutput };
|
package/dist/index.js
CHANGED
|
@@ -3093,7 +3093,7 @@ async function loadStatusCache(packageName, ttlSeconds = DEFAULT_TTL_SECONDS) {
|
|
|
3093
3093
|
const raw = await readFile4(cacheFilePath(packageName), "utf-8");
|
|
3094
3094
|
const entry = JSON.parse(raw);
|
|
3095
3095
|
const age = (Date.now() - new Date(entry.fetchedAt).getTime()) / 1e3;
|
|
3096
|
-
if (age >
|
|
3096
|
+
if (age > ttlSeconds) return null;
|
|
3097
3097
|
const data = entry.data;
|
|
3098
3098
|
return {
|
|
3099
3099
|
...data,
|
|
@@ -3164,6 +3164,14 @@ async function queryVitalWithTrend(reporting, packageName, metricSet, days) {
|
|
|
3164
3164
|
return { current, previous, trend };
|
|
3165
3165
|
}
|
|
3166
3166
|
var SKIPPED_VITAL = { current: void 0, previous: void 0, trend: null };
|
|
3167
|
+
function resolveStatusThresholds(overrides) {
|
|
3168
|
+
return {
|
|
3169
|
+
crashRate: overrides?.crashRate ?? DEFAULT_THRESHOLDS.crashRate,
|
|
3170
|
+
anrRate: overrides?.anrRate ?? DEFAULT_THRESHOLDS.anrRate,
|
|
3171
|
+
slowStartRate: overrides?.slowStartRate ?? DEFAULT_THRESHOLDS.slowStartRate,
|
|
3172
|
+
slowRenderingRate: overrides?.slowRenderingRate ?? DEFAULT_THRESHOLDS.slowRenderingRate
|
|
3173
|
+
};
|
|
3174
|
+
}
|
|
3167
3175
|
function toVitalMetric(value, threshold, previousValue, trend) {
|
|
3168
3176
|
const base = previousValue !== void 0 ? { value, threshold, status: "unknown", previousValue, trend: trend ?? null } : { value, threshold, status: "unknown" };
|
|
3169
3177
|
if (value === void 0) return { ...base, status: "unknown" };
|
|
@@ -3210,12 +3218,7 @@ async function getAppStatus(client, reporting, packageName, options = {}) {
|
|
|
3210
3218
|
const days = options.days ?? 7;
|
|
3211
3219
|
const reviewDays = options.reviewDays ?? 30;
|
|
3212
3220
|
const sections = new Set(options.sections ?? ["releases", "vitals", "reviews"]);
|
|
3213
|
-
const thresholds =
|
|
3214
|
-
crashRate: options.vitalThresholds?.crashRate ?? DEFAULT_THRESHOLDS.crashRate,
|
|
3215
|
-
anrRate: options.vitalThresholds?.anrRate ?? DEFAULT_THRESHOLDS.anrRate,
|
|
3216
|
-
slowStartRate: options.vitalThresholds?.slowStartRate ?? DEFAULT_THRESHOLDS.slowStartRate,
|
|
3217
|
-
slowRenderingRate: options.vitalThresholds?.slowRenderingRate ?? DEFAULT_THRESHOLDS.slowRenderingRate
|
|
3218
|
-
};
|
|
3221
|
+
const thresholds = resolveStatusThresholds(options.vitalThresholds);
|
|
3219
3222
|
const [
|
|
3220
3223
|
releasesResult,
|
|
3221
3224
|
crashesResult,
|
|
@@ -3592,6 +3595,22 @@ function sendNotification(title, body) {
|
|
|
3592
3595
|
} catch {
|
|
3593
3596
|
}
|
|
3594
3597
|
}
|
|
3598
|
+
function applyVitalThresholds(status, vitalThresholds) {
|
|
3599
|
+
const v = status.vitals;
|
|
3600
|
+
if (!v) return status;
|
|
3601
|
+
const t = resolveStatusThresholds(vitalThresholds);
|
|
3602
|
+
const rate = (metric, threshold) => metric && toVitalMetric(metric.value, threshold, metric.previousValue, metric.trend);
|
|
3603
|
+
return {
|
|
3604
|
+
...status,
|
|
3605
|
+
vitals: {
|
|
3606
|
+
...v,
|
|
3607
|
+
crashes: rate(v.crashes, t.crashRate),
|
|
3608
|
+
anr: rate(v.anr, t.anrRate),
|
|
3609
|
+
slowStarts: rate(v.slowStarts, t.slowStartRate),
|
|
3610
|
+
slowRender: rate(v.slowRender, t.slowRenderingRate)
|
|
3611
|
+
}
|
|
3612
|
+
};
|
|
3613
|
+
}
|
|
3595
3614
|
function statusHasBreach(status) {
|
|
3596
3615
|
return status.vitals.crashes.status === "breach" || status.vitals.anr.status === "breach" || status.vitals.slowStarts.status === "breach" || status.vitals.slowRender.status === "breach";
|
|
3597
3616
|
}
|
|
@@ -6285,6 +6304,7 @@ var RESOURCE_IDS = {
|
|
|
6285
6304
|
16843376: "targetSdkVersion",
|
|
6286
6305
|
16842782: "debuggable",
|
|
6287
6306
|
16842786: "permission",
|
|
6307
|
+
16842788: "value",
|
|
6288
6308
|
16842795: "exported",
|
|
6289
6309
|
16843378: "testOnly",
|
|
6290
6310
|
16843760: "usesCleartextTraffic",
|
|
@@ -6413,6 +6433,7 @@ function extractManifestData(manifest) {
|
|
|
6413
6433
|
const services = app ? extractComponents(app, "service") : [];
|
|
6414
6434
|
const receivers = app ? extractComponents(app, "receiver") : [];
|
|
6415
6435
|
const providers = app ? extractComponents(app, "provider") : [];
|
|
6436
|
+
const metaData = app ? extractMetaData(app) : {};
|
|
6416
6437
|
return {
|
|
6417
6438
|
packageName,
|
|
6418
6439
|
versionCode,
|
|
@@ -6429,9 +6450,20 @@ function extractManifestData(manifest) {
|
|
|
6429
6450
|
activities,
|
|
6430
6451
|
services,
|
|
6431
6452
|
receivers,
|
|
6432
|
-
providers
|
|
6453
|
+
providers,
|
|
6454
|
+
metaData
|
|
6433
6455
|
};
|
|
6434
6456
|
}
|
|
6457
|
+
function extractMetaData(elem) {
|
|
6458
|
+
const entries = {};
|
|
6459
|
+
for (const el of getChildren(elem, "meta-data")) {
|
|
6460
|
+
const attrs = el.attribute || [];
|
|
6461
|
+
const name = getAttrByName(attrs, "name");
|
|
6462
|
+
const value = getAttrByName(attrs, "value");
|
|
6463
|
+
if (name && value !== void 0) entries[name] = value;
|
|
6464
|
+
}
|
|
6465
|
+
return entries;
|
|
6466
|
+
}
|
|
6435
6467
|
function extractComponents(appElement, tagName) {
|
|
6436
6468
|
return getChildren(appElement, tagName).map((el) => {
|
|
6437
6469
|
const compAttrs = el.attribute || [];
|
|
@@ -6534,7 +6566,8 @@ function createFallbackManifest() {
|
|
|
6534
6566
|
activities: [],
|
|
6535
6567
|
services: [],
|
|
6536
6568
|
receivers: [],
|
|
6537
|
-
providers: []
|
|
6569
|
+
providers: [],
|
|
6570
|
+
metaData: {}
|
|
6538
6571
|
};
|
|
6539
6572
|
}
|
|
6540
6573
|
function openAndScan(buffer, manifestPath = AAB_MANIFEST_PATH) {
|
|
@@ -6808,7 +6841,7 @@ var manifestScanner = {
|
|
|
6808
6841
|
ruleId: "geofencing-foreground-service",
|
|
6809
6842
|
severity: "warning",
|
|
6810
6843
|
title: `Possible geofencing via foreground service "${service.name}"`,
|
|
6811
|
-
message: `Service "${service.name}" uses foregroundServiceType "location" and the app declares ACCESS_BACKGROUND_LOCATION. Google Play no longer approves geofencing as a foreground service use case (sensitive-permissions policy announced April 15, 2026)
|
|
6844
|
+
message: `Service "${service.name}" uses foregroundServiceType "location" and the app declares ACCESS_BACKGROUND_LOCATION. Google Play no longer approves geofencing as a foreground service use case (sensitive-permissions policy announced April 15, 2026).`,
|
|
6812
6845
|
suggestion: 'If this service performs geofencing, migrate to the Geofencing API (LocationServices.getGeofencingClient) or WorkManager/AlarmManager. If this is legitimate background location tracking (navigation, fitness), suppress this rule via .preflightrc.json: "disabledRules": ["geofencing-foreground-service"].',
|
|
6813
6846
|
policyUrl: "https://support.google.com/googleplay/android-developer/answer/16926792"
|
|
6814
6847
|
});
|
|
@@ -6898,7 +6931,7 @@ var RESTRICTED_PERMISSIONS = [
|
|
|
6898
6931
|
permission: "android.permission.READ_CALL_LOG",
|
|
6899
6932
|
severity: "critical",
|
|
6900
6933
|
title: "READ_CALL_LOG requires declaration form",
|
|
6901
|
-
message: "READ_CALL_LOG is restricted to default phone/assistant handler apps.
|
|
6934
|
+
message: "READ_CALL_LOG is restricted to default phone/assistant handler apps. From January 27, 2027, account verification via phone call is no longer an accepted use case for the Call Log permissions.",
|
|
6902
6935
|
suggestion: "Remove READ_CALL_LOG unless your app is a default phone or assistant handler. For phone-number verification, use the Digital Credentials API; for one-time codes, use the SMS Retriever API instead of reading the call log.",
|
|
6903
6936
|
policyUrl: "https://support.google.com/googleplay/android-developer/answer/10208820"
|
|
6904
6937
|
},
|
|
@@ -7041,14 +7074,14 @@ var permissionsScanner = {
|
|
|
7041
7074
|
].filter((p) => manifest.permissions.includes(p) && !allowed.has(p));
|
|
7042
7075
|
if (contactsPerms.length > 0) {
|
|
7043
7076
|
const names = contactsPerms.map((p) => p.split(".").pop()).join(", ");
|
|
7044
|
-
const enforced = manifest.targetSdk >= 37 ? ` Your app targets API ${manifest.targetSdk}, so this
|
|
7077
|
+
const enforced = manifest.targetSdk >= 37 ? ` Your app targets API ${manifest.targetSdk}, so this applies to it.` : "";
|
|
7045
7078
|
findings.push({
|
|
7046
7079
|
scanner: "permissions",
|
|
7047
7080
|
ruleId: "contacts-permission-broad",
|
|
7048
7081
|
severity: "warning",
|
|
7049
7082
|
title: "Broad contacts access requires migration to Contact Picker",
|
|
7050
|
-
message: `Your app declares ${names}. Google Play's Contacts Permissions policy requires the Android Contact Picker (Intent.ACTION_PICK_CONTACTS) unless broad access is core to your app. Mandatory for apps targeting Android 17 (API 37+) on
|
|
7051
|
-
suggestion: "Migrate to the Android Contact Picker (Intent.ACTION_PICK_CONTACTS) for user-initiated contact selection, or
|
|
7083
|
+
message: `Your app declares ${names}. Google Play's Contacts Permissions policy requires the Android Contact Picker (Intent.ACTION_PICK_CONTACTS) unless broad access is core to your app and you submit a Play Console declaration. Mandatory for apps targeting Android 17 (API 37+) on January 27, 2027.${enforced}`,
|
|
7084
|
+
suggestion: "Migrate to the Android Contact Picker (Intent.ACTION_PICK_CONTACTS) for user-initiated contact selection, or submit the contacts declaration in Play Console before January 27, 2027 if the picker cannot serve your core functionality. Remove READ_CONTACTS/WRITE_CONTACTS unless your app is a dialer, messaging, or contacts management app.",
|
|
7052
7085
|
policyUrl: "https://support.google.com/googleplay/android-developer/answer/16935362"
|
|
7053
7086
|
});
|
|
7054
7087
|
}
|
|
@@ -7060,8 +7093,8 @@ var permissionsScanner = {
|
|
|
7060
7093
|
ruleId: "location-minimal-scope",
|
|
7061
7094
|
severity: targetsApi37 ? "warning" : "info",
|
|
7062
7095
|
title: "Precise location \u2014 consider the location button (minimum scope)",
|
|
7063
|
-
message: `Your app declares ACCESS_FINE_LOCATION. Google Play's Location Permissions policy
|
|
7064
|
-
suggestion: 'For one-time/transactional precise location, use the system location button instead of requesting ACCESS_FINE_LOCATION up front. Only keep continuous fine location if navigation, fitness, or a similar feature is core functionality. Suppress via .preflightrc.json "disabledRules": ["location-minimal-scope"] if fine location is essential.',
|
|
7096
|
+
message: `Your app declares ACCESS_FINE_LOCATION. Google Play's Location Permissions policy requires the Android location button for one-time or infrequent precise location, and a Play Console declaration explaining why coarse location or the location button is not enough. Mandatory for apps targeting Android 17 (API 37+) on January 27, 2027.${targetsApi37 ? ` Your app targets API ${manifest.targetSdk}.` : ""}`,
|
|
7097
|
+
suggestion: 'For one-time/transactional precise location, use the system location button instead of requesting ACCESS_FINE_LOCATION up front. Only keep continuous fine location if navigation, fitness, or a similar feature is core functionality, and complete the precise location declaration in Play Console. Suppress via .preflightrc.json "disabledRules": ["location-minimal-scope"] if fine location is essential.',
|
|
7065
7098
|
policyUrl: "https://support.google.com/googleplay/android-developer/answer/17033915"
|
|
7066
7099
|
});
|
|
7067
7100
|
}
|
|
@@ -7814,6 +7847,129 @@ var privacyScanner = {
|
|
|
7814
7847
|
}
|
|
7815
7848
|
};
|
|
7816
7849
|
|
|
7850
|
+
// src/preflight/billing-library.ts
|
|
7851
|
+
var BILLING_LIBRARY_DEADLINES = {
|
|
7852
|
+
5: { updateDeadline: "2024-08-31", extensionDeadline: "2024-11-01" },
|
|
7853
|
+
6: { updateDeadline: "2025-08-31", extensionDeadline: "2025-11-01" },
|
|
7854
|
+
7: { updateDeadline: "2026-08-31", extensionDeadline: "2026-11-01" },
|
|
7855
|
+
8: { updateDeadline: "2027-08-31", extensionDeadline: "2027-11-01" },
|
|
7856
|
+
9: { updateDeadline: "2028-08-31", extensionDeadline: "2028-11-01" }
|
|
7857
|
+
};
|
|
7858
|
+
var BILLING_PERMISSION = "com.android.vending.BILLING";
|
|
7859
|
+
var VERSION_META_DATA = "com.google.android.play.billingclient.version";
|
|
7860
|
+
var DEPRECATION_FAQ = "https://developer.android.com/google/play/billing/deprecation-faq";
|
|
7861
|
+
var RELEASE_NOTES = "https://developer.android.com/google/play/billing/release-notes";
|
|
7862
|
+
var MIGRATION_GUIDES = {
|
|
7863
|
+
8: "https://developer.android.com/google/play/billing/migrate-gpblv8",
|
|
7864
|
+
9: "https://developer.android.com/google/play/billing/migrate-gpblv9"
|
|
7865
|
+
};
|
|
7866
|
+
var KNOWN_MAJORS = Object.keys(BILLING_LIBRARY_DEADLINES).map(Number).sort((a, b) => a - b);
|
|
7867
|
+
var OLDEST_KNOWN = KNOWN_MAJORS[0] ?? 0;
|
|
7868
|
+
var NEWEST_KNOWN = KNOWN_MAJORS[KNOWN_MAJORS.length - 1] ?? 0;
|
|
7869
|
+
var ISO_DAY_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
7870
|
+
function utcDayStart(isoDay, { years = 0, days = 0 } = {}) {
|
|
7871
|
+
const match = ISO_DAY_RE.exec(isoDay);
|
|
7872
|
+
if (!match) throw new Error(`Invalid Billing Library deadline "${isoDay}" (expected YYYY-MM-DD)`);
|
|
7873
|
+
return Date.UTC(Number(match[1]) + years, Number(match[2]) - 1, Number(match[3]) + days);
|
|
7874
|
+
}
|
|
7875
|
+
var BOUNDARIES = new Map(
|
|
7876
|
+
Object.entries(BILLING_LIBRARY_DEADLINES).map(([key, { updateDeadline, extensionDeadline }]) => {
|
|
7877
|
+
const major = Number(key);
|
|
7878
|
+
return [
|
|
7879
|
+
major,
|
|
7880
|
+
{
|
|
7881
|
+
infoFrom: utcDayStart(updateDeadline, { years: -1 }),
|
|
7882
|
+
updatePastFrom: utcDayStart(updateDeadline, { days: 1 }),
|
|
7883
|
+
extensionPastFrom: utcDayStart(extensionDeadline, { days: 1 })
|
|
7884
|
+
}
|
|
7885
|
+
];
|
|
7886
|
+
})
|
|
7887
|
+
);
|
|
7888
|
+
var STATUS_SEVERITY = {
|
|
7889
|
+
"older-than-table": "error",
|
|
7890
|
+
"past-extension-deadline": "error",
|
|
7891
|
+
"past-update-deadline": "warning",
|
|
7892
|
+
"update-deadline-within-a-year": "info"
|
|
7893
|
+
};
|
|
7894
|
+
function billingLibraryStatus(major, now) {
|
|
7895
|
+
if (major < OLDEST_KNOWN) return "older-than-table";
|
|
7896
|
+
const bounds = BOUNDARIES.get(major);
|
|
7897
|
+
if (!bounds) return void 0;
|
|
7898
|
+
const t = now.getTime();
|
|
7899
|
+
if (t >= bounds.extensionPastFrom) return "past-extension-deadline";
|
|
7900
|
+
if (t >= bounds.updatePastFrom) return "past-update-deadline";
|
|
7901
|
+
if (t >= bounds.infoFrom) return "update-deadline-within-a-year";
|
|
7902
|
+
return void 0;
|
|
7903
|
+
}
|
|
7904
|
+
function targetMajor(major, now) {
|
|
7905
|
+
const next = KNOWN_MAJORS.find((m) => {
|
|
7906
|
+
const bounds = BOUNDARIES.get(m);
|
|
7907
|
+
return m > major && bounds !== void 0 && now.getTime() < bounds.updatePastFrom;
|
|
7908
|
+
});
|
|
7909
|
+
return next ?? NEWEST_KNOWN + 1;
|
|
7910
|
+
}
|
|
7911
|
+
function migrationAdvice(target) {
|
|
7912
|
+
const guide = MIGRATION_GUIDES[target];
|
|
7913
|
+
return guide ? `Move to Billing Library ${target} or later. Migration guide: ${guide}` : `Move to Billing Library ${target} or later. Release notes: ${RELEASE_NOTES}`;
|
|
7914
|
+
}
|
|
7915
|
+
function billingLibraryFindings(manifest, now) {
|
|
7916
|
+
if (!manifest.permissions.includes(BILLING_PERMISSION)) return [];
|
|
7917
|
+
const version = manifest.metaData[VERSION_META_DATA];
|
|
7918
|
+
const majorMatch = version?.trim().match(/^\d+/);
|
|
7919
|
+
if (!version || !majorMatch) {
|
|
7920
|
+
const found = version ? `has an unreadable value ("${version}")` : "is missing";
|
|
7921
|
+
return [
|
|
7922
|
+
{
|
|
7923
|
+
scanner: "policy",
|
|
7924
|
+
ruleId: "billing-library-version-unknown",
|
|
7925
|
+
severity: "info",
|
|
7926
|
+
title: "Google Play Billing Library version could not be determined",
|
|
7927
|
+
message: `This bundle requests ${BILLING_PERMISSION}, but the ${VERSION_META_DATA} manifest entry ${found}. Manifest merging can remove it (for example a tools:node="remove" override), so preflight cannot compare the Billing Library version with Google Play's deadlines.`,
|
|
7928
|
+
suggestion: `Check the Billing Library version in your Gradle dependencies against Google's support timeline: ${DEPRECATION_FAQ}`,
|
|
7929
|
+
policyUrl: DEPRECATION_FAQ
|
|
7930
|
+
}
|
|
7931
|
+
];
|
|
7932
|
+
}
|
|
7933
|
+
const major = Number(majorMatch[0]);
|
|
7934
|
+
const status = billingLibraryStatus(major, now);
|
|
7935
|
+
if (!status) return [];
|
|
7936
|
+
const shipsVersion = `This bundle ships Google Play Billing Library ${version}.`;
|
|
7937
|
+
const advice = migrationAdvice(targetMajor(major, now));
|
|
7938
|
+
let title;
|
|
7939
|
+
let message;
|
|
7940
|
+
let suggestion = advice;
|
|
7941
|
+
if (status === "older-than-table") {
|
|
7942
|
+
const oldest = BILLING_LIBRARY_DEADLINES[OLDEST_KNOWN];
|
|
7943
|
+
title = `Google Play Billing Library ${major} is no longer supported`;
|
|
7944
|
+
message = `${shipsVersion} It is older than Billing Library ${OLDEST_KNOWN}, whose extension deadline passed on ${oldest?.extensionDeadline ?? "an earlier date"}. Google Play no longer accepts new apps or app updates built on it.`;
|
|
7945
|
+
} else {
|
|
7946
|
+
const deadlines = BILLING_LIBRARY_DEADLINES[major];
|
|
7947
|
+
if (!deadlines) return [];
|
|
7948
|
+
if (status === "past-extension-deadline") {
|
|
7949
|
+
title = `Google Play Billing Library ${major} is no longer supported`;
|
|
7950
|
+
message = `${shipsVersion} Its extension deadline passed on ${deadlines.extensionDeadline}, so Google Play no longer accepts new apps or app updates built on Billing Library ${major}.`;
|
|
7951
|
+
} else if (status === "past-update-deadline") {
|
|
7952
|
+
title = `Google Play Billing Library ${major} is past its update deadline`;
|
|
7953
|
+
message = `${shipsVersion} Its update deadline passed on ${deadlines.updateDeadline}. Until ${deadlines.extensionDeadline}, Google Play accepts new apps and app updates on Billing Library ${major} only if the app was granted an extension. After that date it accepts none.`;
|
|
7954
|
+
suggestion = `To keep shipping while you migrate, request an extension from the warning on Play Console's Policy status page. ${advice}`;
|
|
7955
|
+
} else {
|
|
7956
|
+
title = `Google Play Billing Library ${major} update deadline is ${deadlines.updateDeadline}`;
|
|
7957
|
+
message = `${shipsVersion} After ${deadlines.updateDeadline}, Google Play accepts new apps and app updates on Billing Library ${major} only with an extension, and after ${deadlines.extensionDeadline} not at all.`;
|
|
7958
|
+
}
|
|
7959
|
+
}
|
|
7960
|
+
return [
|
|
7961
|
+
{
|
|
7962
|
+
scanner: "policy",
|
|
7963
|
+
ruleId: "billing-library-deprecated",
|
|
7964
|
+
severity: STATUS_SEVERITY[status],
|
|
7965
|
+
title,
|
|
7966
|
+
message,
|
|
7967
|
+
suggestion,
|
|
7968
|
+
policyUrl: DEPRECATION_FAQ
|
|
7969
|
+
}
|
|
7970
|
+
];
|
|
7971
|
+
}
|
|
7972
|
+
|
|
7817
7973
|
// src/preflight/scanners/policy-scanner.ts
|
|
7818
7974
|
var policyScanner = {
|
|
7819
7975
|
name: "policy",
|
|
@@ -7912,6 +8068,18 @@ var policyScanner = {
|
|
|
7912
8068
|
policyUrl: "https://support.google.com/googleplay/android-developer/answer/13392821"
|
|
7913
8069
|
});
|
|
7914
8070
|
}
|
|
8071
|
+
if (perms.has("android.permission.ACCESS_LOCAL_NETWORK") && manifest.targetSdk >= 37) {
|
|
8072
|
+
findings.push({
|
|
8073
|
+
scanner: "policy",
|
|
8074
|
+
ruleId: "policy-local-network-declaration",
|
|
8075
|
+
severity: "info",
|
|
8076
|
+
title: "ACCESS_LOCAL_NETWORK requires a Play Console declaration",
|
|
8077
|
+
message: `This app targets API ${manifest.targetSdk} and requests ACCESS_LOCAL_NETWORK. From August 25, 2027, Google Play requires apps targeting Android 17 (API 37) or higher to submit a Play Console declaration to use this permission, and allows it only for core functionality that device pickers cannot provide. The declaration is stored in Play Console, so it cannot be verified from the AAB.`,
|
|
8078
|
+
suggestion: "If a device picker (for example NsdManager discovery through the system picker) covers your use case, use it and drop ACCESS_LOCAL_NETWORK. Otherwise submit the local network declaration in Play Console, explaining why device pickers are not sufficient.",
|
|
8079
|
+
policyUrl: "https://support.google.com/googleplay/android-developer/answer/16935362#local_network_permission"
|
|
8080
|
+
});
|
|
8081
|
+
}
|
|
8082
|
+
findings.push(...billingLibraryFindings(manifest, /* @__PURE__ */ new Date()));
|
|
7915
8083
|
if (perms.has("android.permission.SYSTEM_ALERT_WINDOW")) {
|
|
7916
8084
|
findings.push({
|
|
7917
8085
|
scanner: "policy",
|
|
@@ -10529,6 +10697,7 @@ export {
|
|
|
10529
10697
|
analyzeReviews2 as analyzeReviews,
|
|
10530
10698
|
annotateListResult,
|
|
10531
10699
|
applyReleaseNotes,
|
|
10700
|
+
applyVitalThresholds,
|
|
10532
10701
|
assertRateThreshold,
|
|
10533
10702
|
assignRelease,
|
|
10534
10703
|
batchGetOrders,
|