Add full HWE lifecycle browser verification
This commit is contained in:
@@ -1,22 +1,21 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
const WORKSPACE_MARKERS = ['pnpm-workspace.yaml', 'package.json'];
|
||||
|
||||
const hasWorkspaceMarker = (dir: string): boolean =>
|
||||
WORKSPACE_MARKERS.some((marker) => fs.existsSync(path.join(dir, marker)));
|
||||
|
||||
export const resolveWorkspaceRoot = (startDir: string, maxDepth = 5): string => {
|
||||
let current = path.resolve(startDir);
|
||||
let packageRoot: string | null = null;
|
||||
for (let depth = 0; depth <= maxDepth; depth += 1) {
|
||||
if (hasWorkspaceMarker(current)) {
|
||||
if (fs.existsSync(path.join(current, 'pnpm-workspace.yaml'))) {
|
||||
return current;
|
||||
}
|
||||
if (!packageRoot && fs.existsSync(path.join(current, 'package.json'))) {
|
||||
packageRoot = current;
|
||||
}
|
||||
const parent = path.dirname(current);
|
||||
if (parent === current) {
|
||||
break;
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
return path.resolve(startDir);
|
||||
return packageRoot ?? path.resolve(startDir);
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { loadScenarioDefinitionById, resolveScenarioDefaultsPath } from '@sammo-ts/game-engine';
|
||||
import { parseScenarioDefaults, parseScenarioDefinition, type ScenarioDefaults } from '@sammo-ts/logic';
|
||||
import { resolveWorkspaceRoot } from '../orchestrator/workspaceRoot.js';
|
||||
|
||||
export interface ScenarioNationPreview {
|
||||
id: number;
|
||||
@@ -34,7 +35,7 @@ const SCENARIO_ROOT = path.join('resources', 'scenario');
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const REPO_ROOT = path.resolve(__dirname, '..', '..', '..', '..');
|
||||
const REPO_ROOT = resolveWorkspaceRoot(process.env.GATEWAY_WORKSPACE_ROOT ?? __dirname);
|
||||
|
||||
const previewCache = new Map<string, { loadedAt: number; data: ScenarioPreview[] }>();
|
||||
const defaultsCache = new Map<string, ScenarioDefaults>();
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
import { afterEach, describe, expect, it } from 'vitest';
|
||||
|
||||
import { resolveWorkspaceRoot } from '../src/orchestrator/workspaceRoot.js';
|
||||
|
||||
const tempDirs: string[] = [];
|
||||
|
||||
const makeTempDir = (): string => {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'sammo-workspace-root-'));
|
||||
tempDirs.push(dir);
|
||||
return dir;
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
for (const dir of tempDirs.splice(0)) {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
describe('resolveWorkspaceRoot', () => {
|
||||
it('prefers the pnpm workspace above a nested package', () => {
|
||||
const root = makeTempDir();
|
||||
const packageDir = path.join(root, 'app', 'gateway-api');
|
||||
const sourceDir = path.join(packageDir, 'dist');
|
||||
fs.mkdirSync(sourceDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(root, 'pnpm-workspace.yaml'), 'packages: []\n');
|
||||
fs.writeFileSync(path.join(packageDir, 'package.json'), '{}\n');
|
||||
|
||||
expect(resolveWorkspaceRoot(sourceDir)).toBe(root);
|
||||
});
|
||||
|
||||
it('falls back to the nearest package when there is no workspace marker', () => {
|
||||
const root = makeTempDir();
|
||||
const sourceDir = path.join(root, 'src', 'nested');
|
||||
fs.mkdirSync(sourceDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(root, 'package.json'), '{}\n');
|
||||
|
||||
expect(resolveWorkspaceRoot(sourceDir)).toBe(root);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user