@dhis2/create-app 5.2.1 → 5.3.0-alpha.1
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/package.json +5 -3
- package/src/index.js +255 -30
- package/templates/package-lock.json +21570 -0
- package/templates/template-ts-dataelements-react-router.zip +0 -0
- package/templates/template-ts-dataelements.zip +0 -0
- package/templates/yarn.lock +10491 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dhis2/create-app",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0-alpha.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -10,9 +10,11 @@
|
|
|
10
10
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@dhis2/cli-app-scripts": "alpha",
|
|
14
13
|
"@dhis2/cli-helpers-engine": "^3.2.2",
|
|
15
|
-
"@inquirer/prompts": "^7.8.4"
|
|
14
|
+
"@inquirer/prompts": "^7.8.4",
|
|
15
|
+
"decompress": "^4.2.1",
|
|
16
|
+
"fast-glob": "^3.3.3",
|
|
17
|
+
"fs-extra": "^11.3.3"
|
|
16
18
|
},
|
|
17
19
|
"private": false,
|
|
18
20
|
"keywords": [],
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
const
|
|
2
|
-
const { reporter,
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const { reporter, exec } = require('@dhis2/cli-helpers-engine')
|
|
3
3
|
const { input, select } = require('@inquirer/prompts')
|
|
4
|
+
const decompress = require('decompress')
|
|
5
|
+
const fg = require('fast-glob')
|
|
6
|
+
const fs = require('fs-extra')
|
|
4
7
|
|
|
5
8
|
process.on('uncaughtException', (error) => {
|
|
6
9
|
if (error instanceof Error && error.name === 'ExitPromptError') {
|
|
@@ -11,18 +14,60 @@ process.on('uncaughtException', (error) => {
|
|
|
11
14
|
}
|
|
12
15
|
})
|
|
13
16
|
|
|
17
|
+
const templates = {
|
|
18
|
+
templateWithList: path.join(
|
|
19
|
+
__dirname,
|
|
20
|
+
'../templates/template-ts-dataelements.zip'
|
|
21
|
+
),
|
|
22
|
+
|
|
23
|
+
templateWithReactRouter: path.join(
|
|
24
|
+
__dirname,
|
|
25
|
+
'../templates/template-ts-dataelements-react-router.zip'
|
|
26
|
+
),
|
|
27
|
+
}
|
|
28
|
+
|
|
14
29
|
const commandHandler = {
|
|
15
30
|
command: '*', // default command
|
|
16
31
|
description: 'Initialize a new DHIS2 web application',
|
|
17
32
|
builder: {
|
|
18
33
|
yes: {
|
|
19
34
|
description:
|
|
20
|
-
'Skips interactive setup questions,
|
|
35
|
+
'Skips interactive setup questions, using default options to create the new app (TypeScript, pnpm, basic template)',
|
|
21
36
|
type: 'boolean',
|
|
22
37
|
default: false,
|
|
38
|
+
alias: 'y',
|
|
39
|
+
},
|
|
40
|
+
typescript: {
|
|
41
|
+
description: 'Use TypeScript or JS',
|
|
42
|
+
type: 'boolean',
|
|
43
|
+
default: true,
|
|
44
|
+
alias: ['ts', 'typeScript'],
|
|
45
|
+
},
|
|
46
|
+
template: {
|
|
47
|
+
description: 'Which template to use (Basic, With React Router)',
|
|
48
|
+
type: 'string',
|
|
49
|
+
default: 'basic',
|
|
50
|
+
},
|
|
51
|
+
packageManager: {
|
|
52
|
+
description: 'Package Manager',
|
|
53
|
+
type: 'string',
|
|
54
|
+
default: 'pnpm',
|
|
55
|
+
alias: ['package', 'packagemanager'],
|
|
23
56
|
},
|
|
24
57
|
},
|
|
25
58
|
}
|
|
59
|
+
const getTemplateFile = (templateName) => {
|
|
60
|
+
return templateName === 'react-router'
|
|
61
|
+
? templates.templateWithReactRouter
|
|
62
|
+
: templates.templateWithList
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const defaultOptions = {
|
|
66
|
+
typeScript: true,
|
|
67
|
+
templateName: 'basic',
|
|
68
|
+
template: getTemplateFile('basic'),
|
|
69
|
+
packageManager: 'pnpm',
|
|
70
|
+
}
|
|
26
71
|
|
|
27
72
|
const command = {
|
|
28
73
|
command: '[app]',
|
|
@@ -32,9 +77,11 @@ const command = {
|
|
|
32
77
|
handler: async (argv) => {
|
|
33
78
|
let name = argv._[0] || argv.name
|
|
34
79
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
80
|
+
const selectedOptions = {
|
|
81
|
+
...defaultOptions,
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
reporter.debug(`running "npm create @dhis2/app" (or npx) command"`)
|
|
38
85
|
const useDefauls = argv.yes
|
|
39
86
|
|
|
40
87
|
if (!name) {
|
|
@@ -47,9 +94,11 @@ const command = {
|
|
|
47
94
|
reporter.log(`name of project: ${name}`)
|
|
48
95
|
}
|
|
49
96
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
97
|
+
selectedOptions.typeScript = argv.typescript
|
|
98
|
+
selectedOptions.packageManager = argv.packageManager
|
|
99
|
+
selectedOptions.templateName = argv.template
|
|
100
|
+
selectedOptions.template = getTemplateFile(argv.template)
|
|
101
|
+
|
|
53
102
|
if (!useDefauls) {
|
|
54
103
|
const packageManager = await select({
|
|
55
104
|
message: 'Select a package manager',
|
|
@@ -61,43 +110,219 @@ const command = {
|
|
|
61
110
|
],
|
|
62
111
|
})
|
|
63
112
|
|
|
64
|
-
pnpm = packageManager === 'pnpm'
|
|
65
|
-
npm = packageManager === 'npm'
|
|
113
|
+
// pnpm = packageManager === 'pnpm'
|
|
114
|
+
// npm = packageManager === 'npm'
|
|
115
|
+
selectedOptions.packageManager = packageManager
|
|
66
116
|
|
|
67
|
-
const
|
|
68
|
-
message: 'Select a
|
|
117
|
+
const language = await select({
|
|
118
|
+
message: 'Select a language',
|
|
69
119
|
default: 'ts',
|
|
70
120
|
choices: [
|
|
71
121
|
{ name: 'JavaScript', value: 'js' },
|
|
72
122
|
{ name: 'TypeScript', value: 'ts' },
|
|
123
|
+
],
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
selectedOptions.typeScript = language === 'ts'
|
|
127
|
+
|
|
128
|
+
const template = await select({
|
|
129
|
+
message: 'Select a teamplate',
|
|
130
|
+
default: 'ts',
|
|
131
|
+
choices: [
|
|
132
|
+
{ name: 'Basic Template', value: 'basic' },
|
|
73
133
|
{
|
|
74
|
-
name: '
|
|
75
|
-
|
|
76
|
-
value: 'custom',
|
|
134
|
+
name: 'Template with React Router',
|
|
135
|
+
value: 'react-router',
|
|
77
136
|
},
|
|
78
137
|
],
|
|
79
138
|
})
|
|
80
139
|
|
|
81
|
-
|
|
140
|
+
selectedOptions.templateName = template
|
|
141
|
+
selectedOptions.template = getTemplateFile(template)
|
|
82
142
|
}
|
|
83
143
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
144
|
+
// let pkgManager = 'yarn'
|
|
145
|
+
// if (pnpm) {
|
|
146
|
+
// pkgManager = 'pnpm'
|
|
147
|
+
// } else if (npm) {
|
|
148
|
+
// pkgManager = 'npm'
|
|
149
|
+
// }
|
|
150
|
+
|
|
151
|
+
reporter.info(
|
|
152
|
+
`Initialising a new project using "${selectedOptions.packageManager}" as a package manager.`
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
if (selectedOptions.packageManager !== 'pnpm') {
|
|
156
|
+
reporter.warn(
|
|
157
|
+
'We recommend using "pnpm" as a package manager for new projects. You can do so by passing the argument --pnpm (i.e. d2 app scripts init --pnpm). This will become the default in future versions of d2 CLI.'
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
// create the folder where the template will be generated
|
|
161
|
+
let cwd = process.cwd()
|
|
162
|
+
cwd = path.join(cwd, name)
|
|
163
|
+
|
|
164
|
+
if (fs.existsSync(cwd)) {
|
|
165
|
+
reporter.error(
|
|
166
|
+
`The folder "${name}" already exists. Please either delete it, or choose a different name.`
|
|
91
167
|
)
|
|
168
|
+
process.exit(1)
|
|
92
169
|
}
|
|
93
170
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
171
|
+
reporter.info(`selected options: ${JSON.stringify(selectedOptions)}`)
|
|
172
|
+
|
|
173
|
+
await decompress(selectedOptions.template, cwd)
|
|
174
|
+
|
|
175
|
+
const paths = {
|
|
176
|
+
base: cwd,
|
|
177
|
+
package: path.join(cwd, 'package.json'),
|
|
178
|
+
config: path.join(cwd, 'd2.config.js'),
|
|
179
|
+
pnpmLock: path.join(cwd, 'pnpm-lock.yaml'),
|
|
180
|
+
pnpmWorkspace: path.join(cwd, 'pnpm-workspace.yaml'),
|
|
181
|
+
appRootFile: path.join(cwd, 'src/App.tsx'),
|
|
182
|
+
initYarnLock: path.join(__dirname, '../templates/yarn.lock'),
|
|
183
|
+
initNpmLock: path.join(__dirname, '../templates/package-lock.json'),
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const pnpm = selectedOptions.packageManager === 'pnpm'
|
|
187
|
+
const npm = selectedOptions.packageManager === 'npm'
|
|
188
|
+
const yarn = selectedOptions.packageManager === 'yarn'
|
|
189
|
+
const pkgManager = selectedOptions.packageManager
|
|
190
|
+
const typeScript = selectedOptions.typeScript
|
|
191
|
+
|
|
192
|
+
// Default template is with PNPM with TypeScript - some modifications here for yarn/npm/JS
|
|
193
|
+
const templateModifications = [
|
|
194
|
+
[paths.package, true, (f) => f.replace('{{template-name}}', name)],
|
|
195
|
+
// [
|
|
196
|
+
// path.join(paths.base, '.husky/pre-commit'),
|
|
197
|
+
// !pnpm,
|
|
198
|
+
// (f) => f.replace(/pnpm/gm, pkgManager),
|
|
199
|
+
// ],
|
|
200
|
+
[
|
|
201
|
+
paths.package,
|
|
202
|
+
yarn,
|
|
203
|
+
(f) => f.replace(/"pnpm@.+"/gm, '"yarn@1.22.22"'),
|
|
204
|
+
],
|
|
205
|
+
[
|
|
206
|
+
paths.package,
|
|
207
|
+
npm,
|
|
208
|
+
(f) => f.replace(/"pnpm@.+"/gm, '"npm@10.8.2"'),
|
|
209
|
+
],
|
|
210
|
+
[paths.package, !pnpm, (f) => f.replace(/pnpm/gm, pkgManager)],
|
|
211
|
+
[paths.config, !typeScript, (f) => f.replace(/\.tsx/gm, '.jsx')],
|
|
212
|
+
[
|
|
213
|
+
paths.appRootFile,
|
|
214
|
+
!typeScript,
|
|
215
|
+
(f) => f.replace(/with TypeScript/gm, 'with JavaScript'),
|
|
216
|
+
],
|
|
217
|
+
]
|
|
218
|
+
templateModifications.forEach(([filePath, condition, replaceFunc]) => {
|
|
219
|
+
const fileExists = fs.existsSync(filePath)
|
|
220
|
+
|
|
221
|
+
if (!condition || !fileExists) {
|
|
222
|
+
if (!fileExists) {
|
|
223
|
+
reporter.debug(
|
|
224
|
+
`File "${filePath}" specified in the template does not exist. This is likely a problem with the CLI and should be reported to the core team.`
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
return
|
|
228
|
+
}
|
|
229
|
+
let fileContent = fs.readFileSync(filePath, {
|
|
230
|
+
encoding: 'utf8',
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
fileContent = replaceFunc(fileContent)
|
|
234
|
+
|
|
235
|
+
fs.writeFileSync(filePath, fileContent)
|
|
100
236
|
})
|
|
237
|
+
|
|
238
|
+
// copy correct lock file for npm/yarn
|
|
239
|
+
if (!pnpm) {
|
|
240
|
+
if (fs.existsSync(paths.pnpmLock)) {
|
|
241
|
+
fs.removeSync(paths.pnpmLock)
|
|
242
|
+
}
|
|
243
|
+
if (fs.existsSync(paths.pnpmWorkspace)) {
|
|
244
|
+
fs.removeSync(paths.pnpmWorkspace)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (npm) {
|
|
248
|
+
fs.copyFileSync(
|
|
249
|
+
paths.initNpmLock,
|
|
250
|
+
path.join(paths.base, 'package-lock.json')
|
|
251
|
+
)
|
|
252
|
+
} else {
|
|
253
|
+
fs.copyFileSync(
|
|
254
|
+
paths.initYarnLock,
|
|
255
|
+
path.join(paths.base, 'yarn.lock')
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// convert to JS
|
|
261
|
+
if (!typeScript) {
|
|
262
|
+
reporter.info('Preparing JavaScript template')
|
|
263
|
+
reporter.info(` running '${pkgManager} install'`)
|
|
264
|
+
|
|
265
|
+
await exec({
|
|
266
|
+
cmd: pkgManager,
|
|
267
|
+
args: ['install'],
|
|
268
|
+
cwd: paths.base,
|
|
269
|
+
})
|
|
270
|
+
reporter.info(' convert template to JS with tsc')
|
|
271
|
+
await exec({
|
|
272
|
+
cmd: 'npx',
|
|
273
|
+
args: [
|
|
274
|
+
'tsc',
|
|
275
|
+
// 'node_modules/.bin/tsc',
|
|
276
|
+
'--project',
|
|
277
|
+
path.join(paths.base, 'tsconfig.json'),
|
|
278
|
+
'--noEmit',
|
|
279
|
+
false,
|
|
280
|
+
'--jsx',
|
|
281
|
+
'preserve',
|
|
282
|
+
],
|
|
283
|
+
|
|
284
|
+
cwd: paths.base,
|
|
285
|
+
pipe: argv.debug,
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
reporter.info(' Deleting TS files')
|
|
289
|
+
const filePathsToRemove = path.join(paths.base, '/src/**/*.ts[x]')
|
|
290
|
+
const filesToRemove = await fg.glob(filePathsToRemove)
|
|
291
|
+
|
|
292
|
+
filesToRemove.forEach((file) => {
|
|
293
|
+
fs.removeSync(file)
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
if (fs.existsSync(path.join(paths.base, 'types'))) {
|
|
297
|
+
fs.removeSync(path.join(paths.base, 'types'))
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (fs.existsSync(path.join(paths.base, 'tsconfig.json'))) {
|
|
301
|
+
fs.removeSync(path.join(paths.base, 'tsconfig.json'))
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
reporter.info('Finished preparing JavaScript template')
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
reporter.info(`Running '${pkgManager} install'`)
|
|
308
|
+
|
|
309
|
+
await exec({
|
|
310
|
+
cmd: pkgManager,
|
|
311
|
+
args: ['install'],
|
|
312
|
+
cwd: paths.base,
|
|
313
|
+
pipe: argv.debug,
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
await exec({
|
|
317
|
+
cmd: pkgManager,
|
|
318
|
+
args: npm ? ['run', 'format'] : ['format'],
|
|
319
|
+
cwd: paths.base,
|
|
320
|
+
pipe: argv.debug,
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
reporter.info('Done!')
|
|
324
|
+
|
|
325
|
+
return
|
|
101
326
|
},
|
|
102
327
|
}
|
|
103
328
|
|