@corva/create-app 0.27.0-rc.0 → 0.28.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.
Files changed (128) hide show
  1. package/README.md +160 -17
  2. package/bin/create-corva-app.js +5 -0
  3. package/lib/app.js +9 -0
  4. package/lib/bump-version.option.js +29 -0
  5. package/{constants → lib/constants}/cli.js +1 -0
  6. package/{constants → lib/constants}/manifest.js +4 -12
  7. package/lib/constants/messages.js +21 -0
  8. package/{constants → lib/constants}/package.js +2 -2
  9. package/lib/flow.js +46 -0
  10. package/lib/flows/lib/create-zip-archive.js +77 -0
  11. package/lib/flows/lib/json.js +28 -0
  12. package/lib/flows/lib/manifest.js +31 -0
  13. package/lib/flows/lib/step-error.js +12 -0
  14. package/lib/flows/prepare.js +8 -0
  15. package/lib/flows/release.js +18 -0
  16. package/lib/flows/steps/prepare-load-app-files.js +18 -0
  17. package/lib/flows/steps/release-get-app-key.js +16 -0
  18. package/lib/flows/steps/release-get-config.js +30 -0
  19. package/lib/flows/steps/release-upload-zip-to-corva.js +34 -0
  20. package/lib/flows/steps/zip-cleanup.js +17 -0
  21. package/lib/flows/steps/zip-create-archive.js +15 -0
  22. package/lib/flows/steps/zip-file-list-resolve.js +185 -0
  23. package/lib/flows/steps/zip-prepare.js +21 -0
  24. package/lib/flows/steps/zip.js +15 -0
  25. package/lib/flows/zip-simple.js +8 -0
  26. package/lib/flows/zip.js +9 -0
  27. package/{helpers → lib/helpers}/manifest.js +11 -13
  28. package/{helpers → lib/helpers}/utils.js +0 -0
  29. package/{helpers → lib/helpers}/versioning.js +0 -0
  30. package/{index.js → lib/index.js} +165 -52
  31. package/{scripts → lib/scripts}/utils/version.js +49 -26
  32. package/package.json +13 -8
  33. package/{template → templates}/scheduler/node/README.md +0 -0
  34. package/{template → templates}/scheduler/node/__test__/processor.test.js +0 -0
  35. package/{template → templates}/scheduler/node/gitignore +0 -0
  36. package/{template → templates}/scheduler/node/index.js +0 -0
  37. package/{template → templates}/scheduler/node/package.json +1 -1
  38. package/{template → templates}/scheduler/node/src/processor.js +0 -0
  39. package/{template → templates}/scheduler/node-ts/README.md +0 -0
  40. package/{template → templates}/scheduler/node-ts/__test__/processor.spec.ts +0 -0
  41. package/{template → templates}/scheduler/node-ts/gitignore +0 -0
  42. package/{template → templates}/scheduler/node-ts/index.ts +0 -0
  43. package/templates/scheduler/node-ts/lib/processor.js +16 -0
  44. package/templates/scheduler/node-ts/lib/processor.js.map +1 -0
  45. package/{template → templates}/scheduler/node-ts/lib/processor.ts +0 -0
  46. package/{template → templates}/scheduler/node-ts/package.json +1 -1
  47. package/{template → templates}/scheduler/node-ts/tsconfig.build.json +0 -0
  48. package/{template → templates}/scheduler/node-ts/tsconfig.json +0 -0
  49. package/templates/scheduler/python/Makefile +15 -0
  50. package/templates/scheduler/python/README.md +31 -0
  51. package/{template → templates}/scheduler/python/lambda_function.py +0 -0
  52. package/{template → templates}/scheduler/python/requirements.txt +0 -0
  53. package/{template → templates}/scheduler/python/test/__init__.py +0 -0
  54. package/{template → templates}/scheduler/python/test/app_test.py +0 -0
  55. package/{template → templates}/stream/node/README.md +0 -0
  56. package/{template → templates}/stream/node/__test__/processor.test.js +0 -0
  57. package/{template → templates}/stream/node/gitignore +0 -0
  58. package/{template → templates}/stream/node/index.js +0 -0
  59. package/{template → templates}/stream/node/package.json +1 -1
  60. package/{template → templates}/stream/node/src/processor.js +0 -0
  61. package/{template → templates}/stream/node-ts/README.md +0 -0
  62. package/{template → templates}/stream/node-ts/__test__/processor.spec.ts +0 -0
  63. package/{template → templates}/stream/node-ts/gitignore +0 -0
  64. package/{template → templates}/stream/node-ts/index.ts +0 -0
  65. package/{template → templates}/stream/node-ts/lib/processor.ts +0 -0
  66. package/{template → templates}/stream/node-ts/package.json +1 -1
  67. package/{template → templates}/stream/node-ts/tsconfig.build.json +0 -0
  68. package/{template → templates}/stream/node-ts/tsconfig.json +0 -0
  69. package/templates/stream/python/Makefile +15 -0
  70. package/templates/stream/python/README.md +31 -0
  71. package/{template → templates}/stream/python/lambda_function.py +0 -0
  72. package/{template → templates}/stream/python/requirements.txt +0 -0
  73. package/{template → templates}/stream/python/test/__init__.py +0 -0
  74. package/{template → templates}/stream/python/test/app_test.py +0 -0
  75. package/{template → templates}/task/node/README.md +0 -0
  76. package/{template → templates}/task/node/__test__/processor.test.js +0 -0
  77. package/{template → templates}/task/node/gitignore +0 -0
  78. package/{template → templates}/task/node/index.js +0 -0
  79. package/{template → templates}/task/node/package.json +1 -1
  80. package/{template → templates}/task/node/src/processor.js +0 -0
  81. package/{template → templates}/task/node-ts/README.md +0 -0
  82. package/{template → templates}/task/node-ts/__test__/processor.spec.ts +0 -0
  83. package/{template → templates}/task/node-ts/gitignore +0 -0
  84. package/{template → templates}/task/node-ts/index.ts +0 -0
  85. package/{template → templates}/task/node-ts/package.json +1 -1
  86. package/{template → templates}/task/node-ts/src/processor.ts +0 -0
  87. package/{template → templates}/task/node-ts/tsconfig.build.json +0 -0
  88. package/{template → templates}/task/node-ts/tsconfig.json +0 -0
  89. package/templates/task/python/Makefile +15 -0
  90. package/templates/task/python/README.md +31 -0
  91. package/{template → templates}/task/python/lambda_function.py +0 -0
  92. package/{template → templates}/task/python/requirements.txt +0 -0
  93. package/{template → templates}/task/python/test/__init__.py +0 -0
  94. package/{template → templates}/task/python/test/app_test.py +0 -0
  95. package/{template → templates}/ui/js/.env +0 -0
  96. package/{template → templates}/ui/js/.env.sample +0 -0
  97. package/{template → templates}/ui/js/.eslintrc +0 -0
  98. package/{template → templates}/ui/js/.prettierrc +0 -0
  99. package/{template → templates}/ui/js/README.md +0 -0
  100. package/{template → templates}/ui/js/config-overrides.js +0 -0
  101. package/{template → templates}/ui/js/gitignore +0 -0
  102. package/{template → templates}/ui/js/src/App.css +0 -0
  103. package/{template → templates}/ui/js/src/App.js +0 -0
  104. package/{template → templates}/ui/js/src/AppSettings.js +0 -0
  105. package/{template → templates}/ui/js/src/assets/logo.svg +0 -0
  106. package/{template → templates}/ui/js/src/constants.js +0 -0
  107. package/{template → templates}/ui/js/src/index.js +0 -0
  108. package/{template → templates}/ui/ts/.env +0 -0
  109. package/{template → templates}/ui/ts/.env.sample +0 -0
  110. package/{template → templates}/ui/ts/.eslintrc +0 -0
  111. package/{template → templates}/ui/ts/.prettierrc +0 -0
  112. package/{template → templates}/ui/ts/README.md +0 -0
  113. package/{template → templates}/ui/ts/config-overrides.js +0 -0
  114. package/{template → templates}/ui/ts/gitignore +0 -0
  115. package/{template → templates}/ui/ts/src/App.css +0 -0
  116. package/{template → templates}/ui/ts/src/App.tsx +0 -0
  117. package/{template → templates}/ui/ts/src/AppSettings.tsx +0 -0
  118. package/{template → templates}/ui/ts/src/assets/logo.svg +0 -0
  119. package/{template → templates}/ui/ts/src/constants.ts +0 -0
  120. package/{template → templates}/ui/ts/src/custom.d.ts +0 -0
  121. package/{template → templates}/ui/ts/src/index.js +0 -0
  122. package/{template → templates}/ui/ts/tsconfig.json +0 -0
  123. package/scripts/ui/index.js +0 -7
  124. package/scripts/ui/releaseAppZip.js +0 -91
  125. package/scripts/ui/zipAppSource.js +0 -103
  126. package/template/scheduler/python/README.md +0 -19
  127. package/template/stream/python/README.md +0 -19
  128. package/template/task/python/README.md +0 -19
