1
- import { spawn } from " child_process" ;
2
- import { existsSync , readdirSync , readFileSync } from "fs" ;
3
- import { readFile } from " fs/promises" ;
4
- import { resolve } from " path" ;
1
+ import { spawn } from ' child_process' ;
2
+ import { existsSync , readdirSync , readFileSync } from 'fs' ;
3
+ import { readFile } from ' fs/promises' ;
4
+ import { resolve } from ' path' ;
5
5
6
- import yaml from " js-yaml" ;
7
- import cheerio from " cheerio" ;
6
+ import yaml from ' js-yaml' ;
7
+ import cheerio from ' cheerio' ;
8
8
9
- import autocompletePrompt from " inquirer-autocomplete-prompt" ;
10
- import fuzzy from " fuzzy" ;
9
+ import autocompletePrompt from ' inquirer-autocomplete-prompt' ;
10
+ import fuzzy from ' fuzzy' ;
11
11
12
12
const fetchPackage = async ( path ) =>
13
- readFile ( resolve ( path , "package.json" ) , {
14
- encoding : "utf8" ,
15
- } ) . then ( JSON . parse ) ;
13
+ readFile ( resolve ( path , 'package.json' ) , {
14
+ encoding : 'utf8'
15
+ } )
16
+ . then ( JSON . parse ) ;
16
17
17
18
export default async ( plop ) => {
18
19
/* Allow customization from the environment variables */
19
- const rootFolder = process . env . ROOT_DIR ?? resolve ( process . cwd ( ) , "../../" ) ;
20
- const srcPath =
21
- process . env . COMPONENT_DIR ?? resolve ( rootFolder , "components" ) ;
22
- const projectName = process . env . PROJECT_NAME ?? "Spectrum CSS" ;
20
+ const rootFolder = process . env . ROOT_DIR ?? resolve ( process . cwd ( ) , '../../' ) ;
21
+ const srcPath = process . env . COMPONENT_DIR ?? resolve ( rootFolder , 'components' ) ;
22
+ const projectName = process . env . PROJECT_NAME ?? 'Spectrum CSS' ;
23
23
const pkg = await fetchPackage ( rootFolder ) ;
24
24
25
- const tokens = await fetchPackage ( resolve ( srcPath , "tokens" ) ) ;
26
- const builder = await fetchPackage (
27
- resolve ( process . cwd ( ) , "../component-builder-simple" )
28
- ) ;
25
+ const tokens = await fetchPackage ( resolve ( srcPath , 'tokens' ) ) ;
26
+ const builder = await fetchPackage ( resolve ( process . cwd ( ) , '../component-builder-simple' ) ) ;
29
27
30
28
/* Fetch the project name */
31
- plop . setWelcomeMessage (
32
- `Welcome to the ${ projectName } component generator!\n To get started, answer a few short questions about your component.`
33
- ) ;
29
+ plop . setWelcomeMessage ( `Welcome to the ${ projectName } component generator!\n To get started, answer a few short questions about your component.` ) ;
34
30
35
31
/* Fetch the list of existing components to avoid conflicts */
36
- const existingComponents = readdirSync ( srcPath , {
37
- withFileTypes : true ,
38
- } ) . reduce ( ( pkgs , dirent ) => {
32
+ const existingComponents = readdirSync ( srcPath , { withFileTypes : true } ) . reduce ( ( pkgs , dirent ) => {
39
33
if ( dirent . isDirectory ( ) ) pkgs . push ( dirent . name ) ;
40
34
return pkgs ;
41
35
} , [ ] ) ;
42
36
43
- plop . setHelper ( " parse" , ( str , sep = "/" , start = 0 , end = undefined ) => {
37
+ plop . setHelper ( ' parse' , ( str , sep = '/' , start = 0 , end = undefined ) => {
44
38
if ( ! str ) return ;
45
39
const array = str . split ( sep ) ;
46
40
return array . slice ( start , end ) . join ( sep ) ;
@@ -49,9 +43,7 @@ export default async (plop) => {
49
43
function getExistingMarkupExample ( metadataPath , name , plop ) {
50
44
if ( existsSync ( `${ metadataPath } /${ name } .yml` ) === false ) return ;
51
45
52
- const r = readFileSync ( `${ metadataPath } /${ name } .yml` , {
53
- encoding : "utf8" ,
54
- } ) ;
46
+ const r = readFileSync ( `${ metadataPath } /${ name } .yml` , { encoding : 'utf8' } ) ;
55
47
const result = yaml . load ( r ) ;
56
48
if ( ! result ) return ;
57
49
@@ -60,139 +52,113 @@ export default async (plop) => {
60
52
61
53
const $ = cheerio . load ( examples [ 0 ] . markup ) ;
62
54
63
- const className = plop . renderString ( "spectrum-{{ pascalCase name }}" , {
64
- name,
65
- } ) ;
55
+ const className = plop . renderString ( 'spectrum-{{ pascalCase name }}' , { name } ) ;
66
56
const $example = $ ( `.${ className } ` ) ;
67
57
68
58
if ( ! $example ) return ;
69
59
70
60
return $example . first ( ) . toString ( ) ;
71
61
}
72
62
73
- plop . setActionType (
74
- "install" ,
75
- ( _ , config ) =>
76
- new Promise ( ( resolve , reject ) => {
77
- const install = spawn ( "yarn" , [ "install" ] , {
78
- cwd : config . root ,
79
- shell : true ,
80
- stdio : "inherit" ,
81
- } ) ;
82
- install . on ( "close" , ( code ) => {
83
- if ( `${ code } ` === "0" ) {
84
- resolve ( `Successfully installed dependencies.` ) ;
85
- } else {
86
- reject ( `Failed to install dependencies; exit code ${ code } .` ) ;
87
- }
88
- } ) ;
89
- } )
90
- ) ;
63
+ plop . setActionType ( 'install' , ( _ , config ) => new Promise ( ( resolve , reject ) => {
64
+ const install = spawn ( 'yarn' , [ 'install' ] , {
65
+ cwd : config . root ,
66
+ shell : true ,
67
+ stdio : 'inherit' ,
68
+ } ) ;
69
+ install . on ( 'close' , ( code ) => {
70
+ if ( `${ code } ` === '0' ) {
71
+ resolve ( `Successfully installed dependencies.` ) ;
72
+ } else {
73
+ reject ( `Failed to install dependencies; exit code ${ code } .` ) ;
74
+ }
75
+ } ) ;
76
+ } ) ) ;
91
77
92
- plop . setGenerator ( " component" , {
93
- description : " Component generator" ,
78
+ plop . setGenerator ( ' component' , {
79
+ description : ' Component generator' ,
94
80
prompts : [
95
81
{
96
- type : " input" ,
97
- name : " name" ,
98
- message : " Component name (i.e. Help text)" ,
82
+ type : ' input' ,
83
+ name : ' name' ,
84
+ message : ' Component name (i.e. Help text)' ,
99
85
validate : ( answer ) => {
100
86
if ( ! answer || answer . length < 1 ) {
101
87
return "Naming is hard; but it must have a name. You can always change it later." ;
102
88
}
103
89
104
- const name = plop . renderString ( "{{ lowerCase (camelCase name) }}" , {
105
- name : answer ,
106
- } ) ;
90
+ const name = plop . renderString ( '{{ lowerCase (camelCase name) }}' , { name : answer } ) ;
107
91
if ( name && existingComponents && existingComponents . includes ( name ) ) {
108
92
return "A component with that name already exists. You can always change it later." ;
109
93
}
110
94
111
95
return true ;
112
96
} ,
113
- transformer : ( answer ) =>
114
- plop . renderString ( "{{ sentenceCase name }}" , {
115
- name : answer ,
116
- } ) ,
97
+ transformer : ( answer ) => plop . renderString ( '{{ sentenceCase name }}' , { name : answer } ) ,
117
98
} ,
118
99
] ,
119
100
actions : ( data ) => {
120
101
data . description = `The ${ data . name } component is...` ;
121
- data . folderName = plop . renderString (
122
- "{{ lowerCase (camelCase name) }}" ,
123
- data
124
- ) ;
102
+ data . folderName = plop . renderString ( '{{ lowerCase (camelCase name) }}' , data ) ;
125
103
data . pkg = pkg ;
126
104
data . tokens = { name : tokens . name , version : tokens . version } ;
127
105
data . builder = { name : builder . name , version : builder . version } ;
128
106
129
107
return [
130
108
{
131
- type : " addMany" ,
109
+ type : ' addMany' ,
132
110
destination : `${ srcPath } /{{ folderName }}` ,
133
- base : " templates" ,
134
- templateFiles : " templates/**/*.hbs" ,
111
+ base : ' templates' ,
112
+ templateFiles : ' templates/**/*.hbs' ,
135
113
skipIfExists : true ,
136
114
} ,
137
115
{
138
- type : " install" ,
116
+ type : ' install' ,
139
117
root : rootFolder ,
140
118
} ,
141
- ( data , config , plop ) =>
142
- plop . renderString (
143
- `Successfully created component {{ folderName }}. To preview your component, run \`yarn dev\` and navigate to the {{ folderName }} story.`
144
- ) ,
119
+ ( data , config , plop ) => plop . renderString ( `Successfully created component {{ folderName }}. To preview your component, run \`yarn dev\` and navigate to the {{ folderName }} story.` ) ,
145
120
] ;
146
121
} ,
147
122
} ) ;
148
123
149
- plop . setPrompt ( " autocomplete" , autocompletePrompt ) ;
150
- plop . setGenerator ( " story" , {
151
- description : " Storybook generator for existing components" ,
124
+ plop . setPrompt ( ' autocomplete' , autocompletePrompt ) ;
125
+ plop . setGenerator ( ' story' , {
126
+ description : ' Storybook generator for existing components' ,
152
127
prompts : [
153
128
{
154
- type : "autocomplete" ,
155
- name : "folderName" ,
156
- message : "Select the component you wish to update" ,
157
- source : ( _ , input = "" ) =>
158
- new Promise ( ( resolve , reject ) => {
159
- if ( existingComponents . length === 0 ) reject ( "No components found." ) ;
160
- setTimeout ( ( ) => {
161
- const results = fuzzy . filter ( input , existingComponents ) ;
162
- if ( results && results . length > 0 )
163
- resolve ( results . map ( ( r ) => r . string ) ) ;
164
- } , Math . random ( ) * 470 + 30 ) ;
165
- } ) ,
166
- emptyText : "No components match the search." ,
129
+ type : 'autocomplete' ,
130
+ name : 'folderName' ,
131
+ message : 'Select the component you wish to update' ,
132
+ source : ( _ , input = '' ) => new Promise ( ( resolve , reject ) => {
133
+ if ( existingComponents . length === 0 ) reject ( 'No components found.' ) ;
134
+ setTimeout ( ( ) => {
135
+ const results = fuzzy . filter ( input , existingComponents ) ;
136
+ if ( results && results . length > 0 ) resolve ( results . map ( ( r ) => r . string ) ) ;
137
+ } , Math . random ( ) * 470 + 30 ) ;
138
+ } ) ,
139
+ emptyText : 'No components match the search.' ,
167
140
} ,
168
141
] ,
169
142
actions : ( data ) => {
170
- data . name = plop . renderString ( " {{ sentenceCase folderName }}" , data ) ;
143
+ data . name = plop . renderString ( ' {{ sentenceCase folderName }}' , data ) ;
171
144
data . description = `The ${ data . name } component is...` ;
172
145
173
- const metadataPath = plop . renderString (
174
- `${ srcPath } /{{ folderName }}/metadata` ,
175
- data
176
- ) ;
146
+ const metadataPath = plop . renderString ( `${ srcPath } /{{ folderName }}/metadata` , data ) ;
177
147
data . example = getExistingMarkupExample ( metadataPath , data . name , plop ) ;
178
148
179
149
return [
180
150
{
181
- type : " addMany" ,
151
+ type : ' addMany' ,
182
152
destination : `${ srcPath } /{{ folderName }}/stories` ,
183
- base : " templates/stories" ,
184
- templateFiles : " templates/stories/*.hbs" ,
153
+ base : ' templates/stories' ,
154
+ templateFiles : ' templates/stories/*.hbs' ,
185
155
skipIfExists : true ,
186
156
} ,
187
157
{
188
- type : " install" ,
158
+ type : ' install' ,
189
159
root : rootFolder ,
190
160
} ,
191
- ( data , config , plop ) =>
192
- plop . renderString (
193
- `Successfully updated {{ folderName }}. To preview your component, run \`yarn dev\` and navigate to the {{ folderName }} story.` ,
194
- data
195
- ) ,
161
+ ( data , config , plop ) => plop . renderString ( `Successfully updated {{ folderName }}. To preview your component, run \`yarn dev\` and navigate to the {{ folderName }} story.` , data ) ,
196
162
] ;
197
163
} ,
198
164
} ) ;
0 commit comments