@corva/create-app 0.28.0-0 → 0.28.0-3

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 (126) 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 +5 -13
  7. package/lib/constants/messages.js +21 -0
  8. package/lib/constants/package.js +161 -0
  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 +47 -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/lib/helpers/resolve-app-runtime.js +29 -0
  29. package/{helpers → lib/helpers}/utils.js +17 -17
  30. package/{helpers → lib/helpers}/versioning.js +0 -0
  31. package/lib/index.js +502 -0
  32. package/{scripts → lib/scripts}/utils/version.js +49 -26
  33. package/package.json +13 -8
  34. package/{template/scheduler/node → templates/javascript/scheduler}/README.md +0 -0
  35. package/{template/scheduler/node → templates/javascript/scheduler}/__test__/processor.test.js +0 -0
  36. package/{template/scheduler/node → templates/javascript/scheduler}/index.js +0 -0
  37. package/{template/scheduler/node → templates/javascript/scheduler}/src/processor.js +0 -0
  38. package/{template/stream/node → templates/javascript/stream}/README.md +0 -0
  39. package/{template/stream/node → templates/javascript/stream}/__test__/processor.test.js +0 -0
  40. package/{template/stream/node → templates/javascript/stream}/index.js +0 -0
  41. package/{template/stream/node → templates/javascript/stream}/src/processor.js +0 -0
  42. package/{template/task/node → templates/javascript/task}/README.md +0 -0
  43. package/{template/task/node → templates/javascript/task}/__test__/processor.test.js +0 -0
  44. package/{template/task/node → templates/javascript/task}/index.js +0 -0
  45. package/{template/task/node → templates/javascript/task}/src/processor.js +0 -0
  46. package/{template/ui/js → templates/javascript/ui}/.env +0 -0
  47. package/{template/ui/js → templates/javascript/ui}/.env.sample +0 -0
  48. package/{template/ui/js → templates/javascript/ui}/.eslintrc +0 -0
  49. package/{template/ui/js → templates/javascript/ui}/.prettierrc +0 -0
  50. package/{template/ui/js → templates/javascript/ui}/README.md +0 -0
  51. package/{template/ui/js → templates/javascript/ui}/config-overrides.js +0 -0
  52. package/{template/ui/js → templates/javascript/ui}/gitignore +0 -0
  53. package/{template/ui/js → templates/javascript/ui}/src/App.css +0 -0
  54. package/{template/ui/js → templates/javascript/ui}/src/App.js +0 -0
  55. package/{template/ui/js → templates/javascript/ui}/src/AppSettings.js +0 -0
  56. package/{template/ui/js → templates/javascript/ui}/src/assets/logo.svg +0 -0
  57. package/{template/ui/js → templates/javascript/ui}/src/constants.js +0 -0
  58. package/{template/ui/js → templates/javascript/ui}/src/index.js +0 -0
  59. package/templates/python/scheduler/README.md +31 -0
  60. package/{template/scheduler/python → templates/python/scheduler}/lambda_function.py +0 -0
  61. package/{template/scheduler/python → templates/python/scheduler}/test/__init__.py +0 -0
  62. package/{template/scheduler/python → templates/python/scheduler}/test/app_test.py +0 -0
  63. package/templates/python/stream/README.md +31 -0
  64. package/{template/stream/python → templates/python/stream}/lambda_function.py +0 -0
  65. package/{template/stream/python → templates/python/stream}/test/__init__.py +0 -0
  66. package/{template/stream/python → templates/python/stream}/test/app_test.py +0 -0
  67. package/templates/python/task/README.md +31 -0
  68. package/{template/task/python → templates/python/task}/lambda_function.py +0 -0
  69. package/{template/task/python → templates/python/task}/test/__init__.py +0 -0
  70. package/{template/task/python → templates/python/task}/test/app_test.py +0 -0
  71. package/{template/scheduler/node-ts → templates/typescript/scheduler}/README.md +0 -0
  72. package/{template/scheduler/node-ts → templates/typescript/scheduler}/__test__/processor.spec.ts +0 -0
  73. package/{template/scheduler/node-ts → templates/typescript/scheduler}/index.ts +0 -0
  74. package/{template/scheduler/node-ts → templates/typescript/scheduler}/lib/processor.ts +0 -0
  75. package/{template/stream/node-ts → templates/typescript/stream}/README.md +0 -0
  76. package/{template/stream/node-ts → templates/typescript/stream}/__test__/processor.spec.ts +0 -0
  77. package/{template/stream/node-ts → templates/typescript/stream}/index.ts +0 -0
  78. package/{template/stream/node-ts → templates/typescript/stream}/lib/processor.ts +0 -0
  79. package/{template/task/node-ts → templates/typescript/task}/README.md +0 -0
  80. package/{template/task/node-ts → templates/typescript/task}/__test__/processor.spec.ts +0 -0
  81. package/{template/task/node-ts → templates/typescript/task}/index.ts +0 -0
  82. package/{template/task/node-ts → templates/typescript/task}/src/processor.ts +0 -0
  83. package/{template/ui/ts → templates/typescript/ui}/.env +0 -0
  84. package/{template/ui/ts → templates/typescript/ui}/.env.sample +0 -0
  85. package/{template/ui/ts → templates/typescript/ui}/.eslintrc +0 -0
  86. package/{template/ui/ts → templates/typescript/ui}/.prettierrc +0 -0
  87. package/{template/ui/ts → templates/typescript/ui}/README.md +0 -0
  88. package/{template/ui/ts → templates/typescript/ui}/config-overrides.js +0 -0
  89. package/{template/ui/ts → templates/typescript/ui}/gitignore +0 -0
  90. package/{template/ui/ts → templates/typescript/ui}/src/App.css +0 -0
  91. package/{template/ui/ts → templates/typescript/ui}/src/App.tsx +0 -0
  92. package/{template/ui/ts → templates/typescript/ui}/src/AppSettings.tsx +0 -0
  93. package/{template/ui/ts → templates/typescript/ui}/src/assets/logo.svg +0 -0
  94. package/{template/ui/ts → templates/typescript/ui}/src/constants.ts +0 -0
  95. package/{template/ui/ts → templates/typescript/ui}/src/custom.d.ts +0 -0
  96. package/{template/ui/ts → templates/typescript/ui}/src/index.js +0 -0
  97. package/{template/ui/ts → templates/typescript/ui}/tsconfig.json +0 -0
  98. package/constants/package.js +0 -50
  99. package/index.js +0 -386
  100. package/scripts/ui/index.js +0 -7
  101. package/scripts/ui/releaseAppZip.js +0 -91
  102. package/scripts/ui/zipAppSource.js +0 -103
  103. package/template/scheduler/node/gitignore +0 -21
  104. package/template/scheduler/node/package.json +0 -17
  105. package/template/scheduler/node-ts/gitignore +0 -25
  106. package/template/scheduler/node-ts/package.json +0 -37
  107. package/template/scheduler/node-ts/tsconfig.build.json +0 -11
  108. package/template/scheduler/node-ts/tsconfig.json +0 -34
  109. package/template/scheduler/python/README.md +0 -19
  110. package/template/scheduler/python/requirements.txt +0 -2
  111. package/template/stream/node/gitignore +0 -21
  112. package/template/stream/node/package.json +0 -17
  113. package/template/stream/node-ts/gitignore +0 -25
  114. package/template/stream/node-ts/package.json +0 -37
  115. package/template/stream/node-ts/tsconfig.build.json +0 -11
  116. package/template/stream/node-ts/tsconfig.json +0 -34
  117. package/template/stream/python/README.md +0 -19
  118. package/template/stream/python/requirements.txt +0 -2
  119. package/template/task/node/gitignore +0 -21
  120. package/template/task/node/package.json +0 -17
  121. package/template/task/node-ts/gitignore +0 -25
  122. package/template/task/node-ts/package.json +0 -37
  123. package/template/task/node-ts/tsconfig.build.json +0 -11
  124. package/template/task/node-ts/tsconfig.json +0 -34
  125. package/template/task/python/README.md +0 -19
  126. package/template/task/python/requirements.txt +0 -2
