Files
Psychotoxical-psysonic/src/utils/licensesData.ts
T
Frank Stellmacher 8692e50603 feat(settings): Open Source Licenses section in System tab (#477)
* feat(licenses): tooling and initial data generation

Adds the maintainer-only generator that produces src/data/licenses.json:
- src-tauri/about.toml + about.hbs: cargo-about config + handlebars template
  for the Rust-side license enumeration
- scripts/generate-licenses.mjs: orchestrator that runs cargo-about and
  license-checker-rseidelsohn (via npx, no devDep), merges the outputs into
  a single per-crate JSON with full license texts, and writes the result to
  src/data/licenses.json

The script is invoked directly with `node scripts/generate-licenses.mjs` —
no npm script wrapper on purpose, since adding one to package.json would
trigger the nix-npm-deps-hash-sync workflow on every push.

Initial generation covers 575 cargo crates + 71 npm packages (646 entries
total, all with full license text bundled, ~1.4 MB JSON).

* feat(licenses): Settings panel UI

Adds a new Open Source Licenses section under Settings → System,
sitting below Contributors. Components:

- LicensesPanel.tsx: search input, curated highlight block of ~10 key
  dependencies (Tauri, React, rodio, symphonia, etc.), TanStack-Virtual
  list of all 600+ entries
- LicenseTextModal.tsx: full-screen-ish modal showing the bundled license
  text plus name/version/license-id badges + repository link
- licensesData.ts: lazy dynamic-import loader (Vite emits the JSON as a
  separate chunk, so the heavy ~1.4 MB payload is only loaded when the
  user actually opens the panel — no runtime fetch, the data is fixed
  into the build artifact)

The panel registers itself in the Settings in-page search index under
the System tab.

* feat(licenses): i18n in 8 locales

Adds the `licenses` namespace (title, intro, highlights, search
placeholder, no-results, loading / load error, no-license-text,
view-source, total line, generated-at) across en, de, fr, nl, zh, nb,
ru, es. License names themselves (MIT, Apache-2.0, GPL-3.0, …) stay
universal and are rendered as-is.

* docs(release): document licenses regeneration step

Adds a Step A.3 to the release SOP describing the maintainer-only
`node scripts/generate-licenses.mjs` workflow, the cargo-about
prerequisite, and explicitly notes why no npm script wrapper exists
(would trigger the nix-npm-deps-hash-sync workflow).
2026-05-06 14:17:13 +02:00

58 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Lazy loader + types for the bundled `src/data/licenses.json` data.
//
// The JSON is generated by `node scripts/generate-licenses.mjs` (maintainer-only)
// and committed to source. Vite bundles it as a separate JS chunk via dynamic
// import below, so the heavy ~12 MB payload is only loaded when the user
// actually opens the Open Source Licenses panel — no runtime fetch, the data
// lives entirely inside the build artifact.
export interface LicenseEntry {
name: string;
version: string;
source: 'npm' | 'cargo';
licenses: string[];
repository?: string;
homepage?: string;
description?: string;
publisher?: string;
licenseText?: string;
}
export interface LicensesData {
generatedAt: string;
project: { name: string; version: string };
stats: { npm: number; cargo: number; total: number; withFullText: number };
entries: LicenseEntry[];
}
let cache: Promise<LicensesData> | null = null;
export function loadLicensesData(): Promise<LicensesData> {
if (cache) return cache;
cache = import('../data/licenses.json')
.then((mod) => (mod.default ?? mod) as LicensesData)
.catch((e) => {
cache = null;
throw e;
});
return cache;
}
/**
* Curated list of dependency names shown in the highlight block at the top of
* the panel — the user-recognisable backbone of the app. Order matters here;
* the panel renders them top-to-bottom as listed.
*/
export const HIGHLIGHTED_DEPENDENCIES: Array<{ source: 'npm' | 'cargo'; name: string }> = [
{ source: 'cargo', name: 'tauri' },
{ source: 'npm', name: 'react' },
{ source: 'npm', name: 'zustand' },
{ source: 'cargo', name: 'rodio' },
{ source: 'cargo', name: 'symphonia' },
{ source: 'cargo', name: 'cpal' },
{ source: 'npm', name: 'axios' },
{ source: 'npm', name: '@tanstack/react-virtual' },
{ source: 'npm', name: 'react-i18next' },
{ source: 'npm', name: 'lucide-react' },
];