feat(wip): 시나리오 로더 및 파서 구현, 관련 타입 추가

This commit is contained in:
2025-12-28 14:42:23 +00:00
parent fab128943c
commit afe5cadd9f
11 changed files with 507 additions and 2 deletions
+2 -1
View File
@@ -10,7 +10,8 @@
"test": "vitest run --config vitest.config.ts"
},
"dependencies": {
"@sammo-ts/common": "workspace:*"
"@sammo-ts/common": "workspace:*",
"@sammo-ts/logic": "workspace:*"
},
"devDependencies": {
"tsdown": "^0.18.3",
+1
View File
@@ -3,3 +3,4 @@ export * from './lifecycle/clock.js';
export * from './lifecycle/inMemoryControlQueue.js';
export * from './lifecycle/turnSchedule.js';
export * from './lifecycle/turnDaemonLifecycle.js';
export * from './scenario/scenarioLoader.js';
@@ -0,0 +1,60 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import {
parseScenarioDefaults,
parseScenarioDefinition,
type ScenarioDefaults,
type ScenarioDefinition,
} from '@sammo-ts/logic';
export interface ScenarioLoaderOptions {
scenarioRoot: string;
defaultsFileName?: string;
}
const readJsonFile = async (filePath: string): Promise<unknown> => {
const raw = await fs.readFile(filePath, 'utf8');
return JSON.parse(raw) as unknown;
};
export const resolveScenarioDefaultsPath = (
options: ScenarioLoaderOptions
): string =>
path.resolve(
options.scenarioRoot,
options.defaultsFileName ?? 'default.json'
);
export const resolveScenarioPath = (
options: ScenarioLoaderOptions,
scenarioId: number
): string => path.resolve(options.scenarioRoot, `scenario_${scenarioId}.json`);
export const loadScenarioDefaults = async (
defaultsPath: string
): Promise<ScenarioDefaults> => {
// 기본 시나리오 파일을 읽고 정규화한다.
const raw = await readJsonFile(defaultsPath);
return parseScenarioDefaults(raw);
};
export const loadScenarioDefinition = async (
scenarioPath: string,
defaults: ScenarioDefaults
): Promise<ScenarioDefinition> => {
// 시나리오 본문을 읽고 기본값과 합쳐서 파싱한다.
const raw = await readJsonFile(scenarioPath);
return parseScenarioDefinition(raw, defaults);
};
export const loadScenarioDefinitionById = async (
scenarioId: number,
options: ScenarioLoaderOptions
): Promise<ScenarioDefinition> => {
// 시나리오 번호로 파일을 찾고 파싱한다.
const defaultsPath = resolveScenarioDefaultsPath(options);
const scenarioPath = resolveScenarioPath(options, scenarioId);
const defaults = await loadScenarioDefaults(defaultsPath);
return loadScenarioDefinition(scenarioPath, defaults);
};