@@ -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 };
@@ -0,0 +1,15 @@
1
+ const { createZipArchive } = require('../lib/create-zip-archive');
2
+ const debug = require('debug')('cca:flow:zip:archive');
3
+
4
+ const CREATE_ARCHIVE_STEP = {
5
+ message: 'Creating archive...',
6
+ fn: async ({ itemsToZip, zipFileName, dirName }) => {
7
+ debug(`Zipping %d items to %s`, itemsToZip.length, zipFileName);
8
+
9
+ const bytes = await createZipArchive(dirName, zipFileName, itemsToZip);
10
+
11
+ debug(`Created %s with %d items (%d bytes)`, zipFileName, itemsToZip.length, bytes);
12
+ },
13
+ };
14
+
15
+ module.exports = { CREATE_ARCHIVE_STEP };
@@ -0,0 +1,185 @@
1
+ const { set } = require('lodash/fp');
2
+ const { resolve } = require('path');
3
+ const { promises: fs } = require('fs');
4
+ const Glob = require('glob');
5
+ const chalk = require('chalk');
6
+ const isGlob = require('is-glob');
7
+ const { promisify } = require('util');
8
+ const { getIncreasedVersion } = require('../../scripts/utils/version');
9
+ const { loadJson } = require('../lib/json');
10
+ const { StepError } = require('../lib/step-error');
11
+
12
+ const glob = promisify(Glob);
13
+ const debug = require('debug')('cca:flow:zip:resolve');
14
+
15
+ const uniqueValues = (array) => Array.from(new Set(array));
16
+
17
+ const FILE_LIST_RESOLVE_STEP = {
18
+ message: 'Resolving files list...',
19
+ fn: async (context) => {
20
+ const { patterns, manifest, dirName } = context;
21
+ const files = await transformPatternsIntoFileNames(dirName, patterns);
22
+
23
+ if (manifest.isUi()) {
24
+ return resolveDataToZipUiApp(files, context);
25
+ }
26
+
27
+ if (manifest.isNode()) {
28
+ return resolveDataForZipNodeJsApp(files, context);
29
+ }
30
+
31
+ if (manifest.isPython()) {
32
+ return resolveDataForZipPythonApp(files, context);
33
+ }
34
+
35
+ throw new Error(`Unsupported runtime: ${manifest.runtime}`);
36
+ },
37
+ };
38
+
39
+ const transformPatternsIntoFileNames = async (dirName, patterns) => {
40
+ const filesFromPatterns = [];
41
+
42
+ for (const pattern of patterns) {
43
+ if (pattern.includes('node_modules')) {
44
+ debug('Invalid file pattern', pattern);
45
+
46
+ continue;
47
+ }
48
+
49
+ if (!isGlob(pattern, { strict: false })) {
50
+ filesFromPatterns.push(pattern);
51
+
52
+ continue;
53
+ }
54
+
55
+ const files = await glob(pattern, { cwd: dirName, ignore: '**/node_modules' });
56
+
57
+ filesFromPatterns.push(...files);
58
+ }
59
+
60
+ return filesFromPatterns;
61
+ };
62
+
63
+ const resolveDataToZipUiApp = async (itemsToZip = [], { options, pkg, dirName }) => {
64
+ const version = await getIncreasedVersion(pkg.version, options);
65
+ const zipFileName = `${pkg.name}-${version}.zip`;
66
+ const itemsToSave = [];
67
+ const shouldUpdateVersion = version !== pkg.version;
68
+
69
+ if (shouldUpdateVersion) {
70
+ pkg.version = version;
71
+
72
+ itemsToSave.push({
73
+ name: 'package.json',
74
+ content: pkg,
75
+ message: chalk(
76
+ `\n${chalk.yellow`NOTE`}: Version of your app was updated to ${version} (package.json), please don't lower it.`
77
+ ),
78
+ });
79
+ }
80
+
81
+ itemsToSave.push({
82
+ name: 'packageForSource.json',
83
+ content: set(
84
+ 'scripts',
85
+ {
86
+ build: 'webpack --config=./config-overrides.js --mode production',
87
+ },
88
+ pkg
89
+ ),
90
+ });
91
+
92
+ const itemsToRemove = ['packageForSource.json'];
93
+
94
+ itemsToZip.push(
95
+ 'manifest.json',
96
+ 'config-overrides.js',
97
+ 'tsconfig.json',
98
+ '.npmrc',
99
+ 'yarn.lock',
100
+ { path: resolve(dirName, 'packageForSource.json'), name: 'package.json' },
101
+ 'src'
102
+ );
103
+
104
+ return {
105
+ zipFileName,
106
+ itemsToZip,
107
+ itemsToSave,
108
+ itemsToRemove,
109
+ };
110
+ };
111
+
112
+ const resolveDataForZipNodeJsApp = async (itemsToZip = [], { options, pkg, dirName }) => {
113
+ const version = await getIncreasedVersion(pkg.version, options);
114
+ const zipFileName = `${pkg.name}-${version}.zip`;
115
+ const itemsToSave = [];
116
+ const shouldUpdateVersion = version !== pkg.version;
117
+
118
+ if (shouldUpdateVersion) {
119
+ pkg.version = version;
120
+
121
+ itemsToSave.push({
122
+ name: 'package.json',
123
+ content: pkg,
124
+ message: chalk(
125
+ `\n${chalk.yellow`NOTE`}: Version of your app was updated to ${version} (package.json), please don't lower it.`
126
+ ),
127
+ });
128
+ }
129
+
130
+ const packageDirContent = await fs.readdir(dirName);
131
+ const shouldPushDefaultSrc = !itemsToZip.length;
132
+
133
+ itemsToZip.push('config', 'manifest.json', 'package.json');
134
+
135
+ if (packageDirContent.includes('package-lock.json')) {
136
+ itemsToZip.push('package-lock.json');
137
+
138
+ if (shouldUpdateVersion) {
139
+ itemsToSave.push({
140
+ name: 'package-lock.json',
141
+ content: set('version', version, await loadJson(dirName, 'package-lock.json')),
142
+ });
143
+ }
144
+ } else if (packageDirContent.includes('yarn.lock')) {
145
+ itemsToZip.push('yarn.lock');
146
+ } else {
147
+ throw new StepError(`No lock file found in ${dirName}`);
148
+ }
149
+
150
+ if (packageDirContent.includes('tsconfig.json')) {
151
+ itemsToZip.push('tsconfig.json', 'tsconfig.build.json');
152
+
153
+ if (shouldPushDefaultSrc) {
154
+ itemsToZip.push('index.ts', ...(await glob('+(src|lib)/**/*.ts', { cwd: dirName })));
155
+ }
156
+ } else if (shouldPushDefaultSrc) {
157
+ itemsToZip.push('index.js', ...(await glob('+(src|lib)/**/*.js', { cwd: dirName })));
158
+ }
159
+
160
+ return {
161
+ zipFileName,
162
+ itemsToZip: uniqueValues(itemsToZip),
163
+ itemsToSave,
164
+ itemsToRemove: [],
165
+ };
166
+ };
167
+
168
+ const resolveDataForZipPythonApp = async (itemsToZip = [], { manifest, dirName }) => {
169
+ const zipFileName = `${manifest.manifest.application.name}.zip`;
170
+
171
+ if (!itemsToZip.length) {
172
+ itemsToZip.push(...(await glob('**/*.py', { cwd: dirName })));
173
+ }
174
+
175
+ itemsToZip.push('manifest.json', 'requirements.txt');
176
+
177
+ return {
178
+ zipFileName,
179
+ itemsToZip: uniqueValues(itemsToZip),
180
+ itemsToSave: [],
181
+ itemsToRemove: [],
182
+ };
183
+ };
184
+
185
+ module.exports = { FILE_LIST_RESOLVE_STEP };
@@ -0,0 +1,21 @@
1
+ const { saveJson } = require('../lib/json');
2
+
3
+ const debug = require('debug')('cca:flow:zip:prepare');
4
+
5
+ const PREPARE_FILES_BEFORE_ZIP_STEP = {
6
+ message: 'Preparing...',
7
+ fn: async ({ itemsToSave, dirName }) => {
8
+ for (const item of itemsToSave) {
9
+ debug(`Updating %s`, item.name);
10
+ await saveJson(dirName, item.name, item.content);
11
+
12
+ if (item.message) {
13
+ process.stdout.write(item.message);
14
+ }
15
+ }
16
+ },
17
+ };
18
+
19
+ module.exports = {
20
+ PREPARE_FILES_BEFORE_ZIP_STEP,
21
+ };
@@ -0,0 +1,15 @@
1
+ const { CLEANUP_STEP } = require('./zip-cleanup');
2
+ const { CREATE_ARCHIVE_STEP } = require('./zip-create-archive');
3
+ const { FILE_LIST_RESOLVE_STEP } = require('./zip-file-list-resolve');
4
+ const { PREPARE_FILES_BEFORE_ZIP_STEP } = require('./zip-prepare');
5
+
6
+ const ZIP_STEPS = [
7
+ FILE_LIST_RESOLVE_STEP,
8
+ PREPARE_FILES_BEFORE_ZIP_STEP,
9
+ CREATE_ARCHIVE_STEP,
10
+ CLEANUP_STEP,
11
+ ];
12
+
13
+ module.exports = {
14
+ ZIP_STEPS,
15
+ };
@@ -0,0 +1,8 @@
1
+ const { ZIP_STEPS } = require('./steps/zip');
2
+
3
+ const ZIP_SIMPLE_FLOW = {
4
+ name: 'zip (simple)',
5
+ steps: ZIP_STEPS,
6
+ };
7
+
8
+ module.exports = { ZIP_SIMPLE_FLOW };
@@ -0,0 +1,9 @@
1
+ const { PREPARE_FLOW } = require('./prepare');
2
+ const { ZIP_STEPS } = require('./steps/zip');
3
+
4
+ const ZIP_FLOW = {
5
+ name: 'zip',
6
+ steps: [PREPARE_FLOW, ...ZIP_STEPS],
7
+ };
8
+
9
+ module.exports = { ZIP_FLOW };
@@ -34,11 +34,11 @@ function fillManifest(answers) {
34
34
  settings: {
35
35
  ...defaultManifestProperties.settings,
36
36
  runtime,
37
- ...defaultAppSettings({
37
+ app: defaultAppSettings({
38
38
  type: answers.appType,
39
39
  schedulerType: answers.schedulerType,
40
40
  cronString: answers.cronString,
41
- depthMilestone: answers.depthMilestone
41
+ depthMilestone: answers.depthMilestone,
42
42
  }),
43
43
  },
44
44
  };
@@ -63,19 +63,17 @@ function defaultAppSettings({ type, schedulerType, cronString, depthMilestone })
63
63
  return {};
64
64
  }
65
65
 
66
- const schedulerAppSettings =
67
- schedulerType === manifestConstants.SCHEDULER_TYPE_DEPTH.value
68
- ? manifestConstants.defaultDepthSchedulerSettings
69
- : manifestConstants.defaultTimeSchedulerSettings;
66
+ if (schedulerType === manifestConstants.SCHEDULER_TYPE_DEPTH.value) {
67
+ return {
68
+ scheduler_type: schedulerType,
69
+ depth_milestone: depthMilestone || 1
70
+ }
71
+ }
70
72
 
71
73
  return {
72
- app: {
73
- ...schedulerAppSettings,
74
- scheduler_type: schedulerType,
75
- cron_string: cronString,
76
- depth_milestone: depthMilestone
77
- },
78
- };
74
+ scheduler_type: schedulerType,
75
+ cron_string: cronString || '*/5 * * * *',
76
+ }
79
77
  }
