Initial commit

This commit is contained in:
juergen committed 2026-11-13 11:50:48 +01:00
commit 2683eae6b3
36 files changed
+7369

No files matched your search

+264
View File
@@ -0,0 +1,264 @@
import { createServer } from 'node:http'
const logo = `<svg xmlns="http://www.w3.org/2000/svg" width="120" height="40" viewBox="0 0 120 40">
<rect width="120" height="40" rx="6" fill="#0b63b6"/>
<text x="60" y="26" text-anchor="middle" font-family="Arial" font-size="16" fill="white">WIKI</text>
</svg>`
const pages = [
{
id: 1,
path: 'docs',
locale: 'en',
title: 'Documentation',
description: 'Documentation root',
contentType: 'markdown',
isPublished: true,
updatedAt: '2026-01-02T10:00:00.000Z',
render: `
<h1 id="welcome">Documentation</h1>
<p>Start with <a href="/en/docs/install">Install</a>. The Linux details are in
<a href="/en/docs/install/linux#requirements">Linux requirements</a>.</p>
<p><a href="#welcome">Jump to welcome</a></p>
<p><a href="https://example.com/docs">External docs</a></p>
<p><a href="/en/guide">Outside guide</a></p>
<p><a href="/en/docs-other">Excluded sibling</a></p>
<img src="/assets/logo.svg" alt="Wiki logo">
<script>window.evil = true</script>
<iframe src="https://example.com/embed"></iframe>
<p>DOCS_MARKER</p>
`,
},
{
id: 2,
path: 'docs/install',
locale: 'en',
title: 'Installation',
description: 'Install guide',
contentType: 'markdown',
isPublished: true,
updatedAt: '2026-01-03T10:00:00.000Z',
render: `
<h1 id="install">Installation</h1>
<p>Back to <a href="/en/docs">Documentation</a>.</p>
<p>Choose <a href="/en/docs/install/linux">Linux</a>.</p>
<p>INSTALL_MARKER</p>
`,
},
{
id: 3,
path: 'docs/install/linux',
locale: 'en',
title: 'Linux requirements',
description: 'Linux install',
contentType: 'markdown',
isPublished: true,
updatedAt: '2026-01-04T10:00:00.000Z',
render: `
<h1 id="linux">Linux</h1>
<h2 id="requirements">Requirements</h2>
<ul><li>Node.js 22</li><li>PostgreSQL</li></ul>
<p><a href="/en/docs/install">Back to installation</a></p>
<p>LINUX_MARKER</p>
`,
},
{
id: 4,
path: 'docs/other',
locale: 'en',
title: 'Other notes',
description: 'Other notes',
contentType: 'markdown',
isPublished: true,
updatedAt: '2026-01-05T10:00:00.000Z',
render: `<h1>Other notes</h1><p>OTHER_MARKER</p>`,
},
{
id: 5,
path: 'docs/fallback',
locale: 'en',
title: 'Fallback Markdown',
description: 'Rendered from source',
contentType: 'markdown',
isPublished: true,
updatedAt: '2026-01-06T10:00:00.000Z',
render: null,
content: `# Fallback Markdown
This page is rendered from its markdown source. See [Installation](install).
FALLBACK_MARKER
`,
},
{
id: 6,
path: 'docs/draft',
locale: 'en',
title: 'Draft page',
description: 'Unpublished',
contentType: 'markdown',
isPublished: false,
updatedAt: '2026-01-07T10:00:00.000Z',
render: `<h1>Draft page</h1><p>DRAFT_MARKER</p>`,
},
{
id: 7,
path: 'docs-other',
locale: 'en',
title: 'Excluded sibling',
description: 'Not below docs',
contentType: 'markdown',
isPublished: true,
updatedAt: '2026-01-08T10:00:00.000Z',
render: `<h1>Excluded sibling</h1><p>EXCLUDED_SIBLING_MARKER</p>`,
},
{
id: 8,
path: 'guide',
locale: 'en',
title: 'Outside guide page',
description: 'Outside the subtree',
contentType: 'markdown',
isPublished: true,
updatedAt: '2026-01-09T10:00:00.000Z',
render: `<h1>Outside guide page</h1><p>GUIDE_OUTSIDE_MARKER</p>`,
},
]
function pageListItem(page) {
return {
id: page.id,
path: page.path,
locale: page.locale,
title: page.title,
description: page.description,
contentType: page.contentType,
isPublished: page.isPublished,
updatedAt: page.updatedAt,
}
}
function sendJson(response, status, payload) {
const body = JSON.stringify(payload)
response.writeHead(status, {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body),
})
response.end(body)
}
export async function startMockWiki() {
const state = { assetHits: 0, graphqlHits: 0 }
const server = createServer((request, response) => {
const url = new URL(request.url, 'http://127.0.0.1')
if (url.pathname === '/assets/logo.svg') {
state.assetHits += 1
response.writeHead(200, { 'Content-Type': 'image/svg+xml' })
response.end(logo)
return
}
if (url.pathname !== '/graphql' || request.method !== 'POST') {
response.writeHead(404, { 'Content-Type': 'text/plain' })
response.end('not found')
return
}
if (request.headers.authorization !== 'Bearer test-key') {
sendJson(response, 401, { error: 'unauthorized' })
return
}
state.graphqlHits += 1
let raw = ''
request.setEncoding('utf8')
request.on('data', (chunk) => {
raw += chunk
})
request.on('end', () => {
let payload
try {
payload = JSON.parse(raw)
} catch {
sendJson(response, 400, { error: 'bad json' })
return
}
const query = payload.query || ''
const variables = payload.variables || {}
if (query.includes('WikiPrintLocalization')) {
sendJson(response, 200, {
data: {
localization: {
config: { locale: 'en', namespacing: true, namespaces: ['en'] },
},
},
})
return
}
if (query.includes('WikiPrintPages')) {
sendJson(response, 200, {
data: { pages: { list: pages.map(pageListItem) } },
})
return
}
if (query.includes('WikiPrintPageSource')) {
const page = pages.find((candidate) => candidate.id === variables.id)
sendJson(response, 200, {
data: {
pages: {
single: page
? { content: page.content || '', contentType: page.contentType }
: null,
},
},
})
return
}
if (query.includes('WikiPrintPage')) {
const page = pages.find(
(candidate) =>
candidate.path === variables.path && candidate.locale === variables.locale,
)
sendJson(response, 200, {
data: {
pages: {
singleByPath: page
? {
id: page.id,
path: page.path,
locale: page.locale,
title: page.title,
description: page.description,
contentType: page.contentType,
render: page.render,
createdAt: page.updatedAt,
updatedAt: page.updatedAt,
}
: null,
},
},
})
return
}
sendJson(response, 400, { errors: [{ message: 'Unknown mock query' }] })
})
})
await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve))
const address = server.address()
return {
url: `http://127.0.0.1:${address.port}`,
state,
pages,
close: () => new Promise((resolve) => server.close(resolve)),
}
}