Files
open-design/nix/package-web.nix
c61ba320fd feat(nix): Add official flake with home-manager and NixOS support (#402)
* nix: add official flake with home-manager and nixos modules

* Pin pnpm version

* Format README.md

* Populate PATH files to discover installed CLIs

* Revert "Populate PATH files to discover installed CLIs"

This reverts commit 18d88781a88b8781913cf5a8b680dfb38eabf7e4.

* Fix missing sqlite issue

* Fix system issue

* Reapply "Populate PATH files to discover installed CLIs"

This reverts commit d02ea994e6.

* Handle different ports for web frontend

* Provide documentation for getting pnpm hash

* Enable nix flake checks for code changes

* Set `OD_WEB_PORT` on daemon when declared

* fix: Fix environmentFile for macOS targets

* chore: Ignore nix and direnv related files

* fix: Read version directly from `package.json`

* feat: Make nix shell entry prettier

* chore: Update pnpm hashes

* chore: Bump `pnpm` hashes

* docs: Add blurb about dev shell in `README.md`

* Address review comments

* Add support for `OD_WEB_ORIGINS`

* Fix `isLocalSameOrigin`

* Update pnpm checksums

* docs: Update documentation on host origins

* Move allowedOrigins mapping out of the webFrontend.enable guard

* fix: Bump pnpm hashes

* Remove changes to `daemon` with `main` changes

`main` merged a feature that addressed our need for allowed origins.
Since this feature branch no longer needs it, remove any remaining
changes in `daemon` code so that this is a pure Nix change.

* Update documentation around `OD_DAEMON_URL`

* Rewrite option docs to match same-origin proxy contract

The port, webFrontend, and webFrontend.port option descriptions still
described OD_DAEMON_URL as the runtime contract for the SPA, but the
SPA issues relative /api/*, /artifacts/*, /frames/* requests and there
is no runtime daemon-URL injection. Rewrite the three blocks to
describe what the caddy / custom proxy must actually do.

* Document daemon-side requirements for custom-server proxy paths

The bring-your-own-server path in section (3) and the same-origin
contract in section (4) understated what the daemon needs: any proxy
whose origin differs from the daemon's bind (including loopback
split-port like 127.0.0.1:8080 while the daemon stays on :7457) is
403'd by the daemon's same-origin gate until told about that origin.

Add a callout under section (3)'s table, expand section (4) with a
decision table covering same-port, loopback split-port (OD_WEB_PORT or
webFrontend.allowedOrigins), and non-loopback (webFrontend.allowedOrigins)
cases, and rewrite the webFrontend.allowedOrigins option description to
enumerate the cases where it's required and surface OD_WEB_PORT as an
alternative for the loopback split-port case.

---------

Co-authored-by: lefarcen <935902669@qq.com>
2026-05-09 23:50:16 +08:00

92 lines
2.4 KiB
Nix

{
lib,
stdenv,
dream2nix,
nixpkgs,
system,
nodejs,
pnpm_10,
fetchPnpmDeps,
pnpmConfigHook,
src,
}:
# Builds the @open-design/web Next.js static export.
#
# Output layout: $out/ contains the contents of `apps/web/out/` (an
# index.html plus _next/ and asset subdirectories). Drop $out into any
# static file server.
#
# OD_DAEMON_URL is set to "" at build time so the bundled JS issues
# relative requests (`/api/*`, `/artifacts/*`, `/frames/*`) instead of
# baking a build-time daemon URL into the export. The serving
# environment is therefore expected to be same-origin with the daemon —
# the bundled caddy in the modules reverse-proxies those paths to
# `127.0.0.1:<cfg.port>`, and a custom nginx/caddy must do the same.
let
pname = "open-design-web";
version = (lib.importJSON ../package.json).version;
# Vendored pnpm store. The hash MUST be pinned on first build:
# `nix build .#web` will fail with the expected hash printed; copy
# that into `pnpmDepsHash` below. Bump it whenever pnpm-lock.yaml
# changes.
pnpmDepsHash = "sha256-KF3Mld72/iau+pJmA7HvnanRx8VLtDP0N624SKrtrrc=";
# pnpmDepsHash = lib.fakeHash;
in
stdenv.mkDerivation (finalAttrs: {
inherit pname version src;
nativeBuildInputs = [
nodejs
pnpm_10
pnpmConfigHook
];
pnpmDeps = fetchPnpmDeps {
inherit (finalAttrs) pname version src;
hash = pnpmDepsHash;
fetcherVersion = 3;
};
env = {
NODE_ENV = "production";
OD_DAEMON_URL = "";
};
buildPhase = ''
runHook preBuild
for target in \
packages/contracts \
packages/sidecar-proto \
packages/sidecar \
packages/platform
do
pnpm -C "$target" run --if-present build
done
# next.config.ts gates static-export emission on NODE_ENV=production
# and writes to apps/web/out/.
pnpm --filter @open-design/web run build
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out
cp -r apps/web/out/. $out/
runHook postInstall
'';
passthru = {
inherit nodejs;
pnpmDeps = finalAttrs.pnpmDeps;
};
meta = with lib; {
description = "Open Design — Next.js static SPA (apps/web)";
homepage = "https://github.com/nexu-io/open-design";
license = licenses.asl20;
platforms = platforms.linux ++ platforms.darwin;
};
})