@corva/create-app 0.16.0-rc.0 → 0.18.0-0

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,7 +2,31 @@
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.16.0-rc.0](https://github.com/corva-ai/create-corva-app/compare/v0.16.0-1...v0.16.0-rc.0) (2021-11-23)
5
+ ## [0.17.0-2](https://github.com/corva-ai/create-corva-app/compare/v0.17.0-0...v0.17.0-2) (2021-12-07)
6
+
7
+
8
+ ### Features
9
+
10
+ * add scheduler type option ([e2d3d3d](https://github.com/corva-ai/create-corva-app/commit/e2d3d3dcc7154d841b3da342a36a7edfbc8488e4))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * diff app types, runtimes and templates ([7c52817](https://github.com/corva-ai/create-corva-app/commit/7c528173535b9a915372ec469df8043b3830e387))
16
+
17
+ ## [0.17.0-1](https://github.com/corva-ai/create-corva-app/compare/v0.17.0-0...v0.17.0-1) (2021-12-03)
18
+
19
+
20
+ ### Features
21
+
22
+ * add scheduler type option ([e2d3d3d](https://github.com/corva-ai/create-corva-app/commit/e2d3d3dcc7154d841b3da342a36a7edfbc8488e4))
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * diff app types, runtimes and templates ([7c52817](https://github.com/corva-ai/create-corva-app/commit/7c528173535b9a915372ec469df8043b3830e387))
28
+
29
+ ## [0.17.0-0](https://github.com/corva-ai/create-corva-app/compare/v0.16.0-1...v0.17.0-0) (2021-11-23)
6
30
 
7
31
  ## [0.16.0-1](https://github.com/corva-ai/create-corva-app/compare/v0.16.0-0...v0.16.0-1) (2021-11-18)
8
32
 
@@ -0,0 +1,26 @@
1
+ const APP_RUNTIMES = {
2
+ UI: 'ui',
3
+ NODE12: 'nodejs12.x',
4
+ PYTHON3: 'python3.8',
5
+ };
6
+
7
+ const TEMPLATE_TYPES = {
8
+ UI: 'js',
9
+ UI_TS: 'ts',
10
+ NODE: 'node',
11
+ NODE_TYPESCRIPT: 'node-ts',
12
+ PYTHON: 'python',
13
+ };
14
+
15
+ const APP_TYPES = {
16
+ UI: 'ui',
17
+ SCHEDULER: 'scheduler',
18
+ STREAM: 'stream',
19
+ TASK: 'task',
20
+ };
21
+
22
+ module.exports = {
23
+ TEMPLATE_TYPES,
24
+ APP_RUNTIMES,
25
+ APP_TYPES,
26
+ };
@@ -1,3 +1,5 @@
1
+ const { APP_RUNTIMES, APP_TYPES, TEMPLATE_TYPES } = require('./cli');
2
+
1
3
  const defaultManifest = {
2
4
  format: 1,
3
5
  license: {
@@ -10,7 +12,7 @@ const defaultManifest = {
10
12
  authors: [],
11
13
  },
12
14
  application: {
13
- type: 'ui',
15
+ type: APP_TYPES.UI,
14
16
  key: 'app.key-goes-here',
15
17
  visibility: 'private',
16
18
  name: 'Name of My App',
@@ -68,16 +70,41 @@ const defaultDataAppPythonManifest = {
68
70
  };
69
71
 
70
72
  const defaultTimeSchedulerSettings = {
71
- scheduler_type: 'data_time',
72
73
  cron_string: '*/5 * * * *',
73
74
  };
74
75
 
75
76
  const defaultDepthSchedulerSettings = {
76
- scheduler_type: 'data_depth',
77
77
  depth_milestone: 1,
78
78
  };
79
79
 
80
- const MANIFEST_MANDATORY_KEYS = ['appType', 'appKey', 'appName', 'category', 'segments', 'runtime'];
80
+ const getManifestMandatoryKeys = (opts) => {
81
+ const keys = manifestOptions(opts.projectName).reduce((acc, option) => {
82
+ if (option.required) {
83
+ acc.push(option.name);
84
+ }
85
+
86
+ return acc;
87
+ }, []);
88
+
89
+ const { appType } = opts;
90
+
91
+ if (appType) {
92
+ if (appType !== APP_TYPES.UI) {
93
+ keys.push('runtime');
94
+ }
95
+
96
+ if (appType === APP_TYPES.SCHEDULER) {
97
+ keys.push('schedulerType');
98
+ keys.push('cronString');
99
+ }
100
+ }
101
+
102
+ return keys;
103
+ };
104
+
105
+ const SCHEDULER_TYPE_NATURAL_TIME = { name: 'Natural Time', value: 1 };
106
+ const SCHEDULER_TYPE_DATA_TIME = { name: 'Data Time', value: 2 };
107
+ const SCHEDULER_TYPE_DEPTH = { name: 'Date Depth', value: 4 };
81
108
 
82
109
  const manifestOptions = (projectName) => [
83
110
  { name: 'developerName', message: 'Enter the Developer Name', default: 'O&G Company' },
@@ -86,11 +113,36 @@ const manifestOptions = (projectName) => [
86
113
  type: 'rawlist',
87
114
  name: 'appType',
88
115
  message: 'Choose the App Type',
89
- default: 'ui',
90
- choices: ['ui', 'scheduler', 'stream', 'task'],
116
+ default: APP_TYPES.UI,
117
+ choices: Object.values(APP_TYPES),
118
+ required: true,
119
+ },
120
+ {
121
+ type: 'rawlist',
122
+ name: 'schedulerType',
123
+ message: 'Choose the scheduler type',
124
+ default: SCHEDULER_TYPE_NATURAL_TIME.value,
125
+ choices: [SCHEDULER_TYPE_NATURAL_TIME, SCHEDULER_TYPE_DATA_TIME, SCHEDULER_TYPE_DEPTH],
126
+ when: (answers) => answers.appType === APP_TYPES.SCHEDULER,
127
+ },
128
+ {
129
+ name: 'cronString',
130
+ message: 'Provide CRON string for the scheduler',
131
+ default: '*/5 * * * *',
132
+ when: (answers) => answers.appType === APP_TYPES.SCHEDULER,
133
+ },
134
+ {
135
+ name: 'appKey',
136
+ message: 'Enter the App Key',
137
+ default: 'app.key-goes-here',
138
+ required: true,
139
+ },
140
+ {
141
+ name: 'appName',
142
+ message: 'Enter the App Name',
143
+ default: projectName,
144
+ required: true,
91
145
  },
92
- { name: 'appKey', message: 'Enter the App Key', default: 'app.key-goes-here' },
93
- { name: 'appName', message: 'Enter the App Name', default: projectName },
94
146
  {
95
147
  name: 'description',
96
148
  message: 'Enter description',
@@ -101,20 +153,32 @@ const manifestOptions = (projectName) => [
101
153
  message: 'Enter summary',
102
154
  default: 'More information about this app goes here',
103
155
  },
104
- { name: 'category', message: 'Enter category', default: '' },
156
+ {
157
+ name: 'category',
158
+ message: 'Enter category',
159
+ default: '',
160
+ required: true,
161
+ },
105
162
  { name: 'website', message: 'Enter website', default: 'https://www.oandgexample.com/my-app/' },
106
163
  {
107
164
  type: 'rawlist',
108
165
  name: 'segments',
109
166
  message: 'Choose segments',
110
167
  choices: ['drilling', 'completion'],
168
+ required: true,
111
169
  },
112
170
  {
113
171
  type: 'rawlist',
114
172
  name: 'runtime',
115
173
  message: 'Choose runtime',
116
- choices: ['python3.8', 'nodejs12.x'],
117
- when: (answers) => answers.appType !== 'ui',
174
+ choices: (answers) => {
175
+ if (answers && answers.appType !== APP_TYPES.UI) {
176
+ return Object.values(APP_RUNTIMES).filter((value) => value !== APP_RUNTIMES.UI);
177
+ }
178
+
179
+ return Object.values(APP_RUNTIMES);
180
+ },
181
+ when: (answers) => answers.appType !== APP_TYPES.UI,
118
182
  },
119
183
  {
120
184
  type: 'rawlist',
@@ -122,7 +186,7 @@ const manifestOptions = (projectName) => [
122
186
  message: 'Please select the desired package manager',
123
187
  default: 'yarn',
124
188
  choices: ['yarn', 'npm'],
125
- when: (answers) => !answers.runtime || !answers.runtime.startsWith('python'),
189
+ when: (answers) => !answers.runtime || !answers.runtime.startsWith(TEMPLATE_TYPES.PYTHON),
126
190
  },
127
191
  {
128
192
  type: 'confirm',
@@ -130,14 +194,8 @@ const manifestOptions = (projectName) => [
130
194
  message: 'Would you like to use TypesScript?',
131
195
  default: false,
132
196
  when: (answers) =>
133
- (answers.runtime && answers.runtime.startsWith('nodejs')) || answers.appType === 'ui',
134
- },
135
- {
136
- type: 'rawlist',
137
- name: 'schedulerType',
138
- message: 'Choose schedulerType',
139
- choices: ['data_time', 'data_depth', 'natural_time'],
140
- when: (answers) => answers.appType === 'scheduler',
197
+ (answers.runtime && answers.runtime.startsWith(TEMPLATE_TYPES.NODE)) ||
198
+ answers.appType === APP_TYPES.UI,
141
199
  },
142
200
  ];
143
201
 
@@ -149,5 +207,8 @@ module.exports = {
149
207
  defaultTimeSchedulerSettings,
150
208
  defaultDepthSchedulerSettings,
151
209
  manifestOptions,
152
- MANIFEST_MANDATORY_KEYS,
210
+ getManifestMandatoryKeys,
211
+ SCHEDULER_TYPE_NATURAL_TIME,
212
+ SCHEDULER_TYPE_DATA_TIME,
213
+ SCHEDULER_TYPE_DEPTH,
153
214
  };
@@ -24,8 +24,8 @@ const dependencies = {
24
24
 
25
25
  const tsDependencies = {
26
26
  devDependencies: {
27
- "@tsconfig/create-react-app": "1.0.2",
28
- "@types/material-ui": "0.21.9",
27
+ '@tsconfig/create-react-app': '1.0.2',
28
+ '@types/material-ui': '0.21.9',
29
29
  '@types/react': '^17.0.22',
30
30
  '@types/react-dom': '^17.0.9',
31
31
  '@typescript-eslint/eslint-plugin': '^4.31.2',
@@ -1,7 +1,8 @@
1
+ const { APP_RUNTIMES, APP_TYPES, TEMPLATE_TYPES } = require('../constants/cli.js');
1
2
  const manifestConstants = require('../constants/manifest.js');
2
3
 
3
4
  function fillManifest(answers) {
4
- const runtime = answers.runtime || 'ui';
5
+ const runtime = answers.runtime || APP_RUNTIMES.UI;
5
6
 
6
7
  const defaultManifestProperties = _defaultManifestProperties({
7
8
  type: answers.appType,
@@ -33,7 +34,11 @@ function fillManifest(answers) {
33
34
  settings: {
34
35
  ...defaultManifestProperties.settings,
35
36
  runtime,
36
- ...defaultAppSettings({ type: answers.appType, schedulerType: answers.schedulerType }),
37
+ ...defaultAppSettings({
38
+ type: answers.appType,
39
+ schedulerType: answers.schedulerType,
40
+ cronString: answers.cronString,
41
+ }),
37
42
  },
38
43
  };
39
44
 
@@ -41,31 +46,32 @@ function fillManifest(answers) {
41
46
  }
42
47
 
43
48
  function _defaultManifestProperties({ type, runtime }) {
44
- if (type === 'ui') {
49
+ if (type === APP_TYPES.UI) {
45
50
  return manifestConstants.defaultUIAppManifest;
46
51
  }
47
52
 
48
- if (runtime.match(/python/)) {
53
+ if (runtime.startsWith(TEMPLATE_TYPES.PYTHON)) {
49
54
  return manifestConstants.defaultDataAppPythonManifest;
50
55
  }
51
56
 
52
57
  return manifestConstants.defaultDataAppNodeManifest;
53
58
  }
54
59
 
55
- function defaultAppSettings({ type, schedulerType }) {
60
+ function defaultAppSettings({ type, schedulerType, cronString }) {
56
61
  if (!schedulerType) {
57
62
  return {};
58
63
  }
59
64
 
60
65
  const schedulerAppSettings =
61
- schedulerType == 'data_depth'
66
+ schedulerType === manifestConstants.SCHEDULER_TYPE_DEPTH.value
62
67
  ? manifestConstants.defaultDepthSchedulerSettings
63
68
  : manifestConstants.defaultTimeSchedulerSettings;
64
69
 
65
70
  return {
66
71
  app: {
67
72
  ...schedulerAppSettings,
68
- scheduler_type: schedulerType || 'data_time',
73
+ scheduler_type: schedulerType,
74
+ cron_string: cronString,
69
75
  },
70
76
  };
71
77
  }
package/index.js CHANGED
@@ -23,6 +23,7 @@ const manifestConstants = require('./constants/manifest.js');
23
23
  const packageJson = require('./package.json');
24
24
  const { clear } = require('console');
25
25
  const spawn = require('cross-spawn');
26
+ const { APP_RUNTIMES, TEMPLATE_TYPES, APP_TYPES } = require('./constants/cli');
26
27
 
27
28
  const YARN_EXECUTABLE = 'yarn';
28
29
 
@@ -38,11 +39,6 @@ clear();
38
39
  let projectName;
39
40
  let program;
40
41
 
41
- const APP_TYPES = {
42
- UI: 'ui',
43
- NODE: 'node',
44
- };
45
-
46
42
  function startingMessage() {
47
43
  console.log(chalk.green(' Welcome to apps generator for:'));
48
44
  console.log(chalk.cyan(figlet.textSync('CORVA.AI', { horizontalLayout: 'full' })));
@@ -55,7 +51,7 @@ function checkNodeVersion() {
55
51
  console.log(
56
52
  chalk.red(
57
53
  `You are using Node ${process.version}.\n\n` +
58
- `Please update to Node 10 or higher for a better, fully supported experience.\n`
54
+ `Please update to Node 10 or higher for a better, fully supported experience.\n`
59
55
  )
60
56
  );
61
57
  // Fall back to latest supported react-scripts on Node 4
@@ -67,7 +63,7 @@ function checkOptions(opts) {
67
63
  let isValid = true;
68
64
  const values = {};
69
65
 
70
- manifestConstants.MANIFEST_MANDATORY_KEYS.forEach((key) => {
66
+ manifestConstants.getManifestMandatoryKeys(opts).forEach((key) => {
71
67
  if (!opts[key]) {
72
68
  isValid = false;
73
69
  }
@@ -92,15 +88,31 @@ async function initialChecks() {
92
88
  projectName = name;
93
89
  })
94
90
  .option('-z, --zip <type>', 'zip app source')
95
- .option('-t, --useTypescript', 'use typescript or javascript', false)
96
91
  .addOption(
97
- new commander.Option(`-p, --packageManager <value>`, 'package manager to use')
92
+ new commander.Option(`-p, --packageManager [string]`, 'package manager to use')
98
93
  .default(YARN_EXECUTABLE)
99
94
  .choices(['npm', YARN_EXECUTABLE])
100
95
  );
101
96
 
102
- manifestConstants.MANIFEST_MANDATORY_KEYS.forEach((key) => {
103
- program.option(`--${key} [value]`);
97
+ manifestConstants.manifestOptions(projectName).forEach((value) => {
98
+ const type = typeof value.default;
99
+ const option = new commander.Option(`--${value.name} [${type !== 'undefined' && type || 'string'}]`, value.message);
100
+
101
+ if (value.choices) {
102
+ if (typeof value.choices === 'function') {
103
+ option.choices(value.choices());
104
+ } else {
105
+ option.choices(
106
+ value.choices.map((choice) => `${typeof choice === 'object' ? choice.value : choice}`)
107
+ );
108
+ }
109
+ }
110
+
111
+ if (type === 'number') {
112
+ option.argParser(Number)
113
+ }
114
+
115
+ program.addOption(option);
104
116
  });
105
117
 
106
118
  program.parse(process.argv);
@@ -113,7 +125,7 @@ async function initialChecks() {
113
125
  useTypescript = opts.useTypescript || useTypescript;
114
126
 
115
127
  if (opts.zip) {
116
- if (opts.zip === APP_TYPES.UI) {
128
+ if (opts.zip === APP_RUNTIMES.UI) {
117
129
  return uiScripts.zipAppSource(shouldUseYarn());
118
130
  }
119
131
 
@@ -137,7 +149,9 @@ async function initialChecks() {
137
149
 
138
150
  async function initPackage(manifest) {
139
151
  const appType = manifest.application.type;
140
- if (appType === APP_TYPES.UI) await ensureLatestVersion();
152
+ if (appType === APP_TYPES.UI) {
153
+ await ensureLatestVersion();
154
+ }
141
155
 
142
156
  const root = path.resolve(projectName);
143
157
 
@@ -153,17 +167,13 @@ async function initPackage(manifest) {
153
167
  // config for every possible version at this point, so just consolidate all versions of a runtime into a single
154
168
  // template directory.
155
169
  if (appType !== APP_TYPES.UI) {
156
- if (runtime.startsWith('python')) {
157
- runtime = 'python';
158
- } else if (runtime.startsWith('nodejs')) {
159
- runtime = 'node';
160
-
161
- if (useTypescript) {
162
- runtime += '-ts';
163
- }
170
+ if (runtime.startsWith(TEMPLATE_TYPES.PYTHON)) {
171
+ runtime = TEMPLATE_TYPES.PYTHON;
172
+ } else {
173
+ runtime = useTypescript ? TEMPLATE_TYPES.NODE_TYPESCRIPT : TEMPLATE_TYPES.NODE;
164
174
  }
165
- } else if (appType === APP_TYPES.UI) {
166
- runtime = useTypescript ? 'ts' : 'js';
175
+ } else {
176
+ runtime = useTypescript ? TEMPLATE_TYPES.UI_TS : TEMPLATE_TYPES.UI;
167
177
  }
168
178
 
169
179
  addTemplate(root, appType, runtime);
@@ -185,7 +195,7 @@ async function createApp(opts) {
185
195
  } else {
186
196
  console.log('Please fill your app Metadata');
187
197
 
188
- inquirer.prompt(manifestConstants.manifestOptions(projectName)).then((answers) => {
198
+ inquirer.prompt(manifestConstants.manifestOptions(projectName), opts).then((answers) => {
189
199
  packageManager = answers.packageManager || packageManager;
190
200
  useTypescript = answers.useTypescript || useTypescript;
191
201
 
@@ -222,15 +232,39 @@ function addTemplate(root, appType, runtime) {
222
232
  function configureApp(root, appType, runtime, manifest) {
223
233
  if (appType === APP_TYPES.UI) {
224
234
  addPackageJSON(root, manifest.application.name);
225
- } else if (runtime.startsWith(APP_TYPES.NODE)) {
235
+ } else if (runtime.startsWith(TEMPLATE_TYPES.NODE)) {
226
236
  updatePackageJSON(root, manifest.application.description, appType, runtime);
227
237
  }
238
+
239
+ if (runtime.startsWith(TEMPLATE_TYPES.PYTHON) && appType === APP_TYPES.SCHEDULER) {
240
+ patchSchedulerForPython(root, appType, runtime, manifest);
241
+ }
242
+ }
243
+
244
+ function patchSchedulerForPython(root, appType, runtime, manifest) {
245
+ const schedulerType = manifest.settings.app.scheduler_type;
246
+
247
+ if (schedulerType === manifestConstants.SCHEDULER_TYPE_DATA_TIME.value) {
248
+ return;
249
+ }
250
+
251
+ const templateFolder = path.resolve(__dirname, 'template', appType, runtime);
252
+ const originalType = 'ScheduledDataTimeEvent';
253
+ const replacementType =
254
+ schedulerType === manifestConstants.SCHEDULER_TYPE_DEPTH.value
255
+ ? 'ScheduledDepthEvent'
256
+ : 'ScheduledNaturalTimeEvent';
257
+ const patchedCode = fs
258
+ .readFileSync(path.join(templateFolder, 'lambda_function.py'), 'utf-8')
259
+ .replace(new RegExp(originalType, 'g'), replacementType);
260
+
261
+ fs.writeFileSync(path.join(root, 'lambda_function.py'), patchedCode);
228
262
  }
229
263
 
230
264
  function addPackageJSON(root, appName) {
231
265
  const devDependencies = {
232
266
  ...packageConstants.dependencies.devDependencies,
233
- ...(useTypescript && packageConstants.tsDependencies.devDependencies)
267
+ ...(useTypescript && packageConstants.tsDependencies.devDependencies),
234
268
  };
235
269
  const packageJson = {
236
270
  name: appName.replace(/\W/g, ''),
@@ -262,7 +296,7 @@ function updatePackageJSON(root, description, appType, runtime) {
262
296
 
263
297
  function installApp(appPath, appType, runtime) {
264
298
  switch (runtime) {
265
- case 'python': {
299
+ case TEMPLATE_TYPES.PYTHON: {
266
300
  break;
267
301
  }
268
302
  default: {
@@ -302,7 +336,7 @@ function installJsApp(appPath, appType) {
302
336
  console.log();
303
337
  console.log(`Success! Created ${projectName} at ${appPath}`);
304
338
 
305
- if (appType === APP_TYPES.UI) {
339
+ if (appType === APP_RUNTIMES.UI) {
306
340
  console.log('Inside that directory, you can run several commands:');
307
341
  helpCommands();
308
342
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corva/create-app",
3
- "version": "0.16.0-rc.0",
3
+ "version": "0.18.0-0",
4
4
  "private": false,
5
5
  "description": "Create app to use it in CORVA.AI",
6
6
  "keywords": [
@@ -85,9 +85,12 @@ async function compressAppToZip(useYarn) {
85
85
  name: 'package.json',
86
86
  });
87
87
 
88
- ['manifest.json', 'config-overrides.js', 'tsconfig.json', useYarn ? 'yarn.lock' : 'package-lock.json'].forEach(
89
- (name) => archive.file(path.resolve(dirname, name), { name })
90
- );
88
+ [
89
+ 'manifest.json',
90
+ 'config-overrides.js',
91
+ 'tsconfig.json',
92
+ useYarn ? 'yarn.lock' : 'package-lock.json',
93
+ ].forEach((name) => archive.file(path.resolve(dirname, name), { name }));
91
94
 
92
95
  archive.directory(path.resolve(dirname, 'src'), 'src');
93
96