@corva/create-app 0.27.0-1 → 0.28.0-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +160 -17
- package/bin/create-corva-app.js +5 -0
- package/lib/app.js +9 -0
- package/lib/bump-version.option.js +29 -0
- package/{constants → lib/constants}/cli.js +1 -0
- package/{constants → lib/constants}/manifest.js +4 -2
- package/lib/constants/messages.js +21 -0
- package/{constants → lib/constants}/package.js +2 -2
- package/lib/flow.js +46 -0
- package/lib/flows/lib/create-zip-archive.js +77 -0
- package/lib/flows/lib/json.js +28 -0
- package/lib/flows/lib/manifest.js +31 -0
- package/lib/flows/lib/step-error.js +12 -0
- package/lib/flows/prepare.js +8 -0
- package/lib/flows/release.js +18 -0
- package/lib/flows/steps/prepare-load-app-files.js +18 -0
- package/lib/flows/steps/release-get-app-key.js +16 -0
- package/lib/flows/steps/release-get-config.js +30 -0
- package/lib/flows/steps/release-upload-zip-to-corva.js +34 -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 +185 -0
- package/lib/flows/steps/zip-prepare.js +21 -0
- package/lib/flows/steps/zip.js +15 -0
- package/lib/flows/zip-simple.js +8 -0
- package/lib/flows/zip.js +9 -0
- package/{helpers → lib/helpers}/manifest.js +2 -2
- package/{helpers → lib/helpers}/utils.js +0 -0
- package/{helpers → lib/helpers}/versioning.js +0 -0
- package/{index.js → lib/index.js} +164 -51
- package/{scripts → lib/scripts}/utils/version.js +49 -26
- package/package.json +13 -8
- package/{template → templates}/scheduler/node/README.md +0 -0
- package/{template → templates}/scheduler/node/__test__/processor.test.js +0 -0
- package/{template → templates}/scheduler/node/gitignore +0 -0
- package/{template → templates}/scheduler/node/index.js +0 -0
- package/{template → templates}/scheduler/node/package.json +1 -1
- package/{template → templates}/scheduler/node/src/processor.js +0 -0
- package/{template → templates}/scheduler/node-ts/README.md +0 -0
- package/{template → templates}/scheduler/node-ts/__test__/processor.spec.ts +0 -0
- package/{template → templates}/scheduler/node-ts/gitignore +0 -0
- package/{template → templates}/scheduler/node-ts/index.ts +0 -0
- package/templates/scheduler/node-ts/lib/processor.js +16 -0
- package/templates/scheduler/node-ts/lib/processor.js.map +1 -0
- package/{template → templates}/scheduler/node-ts/lib/processor.ts +0 -0
- package/{template → templates}/scheduler/node-ts/package.json +1 -1
- package/{template → templates}/scheduler/node-ts/tsconfig.build.json +0 -0
- package/{template → templates}/scheduler/node-ts/tsconfig.json +0 -0
- package/templates/scheduler/python/Makefile +15 -0
- package/templates/scheduler/python/README.md +31 -0
- package/{template → templates}/scheduler/python/lambda_function.py +0 -0
- package/{template → templates}/scheduler/python/requirements.txt +0 -0
- package/{template → templates}/scheduler/python/test/__init__.py +0 -0
- package/{template → templates}/scheduler/python/test/app_test.py +0 -0
- package/{template → templates}/stream/node/README.md +0 -0
- package/{template → templates}/stream/node/__test__/processor.test.js +0 -0
- package/{template → templates}/stream/node/gitignore +0 -0
- package/{template → templates}/stream/node/index.js +0 -0
- package/{template → templates}/stream/node/package.json +1 -1
- package/{template → templates}/stream/node/src/processor.js +0 -0
- package/{template → templates}/stream/node-ts/README.md +0 -0
- package/{template → templates}/stream/node-ts/__test__/processor.spec.ts +0 -0
- package/{template → templates}/stream/node-ts/gitignore +0 -0
- package/{template → templates}/stream/node-ts/index.ts +0 -0
- package/{template → templates}/stream/node-ts/lib/processor.ts +0 -0
- package/{template → templates}/stream/node-ts/package.json +1 -1
- package/{template → templates}/stream/node-ts/tsconfig.build.json +0 -0
- package/{template → templates}/stream/node-ts/tsconfig.json +0 -0
- package/templates/stream/python/Makefile +15 -0
- package/templates/stream/python/README.md +31 -0
- package/{template → templates}/stream/python/lambda_function.py +0 -0
- package/{template → templates}/stream/python/requirements.txt +0 -0
- package/{template → templates}/stream/python/test/__init__.py +0 -0
- package/{template → templates}/stream/python/test/app_test.py +0 -0
- package/{template → templates}/task/node/README.md +0 -0
- package/{template → templates}/task/node/__test__/processor.test.js +0 -0
- package/{template → templates}/task/node/gitignore +0 -0
- package/{template → templates}/task/node/index.js +0 -0
- package/{template → templates}/task/node/package.json +1 -1
- package/{template → templates}/task/node/src/processor.js +0 -0
- package/{template → templates}/task/node-ts/README.md +0 -0
- package/{template → templates}/task/node-ts/__test__/processor.spec.ts +0 -0
- package/{template → templates}/task/node-ts/gitignore +0 -0
- package/{template → templates}/task/node-ts/index.ts +0 -0
- package/{template → templates}/task/node-ts/package.json +1 -1
- package/{template → templates}/task/node-ts/src/processor.ts +0 -0
- package/{template → templates}/task/node-ts/tsconfig.build.json +0 -0
- package/{template → templates}/task/node-ts/tsconfig.json +0 -0
- package/templates/task/python/Makefile +15 -0
- package/templates/task/python/README.md +31 -0
- package/{template → templates}/task/python/lambda_function.py +0 -0
- package/{template → templates}/task/python/requirements.txt +0 -0
- package/{template → templates}/task/python/test/__init__.py +0 -0
- package/{template → templates}/task/python/test/app_test.py +0 -0
- package/{template → templates}/ui/js/.env +0 -0
- package/{template → templates}/ui/js/.env.sample +0 -0
- package/{template → templates}/ui/js/.eslintrc +0 -0
- package/{template → templates}/ui/js/.prettierrc +0 -0
- package/{template → templates}/ui/js/README.md +0 -0
- package/{template → templates}/ui/js/config-overrides.js +0 -0
- package/{template → templates}/ui/js/gitignore +0 -0
- package/{template → templates}/ui/js/src/App.css +0 -0
- package/{template → templates}/ui/js/src/App.js +0 -0
- package/{template → templates}/ui/js/src/AppSettings.js +0 -0
- package/{template → templates}/ui/js/src/assets/logo.svg +0 -0
- package/{template → templates}/ui/js/src/constants.js +0 -0
- package/{template → templates}/ui/js/src/index.js +0 -0
- package/{template → templates}/ui/ts/.env +0 -0
- package/{template → templates}/ui/ts/.env.sample +0 -0
- package/{template → templates}/ui/ts/.eslintrc +0 -0
- package/{template → templates}/ui/ts/.prettierrc +0 -0
- package/{template → templates}/ui/ts/README.md +0 -0
- package/{template → templates}/ui/ts/config-overrides.js +0 -0
- package/{template → templates}/ui/ts/gitignore +0 -0
- package/{template → templates}/ui/ts/src/App.css +0 -0
- package/{template → templates}/ui/ts/src/App.tsx +0 -0
- package/{template → templates}/ui/ts/src/AppSettings.tsx +0 -0
- package/{template → templates}/ui/ts/src/assets/logo.svg +0 -0
- package/{template → templates}/ui/ts/src/constants.ts +0 -0
- package/{template → templates}/ui/ts/src/custom.d.ts +0 -0
- package/{template → templates}/ui/ts/src/index.js +0 -0
- package/{template → templates}/ui/ts/tsconfig.json +0 -0
- package/CHANGELOG.md +0 -489
- package/scripts/ui/index.js +0 -7
- package/scripts/ui/releaseAppZip.js +0 -91
- package/scripts/ui/zipAppSource.js +0 -103
- package/template/scheduler/python/README.md +0 -19
- package/template/stream/python/README.md +0 -19
- package/template/task/python/README.md +0 -19
package/README.md
CHANGED
|
@@ -17,41 +17,184 @@ npm i -g @corva/create-app
|
|
|
17
17
|
`corva-create-app` provides a user-friendly CLI wizard to create an app.
|
|
18
18
|
|
|
19
19
|
```sh
|
|
20
|
-
Usage: corva-
|
|
20
|
+
Usage: create-corva-app [options] [command]
|
|
21
|
+
|
|
22
|
+
Options:
|
|
23
|
+
-h, --help display help for command
|
|
24
|
+
|
|
25
|
+
Commands:
|
|
26
|
+
create [options] [project-directory] Create a new app
|
|
27
|
+
zip [options] <project-directory> [patterns...] Bundle app
|
|
28
|
+
release [options] <project-directory> [patterns...] Release app
|
|
29
|
+
help [command] display help for command
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Create an app
|
|
33
|
+
|
|
34
|
+
To create a new app use `create` command.
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
Usage: create-corva-app create <project-directory> [options]
|
|
38
|
+
|
|
39
|
+
Create a new app
|
|
21
40
|
|
|
22
41
|
Arguments:
|
|
23
|
-
project-directory
|
|
42
|
+
project-directory project directory to work with (default: "Current working dir")
|
|
24
43
|
|
|
25
44
|
Options:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
--
|
|
31
|
-
--
|
|
32
|
-
--
|
|
33
|
-
--
|
|
34
|
-
--
|
|
35
|
-
--
|
|
36
|
-
|
|
45
|
+
--developerName [string] Enter the Developer Name (default: "O&G Company")
|
|
46
|
+
--developerIdentifier [string] Enter the Developer Identifier (default: "oandgc")
|
|
47
|
+
--appType [string] Choose the App Type (choices: "ui", "scheduler", "stream", "task", default: "ui")
|
|
48
|
+
--schedulerType [number] Choose the scheduler type (choices: "1", "2", "4", default: 1)
|
|
49
|
+
--cronString [string] Provide CRON string for the scheduler (default: "*/5 * * * *")
|
|
50
|
+
--depthMilestone [number] Provide depth milestone for the scheduler (default: 1)
|
|
51
|
+
--appKey [string] Enter the App Key (default: "app.key-goes-here")
|
|
52
|
+
--appName [string] Enter the App Name
|
|
53
|
+
--description [string] Enter description (default: "This is the description of my app. You can do great things with it!")
|
|
54
|
+
--summary [string] Enter summary (default: "More information about this app goes here")
|
|
55
|
+
--category [string] Enter category (default: "")
|
|
56
|
+
--website [string] Enter website (default: "https://www.oandgexample.com/my-app/")
|
|
57
|
+
--segments [string] Choose segments (choices: "drilling", "completion")
|
|
58
|
+
--runtime [string] Choose runtime (choices: "ui", "nodejs12.x", "nodejs14.x", "python3.8")
|
|
59
|
+
-p, --packageManager [string] Please select the desired package manager (choices: "yarn", "npm", default: "yarn")
|
|
60
|
+
-t, --useTypescript [boolean] Would you like to use TypesScript? (default: false)
|
|
61
|
+
-V, --version output the version number
|
|
62
|
+
-z, --zip [string] DEPRECATED Use zip command instead
|
|
63
|
+
--release DEPRECATED Use release command instead
|
|
64
|
+
--bump-version <string> DEPRECATED Use with zip or release command instead (choices: "major", "minor", "patch", "skip")
|
|
65
|
+
-h, --help display help for command
|
|
37
66
|
```
|
|
38
67
|
|
|
39
|
-
|
|
68
|
+
### Examples
|
|
40
69
|
|
|
41
|
-
|
|
70
|
+
#### Create a UI application
|
|
42
71
|
|
|
43
72
|
```sh
|
|
44
73
|
create-corva-app test --appName "Test" --segments "drilling" --category "wellDesign" --appKey "some-company.test.ui" --appType "ui" --runtime "ui"
|
|
45
74
|
```
|
|
46
75
|
|
|
47
|
-
|
|
76
|
+
#### Create a NodeJs TypeScript application
|
|
48
77
|
|
|
49
78
|
```sh
|
|
50
79
|
create-corva-app test --appName "Test" --segments "drilling" --category "wellDesign" --appKey "some-company.test.scheduler" --appType "scheduler" --runtime "nodejs12.x" -t
|
|
51
80
|
```
|
|
52
81
|
|
|
53
|
-
|
|
82
|
+
#### Create a Python application
|
|
54
83
|
|
|
55
84
|
```sh
|
|
56
85
|
create-corva-app test --appName "Test" --segments "drilling" --category "analytics" --appKey "some-company.test.stream" --appType "stream" --runtime "python3.8"
|
|
57
86
|
```
|
|
87
|
+
|
|
88
|
+
## Zip
|
|
89
|
+
|
|
90
|
+
To create a zip that contains app ready to be deployed to Corva use `zip` command.
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
Usage: create-corva-app zip [options] <project-directory> [patterns...]
|
|
94
|
+
|
|
95
|
+
Bundle app
|
|
96
|
+
|
|
97
|
+
Arguments:
|
|
98
|
+
project-directory Project directory to work with
|
|
99
|
+
patterns Additional patterns to zip (default: [])
|
|
100
|
+
|
|
101
|
+
Options:
|
|
102
|
+
--bump-version <string> bump version (choices: "major", "minor", "patch", "skip")
|
|
103
|
+
-h, --help display help for command
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### What is getting zipped?
|
|
107
|
+
|
|
108
|
+
By default next files will be included.
|
|
109
|
+
|
|
110
|
+
For `frontend` apps:
|
|
111
|
+
|
|
112
|
+
- `manifest.json`
|
|
113
|
+
- `package.json`
|
|
114
|
+
- `yarn.lock`
|
|
115
|
+
- `.npmrc`
|
|
116
|
+
- `config-overrides.js`
|
|
117
|
+
- all files under `src`
|
|
118
|
+
- `tsconfig.json`
|
|
119
|
+
|
|
120
|
+
For apps that written in `node`:
|
|
121
|
+
|
|
122
|
+
- `manifest.json`
|
|
123
|
+
- `package.json`
|
|
124
|
+
- either `package-lock.json` or `yarn.lock`
|
|
125
|
+
- all files under `config` folder
|
|
126
|
+
- all `*.js` files under `src` and `lib` folders (if `typescript` is not used)
|
|
127
|
+
- `tsconfig.json`, `tsconfig.build.json` (if `typescript` is used)
|
|
128
|
+
- all `*.ts` files under `src` and `lib` folders (if `typescript` is used)
|
|
129
|
+
|
|
130
|
+
For apps that written in `python`:
|
|
131
|
+
|
|
132
|
+
- `manifest.json`
|
|
133
|
+
- `requirements.txt`
|
|
134
|
+
- all `*.py` files
|
|
135
|
+
|
|
136
|
+
If you want to zip some files that are not included pass that as `patterns` arguments.
|
|
137
|
+
|
|
138
|
+
### Examples
|
|
139
|
+
|
|
140
|
+
#### Create a zip file from the content of `test-app` folder & put zip file in it.
|
|
141
|
+
|
|
142
|
+
```sh
|
|
143
|
+
create-corva-app zip test-app
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### Create a zip file & automatically bump version
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
create-corva-app zip test-app --bump-version=patch
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### Create a zip file from the content of `test-app` folder with custom content ([globs](<https://en.wikipedia.org/wiki/Glob_(programming)>) are supported)
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
create-corva-app zip test-app some/missing/file1 some/other/missing/file2 all/files/*.glob
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Release
|
|
159
|
+
|
|
160
|
+
To push app to Corva use `release` command.
|
|
161
|
+
|
|
162
|
+
```sh
|
|
163
|
+
Usage: create-corva-app release [options] <project-directory> [patterns...]
|
|
164
|
+
|
|
165
|
+
Release app
|
|
166
|
+
|
|
167
|
+
Arguments:
|
|
168
|
+
project-directory Project directory to work with
|
|
169
|
+
patterns Additional patterns to zip (default: [])
|
|
170
|
+
|
|
171
|
+
Options:
|
|
172
|
+
--bump-version <string> bump version (choices: "major", "minor", "patch", "skip")
|
|
173
|
+
-h, --help display help for command
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Examples
|
|
177
|
+
|
|
178
|
+
#### Make a release with ask for version
|
|
179
|
+
|
|
180
|
+
```sh
|
|
181
|
+
create-corva-app release test-app
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
#### Make a release without version increase
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
create-corva-app release test-app --bump-version=skip
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### Make a release with increased version
|
|
191
|
+
|
|
192
|
+
```sh
|
|
193
|
+
create-corva-app release test-app --bump-version=patch
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### Make a release with custom version
|
|
197
|
+
|
|
198
|
+
```sh
|
|
199
|
+
create-corva-app release test-app --bump-version=4.2.0
|
|
200
|
+
```
|
package/lib/app.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const { Option, InvalidArgumentError } = require('commander');
|
|
2
|
+
const chalk = require('chalk');
|
|
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
|
+
if (this.argChoices.includes(value) || semver.valid(value)) {
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
throw new InvalidArgumentError(
|
|
14
|
+
`Allowed choices are ${this.argChoices
|
|
15
|
+
.map((choice) => `"${choice}"`)
|
|
16
|
+
.join(', ')} or a valid semver version.`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
const bumpVersionOption = new Option(flags, description).choices(choices).argParser(argParser);
|
|
20
|
+
|
|
21
|
+
const bumpVersionOptionDeprecated = new Option(
|
|
22
|
+
flags,
|
|
23
|
+
chalk.bgYellow`DEPRECATED` +
|
|
24
|
+
` Use with ${chalk.cyan`zip`} or ${chalk.cyan`release`} command instead`
|
|
25
|
+
)
|
|
26
|
+
.choices(choices)
|
|
27
|
+
.argParser(argParser);
|
|
28
|
+
|
|
29
|
+
module.exports = { bumpVersionOption, bumpVersionOptionDeprecated };
|
|
@@ -134,14 +134,15 @@ const manifestOptions = (projectName) => [
|
|
|
134
134
|
name: 'cronString',
|
|
135
135
|
message: 'Provide CRON string for the scheduler',
|
|
136
136
|
default: '*/5 * * * *',
|
|
137
|
-
when: (answers) =>
|
|
137
|
+
when: (answers) =>
|
|
138
|
+
answers.schedulerType && answers.schedulerType !== SCHEDULER_TYPE_DEPTH.value,
|
|
138
139
|
},
|
|
139
140
|
{
|
|
140
141
|
name: 'depthMilestone',
|
|
141
142
|
message: 'Provide depth milestone for the scheduler',
|
|
142
143
|
default: 1,
|
|
143
144
|
when: (answers) => answers.schedulerType === SCHEDULER_TYPE_DEPTH.value,
|
|
144
|
-
filter: (value) => (isNaN(value) ? value : Number(value))
|
|
145
|
+
filter: (value) => (isNaN(value) ? value : Number(value)),
|
|
145
146
|
},
|
|
146
147
|
{
|
|
147
148
|
name: 'appKey',
|
|
@@ -196,6 +197,7 @@ const manifestOptions = (projectName) => [
|
|
|
196
197
|
type: 'rawlist',
|
|
197
198
|
name: 'packageManager',
|
|
198
199
|
message: 'Please select the desired package manager',
|
|
200
|
+
alias: 'p',
|
|
199
201
|
default: 'yarn',
|
|
200
202
|
choices: ['yarn', 'npm'],
|
|
201
203
|
when: (answers) => !answers.runtime || !answers.runtime.startsWith(TEMPLATE_TYPES.PYTHON),
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
|
|
3
|
+
const SUCCESS_ICON = ' ✅ \n';
|
|
4
|
+
const ERROR_ICON = ' ❌ \n';
|
|
5
|
+
|
|
6
|
+
const RELEASE = {
|
|
7
|
+
createZip: 'Creating zip archive...\n',
|
|
8
|
+
createZipError: 'Could not create zip archive.',
|
|
9
|
+
createZipSuccess: `Zip archive has been created ${SUCCESS_ICON}`,
|
|
10
|
+
getAuthToken: 'Reading auth token...',
|
|
11
|
+
getAuthTokenError: `Could not find auth token. For UI app please run ${chalk.cyan`yarn start`} and login to Corva to fetch it.`,
|
|
12
|
+
getAppKey: 'Reading app key...',
|
|
13
|
+
getAppKeyError: "Could not find app key. Please make sure it's defined in manifest.json",
|
|
14
|
+
uploadApp: 'Uploading app...',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
module.exports = {
|
|
18
|
+
RELEASE,
|
|
19
|
+
SUCCESS_ICON,
|
|
20
|
+
ERROR_ICON,
|
|
21
|
+
};
|
|
@@ -38,9 +38,9 @@ const tsDependencies = {
|
|
|
38
38
|
const scripts = {
|
|
39
39
|
build: 'webpack --config=./config-overrides.js --mode production',
|
|
40
40
|
start: 'webpack-dev-server --config=./config-overrides.js --open --mode development',
|
|
41
|
-
zip: 'create-corva-app
|
|
41
|
+
zip: 'create-corva-app zip .',
|
|
42
42
|
lint: 'eslint --cache ./src/',
|
|
43
|
-
release: 'create-corva-app
|
|
43
|
+
release: 'create-corva-app release .',
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
module.exports = {
|
package/lib/flow.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const { SUCCESS_ICON } = require('./constants/messages');
|
|
5
|
+
const { resolve, sep } = require('path');
|
|
6
|
+
|
|
7
|
+
const debug = require('debug')('cca:flow');
|
|
8
|
+
|
|
9
|
+
const runFlow = async (flow, context, indent = '') => {
|
|
10
|
+
process.stdout.write(
|
|
11
|
+
`${indent}Running ${chalk.cyan(flow.name)} in ${chalk.cyan(resolve(context.dirName).split(sep).pop())}\n`
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const result = await runSteps(flow.steps, context, indent + ' ');
|
|
15
|
+
|
|
16
|
+
process.stdout.write(`${indent}Done!` + SUCCESS_ICON);
|
|
17
|
+
|
|
18
|
+
return result;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const runSteps = async (steps = [], context = {}, indent = '') => {
|
|
22
|
+
for (const step of steps) {
|
|
23
|
+
if (step.name) {
|
|
24
|
+
const result = await runFlow(step, context, indent);
|
|
25
|
+
|
|
26
|
+
Object.assign(context, result);
|
|
27
|
+
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const message = indent + step.message;
|
|
32
|
+
|
|
33
|
+
process.stdout.write(message);
|
|
34
|
+
debug('Context: %o', context);
|
|
35
|
+
|
|
36
|
+
const result = await step.fn(context);
|
|
37
|
+
|
|
38
|
+
Object.assign(context, result);
|
|
39
|
+
|
|
40
|
+
process.stdout.write(SUCCESS_ICON);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return context;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
module.exports = { runFlow };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const archiver = require('archiver');
|
|
2
|
+
const debug = require('debug')('cca:zip');
|
|
3
|
+
const { promises: fs, createWriteStream } = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const createZipArchive = async (dirName, zipName, itemsToZip = []) => {
|
|
7
|
+
const filePath = path.resolve(dirName, zipName);
|
|
8
|
+
const archive = archiver.create('zip', {});
|
|
9
|
+
const output = createWriteStream(filePath);
|
|
10
|
+
// pipe archive data to the file
|
|
11
|
+
archive.pipe(output);
|
|
12
|
+
|
|
13
|
+
await new Promise(async (resolve, reject) => {
|
|
14
|
+
output.once('close', resolve).once('end', function () {
|
|
15
|
+
debug('Data has been drained');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
archive.on('warning', function (err) {
|
|
19
|
+
if (err.code === 'ENOENT') {
|
|
20
|
+
console.warn(err.message);
|
|
21
|
+
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
throw err;
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
archive.once('error', reject);
|
|
29
|
+
|
|
30
|
+
const dataToZip = await getDataToZip(itemsToZip, dirName);
|
|
31
|
+
|
|
32
|
+
for (const item of dataToZip) {
|
|
33
|
+
if (item.isDir) {
|
|
34
|
+
debug(`Adding directory %s -> %s`, item.path, item.name);
|
|
35
|
+
archive.directory(item.path, item.name);
|
|
36
|
+
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
debug(`Adding file %s -> %s`, item.path, item.name);
|
|
41
|
+
archive.file(item.path, { name: item.name });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
archive.finalize();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return archive.pointer();
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const getDataToZip = async (itemsToZip, dirName) => {
|
|
51
|
+
const promises = itemsToZip.map(async (name) => {
|
|
52
|
+
const nameWasProvided = typeof name === 'string';
|
|
53
|
+
const filePath = nameWasProvided ? path.resolve(dirName, name) : name.path;
|
|
54
|
+
const fileName = nameWasProvided ? name : name.name;
|
|
55
|
+
|
|
56
|
+
const { exists, isDir } = await fs
|
|
57
|
+
.lstat(filePath)
|
|
58
|
+
.then((stat) => ({ exists: true, isDir: stat.isDirectory() }))
|
|
59
|
+
.catch(() => {
|
|
60
|
+
debug(`%s location not exist, filtering it out`, filePath);
|
|
61
|
+
|
|
62
|
+
return { exists: false, isDir: false };
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
name: fileName,
|
|
67
|
+
path: filePath,
|
|
68
|
+
exists,
|
|
69
|
+
isDir,
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
const allData = await Promise.all(promises);
|
|
73
|
+
|
|
74
|
+
return allData.filter((f) => f.exists);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
module.exports = { createZipArchive };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const { resolve } = require('path');
|
|
2
|
+
const { promises: fs } = require('fs');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
|
|
5
|
+
const debug = require('debug')('cca:json');
|
|
6
|
+
|
|
7
|
+
const loadJson = async (dirName, fileName) => {
|
|
8
|
+
const fullPath = resolve(dirName, fileName);
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
debug('Loading file %s', fullPath);
|
|
12
|
+
const manifest = await fs.readFile(fullPath, 'utf8');
|
|
13
|
+
|
|
14
|
+
return JSON.parse(manifest);
|
|
15
|
+
} catch (e) {
|
|
16
|
+
if (e.code === 'ENOENT') {
|
|
17
|
+
throw new Error(`${fileName} was not found in ${resolve(dirName)}`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
throw e;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const saveJson = async (dirName, fileName, data) => {
|
|
25
|
+
return fs.writeFile(resolve(dirName, fileName), JSON.stringify(data, null, 2) + os.EOL);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
module.exports = { loadJson, saveJson };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const { APP_TYPES, APP_RUNTIMES } = require('../../constants/cli');
|
|
2
|
+
|
|
3
|
+
const NODE_RUNTIMES = [APP_RUNTIMES.NODE12, APP_RUNTIMES.NODE14];
|
|
4
|
+
|
|
5
|
+
class Manifest {
|
|
6
|
+
constructor(manifest) {
|
|
7
|
+
this.manifest = manifest;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
get runtime() {
|
|
11
|
+
return this.manifest.settings.runtime;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
isNode() {
|
|
15
|
+
return NODE_RUNTIMES.includes(this.manifest.settings.runtime);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
isUi() {
|
|
19
|
+
return this.manifest.application.type === APP_TYPES.UI;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
isJs() {
|
|
23
|
+
return this.isUi() || this.isNode();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
isPython() {
|
|
27
|
+
return this.manifest.settings.runtime === APP_RUNTIMES.PYTHON3;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = { Manifest };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const { PREPARE_FLOW } = require('./prepare');
|
|
2
|
+
const { GET_APP_KEY_STEP } = require('./steps/release-get-app-key');
|
|
3
|
+
const { GET_RELEASE_CONFIG_STEP } = require('./steps/release-get-config');
|
|
4
|
+
const { UPLOAD_ZIP_TO_CORVA_STEP } = require('./steps/release-upload-zip-to-corva');
|
|
5
|
+
const { ZIP_SIMPLE_FLOW } = require('./zip-simple');
|
|
6
|
+
|
|
7
|
+
const RELEASE_FLOW = {
|
|
8
|
+
name: 'release',
|
|
9
|
+
steps: [
|
|
10
|
+
PREPARE_FLOW,
|
|
11
|
+
GET_RELEASE_CONFIG_STEP,
|
|
12
|
+
GET_APP_KEY_STEP,
|
|
13
|
+
ZIP_SIMPLE_FLOW,
|
|
14
|
+
UPLOAD_ZIP_TO_CORVA_STEP,
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
module.exports = { RELEASE_FLOW };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const { loadJson } = require('../lib/json');
|
|
2
|
+
const { Manifest } = require('../lib/manifest');
|
|
3
|
+
|
|
4
|
+
const LOAD_APP_FILES_STEP = {
|
|
5
|
+
message: "Loading Corva app's files...",
|
|
6
|
+
async fn(context) {
|
|
7
|
+
const manifest =
|
|
8
|
+
context.manifest || new Manifest(await loadJson(context.dirName, 'manifest.json'));
|
|
9
|
+
const pkg =
|
|
10
|
+
context.package || (manifest.isJs() && (await loadJson(context.dirName, 'package.json')));
|
|
11
|
+
|
|
12
|
+
return { pkg, manifest };
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
LOAD_APP_FILES_STEP,
|
|
18
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const { RELEASE } = require('../../constants/messages');
|
|
2
|
+
|
|
3
|
+
const GET_APP_KEY_STEP = {
|
|
4
|
+
message: RELEASE.getAppKey,
|
|
5
|
+
fn: ({ manifest }) => {
|
|
6
|
+
const appKey = manifest.manifest.application.key;
|
|
7
|
+
|
|
8
|
+
if (!appKey) {
|
|
9
|
+
throw new Error(RELEASE.getAppKeyError);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return { appKey };
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
module.exports = { GET_APP_KEY_STEP };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const { RELEASE } = require('../../constants/messages');
|
|
2
|
+
const { promises: fs } = require('fs');
|
|
3
|
+
const dotenv = require('dotenv');
|
|
4
|
+
const { resolve } = require('path');
|
|
5
|
+
const { StepError } = require('../lib/step-error');
|
|
6
|
+
|
|
7
|
+
const GET_RELEASE_CONFIG_STEP = {
|
|
8
|
+
message: RELEASE.getAuthToken,
|
|
9
|
+
fn: async ({ dirName }) => {
|
|
10
|
+
const env = await fs.readFile(resolve(dirName, '.env')).catch((e) => {
|
|
11
|
+
if (e.code === 'ENOENT') {
|
|
12
|
+
throw new StepError('Mising .env file', { cause: e });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
throw e;
|
|
16
|
+
});
|
|
17
|
+
const { CORVA_API_ENV, AUTH_TOKEN } = dotenv.parse(env);
|
|
18
|
+
|
|
19
|
+
if (!AUTH_TOKEN) {
|
|
20
|
+
throw new StepError(RELEASE.getAuthTokenError);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
CORVA_API_ENV: CORVA_API_ENV || 'production',
|
|
25
|
+
AUTH_TOKEN,
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
module.exports = { GET_RELEASE_CONFIG_STEP };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const { RELEASE } = require('../../constants/messages');
|
|
2
|
+
const axios = require('axios');
|
|
3
|
+
const FormData = require('form-data');
|
|
4
|
+
const { resolve } = require('path');
|
|
5
|
+
const { createReadStream } = require('fs');
|
|
6
|
+
const { StepError } = require('../lib/step-error');
|
|
7
|
+
const { get } = require('lodash/fp');
|
|
8
|
+
|
|
9
|
+
const UPLOAD_ZIP_TO_CORVA_STEP = {
|
|
10
|
+
message: RELEASE.uploadApp,
|
|
11
|
+
fn: async ({ zipFileName, appKey, CORVA_API_ENV, AUTH_TOKEN, dirName }) => {
|
|
12
|
+
const form = new FormData();
|
|
13
|
+
|
|
14
|
+
form.append('package', createReadStream(resolve(dirName, zipFileName)), 'archive.zip');
|
|
15
|
+
|
|
16
|
+
const baseURL = `https://api${
|
|
17
|
+
CORVA_API_ENV === 'production' ? '' : `.${CORVA_API_ENV}`
|
|
18
|
+
}.corva.ai`;
|
|
19
|
+
const uploadURL = `${baseURL}/v2/apps/${appKey}/packages/upload`;
|
|
20
|
+
|
|
21
|
+
await axios
|
|
22
|
+
.post(uploadURL, form, {
|
|
23
|
+
headers: { ...form.getHeaders(), Authorization: `Bearer ${AUTH_TOKEN}` },
|
|
24
|
+
})
|
|
25
|
+
.catch((e) => {
|
|
26
|
+
throw new StepError(
|
|
27
|
+
`${get('response.data.message', e) || ''} \nPOST: ${uploadURL} failed.`,
|
|
28
|
+
{ cause: e }
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
module.exports = { UPLOAD_ZIP_TO_CORVA_STEP };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const { promises: fs } = require('fs');
|
|
2
|
+
const { resolve } = require('path');
|
|
3
|
+
|
|
4
|
+
const debug = require('debug')('cca:flow:zip:cleanup');
|
|
5
|
+
|
|
6
|
+
const CLEANUP_STEP = {
|
|
7
|
+
message: 'Removing temporary files...',
|
|
8
|
+
fn: async ({ itemsToRemove, dirName }) => {
|
|
9
|
+
for (const item of itemsToRemove) {
|
|
10
|
+
debug('Removing %s', item);
|
|
11
|
+
|
|
12
|
+
await fs.unlink(resolve(dirName, item));
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
module.exports = { CLEANUP_STEP };
|