Drop .mjs: rename e2e/dev mock servers to .ts, update refs, document the convention in AGENTS.md

This commit is contained in:
2026-06-23 23:54:42 +02:00
parent 913bd6813a
commit 6d316c4888
8 changed files with 18 additions and 13 deletions
+5
View File
@@ -83,6 +83,11 @@ one home, linking to it rather than restating (credentials, env vars, rotation s
- Node 24 runs `.ts` directly (type stripping). Keep all TypeScript **erasable**
(`erasableSyntaxOnly` is on): no `enum`, `namespace`, parameter properties, or
decorators. Import local modules with their `.ts` extension.
- **No `.mjs`.** Write modules as `.ts` (Prio 1) — even standalone scripts run in bare
`node:24` containers (the e2e mock servers, `examples/shifts-upstream/server.ts`): Node
strips types and detects ESM from syntax, no package.json needed. If a file genuinely
must be plain JavaScript, use `.js` (Prio 2); `"type": "module"` is already set in both
`package.json`s, so `.js` is ESM.
- **No build step** and no compiled artifacts — do not add a bundler or `tsc` emit.
- Before finishing a change, run the typecheck and tests above; both must pass.
- Tests use the built-in `node --test` runner — no test framework dependency.
+3 -3
View File
@@ -680,9 +680,9 @@ docker compose -f compose.yml -f e2e-tests/compose.oauth.yml down -v
**Full browser flow** (`full-flow.spec.ts`) — the real Playwright UI against the live stack:
the themed **password login** and a **mocked-SSO** login (an in-network mock OIDC provider,
`e2e-tests/mock-oidc.mjs`), **menu filtering by role**, the **users/groups/roles** admin CRUD, a
`e2e-tests/mock-oidc.ts`), **menu filtering by role**, the **users/groups/roles** admin CRUD, a
permission-gated **plugin page**, and **logout**. Because the themed form posts straight to
Kratos and cookies are host-scoped, a tiny same-origin gateway (`e2e-tests/proxy.mjs`) fronts web +
Kratos and cookies are host-scoped, a tiny same-origin gateway (`e2e-tests/proxy.ts`) fronts web +
Kratos on one host (`ory/kratos/e2e-proxy.yml` points Kratos at it) — exactly as a production
reverse proxy would.
@@ -932,7 +932,7 @@ ory/ Ory service config (kratos/: identity schema, kratos.yml, o
plugins/ Drop-in plugin folders (scanned at /app/plugins; bind-mount or bake in). Ships scheduling/ — the reference plugin (list/form over an upstream + permission-gated nav) you copy
examples/ Non-app helpers; shifts-upstream/ is the dev mock backend the reference plugin reads/writes (stand-in for your real service)
docs/ Reference docs (plugin-contract.md — the authoritative plugin API)
e2e-tests/ Playwright E2E: visual.spec (design system, Ory-free) + auth-refresh.spec (token timeout/re-mint) + oauth-login.spec (OAuth2 login + consent) + full-flow.spec (browser UI: password/SSO login, menu-by-role, admin CRUD, plugin page, logout) + devstack-login.spec (regression: login works from the banner's localhost URL and 127.0.0.1 is canonicalised, on the plain `docker compose up` topology); proxy.mjs (same-origin gateway) + mock-oidc.mjs (mock SSO provider) back full-flow. e2e-tests/Dockerfile + e2e-tests/compose.{visual,auth,oauth,full,devstack}.yml run them
e2e-tests/ Playwright E2E: visual.spec (design system, Ory-free) + auth-refresh.spec (token timeout/re-mint) + oauth-login.spec (OAuth2 login + consent) + full-flow.spec (browser UI: password/SSO login, menu-by-role, admin CRUD, plugin page, logout) + devstack-login.spec (regression: login works from the banner's localhost URL and 127.0.0.1 is canonicalised, on the plain `docker compose up` topology); proxy.ts (same-origin gateway) + mock-oidc.ts (mock SSO provider) back full-flow. e2e-tests/Dockerfile + e2e-tests/compose.{visual,auth,oauth,full,devstack}.yml run them
ci.sh The full CI gate: typecheck → unit tests → every E2E suite, each on a fresh, always-torn-down stack (`bash ci.sh`)
```
+1 -1
View File
@@ -25,7 +25,7 @@ services:
# the real backend instead. Uses the pinned app image so there's nothing extra to build/pull.
shifts-upstream:
image: node:24.16.0-alpine3.24
command: node /srv/server.mjs
command: node /srv/server.ts
restart: unless-stopped
volumes:
- ./examples/shifts-upstream:/srv:ro
+8 -8
View File
@@ -1,6 +1,6 @@
# Full browser E2E — the real Playwright UI flow against the live stack: password +
# mocked-SSO login, menu filtering by role, users/groups/roles CRUD, a plugin page, logout. A tiny
# same-origin gateway (proxy, e2e-tests/proxy.mjs) fronts web + Kratos on one host so the browser's cookies
# same-origin gateway (proxy, e2e-tests/proxy.ts) fronts web + Kratos on one host so the browser's cookies
# round-trip (ory/kratos/e2e-proxy.yml points Kratos at it); a mock OIDC provider backs the SSO test.
# docker compose -f compose.yml -f e2e-tests/compose.full.yml run --build --rm e2e
# docker compose -f compose.yml -f e2e-tests/compose.full.yml down -v # tear down after
@@ -42,9 +42,9 @@ services:
# The reference plugin's upstream (examples/shifts-upstream) so /scheduling/shifts shows real rows.
shifts-upstream:
image: node:24.16.0-alpine3.24
command: ["node", "/server.mjs"]
command: ["node", "/server.ts"]
volumes:
- ./examples/shifts-upstream/server.mjs:/server.mjs:ro
- ./examples/shifts-upstream/server.ts:/server.ts:ro
healthcheck:
test: ["CMD", "wget", "-q", "-O", "-", "http://localhost:4000/shifts"]
interval: 2s
@@ -55,22 +55,22 @@ services:
# verifies via its jwks. Reachable as the same host (mock-oidc:9000) by both the browser and Kratos.
mock-oidc:
image: node:24.16.0-alpine3.24
command: ["node", "/mock-oidc.mjs"]
command: ["node", "/mock-oidc.ts"]
environment:
ISSUER: http://mock-oidc:9000
SSO_EMAIL: sso-user@plainpages.local
volumes:
- ./e2e-tests/mock-oidc.mjs:/mock-oidc.mjs:ro
- ./e2e-tests/mock-oidc.ts:/mock-oidc.ts:ro
healthcheck:
test: ["CMD", "wget", "-q", "-O", "-", "http://localhost:9000/.well-known/openid-configuration"]
interval: 2s
timeout: 4s
retries: 15
# Same-origin gateway: Kratos-owned paths → kratos, everything else → web (e2e-tests/proxy.mjs).
# Same-origin gateway: Kratos-owned paths → kratos, everything else → web (e2e-tests/proxy.ts).
proxy:
image: node:24.16.0-alpine3.24
command: ["node", "/proxy.mjs"]
command: ["node", "/proxy.ts"]
depends_on:
web:
condition: service_healthy
@@ -78,7 +78,7 @@ services:
KRATOS_URL: http://kratos:4433
WEB_URL: http://web:3000
volumes:
- ./e2e-tests/proxy.mjs:/proxy.mjs:ro
- ./e2e-tests/proxy.ts:/proxy.ts:ro
healthcheck:
test: ["CMD", "wget", "-q", "-O", "-", "http://localhost/public/css/styles.css"]
interval: 2s
+1 -1
View File
@@ -1,6 +1,6 @@
# Browser-E2E overlay (e2e-tests/compose.full.yml) — merged after kratos.yml via a second `-c`. The
# full-flow suite drives the real browser, so web + Kratos must share one origin (the `proxy`
# gateway, e2e-tests/proxy.mjs). Point Kratos' public base_url and every self-service URL at that host so
# gateway, e2e-tests/proxy.ts). Point Kratos' public base_url and every self-service URL at that host so
# the flow action, the session cookie, and the after-login redirect all stay same-origin as the
# browser sees them. The normal (10m) tokenizer TTL from kratos.yml is kept — no re-mint mid-test.
serve: