Initial import

This commit is contained in:
how2ice
2026-04-21 03:33:23 +09:00
commit 9e4b70f1f1
495 changed files with 94680 additions and 0 deletions

View File

@@ -0,0 +1,138 @@
import fs from 'node:fs';
import { readFile } from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
export type WorkServerBuildInfo = {
version: string;
buildId: string;
builtAt: string;
};
export type WorkServerSourceChangeInfo = {
changedAt: string;
path: string;
};
const MODULE_DIR_PATH = path.dirname(fileURLToPath(import.meta.url));
const WORK_SERVER_ROOT_PATH = path.resolve(MODULE_DIR_PATH, '..', '..');
const BUILD_INFO_FILE_PATH = path.join(WORK_SERVER_ROOT_PATH, 'dist', 'build-info.json');
const SOURCE_TARGET_PATHS = [
path.join(WORK_SERVER_ROOT_PATH, 'src'),
path.join(WORK_SERVER_ROOT_PATH, 'scripts'),
path.join(WORK_SERVER_ROOT_PATH, 'package.json'),
path.join(WORK_SERVER_ROOT_PATH, 'tsconfig.json'),
] as const;
function normalizeBuildInfo(value: unknown): WorkServerBuildInfo | null {
if (!value || typeof value !== 'object') {
return null;
}
const candidate = value as Partial<Record<keyof WorkServerBuildInfo, unknown>>;
if (
typeof candidate.version !== 'string' ||
typeof candidate.buildId !== 'string' ||
typeof candidate.builtAt !== 'string'
) {
return null;
}
const builtAt = new Date(candidate.builtAt);
if (Number.isNaN(builtAt.getTime())) {
return null;
}
return {
version: candidate.version,
buildId: candidate.buildId,
builtAt: builtAt.toISOString(),
};
}
function readBuildInfoFromDiskSync(filePath: string) {
try {
if (!fs.existsSync(filePath)) {
return null;
}
return normalizeBuildInfo(JSON.parse(fs.readFileSync(filePath, 'utf8')));
} catch {
return null;
}
}
export async function readLatestWorkServerBuildInfo() {
try {
return normalizeBuildInfo(JSON.parse(await readFile(BUILD_INFO_FILE_PATH, 'utf8')));
} catch {
return null;
}
}
const runtimeWorkServerBuildInfo = readBuildInfoFromDiskSync(BUILD_INFO_FILE_PATH);
export function getRuntimeWorkServerBuildInfo() {
return runtimeWorkServerBuildInfo;
}
async function findLatestSourceChangeInPath(targetPath: string): Promise<WorkServerSourceChangeInfo | null> {
try {
const stats = await fs.promises.stat(targetPath);
if (stats.isFile()) {
return {
changedAt: stats.mtime.toISOString(),
path: path.relative(WORK_SERVER_ROOT_PATH, targetPath) || path.basename(targetPath),
};
}
if (!stats.isDirectory()) {
return null;
}
const entries = await fs.promises.readdir(targetPath, { withFileTypes: true });
let latest: WorkServerSourceChangeInfo | null = null;
for (const entry of entries) {
if (entry.name === 'node_modules' || entry.name === 'dist' || entry.name === '.docker') {
continue;
}
const childPath = path.join(targetPath, entry.name);
const childLatest = await findLatestSourceChangeInPath(childPath);
if (!childLatest) {
continue;
}
if (!latest || childLatest.changedAt > latest.changedAt) {
latest = childLatest;
}
}
return latest;
} catch {
return null;
}
}
export async function readLatestWorkServerSourceChange() {
let latest: WorkServerSourceChangeInfo | null = null;
for (const targetPath of SOURCE_TARGET_PATHS) {
const candidate = await findLatestSourceChangeInPath(targetPath);
if (!candidate) {
continue;
}
if (!latest || candidate.changedAt > latest.changedAt) {
latest = candidate;
}
}
return latest;
}