@docsector/docsector-reader 2.0.7 → 2.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.
Files changed (32) hide show
  1. package/README.md +19 -7
  2. package/bin/docsector.js +28 -7
  3. package/docsector.config.js +13 -1
  4. package/package.json +1 -1
  5. package/src/components/DMenu.vue +241 -12
  6. package/src/components/DMenuItem.vue +25 -2
  7. package/src/components/DPageBar.vue +35 -5
  8. package/src/components/DPageMeta.vue +40 -26
  9. package/src/i18n/helpers.js +84 -18
  10. package/src/i18n/index.js +5 -3
  11. package/src/i18n/languages/en-US.hjson +14 -0
  12. package/src/i18n/languages/pt-BR.hjson +14 -0
  13. package/src/i18n/path.js +15 -2
  14. package/src/index.js +2 -2
  15. package/src/layouts/DefaultLayout.vue +16 -2
  16. package/src/pages/.old/v0.x/guide/getting-started.overview.en-US.md +7 -0
  17. package/src/pages/.old/v0.x/guide/getting-started.overview.pt-BR.md +7 -0
  18. package/src/pages/.old/v0.x/guide.book.js +12 -0
  19. package/src/pages/.old/v0.x/guide.index.js +28 -0
  20. package/src/pages/guide/configuration.overview.en-US.md +13 -2
  21. package/src/pages/guide/configuration.overview.pt-BR.md +13 -2
  22. package/src/pages/guide/pages-and-routing.overview.en-US.md +6 -2
  23. package/src/pages/guide/pages-and-routing.overview.pt-BR.md +6 -2
  24. package/src/pages/guide.index.js +3 -1
  25. package/src/pages/manual/components/d-menu.overview.en-US.md +6 -2
  26. package/src/pages/manual/components/d-menu.overview.pt-BR.md +6 -2
  27. package/src/pages/manual/components/d-page-meta.overview.en-US.md +1 -0
  28. package/src/pages/manual/components/d-page-meta.overview.pt-BR.md +1 -0
  29. package/src/pages/manual.index.js +2 -1
  30. package/src/quasar.factory.js +648 -91
  31. package/src/router/routes.js +129 -95
  32. package/src/store/App.js +15 -5
@@ -1,4 +1,4 @@
1
- import { books } from 'virtual:docsector-books'
1
+ import { pageEntries, versions } from 'virtual:docsector-books'
2
2
  import boot from 'pages/boot'
3
3
 
