@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.
- package/README.md +1 -0
- package/lib/bump-version.option.js +12 -5
- package/lib/flow.js +1 -1
- package/lib/flows/attach.js +8 -0
- package/lib/flows/lib/api.js +108 -77
- package/lib/flows/lib/notification.js +139 -0
- package/lib/flows/lib/waitForMs.js +1 -1
- package/lib/flows/release.js +1 -1
- package/lib/flows/steps/attach/add-app-to-stream.js +24 -0
- package/lib/flows/steps/attach/get-all-live-assets.js +142 -0
- package/lib/flows/steps/attach/index.js +9 -0
- package/lib/flows/steps/attach/prepare-data.js +20 -0
- package/lib/flows/steps/release/add-label.js +2 -3
- package/lib/flows/steps/release/add-notes.js +2 -2
- package/lib/flows/steps/release/get-config.js +4 -1
- package/lib/flows/steps/release/prepare-data.js +3 -3
- package/lib/flows/steps/release/publish.js +6 -4
- package/lib/flows/steps/release/remove-failed-upload.js +7 -5
- package/lib/flows/steps/release/upload-zip-to-corva.js +9 -6
- package/lib/flows/steps/release/wait-for-build.js +4 -4
- package/lib/flows/steps/rerun/create-task.js +12 -15
- package/lib/flows/steps/rerun/ensure-that-app-in-stream.js +33 -25
- package/lib/flows/steps/rerun/get-app-version.js +14 -12
- package/lib/flows/steps/rerun/prepare-data.js +6 -8
- package/lib/flows/steps/rerun/prepare-well-and-stream-data.js +29 -36
- package/lib/flows/steps/rerun/rerun.js +5 -5
- package/lib/helpers/logger.js +22 -22
- package/lib/main.js +55 -31
- package/package.json +3 -2
- package/templates/python/scheduler/README.md +1 -1
- package/templates/python/stream/README.md +1 -1
- 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(
|
|
25
|
-
'
|
|
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(
|
|
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
|
-
|
|
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
|
@@ -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
|
+
};
|
package/lib/flows/lib/api.js
CHANGED
|
@@ -11,8 +11,8 @@ const debug = Debug('cca:api');
|
|
|
11
11
|
*/
|
|
12
12
|
export class Api {
|
|
13
13
|
/**
|
|
14
|
-
|
|
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
|
|
46
|
-
|
|
47
|
-
|
|
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
|
|
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
|
|
93
|
+
* Get assets streams by ids
|
|
88
94
|
*
|
|
89
95
|
* @public
|
|
90
96
|
*
|
|
91
|
-
* @param {string}
|
|
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
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
|
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
|
|
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
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
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
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
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
|
|
271
|
-
|
|
272
|
-
|
|
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
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
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
|
-
|
|
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
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
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
|
+
}
|
package/lib/flows/release.js
CHANGED
|
@@ -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
|
+
];
|