@newlogic-digital/cli 1.3.0 → 1.4.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/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 +151 -88
- package/src/utils.mjs +18 -17
|
@@ -2,586 +2,652 @@ import FastGlob from 'fast-glob'
|
|
|
2
2
|
import { join, relative, extname, basename } from 'path'
|
|
3
3
|
import fs from 'fs'
|
|
4
4
|
import fse from 'fs-extra'
|
|
5
|
-
import pc from 'picocolors'
|
|
6
|
-
import lodash from 'lodash'
|
|
7
5
|
import dedent from 'dedent'
|
|
6
|
+
import { merge } from 'es-toolkit'
|
|
7
|
+
import * as child_process from 'node:child_process'
|
|
8
|
+
import { styleText } from 'node:util'
|
|
8
9
|
|
|
9
10
|
let sectionsCount = 0
|
|
10
11
|
let sectionsFactoryCount = 0
|
|
11
12
|
let templatesCount = 0
|
|
12
13
|
|
|
13
14
|
function generatePhpType(control, controlValue) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
15
|
+
const type = typeof controlValue
|
|
16
|
+
let phpType = type
|
|
17
|
+
|
|
18
|
+
if (type === 'object' && Array.isArray(controlValue)) {
|
|
19
|
+
phpType = 'array'
|
|
20
|
+
}
|
|
21
|
+
else if (type === 'boolean') {
|
|
22
|
+
phpType = 'bool'
|
|
23
|
+
}
|
|
24
|
+
else if (type === 'number') {
|
|
25
|
+
phpType = 'int'
|
|
26
|
+
}
|
|
27
|
+
if (type === 'string') {
|
|
28
|
+
phpType = 'UserText'
|
|
29
|
+
}
|
|
30
|
+
return phpType
|
|
25
31
|
}
|
|
26
32
|
function getFieldType(control, controlValue) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
const type = typeof controlValue
|
|
34
|
+
if (type === 'number') {
|
|
35
|
+
return 'INT'
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (control.startsWith('table')) {
|
|
39
|
+
return 'TABLE'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (control === 'heading' || control === 'title') {
|
|
43
|
+
return 'TEXT'
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (control === 'content') {
|
|
47
|
+
return 'WSW'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (type === 'string') {
|
|
51
|
+
if (controlValue.startsWith('https://') || controlValue.startsWith('http://') || controlValue.trim().endsWith('.html')) {
|
|
52
|
+
return 'LINK'
|
|
42
53
|
}
|
|
43
|
-
|
|
44
|
-
|
|
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'
|
|
54
|
+
if (controlValue.trim().startsWith('<') && controlValue.trim().endsWith('/>')) {
|
|
55
|
+
return 'WSW'
|
|
52
56
|
}
|
|
57
|
+
return 'TEXTAREA'
|
|
58
|
+
}
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
if (type === 'boolean') {
|
|
61
|
+
return 'BOOLEAN'
|
|
62
|
+
}
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
if (type === 'object') {
|
|
65
|
+
return 'REPEATER'
|
|
66
|
+
}
|
|
67
|
+
return 'OTHER'
|
|
62
68
|
}
|
|
63
69
|
function getTitle(control) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
70
|
+
if (control === 'heading') {
|
|
71
|
+
return 'Nadpis'
|
|
72
|
+
}
|
|
67
73
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
if (control === 'title') {
|
|
75
|
+
return 'Titulek'
|
|
76
|
+
}
|
|
71
77
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
if (control === 'content') {
|
|
79
|
+
return 'Obsah'
|
|
80
|
+
}
|
|
75
81
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
82
|
+
if (control === 'text') {
|
|
83
|
+
return 'Text'
|
|
84
|
+
}
|
|
79
85
|
|
|
80
|
-
|
|
86
|
+
return control[0].toUpperCase() + control.slice(1)
|
|
81
87
|
}
|
|
82
88
|
|
|
83
89
|
function buildAttributeInternals(control, controlValue) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
}
|
|
90
|
+
const type = getFieldType(control, controlValue)
|
|
91
|
+
const name = getTitle(control)
|
|
92
|
+
let subfields = ''
|
|
93
|
+
let phpType = generatePhpType(control, controlValue)
|
|
94
|
+
if (type === 'REPEATER') {
|
|
95
|
+
subfields = ', subfields: [\n'
|
|
96
|
+
phpType = 'list<object{'
|
|
97
|
+
if (Array.isArray(controlValue)) {
|
|
98
|
+
const visited = {}
|
|
99
|
+
for (const object in controlValue) {
|
|
100
|
+
if (typeof controlValue[object] !== 'object') {
|
|
101
|
+
const key = 'SomethingIsWrongHere'
|
|
102
|
+
if (visited[key]) {
|
|
103
|
+
continue
|
|
104
|
+
}
|
|
105
|
+
visited[key] = true
|
|
106
|
+
const [attribute, type] = buildAttributeInternals('SomethingIsWrongHere', controlValue[object])
|
|
107
|
+
subfields += `'SomethingIsWrongHere' => new ${attribute},\n`
|
|
108
|
+
phpType += `SomethingIsWrongHere: ${type}, `
|
|
109
|
+
continue
|
|
121
110
|
}
|
|
122
|
-
|
|
123
|
-
|
|
111
|
+
for (const key in controlValue[object]) {
|
|
112
|
+
if (visited[key]) {
|
|
113
|
+
continue
|
|
114
|
+
}
|
|
115
|
+
visited[key] = true
|
|
116
|
+
const [attribute, type] = buildAttributeInternals(key, controlValue[object][key])
|
|
117
|
+
subfields += `'${key}' => new ${attribute},\n`
|
|
118
|
+
phpType += `${key}: ${type}, `
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
for (const key in controlValue) {
|
|
124
|
+
const [attribute, type] = buildAttributeInternals(key, controlValue[key])
|
|
125
|
+
subfields += `'${key}' => new ${attribute},\n`
|
|
126
|
+
phpType += `${key}: ${type}, `
|
|
127
|
+
}
|
|
124
128
|
}
|
|
125
|
-
|
|
129
|
+
subfields += ']'
|
|
130
|
+
phpType = phpType.slice(0, -2) + '}>'
|
|
131
|
+
}
|
|
132
|
+
return [`FieldConfig(type: FieldTypeEnum::${type}, name: '${name}'${subfields})`, phpType]
|
|
126
133
|
}
|
|
127
134
|
function buildAttribute(control, controlValue) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
135
|
+
const [attribute, type] = buildAttributeInternals(control, controlValue)
|
|
136
|
+
if (type.startsWith('list')) {
|
|
137
|
+
return `/** @var null|${type} */\n#[${attribute}]`
|
|
138
|
+
}
|
|
139
|
+
return `#[${attribute}]`
|
|
133
140
|
}
|
|
134
141
|
|
|
135
142
|
export default function prepare(options) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (!fs.existsSync(options.path.app.componentsFactory)) {
|
|
150
|
-
fs.mkdirSync(options.path.app.componentsFactory)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
await this.copyComponents(name === 'components')
|
|
154
|
-
}
|
|
143
|
+
return {
|
|
144
|
+
async copy(name) {
|
|
145
|
+
if (!name || name === 'components') {
|
|
146
|
+
if (!fs.existsSync(options.path.src.components)) {
|
|
147
|
+
console.log(`${styleText('red', '✖')} path ${options.path.src.components} doesn't exists`)
|
|
148
|
+
process.exit(1)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (!fs.existsSync(options.path.app.components)) {
|
|
152
|
+
console.log(`${styleText('red', '✖')} path ${options.path.app.components} doesn't exists`)
|
|
153
|
+
process.exit(1)
|
|
154
|
+
}
|
|
155
155
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
process.exit(1)
|
|
160
|
-
}
|
|
156
|
+
if (!fs.existsSync(options.path.app.componentsFactory)) {
|
|
157
|
+
fs.mkdirSync(options.path.app.componentsFactory)
|
|
158
|
+
}
|
|
161
159
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
process.exit(1)
|
|
165
|
-
}
|
|
160
|
+
await this.copyComponents(name === 'components')
|
|
161
|
+
}
|
|
166
162
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
163
|
+
if (name === 'sections') {
|
|
164
|
+
if (!fs.existsSync(options.path.src.sections)) {
|
|
165
|
+
console.log(`${styleText('red', '✖')} path ${options.path.src.sections} doesn't exists`)
|
|
166
|
+
process.exit(1)
|
|
167
|
+
}
|
|
170
168
|
|
|
171
|
-
|
|
172
|
-
|
|
169
|
+
if (!fs.existsSync(options.path.app.sections)) {
|
|
170
|
+
console.log(`${styleText('red', '✖')} path ${options.path.app.sections} doesn't exists`)
|
|
171
|
+
process.exit(1)
|
|
172
|
+
}
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
process.exit(1)
|
|
178
|
-
}
|
|
174
|
+
if (!fs.existsSync(options.path.app.sectionsFactory)) {
|
|
175
|
+
fs.mkdirSync(options.path.app.sectionsFactory)
|
|
176
|
+
}
|
|
179
177
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
178
|
+
await this.copySections(name === 'sections')
|
|
179
|
+
}
|
|
183
180
|
|
|
184
|
-
|
|
185
|
-
|
|
181
|
+
if (!name || name === 'views') {
|
|
182
|
+
if (!fs.existsSync(options.path.src.templates)) {
|
|
183
|
+
console.log(`${styleText('red', '✖')} path ${options.path.src.templates} doesn't exists`)
|
|
184
|
+
process.exit(1)
|
|
185
|
+
}
|
|
186
186
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
187
|
+
if (!fs.existsSync(options.path.app.components)) {
|
|
188
|
+
fs.mkdirSync(options.path.app.components)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
await this.copyViews(name === 'views')
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (name === 'templates') {
|
|
195
|
+
if (!fs.existsSync(options.path.src.templates)) {
|
|
196
|
+
console.log(`${styleText('red', '✖')} path ${options.path.src.templates} doesn't exists`)
|
|
197
|
+
process.exit(1)
|
|
198
|
+
}
|
|
192
199
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
200
|
+
if (!fs.existsSync(options.path.app.sections)) {
|
|
201
|
+
fs.mkdirSync(options.path.app.sections)
|
|
202
|
+
}
|
|
196
203
|
|
|
197
|
-
|
|
204
|
+
await this.copyTemplates(name === 'templates')
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
writeSection(name, path, force) {
|
|
208
|
+
if (!path) {
|
|
209
|
+
path = join(relative(options.path.src.templates, options.path.src.sections), name) + '.latte'
|
|
210
|
+
name = name.replaceAll('/', '')
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (!name.match(/(Ui)/)) {
|
|
214
|
+
if (!fs.existsSync(join(options.path.app.sections, `${name}.php`)) || force) {
|
|
215
|
+
const schema = this.getSectionsSchema()
|
|
216
|
+
const controls = schema[path] ?? {}
|
|
217
|
+
let annotations = []
|
|
218
|
+
let objects = []
|
|
219
|
+
|
|
220
|
+
const getField = (control, type) => {
|
|
221
|
+
if (type === 'number') {
|
|
222
|
+
return 'INT'
|
|
198
223
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
path = join(relative(options.path.src.templates, options.path.src.sections), name) + '.latte'
|
|
203
|
-
name = name.replaceAll('/', '')
|
|
224
|
+
|
|
225
|
+
if (control.startsWith('table')) {
|
|
226
|
+
return 'TABLE'
|
|
204
227
|
}
|
|
205
228
|
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
const schema = this.getSectionsSchema()
|
|
209
|
-
const controls = schema[path] ?? {}
|
|
210
|
-
let annotations = []
|
|
211
|
-
let objects = []
|
|
212
|
-
|
|
213
|
-
const getField = (control, type) => {
|
|
214
|
-
if (type === 'number') {
|
|
215
|
-
return 'INT'
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (control.startsWith('table')) {
|
|
219
|
-
return 'TABLE'
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (control === 'heading' || control === 'title') {
|
|
223
|
-
return 'TEXT'
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
if (control === 'content') {
|
|
227
|
-
return 'WSW'
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (type === 'string') {
|
|
231
|
-
return 'TEXTAREA'
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (type === 'boolean') {
|
|
235
|
-
return 'BOOLEAN'
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
return 'OTHER'
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
const getTitle = (control) => {
|
|
242
|
-
if (control === 'heading') {
|
|
243
|
-
return 'Nadpis'
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
if (control === 'title') {
|
|
247
|
-
return 'Titulek'
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
if (control === 'content') {
|
|
251
|
-
return 'Obsah'
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
if (control === 'text') {
|
|
255
|
-
return 'Text'
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
return control[0].toUpperCase() + control.slice(1)
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
Object.keys(controls).forEach(control => {
|
|
262
|
-
if (control !== 'src') {
|
|
263
|
-
const type = typeof controls[control]
|
|
264
|
-
const value = typeof controls[control] === 'object' ? JSON.stringify(controls[control]) : controls[control]
|
|
265
|
-
|
|
266
|
-
let phpType = type
|
|
267
|
-
|
|
268
|
-
if (type === 'object' && Array.isArray(controls[control])) {
|
|
269
|
-
phpType = 'array'
|
|
270
|
-
} else if (type === 'boolean') {
|
|
271
|
-
phpType = 'bool'
|
|
272
|
-
} else if (type === 'number') {
|
|
273
|
-
phpType = 'int'
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
annotations.push(`
|
|
277
|
-
#[FieldType(FieldType::${getField(control, type)})]
|
|
278
|
-
#[FieldName('${getTitle(control)}')]
|
|
279
|
-
public ?${phpType} $${control}${type === 'string' ? " = '" + value + "'" : ' = null'};
|
|
280
|
-
`)
|
|
281
|
-
|
|
282
|
-
if (type === 'object') {
|
|
283
|
-
objects.push(`
|
|
284
|
-
$this->${control} = json_decode('${value}', false);
|
|
285
|
-
`)
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
})
|
|
289
|
-
|
|
290
|
-
if (annotations.length > 0) {
|
|
291
|
-
annotations = annotations.map(item => item).join('')
|
|
292
|
-
} else {
|
|
293
|
-
annotations = ''
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
if (objects.length > 0) {
|
|
297
|
-
objects = objects.map(item => item).join('')
|
|
298
|
-
} else {
|
|
299
|
-
objects = ''
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
fs.writeFileSync(join(options.path.app.sections, `${name}.php`),
|
|
303
|
-
dedent`
|
|
304
|
-
<?php
|
|
305
|
-
|
|
306
|
-
declare(strict_types=1);
|
|
307
|
-
|
|
308
|
-
namespace App\Sections;
|
|
309
|
-
|
|
310
|
-
use App\Sections\Attributes\FieldName;
|
|
311
|
-
use App\Sections\Attributes\FieldType;
|
|
312
|
-
use App\Sections\Attributes\SectionName;
|
|
313
|
-
|
|
314
|
-
#[SectionName('${name}')]
|
|
315
|
-
class ${name} extends BaseSection
|
|
316
|
-
{
|
|
317
|
-
${annotations}
|
|
318
|
-
public function render() : void
|
|
319
|
-
{
|
|
320
|
-
${objects}
|
|
321
|
-
$this->template->render(TEMPLATES_DIR . '/${path}');
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
`
|
|
325
|
-
)
|
|
326
|
-
|
|
327
|
-
sectionsCount += 1
|
|
328
|
-
}
|
|
229
|
+
if (control === 'heading' || control === 'title') {
|
|
230
|
+
return 'TEXT'
|
|
329
231
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
if (!fs.existsSync(join(options.path.app.sectionsFactory, `${name}Factory.php`)) || force) {
|
|
334
|
-
fs.writeFileSync(join(options.path.app.sectionsFactory, `${name}Factory.php`),
|
|
335
|
-
dedent`
|
|
336
|
-
<?php
|
|
337
|
-
|
|
338
|
-
declare(strict_types=1);
|
|
339
|
-
|
|
340
|
-
namespace App\Sections\Factory;
|
|
341
|
-
|
|
342
|
-
use ${'App\\Sections\\'}${name};
|
|
343
|
-
|
|
344
|
-
interface ${name}Factory
|
|
345
|
-
{
|
|
346
|
-
public function create(): ${name};
|
|
347
|
-
}
|
|
348
|
-
`
|
|
349
|
-
)
|
|
350
|
-
|
|
351
|
-
sectionsFactoryCount += 1
|
|
352
|
-
}
|
|
232
|
+
|
|
233
|
+
if (control === 'content') {
|
|
234
|
+
return 'WSW'
|
|
353
235
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
path = name + '.latte'
|
|
358
|
-
name = name.replaceAll('/', '')
|
|
236
|
+
|
|
237
|
+
if (type === 'string') {
|
|
238
|
+
return 'TEXTAREA'
|
|
359
239
|
}
|
|
360
240
|
|
|
361
|
-
if (
|
|
362
|
-
|
|
363
|
-
const schema = this.getComponentsSchema()
|
|
364
|
-
const controls = schema[path] ?? {}
|
|
365
|
-
let annotations = []
|
|
366
|
-
let objects = []
|
|
367
|
-
|
|
368
|
-
Object.keys(controls).forEach(control => {
|
|
369
|
-
if (control !== 'src') {
|
|
370
|
-
const type = typeof controls[control]
|
|
371
|
-
const value = typeof controls[control] === 'object' ? JSON.stringify(controls[control]) : controls[control]
|
|
372
|
-
|
|
373
|
-
const phpType = generatePhpType(control, controls[control])
|
|
374
|
-
|
|
375
|
-
annotations.push(`
|
|
376
|
-
${buildAttribute(control, controls[control])}
|
|
377
|
-
public ?${phpType} $${control} = null;
|
|
378
|
-
`)
|
|
379
|
-
|
|
380
|
-
if (type === 'object') {
|
|
381
|
-
objects.push(`
|
|
382
|
-
$this->${control} = json_decode('${value}', false);
|
|
383
|
-
`)
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
})
|
|
387
|
-
|
|
388
|
-
if (annotations.length > 0) {
|
|
389
|
-
annotations = annotations.map(item => item).join('')
|
|
390
|
-
} else {
|
|
391
|
-
annotations = ''
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
if (objects.length > 0) {
|
|
395
|
-
objects = objects.map(item => item).join('')
|
|
396
|
-
} else {
|
|
397
|
-
objects = ''
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
fs.writeFileSync(join(options.path.app.components, `${name}.php`),
|
|
401
|
-
dedent`
|
|
402
|
-
<?php
|
|
403
|
-
|
|
404
|
-
declare(strict_types=1);
|
|
405
|
-
|
|
406
|
-
namespace App\Components;
|
|
407
|
-
|
|
408
|
-
use App\Components\Attributes\ComponentName;
|
|
409
|
-
use App\Components\Attributes\FieldTypeEnum;
|
|
410
|
-
use App\Components\Attributes\FieldConfig;
|
|
411
|
-
|
|
412
|
-
#[ComponentName('${name}')]
|
|
413
|
-
class ${name} extends BaseComponent
|
|
414
|
-
{
|
|
415
|
-
${annotations}
|
|
416
|
-
public function render() : void
|
|
417
|
-
{
|
|
418
|
-
${objects}
|
|
419
|
-
$this->template->render(TEMPLATES_DIR . '/${path}');
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
`
|
|
423
|
-
)
|
|
424
|
-
|
|
425
|
-
sectionsCount += 1
|
|
426
|
-
}
|
|
241
|
+
if (type === 'boolean') {
|
|
242
|
+
return 'BOOLEAN'
|
|
427
243
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
declare(strict_types=1);
|
|
437
|
-
|
|
438
|
-
namespace App\Components\Factory;
|
|
439
|
-
|
|
440
|
-
use ${'App\\Components\\'}${name};
|
|
441
|
-
|
|
442
|
-
interface ${name}Factory
|
|
443
|
-
{
|
|
444
|
-
public function create(): ${name};
|
|
445
|
-
}
|
|
446
|
-
`
|
|
447
|
-
)
|
|
448
|
-
|
|
449
|
-
sectionsFactoryCount += 1
|
|
450
|
-
}
|
|
244
|
+
|
|
245
|
+
return 'OTHER'
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const getTitle = (control) => {
|
|
249
|
+
if (control === 'heading') {
|
|
250
|
+
return 'Nadpis'
|
|
451
251
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
components.forEach(path => {
|
|
457
|
-
const name = basename(relative(options.path.src.components, path), extname(relative(options.path.src.components, path)))
|
|
458
|
-
|
|
459
|
-
this.writeComponent(name, relative(options.path.src.templates, path), force)
|
|
460
|
-
this.writeComponentFactory(name, force)
|
|
461
|
-
})
|
|
462
|
-
|
|
463
|
-
console.log(`${pc.green('✔')} ${sectionsCount} components and ${sectionsFactoryCount} factory files copied to app`)
|
|
464
|
-
},
|
|
465
|
-
async copySections(force = false) {
|
|
466
|
-
const sections = FastGlob.sync(join(options.path.src.sections, '/**'))
|
|
467
|
-
|
|
468
|
-
sections.forEach(path => {
|
|
469
|
-
const name = relative(options.path.src.sections, path).replace(extname(relative(options.path.src.sections, path)), '').replaceAll('/', '')
|
|
470
|
-
|
|
471
|
-
this.writeSection(name, relative(options.path.src.templates, path), force)
|
|
472
|
-
this.writeSectionFactory(name, force)
|
|
473
|
-
})
|
|
474
|
-
|
|
475
|
-
console.log(`${pc.green('✔')} ${sectionsCount} sections and ${sectionsFactoryCount} factory files copied to app`)
|
|
476
|
-
},
|
|
477
|
-
async copyViews(force = false) {
|
|
478
|
-
const templates = FastGlob.sync(join(options.path.src.templates, '/**')).filter(entry => {
|
|
479
|
-
return !fs.existsSync(join(options.path.src.views, relative(options.path.src.templates, entry))) || force
|
|
480
|
-
})
|
|
481
|
-
|
|
482
|
-
for (const path of templates) {
|
|
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)
|
|
503
|
-
templatesCount += 1
|
|
252
|
+
|
|
253
|
+
if (control === 'title') {
|
|
254
|
+
return 'Titulek'
|
|
504
255
|
}
|
|
505
256
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
const templates = FastGlob.sync(join(options.path.src.templates, '/**')).filter(entry => {
|
|
510
|
-
return !fs.existsSync(join(options.path.app.templates, relative(options.path.src.templates, entry))) || force
|
|
511
|
-
})
|
|
257
|
+
if (control === 'content') {
|
|
258
|
+
return 'Obsah'
|
|
259
|
+
}
|
|
512
260
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
templatesCount += 1
|
|
261
|
+
if (control === 'text') {
|
|
262
|
+
return 'Text'
|
|
516
263
|
}
|
|
517
264
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
265
|
+
return control[0].toUpperCase() + control.slice(1)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
Object.keys(controls).forEach((control) => {
|
|
269
|
+
if (control !== 'src') {
|
|
270
|
+
const type = typeof controls[control]
|
|
271
|
+
const value = typeof controls[control] === 'object' ? JSON.stringify(controls[control]) : controls[control]
|
|
272
|
+
|
|
273
|
+
let phpType = type
|
|
274
|
+
|
|
275
|
+
if (type === 'object' && Array.isArray(controls[control])) {
|
|
276
|
+
phpType = 'array'
|
|
277
|
+
}
|
|
278
|
+
else if (type === 'boolean') {
|
|
279
|
+
phpType = 'bool'
|
|
280
|
+
}
|
|
281
|
+
else if (type === 'number') {
|
|
282
|
+
phpType = 'int'
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
annotations.push(`
|
|
286
|
+
#[FieldType(FieldType::${getField(control, type)})]
|
|
287
|
+
#[FieldName('${getTitle(control)}')]
|
|
288
|
+
public ?${phpType} $${control}${type === 'string' ? ' = \'' + value + '\'' : ' = null'};
|
|
289
|
+
`)
|
|
290
|
+
|
|
291
|
+
if (type === 'object') {
|
|
292
|
+
objects.push(`
|
|
293
|
+
$this->${control} = json_decode('${value}', false);
|
|
294
|
+
`)
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
if (annotations.length > 0) {
|
|
300
|
+
annotations = annotations.map(item => item).join('')
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
annotations = ''
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (objects.length > 0) {
|
|
307
|
+
objects = objects.map(item => item).join('')
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
objects = ''
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
fs.writeFileSync(join(options.path.app.sections, `${name}.php`),
|
|
314
|
+
dedent`
|
|
315
|
+
<?php
|
|
316
|
+
|
|
317
|
+
declare(strict_types=1);
|
|
318
|
+
|
|
319
|
+
namespace App\Sections;
|
|
320
|
+
|
|
321
|
+
use App\Sections\Attributes\FieldName;
|
|
322
|
+
use App\Sections\Attributes\FieldType;
|
|
323
|
+
use App\Sections\Attributes\SectionName;
|
|
324
|
+
|
|
325
|
+
#[SectionName('${name}')]
|
|
326
|
+
class ${name} extends BaseSection
|
|
327
|
+
{
|
|
328
|
+
${annotations}
|
|
329
|
+
public function render() : void
|
|
330
|
+
{
|
|
331
|
+
${objects}
|
|
332
|
+
$this->template->render(TEMPLATES_DIR . '/${path}');
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
`,
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
sectionsCount += 1
|
|
585
339
|
}
|
|
586
|
-
|
|
340
|
+
}
|
|
341
|
+
},
|
|
342
|
+
writeSectionFactory(name, force) {
|
|
343
|
+
if (!name.match(/(Ui)/)) {
|
|
344
|
+
if (!fs.existsSync(join(options.path.app.sectionsFactory, `${name}Factory.php`)) || force) {
|
|
345
|
+
fs.writeFileSync(join(options.path.app.sectionsFactory, `${name}Factory.php`),
|
|
346
|
+
dedent`
|
|
347
|
+
<?php
|
|
348
|
+
|
|
349
|
+
declare(strict_types=1);
|
|
350
|
+
|
|
351
|
+
namespace App\Sections\Factory;
|
|
352
|
+
|
|
353
|
+
use ${'App\\Sections\\'}${name};
|
|
354
|
+
|
|
355
|
+
interface ${name}Factory
|
|
356
|
+
{
|
|
357
|
+
public function create(): ${name};
|
|
358
|
+
}
|
|
359
|
+
`,
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
sectionsFactoryCount += 1
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
writeComponent(name, path, force, imageSubstitutions) {
|
|
367
|
+
if (!path) {
|
|
368
|
+
path = name + '.latte'
|
|
369
|
+
name = name.replaceAll('/', '')
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (!name.match(/(Ui)/)) {
|
|
373
|
+
if (!fs.existsSync(join(options.path.app.components, `${name}.php`)) || force) {
|
|
374
|
+
const schema = this.getComponentsSchema()
|
|
375
|
+
const controls = schema[path] ?? {}
|
|
376
|
+
let annotations = []
|
|
377
|
+
let objects = []
|
|
378
|
+
|
|
379
|
+
Object.keys(controls).forEach((control) => {
|
|
380
|
+
if (control !== 'src') {
|
|
381
|
+
const type = typeof controls[control]
|
|
382
|
+
const value = typeof controls[control] === 'object' ? JSON.stringify(controls[control]) : controls[control]
|
|
383
|
+
|
|
384
|
+
const phpType = generatePhpType(control, controls[control])
|
|
385
|
+
|
|
386
|
+
annotations.push(`
|
|
387
|
+
${buildAttribute(control, controls[control])}
|
|
388
|
+
public ?${phpType} $${control} = null;
|
|
389
|
+
`)
|
|
390
|
+
|
|
391
|
+
if (type === 'object') {
|
|
392
|
+
objects.push(`
|
|
393
|
+
$this->${control} = json_decode('${value}', false);
|
|
394
|
+
`)
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
})
|
|
398
|
+
for (const [value, x, y] of (imageSubstitutions ?? [])) {
|
|
399
|
+
annotations.push(`
|
|
400
|
+
#[FieldConfig(type: FieldTypeEnum::FILE, name: 'PLACEHOLDER ${value}', help: '${x} x ${y}')]
|
|
401
|
+
public ?File $${value} = null;
|
|
402
|
+
`)
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (annotations.length > 0) {
|
|
406
|
+
annotations = annotations.map(item => item).join('')
|
|
407
|
+
}
|
|
408
|
+
else {
|
|
409
|
+
annotations = ''
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (objects.length > 0) {
|
|
413
|
+
objects = objects.map(item => item).join('')
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
objects = ''
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
fs.writeFileSync(join(options.path.app.components, `${name}.php`),
|
|
420
|
+
dedent`
|
|
421
|
+
<?php
|
|
422
|
+
|
|
423
|
+
declare(strict_types=1);
|
|
424
|
+
|
|
425
|
+
namespace App\Components;
|
|
426
|
+
|
|
427
|
+
use App\Components\Attributes\Component\Category;
|
|
428
|
+
use App\Components\Attributes\Component\Focus;
|
|
429
|
+
use App\Components\Attributes\Component\Component;
|
|
430
|
+
use App\Components\Attributes\FieldTypeEnum;
|
|
431
|
+
use App\Components\Attributes\FieldConfig;
|
|
432
|
+
use App\Model\File\File;
|
|
433
|
+
use NewlogicDigital\Cms\Core\Model\UserText;
|
|
434
|
+
|
|
435
|
+
#[Component(name: '${name}', category: Category::Text, focuses: [Focus::Page], cache: true)]
|
|
436
|
+
class ${name} extends BaseComponent
|
|
437
|
+
{
|
|
438
|
+
${annotations}
|
|
439
|
+
public function render() : void
|
|
440
|
+
{
|
|
441
|
+
${objects}
|
|
442
|
+
$this->template->render(TEMPLATES_DIR . '/${path}');
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
`,
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
sectionsCount += 1
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
writeComponentFactory(name, force) {
|
|
453
|
+
if (!name.match(/(Ui)/)) {
|
|
454
|
+
if (!fs.existsSync(join(options.path.app.componentsFactory, `${name}Factory.php`)) || force) {
|
|
455
|
+
fs.writeFileSync(join(options.path.app.componentsFactory, `${name}Factory.php`),
|
|
456
|
+
dedent`
|
|
457
|
+
<?php
|
|
458
|
+
|
|
459
|
+
declare(strict_types=1);
|
|
460
|
+
|
|
461
|
+
namespace App\Components\Factory;
|
|
462
|
+
|
|
463
|
+
use ${'App\\Components\\'}${name};
|
|
464
|
+
|
|
465
|
+
interface ${name}Factory
|
|
466
|
+
{
|
|
467
|
+
public function create(): ${name};
|
|
468
|
+
}
|
|
469
|
+
`,
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
sectionsFactoryCount += 1
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
},
|
|
476
|
+
async copyComponents(force = false, buildFactories = false) {
|
|
477
|
+
const components = FastGlob.sync(join(options.path.src.components, '/**'))
|
|
478
|
+
|
|
479
|
+
components.forEach((path) => {
|
|
480
|
+
const name = basename(relative(options.path.src.components, path), extname(relative(options.path.src.components, path)))
|
|
481
|
+
if (name.startsWith('CookieConsent')) {
|
|
482
|
+
return
|
|
483
|
+
}
|
|
484
|
+
const check = child_process.spawn('grep', ['-ri', '{[(include)|(import)][^}]*' + name + '.latte', options.path.src.templates])
|
|
485
|
+
check.stderr.on('data', () => '')
|
|
486
|
+
var buffer = ''
|
|
487
|
+
check.stdout.on('data', function (a) {
|
|
488
|
+
buffer += a
|
|
489
|
+
})
|
|
490
|
+
const ref = this
|
|
491
|
+
check.on('exit', function (code) {
|
|
492
|
+
if (code !== 0) {
|
|
493
|
+
// console.log('Creating:' +name+ ' - buffer: '+ buffer);
|
|
494
|
+
let res = []
|
|
495
|
+
let counter = 0
|
|
496
|
+
let a
|
|
497
|
+
for (a of fs.readFileSync(path).toString().matchAll(/=\(*placeholder\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*\)+/ig)) {
|
|
498
|
+
res.push(['image' + counter, a[1], a[2]])
|
|
499
|
+
counter += 1
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
ref.writeComponent(name, relative(options.path.src.templates, path), force, res)
|
|
503
|
+
if (buildFactories) {
|
|
504
|
+
ref.writeComponentFactory(name, force)
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
else {
|
|
508
|
+
console.info('Skiping `' + name + '` grep -ri found ' + buffer)
|
|
509
|
+
}
|
|
510
|
+
})
|
|
511
|
+
})
|
|
512
|
+
|
|
513
|
+
console.log(`${styleText('green', '✔')} ${sectionsCount} components and ${sectionsFactoryCount} factory files copied to app`)
|
|
514
|
+
},
|
|
515
|
+
async copySections(force = false) {
|
|
516
|
+
const sections = FastGlob.sync(join(options.path.src.sections, '/**'))
|
|
517
|
+
|
|
518
|
+
sections.forEach((path) => {
|
|
519
|
+
const name = relative(options.path.src.sections, path).replace(extname(relative(options.path.src.sections, path)), '').replaceAll('/', '')
|
|
520
|
+
|
|
521
|
+
this.writeSection(name, relative(options.path.src.templates, path), force)
|
|
522
|
+
this.writeSectionFactory(name, force)
|
|
523
|
+
})
|
|
524
|
+
|
|
525
|
+
console.log(`${styleText('green', '✔')} ${sectionsCount} sections and ${sectionsFactoryCount} factory files copied to app`)
|
|
526
|
+
},
|
|
527
|
+
async copyViews(force = false) {
|
|
528
|
+
const templates = FastGlob.sync(join(options.path.src.templates, '/**')).filter((entry) => {
|
|
529
|
+
return !fs.existsSync(join(options.path.src.views, relative(options.path.src.templates, entry))) || force
|
|
530
|
+
})
|
|
531
|
+
|
|
532
|
+
for (const path of templates) {
|
|
533
|
+
const copyAppend = async function (source) {
|
|
534
|
+
const dest = join(options.path.src.views, relative(options.path.src.templates, path))
|
|
535
|
+
fse.copy(source, dest).then(
|
|
536
|
+
() => {
|
|
537
|
+
// Prepend data
|
|
538
|
+
let data = fs.readFileSync(dest).toString()
|
|
539
|
+
const fd = fs.openSync(dest, 'w+')
|
|
540
|
+
const base = basename(dest, '.latte')
|
|
541
|
+
const componentNameFinal = base.charAt(0).toUpperCase() + base.slice(1)
|
|
542
|
+
let insert = Buffer.from(`{varType App\\Components\\${componentNameFinal} $control}\n`)
|
|
543
|
+
let full, a, b
|
|
544
|
+
let res
|
|
545
|
+
let count = 0
|
|
546
|
+
|
|
547
|
+
res = data.match(/=\(*placeholder\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*\)+/i)
|
|
548
|
+
|
|
549
|
+
while (res) {
|
|
550
|
+
[full, a, b] = res
|
|
551
|
+
data = data.replace(full, `$control->image${count}|thumb:${a}, ${b},true`)
|
|
552
|
+
count += 1
|
|
553
|
+
res = data.match(/=\(*placeholder\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*\)+/i)
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
data = insert.toString() + data
|
|
557
|
+
|
|
558
|
+
fs.writeSync(fd, data)
|
|
559
|
+
fs.close(fd, (err) => {
|
|
560
|
+
if (err) throw err
|
|
561
|
+
})
|
|
562
|
+
},
|
|
563
|
+
)
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
await copyAppend(path)
|
|
567
|
+
templatesCount += 1
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
console.log(`${styleText('green', '✔')} ${templatesCount} views files copied from templates`)
|
|
571
|
+
},
|
|
572
|
+
async copyTemplates(force = false) {
|
|
573
|
+
const templates = FastGlob.sync(join(options.path.src.templates, '/**')).filter((entry) => {
|
|
574
|
+
return !fs.existsSync(join(options.path.app.templates, relative(options.path.src.templates, entry))) || force
|
|
575
|
+
})
|
|
576
|
+
|
|
577
|
+
for (const path of templates) {
|
|
578
|
+
await fse.copy(path, join(options.path.app.templates, relative(options.path.src.templates, path)))
|
|
579
|
+
templatesCount += 1
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
console.log(`${styleText('green', '✔')} ${templatesCount} template files copied to app`)
|
|
583
|
+
},
|
|
584
|
+
getSectionsSchema() {
|
|
585
|
+
const views = FastGlob.sync(join(options.path.src.views, '/**/*.json'))
|
|
586
|
+
const sectionsUnsorted = {}
|
|
587
|
+
const sectionsSchema = {}
|
|
588
|
+
|
|
589
|
+
views.forEach((path) => {
|
|
590
|
+
const json = JSON.parse(fs.readFileSync(path).toString())
|
|
591
|
+
const sections = [...(json.page.body ?? []), ...(json.page.head ?? []), ...(json.page.foot ?? [])]
|
|
592
|
+
|
|
593
|
+
sections.forEach((section) => {
|
|
594
|
+
if (section.src) {
|
|
595
|
+
if (typeof sectionsUnsorted[section.src] === 'undefined') {
|
|
596
|
+
sectionsUnsorted[section.src] = []
|
|
597
|
+
sectionsUnsorted[section.src].push(section)
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
sectionsUnsorted[section.src].push(section)
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
})
|
|
604
|
+
})
|
|
605
|
+
|
|
606
|
+
Object.keys(sectionsUnsorted).forEach((key) => {
|
|
607
|
+
const sortedSection = {}
|
|
608
|
+
|
|
609
|
+
sectionsUnsorted[key].forEach((section) => {
|
|
610
|
+
merge(sortedSection, section)
|
|
611
|
+
})
|
|
612
|
+
|
|
613
|
+
sectionsSchema[sortedSection.src] = sortedSection
|
|
614
|
+
})
|
|
615
|
+
|
|
616
|
+
return sectionsSchema
|
|
617
|
+
},
|
|
618
|
+
getComponentsSchema() {
|
|
619
|
+
const views = FastGlob.sync(join(options.path.src.pages, '/**/*.json'))
|
|
620
|
+
const sectionsUnsorted = {}
|
|
621
|
+
const sectionsSchema = {}
|
|
622
|
+
|
|
623
|
+
views.forEach((path) => {
|
|
624
|
+
const json = JSON.parse(fs.readFileSync(path).toString())
|
|
625
|
+
const sections = [...(json.body ?? []), ...(json.head ?? []), ...(json.foot ?? [])]
|
|
626
|
+
|
|
627
|
+
sections.forEach((section) => {
|
|
628
|
+
if (section.src) {
|
|
629
|
+
if (typeof sectionsUnsorted[section.src] === 'undefined') {
|
|
630
|
+
sectionsUnsorted[section.src] = []
|
|
631
|
+
sectionsUnsorted[section.src].push(section)
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
sectionsUnsorted[section.src].push(section)
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
})
|
|
638
|
+
})
|
|
639
|
+
|
|
640
|
+
Object.keys(sectionsUnsorted).forEach((key) => {
|
|
641
|
+
const sortedSection = {}
|
|
642
|
+
|
|
643
|
+
sectionsUnsorted[key].forEach((section) => {
|
|
644
|
+
merge(sortedSection, section)
|
|
645
|
+
})
|
|
646
|
+
|
|
647
|
+
sectionsSchema[sortedSection.src] = sortedSection
|
|
648
|
+
})
|
|
649
|
+
|
|
650
|
+
return sectionsSchema
|
|
651
|
+
},
|
|
652
|
+
}
|
|
587
653
|
}
|