fix(core): pass site context to trusted plugin routes#2080
Conversation
🦋 Changeset detectedLatest commit: f9f3391 The changes in this PR will be included in the next version bump. This PR includes changesets to release 16 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
This is the right fix for the reported issue: trusted plugin API routes were getting their context factory built from a partial options bag (db + storage) while plugin hooks were built from pipelineFactoryOptions, which includes siteInfo. Reusing this.pipelineFactoryOptions in handlePluginApiRoute aligns the two paths with the smallest possible surface change and is consistent with the existing media:write fix that also broadened the options passed to the route registry.
I checked:
- The diff in
packages/core/src/emdash-runtime.ts:PluginRouteRegistrynow receives...this.pipelineFactoryOptions, which carriessiteInfoandgetDb, plus the previously-passedemailPipelineandtrustedProxyHeaders. packages/core/src/plugins/routes.tsandpackages/core/src/plugins/context.ts:PluginRouteRegistrystores aPluginContextFactoryOptionsand uses it to create aPluginContextFactory; the factory normalizessiteInfointoctx.siteand buildsctx.url()from the configured base URL.packages/core/src/emdash-runtime.ts(EmDashRuntime.create):pipelineFactoryOptionsis already built withdb,getDb,storage, andsiteInfo, so trusted routes now pick up the same snapshot as hooks.- The new regression test
packages/core/tests/integration/runtime/plugin-route-site-info.test.ts: it manually constructs a runtime whosepipelineFactoryOptionscarrysiteInfo, invokes a trusted route, and asserts bothctx.siteshape and an absolutectx.url()output. - The changeset
.changeset/plugin-route-site-context.md: correctly scoped toemdash: patch, user-facing, present-tense, describes the observable fix.
No logic bugs, authorization gaps, SQL issues, locale-filter issues, or convention violations. The sandboxed-plugin route path is intentionally untouched by this PR (it uses a different, sandbox-isolated invocation), and the standalone PluginManager route registry is not exercised by the production route dispatch path, so I did not flag it. Clean to merge.
What does this PR do?
Passes the runtime's configured site context into trusted plugin API route contexts. Route handlers now receive the same normalized
ctx.sitedata as plugin hooks, andctx.url(path)returns an absolute URL when a site URL is configured.The route registry was previously created with database and storage dependencies but without
siteInfo, so it fell back to an empty site context.Closes #1813
Type of change
Checklist
pnpm --filter emdash typecheckpassesValidation
pnpm --filter emdash typecheckpnpm --filter emdash buildpnpm --filter emdash checkvitest run tests/integration/runtime/plugin-route-site-info.test.tsoxlint --type-aware --deny-warningson changed source and test filesoxfmt --checkon changed source and test filesprettier --check .changeset/plugin-route-site-context.md