182 lines
12 KiB
Zig
182 lines
12 KiB
Zig
// The third-party licence inventory: what a released nxdns artifact actually
|
|
// contains, in the order `zig build dist` concatenates it into
|
|
// THIRD-PARTY-NOTICES. Hand-written and reviewed on purpose — a notices file
|
|
// scraped from the dependency tree at build time rots into a false statement
|
|
// without anyone noticing (milestone-14 ruling 3).
|
|
//
|
|
// "Artifact" means the two tarballs *and* the container image. The image is
|
|
// built FROM scratch and carries one third-party file the binary does not
|
|
// contain, the Mozilla CA bundle; distributing the image is distribution, so
|
|
// that file is inventoried here like anything else. licenses/preamble.txt says
|
|
// so at the head of the assembled notices.
|
|
//
|
|
// Each entry: the component, the version(s) actually shipped, why it is here
|
|
// and which licence option was taken, and the file under licenses/ holding the
|
|
// licence text. tools/dist_stage.zig parses exactly this shape and
|
|
// src/licenses_drift_test.zig type-checks the same file, so the two must agree.
|
|
//
|
|
// Order matters. The full Apache License 2.0 text is carried once, by the
|
|
// Mbed TLS entry; the Project Everest and p256-m entries that follow refer back
|
|
// to it. src/licenses_drift_test.zig enforces that ordering, and fails when the
|
|
// dependency sets change without a matching change under licenses/.
|
|
//
|
|
// For npm packages the `.version` field spells `<package> <version>` for every
|
|
// package the entry covers. src/licenses_drift_test.zig compares those pairs
|
|
// against licenses/dependency-identity.txt, so a version bump that touches only
|
|
// the identity file fails.
|
|
//
|
|
// The web entries are the packages whose code is actually in web/dist, read off
|
|
// a `vite build --sourcemap`: the sourcemap `sources` lists give the packages
|
|
// whose modules were bundled, and the regions of each chunk that *no* sourcemap
|
|
// segment maps back to a source file give the code the toolchain injected on
|
|
// its own. That second half is how vite and rolldown got here — neither appears
|
|
// in any `sources` list, and both emit their own runtime source verbatim.
|
|
//
|
|
// Four packages of the lockfile's non-dev closure contribute no module to any
|
|
// chunk and are therefore not inventoried: cookie-es, isbot, seroval,
|
|
// seroval-plugins — all four reach the tree only through @tanstack/router-core's
|
|
// server-side paths, which this SPA never imports, and rollup drops them. They
|
|
// stay listed in licenses/dependency-identity.txt so that a future build which
|
|
// does pull them in trips the guard.
|
|
//
|
|
// Four more joined that list with the StyleX build integration: css-mediaquery,
|
|
// invariant, and loose-envify with js-tokens under it. They are @stylexjs/
|
|
// stylex's own dependencies, they serve its compiler and not its runtime, and a
|
|
// sourcemap build of a component calling stylex.props shows none of them in any
|
|
// `sources` list.
|
|
//
|
|
// Seven more joined that list with React Aria, and the sourcemap build is again
|
|
// what settled which: @internationalized/date, @internationalized/number,
|
|
// @react-types/shared, @swc/helpers, aria-hidden, client-only and tslib are in
|
|
// the runtime closure but contribute no module to any chunk. The date and number
|
|
// packages serve the calendar and number-field components ruling 4 keeps out of
|
|
// scope; @react-types/shared is types only and emits no runtime code;
|
|
// client-only is a build-time marker for React Server Components; @swc/helpers
|
|
// and tslib are downlevelling helpers the published ESM builds never reach for;
|
|
// and aria-hidden sits behind a react-aria path the four adopted components do
|
|
// not take. Their licences differ and are recorded one by one in
|
|
// src/licenses_drift_test.zig rather than lumped together: @internationalized/
|
|
// date, @internationalized/number, @react-types/shared and @swc/helpers are
|
|
// Apache-2.0, tslib is 0BSD, aria-hidden and client-only are MIT. Keeping all
|
|
// seven out of the bundle is a fact worth re-checking rather than assuming, so
|
|
// the guard fails if any of them turns up in a `sources` list.
|
|
//
|
|
// StyleX now ships: the converted pages call stylex.props, and a sourcemap build
|
|
// puts @stylexjs/stylex in the bundle. What that build settles is not the
|
|
// obvious answer, though: only @stylexjs/stylex appears as a bundled package,
|
|
// and styleq arrives inside it. The published lib/es/stylex.mjs vendors styleq's source
|
|
// instead of importing it, so styleq's bytes ship while styleq never appears in
|
|
// a `sources` list — no guard would raise it, which is why it is written down
|
|
// here.
|
|
//
|
|
// Of the remaining devDependencies, none puts a byte in web/dist: @vitejs/
|
|
// plugin-react and typescript only transform our own sources (react-refresh is
|
|
// dev-server only, and tslib is optional and unused), @tailwindcss/vite
|
|
// orchestrates tailwindcss without contributing CSS of its own, lightningcss
|
|
// only minifies, and @testing-library/*, jsdom, vitest, oxlint and prettier
|
|
// never touch the build output.
|
|
.{
|
|
.{
|
|
.component = "musl libc",
|
|
.version = "1.2.5 (as bundled with Zig 0.16.0)",
|
|
.note = "Statically linked into both released binaries: every nxdns build targets *-linux-musl with .linkage = .static. In the tarballs and in the image.",
|
|
.file = "musl-copyright.txt",
|
|
},
|
|
.{
|
|
.component = "Zig standard library, compiler-rt and runtime",
|
|
.version = "0.16.0",
|
|
.note = "The standard library, compiler-rt and the safety runtime are compiled into the binary, so the Zig licence travels with the artifact and not only with the toolchain. Parts of Zig's compiler-rt are ported from LLVM's compiler-rt, which the LLVM project licenses under Apache-2.0 WITH LLVM-exception; that exception waives Sections 4(a), 4(b) and 4(d) of the Apache licence for portions embedded in object form, which is the only form nxdns ships, so no further LLVM notice is required here. Zig redistributes those ports under the MIT text below. In the tarballs and in the image.",
|
|
.file = "zig-mit.txt",
|
|
},
|
|
.{
|
|
.component = "SQLite",
|
|
.version = "3.53.4",
|
|
.note = "Vendored amalgamation, statically linked. Public domain: listed for completeness, no obligation attaches. In the tarballs and in the image.",
|
|
.file = "sqlite-public-domain.txt",
|
|
},
|
|
.{
|
|
.component = "Mbed TLS",
|
|
.version = "3.6.7",
|
|
.note = "Vendored, statically linked. Dual Apache-2.0 OR GPL-2.0-or-later; nxdns takes the Apache-2.0 option, and the full Apache-2.0 text is reproduced below. In the tarballs and in the image.",
|
|
.file = "mbedtls-apache-2.0.txt",
|
|
},
|
|
.{
|
|
.component = "Project Everest (Curve25519, HACL*)",
|
|
.version = "as vendored in Mbed TLS 3.6.7 (3rdparty/everest)",
|
|
.note = "Compiled in through build.zig's mbedtls_3rdparty_sources even though the stock config leaves MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED off: the object code is in the binary either way.",
|
|
.file = "everest-apache-2.0.txt",
|
|
},
|
|
.{
|
|
.component = "p256-m",
|
|
.version = "as vendored in Mbed TLS 3.6.7 (3rdparty/p256-m)",
|
|
.note = "Compiled in through build.zig's mbedtls_3rdparty_sources even though the P-256 driver is not enabled. Dual Apache-2.0 OR GPL-2.0-or-later; nxdns takes the Apache-2.0 option.",
|
|
.file = "p256-m-apache-2.0.txt",
|
|
},
|
|
.{
|
|
.component = "React (react, react-dom, scheduler, use-sync-external-store)",
|
|
.version = "react 19.2.8, react-dom 19.2.8, scheduler 0.27.0, use-sync-external-store 1.6.0",
|
|
.note = "Bundled into the admin UI JavaScript that is embedded in the binary. All four ship under the same Meta MIT text.",
|
|
.file = "react-mit.txt",
|
|
},
|
|
.{
|
|
.component = "TanStack Query, Router and History",
|
|
.version = "@tanstack/react-query 5.101.4, @tanstack/query-core 5.101.4, @tanstack/react-router 1.170.18, @tanstack/router-core 1.171.15, @tanstack/history 1.162.0",
|
|
.note = "Bundled into the admin UI JavaScript. Grouped because all five carry the identical MIT text and copyright line.",
|
|
.file = "tanstack-mit.txt",
|
|
},
|
|
.{
|
|
.component = "React Aria (react-aria-components, react-aria, react-stately, @internationalized/string)",
|
|
.version = "react-aria-components 1.20.0, react-aria 3.51.0, react-stately 3.49.0, @internationalized/string 3.2.10",
|
|
.note = "The dialog, alert dialog, tab and select behaviour of the admin UI, bundled into the JavaScript embedded in the binary. The first Apache-2.0 npm dependency this project has taken, and the first non-MIT one: Mokhtar Mial accepted Apache-2.0 inbound for nxdns on 2026-08-12, which is the decision that let these four ship. Apache-2.0 Section 4 attribution is satisfied by carrying the licence text in THIRD-PARTY-NOTICES, which the file below does; none of the four ships a NOTICE file, so 4(d) adds nothing. All four carry a byte-identical LICENSE. In the tarballs and in the image.",
|
|
.file = "react-aria-apache-2.0.txt",
|
|
},
|
|
.{
|
|
.component = "clsx",
|
|
.version = "clsx 2.1.1",
|
|
.note = "The class-name joiner React Aria calls when it merges a render-prop class name with its own. Bundled into the admin UI JavaScript. Separate entry from the other MIT packages: same MIT text, different copyright line.",
|
|
.file = "clsx-mit.txt",
|
|
},
|
|
.{
|
|
.component = "StyleX",
|
|
.version = "@stylexjs/stylex 0.19.0",
|
|
.note = "The style runtime for the admin UI. Its published dist vendors styleq's source, so the styleq entry below covers bytes that arrive inside this package. The npm tarball ships no licence file of its own; this text is the LICENSE of facebook/stylex at tag 0.19.0, which is byte-identical to the one on main.",
|
|
.file = "stylex-mit.txt",
|
|
},
|
|
.{
|
|
.component = "styleq",
|
|
.version = "styleq 0.2.1",
|
|
.note = "The class-name merger StyleX calls at runtime. Never a bundled package in its own right: @stylexjs/stylex vendors its source into lib/es/stylex.mjs, so it reaches web/dist without appearing in any sourcemap `sources` list. Separate entry from StyleX: same MIT text, different copyright line.",
|
|
.file = "styleq-mit.txt",
|
|
},
|
|
.{
|
|
.component = "TanStack Store",
|
|
.version = "@tanstack/store 0.9.3, @tanstack/react-store 0.9.3",
|
|
.note = "Bundled into the admin UI JavaScript. Separate entry from the other TanStack packages: same MIT text, different copyright line.",
|
|
.file = "tanstack-store-mit.txt",
|
|
},
|
|
.{
|
|
.component = "Tailwind CSS",
|
|
.version = "tailwindcss 4.3.3",
|
|
.note = "A devDependency whose output ships: the admin UI stylesheet is generated from Tailwind's own CSS sources, so the generated CSS in the binary is a derivative of them.",
|
|
.file = "tailwindcss-mit.txt",
|
|
},
|
|
.{
|
|
.component = "Vite",
|
|
.version = "vite 8.1.5",
|
|
.note = "A devDependency whose own runtime source ships: the preload helper and the modulepreload polyfill are injected verbatim into web/dist/assets/index-*.js, which is embedded in the binary.",
|
|
.file = "vite-mit.txt",
|
|
},
|
|
.{
|
|
.component = "Rolldown",
|
|
.version = "rolldown 1.1.5",
|
|
.note = "A devDependency whose own runtime source ships: the bundler Vite 8 runs prepends its CommonJS interop helpers verbatim to web/dist/assets/classes-*.js, which is embedded in the binary.",
|
|
.file = "rolldown-mit.txt",
|
|
},
|
|
.{
|
|
.component = "Mozilla CA certificate bundle (Alpine ca-certificates-bundle)",
|
|
.version = "20260611-r0 (alpine 3.22)",
|
|
.note = "In the container image only, at /etc/ssl/certs/ca-certificates.crt: deploy/docker/Dockerfile copies it out of the pinned base into the scratch image so DoH and DoT upstreams verify. apk records the package as MPL-2.0 AND MIT; the shipped bytes derive from Mozilla NSS certdata.txt under MPL-2.0, whose full text follows. Not in the tarballs and not in the binary.",
|
|
.file = "mozilla-ca-bundle-mpl-2.0.txt",
|
|
},
|
|
}
|