-
Notifications
You must be signed in to change notification settings - Fork 6
/
arrow-function-component-generator.ts
106 lines (93 loc) · 2.65 KB
/
arrow-function-component-generator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import * as path from 'path'
import { Project, VariableDeclarationKind } from 'ts-morph'
import { RootContext } from '../../tools/context'
import { ReactUtils } from '../utils/react'
import { SourceUtils } from '../utils/source'
import { TsUtils } from '../utils/ts'
import {
CreateComponentArgs,
CreateComponentResult,
ViewKindEnum
} from './types'
export class ArrowFunctionComponentGenerator {
context: RootContext
reactUtils: ReactUtils
sourceUtils: SourceUtils
tsUtils: TsUtils
constructor(context: RootContext) {
this.context = context
this.reactUtils = new ReactUtils(context)
this.sourceUtils = new SourceUtils(context)
this.tsUtils = new TsUtils(context)
}
async generate(args: CreateComponentArgs): Promise<CreateComponentResult> {
const { naming } = this.context
// processing
const project = new Project()
const { location, props, state } = args
const name =
args.kind === ViewKindEnum.component
? naming.component(args.name)
: naming.screen(args.name)
// build view file
const viewPath = path.join(location, 'index.tsx')
const viewFile = project.createSourceFile(viewPath)
// build props as required
const hasProps = props && props.length
let propsName: string
if (hasProps) {
const propsInterface = this.reactUtils.createPropsInterface(
project,
name,
location,
props
)
propsName = propsInterface.getName()
viewFile.addImportDeclaration({
moduleSpecifier: './props',
namedImports: [propsName]
})
}
// build hooks as required
const hasState = state && state.length
let hooks = ''
if (hasState) {
viewFile.addImportDeclaration({
moduleSpecifier: 'react',
namedImports: ['useState']
})
hooks = this.reactUtils.createHooksStatements(state)
}
// add common react imports
viewFile.addImportDeclarations([
{
moduleSpecifier: 'react',
defaultImport: 'React'
},
{
moduleSpecifier: 'react-native',
namedImports: ['View', 'Text']
}
])
// add main function
viewFile.addVariableStatement({
declarationKind: VariableDeclarationKind.Const,
isExported: true,
declarations: [
{
name,
type: `React.FC${hasProps ? `<${propsName}>` : ''}`,
initializer: `${hasProps ? 'props' : '()'} => {
${hooks}
return (<View><Text>${name}</Text></View>)
}`
}
]
})
await this.sourceUtils.prettifyProjectFiles(project)
await project.save()
return {
path: viewPath
}
}
}