@newlogic-digital/cli 1.3.0 → 1.4.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/index.mjs +69 -69
- package/package.json +13 -12
- package/src/commands/cms/index.mjs +46 -46
- package/src/commands/cms/prepare.mjs +594 -528
- package/src/commands/init/cms.mjs +178 -179
- package/src/commands/init/index.mjs +63 -78
- package/src/commands/init/options.mjs +27 -27
- package/src/commands/init/ui.mjs +179 -88
- package/src/utils.mjs +18 -17
package/src/commands/init/ui.mjs
CHANGED
|
@@ -1,114 +1,205 @@
|
|
|
1
|
+
import { cancel, confirm, isCancel, select, text } from '@clack/prompts'
|
|
1
2
|
import { execSync } from '../../utils.mjs'
|
|
2
3
|
import fse from 'fs-extra'
|
|
3
|
-
import prompts from 'prompts'
|
|
4
4
|
import { join, resolve } from 'path'
|
|
5
5
|
import { isAutoYes, normalizeEnum, normalizeYesNo } from './options.mjs'
|
|
6
6
|
|
|
7
|
+
function replaceInFile(path, searchValue, replaceValue) {
|
|
8
|
+
if (!fse.existsSync(path)) {
|
|
9
|
+
return
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const content = fse.readFileSync(path, 'utf8')
|
|
13
|
+
fse.writeFileSync(path, content.replace(searchValue, replaceValue))
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function updateBlankPackageJson(path) {
|
|
17
|
+
if (!fse.existsSync(path)) {
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const packageJson = JSON.parse(fse.readFileSync(path, 'utf8'))
|
|
22
|
+
const originalDependencies = (packageJson.dependencies && typeof packageJson.dependencies === 'object')
|
|
23
|
+
? packageJson.dependencies
|
|
24
|
+
: {}
|
|
25
|
+
|
|
26
|
+
if (packageJson.scripts && typeof packageJson.scripts === 'object') {
|
|
27
|
+
delete packageJson.scripts['build-emails']
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
packageJson.dependencies = Object.fromEntries(
|
|
31
|
+
['@newlogic-digital/utils-js', 'winduum']
|
|
32
|
+
.flatMap(name => Object.hasOwn(originalDependencies, name) ? [[name, originalDependencies[name]]] : []),
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
fse.writeFileSync(path, `${JSON.stringify(packageJson, null, 2)}\n`)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function prepareBlankInstall(projectPath) {
|
|
39
|
+
[
|
|
40
|
+
join(projectPath, 'src', 'template', 'emails'),
|
|
41
|
+
join(projectPath, 'src', 'templates', 'emails'),
|
|
42
|
+
join(projectPath, 'src', 'styles', 'emails'),
|
|
43
|
+
join(projectPath, 'src', 'data', 'nav.json'),
|
|
44
|
+
join(projectPath, 'src', 'data', 'socials.json'),
|
|
45
|
+
join(projectPath, 'src', 'styles', 'tinymce.css'),
|
|
46
|
+
].forEach(path => fse.removeSync(path))
|
|
47
|
+
|
|
48
|
+
replaceInFile(join(projectPath, 'src', 'data', 'main.json'), '"cookieConsent": true', '"cookieConsent": false')
|
|
49
|
+
replaceInFile(join(projectPath, 'src', 'templates', 'layouts', 'default.latte'), '<body data-controller="x-app invoke" data-naja-snippet-append>', '<body>')
|
|
50
|
+
updateBlankPackageJson(join(projectPath, 'package.json'))
|
|
51
|
+
|
|
52
|
+
const iconsPath = join(projectPath, 'src', 'icons')
|
|
53
|
+
fse.ensureDirSync(iconsPath)
|
|
54
|
+
fse.emptyDirSync(iconsPath)
|
|
55
|
+
|
|
56
|
+
const scriptsPath = join(projectPath, 'src', 'scripts')
|
|
57
|
+
fse.emptyDirSync(scriptsPath)
|
|
58
|
+
fse.outputFileSync(join(scriptsPath, 'main.js'), '')
|
|
59
|
+
|
|
60
|
+
const stylesComponentsPath = join(projectPath, 'src', 'styles', 'components')
|
|
61
|
+
fse.emptyDirSync(stylesComponentsPath)
|
|
62
|
+
fse.outputFileSync(join(stylesComponentsPath, '+.css'), '')
|
|
63
|
+
|
|
64
|
+
const templatesComponentsPath = join(projectPath, 'src', 'templates', 'components')
|
|
65
|
+
fse.emptyDirSync(templatesComponentsPath)
|
|
66
|
+
fse.outputFileSync(join(templatesComponentsPath, 'footer', 'Footer.latte'), '')
|
|
67
|
+
fse.outputFileSync(join(templatesComponentsPath, 'header', 'Header.latte'), '')
|
|
68
|
+
|
|
69
|
+
const pagesPath = join(projectPath, 'src', 'pages')
|
|
70
|
+
fse.emptyDirSync(pagesPath)
|
|
71
|
+
fse.outputFileSync(join(pagesPath, 'index.json'), '{\n "title": "Hello world"\n}\n')
|
|
72
|
+
}
|
|
73
|
+
|
|
7
74
|
export default async function ui(name, { branch, ...options } = {}) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (!clone) {
|
|
12
|
-
if (autoYes) {
|
|
13
|
-
clone = 'https'
|
|
14
|
-
} else {
|
|
15
|
-
const response = await prompts([
|
|
16
|
-
{
|
|
17
|
-
type: 'select',
|
|
18
|
-
name: 'clone',
|
|
19
|
-
message: 'Clone with SSH or HTTPS?',
|
|
20
|
-
choices: [
|
|
21
|
-
{ title: 'SSH', value: 'ssh' },
|
|
22
|
-
{ title: 'HTTPS', value: 'https' }
|
|
23
|
-
]
|
|
24
|
-
}
|
|
25
|
-
])
|
|
26
|
-
|
|
27
|
-
clone = response.clone
|
|
28
|
-
}
|
|
29
|
-
}
|
|
75
|
+
const autoYes = isAutoYes(options)
|
|
76
|
+
let clone = normalizeEnum(options.clone, ['ssh', 'https'])
|
|
77
|
+
let scope = normalizeEnum(options.scope, ['default', 'blank'])
|
|
30
78
|
|
|
31
|
-
|
|
79
|
+
if (!clone) {
|
|
80
|
+
if (autoYes) {
|
|
81
|
+
clone = 'https'
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
clone = await select({
|
|
85
|
+
message: 'Clone with SSH or HTTPS?',
|
|
86
|
+
options: [
|
|
87
|
+
{ label: 'SSH', value: 'ssh' },
|
|
88
|
+
{ label: 'HTTPS', value: 'https' },
|
|
89
|
+
],
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
if (isCancel(clone)) {
|
|
93
|
+
cancel('Operation cancelled.')
|
|
94
|
+
process.exit(1)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
32
98
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
url = 'https://git.newlogic.cz/newlogic-digital'
|
|
99
|
+
if (!scope) {
|
|
100
|
+
if (autoYes) {
|
|
101
|
+
scope = 'default'
|
|
37
102
|
}
|
|
103
|
+
else {
|
|
104
|
+
scope = await select({
|
|
105
|
+
message: 'Select install scope',
|
|
106
|
+
options: [
|
|
107
|
+
{ label: 'default', value: 'default' },
|
|
108
|
+
{ label: 'blank', value: 'blank' },
|
|
109
|
+
],
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
if (isCancel(scope)) {
|
|
113
|
+
cancel('Operation cancelled.')
|
|
114
|
+
process.exit(1)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
38
118
|
|
|
39
|
-
|
|
119
|
+
let url = ''
|
|
40
120
|
|
|
41
|
-
|
|
121
|
+
if (clone === 'ssh') {
|
|
122
|
+
url = 'git@git.newlogic.cz:newlogic-digital'
|
|
123
|
+
}
|
|
124
|
+
else if (clone === 'https') {
|
|
125
|
+
url = 'https://git.newlogic.cz/newlogic-digital'
|
|
126
|
+
}
|
|
42
127
|
|
|
43
|
-
|
|
128
|
+
execSync(`git clone -b ${branch} --single-branch --depth 1 ${url}/newlogic-ui.git ${name || '.'}`)
|
|
44
129
|
|
|
45
|
-
|
|
130
|
+
const projectPath = name ? resolve(process.cwd(), name) : resolve(process.cwd())
|
|
131
|
+
const gitPath = join(projectPath, '.git')
|
|
46
132
|
|
|
47
|
-
|
|
48
|
-
if (autoYes) {
|
|
49
|
-
git = 'no'
|
|
50
|
-
} else {
|
|
51
|
-
const response = await prompts([
|
|
52
|
-
{
|
|
53
|
-
type: 'select',
|
|
54
|
-
name: 'git',
|
|
55
|
-
message: 'Init as git repository?',
|
|
56
|
-
choices: [
|
|
57
|
-
{ title: 'yes', value: 'yes' },
|
|
58
|
-
{ title: 'no', value: 'no' }
|
|
59
|
-
]
|
|
60
|
-
}
|
|
61
|
-
])
|
|
133
|
+
fse.removeSync(gitPath)
|
|
62
134
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
135
|
+
if (scope === 'blank') {
|
|
136
|
+
prepareBlankInstall(projectPath)
|
|
137
|
+
}
|
|
66
138
|
|
|
67
|
-
|
|
68
|
-
execSync(`git init ${name || ''}`)
|
|
139
|
+
let git = normalizeYesNo(options.git)
|
|
69
140
|
|
|
70
|
-
|
|
141
|
+
if (!git) {
|
|
142
|
+
if (autoYes) {
|
|
143
|
+
git = 'no'
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
const response = await confirm({
|
|
147
|
+
message: 'Init as git repository?',
|
|
148
|
+
initialValue: true,
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
if (isCancel(response)) {
|
|
152
|
+
cancel('Operation cancelled.')
|
|
153
|
+
process.exit(1)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
git = response ? 'yes' : 'no'
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (git === 'yes') {
|
|
161
|
+
execSync(`git init ${name || ''}`)
|
|
71
162
|
|
|
72
|
-
|
|
73
|
-
const response = await prompts([
|
|
74
|
-
{
|
|
75
|
-
type: 'text',
|
|
76
|
-
name: 'remote',
|
|
77
|
-
message: 'Set remote for git repository'
|
|
78
|
-
}
|
|
79
|
-
])
|
|
163
|
+
let remote = (typeof options.remote === 'string' && options.remote.trim()) ? options.remote.trim() : undefined
|
|
80
164
|
|
|
81
|
-
|
|
82
|
-
|
|
165
|
+
if (!remote && !autoYes) {
|
|
166
|
+
remote = await text({
|
|
167
|
+
message: 'Set remote for git repository',
|
|
168
|
+
})
|
|
83
169
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
170
|
+
if (isCancel(remote)) {
|
|
171
|
+
cancel('Operation cancelled.')
|
|
172
|
+
process.exit(1)
|
|
173
|
+
}
|
|
87
174
|
}
|
|
88
175
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (!install) {
|
|
92
|
-
if (autoYes) {
|
|
93
|
-
install = 'yes'
|
|
94
|
-
} else {
|
|
95
|
-
const response = await prompts([
|
|
96
|
-
{
|
|
97
|
-
type: 'select',
|
|
98
|
-
name: 'install',
|
|
99
|
-
message: 'Install project?',
|
|
100
|
-
choices: [
|
|
101
|
-
{ title: 'yes', value: 'yes' },
|
|
102
|
-
{ title: 'no', value: 'no' }
|
|
103
|
-
]
|
|
104
|
-
}
|
|
105
|
-
])
|
|
106
|
-
|
|
107
|
-
install = response.install
|
|
108
|
-
}
|
|
176
|
+
if (remote) {
|
|
177
|
+
execSync(`cd ${name || '.'} && git remote add origin ${remote} ${name ? '&& cd ..' : ''}`)
|
|
109
178
|
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
let install = normalizeYesNo(options.install)
|
|
110
182
|
|
|
111
|
-
|
|
112
|
-
|
|
183
|
+
if (!install) {
|
|
184
|
+
if (autoYes) {
|
|
185
|
+
install = 'yes'
|
|
113
186
|
}
|
|
187
|
+
else {
|
|
188
|
+
const response = await confirm({
|
|
189
|
+
message: 'Install project?',
|
|
190
|
+
initialValue: true,
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
if (isCancel(response)) {
|
|
194
|
+
cancel('Operation cancelled.')
|
|
195
|
+
process.exit(1)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
install = response ? 'yes' : 'no'
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (install === 'yes') {
|
|
203
|
+
execSync(`cd ${name || '.'} && npm i`)
|
|
204
|
+
}
|
|
114
205
|
}
|
package/src/utils.mjs
CHANGED
|
@@ -6,31 +6,32 @@ import { fileURLToPath } from 'url'
|
|
|
6
6
|
const { version, name } = JSON.parse(fs.readFileSync(resolve(dirname((fileURLToPath(import.meta.url))), '../package.json')).toString())
|
|
7
7
|
|
|
8
8
|
const execSync = (cmd) => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
try {
|
|
10
|
+
childProcess.execSync(cmd, { stdio: [0, 1, 2] })
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
process.exit(1)
|
|
14
|
+
}
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
const stripIndent = (string) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (!match) {
|
|
21
|
-
return 0
|
|
22
|
-
}
|
|
18
|
+
const indent = () => {
|
|
19
|
+
const match = string.match(/^[ \t]*(?=\S)/gm)
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
if (!match) {
|
|
22
|
+
return 0
|
|
25
23
|
}
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
return match.reduce((r, a) => Math.min(r, a.length), Infinity)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (indent() === 0) {
|
|
29
|
+
return string
|
|
30
|
+
}
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
const regex = new RegExp(`^[ \\t]{${indent()}}`, 'gm')
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
return string.replace(regex, '')
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
export { execSync, stripIndent, version, name }
|