Skip to content

Add fastboot/prember#1691

Merged
RobbieTheWagner merged 19 commits into
mainfrom
prember
Mar 25, 2026
Merged

Add fastboot/prember#1691
RobbieTheWagner merged 19 commits into
mainfrom
prember

Conversation

@RobbieTheWagner

Copy link
Copy Markdown
Member

This PR will have addon docs create static output via prember.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces static site generation for addon documentation via Prember + FastBoot, and updates runtime/deploy behavior so the built output can be served statically and then rewritten to versioned paths at deploy time.

Changes:

  • Add Prember URL discovery (lib/prember-urls.js) and auto-configure Prember in the addon’s included() hook.
  • Update deploy-time token replacement to rewrite rootURL, asset URLs, and deploy version in built output.
  • Add FastBoot-safe guards/behavior in several services/components and add unit test coverage (Ember + Node).

Reviewed changes

Copilot reviewed 20 out of 21 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/unit/services/docs-store-test.js Adds QUnit coverage for docs-store JSON:API deserialization and relationship resolution.
tests/unit/models/component-test.js Adds QUnit coverage for Component model derived properties.
tests/unit/models/class-test.js Adds QUnit coverage for Class model derived properties.
tests/dummy/config/environment.js Adjusts production rootURL behavior and adds FastBoot config for dummy app.
tests/dummy/app/templates/docs/build-options.md Documents Prember/FastBoot static site generation and override hooks.
tests-node/unit/prember-urls-test.js Adds Mocha/Chai coverage for Prember URL enumeration.
tests-node/unit/deploy/plugin-test.js Updates deploy token replacement tests and adds new cases.
package.json Adds ember-cli-fastboot/prember, plus peerDeps and FastBoot module allowlisting.
pnpm-lock.yaml Locks dependency additions for FastBoot and Prember.
lib/utils/find-and-replace-in-directory.js Replaces legacy rootURL token replacement with broader deploy token rewriting.
lib/prember-urls.js New Prember URL enumerator using dist search index + docs JSON.
index.js Auto-configures Prember when not explicitly configured by the consuming app.
blueprints/ember-cli-addon-docs/index.js Blueprint now installs ember-cli-fastboot and prember.
addon/services/project-version.js Avoids version manifest fetch in FastBoot; adds FastBoot guard for redirects.
addon/services/docs-store.js Adds FastBoot-specific fetching strategy for docs JSON.
addon/services/docs-search.js Disables search index loading in FastBoot and returns empty results.
addon/keyboard-config.js Adds non-browser guard for document.
addon/components/docs-viewer/x-main/index.js Adds non-browser guard for MutationObserver.
addon/components/docs-modal-dialog.js Forces renderInPlace in FastBoot to avoid DOM issues.
addon/components/docs-header/search-box/index.js Adds non-browser guard for document.
addon/components/docs-header/index.js Makes document usage FastBoot-safe.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread addon/services/docs-store.js Outdated
Comment thread lib/prember-urls.js
Comment thread lib/prember-urls.js
Comment thread tests-node/unit/prember-urls-test.js Outdated
Comment thread tests-node/unit/prember-urls-test.js Outdated
Comment thread tests/dummy/config/environment.js Outdated
Comment thread addon/services/docs-store.js Outdated
RobbieTheWagner and others added 10 commits March 25, 2026 14:01
This reverts commit bbaa25e.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 21 changed files in this pull request and generated 5 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread addon/services/docs-store.js Outdated
Comment on lines +65 to +78
// Derive host and protocol from the FastBoot/Node request in a standards-based way
let host =
(request &&
request.headers &&
(request.headers.host || request.headers.Host)) ||
request.host;
let protocol =
(request && request.protocol) ||
(request &&
request.headers &&
(request.headers['x-forwarded-proto'] ||
request.headers['X-Forwarded-Proto'])) ||
'http';
let url = `${protocol}://${host}/docs/${id}.json`;

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In FastBoot, host/protocol are derived from request headers (e.g. Host, x-forwarded-proto). If those headers are missing or user-controlled, this can produce an invalid URL (e.g. http://undefined/...) and can enable server-side request forgery by redirecting the fetch off-box. Prefer deriving the origin from a trusted FastBoot/Express request property (or a configured base URL) and validate/guard before building the request URL.

Suggested change
// Derive host and protocol from the FastBoot/Node request in a standards-based way
let host =
(request &&
request.headers &&
(request.headers.host || request.headers.Host)) ||
request.host;
let protocol =
(request && request.protocol) ||
(request &&
request.headers &&
(request.headers['x-forwarded-proto'] ||
request.headers['X-Forwarded-Proto'])) ||
'http';
let url = `${protocol}://${host}/docs/${id}.json`;
// Build a URL that targets the local FastBoot server using only trusted
// server-side properties, not user-controlled headers, to avoid SSRF.
let port =
(request &&
request.socket &&
request.socket.localPort) ||
process.env.PORT ||
80;
// Only trust a known-safe protocol value; default to http otherwise.
let protocol = request && request.protocol === 'https' ? 'https' : 'http';
let host = 'localhost';
let url =
port === 80 || port === 443
? `${protocol}://${host}/docs/${id}.json`
: `${protocol}://${host}:${port}/docs/${id}.json`;

Copilot uses AI. Check for mistakes.
Comment thread addon/services/docs-store.js Outdated
Comment on lines +103 to +107
req.abort();
reject(new Error(`Request to ${url} timed out`));
});
});

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

req.abort() is deprecated on Node’s http client request. Use req.destroy() (and ideally clear the timeout) to avoid relying on deprecated APIs and to ensure the socket is properly torn down on timeouts.

Copilot uses AI. Check for mistakes.

payload = JSON.parse(data);
} else {
let namespace = `${getRootURL(this).replace(/\/$/, '')}/docs`;

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON.parse(data) can throw with an unhelpful error if the response body isn’t valid JSON (e.g. an HTML error page from the FastBoot server). Consider wrapping the parse in a try/catch and throwing an error that includes the URL and a short snippet of the body to aid debugging.

Copilot uses AI. Check for mistakes.
let payload;

let fastboot = getOwner(this).lookup('service:fastboot');
if (fastboot?.isFastBoot) {

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The FastBoot-specific _fetchProject path (Node http request + header-derived origin) isn’t covered by the current unit tests. Adding a test that stubs service:fastboot and FastBoot.require('http') would help prevent regressions in the static prerendering path.

Suggested change
if (fastboot?.isFastBoot) {
if (
fastboot?.isFastBoot &&
typeof FastBoot !== 'undefined' &&
typeof FastBoot.require === 'function'
) {

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +23
truncatedSha: this.currentVersion.sha?.substr(0, 5) || '',
key: this.config.latestVersionName,
},

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

substr is deprecated in modern JS runtimes. Prefer slice(0, 5) here (and elsewhere in this service) to avoid deprecation warnings and keep string handling consistent.

Copilot uses AI. Check for mistakes.
@RobbieTheWagner RobbieTheWagner merged commit 31584ad into main Mar 25, 2026
15 checks passed
@RobbieTheWagner RobbieTheWagner deleted the prember branch March 25, 2026 18:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants