eas-cli 0.52.0 → 0.54.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.
Files changed (119) hide show
  1. package/README.md +132 -44
  2. package/build/analytics/events.d.ts +5 -1
  3. package/build/analytics/events.js +6 -1
  4. package/build/build/android/version.js +1 -1
  5. package/build/build/build.js +38 -27
  6. package/build/build/local.js +1 -1
  7. package/build/build/runBuildAndSubmit.js +4 -2
  8. package/build/build/utils/url.d.ts +1 -0
  9. package/build/build/utils/url.js +5 -1
  10. package/build/commands/branch/create.js +2 -2
  11. package/build/commands/branch/delete.js +2 -2
  12. package/build/commands/branch/list.js +2 -2
  13. package/build/commands/branch/rename.js +2 -2
  14. package/build/commands/branch/view.js +2 -2
  15. package/build/commands/build/cancel.js +3 -3
  16. package/build/commands/build/configure.js +2 -2
  17. package/build/commands/build/index.d.ts +0 -1
  18. package/build/commands/build/index.js +1 -53
  19. package/build/commands/build/inspect.js +1 -1
  20. package/build/commands/build/list.js +2 -2
  21. package/build/commands/build/view.js +2 -2
  22. package/build/commands/channel/create.js +2 -2
  23. package/build/commands/channel/delete.js +2 -2
  24. package/build/commands/channel/edit.js +2 -2
  25. package/build/commands/channel/list.js +2 -2
  26. package/build/commands/channel/rollout.js +2 -2
  27. package/build/commands/channel/view.js +3 -3
  28. package/build/commands/config.js +0 -2
  29. package/build/commands/device/delete.js +2 -2
  30. package/build/commands/device/list.js +2 -2
  31. package/build/commands/device/view.js +2 -2
  32. package/build/commands/metadata/pull.d.ts +8 -0
  33. package/build/commands/metadata/pull.js +59 -0
  34. package/build/commands/metadata/push.d.ts +8 -0
  35. package/build/commands/metadata/push.js +51 -0
  36. package/build/commands/project/info.js +2 -2
  37. package/build/commands/project/init.js +2 -2
  38. package/build/commands/secret/create.js +2 -2
  39. package/build/commands/secret/delete.js +2 -2
  40. package/build/commands/secret/list.js +2 -2
  41. package/build/commands/submit.js +4 -3
  42. package/build/commands/update/configure.js +2 -3
  43. package/build/commands/update/index.d.ts +12 -0
  44. package/build/commands/update/index.js +81 -39
  45. package/build/commands/update/list.js +2 -2
  46. package/build/commands/webhook/create.js +2 -2
  47. package/build/commands/webhook/delete.js +2 -2
  48. package/build/commands/webhook/list.js +2 -2
  49. package/build/credentials/android/utils/googleServiceAccountKey.js +1 -1
  50. package/build/credentials/android/utils/keystore.js +1 -1
  51. package/build/credentials/android/utils/keystoreNew.js +2 -2
  52. package/build/credentials/context.js +2 -3
  53. package/build/credentials/credentialsJson/read.js +1 -1
  54. package/build/credentials/ios/utils/provisioningProfile.js +1 -1
  55. package/build/credentials/ios/validators/validateProvisioningProfile.js +1 -1
  56. package/build/graphql/generated.d.ts +90 -33
  57. package/build/graphql/generated.js +5 -0
  58. package/build/graphql/queries/UpdateQuery.d.ts +4 -1
  59. package/build/graphql/queries/UpdateQuery.js +8 -7
  60. package/build/metadata/apple/config/reader.d.ts +25 -0
  61. package/build/metadata/apple/config/reader.js +95 -0
  62. package/build/metadata/apple/config/writer.d.ts +23 -0
  63. package/build/metadata/apple/config/writer.js +85 -0
  64. package/build/metadata/apple/data.d.ts +20 -0
  65. package/build/metadata/apple/data.js +2 -0
  66. package/build/metadata/apple/task.d.ts +24 -0
  67. package/build/metadata/apple/task.js +6 -0
  68. package/build/metadata/apple/tasks/age-rating.d.ts +13 -0
  69. package/build/metadata/apple/tasks/age-rating.js +39 -0
  70. package/build/metadata/apple/tasks/app-info.d.ts +15 -0
  71. package/build/metadata/apple/tasks/app-info.js +73 -0
  72. package/build/metadata/apple/tasks/app-version.d.ts +27 -0
  73. package/build/metadata/apple/tasks/app-version.js +104 -0
  74. package/build/metadata/apple/tasks/index.d.ts +6 -0
  75. package/build/metadata/apple/tasks/index.js +13 -0
  76. package/build/metadata/apple/types.d.ts +50 -0
  77. package/build/metadata/apple/types.js +2 -0
  78. package/build/metadata/config.d.ts +22 -0
  79. package/build/metadata/config.js +32 -0
  80. package/build/metadata/context.d.ts +46 -0
  81. package/build/metadata/context.js +48 -0
  82. package/build/metadata/download.d.ts +6 -0
  83. package/build/metadata/download.js +65 -0
  84. package/build/metadata/errors.d.ts +37 -0
  85. package/build/metadata/errors.js +69 -0
  86. package/build/metadata/upload.d.ts +6 -0
  87. package/build/metadata/upload.js +57 -0
  88. package/build/metadata/utils/asc.d.ts +4 -0
  89. package/build/metadata/utils/asc.js +2 -0
  90. package/build/metadata/utils/date.d.ts +12 -0
  91. package/build/metadata/utils/date.js +30 -0
  92. package/build/metadata/utils/log.d.ts +16 -0
  93. package/build/metadata/utils/log.js +23 -0
  94. package/build/metadata/utils/retry.d.ts +8 -0
  95. package/build/metadata/utils/retry.js +22 -0
  96. package/build/metadata/utils/telemetry.d.ts +20 -0
  97. package/build/metadata/utils/telemetry.js +87 -0
  98. package/build/project/android/applicationId.js +1 -1
  99. package/build/project/ensureProjectExists.js +4 -1
  100. package/build/project/ios/bundleIdentifier.js +1 -1
  101. package/build/project/publish.d.ts +6 -1
  102. package/build/project/publish.js +16 -3
  103. package/build/submit/ArchiveSource.js +1 -1
  104. package/build/submit/submit.js +1 -1
  105. package/build/submit/utils/errors.js +2 -0
  106. package/build/submit/utils/files.js +1 -1
  107. package/build/submit/utils/logs.js +1 -1
  108. package/build/update/android/UpdatesModule.js +2 -2
  109. package/build/update/ios/UpdatesModule.js +2 -2
  110. package/build/user/actions.js +1 -1
  111. package/build/utils/expodash/uniq.d.ts +1 -0
  112. package/build/utils/expodash/uniq.js +7 -0
  113. package/build/utils/profiles.d.ts +3 -3
  114. package/build/utils/profiles.js +5 -93
  115. package/build/vcs/clients/git.js +5 -5
  116. package/build/vcs/git.js +1 -1
  117. package/build/webhooks/input.js +1 -1
  118. package/oclif.manifest.json +1 -1
  119. package/package.json +43 -38
