@corva/create-app 0.0.0-2576df8

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 (204) hide show
  1. package/README.md +218 -0
  2. package/bin/cca.js +5 -0
  3. package/bin/create-corva-app.cjs +25 -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 +58 -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 +35 -0
  20. package/lib/constants/manifest.js +263 -0
  21. package/lib/constants/messages.js +15 -0
  22. package/lib/constants/package.js +288 -0
  23. package/lib/flow.js +53 -0
  24. package/lib/flows/attach.js +8 -0
  25. package/lib/flows/lib/api.js +385 -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 +136 -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 +266 -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 +150 -0
  62. package/lib/helpers/commands.js +13 -0
  63. package/lib/helpers/logger.js +35 -0
  64. package/lib/helpers/manifest.js +82 -0
  65. package/lib/helpers/resolve-app-runtime.js +132 -0
  66. package/lib/helpers/utils.js +97 -0
  67. package/lib/helpers/versioning.js +94 -0
  68. package/lib/main.js +64 -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 +1 -0
  78. package/template_extensions/corva/.commitlintrc.json +6 -0
  79. package/template_extensions/corva/.eslintrc +32 -0
  80. package/template_extensions/corva/.github/pull_request_template.md +14 -0
  81. package/template_extensions/corva/.github/workflows/code-checks.yml +15 -0
  82. package/template_extensions/corva/.github/workflows/develop.yml +19 -0
  83. package/template_extensions/corva/.github/workflows/feat-fix-delete.yml +14 -0
  84. package/template_extensions/corva/.github/workflows/feat-fix.yml +23 -0
  85. package/template_extensions/corva/.github/workflows/release-fix-X.X.X.yml +16 -0
  86. package/template_extensions/corva/.github/workflows/validate-pr-title.yml +19 -0
  87. package/template_extensions/corva/.husky/commit-msg +5 -0
  88. package/template_extensions/corva/.husky/pre-commit +4 -0
  89. package/template_extensions/corva/.release-please-manifest.json +3 -0
  90. package/template_extensions/corva/release-please-config.json +10 -0
  91. package/templates/scheduler_data-time/javascript/README.md +19 -0
  92. package/templates/scheduler_data-time/javascript/__tests__/processor.spec.js +15 -0
  93. package/templates/scheduler_data-time/javascript/index.js +15 -0
  94. package/templates/scheduler_data-time/python/README.md +31 -0
  95. package/templates/scheduler_data-time/python/lambda_function.py +7 -0
  96. package/templates/scheduler_data-time/python/test/__init__.py +0 -0
  97. package/templates/scheduler_data-time/python/test/app_test.py +10 -0
  98. package/templates/scheduler_data-time/typescript/README.md +25 -0
  99. package/templates/scheduler_data-time/typescript/__tests__/processor.spec.ts +15 -0
  100. package/templates/scheduler_data-time/typescript/index.ts +8 -0
  101. package/templates/scheduler_depth/javascript/README.md +19 -0
  102. package/templates/scheduler_depth/javascript/__tests__/processor.spec.js +17 -0
  103. package/templates/scheduler_depth/javascript/index.js +15 -0
  104. package/templates/scheduler_depth/python/README.md +31 -0
  105. package/templates/scheduler_depth/python/lambda_function.py +7 -0
  106. package/templates/scheduler_depth/python/test/__init__.py +0 -0
  107. package/templates/scheduler_depth/python/test/app_test.py +10 -0
  108. package/templates/scheduler_depth/typescript/README.md +25 -0
  109. package/templates/scheduler_depth/typescript/__tests__/processor.spec.ts +17 -0
  110. package/templates/scheduler_depth/typescript/index.ts +8 -0
  111. package/templates/scheduler_natural-time/javascript/README.md +19 -0
  112. package/templates/scheduler_natural-time/javascript/__tests__/processor.spec.js +15 -0
  113. package/templates/scheduler_natural-time/javascript/index.js +15 -0
  114. package/templates/scheduler_natural-time/python/README.md +31 -0
  115. package/templates/scheduler_natural-time/python/lambda_function.py +7 -0
  116. package/templates/scheduler_natural-time/python/test/__init__.py +0 -0
  117. package/templates/scheduler_natural-time/python/test/app_test.py +10 -0
  118. package/templates/scheduler_natural-time/typescript/README.md +25 -0
  119. package/templates/scheduler_natural-time/typescript/__tests__/processor.spec.ts +15 -0
  120. package/templates/scheduler_natural-time/typescript/index.ts +8 -0
  121. package/templates/stream_depth/javascript/README.md +19 -0
  122. package/templates/stream_depth/javascript/__tests__/processor.spec.js +20 -0
  123. package/templates/stream_depth/javascript/index.js +14 -0
  124. package/templates/stream_depth/python/README.md +31 -0
  125. package/templates/stream_depth/python/lambda_function.py +7 -0
  126. package/templates/stream_depth/python/test/__init__.py +0 -0
  127. package/templates/stream_depth/python/test/app_test.py +16 -0
  128. package/templates/stream_depth/typescript/README.md +25 -0
  129. package/templates/stream_depth/typescript/__tests__/processor.spec.ts +20 -0
  130. package/templates/stream_depth/typescript/index.ts +8 -0
  131. package/templates/stream_time/javascript/README.md +19 -0
  132. package/templates/stream_time/javascript/__tests__/processor.spec.js +14 -0
  133. package/templates/stream_time/javascript/index.js +14 -0
  134. package/templates/stream_time/python/README.md +31 -0
  135. package/templates/stream_time/python/lambda_function.py +7 -0
  136. package/templates/stream_time/python/test/__init__.py +0 -0
  137. package/templates/stream_time/python/test/app_test.py +16 -0
  138. package/templates/stream_time/typescript/README.md +25 -0
  139. package/templates/stream_time/typescript/__tests__/processor.spec.ts +14 -0
  140. package/templates/stream_time/typescript/index.ts +8 -0
  141. package/templates/task/javascript/README.md +19 -0
  142. package/templates/task/javascript/__tests__/processor.spec.js +16 -0
  143. package/templates/task/javascript/index.js +15 -0
  144. package/templates/task/python/README.md +31 -0
  145. package/templates/task/python/lambda_function.py +7 -0
  146. package/templates/task/python/test/__init__.py +0 -0
  147. package/templates/task/python/test/app_test.py +8 -0
  148. package/templates/task/typescript/README.md +25 -0
  149. package/templates/task/typescript/__tests__/processor.spec.ts +16 -0
  150. package/templates/task/typescript/index.ts +8 -0
  151. package/templates/ui/javascript/.codex/config.toml +3 -0
  152. package/templates/ui/javascript/.cursor/mcp.json +8 -0
  153. package/templates/ui/javascript/.eslintrc +11 -0
  154. package/templates/ui/javascript/.mcp.json +8 -0
  155. package/templates/ui/javascript/.prettierrc +1 -0
  156. package/templates/ui/javascript/AGENTS.md +304 -0
  157. package/templates/ui/javascript/CLAUDE.md +1 -0
  158. package/templates/ui/javascript/README.md +31 -0
  159. package/templates/ui/javascript/config/jest/babelTransform.js +16 -0
  160. package/templates/ui/javascript/config/jest/cssTransform.js +16 -0
  161. package/templates/ui/javascript/config/jest/fileTransform.js +48 -0
  162. package/templates/ui/javascript/config/jest/globalSetup.js +5 -0
  163. package/templates/ui/javascript/config/jest/setupTests.js +30 -0
  164. package/templates/ui/javascript/config-overrides.js +10 -0
  165. package/templates/ui/javascript/gitignore +27 -0
  166. package/templates/ui/javascript/src/App.completion.js +52 -0
  167. package/templates/ui/javascript/src/App.drilling.js +49 -0
  168. package/templates/ui/javascript/src/App.scss +17 -0
  169. package/templates/ui/javascript/src/AppSettings.js +28 -0
  170. package/templates/ui/javascript/src/__tests__/App.test.js +26 -0
  171. package/templates/ui/javascript/src/__tests__/AppSettings.test.js +28 -0
  172. package/templates/ui/javascript/src/__tests__/TestsExample.test.js +37 -0
  173. package/templates/ui/javascript/src/assets/logo.svg +7 -0
  174. package/templates/ui/javascript/src/constants.js +3 -0
  175. package/templates/ui/javascript/src/index.js +8 -0
  176. package/templates/ui/typescript/.codex/config.toml +3 -0
  177. package/templates/ui/typescript/.cursor/mcp.json +8 -0
  178. package/templates/ui/typescript/.eslintrc +28 -0
  179. package/templates/ui/typescript/.mcp.json +8 -0
  180. package/templates/ui/typescript/.prettierrc +1 -0
  181. package/templates/ui/typescript/AGENTS.md +344 -0
  182. package/templates/ui/typescript/CLAUDE.md +1 -0
  183. package/templates/ui/typescript/README.md +31 -0
  184. package/templates/ui/typescript/config/jest/babelTransform.js +16 -0
  185. package/templates/ui/typescript/config/jest/cssTransform.js +16 -0
  186. package/templates/ui/typescript/config/jest/fileTransform.js +48 -0
  187. package/templates/ui/typescript/config/jest/globalSetup.js +5 -0
  188. package/templates/ui/typescript/config/jest/setupTests.js +30 -0
  189. package/templates/ui/typescript/config-overrides.js +10 -0
  190. package/templates/ui/typescript/gitignore +27 -0
  191. package/templates/ui/typescript/src/App.completion.tsx +52 -0
  192. package/templates/ui/typescript/src/App.drilling.tsx +49 -0
  193. package/templates/ui/typescript/src/App.scss +17 -0
  194. package/templates/ui/typescript/src/AppSettings.tsx +28 -0
  195. package/templates/ui/typescript/src/__mocks__/mockData.ts +22 -0
  196. package/templates/ui/typescript/src/__tests__/App.test.tsx +27 -0
  197. package/templates/ui/typescript/src/__tests__/AppSettings.test.tsx +28 -0
  198. package/templates/ui/typescript/src/__tests__/TestsExample.test.tsx +37 -0
  199. package/templates/ui/typescript/src/assets/logo.svg +7 -0
  200. package/templates/ui/typescript/src/constants.ts +3 -0
  201. package/templates/ui/typescript/src/custom.d.ts +19 -0
  202. package/templates/ui/typescript/src/index.js +8 -0
  203. package/templates/ui/typescript/src/types.ts +3 -0
  204. package/templates/ui/typescript/tsconfig.json +7 -0
