@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.
@@ -1,229 +1,228 @@
1
+ import { cancel, confirm, isCancel, select } from '@clack/prompts'
1
2
  import { execSync } from '../../utils.mjs'
2
3
  import { join, resolve } from 'path'
3
4
  import fs from 'fs'
5
+ import { styleText } from 'node:util'
4
6
  import os from 'os'
5
- import pc from 'picocolors'
6
7
  import fse from 'fs-extra'
7
- import prompts from 'prompts'
8
8
  import { isAutoYes, normalizeEnum, normalizeYesNo } from './options.mjs'
9
9
 
10
10
  const tempDir = join(os.tmpdir(), 'newlogic-cms-web')
11
11
 
12
12
  async function move(path, options = {}) {
13
- await fse.move(join(tempDir, path), resolve(process.cwd(), path), options).catch(err => console.log(`${pc.red(err)} - ${path}`))
13
+ await fse.move(join(tempDir, path), resolve(process.cwd(), path), options).catch(err => console.log(`${styleText('red', err)} - ${path}`))
14
14
  }
15
15
 
16
16
  async function clone(path, { variant, branch, clone: cloneOption, y, yes } = {}) {
17
- if (variant === 'cms-web') {
18
- variant = 'newlogic-cms-next-web'
19
- } else if (variant === 'cms-eshop') {
20
- variant = 'newlogic-cms-next-eshop'
17
+ if (variant === 'cms-web') {
18
+ variant = 'newlogic-cms-next-web'
19
+ }
20
+ else if (variant === 'cms-eshop') {
21
+ variant = 'newlogic-cms-next-eshop'
22
+ }
23
+
24
+ let cloneMethod = normalizeEnum(cloneOption, ['ssh', 'https'])
25
+ const autoYes = isAutoYes({ y, yes })
26
+
27
+ if (!cloneMethod) {
28
+ if (autoYes) {
29
+ cloneMethod = 'https'
21
30
  }
22
-
23
- let cloneMethod = normalizeEnum(cloneOption, ['ssh', 'https'])
24
- const autoYes = isAutoYes({ y, yes })
25
-
26
- if (!cloneMethod) {
27
- if (autoYes) {
28
- cloneMethod = 'https'
29
- } else {
30
- const response = await prompts([
31
- {
32
- type: 'select',
33
- name: 'clone',
34
- message: 'Clone with SSH or HTTPS?',
35
- choices: [
36
- { title: 'SSH', value: 'ssh' },
37
- { title: 'HTTPS', value: 'https' }
38
- ]
39
- }
40
- ])
41
-
42
- cloneMethod = response.clone
43
- }
31
+ else {
32
+ cloneMethod = await select({
33
+ message: 'Clone with SSH or HTTPS?',
34
+ options: [
35
+ { label: 'SSH', value: 'ssh' },
36
+ { label: 'HTTPS', value: 'https' },
37
+ ],
38
+ })
39
+
40
+ if (isCancel(cloneMethod)) {
41
+ cancel('Operation cancelled.')
42
+ process.exit(1)
43
+ }
44
44
  }
45
+ }
45
46
 
46
- let url = ''
47
+ let url = ''
47
48
 
48
- if (cloneMethod === 'ssh') {
49
- url = 'git@git.newlogic.cz:newlogic-digital'
50
- } else if (cloneMethod === 'https') {
51
- url = 'https://git.newlogic.cz/newlogic-digital'
52
- }
49
+ if (cloneMethod === 'ssh') {
50
+ url = 'git@git.newlogic.cz:newlogic-digital'
51
+ }
52
+ else if (cloneMethod === 'https') {
53
+ url = 'https://git.newlogic.cz/newlogic-digital'
54
+ }
53
55
 
54
- execSync(`git clone -b ${branch} --single-branch --depth 1 ${url}/${variant}.git ${path}`)
56
+ execSync(`git clone -b ${branch} --single-branch --depth 1 ${url}/${variant}.git ${path}`)
55
57
  }
56
58
 
57
59
  async function install(name, branch, { install: installOption, y, yes } = {}) {
58
- let install = normalizeYesNo(installOption)
59
- const autoYes = isAutoYes({ y, yes })
60
-
61
- if (!install) {
62
- if (autoYes) {
63
- install = 'yes'
64
- } else {
65
- const response = await prompts([
66
- {
67
- type: 'select',
68
- name: 'install',
69
- message: 'Install project?',
70
- choices: [
71
- { title: 'yes', value: 'yes' },
72
- { title: 'no', value: 'no' }
73
- ]
74
- }
75
- ])
76
-
77
- install = response.install
78
- }
60
+ let install = normalizeYesNo(installOption)
61
+ const autoYes = isAutoYes({ y, yes })
62
+
63
+ if (!install) {
64
+ if (autoYes) {
65
+ install = 'yes'
79
66
  }
67
+ else {
68
+ const response = await confirm({
69
+ message: 'Install project?',
70
+ initialValue: true,
71
+ })
72
+
73
+ if (isCancel(response)) {
74
+ cancel('Operation cancelled.')
75
+ process.exit(1)
76
+ }
77
+
78
+ install = response ? 'yes' : 'no'
79
+ }
80
+ }
80
81
 
81
- if (install === 'yes') {
82
- execSync(`cd ${name || '.'} && composer install`)
83
- execSync(`cd ${name || '.'} && composer install-${branch || ''}`)
82
+ if (install === 'yes') {
83
+ execSync(`cd ${name || '.'} && composer install`)
84
+ execSync(`cd ${name || '.'} && composer install-${branch || ''}`)
84
85
 
85
- if (fs.existsSync(resolve(process.cwd(), 'package.json'))) {
86
- execSync(`cd ${name || '.'} && npm i && npx vite build`)
87
- }
86
+ if (fs.existsSync(resolve(process.cwd(), 'package.json'))) {
87
+ execSync(`cd ${name || '.'} && npm i && npx vite build`)
88
88
  }
89
+ }
89
90
  }
90
91
 
91
92
  async function dev(name, { dev: devOption, y, yes } = {}) {
92
- let shouldStartDev = normalizeYesNo(devOption)
93
- const autoYes = isAutoYes({ y, yes })
94
-
95
- if (!shouldStartDev) {
96
- if (autoYes) {
97
- shouldStartDev = 'no'
98
- } else {
99
- const response = await prompts([
100
- {
101
- type: 'select',
102
- name: 'install',
103
- message: 'Start dev server?',
104
- choices: [
105
- { title: 'yes', value: 'yes' },
106
- { title: 'no', value: 'no' }
107
- ]
108
- }
109
- ])
110
-
111
- shouldStartDev = response.install
112
- }
113
- }
93
+ let shouldStartDev = normalizeYesNo(devOption)
94
+ const autoYes = isAutoYes({ y, yes })
114
95
 
115
- if (shouldStartDev === 'yes') {
116
- execSync(`cd ${name || '.'} && composer dev-headless`)
96
+ if (!shouldStartDev) {
97
+ if (autoYes) {
98
+ shouldStartDev = 'no'
117
99
  }
100
+ else {
101
+ const response = await confirm({
102
+ message: 'Start dev server?',
103
+ initialValue: true,
104
+ })
105
+
106
+ if (isCancel(response)) {
107
+ cancel('Operation cancelled.')
108
+ process.exit(1)
109
+ }
110
+
111
+ shouldStartDev = response ? 'yes' : 'no'
112
+ }
113
+ }
114
+
115
+ if (shouldStartDev === 'yes') {
116
+ execSync(`cd ${name || '.'} && composer dev-headless`)
117
+ }
118
118
  }
119
119
 
120
120
  async function migrations(name, { migrations: migrationsOption, y, yes } = {}) {
121
- let shouldInitMigrations = normalizeYesNo(migrationsOption)
122
- const autoYes = isAutoYes({ y, yes })
123
-
124
- if (!shouldInitMigrations) {
125
- if (autoYes) {
126
- shouldInitMigrations = 'no'
127
- } else {
128
- const response = await prompts([
129
- {
130
- type: 'select',
131
- name: 'install',
132
- message: 'Init phinx migrations and seed?',
133
- choices: [
134
- { title: 'yes', value: 'yes' },
135
- { title: 'no', value: 'no' }
136
- ]
137
- }
138
- ])
139
-
140
- shouldInitMigrations = response.install
141
- }
142
- }
121
+ let shouldInitMigrations = normalizeYesNo(migrationsOption)
122
+ const autoYes = isAutoYes({ y, yes })
143
123
 
144
- if (shouldInitMigrations === 'yes') {
145
- execSync(`cd ${name || '.'} && composer phinx-init`)
124
+ if (!shouldInitMigrations) {
125
+ if (autoYes) {
126
+ shouldInitMigrations = 'no'
127
+ }
128
+ else {
129
+ const response = await confirm({
130
+ message: 'Init phinx migrations and seed?',
131
+ initialValue: true,
132
+ })
133
+
134
+ if (isCancel(response)) {
135
+ cancel('Operation cancelled.')
136
+ process.exit(1)
137
+ }
138
+
139
+ shouldInitMigrations = response ? 'yes' : 'no'
146
140
  }
141
+ }
142
+
143
+ if (shouldInitMigrations === 'yes') {
144
+ execSync(`cd ${name || '.'} && composer phinx-init`)
145
+ }
147
146
  }
148
147
 
149
148
  async function prepare({ prepare: prepareOption, y, yes } = {}) {
150
- let shouldPrepare = normalizeYesNo(prepareOption)
151
- const autoYes = isAutoYes({ y, yes })
152
-
153
- if (!shouldPrepare) {
154
- if (autoYes) {
155
- shouldPrepare = 'no'
156
- } else {
157
- const response = await prompts([
158
- {
159
- type: 'select',
160
- name: 'install',
161
- message: 'Prepare project with templates from frontend?',
162
- choices: [
163
- { title: 'yes', value: 'yes' },
164
- { title: 'no', value: 'no' }
165
- ]
166
- }
167
- ])
168
-
169
- shouldPrepare = response.install
170
- }
171
- }
149
+ let shouldPrepare = normalizeYesNo(prepareOption)
150
+ const autoYes = isAutoYes({ y, yes })
172
151
 
173
- if (shouldPrepare === 'yes') {
174
- execSync('newlogic cms prepare')
152
+ if (!shouldPrepare) {
153
+ if (autoYes) {
154
+ shouldPrepare = 'no'
155
+ }
156
+ else {
157
+ const response = await confirm({
158
+ message: 'Prepare project with templates from frontend?',
159
+ initialValue: true,
160
+ })
161
+
162
+ if (isCancel(response)) {
163
+ cancel('Operation cancelled.')
164
+ process.exit(1)
165
+ }
166
+
167
+ shouldPrepare = response ? 'yes' : 'no'
175
168
  }
169
+ }
170
+
171
+ if (shouldPrepare === 'yes') {
172
+ execSync('newlogic cms prepare')
173
+ }
176
174
  }
177
175
 
178
176
  export default async function cms(name, { variant, branch, ...options } = {}) {
179
- if (name) {
180
- if (!fs.existsSync(resolve(process.cwd(), name))) {
181
- await clone(name, { variant, branch, clone: options.clone, y: options.y, yes: options.yes })
182
- }
183
-
184
- await install(name, branch, { install: options.install, y: options.y, yes: options.yes })
185
- await prepare({ prepare: options.prepare, y: options.y, yes: options.yes })
186
- await dev(name, { dev: options.dev, y: options.y, yes: options.yes })
187
- await migrations(name, { migrations: options.migrations, y: options.y, yes: options.yes })
188
- return
189
- }
190
-
191
- if (!fs.existsSync(resolve(process.cwd(), 'composer.json'))) {
192
- if (fs.existsSync(tempDir)) {
193
- fse.removeSync(tempDir)
194
- }
195
-
196
- await clone(tempDir, { variant, branch, clone: options.clone, y: options.y, yes: options.yes })
197
-
198
- await move('.docker')
199
- await move('app')
200
- await move('bin')
201
- await move('config')
202
- await move('log')
203
- await move('public/index.php')
204
- await move('src/views')
205
- await move('storage')
206
- await move('temp')
207
- await move('tests')
208
- await move('.gitignore', { overwrite: true })
209
- await move('README.md', { overwrite: true })
210
- await move('composer.json')
211
- await move('composer.lock')
212
- await move('docker-compose.yml')
213
- await move('Makefile') // deprecated
214
- await move('phpstan.neon')
215
- await move('phpunit.xml')
216
- await move('pint.json')
217
- await move('rector.php')
218
- await fse.move(join(tempDir, '.gitlab-ci.prod.yml'), resolve(process.cwd(), '.gitlab-ci.yml'), { overwrite: true }).catch(err => console.log(`${pc.red(err)} - .gitlab-ci.yml`))
219
-
220
- fse.removeSync(tempDir)
221
- } else {
222
- console.log(pc.yellow('Project files already exist in the directory, skipping copy step (delete composer.json to force)'))
177
+ if (name) {
178
+ if (!fs.existsSync(resolve(process.cwd(), name))) {
179
+ await clone(name, { variant, branch, clone: options.clone, y: options.y, yes: options.yes })
223
180
  }
224
181
 
225
182
  await install(name, branch, { install: options.install, y: options.y, yes: options.yes })
226
183
  await prepare({ prepare: options.prepare, y: options.y, yes: options.yes })
227
184
  await dev(name, { dev: options.dev, y: options.y, yes: options.yes })
228
185
  await migrations(name, { migrations: options.migrations, y: options.y, yes: options.yes })
186
+ return
187
+ }
188
+
189
+ if (!fs.existsSync(resolve(process.cwd(), 'composer.json'))) {
190
+ if (fs.existsSync(tempDir)) {
191
+ fse.removeSync(tempDir)
192
+ }
193
+
194
+ await clone(tempDir, { variant, branch, clone: options.clone, y: options.y, yes: options.yes })
195
+
196
+ await move('.docker')
197
+ await move('app')
198
+ await move('bin')
199
+ await move('config')
200
+ await move('log')
201
+ await move('public/index.php')
202
+ await move('src/views')
203
+ await move('storage')
204
+ await move('temp')
205
+ await move('tests')
206
+ await move('.gitignore', { overwrite: true })
207
+ await move('README.md', { overwrite: true })
208
+ await move('composer.json')
209
+ await move('composer.lock')
210
+ await move('docker-compose.yml')
211
+ await move('Makefile') // deprecated
212
+ await move('phpstan.neon')
213
+ await move('phpunit.xml')
214
+ await move('pint.json')
215
+ await move('rector.php')
216
+ await fse.move(join(tempDir, '.gitlab-ci.prod.yml'), resolve(process.cwd(), '.gitlab-ci.yml'), { overwrite: true }).catch(err => console.log(`${styleText('red', err)} - .gitlab-ci.yml`))
217
+
218
+ fse.removeSync(tempDir)
219
+ }
220
+ else {
221
+ console.log(styleText('yellow', 'Project files already exist in the directory, skipping copy step (delete composer.json to force)'))
222
+ }
223
+
224
+ await install(name, branch, { install: options.install, y: options.y, yes: options.yes })
225
+ await prepare({ prepare: options.prepare, y: options.y, yes: options.yes })
226
+ await dev(name, { dev: options.dev, y: options.y, yes: options.yes })
227
+ await migrations(name, { migrations: options.migrations, y: options.y, yes: options.yes })
229
228
  }
@@ -1,100 +1,85 @@
1
- import prompts from 'prompts'
1
+ import { cancel, isCancel, select } from '@clack/prompts'
2
2
  import ui from './ui.mjs'
3
3
  import cms from './cms.mjs'
4
4
  import { isAutoYes, normalizeEnum } from './options.mjs'
5
5
 
6
6
  async function init(project, name, options = {}) {
7
- const nameAsProject = (project && !project.match(/^(ui|cms)$/))
8
- const autoYes = isAutoYes(options)
7
+ const nameAsProject = (project && !project.match(/^(ui|cms)$/))
8
+ const autoYes = isAutoYes(options)
9
9
 
10
- name = nameAsProject ? project : name
10
+ name = nameAsProject ? project : name
11
11
 
12
- if (!project || nameAsProject) {
13
- if (autoYes) {
14
- project = 'ui'
15
- } else {
16
- const response = await prompts([
17
- {
18
- type: 'select',
19
- name: 'project',
20
- message: 'Select a project to init',
21
- choices: [
22
- { title: 'ui', value: 'ui' },
23
- { title: 'cms', value: 'cms' }
24
- ],
25
- onState: (state) => {
26
- if (state.aborted) {
27
- process.exit(1)
28
- }
29
- }
30
- }
31
- ])
32
-
33
- project = response.project
34
- }
12
+ if (!project || nameAsProject) {
13
+ if (autoYes) {
14
+ project = 'ui'
35
15
  }
16
+ else {
17
+ project = await select({
18
+ message: 'Select a project to init',
19
+ options: [
20
+ { label: 'ui', value: 'ui' },
21
+ { label: 'cms', value: 'cms' },
22
+ ],
23
+ })
36
24
 
37
- let branch = normalizeEnum(options.branch, ['main', 'dev'])
25
+ if (isCancel(project)) {
26
+ cancel('Operation cancelled.')
27
+ process.exit(1)
28
+ }
29
+ }
30
+ }
38
31
 
39
- if (!branch) {
40
- if (autoYes) {
41
- branch = 'main'
42
- } else {
43
- const response = await prompts([
44
- {
45
- type: 'select',
46
- name: 'branch',
47
- message: 'Select a git branch',
48
- choices: [
49
- { title: 'main', value: 'main' },
50
- { title: 'dev', value: 'dev' }
51
- ],
52
- onState: (state) => {
53
- if (state.aborted) {
54
- process.exit(1)
55
- }
56
- }
57
- }
58
- ])
32
+ let branch = normalizeEnum(options.branch, ['main', 'dev'])
59
33
 
60
- branch = response.branch
61
- }
34
+ if (!branch) {
35
+ if (autoYes) {
36
+ branch = 'main'
62
37
  }
38
+ else {
39
+ branch = await select({
40
+ message: 'Select a git branch',
41
+ options: [
42
+ { label: 'main', value: 'main' },
43
+ { label: 'dev', value: 'dev' },
44
+ ],
45
+ })
63
46
 
64
- if (project === 'ui') {
65
- await ui(name, { ...options, branch })
47
+ if (isCancel(branch)) {
48
+ cancel('Operation cancelled.')
49
+ process.exit(1)
50
+ }
66
51
  }
52
+ }
67
53
 
68
- if (project === 'cms') {
69
- let variant = normalizeEnum(options.variant, ['cms-web', 'cms-eshop'])
54
+ if (project === 'ui') {
55
+ await ui(name, { ...options, branch })
56
+ }
70
57
 
71
- if (!variant) {
72
- if (autoYes) {
73
- variant = 'cms-web'
74
- } else {
75
- const response = await prompts([
76
- {
77
- type: 'select',
78
- name: 'variant',
79
- message: 'Select a variant to install',
80
- choices: [
81
- { title: 'cms-web', value: 'cms-web' },
82
- { title: 'cms-eshop', value: 'cms-eshop' }
83
- ],
84
- onState: (state) => {
85
- if (state.aborted) {
86
- process.exit(1)
87
- }
88
- }
89
- }
90
- ])
58
+ if (project === 'cms') {
59
+ let variant = normalizeEnum(options.variant, ['cms-web', 'cms-eshop'])
91
60
 
92
- variant = response.variant
93
- }
94
- }
61
+ if (!variant) {
62
+ if (autoYes) {
63
+ variant = 'cms-web'
64
+ }
65
+ else {
66
+ variant = await select({
67
+ message: 'Select a variant to install',
68
+ options: [
69
+ { label: 'cms-web', value: 'cms-web' },
70
+ { label: 'cms-eshop', value: 'cms-eshop' },
71
+ ],
72
+ })
95
73
 
96
- await cms(name, { ...options, branch, variant })
74
+ if (isCancel(variant)) {
75
+ cancel('Operation cancelled.')
76
+ process.exit(1)
77
+ }
78
+ }
97
79
  }
80
+
81
+ await cms(name, { ...options, branch, variant })
82
+ }
98
83
  }
99
84
 
100
85
  export default init
@@ -1,47 +1,47 @@
1
1
  function normalizeEnum(value, allowed = []) {
2
- if (typeof value !== 'string') {
3
- return undefined
4
- }
2
+ if (typeof value !== 'string') {
3
+ return undefined
4
+ }
5
5
 
6
- const normalized = value.trim().toLowerCase()
6
+ const normalized = value.trim().toLowerCase()
7
7
 
8
- if (!allowed.includes(normalized)) {
9
- return undefined
10
- }
8
+ if (!allowed.includes(normalized)) {
9
+ return undefined
10
+ }
11
11
 
12
- return normalized
12
+ return normalized
13
13
  }
14
14
 
15
15
  function normalizeYesNo(value) {
16
- if (typeof value === 'boolean') {
17
- return value ? 'yes' : 'no'
18
- }
16
+ if (typeof value === 'boolean') {
17
+ return value ? 'yes' : 'no'
18
+ }
19
19
 
20
- if (typeof value !== 'string') {
21
- return undefined
22
- }
20
+ if (typeof value !== 'string') {
21
+ return undefined
22
+ }
23
23
 
24
- const normalized = value.trim().toLowerCase()
24
+ const normalized = value.trim().toLowerCase()
25
25
 
26
- if (['yes', 'y', 'true', '1'].includes(normalized)) {
27
- return 'yes'
28
- }
26
+ if (['yes', 'y', 'true', '1'].includes(normalized)) {
27
+ return 'yes'
28
+ }
29
29
 
30
- if (['no', 'n', 'false', '0'].includes(normalized)) {
31
- return 'no'
32
- }
30
+ if (['no', 'n', 'false', '0'].includes(normalized)) {
31
+ return 'no'
32
+ }
33
33
 
34
- return undefined
34
+ return undefined
35
35
  }
36
36
 
37
37
  function isAutoYes(options = {}) {
38
- const values = [normalizeYesNo(options.y), normalizeYesNo(options.yes)]
38
+ const values = [normalizeYesNo(options.y), normalizeYesNo(options.yes)]
39
39
 
40
- if (values.includes('no')) {
41
- return false
42
- }
40
+ if (values.includes('no')) {
41
+ return false
42
+ }
43
43
 
44
- return values.includes('yes')
44
+ return values.includes('yes')
45
45
  }
46
46
 
47
47
  export { normalizeEnum, normalizeYesNo, isAutoYes }