mirror of
https://github.com/fluxerapp/fluxer.git
synced 2026-09-02 21:04:06 +03:00
88 lines
2.7 KiB
JavaScript
88 lines
2.7 KiB
JavaScript
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
import {existsSync, readFileSync, rmSync, statSync} from 'node:fs';
|
|
import {isBuiltin} from 'node:module';
|
|
import {dirname, join, resolve} from 'node:path';
|
|
import {fileURLToPath} from 'node:url';
|
|
import {build} from 'esbuild';
|
|
|
|
const API_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
const REPO_ROOT = resolve(API_ROOT, '..');
|
|
const OUT_DIR = join(API_ROOT, 'dist');
|
|
const CANDIDATE_SUFFIXES = ['', '.ts', '.tsx', '.js', '.mjs', '/index.ts', '/index.tsx', '/index.js', '/src/index.ts'];
|
|
|
|
const WORKSPACE_ROOTS = {
|
|
'@app/': join(API_ROOT, 'src'),
|
|
'@pkgs/': join(API_ROOT, 'pkgs'),
|
|
'@fluxer/': join(REPO_ROOT, 'packages'),
|
|
};
|
|
|
|
function resolveWorkspacePath(specifier) {
|
|
for (const [prefix, root] of Object.entries(WORKSPACE_ROOTS)) {
|
|
if (!specifier.startsWith(prefix)) {
|
|
continue;
|
|
}
|
|
const base = join(root, specifier.slice(prefix.length));
|
|
for (const suffix of CANDIDATE_SUFFIXES) {
|
|
const candidate = `${base}${suffix}`;
|
|
if (existsSync(candidate) && statSync(candidate).isFile()) {
|
|
return candidate;
|
|
}
|
|
}
|
|
throw new Error(`Unable to resolve workspace import ${specifier}`);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function packageNameOf(specifier) {
|
|
const segments = specifier.split('/');
|
|
return specifier.startsWith('@') ? segments.slice(0, 2).join('/') : segments[0];
|
|
}
|
|
|
|
const declaredDependencies = new Set(
|
|
Object.keys(JSON.parse(readFileSync(join(API_ROOT, 'package.json'), 'utf-8')).dependencies),
|
|
);
|
|
const undeclaredDependencies = new Set();
|
|
|
|
const workspacePlugin = {
|
|
name: 'fluxer-workspace',
|
|
setup(pluginBuild) {
|
|
pluginBuild.onResolve({filter: /^[^./]/}, (args) => {
|
|
const workspacePath = resolveWorkspacePath(args.path);
|
|
if (workspacePath) {
|
|
return {path: workspacePath};
|
|
}
|
|
const packageName = packageNameOf(args.path);
|
|
if (!isBuiltin(args.path) && !declaredDependencies.has(packageName)) {
|
|
undeclaredDependencies.add(packageName);
|
|
}
|
|
return {path: args.path, external: true};
|
|
});
|
|
},
|
|
};
|
|
|
|
rmSync(OUT_DIR, {recursive: true, force: true});
|
|
|
|
await build({
|
|
entryPoints: [join(API_ROOT, 'src/AppEntrypoint.ts'), join(API_ROOT, 'src/WorkerEntrypoint.ts')],
|
|
outdir: OUT_DIR,
|
|
bundle: true,
|
|
platform: 'node',
|
|
format: 'esm',
|
|
target: 'node24',
|
|
charset: 'utf8',
|
|
sourcemap: true,
|
|
sourcesContent: false,
|
|
logLevel: 'info',
|
|
banner: {js: '// SPDX-License-Identifier: AGPL-3.0-or-later'},
|
|
plugins: [workspacePlugin],
|
|
});
|
|
|
|
if (undeclaredDependencies.size > 0) {
|
|
const names = [...undeclaredDependencies].sort().join(', ');
|
|
throw new Error(
|
|
`The bundle imports packages that fluxer_api does not declare as dependencies: ${names}. ` +
|
|
'Workspace packages keep their own node_modules, so the bundle cannot reach them from fluxer_api.',
|
|
);
|
|
}
|