@corva/create-app 0.42.0-0 → 0.42.0-2
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 +2 -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 +109 -79
- 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 +18 -7
- 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 +61 -31
- package/package.json +4 -3
- 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
|
|
|
@@ -176,6 +177,7 @@ Options:
|
|
|
176
177
|
--label [string] Put a label on the release (choices: "BETA", "STABLE")
|
|
177
178
|
--remove-on-fail [boolean] Remove release if it fails during deployment (default: false)
|
|
178
179
|
--silent [boolean] Only log result of the operation (default: false)
|
|
180
|
+
--remove-on-success App package (.zip) will not be deleted after upload (default: true)
|
|
179
181
|
```
|
|
180
182
|
|
|
181
183
|
### Examples
|
|
@@ -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
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import got from 'got';
|
|
2
2
|
import Debug from 'debug';
|
|
3
3
|
import { StepError } from './step-error.js';
|
|
4
|
-
import _ from 'lodash/fp.js';
|
|
5
4
|
|
|
6
5
|
const debug = Debug('cca:api');
|
|
7
6
|
|
|
@@ -11,8 +10,8 @@ const debug = Debug('cca:api');
|
|
|
11
10
|
*/
|
|
12
11
|
export class Api {
|
|
13
12
|
/**
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
* @type {import('got').Got}
|
|
14
|
+
*/
|
|
16
15
|
#api;
|
|
17
16
|
|
|
18
17
|
constructor(envName, apiKey, authToken = null) {
|
|
@@ -27,9 +26,9 @@ export class Api {
|
|
|
27
26
|
'Accept': 'application/json',
|
|
28
27
|
},
|
|
29
28
|
hooks: {
|
|
30
|
-
beforeRequest: [debug]
|
|
31
|
-
}
|
|
32
|
-
})
|
|
29
|
+
beforeRequest: [debug],
|
|
30
|
+
},
|
|
31
|
+
});
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
/**
|
|
@@ -42,11 +41,13 @@ export class Api {
|
|
|
42
41
|
* @returns {object}
|
|
43
42
|
*/
|
|
44
43
|
async getAppByKey(appKey) {
|
|
45
|
-
const { data } = await this.#api
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
const { data } = await this.#api
|
|
45
|
+
.get('v2/apps', {
|
|
46
|
+
searchParams: { per_page: 2, search: appKey },
|
|
47
|
+
})
|
|
48
|
+
.json();
|
|
48
49
|
|
|
49
|
-
const app = data.find(app => app.attributes.app_key === appKey);
|
|
50
|
+
const app = data.find((app) => app.attributes.app_key === appKey);
|
|
50
51
|
if (!app) {
|
|
51
52
|
throw new Error(`App with key - ${appKey}, not exist`);
|
|
52
53
|
}
|
|
@@ -64,7 +65,11 @@ export class Api {
|
|
|
64
65
|
* @returns {object}
|
|
65
66
|
*/
|
|
66
67
|
async getAppDatasetsOperationWrite(appId) {
|
|
67
|
-
const { data } = await this.#api
|
|
68
|
+
const { data } = await this.#api
|
|
69
|
+
.get(
|
|
70
|
+
`v2/apps/${appId}/app_datasets?dataset_operation=write&fields[]=app_dataset.dataset_name`
|
|
71
|
+
)
|
|
72
|
+
.json();
|
|
68
73
|
return data;
|
|
69
74
|
}
|
|
70
75
|
|
|
@@ -84,27 +89,42 @@ export class Api {
|
|
|
84
89
|
}
|
|
85
90
|
|
|
86
91
|
/**
|
|
87
|
-
* Get
|
|
92
|
+
* Get assets streams by ids
|
|
88
93
|
*
|
|
89
94
|
* @public
|
|
90
95
|
*
|
|
91
|
-
* @param {string}
|
|
96
|
+
* @param {string[]} assetIds
|
|
97
|
+
* @param {string[]} segments
|
|
98
|
+
* @param {string[]} statuses
|
|
92
99
|
*
|
|
93
|
-
* @returns {object[]}
|
|
100
|
+
* @returns {Promise<object[]>}
|
|
94
101
|
*/
|
|
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
|
-
}
|
|
102
|
+
async getStreamsByAssetIds(assetIds, segments, statuses = ['complete']) {
|
|
103
|
+
const searchParams = new URLSearchParams([
|
|
104
|
+
...assetIds.map((assetId) => ['asset_id[]', assetId]),
|
|
105
|
+
...segments.map((segment) => ['segment[]', segment]),
|
|
106
|
+
...statuses.map((status) => ['status[]', status]),
|
|
107
|
+
]);
|
|
108
|
+
|
|
109
|
+
return this.#api.get(`v1/app_streams`, { searchParams }).json();
|
|
110
|
+
}
|
|
107
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Get all assets
|
|
114
|
+
*
|
|
115
|
+
* @public
|
|
116
|
+
*
|
|
117
|
+
* @param {string} status
|
|
118
|
+
* @param {number} perPage
|
|
119
|
+
*
|
|
120
|
+
* @returns {Promise<object[]>}
|
|
121
|
+
*/
|
|
122
|
+
async getAllAssets(status = 'active', perPage = 1000) {
|
|
123
|
+
const { data } = await this.#api
|
|
124
|
+
.get(`v2/assets`, {
|
|
125
|
+
searchParams: { status, per_page: perPage },
|
|
126
|
+
})
|
|
127
|
+
.json();
|
|
108
128
|
return data;
|
|
109
129
|
}
|
|
110
130
|
|
|
@@ -118,7 +138,9 @@ export class Api {
|
|
|
118
138
|
* @returns {object[]}
|
|
119
139
|
*/
|
|
120
140
|
async getWellByAssetId(assetId) {
|
|
121
|
-
const { wells } = await this.#api
|
|
141
|
+
const { wells } = await this.#api
|
|
142
|
+
.post('v2/assets/resolve', { json: { assets: [assetId] } })
|
|
143
|
+
.json();
|
|
122
144
|
|
|
123
145
|
if (!wells.length) {
|
|
124
146
|
throw new Error(`Could not found wells by asset ID - ${assetId}`);
|
|
@@ -176,7 +198,11 @@ export class Api {
|
|
|
176
198
|
* @returns {object[]}
|
|
177
199
|
*/
|
|
178
200
|
async getAppRuns(appId) {
|
|
179
|
-
const { data } = await this.#api
|
|
201
|
+
const { data } = await this.#api
|
|
202
|
+
.get(
|
|
203
|
+
`v2/apps/${appId}/app_runs?page=1&per_page=500&status[]=pending&status[]=in_progress&status[]=running`
|
|
204
|
+
)
|
|
205
|
+
.json();
|
|
180
206
|
|
|
181
207
|
return data;
|
|
182
208
|
}
|
|
@@ -195,10 +221,12 @@ export class Api {
|
|
|
195
221
|
const uploadURL = `v2/apps/${appKey}/packages/upload`;
|
|
196
222
|
|
|
197
223
|
try {
|
|
198
|
-
const { data } = await this.#api
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
224
|
+
const { data } = await this.#api
|
|
225
|
+
.post(uploadURL, {
|
|
226
|
+
headers: formData.getHeaders(),
|
|
227
|
+
body: formData,
|
|
228
|
+
})
|
|
229
|
+
.json();
|
|
202
230
|
|
|
203
231
|
return {
|
|
204
232
|
id: data.id,
|
|
@@ -209,22 +237,22 @@ export class Api {
|
|
|
209
237
|
`${JSON.parse(e.response.body).message || ''} \nPOST: ${uploadURL} failed.`,
|
|
210
238
|
{ cause: e }
|
|
211
239
|
);
|
|
212
|
-
|
|
213
240
|
}
|
|
214
241
|
}
|
|
215
242
|
|
|
216
|
-
|
|
217
243
|
/**
|
|
218
|
-
* @param {string} appId
|
|
219
|
-
* @param {string} id
|
|
220
|
-
* @param {string} notes
|
|
221
|
-
*
|
|
222
|
-
* @returns { Promise<{id: number, status: string}>}
|
|
223
|
-
*/
|
|
244
|
+
* @param {string} appId
|
|
245
|
+
* @param {string} id
|
|
246
|
+
* @param {string} notes
|
|
247
|
+
*
|
|
248
|
+
* @returns { Promise<{id: number, status: string}>}
|
|
249
|
+
*/
|
|
224
250
|
async addNotes(appId, id, notes) {
|
|
225
|
-
const { data } = await this.#api
|
|
226
|
-
|
|
227
|
-
|
|
251
|
+
const { data } = await this.#api
|
|
252
|
+
.patch(`v2/apps/${appId}/packages/${id}`, {
|
|
253
|
+
json: { package: { notes } },
|
|
254
|
+
})
|
|
255
|
+
.json();
|
|
228
256
|
|
|
229
257
|
return {
|
|
230
258
|
id: data.id,
|
|
@@ -233,11 +261,11 @@ export class Api {
|
|
|
233
261
|
}
|
|
234
262
|
|
|
235
263
|
/**
|
|
236
|
-
* @param {string} appId
|
|
237
|
-
* @param {string} uploadId
|
|
238
|
-
*
|
|
239
|
-
* @returns { Promise<{id: number, status: string}>}
|
|
240
|
-
*/
|
|
264
|
+
* @param {string} appId
|
|
265
|
+
* @param {string} uploadId
|
|
266
|
+
*
|
|
267
|
+
* @returns { Promise<{id: number, status: string}>}
|
|
268
|
+
*/
|
|
241
269
|
async checkApp(appId, uploadId) {
|
|
242
270
|
const { data } = await this.#api.get(`v2/apps/${appId}/packages/${uploadId}`).json();
|
|
243
271
|
|
|
@@ -248,30 +276,32 @@ export class Api {
|
|
|
248
276
|
}
|
|
249
277
|
|
|
250
278
|
/**
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
279
|
+
* @param {string} appId
|
|
280
|
+
* @param {string} uploadId
|
|
281
|
+
*
|
|
282
|
+
* @returns { Promise<void>}
|
|
283
|
+
*/
|
|
256
284
|
deleteAppUpload(appId, uploadId) {
|
|
257
|
-
return this.#api.
|
|
285
|
+
return this.#api.delete(`v2/apps/${appId}/packages/${uploadId}`).json();
|
|
258
286
|
}
|
|
259
287
|
|
|
260
288
|
/**
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
289
|
+
* @param {string} appId
|
|
290
|
+
* @param {string} id
|
|
291
|
+
*
|
|
292
|
+
* @returns { Promise<{id: number, status: string}>}
|
|
293
|
+
*/
|
|
266
294
|
async publishApp(appId, id) {
|
|
267
295
|
console.log(`v2/apps/${appId}/packages/${id}`, {
|
|
268
296
|
json: { package: { status: 'published' } },
|
|
269
|
-
})
|
|
270
|
-
const { data } = await this.#api
|
|
271
|
-
|
|
272
|
-
|
|
297
|
+
});
|
|
298
|
+
const { data } = await this.#api
|
|
299
|
+
.patch(`v2/apps/${appId}/packages/${id}`, {
|
|
300
|
+
json: { package: { status: 'published' } },
|
|
301
|
+
})
|
|
302
|
+
.json();
|
|
273
303
|
|
|
274
|
-
console.log('done')
|
|
304
|
+
console.log('done');
|
|
275
305
|
|
|
276
306
|
return {
|
|
277
307
|
id: data.id,
|
|
@@ -279,13 +309,13 @@ export class Api {
|
|
|
279
309
|
};
|
|
280
310
|
}
|
|
281
311
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
312
|
+
/**
|
|
313
|
+
* Get app packages
|
|
314
|
+
*
|
|
315
|
+
* @param {string} appId
|
|
316
|
+
*
|
|
317
|
+
* @returns { Promise<object[]>}
|
|
318
|
+
*/
|
|
289
319
|
async getAppPackages(appId) {
|
|
290
320
|
const { data } = await this.#api.get(`v2/apps/${appId}/packages`).json();
|
|
291
321
|
return data;
|
|
@@ -303,25 +333,25 @@ export class Api {
|
|
|
303
333
|
*
|
|
304
334
|
* @returns { Promise<object> }
|
|
305
335
|
*/
|
|
306
|
-
|
|
336
|
+
async connectAppToStream(appId, streamId, settings, status = 'active') {
|
|
307
337
|
const json = {
|
|
308
338
|
app_stream_id: streamId,
|
|
309
339
|
app_id: appId,
|
|
310
340
|
status,
|
|
311
341
|
settings: settings,
|
|
312
|
-
scheduler_type: settings.scheduler_type
|
|
342
|
+
scheduler_type: settings.scheduler_type,
|
|
313
343
|
};
|
|
314
344
|
|
|
315
345
|
return this.#api.post('v1/app_connections', { json }).json();
|
|
316
346
|
}
|
|
317
347
|
|
|
318
348
|
/**
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
349
|
+
* @param {string} appId
|
|
350
|
+
* @param {string} id
|
|
351
|
+
* @param {'BETA' | 'PROD'} label
|
|
352
|
+
*
|
|
353
|
+
* @returns { Promise<{id: number, status: string}>}
|
|
354
|
+
*/
|
|
325
355
|
async putLabel(appId, id, label) {
|
|
326
356
|
await this.#api.patch(`v2/apps/${appId}/packages/${id}`, {
|
|
327
357
|
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
|
+
};
|