package/lib/index.js ADDED
@@ -0,0 +1,502 @@
1
+ #!/usr/bin/env node
2
+
3
+ 'use strict';
4
+
5
+ const chalk = require('chalk');
6
+ const figlet = require('figlet');
7
+ const { Command, CommanderError, Option } = require('commander');
8
+ const fs = require('fs-extra');
9
+ const inquirer = require('inquirer');
10
+ const os = require('os');
11
+ const path = require('path');
12
+ const semver = require('semver');
13
+
14
+ const {
15
+ ensureLatestVersion,
16
+ warnIfOutdated,
17
+ ensureBumpVersion,
18
+ } = require('./scripts/utils/version');
19
+ const utils = require('./helpers/utils.js');
20
+ const manifestHelpers = require('./helpers/manifest.js');
21
+ const versioning = require('./helpers/versioning.js');
22
+
23
+ const { getDefaultsForPackageJson } = require('./constants/package.js');
24
+ const manifestConstants = require('./constants/manifest.js');
25
+
26
+ const packageJson = require('../package.json');
27
+ const { clear } = require('console');
28
+ const spawn = require('cross-spawn');
29
+ const { runFlow } = require('./flow');
30
+ const { ERROR_ICON } = require('./constants/messages');
31
+ const { StepError } = require('./flows/lib/step-error');
32
+ const { RELEASE_FLOW } = require('./flows/release');
33
+ const { ZIP_FLOW } = require('./flows/zip');
34
+ const { bumpVersionOptionDeprecated, bumpVersionOption } = require('./bump-version.option');
35
+ const { Manifest } = require('./flows/lib/manifest');
36
+ const { resolveAppRuntime } = require('./helpers/resolve-app-runtime');
37
+
38
+ const writejsonOptions = {
39
+ spaces: 2,
40
+ EOL: os.EOL
41
+ };
42
+
43
+ function startingMessage() {
44
+ clear();
45
+ console.log(chalk.green(' Welcome to apps generator for:'));
46
+ console.log(chalk.cyan(figlet.textSync('CORVA.AI', { horizontalLayout: 'full' })));
47
+ }
48
+
49
+ function checkNodeVersion() {
50
+ process.stdout.write('Checking node version...');
51
+
52
+ const unsupportedNodeVersion = !semver.satisfies(process.version, '>=10');
53
+ if (unsupportedNodeVersion) {
54
+ console.log(
55
+ chalk.red(
56
+ `\nYou are using Node ${process.version}.\n\n` +
57
+ `Please update to Node 10 or higher for a better, fully supported experience.\n`
58
+ )
59
+ );
60
+ // Fall back to latest supported react-scripts on Node 4
61
+ return process.exit(1);
62
+ }
63
+ process.stdout.write(' ✅ \n');
64
+ }
65
+
66
+ function checkOptions(opts) {
67
+ let isValid = true;
68
+ const values = {};
69
+
70
+ manifestConstants.getManifestMandatoryKeys(opts).forEach((key) => {
71
+ if (!opts[key]) {
72
+ isValid = false;
73
+ }
74
+
75
+ values[key] = opts[key];
76
+ });
77
+
78
+ return {
79
+ isValid,
80
+ values,
81
+ };
82
+ }
83
+
84
+ const printDeprecationNotice = (param) =>
85
+ console.warn(
86
+ chalk.bgYellowBright`DEPRECATED OPTION: ${param}` +
87
+ ` Use ${chalk.cyan(`create-corva-app ${param} .`)} instead`
88
+ );
89
+
90
+ async function initialChecks() {
91
+ const program = new Command()
92
+ .hook('preAction', async () => {
93
+ checkNodeVersion();
94
+
95
+ await warnIfOutdated();
96
+ })
97
+ .configureOutput({ writeErr: () => undefined })
98
+ .exitOverride();
99
+
100
+ const createCommand = program
101
+ .command('create', { isDefault: true })
102
+ .description('Create a new app')
103
+ .argument('[project-directory]', 'project directory to work with', process.cwd())
104
+ .usage(`${chalk.green('<project-directory>')} [options]`);
105
+
106
+ manifestConstants.manifestOptions().forEach((value) => {
107
+ const type = typeof value.default;
108
+ const option = new Option(
109
+ `${value.alias ? `-${value.alias}, ` : ''}--${value.name} [${(type !== 'undefined' && type) || 'string'
110
+ }]`,
111
+ value.message
112
+ );
113
+
114
+ if (value.choices) {
115
+ if (typeof value.choices === 'function') {
116
+ option.choices(value.choices());
117
+ } else {
118
+ option.choices(
119
+ value.choices.map((choice) => `${typeof choice === 'object' ? choice.value : choice}`)
120
+ );
121
+ }
122
+ }
123
+
124
+ if (type === 'number') {
125
+ option.argParser(Number);
126
+ }
127
+
128
+ if (type !== 'undefined') {
129
+ option.default(value.default);
130
+ }
131
+
132
+ createCommand.addOption(option);
133
+ });
134
+
135
+ createCommand
136
+ .version(packageJson.version)
137
+ .addOption(
138
+ new Option(
139
+ '-z, --zip [string]',
140
+ chalk.bgYellow`DEPRECATED` + ` Use ${chalk.cyan`zip`} command instead`
141
+ )
142
+ )
143
+ .addOption(
144
+ new Option(
145
+ '--release',
146
+ chalk.bgYellow`DEPRECATED` + ` Use ${chalk.cyan`release`} command instead`
147
+ )
148
+ )
149
+ .addOption(bumpVersionOptionDeprecated);
150
+
151
+ createCommand.action(async (dirName, options) => {
152
+ if (options.zip || options.release) {
153
+ options.bumpVersion = await ensureBumpVersion(options.bumpVersion);
154
+ }
155
+
156
+ if (options.zip) {
157
+ printDeprecationNotice('zip');
158
+
159
+ return runFlow(ZIP_FLOW, { dirName, patterns: [], options });
160
+ }
161
+
162
+ if (options.release) {
163
+ printDeprecationNotice('release');
164
+
165
+ return runFlow(RELEASE_FLOW, { dirName, patterns: [], options });
166
+ }
167
+
168
+ startingMessage();
169
+
170
+ // NOTE: Default action
171
+ await createApp(dirName, options);
172
+ });
173
+
174
+ program
175
+ .command('zip')
176
+ .description('Bundle app')
177
+ .argument('<project-directory>', 'Project directory to work with')
178
+ .argument('[patterns...]', 'Additional patterns to zip', [])
179
+ .addOption(bumpVersionOption)
180
+ .action(async (dirName, patterns, options) => {
181
+ options.bumpVersion = await ensureBumpVersion(options.bumpVersion);
182
+
183
+ return runFlow(ZIP_FLOW, { dirName, patterns, options });
184
+ });
185
+
186
+ program
187
+ .command('release')
188
+ .description('Release app')
189
+ .argument('<project-directory>', 'Project directory to work with')
190
+ .argument('[patterns...]', 'Additional patterns to zip', [])
191
+ .addOption(bumpVersionOption)
192
+ .action(async (dirName, patterns, options) => {
193
+ options.bumpVersion = await ensureBumpVersion(options.bumpVersion);
194
+
195
+ return runFlow(RELEASE_FLOW, { dirName, patterns, options });
196
+ });
197
+
198
+ try {
199
+ await program.parseAsync(process.argv);
200
+ } catch (e) {
201
+ handleError(e);
202
+
203
+ process.exit(1);
204
+ }
205
+ }
206
+
207
+ const handleError = (e) => {
208
+ if (e instanceof CommanderError) {
209
+ handleCommanderError(e);
210
+
211
+ return;
212
+ }
213
+
214
+ process.stdout.write(ERROR_ICON);
215
+
216
+ if (!(e instanceof StepError)) {
217
+ console.error(chalk.red(e));
218
+
219
+ return;
220
+ }
221
+
222
+ console.log(chalk.red(e.message));
223
+ e.cause && console.error(chalk.red(e.cause));
224
+ };
225
+
226
+ const handleCommanderError = (e) => {
227
+ switch (e.code) {
228
+ case 'commander.missingArgument': {
229
+ const match = /error:.*'(.*)'/.exec(e.message);
230
+
231
+ if (match && match[1] === 'project-directory') {
232
+ const commandName = program.args[0] || program._defaultCommandName;
233
+
234
+ console.error('Please specify the project directory:');
235
+ console.log(
236
+ ` ${chalk.cyan(program.name())} ${commandName} ${chalk.green('<project-directory>')}`
237
+ );
238
+ console.log();
239
+ console.log('For example:');
240
+ console.log(
241
+ ` ${chalk.cyan(program.name())} ${commandName} ${chalk.green('my-react-app')}`
242
+ );
243
+ console.log();
244
+ console.log(
245
+ `Run ${chalk.cyan(`${program.name()} help ${commandName}`)} to see all options.`
246
+ );
247
+ } else {
248
+ console.error('❌', e.message);
249
+ }
250
+
251
+ break;
252
+ }
253
+ case 'commander.help':
254
+ case 'commander.helpDisplayed': {
255
+ // ignore
256
+ break;
257
+ }
258
+ default: {
259
+ console.error('❌', e.message);
260
+ }
261
+ }
262
+ };
263
+
264
+ async function initPackage(projectName, opts) {
265
+ const manifest = new Manifest(manifestHelpers.fillManifest(opts));
266
+ const runtime = resolveAppRuntime(opts);
267
+
268
+ if (manifest.isUi()) {
269
+ await ensureLatestVersion();
270
+ }
271
+
272
+ const root = path.resolve(projectName);
273
+
274
+ console.log(`Creating a new Corva app in ${chalk.green(root)}.`);
275
+
276
+ if (fs.existsSync(root)) {
277
+ throw new Error(`Directory already exists: ${root}`);
278
+ }
279
+ await fs.mkdir(root);
280
+ await fs.writeJSON(path.join(root, 'manifest.json'), manifest.manifest, writejsonOptions);
281
+
282
+ await addTemplate(root, manifest, runtime);
283
+ await configureApp(root, manifest, runtime);
284
+ await installApp(root, manifest, runtime);
285
+
286
+ console.log();
287
+ }
288
+
289
+ async function createApp(dirName, opts) {
290
+ const { isValid, values } = checkOptions(opts);
291
+
292
+ if (isValid) {
293
+ Object.keys(values).forEach((key) => {
294
+ console.log(`${key} : ${values[key]}`);
295
+ });
296
+
297
+ return initPackage(dirName, opts);
298
+ }
299
+
300
+ console.log('Please fill your app Metadata');
301
+
302
+ const answers = inquirer.prompt(manifestConstants.manifestOptions(dirName), opts)
303
+
304
+ return initPackage(dirName, answers);
305
+ }
306
+
307
+ /**
308
+ *
309
+ * @param {string} root
310
+ * @param {import('./flows/lib/manifest').Manifest} manifest
311
+ * @param {*} runtime
312
+ */
313
+ async function addTemplate(root, manifest, runtime) {
314
+ console.log(chalk.green('Copying app template...'));
315
+ console.log();
316
+
317
+ const templateFolder = path.resolve(__dirname, '..', 'templates', runtime.language, manifest.type);
318
+
319
+ utils.copyFolderRecursiveSync(templateFolder, root);
320
+
321
+ if (manifest.isNode()) {
322
+ utils.copyFolderRecursiveSync(path.resolve(__dirname, '..', 'common', 'node'), root);
323
+ }
324
+
325
+ if (manifest.isPython()) {
326
+ utils.copyFolderRecursiveSync(path.resolve(__dirname, '..', 'common', 'python'), root);
327
+ }
328
+
329
+ // We can't have .gitignore file in our templates.
330
+ // It's missing when @corva/create-app is installed.
331
+ // That's why we manually rename gitignore to .gitignore after copying template
332
+ fs.renameSync(path.join(root, 'gitignore'), path.join(root, '.gitignore'));
333
+
334
+ console.log(chalk.green('Done: copying app template!'));
335
+ }
336
+
337
+ /**
338
+ *
339
+ * @param {string} root
340
+ * @param {import('./flows/lib/manifest').Manifest} manifest
341
+ * @param {*} runtime
342
+ */
343
+ async function configureApp(root, manifest, runtime) {
344
+ if (manifest.isJs()) {
345
+ await addPackageJSON(root, manifest, runtime);
346
+ }
347
+
348
+ if (manifest.isNode()) {
349
+ await addTsConfigs(root, manifest, runtime);
350
+ }
351
+
352
+ if (manifest.isPython() && manifest.isScheduler()) {
353
+ patchSchedulerForPython(root, manifest, runtime);
354
+ }
355
+ }
356
+
357
+ const addTsConfigs = (root, manifest, runtime) => {
358
+ if (runtime.language !== 'typescript') {
359
+ return;
360
+ }
361
+
362
+ return Promise.all([
363
+ fs.writeJson(path.resolve(root, 'tsconfig.json'),
364
+ {
365
+ extends: `@tsconfig/node${runtime.version}/tsconfig.json`,
366
+ compilerOptions: {
367
+ inlineSourceMap: true
368
+ }
369
+ },
370
+ writejsonOptions
371
+ ),
372
+ fs.writeJson(path.resolve(root, 'tsconfig.build.json'),
373
+ {
374
+ "extends": "./tsconfig.json",
375
+ "include": [
376
+ "lib/**/*.ts",
377
+ "index.ts"
378
+ ],
379
+ "exclude": [
380
+ "node_modules",
381
+ "**/*.spec.ts"
382
+ ]
383
+ },
384
+ writejsonOptions
385
+ ),
386
+ ])
387
+ }
388
+
389
+ function patchSchedulerForPython(root, manifest, runtime) {
390
+ const schedulerType = manifest.manifest.settings.app.scheduler_type;
391
+
392
+ if (schedulerType === manifestConstants.SCHEDULER_TYPE_DATA_TIME.value) {
393
+ return;
394
+ }
395
+
396
+ const templateFolder = path.resolve(__dirname, '..', 'templates', runtime.language, manifest.type);
397
+ const originalType = 'ScheduledDataTimeEvent';
398
+ const replacementType =
399
+ schedulerType === manifestConstants.SCHEDULER_TYPE_DEPTH.value
400
+ ? 'ScheduledDepthEvent'
401
+ : 'ScheduledNaturalTimeEvent';
402
+ const patchedCode = fs
403
+ .readFileSync(path.join(templateFolder, 'lambda_function.py'), 'utf-8')
404
+ .replace(new RegExp(originalType, 'g'), replacementType);
405
+
406
+ fs.writeFileSync(path.join(root, 'lambda_function.py'), patchedCode);
407
+ }
408
+
409
+ /**
410
+ *
411
+ * @param {string} root
412
+ * @param {import('./flows/lib/manifest').Manifest} manifest
413
+ */
414
+ function addPackageJSON(root, manifest, runtime) {
415
+ const defaults = getDefaultsForPackageJson(manifest, runtime);
416
+
417
+ const packageJson = {
418
+ name: manifest.name.replace(/\W/g, ''),
419
+ version: defaults.version,
420
+ description: manifest.description || defaults.description,
421
+ engines: {
422
+ node: `>=12.22.12`,
423
+ // node: `>=${runtime.version}`,
424
+ [runtime.packageManager]: '*'
425
+ },
426
+ scripts: defaults.scripts,
427
+ dependencies: defaults.dependencies,
428
+ devDependencies: defaults.devDependencies,
429
+ };
430
+
431
+ return fs.writeJSON(path.join(root, 'package.json'), packageJson, writejsonOptions);
432
+ }
433
+
434
+ /**
435
+ *
436
+ * @param {string} root
437
+ * @param {import('./flows/lib/manifest').Manifest} manifest
438
+ */
439
+ async function installApp(root, manifest, runtime) {
440
+ const command = manifest.isJs() ? runtime.packageManager : 'make';
441
+ const args = ['install'];
442
+
443
+ console.log(chalk.yellow(`Installing template dependencies using ${runtime.packageManager}...`));
444
+ const proc = spawn.sync(command, args, { stdio: ['inherit', 'inherit', 'pipe'], cwd: root });
445
+
446
+ if (proc.stderr) {
447
+ const error = proc.stderr
448
+ .toString('utf8')
449
+ .split('\n')
450
+ // NOTE: filter out warnings caused by @corva/ui peer dependencies
451
+ .filter((line) => !line.includes('@corva/ui'))
452
+ .join('\n');
453
+ console.log(error);
454
+ }
455
+
456
+ if (proc.status !== 0) {
457
+ console.error(`\`${command} ${args.join(' ')}\` failed`);
458
+ return;
459
+ }
460
+
461
+ console.log(chalk.green('Successfull project install'));
462
+
463
+ if (versioning.tryGitInit(root)) {
464
+ console.log();
465
+ console.log('Initialized a git repository.');
466
+
467
+ if (versioning.tryGitCommit(root)) {
468
+ console.log();
469
+ console.log('Created git commit.');
470
+ }
471
+ }
472
+
473
+ console.log();
474
+ console.log(`Success! Created ${manifest.name} at ${root}`);
475
+
476
+ helpCommands(manifest, runtime);
477
+ }
478
+
479
+ async function helpCommands(manifest, { packageManager: displayedCommand }) {
480
+ if (!manifest.isUi()) {
481
+ return
482
+ }
483
+
484
+ const useYarn = displayedCommand === 'yarn';
485
+
486
+ console.log('Inside that directory, you can run several commands:');
487
+ console.log();
488
+ console.log(chalk.cyan(` ${displayedCommand} start`));
489
+ console.log(' Starts the development server.');
490
+ console.log();
491
+ console.log(chalk.cyan(` ${displayedCommand} ${useYarn ? '' : 'run '}build`));
492
+ console.log(' Bundles the app into static files for production.');
493
+ console.log();
494
+ console.log(chalk.cyan(` ${displayedCommand} ${useYarn ? '' : 'run '}zip`));
495
+ console.log(' Bundles the app into ZIP file in app root directory');
496
+ console.log();
497
+ console.log(chalk.cyan(` ${displayedCommand} ${useYarn ? '' : 'run '}release`));
498
+ console.log(' Uploads the app ZIP to Corva');
499
+ console.log();
500
+ }
501
+
502
+ initialChecks();
@@ -1,10 +1,9 @@
1
1
  const NpmApi = require('npm-api');
