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
6 changes: 6 additions & 0 deletions .github/workflows/frontend-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ jobs:
env:
MODE: production
ASTRO_TELEMETRY_DISABLED: 1
# The built artifact is consumed by `astro preview` during the
# e2e step below. `config/cookie.config.ts` reads `E2E_TESTS`
# at build time to disable the cookie-consent bot check; without
# this, the preview serves a production-configured modal that
# playwright is mistaken for a bot and never opens.
E2E_TESTS: 1
run: pnpm build:production

# Upload before the dist sanity-check so the artifact is always
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ test-results/
.astro/
.cache/
.netlify/
.twoslash-types/
tmp/

# Logs
Expand Down
58 changes: 57 additions & 1 deletion src/frontend/ec.config.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,66 @@
import { readFileSync, existsSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, resolve } from 'node:path';

import { pluginCollapsibleSections } from '@expressive-code/plugin-collapsible-sections';
import { pluginLineNumbers } from '@expressive-code/plugin-line-numbers';
import ecTwoSlash from 'expressive-code-twoslash';
import { pluginDisableCopy } from './src/expressive-code-plugins/disable-copy.mjs';

const __dirname = dirname(fileURLToPath(import.meta.url));
const ASPIRE_TYPES_PATH = resolve(__dirname, '.twoslash-types/aspire.d.ts');
const aspireTypes = existsSync(ASPIRE_TYPES_PATH)
? readFileSync(ASPIRE_TYPES_PATH, 'utf8')
: '';

if (!aspireTypes) {
// Non-fatal — twoslash blocks that import the SDK will just show `any`.
// Run `pnpm twoslash-types` to refresh.
console.warn('[ec] .twoslash-types/aspire.d.ts missing — run `pnpm twoslash-types`');
}

