@lakutata/cli 2.1.0-alpha.4 → 2.2.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/CHANGELOG.md +22 -0
- package/README.md +0 -10
- package/dist/CLIApp.d.ts +3 -0
- package/dist/CLIApp.d.ts.map +1 -0
- package/dist/CLIApp.js +75 -0
- package/dist/controllers/CommandLineController.d.ts +20 -0
- package/dist/controllers/CommandLineController.d.ts.map +1 -0
- package/dist/controllers/CommandLineController.js +61 -0
- package/dist/lib/ProjectTypeConfig.d.ts +8 -0
- package/dist/lib/ProjectTypeConfig.d.ts.map +1 -0
- package/{src/lib/ProjectTypeConfig.ts → dist/lib/ProjectTypeConfig.js} +5 -8
- package/dist/lib/SpecialChar.d.ts +9 -0
- package/dist/lib/SpecialChar.d.ts.map +1 -0
- package/dist/lib/SpecialChar.js +11 -0
- package/dist/lib/components/DeGitPuller.d.ts +19 -0
- package/dist/lib/components/DeGitPuller.d.ts.map +1 -0
- package/dist/lib/components/DeGitPuller.js +65 -0
- package/dist/lib/components/Spinner.d.ts +23 -0
- package/dist/lib/components/Spinner.d.ts.map +1 -0
- package/dist/lib/components/Spinner.js +61 -0
- package/dist/lib/providers/Creator.d.ts +38 -0
- package/dist/lib/providers/Creator.d.ts.map +1 -0
- package/dist/lib/providers/Creator.js +142 -0
- package/dist/lib/providers/Information.d.ts +91 -0
- package/dist/lib/providers/Information.d.ts.map +1 -0
- package/dist/lib/providers/Information.js +222 -0
- package/dist/options/CreateProjectOptions.d.ts +15 -0
- package/dist/options/CreateProjectOptions.d.ts.map +1 -0
- package/dist/options/CreateProjectOptions.js +86 -0
- package/dist/options/LakutataInfoOptions.d.ts +4 -0
- package/dist/options/LakutataInfoOptions.d.ts.map +1 -0
- package/dist/options/LakutataInfoOptions.js +7 -0
- package/package.json +5 -2
- package/src/CLIApp.ts +0 -86
- package/src/controllers/CommandLineController.ts +0 -34
- package/src/lib/SpecialChar.ts +0 -8
- package/src/lib/components/DeGitPuller.ts +0 -41
- package/src/lib/components/Spinner.ts +0 -48
- package/src/lib/providers/Creator.ts +0 -125
- package/src/lib/providers/Information.ts +0 -221
- package/src/options/CreateProjectOptions.ts +0 -82
- package/src/options/LakutataInfoOptions.ts +0 -4
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import {type Spinner as CliSpinner, dots} from 'cli-spinners'
|
|
2
|
-
import {Configurable, Singleton} from 'lakutata/decorator/di'
|
|
3
|
-
import {Component} from 'lakutata'
|
|
4
|
-
import {As} from 'lakutata/helper'
|
|
5
|
-
|
|
6
|
-
@Singleton()
|
|
7
|
-
export class Spinner extends Component {
|
|
8
|
-
|
|
9
|
-
@Configurable()
|
|
10
|
-
protected readonly style: CliSpinner = dots
|
|
11
|
-
|
|
12
|
-
protected spinnerInterval: NodeJS.Timeout | null = null
|
|
13
|
-
|
|
14
|
-
protected logUpdate: any
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Initializer
|
|
18
|
-
* @protected
|
|
19
|
-
*/
|
|
20
|
-
protected async init(): Promise<void> {
|
|
21
|
-
this.logUpdate = As(await import('log-update'))
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Start spinner
|
|
26
|
-
* @param description
|
|
27
|
-
*/
|
|
28
|
-
public start(description?: string | (() => string)): void {
|
|
29
|
-
this.stop()
|
|
30
|
-
let i: number = 0
|
|
31
|
-
this.spinnerInterval = setInterval((): void => {
|
|
32
|
-
const {frames} = this.style
|
|
33
|
-
const text: string = description ? `${frames[i = ++i % frames.length]} ${typeof description === 'function' ? description() : description}` : frames[i = ++i % frames.length]
|
|
34
|
-
this.logUpdate(text)
|
|
35
|
-
}, dots.interval)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Stop spinner
|
|
40
|
-
*/
|
|
41
|
-
public stop(): void {
|
|
42
|
-
if (this.spinnerInterval) {
|
|
43
|
-
clearInterval(this.spinnerInterval)
|
|
44
|
-
this.spinnerInterval = null
|
|
45
|
-
this.logUpdate.clear()
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import {Information} from './Information.js'
|
|
2
|
-
import {DeGitPuller} from '../components/DeGitPuller.js'
|
|
3
|
-
import {Spinner} from '../components/Spinner.js'
|
|
4
|
-
import {CreateProjectOptions} from '../../options/CreateProjectOptions.js'
|
|
5
|
-
import {ProjectTypeConfig} from '../ProjectTypeConfig.js'
|
|
6
|
-
import path from 'node:path'
|
|
7
|
-
import {mkdir, readdir, stat} from 'node:fs/promises'
|
|
8
|
-
import {Stats} from 'node:fs'
|
|
9
|
-
import {charCheck, charCross} from '../SpecialChar.js'
|
|
10
|
-
import {Application, Provider} from 'lakutata'
|
|
11
|
-
import {Inject} from 'lakutata/decorator/di'
|
|
12
|
-
import {Logger} from 'lakutata/com/logger'
|
|
13
|
-
import {IsExists} from 'lakutata/helper'
|
|
14
|
-
import {Accept} from 'lakutata/decorator/dto'
|
|
15
|
-
import ansis from 'ansis'
|
|
16
|
-
import CLITable from 'cli-table3'
|
|
17
|
-
|
|
18
|
-
export class Creator extends Provider {
|
|
19
|
-
|
|
20
|
-
@Inject(Application)
|
|
21
|
-
protected readonly app: Application
|
|
22
|
-
|
|
23
|
-
@Inject('log')
|
|
24
|
-
protected readonly log: Logger
|
|
25
|
-
|
|
26
|
-
@Inject('spinner')
|
|
27
|
-
protected readonly spinner: Spinner
|
|
28
|
-
|
|
29
|
-
@Inject('puller')
|
|
30
|
-
protected readonly puller: DeGitPuller
|
|
31
|
-
|
|
32
|
-
@Inject('info')
|
|
33
|
-
protected readonly frameworkInfo: Information
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Check if the target path exists
|
|
37
|
-
* @param targetDirectory
|
|
38
|
-
* @param initOnly
|
|
39
|
-
* @protected
|
|
40
|
-
*/
|
|
41
|
-
protected async checkTargetPathExistence(targetDirectory: string, initOnly: boolean): Promise<void> {
|
|
42
|
-
const exists: boolean = await IsExists(targetDirectory)
|
|
43
|
-
if (!exists && initOnly) {
|
|
44
|
-
this.log.error(`${charCross} The target path does not exist.`)
|
|
45
|
-
return this.app.exit(1)
|
|
46
|
-
}
|
|
47
|
-
await mkdir(targetDirectory, {recursive: true})
|
|
48
|
-
this.log.info(`${charCheck} The target path does not exist.`)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Check target path is a valid directory
|
|
53
|
-
* @param targetDirectory
|
|
54
|
-
* @protected
|
|
55
|
-
*/
|
|
56
|
-
protected async checkTargetPathIsDirectory(targetDirectory: string): Promise<void> {
|
|
57
|
-
const targetInfo: Stats = await stat(targetDirectory)
|
|
58
|
-
if (!targetInfo.isDirectory()) {
|
|
59
|
-
this.log.error(`${charCross} The target path is not a valid directory.`)
|
|
60
|
-
return this.app.exit(1)
|
|
61
|
-
}
|
|
62
|
-
this.log.info(`${charCheck} The target path is a valid directory.`)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Check target directory is empty, if the target directory is not empty, throw error and exit
|
|
67
|
-
* @param targetDirectory
|
|
68
|
-
* @protected
|
|
69
|
-
*/
|
|
70
|
-
protected async checkTargetDirectoryIsEmpty(targetDirectory: string): Promise<void> {
|
|
71
|
-
const files: string[] = await readdir(targetDirectory)
|
|
72
|
-
if (files.length) {
|
|
73
|
-
this.log.error(`${charCross} The target directory is not empty.`)
|
|
74
|
-
return this.app.exit(1)
|
|
75
|
-
}
|
|
76
|
-
this.log.info(`${charCheck} The target directory is empty.`)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Exec create
|
|
81
|
-
* @param options
|
|
82
|
-
*/
|
|
83
|
-
@Accept(CreateProjectOptions.required())
|
|
84
|
-
public async create(options: CreateProjectOptions): Promise<void> {
|
|
85
|
-
const appName: string = options.name
|
|
86
|
-
const appId: string = options.id
|
|
87
|
-
const appDescription: string = options.description
|
|
88
|
-
const packageName: string = appId
|
|
89
|
-
const authorName: string = options.author
|
|
90
|
-
const licenseName: string = options.license
|
|
91
|
-
const appType: string = options.type
|
|
92
|
-
const targetPath: string = options.initOnly ? path.resolve(options.path) : path.resolve(options.path, options.name)
|
|
93
|
-
const {branch} = ProjectTypeConfig[appType]
|
|
94
|
-
const table: CLITable.Table = new CLITable()
|
|
95
|
-
table.push(
|
|
96
|
-
[{content: ansis.bold.cyan('Project Creation Information'), colSpan: 2, hAlign: 'center'}],
|
|
97
|
-
[ansis.blue('APP ID & Project Name'), appId],
|
|
98
|
-
[ansis.blue('APP Name'), appName],
|
|
99
|
-
[ansis.blue('APP Description'), appDescription],
|
|
100
|
-
[ansis.blue('Project Create Target Path'), targetPath],
|
|
101
|
-
[ansis.blue('Project Create Mode'), options.initOnly ? ansis.yellow('Initialize project in an existing directory') : ansis.green('Create a new folder for the project')],
|
|
102
|
-
[ansis.blue('Project Author Name'), authorName],
|
|
103
|
-
[ansis.blue('Project License'), licenseName],
|
|
104
|
-
[ansis.blue('Project Template Branch'), this.puller.getGitSource(branch)]
|
|
105
|
-
)
|
|
106
|
-
console.log(table.toString())
|
|
107
|
-
await new Promise<void>(resolve => {
|
|
108
|
-
let timeLeft: number = 15
|
|
109
|
-
const interval: NodeJS.Timeout = setInterval((): void => {
|
|
110
|
-
timeLeft -= 1
|
|
111
|
-
if (!timeLeft) {
|
|
112
|
-
clearInterval(interval)
|
|
113
|
-
this.spinner.stop()
|
|
114
|
-
return resolve()
|
|
115
|
-
}
|
|
116
|
-
}, 1000)
|
|
117
|
-
this.spinner.start((): string => `Please confirm the project creation information; the creation process will commence in ${timeLeft} seconds.`)
|
|
118
|
-
})
|
|
119
|
-
await this.checkTargetPathExistence(targetPath, options.initOnly)
|
|
120
|
-
await this.checkTargetPathIsDirectory(targetPath)
|
|
121
|
-
await this.checkTargetDirectoryIsEmpty(targetPath)
|
|
122
|
-
this.log.info('Begin project creation')
|
|
123
|
-
//TODO
|
|
124
|
-
}
|
|
125
|
-
}
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
import ansis from 'ansis'
|
|
2
|
-
import {dirname, resolve} from 'node:path'
|
|
3
|
-
import {readFile} from 'node:fs/promises'
|
|
4
|
-
import {DTO, Provider, Time} from 'lakutata'
|
|
5
|
-
import {Configurable} from 'lakutata/decorator/di'
|
|
6
|
-
import {DevNull} from 'lakutata/helper'
|
|
7
|
-
|
|
8
|
-
export class Information extends Provider {
|
|
9
|
-
|
|
10
|
-
@Configurable(DTO.String().required())
|
|
11
|
-
protected readonly name: string
|
|
12
|
-
|
|
13
|
-
@Configurable(DTO.String().required())
|
|
14
|
-
protected readonly version: string
|
|
15
|
-
|
|
16
|
-
@Configurable(DTO.String().required())
|
|
17
|
-
protected readonly description: string
|
|
18
|
-
|
|
19
|
-
@Configurable(DTO.String().required())
|
|
20
|
-
protected readonly license: string
|
|
21
|
-
|
|
22
|
-
@Configurable(DTO.String().required())
|
|
23
|
-
protected readonly currentDirectory: string
|
|
24
|
-
|
|
25
|
-
@Configurable(DTO.String().required())
|
|
26
|
-
protected readonly workingDirectory: string
|
|
27
|
-
|
|
28
|
-
protected packageDirectory: (options?: any) => Promise<string | undefined>
|
|
29
|
-
|
|
30
|
-
protected installPath: string
|
|
31
|
-
|
|
32
|
-
protected projectRoot: string | null
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Initializer
|
|
36
|
-
* @protected
|
|
37
|
-
*/
|
|
38
|
-
protected async init(): Promise<void> {
|
|
39
|
-
const {packageDirectory} = await import('pkg-dir')
|
|
40
|
-
this.packageDirectory = packageDirectory
|
|
41
|
-
const installPath: string | undefined = await packageDirectory({cwd: this.currentDirectory})
|
|
42
|
-
this.installPath = installPath ? installPath : 'UNKNOWN'
|
|
43
|
-
|
|
44
|
-
const projectRoot: string | null = await this.findProjectRoot(this.workingDirectory)
|
|
45
|
-
if (projectRoot) {
|
|
46
|
-
const packageJsonPath: string = resolve(projectRoot, './package.json')
|
|
47
|
-
try {
|
|
48
|
-
const packageJson = JSON.parse(await readFile(packageJsonPath, {encoding: 'utf-8'}))
|
|
49
|
-
const dependenciesKeyRegExp: RegExp = new RegExp('dependencies'.toUpperCase())
|
|
50
|
-
Object.keys(packageJson).forEach((key: string): void => {
|
|
51
|
-
if (dependenciesKeyRegExp.test(key.toUpperCase())) {
|
|
52
|
-
Object.keys(packageJson[key]).forEach((dependencyName: string) => {
|
|
53
|
-
if (dependencyName === this.name) {
|
|
54
|
-
this.projectRoot = projectRoot
|
|
55
|
-
}
|
|
56
|
-
})
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
} catch (e) {
|
|
60
|
-
DevNull(e)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* To find the root path of the project where the working directory is located
|
|
67
|
-
* @param path
|
|
68
|
-
* @private
|
|
69
|
-
*/
|
|
70
|
-
private async findProjectRoot(path: string): Promise<string | null> {
|
|
71
|
-
let localRootPath: string | null = null
|
|
72
|
-
while (true) {
|
|
73
|
-
const _localRootPath: string | null = await this.findLocalRoot(localRootPath ? dirname(localRootPath) : path)
|
|
74
|
-
if (!_localRootPath)
|
|
75
|
-
break
|
|
76
|
-
else
|
|
77
|
-
localRootPath = _localRootPath
|
|
78
|
-
}
|
|
79
|
-
return localRootPath
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* To locate the root path containing the package.json file
|
|
84
|
-
* @param path
|
|
85
|
-
* @private
|
|
86
|
-
*/
|
|
87
|
-
private async findLocalRoot(path: string): Promise<string | null> {
|
|
88
|
-
try {
|
|
89
|
-
const dir: string | undefined = await this.packageDirectory({cwd: path})
|
|
90
|
-
return dir ? dir : null
|
|
91
|
-
} catch (e) {
|
|
92
|
-
return null
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Convert string first char to upper case
|
|
98
|
-
* @param str
|
|
99
|
-
* @private
|
|
100
|
-
*/
|
|
101
|
-
private stringFirstCharUpperCase(str: string): string {
|
|
102
|
-
return str.charAt(0).toUpperCase() + str.slice(1)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Format framework ascii logo
|
|
107
|
-
* @protected
|
|
108
|
-
*/
|
|
109
|
-
protected formatFrameworkAsciiLogo(): string {
|
|
110
|
-
const asciiLogo: string = '' +
|
|
111
|
-
' _ _ _ \n' +
|
|
112
|
-
'| | _ | | | | \n' +
|
|
113
|
-
'| | __ _ | | _ _ _ | |_ __ _ | |_ __ _ \n' +
|
|
114
|
-
'| | / _` | | |/ / | | | | | __| / _` | | __| / _` | \n' +
|
|
115
|
-
'| |____ | (_| | | < | |_| | \\ |_ | (_| | \\ |_ | (_| | \n' +
|
|
116
|
-
'|______| \\__,_| |_|\\_\\ \\__,_| \\__| \\__,_| \\__| \\__,_| \n' +
|
|
117
|
-
' '
|
|
118
|
-
return `${ansis.yellow(asciiLogo)}`
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Format framework description
|
|
123
|
-
* @protected
|
|
124
|
-
*/
|
|
125
|
-
protected formatFrameworkDescription(): string {
|
|
126
|
-
return `${ansis.bold(this.stringFirstCharUpperCase(this.name))} is ${ansis.blue(this.description)}`
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Format version text
|
|
131
|
-
* @protected
|
|
132
|
-
*/
|
|
133
|
-
protected formatVersionText(): string {
|
|
134
|
-
return `The current version is ${ansis.bold(this.version)}`
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Format framework installation path
|
|
139
|
-
* @protected
|
|
140
|
-
*/
|
|
141
|
-
protected formatInstallationPath(): string {
|
|
142
|
-
return `The installation directory path is ${ansis.underline(this.getInstallPath())}`
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Format current running level
|
|
147
|
-
* @protected
|
|
148
|
-
*/
|
|
149
|
-
protected formatRunningLevel(): string {
|
|
150
|
-
return `Currently running at ${ansis.bold(this.getLevel())} level`
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Format license
|
|
155
|
-
* @protected
|
|
156
|
-
*/
|
|
157
|
-
protected formatLicense(): string {
|
|
158
|
-
return `${this.stringFirstCharUpperCase(this.name)} is ${ansis.cyan(this.license)} licensed.`
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Format copyright
|
|
163
|
-
* @protected
|
|
164
|
-
*/
|
|
165
|
-
protected formatCopyright(): string {
|
|
166
|
-
return `Copyright (c) ${new Time().format('YYYY')} ${ansis.bold(this.stringFirstCharUpperCase(this.name))}. All rights reserved.`
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* To retrieve the hierarchy level of the project containing the package under the current command
|
|
171
|
-
*/
|
|
172
|
-
public getLevel(): 'PROJECT' | 'GLOBAL' {
|
|
173
|
-
return this.projectRoot ? 'PROJECT' : 'GLOBAL'
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Locate the root path of the project
|
|
178
|
-
*/
|
|
179
|
-
public getRoot(): string | null {
|
|
180
|
-
return this.projectRoot
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Locate the installation directory
|
|
185
|
-
*/
|
|
186
|
-
public getInstallPath(): string {
|
|
187
|
-
return this.installPath
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Retrieve the framework installation version at the project level
|
|
192
|
-
*/
|
|
193
|
-
public async getProjectLevelInstalledFrameworkVersion(): Promise<string | null> {
|
|
194
|
-
const projectRoot: string | null = this.getRoot()
|
|
195
|
-
if (projectRoot) {
|
|
196
|
-
try {
|
|
197
|
-
const version: string = JSON.parse(await readFile(resolve(projectRoot, './node_modules', `./${this.name}/package.json`), {encoding: 'utf-8'})).version
|
|
198
|
-
return version ? version : null
|
|
199
|
-
} catch (e) {
|
|
200
|
-
return null
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
return null
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Print infos
|
|
208
|
-
*/
|
|
209
|
-
public async print(): Promise<void> {
|
|
210
|
-
const texts: string[] = [
|
|
211
|
-
this.formatFrameworkAsciiLogo(),
|
|
212
|
-
this.formatFrameworkDescription(),
|
|
213
|
-
this.formatVersionText(),
|
|
214
|
-
this.formatInstallationPath(),
|
|
215
|
-
this.formatRunningLevel(),
|
|
216
|
-
this.formatLicense(),
|
|
217
|
-
this.formatCopyright()
|
|
218
|
-
]
|
|
219
|
-
console.info(texts.join('\n'))
|
|
220
|
-
}
|
|
221
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import {ProjectTypeConfig} from '../lib/ProjectTypeConfig'
|
|
2
|
-
import {DTO} from 'lakutata'
|
|
3
|
-
import {Expect} from 'lakutata/decorator/dto'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Create project options
|
|
7
|
-
*/
|
|
8
|
-
export class CreateProjectOptions extends DTO {
|
|
9
|
-
|
|
10
|
-
@Expect(
|
|
11
|
-
DTO
|
|
12
|
-
.String()
|
|
13
|
-
.required()
|
|
14
|
-
.pattern(/^(\w+\.?)*\w+$/)
|
|
15
|
-
.description('specify the name of the project and application')
|
|
16
|
-
)
|
|
17
|
-
public name: string
|
|
18
|
-
|
|
19
|
-
@Expect(
|
|
20
|
-
DTO
|
|
21
|
-
.String()
|
|
22
|
-
.required()
|
|
23
|
-
.pattern(/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/)//Match package json name regex
|
|
24
|
-
.description('specify the ID of the application')
|
|
25
|
-
)
|
|
26
|
-
public id: string
|
|
27
|
-
|
|
28
|
-
@Expect(
|
|
29
|
-
DTO
|
|
30
|
-
.String()
|
|
31
|
-
.required()
|
|
32
|
-
.valid(...Object.keys(ProjectTypeConfig))
|
|
33
|
-
.description(`select the type of the project (choices: ${Object.keys(ProjectTypeConfig).map((type: string): string => `"${type}"`).join(',')})`)
|
|
34
|
-
)
|
|
35
|
-
public type: string
|
|
36
|
-
|
|
37
|
-
@Expect(
|
|
38
|
-
DTO
|
|
39
|
-
.String()
|
|
40
|
-
.optional()
|
|
41
|
-
.default(process.cwd())
|
|
42
|
-
.description(`specify the path for creating the project (default: "${process.cwd()}")`)
|
|
43
|
-
)
|
|
44
|
-
public path: string
|
|
45
|
-
|
|
46
|
-
@Expect(
|
|
47
|
-
DTO
|
|
48
|
-
.Boolean()
|
|
49
|
-
.strict(false)
|
|
50
|
-
.optional()
|
|
51
|
-
.default(false)
|
|
52
|
-
.description('initialize project only in specified directory without creating a new folder (default: false)')
|
|
53
|
-
)
|
|
54
|
-
public initOnly: boolean
|
|
55
|
-
|
|
56
|
-
@Expect(
|
|
57
|
-
DTO
|
|
58
|
-
.String()
|
|
59
|
-
.optional()
|
|
60
|
-
.default('none')
|
|
61
|
-
.description('specify the description of the application (default: "none")')
|
|
62
|
-
)
|
|
63
|
-
public description: string
|
|
64
|
-
|
|
65
|
-
@Expect(
|
|
66
|
-
DTO
|
|
67
|
-
.String()
|
|
68
|
-
.optional()
|
|
69
|
-
.default('Anonymous')
|
|
70
|
-
.description('specify the name of the author of the application (default: "Anonymous")')
|
|
71
|
-
)
|
|
72
|
-
public author: string
|
|
73
|
-
|
|
74
|
-
@Expect(
|
|
75
|
-
DTO
|
|
76
|
-
.String()
|
|
77
|
-
.optional()
|
|
78
|
-
.default('UNLICENSED')
|
|
79
|
-
.description('specify the name of the license for the application (default: "UNLICENSED")')
|
|
80
|
-
)
|
|
81
|
-
public license: string
|
|
82
|
-
}
|