generator-reackt 0.5.0 → 0.6.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.
Files changed (42) hide show
  1. package/.prettierrc +5 -5
  2. package/.stylelintrc +188 -104
  3. package/LICENSE +7 -9
  4. package/README.md +18 -18
  5. package/generators/app/index.js +392 -1
  6. package/generators/component/index.js +51 -1
  7. package/generators/module/index.js +127 -1
  8. package/generators/util/fs.js +34 -1
  9. package/package.json +63 -69
  10. package/templates/app/.babelrc +4 -9
  11. package/templates/app/.browserslistrc +3 -3
  12. package/templates/app/.editorconfig +11 -11
  13. package/templates/app/.esdoc.json +23 -23
  14. package/templates/app/.eslintrc.js +46 -185
  15. package/templates/app/.lintstagedrc +4 -4
  16. package/templates/app/.prettierrc +4 -4
  17. package/templates/app/.storybook/addons.js +1 -1
  18. package/templates/app/.storybook/config.js +14 -14
  19. package/templates/app/.storybook/webpack.config.babel.js +7 -7
  20. package/templates/app/.stylelintrc +188 -271
  21. package/templates/app/gitignore +2 -2
  22. package/templates/app/jest.config.js +15 -15
  23. package/templates/app/jsconfig.json +7 -8
  24. package/templates/app/package.json +18 -18
  25. package/templates/app/src/components/App.js +14 -14
  26. package/templates/app/src/index.html +10 -10
  27. package/templates/app/src/index.js +47 -50
  28. package/templates/app/src/index.scss +16 -16
  29. package/templates/app/src/reducers/application.js +21 -21
  30. package/templates/app/src/reducers/index.js +7 -7
  31. package/templates/app/src/sagas/application.js +9 -9
  32. package/templates/app/src/sagas/index.js +7 -7
  33. package/templates/app/src/selectors/application.js +1 -1
  34. package/templates/app/src/selectors/application.test.js +13 -13
  35. package/templates/app/src/utils/index.js +36 -36
  36. package/templates/app/webpack.config.babel.js +103 -103
  37. package/templates/component/index.js +19 -19
  38. package/templates/component/index.test.js +14 -14
  39. package/templates/module/reducer/index.js +20 -20
  40. package/templates/module/saga/index.js +9 -9
  41. package/generators/es.regexp.flags-ccfbed60.js +0 -1
  42. package/templates/app/src/icons.js +0 -4