@@ -0,0 +1,23 @@
1
+ /// <reference types="@expo/apple-utils/ts-declarations/expo__app-store" />
2
+ import { AgeRatingDeclaration, AppInfo, AppInfoLocalization, AppStoreVersion, AppStoreVersionLocalization } from '@expo/apple-utils';
3
+ import { AttributesOf } from '../../utils/asc';
4
+ import { AppleMetadata } from '../types';
5
+ /**
6
+ * Serializes the Apple ASC entities into the metadata configuration schema.
7
+ * This uses version 0 of the config schema.
8
+ */
9
+ export declare class AppleConfigWriter {
10
+ readonly schema: Partial<AppleMetadata>;
11
+ constructor(schema?: Partial<AppleMetadata>);
12
+ /** Get the schema result to write it to the config file */
13
+ toSchema(): {
14
+ configVersion: number;
15
+ apple: Partial<AppleMetadata>;
16
+ };
17
+ setAgeRating(attributes: AttributesOf<AgeRatingDeclaration>): void;
18
+ setInfoLocale(attributes: AttributesOf<AppInfoLocalization>): void;
19
+ setCategories({ primaryCategory, secondaryCategory }: AttributesOf<AppInfo>): void;
20
+ setVersion(attributes: Omit<AttributesOf<AppStoreVersion>, 'releaseType' | 'earliestReleaseDate'>): void;
21
+ setVersionRelease(attributes: Pick<AttributesOf<AppStoreVersion>, 'releaseType' | 'earliestReleaseDate'>): void;
22
+ setVersionLocale(attributes: AttributesOf<AppStoreVersionLocalization>): void;
23
+ }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AppleConfigWriter = void 0;
4
+ const apple_utils_1 = require("@expo/apple-utils");
5
+ /**
6
+ * Serializes the Apple ASC entities into the metadata configuration schema.
7
+ * This uses version 0 of the config schema.
8
+ */
9
+ class AppleConfigWriter {
10
+ constructor(schema = {}) {
11
+ this.schema = schema;
12
+ }
13
+ /** Get the schema result to write it to the config file */
14
+ toSchema() {
15
+ return {
16
+ configVersion: 0,
17
+ apple: this.schema,
18
+ };
19
+ }
20
+ setAgeRating(attributes) {
21
+ this.schema.advisory = attributes;
22
+ }
23
+ setInfoLocale(attributes) {
24
+ var _a, _b, _c;
25
+ this.schema.info = (_a = this.schema.info) !== null && _a !== void 0 ? _a : {};
26
+ const existing = (_b = this.schema.info[attributes.locale]) !== null && _b !== void 0 ? _b : {};
27
+ this.schema.info[attributes.locale] = {
28
+ ...existing,
29
+ title: (_c = attributes.name) !== null && _c !== void 0 ? _c : 'no name provided',
30
+ subtitle: optional(attributes.subtitle),
31
+ privacyPolicyUrl: optional(attributes.privacyPolicyUrl),
32
+ privacyPolicyText: optional(attributes.privacyPolicyText),
33
+ privacyChoicesUrl: optional(attributes.privacyChoicesUrl),
34
+ };
35
+ }
36
+ setCategories({ primaryCategory, secondaryCategory }) {
37
+ this.schema.categories = [];
38
+ // TODO: see why these types are conflicting
39
+ if (primaryCategory) {
40
+ this.schema.categories.push(primaryCategory.id);
41
+ if (secondaryCategory) {
42
+ this.schema.categories.push(secondaryCategory.id);
43
+ }
44
+ }
45
+ }
46
+ setVersion(attributes) {
47
+ this.schema.copyright = optional(attributes.copyright);
48
+ }
49
+ setVersionRelease(attributes) {
50
+ if (attributes.releaseType === apple_utils_1.ReleaseType.SCHEDULED) {
51
+ this.schema.release = {
52
+ autoReleaseDate: optional(attributes.earliestReleaseDate),
53
+ };
54
+ }
55
+ if (attributes.releaseType === apple_utils_1.ReleaseType.AFTER_APPROVAL) {
56
+ this.schema.release = {
57
+ automaticRelease: true,
58
+ };
59
+ }
60
+ if (attributes.releaseType === apple_utils_1.ReleaseType.MANUAL) {
61
+ this.schema.release = {
62
+ automaticRelease: false,
63
+ };
64
+ }
65
+ }
66
+ setVersionLocale(attributes) {
67
+ var _a, _b, _c;
68
+ this.schema.info = (_a = this.schema.info) !== null && _a !== void 0 ? _a : {};
69
+ const existing = (_b = this.schema.info[attributes.locale]) !== null && _b !== void 0 ? _b : {};
70
+ this.schema.info[attributes.locale] = {
71
+ ...existing,
72
+ description: optional(attributes.description),
73
+ keywords: (_c = optional(attributes.keywords)) === null || _c === void 0 ? void 0 : _c.split(',').map(keyword => keyword.trim()),
74
+ releaseNotes: optional(attributes.whatsNew),
75
+ marketingUrl: optional(attributes.marketingUrl),
76
+ promoText: optional(attributes.promotionalText),
77
+ supportUrl: optional(attributes.supportUrl),
78
+ };
79
+ }
80
+ }
81
+ exports.AppleConfigWriter = AppleConfigWriter;
82
+ /** Helper function to convert `T | null` to `T | undefined`, required for the entity properties */
83
+ function optional(value) {
84
+ return value !== null && value !== void 0 ? value : undefined;
85
+ }
@@ -0,0 +1,20 @@
1
+ /// <reference types="@expo/apple-utils/ts-declarations/expo__app-store" />
2
+ import type { App } from '@expo/apple-utils';
3
+ import type { AgeRatingData } from './tasks/age-rating';
4
+ import type { AppInfoData } from './tasks/app-info';
5
+ import type { AppVersionData } from './tasks/app-version';
6
+ /**
7
+ * The fully prepared apple data, used within the `downloadAsync` or `uploadAsync` tasks.
8
+ * It contains references to each individual models, to either upload or download App Store data.
9
+ */
10
+ export declare type AppleData = {
11
+ app: App;
12
+ } & AppInfoData & AppVersionData & AgeRatingData;
13
+ /**
14
+ * The unprepared partial apple data, used within the `prepareAsync` tasks.
15
+ * It contains a reference to the app, each task should populate the necessary data.
16
+ * If an entity fails to prepare the data, individual tasks should raise errors about the missing data.
17
+ */
18
+ export declare type PartialAppleData = {
19
+ app: App;
20
+ } & Partial<Omit<AppleData, 'app'>>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,24 @@
1
+ import { AppleConfigReader } from './config/reader';
2
+ import { AppleConfigWriter } from './config/writer';
3
+ import { AppleData, PartialAppleData } from './data';
4
+ export declare abstract class AppleTask {
5
+ /** Get a description from the task to use as section headings in the log */
6
+ abstract name(): string;
7
+ /** Prepare the data from the App Store to start syncing with the store configuration */
8
+ abstract prepareAsync(options: TaskPrepareOptions): Promise<void>;
9
+ /** Download all information from the App Store to generate the store configuration */
10
+ abstract downloadAsync(options: TaskDownloadOptions): Promise<void>;
11
+ /** Upload all information from the store configuration to the App Store */
12
+ abstract uploadAsync(options: TaskUploadOptions): Promise<void>;
13
+ }
14
+ export declare type TaskPrepareOptions = {
15
+ context: PartialAppleData;
16
+ };
17
+ export declare type TaskDownloadOptions = {
18
+ config: AppleConfigWriter;
19
+ context: AppleData;
20
+ };
21
+ export declare type TaskUploadOptions = {
22
+ config: AppleConfigReader;
23
+ context: AppleData;
24
+ };
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AppleTask = void 0;
4
+ class AppleTask {
5
+ }
6
+ exports.AppleTask = AppleTask;
@@ -0,0 +1,13 @@
1
+ /// <reference types="@expo/apple-utils/ts-declarations/expo__app-store" />
2
+ import { AgeRatingDeclaration } from '@expo/apple-utils';
3
+ import { AppleTask, TaskDownloadOptions, TaskPrepareOptions, TaskUploadOptions } from '../task';
4
+ export declare type AgeRatingData = {
5
+ /** The app age rating declaration for the app version */
6
+ ageRating: AgeRatingDeclaration;
7
+ };
8
+ export declare class AgeRatingTask extends AppleTask {
9
+ name: () => string;
10
+ prepareAsync({ context }: TaskPrepareOptions): Promise<void>;
11
+ downloadAsync({ config, context }: TaskDownloadOptions): Promise<void>;
12
+ uploadAsync({ config, context }: TaskUploadOptions): Promise<void>;
13
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgeRatingTask = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const assert_1 = tslib_1.__importDefault(require("assert"));
6
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
+ const log_1 = tslib_1.__importDefault(require("../../../log"));
8
+ const log_2 = require("../../utils/log");
9
+ const task_1 = require("../task");
10
+ class AgeRatingTask extends task_1.AppleTask {
11
+ constructor() {
12
+ super(...arguments);
13
+ this.name = () => 'age rating declarations';
14
+ }
15
+ async prepareAsync({ context }) {
16
+ (0, assert_1.default)(context.version, `App version information is not prepared, can't update age rating`);
17
+ context.ageRating = (await context.version.getAgeRatingDeclarationAsync()) || undefined;
18
+ }
19
+ async downloadAsync({ config, context }) {
20
+ if (context.ageRating) {
21
+ config.setAgeRating(context.ageRating.attributes);
22
+ }
23
+ }
24
+ async uploadAsync({ config, context }) {
25
+ (0, assert_1.default)(context.ageRating, `Age rating not initialized, can't update age rating`);
26
+ const ageRating = config.getAgeRating();
27
+ if (!ageRating) {
28
+ log_1.default.log((0, chalk_1.default) `{dim - Skipped age rating update, no advisory configured}`);
29
+ }
30
+ else {
31
+ context.ageRating = await (0, log_2.logAsync)(() => context.ageRating.updateAsync(ageRating), {
32
+ pending: 'Updating age rating declaration...',
33
+ success: 'Updated age rating declaration',
34
+ failure: 'Failed to update age rating declaration',
35
+ });
36
+ }
37
+ }
38
+ }
39
+ exports.AgeRatingTask = AgeRatingTask;
@@ -0,0 +1,15 @@
1
+ /// <reference types="@expo/apple-utils/ts-declarations/expo__app-store" />
2
+ import { AppInfo, AppInfoLocalization } from '@expo/apple-utils';
3
+ import { AppleTask, TaskDownloadOptions, TaskPrepareOptions, TaskUploadOptions } from '../task';
4
+ export declare type AppInfoData = {
5
+ /** The current app info that should be edited */
6
+ info: AppInfo;
7
+ /** All info locales that are enabled */
8
+ infoLocales: AppInfoLocalization[];
9
+ };
10
+ export declare class AppInfoTask extends AppleTask {
11
+ name: () => string;
12
+ prepareAsync({ context }: TaskPrepareOptions): Promise<void>;
13
+ downloadAsync({ config, context }: TaskDownloadOptions): Promise<void>;
14
+ uploadAsync({ config, context }: TaskUploadOptions): Promise<void>;
15
+ }
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AppInfoTask = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const assert_1 = tslib_1.__importDefault(require("assert"));
6
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
+ const log_1 = tslib_1.__importDefault(require("../../../log"));
8
+ const log_2 = require("../../utils/log");
9
+ const retry_1 = require("../../utils/retry");
10
+ const task_1 = require("../task");
11
+ class AppInfoTask extends task_1.AppleTask {
12
+ constructor() {
13
+ super(...arguments);
14
+ this.name = () => 'app information';
15
+ }
16
+ async prepareAsync({ context }) {
17
+ const info = await (0, retry_1.retryIfNullAsync)(() => context.app.getEditAppInfoAsync());
18
+ (0, assert_1.default)(info, 'Could not resolve the editable app info to update');
19
+ context.info = info;
20
+ context.infoLocales = await info.getLocalizationsAsync();
21
+ }
22
+ async downloadAsync({ config, context }) {
23
+ (0, assert_1.default)(context.info, `App info not initialized, can't download info`);
24
+ config.setCategories(context.info.attributes);
25
+ for (const locale of context.infoLocales) {
26
+ config.setInfoLocale(locale.attributes);
27
+ }
28
+ }
29
+ async uploadAsync({ config, context }) {
30
+ (0, assert_1.default)(context.info, `App info not initialized, can't update info`);
31
+ const categories = config.getCategories();
32
+ if (!categories) {
33
+ log_1.default.log((0, chalk_1.default) `{dim - Skipped app category update, not configured}`);
34
+ }
35
+ else {
36
+ context.info = await (0, log_2.logAsync)(() => context.info.updateCategoriesAsync(categories), {
37
+ pending: 'Updating app categories...',
38
+ success: 'Updated app categories',
39
+ failure: 'Failed updating app categories',
40
+ });
41
+ }
42
+ const locales = config.getLocales();
43
+ if (locales.length <= 0) {
44
+ log_1.default.log((0, chalk_1.default) `{dim - Skipped localized info update, no locales configured}`);
45
+ }
46
+ else {
47
+ // BUG: new issue introduced in ASC 1.8.0, when creating version locales, info locales are also generated
48
+ context.infoLocales = await (0, log_2.logAsync)(() => context.info.getLocalizationsAsync(), {
49
+ pending: 'Reloading localized info...',
50
+ success: 'Reloaded localized info',
51
+ failure: 'Failed reloading localized info',
52
+ });
53
+ for (const locale of locales) {
54
+ const attributes = config.getInfoLocale(locale);
55
+ if (!attributes) {
56
+ continue;
57
+ }
58
+ const model = context.infoLocales.find(model => model.attributes.locale === locale);
59
+ await (0, log_2.logAsync)(async () => {
60
+ return model
61
+ ? await model.updateAsync(attributes)
62
+ : await context.info.createLocalizationAsync({ ...attributes, locale });
63
+ }, {
64
+ pending: `${model ? 'Updating' : 'Creating'} localized info for ${chalk_1.default.bold(locale)}...`,
65
+ success: `${model ? 'Updated' : 'Created'} localized info for ${chalk_1.default.bold(locale)}`,
66
+ failure: `Failed ${model ? 'updating' : 'creating'} localized info for ${chalk_1.default.bold(locale)}`,
67
+ });
68
+ }
69
+ context.infoLocales = await context.info.getLocalizationsAsync();
70
+ }
71
+ }
72
+ }
73
+ exports.AppInfoTask = AppInfoTask;
@@ -0,0 +1,27 @@
1
+ /// <reference types="@expo/apple-utils/ts-declarations/expo__app-store" />
2
+ import { AppStoreVersion, AppStoreVersionLocalization, Platform } from '@expo/apple-utils';
3
+ import { AppleTask, TaskDownloadOptions, TaskPrepareOptions, TaskUploadOptions } from '../task';
4
+ export declare type AppVersionOptions = {
5
+ /** If we should use the live version of the app (if available - defaults to false) */
6
+ editLive: boolean;
7
+ /** The platform to use (defaults to IOS) */
8
+ platform: Platform;
9
+ };
10
+ export declare type AppVersionData = {
11
+ /** The current selected app store version to update */
12
+ version: AppStoreVersion;
13
+ /** If the current selected version is a live version, where not all properties are editable */
14
+ versionIsLive: boolean;
15
+ /** If the current selected version is the first version to be created */
16
+ versionIsFirst: boolean;
17
+ /** All version locales that should be, or are enabled */
18
+ versionLocales: AppStoreVersionLocalization[];
19
+ };
20
+ export declare class AppVersionTask extends AppleTask {
21
+ private options;
22
+ constructor(options?: Partial<AppVersionOptions>);
23
+ name: () => string;
24
+ prepareAsync({ context }: TaskPrepareOptions): Promise<void>;
25
+ downloadAsync({ config, context }: TaskDownloadOptions): Promise<void>;
26
+ uploadAsync({ config, context }: TaskUploadOptions): Promise<void>;
27
+ }
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AppVersionTask = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const apple_utils_1 = require("@expo/apple-utils");
6
+ const assert_1 = tslib_1.__importDefault(require("assert"));
7
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
+ const log_1 = tslib_1.__importDefault(require("../../../log"));
9
+ const log_2 = require("../../utils/log");
10
+ const retry_1 = require("../../utils/retry");
11
+ const task_1 = require("../task");
12
+ class AppVersionTask extends task_1.AppleTask {
13
+ constructor(options = {}) {
14
+ var _a, _b;
15
+ super();
16
+ this.name = () => (this.options.editLive ? 'live app version' : 'editable app version');
17
+ this.options = {
18
+ platform: (_a = options.platform) !== null && _a !== void 0 ? _a : apple_utils_1.Platform.IOS,
19
+ editLive: (_b = options.editLive) !== null && _b !== void 0 ? _b : false,
20
+ };
21
+ }
22
+ async prepareAsync({ context }) {
23
+ const { version, versionIsFirst, versionIsLive } = await resolveVersionAsync(context.app, this.options);
24
+ (0, assert_1.default)(version, 'Could not resolve a live or editable app version');
25
+ context.version = version;
26
+ context.versionIsFirst = versionIsFirst;
27
+ context.versionIsLive = versionIsLive;
28
+ context.versionLocales = await version.getLocalizationsAsync();
29
+ }
30
+ async downloadAsync({ config, context }) {
31
+ (0, assert_1.default)(context.version, `App version not initialized, can't download version`);
32
+ config.setVersion(context.version.attributes);
33
+ config.setVersionRelease(context.version.attributes);
34
+ for (const locale of context.versionLocales) {
35
+ config.setVersionLocale(locale.attributes);
36
+ }
37
+ }
38
+ async uploadAsync({ config, context }) {
39
+ (0, assert_1.default)(context.version, `App version not initialized, can't update version`);
40
+ const version = config.getVersion();
41
+ const release = config.getVersionRelease();
42
+ if (!version && !release) {
43
+ log_1.default.log((0, chalk_1.default) `{dim - Skipped version and release update, not configured}`);
44
+ }
45
+ else {
46
+ const { versionString } = context.version.attributes;
47
+ const description = [version && 'version', release && 'release']
48
+ .filter(Boolean)
49
+ .join(' and ');
50
+ context.version = await (0, log_2.logAsync)(() => context.version.updateAsync({ ...version, ...release }), {
51
+ pending: `Updating ${description} info for ${chalk_1.default.bold(versionString)}...`,
52
+ success: `Updated ${description} info for ${chalk_1.default.bold(versionString)}...`,
53
+ failure: `Failed updating ${description} info for ${chalk_1.default.bold(versionString)}...`,
54
+ });
55
+ }
56
+ const locales = config.getLocales();
57
+ if (locales.length <= 0) {
58
+ log_1.default.log((0, chalk_1.default) `{dim - Skipped localized version update, no locales configured}`);
59
+ }
60
+ else {
61
+ for (const locale of locales) {
62
+ const attributes = config.getVersionLocale(locale, context);
63
+ if (!attributes) {
64
+ continue;
65
+ }
66
+ const oldModel = context.versionLocales.find(model => model.attributes.locale === locale);
67
+ await (0, log_2.logAsync)(async () => {
68
+ return oldModel
69
+ ? await oldModel.updateAsync(attributes)
70
+ : await context.version.createLocalizationAsync({ ...attributes, locale });
71
+ }, {
72
+ pending: `${oldModel ? 'Updating' : 'Creating'} localized version for ${chalk_1.default.bold(locale)}...`,
73
+ success: `${oldModel ? 'Updated' : 'Created'} localized version for ${chalk_1.default.bold(locale)}`,
74
+ failure: `Failed ${oldModel ? 'updating' : 'creating'} localized version for ${chalk_1.default.bold(locale)}`,
75
+ });
76
+ }
77
+ context.versionLocales = await context.version.getLocalizationsAsync();
78
+ }
79
+ }
80
+ }
81
+ exports.AppVersionTask = AppVersionTask;
82
+ /**
83
+ * Resolve the AppStoreVersion instance, either from live or editable version.
84
+ * This also checks if this is the first version, which disallow release notes.
85
+ */
86
+ async function resolveVersionAsync(app, { editLive, platform }) {
87
+ let version = null;
88
+ let versionIsLive = false;
89
+ if (editLive) {
90
+ version = await app.getLiveAppStoreVersionAsync({ platform });
91
+ versionIsLive = !!version;
92
+ }
93
+ if (!version) {
94
+ version = await (0, retry_1.retryIfNullAsync)(() => app.getEditAppStoreVersionAsync({ platform }));
95
+ }
96
+ const versions = await app.getAppStoreVersionsAsync({
97
+ query: { limit: 2, filter: { platform } },
98
+ });
99
+ return {
100
+ version,
101
+ versionIsLive,
102
+ versionIsFirst: versions.length === 1,
103
+ };
104
+ }
@@ -0,0 +1,6 @@
1
+ import { MetadataContext } from '../../context';
2
+ import { AppleTask } from '../task';
3
+ /**
4
+ * List of all eligible tasks to sync local store configuration to the App store.
5
+ */
6
+ export declare function createAppleTasks(_ctx: MetadataContext): AppleTask[];
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAppleTasks = void 0;
4
+ const age_rating_1 = require("./age-rating");
5
+ const app_info_1 = require("./app-info");
6
+ const app_version_1 = require("./app-version");
7
+ /**
8
+ * List of all eligible tasks to sync local store configuration to the App store.
9
+ */
10
+ function createAppleTasks(_ctx) {
11
+ return [new app_version_1.AppVersionTask(), new app_info_1.AppInfoTask(), new age_rating_1.AgeRatingTask()];
12
+ }
13
+ exports.createAppleTasks = createAppleTasks;
@@ -0,0 +1,50 @@
1
+ /// <reference types="@expo/apple-utils/ts-declarations/expo__app-store" />
2
+ import type { AgeRatingDeclarationProps, AppCategoryId, AppSubcategoryId } from '@expo/apple-utils';
3
+ export declare type AppleLocale = string;
4
+ export interface AppleMetadata {
5
+ copyright?: string;
6
+ info?: Record<AppleLocale, AppleInfo>;
7
+ categories?: AppCategoryId[] | AppleCategory;
8
+ release?: AppleRelease;
9
+ advisory?: AppleAdvisory;
10
+ preview?: Record<string, string[]>;
11
+ review?: AppleReview;
12
+ }
13
+ export declare type AppleAdvisory = Partial<AgeRatingDeclarationProps>;
14
+ export interface AppleCategory {
15
+ category: AppCategoryId;
16
+ subcategory?: AppSubcategoryId[];
17
+ }
18
+ export interface AppleRelease {
19
+ isPhasedReleaseEnabled?: boolean;
20
+ shouldResetRatings?: boolean;
21
+ autoReleaseDate?: number | string;
22
+ automaticRelease?: boolean;
23
+ usesThirdPartyContent?: boolean;
24
+ /** Alternative to setting `ITSAppUsesNonExemptEncryption` in the binary's `Info.plist`. */
25
+ usesNonExemptEncryption?: boolean;
26
+ }
27
+ export interface AppleInfo {
28
+ title: string;
29
+ subtitle?: string;
30
+ /** Does not effect ASO https://developer.apple.com/app-store/product-page/ */
31
+ promoText?: string;
32
+ description?: string;
33
+ keywords?: string[];
34
+ releaseNotes?: string;
35
+ marketingUrl?: string;
36
+ privacyPolicyUrl?: string;
37
+ privacyPolicyText?: string;
38
+ privacyChoicesUrl?: string;
39
+ supportUrl?: string;
40
+ }
41
+ export interface AppleReview {
42
+ firstName?: string;
43
+ lastName?: string;
44
+ phone?: string;
45
+ email?: string;
46
+ demoUsername?: string;
47
+ demoPassword?: string;
48
+ notes?: string;
49
+ attachment?: string;
50
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,22 @@
1
+ import Ajv from 'ajv';
2
+ import { AppleConfigReader } from './apple/config/reader';
3
+ import { AppleConfigWriter } from './apple/config/writer';
4
+ import { AppleMetadata } from './apple/types';
5
+ export interface MetadataConfig {
6
+ /** The store configuration version */
7
+ configVersion: number;
8
+ /** All App Store related configuration */
9
+ apple?: AppleMetadata;
10
+ }
11
+ /**
12
+ * Run the JSON Schema validation to normalize defaults and flag early config errors.
13
+ * This includes validating the known store limitations for every configurable property.
14
+ */
15
+ export declare function validateConfig(config: unknown): {
16
+ valid: boolean;
17
+ errors: Ajv.ErrorObject[];
18
+ };
19
+ /** Create a versioned deserializer to fetch App Store data from the store configuration. */
20
+ export declare function createAppleReader(config: MetadataConfig): AppleConfigReader;
21
+ /** Create the serializer to write the App Store to the store configuration. */
22
+ export declare function createAppleWriter(): AppleConfigWriter;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAppleWriter = exports.createAppleReader = exports.validateConfig = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const ajv_1 = tslib_1.__importDefault(require("ajv"));
6
+ const assert_1 = tslib_1.__importDefault(require("assert"));
7
+ const reader_1 = require("./apple/config/reader");
8
+ const writer_1 = require("./apple/config/writer");
9
+ /**
10
+ * Run the JSON Schema validation to normalize defaults and flag early config errors.
11
+ * This includes validating the known store limitations for every configurable property.
12
+ */
13
+ function validateConfig(config) {
14
+ const validator = new ajv_1.default({ allErrors: true, useDefaults: true })
15
+ .addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'))
16
+ .compile(require('../../schema/metadata-0.json'));
17
+ const valid = validator(config);
18
+ return { valid, errors: validator.errors || [] };
19
+ }
20
+ exports.validateConfig = validateConfig;
21
+ /** Create a versioned deserializer to fetch App Store data from the store configuration. */
22
+ function createAppleReader(config) {
23
+ (0, assert_1.default)(config.configVersion === 0, 'Unsupported store configuration version');
24
+ (0, assert_1.default)(config.apple, 'No apple configuration found');
25
+ return new reader_1.AppleConfigReader(config.apple);
26
+ }
27
+ exports.createAppleReader = createAppleReader;
28
+ /** Create the serializer to write the App Store to the store configuration. */
29
+ function createAppleWriter() {
30
+ return new writer_1.AppleConfigWriter();
31
+ }
32
+ exports.createAppleWriter = createAppleWriter;
@@ -0,0 +1,46 @@
1
+ /// <reference types="@expo/apple-utils/ts-declarations/expo__app-store" />
2
+ import { App, Session } from '@expo/apple-utils';
3
+ import { ExpoConfig } from '@expo/config';
4
+ import { Platform } from '@expo/eas-build-job';
5
+ import { SubmitProfile } from '@expo/eas-json';
6
+ import { CredentialsContext } from '../credentials/context';
7
+ import { Actor } from '../user/User';
8
+ export declare type MetadataContext = {
9
+ /** Submission profile platform to use */
10
+ platform: Platform.IOS;
11
+ /** Resolved submission profile configuration */
12
+ profile: SubmitProfile<Platform.IOS>;
13
+ /** Configured store config path, relative from projectDir (defaults to store.config.json) */
14
+ metadataPath: string;
15
+ /** Authenticated Expo account */
16
+ user: Actor;
17
+ /** The store credentials manager */
18
+ credentialsCtx: CredentialsContext;
19
+ /** The app bundle identifier to use for the store */
20
+ bundleIdentifier: string;
21
+ /** Root of the Expo project directory */
22
+ projectDir: string;
23
+ /** Resolved Expo app configuration */
24
+ exp: ExpoConfig;
25
+ };
26
+ export declare type MetadataAppStoreAuthentication = {
27
+ /** The root entity of the App store */
28
+ app: App;
29
+ /** The authentication state we used to fetch the root entity */
30
+ auth: Partial<Session.AuthState>;
31
+ };
32
+ /**
33
+ * Metadata uses the submission profile to find the configured metadata filename.
34
+ * Note, only iOS is supported for metadata right now.
35
+ */
36
+ export declare function createMetadataContextAsync(params: {
37
+ projectDir: string;
38
+ credentialsCtx: CredentialsContext;
39
+ exp?: ExpoConfig;
40
+ profileName?: string;
41
+ }): Promise<MetadataContext>;
42
+ /**
43
+ * To start syncing ASC entities, we need access to the apple utils App instance.
44
+ * This ensures we are authenticated and have the app instance ready to use.
45
+ */
46
+ export declare function ensureMetadataAppStoreAuthenticatedAsync({ credentialsCtx, bundleIdentifier, }: MetadataContext): Promise<MetadataAppStoreAuthentication>;