2
2
  const chalk = require('chalk');
3
- const semverGt = require('semver/functions/gt');
4
- const semverInc = require('semver/functions/inc');
3
+ const semver = require('semver');
5
4
  const inquirer = require('inquirer');
6
5
 
7
- const packageJson = require('../../package.json');
6
+ const packageJson = require('../../../package.json');
8
7
  const npm = new NpmApi();
9
8
  const errorStyle = chalk.bold.red;
10
9
 
@@ -16,7 +15,7 @@ async function ensureLatestVersion() {
16
15
  const currentVersion = getCurrentVersion();
17
16
  const latestVersion = await getLatestVersion();
18
17
 
19
- const isCurrentVersionOutdated = semverGt(latestVersion, currentVersion);
18
+ const isCurrentVersionOutdated = semver.gt(latestVersion, currentVersion);
20
19
  if (isCurrentVersionOutdated) {
21
20
  console.log(errorStyle('****************************************************************'));
22
21
  console.log(chalk`
@@ -34,10 +33,12 @@ async function ensureLatestVersion() {
34
33
 
35
34
  // NOTE: Show user-friendly warning if version is outdated
36
35
  async function warnIfOutdated() {
36
+ process.stdout.write('Checking for updates...');
37
+
37
38
  const currentVersion = getCurrentVersion();
38
39
  const latestVersion = await getLatestVersion();
39
40
 
40
- const isCurrentVersionOutdated = semverGt(latestVersion, currentVersion);
41
+ const isCurrentVersionOutdated = semver.gt(latestVersion, currentVersion);
41
42
 
42
43
  if (isCurrentVersionOutdated) {
43
44
  console.log('****************************************************************');
@@ -49,35 +50,57 @@ async function warnIfOutdated() {
49
50
 
50
51
  `);
51
52
  console.log('****************************************************************');
53
+ } else {
54
+ process.stdout.write(' ✅ \n');
52
55
  }
53
56
  }
