@corva/create-app 0.42.0-0 → 0.42.0-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 (32) hide show
  1. package/README.md +1 -0
  2. package/lib/bump-version.option.js +12 -5
  3. package/lib/flow.js +1 -1
  4. package/lib/flows/attach.js +8 -0
  5. package/lib/flows/lib/api.js +108 -77
  6. package/lib/flows/lib/notification.js +139 -0
  7. package/lib/flows/lib/waitForMs.js +1 -1
  8. package/lib/flows/release.js +1 -1
  9. package/lib/flows/steps/attach/add-app-to-stream.js +24 -0
  10. package/lib/flows/steps/attach/get-all-live-assets.js +142 -0
  11. package/lib/flows/steps/attach/index.js +9 -0
  12. package/lib/flows/steps/attach/prepare-data.js +20 -0
  13. package/lib/flows/steps/release/add-label.js +2 -3
  14. package/lib/flows/steps/release/add-notes.js +2 -2
  15. package/lib/flows/steps/release/get-config.js +4 -1
  16. package/lib/flows/steps/release/prepare-data.js +3 -3
  17. package/lib/flows/steps/release/publish.js +6 -4
  18. package/lib/flows/steps/release/remove-failed-upload.js +7 -5
  19. package/lib/flows/steps/release/upload-zip-to-corva.js +9 -6
  20. package/lib/flows/steps/release/wait-for-build.js +4 -4
  21. package/lib/flows/steps/rerun/create-task.js +12 -15
  22. package/lib/flows/steps/rerun/ensure-that-app-in-stream.js +33 -25
  23. package/lib/flows/steps/rerun/get-app-version.js +14 -12
  24. package/lib/flows/steps/rerun/prepare-data.js +6 -8
  25. package/lib/flows/steps/rerun/prepare-well-and-stream-data.js +29 -36
  26. package/lib/flows/steps/rerun/rerun.js +5 -5
  27. package/lib/helpers/logger.js +22 -22
  28. package/lib/main.js +55 -31
  29. package/package.json +3 -2
  30. package/templates/python/scheduler/README.md +1 -1
  31. package/templates/python/stream/README.md +1 -1
  32. package/templates/python/task/README.md +1 -1
package/README.md CHANGED
@@ -27,6 +27,7 @@ Commands:
27
27
  zip [options] <project-directory> [patterns...] Bundle app
28
28
  release [options] <project-directory> [patterns...] Release app
29
29
  rerun [options] <project-directory> Rerun app
30
+ attach [options] <project-directory> Add app to live assets streams
30
31
  help [command] display help for command
31
32
  ```
32
33
 
@@ -21,19 +21,26 @@ export const bumpVersionOption = new Option(flags, description)
21
21
  .choices(choices)
22
22
  .argParser(argParser);
23
23
 
24
- export const apiKeyOption = new Option('--api-key [string]',
25
- 'Pre generated API key for authorization during app upload')
24
+ export const apiKeyOption = new Option(
25
+ '--api-key [string]',
26
+ 'Pre generated API key for authorization during app upload'
27
+ );
28
+
29
+ export const appVersion = new Option('--app-version [number]', 'App version (exp. 1, 2, 3)');
26
30
 
27
31
  export const envOption = new Option('--env [string]', 'Environment to use')
28
32
  .choices(['qa', 'staging', 'production'])
29
- .default('qa')
33
+ .default('qa');
30
34
 
31
- export const silentOption = new Option('--silent [boolean]', 'Only log result of the operation').default(false)
35
+ export const silentOption = new Option(
36
+ '--silent [boolean]',
37
+ 'Only log result of the operation'
38
+ ).default(false);
32
39
 
33
40
  export const bumpVersionOptionDeprecated = new Option(
34
41
  flags,
35
42
  chalk.bgYellow`DEPRECATED` +
36
- ` Use with ${chalk.cyan`zip`} or ${chalk.cyan`release`} command instead`
43
+ ` Use with ${chalk.cyan`zip`} or ${chalk.cyan`release`} command instead`
37
44
  )
38
45
  .choices(choices)
39
46
  .argParser(argParser);
package/lib/flow.js CHANGED
@@ -14,7 +14,7 @@ export const runFlow = async (flow, context, indent = '') => {
14
14
  )}\n`
15
15
  );
16
16
 
17
- context.progress = () => logger.write('.')
17
+ context.progress = () => logger.write('.');
18
18
 