@@ -1 +1,392 @@
1
- "use strict";var e=require("got"),t=require("path"),s=require("gulp-if"),a=require("date-fns"),i=require("../util/fs.js"),o=require("gulp-prettier"),r=require("jsonfile"),n=require("yeoman-stylelint"),l=require("spdx-license-ids");require("mkdirp"),l.push("SEE LICENSE IN LICENSE"),l.sort();const p=require("yeoman-generator"),c=(...e)=>t.join("src",...e),d=[{value:null,name:"None"},{value:"bootstrap",name:"Bootstrap"},{value:"bulma",name:"Bulma"},{value:"foundation",name:"Foundation"},{value:"materialize",name:"Materialize"},{value:"uikit",name:"UIKit"},{value:"materialUi",name:"Material-UI"}],m={fontAwesome:["@fortawesome/fontawesome-svg-core","@fortawesome/free-solid-svg-icons","@fortawesome/react-fontawesome"],bootstrap:["bootstrap"],uikit:["uikit","uikit-react"],foundation:["foundation-sites"],materialize:["materialize-css"],bulma:["bulma"],materialUi:["@material-ui/core"],lintStaged:["husky","lint-staged"],redux:["redux","react-redux","redux-saga"],reduxJest:["redux-mock-store"],core:["@babel/runtime","core-js","normalize-scss","prop-types","react@17","react-dom@17","react-router-dom","reselect","classnames"],storybook:["@storybook/react","@storybook/addons","@storybook/addon-knobs"],esdoc:["esdoc","esdoc-ecmascript-proposal-plugin","esdoc-jsx-plugin","esdoc-standard-plugin","opener"],jest:["babel-jest","eslint-plugin-jest","jest","react-test-renderer","opener"],dev:["@babel/core","@babel/eslint-parser","@babel/plugin-proposal-class-properties","@babel/plugin-proposal-object-rest-spread","@babel/plugin-transform-regenerator","@babel/plugin-transform-runtime","@babel/preset-env","@babel/preset-react","@babel/register","autoprefixer","babel-loader","clean-webpack-plugin","cross-env","css-loader","css-minimizer-webpack-plugin","eslint-config-prettier","eslint-import-resolver-webpack","eslint-plugin-import","eslint-plugin-jsx-a11y","eslint-plugin-prettier","eslint-plugin-react-hooks","eslint-plugin-react","eslint-webpack-plugin","eslint","html-loader","html-webpack-plugin","mini-css-extract-plugin","postcss-flexbugs-fixes","postcss-loader","postcss-scss","prettier","sass-loader","sass","style-loader","stylelint-config-recommended","stylelint-webpack-plugin","stylelint","terser-webpack-plugin","webpack-cli","webpack","webpack-dev-server"]},u={core:[".babelrc",".prettierrc",".stylelintrc",".editorconfig","jsconfig.json",".browserslistrc",c("utils","index.js")],templated:[".eslintrc.js","package.json",c("index.js"),c("index.html"),c("index.scss"),"webpack.config.babel.js"],esdoc:[".esdoc.json"],jest:["jest.config.js"],lintStaged:[".lintstagedrc"],fontAwesome:[c("icons.js")]},g={redux:[c("reducers"),c("sagas"),c("selectors")],core:[c("components"),c("utils")]},h={"build:documentation":"esdoc","view:documentation":"opener ./docs/index.html"},y={test:"jest","view:coverage":"opener ./coverage/index.html"};module.exports=class extends p{constructor(...e){super(...e),this.env.adapter.promptModule.registerPrompt("autocomplete",require("inquirer-autocomplete-prompt")),this.sourceRoot(t.join(__dirname,"..","..","templates","app")),this.answers={},this.fileSystem=i(this),this.registerTransformStream(s(/\.js$/,o(r.readFileSync(t.join(__dirname,"..","..",".prettierrc"))))),this.registerTransformStream(s(/\.scss$/,n({configFile:t.join(__dirname,"..","..",".stylelintrc")})))}async prompting(){const{name:e,email:t}=this.user.git;this.answers=await this.prompt([{type:"input",name:"package.name",message:"Package name",default:this.appname.replace(/\s+/g,"-")},{type:"input",name:"package.version",message:"Package version",default:"0.1.0"},{type:"autocomplete",name:"package.license",message:"Package license",source:(e,t)=>{const s=new RegExp(`.*${t}.*`,"i");return new Promise((e=>{e(l.filter((e=>s.test(e))))}))}},{type:"input",name:"package.description",message:"Package description"},{type:"input",name:"author.name",message:"Author name",default:e()},{type:"input",name:"author.email",message:"Author email address",default:t()},{type:"list",name:"styleFramework",message:"What CSS framework would you like to use?",choices:d},{type:"confirm",name:"flags.addLintStaged",message:"Force linting before commits?",default:!0},{type:"confirm",name:"flags.addFontAwesome",message:"Add Font Awesome?",default:!0},{type:"confirm",name:"flags.addRedux",message:"Add Redux?",default:!0},{type:"confirm",name:"flags.addJest",message:"Add Jest?",default:!0},{type:"confirm",name:"flags.addStorybook",message:"Add Storybook?",default:!1},{type:"confirm",name:"flags.addESDoc",message:"Add ESDoc?",default:!1}])}async writing(){const{flags:t,package:{license:s},author:{name:i,email:o}}=this.answers;let r="Place your license here.\n";if("SEE LICENSE IN LICENSE"!==s){this.log(`Downloading ${s} license from spdx/license-list-data...`);const{body:t}=await e(`https://raw.githubusercontent.com/spdx/license-list-data/master/text/${s}.txt`);r=t.replace("<year>",a.format(new Date,"yyyy")).replace("<copyright holders>",`${i} <${o}>`)}this.fileSystem.createFile("LICENSE",r),u.core.forEach(this.fileSystem.copy),u.templated.forEach(this.fileSystem.copyTemplateInPlace),g.core.forEach(this.fileSystem.copyDirectory),this.fileSystem.copyTo("gitignore",".gitignore"),t.addRedux&&g.redux.forEach(this.fileSystem.copyDirectory),t.addJest&&(u.jest.forEach(this.fileSystem.copy),this.fs.append(this.destinationPath(".gitignore"),"coverage/"),this.fs.extendJSON(this.destinationPath("package.json"),{scripts:{...y}})),t.addESDoc&&(u.esdoc.forEach(this.fileSystem.copy),this.fs.append(this.destinationPath(".gitignore"),"docs/"),this.fs.extendJSON(this.destinationPath("package.json"),{scripts:{...h}})),t.addLintStaged&&u.lintStaged.forEach(this.fileSystem.copy),t.addFontAwesome&&u.fontAwesome.forEach(this.fileSystem.copy)}install(){const e=[],t=[],{flags:s,styleFramework:a}=this.answers;this.log("Building a list of packages to install"),e.push.apply(e,m.core),t.push.apply(t,m.dev),null!==a&&e.push.apply(e,m[a]),s.addLintStaged&&t.push.apply(t,m.lintStaged),s.addFontAwesome&&e.push.apply(e,m.fontAwesome),s.addRedux&&e.push.apply(e,m.redux),s.addJest&&t.push.apply(t,m.jest),s.addRedux&&s.addJest&&t.push.apply(t,m.reduxJest),s.addStorybook&&t.push.apply(t,m.storybook),s.addESDoc&&e.push.apply(e,m.esdoc),this.log(`Getting ready to install ${e.length} dependencies and ${t.length} dev dependencies.`),this.npmInstall(e,{save:!0}),this.npmInstall(t,{"save-dev":!0}),this.spawnCommandSync("git",["init"]),this.spawnCommandSync("npx",["husky","install"]),this.spawnCommandSync("npx",["husky","add",".husky/pre-commit","npx lint-staged"])}};
1
+ import { got } from 'got';
2
+ import { join } from 'path';
3
+ import gulpIf from 'gulp-if';
4
+ import jsonfile from 'jsonfile';
5
+ import { format } from 'date-fns';
6
+ import prettier from 'gulp-prettier';
7
+ import { createRequire } from 'module';
8
+ import stylelint from 'yeoman-stylelint';
9
+ import inquirerPrompt from 'inquirer-autocomplete-prompt';
10
+ import spdxIdentifiers from 'spdx-license-ids' assert { type: 'json' };
11
+
12
+ import fileSystem from '../util/fs.js';
13
+
14
+ spdxIdentifiers.push('SEE LICENSE IN LICENSE');
15
+ spdxIdentifiers.sort();
16
+
17
+ const { readFileSync } = jsonfile;
18
+
19
+ // we cannot use ES6 imports on this object, as it directly exports a class to
20
+ // module.exports - no default export nor a named export is present for us to use
21
+ const require = createRequire(import.meta.url);
22
+ const Generator = require('yeoman-generator');
23
+
24
+ const src = (...paths) => join('src', ...paths);
25
+
26
+ const styleFrameworks = [
27
+ { value: null, name: 'None' },
28
+ { value: 'bootstrap', name: 'Bootstrap' },
29
+ { value: 'bulma', name: 'Bulma' },
30
+ { value: 'foundation', name: 'Foundation' },
31
+ { value: 'materialize', name: 'Materialize' },
32
+ { value: 'uikit', name: 'UIKit' },
33
+ { value: 'materialUi', name: 'Material-UI' }
34
+ ];
35
+ const packages = {
36
+ fontAwesome: [
37
+ '@fortawesome/fontawesome-svg-core',
38
+ '@fortawesome/free-solid-svg-icons',
39
+ '@fortawesome/react-fontawesome'
40
+ ],
41
+ bootstrap: ['bootstrap', 'react-bootstrap'],
42
+ uikit: ['uikit', 'uikit-react'],
43
+ foundation: ['foundation-sites'],
44
+ materialize: ['materialize-css'],
45
+ bulma: ['bulma'],
46
+ materialUi: ['@material-ui/core'],
47
+ lintStaged: ['husky', 'lint-staged'],
48
+ redux: ['redux', 'react-redux', 'redux-saga'],
49
+ reduxJest: ['redux-mock-store'],
50
+ core: [
51
+ '@babel/runtime-corejs3',
52
+ 'core-js@3',
53
+ 'normalize-scss',
54
+ 'prop-types',
55
+ 'react',
56
+ 'react-dom',
57
+ 'react-router-dom',
58
+ 'reselect',
59
+ 'classnames'
60
+ ],
61
+ storybook: [
62
+ '@storybook/react',
63
+ '@storybook/builder-webpack5',
64
+ '@storybook/manager-webpack5'
65
+ ],
66
+ esdoc: [
67
+ 'esdoc',
68
+ 'esdoc-ecmascript-proposal-plugin',
69
+ 'esdoc-jsx-plugin',
70
+ 'esdoc-standard-plugin',
71
+ 'opener'
72
+ ],
73
+ jest: [
74
+ 'babel-jest',
75
+ 'eslint-plugin-jest',
76
+ 'jest',
77
+ 'react-test-renderer',
78
+ 'opener'
79
+ ],
80
+ dev: [
81
+ '@babel/core',
82
+ '@babel/eslint-parser',
83
+ '@babel/plugin-transform-runtime',
84
+ '@babel/preset-env',
85
+ '@babel/preset-react',
86
+ '@babel/register',
87
+ 'autoprefixer',
88
+ 'babel-loader',
89
+ 'clean-webpack-plugin',
90
+ 'cross-env',
91
+ 'css-loader',
92
+ 'css-minimizer-webpack-plugin',
93
+ 'eslint-config-prettier',
94
+ 'eslint-import-resolver-webpack',
95
+ 'eslint-plugin-import',
96
+ 'eslint-plugin-jsx-a11y',
97
+ 'eslint-plugin-prettier',
98
+ 'eslint-plugin-react-hooks',
99
+ 'eslint-plugin-react',
100
+ 'eslint-webpack-plugin',
101
+ 'eslint',
102
+ 'html-loader',
103
+ 'html-webpack-plugin',
104
+ 'mini-css-extract-plugin',
105
+ 'postcss-flexbugs-fixes',
106
+ 'postcss-loader',
107
+ 'postcss-scss',
108
+ 'prettier',
109
+ 'sass-loader',
110
+ 'sass',
111
+ 'style-loader',
112
+ 'stylelint-config-recommended',
113
+ 'stylelint-webpack-plugin',
114
+ 'stylelint',
115
+ 'terser-webpack-plugin',
116
+ 'webpack-cli',
117
+ 'webpack',
118
+ 'webpack-dev-server'
119
+ ]
120
+ };
121
+ const files = {
122
+ core: [
123
+ '.babelrc',
124
+ '.prettierrc',
125
+ '.stylelintrc',
126
+ '.editorconfig',
127
+ 'jsconfig.json',
128
+ '.browserslistrc',
129
+ src('utils', 'index.js')
130
+ ],
131
+ templated: [
132
+ '.eslintrc.js',
133
+ 'package.json',
134
+ src('index.js'),
135
+ src('index.html'),
136
+ src('index.scss'),
137
+ 'webpack.config.babel.js'
138
+ ],
139
+ esdoc: ['.esdoc.json'],
140
+ jest: ['jest.config.js'],
141
+ lintStaged: ['.lintstagedrc']
142
+ };
143
+ const directories = {
144
+ redux: [src('reducers'), src('sagas'), src('selectors')],
145
+ core: [src('components'), src('utils')]
146
+ };
147
+ const scripts = {
148
+ esdoc: {
149
+ 'build:documentation': 'esdoc',
150
+ 'view:documentation': 'opener ./docs/index.html'
151
+ },
152
+ jest: {
153
+ test: 'jest',
154
+ 'view:coverage': 'opener ./coverage/index.html'
155
+ }
156
+ };
157
+
158
+ export default class extends Generator {
159
+ constructor(...args) {
160
+ super(...args);
161
+
162
+ this.env.adapter.promptModule.registerPrompt(
163
+ 'autocomplete',
164
+ inquirerPrompt
165
+ );
166
+
167
+ this.answers = {};
168
+ this.fileSystem = fileSystem(this);
169
+ this.sourceRoot(this.fileSystem.resolve('templates', 'app'));
170
+ this.registerTransformStream(
171
+ gulpIf(
172
+ /\.js$/,
173
+ prettier(readFileSync(this.fileSystem.resolve('.prettierrc')))
174
+ )
175
+ );
176
+ this.registerTransformStream(
177
+ gulpIf(
178
+ /\.scss$/,
179
+ stylelint({
180
+ configFile: this.fileSystem.resolve('.stylelintrc')
181
+ })
182
+ )
183
+ );
184
+ }
185
+
186
+ async prompting() {
187
+ const { name, email } = this.user.git;
188
+
189
+ this.answers = await this.prompt([
190
+ {
191
+ type: 'input',
192
+ name: 'package.name',
193
+ message: 'Package name',
194
+ default: this.appname.replace(/\s+/g, '-')
195
+ },
196
+ {
197
+ type: 'input',
198
+ name: 'package.version',
199
+ message: 'Package version',
200
+ default: '0.1.0'
201
+ },
202
+ {
203
+ type: 'autocomplete',
204
+ name: 'package.license',
205
+ message: 'Package license',
206
+ source: (_, input) => {
207
+ const pattern = new RegExp(`.*${input}.*`, 'i');
208
+
209
+ return new Promise((resolve) => {
210
+ resolve(
211
+ spdxIdentifiers.filter((identifier) => pattern.test(identifier))
212
+ );
213
+ });
214
+ }
215
+ },
216
+ {
217
+ type: 'input',
218
+ name: 'package.description',
219
+ message: 'Package description'
220
+ },
221
+ {
222
+ type: 'input',
223
+ name: 'author.name',
224
+ message: 'Author name',
225
+ default: name()
226
+ },
227
+ {
228
+ type: 'input',
229
+ name: 'author.email',
230
+ message: 'Author email address',
231
+ default: email()
232
+ },
233
+ {
234
+ type: 'list',
235
+ name: 'styleFramework',
236
+ message: 'What CSS framework would you like to use?',
237
+ choices: styleFrameworks
238
+ },
239
+ {
240
+ type: 'confirm',
241
+ name: 'flags.addLintStaged',
242
+ message: 'Force linting before commits?',
243
+ default: true
244
+ },
245
+ {
246
+ type: 'confirm',
247
+ name: 'flags.addFontAwesome',
248
+ message: 'Add Font Awesome?',
249
+ default: true
250
+ },
251
+ {
252
+ type: 'confirm',
253
+ name: 'flags.addRedux',
254
+ message: 'Add Redux?',
255
+ default: true
256
+ },
257
+ {
258
+ type: 'confirm',
259
+ name: 'flags.addJest',
260
+ message: 'Add Jest?',
261
+ default: true
262
+ },
263
+ {
264
+ type: 'confirm',
265
+ name: 'flags.addStorybook',
266
+ message: 'Add Storybook?',
267
+ default: false
268
+ },
269
+ {
270
+ type: 'confirm',
271
+ name: 'flags.addESDoc',
272
+ message: 'Add ESDoc?',
273
+ default: false
274
+ }
275
+ ]);
276
+ }
277
+
278
+ async writing() {
279
+ const {
280
+ flags,
281
+ package: { license },
282
+ author: { name, email }
283
+ } = this.answers;
284
+
285
+ let licenseText = 'Place your license here.\n';
286
+
287
+ if (license !== 'SEE LICENSE IN LICENSE') {
288
+ this.log(`Downloading ${license} license from spdx/license-list-data...`);
289
+ const { body: rawLicense } = await got(
290
+ `https://raw.githubusercontent.com/spdx/license-list-data/master/text/${license}.txt`
291
+ );
292
+
293
+ licenseText = rawLicense
294
+ .replace('<year>', format(new Date(), 'yyyy'))
295
+ .replace('<copyright holders>', `${name} <${email}>`);
296
+ }
297
+ this.fileSystem.createFile('LICENSE', licenseText);
298
+
299
+ // copy files and directories
300
+ files.core.forEach(this.fileSystem.copy);
301
+ files.templated.forEach(this.fileSystem.copyTemplateInPlace);
302
+ directories.core.forEach(this.fileSystem.copyDirectory);
303
+
304
+ // this is a workaround for npm not packaging up .gitignore files
305
+ this.fileSystem.copyTo('gitignore', '.gitignore');
306
+
307
+ if (flags.addRedux) {
308
+ directories.redux.forEach(this.fileSystem.copyDirectory);
309
+ }
310
+
311
+ if (flags.addJest) {
312
+ files.jest.forEach(this.fileSystem.copy);
313
+ this.fs.append(this.destinationPath('.gitignore'), 'coverage/');
314
+ this.fs.extendJSON(this.destinationPath('package.json'), {
315
+ scripts: {
316
+ ...scripts.jest
317
+ }
318
+ });
319
+ }
320
+
321
+ if (flags.addESDoc) {
322
+ files.esdoc.forEach(this.fileSystem.copy);
323
+ this.fs.append(this.destinationPath('.gitignore'), 'docs/');
324
+ this.fs.extendJSON(this.destinationPath('package.json'), {
325
+ scripts: {
326
+ ...scripts.esdoc
327
+ }
328
+ });
329
+ }
330
+
331
+ if (flags.addLintStaged) {
332
+ files.lintStaged.forEach(this.fileSystem.copy);
333
+ }
334
+ }
335
+
336
+ install() {
337
+ const main = [];
338
+ const dev = [];
339
+ const { flags, styleFramework } = this.answers;
340
+
341
+ this.log('Building a list of packages to install');
342
+
343
+ main.push.apply(main, packages.core);
344
+ dev.push.apply(dev, packages.dev);
345
+
346
+ if (styleFramework !== null) {
347
+ main.push.apply(main, packages[styleFramework]);
348
+ }
349
+
350
+ if (flags.addLintStaged) {
351
+ dev.push.apply(dev, packages.lintStaged);
352
+ }
353
+
354
+ if (flags.addFontAwesome) {
355
+ main.push.apply(main, packages.fontAwesome);
356
+ }
357
+
358
+ if (flags.addRedux) {
359
+ main.push.apply(main, packages.redux);
360
+ }
361
+
362
+ if (flags.addJest) {
363
+ dev.push.apply(dev, packages.jest);
364
+ }
365
+
366
+ if (flags.addRedux && flags.addJest) {
367
+ dev.push.apply(dev, packages.reduxJest);
368
+ }
369
+
370
+ if (flags.addStorybook) {
371
+ dev.push.apply(dev, packages.storybook);
372
+ }
373
+
374
+ if (flags.addESDoc) {
375
+ main.push.apply(main, packages.esdoc);
376
+ }
377
+
378
+ this.log(
379
+ `Getting ready to install ${main.length} dependencies and ${dev.length} dev dependencies.`
380
+ );
381
+ this.log(`Dependencies: ${main.join(' ')}
382
+ Dev dependencies: ${dev.join(' ')}`);
383
+ this.npmInstall(main, { save: true });
384
+ this.npmInstall(dev, { 'save-dev': true });
385
+ this.spawnCommandSync('git', ['init']);
386
+ this.spawnCommandSync('npx', ['husky', 'init']);
387
+ this.spawnCommandSync('bash', [
388
+ '-c',
389
+ 'echo "npx lint-staged" > .husky/pre-commit'
390
+ ]);
391
+ }
392
+ }
@@ -1 +1,51 @@
1
- "use strict";var e=require("path"),t=require("../util/fs.js");require("mkdirp");const s=require("yeoman-generator"),n=(...t)=>e.join("src",...t);module.exports=class extends s{constructor(...s){super(...s),this.sourceRoot(e.join(__dirname,"..","..","templates","component")),this.answers={},this.fileSystem=t(this)}async prompting(){this.answers=await this.prompt([{type:"input",name:"component.name",message:"Component name"},{type:"confirm",name:"flags.addRedux",message:"Connect this component to the Redux store?",default:!1}])}async writing(){const{component:{name:e}}=this.answers,t=n("components",`${e}.js`),s=n("components",`${e}.test.js`);this.log(`Creating ${e} component`),await this.fileSystem.copyTemplate("index.js",t),await this.fileSystem.copyTemplate("index.test.js",s)}};
1
+ import { join } from 'path';
2
+ import { createRequire } from 'module';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ import fileSystem from '../util/fs.js';
6
+
7
+ // we cannot use ES6 imports on this object, as it directly exports a class to
8
+ // module.exports - no default export nor a named export is present for us to use
9
+ const require = createRequire(import.meta.url);
10
+ const __dirname = fileURLToPath(import.meta.url);
11
+ const Generator = require('yeoman-generator');
12
+
13
+ const src = (...paths) => join('src', ...paths);
14
+
15
+ export default class extends Generator {
16
+ constructor(...args) {
17
+ super(...args);
18
+
19
+ this.sourceRoot(join(__dirname, '..', '..', 'templates', 'component'));
20
+ this.answers = {};
21
+ this.fileSystem = fileSystem(this);
22
+ }
23
+
24
+ async prompting() {
25
+ this.answers = await this.prompt([
26
+ {
27
+ type: 'input',
28
+ name: 'component.name',
29
+ message: 'Component name'
30
+ },
31
+ {
32
+ type: 'confirm',
33
+ name: 'flags.addRedux',
34
+ message: 'Connect this component to the Redux store?',
35
+ default: false
36
+ }
37
+ ]);
38
+ }
39
+
40
+ async writing() {
41
+ const {
42
+ component: { name }
43
+ } = this.answers;
44
+ const fileName = src('components', `${name}.js`);
45
+ const testName = src('components', `${name}.test.js`);
46
+
47
+ this.log(`Creating ${name} component`);
48
+ await this.fileSystem.copyTemplate('index.js', fileName);
49
+ await this.fileSystem.copyTemplate('index.test.js', testName);
50
+ }
51
+ }
@@ -1 +1,127 @@
1
- "use strict";var e=require("path"),t=require("../util/fs.js");require("mkdirp");const a=require("yeoman-generator"),s=(...t)=>e.join("src",...t);module.exports=class extends a{constructor(...a){super(...a),this.sourceRoot(e.join(__dirname,"..","..","templates","module")),this.answers={},this.fileSystem=t(this)}async prompting(){this.answers=await this.prompt([{type:"input",name:"module.name",message:"Module name"},{type:"list",name:"directoryMode",message:"Choose a way of structuring the module.",choices:[{name:"Create a directory with the module name and an index.js file inside that.",value:"dir",short:"Directory"},{name:"Create a file with the module name.",value:"file",short:"File"}]},{type:"confirm",name:"flags.createReducer",message:"Generate a reducer?",default:!0},{type:"confirm",name:"flags.createSaga",message:"Generate a saga?",default:!0},{type:"confirm",name:"flags.createSelector",message:"Generate a selector?",default:!0},{type:"confirm",name:"flags.addJest",message:"Generate test files?",default:!0}])}async writing(){const{directoryMode:t,module:{name:a},flags:r}=this.answers;this.log(`Creating module ${a}`);const i=i=>{const o=`${a}${i}`,n=`index${i}`,c=[];switch(t){default:case"file":c.push(o);break;case"dir":c.push(a,n)}r.createReducer&&this.fileSystem.copyTemplate(e.join("reducer",n),s("reducers",...c)),r.createSaga&&this.fileSystem.copyTemplate(e.join("saga",n),s("sagas",...c)),r.createSelector&&this.fileSystem.copyTemplate(e.join("selector",n),s("selectors",...c))};i(".js"),r.addJest&&i(".test.js")}};
1
+ import { join, dirname } from 'path';
2
+ import { createRequire } from 'module';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ import fileSystem from '../util/fs.js';
6
+
7
+ // we cannot use ES6 imports on this object, as it directly exports a class to
8
+ // module.exports - no default export nor a named export is present for us to use
9
+ const require = createRequire(import.meta.url);
10
+ const __dirname = fileURLToPath(import.meta.url);
11
+ const Generator = require('yeoman-generator');
12
+
13
+ const src = (...paths) => join('src', ...paths);
14
+
15
+ export default class extends Generator {
16
+ constructor(...args) {
17
+ super(...args);
18
+
19
+ this.sourceRoot(join(__dirname, '..', '..', 'templates', 'module'));
20
+ this.answers = {};
21
+ this.fileSystem = fileSystem(this);
22
+ }
23
+
24
+ async prompting() {
25
+ this.answers = await this.prompt([
26
+ {
27
+ type: 'input',
28
+ name: 'module.name',
29
+ message: 'Module name'
30
+ },
31
+ {
32
+ type: 'list',
33
+ name: 'directoryMode',
34
+ message: 'Choose a way of structuring the module.',
35
+ choices: [
36
+ {
37
+ name: 'Create a directory with the module name and an index.js file inside that.',
38
+ value: 'dir',
39
+ short: 'Directory'
40
+ },
41
+ {
42
+ name: 'Create a file with the module name.',
43
+ value: 'file',
44
+ short: 'File'
45
+ }
46
+ ]
47
+ },
48
+ {
49
+ type: 'confirm',
50
+ name: 'flags.createReducer',
51
+ message: 'Generate a reducer?',
52
+ default: true
53
+ },
54
+ {
55
+ type: 'confirm',
56
+ name: 'flags.createSaga',
57
+ message: 'Generate a saga?',
58
+ default: true
59
+ },
60
+ {
61
+ type: 'confirm',
62
+ name: 'flags.createSelector',
63
+ message: 'Generate a selector?',
64
+ default: true
65
+ },
66
+ {
67
+ type: 'confirm',
68
+ name: 'flags.addJest',
69
+ message: 'Generate test files?',
70
+ default: true
71
+ }
72
+ ]);
73
+ }
74
+
75
+ async writing() {
76
+ const {
77
+ directoryMode,
78
+ module: { name },
79
+ flags
80
+ } = this.answers;
81
+
82
+ this.log(`Creating module ${name}`);
83
+
84
+ const buildPaths = (ext) => {
85
+ const namePath = `${name}${ext}`;
86
+ const indexPath = `index${ext}`;
87
+ const destPath = [];
88
+
89
+ switch (directoryMode) {
90
+ default:
91
+ case 'file':
92
+ destPath.push(namePath);
93
+ break;
94
+ case 'dir':
95
+ destPath.push(name, indexPath);
96
+ break;
97
+ }
98
+
99
+ if (flags.createReducer) {
100
+ this.fileSystem.copyTemplate(
101
+ join('reducer', indexPath),
102
+ src('reducers', ...destPath)
103
+ );
104
+ }
105
+
106
+ if (flags.createSaga) {
107
+ this.fileSystem.copyTemplate(
108
+ join('saga', indexPath),
109
+ src('sagas', ...destPath)
110
+ );
111
+ }
112
+
113
+ if (flags.createSelector) {
114
+ this.fileSystem.copyTemplate(
115
+ join('selector', indexPath),
116
+ src('selectors', ...destPath)
117
+ );
118
+ }
119
+ };
120
+
121
+ buildPaths('.js');
122
+
123
+ if (flags.addJest) {
124
+ buildPaths('.test.js');
125
+ }
126
+ }
127
+ }
@@ -1 +1,34 @@
1
- "use strict";var t=require("mkdirp");module.exports=e=>({copy:t=>e.fs.copy(e.templatePath(t),e.destinationPath(t)),copyTo:(t,a)=>e.fs.copy(e.templatePath(t),e.destinationPath(a)),copyDirectory:t=>e.fs.copyTpl(e.templatePath(`${t}/**/*`),e.destinationPath(t),e.answers),copyTemplate:(t,a)=>e.fs.copyTpl(e.templatePath(t),e.destinationPath(a),e.answers),copyTemplateInPlace:t=>e.fs.copyTpl(e.templatePath(t),e.destinationPath(t),e.answers),createFile:(t,a)=>e.fs.write(e.destinationPath(t),a),makeDirectory:t});
1
+ import { mkdirp } from 'mkdirp';
2
+ import { join } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const __dirname = fileURLToPath(import.meta.url);
6
+
7
+ export default (gen) => ({
8
+ copy: (file) =>
9
+ gen.fs.copy(gen.templatePath(file), gen.destinationPath(file)),
10
+ copyTo: (src, dst) =>
11
+ gen.fs.copy(gen.templatePath(src), gen.destinationPath(dst)),
12
+ copyDirectory: (dir) =>
13
+ gen.fs.copyTpl(
14
+ gen.templatePath(`${dir}/**/*`),
15
+ gen.destinationPath(dir),
16
+ gen.answers
17
+ ),
18
+ copyTemplate: (source, destination) =>
19
+ gen.fs.copyTpl(
20
+ gen.templatePath(source),
21
+ gen.destinationPath(destination),
22
+ gen.answers
23
+ ),
24
+ copyTemplateInPlace: (file) =>
25
+ gen.fs.copyTpl(
26
+ gen.templatePath(file),
27
+ gen.destinationPath(file),
28
+ gen.answers
29
+ ),
30
+ createFile: (file, contents) =>
31
+ gen.fs.write(gen.destinationPath(file), contents),
32
+ makeDirectory: mkdirp,
33
+ resolve: (...paths) => join(__dirname, '..', '..', '..', ...paths)
34
+ });