1
1
#! /usr/bin/env node
2
2
3
- const prompts = require ( 'prompts' ) ;
4
-
5
- const selectPluginTYpe = [
6
- {
7
- type : 'select' ,
8
- name : 'pluginType' ,
9
- message : 'What type of plugin do you want to create?' ,
10
- choices : [
11
- { title : 'Backend Plugin' , value : 'backend' } ,
12
- { title : 'Frontend Plugin' , value : 'frontend' } ,
13
- { title : "Standard Plugin" , value : 'standard' }
14
- ]
15
- }
16
- ] ;
17
-
18
- ( async ( ) => {
19
- const { pluginType } = await prompts ( selectPluginTYpe ) ;
20
- console . log ( pluginType ) ;
21
- }
22
- ) ( ) ;
3
+ import prompts from 'prompts'
4
+ import path from 'path'
5
+ import fs from 'fs'
6
+ import humps from 'humps'
7
+ import { exec } from 'child_process'
8
+ import ora from 'ora'
9
+ import { URL } from 'node:url' ;
10
+
11
+ const __dirname = path . dirname ( new URL ( import . meta. url ) . pathname )
12
+
13
+ const args = process . argv . slice ( 2 )
14
+
15
+ const selectPluginType = [
16
+ {
17
+ type : 'text' ,
18
+ name : 'pluginName' ,
19
+ message : 'What is the name of your plugin?' ,
20
+ initial : args [ 0 ] || '' ,
21
+ validate : ( name ) => {
22
+ if ( ! name ) {
23
+ return 'Plugin name is required'
24
+ }
25
+ if ( ! validatePluginName ( name ) ) {
26
+ return 'Invalid plugin name, please use only letters, numbers, underscores, and hyphens, and cannot start with a number.'
27
+ }
28
+ return true
29
+ } ,
30
+ } ,
31
+ {
32
+ type : 'select' ,
33
+ name : 'pluginType' ,
34
+ message : 'What type of plugin do you want to create?' ,
35
+ choices : [
36
+ { title : 'Backend Plugin' , value : 'backend' } ,
37
+ { title : 'Standard Plugin' , value : 'standard' } ,
38
+ ] ,
39
+ } ,
40
+ ]
41
+
42
+ const validatePluginName = ( name ) => {
43
+ const reg = / ^ [ a - z A - Z _ ] [ a - z A - Z 0 - 9 _ - ] * $ /
44
+ return reg . test ( name )
45
+ }
46
+
47
+ const createPluginDir = async ( name ) => {
48
+ const pluginName = humps . camelize ( name )
49
+ const packageName = humps . decamelize ( pluginName , { separator : '-' } )
50
+ const pluginDisplayName = humps . pascalize ( pluginName )
51
+ const pluginSlugName = humps . decamelize ( pluginName , { separator : '_' } )
52
+ const targetPath = path . resolve ( process . cwd ( ) , packageName )
53
+
54
+ fs . mkdirSync ( targetPath )
55
+ return {
56
+ pluginName,
57
+ packageName,
58
+ pluginDisplayName,
59
+ pluginSlugName,
60
+ targetPath,
61
+ }
62
+ }
63
+
64
+ const createBackendPlugin = async ( {
65
+ pluginName,
66
+ pluginDisplayName,
67
+ pluginSlugName,
68
+ targetPath,
69
+ } ) => {
70
+ const templatePath = path . resolve ( __dirname , '../template/plugin.go' )
71
+ const content = fs . readFileSync ( templatePath , 'utf-8' )
72
+ const result = content
73
+ . replace ( / { { plugin_ d i s p l a y _ n a m e } } / g, pluginDisplayName )
74
+ . replace ( / { { plugin_ s l u g _ n a m e } } / g, pluginSlugName )
75
+
76
+ fs . writeFileSync ( path . resolve ( targetPath , `${ pluginName } .go` ) , result )
77
+ }
78
+
79
+ const createStandardPlugin = async ( { packageName, pluginSlugName, targetPath } ) => {
80
+ const templatePath = path . resolve ( __dirname , '../template/ui' )
81
+ fs . readdirSync ( templatePath ) . forEach ( ( file ) => {
82
+ const content = fs . readFileSync ( path . resolve ( templatePath , file ) , 'utf-8' )
83
+ const result = content
84
+ . replace ( / { { plugin_ n a m e } } / g, packageName )
85
+ . replace ( / { { plugin_ s l u g _ n a m e } } / g, pluginSlugName )
86
+ fs . writeFileSync ( path . resolve ( targetPath , file ) , result )
87
+ } )
88
+ }
89
+
90
+ const createI18n = async ( { pluginSlugName, targetPath, pluginType } ) => {
91
+ const i18nDir = path . resolve ( __dirname , '../template/i18n' )
92
+ fs . mkdirSync ( path . resolve ( targetPath , 'i18n' ) )
93
+ fs . readdirSync ( i18nDir ) . forEach ( ( file ) => {
94
+ if ( pluginType === 'backend' && file === 'index.ts' ) return
95
+ const content = fs . readFileSync ( path . resolve ( i18nDir , file ) , 'utf-8' )
96
+ const result = content . replace ( / { { plugin_ s l u g _ n a m e } } / g, pluginSlugName )
97
+ fs . writeFileSync ( path . resolve ( targetPath , 'i18n' , file ) , result )
98
+ } )
99
+ }
100
+
101
+ const createReadme = async ( { pluginName, targetPath } ) => {
102
+ const name = humps . pascalize ( pluginName )
103
+ const content = `# ${ name } Plugin`
104
+ fs . writeFileSync ( path . resolve ( targetPath , 'README.md' ) , content )
105
+ }
106
+ const installGoMod = async ( { packageName } ) => {
107
+ process . chdir ( path . resolve ( process . cwd ( ) , packageName ) )
108
+ await exec ( `go mod init github.com/apache/incubator-answer-plugins/${ packageName } && go mod tidy` )
109
+ }
110
+
111
+ const installNpm = async ( ) => {
112
+ await exec ( `pnpm install` )
113
+ }
114
+
115
+ ; ( async ( ) => {
116
+ const { pluginType, pluginName } = await prompts ( selectPluginType )
117
+ const result = await createPluginDir ( pluginName )
118
+ createI18n ( {
119
+ ...result ,
120
+ pluginType,
121
+ } )
122
+ if ( pluginType === 'standard' ) {
123
+ await createStandardPlugin ( result )
124
+
125
+ const spinner = ora ( 'Loading unicorns' ) . start ( )
126
+ await installNpm ( )
127
+ spinner . succeed ( 'Unicorns loaded' )
128
+ }
129
+
130
+ await createBackendPlugin ( result )
131
+ await installGoMod ( result )
132
+
133
+ await createReadme ( result )
134
+ } ) ( )
135
+
0 commit comments