@corva/create-app 0.0.0-73c49372

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 (193) hide show
  1. package/README.md +211 -0
  2. package/bin/cca.js +5 -0
  3. package/bin/create-corva-app.cjs +30 -0
  4. package/common/node/.env +15 -0
  5. package/common/node/.env.sample +26 -0
  6. package/common/node/gitignore +130 -0
  7. package/common/package.json +3 -0
  8. package/common/python/.env +5 -0
  9. package/common/python/.env.sample +7 -0
  10. package/common/python/Makefile +15 -0
  11. package/common/python/gitignore +161 -0
  12. package/common/python/requirements.txt +2 -0
  13. package/lib/commands/attach.js +28 -0
  14. package/lib/commands/create.js +463 -0
  15. package/lib/commands/release.js +52 -0
  16. package/lib/commands/rerun.js +34 -0
  17. package/lib/commands/zip.js +39 -0
  18. package/lib/constants/cache.js +5 -0
  19. package/lib/constants/cli.js +24 -0
  20. package/lib/constants/manifest.js +262 -0
  21. package/lib/constants/messages.js +15 -0
  22. package/lib/constants/package.js +269 -0
  23. package/lib/flow.js +53 -0
  24. package/lib/flows/attach.js +8 -0
  25. package/lib/flows/lib/api.js +376 -0
  26. package/lib/flows/lib/create-zip-archive.js +83 -0
  27. package/lib/flows/lib/json.js +30 -0
  28. package/lib/flows/lib/manifest.js +81 -0
  29. package/lib/flows/lib/notification.js +142 -0
  30. package/lib/flows/lib/step-error.js +10 -0
  31. package/lib/flows/lib/waitForMs.js +3 -0
  32. package/lib/flows/prepare.js +6 -0
  33. package/lib/flows/release.js +26 -0
  34. package/lib/flows/rerun.js +8 -0
  35. package/lib/flows/steps/attach/add-app-to-stream.js +23 -0
  36. package/lib/flows/steps/attach/get-all-live-assets.js +135 -0
  37. package/lib/flows/steps/attach/index.js +5 -0
  38. package/lib/flows/steps/attach/prepare-data.js +19 -0
  39. package/lib/flows/steps/prepare-load-app-files.js +12 -0
  40. package/lib/flows/steps/release/add-label.js +10 -0
  41. package/lib/flows/steps/release/add-notes.js +10 -0
  42. package/lib/flows/steps/release/get-config.js +41 -0
  43. package/lib/flows/steps/release/prepare-data.js +12 -0
  44. package/lib/flows/steps/release/publish.js +11 -0
  45. package/lib/flows/steps/release/remove-failed-upload.js +21 -0
  46. package/lib/flows/steps/release/upload-zip-to-corva.js +62 -0
  47. package/lib/flows/steps/release/wait-for-build.js +36 -0
  48. package/lib/flows/steps/rerun/create-task.js +77 -0
  49. package/lib/flows/steps/rerun/ensure-that-app-in-stream.js +68 -0
  50. package/lib/flows/steps/rerun/get-app-version.js +111 -0
  51. package/lib/flows/steps/rerun/prepare-data.js +162 -0
  52. package/lib/flows/steps/rerun/prepare-well-and-stream-data.js +188 -0
  53. package/lib/flows/steps/rerun/rerun.js +13 -0
  54. package/lib/flows/steps/zip-cleanup.js +17 -0
  55. package/lib/flows/steps/zip-create-archive.js +15 -0
  56. package/lib/flows/steps/zip-file-list-resolve.js +260 -0
  57. package/lib/flows/steps/zip-prepare.js +20 -0
  58. package/lib/flows/steps/zip.js +6 -0
  59. package/lib/flows/zip-simple.js +6 -0
  60. package/lib/flows/zip.js +7 -0
  61. package/lib/helpers/cli-version.js +114 -0
  62. package/lib/helpers/commands.js +13 -0
  63. package/lib/helpers/logger.js +35 -0
  64. package/lib/helpers/manifest.js +74 -0
  65. package/lib/helpers/resolve-app-runtime.js +128 -0
  66. package/lib/helpers/utils.js +91 -0
  67. package/lib/helpers/versioning.js +94 -0
  68. package/lib/main.js +68 -0
  69. package/lib/options/api-key.js +6 -0
  70. package/lib/options/app-key.js +6 -0
  71. package/lib/options/app-version.js +3 -0
  72. package/lib/options/bump-version.js +19 -0
  73. package/lib/options/cache.js +11 -0
  74. package/lib/options/env.js +3 -0
  75. package/lib/options/original-cwd.js +3 -0
  76. package/lib/options/silent.js +3 -0
  77. package/package.json +104 -0
  78. package/template_extensions/corva/.commitlintrc.json +6 -0
  79. package/template_extensions/corva/.github/pull_request_template.md +14 -0
  80. package/template_extensions/corva/.github/workflows/code-checks.yml +15 -0
  81. package/template_extensions/corva/.github/workflows/develop.yml +17 -0
  82. package/template_extensions/corva/.github/workflows/feat-fix-delete.yml +14 -0
  83. package/template_extensions/corva/.github/workflows/feat-fix.yml +23 -0
  84. package/template_extensions/corva/.github/workflows/release-fix-X.X.X.yml +16 -0
  85. package/template_extensions/corva/.github/workflows/validate-pr-title.yml +19 -0
  86. package/template_extensions/corva/.husky/commit-msg +5 -0
  87. package/template_extensions/corva/.husky/pre-commit +4 -0
  88. package/templates/scheduler_data-time/javascript/README.md +19 -0
  89. package/templates/scheduler_data-time/javascript/__tests__/processor.spec.js +15 -0
  90. package/templates/scheduler_data-time/javascript/index.js +15 -0
  91. package/templates/scheduler_data-time/python/README.md +31 -0
  92. package/templates/scheduler_data-time/python/lambda_function.py +7 -0
  93. package/templates/scheduler_data-time/python/test/__init__.py +0 -0
  94. package/templates/scheduler_data-time/python/test/app_test.py +10 -0
  95. package/templates/scheduler_data-time/typescript/README.md +25 -0
  96. package/templates/scheduler_data-time/typescript/__tests__/processor.spec.ts +15 -0
  97. package/templates/scheduler_data-time/typescript/index.ts +8 -0
  98. package/templates/scheduler_depth/javascript/README.md +19 -0
  99. package/templates/scheduler_depth/javascript/__tests__/processor.spec.js +17 -0
  100. package/templates/scheduler_depth/javascript/index.js +15 -0
  101. package/templates/scheduler_depth/python/README.md +31 -0
  102. package/templates/scheduler_depth/python/lambda_function.py +7 -0
  103. package/templates/scheduler_depth/python/test/__init__.py +0 -0
  104. package/templates/scheduler_depth/python/test/app_test.py +10 -0
  105. package/templates/scheduler_depth/typescript/README.md +25 -0
  106. package/templates/scheduler_depth/typescript/__tests__/processor.spec.ts +17 -0
  107. package/templates/scheduler_depth/typescript/index.ts +8 -0
  108. package/templates/scheduler_natural-time/javascript/README.md +19 -0
  109. package/templates/scheduler_natural-time/javascript/__tests__/processor.spec.js +15 -0
  110. package/templates/scheduler_natural-time/javascript/index.js +15 -0
  111. package/templates/scheduler_natural-time/python/README.md +31 -0
  112. package/templates/scheduler_natural-time/python/lambda_function.py +7 -0
  113. package/templates/scheduler_natural-time/python/test/__init__.py +0 -0
  114. package/templates/scheduler_natural-time/python/test/app_test.py +10 -0
  115. package/templates/scheduler_natural-time/typescript/README.md +25 -0
  116. package/templates/scheduler_natural-time/typescript/__tests__/processor.spec.ts +15 -0
  117. package/templates/scheduler_natural-time/typescript/index.ts +8 -0
  118. package/templates/stream_depth/javascript/README.md +19 -0
  119. package/templates/stream_depth/javascript/__tests__/processor.spec.js +20 -0
  120. package/templates/stream_depth/javascript/index.js +14 -0
  121. package/templates/stream_depth/python/README.md +31 -0
  122. package/templates/stream_depth/python/lambda_function.py +7 -0
  123. package/templates/stream_depth/python/test/__init__.py +0 -0
  124. package/templates/stream_depth/python/test/app_test.py +16 -0
  125. package/templates/stream_depth/typescript/README.md +25 -0
  126. package/templates/stream_depth/typescript/__tests__/processor.spec.ts +20 -0
  127. package/templates/stream_depth/typescript/index.ts +8 -0
  128. package/templates/stream_time/javascript/README.md +19 -0
  129. package/templates/stream_time/javascript/__tests__/processor.spec.js +14 -0
  130. package/templates/stream_time/javascript/index.js +14 -0
  131. package/templates/stream_time/python/README.md +31 -0
  132. package/templates/stream_time/python/lambda_function.py +7 -0
  133. package/templates/stream_time/python/test/__init__.py +0 -0
  134. package/templates/stream_time/python/test/app_test.py +16 -0
  135. package/templates/stream_time/typescript/README.md +25 -0
  136. package/templates/stream_time/typescript/__tests__/processor.spec.ts +14 -0
  137. package/templates/stream_time/typescript/index.ts +8 -0
  138. package/templates/task/javascript/README.md +19 -0
  139. package/templates/task/javascript/__tests__/processor.spec.js +16 -0
  140. package/templates/task/javascript/index.js +15 -0
  141. package/templates/task/python/README.md +31 -0
  142. package/templates/task/python/lambda_function.py +7 -0
  143. package/templates/task/python/test/__init__.py +0 -0
  144. package/templates/task/python/test/app_test.py +8 -0
  145. package/templates/task/typescript/README.md +25 -0
  146. package/templates/task/typescript/__tests__/processor.spec.ts +16 -0
  147. package/templates/task/typescript/index.ts +8 -0
  148. package/templates/ui/javascript/.eslintrc +11 -0
  149. package/templates/ui/javascript/.prettierrc +1 -0
  150. package/templates/ui/javascript/README.md +31 -0
  151. package/templates/ui/javascript/config/jest/babelTransform.js +16 -0
  152. package/templates/ui/javascript/config/jest/cssTransform.js +16 -0
  153. package/templates/ui/javascript/config/jest/fileTransform.js +48 -0
  154. package/templates/ui/javascript/config/jest/globalSetup.js +5 -0
  155. package/templates/ui/javascript/config/jest/setupTests.js +11 -0
  156. package/templates/ui/javascript/config-overrides.js +10 -0
  157. package/templates/ui/javascript/gitignore +27 -0
  158. package/templates/ui/javascript/src/App.completion.js +64 -0
  159. package/templates/ui/javascript/src/App.css +30 -0
  160. package/templates/ui/javascript/src/App.drilling.js +58 -0
  161. package/templates/ui/javascript/src/AppSettings.js +42 -0
  162. package/templates/ui/javascript/src/__mocks__/mockAppProps.js +590 -0
  163. package/templates/ui/javascript/src/__mocks__/mockAppSettingsProps.js +290 -0
  164. package/templates/ui/javascript/src/__tests__/App.test.js +21 -0
  165. package/templates/ui/javascript/src/__tests__/AppSettings.test.js +21 -0
  166. package/templates/ui/javascript/src/__tests__/TestsExample.test.js +37 -0
  167. package/templates/ui/javascript/src/assets/logo.svg +7 -0
  168. package/templates/ui/javascript/src/constants.js +3 -0
  169. package/templates/ui/javascript/src/index.js +7 -0
  170. package/templates/ui/typescript/.eslintrc +28 -0
  171. package/templates/ui/typescript/.prettierrc +1 -0
  172. package/templates/ui/typescript/README.md +31 -0
  173. package/templates/ui/typescript/config/jest/babelTransform.js +16 -0
  174. package/templates/ui/typescript/config/jest/cssTransform.js +16 -0
  175. package/templates/ui/typescript/config/jest/fileTransform.js +48 -0
  176. package/templates/ui/typescript/config/jest/globalSetup.js +5 -0
  177. package/templates/ui/typescript/config/jest/setupTests.js +11 -0
  178. package/templates/ui/typescript/config-overrides.js +10 -0
  179. package/templates/ui/typescript/gitignore +27 -0
  180. package/templates/ui/typescript/src/App.completion.tsx +66 -0
  181. package/templates/ui/typescript/src/App.css +30 -0
  182. package/templates/ui/typescript/src/App.drilling.tsx +60 -0
  183. package/templates/ui/typescript/src/AppSettings.tsx +38 -0
  184. package/templates/ui/typescript/src/__mocks__/mockAppProps.ts +590 -0
  185. package/templates/ui/typescript/src/__mocks__/mockAppSettingsProps.ts +290 -0
  186. package/templates/ui/typescript/src/__tests__/App.test.tsx +21 -0
  187. package/templates/ui/typescript/src/__tests__/AppSettings.test.tsx +21 -0
  188. package/templates/ui/typescript/src/__tests__/TestsExample.test.tsx +37 -0
  189. package/templates/ui/typescript/src/assets/logo.svg +7 -0
  190. package/templates/ui/typescript/src/constants.ts +3 -0
  191. package/templates/ui/typescript/src/custom.d.ts +9 -0
  192. package/templates/ui/typescript/src/index.js +7 -0
  193. package/templates/ui/typescript/tsconfig.json +8 -0
