Files
native/scripts/generate-licences.mjs
Linus Rath 6f515e15f7 feat: rework settings into the picked list, About and Storage & backup pages
The settings list now has the account card on top, title-case group
labels and 56 dp rows that show each pane's current value. About and
"About & Data" were one placeholder page with a letter logo, a fixed
name and a store link that pointed at GitHub releases.

- About: the real logo, the app name from app.config.js, the update
  state, a source link that a build can set with SOURCE_CODE_URL, and
  rows for the server, update checks (Android), open-source licences,
  privacy and a prefilled GitHub issue. iPhone updates link TestFlight.
- Storage & backup: usage card, offline mail, settings export/import
  and reset, and a Troubleshooting page for refresh and debug logging.
- Sender favicons moved to Appearance, like the webmail.
- The S/MIME and Plugins stub pages are gone; both are webmail plugins.

The licence list is generated by `scripts/generate-licences.mjs`.
2026-10-15 14:49:37 +02:00

47 lines
1.8 KiB
JavaScript

// Writes src/lib/licences.json: the libraries the app ships (the runtime
// dependencies in package.json) with their licence, for Settings → About →
// Open-source licences. Run after adding or upgrading a dependency:
//
// node scripts/generate-licences.mjs
//
// The test in src/lib/__tests__/licences.test.ts fails when a dependency is
// missing from the list.
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
const pkg = JSON.parse(readFileSync(join(ROOT, 'package.json'), 'utf8'));
// Code that isn't an npm dependency but ships in the app.
const VENDORED = [
{ name: 'Tabler Icons', version: '', license: 'MIT', url: 'https://tabler.io/icons' },
];
function repoUrl(meta) {
const repo = typeof meta.repository === 'string' ? meta.repository : meta.repository?.url;
const url = meta.homepage || repo || '';
return url
.replace(/^git\+/, '')
.replace(/^git:\/\//, 'https://')
.replace(/^github:/, 'https://github.com/')
.replace(/\.git$/, '')
.replace(/#.*$/, '');
}
const libraries = Object.keys(pkg.dependencies).sort().map((name) => {
const file = join(ROOT, 'node_modules', name, 'package.json');
if (!existsSync(file)) throw new Error(`${name} is not installed`);
const meta = JSON.parse(readFileSync(file, 'utf8'));
const license = typeof meta.license === 'string' ? meta.license : meta.license?.type ?? 'See package';
return { name, version: meta.version, license, url: repoUrl(meta) };
});
const out = {
app: { name: pkg.name, license: pkg.license },
libraries: [...libraries, ...VENDORED],
};
writeFileSync(join(ROOT, 'src', 'lib', 'licences.json'), `${JSON.stringify(out, null, 2)}\n`);
console.log(`${out.libraries.length} libraries`);