eas-cli 3.17.1 → 3.18.1

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 (68) hide show
  1. package/README.md +55 -55
  2. package/build/branch/actions/SelectBranch.d.ts +33 -0
  3. package/build/branch/actions/SelectBranch.js +67 -0
  4. package/build/build/android/build.js +1 -2
  5. package/build/build/local.js +1 -1
  6. package/build/build/runBuildAndSubmit.js +2 -0
  7. package/build/channel/actions/SelectChannel.d.ts +33 -0
  8. package/build/channel/actions/SelectChannel.js +67 -0
  9. package/build/channel/branch-mapping.d.ts +20 -0
  10. package/build/channel/branch-mapping.js +75 -5
  11. package/build/channel/queries.d.ts +1 -6
  12. package/build/channel/queries.js +1 -25
  13. package/build/commands/build/version/get.js +1 -0
  14. package/build/commands/build/version/sync.js +1 -0
  15. package/build/commands/channel/rollout-preview.d.ts +32 -0
  16. package/build/commands/channel/rollout-preview.js +109 -0
  17. package/build/commands/metadata/lint.js +1 -0
  18. package/build/commands/metadata/pull.js +1 -0
  19. package/build/commands/metadata/push.js +1 -0
  20. package/build/commands/submit.js +1 -0
  21. package/build/commands/update/republish.js +23 -74
  22. package/build/eas-update/utils.d.ts +15 -0
  23. package/build/eas-update/utils.js +6 -0
  24. package/build/graphql/generated.d.ts +192 -18
  25. package/build/graphql/generated.js +8 -2
  26. package/build/graphql/queries/BranchQuery.d.ts +3 -2
  27. package/build/graphql/queries/BranchQuery.js +43 -1
  28. package/build/graphql/queries/ChannelQuery.d.ts +3 -2
  29. package/build/graphql/queries/ChannelQuery.js +19 -5
  30. package/build/graphql/queries/RuntimeQuery.d.ts +6 -0
  31. package/build/graphql/queries/RuntimeQuery.js +70 -0
  32. package/build/graphql/types/Runtime.d.ts +1 -0
  33. package/build/graphql/types/Runtime.js +11 -0
  34. package/build/graphql/types/UpdateBranch.js +3 -1
  35. package/build/graphql/types/UpdateBranchBasicInfo.d.ts +1 -0
  36. package/build/graphql/types/UpdateBranchBasicInfo.js +11 -0
  37. package/build/project/ios/target.d.ts +1 -1
  38. package/build/project/ios/target.js +4 -4
  39. package/build/rollout/actions/CreateRollout.d.ts +23 -0
  40. package/build/rollout/actions/CreateRollout.js +153 -0
  41. package/build/rollout/actions/EditRollout.d.ts +17 -0
  42. package/build/rollout/actions/EditRollout.js +79 -0
  43. package/build/rollout/actions/EndRollout.d.ts +24 -0
  44. package/build/rollout/actions/EndRollout.js +164 -0
  45. package/build/rollout/actions/ManageRollout.d.ts +24 -0
  46. package/build/rollout/actions/ManageRollout.js +78 -0
  47. package/build/rollout/actions/NonInteractiveRollout.d.ts +18 -0
  48. package/build/rollout/actions/NonInteractiveRollout.js +46 -0
  49. package/build/rollout/actions/RolloutMainMenu.d.ts +28 -0
  50. package/build/rollout/actions/RolloutMainMenu.js +110 -0
  51. package/build/rollout/actions/SelectRollout.d.ts +8 -0
  52. package/build/rollout/actions/SelectRollout.js +33 -0
  53. package/build/rollout/actions/SelectRuntime.d.ts +36 -0
  54. package/build/rollout/actions/SelectRuntime.js +167 -0
  55. package/build/rollout/branch-mapping.d.ts +128 -0
  56. package/build/rollout/branch-mapping.js +260 -0
  57. package/build/rollout/utils.d.ts +10 -53
  58. package/build/rollout/utils.js +78 -94
  59. package/build/update/configure.d.ts +6 -1
  60. package/build/update/configure.js +18 -8
  61. package/build/update/republish.d.ts +26 -0
  62. package/build/update/republish.js +83 -0
  63. package/build/utils/profiles.d.ts +2 -1
  64. package/build/utils/profiles.js +35 -3
  65. package/build/utils/relay.d.ts +80 -15
  66. package/build/utils/relay.js +211 -28
  67. package/oclif.manifest.json +1 -1
  68. package/package.json +5 -5
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NonInteractiveRollout = void 0;
4
+ const ChannelQuery_1 = require("../../graphql/queries/ChannelQuery");
5
+ const CreateRollout_1 = require("./CreateRollout");
6
+ const EditRollout_1 = require("./EditRollout");
7
+ const EndRollout_1 = require("./EndRollout");
8
+ const ManageRollout_1 = require("./ManageRollout");
9
+ const RolloutMainMenu_1 = require("./RolloutMainMenu");
10
+ /**
11
+ * Control a rollout in non interactive mode.
12
+ */
13
+ class NonInteractiveRollout {
14
+ constructor(options = {}) {
15
+ this.options = options;
16
+ }
17
+ async runAsync(ctx) {
18
+ const { channelName, action } = this.options;
19
+ const { nonInteractive, app, graphqlClient } = ctx;
20
+ if (!nonInteractive) {
21
+ throw new Error(`This action is meant for non-interactive mode.`);
22
+ }
23
+ if (!channelName) {
24
+ throw new Error(`The channel argument is required in non-interactive mode. Run eas channel:rollout [channel-name]`);
25
+ }
26
+ const channelInfo = await ChannelQuery_1.ChannelQuery.viewUpdateChannelAsync(graphqlClient, {
27
+ appId: app.projectId,
28
+ channelName,
29
+ });
30
+ if (!action) {
31
+ throw new Error(`--action is required in non-interactive mode.`);
32
+ }
33
+ await this.runActionAsync(ctx, action, channelInfo, this.options);
34
+ }
35
+ async runActionAsync(ctx, action, channelInfo, options) {
36
+ switch (action) {
37
+ case RolloutMainMenu_1.MainMenuActions.CREATE_NEW:
38
+ return await new CreateRollout_1.CreateRollout(channelInfo, options).runAsync(ctx);
39
+ case ManageRollout_1.ManageRolloutActions.EDIT:
40
+ return await new EditRollout_1.EditRollout(channelInfo, options).runAsync(ctx);
41
+ case ManageRollout_1.ManageRolloutActions.END:
42
+ return await new EndRollout_1.EndRollout(channelInfo, options).runAsync(ctx);
43
+ }
44
+ }
45
+ }
46
+ exports.NonInteractiveRollout = NonInteractiveRollout;
@@ -0,0 +1,28 @@
1
+ import { EASUpdateAction, EASUpdateContext } from '../../eas-update/utils';
2
+ import { UpdateChannelBasicInfoFragment } from '../../graphql/generated';
3
+ import { NonInteractiveOptions as CreateRolloutNonInteractiveOptions } from './CreateRollout';
4
+ import { NonInteractiveOptions as EditRolloutNonInteractiveOptions } from './EditRollout';
5
+ import { NonInteractiveOptions as EndRolloutNonInteractiveOptions } from './EndRollout';
6
+ import { ManageRolloutActions } from './ManageRollout';
7
+ export declare enum MainMenuActions {
8
+ CREATE_NEW = "Create a new rollout",
9
+ MANAGE_EXISTING = "Manage an existing rollout"
10
+ }
11
+ export type RolloutActions = MainMenuActions.CREATE_NEW | ManageRolloutActions.EDIT | ManageRolloutActions.END;
12
+ /**
13
+ * Manage a rollout for the project.
14
+ */
15
+ export declare class RolloutMainMenu implements EASUpdateAction<void> {
16
+ private options;
17
+ constructor(options?: {
18
+ channelName?: string;
19
+ action?: RolloutActions;
20
+ } & Partial<EditRolloutNonInteractiveOptions> & Partial<EndRolloutNonInteractiveOptions> & Partial<CreateRolloutNonInteractiveOptions>);
21
+ runAsync(ctx: EASUpdateContext): Promise<void>;
22
+ runActionAsync(ctx: EASUpdateContext, menuAction: MainMenuActions): Promise<null>;
23
+ selectRolloutAsync(ctx: EASUpdateContext): Promise<UpdateChannelBasicInfoFragment | null>;
24
+ selectChannelAsync(ctx: EASUpdateContext, filterPredicate?: (channelInfo: UpdateChannelBasicInfoFragment) => boolean): Promise<UpdateChannelBasicInfoFragment>;
25
+ resolveChannelNameAsync(ctx: EASUpdateContext, channelName: string): Promise<UpdateChannelBasicInfoFragment>;
26
+ toMainMenuAction(action: RolloutActions): MainMenuActions;
27
+ promptMenuActionAsync(): Promise<MainMenuActions>;
28
+ }
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RolloutMainMenu = exports.MainMenuActions = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const assert_1 = tslib_1.__importDefault(require("assert"));
6
+ const SelectChannel_1 = require("../../channel/actions/SelectChannel");
7
+ const ChannelQuery_1 = require("../../graphql/queries/ChannelQuery");
8
+ const log_1 = tslib_1.__importDefault(require("../../log"));
9
+ const prompts_1 = require("../../prompts");
10
+ const branch_mapping_1 = require("../branch-mapping");
11
+ const CreateRollout_1 = require("./CreateRollout");
12
+ const ManageRollout_1 = require("./ManageRollout");
13
+ const SelectRollout_1 = require("./SelectRollout");
14
+ var MainMenuActions;
15
+ (function (MainMenuActions) {
16
+ MainMenuActions["CREATE_NEW"] = "Create a new rollout";
17
+ MainMenuActions["MANAGE_EXISTING"] = "Manage an existing rollout";
18
+ })(MainMenuActions = exports.MainMenuActions || (exports.MainMenuActions = {}));
19
+ /**
20
+ * Manage a rollout for the project.
21
+ */
22
+ class RolloutMainMenu {
23
+ constructor(options = {}) {
24
+ this.options = options;
25
+ }
26
+ async runAsync(ctx) {
27
+ const { action } = this.options;
28
+ const { nonInteractive } = ctx;
29
+ if (nonInteractive) {
30
+ throw new Error(`rollout main menu cannot be run in non-interactive mode.`);
31
+ }
32
+ const menuOption = action ? this.toMainMenuAction(action) : await this.promptMenuActionAsync();
33
+ await this.runActionAsync(ctx, menuOption);
34
+ }
35
+ async runActionAsync(ctx, menuAction) {
36
+ const { channelName } = this.options;
37
+ switch (menuAction) {
38
+ case MainMenuActions.CREATE_NEW: {
39
+ const channelInfo = channelName
40
+ ? await this.resolveChannelNameAsync(ctx, channelName)
41
+ : await this.selectChannelAsync(ctx, channelInfo => !(0, branch_mapping_1.isRollout)(channelInfo));
42
+ await new CreateRollout_1.CreateRollout(channelInfo, this.options).runAsync(ctx);
43
+ return null;
44
+ }
45
+ case MainMenuActions.MANAGE_EXISTING: {
46
+ const channelInfo = channelName
47
+ ? await this.resolveChannelNameAsync(ctx, channelName)
48
+ : await this.selectRolloutAsync(ctx);
49
+ if (!channelInfo) {
50
+ log_1.default.log('You dont have any rollouts.');
51
+ }
52
+ else {
53
+ (0, assert_1.default)(this.options.action !== MainMenuActions.CREATE_NEW, 'Invalid route for create action');
54
+ const manageAction = await new ManageRollout_1.ManageRollout(channelInfo, {
55
+ ...this.options,
56
+ action: this.options.action,
57
+ callingAction: this,
58
+ }).runAsync(ctx);
59
+ await manageAction.runAsync(ctx);
60
+ }
61
+ return null;
62
+ }
63
+ }
64
+ }
65
+ async selectRolloutAsync(ctx) {
66
+ const selectRollout = new SelectRollout_1.SelectRollout();
67
+ const channelInfo = await selectRollout.runAsync(ctx);
68
+ return channelInfo;
69
+ }
70
+ async selectChannelAsync(ctx, filterPredicate) {
71
+ const selectChannelAction = new SelectChannel_1.SelectChannel({ filterPredicate });
72
+ const channelInfo = await selectChannelAction.runAsync(ctx);
73
+ if (!channelInfo) {
74
+ throw new Error(`You dont have any channels. Create one with <TODO>`);
75
+ }
76
+ return channelInfo;
77
+ }
78
+ async resolveChannelNameAsync(ctx, channelName) {
79
+ const { graphqlClient, app } = ctx;
80
+ return await ChannelQuery_1.ChannelQuery.viewUpdateChannelAsync(graphqlClient, {
81
+ appId: app.projectId,
82
+ channelName,
83
+ });
84
+ }
85
+ toMainMenuAction(action) {
86
+ if (action === MainMenuActions.CREATE_NEW) {
87
+ return MainMenuActions.CREATE_NEW;
88
+ }
89
+ else if (action === ManageRollout_1.ManageRolloutActions.EDIT || action === ManageRollout_1.ManageRolloutActions.END) {
90
+ return MainMenuActions.MANAGE_EXISTING;
91
+ }
92
+ else {
93
+ throw new Error(`Action not supported yet: ` + action);
94
+ }
95
+ }
96
+ async promptMenuActionAsync() {
97
+ const menuOptions = [MainMenuActions.CREATE_NEW, MainMenuActions.MANAGE_EXISTING];
98
+ const { menuOption: selectedMenuOption } = await (0, prompts_1.promptAsync)({
99
+ type: 'select',
100
+ name: 'menuOption',
101
+ message: `What would you like to do?`,
102
+ choices: menuOptions.map(menuOption => ({
103
+ value: menuOption,
104
+ title: menuOption,
105
+ })),
106
+ });
107
+ return selectedMenuOption;
108
+ }
109
+ }
110
+ exports.RolloutMainMenu = RolloutMainMenu;
@@ -0,0 +1,8 @@
1
+ import { EASUpdateAction, EASUpdateContext } from '../../eas-update/utils';
2
+ import { UpdateChannelBasicInfoFragment } from '../../graphql/generated';
3
+ /**
4
+ * Select an existing rollout for the project.
5
+ */
6
+ export declare class SelectRollout implements EASUpdateAction<UpdateChannelBasicInfoFragment | null> {
7
+ runAsync(ctx: EASUpdateContext): Promise<UpdateChannelBasicInfoFragment | null>;
8
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SelectRollout = void 0;
4
+ const SelectChannel_1 = require("../../channel/actions/SelectChannel");
5
+ const ora_1 = require("../../ora");
6
+ const branch_mapping_1 = require("../branch-mapping");
7
+ /**
8
+ * Select an existing rollout for the project.
9
+ */
10
+ class SelectRollout {
11
+ async runAsync(ctx) {
12
+ let assetSpinner = null;
13
+ const afterEachFilterQuery = (_externalQueryParams, totalNodesFetched, _dataset, willFetchAgain) => {
14
+ if (willFetchAgain && !assetSpinner) {
15
+ assetSpinner = (0, ora_1.ora)().start('Fetching channels...');
16
+ }
17
+ if (assetSpinner) {
18
+ assetSpinner.text = `Fetched ${totalNodesFetched} channels`;
19
+ }
20
+ };
21
+ const selectChannelAction = new SelectChannel_1.SelectChannel({
22
+ printedType: 'rollout',
23
+ filterPredicate: branch_mapping_1.isRollout,
24
+ afterEachFilterQuery,
25
+ });
26
+ const channelInfo = await selectChannelAction.runAsync(ctx);
27
+ if (assetSpinner) {
28
+ assetSpinner.succeed(`Fetched all channels`);
29
+ }
30
+ return channelInfo;
31
+ }
32
+ }
33
+ exports.SelectRollout = SelectRollout;
@@ -0,0 +1,36 @@
1
+ import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
2
+ import { EASUpdateAction, EASUpdateContext } from '../../eas-update/utils';
3
+ import { RuntimeFragment, UpdateBranchBasicInfoFragment } from '../../graphql/generated';
4
+ import { Connection } from '../../utils/relay';
5
+ /**
6
+ * Select a runtime from a branch
7
+ */
8
+ export declare class SelectRuntime implements EASUpdateAction<string> {
9
+ private branchInfo;
10
+ private options;
11
+ private printedType;
12
+ constructor(branchInfo: UpdateBranchBasicInfoFragment, options?: {
13
+ anotherBranchToIntersectRuntimesBy?: UpdateBranchBasicInfoFragment;
14
+ });
15
+ warnNoRuntime(): void;
16
+ formatCantFindRuntime(): string;
17
+ runAsync(ctx: EASUpdateContext): Promise<string>;
18
+ getNewestRuntimeAsync(graphqlClient: ExpoGraphqlClient, { appId, branchName, anotherBranchIdToIntersectRuntimesBy, }: {
19
+ appId: string;
20
+ branchName: string;
21
+ anotherBranchIdToIntersectRuntimesBy?: string;
22
+ }): Promise<Connection<RuntimeFragment> | null>;
23
+ displayLatestUpdateGroupAsync({ graphqlClient, appId, branchName, runtime, }: {
24
+ graphqlClient: ExpoGraphqlClient;
25
+ appId: string;
26
+ branchName: string;
27
+ runtime: RuntimeFragment;
28
+ }): Promise<string>;
29
+ selectRuntimesAsync(graphqlClient: ExpoGraphqlClient, { appId, branchName, anotherBranchIdToIntersectRuntimesBy, batchSize, }: {
30
+ appId: string;
31
+ branchName: string;
32
+ anotherBranchIdToIntersectRuntimesBy?: string;
33
+ batchSize?: number;
34
+ }): Promise<RuntimeFragment | null>;
35
+ promptForRuntimeAsync(): Promise<string>;
36
+ }
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SelectRuntime = 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 utils_1 = require("../../eas-update/utils");
8
+ const RuntimeQuery_1 = require("../../graphql/queries/RuntimeQuery");
9
+ const UpdateQuery_1 = require("../../graphql/queries/UpdateQuery");
10
+ const log_1 = tslib_1.__importStar(require("../../log"));
11
+ const prompts_1 = require("../../prompts");
12
+ const relay_1 = require("../../utils/relay");
13
+ const utils_2 = require("../utils");
14
+ function beginSentence(phrase) {
15
+ if (typeof phrase !== 'string' || phrase.length === 0) {
16
+ return phrase; // Return the input without any modification if it's not a string or empty
17
+ }
18
+ return phrase.charAt(0).toUpperCase() + phrase.slice(1);
19
+ }
20
+ /**
21
+ * Select a runtime from a branch
22
+ */
23
+ class SelectRuntime {
24
+ constructor(branchInfo, options = {}) {
25
+ this.branchInfo = branchInfo;
26
+ this.options = options;
27
+ this.printedType = options.anotherBranchToIntersectRuntimesBy
28
+ ? `compatible runtime`
29
+ : `runtime`;
30
+ }
31
+ warnNoRuntime() {
32
+ if (this.options.anotherBranchToIntersectRuntimesBy) {
33
+ const intersectBranchName = this.options.anotherBranchToIntersectRuntimesBy.name;
34
+ log_1.default.warn(`⚠️ Branches ${this.branchInfo.name} and ${intersectBranchName} dont have any updates with the same runtime.`);
35
+ // TODO(quin): write a learn more
36
+ log_1.default.warn(`Your updates could be misconfigured. ${(0, log_1.learnMore)('https://expo.fyi/todo')}`);
37
+ }
38
+ else {
39
+ // no runtime on branch means no updates published on branch
40
+ log_1.default.warn(`⚠️ There are no updates published on branch ${this.branchInfo.name}.`);
41
+ }
42
+ }
43
+ formatCantFindRuntime() {
44
+ return `🕵️ Not finding the update you were looking for? ${(0, log_1.learnMore)('https://expo.fyi/todo')}`;
45
+ }
46
+ async runAsync(ctx) {
47
+ var _a, _b;
48
+ const { nonInteractive, graphqlClient, app } = ctx;
49
+ const { projectId } = app;
50
+ if (nonInteractive) {
51
+ throw new utils_1.NonInteractiveError(`runtime selection cannot be run in non-interactive mode.`);
52
+ }
53
+ const newestRuntimeConnection = await this.getNewestRuntimeAsync(graphqlClient, {
54
+ appId: projectId,
55
+ branchName: this.branchInfo.name,
56
+ anotherBranchIdToIntersectRuntimesBy: (_a = this.options.anotherBranchToIntersectRuntimesBy) === null || _a === void 0 ? void 0 : _a.id,
57
+ });
58
+ if (!newestRuntimeConnection) {
59
+ log_1.default.addNewLineIfNone();
60
+ this.warnNoRuntime();
61
+ return await this.promptForRuntimeAsync();
62
+ }
63
+ const moreThanOneRuntime = newestRuntimeConnection.edges.length > 1;
64
+ log_1.default.log(`✅ ${beginSentence(this.printedType)}${moreThanOneRuntime ? 's' : ''} detected`);
65
+ if (!moreThanOneRuntime) {
66
+ const runtime = newestRuntimeConnection.edges[0].node;
67
+ const formattedRuntimeWithGroup = await this.displayLatestUpdateGroupAsync({
68
+ graphqlClient,
69
+ appId: projectId,
70
+ branchName: this.branchInfo.name,
71
+ runtime,
72
+ });
73
+ log_1.default.addNewLineIfNone();
74
+ log_1.default.log(formattedRuntimeWithGroup);
75
+ log_1.default.addNewLineIfNone();
76
+ const useRuntime = await (0, prompts_1.confirmAsync)({
77
+ message: `Target ${this.printedType} ${chalk_1.default.bold(runtime.version)}?`,
78
+ });
79
+ if (useRuntime) {
80
+ return runtime.version;
81
+ }
82
+ else {
83
+ log_1.default.newLine();
84
+ log_1.default.warn(this.formatCantFindRuntime());
85
+ return await this.promptForRuntimeAsync();
86
+ }
87
+ }
88
+ log_1.default.log(this.formatCantFindRuntime());
89
+ const selectedRuntime = await this.selectRuntimesAsync(graphqlClient, {
90
+ appId: projectId,
91
+ branchName: this.branchInfo.name,
92
+ anotherBranchIdToIntersectRuntimesBy: (_b = this.options.anotherBranchToIntersectRuntimesBy) === null || _b === void 0 ? void 0 : _b.id,
93
+ });
94
+ if (!selectedRuntime) {
95
+ throw new Error(`No ${this.printedType} selected`);
96
+ }
97
+ return selectedRuntime.version;
98
+ }
99
+ async getNewestRuntimeAsync(graphqlClient, { appId, branchName, anotherBranchIdToIntersectRuntimesBy, }) {
100
+ const connection = await RuntimeQuery_1.RuntimeQuery.getRuntimesOnBranchAsync(graphqlClient, {
101
+ appId,
102
+ name: branchName,
103
+ first: 1,
104
+ filter: {
105
+ branchId: anotherBranchIdToIntersectRuntimesBy,
106
+ },
107
+ });
108
+ const { edges } = connection;
109
+ if (edges.length === 0) {
110
+ return null;
111
+ }
112
+ return connection;
113
+ }
114
+ async displayLatestUpdateGroupAsync({ graphqlClient, appId, branchName, runtime, }) {
115
+ const updateGroups = await UpdateQuery_1.UpdateQuery.viewUpdateGroupsOnBranchAsync(graphqlClient, {
116
+ appId,
117
+ branchName,
118
+ limit: 1,
119
+ offset: 0,
120
+ filter: {
121
+ runtimeVersions: [runtime.version],
122
+ },
123
+ });
124
+ (0, assert_1.default)(updateGroups.length < 2, `Expected at most one update group. Received: ${JSON.stringify(updateGroups)}`);
125
+ return (0, utils_2.formatRuntimeWithUpdateGroup)(updateGroups[0], runtime);
126
+ }
127
+ async selectRuntimesAsync(graphqlClient, { appId, branchName, anotherBranchIdToIntersectRuntimesBy, batchSize = 5, }) {
128
+ const queryAsync = async (queryParams) => {
129
+ return await RuntimeQuery_1.RuntimeQuery.getRuntimesOnBranchAsync(graphqlClient, {
130
+ appId,
131
+ name: branchName,
132
+ first: queryParams.first,
133
+ after: queryParams.after,
134
+ last: queryParams.last,
135
+ before: queryParams.before,
136
+ filter: {
137
+ branchId: anotherBranchIdToIntersectRuntimesBy,
138
+ },
139
+ });
140
+ };
141
+ const getTitleAsync = async (runtime) => {
142
+ return await this.displayLatestUpdateGroupAsync({
143
+ graphqlClient,
144
+ appId,
145
+ branchName,
146
+ runtime,
147
+ });
148
+ };
149
+ return await (0, relay_1.selectPaginatedAsync)({
150
+ queryAsync,
151
+ getTitleAsync,
152
+ printedType: 'target runtime',
153
+ pageSize: batchSize,
154
+ });
155
+ }
156
+ async promptForRuntimeAsync() {
157
+ log_1.default.log(`You can input a runtime manually then publish an update later.`);
158
+ const { runtimeVersion } = await (0, prompts_1.promptAsync)({
159
+ type: 'text',
160
+ name: 'runtimeVersion',
161
+ message: 'Input a runtime version:',
162
+ initial: '1.0.0',
163
+ });
164
+ return runtimeVersion;
165
+ }
166
+ }
167
+ exports.SelectRuntime = SelectRuntime;
@@ -0,0 +1,128 @@
1
+ import { BranchMapping, BranchMappingAlwaysTrue } from '../channel/branch-mapping';
2
+ import { UpdateChannelBasicInfoFragment } from '../graphql/generated';
3
+ import { UpdateBranchObject, UpdateChannelObject } from '../graphql/queries/ChannelQuery';
4
+ export type Rollout = LegacyRollout | ConstrainedRollout;
5
+ export type RolloutInfo = LegacyRolloutInfo | ConstrainedRolloutInfo;
6
+ type ConstrainedRollout = LegacyRollout & {
7
+ runtimeVersion: string;
8
+ };
9
+ type LegacyRollout = {
10
+ rolledOutBranch: UpdateBranchObject;
11
+ defaultBranch: UpdateBranchObject;
12
+ } & LegacyRolloutInfo;
13
+ type ConstrainedRolloutInfo = LegacyRolloutInfo & {
14
+ runtimeVersion: string;
15
+ };
16
+ type LegacyRolloutInfo = {
17
+ rolledOutBranchId: string;
18
+ percentRolledOut: number;
19
+ defaultBranchId: string;
20
+ };
21
+ export type RolloutBranchMapping = LegacyRolloutBranchMapping | ConstrainedRolloutBranchMapping;
22
+ type RolloutNode = {
23
+ clientKey: 'rolloutToken';
24
+ branchMappingOperator: 'hash_lt';
25
+ operand: number;
26
+ };
27
+ type RuntimeVersionNode = {
28
+ clientKey: 'runtimeVersion';
29
+ branchMappingOperator: '==';
30
+ operand: string;
31
+ };
32
+ type RtvConstrainedRolloutNode = ['and', RolloutNode, RuntimeVersionNode] | ['and', RuntimeVersionNode, RolloutNode];
33
+ export type LegacyRolloutBranchMapping = {
34
+ version: number;
35
+ data: [
36
+ {
37
+ branchId: string;
38
+ branchMappingLogic: RolloutNode;
39
+ },
40
+ {
41
+ branchId: string;
42
+ branchMappingLogic: BranchMappingAlwaysTrue;
43
+ }
44
+ ];
45
+ };
46
+ export type ConstrainedRolloutBranchMapping = {
47
+ version: number;
48
+ data: [
49
+ {
50
+ branchId: string;
51
+ branchMappingLogic: RtvConstrainedRolloutNode;
52
+ },
53
+ {
54
+ branchId: string;
55
+ branchMappingLogic: BranchMappingAlwaysTrue;
56
+ }
57
+ ];
58
+ };
59
+ export declare function isLegacyRolloutInfo(rollout: RolloutInfo): rollout is LegacyRolloutInfo;
60
+ export declare function isConstrainedRolloutInfo(rollout: RolloutInfo): rollout is ConstrainedRolloutInfo;
61
+ export declare function isConstrainedRollout(rollout: Rollout): rollout is ConstrainedRollout;
62
+ export declare function getRolloutInfo(basicChannelInfo: UpdateChannelBasicInfoFragment): RolloutInfo;
63
+ export declare function getRolloutInfoFromBranchMapping(branchMapping: RolloutBranchMapping): RolloutInfo;
64
+ export declare function getRollout(channel: UpdateChannelObject): Rollout;
65
+ export declare function composeRollout(rolloutInfo: RolloutInfo, defaultBranch: UpdateBranchObject, rolledOutBranch: UpdateBranchObject): Rollout;
66
+ export declare function getRolloutBranchMapping(branchMappingString: string): RolloutBranchMapping;
67
+ /**
68
+ * Detect if a branch mapping is a rollout.
69
+ *
70
+ * Types of rollout:
71
+ * 1. Legacy unconstrained rollout:
72
+ * Maps to a rollout branch via a rollout token
73
+ * Falls back to a default branch
74
+ *
75
+ * Example:
76
+ * {
77
+ version: 0,
78
+ data: [
79
+ {
80
+ branchId: uuidv4(),
81
+ branchMappingLogic: {
82
+ operand: 10 / 100,
83
+ clientKey: 'rolloutToken',
84
+ branchMappingOperator: hashLtOperator(),
85
+ },
86
+ },
87
+ { branchId: uuidv4(), branchMappingLogic: alwaysTrue() },
88
+ ],
89
+ }
90
+ *
91
+ * 2. RTV constrained rollout:
92
+ * Maps to a rollout branch via a rollout token, constrained by runtime version
93
+ * Falls back to a default branch
94
+ *
95
+ * Example:
96
+ * {
97
+ version: 0,
98
+ data: [
99
+ {
100
+ branchId: uuidv4(),
101
+ branchMappingLogic: andStatement([
102
+ {
103
+ operand: '1.0.0',
104
+ clientKey: 'runtimeVersion',
105
+ branchMappingOperator: equalsOperator(),
106
+ },
107
+ {
108
+ operand: 10 / 100,
109
+ clientKey: 'rolloutToken',
110
+ branchMappingOperator: hashLtOperator(),
111
+ },
112
+ ]),
113
+ },
114
+ { branchId: uuidv4(), branchMappingLogic: alwaysTrue() },
115
+ ],
116
+ }
117
+ */
118
+ export declare function isRolloutBranchMapping(branchMapping: BranchMapping): branchMapping is RolloutBranchMapping;
119
+ export declare function isRollout(channelInfo: UpdateChannelBasicInfoFragment): boolean;
120
+ export declare function createRolloutBranchMapping({ defaultBranchId, rolloutBranchId, percent, runtimeVersion, }: {
121
+ defaultBranchId: string;
122
+ rolloutBranchId: string;
123
+ percent: number;
124
+ runtimeVersion: string;
125
+ }): ConstrainedRolloutBranchMapping;
126
+ export declare function editRolloutBranchMapping(branchMapping: RolloutBranchMapping, percent: number): RolloutBranchMapping;
127
+ export declare function assertRolloutBranchMapping(branchMapping: BranchMapping): asserts branchMapping is RolloutBranchMapping;
128
+ export {};