@newlogic-digital/cli 1.0.3 → 1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newlogic-digital/cli",
3
- "version": "1.0.3",
3
+ "version": "1.2.0",
4
4
  "main": "index.mjs",
5
5
  "bin": {
6
6
  "newlogic-cli": "index.mjs",
@@ -10,6 +10,128 @@ let sectionsCount = 0
10
10
  let sectionsFactoryCount = 0
11
11
  let templatesCount = 0
12
12
 
13
+ function generatePhpType(control, controlValue) {
14
+ const type = typeof controlValue
15
+ let phpType = type
16
+
17
+ if (type === 'object' && Array.isArray(controlValue)) {
18
+ phpType = 'array'
19
+ } else if (type === 'boolean') {
20
+ phpType = 'bool'
21
+ } else if (type === 'number') {
22
+ phpType = 'int'
23
+ }
24
+ return phpType
25
+ }
26
+ function getFieldType(control, controlValue) {
27
+ const type = typeof controlValue
28
+ if (type === 'number') {
29
+ return 'INT'
30
+ }
31
+
32
+ if (control.startsWith('table')) {
33
+ return 'TABLE'
34
+ }
35
+
36
+ if (control === 'heading' || control === 'title') {
37
+ return 'TEXT'
38
+ }
39
+
40
+ if (control === 'content') {
41
+ return 'WSW'
42
+ }
43
+
44
+ if (type === 'string') {
45
+ if (controlValue.startsWith('https://') || controlValue.startsWith('http://') || controlValue.trim().endsWith('.html')) {
46
+ return 'LINK'
47
+ }
48
+ if (controlValue.trim().startsWith('<') && controlValue.trim().endsWith('/>')) {
49
+ return 'WSW'
50
+ }
51
+ return 'TEXTAREA'
52
+ }
53
+
54
+ if (type === 'boolean') {
55
+ return 'BOOLEAN'
56
+ }
57
+
58
+ if (type === 'object') {
59
+ return 'REPEATER'
60
+ }
61
+ return 'OTHER'
62
+ }
63
+ function getTitle(control) {
64
+ if (control === 'heading') {
65
+ return 'Nadpis'
66
+ }
67
+
68
+ if (control === 'title') {
69
+ return 'Titulek'
70
+ }
71
+
72
+ if (control === 'content') {
73
+ return 'Obsah'
74
+ }
75
+
76
+ if (control === 'text') {
77
+ return 'Text'
78
+ }
79
+
80
+ return control[0].toUpperCase() + control.slice(1)
81
+ }
82
+
83
+ function buildAttributeInternals(control, controlValue) {
84
+ const type = getFieldType(control, controlValue)
85
+ const name = getTitle(control)
86
+ let subfields = ''
87
+ let phpType = generatePhpType(control, controlValue)
88
+ if (type === 'REPEATER') {
89
+ subfields = ', subfields: [\n'
90
+ phpType = 'list<object{'
91
+ if (Array.isArray(controlValue)) {
92
+ const visited = {}
93
+ for (const object in controlValue) {
94
+ if (typeof controlValue[object] !== 'object') {
95
+ const key = 'SomethingIsWrongHere'
96
+ if (visited[key]) {
97
+ continue
98
+ }
99
+ visited[key] = true
100
+ const [attribute, type] = buildAttributeInternals('SomethingIsWrongHere', controlValue[object])
101
+ subfields += `'SomethingIsWrongHere' => new ${attribute},\n`
102
+ phpType += `SomethingIsWrongHere: ${type}, `
103
+ continue
104
+ }
105
+ for (const key in controlValue[object]) {
106
+ if (visited[key]) {
107
+ continue
108
+ }
109
+ visited[key] = true
110
+ const [attribute, type] = buildAttributeInternals(key, controlValue[object][key])
111
+ subfields += `'${key}' => new ${attribute},\n`
112
+ phpType += `${key}: ${type}, `
113
+ }
114
+ }
115
+ } else {
116
+ for (const key in controlValue) {
117
+ const [attribute, type] = buildAttributeInternals(key, controlValue[key])
118
+ subfields += `'${key}' => new ${attribute},\n`
119
+ phpType += `${key}: ${type}, `
120
+ }
121
+ }
122
+ subfields += ']'
123
+ phpType = phpType.slice(0, -2) + '}>'
124
+ }
125
+ return [`FieldConfig(type: FieldTypeEnum::${type}, name: '${name}'${subfields})`, phpType]
126
+ }
127
+ function buildAttribute(control, controlValue) {
128
+ const [attribute, type] = buildAttributeInternals(control, controlValue)
129
+ if (type.startsWith('list')) {
130
+ return `/** @var null|${type} */\n#[${attribute}]`
131
+ }
132
+ return `#[${attribute}]`
133
+ }
134
+
13
135
  export default function prepare(options) {
14
136
  return {
15
137
  async copy(name) {
@@ -243,73 +365,16 @@ export default function prepare(options) {
243
365
  let annotations = []
244
366
  let objects = []
245
367
 
246
- const getField = (control, type) => {
247
- if (type === 'number') {
248
- return 'INT'
249
- }
250
-
251
- if (control.startsWith('table')) {
252
- return 'TABLE'
253
- }
254
-
255
- if (control === 'heading' || control === 'title') {
256
- return 'TEXT'
257
- }
258
-
259
- if (control === 'content') {
260
- return 'WSW'
261
- }
262
-
263
- if (type === 'string') {
264
- return 'TEXTAREA'
265
- }
266
-
267
- if (type === 'boolean') {
268
- return 'BOOLEAN'
269
- }
270
-
271
- return 'OTHER'
272
- }
273
-
274
- const getTitle = (control) => {
275
- if (control === 'heading') {
276
- return 'Nadpis'
277
- }
278
-
279
- if (control === 'title') {
280
- return 'Titulek'
281
- }
282
-
283
- if (control === 'content') {
284
- return 'Obsah'
285
- }
286
-
287
- if (control === 'text') {
288
- return 'Text'
289
- }
290
-
291
- return control[0].toUpperCase() + control.slice(1)
292
- }
293
-
294
368
  Object.keys(controls).forEach(control => {
295
369
  if (control !== 'src') {
296
370
  const type = typeof controls[control]
297
371
  const value = typeof controls[control] === 'object' ? JSON.stringify(controls[control]) : controls[control]
298
372
 
299
- let phpType = type
300
-
301
- if (type === 'object' && Array.isArray(controls[control])) {
302
- phpType = 'array'
303
- } else if (type === 'boolean') {
304
- phpType = 'bool'
305
- } else if (type === 'number') {
306
- phpType = 'int'
307
- }
373
+ const phpType = generatePhpType(control, controls[control])
308
374
 
309
375
  annotations.push(`
310
- #[FieldType(FieldType::${getField(control, type)})]
311
- #[FieldName('${getTitle(control)}')]
312
- public ?${phpType} $${control}${type === 'string' ? " = '" + value + "'" : ' = null'};
376
+ ${buildAttribute(control, controls[control])}
377
+ public ?${phpType} $${control} = null;
313
378
  `)
314
379
 
315
380
  if (type === 'object') {
@@ -341,8 +406,8 @@ export default function prepare(options) {
341
406
  namespace App\Components;
342
407
 
343
408
  use App\Components\Attributes\ComponentName;
344
- use App\Components\Attributes\FieldName;
345
- use App\Components\Attributes\FieldType;
409
+ use App\Components\Attributes\FieldTypeEnum;
410
+ use App\Components\Attributes\FieldConfig;
346
411
 
347
412
  #[ComponentName('${name}')]
348
413
  class ${name} extends BaseComponent
@@ -415,7 +480,26 @@ export default function prepare(options) {
415
480
  })
416
481
 
417
482
  for (const path of templates) {
418
- await fse.copy(path, join(options.path.src.views, relative(options.path.src.templates, path)))
483
+ const copyAppend = async function(source) {
484
+ const dest = join(options.path.src.views, relative(options.path.src.templates, path))
485
+ fse.copy(source, dest).then(
486
+ () => {
487
+ // Prepend data
488
+ const data = fs.readFileSync(dest)
489
+ const fd = fs.openSync(dest, 'w+')
490
+ const base = basename(dest, '.latte')
491
+ const componentNameFinal = base.charAt(0).toUpperCase() + base.slice(1)
492
+ const insert = Buffer.from(`{varType App\\Components\\${componentNameFinal} $control}\n`)
493
+ fs.writeSync(fd, insert, 0, insert.length, 0)
494
+ fs.writeSync(fd, data, 0, data.length, insert.length)
495
+ fs.close(fd, (err) => {
496
+ if (err) throw err
497
+ })
498
+ }
499
+ )
500
+ }
501
+
502
+ await copyAppend(path)
419
503
  templatesCount += 1
420
504
  }
421
505
 
@@ -36,7 +36,53 @@ async function install(name, branch) {
36
36
  ])
37
37
 
38
38
  if (install === 'yes') {
39
- execSync(`cd ${name || '.'} && make install ${branch || ''}`)
39
+ execSync(`cd ${name || '.'} && composer install`)
40
+
41
+ if (fs.existsSync(resolve(process.cwd(), 'Makefile'))) {
42
+ execSync(`cd ${name || '.'} && make install ${branch || ''}`)
43
+ } else {
44
+ execSync(`cd ${name || '.'} && composer install-${branch || ''}`)
45
+ }
46
+
47
+ if (fs.existsSync(resolve(process.cwd(), 'package.json'))) {
48
+ execSync(`cd ${name || '.'} && npm i && npx vite build`)
49
+ }
50
+ }
51
+ }
52
+
53
+ async function dev(name) {
54
+ const { install } = await prompts([
55
+ {
56
+ type: 'select',
57
+ name: 'install',
58
+ message: 'Start dev server?',
59
+ choices: [
60
+ { title: 'yes', value: 'yes' },
61
+ { title: 'no', value: 'no' }
62
+ ]
63
+ }
64
+ ])
65
+
66
+ if (install === 'yes') {
67
+ execSync(`cd ${name || '.'} && composer dev-headless`)
68
+ }
69
+ }
70
+
71
+ async function migrations(name) {
72
+ const { install } = await prompts([
73
+ {
74
+ type: 'select',
75
+ name: 'install',
76
+ message: 'Init phinx migrations?',
77
+ choices: [
78
+ { title: 'yes', value: 'yes' },
79
+ { title: 'no', value: 'no' }
80
+ ]
81
+ }
82
+ ])
83
+
84
+ if (install === 'yes') {
85
+ execSync(`cd ${name || '.'} && composer phinx-init`)
40
86
  }
41
87
  }
42
88
 
@@ -63,6 +109,8 @@ export default async function cms(name, { variant, branch }) {
63
109
  clone(name, { variant, branch })
64
110
  await install(name, branch)
65
111
  await prepare()
112
+ await dev()
113
+ await migrations()
66
114
  return
67
115
  }
68
116
 
@@ -79,6 +127,7 @@ export default async function cms(name, { variant, branch }) {
79
127
  await move('log')
80
128
  await move('public/index.php')
81
129
  await move('src/views')
130
+ await move('storage')
82
131
  await move('temp')
83
132
  await move('tests')
84
133
  await move('.gitignore', { overwrite: true })
@@ -86,7 +135,7 @@ export default async function cms(name, { variant, branch }) {
86
135
  await move('composer.json')
87
136
  await move('composer.lock')
88
137
  await move('docker-compose.yml')
89
- await move('Makefile')
138
+ await move('Makefile') // deprecated
90
139
  await move('phpstan.neon')
91
140
  await move('phpunit.xml')
92
141
  await move('pint.json')