4
4
  const normalizeInternalLink = (linkTo) => {
@@ -31,114 +31,148 @@ const resolveInternalLinkBasePath = (linkTo) => {
31
31
  return normalizeRoutePath(withoutSubpage || '/')
32
32
  }
33
33
 
34
- const routeConfigByPath = new Map()
35
- for (const [bookId, book] of Object.entries(books || {})) {
36
- const bookRoutes = book?.routes || {}
34
+ const versionPrefixes = (versions || [])
35
+ .map(version => normalizeRoutePath(version?.routePrefix || ''))
36
+ .filter(prefix => prefix !== '/')
37
37
 
38
- for (const [path, page] of Object.entries(bookRoutes)) {
39
- const config = page?.config
40
- if (config === null) {
41
- continue
42
- }
38
+ const linkHasVersionPrefix = (linkTo) => {
39
+ const normalized = normalizeRoutePath(linkTo)
40
+ return versionPrefixes.some(prefix => normalized === prefix || normalized.startsWith(`${prefix}/`))
41
+ }
43
42
 
44
- const topPage = config?.book ?? config?.type ?? bookId ?? 'manual'
45
- const routePath = normalizeRoutePath('/' + topPage + path)
43
+ const normalizeVersionedInternalLink = (linkTo, versionPrefix = '') => {
44
+ const normalized = normalizeInternalLink(linkTo)
45
+ const prefix = normalizeRoutePath(versionPrefix)
46
46
 
47
- routeConfigByPath.set(routePath, config || {})
47
+ if (prefix === '/' || linkHasVersionPrefix(normalized)) {
48
+ return normalized
48
49
  }
50
+
51
+ return normalizeRoutePath(`${prefix}${normalized}`)
52
+ }
53
+
54
+ const buildSourcePathBase = (entry, book, path) => {
55
+ return [entry?.sourceRoot, `${book}${path}`]
56
+ .filter(Boolean)
57
+ .map(segment => String(segment).replace(/^\/+|\/+$/g, ''))
58
+ .join('/')
59
+ }
60
+
61
+ const routeConfigByPath = new Map()
62
+ for (const entry of pageEntries || []) {
63
+ const config = entry?.page?.config
64
+ if (config === null) {
65
+ continue
66
+ }
67
+
68
+ const topPage = config?.book ?? config?.type ?? entry?.book ?? 'manual'
69
+ const routePath = normalizeRoutePath(`${entry?.versionPrefix || ''}/${topPage}${entry?.pagePath || ''}`)
70
+
71
+ routeConfigByPath.set(routePath, config || {})
49
72
  }
50
73
 
51
74
  const pagesRoutes = []
52
- for (const [bookId, book] of Object.entries(books || {})) {
53
- const bookRoutes = book?.routes || {}
54
-
55
- for (const [path, page] of Object.entries(bookRoutes)) {
56
- const rawConfig = page.config
57
- if (rawConfig === null) {
58
- continue
59
- }
60
-
61
- const config = rawConfig || {}
62
- const menu = (typeof config.menu === 'object' && config.menu !== null) ? config.menu : {}
63
- const subpages = {
64
- showcase: config?.subpages?.showcase === true,
65
- vs: config?.subpages?.vs === true
66
- }
67
-
68
- const topPage = config.book ?? config.type ?? bookId ?? 'manual'
69
- const hasInternalLink = typeof config?.link?.to === 'string' && config.link.to.trim().length > 0
70
- const internalLinkTo = hasInternalLink ? normalizeInternalLink(config.link.to) : null
71
- const linkedConfig = hasInternalLink
72
- ? routeConfigByPath.get(resolveInternalLinkBasePath(config.link.to))
73
- : null
74
- const icon = config.icon ?? linkedConfig?.icon
75
- const status = typeof config.status === 'string'
76
- ? config.status
77
- : (typeof linkedConfig?.status === 'string' ? linkedConfig.status : 'done')
78
-
79
- // @ Construct children
80
- const children = hasInternalLink
81
- ? [
82
- {
83
- path: '',
84
- redirect: () => internalLinkTo
85
- },
86
- {
87
- path: 'overview',
88
- redirect: () => internalLinkTo
89
- }
90
- ]
91
- : [
92
- {
93
- path: '',
94
- redirect: (to) => `${to.path.replace(/\/$/, '')}/overview/`
95
- },
96
- {
97
- path: 'overview',
98
- component: () => import('components/DSubpage.vue'),
99
- meta: {
100
- status
101
- }
102
- }
103
- ]
75
+ for (const entry of pageEntries || []) {
76
+ const path = entry?.pagePath || ''
77
+ const page = entry?.page || {}
78
+ const rawConfig = page.config
79
+ if (rawConfig === null) {
80
+ continue
81
+ }
104
82
 
105
- if (!hasInternalLink && subpages.showcase === true) {
106
- children.push({
107
- path: 'showcase',
108
- component: () => import('components/DSubpage.vue'),
109
- meta: {
110
- status
83
+ const config = rawConfig || {}
84
+ const menu = (typeof config.menu === 'object' && config.menu !== null) ? config.menu : {}
85
+ const subpages = {
86
+ showcase: config?.subpages?.showcase === true,
87
+ vs: config?.subpages?.vs === true
88
+ }
89
+
90
+ const topPage = config.book ?? config.type ?? entry?.book ?? 'manual'
91
+ const routePath = normalizeRoutePath(`${entry?.versionPrefix || ''}/${topPage}${path}`)
92
+ const hasInternalLink = typeof config?.link?.to === 'string' && config.link.to.trim().length > 0
93
+ const internalLinkTo = hasInternalLink ? normalizeVersionedInternalLink(config.link.to, entry?.versionPrefix || '') : null
94
+ const linkedConfig = hasInternalLink
95
+ ? routeConfigByPath.get(resolveInternalLinkBasePath(internalLinkTo))
96
+ : null
97
+ const icon = config.icon ?? linkedConfig?.icon
98
+ const status = typeof config.status === 'string'
99
+ ? config.status
100
+ : (typeof linkedConfig?.status === 'string' ? linkedConfig.status : 'done')
101
+ const pageVersion = config.version ?? config.pageVersion ?? config.since ?? null
102
+
103
+ // @ Construct children
104
+ const children = hasInternalLink
105
+ ? [
106
+ {
107
+ path: '',
108
+ redirect: () => internalLinkTo
109
+ },
110
+ {
111
+ path: 'overview',
112
+ redirect: () => internalLinkTo
111
113
  }
112
- })
113
- }
114
- if (!hasInternalLink && subpages.vs === true) {
115
- children.push({
116
- path: 'vs',
117
- component: () => import('components/DSubpage.vue'),
118
- meta: {
119
- status
114
+ ]
115
+ : [
116
+ {
117
+ path: '',
118
+ redirect: (to) => `${to.path.replace(/\/$/, '')}/overview/`
119
+ },
120
+ {
121
+ path: 'overview',
122
+ component: () => import('components/DSubpage.vue'),
123
+ meta: {
124
+ status
125
+ }
120
126
  }
121
- })
122
- }
127
+ ]
123
128
 
124
- // @ Push route to pageRoutes
125
- pagesRoutes.push({
126
- path: '/' + topPage + path,
127
- component: () => import('layouts/DefaultLayout.vue'),
129
+ if (!hasInternalLink && subpages.showcase === true) {
130
+ children.push({
131
+ path: 'showcase',
132
+ component: () => import('components/DSubpage.vue'),
128
133
  meta: {
129
- ...config,
130
- icon,
131
- status,
132
- menu,
133
- subpages,
134
- data: page.data,
135
- book: topPage,
136
- // legacy compatibility
137
- type: topPage
138
- },
139
- children
134
+ status
135
+ }
140
136
  })
141
137
  }
138
+ if (!hasInternalLink && subpages.vs === true) {
139
+ children.push({
140
+ path: 'vs',
141
+ component: () => import('components/DSubpage.vue'),
142
+ meta: {
143
+ status
144
+ }
145
+ })
146
+ }
147
+
148
+ // @ Push route to pageRoutes
149
+ pagesRoutes.push({
150
+ path: routePath,
151
+ component: () => import('layouts/DefaultLayout.vue'),
152
+ meta: {
153
+ ...config,
154
+ icon,
155
+ status,
156
+ pageVersion,
157
+ menu,
158
+ subpages,
159
+ data: page.data,
160
+ book: topPage,
161
+ // legacy compatibility
162
+ type: topPage,
163
+ version: entry.version,
164
+ versionLabel: entry.versionLabel,
165
+ versionCurrent: entry.versionCurrent,
166
+ versionPrefix: entry.versionPrefix || '',
167
+ sourceRoot: entry.sourceRoot || '',
168
+ sourcePathBase: buildSourcePathBase(entry, topPage, path),
169
+ pagePath: path,
170
+ i18nSegments: entry.i18nSegments || [topPage, ...String(path).replace(/^\//, '').split('/').filter(Boolean)],
171
+ menuGroupPath: String(path).replace(/^\//, '').split('/').filter(Boolean)[0] || '',
172
+ unversionedPath: entry.unversionedPath || `/${topPage}${path}`
173
+ },
174
+ children
175
+ })
142
176
  }
143
177
 
144
178
  const routes = [
package/src/store/App.js CHANGED
@@ -5,7 +5,7 @@ export default {
5
5
  getters: {},
6
6
  mutations: {},
7
7
  actions: {
8
- configureLanguage ({ commit, state }, routeMatched) {
8
+ configureLanguage ({ commit }, routeMatched) {
9
9
  // Reset stale nodes before configuring new language state
10
10
  commit('page/resetAnchor', null, { root: true })
11
11
  commit('page/resetAnchors', null, { root: true })
@@ -14,6 +14,7 @@ export default {
14
14
  // Route
15
15
  const firstRoutePath = routeMatched[0]?.path || ''
16
16
  const secondRoutePath = routeMatched[1]?.path || ''
17
+ const routeMeta = routeMatched[0]?.meta || {}
17
18
 
18
19
  const base = firstRoutePath === '/' ? 'home' : firstRoutePath.substr(1)
19
20
  let relative = secondRoutePath.substr(firstRoutePath.length)
@@ -31,12 +32,21 @@ export default {
31
32
  commit('page/setAbsolute', base + relative, { root: true })
32
33
 
33
34
  if (firstRoutePath) {
34
- const i18nBase = base.replace(/_$/, '').replace(/\//g, '.')
35
- const i18nRelative = relative.replace(/_$/, '').replace(/\//g, '.')
35
+ const fallbackBaseSegments = base
36
+ .replace(/_$/, '')
37
+ .split('/')
38
+ .filter(Boolean)
39
+ const i18nBase = Array.isArray(routeMeta.i18nSegments) && routeMeta.i18nSegments.length > 0
40
+ ? routeMeta.i18nSegments
41
+ : fallbackBaseSegments
42
+ const i18nRelative = relative
43
+ .replace(/_$/, '')
44
+ .split('/')
45
+ .filter(Boolean)
36
46
 
37
47
  commit('i18n/setBase', i18nBase, { root: true })
38
- commit('i18n/setRelative', i18nRelative.substr(1), { root: true })
39
- commit('i18n/setAbsolute', i18nBase + i18nRelative, { root: true })
48
+ commit('i18n/setRelative', i18nRelative, { root: true })
49
+ commit('i18n/setAbsolute', [...i18nBase, ...i18nRelative], { root: true })
40
50
  } else {
41
51
  commit('i18n/setBase', '', { root: true })
42
52
  commit('i18n/setRelative', '', { root: true })