@@ -0,0 +1,3 @@
1
+ export async function waitForMs(ms) {
2
+ return new Promise((resolve) => setTimeout(resolve, ms));
3
+ }
@@ -0,0 +1,6 @@
1
+ import { LOAD_APP_FILES_STEP } from './steps/prepare-load-app-files.js';
2
+
3
+ export const PREPARE_FLOW = {
4
+ name: 'prepare',
5
+ steps: [LOAD_APP_FILES_STEP],
6
+ };
@@ -0,0 +1,26 @@
1
+ import { PREPARE_FLOW } from './prepare.js';
2
+ import { SETUP_API_CLIENT_STEP } from './steps/release/get-config.js';
3
+ import { UPLOAD_ZIP_TO_CORVA_STEP } from './steps/release/upload-zip-to-corva.js';
4
+ import { ZIP_SIMPLE_FLOW } from './zip-simple.js';
5
+ import { WAIT_FOR_BUILD_FINISH_STEP } from './steps/release/wait-for-build.js';
6
+ import { REMOVE_FAILED_UPLOAD_STEP } from './steps/release/remove-failed-upload.js';
7
+ import { ADD_LABEL_STEP } from './steps/release/add-label.js';
8
+ import { ADD_NOTES_STEP } from './steps/release/add-notes.js';
9
+ import { PUBLISH_PACKAGE_STEP } from './steps/release/publish.js';
10
+ import { RELEASE_PREPARE_DATA_STEP } from './steps/release/prepare-data.js';
11
+
12
+ export const RELEASE_FLOW = {
13
+ name: 'release',
14
+ steps: [
15
+ PREPARE_FLOW,
16
+ SETUP_API_CLIENT_STEP,
17
+ RELEASE_PREPARE_DATA_STEP,
18
+ ZIP_SIMPLE_FLOW,
19
+ UPLOAD_ZIP_TO_CORVA_STEP,
20
+ WAIT_FOR_BUILD_FINISH_STEP,
21
+ REMOVE_FAILED_UPLOAD_STEP,
22
+ PUBLISH_PACKAGE_STEP,
23
+ ADD_LABEL_STEP,
24
+ ADD_NOTES_STEP,
25
+ ],
26
+ };
@@ -0,0 +1,8 @@
1
+ import { PREPARE_FLOW } from './prepare.js';
2
+ import { RERUN_STEPS } from './steps/rerun/rerun.js';
3
+ import { SETUP_API_CLIENT_STEP } from './steps/release/get-config.js';
4
+
5
+ export const RERUN_FLOW = {
6
+ name: 'rerun',
7
+ steps: [PREPARE_FLOW, SETUP_API_CLIENT_STEP, ...RERUN_STEPS],
8
+ };
@@ -0,0 +1,23 @@
1
+ export const ADD_APP_TO_STREAM_TASK_STEP = {
2
+ message: 'Add app to streams...',
3
+ fn: async (context) => {
4
+ const { assetsStreamsDataToProcess, api, app, manifest, notification } = context;
5
+
6
+ let counter = 0;
7
+
8
+ for (const assetStreamsData of assetsStreamsDataToProcess) {
9
+ for (const stream of assetStreamsData.selectedStreams) {
10
+ notification.printStreamLink(stream.name, stream.id);
11
+
12
+ try {
13
+ await api.connectAppToStream(app.id, stream.id, manifest.manifest.settings.app);
14
+ ++counter;
15
+ } catch (e) {
16
+ notification.printError(`Could not add app to the stream, an error occurred: ${e.message}`);
17
+ }
18
+ }
19
+ }
20
+
21
+ notification.print(`The app has been added to ${counter} - stream(s)`);
22
+ },
23
+ };
@@ -0,0 +1,135 @@
1
+ import inquirer from 'inquirer';
2
+
3
+ export const GET_ALL_LIVE_ASSETS_TASK_STEP = {
4
+ message: 'Fetching all live assets information...',
5
+ fn: async (context) => {
6
+ const { manifest, api, app, notification } = context;
7
+
8
+ const assets = await api.getAllAssets();
9
+
10
+ notification.print(`${assets.length} - asset was found`);
11
+
12
+ const selectedAssets = await getAssetsListWithPrompt(assets, notification);
13
+
14
+ const assetsIds = selectedAssets.map((asset) => asset.id);
15
+ const streams = await api.getStreamsByAssetIds(assetsIds, manifest.manifest.application.segments);
16
+
17
+ const mappedAssetStreamsData = mapAssetsStreamsData(selectedAssets, streams);
18
+
19
+ const assetsStreamsDataToProcess = await getAssetsStreamsWithPrompt(mappedAssetStreamsData, app.id, notification);
20
+
21
+ return {
22
+ ...context,
23
+ assetsStreamsDataToProcess,
24
+ };
25
+ },
26
+ };
27
+
28
+ /**
29
+ * CLI get assets list
30
+ *
31
+ * @param {object[]} assets
32
+ * @param {import('../../lib/notification').Notification} notification
33
+ *
34
+ * @returns {Promise<object[]>}
35
+ */
36
+ const getAssetsListWithPrompt = (assets, notification) => {
37
+ const choices = assets.map((asset) => {
38
+ return {
39
+ value: asset,
40
+ name: notification.getAssetLink(asset.attributes.name, asset.id),
41
+ checked: true,
42
+ };
43
+ });
44
+
45
+ return inquirer
46
+ .prompt([
47
+ {
48
+ message: 'Please choose assets?',
49
+ name: 'option',
50
+ type: 'checkbox',
51
+ choices,
52
+ },
53
+ ])
54
+ .then((res) => res.option);
55
+ };
56
+
57
+ /**
58
+ * Map asset and stream data
59
+ *
60
+ * @param {object[]} assets
61
+ * @param {object[]} streamsData
62
+ *
63
+ * @returns {object[]}
64
+ */
65
+ const mapAssetsStreamsData = (assets, streamsData) => {
66
+ return assets.map((asset) => {
67
+ const currentStreams = streamsData.filter((stream) => stream.asset_id === parseInt(asset.id));
68
+
69
+ return {
70
+ assetId: asset.id,
71
+ assetName: asset.attributes.name,
72
+ streams: currentStreams,
73
+ selectedStreams: [],
74
+ };
75
+ });
76
+ };
77
+
78
+ /**
79
+ * CLI get streams list to process
80
+ *
81
+ * @param {object[]} mappedAssetsStreamsData
82
+ * @param {number} appId
83
+ * @param {import('../../lib/notification').Notification} notification
84
+ *
85
+ * @returns {Promise<object[]>}
86
+ */
87
+ const getAssetsStreamsWithPrompt = async (mappedAssetsStreamsData, appId, notification) => {
88
+ notification.printLineBreak();
89
+
90
+ for (const mappedData of mappedAssetsStreamsData) {
91
+ const currentStreamsCount = mappedData.streams.length;
92
+
93
+ if (!currentStreamsCount) {
94
+ continue;
95
+ }
96
+
97
+ const streamsWithoutCurrentApp = mappedData.streams.filter((stream) => {
98
+ return !stream.app_connections.find((appConnection) => appConnection.app_id === parseInt(appId));
99
+ });
100
+
101
+ if (!streamsWithoutCurrentApp.length) {
102
+ continue;
103
+ }
104
+
105
+ if (streamsWithoutCurrentApp.length === 1) {
106
+ mappedData.selectedStreams = streamsWithoutCurrentApp;
107
+
108
+ continue;
109
+ }
110
+
111
+ const choices = streamsWithoutCurrentApp.map((stream) => {
112
+ return {
113
+ value: stream,
114
+ name: notification.getStreamLink(stream.name, stream.id),
115
+ checked: true,
116
+ };
117
+ });
118
+
119
+ const link = notification.getAssetLink(mappedData.assetName, mappedData.assetId);
120
+ const selectedStreams = await inquirer
121
+ .prompt([
122
+ {
123
+ message: `Please choose streams for the asset - ${link}?`,
124
+ name: 'option',
125
+ type: 'checkbox',
126
+ choices,
127
+ },
128
+ ])
129
+ .then((res) => res.option);
130
+
131
+ mappedData.selectedStreams = selectedStreams;
132
+ }
133
+
134
+ return mappedAssetsStreamsData;
135
+ };
@@ -0,0 +1,5 @@
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 = [PREPARE_DATA_TASK_STEP, GET_ALL_LIVE_ASSETS_TASK_STEP, ADD_APP_TO_STREAM_TASK_STEP];
@@ -0,0 +1,19 @@
1
+ import { StepError } from '../../lib/step-error.js';
2
+
3
+ export const PREPARE_DATA_TASK_STEP = {
4
+ message: 'Preparing and checking data...',
5
+ fn: async (context) => {
6
+ const { manifest, api } = context;
7
+
8
+ if (!['scheduler', 'stream'].includes(manifest.manifest.application.type)) {
9
+ throw new StepError('Command supports only "scheduler" or "stream" apps');
10
+ }
11
+
12
+ const app = await api.getAppByKey(manifest.manifest.application.key);
13
+
14
+ return {
15
+ app,
16
+ ...context,
17
+ };
18
+ },
19
+ };
@@ -0,0 +1,12 @@
1
+ import { loadJson } from '../lib/json.js';
2
+ import { Manifest } from '../lib/manifest.js';
3
+
4
+ export const LOAD_APP_FILES_STEP = {
5
+ message: "Loading Corva app's files...",
6
+ async fn(context) {
7
+ const manifest = context.manifest || new Manifest(await loadJson(context.dirName, 'manifest.json'));
8
+ const pkg = context.package || (manifest.isJs() && (await loadJson(context.dirName, 'package.json')));
9
+
10
+ return { pkg, manifest };
11
+ },
12
+ };
@@ -0,0 +1,10 @@
1
+ export const ADD_LABEL_STEP = {
2
+ message: 'Adding label...',
3
+ async fn({ options: { label }, api, appId, packageId }) {
4
+ if (!label) {
5
+ return;
6
+ }
7
+
8
+ await api.putLabel(appId, packageId, label);
9
+ },
10
+ };
@@ -0,0 +1,10 @@
1
+ export const ADD_NOTES_STEP = {
2
+ message: 'Adding notes...',
3
+ async fn({ api, appId, packageId, options: { notes } }) {
4
+ if (!notes) {
5
+ return;
6
+ }
7
+
8
+ await api.addNotes(appId, packageId, notes);
9
+ },
10
+ };
@@ -0,0 +1,41 @@
1
+ import { RELEASE } from '../../../constants/messages.js';
2
+ import { promises as fs } from 'node:fs';
3
+ import dotenv from 'dotenv';
4
+ import { resolve } from 'node:path';
5
+ import { StepError } from '../../lib/step-error.js';
6
+ import { Api } from '../../lib/api.js';
7
+ import { Notification } from '../../lib/notification.js';
8
+
9
+ async function getVarsFromDotEnv({ dirName }) {
10
+ try {
11
+ const envFile = await fs.readFile(resolve(dirName, '.env'));
12
+
13
+ return dotenv.parse(envFile);
14
+ } catch (error) {
15
+ return {};
16
+ }
17
+ }
18
+
19
+ export const SETUP_API_CLIENT_STEP = {
20
+ message: RELEASE.getAuthToken,
21
+ fn: async ({ dirName, options: { apiKey, env } }) => {
22
+ const parsedEnv = await getVarsFromDotEnv({ dirName });
23
+
24
+ const CORVA_API_ENV = env || parsedEnv.CORVA_API_ENV || process.env.CORVA_API_ENV || 'production';
25
+ const AUTH_TOKEN = process.env.AUTH_TOKEN || parsedEnv.AUTH_TOKEN;
26
+ const API_KEY = apiKey || process.env.API_KEY || parsedEnv.API_KEY;
27
+
28
+ if (!AUTH_TOKEN && !API_KEY) {
29
+ throw new StepError(RELEASE.getAuthTokenError);
30
+ }
31
+
32
+ const api = new Api(CORVA_API_ENV, API_KEY, AUTH_TOKEN);
33
+ const notification = new Notification(CORVA_API_ENV);
34
+
35
+ return {
36
+ CORVA_API_ENV,
37
+ api,
38
+ notification,
39
+ };
40
+ },
41
+ };
@@ -0,0 +1,12 @@
1
+ export const RELEASE_PREPARE_DATA_STEP = {
2
+ message: 'Preparing data...',
3
+ async fn({ api, manifest, options }) {
4
+ const appKey = options.appKey || manifest.manifest.application.key;
5
+ const app = await api.getAppByKey(appKey);
6
+
7
+ return {
8
+ appId: app.id,
9
+ appKey,
10
+ };
11
+ },
12
+ };
@@ -0,0 +1,11 @@
1
+ export const PUBLISH_PACKAGE_STEP = {
2
+ message: 'Publishing app...',
3
+ /**
4
+ *
5
+ * @param {object} param0
6
+ * @param {import('../../lib/api').Api} param0.api
7
+ */
8
+ async fn({ api, appId, packageId }) {
9
+ await api.publishApp(appId, packageId);
10
+ },
11
+ };
@@ -0,0 +1,21 @@
1
+ import { resolve } from 'node:path';
2
+ import { unlink } from 'node:fs/promises';
3
+ import { StepError } from '../../lib/step-error.js';
4
+
5
+ export const REMOVE_FAILED_UPLOAD_STEP = {
6
+ message: 'Cleaning up...',
7
+ async fn({ api, appId, packageId, removeOnFail, uploadStatus, dirName, zipFileName, removeOnSuccess }) {
8
+ if (uploadStatus === 'draft') {
9
+ removeOnSuccess && (await unlink(resolve(dirName, zipFileName)));
10
+
11
+ return;
12
+ }
13
+
14
+ if (removeOnFail) {
15
+ await unlink(resolve(dirName, zipFileName));
16
+ await api.deleteAppUpload(appId, packageId);
17
+ }
18
+
19
+ throw new StepError(`Got unexpected status '${uploadStatus}' while processing package ${packageId}.`);
20
+ },
21
+ };
@@ -0,0 +1,62 @@
1
+ import FormData from 'form-data';
2
+ import chalk from 'chalk';
3
+ import { createReadStream } from 'node:fs';
4
+ import { resolve } from 'node:path';
5
+ import { RELEASE } from '../../../constants/messages.js';
6
+ import { StepError } from '../../lib/step-error.js';
7
+ import { logger } from '../../../helpers/logger.js';
8
+
9
+ async function deleteAppPackage({ api, appId, appPkgVersion }) {
10
+ const appPackages = await api.getAppPackages(appId);
11
+ const packageToDelete = appPackages.find(
12
+ (appPackage) => appPackage.attributes.package_code_version === appPkgVersion,
13
+ );
14
+
15
+ if (!packageToDelete) {
16
+ throw new StepError('No matching version while trying to remove the existing package, unrecoverable error');
17
+ }
18
+
19
+ try {
20
+ await api.deleteAppUpload(appId, packageToDelete?.id);
21
+ } catch (error) {
22
+ throw new StepError('Failed to remove the package, probably can retry');
23
+ }
24
+ }
25
+
26
+ export const UPLOAD_ZIP_TO_CORVA_STEP = {
27
+ message: RELEASE.uploadApp,
28
+ /**
29
+ *
30
+ * @param {object} param0
31
+ * @param {import('../../lib/api').Api} param0.api
32
+ */
33
+ fn: async ({ zipFileName, api, appId, appKey, dirName, options, pkg }) => {
34
+ async function uploadAppPackage() {
35
+ const form = new FormData();
36
+
37
+ form.append('package', createReadStream(resolve(dirName, zipFileName)), 'package.zip');
38
+
39
+ const { id: packageId, isDeletedDueToLimit } = await api.uploadPackages(appKey, form);
40
+
41
+ if (isDeletedDueToLimit) {
42
+ logger.write(
43
+ `\n${chalk.yellow`NOTE`}: Version number limit reached. The oldest version without label was deleted.`,
44
+ );
45
+ }
46
+
47
+ return { packageId };
48
+ }
49
+
50
+ try {
51
+ return await uploadAppPackage();
52
+ } catch (error) {
53
+ if (error?.message?.includes('Package code version has already been taken') && options.removeExisting) {
54
+ await deleteAppPackage({ api, appPkgVersion: pkg.version, appId });
55
+
56
+ return uploadAppPackage();
57
+ }
58
+
59
+ throw error;
60
+ }
61
+ },
62
+ };
@@ -0,0 +1,36 @@
1
+ import debugFn from 'debug';
2
+ import { waitForMs } from '../../lib/waitForMs.js';
3
+ import { logger } from '../../../helpers/logger.js';
4
+
5
+ const debug = debugFn('cca:flow:release:step:wait-for-build');
6
+
7
+ const PROCESSING_STATUSES = ['pending', 'processing', 'queued', 'deploying'];
8
+
9
+ export const WAIT_FOR_BUILD_FINISH_STEP = {
10
+ message: 'Wait till the app will process to draft status...',
11
+ /**
12
+ * @param {object} param0
13
+ * @param {import('../../lib/api').Api} param0.api
14
+ */
15
+ async fn({ api, appId, packageId, progress }) {
16
+ do {
17
+ const { status, notes } = await api.checkApp(appId, packageId);
18
+
19
+ progress();
20
+
21
+ debug(`Status: ${status}`);
22
+
23
+ if (!PROCESSING_STATUSES.includes(status)) {
24
+ if (notes) {
25
+ logger.write('\nNotes after package upload:\n\n');
26
+ logger.write(notes);
27
+ }
28
+
29
+ return { uploadStatus: status };
30
+ }
31
+
32
+ await waitForMs(5000);
33
+ // eslint-disable-next-line no-constant-condition
34
+ } while (true);
35
+ },
36
+ };
@@ -0,0 +1,77 @@
1
+ import chalk from 'chalk';
2
+
3
+ import { logger } from '../../../helpers/logger.js';
4
+
5
+ export const CREATE_TASK_STEP = {
6
+ message: 'Creating tasks...',
7
+ /**
8
+ *
9
+ * @param {object} param0
10
+ * @param {import('../../lib/api').Api} param0.api
11
+ */
12
+ fn: async ({
13
+ app,
14
+ assets,
15
+ appDatasetsNames,
16
+ mappedAssetsToStreams,
17
+ mappedAssetsToWells,
18
+ api,
19
+ version,
20
+ interval,
21
+ corvaUrl,
22
+ options,
23
+ }) => {
24
+ const { cache } = options;
25
+
26
+ if (!assets.length) {
27
+ logger.write(`\n\n${chalk.yellow.bold('There is no asset ID to create a new task')}`);
28
+ }
29
+
30
+ logger.write(`\n ${corvaUrl}/dev-center/apps/${app.id}/runner`);
31
+
32
+ let i = 1;
33
+
34
+ for (const assetId of assets) {
35
+ const wellId = mappedAssetsToWells.get(parseInt(assetId)).id;
36
+ const stream = mappedAssetsToStreams.get(parseInt(assetId));
37
+ const streamId = stream.id;
38
+ const connectedApps = stream.app_connections.filter((connectedApp) => connectedApp.app_id === Number(app.id));
39
+
40
+ if (!wellId || !streamId) {
41
+ logger.write(
42
+ `\n\n${chalk.red.underline.bold(
43
+ `Skipped creating a task for asset ID - ${assetId}, well ID or stream ID is missing`,
44
+ )}\n\n`,
45
+ );
46
+
47
+ continue;
48
+ }
49
+
50
+ try {
51
+ for (const connectedApp of connectedApps) {
52
+ const extraNotification = connectedApps.length > 1 ? `(connected app ID ${connectedApp.id})` : '';
53
+ const result = await api
54
+ .queueAppRun(app.id, version, interval, wellId, appDatasetsNames, stream.id, connectedApp.id, cache)
55
+ .catch((e) => {
56
+ console.log(e.response.body);
57
+
58
+ throw e;
59
+ });
60
+
61
+ logger.write(`
62
+ \n${i}/${assets.length}. Re-run ID ${chalk.yellow(
63
+ result.id,
64
+ )} for the asset - ${corvaUrl}/assets/${assetId} ${extraNotification}`);
65
+ }
66
+
67
+ i++;
68
+ } catch (e) {
69
+ logger.write(
70
+ `\n\n${chalk.red.underline.bold(
71
+ `Could not rerun app for asset ID - ${assetId}, an error occurred: ${e.message}`,
72
+ )}\n\n`,
73
+ );
74
+ }
75
+ }
76
+ },
77
+ };
@@ -0,0 +1,68 @@
1
+ import chalk from 'chalk';
2
+
3
+ import { logger } from '../../../helpers/logger.js';
4
+
5
+ export const ENSURE_APP_IN_STREAM_TASK_STEP = {
6
+ message: 'Ensure that app in the stream...',
7
+ /**
8
+ *
9
+ * @param {object} context
10
+ */
11
+ fn: async (context) => {
12
+ const { mappedAssetsToStreams, app, api, manifest, corvaUrl } = context;
13
+
14
+ await Promise.all(
15
+ [...mappedAssetsToStreams].map(([assetId, stream]) => {
16
+ return ensureAppIsInTheStream(assetId, stream, app.id, api, manifest, corvaUrl);
17
+ }),
18
+ );
19
+
20
+ return context;
21
+ },
22
+ };
23
+
24
+ /**
25
+ * Ensure if the app is in the stream, if no, add app to the stream
26
+ *
27
+ * @param {string} assetId
28
+ * @param {object} stream
29
+ * @param {string} appId
30
+ * @param {import('../lib/api').Api} api
31
+ * @param {object} manifest
32
+ * @param {string} corvaUrl
33
+ *
34
+ * @returns {void}
35
+ */
36
+ const ensureAppIsInTheStream = async (assetId, stream, appId, api, manifest, corvaUrl) => {
37
+ const connectedApps = stream.app_connections.filter((connection) => connection.app_id === parseInt(appId));
38
+
39
+ if (connectedApps.length) {
40
+ if (connectedApps.length > 1) {
41
+ logger.write(
42
+ `\n\n${chalk.black.underline.bold(
43
+ `Attention, this app connected to the stream more than once: ${corvaUrl}/config/streams/${stream.id}, Asset ID: ${assetId}. Logic will make a rerun per each app`,
44
+ )}`,
45
+ );
46
+
47
+ return;
48
+ }
49
+
50
+ logger.write(
51
+ `\n\n${chalk.black.underline.bold(
52
+ `App has been already connected to the stream: ${corvaUrl}/config/streams/${stream.id}, Asset ID: ${assetId}`,
53
+ )}`,
54
+ );
55
+
56
+ return;
57
+ }
58
+
59
+ const newConnection = await api.connectAppToStream(appId, stream.id, manifest.manifest.settings.app);
60
+
61
+ stream.app_connections.push(newConnection);
62
+
63
+ logger.write(
64
+ `\n\n${chalk.black.underline.bold(
65
+ `Added app to the stream: ${corvaUrl}/config/streams/${stream.id} App: ${corvaUrl}/config/streams/${stream.id}/apps/${newConnection.id}, Asset ID: ${assetId}`,
66
+ )}`,
67
+ );
68
+ };