@docsector/docsector-reader 0.5.1 → 0.5.2
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/bin/docsector.js +8 -2
- package/package.json +1 -1
- package/src/layouts/DefaultLayout.vue +30 -3
- package/src/pages/index.js +121 -0
- package/src/quasar.factory.js +26 -1
package/bin/docsector.js
CHANGED
|
@@ -23,7 +23,7 @@ const packageRoot = resolve(__dirname, '..')
|
|
|
23
23
|
const args = process.argv.slice(2)
|
|
24
24
|
const command = args[0]
|
|
25
25
|
|
|
26
|
-
const VERSION = '0.5.
|
|
26
|
+
const VERSION = '0.5.2'
|
|
27
27
|
|
|
28
28
|
const HELP = `
|
|
29
29
|
Docsector Reader v${VERSION}
|
|
@@ -71,7 +71,7 @@ function getTemplatePackageJson (name) {
|
|
|
71
71
|
serve: 'docsector serve'
|
|
72
72
|
},
|
|
73
73
|
dependencies: {
|
|
74
|
-
'@docsector/docsector-reader': '^0.5.
|
|
74
|
+
'@docsector/docsector-reader': '^0.5.2',
|
|
75
75
|
'@quasar/extras': '^1.16.12',
|
|
76
76
|
'quasar': '^2.16.6',
|
|
77
77
|
'vue': '^3.5.13',
|
|
@@ -276,6 +276,7 @@ const TEMPLATE_PAGES_INDEX = `\
|
|
|
276
276
|
*
|
|
277
277
|
* config.type: top-level route prefix — 'manual', 'guide', etc.
|
|
278
278
|
* config.status: 'done' | 'draft' | 'empty'
|
|
279
|
+
* config.meta.description: string or localized object for SEO/social description
|
|
279
280
|
* config.icon: Material Design icon name
|
|
280
281
|
* config.menu: menu display options (header, subheader, separator)
|
|
281
282
|
* config.subpages: { showcase: bool, vs: bool }
|
|
@@ -288,6 +289,11 @@ export default {
|
|
|
288
289
|
config: {
|
|
289
290
|
icon: 'flag',
|
|
290
291
|
status: 'done',
|
|
292
|
+
meta: {
|
|
293
|
+
description: {
|
|
294
|
+
'en-US': 'Get started quickly with setup and project structure.'
|
|
295
|
+
}
|
|
296
|
+
},
|
|
291
297
|
type: 'guide',
|
|
292
298
|
menu: {
|
|
293
299
|
header: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docsector/docsector-reader",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "A documentation rendering engine built with Vue 3, Quasar v2 and Vite. Transform Markdown into beautiful, navigable documentation sites.",
|
|
5
5
|
"productName": "Docsector Reader",
|
|
6
6
|
"author": "Rodrigo de Araujo Vieira",
|
|
@@ -62,13 +62,34 @@ const headerTitleText = computed(() => {
|
|
|
62
62
|
}
|
|
63
63
|
})
|
|
64
64
|
|
|
65
|
+
const resolveLocalizedValue = (source) => {
|
|
66
|
+
if (!source) return ''
|
|
67
|
+
if (typeof source === 'string') return source
|
|
68
|
+
if (typeof source === 'object') {
|
|
69
|
+
return source[locale.value] || source['*'] || source['en-US'] || Object.values(source)[0] || ''
|
|
70
|
+
}
|
|
71
|
+
return ''
|
|
72
|
+
}
|
|
73
|
+
|
|
65
74
|
// @ Dynamic page title & meta tags
|
|
66
75
|
const pageTitle = computed(() => {
|
|
67
76
|
const data = route.matched[0]?.meta?.data
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
77
|
+
const langData = data?.[locale.value] || data?.['*'] || data?.['en-US'] || Object.values(data || {})[0]
|
|
78
|
+
return langData?.title || ''
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
const pageDescription = computed(() => {
|
|
82
|
+
const description = resolveLocalizedValue(route.matched[0]?.meta?.meta?.description)
|
|
83
|
+
if (description) return description
|
|
84
|
+
|
|
85
|
+
if (pageTitle.value && branding.name) {
|
|
86
|
+
return `${pageTitle.value} — Documentation of ${branding.name}`
|
|
71
87
|
}
|
|
88
|
+
|
|
89
|
+
if (branding.name) {
|
|
90
|
+
return `Documentation of ${branding.name}`
|
|
91
|
+
}
|
|
92
|
+
|
|
72
93
|
return ''
|
|
73
94
|
})
|
|
74
95
|
|
|
@@ -77,14 +98,20 @@ useMeta(() => {
|
|
|
77
98
|
? `${pageTitle.value} — ${branding.name || ''}`
|
|
78
99
|
: branding.name || ''
|
|
79
100
|
|
|
101
|
+
const description = pageDescription.value
|
|
80
102
|
const image = branding.logo || ''
|
|
81
103
|
|
|
82
104
|
return {
|
|
83
105
|
title,
|
|
84
106
|
meta: {
|
|
107
|
+
description: { name: 'description', content: description },
|
|
85
108
|
ogTitle: { property: 'og:title', content: title },
|
|
109
|
+
ogDescription: { property: 'og:description', content: description },
|
|
86
110
|
ogType: { property: 'og:type', content: 'article' },
|
|
87
111
|
ogImage: { property: 'og:image', content: image },
|
|
112
|
+
twitterCard: { name: 'twitter:card', content: 'summary_large_image' },
|
|
113
|
+
twitterTitle: { name: 'twitter:title', content: title },
|
|
114
|
+
twitterDescription: { name: 'twitter:description', content: description },
|
|
88
115
|
twitterImage: { name: 'twitter:image', content: image }
|
|
89
116
|
}
|
|
90
117
|
}
|
package/src/pages/index.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* config.type: determines the top-level route prefix (e.g., 'manual', 'guide', 'API')
|
|
8
8
|
* config.status: 'done' | 'draft' | 'empty'
|
|
9
|
+
* config.meta.description: string or localized object for SEO/social description
|
|
9
10
|
* config.icon: Material Design icon name
|
|
10
11
|
* config.menu: menu display options (header, subheader, separator)
|
|
11
12
|
* config.subpages: { showcase: bool, vs: bool }
|
|
@@ -22,6 +23,12 @@ export default {
|
|
|
22
23
|
config: {
|
|
23
24
|
icon: 'flag',
|
|
24
25
|
status: 'done',
|
|
26
|
+
meta: {
|
|
27
|
+
description: {
|
|
28
|
+
'en-US': 'Getting Started — Documentation of Docsector Reader',
|
|
29
|
+
'pt-BR': 'Começando — Documentacao do Docsector Reader'
|
|
30
|
+
}
|
|
31
|
+
},
|
|
25
32
|
type: 'guide',
|
|
26
33
|
menu: {
|
|
27
34
|
header: {
|
|
@@ -43,6 +50,12 @@ export default {
|
|
|
43
50
|
config: {
|
|
44
51
|
icon: 'tune',
|
|
45
52
|
status: 'done',
|
|
53
|
+
meta: {
|
|
54
|
+
description: {
|
|
55
|
+
'en-US': 'Configuration — Documentation of Docsector Reader',
|
|
56
|
+
'pt-BR': 'Configuração — Documentacao do Docsector Reader'
|
|
57
|
+
}
|
|
58
|
+
},
|
|
46
59
|
type: 'guide',
|
|
47
60
|
menu: {
|
|
48
61
|
separator: ' page'
|
|
@@ -61,6 +74,12 @@ export default {
|
|
|
61
74
|
config: {
|
|
62
75
|
icon: 'route',
|
|
63
76
|
status: 'done',
|
|
77
|
+
meta: {
|
|
78
|
+
description: {
|
|
79
|
+
'en-US': 'Pages & Routing — Documentation of Docsector Reader',
|
|
80
|
+
'pt-BR': 'Páginas & Rotas — Documentacao do Docsector Reader'
|
|
81
|
+
}
|
|
82
|
+
},
|
|
64
83
|
type: 'guide',
|
|
65
84
|
menu: {},
|
|
66
85
|
subpages: {
|
|
@@ -77,6 +96,12 @@ export default {
|
|
|
77
96
|
config: {
|
|
78
97
|
icon: 'translate',
|
|
79
98
|
status: 'done',
|
|
99
|
+
meta: {
|
|
100
|
+
description: {
|
|
101
|
+
'en-US': 'i18n & Markdown — Documentation of Docsector Reader',
|
|
102
|
+
'pt-BR': 'i18n & Markdown — Documentacao do Docsector Reader'
|
|
103
|
+
}
|
|
104
|
+
},
|
|
80
105
|
type: 'guide',
|
|
81
106
|
menu: {},
|
|
82
107
|
subpages: {
|
|
@@ -93,6 +118,12 @@ export default {
|
|
|
93
118
|
config: {
|
|
94
119
|
icon: 'palette',
|
|
95
120
|
status: 'done',
|
|
121
|
+
meta: {
|
|
122
|
+
description: {
|
|
123
|
+
'en-US': 'Theming — Documentation of Docsector Reader',
|
|
124
|
+
'pt-BR': 'Temas — Documentacao do Docsector Reader'
|
|
125
|
+
}
|
|
126
|
+
},
|
|
96
127
|
type: 'guide',
|
|
97
128
|
menu: {},
|
|
98
129
|
subpages: {
|
|
@@ -109,6 +140,12 @@ export default {
|
|
|
109
140
|
config: {
|
|
110
141
|
icon: 'cloud_upload',
|
|
111
142
|
status: 'draft',
|
|
143
|
+
meta: {
|
|
144
|
+
description: {
|
|
145
|
+
'en-US': 'Deployment — Documentation of Docsector Reader',
|
|
146
|
+
'pt-BR': 'Deploy — Documentacao do Docsector Reader'
|
|
147
|
+
}
|
|
148
|
+
},
|
|
112
149
|
type: 'guide',
|
|
113
150
|
menu: {},
|
|
114
151
|
subpages: {
|
|
@@ -125,6 +162,12 @@ export default {
|
|
|
125
162
|
config: {
|
|
126
163
|
icon: 'extension',
|
|
127
164
|
status: 'empty',
|
|
165
|
+
meta: {
|
|
166
|
+
description: {
|
|
167
|
+
'en-US': 'Plugins — Documentation of Docsector Reader',
|
|
168
|
+
'pt-BR': 'Plugins — Documentacao do Docsector Reader'
|
|
169
|
+
}
|
|
170
|
+
},
|
|
128
171
|
type: 'guide',
|
|
129
172
|
menu: {},
|
|
130
173
|
subpages: {
|
|
@@ -152,6 +195,12 @@ export default {
|
|
|
152
195
|
config: {
|
|
153
196
|
icon: 'web',
|
|
154
197
|
status: 'done',
|
|
198
|
+
meta: {
|
|
199
|
+
description: {
|
|
200
|
+
'en-US': 'DPage — Documentation of Docsector Reader',
|
|
201
|
+
'pt-BR': 'DPage — Documentacao do Docsector Reader'
|
|
202
|
+
}
|
|
203
|
+
},
|
|
155
204
|
type: 'manual',
|
|
156
205
|
menu: {
|
|
157
206
|
header: {
|
|
@@ -174,6 +223,12 @@ export default {
|
|
|
174
223
|
config: {
|
|
175
224
|
icon: 'layers',
|
|
176
225
|
status: 'done',
|
|
226
|
+
meta: {
|
|
227
|
+
description: {
|
|
228
|
+
'en-US': 'DSubpage — Documentation of Docsector Reader',
|
|
229
|
+
'pt-BR': 'DSubpage — Documentacao do Docsector Reader'
|
|
230
|
+
}
|
|
231
|
+
},
|
|
177
232
|
type: 'manual',
|
|
178
233
|
menu: {},
|
|
179
234
|
subpages: {
|
|
@@ -190,6 +245,12 @@ export default {
|
|
|
190
245
|
config: {
|
|
191
246
|
icon: 'article',
|
|
192
247
|
status: 'done',
|
|
248
|
+
meta: {
|
|
249
|
+
description: {
|
|
250
|
+
'en-US': 'DPageSection — Documentation of Docsector Reader',
|
|
251
|
+
'pt-BR': 'DPageSection — Documentacao do Docsector Reader'
|
|
252
|
+
}
|
|
253
|
+
},
|
|
193
254
|
type: 'manual',
|
|
194
255
|
menu: {
|
|
195
256
|
separator: ' page'
|
|
@@ -211,6 +272,12 @@ export default {
|
|
|
211
272
|
config: {
|
|
212
273
|
icon: 'title',
|
|
213
274
|
status: 'done',
|
|
275
|
+
meta: {
|
|
276
|
+
description: {
|
|
277
|
+
'en-US': 'DH1 – DH6 (Headings) — Documentation of Docsector Reader',
|
|
278
|
+
'pt-BR': 'DH1 – DH6 (Títulos) — Documentacao do Docsector Reader'
|
|
279
|
+
}
|
|
280
|
+
},
|
|
214
281
|
type: 'manual',
|
|
215
282
|
menu: {},
|
|
216
283
|
subpages: {
|
|
@@ -227,6 +294,12 @@ export default {
|
|
|
227
294
|
config: {
|
|
228
295
|
icon: 'code',
|
|
229
296
|
status: 'done',
|
|
297
|
+
meta: {
|
|
298
|
+
description: {
|
|
299
|
+
'en-US': 'DPageSourceCode — Documentation of Docsector Reader',
|
|
300
|
+
'pt-BR': 'DPageSourceCode — Documentacao do Docsector Reader'
|
|
301
|
+
}
|
|
302
|
+
},
|
|
230
303
|
type: 'manual',
|
|
231
304
|
menu: {},
|
|
232
305
|
subpages: {
|
|
@@ -243,6 +316,12 @@ export default {
|
|
|
243
316
|
config: {
|
|
244
317
|
icon: 'account_tree',
|
|
245
318
|
status: 'done',
|
|
319
|
+
meta: {
|
|
320
|
+
description: {
|
|
321
|
+
'en-US': 'DMermaidDiagram — Documentation of Docsector Reader',
|
|
322
|
+
'pt-BR': 'DMermaidDiagram — Documentacao do Docsector Reader'
|
|
323
|
+
}
|
|
324
|
+
},
|
|
246
325
|
type: 'manual',
|
|
247
326
|
menu: {},
|
|
248
327
|
subpages: {
|
|
@@ -259,6 +338,12 @@ export default {
|
|
|
259
338
|
config: {
|
|
260
339
|
icon: 'format_quote',
|
|
261
340
|
status: 'done',
|
|
341
|
+
meta: {
|
|
342
|
+
description: {
|
|
343
|
+
'en-US': 'DPageBlockquote — Documentation of Docsector Reader',
|
|
344
|
+
'pt-BR': 'DPageBlockquote — Documentacao do Docsector Reader'
|
|
345
|
+
}
|
|
346
|
+
},
|
|
262
347
|
type: 'manual',
|
|
263
348
|
menu: {
|
|
264
349
|
separator: ' page'
|
|
@@ -280,6 +365,12 @@ export default {
|
|
|
280
365
|
config: {
|
|
281
366
|
icon: 'menu_open',
|
|
282
367
|
status: 'done',
|
|
368
|
+
meta: {
|
|
369
|
+
description: {
|
|
370
|
+
'en-US': 'DMenu — Documentation of Docsector Reader',
|
|
371
|
+
'pt-BR': 'DMenu — Documentacao do Docsector Reader'
|
|
372
|
+
}
|
|
373
|
+
},
|
|
283
374
|
type: 'manual',
|
|
284
375
|
menu: {},
|
|
285
376
|
subpages: {
|
|
@@ -296,6 +387,12 @@ export default {
|
|
|
296
387
|
config: {
|
|
297
388
|
icon: 'account_tree',
|
|
298
389
|
status: 'done',
|
|
390
|
+
meta: {
|
|
391
|
+
description: {
|
|
392
|
+
'en-US': 'DPageAnchor — Documentation of Docsector Reader',
|
|
393
|
+
'pt-BR': 'DPageAnchor — Documentacao do Docsector Reader'
|
|
394
|
+
}
|
|
395
|
+
},
|
|
299
396
|
type: 'manual',
|
|
300
397
|
menu: {},
|
|
301
398
|
subpages: {
|
|
@@ -312,6 +409,12 @@ export default {
|
|
|
312
409
|
config: {
|
|
313
410
|
icon: 'info',
|
|
314
411
|
status: 'done',
|
|
412
|
+
meta: {
|
|
413
|
+
description: {
|
|
414
|
+
'en-US': 'DPageMeta — Documentation of Docsector Reader',
|
|
415
|
+
'pt-BR': 'DPageMeta — Documentacao do Docsector Reader'
|
|
416
|
+
}
|
|
417
|
+
},
|
|
315
418
|
type: 'manual',
|
|
316
419
|
menu: {},
|
|
317
420
|
subpages: {
|
|
@@ -331,6 +434,12 @@ export default {
|
|
|
331
434
|
config: {
|
|
332
435
|
icon: 'zoom_in',
|
|
333
436
|
status: 'done',
|
|
437
|
+
meta: {
|
|
438
|
+
description: {
|
|
439
|
+
'en-US': 'QZoom — Documentation of Docsector Reader',
|
|
440
|
+
'pt-BR': 'QZoom — Documentacao do Docsector Reader'
|
|
441
|
+
}
|
|
442
|
+
},
|
|
334
443
|
type: 'manual',
|
|
335
444
|
menu: {
|
|
336
445
|
separator: ' page'
|
|
@@ -360,6 +469,12 @@ export default {
|
|
|
360
469
|
config: {
|
|
361
470
|
icon: 'navigation',
|
|
362
471
|
status: 'done',
|
|
472
|
+
meta: {
|
|
473
|
+
description: {
|
|
474
|
+
'en-US': 'useNavigator — Documentation of Docsector Reader',
|
|
475
|
+
'pt-BR': 'useNavigator — Documentacao do Docsector Reader'
|
|
476
|
+
}
|
|
477
|
+
},
|
|
363
478
|
type: 'manual',
|
|
364
479
|
menu: {},
|
|
365
480
|
subpages: {
|
|
@@ -387,6 +502,12 @@ export default {
|
|
|
387
502
|
config: {
|
|
388
503
|
icon: 'storage',
|
|
389
504
|
status: 'done',
|
|
505
|
+
meta: {
|
|
506
|
+
description: {
|
|
507
|
+
'en-US': 'Vuex Modules — Documentation of Docsector Reader',
|
|
508
|
+
'pt-BR': 'Módulos Vuex — Documentacao do Docsector Reader'
|
|
509
|
+
}
|
|
510
|
+
},
|
|
390
511
|
type: 'manual',
|
|
391
512
|
menu: {},
|
|
392
513
|
subpages: {
|
package/src/quasar.factory.js
CHANGED
|
@@ -156,16 +156,29 @@ function createPrerenderMetaPlugin (projectRoot) {
|
|
|
156
156
|
const brandingLogo = config.branding?.logo || ''
|
|
157
157
|
const defaultLang = config.defaultLanguage || config.languages?.[0]?.value || 'en-US'
|
|
158
158
|
|
|
159
|
+
const resolveLocalizedValue = (source) => {
|
|
160
|
+
if (!source) return ''
|
|
161
|
+
if (typeof source === 'string') return source
|
|
162
|
+
if (typeof source === 'object') {
|
|
163
|
+
return source[defaultLang] || source['*'] || source['en-US'] || Object.values(source)[0] || ''
|
|
164
|
+
}
|
|
165
|
+
return ''
|
|
166
|
+
}
|
|
167
|
+
|
|
159
168
|
let count = 0
|
|
160
169
|
|
|
161
170
|
for (const [pagePath, page] of Object.entries(pages)) {
|
|
162
171
|
if (page.config === null) continue
|
|
163
172
|
|
|
164
173
|
const type = page.config.type ?? 'manual'
|
|
165
|
-
const
|
|
174
|
+
const titleData = page.data?.[defaultLang] || page.data?.['*'] || page.data?.['en-US'] || Object.values(page.data || {})[0]
|
|
175
|
+
const title = titleData?.title || ''
|
|
166
176
|
const fullTitle = title
|
|
167
177
|
? `${title} — ${brandingName}`
|
|
168
178
|
: brandingName
|
|
179
|
+
const pageDescription = resolveLocalizedValue(page.config?.meta?.description)
|
|
180
|
+
const fullDescription = pageDescription
|
|
181
|
+
|| (title && brandingName ? `${title} — Documentation of ${brandingName}` : `Documentation of ${brandingName}`)
|
|
169
182
|
|
|
170
183
|
// Each page can have sub-routes: overview, showcase, vs
|
|
171
184
|
const subpages = ['overview']
|
|
@@ -177,10 +190,18 @@ function createPrerenderMetaPlugin (projectRoot) {
|
|
|
177
190
|
|
|
178
191
|
const html = baseHtml
|
|
179
192
|
.replace(/<title>[^<]*<\/title>/, () => `<title>${fullTitle}</title>`)
|
|
193
|
+
.replace(
|
|
194
|
+
/(<meta\s+name="?description"?\s+content=")[^"]*"/,
|
|
195
|
+
(_, p1) => `${p1}${fullDescription}"`
|
|
196
|
+
)
|
|
180
197
|
.replace(
|
|
181
198
|
/(<meta\s+property="?og:title"?\s+content=")[^"]*"/,
|
|
182
199
|
(_, p1) => `${p1}${fullTitle}"`
|
|
183
200
|
)
|
|
201
|
+
.replace(
|
|
202
|
+
/(<meta\s+property="?og:description"?\s+content=")[^"]*"/,
|
|
203
|
+
(_, p1) => `${p1}${fullDescription}"`
|
|
204
|
+
)
|
|
184
205
|
.replace(
|
|
185
206
|
/(<meta\s+property="?og:image"?\s+content=")[^"]*"/,
|
|
186
207
|
(_, p1) => `${p1}${brandingLogo}"`
|
|
@@ -189,6 +210,10 @@ function createPrerenderMetaPlugin (projectRoot) {
|
|
|
189
210
|
/(<meta\s+name="?twitter:title"?\s+content=")[^"]*"/,
|
|
190
211
|
(_, p1) => `${p1}${fullTitle}"`
|
|
191
212
|
)
|
|
213
|
+
.replace(
|
|
214
|
+
/(<meta\s+name="?twitter:description"?\s+content=")[^"]*"/,
|
|
215
|
+
(_, p1) => `${p1}${fullDescription}"`
|
|
216
|
+
)
|
|
192
217
|
.replace(
|
|
193
218
|
/(<meta\s+name="?twitter:image"?\s+content=")[^"]*"/,
|
|
194
219
|
(_, p1) => `${p1}${brandingLogo}"`
|