generate-react-cli 8.3.0-alpha.1 → 8.3.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "generate-react-cli",
|
|
3
|
-
"version": "8.3.0
|
|
3
|
+
"version": "8.3.0",
|
|
4
4
|
"description": "A simple React CLI to generate components instantly and more.",
|
|
5
5
|
"repository": "https://github.com/arminbro/generate-react-cli",
|
|
6
6
|
"bugs": "https://github.com/arminbro/generate-react-cli/issues",
|
package/readme.md
CHANGED
|
@@ -478,49 +478,6 @@ GlobalNav.defaultProps = {};
|
|
|
478
478
|
export default GlobalNav;
|
|
479
479
|
```
|
|
480
480
|
|
|
481
|
-
If you have unit testing enabled in your project and have the `withTest` flag enabled, it will generate the unit test file and initialize with some test cases for the generated component right out of the box!
|
|
482
|
-
|
|
483
|
-
Here are the unit tests it generated for the GlobalNav component using the default testing library template (`@testing-library/react`) that comes with GRC.
|
|
484
|
-
|
|
485
|
-
```tsx
|
|
486
|
-
import React from 'react';
|
|
487
|
-
import { render, screen } from '@testing-library/react';
|
|
488
|
-
import '@testing-library/jest-dom/extend-expect';
|
|
489
|
-
import GlobalNav from './GlobalNav';
|
|
490
|
-
|
|
491
|
-
describe('<GlobalNav />', () => {
|
|
492
|
-
test('it should mount', () => {
|
|
493
|
-
render(<GlobalNav />);
|
|
494
|
-
|
|
495
|
-
const globalNav = screen.getByTestId('GlobalNav');
|
|
496
|
-
|
|
497
|
-
expect(globalNav).toBeInTheDocument();
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
test('it should display the logo "GRC"', () => {
|
|
501
|
-
render(<GlobalNav />);
|
|
502
|
-
|
|
503
|
-
const logo = screen.getByText('GRC');
|
|
504
|
-
|
|
505
|
-
expect(logo).toBeInTheDocument();
|
|
506
|
-
});
|
|
507
|
-
|
|
508
|
-
test('it should display three links: Home, About and Contact', () => {
|
|
509
|
-
render(<GlobalNav />);
|
|
510
|
-
|
|
511
|
-
const homeLink = screen.getByText('Home');
|
|
512
|
-
const aboutLink = screen.getByText('About');
|
|
513
|
-
const contactLink = screen.getByText('Contact');
|
|
514
|
-
|
|
515
|
-
expect(homeLink).toBeInTheDocument();
|
|
516
|
-
expect(aboutLink).toBeInTheDocument();
|
|
517
|
-
expect(contactLink).toBeInTheDocument();
|
|
518
|
-
});
|
|
519
|
-
});
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
Please note, If you're using a different testing library, you need to provide it as a [custom testing component template](#custom-component-templates), and GRC will instruct openAi to use that to write your unit tests.
|
|
523
|
-
|
|
524
481
|
That's a wrap. I hope this integration will allow us to generate React components more efficiently, and we can still go in and make the necessary adjustments.
|
|
525
482
|
|
|
526
483
|
Again, please provide any feedback if you have any, and I would love to see some of the components that you generate with GRC+OpenAI.
|
|
@@ -16,20 +16,3 @@ export async function aiComponentGenerator(componentTemplate, prompt) {
|
|
|
16
16
|
|
|
17
17
|
return generatedComponent.data.choices[0].text;
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
export async function aiComponentTestGenerator(componentTemplate, prompt) {
|
|
21
|
-
const configuration = new Configuration({ apiKey: process.env.OPENAI_API_KEY });
|
|
22
|
-
const openAiApi = new OpenAIApi(configuration);
|
|
23
|
-
|
|
24
|
-
const generatedComponent = await openAiApi.createCompletion({
|
|
25
|
-
model: 'text-davinci-003',
|
|
26
|
-
prompt: `Create a React component unit tests using this template "${componentTemplate}", but make the adjustments needed with these instructions as follows "${prompt}"`,
|
|
27
|
-
temperature: 0.7,
|
|
28
|
-
max_tokens: 2000,
|
|
29
|
-
top_p: 1.0,
|
|
30
|
-
frequency_penalty: 0.0,
|
|
31
|
-
presence_penalty: 1,
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
return generatedComponent.data.choices[0].text;
|
|
35
|
-
}
|
|
@@ -7,10 +7,11 @@ import snakeCase from 'lodash/snakeCase.js';
|
|
|
7
7
|
import startCase from 'lodash/startCase.js';
|
|
8
8
|
import fsExtra from 'fs-extra';
|
|
9
9
|
|
|
10
|
-
import { aiComponentGenerator
|
|
10
|
+
import { aiComponentGenerator } from '../services/openAiService.js';
|
|
11
11
|
import componentJsTemplate from '../templates/component/componentJsTemplate.js';
|
|
12
12
|
import componentTsTemplate from '../templates/component/componentTsTemplate.js';
|
|
13
13
|
import componentCssTemplate from '../templates/component/componentCssTemplate.js';
|
|
14
|
+
import componentStyledTemplate from '../templates/component/componentStyledTemplate.js';
|
|
14
15
|
import componentLazyTemplate from '../templates/component/componentLazyTemplate.js';
|
|
15
16
|
import componentTsLazyTemplate from '../templates/component/componentTsLazyTemplate.js';
|
|
16
17
|
import componentStoryTemplate from '../templates/component/componentStoryTemplate.js';
|
|
@@ -81,7 +82,7 @@ Please make sure you're pointing to the right custom template path in your gener
|
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
function componentTemplateGenerator({ cmd, componentName, cliConfigFile }) {
|
|
84
|
-
const { cssPreprocessor, testLibrary, usesCssModule, usesTypeScript } = cliConfigFile;
|
|
85
|
+
const { usesStyledComponents, cssPreprocessor, testLibrary, usesCssModule, usesTypeScript } = cliConfigFile;
|
|
85
86
|
const { customTemplates } = cliConfigFile.component[cmd.type];
|
|
86
87
|
let template = null;
|
|
87
88
|
let filename = null;
|
|
@@ -113,16 +114,27 @@ function componentTemplateGenerator({ cmd, componentName, cliConfigFile }) {
|
|
|
113
114
|
// --- If it has a corresponding stylesheet
|
|
114
115
|
|
|
115
116
|
if (cmd.withStyle) {
|
|
116
|
-
|
|
117
|
-
|
|
117
|
+
if (cliConfigFile.usesStyledComponents) {
|
|
118
|
+
const cssPath = `${componentName}.styled`;
|
|
119
|
+
template = template.replace(
|
|
120
|
+
`import styles from './TemplateName.module.css'`,
|
|
121
|
+
`import { TemplateNameWrapper } from './${cssPath}'`
|
|
122
|
+
);
|
|
123
|
+
template = template.replace(` className={styles.TemplateName}`, '');
|
|
124
|
+
template = template.replace(` <div`, '<TemplateNameWrapper');
|
|
125
|
+
template = template.replace(` </div>`, '</TemplateNameWrapper>');
|
|
126
|
+
} else {
|
|
127
|
+
const module = usesCssModule ? '.module' : '';
|
|
128
|
+
const cssPath = `${componentName}${module}.${cssPreprocessor}`;
|
|
118
129
|
|
|
119
|
-
|
|
130
|
+
// --- If the css module is true make sure to update the template accordingly
|
|
120
131
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
132
|
+
if (module.length) {
|
|
133
|
+
template = template.replace(`'./TemplateName.module.css'`, `'./${cssPath}'`);
|
|
134
|
+
} else {
|
|
135
|
+
template = template.replace(`{styles.TemplateName}`, `"${componentName}"`);
|
|
136
|
+
template = template.replace(`styles from './TemplateName.module.css'`, `'./${cssPath}'`);
|
|
137
|
+
}
|
|
126
138
|
}
|
|
127
139
|
} else {
|
|
128
140
|
// --- If no stylesheet, remove className attribute and style import from jsTemplate
|
|
@@ -157,14 +169,19 @@ function componentStyleTemplateGenerator({ cliConfigFile, cmd, componentName })
|
|
|
157
169
|
template = customTemplate;
|
|
158
170
|
filename = customTemplateFilename;
|
|
159
171
|
} else {
|
|
160
|
-
const { cssPreprocessor, usesCssModule } = cliConfigFile;
|
|
161
|
-
|
|
162
|
-
|
|
172
|
+
const { usesTypeScript, usesStyledComponents, cssPreprocessor, usesCssModule } = cliConfigFile;
|
|
173
|
+
if (usesStyledComponents) {
|
|
174
|
+
filename = usesTypeScript ? `${componentName}.styled.ts` : `${componentName}.styled.js`;
|
|
175
|
+
template = componentStyledTemplate;
|
|
176
|
+
} else {
|
|
177
|
+
const module = usesCssModule ? '.module' : '';
|
|
178
|
+
const cssFilename = `${componentName}${module}.${cssPreprocessor}`;
|
|
163
179
|
|
|
164
|
-
|
|
180
|
+
// --- Else use GRC built-in style template
|
|
165
181
|
|
|
166
|
-
|
|
167
|
-
|
|
182
|
+
template = componentCssTemplate;
|
|
183
|
+
filename = cssFilename;
|
|
184
|
+
}
|
|
168
185
|
}
|
|
169
186
|
|
|
170
187
|
return {
|
|
@@ -438,30 +455,6 @@ export function generateComponent(componentName, cmd, cliConfigFile) {
|
|
|
438
455
|
return;
|
|
439
456
|
}
|
|
440
457
|
|
|
441
|
-
// Generate component test with openAi, if component description is provided
|
|
442
|
-
|
|
443
|
-
if (cmd.describe && componentFileType === buildInComponentFileTypes.TEST) {
|
|
444
|
-
aiComponentTestGenerator(template, cmd.describe)
|
|
445
|
-
.then((aiGeneratedComponentTest) => {
|
|
446
|
-
outputFileSync(componentPath, aiGeneratedComponentTest.trim());
|
|
447
|
-
console.log(
|
|
448
|
-
chalk.green(
|
|
449
|
-
`OpenAI Successfully created the ${filename} component test with the provided description.`
|
|
450
|
-
)
|
|
451
|
-
);
|
|
452
|
-
})
|
|
453
|
-
.catch((error) =>
|
|
454
|
-
console.log(
|
|
455
|
-
chalk.red(
|
|
456
|
-
`OpenAI failed to create the ${filename} component test with the provided description.`,
|
|
457
|
-
error
|
|
458
|
-
)
|
|
459
|
-
)
|
|
460
|
-
);
|
|
461
|
-
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
458
|
console.log(chalk.green(`${filename} was successfully created at ${componentPath}`));
|
|
466
459
|
} catch (error) {
|
|
467
460
|
console.error(chalk.red(`${filename} failed and was not created.`));
|
|
@@ -20,12 +20,19 @@ const projectLevelQuestions = [
|
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
type: 'confirm',
|
|
23
|
+
name: 'usesStyledComponents',
|
|
24
|
+
message: 'Does this project use styled-components?',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
type: 'confirm',
|
|
28
|
+
when: (answers) => !answers['usesStyledComponents'],
|
|
23
29
|
name: 'usesCssModule',
|
|
24
30
|
message: 'Does this project use CSS modules?',
|
|
25
31
|
},
|
|
26
32
|
{
|
|
27
33
|
type: 'list',
|
|
28
34
|
name: 'cssPreprocessor',
|
|
35
|
+
when: (answers) => !answers['usesStyledComponents'],
|
|
29
36
|
message: 'Does this project use a CSS Preprocessor?',
|
|
30
37
|
choices: ['css', 'scss', 'less', 'styl'],
|
|
31
38
|
},
|
|
@@ -184,7 +191,9 @@ export async function getCLIConfigFile() {
|
|
|
184
191
|
*/
|
|
185
192
|
|
|
186
193
|
const missingConfigQuestions = grcConfigQuestions.filter(
|
|
187
|
-
(question) =>
|
|
194
|
+
(question) =>
|
|
195
|
+
!deepKeys(currentConfigFile).includes(question.name) &&
|
|
196
|
+
(question.when ? question.when(currentConfigFile) : true)
|
|
188
197
|
);
|
|
189
198
|
|
|
190
199
|
if (missingConfigQuestions.length) {
|