80
78
 
81
79
  module.exports = {
File without changes
File without changes
@@ -4,15 +4,18 @@
4
4
 
5
5
  const chalk = require('chalk');
6
6
  const figlet = require('figlet');
7
- const commander = require('commander');
7
+ const { Command, CommanderError, Option } = require('commander');
8
8
  const fs = require('fs-extra');
9
9
  const inquirer = require('inquirer');
10
10
  const os = require('os');
11
11
  const path = require('path');
12
12
  const semver = require('semver');
13
13
 
14
- const uiScripts = require('./scripts/ui');
15
- const { ensureLatestVersion } = require('./scripts/utils/version');
14
+ const {
15
+ ensureLatestVersion,
16
+ warnIfOutdated,
17
+ ensureBumpVersion,
18
+ } = require('./scripts/utils/version');
16
19
  const utils = require('./helpers/utils.js');
17
20
  const manifestHelpers = require('./helpers/manifest.js');
18
21
  const versioning = require('./helpers/versioning.js');
@@ -20,10 +23,16 @@ const versioning = require('./helpers/versioning.js');
20
23
  const packageConstants = require('./constants/package.js');
21
24
  const manifestConstants = require('./constants/manifest.js');
22
25
 
23
- const packageJson = require('./package.json');
26
+ const packageJson = require('../package.json');
24
27
  const { clear } = require('console');
25
28
  const spawn = require('cross-spawn');
26
29
  const { APP_RUNTIMES, TEMPLATE_TYPES, APP_TYPES } = require('./constants/cli');
30
+ const { runFlow } = require('./flow');
31
+ const { ERROR_ICON } = require('./constants/messages');
32
+ const { StepError } = require('./flows/lib/step-error');
33
+ const { RELEASE_FLOW } = require('./flows/release');
34
+ const { ZIP_FLOW } = require('./flows/zip');
35
+ const { bumpVersionOptionDeprecated, bumpVersionOption } = require('./bump-version.option');
27
36
 
28
37
  const YARN_EXECUTABLE = 'yarn';
29
38
 
@@ -78,26 +87,31 @@ function checkOptions(opts) {
78
87
  };
79
88
  }