@@ -0,0 +1,132 @@
1
+ import debugFn from 'debug';
2
+ import { APP_TYPES } from '../constants/cli.js';
3
+ import spawn from 'cross-spawn';
4
+ import { promises as fs } from 'fs';
5
+ import os from 'os';
6
+ import semver from 'semver';
7
+
8
+ const debug = debugFn('cca:resolve-app-runtime');
9
+
10
+ /**
11
+ *
12
+ * @param {string} command
13
+ * @param {string} version
14
+ * @returns {Promise<boolean>}
15
+ */
16
+ const checkCliVersion = async (command, version) =>
17
+ new Promise((resolve) => {
18
+ const child = spawn(command, ['--version']);
19
+
20
+ let data = '';
21
+
22
+ child.stderr.on('data', (buffer) => {
23
+ data += buffer;
24
+ });
25
+
26
+ child.stdout.on('data', (buffer) => {
27
+ data += buffer;
28
+ });
29
+
30
+ child.once('close', (code) => {
31
+ if (code !== 0) {
32
+ debug(`Command ${command} exited with code ${code}`);
33
+ debug('Output:', data.toString());
34
+
35
+ return resolve(false);
36
+ }
37
+
38
+ debug(`%s version output: %s`, command, data.toString());
39
+
40
+ resolve(semver.satisfies(semver.coerce(data.toString('utf-8')), version));
41
+ });
42
+ });
43
+
44
+ const checkNodeVersion = (version) => async () => {
45
+ try {
46
+ await fs.access(`${os.homedir()}/.nvm/nvm.sh`);
47
+
48
+ debug('nvm is installed');
49
+
50
+ return true;
51
+ } catch (e) {
52
+ debug(e);
53
+ debug('nvm is not installed, checking node version');
54
+
55
+ return checkCliVersion('node', version);
56
+ }
57
+ };
58
+
59
+ export const IS_WINDOWS = process.platform === 'win32';
60
+
61
+ const semverVersionsMapping = {
62
+ node: {
63
+ 18: '18.14.0',
64
+ 20: '20.16.0',
65
+ 24: '24.14.0',
66
+ },
67
+ python: {
68
+ '3.8': '3.8.16',
69
+ '3.9': '3.9.16',
70
+ '3.10': '3.10.9',
71
+ '3.11': '3.11.1',
72
+ '3.13': '3.13.7',
73
+ },
74
+ };
75
+
76
+ /**
77
+ * @typedef {Object} Runtime
78
+ * @property {string} language
79
+ * @property {boolean} isRuntimeAvailable
80
+ * @property {string} packageManager
81
+ * @property {string} version
82
+ * @property {string} semver
83
+ */
84
+ export const resolveAppRuntime = (opts) => {
85
+ if (opts.appType === APP_TYPES.UI) {
86
+ const version = '20';
87
+
88
+ return {
89
+ environment: 'node',
90
+ language: opts.useTypescript ? 'typescript' : 'javascript',
91
+ isRuntimeAvailable: checkNodeVersion(version),
92
+ packageManager: opts.packageManager,
93
+ version,
94
+ semver: semverVersionsMapping.node[version],
95
+ };
96
+ }
97
+
98
+ if (opts.runtime.startsWith('node')) {
99
+ const version = /nodejs(\d{2})\.x/.exec(opts.runtime)[1];
100
+
101
+ return {
102
+ environment: 'node',
103
+ language: opts.useTypescript ? 'typescript' : 'javascript',
104
+ isRuntimeAvailable: checkNodeVersion(version),
105
+ packageManager: opts.packageManager,
106
+ version,
107
+ semver: semverVersionsMapping.node[version],
108
+ };
109
+ }
110
+
111
+ const version = /python(\d\.\d+)/.exec(opts.runtime)[1];
112
+
113
+ return {
114
+ environment: 'python',
115
+ language: 'python',
116
+ isRuntimeAvailable: async () => {
117
+ if (!IS_WINDOWS) {
118
+ return checkCliVersion(`python3`, version);
119
+ }
120
+
121
+ return (
122
+ (await checkCliVersion(`py -${version}`, version)) ||
123
+ (await checkCliVersion('python', version)) ||
124
+ (await checkCliVersion('python3', version))
125
+ );
126
+ },
127
+
128
+ packageManager: 'pip',
129
+ version,
130
+ semver: semverVersionsMapping.python[version],
131
+ };
132
+ };
@@ -0,0 +1,97 @@
1
+ import path, { join } from 'node:path';
2
+ import fs from 'fs-extra';
3
+ import chalk from 'chalk';
4
+ import { logger } from './logger.js';
5
+
6
+ export const addUiAppFile = (templateFolder, root, runtime, manifest, opts) => {
7
+ try {
8
+ logger.log(chalk.green('adding app file'));
9
+
10
+ const fileExtension = runtime.language === 'typescript' ? 'tsx' : 'js';
11
+
12
+ const segment =
13
+ {
14
+ drilling: 'drilling',
15
+ completion: 'completion',
16
+ intervention: 'drilling', // same as drilling for now
17
+ }[opts.segments] || 'drilling';
18
+ const appFilePath = join(templateFolder, 'src', `App.${segment}.${fileExtension}`);
19
+
20
+ copyFileSync(appFilePath, join(root, 'src', `App.${fileExtension}`));
21
+ logger.log(chalk.green('Done: adding app file!'));
22
+ } catch (e) {
23
+ logger.log(chalk.red('Error: adding app file!'));
24
+ logger.log(e);
25
+ }
26
+ };
27
+
28
+ export const getExcludedFiles = (manifest) => {
29
+ if (manifest.isUi()) return ['App.drilling.js', 'App.completion.js', 'App.drilling.tsx', 'App.completion.tsx'];
30
+
31
+ return [];
32
+ };
33
+
34
+ export function copyFileSync(source, target) {
35
+ let targetFile = target;
36
+
37
+ // if target is a directory a new file with the same name will be created
38
+ if (fs.existsSync(target)) {
39
+ if (fs.lstatSync(target).isDirectory()) {
40
+ targetFile = path.join(target, path.basename(source));
41
+ }
42
+ }
43
+
44
+ fs.writeFileSync(targetFile, fs.readFileSync(source));
45
+
46
+ const targetMode = fs.lstatSync(source).mode;
47
+
48
+ fs.chmodSync(targetFile, targetMode);
49
+ }
50
+
51
+ export function copyFolderRecursiveSync(sourceFolder, targetFolder, excludeFiles = []) {
52
+ // check if folder needs to be created or integrated
53
+ if (!fs.existsSync(targetFolder)) {
54
+ fs.mkdirSync(targetFolder);
55
+ }
56
+
57
+ if (!fs.lstatSync(sourceFolder).isDirectory()) {
58
+ return;
59
+ }
60
+
61
+ // copy
62
+ const items = fs.readdirSync(sourceFolder);
63
+
64
+ for (const item of items) {
65
+ if (excludeFiles.includes(item)) continue; // Skip the files in the exclude list
66
+
67
+ const curSource = path.join(sourceFolder, item);
68
+
69
+ if (fs.lstatSync(curSource).isDirectory()) {
70
+ copyFolderRecursiveSync(curSource, path.join(targetFolder, item), excludeFiles);
71
+
72
+ continue;
73
+ }
74
+
75
+ copyFileSync(curSource, targetFolder);
76
+ }
77
+ }
78
+
79
+ /**
80
+ *
81
+ * @param {string} root
82
+ * @param {import('../flows/lib/manifest').Manifest} manifest
83
+ */
84
+ export const putVariablesInEnvFile = async (root, manifest) => {
85
+ const pathToEnvFile = join(root, '.env');
86
+ const envFileContent = await fs.readFile(pathToEnvFile, 'utf8');
87
+
88
+ await fs.writeFile(
89
+ pathToEnvFile,
90
+ envFileContent
91
+ .replace(new RegExp('\\${APP_KEY}', 'g'), manifest.manifest.application.key)
92
+ .replace(new RegExp('\\${PROVIDER}', 'g'), manifest.manifest.application.key.split('.')[0])
93
+ .replace(new RegExp('\\${APP_NAME}', 'g'), manifest.manifest.application.name),
94
+ );
95
+ };
96
+
97
+ export const generateRandomString = () => Math.floor(Math.random() * Date.now()).toString(36);
@@ -0,0 +1,94 @@
1
+ import debugFn from 'debug';
2
+ import { execSync } from 'node:child_process';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { logger } from './logger.js';
6
+
7
+ const debug = debugFn('cca:versioning');
8
+
9
+ /**
10
+ *
11
+ * @param {string} root
12
+ */
13
+ export async function initVersioning(root) {
14
+ logger.log();
15
+
16
+ if (!tryGitInit(root)) {
17
+ logger.log('Already in a git repository. Skipping git initialization.');
18
+
19
+ return;
20
+ }
21
+
22
+ if (tryGitCommit(root)) {
23
+ logger.log();
24
+ logger.log('Created git commit');
25
+ }
26
+ }
27
+
28
+ export function isInGitRepository(appPath) {
29
+ try {
30
+ execSync('git rev-parse --is-inside-work-tree', {
31
+ stdio: 'ignore',
32
+ cwd: appPath,
33
+ });
34
+
35
+ return true;
36
+ } catch (e) {
37
+ debug(e);
38
+
39
+ return false;
40
+ }
41
+ }
42
+
43
+ export function tryGitInit(appPath) {
44
+ try {
45
+ if (isInGitRepository(appPath)) {
46
+ debug('is in git repository');
47
+
48
+ return false;
49
+ }
50
+
51
+ execSync('git --version', { stdio: 'ignore', cwd: appPath });
52
+
53
+ execSync('git init', { stdio: 'ignore', cwd: appPath });
54
+ logger.log('Initialized git repo in app');
55
+
56
+ return true;
57
+ } catch (e) {
58
+ debug(e);
59
+ console.warn('Git repo not initialized');
60
+
61
+ return false;
62
+ }
63
+ }
64
+
65
+ export function tryGitCommit(appPath) {
66
+ try {
67
+ execSync('git add -A', { stdio: 'ignore', cwd: appPath });
68
+ execSync('git commit -m "chore: initialize project using @corva/create-app" -n', {
69
+ stdio: 'ignore',
70
+ cwd: appPath,
71
+ });
72
+
73
+ return true;
74
+ } catch (e) {
75
+ // We couldn't commit in already initialized git repo,
76
+ // maybe the commit author config is not set.
77
+ // In the future, we might supply our own committer
78
+ // like Ember CLI does, but for now, let's just
79
+ // remove the Git files to avoid a half-done state.
80
+ debug(e);
81
+ console.warn('Git commit not created');
82
+ console.warn('Removing .git directory...');
83
+
84
+ try {
85
+ // unlinkSync() doesn't work on directories.
86
+ fs.removeSync(path.join(appPath, '.git'));
87
+ } catch (removeErr) {
88
+ debug(removeErr);
89
+ // Ignore.
90
+ }
91
+
92
+ return false;
93
+ }
94
+ }
package/lib/main.js ADDED
@@ -0,0 +1,64 @@
1
+ import chalk from 'chalk';
2
+ import { Command } from 'commander';
3
+ import semver from 'semver';
4
+
5
+ import { warnIfOutdated } from './helpers/cli-version.js';
6
+ import { logger } from './helpers/logger.js';
7
+
8
+ import { zipCommand } from './commands/zip.js';
9
+ import { releaseCommand } from './commands/release.js';
10
+ import { rerunCommand } from './commands/rerun.js';
11
+ import { attachCommand } from './commands/attach.js';
12
+ import { createCommand } from './commands/create.js';
13
+
14
+ import { ERROR_ICON } from './constants/messages.js';
15
+ import { StepError } from './flows/lib/step-error.js';
16
+
17
+ function checkNodeVersion() {
18
+ logger.write('Checking node version...');
19
+
20
+ const unsupportedNodeVersion = !semver.satisfies(process.version, '>=16');
21
+
22
+ if (unsupportedNodeVersion) {
23
+ logger.log(
24
+ chalk.red(
25
+ `\nYou are using Node ${process.version}.\n\n` +
26
+ `Please update to Node 16 or higher for a better, fully supported experience.\n`,
27
+ ),
28
+ );
29
+
30
+ // Fall back to latest supported react-scripts on Node 4
31
+ return process.exit(1);
32
+ }
33
+
34
+ logger.write(' ✅ \n');
35
+ }
36
+
37
+ export async function run() {
38
+ const program = new Command('create-corva-app')
39
+ .hook('preAction', async () => {
40
+ checkNodeVersion();
41
+
42
+ await warnIfOutdated();
43
+ })
44
+ .addCommand(createCommand, { isDefault: true })
45
+ .addCommand(zipCommand)
46
+ .addCommand(releaseCommand)
47
+ .addCommand(rerunCommand)
48
+ .addCommand(attachCommand)
49
+ .showHelpAfterError()
50
+ .showSuggestionAfterError(true);
51
+
52
+ try {
53
+ await program.parseAsync(process.argv);
54
+ } catch (e) {
55
+ if (e instanceof StepError) {
56
+ console.error(chalk.red(`${ERROR_ICON} ${e.message}`));
57
+ } else {
58
+ console.error(chalk.red(`${ERROR_ICON} Unknown error occured, please contact support`));
59
+ console.error(e);
60
+ }
61
+
62
+ process.exit(1);
63
+ }
64
+ }
@@ -0,0 +1,6 @@
1
+ import { Option } from 'commander';
2
+
3
+ export const apiKeyOption = new Option(
4
+ '--api-key [string]',
5
+ 'Pre generated API key for authorization during app upload',
6
+ );
@@ -0,0 +1,6 @@
1
+ import { Option } from 'commander';
2
+
3
+ export const appKeyOption = new Option(
4
+ '--app-key [string]',
5
+ 'Explicitely set appKey. Otherwise it will be taked from the manifest.json',
6
+ );
@@ -0,0 +1,3 @@
1
+ import { Option } from 'commander';
2
+
3
+ export const appVersion = new Option('--app-version [number]', 'App version (exp. 1, 2, 3)');
@@ -0,0 +1,19 @@
1
+ import { InvalidArgumentError, Option } from 'commander';
2
+ import semver from 'semver';
3
+
4
+ const flags = '--bump-version <string>';
5
+ const description = 'Bump version';
6
+ const choices = ['major', 'minor', 'patch', 'skip'];
7
+
8
+ function argParser(value, previous) {
9
+ // eslint-disable-next-line no-invalid-this
10
+ if (this.argChoices.includes(value) || semver.valid(value)) {
11
+ return value;
12
+ }
13
+
14
+ throw new InvalidArgumentError(
15
+ // eslint-disable-next-line no-invalid-this
16
+ `Allowed choices are ${this.argChoices.map((choice) => `"${choice}"`).join(', ')} or a valid semver version.`,
17
+ );
18
+ }
19
+ export const bumpVersionOption = new Option(flags, description).choices(choices).argParser(argParser);
@@ -0,0 +1,11 @@
1
+ import { Option } from 'commander';
2
+ import fs from 'fs';
3
+
4
+ const parseJSON = (filename) => {
5
+ const path = `${process.cwd()}/${filename}`;
6
+ const value = JSON.parse(fs.readFileSync(path, 'utf8'));
7
+
8
+ return value;
9
+ };
10
+
11
+ export const cacheOption = new Option('--cache [filename]', 'cache object for rerunning app').argParser(parseJSON);
@@ -0,0 +1,3 @@
1
+ import { Option } from 'commander';
2
+
3
+ export const envOption = new Option('--env [string]', 'Environment to use').choices(['qa', 'staging', 'production']);
@@ -0,0 +1,3 @@
1
+ import { Option } from 'commander';
2
+
3
+ export const originalCwdOption = new Option('--original-cwd <string>').hideHelp();
@@ -0,0 +1,3 @@
1
+ import { Option } from 'commander';
2
+
3
+ export const silentOption = new Option('--silent [boolean]', 'Only log result of the operation').default(false);
package/package.json ADDED
@@ -0,0 +1 @@
1
+ {"name":"@corva/create-app","version":"0.0.0-2576df8","private":false,"description":"Create an app to use it in CORVA.AI","keywords":["react"],"bugs":{"url":"https://github.com/facebook/create-react-app/issues"},"repository":{"type":"git","url":"https://github.com/corva-ai/create-corva-app","directory":"@corva/create-app"},"license":"MIT","type":"module","bin":{"create-corva-app":"./bin/create-corva-app.cjs"},"files":["bin/**/*.cjs","bin/**/*.js","lib/**/*.js","templates","template_extensions","common"],"scripts":{"build":"echo \"build is not configured for package \\\"×\\\", skipping.\"","get-changelog":"conventional-changelog -r 2 -p angular","lint":"eslint . --resolve-plugins-relative-to $(pwd) --max-warnings 0","lint:fix":"eslint . --fix","release":"git add -A && standard-version -a","release-rc":"npm run release -- --prerelease","run:local-ui-ts-completion":"node ./bin/create-corva-app.cjs ../test-app-ui-ts-completions --appName 'TestAppUiTsCompletions' --segments 'completion' --category 'analytics' --appKey 'corva.testappuitscompletions.ui' --appType 'ui' --runtime 'ui' -t --extensions corva","run:local-ui-ts-drilling":"node ./bin/create-corva-app.cjs ../test-app-ui-ts-drilling --appName 'TestAppUiTsDrilling' --segments 'drilling' --category 'analytics' --appKey 'corva.testappuitsdrilling.ui' --appType 'ui' --runtime 'ui' -t --extensions corva","run:local-ui-ts-intervention":"node ./bin/create-corva-app.cjs ../test-app-ui-ts-intervention --appName 'TestAppUiTsIntervention' --segments 'intervention' --category 'analytics' --appKey 'corva.testappuitsintervention.ui' --appType 'ui' --runtime 'ui' -t --extensions corva","test":"NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest"},"lint-staged":{"*.js":"npm run lint:fix"},"dependencies":{"archiver":"^5.3.0","chalk":"^4.1.0","commander":"^9.1.0","cross-spawn":"^7.0.3","debug":"^4.3.4","dotenv":"^16.0.0","figlet":"^1.5.0","form-data":"^4.0.0","fs-extra":"^9.0.1","glob":"^8.0.1","got":"^12.5.1","inquirer":"^8.2.3","is-glob":"^4.0.3","lodash":"^4.17.21","npm-api":"^1.0.0","semver":"^7.3.2","terminal-link":"^3.0.0"},"devDependencies":{"@babel/core":"^7.11.0","@babel/eslint-parser":"^7.19.1","@babel/plugin-proposal-class-properties":"^7.18.6","@babel/plugin-syntax-import-assertions":"^7.20.0","@babel/preset-react":"^7.18.6","@commitlint/cli":"^17.3.0","@commitlint/config-conventional":"^17.3.0","@corva/eslint-config-browser":"^0.1.7","@corva/eslint-config-node":"^5.1.1","@corva/node-sdk":"^8.0.1","@types/cross-spawn":"^6.0.2","@types/jest":"^29.5.4","@typescript-eslint/eslint-plugin":"^5.42.1","@typescript-eslint/parser":"^5.42.1","conventional-changelog-cli":"^2.1.0","eslint":"^8.2.0","eslint-config-google":"^0.14.0","eslint-config-prettier":"^8.5.0","eslint-plugin-import":"^2.26.0","eslint-plugin-jest":"^27.1.5","eslint-plugin-jsx-a11y":"^6.7.1","eslint-plugin-prettier":"^4.2.1","eslint-plugin-react":"^7.32.0","eslint-plugin-react-hooks":"^4.6.0","eslint-plugin-require-sort":"^1.3.0","husky":"^8.0.2","jest":"^29.6.4","prettier":"^2.0.0","prettier-plugin-packagejson":"^2.3.0","standard-version":"^9.0.0","typescript":"^4.8.4","zx":"^7.2.3"},"packageManager":"yarn@1.22.19+sha512.ff4579ab459bb25aa7c0ff75b62acebe576f6084b36aa842971cf250a5d8c6cd3bc9420b22ce63c7f93a0857bc6ef29291db39c3e7a23aab5adfd5a4dd6c5d71","engines":{"node":">=18"},"standard-version":{"skip":{"tag":true}}}
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": ["@commitlint/config-conventional"],
3
+ "rules": {
4
+ "subject-case": [0]
5
+ }
6
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "root": true,
3
+ "parser": "@typescript-eslint/parser",
4
+ "parserOptions": {
5
+ "ecmaVersion": 2020,
6
+ "sourceType": "module",
7
+ "ecmaFeature": {
8
+ "jsx": true
9
+ }
10
+ },
11
+ "extends": ["@corva/eslint-config-browser"],
12
+ "overrides": [
13
+ {
14
+ "files": ["*.ts", "*.tsx"],
15
+ "extends": [
16
+ "@corva/eslint-config-browser",
17
+ "plugin:@typescript-eslint/recommended",
18
+ "plugin:@tanstack/eslint-plugin-query/recommended"
19
+ ],
20
+ "rules": {
21
+ "@typescript-eslint/no-explicit-any": 2,
22
+ "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx", ".ts", ".tsx"] }],
23
+ /* Turned off until adopted by @corva/eslint-config-browser */
24
+ "react/prop-types": 0,
25
+ "react/default-props-match-prop-types": 0,
26
+ "react/no-unused-prop-types": 0,
27
+ "react/require-default-props": 0
28
+ /* Turned off until adopted by @corva/eslint-config-browser */
29
+ }
30
+ }
31
+ ]
32
+ }
@@ -0,0 +1,14 @@
1
+ # Description
2
+
3
+ [Optional]: a screenshot / video / text description / please check the ticket using the ticket ID
4
+
5
+ ### To be merged the changes also should be approved by:
6
+
7
+ - QA, PO ( for features / fixes / tech tickets that also require QA/PO validation )
8
+ - Designer ( when there're design changes )
9
+ - BE developer ( when there're MongoDB queries, to be sure they are optimal )
10
+
11
+ ### Checklist
12
+
13
+ - [ ] I have commented possibly difficult-to-understand places
14
+ - [ ] I have covered the new code with the tests _([Our tests guide](https://corva.notion.site/Tests-guide-520058fa52454e5aa08ef9225d7d76e9))_
@@ -0,0 +1,15 @@
1
+ name: Code Checks
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - develop
7
+
8
+ jobs:
9
+ Lint-and-Test:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - name: 'Lint and test'
13
+ uses: corva-ai/gh-actions/shared-dc-workflows/lint-and-test@develop
14
+ with:
15
+ npm-token: ${{ secrets.CORVA_NPM_TOKEN }}
@@ -0,0 +1,19 @@
1
+ name: develop branch flow
2
+ on:
3
+ push:
4
+ branches:
5
+ - 'develop'
6
+
7
+ jobs:
8
+ develop-flow:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - name: develop branch flow
12
+ id: shared-workflow
13
+ uses: corva-ai/gh-actions/shared-dc-workflows/develop@develop
14
+ env:
15
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16
+ with:
17
+ qa-api-key: ${{ secrets.API_KEY_QA }}
18
+ prod-api-key: ${{ secrets.API_KEY }}
19
+ npm-token: ${{ secrets.CORVA_NPM_TOKEN }}
@@ -0,0 +1,14 @@
1
+ name: branch deletion flow
2
+ on:
3
+ delete:
4
+
5
+ jobs:
6
+ branch-deletion-flow:
7
+ runs-on: ubuntu-latest
8
+ if: startsWith(github.event.ref, 'feat/') || startsWith(github.event.ref, 'fix/')
9
+ steps:
10
+ - name: branch deletion flow
11
+ uses: corva-ai/gh-actions/shared-dc-workflows/feat-fix-delete@develop
12
+ with:
13
+ qa-api-key: ${{ secrets.API_KEY_QA }}
14
+ prod-api-key: ${{ secrets.API_KEY }}
@@ -0,0 +1,23 @@
1
+ name: feat/fix branch flow
2
+ on:
3
+ push:
4
+ branches:
5
+ - feat/*
6
+ - fix/*
7
+
8
+ concurrency:
9
+ group: ${{ github.workflow }}-${{ github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ jobs:
13
+ feat-fix-flow:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: feat/fix flow
17
+ uses: corva-ai/gh-actions/shared-dc-workflows/feat-fix@develop
18
+ with:
19
+ qa-api-key: ${{ secrets.API_KEY_QA }}
20
+ prod-api-key: ${{ secrets.API_KEY }}
21
+ npm-token: ${{ secrets.CORVA_NPM_TOKEN }}
22
+ jira-user-email: ${{ secrets.JIRA_AUTOTEST_USERNAME }}
23
+ jira-api-token: ${{ secrets.JIRA_AUTOTEST_API_TOKEN }}
@@ -0,0 +1,16 @@
1
+ name: release-fix/X.X.X branch flow
2
+ on:
3
+ push:
4
+ branches:
5
+ - 'release-fix/[0-9]+.[0-9]+.[0-9]+'
6
+
7
+ jobs:
8
+ release-fix-flow:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - name: release-fix/X.X.X flow
12
+ uses: corva-ai/gh-actions/shared-dc-workflows/release-fix-X.X.X@develop
13
+ with:
14
+ qa-api-key: ${{ secrets.API_KEY_QA }}
15
+ prod-api-key: ${{ secrets.API_KEY }}
16
+ npm-token: ${{ secrets.CORVA_NPM_TOKEN }}
@@ -0,0 +1,19 @@
1
+ name: 'PR title matches "<type>(<scope>): <description>"'
2
+
3
+ on:
4
+ pull_request:
5
+ types:
6
+ - opened
7
+ - edited
8
+ - synchronize
9
+
10
+ concurrency:
11
+ group: ${{ github.workflow }}-${{ github.head_ref }}
12
+ cancel-in-progress: true
13
+
14
+ jobs:
15
+ validate-pr-title:
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - name: Validate PR title
19
+ uses: corva-ai/gh-actions/shared-dc-workflows/validate-pr-title@develop
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env sh
2
+ . "$(dirname -- "$0")/_/husky.sh"
3
+
4
+ echo "Validating commit message..."
5
+ ./node_modules/.bin/commitlint --edit $1
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env sh
2
+ . "$(dirname -- "$0")/_/husky.sh"
3
+
4
+ ./node_modules/.bin/lint-staged
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.0.1"
3
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "packages": {
3
+ ".": {
4
+ "release-type": "node",
5
+ "versioning": "always-bump-minor"
6
+ }
7
+ },
8
+ "always-update": true,
9
+ "include-component-in-tag": false
10
+ }