19
19
  const result = await runSteps(flow.steps, context, indent + ' ');
20
20
 
@@ -0,0 +1,8 @@
1
+ import { PREPARE_FLOW } from './prepare.js';
2
+ import { SETUP_API_CLIENT_STEP } from './steps/release/get-config.js';
3
+ import { ATTACH_STEPS } from './steps/attach/index.js';
4
+
5
+ export const ATTACH_FLOW = {
6
+ name: 'attach',
7
+ steps: [PREPARE_FLOW, SETUP_API_CLIENT_STEP, ...ATTACH_STEPS],
8
+ };
@@ -11,8 +11,8 @@ const debug = Debug('cca:api');
11
11
  */
12
12
  export class Api {
13
13
  /**
14
- * @type {import('got').Got}
15
- */
14
+ * @type {import('got').Got}
15
+ */
16
16
  #api;
17
17
 
18
18
  constructor(envName, apiKey, authToken = null) {
@@ -27,9 +27,9 @@ export class Api {
27
27
  'Accept': 'application/json',
28
28
  },
29
29
  hooks: {
30
- beforeRequest: [debug]
31
- }
32
- })
30
+ beforeRequest: [debug],
31
+ },
32
+ });
33
33
  }
34
34
 
35
35
  /**
@@ -42,11 +42,13 @@ export class Api {
42
42
  * @returns {object}
43
43
  */
44
44
  async getAppByKey(appKey) {
45
- const { data } = await this.#api.get('v2/apps', {
46
- searchParams: { per_page: 2, search: appKey }
47
- }).json();
45
+ const { data } = await this.#api
46
+ .get('v2/apps', {
47
+ searchParams: { per_page: 2, search: appKey },
48
+ })
49
+ .json();
48
50
 
49
- const app = data.find(app => app.attributes.app_key === appKey);
51
+ const app = data.find((app) => app.attributes.app_key === appKey);
50
52
  if (!app) {
51
53
  throw new Error(`App with key - ${appKey}, not exist`);
52
54
  }
@@ -64,7 +66,11 @@ export class Api {
64
66
  * @returns {object}
65
67
  */
66
68
  async getAppDatasetsOperationWrite(appId) {
67
- const { data } = await this.#api.get(`v2/apps/${appId}/app_datasets?dataset_operation=write&fields[]=app_dataset.dataset_name`).json();
69
+ const { data } = await this.#api
70
+ .get(
71
+ `v2/apps/${appId}/app_datasets?dataset_operation=write&fields[]=app_dataset.dataset_name`
72
+ )
73
+ .json();
68
74
  return data;
69
75
  }
70
76
 
@@ -84,27 +90,42 @@ export class Api {
84
90
  }
85
91
 
86
92
  /**
87
- * Get asset streams
93
+ * Get assets streams by ids
88
94
  *
89
95
  * @public
90
96
  *
91
- * @param {string} assetId
97
+ * @param {string[]} assetIds
98
+ * @param {string[]} segments
99
+ * @param {string[]} statuses
92
100
  *
93
- * @returns {object[]}
101
+ * @returns {Promise<object[]>}
94
102
  */
95
- async getStreamByAssetId(assetId) {
96
- const data = await this.#api.get(`v1/app_streams`, {
97
- searchParams: {
98
- asset_id: assetId,
99
- segment: 'drilling',
100
- status: 'complete'
101
- }
102
- }).json();
103
-
104
- if (!data[0]) {
105
- throw new Error(`Could not found streams for asset ID - ${assetId}`);
106
- }
103
+ async getStreamsByAssetIds(assetIds, segments, statuses = ['complete']) {
104
+ const searchParams = new URLSearchParams([
105
+ ...assetIds.map((assetId) => ['asset_id[]', assetId]),
106
+ ...segments.map((segment) => ['segment[]', segment]),
107
+ ...statuses.map((status) => ['status[]', status]),
108
+ ]);
109
+
110
+ return this.#api.get(`v1/app_streams`, { searchParams }).json();
111
+ }
107
112
 
113
+ /**
114
+ * Get all assets
115
+ *
116
+ * @public
117
+ *
118
+ * @param {string} status
119
+ * @param {number} perPage
120
+ *
121
+ * @returns {Promise<object[]>}
122
+ */
123
+ async getAllAssets(status = 'active', perPage = 1000) {
124
+ const { data } = await this.#api
125
+ .get(`v2/assets`, {
126
+ searchParams: { status, per_page: perPage },
127
+ })
128
+ .json();
108
129
  return data;
109
130
  }
