Page MenuHomeSealhub

build.ts
No OneTemporary

build.ts

import { promises as fs } from "fs";
import * as chokidar from "chokidar";
import { make_notifier } from "./notifier.js";
import getPort from "get-port";
import { resolve } from "node:path";
import _locreq from "locreq";
import {
BackendTSBuilder,
FontsBuilder,
FrontendTSBuilder,
} from "./builder.js";
import { CSSBuilder } from "./CSSBuilder.js";
import { hasShape, predicates } from "@sealcode/ts-predicates";
const target_locreq = _locreq(process.cwd());
async function get_notifier_port() {
return getPort({ port: 4000 });
}
async function write_notifier_config(watch: boolean, port?: number) {
const config = { watch } as Record<string, boolean | number>;
if (port) {
config.port = port;
}
await fs.writeFile(
target_locreq.resolve("public/dist/notifier.json"),
JSON.stringify(config)
);
}
const package_json_shape = {
sealgen: predicates.maybe(
predicates.shape({
styleDirs: predicates.maybe(predicates.array(predicates.string)),
controllerDirs: predicates.maybe(
predicates.array(predicates.string)
),
copyToPublic: predicates.maybe(
predicates.array(
predicates.shape({
from: predicates.string,
to: predicates.string,
})
)
),
})
),
};
async function build(watch: boolean): Promise<void> {
const project_dir = target_locreq.resolve("");
const package_json = JSON.parse(
await fs.readFile(resolve(project_dir, "package.json"), "utf-8")
) as Record<string, unknown>;
if (!hasShape(package_json_shape, package_json)) {
throw new Error("Misshaped package.json props");
}
const style_dirs = package_json.sealgen?.styleDirs || [];
const controller_dirs = package_json.sealgen?.controllerDirs || [];
const copy_to_public = package_json.sealgen?.copyToPublic || [];
await Promise.all(
copy_to_public.map(async ({ from, to }) => {
try {
await fs.stat(resolve(project_dir, "public", to));
} catch (e) {
await fs.mkdir(resolve(project_dir, "public", to, "../"), {
recursive: true,
});
await fs.symlink(
resolve(project_dir, from),
resolve(project_dir, "public", to)
);
}
})
);
const fonts_builder = new FontsBuilder(project_dir, style_dirs);
const backend_ts_builder = new BackendTSBuilder(project_dir, style_dirs);
const frontend_ts_builder = new FrontendTSBuilder(
project_dir,
style_dirs,
controller_dirs
);
const css_builder = new CSSBuilder(project_dir, style_dirs);
const builders = [
fonts_builder,
backend_ts_builder,
css_builder,
frontend_ts_builder,
];
await Promise.all(builders.map((b) => b.build()));
if (watch) {
const watcher = chokidar.watch("src", { ignoreInitial: true });
const port = await get_notifier_port();
const notifier = make_notifier(port);
await write_notifier_config(watch, port);
watcher.on("all", (_, file_path) => {
console.log("Detected a change!", file_path);
builders.forEach((builder) => {
const owns_a_file = builder.ownsFile(file_path);
if (owns_a_file) {
void builder.build(notifier);
}
});
});
} else {
await write_notifier_config(watch);
builders.forEach((builder) => {
void builder.dispose();
});
}
}
export async function buildProject({
watch,
}: {
watch: boolean;
}): Promise<void> {
try {
await build(watch);
} catch (e) {
console.log("CAUGHT!");
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
console.error(e.message);
if (!watch) {
process.exit(1);
}
}
}

File Metadata

Mime Type
text/x-java
Expires
Tue, Dec 24, 14:02 (17 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
557147
Default Alt Text
build.ts (3 KB)

Event Timeline