Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions scripts/verify-discovery.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ for (const route of routes) {
assert.equal(trail[1].item, `https://nestflow.art${route}`)
}
if (/\/about\/$/.test(route)) {
assert(local.includes('<!--email_off--><article') && local.includes('</article><!--/email_off-->'), `${route}: identity answer must survive CDN email protection`)
assert(typed('AboutPage'), `${route}: official identity page type missing`)
assert.equal(typed('AboutPage').mainEntity?.['@id'], typed('SoftwareApplication')['@id'], `${route}: main identity must reference the official app`)
assert(typed('SoftwareApplication').sameAs.includes('https://github.com/VelvetAbyss/Focus-Go'))
Expand Down
6 changes: 6 additions & 0 deletions scripts/verify-discovery.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,9 @@ test('rejects a Chinese page canonicalized to English', async t => {
test('rejects an identity page whose main entity is an unrelated product', async t => {
await assert.rejects(check(t, response => ({ ...response, html: response.route === '/about/' ? response.html.replace('"mainEntity":{"@id":"https://nestflow.art/#application"}', '"mainEntity":{"@id":"https://example.invalid/other"}') : response.html })), error => /main identity/.test(error.stderr))
})

test('keeps identity contact readable when CDN email protection runs', async t => {
const result = await check(t, response => ({ ...response, html: response.html.split(/(<!--email_off-->[\s\S]*?<!--\/email_off-->)/g).map(part => part.startsWith('<!--email_off-->') ? part : part.replaceAll('support@nestflow.art', '<a class="__cf_email__">[email&#160;protected]</a>')).join('') }))
assert(result.stdout.includes('PASS discovery: /about/'))
assert(result.stdout.includes('PASS discovery: /zh/about/'))
})
2 changes: 1 addition & 1 deletion scripts/website-pages.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export async function buildContentPages(output, release) {
<meta property="og:title" content="${escape(c.title)}"><meta property="og:description" content="${escape(c.description)}"><meta property="og:type" content="article"><meta property="og:url" content="https://nestflow.art${route}"><meta property="og:image" content="https://nestflow.art/assets/product-dashboard.png">
<meta name="focusgo-site-release" content="${escape(release)}"><link rel="icon" href="/favicon.ico"><link rel="stylesheet" href="/assets/content.css?v=${release}">${structuredData({ route, lang, title: c.title, description: c.description, breadcrumb: c.h1, application: true, pageType: page.pageType })}</head>
<body><a class="skip" href="#content">${lang === 'zh' ? '跳至正文' : 'Skip to content'}</a><header><nav aria-label="${lang === 'zh' ? '主导航' : 'Main navigation'}"><a class="brand" href="${homeFor(lang)}">Focus&amp;go</a><div><a href="${homeFor(lang)}">${t.home}</a><a lang="${lang === 'zh' ? 'en' : 'zh-CN'}" href="${urlFor(page, lang === 'zh' ? 'en' : 'zh')}">${t.switch}</a><a class="button" href="https://app.nestflow.art/">${t.open}</a></div></nav></header>
<main id="content">${breadcrumbs(lang, route, c.h1)}<article><p class="eyebrow">Focus&amp;go · ${checked}</p><h1>${escape(c.h1)}</h1><p class="summary">${escape(c.summary)}</p>${sections}${links}<section><h2>${t.faq}</h2>${questions}</section><aside><h2>${t.sources}</h2><p><a href="https://github.com/VelvetAbyss/Focus-Go/blob/${sourceRef}/README.md">README · MIT</a> · <a href="https://github.com/VelvetAbyss/Focus-Go/tree/${sourceRef}/apps/web/src/features/focus">${lang === 'zh' ? '专注功能' : 'Focus functionality'}</a> · <a href="${lang === 'zh' ? '/zh/privacy/' : '/privacy/'}">${t.privacy}</a></p><p>${escape(t.note)}</p></aside></article><section class="related"><h2>${t.related}</h2><div>${navigation}</div></section></main><footer><p>Focus&amp;go · ${lang === 'zh' ? '维护者' : 'Maintained by'} Dylan Feng · <a href="${lang === 'zh' ? '/zh/privacy/' : '/privacy/'}">${t.privacy}</a> · <a href="${lang === 'zh' ? '/zh/terms/' : '/terms/'}">${lang === 'zh' ? '服务条款' : 'Terms'}</a> · <a href="https://github.com/VelvetAbyss/Focus-Go">GitHub</a> · <a href="mailto:support@nestflow.art">support@nestflow.art</a></p></footer></body></html>`
<main id="content">${breadcrumbs(lang, route, c.h1)}<!--email_off--><article><p class="eyebrow">Focus&amp;go · ${checked}</p><h1>${escape(c.h1)}</h1><p class="summary">${escape(c.summary)}</p>${sections}${links}<section><h2>${t.faq}</h2>${questions}</section><aside><h2>${t.sources}</h2><p><a href="https://github.com/VelvetAbyss/Focus-Go/blob/${sourceRef}/README.md">README · MIT</a> · <a href="https://github.com/VelvetAbyss/Focus-Go/tree/${sourceRef}/apps/web/src/features/focus">${lang === 'zh' ? '专注功能' : 'Focus functionality'}</a> · <a href="${lang === 'zh' ? '/zh/privacy/' : '/privacy/'}">${t.privacy}</a></p><p>${escape(t.note)}</p></aside></article><!--/email_off--><section class="related"><h2>${t.related}</h2><div>${navigation}</div></section></main><footer><p>Focus&amp;go · ${lang === 'zh' ? '维护者' : 'Maintained by'} Dylan Feng · <a href="${lang === 'zh' ? '/zh/privacy/' : '/privacy/'}">${t.privacy}</a> · <a href="${lang === 'zh' ? '/zh/terms/' : '/terms/'}">${lang === 'zh' ? '服务条款' : 'Terms'}</a> · <a href="https://github.com/VelvetAbyss/Focus-Go">GitHub</a> · <a href="mailto:support@nestflow.art">support@nestflow.art</a></p></footer></body></html>`
const dir = path.join(output, route)
await mkdir(dir, { recursive: true })
await writeFile(path.join(dir, 'index.html'), html)
Expand Down
Loading