@gpc-cli/core 0.9.10 → 0.9.12

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 CHANGED
@@ -30,6 +30,7 @@ declare class NetworkError extends GpcError {
30
30
 
31
31
  declare function detectOutputFormat(): OutputFormat;
32
32
  declare function formatOutput(data: unknown, format: OutputFormat, redact?: boolean): string;
33
+ declare const SENSITIVE_KEYS: Set<string>;
33
34
  /** Recursively redact sensitive fields from data before output. */
34
35
  declare function redactSensitive(data: unknown): unknown;
35
36
  declare function formatJunit(data: unknown, commandName?: string): string;
@@ -235,6 +236,12 @@ declare function writeMigrationOutput(result: MigrationResult, dir: string): Pro
235
236
  declare const GOOGLE_PLAY_LANGUAGES: string[];
236
237
  declare function isValidBcp47(tag: string): boolean;
237
238
 
239
+ declare function validatePackageName(name: string): void;
240
+ declare function validateVersionCode(code: string | number): void;
241
+ declare function validateLanguageCode(code: string): void;
242
+ declare function validateTrackName(name: string): void;
243
+ declare function validateSku(sku: string): void;
244
+
238
245
  interface FileValidationResult {
239
246
  valid: boolean;
240
247
  fileType: "aab" | "apk" | "unknown";
@@ -593,6 +600,9 @@ declare function initAudit(configDir: string): void;
593
600
  * Write an audit log entry. Non-blocking — errors are silently ignored.
594
601
  */
595
602
  declare function writeAuditLog(entry: AuditEntry): Promise<void>;
603
+ declare const SENSITIVE_ARG_KEYS: Set<string>;
604
+
605
+ declare function redactAuditArgs(entry: AuditEntry): AuditEntry;
596
606
  /**
597
607
  * Convenience: create an audit entry for a write command.
598
608
  */
@@ -631,4 +641,4 @@ declare function createPurchaseOption(client: PlayApiClient, packageName: string
631
641
  declare function activatePurchaseOption(client: PlayApiClient, packageName: string, purchaseOptionId: string): Promise<PurchaseOption>;
632
642
  declare function deactivatePurchaseOption(client: PlayApiClient, packageName: string, purchaseOptionId: string): Promise<PurchaseOption>;
633
643
 
634
- export { ApiError, type AppInfo, type AuditEntry, type BatchSyncResult, type CommandContext, ConfigError, type DiscoverPluginsOptions, type DryRunPublishResult, type DryRunResult, type DryRunUploadResult, type ExportImagesOptions, type ExportImagesSummary, type FastlaneDetection, type FastlaneLane, type FileValidationResult, GOOGLE_PLAY_LANGUAGES, type GitNotesOptions, type GitReleaseNotes, GpcError, type ImageValidationResult, type InternalSharingUploadResult, type ListIapOptions, type ListSubscriptionsOptions, type ListUsersOptions, type ListVoidedOptions, type ListingDiff, type ListingsResult, type LoadedPlugin, type MigrationResult, NetworkError, PERMISSION_PROPAGATION_WARNING, type ParsedMonth, PluginManager, type PublishOptions, type PublishResult, type PushResult, type ReleaseNotesValidation, type ReleaseStatusResult, type ReviewExportOptions, type ReviewsFilterOptions, type ScaffoldOptions, type ScaffoldResult, type Spinner, type SyncResult, type ThresholdResult, type UploadResult, type ValidateCheck, type ValidateOptions, type ValidateResult, type VitalsOverview, type VitalsQueryOptions, type VitalsTrendComparison, type WebhookPayload, acknowledgeProductPurchase, activateBasePlan, activateOffer, activatePurchaseOption, addRecoveryTargeting, addTesters, batchSyncInAppProducts, cancelRecoveryAction, cancelSubscriptionPurchase, checkThreshold, compareVitalsTrend, consumeProductPurchase, convertRegionPrices, createAuditEntry, createDeviceTier, createExternalTransaction, createInAppProduct, createOffer, createOneTimeOffer, createOneTimeProduct, createPurchaseOption, createRecoveryAction, createSpinner, createSubscription, createTrack, deactivateBasePlan, deactivateOffer, deactivatePurchaseOption, deferSubscriptionPurchase, deleteBasePlan, deleteImage, deleteInAppProduct, deleteListing, deleteOffer, deleteOneTimeOffer, deleteOneTimeProduct, deleteSubscription, deployRecoveryAction, detectFastlane, detectOutputFormat, diffListings, diffListingsCommand, discoverPlugins, downloadGeneratedApk, downloadReport, exportDataSafety, exportImages, exportReviews, formatCustomPayload, formatDiscordPayload, formatJunit, formatOutput, formatSlackPayload, generateMigrationPlan, generateNotesFromGit, getAppInfo, getCountryAvailability, getDataSafety, getDeviceTier, getExternalTransaction, getInAppProduct, getListings, getOffer, getOneTimeOffer, getOneTimeProduct, getProductPurchase, getPurchaseOption, getReleasesStatus, getReview, getSubscription, getSubscriptionPurchase, getUser, getVitalsAnomalies, getVitalsAnr, getVitalsBattery, getVitalsCrashes, getVitalsMemory, getVitalsOverview, getVitalsRendering, getVitalsStartup, importDataSafety, importTestersFromCsv, initAudit, inviteUser, isFinancialReportType, isStatsReportType, isValidBcp47, isValidReportType, isValidStatsDimension, listDeviceTiers, listGeneratedApks, listImages, listInAppProducts, listOffers, listOneTimeOffers, listOneTimeProducts, listPurchaseOptions, listRecoveryActions, listReports, listReviews, listSubscriptions, listTesters, listTracks, listUsers, listVoidedPurchases, migratePrices, parseAppfile, parseFastfile, parseGrantArg, parseMonth, promoteRelease, publish, pullListings, pushListings, readListingsFromDir, readReleaseNotesFromDir, redactSensitive, refundExternalTransaction, refundOrder, removeTesters, removeUser, replyToReview, revokeSubscriptionPurchase, safePath, safePathWithin, scaffoldPlugin, searchVitalsErrors, sendWebhook, sortResults, syncInAppProducts, updateAppDetails, updateDataSafety, updateInAppProduct, updateListing, updateOffer, updateOneTimeOffer, updateOneTimeProduct, updateRollout, updateSubscription, updateTrackConfig, updateUser, uploadExternallyHosted, uploadImage, uploadInternalSharing, uploadRelease, validateImage, validatePreSubmission, validateReleaseNotes, validateUploadFile, writeAuditLog, writeListingsToDir, writeMigrationOutput };
644
+ export { ApiError, type AppInfo, type AuditEntry, type BatchSyncResult, type CommandContext, ConfigError, type DiscoverPluginsOptions, type DryRunPublishResult, type DryRunResult, type DryRunUploadResult, type ExportImagesOptions, type ExportImagesSummary, type FastlaneDetection, type FastlaneLane, type FileValidationResult, GOOGLE_PLAY_LANGUAGES, type GitNotesOptions, type GitReleaseNotes, GpcError, type ImageValidationResult, type InternalSharingUploadResult, type ListIapOptions, type ListSubscriptionsOptions, type ListUsersOptions, type ListVoidedOptions, type ListingDiff, type ListingsResult, type LoadedPlugin, type MigrationResult, NetworkError, PERMISSION_PROPAGATION_WARNING, type ParsedMonth, PluginManager, type PublishOptions, type PublishResult, type PushResult, type ReleaseNotesValidation, type ReleaseStatusResult, type ReviewExportOptions, type ReviewsFilterOptions, SENSITIVE_ARG_KEYS, SENSITIVE_KEYS, type ScaffoldOptions, type ScaffoldResult, type Spinner, type SyncResult, type ThresholdResult, type UploadResult, type ValidateCheck, type ValidateOptions, type ValidateResult, type VitalsOverview, type VitalsQueryOptions, type VitalsTrendComparison, type WebhookPayload, acknowledgeProductPurchase, activateBasePlan, activateOffer, activatePurchaseOption, addRecoveryTargeting, addTesters, batchSyncInAppProducts, cancelRecoveryAction, cancelSubscriptionPurchase, checkThreshold, compareVitalsTrend, consumeProductPurchase, convertRegionPrices, createAuditEntry, createDeviceTier, createExternalTransaction, createInAppProduct, createOffer, createOneTimeOffer, createOneTimeProduct, createPurchaseOption, createRecoveryAction, createSpinner, createSubscription, createTrack, deactivateBasePlan, deactivateOffer, deactivatePurchaseOption, deferSubscriptionPurchase, deleteBasePlan, deleteImage, deleteInAppProduct, deleteListing, deleteOffer, deleteOneTimeOffer, deleteOneTimeProduct, deleteSubscription, deployRecoveryAction, detectFastlane, detectOutputFormat, diffListings, diffListingsCommand, discoverPlugins, downloadGeneratedApk, downloadReport, exportDataSafety, exportImages, exportReviews, formatCustomPayload, formatDiscordPayload, formatJunit, formatOutput, formatSlackPayload, generateMigrationPlan, generateNotesFromGit, getAppInfo, getCountryAvailability, getDataSafety, getDeviceTier, getExternalTransaction, getInAppProduct, getListings, getOffer, getOneTimeOffer, getOneTimeProduct, getProductPurchase, getPurchaseOption, getReleasesStatus, getReview, getSubscription, getSubscriptionPurchase, getUser, getVitalsAnomalies, getVitalsAnr, getVitalsBattery, getVitalsCrashes, getVitalsMemory, getVitalsOverview, getVitalsRendering, getVitalsStartup, importDataSafety, importTestersFromCsv, initAudit, inviteUser, isFinancialReportType, isStatsReportType, isValidBcp47, isValidReportType, isValidStatsDimension, listDeviceTiers, listGeneratedApks, listImages, listInAppProducts, listOffers, listOneTimeOffers, listOneTimeProducts, listPurchaseOptions, listRecoveryActions, listReports, listReviews, listSubscriptions, listTesters, listTracks, listUsers, listVoidedPurchases, migratePrices, parseAppfile, parseFastfile, parseGrantArg, parseMonth, promoteRelease, publish, pullListings, pushListings, readListingsFromDir, readReleaseNotesFromDir, redactAuditArgs, redactSensitive, refundExternalTransaction, refundOrder, removeTesters, removeUser, replyToReview, revokeSubscriptionPurchase, safePath, safePathWithin, scaffoldPlugin, searchVitalsErrors, sendWebhook, sortResults, syncInAppProducts, updateAppDetails, updateDataSafety, updateInAppProduct, updateListing, updateOffer, updateOneTimeOffer, updateOneTimeProduct, updateRollout, updateSubscription, updateTrackConfig, updateUser, uploadExternallyHosted, uploadImage, uploadInternalSharing, uploadRelease, validateImage, validateLanguageCode, validatePackageName, validatePreSubmission, validateReleaseNotes, validateSku, validateTrackName, validateUploadFile, validateVersionCode, writeAuditLog, writeListingsToDir, writeMigrationOutput };
package/dist/index.js CHANGED
@@ -74,7 +74,20 @@ var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
74
74
  "token",
75
75
  "password",
76
76
  "secret",
77
- "credentials"
77
+ "credentials",
78
+ "keyFile",
79
+ "key_file",
80
+ "serviceAccount",
81
+ "service-account",
82
+ "apiKey",
83
+ "api_key",
84
+ "auth_token",
85
+ "bearer",
86
+ "jwt",
87
+ "signing_key",
88
+ "keystore_password",
89
+ "store_password",
90
+ "key_password"
78
91
  ]);
79
92
  var REDACTED = "[REDACTED]";
80
93
  function redactSensitive(data) {
@@ -1535,6 +1548,71 @@ async function writeMigrationOutput(result, dir) {
1535
1548
  return files;
1536
1549
  }
1537
1550
 
1551
+ // src/utils/validation.ts
1552
+ var PACKAGE_NAME_RE = /^[a-zA-Z][a-zA-Z0-9_]*(\.[a-zA-Z][a-zA-Z0-9_]*){1,}$/;
1553
+ var SKU_RE = /^[a-zA-Z0-9._]+$/;
1554
+ var TRACK_NAMES = ["internal", "alpha", "beta", "production"];
1555
+ var CUSTOM_TRACK_RE = /^[a-zA-Z0-9\-_]+$/;
1556
+ function validatePackageName(name) {
1557
+ if (!name || !PACKAGE_NAME_RE.test(name)) {
1558
+ throw new GpcError(
1559
+ `Invalid package name: "${name}"`,
1560
+ "INVALID_PACKAGE_NAME",
1561
+ 2,
1562
+ "Package name must be a valid Android application ID (e.g., com.example.myapp)"
1563
+ );
1564
+ }
1565
+ }
1566
+ function validateVersionCode(code) {
1567
+ const num = typeof code === "string" ? parseInt(code, 10) : code;
1568
+ if (!Number.isInteger(num) || num < 1) {
1569
+ throw new GpcError(
1570
+ `Invalid version code: "${code}"`,
1571
+ "INVALID_VERSION_CODE",
1572
+ 2,
1573
+ "Version code must be a positive integer (e.g., 142)"
1574
+ );
1575
+ }
1576
+ }
1577
+ function validateLanguageCode(code) {
1578
+ if (!code || !isValidBcp47(code)) {
1579
+ throw new GpcError(
1580
+ `Invalid language code: "${code}"`,
1581
+ "INVALID_LANGUAGE_CODE",
1582
+ 2,
1583
+ "Language code must be a valid BCP-47 tag supported by Google Play (e.g., en-US, ja-JP, fr-FR)"
1584
+ );
1585
+ }
1586
+ }
1587
+ function validateTrackName(name) {
1588
+ if (!name) {
1589
+ throw new GpcError(
1590
+ "Track name is required",
1591
+ "INVALID_TRACK_NAME",
1592
+ 2,
1593
+ "Specify a track: internal, alpha, beta, production, or a custom track name"
1594
+ );
1595
+ }
1596
+ if (!TRACK_NAMES.includes(name) && !CUSTOM_TRACK_RE.test(name)) {
1597
+ throw new GpcError(
1598
+ `Invalid track name: "${name}"`,
1599
+ "INVALID_TRACK_NAME",
1600
+ 2,
1601
+ `Valid tracks: ${TRACK_NAMES.join(", ")}, or a custom track matching [a-zA-Z0-9-_]+`
1602
+ );
1603
+ }
1604
+ }
1605
+ function validateSku(sku) {
1606
+ if (!sku || !SKU_RE.test(sku)) {
1607
+ throw new GpcError(
1608
+ `Invalid product ID (SKU): "${sku}"`,
1609
+ "INVALID_SKU",
1610
+ 2,
1611
+ "Product ID must contain only letters, numbers, dots, and underscores (e.g., premium_upgrade)"
1612
+ );
1613
+ }
1614
+ }
1615
+
1538
1616
  // src/utils/release-notes.ts
1539
1617
  import { readdir as readdir3, readFile as readFile4, stat as stat4 } from "fs/promises";
1540
1618
  import { extname as extname3, basename, join as join3 } from "path";
@@ -1971,6 +2049,7 @@ function checkThreshold(value, threshold) {
1971
2049
  // src/commands/subscriptions.ts
1972
2050
  import { paginateAll as paginateAll2 } from "@gpc-cli/api";
1973
2051
  async function listSubscriptions(client, packageName, options) {
2052
+ validatePackageName(packageName);
1974
2053
  if (options?.limit || options?.nextPage) {
1975
2054
  const result = await paginateAll2(
1976
2055
  async (pageToken) => {
@@ -1990,39 +2069,62 @@ async function listSubscriptions(client, packageName, options) {
1990
2069
  });
1991
2070
  }
1992
2071
  async function getSubscription(client, packageName, productId) {
2072
+ validatePackageName(packageName);
2073
+ validateSku(productId);
1993
2074
  return client.subscriptions.get(packageName, productId);
1994
2075
  }
1995
2076
  async function createSubscription(client, packageName, data) {
2077
+ validatePackageName(packageName);
1996
2078
  return client.subscriptions.create(packageName, data);
1997
2079
  }
1998
2080
  async function updateSubscription(client, packageName, productId, data, updateMask) {
2081
+ validatePackageName(packageName);
2082
+ validateSku(productId);
1999
2083
  return client.subscriptions.update(packageName, productId, data, updateMask);
2000
2084
  }
2001
2085
  async function deleteSubscription(client, packageName, productId) {
2086
+ validatePackageName(packageName);
2087
+ validateSku(productId);
2002
2088
  return client.subscriptions.delete(packageName, productId);
2003
2089
  }
2004
2090
  async function activateBasePlan(client, packageName, productId, basePlanId) {
2091
+ validatePackageName(packageName);
2092
+ validateSku(productId);
2005
2093
  return client.subscriptions.activateBasePlan(packageName, productId, basePlanId);
2006
2094
  }
2007
2095
  async function deactivateBasePlan(client, packageName, productId, basePlanId) {
2096
+ validatePackageName(packageName);
2097
+ validateSku(productId);
2008
2098
  return client.subscriptions.deactivateBasePlan(packageName, productId, basePlanId);
2009
2099
  }
2010
2100
  async function deleteBasePlan(client, packageName, productId, basePlanId) {
2101
+ validatePackageName(packageName);
2102
+ validateSku(productId);
2011
2103
  return client.subscriptions.deleteBasePlan(packageName, productId, basePlanId);
2012
2104
  }
2013
2105
  async function migratePrices(client, packageName, productId, basePlanId, data) {
2106
+ validatePackageName(packageName);
2107
+ validateSku(productId);
2014
2108
  return client.subscriptions.migratePrices(packageName, productId, basePlanId, data);
2015
2109
  }
2016
2110
  async function listOffers(client, packageName, productId, basePlanId) {
2111
+ validatePackageName(packageName);
2112
+ validateSku(productId);
2017
2113
  return client.subscriptions.listOffers(packageName, productId, basePlanId);
2018
2114
  }
2019
2115
  async function getOffer(client, packageName, productId, basePlanId, offerId) {
2116
+ validatePackageName(packageName);
2117
+ validateSku(productId);
2020
2118
  return client.subscriptions.getOffer(packageName, productId, basePlanId, offerId);
2021
2119
  }
2022
2120
  async function createOffer(client, packageName, productId, basePlanId, data) {
2121
+ validatePackageName(packageName);
2122
+ validateSku(productId);
2023
2123
  return client.subscriptions.createOffer(packageName, productId, basePlanId, data);
2024
2124
  }
2025
2125
  async function updateOffer(client, packageName, productId, basePlanId, offerId, data, updateMask) {
2126
+ validatePackageName(packageName);
2127
+ validateSku(productId);
2026
2128
  return client.subscriptions.updateOffer(
2027
2129
  packageName,
2028
2130
  productId,
@@ -2033,12 +2135,18 @@ async function updateOffer(client, packageName, productId, basePlanId, offerId,
2033
2135
  );
2034
2136
  }
2035
2137
  async function deleteOffer(client, packageName, productId, basePlanId, offerId) {
2138
+ validatePackageName(packageName);
2139
+ validateSku(productId);
2036
2140
  return client.subscriptions.deleteOffer(packageName, productId, basePlanId, offerId);
2037
2141
  }
2038
2142
  async function activateOffer(client, packageName, productId, basePlanId, offerId) {
2143
+ validatePackageName(packageName);
2144
+ validateSku(productId);
2039
2145
  return client.subscriptions.activateOffer(packageName, productId, basePlanId, offerId);
2040
2146
  }
2041
2147
  async function deactivateOffer(client, packageName, productId, basePlanId, offerId) {
2148
+ validatePackageName(packageName);
2149
+ validateSku(productId);
2042
2150
  return client.subscriptions.deactivateOffer(packageName, productId, basePlanId, offerId);
2043
2151
  }
2044
2152
 
@@ -2200,22 +2308,28 @@ async function batchSyncInAppProducts(client, packageName, dir, options) {
2200
2308
  // src/commands/purchases.ts
2201
2309
  import { paginateAll as paginateAll4 } from "@gpc-cli/api";
2202
2310
  async function getProductPurchase(client, packageName, productId, token) {
2311
+ validatePackageName(packageName);
2203
2312
  return client.purchases.getProduct(packageName, productId, token);
2204
2313
  }
2205
2314
  async function acknowledgeProductPurchase(client, packageName, productId, token, payload) {
2315
+ validatePackageName(packageName);
2206
2316
  const body = payload ? { developerPayload: payload } : void 0;
2207
2317
  return client.purchases.acknowledgeProduct(packageName, productId, token, body);
2208
2318
  }
2209
2319
  async function consumeProductPurchase(client, packageName, productId, token) {
2320
+ validatePackageName(packageName);
2210
2321
  return client.purchases.consumeProduct(packageName, productId, token);
2211
2322
  }
2212
2323
  async function getSubscriptionPurchase(client, packageName, token) {
2324
+ validatePackageName(packageName);
2213
2325
  return client.purchases.getSubscriptionV2(packageName, token);
2214
2326
  }
2215
2327
  async function cancelSubscriptionPurchase(client, packageName, subscriptionId, token) {
2328
+ validatePackageName(packageName);
2216
2329
  return client.purchases.cancelSubscription(packageName, subscriptionId, token);
2217
2330
  }
2218
2331
  async function deferSubscriptionPurchase(client, packageName, subscriptionId, token, desiredExpiry) {
2332
+ validatePackageName(packageName);
2219
2333
  const sub = await client.purchases.getSubscriptionV1(packageName, subscriptionId, token);
2220
2334
  return client.purchases.deferSubscription(packageName, subscriptionId, token, {
2221
2335
  deferralInfo: {
@@ -2225,9 +2339,11 @@ async function deferSubscriptionPurchase(client, packageName, subscriptionId, to
2225
2339
  });
2226
2340
  }
2227
2341
  async function revokeSubscriptionPurchase(client, packageName, token) {
2342
+ validatePackageName(packageName);
2228
2343
  return client.purchases.revokeSubscriptionV2(packageName, token);
2229
2344
  }
2230
2345
  async function listVoidedPurchases(client, packageName, options) {
2346
+ validatePackageName(packageName);
2231
2347
  if (options?.limit || options?.nextPage) {
2232
2348
  const result = await paginateAll4(
2233
2349
  async (pageToken) => {
@@ -2249,6 +2365,7 @@ async function listVoidedPurchases(client, packageName, options) {
2249
2365
  return client.purchases.listVoided(packageName, options);
2250
2366
  }
2251
2367
  async function refundOrder(client, packageName, orderId, options) {
2368
+ validatePackageName(packageName);
2252
2369
  return client.orders.refund(packageName, orderId, options);
2253
2370
  }
2254
2371
 
@@ -3112,9 +3229,8 @@ async function writeAuditLog(entry) {
3112
3229
  }
3113
3230
  }
3114
3231
  var SENSITIVE_ARG_KEYS = /* @__PURE__ */ new Set([
3115
- "key",
3116
3232
  "keyFile",
3117
- "key-file",
3233
+ "key_file",
3118
3234
  "serviceAccount",
3119
3235
  "service-account",
3120
3236
  "token",
@@ -3122,7 +3238,24 @@ var SENSITIVE_ARG_KEYS = /* @__PURE__ */ new Set([
3122
3238
  "secret",
3123
3239
  "credentials",
3124
3240
  "private_key",
3125
- "client_secret"
3241
+ "privateKey",
3242
+ "private_key_id",
3243
+ "privateKeyId",
3244
+ "client_secret",
3245
+ "clientSecret",
3246
+ "accessToken",
3247
+ "access_token",
3248
+ "refreshToken",
3249
+ "refresh_token",
3250
+ "apiKey",
3251
+ "api_key",
3252
+ "auth_token",
3253
+ "bearer",
3254
+ "jwt",
3255
+ "signing_key",
3256
+ "keystore_password",
3257
+ "store_password",
3258
+ "key_password"
3126
3259
  ]);
3127
3260
  function redactAuditArgs(entry) {
3128
3261
  const redacted = {};
@@ -3389,6 +3522,8 @@ export {
3389
3522
  NetworkError,
3390
3523
  PERMISSION_PROPAGATION_WARNING,
3391
3524
  PluginManager,
3525
+ SENSITIVE_ARG_KEYS,
3526
+ SENSITIVE_KEYS,
3392
3527
  acknowledgeProductPurchase,
3393
3528
  activateBasePlan,
3394
3529
  activateOffer,
@@ -3505,6 +3640,7 @@ export {
3505
3640
  pushListings,
3506
3641
  readListingsFromDir,
3507
3642
  readReleaseNotesFromDir,
3643
+ redactAuditArgs,
3508
3644
  redactSensitive,
3509
3645
  refundExternalTransaction,
3510
3646
  refundOrder,
@@ -3535,9 +3671,14 @@ export {
3535
3671
  uploadInternalSharing,
3536
3672
  uploadRelease,
3537
3673
  validateImage,
3674
+ validateLanguageCode,
3675
+ validatePackageName,
3538
3676
  validatePreSubmission,
3539
3677
  validateReleaseNotes,
3678
+ validateSku,
3679
+ validateTrackName,
3540
3680
  validateUploadFile,
3681
+ validateVersionCode,
3541
3682
  writeAuditLog,
3542
3683
  writeListingsToDir,
3543
3684
  writeMigrationOutput