54
57
 
55
- const BUMP_OPTIONS = { 1: 'patch', 2: 'minor', 3: 'major' };
56
58
  const PROMPT_MESSAGE = `Bumping package version:
57
- ${chalk.bold` Please select one of the options below or press ENTER for patch or type custom version:`}
58
- 1. patch (x.y.z+1)
59
- 2. minor (x.y+1.z)
60
- 3. major (x+1.y.z)
61
- 4. skip
59
+ ${chalk.bold` Please select one of the options below:`}
62
60
  `;
63
61
 
64
- async function getIncreasedVersion(currentVersion, { bumpVersion }) {
65
- // NOTE: Either use provided bumpVersion for increase or prompt user
66
- if (bumpVersion) return semverInc(currentVersion, bumpVersion) || bumpVersion; // Use option providedw
62
+ const ensureBumpVersion = async (bumpVersion) => {
63
+ if (bumpVersion) {
64
+ return bumpVersion;
65
+ }
67
66
 
68
- let version = currentVersion;
69
- const { option } = await inquirer.prompt({
70
- message: PROMPT_MESSAGE,
71
- name: 'option',
72
- type: 'string',
73
- prefix: '',
74
- default: '1',
75
- });
76
- if (option === '4') return version; // SKIP version bump, return current version
67
+ const { option, custom } = await inquirer.prompt([
68
+ {
69
+ message: PROMPT_MESSAGE,
70
+ name: 'option',
71
+ type: 'list',
72
+ choices: [
73
+ { value: 'major', name: 'major (x+1.y.z)' },
74
+ { value: 'minor', name: 'minor (x.y+1.z)' },
75
+ { value: 'patch', name: 'patch (x.y.z+1)' },
76
+ new inquirer.Separator(),
77
+ { value: 'custom', name: 'Enter a custom version' },
78
+ { value: 'skip', name: 'Skip version bump' },
79
+ ],
80
+ default: 'patch',
81
+ },
82
+ {
83
+ message: 'Enter custom version',
84
+ name: 'custom',
85
+ when: (answers) => answers.option === 'custom',
86
+ type: 'input',
87
+ validate: (input) => (semver.valid(input) ? true : 'Invalid semver version'),
88
+ },
89
+ ]);
90
+
91
+ return option === 'custom' ? custom : option;
92
+ };
93
+
94
+ async function getIncreasedVersion(version, { bumpVersion: releaseTypeOrNewVersion }) {
95
+ if (releaseTypeOrNewVersion === 'skip') {
96
+ return version;
97
+ }
77
98
 
78
- const semverReleaseOption = option ? BUMP_OPTIONS[option] || option : 'patch'; // Patch by default
99
+ if (semver.valid(releaseTypeOrNewVersion)) {
100
+ return releaseTypeOrNewVersion;
101
+ }
79
102
 
80
- return semverInc(version, semverReleaseOption) || option;
103
+ return semver.inc(version, releaseTypeOrNewVersion);
81
104
  }
82
105
 
83
- module.exports = { ensureLatestVersion, warnIfOutdated, getIncreasedVersion };
106
+ module.exports = { ensureLatestVersion, warnIfOutdated, getIncreasedVersion, ensureBumpVersion };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corva/create-app",
3
- "version": "0.28.0-0",
3
+ "version": "0.28.0-3",
4
4
  "private": false,
5
5
  "description": "Create app to use it in CORVA.AI",
6
6
  "keywords": [
@@ -16,14 +16,12 @@
16
16
  },
17
17
  "license": "MIT",
18
18
  "bin": {
19
- "create-corva-app": "./index.js"
19
+ "create-corva-app": "./bin/create-corva-app.js"
20
20
  },
21
21
  "files": [
22
- "index.js",
23
- "constants",
24
- "helpers",
25
- "template",
26
- "scripts"
22
+ "bin/**/*.js",
23
+ "lib/**/*.js",
24
+ "templates"
27
25
  ],
28
26
  "scripts": {
29
27
  "lint": "prettier . --write",
@@ -36,16 +34,20 @@
36
34
  "archiver": "^5.3.0",
37
35
  "axios": "^0.25.0",
38
36
  "chalk": "4.1.0",
39
- "commander": "^8.2.0",
37
+ "commander": "^9.1.0",
40
38
  "conventional-changelog-cli": "^2.1.0",
41
39
  "cross-spawn": "7.0.3",
40
+ "debug": "^4.3.4",
42
41
  "dotenv": "^16.0.0",
43
42
  "envinfo": "7.5.1",
44
43
  "figlet": "^1.5.0",
45
44
  "form-data": "^4.0.0",
46
45
  "fs-extra": "9.0.1",
46
+ "glob": "^8.0.1",
47
47
  "hyperquest": "2.1.3",
48
48
  "inquirer": "7.3.2",
49
+ "is-glob": "^4.0.3",
50
+ "lodash": "^4.17.21",
49
51
  "npm-api": "^1.0.0",
50
52
  "semver": "7.3.2",
51
53
  "tar-pack": "3.4.1",
@@ -58,6 +60,9 @@
58
60
  "prettier": "^2.4.1",
59
61
  "standard-version": "^9.0.0"
60
62
  },
63
+ "engines": {
64
+ "node": "^12.20.0 || >=14"
65
+ },
61
66
  "standard-version": {
62
67
  "skip": {
63
68
  "tag": true