/** @type {import('@astrojs/starlight/expressive-code').StarlightExpressiveCodeOptions} */
export default {
plugins: [pluginCollapsibleSections(), pluginLineNumbers(), pluginDisableCopy()],
plugins: [
pluginCollapsibleSections(),
pluginLineNumbers(),
pluginDisableCopy(),
ecTwoSlash({
// Only run on TS blocks that opt in via the `twoslash` meta flag.
instanceConfigs: {
// Docs samples use both `ts` and `typescript` fence languages; accept both.
twoslash: { explicitTrigger: true, languages: ['ts', 'tsx', 'typescript'] },
},
includeJsDoc: true,
twoslashOptions: {
compilerOptions: {
// ts.ModuleResolutionKind.Bundler so `./.modules/aspire.js` falls
// through to the virtual `.modules/aspire.ts` file declared below.
moduleResolution: 100,
// ts.ModuleKind.ESNext (paired with bundler resolution).
module: 99,
// ts.ScriptTarget.ESNext.
target: 99,
strict: true,
noEmit: true,
// Omit `lib` so twoslash falls back to `lib.esnext.full.d.ts`
// (target: ESNext) — that bundle pulls in `Date`, `URL`, DOM,
// and other common globals via triple-slash references. Pinning
// an explicit `lib` array breaks those references in the VFS.
},
handbookOptions: {
// Keep type squigglies rendered inline but don't fail the build when
// a sample has unannotated compiler errors — the generated SDK is a
// best-effort shape and docs samples shouldn't need `// @errors` tags.
noErrorValidation: true,
},
// Virtual files merged into the Twoslash VFS. The Aspire SDK types
// are declared at `.modules/aspire.ts` so docs samples that import
// `'./.modules/aspire.js'` resolve against the real API surface.
extraFiles: aspireTypes ? { '.modules/aspire.ts': aspireTypes } : {},
},
}),
],
defaultProps: {
showLineNumbers: false,
},
Expand Down
20 changes: 12 additions & 8 deletions src/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,23 @@
"scripts": {
"git-env": "node ./scripts/write-git-env.mjs",
"check-data": "node ./scripts/check-data-files.mjs",
"dev": "pnpm git-env && pnpm check-data && astro dev",
"dev:host": "pnpm git-env && pnpm check-data && astro dev --host",
"start": "pnpm git-env && pnpm check-data && astro dev",
"start:host": "pnpm git-env && pnpm check-data && astro dev --host",
"build": "pnpm git-env && astro build",
"build:skip-search": "pnpm git-env && astro build --mode skip-search",
"build:production": "pnpm git-env && astro build --mode production",
"twoslash-types": "tsx ./scripts/generate-twoslash-types.ts",
"dev": "pnpm git-env && pnpm check-data && pnpm twoslash-types && astro dev",
"dev:host": "pnpm git-env && pnpm check-data && pnpm twoslash-types && astro dev --host",
"start": "pnpm git-env && pnpm check-data && pnpm twoslash-types && astro dev",
"start:host": "pnpm git-env && pnpm check-data && pnpm twoslash-types && astro dev --host",
"build": "pnpm git-env && pnpm twoslash-types && astro build",
"build:skip-search": "pnpm git-env && pnpm twoslash-types && astro build --mode skip-search",
"build:production": "pnpm git-env && pnpm twoslash-types && astro build --mode production",
"preview": "astro preview",
"preview:host": "astro preview --host",
"astro": "pnpm git-env && astro",
"test": "pnpm test:unit && pnpm test:e2e",
"test:all": "pnpm lint && pnpm test",
"test:unit": "pnpm test:unit:contracts && pnpm test:unit:components && pnpm test:unit:docs && pnpm test:unit:api-markdown && pnpm test:unit:ts-api",
"test:unit": "pnpm test:unit:contracts && pnpm test:unit:components && pnpm test:unit:docs && pnpm test:unit:api-markdown && pnpm test:unit:ts-api && pnpm test:unit:twoslash-types",
"test:unit:api-markdown": "vitest run --config vitest.config.ts tests/unit/api-markdown.vitest.test.ts",
"test:unit:ts-api": "vitest run --config vitest.config.ts tests/unit/ts-api-routes.vitest.test.ts tests/unit/ts-api-search.vitest.test.ts",
"test:unit:twoslash-types": "vitest run --config vitest.config.ts tests/unit/twoslash-types-generator.vitest.test.ts",
"test:unit:contracts": "vitest run --config vitest.config.ts tests/unit/analytics-script-contracts.vitest.test.ts",
"test:unit:components": "vitest run --config vitest.config.ts tests/unit/custom-components.vitest.test.ts tests/unit/site-tour.vitest.test.ts",
"test:unit:docs": "vitest run --config vitest.config.ts tests/unit/filetree-format.vitest.test.ts",
Expand Down Expand Up @@ -88,13 +90,15 @@
"astro-vtbot": "^2.1.12",
"eslint": "^10.2.0",
"eslint-config-prettier": "^10.1.8",
"expressive-code-twoslash": "^0.6.1",
"globals": "^17.5.0",
"http-proxy-agent": "^9.0.0",
"https-proxy-agent": "^9.0.0",
"node-fetch": "^3.3.2",
"prettier": "^3.8.2",
"prettier-plugin-astro": "^0.14.1",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.58.2",
"vitest": "^4.1.4"
},
Expand Down
14 changes: 13 additions & 1 deletion src/frontend/playwright.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export default defineConfig({
forbidOnly: isCI,
retries: isCI ? 2 : 0,
workers: isCI ? 2 : undefined,
// Default (30s) is tight once twoslash code blocks add server-side work
// during dev mode. 60s gives `page.goto` enough headroom without masking
// real regressions.
timeout: 60_000,
reporter: isCI
? [
['github'],
Expand Down Expand Up @@ -50,7 +54,15 @@ export default defineConfig({
},
],
webServer: {
command: `pnpm git-env && pnpm check-data && astro dev --host 127.0.0.1 --port ${e2ePort}`,
// In CI the preceding `pnpm build:production` step has already produced
// `dist/`, so serve the built site via `astro preview`. Under `astro dev`
// the first request to each page triggers twoslash processing, which
// stacks up under parallel test workers and blows past the default
// 30s test timeout. Locally we keep `astro dev` so interactive work
// doesn't require a full rebuild.
command: isCI
? `astro preview --host 127.0.0.1 --port ${e2ePort}`
: `pnpm git-env && pnpm check-data && astro dev --host 127.0.0.1 --port ${e2ePort}`,
env: {
...process.env,
ASTRO_TELEMETRY_DISABLED: '1',
Expand Down
Loading
Loading