80
89
 
90
+ const printDeprecationNotice = (param) =>
91
+ console.warn(
92
+ chalk.bgYellowBright`DEPRECATED OPTION: ${param}` +
93
+ ` Use ${chalk.cyan(`create-corva-app ${param} .`)} instead`
94
+ );
95
+
81
96
  async function initialChecks() {
82
- program = new commander.Command('corva-create-app')
83
- .version(packageJson.version)
84
- .argument('[project-directory]', 'project directory to work with')
85
- .usage(`${chalk.green('<project-directory>')} [options]`)
86
- .action((name) => {
87
- projectName = name;
97
+ program = new Command()
98
+ .hook('preAction', async () => {
99
+ checkNodeVersion();
100
+
101
+ await warnIfOutdated();
88
102
  })
89
- .option('-z, --zip <type>', 'zip app source')
90
- .option('--bump-version [string]', 'bump version')
91
- .option('--release', 'release app')
92
- .addOption(
93
- new commander.Option(`-p, --packageManager [string]`, 'package manager to use')
94
- .default(YARN_EXECUTABLE)
95
- .choices(['npm', YARN_EXECUTABLE])
96
- );
103
+ .configureOutput({ writeErr: () => undefined })
104
+ .exitOverride();
105
+
106
+ const createCommand = program
107
+ .command('create', { isDefault: true })
108
+ .description('Create a new app')
109
+ .argument('[project-directory]', 'project directory to work with', process.cwd())
110
+ .usage(`${chalk.green('<project-directory>')} [options]`);
97
111
 
98
112
  manifestConstants.manifestOptions(projectName).forEach((value) => {
99
113
  const type = typeof value.default;
100
- const option = new commander.Option(
114
+ const option = new Option(
101
115
  `${value.alias ? `-${value.alias}, ` : ''}--${value.name} [${
102
116
  (type !== 'undefined' && type) || 'string'
103
117
  }]`,
@@ -118,46 +132,145 @@ async function initialChecks() {
118
132
  option.argParser(Number);
119
133
  }
120
134
 
121
- program.addOption(option);
135
+ if (type !== 'undefined') {
136
+ option.default(value.default);
137
+ }
138
+
139
+ createCommand.addOption(option);
122
140
  });
123
141
 
124
- program.parse(process.argv);
142
+ createCommand
143
+ .version(packageJson.version)
144
+ .addOption(
145
+ new Option(
146
+ '-z, --zip [string]',
147
+ chalk.bgYellow`DEPRECATED` + ` Use ${chalk.cyan`zip`} command instead`
148
+ )
149
+ )
150
+ .addOption(
151
+ new Option(
152
+ '--release',
153
+ chalk.bgYellow`DEPRECATED` + ` Use ${chalk.cyan`release`} command instead`
154
+ )
155
+ )
156
+ .addOption(bumpVersionOptionDeprecated);
125
157
 
126
- checkNodeVersion();
158
+ createCommand.action(async (dirName, options) => {
159
+ projectName = dirName;
160
+ packageManager = options.packageManager || packageManager;
161
+ useTypescript = options.useTypescript || useTypescript;
127
162
 
128
- const opts = program.opts();
163
+ if (options.zip || options.release) {
164
+ options.bumpVersion = await ensureBumpVersion(options.bumpVersion);
165
+ }
129
166
 
130
- packageManager = opts.packageManager || packageManager;
131
- useTypescript = opts.useTypescript || useTypescript;
167
+ if (options.zip) {
168
+ printDeprecationNotice('zip');
169
+
170
+ return runFlow(ZIP_FLOW, { dirName, patterns: [], options });
171
+ }
172
+
173
+ if (options.release) {
174
+ printDeprecationNotice('release');
175
+
176
+ return runFlow(RELEASE_FLOW, { dirName, patterns: [], options });
177
+ }
178
+
179
+ startingMessage();
180
+
181
+ // NOTE: Default action
182
+ await createApp(options);
183
+ });
184
+
185
+ program
186
+ .command('zip')
187
+ .description('Bundle app')
188
+ .argument('<project-directory>', 'Project directory to work with')
189
+ .argument('[patterns...]', 'Additional patterns to zip', [])
190
+ .addOption(bumpVersionOption)
191
+ .action(async (dirName, patterns, options) => {
192
+ options.bumpVersion = await ensureBumpVersion(options.bumpVersion);
193
+
194
+ return runFlow(ZIP_FLOW, { dirName, patterns, options });
195
+ });
196
+
197
+ program
198
+ .command('release')
199
+ .description('Release app')
200
+ .argument('<project-directory>', 'Project directory to work with')
201
+ .argument('[patterns...]', 'Additional patterns to zip', [])
202
+ .addOption(bumpVersionOption)
203
+ .action(async (dirName, patterns, options) => {
204
+ options.bumpVersion = await ensureBumpVersion(options.bumpVersion);
205
+
206
+ return runFlow(RELEASE_FLOW, { dirName, patterns, options });
207
+ });
132
208
 
133
- if (opts.zip) {
134
- if (opts.zip === APP_RUNTIMES.UI)
135
- return uiScripts.zipAppSource({
136
- bumpVersion: opts.bumpVersion,
137
- });
138
- process.exit(0);
209
+ try {
210
+ await program.parseAsync(process.argv);
211
+ } catch (e) {
212
+ handleError(e);
213
+
214
+ process.exit(1);
139
215
  }
140
- if (opts.release) {
141
- return uiScripts.releaseAppZip({ bumpVersion: opts.bumpVersion });
142
- process.exit(0);
216
+ }
217
+
218
+ const handleError = (e) => {
219
+ if (e instanceof CommanderError) {
220
+ handleCommanderError(e);
221
+
222
+ return;
143
223
  }
144
224
 
145
- startingMessage();
225
+ process.stdout.write(ERROR_ICON);
146
226
 
147
- if (!projectName) {
148
- console.error('Please specify the project directory:');
149
- console.log(` ${chalk.cyan(program.name())} ${chalk.green('<project-directory>')}`);
150
- console.log();
151
- console.log('For example:');
152
- console.log(` ${chalk.cyan(program.name())} ${chalk.green('my-react-app')}`);
153
- console.log();
154
- console.log(`Run ${chalk.cyan(`${program.name()} --help`)} to see all options.`);
155
- process.exit(1);
227
+ if (!(e instanceof StepError)) {
228
+ console.error(chalk.red(e));
229
+
230
+ return;
156
231
  }
157
232
 
158
- // NOTE: Default action
159
- await createApp(opts);
160
- }
233
+ console.log(chalk.red(e.message));
234
+ e.cause && console.error(chalk.red(e.cause));
235
+ };
236
+
237
+ const handleCommanderError = (e) => {
238
+ switch (e.code) {
239
+ case 'commander.missingArgument': {
240
+ const match = /error:.*'(.*)'/.exec(e.message);
241
+
242
+ if (match && match[1] === 'project-directory') {
243
+ const commandName = program.args[0] || program._defaultCommandName;
244
+
245
+ console.error('Please specify the project directory:');
246
+ console.log(
247
+ ` ${chalk.cyan(program.name())} ${commandName} ${chalk.green('<project-directory>')}`
248
+ );
249
+ console.log();
250
+ console.log('For example:');
251
+ console.log(
252
+ ` ${chalk.cyan(program.name())} ${commandName} ${chalk.green('my-react-app')}`
253
+ );
254
+ console.log();
255
+ console.log(
256
+ `Run ${chalk.cyan(`${program.name()} help ${commandName}`)} to see all options.`
257
+ );
258
+ } else {
259
+ console.error('❌', e.message);
260
+ }
261
+
262
+ break;
263
+ }
264
+ case 'commander.help':
265
+ case 'commander.helpDisplayed': {
266
+ // ignore
267
+ break;
268
+ }
269
+ default: {
270
+ console.error('❌', e.message);
271
+ }
272
+ }
273
+ };
161
274
 
162
275
  async function initPackage(manifest) {
163
276
  const appType = manifest.application.type;
@@ -201,7 +314,7 @@ async function createApp(opts) {
201
314
  console.log(`${key} : ${values[key]}`);
202
315
  });
203
316
 
204
- const manifest = manifestHelpers.fillManifest(values);
317
+ const manifest = manifestHelpers.fillManifest(opts);
205
318
 
206
319
  await initPackage(manifest);
207
320
  } else {
@@ -224,7 +337,7 @@ function addTemplate(root, appType, runtime) {
224
337
  console.log(chalk.green('Copying app template...'));
225
338
  console.log();
226
339
 
227
- const templateFolder = path.resolve(__dirname, 'template', appType, runtime);
340
+ const templateFolder = path.resolve(__dirname, '..', 'templates', appType, runtime);
228
341
 
229
342
  utils.copyFolderRecursiveSync(templateFolder, root, runtime);
230
343
 
@@ -260,7 +373,7 @@ function patchSchedulerForPython(root, appType, runtime, manifest) {
260
373
  return;
261
374
  }
262
375
 
263
- const templateFolder = path.resolve(__dirname, 'template', appType, runtime);
376
+ const templateFolder = path.resolve(__dirname, '..', 'templates', appType, runtime);
264
377
  const originalType = 'ScheduledDataTimeEvent';
265
378
  const replacementType =
266
379
  schedulerType === manifestConstants.SCHEDULER_TYPE_DEPTH.value
@@ -291,7 +404,7 @@ function addPackageJSON(root, appName) {
291
404
  }
292
405
 
293
406
  function updatePackageJSON(root, description, appType, runtime) {
294
- const templateFolder = path.resolve(__dirname, 'template', appType, runtime);
407
+ const templateFolder = path.resolve(__dirname, '..', 'templates', appType, runtime);
295
408
 
296
409
  let packageJson = JSON.parse(fs.readFileSync(path.join(templateFolder, 'package.json'), 'utf-8'));
297
410
 
@@ -331,7 +444,7 @@ function installJsApp(appPath, appType) {
331
444
  .toString('utf8')
332
445
  .split('\n')
333
446
  // NOTE: filter out warnings caused by @corva/ui peer dependencies
334
- .filter(line => !line.includes('@corva/ui'))
447
+ .filter((line) => !line.includes('@corva/ui'))
335
448
  .join('\n');
336
449
  console.log(error);
337
450
  }