@corva/create-app 0.22.0-0 → 0.23.0-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [0.23.0-2](https://github.com/corva-ai/create-corva-app/compare/v0.23.0-1...v0.23.0-2) (2022-02-21)
6
+
7
+
8
+ ### Features
9
+
10
+ * **DC-3051:** run release command for all app types ([5f7a2d8](https://github.com/corva-ai/create-corva-app/commit/5f7a2d850f29c903cf2c4cb6f83c63192519c192))
11
+
12
+ ## [0.23.0-1](https://github.com/corva-ai/create-corva-app/compare/v0.23.0-0...v0.23.0-1) (2022-02-17)
13
+
14
+
15
+ ### Features
16
+
17
+ * **DC-2291:** add release script to FE dc apps ([fe1bda2](https://github.com/corva-ai/create-corva-app/commit/fe1bda29aa2b68d6912894353d731e73aadeb47b))
18
+
19
+ ## [0.23.0-0](https://github.com/corva-ai/create-corva-app/compare/v0.22.0-0...v0.23.0-0) (2022-02-15)
20
+
5
21
  ## [0.22.0-0](https://github.com/corva-ai/create-corva-app/compare/v0.21.0-2...v0.22.0-0) (2022-02-01)
6
22
 
7
23
  ## [0.21.0-2](https://github.com/corva-ai/create-corva-app/compare/v0.21.0-1...v0.21.0-2) (2022-01-25)
@@ -40,6 +40,7 @@ const scripts = {
40
40
  start: 'webpack-dev-server --config=./config-overrides.js --open --mode development',
41
41
  zip: 'create-corva-app --zip ui',
42
42
  lint: 'eslint --cache ./src/',
43
+ release: 'create-corva-app --release',
43
44
  };
44
45
 
45
46
  module.exports = {
package/index.js CHANGED
@@ -34,29 +34,30 @@ const shouldUseYarn = () => packageManager === YARN_EXECUTABLE;
34
34
  const getLockFileName = (manager) =>
35
35
  manager === YARN_EXECUTABLE ? 'yarn.lock' : 'package-lock.json';
36
36
 
37
- clear();
38
-
39
37
  let projectName;
40
38
  let program;
41
39
 
42
40
  function startingMessage() {
41
+ clear();
43
42
  console.log(chalk.green(' Welcome to apps generator for:'));
44
43
  console.log(chalk.cyan(figlet.textSync('CORVA.AI', { horizontalLayout: 'full' })));
45
44
  }
46
45
 
47
46
  function checkNodeVersion() {
48
- console.log('Checking node version...');
47
+ process.stdout.write('Checking node version...');
48
+
49
49
  const unsupportedNodeVersion = !semver.satisfies(process.version, '>=10');
50
50
  if (unsupportedNodeVersion) {
51
51
  console.log(
52
52
  chalk.red(
53
- `You are using Node ${process.version}.\n\n` +
54
- `Please update to Node 10 or higher for a better, fully supported experience.\n`
53
+ `\nYou are using Node ${process.version}.\n\n` +
54
+ `Please update to Node 10 or higher for a better, fully supported experience.\n`
55
55
  )
56
56
  );
57
57
  // Fall back to latest supported react-scripts on Node 4
58
58
  return process.exit(1);
59
59
  }
60
+ process.stdout.write(' ✅ \n');
60
61
  }
61
62
 
62
63
  function checkOptions(opts) {
@@ -78,8 +79,6 @@ function checkOptions(opts) {
78
79
  }
79
80
 
80
81
  async function initialChecks() {
81
- startingMessage();
82
-
83
82
  program = new commander.Command('corva-create-app')
84
83
  .version(packageJson.version)
85
84
  .argument('[project-directory]', 'project directory to work with')
@@ -88,6 +87,7 @@ async function initialChecks() {
88
87
  projectName = name;
89
88
  })
90
89
  .option('-z, --zip <type>', 'zip app source')
90
+ .option('--release', 'release app')
91
91
  .addOption(
92
92
  new commander.Option(`-p, --packageManager [string]`, 'package manager to use')
93
93
  .default(YARN_EXECUTABLE)
@@ -96,7 +96,11 @@ async function initialChecks() {
96
96
 
97
97
  manifestConstants.manifestOptions(projectName).forEach((value) => {
98
98
  const type = typeof value.default;
99
- const option = new commander.Option(`${value.alias ? `-${value.alias}, ` : ''}--${value.name} [${type !== 'undefined' && type || 'string'}]`, value.message);
99
+ const option = new commander.Option(
100
+ `${value.alias ? `-${value.alias}, ` : ''}--${value.name} [${(type !== 'undefined' && type) ||
101
+ 'string'}]`,
102
+ value.message
103
+ );
100
104
 
101
105
  if (value.choices) {
102
106
  if (typeof value.choices === 'function') {
@@ -109,7 +113,7 @@ async function initialChecks() {
109
113
  }
110
114
 
111
115
  if (type === 'number') {
112
- option.argParser(Number)
116
+ option.argParser(Number);
113
117
  }
114
118
 
115
119
  program.addOption(option);
@@ -125,13 +129,16 @@ async function initialChecks() {
125
129
  useTypescript = opts.useTypescript || useTypescript;
126
130
 
127
131
  if (opts.zip) {
128
- if (opts.zip === APP_RUNTIMES.UI) {
129
- return uiScripts.zipAppSource(shouldUseYarn());
130
- }
131
-
132
+ if (opts.zip === APP_RUNTIMES.UI) return uiScripts.zipAppSource();
133
+ process.exit(0);
134
+ }
135
+ if (opts.release) {
136
+ return uiScripts.releaseAppZip();
132
137
  process.exit(0);
133
138
  }
134
139
 
140
+ startingMessage();
141
+
135
142
  if (!projectName) {
136
143
  console.error('Please specify the project directory:');
137
144
  console.log(` ${chalk.cyan(program.name())} ${chalk.green('<project-directory>')}`);
@@ -356,6 +363,9 @@ async function helpCommands() {
356
363
  console.log(chalk.cyan(` ${displayedCommand} ${useYarn ? '' : 'run '}zip`));
357
364
  console.log(' Bundles the app into ZIP file in app root directory');
358
365
  console.log();
366
+ console.log(chalk.cyan(` ${displayedCommand} ${useYarn ? '' : 'run '}release`));
367
+ console.log(' Uploads the app ZIP to Corva');
368
+ console.log();
359
369
  }
360
370
 
361
371
  initialChecks();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corva/create-app",
3
- "version": "0.22.0-0",
3
+ "version": "0.23.0-2",
4
4
  "private": false,
5
5
  "description": "Create app to use it in CORVA.AI",
6
6
  "keywords": [
@@ -33,12 +33,15 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "archiver": "^5.3.0",
36
+ "axios": "^0.25.0",
36
37
  "chalk": "4.1.0",
37
38
  "commander": "^8.2.0",
38
39
  "conventional-changelog-cli": "^2.1.0",
39
40
  "cross-spawn": "7.0.3",
41
+ "dotenv": "^16.0.0",
40
42
  "envinfo": "7.5.1",
41
43
  "figlet": "^1.5.0",
44
+ "form-data": "^4.0.0",
42
45
  "fs-extra": "9.0.1",
43
46
  "hyperquest": "2.1.3",
44
47
  "inquirer": "7.3.2",
@@ -1,5 +1,7 @@
1
1
  const zipAppSource = require('./zipAppSource');
2
+ const releaseAppZip = require('./releaseAppZip');
2
3
 
3
4
  module.exports = {
4
5
  zipAppSource,
6
+ releaseAppZip,
5
7
  };
@@ -0,0 +1,90 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const axios = require('axios');
4
+ const FormData = require('form-data');
5
+ const chalk = require('chalk');
6
+ const dotenv = require('dotenv');
7
+ const get = require('lodash').get;
8
+ const zipAppSource = require('./zipAppSource');
9
+
10
+ const SUCCESS_ICON = ' ✅ \n';
11
+ const ERROR_ICON = ' ❌ \n';
12
+
13
+ const CONSOLE_MESSAGES = {
14
+ createZip: 'Creating zip archive...',
15
+ createZipError: 'Could not create zip archive.',
16
+ getAuthToken: 'Reading auth token...',
17
+ getAuthTokenError: `Could not find auth token. Please run ${chalk.cyan(
18
+ 'yarn start'
19
+ )} and login to Corva`,
20
+ getAppKey: 'Reading app key...',
21
+ getAppKeyError: "Could not find app key. Please make sure it's defined in manifest.json",
22
+ uploadApp: 'Uploading app...',
23
+ };
24
+
25
+ function handleError(e, message) {
26
+ process.stdout.write(ERROR_ICON);
27
+ message && console.log(chalk.red(message));
28
+ console.error(chalk.red(e));
29
+ process.exit(1);
30
+ }
31
+
32
+ async function releaseAppZip() {
33
+ const dirname = process.cwd();
34
+
35
+ // Read auth token
36
+ let authToken;
37
+ let corvaAPIEnv = 'production';
38
+ try {
39
+ process.stdout.write(CONSOLE_MESSAGES.getAuthToken);
40
+ const env = await fs.promises.readFile(path.resolve(dirname, './.env'));
41
+ const config = dotenv.parse(env);
42
+ authToken = config.AUTH_TOKEN;
43
+ if (!authToken) throw new Error('No auth token.');
44
+ if (config.CORVA_API_ENV) corvaAPIEnv = config.CORVA_API_ENV;
45
+ process.stdout.write(SUCCESS_ICON);
46
+ } catch (e) {
47
+ handleError(e, CONSOLE_MESSAGES.getAuthTokenError);
48
+ }
49
+
50
+ // Read app key
51
+ let appKey;
52
+ try {
53
+ process.stdout.write(CONSOLE_MESSAGES.getAppKey);
54
+ const manifest = JSON.parse(
55
+ await fs.promises.readFile(path.resolve(dirname, './manifest.json'))
56
+ );
57
+ appKey = manifest.application.key;
58
+ if (!appKey) throw new Error('No app key.');
59
+ process.stdout.write(SUCCESS_ICON);
60
+ } catch (e) {
61
+ handleError(e, CONSOLE_MESSAGES.getAppKeyError);
62
+ }
63
+
64
+ // Zip archive
65
+ let zipPath;
66
+ try {
67
+ process.stdout.write(CONSOLE_MESSAGES.createZip);
68
+ zipPath = await zipAppSource({ silent: true });
69
+ process.stdout.write(SUCCESS_ICON);
70
+ } catch (e) {
71
+ handleError(e, CONSOLE_MESSAGES.createZipError);
72
+ }
73
+
74
+ let uploadURL;
75
+ try {
76
+ process.stdout.write(CONSOLE_MESSAGES.uploadApp);
77
+ const form = new FormData();
78
+ form.append('package', fs.createReadStream(zipPath), 'archive.zip');
79
+ const baseURL = `https://api${corvaAPIEnv === 'production' ? '' : `.${corvaAPIEnv}`}.corva.ai`;
80
+ uploadURL = `${baseURL}/v2/apps/${appKey}/packages/upload`;
81
+ await axios.post(uploadURL, form, {
82
+ headers: { ...form.getHeaders(), Authorization: `Bearer ${authToken}` },
83
+ });
84
+ process.stdout.write(SUCCESS_ICON);
85
+ } catch (e) {
86
+ handleError(e, `${get(e, 'response.data.message', '')} \nPOST: ${uploadURL} failed.`);
87
+ }
88
+ }
89
+
90
+ module.exports = releaseAppZip;
@@ -4,17 +4,18 @@ const archiver = require('archiver');
4
4
  const os = require('os');
5
5
  const chalk = require('chalk');
6
6
  const semverInc = require('semver/functions/inc');
7
+ const noop = require('lodash').noop;
7
8
 
8
9
  const { warnIfOutdated } = require('../utils/version');
9
10
 
10
- async function compressAppToZip(useYarn) {
11
+ async function compressAppToZip({ silent = false }={}) {
12
+ const log = silent ? noop : console.log;
11
13
  warnIfOutdated();
12
14
 
13
15
  const dirname = process.cwd();
14
16
 
15
17
  // Left only build script for package json;
16
18
  const packageJsonContent = fs.readFileSync(path.resolve(dirname, 'package.json'), 'utf-8');
17
-
18
19
  const packageJson = JSON.parse(packageJsonContent);
19
20
 
20
21
  const updatedVersion = semverInc(packageJson.version, 'patch');
@@ -27,7 +28,8 @@ async function compressAppToZip(useYarn) {
27
28
  },
28
29
  };
29
30
 
30
- const zipPath = path.resolve(path.resolve(dirname, `${packageJson.name}-${updatedVersion}.zip`));
31
+ const zipFileName = `${packageJson.name}-${updatedVersion}.zip`;
32
+ const zipPath = path.resolve(path.resolve(dirname, zipFileName));
31
33
 
32
34
  var archive = archiver.create('zip', {});
33
35
  var output = fs.createWriteStream(zipPath);
@@ -35,8 +37,8 @@ async function compressAppToZip(useYarn) {
35
37
  // pipe archive data to the file
36
38
  archive.pipe(output);
37
39
 
38
- output.on('close', function () {
39
- console.log(`Created ${zipPath.replace(dirname + '/', '')}, ${archive.pointer()} bytes written\n`);
40
+ output.on('close', function() {
41
+ log(`Created ${zipPath.replace(dirname + '/', '')}, ${archive.pointer()} bytes written\n`);
40
42
 
41
43
  // clean up temp package.json file
42
44
  try {
@@ -47,19 +49,19 @@ async function compressAppToZip(useYarn) {
47
49
  }
48
50
  });
49
51
 
50
- output.on('end', function () {
51
- console.log('Data has been drained');
52
+ output.on('end', function() {
53
+ log('Data has been drained');
52
54
  });
53
55
 
54
- archive.on('warning', function (err) {
56
+ archive.on('warning', function(err) {
55
57
  if (err.code === 'ENOENT') {
56
- console.log(err.message);
58
+ log(err.message);
57
59
  } else {
58
60
  throw err;
59
61
  }
60
62
  });
61
63
 
62
- archive.on('error', function (err) {
64
+ archive.on('error', function(err) {
63
65
  throw err;
64
66
  });
65
67
 
@@ -68,7 +70,7 @@ async function compressAppToZip(useYarn) {
68
70
  JSON.stringify({ ...packageJson, version: updatedVersion }, null, 2) + os.EOL
69
71
  );
70
72
 
71
- console.log(
73
+ log(
72
74
  chalk(`
73
75
  NOTE: Version of your app was updated to ${updatedVersion} (package.json), please don't lower it.
74
76
  `)
@@ -83,26 +85,22 @@ async function compressAppToZip(useYarn) {
83
85
  name: 'package.json',
84
86
  });
85
87
 
86
- [
87
- 'manifest.json',
88
- 'config-overrides.js',
89
- 'tsconfig.json',
90
- '.npmrc',
91
- useYarn ? 'yarn.lock' : 'package-lock.json',
92
- ].forEach((name) => {
93
- const file = path.resolve(dirname, name);
94
-
95
- // not all app templates have the tsconfig, archive will raise an error with missing files, have to filter-out that
96
- if (!fs.existsSync(file)) {
97
- return;
98
- }
88
+ ['manifest.json', 'config-overrides.js', 'tsconfig.json', '.npmrc', 'yarn.lock'].forEach(
89
+ (name) => {
90
+ const file = path.resolve(dirname, name);
99
91
 
100
- archive.file(file, { name })
101
- });
92
+ // not all app templates have the tsconfig, archive will raise an error with missing files, have to filter-out that
93
+ if (!fs.existsSync(file)) return;
94
+
95
+ archive.file(file, { name });
96
+ }
97
+ );
102
98
 
103
99
  archive.directory(path.resolve(dirname, 'src'), 'src');
104
100
 
105
- archive.finalize();
101
+ await archive.finalize();
102
+ log(zipPath);
103
+ return zipPath;
106
104
  }
107
105
 
108
106
  module.exports = compressAppToZip;
@@ -3,5 +3,5 @@
3
3
  "compilerOptions": {
4
4
  "noEmit": false,
5
5
  "strict": false
6
- },
6
+ }
7
7
  }