@life-and-dev/mdsite 0.0.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/README.md +228 -0
- package/bin/mdsite.js +3 -0
- package/dist/commands/commands.test.d.ts +1 -0
- package/dist/commands/commands.test.js +302 -0
- package/dist/commands/commands.test.js.map +1 -0
- package/dist/commands/generate.d.ts +1 -0
- package/dist/commands/generate.js +20 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +16 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/prepare.d.ts +1 -0
- package/dist/commands/prepare.js +111 -0
- package/dist/commands/prepare.js.map +1 -0
- package/dist/commands/prepare.test.d.ts +1 -0
- package/dist/commands/prepare.test.js +131 -0
- package/dist/commands/prepare.test.js.map +1 -0
- package/dist/commands/preview.d.ts +5 -0
- package/dist/commands/preview.js +62 -0
- package/dist/commands/preview.js.map +1 -0
- package/dist/commands/start.d.ts +5 -0
- package/dist/commands/start.js +50 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/stop.d.ts +1 -0
- package/dist/commands/stop.js +26 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/workflows.test.d.ts +1 -0
- package/dist/commands/workflows.test.js +183 -0
- package/dist/commands/workflows.test.js.map +1 -0
- package/dist/config/default-mdsite-config.d.ts +2 -0
- package/dist/config/default-mdsite-config.js +82 -0
- package/dist/config/default-mdsite-config.js.map +1 -0
- package/dist/config/default-mdsite-config.test.d.ts +1 -0
- package/dist/config/default-mdsite-config.test.js +42 -0
- package/dist/config/default-mdsite-config.test.js.map +1 -0
- package/dist/config/mdsite-config.d.ts +42 -0
- package/dist/config/mdsite-config.js +74 -0
- package/dist/config/mdsite-config.js.map +1 -0
- package/dist/config/mdsite-config.test.d.ts +1 -0
- package/dist/config/mdsite-config.test.js +115 -0
- package/dist/config/mdsite-config.test.js.map +1 -0
- package/dist/config/menu.d.ts +3 -0
- package/dist/config/menu.js +58 -0
- package/dist/config/menu.js.map +1 -0
- package/dist/config/menu.test.d.ts +1 -0
- package/dist/config/menu.test.js +53 -0
- package/dist/config/menu.test.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +99 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +1 -0
- package/dist/index.test.js +133 -0
- package/dist/index.test.js.map +1 -0
- package/dist/process/child-process.d.ts +9 -0
- package/dist/process/child-process.js +142 -0
- package/dist/process/child-process.js.map +1 -0
- package/dist/process/child-process.test.d.ts +1 -0
- package/dist/process/child-process.test.js +131 -0
- package/dist/process/child-process.test.js.map +1 -0
- package/dist/process/runtime-state.d.ts +16 -0
- package/dist/process/runtime-state.js +42 -0
- package/dist/process/runtime-state.js.map +1 -0
- package/dist/process/runtime-state.test.d.ts +1 -0
- package/dist/process/runtime-state.test.js +57 -0
- package/dist/process/runtime-state.test.js.map +1 -0
- package/dist/renderer/mdsite-nuxt.d.ts +22 -0
- package/dist/renderer/mdsite-nuxt.js +194 -0
- package/dist/renderer/mdsite-nuxt.js.map +1 -0
- package/dist/renderer/mdsite-nuxt.test.d.ts +1 -0
- package/dist/renderer/mdsite-nuxt.test.js +226 -0
- package/dist/renderer/mdsite-nuxt.test.js.map +1 -0
- package/mdsite-nuxt/app/app.vue +7 -0
- package/mdsite-nuxt/app/assets/css/bible-tooltips.css +87 -0
- package/mdsite-nuxt/app/assets/css/markdown.css +195 -0
- package/mdsite-nuxt/app/assets/css/print.css +133 -0
- package/mdsite-nuxt/app/components/AppBar.vue +138 -0
- package/mdsite-nuxt/app/components/AppFooter.vue +88 -0
- package/mdsite-nuxt/app/components/AppNavigation.vue +162 -0
- package/mdsite-nuxt/app/components/AppTableOfContents.vue +149 -0
- package/mdsite-nuxt/app/components/BreadcrumbNav.vue +139 -0
- package/mdsite-nuxt/app/components/NavigationTree.vue +169 -0
- package/mdsite-nuxt/app/components/SearchBox.vue +212 -0
- package/mdsite-nuxt/app/components/TocItem.vue +75 -0
- package/mdsite-nuxt/app/components/TreeNode.vue +264 -0
- package/mdsite-nuxt/app/components/content/MarkdownAlert.vue +42 -0
- package/mdsite-nuxt/app/components/content/Mermaid.vue +103 -0
- package/mdsite-nuxt/app/components/content/ProseA.vue +57 -0
- package/mdsite-nuxt/app/components/content/ProseBlockquote.vue +14 -0
- package/mdsite-nuxt/app/components/content/ProsePre.vue +49 -0
- package/mdsite-nuxt/app/components/content/ProseTable.vue +143 -0
- package/mdsite-nuxt/app/composables/useAppTheme.ts +89 -0
- package/mdsite-nuxt/app/composables/useBibleTooltips.ts +21 -0
- package/mdsite-nuxt/app/composables/useBreadcrumbs.ts +70 -0
- package/mdsite-nuxt/app/composables/useContentPostProcessing.ts +89 -0
- package/mdsite-nuxt/app/composables/useNavigationTree.ts +174 -0
- package/mdsite-nuxt/app/composables/useSearchIndex.ts +47 -0
- package/mdsite-nuxt/app/composables/useSearchRelevance.test.ts +255 -0
- package/mdsite-nuxt/app/composables/useSearchRelevance.ts +207 -0
- package/mdsite-nuxt/app/composables/useSidebarState.ts +62 -0
- package/mdsite-nuxt/app/composables/useSiteConfig.ts +37 -0
- package/mdsite-nuxt/app/composables/useSourceEdit.ts +69 -0
- package/mdsite-nuxt/app/composables/useTableOfContents.ts +141 -0
- package/mdsite-nuxt/app/composables/useTableParser.ts +106 -0
- package/mdsite-nuxt/app/composables/useTooltipConfig.ts +20 -0
- package/mdsite-nuxt/app/config/themes.ts +17 -0
- package/mdsite-nuxt/app/layouts/default.vue +376 -0
- package/mdsite-nuxt/app/pages/[...slug].vue +56 -0
- package/mdsite-nuxt/app/pages/index.vue +54 -0
- package/mdsite-nuxt/app/plugins/bible-tooltips.client.ts +401 -0
- package/mdsite-nuxt/app/plugins/bible-tooltips.test.ts +284 -0
- package/mdsite-nuxt/app/types/content.d.ts +10 -0
- package/mdsite-nuxt/app/types/table.ts +57 -0
- package/mdsite-nuxt/app/utils/bible-book-names.ts +37 -0
- package/mdsite-nuxt/app/utils/bible-verse-utils.test.ts +148 -0
- package/mdsite-nuxt/app/utils/bible-verse-utils.ts +236 -0
- package/mdsite-nuxt/content.config.ts +18 -0
- package/mdsite-nuxt/example.config.yml +67 -0
- package/mdsite-nuxt/nuxt.config.ts +247 -0
- package/mdsite-nuxt/package-lock.json +15922 -0
- package/mdsite-nuxt/package.json +50 -0
- package/mdsite-nuxt/playwright.config.js +47 -0
- package/mdsite-nuxt/public/robots.txt +2 -0
- package/mdsite-nuxt/scripts/generate-favicons.ts +192 -0
- package/mdsite-nuxt/scripts/generate-indices.ts +508 -0
- package/mdsite-nuxt/scripts/renderer-hooks.test.ts +277 -0
- package/mdsite-nuxt/scripts/renderer-hooks.ts +141 -0
- package/mdsite-nuxt/scripts/start.test.ts +164 -0
- package/mdsite-nuxt/scripts/start.ts +55 -0
- package/mdsite-nuxt/scripts/sync-content.ts +504 -0
- package/mdsite-nuxt/tsconfig.json +18 -0
- package/mdsite-nuxt/utils/mdsite-config.ts +240 -0
- package/mdsite-nuxt/vitest.config.ts +7 -0
- package/package.json +36 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mdsite-nuxt-renderer",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"private": true,
|
|
6
|
+
"description": "Nuxt-based renderer for MD-Site CLI utility",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsx scripts/start.ts --build",
|
|
9
|
+
"build:renderer": "npm run build",
|
|
10
|
+
"dev": "tsx scripts/start.ts",
|
|
11
|
+
"dev:cached": "tsx scripts/start.ts --cached",
|
|
12
|
+
"favicon": "tsx scripts/generate-favicons.ts",
|
|
13
|
+
"generate-favicons": "npm run favicon",
|
|
14
|
+
"generate-indices": "tsx scripts/generate-indices.ts",
|
|
15
|
+
"generate": "tsx scripts/start.ts --generate",
|
|
16
|
+
"postinstall": "npm run prepare:nuxt",
|
|
17
|
+
"prepare:nuxt": "nuxt prepare",
|
|
18
|
+
"prepare:renderer": "tsx scripts/start.ts --prepare",
|
|
19
|
+
"preview": "tsx scripts/start.ts --preview",
|
|
20
|
+
"setup": "npm run prepare:renderer",
|
|
21
|
+
"sync-content": "tsx scripts/sync-content.ts --sync",
|
|
22
|
+
"start": "tsx scripts/start.ts",
|
|
23
|
+
"test": "vitest"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@nuxt/content": "^3.8.0",
|
|
27
|
+
"@types/node": "^24.10.0",
|
|
28
|
+
"better-sqlite3": "^12.4.1",
|
|
29
|
+
"fs-extra": "^11.3.2",
|
|
30
|
+
"gray-matter": "^4.0.3",
|
|
31
|
+
"mermaid": "^11.12.2",
|
|
32
|
+
"nuxt": "^4.2.1",
|
|
33
|
+
"typescript": "^5.9.3",
|
|
34
|
+
"vue": "^3.5.24",
|
|
35
|
+
"vue-router": "^4.6.3",
|
|
36
|
+
"vue-tsc": "^3.1.3",
|
|
37
|
+
"vuetify-nuxt-module": "^0.19.2",
|
|
38
|
+
"yaml": "^2.8.1"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@playwright/test": "^1.56.1",
|
|
42
|
+
"@types/fs-extra": "^11.0.4",
|
|
43
|
+
"@vitest/ui": "^4.0.8",
|
|
44
|
+
"playwright": "^1.56.1",
|
|
45
|
+
"remark-github-blockquote-alert": "^2.0.1",
|
|
46
|
+
"sharp": "^0.34.5",
|
|
47
|
+
"tsx": "^4.20.6",
|
|
48
|
+
"vitest": "^4.0.8"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
testDir: './tests/e2e',
|
|
5
|
+
fullyParallel: false,
|
|
6
|
+
forbidOnly: false,
|
|
7
|
+
retries: 0,
|
|
8
|
+
workers: 1,
|
|
9
|
+
reporter: 'html',
|
|
10
|
+
use: {
|
|
11
|
+
baseURL: 'http://localhost:3000',
|
|
12
|
+
trace: 'on-first-retry',
|
|
13
|
+
screenshot: 'only-on-failure',
|
|
14
|
+
video: 'retain-on-failure',
|
|
15
|
+
// Set reasonable timeout for page actions
|
|
16
|
+
actionTimeout: 10000,
|
|
17
|
+
navigationTimeout: 30000,
|
|
18
|
+
},
|
|
19
|
+
timeout: 60000, // Set default timeout to 60 seconds for all tests
|
|
20
|
+
|
|
21
|
+
projects: [
|
|
22
|
+
{
|
|
23
|
+
name: 'chromium',
|
|
24
|
+
use: {
|
|
25
|
+
...devices['Desktop Chrome'],
|
|
26
|
+
viewport: { width: 1366, height: 768 }, // Typical budget laptop resolution
|
|
27
|
+
launchOptions: {
|
|
28
|
+
args: [
|
|
29
|
+
'--no-sandbox',
|
|
30
|
+
'--disable-setuid-sandbox',
|
|
31
|
+
'--disable-dev-shm-usage',
|
|
32
|
+
'--disable-gpu',
|
|
33
|
+
'--disable-web-security',
|
|
34
|
+
'--disable-features=VizDisplayCompositor'
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
|
|
41
|
+
webServer: {
|
|
42
|
+
command: 'npm run dev',
|
|
43
|
+
url: 'http://localhost:3000',
|
|
44
|
+
reuseExistingServer: true,
|
|
45
|
+
timeout: 30000,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import sharp from 'sharp'
|
|
4
|
+
import fs from 'fs-extra'
|
|
5
|
+
import path from 'path'
|
|
6
|
+
import { fileURLToPath } from 'url'
|
|
7
|
+
import { loadMdsiteConfigSync, resolveMdsiteConfigPath } from '../utils/mdsite-config.js'
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
10
|
+
const __dirname = path.dirname(__filename)
|
|
11
|
+
|
|
12
|
+
const FAVICON_SIZES = {
|
|
13
|
+
ico: [16, 32],
|
|
14
|
+
appleTouchIcon: 180,
|
|
15
|
+
pwaIcon192: 192,
|
|
16
|
+
pwaIcon512: 512
|
|
17
|
+
} as const
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Generate favicons from the active mdsite config
|
|
21
|
+
*/
|
|
22
|
+
export async function generateFavicons() {
|
|
23
|
+
const { contentDir, config } = loadMdsiteConfigSync()
|
|
24
|
+
const logoPath = path.join(contentDir, 'logo.svg')
|
|
25
|
+
const faviconDir = path.join(contentDir, 'favicon')
|
|
26
|
+
|
|
27
|
+
// Check if logo exists
|
|
28
|
+
if (!await fs.pathExists(logoPath)) {
|
|
29
|
+
console.error(`❌ Logo not found: ${logoPath}`)
|
|
30
|
+
return false
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
await fs.ensureDir(faviconDir)
|
|
34
|
+
|
|
35
|
+
console.log(`🎨 Generating favicons for site: ${config.site.name}`)
|
|
36
|
+
console.log(` Source: ${logoPath}`)
|
|
37
|
+
console.log(` Output: ${faviconDir}`)
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
// Copy SVG as-is (for modern browsers)
|
|
41
|
+
const svgTargetPath = path.join(faviconDir, 'favicon.svg')
|
|
42
|
+
await fs.copy(logoPath, svgTargetPath)
|
|
43
|
+
console.log(` ✓ SVG: favicon.svg`)
|
|
44
|
+
|
|
45
|
+
// Generate ICO (32x32 with transparent padding)
|
|
46
|
+
const icoTargetPath = path.join(faviconDir, 'favicon.ico')
|
|
47
|
+
const png32Buffer = await sharp(logoPath)
|
|
48
|
+
.resize(32, 32, {
|
|
49
|
+
fit: 'contain',
|
|
50
|
+
background: { r: 255, g: 255, b: 255, alpha: 0 }
|
|
51
|
+
})
|
|
52
|
+
.png()
|
|
53
|
+
.toBuffer()
|
|
54
|
+
|
|
55
|
+
await fs.writeFile(icoTargetPath, png32Buffer)
|
|
56
|
+
console.log(` ✓ ICO: favicon.ico`)
|
|
57
|
+
|
|
58
|
+
// Generate Apple Touch Icon (180x180 with transparent padding)
|
|
59
|
+
const appleTouchPath = path.join(faviconDir, 'apple-touch-icon.png')
|
|
60
|
+
await sharp(logoPath)
|
|
61
|
+
.resize(FAVICON_SIZES.appleTouchIcon, FAVICON_SIZES.appleTouchIcon, {
|
|
62
|
+
fit: 'contain',
|
|
63
|
+
background: { r: 255, g: 255, b: 255, alpha: 0 }
|
|
64
|
+
})
|
|
65
|
+
.png()
|
|
66
|
+
.toFile(appleTouchPath)
|
|
67
|
+
console.log(` ✓ Apple Touch Icon: apple-touch-icon.png`)
|
|
68
|
+
|
|
69
|
+
// Generate PWA Icon 192x192
|
|
70
|
+
const icon192Path = path.join(faviconDir, 'icon-192.png')
|
|
71
|
+
await sharp(logoPath)
|
|
72
|
+
.resize(FAVICON_SIZES.pwaIcon192, FAVICON_SIZES.pwaIcon192, {
|
|
73
|
+
fit: 'contain',
|
|
74
|
+
background: { r: 255, g: 255, b: 255, alpha: 0 }
|
|
75
|
+
})
|
|
76
|
+
.png()
|
|
77
|
+
.toFile(icon192Path)
|
|
78
|
+
console.log(` ✓ PWA Icon 192: icon-192.png`)
|
|
79
|
+
|
|
80
|
+
// Generate PWA Icon 512x512
|
|
81
|
+
const icon512Path = path.join(faviconDir, 'icon-512.png')
|
|
82
|
+
await sharp(logoPath)
|
|
83
|
+
.resize(FAVICON_SIZES.pwaIcon512, FAVICON_SIZES.pwaIcon512, {
|
|
84
|
+
fit: 'contain',
|
|
85
|
+
background: { r: 255, g: 255, b: 255, alpha: 0 }
|
|
86
|
+
})
|
|
87
|
+
.png()
|
|
88
|
+
.toFile(icon512Path)
|
|
89
|
+
console.log(` ✓ PWA Icon 512: icon-512.png`)
|
|
90
|
+
|
|
91
|
+
console.log(`✅ Favicons generated successfully for ${config.site.name}\n`)
|
|
92
|
+
return true
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error(`❌ Failed to generate favicons for ${config.site.name}:`, error)
|
|
95
|
+
return false
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Copy favicon files from content submodule to public directory
|
|
101
|
+
*/
|
|
102
|
+
export async function copyFaviconsToPublic() {
|
|
103
|
+
const projectRoot = path.resolve(__dirname, '..')
|
|
104
|
+
const { contentDir, config } = loadMdsiteConfigSync()
|
|
105
|
+
const faviconDir = path.join(contentDir, 'favicon')
|
|
106
|
+
const publicDir = path.join(projectRoot, 'public')
|
|
107
|
+
|
|
108
|
+
console.log(`📋 Copying ${config.site.name} favicons to public...`)
|
|
109
|
+
|
|
110
|
+
const files = [
|
|
111
|
+
'favicon.svg',
|
|
112
|
+
'favicon.ico',
|
|
113
|
+
'apple-touch-icon.png',
|
|
114
|
+
'icon-192.png',
|
|
115
|
+
'icon-512.png'
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
for (const file of files) {
|
|
119
|
+
const sourcePath = path.join(faviconDir, file)
|
|
120
|
+
const targetPath = path.join(publicDir, file)
|
|
121
|
+
|
|
122
|
+
if (await fs.pathExists(sourcePath)) {
|
|
123
|
+
await fs.copy(sourcePath, targetPath)
|
|
124
|
+
console.log(` ✓ ${file}`)
|
|
125
|
+
} else {
|
|
126
|
+
console.warn(` ⚠ Missing: ${file}`)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
console.log(`✅ Favicon copy complete\n`)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Generate web manifest for PWA support
|
|
135
|
+
*/
|
|
136
|
+
export async function generateWebManifest(name: string) {
|
|
137
|
+
const projectRoot = path.resolve(__dirname, '..')
|
|
138
|
+
const publicDir = path.join(projectRoot, 'public')
|
|
139
|
+
const manifestPath = path.join(publicDir, 'site.webmanifest')
|
|
140
|
+
|
|
141
|
+
const manifest = {
|
|
142
|
+
name: name,
|
|
143
|
+
short_name: name,
|
|
144
|
+
icons: [
|
|
145
|
+
{
|
|
146
|
+
src: '/icon-192.png',
|
|
147
|
+
sizes: '192x192',
|
|
148
|
+
type: 'image/png'
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
src: '/icon-512.png',
|
|
152
|
+
sizes: '512x512',
|
|
153
|
+
type: 'image/png'
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
theme_color: '#ffffff',
|
|
157
|
+
background_color: '#ffffff',
|
|
158
|
+
display: 'standalone'
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
await fs.writeJson(manifestPath, manifest, { spaces: 2 })
|
|
162
|
+
console.log(`📱 Web manifest generated: site.webmanifest\n`)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* CLI execution
|
|
167
|
+
*/
|
|
168
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
169
|
+
const args = process.argv.slice(2)
|
|
170
|
+
const configArg = args.find(arg => /\.ya?ml$/i.test(arg))
|
|
171
|
+
const configPath = resolveMdsiteConfigPath({ configPath: configArg, contentPath: process.env.NUXT_CONTENT_PATH })
|
|
172
|
+
|
|
173
|
+
if (!configPath) {
|
|
174
|
+
console.error('❌ No mdsite.yml configuration found. Set MDSITE_CONFIG_PATH or pass a mdsite.yml path.')
|
|
175
|
+
process.exit(1)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const { config, contentDir } = loadMdsiteConfigSync({ configPath, contentPath: process.env.NUXT_CONTENT_PATH })
|
|
179
|
+
process.env.MDSITE_CONFIG_PATH = configPath
|
|
180
|
+
process.env.NUXT_CONTENT_PATH = contentDir
|
|
181
|
+
process.env.CONTENT_DIR = contentDir
|
|
182
|
+
|
|
183
|
+
; (async () => {
|
|
184
|
+
const success = await generateFavicons()
|
|
185
|
+
if (success) {
|
|
186
|
+
await copyFaviconsToPublic()
|
|
187
|
+
await generateWebManifest(config.site.name)
|
|
188
|
+
} else {
|
|
189
|
+
process.exit(1)
|
|
190
|
+
}
|
|
191
|
+
})()
|
|
192
|
+
}
|