@docsector/docsector-reader 0.5.1 → 0.5.3

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 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.1'
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.1',
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.1",
3
+ "version": "0.5.3",
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",
@@ -26,7 +26,8 @@ async function render () {
26
26
 
27
27
  mermaid.initialize({
28
28
  startOnLoad: false,
29
- theme: $q.dark.isActive ? 'dark' : 'default'
29
+ theme: $q.dark.isActive ? 'dark' : 'default',
30
+ fontSize: 20
30
31
  })
31
32
 
32
33
  const decoded = props.content
@@ -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
- if (data) {
69
- const langData = data[locale.value] || data['en-US'] || Object.values(data)[0]
70
- return langData?.title || ''
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
  }
@@ -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: {
@@ -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 title = page.data?.[defaultLang]?.title || ''
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}"`