diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index e6c97a3..35eae44 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -15,7 +15,7 @@ "cf:deploy:preview": "pnpm run build && wrangler deploy --env preview", "email:dev": "bse dev -c src/routes/layout.css", "prepare": "svelte-kit sync || echo ''", - "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --tsgo-experimental-api", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --tsgo-experimental-api && node scripts/check-svelte-head.js", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "lint": "prettier --check .", "format": "prettier --write .", diff --git a/apps/dashboard/scripts/check-svelte-head.js b/apps/dashboard/scripts/check-svelte-head.js new file mode 100644 index 0000000..66d60dc --- /dev/null +++ b/apps/dashboard/scripts/check-svelte-head.js @@ -0,0 +1,82 @@ +#!/usr/bin/env node +import { readdir, readFile } from 'node:fs/promises'; +import { join, relative } from 'node:path'; + +const ROUTES_DIR = new URL('../src/routes', import.meta.url).pathname; +const OPT_OUT_COMMENT = 'check:allow-missing-head'; +const HARD_EXCLUDES = ['src/routes/+layout.svelte']; +const strict = process.argv.includes('--strict'); + +async function* walk(dir) { + const entries = await readdir(dir, { withFileTypes: true }); + for (const entry of entries) { + const path = join(dir, entry.name); + if (entry.isDirectory()) { + yield* walk(path); + } else if (entry.isFile()) { + yield path; + } + } +} + +async function main() { + const missing = []; + + for await (const filePath of walk(ROUTES_DIR)) { + const fileName = filePath.split('/').pop(); + const projectRelative = relative(join(ROUTES_DIR, '..', '..'), filePath); + + if (HARD_EXCLUDES.some((ex) => projectRelative.endsWith(ex))) { + continue; + } + + let shouldCheck = false; + if (fileName === '+page.svelte' || fileName === '+error.svelte') { + shouldCheck = true; + } + + if (!shouldCheck) { + continue; + } + + const content = await readFile(filePath, 'utf-8'); + if (content.includes('')) { + continue; + } + if (content.includes(' component, a section, or an opt-out comment.' + ); + process.exit(0); + } + + console.error('✗ Missing or in the following route files:\n'); + for (const file of missing) { + console.error(` - ${file}`); + } + console.error( + '\nAdd a component to each file, or add to opt out.' + ); + + if (strict) { + process.exit(1); + } else { + console.error('\n(passing because --strict was not set)'); + process.exit(0); + } +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/apps/dashboard/src/lib/components/PageTitle.svelte b/apps/dashboard/src/lib/components/PageTitle.svelte new file mode 100644 index 0000000..b411c84 --- /dev/null +++ b/apps/dashboard/src/lib/components/PageTitle.svelte @@ -0,0 +1,10 @@ + + + + {formatted} / Stack + diff --git a/apps/dashboard/src/routes/(app)/+error.svelte b/apps/dashboard/src/routes/(app)/+error.svelte index e0a0731..ae1d16f 100644 --- a/apps/dashboard/src/routes/(app)/+error.svelte +++ b/apps/dashboard/src/routes/(app)/+error.svelte @@ -3,6 +3,7 @@ import { Button } from '$lib/components/ui/button'; import { goto } from '$app/navigation'; import { resolve } from '$app/paths'; + import PageTitle from '$lib/components/PageTitle.svelte'; const isNotFound = $derived(page.status === 404); const isServerError = $derived(page.status >= 500); diff --git a/apps/dashboard/src/routes/(app)/+page.svelte b/apps/dashboard/src/routes/(app)/+page.svelte index 4fcbeca..24eca31 100644 --- a/apps/dashboard/src/routes/(app)/+page.svelte +++ b/apps/dashboard/src/routes/(app)/+page.svelte @@ -1,6 +1,7 @@ - - Projects / Stack - +
diff --git a/apps/dashboard/src/routes/(app)/admin/emails/+page.svelte b/apps/dashboard/src/routes/(app)/admin/emails/+page.svelte index f065097..5c835e3 100644 --- a/apps/dashboard/src/routes/(app)/admin/emails/+page.svelte +++ b/apps/dashboard/src/routes/(app)/admin/emails/+page.svelte @@ -1,5 +1,6 @@ - - Emails - +
diff --git a/apps/dashboard/src/routes/(app)/admin/features/+page.svelte b/apps/dashboard/src/routes/(app)/admin/features/+page.svelte index 122812a..372bcee 100644 --- a/apps/dashboard/src/routes/(app)/admin/features/+page.svelte +++ b/apps/dashboard/src/routes/(app)/admin/features/+page.svelte @@ -1,5 +1,6 @@ + +
{#if admin.featureFlagError} diff --git a/apps/dashboard/src/routes/(app)/admin/images/+page.svelte b/apps/dashboard/src/routes/(app)/admin/images/+page.svelte index 0eafee9..d883081 100644 --- a/apps/dashboard/src/routes/(app)/admin/images/+page.svelte +++ b/apps/dashboard/src/routes/(app)/admin/images/+page.svelte @@ -1,5 +1,6 @@ + +