Files
julian.kiedaischandClaude Opus 5.5 fb1a467221 feat: F6.1 FILIUS files on F: projects from examples and .fls, copies, export
/svc/examples lists FILIUS' examples, which lie beside F in the image (GPL
like this repository, kept out of the dashboard); /svc/projects makes a
project from one; /svc/projects/<id>/import takes a .fls (up to 64 MiB),
/copy copies a project as it is now, /export gives it back as a .fls with its
warnings. Large files go into the blob store on import and come back from it
on export, which is refused when one is missing.

Found on the way: Node's request body is a Buffer, and Yjs takes no Buffer
into a document, so every .fls with binary files would have failed; and
fflate, now in the bundle, imports createRequire itself, which the build's
banner declared again, so F did not start. The banner names it otherwise and
a test builds and starts the bundle. The proxy's /svc/ takes 70 MB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 07:55:11 +00:00

24 lines
1.2 KiB
TypeScript

// Server F as the image runs it: built by the package's own build script
// and started with node. Without its environment it stops at once and says
// what is missing — which it can only say when the bundle loads at all (a
// bundled library that declared createRequire again kept it from loading).
import { spawnSync } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';
const server = fileURLToPath(new URL('..', import.meta.url));
describe('the built server', () => {
it('loads, and stops for want of its environment', () => {
const built = spawnSync('npm', ['run', 'build'], { cwd: server, encoding: 'utf8' });
expect(built.status, built.stderr).toBe(0);
const started = spawnSync(process.execPath, ['dist/main.mjs'], { cwd: server, encoding: 'utf8', env: { PATH: process.env.PATH }, timeout: 20_000 });
expect(started.status, started.stderr).toBe(1);
expect(JSON.parse(started.stdout.trim().split('\n').at(-1)!)).toMatchObject({
event: 'config.missing',
variables: ['DATABASE_URL', 'FILIUS_TICKET_SECRET', 'FILIUS_SERVICE_KEY', 'FILIUS_ORIGINS'],
});
}, 60_000);
});