@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.
- package/README.md +218 -0
- package/bin/cca.js +5 -0
- package/bin/create-corva-app.cjs +25 -0
- package/common/node/.env +15 -0
- package/common/node/.env.sample +26 -0
- package/common/node/gitignore +130 -0
- package/common/package.json +3 -0
- package/common/python/.env +5 -0
- package/common/python/.env.sample +7 -0
- package/common/python/Makefile +15 -0
- package/common/python/gitignore +161 -0
- package/common/python/requirements.txt +2 -0
- package/lib/commands/attach.js +28 -0
- package/lib/commands/create.js +463 -0
- package/lib/commands/release.js +58 -0
- package/lib/commands/rerun.js +34 -0
- package/lib/commands/zip.js +39 -0
- package/lib/constants/cache.js +5 -0
- package/lib/constants/cli.js +35 -0
- package/lib/constants/manifest.js +263 -0
- package/lib/constants/messages.js +15 -0
- package/lib/constants/package.js +288 -0
- package/lib/flow.js +53 -0
- package/lib/flows/attach.js +8 -0
- package/lib/flows/lib/api.js +385 -0
- package/lib/flows/lib/create-zip-archive.js +83 -0
- package/lib/flows/lib/json.js +30 -0
- package/lib/flows/lib/manifest.js +81 -0
- package/lib/flows/lib/notification.js +142 -0
- package/lib/flows/lib/step-error.js +10 -0
- package/lib/flows/lib/waitForMs.js +3 -0
- package/lib/flows/prepare.js +6 -0
- package/lib/flows/release.js +26 -0
- package/lib/flows/rerun.js +8 -0
- package/lib/flows/steps/attach/add-app-to-stream.js +23 -0
- package/lib/flows/steps/attach/get-all-live-assets.js +135 -0
- package/lib/flows/steps/attach/index.js +5 -0
- package/lib/flows/steps/attach/prepare-data.js +19 -0
- package/lib/flows/steps/prepare-load-app-files.js +12 -0
- package/lib/flows/steps/release/add-label.js +10 -0
- package/lib/flows/steps/release/add-notes.js +10 -0
- package/lib/flows/steps/release/get-config.js +41 -0
- package/lib/flows/steps/release/prepare-data.js +12 -0
- package/lib/flows/steps/release/publish.js +11 -0
- package/lib/flows/steps/release/remove-failed-upload.js +21 -0
- package/lib/flows/steps/release/upload-zip-to-corva.js +136 -0
- package/lib/flows/steps/release/wait-for-build.js +36 -0
- package/lib/flows/steps/rerun/create-task.js +77 -0
- package/lib/flows/steps/rerun/ensure-that-app-in-stream.js +68 -0
- package/lib/flows/steps/rerun/get-app-version.js +111 -0
- package/lib/flows/steps/rerun/prepare-data.js +162 -0
- package/lib/flows/steps/rerun/prepare-well-and-stream-data.js +188 -0
- package/lib/flows/steps/rerun/rerun.js +13 -0
- package/lib/flows/steps/zip-cleanup.js +17 -0
- package/lib/flows/steps/zip-create-archive.js +15 -0
- package/lib/flows/steps/zip-file-list-resolve.js +266 -0
- package/lib/flows/steps/zip-prepare.js +20 -0
- package/lib/flows/steps/zip.js +6 -0
- package/lib/flows/zip-simple.js +6 -0
- package/lib/flows/zip.js +7 -0
- package/lib/helpers/cli-version.js +150 -0
- package/lib/helpers/commands.js +13 -0
- package/lib/helpers/logger.js +35 -0
- package/lib/helpers/manifest.js +82 -0
- package/lib/helpers/resolve-app-runtime.js +132 -0
- package/lib/helpers/utils.js +97 -0
- package/lib/helpers/versioning.js +94 -0
- package/lib/main.js +64 -0
- package/lib/options/api-key.js +6 -0
- package/lib/options/app-key.js +6 -0
- package/lib/options/app-version.js +3 -0
- package/lib/options/bump-version.js +19 -0
- package/lib/options/cache.js +11 -0
- package/lib/options/env.js +3 -0
- package/lib/options/original-cwd.js +3 -0
- package/lib/options/silent.js +3 -0
- package/package.json +1 -0
- package/template_extensions/corva/.commitlintrc.json +6 -0
- package/template_extensions/corva/.eslintrc +32 -0
- package/template_extensions/corva/.github/pull_request_template.md +14 -0
- package/template_extensions/corva/.github/workflows/code-checks.yml +15 -0
- package/template_extensions/corva/.github/workflows/develop.yml +19 -0
- package/template_extensions/corva/.github/workflows/feat-fix-delete.yml +14 -0
- package/template_extensions/corva/.github/workflows/feat-fix.yml +23 -0
- package/template_extensions/corva/.github/workflows/release-fix-X.X.X.yml +16 -0
- package/template_extensions/corva/.github/workflows/validate-pr-title.yml +19 -0
- package/template_extensions/corva/.husky/commit-msg +5 -0
- package/template_extensions/corva/.husky/pre-commit +4 -0
- package/template_extensions/corva/.release-please-manifest.json +3 -0
- package/template_extensions/corva/release-please-config.json +10 -0
- package/templates/scheduler_data-time/javascript/README.md +19 -0
- package/templates/scheduler_data-time/javascript/__tests__/processor.spec.js +15 -0
- package/templates/scheduler_data-time/javascript/index.js +15 -0
- package/templates/scheduler_data-time/python/README.md +31 -0
- package/templates/scheduler_data-time/python/lambda_function.py +7 -0
- package/templates/scheduler_data-time/python/test/__init__.py +0 -0
- package/templates/scheduler_data-time/python/test/app_test.py +10 -0
- package/templates/scheduler_data-time/typescript/README.md +25 -0
- package/templates/scheduler_data-time/typescript/__tests__/processor.spec.ts +15 -0
- package/templates/scheduler_data-time/typescript/index.ts +8 -0
- package/templates/scheduler_depth/javascript/README.md +19 -0
- package/templates/scheduler_depth/javascript/__tests__/processor.spec.js +17 -0
- package/templates/scheduler_depth/javascript/index.js +15 -0
- package/templates/scheduler_depth/python/README.md +31 -0
- package/templates/scheduler_depth/python/lambda_function.py +7 -0
- package/templates/scheduler_depth/python/test/__init__.py +0 -0
- package/templates/scheduler_depth/python/test/app_test.py +10 -0
- package/templates/scheduler_depth/typescript/README.md +25 -0
- package/templates/scheduler_depth/typescript/__tests__/processor.spec.ts +17 -0
- package/templates/scheduler_depth/typescript/index.ts +8 -0
- package/templates/scheduler_natural-time/javascript/README.md +19 -0
- package/templates/scheduler_natural-time/javascript/__tests__/processor.spec.js +15 -0
- package/templates/scheduler_natural-time/javascript/index.js +15 -0
- package/templates/scheduler_natural-time/python/README.md +31 -0
- package/templates/scheduler_natural-time/python/lambda_function.py +7 -0
- package/templates/scheduler_natural-time/python/test/__init__.py +0 -0
- package/templates/scheduler_natural-time/python/test/app_test.py +10 -0
- package/templates/scheduler_natural-time/typescript/README.md +25 -0
- package/templates/scheduler_natural-time/typescript/__tests__/processor.spec.ts +15 -0
- package/templates/scheduler_natural-time/typescript/index.ts +8 -0
- package/templates/stream_depth/javascript/README.md +19 -0
- package/templates/stream_depth/javascript/__tests__/processor.spec.js +20 -0
- package/templates/stream_depth/javascript/index.js +14 -0
- package/templates/stream_depth/python/README.md +31 -0
- package/templates/stream_depth/python/lambda_function.py +7 -0
- package/templates/stream_depth/python/test/__init__.py +0 -0
- package/templates/stream_depth/python/test/app_test.py +16 -0
- package/templates/stream_depth/typescript/README.md +25 -0
- package/templates/stream_depth/typescript/__tests__/processor.spec.ts +20 -0
- package/templates/stream_depth/typescript/index.ts +8 -0
- package/templates/stream_time/javascript/README.md +19 -0
- package/templates/stream_time/javascript/__tests__/processor.spec.js +14 -0
- package/templates/stream_time/javascript/index.js +14 -0
- package/templates/stream_time/python/README.md +31 -0
- package/templates/stream_time/python/lambda_function.py +7 -0
- package/templates/stream_time/python/test/__init__.py +0 -0
- package/templates/stream_time/python/test/app_test.py +16 -0
- package/templates/stream_time/typescript/README.md +25 -0
- package/templates/stream_time/typescript/__tests__/processor.spec.ts +14 -0
- package/templates/stream_time/typescript/index.ts +8 -0
- package/templates/task/javascript/README.md +19 -0
- package/templates/task/javascript/__tests__/processor.spec.js +16 -0
- package/templates/task/javascript/index.js +15 -0
- package/templates/task/python/README.md +31 -0
- package/templates/task/python/lambda_function.py +7 -0
- package/templates/task/python/test/__init__.py +0 -0
- package/templates/task/python/test/app_test.py +8 -0
- package/templates/task/typescript/README.md +25 -0
- package/templates/task/typescript/__tests__/processor.spec.ts +16 -0
- package/templates/task/typescript/index.ts +8 -0
- package/templates/ui/javascript/.codex/config.toml +3 -0
- package/templates/ui/javascript/.cursor/mcp.json +8 -0
- package/templates/ui/javascript/.eslintrc +11 -0
- package/templates/ui/javascript/.mcp.json +8 -0
- package/templates/ui/javascript/.prettierrc +1 -0
- package/templates/ui/javascript/AGENTS.md +304 -0
- package/templates/ui/javascript/CLAUDE.md +1 -0
- package/templates/ui/javascript/README.md +31 -0
- package/templates/ui/javascript/config/jest/babelTransform.js +16 -0
- package/templates/ui/javascript/config/jest/cssTransform.js +16 -0
- package/templates/ui/javascript/config/jest/fileTransform.js +48 -0
- package/templates/ui/javascript/config/jest/globalSetup.js +5 -0
- package/templates/ui/javascript/config/jest/setupTests.js +30 -0
- package/templates/ui/javascript/config-overrides.js +10 -0
- package/templates/ui/javascript/gitignore +27 -0
- package/templates/ui/javascript/src/App.completion.js +52 -0
- package/templates/ui/javascript/src/App.drilling.js +49 -0
- package/templates/ui/javascript/src/App.scss +17 -0
- package/templates/ui/javascript/src/AppSettings.js +28 -0
- package/templates/ui/javascript/src/__tests__/App.test.js +26 -0
- package/templates/ui/javascript/src/__tests__/AppSettings.test.js +28 -0
- package/templates/ui/javascript/src/__tests__/TestsExample.test.js +37 -0
- package/templates/ui/javascript/src/assets/logo.svg +7 -0
- package/templates/ui/javascript/src/constants.js +3 -0
- package/templates/ui/javascript/src/index.js +8 -0
- package/templates/ui/typescript/.codex/config.toml +3 -0
- package/templates/ui/typescript/.cursor/mcp.json +8 -0
- package/templates/ui/typescript/.eslintrc +28 -0
- package/templates/ui/typescript/.mcp.json +8 -0
- package/templates/ui/typescript/.prettierrc +1 -0
- package/templates/ui/typescript/AGENTS.md +344 -0
- package/templates/ui/typescript/CLAUDE.md +1 -0
- package/templates/ui/typescript/README.md +31 -0
- package/templates/ui/typescript/config/jest/babelTransform.js +16 -0
- package/templates/ui/typescript/config/jest/cssTransform.js +16 -0
- package/templates/ui/typescript/config/jest/fileTransform.js +48 -0
- package/templates/ui/typescript/config/jest/globalSetup.js +5 -0
- package/templates/ui/typescript/config/jest/setupTests.js +30 -0
- package/templates/ui/typescript/config-overrides.js +10 -0
- package/templates/ui/typescript/gitignore +27 -0
- package/templates/ui/typescript/src/App.completion.tsx +52 -0
- package/templates/ui/typescript/src/App.drilling.tsx +49 -0
- package/templates/ui/typescript/src/App.scss +17 -0
- package/templates/ui/typescript/src/AppSettings.tsx +28 -0
- package/templates/ui/typescript/src/__mocks__/mockData.ts +22 -0
- package/templates/ui/typescript/src/__tests__/App.test.tsx +27 -0
- package/templates/ui/typescript/src/__tests__/AppSettings.test.tsx +28 -0
- package/templates/ui/typescript/src/__tests__/TestsExample.test.tsx +37 -0
- package/templates/ui/typescript/src/assets/logo.svg +7 -0
- package/templates/ui/typescript/src/constants.ts +3 -0
- package/templates/ui/typescript/src/custom.d.ts +19 -0
- package/templates/ui/typescript/src/index.js +8 -0
- package/templates/ui/typescript/src/types.ts +3 -0
- package/templates/ui/typescript/tsconfig.json +7 -0
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
import { dirname, join, resolve } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { clear } from 'node:console';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import { existsSync } from 'node:fs';
|
|
6
|
+
|
|
7
|
+
import { Command, Option } from 'commander';
|
|
8
|
+
import spawn from 'cross-spawn';
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
import fs from 'fs-extra';
|
|
11
|
+
import figlet from 'figlet';
|
|
12
|
+
import _ from 'lodash/fp.js';
|
|
13
|
+
import inquirer from 'inquirer';
|
|
14
|
+
|
|
15
|
+
import { originalCwdOption } from '../options/original-cwd.js';
|
|
16
|
+
import { ensureBumpVersion, ensureLatestVersion } from '../helpers/cli-version.js';
|
|
17
|
+
import { logger } from '../helpers/logger.js';
|
|
18
|
+
import { IS_WINDOWS, resolveAppRuntime } from '../helpers/resolve-app-runtime.js';
|
|
19
|
+
import { tryGitCommit, tryGitInit } from '../helpers/versioning.js';
|
|
20
|
+
import { addUiAppFile, copyFolderRecursiveSync, getExcludedFiles, putVariablesInEnvFile } from '../helpers/utils.js';
|
|
21
|
+
import { getDefaultsForPackageJson } from '../constants/package.js';
|
|
22
|
+
import { getRealWorkingDir } from '../helpers/commands.js';
|
|
23
|
+
import { Manifest } from '../flows/lib/manifest.js';
|
|
24
|
+
import { fillManifest } from '../helpers/manifest.js';
|
|
25
|
+
import { getManifestMandatoryKeys, manifestOptions } from '../constants/manifest.js';
|
|
26
|
+
import { StepError } from '../flows/lib/step-error.js';
|
|
27
|
+
|
|
28
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
29
|
+
const __dirname = dirname(__filename);
|
|
30
|
+
|
|
31
|
+
const WRITE_TO_JSON_OPTS = {
|
|
32
|
+
spaces: 2,
|
|
33
|
+
EOL: os.EOL,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const createCommand = new Command('create')
|
|
37
|
+
.description('Create a new app')
|
|
38
|
+
.argument('[project-directory]', 'project directory to work with', process.argv[process.argv.length - 1])
|
|
39
|
+
.addOption(originalCwdOption);
|
|
40
|
+
|
|
41
|
+
manifestOptions().forEach((value) => {
|
|
42
|
+
const type = value.commaSeparated ? 'string' : typeof value.default;
|
|
43
|
+
const cliType = type === 'undefined' ? (value.choices ? ' [string]' : '') : ` [${type}]`;
|
|
44
|
+
const alias = value.alias ? `-${value.alias}, ` : '';
|
|
45
|
+
const optionString = `${alias}--${value.name}${cliType}`;
|
|
46
|
+
|
|
47
|
+
const option = new Option(optionString, value.message);
|
|
48
|
+
|
|
49
|
+
if (value.choices) {
|
|
50
|
+
if (typeof value.choices === 'function') {
|
|
51
|
+
option.choices(value.choices());
|
|
52
|
+
} else {
|
|
53
|
+
option.choices(value.choices.map((choice) => `${typeof choice === 'object' ? choice.value : choice}`));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (type === 'number') {
|
|
58
|
+
option.argParser(Number);
|
|
59
|
+
} else if (value.commaSeparated) {
|
|
60
|
+
option.argParser((str) => str.split(',').map((s) => s.trim()));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (type !== 'undefined') {
|
|
64
|
+
option.default(value.default);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
createCommand.addOption(option);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
createCommand.version(fs.readJSONSync(join(__dirname, '../../package.json')).version);
|
|
71
|
+
|
|
72
|
+
createCommand.action(async (dirName, options) => {
|
|
73
|
+
if (options.zip || options.release) {
|
|
74
|
+
options.bumpVersion = await ensureBumpVersion(options.bumpVersion);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
startingMessage();
|
|
78
|
+
|
|
79
|
+
// NOTE: Default action
|
|
80
|
+
await createApp(dirName, options);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
*
|
|
85
|
+
* @param {import('./flows/lib/manifest').Manifest} manifest
|
|
86
|
+
*/
|
|
87
|
+
const getEnvManagementLink = (manifest) => {
|
|
88
|
+
if (manifest.isJs()) {
|
|
89
|
+
if (IS_WINDOWS) {
|
|
90
|
+
return 'https://github.com/coreybutler/nvm-windows';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return 'https://github.com/nvm-sh/nvm';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (IS_WINDOWS) {
|
|
97
|
+
return 'https://docs.python.org/3/using/windows.html#using-python-on-windows';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return 'https://github.com/pyenv/pyenv';
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
async function initPackage(projectName, opts) {
|
|
104
|
+
const manifest = new Manifest(fillManifest(opts));
|
|
105
|
+
const runtime = resolveAppRuntime(opts);
|
|
106
|
+
|
|
107
|
+
if (!(await runtime.isRuntimeAvailable())) {
|
|
108
|
+
throw new StepError(
|
|
109
|
+
`You need ${runtime.environment} version ${runtime.version} to use "${opts.runtime}" runtime. ` +
|
|
110
|
+
`Please install it manually or proceed to ${chalk.green(getEnvManagementLink(manifest))} ` +
|
|
111
|
+
`to install a node version manager`,
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (manifest.isUi()) {
|
|
116
|
+
await ensureLatestVersion();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const root = getRealWorkingDir(projectName, opts);
|
|
120
|
+
|
|
121
|
+
logger.log(`Creating a new Corva app in ${chalk.green(root)}.`);
|
|
122
|
+
|
|
123
|
+
await fs.ensureDir(root);
|
|
124
|
+
|
|
125
|
+
if ((await fs.readdir(root)).length) {
|
|
126
|
+
const shouldCleanup = await inquirer
|
|
127
|
+
.prompt([
|
|
128
|
+
{
|
|
129
|
+
message: `Directory "${root}" is not empty. Clean it to proceed?`,
|
|
130
|
+
name: 'cleanup',
|
|
131
|
+
type: 'confirm',
|
|
132
|
+
},
|
|
133
|
+
])
|
|
134
|
+
.then(_.get('cleanup'));
|
|
135
|
+
|
|
136
|
+
if (shouldCleanup) {
|
|
137
|
+
await fs.emptyDir(root);
|
|
138
|
+
} else {
|
|
139
|
+
throw new StepError(`Directory is not empty: ${root}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
await fs.writeJSON(join(root, 'manifest.json'), manifest.manifest, WRITE_TO_JSON_OPTS);
|
|
144
|
+
|
|
145
|
+
await addTemplate(root, manifest, runtime, opts);
|
|
146
|
+
await configureApp(root, manifest, runtime, opts);
|
|
147
|
+
|
|
148
|
+
if (opts.gitInit) {
|
|
149
|
+
if (!tryGitInit(root)) {
|
|
150
|
+
logger.log('Already in a git repository. Skipping git initialization.');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
opts.dependenciesInstall && (await installDependencies(root, manifest, runtime));
|
|
155
|
+
|
|
156
|
+
if (opts.gitInit) {
|
|
157
|
+
if (tryGitCommit(root)) {
|
|
158
|
+
logger.log();
|
|
159
|
+
logger.log('Created git commit');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
logger.log();
|
|
164
|
+
logger.log(`Success! Created ${chalk.green(manifest.name)} at ${chalk.yellow(root)}`);
|
|
165
|
+
|
|
166
|
+
helpCommands(manifest, runtime);
|
|
167
|
+
|
|
168
|
+
logger.log();
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async function createApp(dirName, opts) {
|
|
172
|
+
const { isValid, values } = checkOptions(opts);
|
|
173
|
+
|
|
174
|
+
if (isValid) {
|
|
175
|
+
Object.keys(values).forEach((key) => {
|
|
176
|
+
logger.log(`${key} : ${values[key]}`);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
return initPackage(dirName, opts);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
console.log('Please fill your app Metadata');
|
|
183
|
+
|
|
184
|
+
const answers = await inquirer.prompt(manifestOptions(dirName), opts);
|
|
185
|
+
|
|
186
|
+
return initPackage(dirName, answers);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
*
|
|
191
|
+
* @param {string} root
|
|
192
|
+
* @param {import('./flows/lib/manifest').Manifest} manifest
|
|
193
|
+
* @param {*} runtime
|
|
194
|
+
* @param {*} opts
|
|
195
|
+
*/
|
|
196
|
+
async function addTemplate(root, manifest, runtime, opts) {
|
|
197
|
+
logger.log(chalk.green('Copying app template...'));
|
|
198
|
+
logger.log();
|
|
199
|
+
|
|
200
|
+
const cliRoot = resolve(__dirname, '..', '..');
|
|
201
|
+
|
|
202
|
+
const templateFolder = join(cliRoot, 'templates', manifest.templateName, runtime.language);
|
|
203
|
+
|
|
204
|
+
const excludeFiles = getExcludedFiles(manifest);
|
|
205
|
+
|
|
206
|
+
copyFolderRecursiveSync(templateFolder, root, excludeFiles);
|
|
207
|
+
|
|
208
|
+
if (manifest.isNode()) {
|
|
209
|
+
copyFolderRecursiveSync(join(cliRoot, 'common', 'node'), root);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (manifest.isPython()) {
|
|
213
|
+
copyFolderRecursiveSync(join(cliRoot, 'common', 'python'), root);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (!manifest.isUi()) {
|
|
217
|
+
await putVariablesInEnvFile(root, manifest);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// We can't have .gitignore file in our templates.
|
|
221
|
+
// It's missing when @corva/create-app is installed.
|
|
222
|
+
// That's why we manually rename gitignore to .gitignore after copying template
|
|
223
|
+
const targetGitignore = join(root, '.gitignore');
|
|
224
|
+
|
|
225
|
+
fs.renameSync(join(root, 'gitignore'), targetGitignore);
|
|
226
|
+
|
|
227
|
+
if (runtime.language === 'typescript' && manifest.isNode()) {
|
|
228
|
+
await fs.appendFile(targetGitignore, '\n**/*.js\n');
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
logger.log(chalk.green('Done: copying app template!'));
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
if (Array.isArray(opts?.extensions) && opts.extensions.length) {
|
|
235
|
+
opts.extensions.forEach((extension) => {
|
|
236
|
+
const extPath = join(cliRoot, 'template_extensions', extension);
|
|
237
|
+
|
|
238
|
+
if (fs.existsSync(extPath)) {
|
|
239
|
+
copyFolderRecursiveSync(extPath, root);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
logger.log(chalk.green('Done: applying app extensions!'));
|
|
244
|
+
}
|
|
245
|
+
} catch (e) {
|
|
246
|
+
logger.log(chalk.red('Error: applying app extensions!'));
|
|
247
|
+
logger.log(e);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (manifest.isUi()) {
|
|
251
|
+
addUiAppFile(templateFolder, root, runtime, manifest, opts);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
*
|
|
257
|
+
* @param {string} root
|
|
258
|
+
* @param {import('./flows/lib/manifest').Manifest} manifest
|
|
259
|
+
* @param {*} runtime
|
|
260
|
+
* @param {*} opts
|
|
261
|
+
*/
|
|
262
|
+
async function configureApp(root, manifest, runtime, opts) {
|
|
263
|
+
if (manifest.isJs()) {
|
|
264
|
+
await addNvmRc(root, manifest, runtime);
|
|
265
|
+
await addPackageJSON(root, manifest, runtime, opts);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (manifest.isNode()) {
|
|
269
|
+
await addTsConfigs(root, manifest, runtime);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (manifest.isPython()) {
|
|
273
|
+
await addPythonConfigs(root, manifest, runtime);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const addNvmRc = async (root, manifest, runtime) => {
|
|
278
|
+
await fs.outputFile(join(root, '.nvmrc'), `${runtime.semver}\n`);
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
*
|
|
283
|
+
* @param {string} root
|
|
284
|
+
* @param {Manifest} manifest
|
|
285
|
+
* @param {import('../helpers/resolve-app-runtime.js').Runtime} runtime
|
|
286
|
+
*/
|
|
287
|
+
const addPythonConfigs = async (root, manifest, runtime) => {
|
|
288
|
+
await fs.writeFile(resolve(root, '.python-version'), `${runtime.version}\n`);
|
|
289
|
+
await fs.writeFile(resolve(root, '.python-virtualenv'), `${manifest.unix_name}\n`);
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const addTsConfigs = (root, manifest, runtime) => {
|
|
293
|
+
if (runtime.language !== 'typescript') {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return Promise.all([
|
|
298
|
+
fs.writeJson(
|
|
299
|
+
resolve(root, 'tsconfig.json'),
|
|
300
|
+
{
|
|
301
|
+
extends: `@tsconfig/node${runtime.version}/tsconfig.json`,
|
|
302
|
+
compilerOptions: {
|
|
303
|
+
inlineSourceMap: true,
|
|
304
|
+
strict: false,
|
|
305
|
+
outDir: 'dist',
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
WRITE_TO_JSON_OPTS,
|
|
309
|
+
),
|
|
310
|
+
fs.writeJson(
|
|
311
|
+
resolve(root, 'tsconfig.build.json'),
|
|
312
|
+
{
|
|
313
|
+
extends: './tsconfig.json',
|
|
314
|
+
include: ['lib/**/*.ts', 'index.ts'],
|
|
315
|
+
exclude: ['node_modules', '**/*.spec.ts'],
|
|
316
|
+
},
|
|
317
|
+
WRITE_TO_JSON_OPTS,
|
|
318
|
+
),
|
|
319
|
+
]);
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
*
|
|
324
|
+
* @param {string} root
|
|
325
|
+
* @param {import('./flows/lib/manifest').Manifest} manifest
|
|
326
|
+
*/
|
|
327
|
+
function addPackageJSON(root, manifest, runtime, opts) {
|
|
328
|
+
const {
|
|
329
|
+
version,
|
|
330
|
+
description,
|
|
331
|
+
scripts,
|
|
332
|
+
dependencies,
|
|
333
|
+
devDependencies,
|
|
334
|
+
main,
|
|
335
|
+
license = 'UNLICENSED',
|
|
336
|
+
private: isPrivate = true,
|
|
337
|
+
...rest
|
|
338
|
+
} = getDefaultsForPackageJson(manifest, runtime, opts);
|
|
339
|
+
|
|
340
|
+
const packageJson = {
|
|
341
|
+
name: manifest.unix_name,
|
|
342
|
+
version,
|
|
343
|
+
description: manifest.description || description,
|
|
344
|
+
main,
|
|
345
|
+
private: isPrivate,
|
|
346
|
+
license,
|
|
347
|
+
engines: {
|
|
348
|
+
node: `^${runtime.version}`,
|
|
349
|
+
[runtime.packageManager]: '*',
|
|
350
|
+
},
|
|
351
|
+
scripts,
|
|
352
|
+
dependencies,
|
|
353
|
+
devDependencies,
|
|
354
|
+
...rest,
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
return fs.writeJSON(join(root, 'package.json'), packageJson, WRITE_TO_JSON_OPTS);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* @param {string} root
|
|
362
|
+
* @param {import('./flows/lib/manifest').Manifest} manifest
|
|
363
|
+
* @param {import('./helpers/resolve-app-runtime.js').Runtime} runtime
|
|
364
|
+
* @returns {Promise<void>}
|
|
365
|
+
* @throws {Error}
|
|
366
|
+
* @throws {import('child_process').ExecException}
|
|
367
|
+
* @throws {import('child_process').SpawnSyncReturns<Buffer>}
|
|
368
|
+
*/
|
|
369
|
+
async function installDependencies(root, manifest, runtime) {
|
|
370
|
+
const command = manifest.isJs() ? runtime.packageManager : 'make';
|
|
371
|
+
|
|
372
|
+
if (IS_WINDOWS && !manifest.isJs()) {
|
|
373
|
+
logger.log();
|
|
374
|
+
logger.log(`⚠️ ${chalk.yellow('Please install project dependencies manually')}`);
|
|
375
|
+
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const args = ['install'];
|
|
380
|
+
const opts = { stdio: ['inherit', 'inherit', 'pipe'], cwd: root };
|
|
381
|
+
|
|
382
|
+
if (process.env.CI && command === 'yarn') {
|
|
383
|
+
args.push('--cache-folder=".yarn-cache"');
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
logger.log(chalk.yellow(`Installing template dependencies using ${runtime.packageManager}...`));
|
|
387
|
+
|
|
388
|
+
const nvmOpts = {
|
|
389
|
+
shell: true,
|
|
390
|
+
...opts,
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
const proc =
|
|
394
|
+
manifest.isJs() && existsSync(`${os.homedir()}/.nvm/nvm.sh`)
|
|
395
|
+
? spawn.sync(`\\. ${os.homedir()}/.nvm/nvm.sh && nvm i && ${command} ${args.join(' ')}`, nvmOpts)
|
|
396
|
+
: spawn.sync(command, args, opts);
|
|
397
|
+
|
|
398
|
+
if (proc.stderr) {
|
|
399
|
+
const error = proc.stderr
|
|
400
|
+
.toString('utf8')
|
|
401
|
+
.split('\n')
|
|
402
|
+
// NOTE: filter out warnings caused by @corva/ui peer dependencies
|
|
403
|
+
.filter((line) => !line.includes('@corva/ui'))
|
|
404
|
+
.join('\n');
|
|
405
|
+
|
|
406
|
+
console.log(error);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (proc.status !== 0) {
|
|
410
|
+
console.error(`\`${command} ${args.join(' ')}\` failed`);
|
|
411
|
+
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
logger.log(chalk.green('Successfull project install'));
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
async function helpCommands(manifest, { packageManager: displayedCommand }) {
|
|
419
|
+
if (!manifest.isUi()) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
const useYarn = displayedCommand === 'yarn';
|
|
424
|
+
|
|
425
|
+
logger.log('Inside that directory, you can run several commands:');
|
|
426
|
+
logger.log();
|
|
427
|
+
logger.log(chalk.cyan(` ${displayedCommand} start`));
|
|
428
|
+
logger.log(' Starts the development server.');
|
|
429
|
+
logger.log();
|
|
430
|
+
logger.log(chalk.cyan(` ${displayedCommand} ${useYarn ? '' : 'run '}build`));
|
|
431
|
+
logger.log(' Bundles the app into static files for production.');
|
|
432
|
+
logger.log();
|
|
433
|
+
logger.log(chalk.cyan(` ${displayedCommand} ${useYarn ? '' : 'run '}zip`));
|
|
434
|
+
logger.log(' Bundles the app into ZIP file in app root directory');
|
|
435
|
+
logger.log();
|
|
436
|
+
logger.log(chalk.cyan(` ${displayedCommand} ${useYarn ? '' : 'run '}release`));
|
|
437
|
+
logger.log(' Uploads the app ZIP to Corva');
|
|
438
|
+
logger.log();
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function startingMessage() {
|
|
442
|
+
clear();
|
|
443
|
+
console.log(chalk.green(' Welcome to apps generator for:'));
|
|
444
|
+
console.log(chalk.cyan(figlet.textSync('CORVA.AI', { horizontalLayout: 'full' })));
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function checkOptions(opts) {
|
|
448
|
+
let isValid = true;
|
|
449
|
+
const values = {};
|
|
450
|
+
|
|
451
|
+
getManifestMandatoryKeys(opts).forEach((key) => {
|
|
452
|
+
if (!opts[key]) {
|
|
453
|
+
isValid = false;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
values[key] = opts[key];
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
return {
|
|
460
|
+
isValid,
|
|
461
|
+
values,
|
|
462
|
+
};
|
|
463
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { Command, Option } from 'commander';
|
|
3
|
+
import { runFlow } from '../flow.js';
|
|
4
|
+
import { RELEASE_FLOW } from '../flows/release.js';
|
|
5
|
+
import { getRealWorkingDir } from '../helpers/commands.js';
|
|
6
|
+
import { apiKeyOption } from '../options/api-key.js';
|
|
7
|
+
import { bumpVersionOption } from '../options/bump-version.js';
|
|
8
|
+
import { envOption } from '../options/env.js';
|
|
9
|
+
import { originalCwdOption } from '../options/original-cwd.js';
|
|
10
|
+
import { silentOption } from '../options/silent.js';
|
|
11
|
+
import { ensureBumpVersion } from '../helpers/cli-version.js';
|
|
12
|
+
import { ERROR_ICON } from '../constants/messages.js';
|
|
13
|
+
import { appKeyOption } from '../options/app-key.js';
|
|
14
|
+
|
|
15
|
+
export const releaseCommand = new Command('release')
|
|
16
|
+
.description('Release app')
|
|
17
|
+
.argument('<project-directory>', 'Project directory to work with')
|
|
18
|
+
.argument('[patterns...]', 'Additional patterns to zip', [])
|
|
19
|
+
.addOption(bumpVersionOption)
|
|
20
|
+
.addOption(new Option('--ignored-files [string...]', 'Patterns to skip zip').default([]))
|
|
21
|
+
.addOption(silentOption)
|
|
22
|
+
.addOption(envOption)
|
|
23
|
+
.addOption(apiKeyOption)
|
|
24
|
+
.addOption(appKeyOption)
|
|
25
|
+
.addOption(originalCwdOption)
|
|
26
|
+
.addOption(new Option('--notes [string]', 'Add custom notes to published app'))
|
|
27
|
+
.addOption(new Option('--label [string]', 'Put a label on the release').choices(['DEV', 'BETA', 'PROD']))
|
|
28
|
+
.addOption(new Option('--remove-on-fail [boolean]', 'Remove release if it fails during deployment').default(false))
|
|
29
|
+
.addOption(
|
|
30
|
+
new Option('--remove-on-success [boolean]', 'App package (.zip) will not be deleted after upload').default(true),
|
|
31
|
+
)
|
|
32
|
+
.addOption(
|
|
33
|
+
new Option(
|
|
34
|
+
'--remove-existing [boolean]',
|
|
35
|
+
'If package version is already taken - remove the previously published package and upload a new one',
|
|
36
|
+
).default(false),
|
|
37
|
+
)
|
|
38
|
+
// .addOption(new Option('--zip-file-name [string]', 'Prebuilt zip file name in dir'))
|
|
39
|
+
.addOption(new Option('--author [string]', 'Author name for the audit'))
|
|
40
|
+
.action(async (dirName, patterns, options) => {
|
|
41
|
+
// if author is present in CLI, save it to process.env
|
|
42
|
+
if (options.author) {
|
|
43
|
+
process.env.githubUsername = options.author;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
options.bumpVersion = await ensureBumpVersion(options.bumpVersion);
|
|
47
|
+
|
|
48
|
+
await runFlow(RELEASE_FLOW, {
|
|
49
|
+
dirName: getRealWorkingDir(dirName, options),
|
|
50
|
+
patterns,
|
|
51
|
+
options,
|
|
52
|
+
});
|
|
53
|
+
})
|
|
54
|
+
.showHelpAfterError()
|
|
55
|
+
.showSuggestionAfterError(true)
|
|
56
|
+
.configureOutput({
|
|
57
|
+
outputError: (str, write) => write(chalk.red(`${ERROR_ICON} ${str}`)),
|
|
58
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { Command, Option } from 'commander';
|
|
3
|
+
import { ERROR_ICON } from '../constants/messages.js';
|
|
4
|
+
import { runFlow } from '../flow.js';
|
|
5
|
+
import { RERUN_FLOW } from '../flows/rerun.js';
|
|
6
|
+
import { getRealWorkingDir } from '../helpers/commands.js';
|
|
7
|
+
import { apiKeyOption } from '../options/api-key.js';
|
|
8
|
+
import { appVersion } from '../options/app-version.js';
|
|
9
|
+
import { envOption } from '../options/env.js';
|
|
10
|
+
import { originalCwdOption } from '../options/original-cwd.js';
|
|
11
|
+
import { silentOption } from '../options/silent.js';
|
|
12
|
+
import { cacheOption } from '../options/cache.js';
|
|
13
|
+
|
|
14
|
+
export const rerunCommand = new Command('rerun')
|
|
15
|
+
.description('Rerun app')
|
|
16
|
+
.argument('<project-directory>', 'Project directory to work with')
|
|
17
|
+
.addOption(apiKeyOption)
|
|
18
|
+
.addOption(envOption)
|
|
19
|
+
.addOption(silentOption)
|
|
20
|
+
.addOption(cacheOption)
|
|
21
|
+
.addOption(appVersion)
|
|
22
|
+
.addOption(new Option('--assets [assets...]', 'Assets IDs list', []).conflicts('companyId'))
|
|
23
|
+
.addOption(new Option('--company-id [number]', 'Company ID', []))
|
|
24
|
+
.addOption(new Option('--interval [number]', 'Interval for scheduler apps (exp. 1200)'))
|
|
25
|
+
.addOption(new Option('--force-stream-log-type [string]', 'Force stream log type').choices(['time', 'depth']))
|
|
26
|
+
.addOption(originalCwdOption)
|
|
27
|
+
.action(async (dirName, options) => {
|
|
28
|
+
await runFlow(RERUN_FLOW, { dirName: getRealWorkingDir(dirName, options), options });
|
|
29
|
+
})
|
|
30
|
+
.showHelpAfterError()
|
|
31
|
+
.showSuggestionAfterError(true)
|
|
32
|
+
.configureOutput({
|
|
33
|
+
outputError: (str, write) => write(chalk.red(`${ERROR_ICON} ${str}`)),
|
|
34
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { Command, Option } from 'commander';
|
|
3
|
+
import _ from 'lodash/fp.js';
|
|
4
|
+
|
|
5
|
+
import { runFlow } from '../flow.js';
|
|
6
|
+
import { ZIP_FLOW } from '../flows/zip.js';
|
|
7
|
+
import { getRealWorkingDir, silencer } from '../helpers/commands.js';
|
|
8
|
+
import { bumpVersionOption } from '../options/bump-version.js';
|
|
9
|
+
import { originalCwdOption } from '../options/original-cwd.js';
|
|
10
|
+
import { silentOption } from '../options/silent.js';
|
|
11
|
+
import { ensureBumpVersion } from '../helpers/cli-version.js';
|
|
12
|
+
import { ERROR_ICON } from '../constants/messages.js';
|
|
13
|
+
|
|
14
|
+
export const zipCommand = new Command('zip')
|
|
15
|
+
.description('Bundle app')
|
|
16
|
+
.argument('<project-directory>', 'Project directory to work with')
|
|
17
|
+
.argument('[patterns...]', 'Additional patterns to zip', [])
|
|
18
|
+
.addOption(bumpVersionOption)
|
|
19
|
+
.addOption(new Option('--ignored-files [ignoredFiles...]', 'Patterns to skip zip', []))
|
|
20
|
+
.addOption(originalCwdOption)
|
|
21
|
+
.addOption(silentOption)
|
|
22
|
+
.action(
|
|
23
|
+
silencer(async (dirName, patterns, options) => {
|
|
24
|
+
options.bumpVersion = await ensureBumpVersion(options.bumpVersion);
|
|
25
|
+
|
|
26
|
+
console.log(getRealWorkingDir(dirName, options), options);
|
|
27
|
+
|
|
28
|
+
return runFlow(ZIP_FLOW, {
|
|
29
|
+
dirName: getRealWorkingDir(dirName, options),
|
|
30
|
+
patterns,
|
|
31
|
+
options,
|
|
32
|
+
}).then(_.get('zipFileName'));
|
|
33
|
+
}),
|
|
34
|
+
)
|
|
35
|
+
.showHelpAfterError()
|
|
36
|
+
.showSuggestionAfterError(true)
|
|
37
|
+
.configureOutput({
|
|
38
|
+
outputError: (str, write) => write(chalk.red(`${ERROR_ICON} ${str}`)),
|
|
39
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const APP_RUNTIMES = {
|
|
2
|
+
UI: 'ui',
|
|
3
|
+
// NODE12: 'nodejs12.x',
|
|
4
|
+
// NODE14: 'nodejs14.x',
|
|
5
|
+
// NODE16: 'nodejs16.x',
|
|
6
|
+
NODE18: 'nodejs18.x',
|
|
7
|
+
NODE20: 'nodejs20.x',
|
|
8
|
+
NODE22: 'nodejs22.x',
|
|
9
|
+
NODE24: 'nodejs24.x',
|
|
10
|
+
// PYTHON3_8: 'python3.8',
|
|
11
|
+
// PYTHON3_9: 'python3.9',
|
|
12
|
+
// PYTHON3_10: 'python3.10',
|
|
13
|
+
PYTHON3_11: 'python3.11',
|
|
14
|
+
PYTHON3_12: 'python3.12',
|
|
15
|
+
PYTHON3_13: 'python3.13',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const TEMPLATE_TYPES = {
|
|
19
|
+
UI: 'js',
|
|
20
|
+
UI_TS: 'ts',
|
|
21
|
+
NODE: 'node',
|
|
22
|
+
NODE_TYPESCRIPT: 'node-ts',
|
|
23
|
+
PYTHON: 'python',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const APP_TYPES = {
|
|
27
|
+
UI: 'ui',
|
|
28
|
+
SCHEDULER: 'scheduler',
|
|
29
|
+
STREAM: 'stream',
|
|
30
|
+
TASK: 'task',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const APP_EXTENSIONS = {
|
|
34
|
+
CORVA: 'corva',
|
|
35
|
+
};
|