110
131
 
@@ -118,7 +139,9 @@ export class Api {
118
139
  * @returns {object[]}
119
140
  */
120
141
  async getWellByAssetId(assetId) {
121
- const { wells } = await this.#api.post('v2/assets/resolve', { json: { assets: [assetId], } }).json();
142
+ const { wells } = await this.#api
143
+ .post('v2/assets/resolve', { json: { assets: [assetId] } })
144
+ .json();
122
145
 
123
146
  if (!wells.length) {
124
147
  throw new Error(`Could not found wells by asset ID - ${assetId}`);
@@ -176,7 +199,11 @@ export class Api {
176
199
  * @returns {object[]}
177
200
  */
178
201
  async getAppRuns(appId) {
179
- const { data } = await this.#api.get(`v2/apps/${appId}/app_runs?page=1&per_page=500&status[]=pending&status[]=in_progress&status[]=running`).json();
202
+ const { data } = await this.#api
203
+ .get(
204
+ `v2/apps/${appId}/app_runs?page=1&per_page=500&status[]=pending&status[]=in_progress&status[]=running`
205
+ )
206
+ .json();
180
207
 
181
208
  return data;
182
209
  }
@@ -195,10 +222,12 @@ export class Api {
195
222
  const uploadURL = `v2/apps/${appKey}/packages/upload`;
196
223
 
197
224
  try {
198
- const { data } = await this.#api.post(uploadURL, {
199
- headers: formData.getHeaders(),
200
- body: formData,
201
- }).json();
225
+ const { data } = await this.#api
226
+ .post(uploadURL, {
227
+ headers: formData.getHeaders(),
228
+ body: formData,
229
+ })
230
+ .json();
202
231
 
203
232
  return {
204
233
  id: data.id,
@@ -209,22 +238,22 @@ export class Api {
209
238
  `${JSON.parse(e.response.body).message || ''} \nPOST: ${uploadURL} failed.`,
210
239
  { cause: e }
211
240
  );
212
-
213
241
  }
214
242
  }
215
243
 
216
-
217
244
  /**
218
- * @param {string} appId
219
- * @param {string} id
220
- * @param {string} notes
221
- *
222
- * @returns { Promise<{id: number, status: string}>}
223
- */
245
+ * @param {string} appId
246
+ * @param {string} id
247
+ * @param {string} notes
248
+ *
249
+ * @returns { Promise<{id: number, status: string}>}
250
+ */
224
251
  async addNotes(appId, id, notes) {
225
- const { data } = await this.#api.patch(`v2/apps/${appId}/packages/${id}`, {
226
- json: { package: { notes } },
227
- }).json();
252
+ const { data } = await this.#api
253
+ .patch(`v2/apps/${appId}/packages/${id}`, {
254
+ json: { package: { notes } },
255
+ })
256
+ .json();
228
257
 
229
258
  return {
230
259
  id: data.id,
@@ -233,11 +262,11 @@ export class Api {
233
262
  }
234
263
 
235
264
  /**
236
- * @param {string} appId
237
- * @param {string} uploadId
238
- *
239
- * @returns { Promise<{id: number, status: string}>}
240
- */
265
+ * @param {string} appId
266
+ * @param {string} uploadId
267
+ *
268
+ * @returns { Promise<{id: number, status: string}>}
269
+ */
241
270
  async checkApp(appId, uploadId) {
242
271
  const { data } = await this.#api.get(`v2/apps/${appId}/packages/${uploadId}`).json();
243
272
 
@@ -248,30 +277,32 @@ export class Api {
248
277
  }
249
278
 
250
279
  /**
251
- * @param {string} appId
252
- * @param {string} uploadId
253
- *
254
- * @returns { Promise<void>}
255
- */
280
+ * @param {string} appId
281
+ * @param {string} uploadId
282
+ *
283
+ * @returns { Promise<void>}
284
+ */
256
285
  deleteAppUpload(appId, uploadId) {
257
286
  return this.#api.del(`v2/apps/${appId}/packages/${uploadId}`).json();
258
287
  }
259
288
 
260
289
  /**
261
- * @param {string} appId
262
- * @param {string} id
263
- *
264
- * @returns { Promise<{id: number, status: string}>}
265
- */
290
+ * @param {string} appId
291
+ * @param {string} id
292
+ *
293
+ * @returns { Promise<{id: number, status: string}>}
294
+ */
266
295
  async publishApp(appId, id) {
267
296
  console.log(`v2/apps/${appId}/packages/${id}`, {
268
297
  json: { package: { status: 'published' } },
269
- })
270
- const { data } = await this.#api.patch(`v2/apps/${appId}/packages/${id}`, {
271
- json: { package: { status: 'published' } },
272
- }).json();
298
+ });
299
+ const { data } = await this.#api
300
+ .patch(`v2/apps/${appId}/packages/${id}`, {
301
+ json: { package: { status: 'published' } },
302
+ })
303
+ .json();
273
304
 
274
- console.log('done')
305
+ console.log('done');
275
306
 
276
307
  return {
277
308
  id: data.id,
@@ -279,13 +310,13 @@ export class Api {
279
310
  };
280
311
  }
281
312
 
282
- /**
283
- * Get app packages
284
- *
285
- * @param {string} appId
286
- *
287
- * @returns { Promise<object[]>}
288
- */
313
+ /**
314
+ * Get app packages
315
+ *
316
+ * @param {string} appId
317
+ *
318
+ * @returns { Promise<object[]>}
319
+ */
289
320
  async getAppPackages(appId) {
290
321
  const { data } = await this.#api.get(`v2/apps/${appId}/packages`).json();
291
322
  return data;
@@ -303,25 +334,25 @@ export class Api {
303
334
  *
304
335
  * @returns { Promise<object> }
305
336
  */
306
- async connectAppToStream(appId, streamId, settings, status='active') {
337
+ async connectAppToStream(appId, streamId, settings, status = 'active') {
307
338
  const json = {
308
339
  app_stream_id: streamId,
309
340
  app_id: appId,
310
341
  status,
311
342
  settings: settings,
312
- scheduler_type: settings.scheduler_type
343
+ scheduler_type: settings.scheduler_type,
313
344
  };
314
345
 
315
346
  return this.#api.post('v1/app_connections', { json }).json();
316
347
  }
317
348
 
318
349
  /**
319
- * @param {string} appId
320
- * @param {string} id
321
- * @param {'BETA' | 'PROD'} label
322
- *
323
- * @returns { Promise<{id: number, status: string}>}
324
- */
350
+ * @param {string} appId
351
+ * @param {string} id
352
+ * @param {'BETA' | 'PROD'} label
353
+ *
354
+ * @returns { Promise<{id: number, status: string}>}
355
+ */
325
356
  async putLabel(appId, id, label) {
326
357
  await this.#api.patch(`v2/apps/${appId}/packages/${id}`, {
327
358
  json: { package: { label } },
@@ -0,0 +1,139 @@
1
+ import chalk from 'chalk';
2
+ import terminalLink from 'terminal-link';
3
+
4
+ import { logger } from '../../helpers/logger.js';
5
+
6
+ /**
7
+ * Console notification
8
+ *
9
+ */
10
+ export class Notification {
11
+ #prefixUrl;
12
+
13
+ constructor(envName) {
14
+ this.#prefixUrl = `https://app${envName === 'production' ? '.' : `.${envName}.`}corva.ai`;
15
+ }
16
+
17
+ /**
18
+ * Create link
19
+ *
20
+ * @private
21
+ *
22
+ * @param {string} title
23
+ * @param {string} url
24
+ *
25
+ * @returns {string}
26
+ */
27
+ _createLink(title, url) {
28
+ return this._addLinkDecoration(terminalLink(title, url));
29
+ }
30
+
31
+ /**
32
+ * Print to console line break
33
+ *
34
+ * @public
35
+ *
36
+ * @returns {void}
37
+ */
38
+ printLineBreak() {
39
+ logger.write('\n');
40
+ }
41
+
42
+ /**
43
+ * Print to console text
44
+ *
45
+ * @public
46
+ *
47
+ * @param {string} text
48
+ *
49
+ * @returns {void}
50
+ */
51
+ print(text) {
52
+ this.printLineBreak();
53
+ logger.write(text);
54
+ }
55
+
56
+ /**
57
+ * Add a link styles
58
+ *
59
+ * @private
60
+ *
61
+ * @param {string} context
62
+ *
63
+ * @returns {string}
64
+ */
65
+ _addLinkDecoration(context) {
66
+ return chalk.blue.underline(context);
67
+ }
68
+
69
+ /**
70
+ * Add an error styles
71
+ *
72
+ * @private
73
+ *
74
+ * @param {string} context
75
+ *
76
+ * @returns {string}
77
+ */
78
+ _addErrorDecoration(context) {
79
+ return chalk.red.bold(context);
80
+ }
81
+
82
+ /**
83
+ * Get stream link
84
+ *
85
+ * @public
86
+ *
87
+ * @param {string} title
88
+ * @param {string} streamId
89
+ *
90
+ * @returns {string}
91
+ */
92
+ getStreamLink(title, streamId) {
93
+ const streamUrl = `${this.#prefixUrl}/config/streams/${streamId}`;
94
+ return this._createLink(title, streamUrl);
95
+ }
96
+
97
+ /**
98
+ * Print stream link
99
+ *
100
+ * @public
101
+ *
102
+ * @param {string} title
103
+ * @param {string} streamId
104
+ *
105
+ * @returns {avoid}
106
+ */
107
+ printStreamLink(title, streamId) {
108
+ const link = this.getStreamLink(title, streamId);
109
+ this.print(link);
110
+ }
111
+
112
+ /**
113
+ * Get asset link
114
+ *
115
+ * @public
116
+ *
117
+ * @param {string} title
118
+ * @param {string} assetId
119
+ *
120
+ * @returns {string}
121
+ */
122
+ getAssetLink(title, assetId) {
123
+ const assetUrl = `${this.#prefixUrl}/assets/${assetId}`;
124
+ return this._createLink(title, assetUrl);
125
+ }
126
+
127
+ /**
128
+ * Print an error
129
+ *
130
+ * @public
131
+ *
132
+ * @param {string} error
133
+ *
134
+ * @returns {void}
135
+ */
136
+ printError(error) {
137
+ this.print(this._addErrorDecoration(error));
138
+ }
139
+ }
@@ -1,3 +1,3 @@
1
1
  export async function waitForMs(ms) {
2
- return new Promise(resolve => setTimeout(resolve, ms));
2
+ return new Promise((resolve) => setTimeout(resolve, ms));
3
3
  }
@@ -21,6 +21,6 @@ export const RELEASE_FLOW = {
21
21
  REMOVE_FAILED_UPLOAD_STEP,
22
22
  PUBLISH_PACKAGE_STEP,
23
23
  ADD_LABEL_STEP,
24
- ADD_NOTES_STEP
24
+ ADD_NOTES_STEP,
25
25
  ],
26
26
  };
@@ -0,0 +1,24 @@
1
+ import _ from 'lodash';
2
+
3
+ export const ADD_APP_TO_STREAM_TASK_STEP = {
4
+ message: 'Add app to streams...',
5
+ fn: async (context) => {
6
+ const { assetsStreamsDataToProcess, api, app, manifest, notification } = context;
7
+
8
+ let counter = 0;
9
+ for (const assetStreamsData of assetsStreamsDataToProcess) {
10
+ for (const stream of assetStreamsData.selectedStreams) {
11
+ notification.printStreamLink(stream.name, stream.id);
12
+ try {
13
+ await api.connectAppToStream(app.id, stream.id, manifest.manifest.settings.app);
14
+ ++counter;
15
+ } catch (e) {
16
+ notification.printError(
17
+ `Could not add app to the stream, an error occurred: ${e.message}`
18
+ );
19
+ }
20
+ }
21
+ }
22
+ notification.print(`The app has been added to ${counter} - stream(s)`);
23
+ },
24
+ };
@@ -0,0 +1,142 @@
1
+ import _ from 'lodash';
2
+ import inquirer from 'inquirer';
3
+
4
+ export const GET_ALL_LIVE_ASSETS_TASK_STEP = {
5
+ message: 'Fetching all live assets information...',
6
+ fn: async (context) => {
7
+ const { manifest, api, app, notification } = context;
8
+
9
+ const assets = await api.getAllAssets();
10
+
11
+ notification.print(`${assets.length} - asset was found`);
12
+
13
+ const selectedAssets = await getAssetsListWithPrompt(assets, notification);
14
+
15
+ const assetsIds = selectedAssets.map((asset) => asset.id);
16
+ const streams = await api.getStreamsByAssetIds(
17
+ assetsIds,
18
+ manifest.manifest.application.segments
19
+ );
20
+
21
+ const mappedAssetStreamsData = mapAssetsStreamsData(selectedAssets, streams);
22
+
23
+ const assetsStreamsDataToProcess = await getAssetsStreamsWithPrompt(
24
+ mappedAssetStreamsData,
25
+ app.id,
26
+ notification
27
+ );
28
+
29
+ return {
30
+ ...context,
31
+ assetsStreamsDataToProcess,
32
+ };
33
+ },
34
+ };
35
+
36
+ /**
37
+ * CLI get assets list
38
+ *
39
+ * @param {object[]} assets
40
+ * @param {import('../../lib/notification').Notification} notification
41
+ *
42
+ * @returns {Promise<object[]>}
43
+ */
44
+ const getAssetsListWithPrompt = (assets, notification) => {
45
+ const choices = assets.map((asset) => {
46
+ return {
47
+ value: asset,
48
+ name: notification.getAssetLink(asset.attributes.name, asset.id),
49
+ checked: true,
50
+ };
51
+ });
52
+
53
+ return inquirer
54
+ .prompt([
55
+ {
56
+ message: 'Please choose assets?',
57
+ name: 'option',
58
+ type: 'checkbox',
59
+ choices,
60
+ },
61
+ ])
62
+ .then((res) => res.option);
63
+ };
64
+
65
+ /**
66
+ * Map asset and stream data
67
+ *
68
+ * @param {object[]} assets
69
+ * @param {object[]} streamsData
70
+ *
71
+ * @returns {object[]}
72
+ */
73
+ const mapAssetsStreamsData = (assets, streamsData) => {
74
+ return assets.map((asset) => {
75
+ const currentStreams = streamsData.filter((stream) => stream.asset_id === parseInt(asset.id));
76
+ return {
77
+ assetId: asset.id,
78
+ assetName: asset.attributes.name,
79
+ streams: currentStreams,
80
+ selectedStreams: [],
81
+ };
82
+ });
83
+ };
84
+
85
+ /**
86
+ * CLI get streams list to process
87
+ *
88
+ * @param {object[]} mappedAssetsStreamsData
89
+ * @param {number} appId
90
+ * @param {import('../../lib/notification').Notification} notification
91
+ *
92
+ * @returns {Promise<object[]>}
93
+ */
94
+ const getAssetsStreamsWithPrompt = async (mappedAssetsStreamsData, appId, notification) => {
95
+ notification.printLineBreak();
96
+ for (let mappedData of mappedAssetsStreamsData) {
97
+ const currentStreamsCount = mappedData.streams.length;
98
+
99
+ if (!currentStreamsCount) {
100
+ continue;
101
+ }
102
+
103
+ const streamsWithoutCurrentApp = mappedData.streams.filter((stream) => {
104
+ return !stream.app_connections.find(
105
+ (appConnection) => appConnection.app_id === parseInt(appId)
106
+ );
107
+ });
108
+
109
+ if (!streamsWithoutCurrentApp.length) {
110
+ continue;
111
+ }
112
+
113
+ if (streamsWithoutCurrentApp.length === 1) {
114
+ mappedData.selectedStreams = streamsWithoutCurrentApp;
115
+ continue;
116
+ }
117
+
118
+ const choices = streamsWithoutCurrentApp.map((stream) => {
119
+ return {
120
+ value: stream,
121
+ name: notification.getStreamLink(stream.name, stream.id),
122
+ checked: true,
123
+ };
124
+ });
125
+
126
+ const link = notification.getAssetLink(mappedData.assetName, mappedData.assetId);
127
+ const selectedStreams = await inquirer
128
+ .prompt([
129
+ {
130
+ message: `Please choose streams for the asset - ${link}?`,
131
+ name: 'option',
132
+ type: 'checkbox',
133
+ choices,
134
+ },
135
+ ])
136
+ .then((res) => res.option);
137
+
138
+ mappedData.selectedStreams = selectedStreams;
139
+ }
140
+
141
+ return mappedAssetsStreamsData;
142
+ };
@@ -0,0 +1,9 @@
1
+ import { PREPARE_DATA_TASK_STEP } from './prepare-data.js';
2
+ import { GET_ALL_LIVE_ASSETS_TASK_STEP } from './get-all-live-assets.js';
3
+ import { ADD_APP_TO_STREAM_TASK_STEP } from './add-app-to-stream.js';
4
+
5
+ export const ATTACH_STEPS = [
6
+ PREPARE_DATA_TASK_STEP,
7
+ GET_ALL_LIVE_ASSETS_TASK_STEP,
8
+ ADD_APP_TO_STREAM_TASK_STEP,
9
+ ];