@docsector/docsector-reader 0.1.3 → 0.2.1

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.
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Docsector Reader — Quasar Config Factory
3
+ *
4
+ * This module exports a function that generates a complete Quasar configuration
5
+ * for consumer projects that use @docsector/docsector-reader as a dependency.
6
+ *
7
+ * Usage in consumer's quasar.config.js:
8
+ *
9
+ * import { createQuasarConfig } from '@docsector/docsector-reader/quasar-factory'
10
+ * import { configure } from 'quasar/wrappers'
11
+ *
12
+ * export default configure((ctx) => {
13
+ * return createQuasarConfig({
14
+ * projectRoot: import.meta.dirname
15
+ * })
16
+ * })
17
+ *
18
+ * @param {Object} options
19
+ * @param {string} options.projectRoot - Absolute path to the consumer project root
20
+ * @param {number} [options.port=8181] - Dev server port
21
+ * @param {Object} [options.pwa] - PWA manifest overrides
22
+ * @param {Array} [options.vitePlugins] - Additional Vite plugins
23
+ * @param {Function} [options.extendViteConf] - Additional Vite config extension
24
+ */
25
+
26
+ import { readFileSync, existsSync } from 'fs'
27
+ import { resolve } from 'path'
28
+ import HJSON from 'hjson'
29
+
30
+ /**
31
+ * No-op configure wrapper.
32
+ * Quasar's `configure` from `quasar/wrappers` is a TypeScript identity function.
33
+ * We re-export it here so consumer projects don't need `quasar` in their own
34
+ * node_modules just for the config file.
35
+ */
36
+ export function configure (callback) {
37
+ return callback
38
+ }
39
+
40
+ /**
41
+ * Resolve the docsector-reader package root.
42
+ *
43
+ * In consumer mode, the package lives in node_modules/@docsector/docsector-reader.
44
+ * In standalone mode (docsector-reader running itself), the package IS the project.
45
+ *
46
+ * Note: We can't use import.meta.dirname here because Quasar's ESM config loader
47
+ * inlines imports, causing import.meta to refer to the config file's context.
48
+ */
49
+ function getPackageRoot (projectRoot) {
50
+ // Consumer mode: package installed in node_modules
51
+ const nodeModulesPath = resolve(projectRoot, 'node_modules', '@docsector', 'docsector-reader')
52
+ if (existsSync(resolve(nodeModulesPath, 'package.json'))) {
53
+ return nodeModulesPath
54
+ }
55
+
56
+ // Standalone mode: we ARE the project
57
+ return projectRoot
58
+ }
59
+
60
+ /**
61
+ * Create the HJSON Vite plugin for loading .hjson files as ES modules.
62
+ */
63
+ function createHjsonPlugin () {
64
+ return {
65
+ name: 'vite-plugin-hjson',
66
+ transform (code, id) {
67
+ if (id.endsWith('.hjson')) {
68
+ const parsed = HJSON.parse(readFileSync(id, 'utf-8'))
69
+ return {
70
+ code: `export default ${JSON.stringify(parsed, null, 2)};`,
71
+ map: null
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Create a complete Quasar configuration for a docsector-reader consumer project.
80
+ *
81
+ * In **standalone** mode (docsector-reader running itself), all paths resolve
82
+ * naturally via Quasar defaults — no alias overrides needed.
83
+ *
84
+ * In **consumer** mode (installed as a dependency), Vite aliases redirect
85
+ * engine internals (components, layouts, composables, boot) to the package
86
+ * while content paths (pages, src/i18n) stay in the consumer project.
87
+ *
88
+ * Boot file resolution trick:
89
+ * - boot/store, boot/QZoom, boot/axios → package (relative imports: ../store/, ../components/)
90
+ * - boot/i18n → package file, BUT it imports 'src/i18n' which Quasar aliases to consumer's src/
91
+ *
92
+ * @param {Object} options - Configuration options
93
+ * @param {string} options.projectRoot - Absolute path to the consumer project root
94
+ * @param {number} [options.port=8181] - Dev server port
95
+ * @param {Object} [options.pwa] - PWA manifest overrides (merged with defaults)
96
+ * @param {Array} [options.vitePlugins=[]] - Additional Vite plugins to include
97
+ * @param {Array} [options.boot=[]] - Additional boot files to include
98
+ * @param {Function} [options.extendViteConf] - Additional Vite configuration callback
99
+ * @returns {Object} Complete Quasar configuration object
100
+ */
101
+ export function createQuasarConfig (options = {}) {
102
+ const {
103
+ projectRoot = process.cwd(),
104
+ port = 8181,
105
+ pwa = {},
106
+ vitePlugins = [],
107
+ boot: extraBoot = [],
108
+ extendViteConf: userExtendViteConf
109
+ } = options
110
+
111
+ const packageRoot = getPackageRoot(projectRoot)
112
+ const isStandalone = projectRoot === packageRoot
113
+
114
+ return {
115
+ // Boot files — Quasar resolves these via 'boot/<name>' imports.
116
+ // Since the 'boot' alias points to packageRoot/src/boot/ in consumer mode,
117
+ // consumer-specific boot files are resolved via per-file Vite aliases
118
+ // added in extendViteConf below.
119
+ boot: [
120
+ 'store',
121
+ 'QZoom',
122
+ 'i18n',
123
+ 'axios',
124
+ ...extraBoot
125
+ ],
126
+
127
+ // CSS — Quasar resolves from src/css/
128
+ css: [
129
+ 'app.sass'
130
+ ],
131
+
132
+ extras: [
133
+ 'fontawesome-v5',
134
+ 'roboto-font',
135
+ 'material-icons'
136
+ ],
137
+
138
+ build: {
139
+ target: {
140
+ browser: ['es2022', 'firefox115', 'chrome115', 'safari14'],
141
+ node: 'node20'
142
+ },
143
+
144
+ vueRouterMode: 'history',
145
+
146
+ vitePlugins: [
147
+ createHjsonPlugin(),
148
+ ...vitePlugins
149
+ ],
150
+
151
+ extendViteConf (viteConf) {
152
+ viteConf.resolve = viteConf.resolve || {}
153
+ viteConf.resolve.alias = viteConf.resolve.alias || {}
154
+
155
+ if (!isStandalone) {
156
+ // --- Consumer project mode ---
157
+ // Allow Vite to serve files from the package root (needed for symlinked/npm-linked packages)
158
+ viteConf.server = viteConf.server || {}
159
+ viteConf.server.fs = viteConf.server.fs || {}
160
+ viteConf.server.fs.allow = viteConf.server.fs.allow || []
161
+ viteConf.server.fs.allow.push(packageRoot, projectRoot)
162
+ viteConf.server.fs.strict = false
163
+
164
+ // Consumer boot files — per-file aliases must come BEFORE the general
165
+ // 'boot' alias in the object, otherwise Vite matches 'boot' first.
166
+ // We delete the pre-existing 'boot' alias (set by Quasar), add specific
167
+ // entries, then re-add the general 'boot' alias after them.
168
+ delete viteConf.resolve.alias.boot
169
+ for (const bootName of extraBoot) {
170
+ if (typeof bootName === 'string') {
171
+ viteConf.resolve.alias[`boot/${bootName}`] = resolve(projectRoot, 'src/boot', bootName)
172
+ }
173
+ }
174
+
175
+ // Engine internals from the package (components, layouts, composables, boot, css):
176
+ viteConf.resolve.alias.components = resolve(packageRoot, 'src/components')
177
+ viteConf.resolve.alias.layouts = resolve(packageRoot, 'src/layouts')
178
+ viteConf.resolve.alias.composables = resolve(packageRoot, 'src/composables')
179
+ viteConf.resolve.alias.boot = resolve(packageRoot, 'src/boot')
180
+ viteConf.resolve.alias.css = resolve(packageRoot, 'src/css')
181
+ viteConf.resolve.alias.stores = resolve(packageRoot, 'src/store')
182
+
183
+ // Content from the consumer project:
184
+ viteConf.resolve.alias.pages = resolve(projectRoot, 'src/pages')
185
+ }
186
+
187
+ // Tags for menu search — consumer's tags if available, else package's
188
+ const consumerTags = resolve(projectRoot, 'src/i18n/tags.hjson')
189
+ const packageTags = resolve(packageRoot, 'src/i18n/tags.hjson')
190
+ viteConf.resolve.alias['@docsector/tags'] = existsSync(consumerTags) ? consumerTags : packageTags
191
+
192
+ // docsector.config.js — always from consumer/project root
193
+ viteConf.resolve.alias['docsector.config.js'] = resolve(projectRoot, 'docsector.config.js')
194
+
195
+ // Allow consumer to extend further
196
+ if (typeof userExtendViteConf === 'function') {
197
+ userExtendViteConf(viteConf)
198
+ }
199
+ }
200
+ },
201
+
202
+ // Source files — point App.vue, router, store to the package in consumer mode
203
+ // Quasar prepends 'app/' to these, so use paths relative to projectRoot
204
+ sourceFiles: isStandalone
205
+ ? {}
206
+ : {
207
+ rootComponent: 'node_modules/@docsector/docsector-reader/src/App.vue',
208
+ router: 'node_modules/@docsector/docsector-reader/src/router/index'
209
+ },
210
+
211
+ devServer: {
212
+ port,
213
+ open: false
214
+ },
215
+
216
+ framework: {
217
+ config: {},
218
+ lang: 'en-US',
219
+ plugins: [
220
+ 'LocalStorage', 'SessionStorage'
221
+ ]
222
+ },
223
+
224
+ animations: ['zoomIn', 'zoomOut'],
225
+
226
+ pwa: {
227
+ workboxMode: 'GenerateSW',
228
+ manifest: {
229
+ name: 'Documentation',
230
+ short_name: 'Docs',
231
+ description: 'Documentation powered by Docsector Reader.',
232
+ display: 'standalone',
233
+ orientation: 'portrait',
234
+ background_color: '#ffffff',
235
+ theme_color: '#655529',
236
+ icons: [
237
+ { src: 'icons/icon-128x128.png', sizes: '128x128', type: 'image/png' },
238
+ { src: 'icons/icon-192x192.png', sizes: '192x192', type: 'image/png' },
239
+ { src: 'icons/icon-256x256.png', sizes: '256x256', type: 'image/png' },
240
+ { src: 'icons/icon-384x384.png', sizes: '384x384', type: 'image/png' },
241
+ { src: 'icons/icon-512x512.png', sizes: '512x512', type: 'image/png' }
242
+ ],
243
+ ...pwa
244
+ }
245
+ }
246
+ }
247
+ }
248
+
249
+ export default createQuasarConfig
@@ -1,43 +0,0 @@
1
- $box-shadow ?= 1px 1px 7px 1px rgba(0,0,0,.2)
2
-
3
- .q-zoom
4
- position relative
5
- padding 0
6
- margin 0
7
-
8
- &__zoom-in
9
- cursor zoom-in
10
-
11
- &__zoom-out
12
- cursor zoom-out
13
-
14
- &__overlay
15
- position fixed
16
- transition all .5s linear
17
- left 0
18
- top 0
19
- width 100%
20
- height 100%
21
- background-color transparent
22
- padding 0
23
- margin 0
24
- z-index 6000
25
-
26
- &__content
27
- position relative
28
- display block
29
- transition all .5s cubic-bezier(.2,0,.2,1)
30
- text-align center
31
- vertical-align middle
32
- width 100%
33
- height 0
34
- max-width 100%
35
- max-height 100%
36
- overflow hidden
37
-
38
- &__no-center
39
- text-align unset
40
- vertical-align unset
41
-
42
- &__no-scroll
43
- overflow: hidden;