feat: eslint 적용 및 관련 코드 일괄 수정

This commit is contained in:
2026-01-05 15:46:47 +00:00
parent cb312f02b3
commit c965b1120f
387 changed files with 39808 additions and 38800 deletions
+19 -82
View File
@@ -1,14 +1,5 @@
import type {
City,
General,
GeneralTriggerState,
Nation,
TriggerValue,
} from '@sammo-ts/logic/domain/entities.js';
import type {
ScenarioDefinition,
ScenarioGeneral,
} from '@sammo-ts/logic/scenario/types.js';
import type { City, General, GeneralTriggerState, Nation, TriggerValue } from '@sammo-ts/logic/domain/entities.js';
import type { ScenarioDefinition, ScenarioGeneral } from '@sammo-ts/logic/scenario/types.js';
import type {
CitySeed,
GeneralSeed,
@@ -97,35 +88,17 @@ const addTriggerMeta = (
meta[key] = value;
};
const resolveMapDefaults = (
map: MapDefinition,
options?: ScenarioBootstrapOptions
): MapDefaults => {
const resolveMapDefaults = (map: MapDefinition, options?: ScenarioBootstrapOptions): MapDefaults => {
const override = options?.mapDefaults ?? {};
return {
trust:
override.trust ??
map.defaults?.trust ??
DEFAULT_CITY_TRUST,
trade:
override.trade ??
map.defaults?.trade ??
DEFAULT_CITY_TRADE,
supplyState:
override.supplyState ??
map.defaults?.supplyState ??
DEFAULT_CITY_SUPPLY_STATE,
frontState:
override.frontState ??
map.defaults?.frontState ??
DEFAULT_CITY_FRONT_STATE,
trust: override.trust ?? map.defaults?.trust ?? DEFAULT_CITY_TRUST,
trade: override.trade ?? map.defaults?.trade ?? DEFAULT_CITY_TRADE,
supplyState: override.supplyState ?? map.defaults?.supplyState ?? DEFAULT_CITY_SUPPLY_STATE,
frontState: override.frontState ?? map.defaults?.frontState ?? DEFAULT_CITY_FRONT_STATE,
};
};
const resolveNationType = (
rawType: string,
prefix: string
): string => {
const resolveNationType = (rawType: string, prefix: string): string => {
const trimmed = rawType.trim();
if (!trimmed) {
return `${prefix}중립`;
@@ -136,10 +109,7 @@ const resolveNationType = (
return `${prefix}${trimmed}`;
};
const resolveBirthYear = (
birthYear: number,
startYear: number | null
): number => {
const resolveBirthYear = (birthYear: number, startYear: number | null): number => {
if (birthYear > 0) {
return birthYear;
}
@@ -149,11 +119,7 @@ const resolveBirthYear = (
return 0;
};
const resolveDeathYear = (
deathYear: number,
birthYear: number,
startYear: number | null
): number => {
const resolveDeathYear = (deathYear: number, birthYear: number, startYear: number | null): number => {
if (deathYear > 0) {
return deathYear;
}
@@ -253,24 +219,10 @@ const buildGeneralSeeds = (
const id = nextId;
nextId += 1;
const nationId = resolveNationId(
row.nation,
nationNameToId,
warnings,
row.name
);
const cityId = resolveCityId(
row.city,
cityByName,
warnings,
row.name
);
const nationId = resolveNationId(row.nation, nationNameToId, warnings, row.name);
const cityId = resolveCityId(row.city, cityByName, warnings, row.name);
const birthYear = resolveBirthYear(row.birthYear, scenario.startYear);
const deathYear = resolveDeathYear(
row.deathYear,
birthYear,
scenario.startYear
);
const deathYear = resolveDeathYear(row.deathYear, birthYear, scenario.startYear);
const officerLevel = resolveOfficerLevel(row.officerLevel, nationId);
const age = resolveAge(scenario.startYear, birthYear);
const stats = {
@@ -346,11 +298,7 @@ const buildGeneralSeeds = (
addTriggerMeta(generalMeta, 'personality', row.personality ?? undefined);
addTriggerMeta(generalMeta, 'special', row.special ?? undefined);
addTriggerMeta(generalMeta, 'picture', row.picture ?? undefined);
addTriggerMeta(
generalMeta,
'specialWar',
row.specialWar ?? undefined
);
addTriggerMeta(generalMeta, 'specialWar', row.specialWar ?? undefined);
addTriggerMeta(generalMeta, 'horse', row.horse ?? undefined);
addTriggerMeta(generalMeta, 'weapon', row.weapon ?? undefined);
addTriggerMeta(generalMeta, 'book', row.book ?? undefined);
@@ -398,9 +346,7 @@ const buildGeneralSeeds = (
};
// 시나리오, 맵, 유닛셋을 묶어 초기 월드 스냅샷과 시드 데이터를 만든다.
export const buildScenarioBootstrap = (
input: ScenarioBootstrapInput
): ScenarioBootstrapResult => {
export const buildScenarioBootstrap = (input: ScenarioBootstrapInput): ScenarioBootstrapResult => {
const { scenario, map, unitSet, options } = input;
const warnings: ScenarioBootstrapWarning[] = [];
@@ -411,11 +357,7 @@ export const buildScenarioBootstrap = (
message: `Scenario mapName ${environment.mapName} does not match map definition ${map.id}.`,
});
}
if (
unitSet &&
unitSet.id !== environment.unitSet &&
unitSet.name !== environment.unitSet
) {
if (unitSet && unitSet.id !== environment.unitSet && unitSet.name !== environment.unitSet) {
warnings.push({
code: 'unit_set_mismatch',
message: `Scenario unitSet ${environment.unitSet} does not match unit set ${unitSet.id}.`,
@@ -467,15 +409,13 @@ export const buildScenarioBootstrap = (
}
const scenarioMeta = createScenarioMeta(scenario);
const typePrefix =
options?.nationTypePrefix ?? `${environment.mapName}_`;
const typePrefix = options?.nationTypePrefix ?? `${environment.mapName}_`;
const seedNations: NationSeed[] = [];
const domainNations: Nation[] = [];
const includeNeutralNation = options?.includeNeutralNation ?? true;
const includeNeutralNationInSeed =
options?.includeNeutralNationInSeed ?? false;
const includeNeutralNationInSeed = options?.includeNeutralNationInSeed ?? false;
if (includeNeutralNation) {
const neutralNation: Nation = {
id: 0,
@@ -550,10 +490,7 @@ export const buildScenarioBootstrap = (
}
const mapDefaults = resolveMapDefaults(map, options);
const defaultCrewTypeId =
unitSet?.defaultCrewTypeId ??
options?.defaultCrewTypeId ??
DEFAULT_CREWTYPE_ID;
const defaultCrewTypeId = unitSet?.defaultCrewTypeId ?? options?.defaultCrewTypeId ?? DEFAULT_CREWTYPE_ID;
const seedCities: CitySeed[] = [];
const domainCities: City[] = [];
+7 -26
View File
@@ -1,25 +1,15 @@
import type { City, General, Nation, Troop } from '@sammo-ts/logic/domain/entities.js';
import type { ScenarioConfig, ScenarioDiplomacy } from '@sammo-ts/logic/scenario/types.js';
import type { ScenarioConfigSource, WorldStateSnapshotSource } from '@sammo-ts/logic/ports/worldSnapshot.js';
import type {
MapDefinition,
ScenarioMeta,
UnitSetDefinition,
WorldSnapshot,
} from './types.js';
import type { MapDefinition, ScenarioMeta, UnitSetDefinition, WorldSnapshot } from './types.js';
export interface WorldSnapshotLoadInput<
GeneralType extends General = General,
CityType extends City = City,
NationType extends Nation = Nation,
TroopType extends Troop = Troop
TroopType extends Troop = Troop,
> {
worldSource: WorldStateSnapshotSource<
GeneralType,
CityType,
NationType,
TroopType
>;
worldSource: WorldStateSnapshotSource<GeneralType, CityType, NationType, TroopType>;
scenarioConfig?: ScenarioConfig;
scenarioMeta?: ScenarioMeta;
scenarioSource?: ScenarioConfigSource;
@@ -35,29 +25,20 @@ export const loadWorldSnapshot = async <
GeneralType extends General,
CityType extends City,
NationType extends Nation,
TroopType extends Troop
TroopType extends Troop,
>(
input: WorldSnapshotLoadInput<
GeneralType,
CityType,
NationType,
TroopType
>
input: WorldSnapshotLoadInput<GeneralType, CityType, NationType, TroopType>
): Promise<WorldSnapshot> => {
const { worldSource, scenarioSource } = input;
const scenarioConfig =
input.scenarioConfig ??
(scenarioSource ? await scenarioSource.loadScenarioConfig() : undefined);
input.scenarioConfig ?? (scenarioSource ? await scenarioSource.loadScenarioConfig() : undefined);
if (!scenarioConfig) {
throw new Error('Scenario config is required to load world snapshot.');
}
const scenarioMeta =
input.scenarioMeta ??
(scenarioSource?.loadScenarioMeta
? await scenarioSource.loadScenarioMeta()
: undefined);
input.scenarioMeta ?? (scenarioSource?.loadScenarioMeta ? await scenarioSource.loadScenarioMeta() : undefined);
const [generals, cities, nations, troops] = await Promise.all([
worldSource.listGenerals(),
+2 -11
View File
@@ -1,14 +1,5 @@
import type {
City,
General,
Nation,
StatBlock,
Troop,
} from '@sammo-ts/logic/domain/entities.js';
import type {
ScenarioConfig,
ScenarioDiplomacy,
} from '@sammo-ts/logic/scenario/types.js';
import type { City, General, Nation, StatBlock, Troop } from '@sammo-ts/logic/domain/entities.js';
import type { ScenarioConfig, ScenarioDiplomacy } from '@sammo-ts/logic/scenario/types.js';
export interface ScenarioMeta {
title: string;
+31 -100
View File
@@ -1,10 +1,5 @@
import type { City, General, Nation } from '@sammo-ts/logic/domain/entities.js';
import type {
CrewTypeDefinition,
CrewTypeRequirement,
MapDefinition,
UnitSetDefinition,
} from './types.js';
import type { CrewTypeDefinition, CrewTypeRequirement, MapDefinition, UnitSetDefinition } from './types.js';
const DEFAULT_REGION_MAP: Record<string, number> = {
하북: 1,
@@ -22,19 +17,15 @@ const DEFAULT_MAX_TECH_LEVEL = 12;
const isRecord = (value: unknown): value is Record<string, unknown> =>
value !== null && typeof value === 'object' && !Array.isArray(value);
const asRecord = (value: unknown): Record<string, unknown> =>
isRecord(value) ? value : {};
const asRecord = (value: unknown): Record<string, unknown> => (isRecord(value) ? value : {});
const asNumber = (value: unknown, fallback: number): number =>
typeof value === 'number' && Number.isFinite(value) ? value : fallback;
const asString = (value: unknown, fallback: string): string =>
typeof value === 'string' ? value : fallback;
const asString = (value: unknown, fallback: string): string => (typeof value === 'string' ? value : fallback);
const asStringArray = (value: unknown): string[] =>
Array.isArray(value)
? value.filter((item): item is string => typeof item === 'string')
: [];
Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : [];
const asNullableStringArray = (value: unknown): string[] | null => {
if (value === null || value === undefined) {
@@ -88,11 +79,7 @@ const parseRequirement = (value: unknown): CrewTypeRequirement | null => {
type,
key: asString(value.key, ''),
op: asString(value.op, '=='),
value:
typeof value.value === 'number' ||
typeof value.value === 'string'
? value.value
: 0,
value: typeof value.value === 'number' || typeof value.value === 'string' ? value.value : 0,
};
case 'ReqMinRelYear':
return { type, year: asNumber(value.year, 0) };
@@ -114,9 +101,7 @@ const parseCrewType = (value: unknown): CrewTypeDefinition | null => {
return null;
}
const requirements = Array.isArray(value.requirements)
? value.requirements
.map(parseRequirement)
.filter((entry): entry is CrewTypeRequirement => entry !== null)
? value.requirements.map(parseRequirement).filter((entry): entry is CrewTypeRequirement => entry !== null)
: [];
return {
@@ -149,20 +134,15 @@ export const parseUnitSetDefinition = (value: unknown): UnitSetDefinition => {
? data.defaultCrewTypeId
: null;
const armTypes = isRecord(data.armTypes)
? Object.entries(data.armTypes).reduce<Record<string, string>>(
(acc, [key, entry]) => {
if (typeof entry === 'string') {
acc[key] = entry;
}
return acc;
},
{}
)
? Object.entries(data.armTypes).reduce<Record<string, string>>((acc, [key, entry]) => {
if (typeof entry === 'string') {
acc[key] = entry;
}
return acc;
}, {})
: undefined;
const crewTypes = Array.isArray(data.crewTypes)
? data.crewTypes
.map(parseCrewType)
.filter((entry): entry is CrewTypeDefinition => entry !== null)
? data.crewTypes.map(parseCrewType).filter((entry): entry is CrewTypeDefinition => entry !== null)
: [];
const result: UnitSetDefinition = {
@@ -182,9 +162,7 @@ export const parseUnitSetDefinition = (value: unknown): UnitSetDefinition => {
return result;
};
export const buildCrewTypeIndex = (
unitSet: UnitSetDefinition | null | undefined
): Map<number, CrewTypeDefinition> => {
export const buildCrewTypeIndex = (unitSet: UnitSetDefinition | null | undefined): Map<number, CrewTypeDefinition> => {
const index = new Map<number, CrewTypeDefinition>();
for (const crewType of unitSet?.crewTypes ?? []) {
index.set(crewType.id, crewType);
@@ -202,10 +180,7 @@ export const findCrewTypeById = (
return unitSet.crewTypes.find((crewType) => crewType.id === crewTypeId) ?? null;
};
export const getTechLevel = (
tech: number,
maxLevel = DEFAULT_MAX_TECH_LEVEL
): number => {
export const getTechLevel = (tech: number, maxLevel = DEFAULT_MAX_TECH_LEVEL): number => {
if (!Number.isFinite(tech)) {
return 0;
}
@@ -263,7 +238,9 @@ const resolveRegionMap = (map: MapDefinition): Record<string, number> => {
return Object.keys(extracted).length > 0 ? extracted : DEFAULT_REGION_MAP;
};
const buildCityIndex = (map: MapDefinition): {
const buildCityIndex = (
map: MapDefinition
): {
nameToId: Map<string, number>;
regionById: Map<number, number>;
} => {
@@ -276,23 +253,10 @@ const buildCityIndex = (map: MapDefinition): {
return { nameToId, regionById };
};
const compareAuxValue = (
actual: unknown,
op: string,
expected: number | string
): boolean => {
const actualNum =
typeof actual === 'number'
? actual
: typeof actual === 'string'
? Number(actual)
: Number.NaN;
const compareAuxValue = (actual: unknown, op: string, expected: number | string): boolean => {
const actualNum = typeof actual === 'number' ? actual : typeof actual === 'string' ? Number(actual) : Number.NaN;
const expectedNum =
typeof expected === 'number'
? expected
: typeof expected === 'string'
? Number(expected)
: Number.NaN;
typeof expected === 'number' ? expected : typeof expected === 'string' ? Number(expected) : Number.NaN;
if (!Number.isNaN(actualNum) && !Number.isNaN(expectedNum)) {
switch (op) {
@@ -314,9 +278,7 @@ const compareAuxValue = (
}
if (op === '!=' || op === '==') {
return op === '!='
? String(actual ?? '') !== String(expected)
: String(actual ?? '') === String(expected);
return op === '!=' ? String(actual ?? '') !== String(expected) : String(actual ?? '') === String(expected);
}
return false;
};
@@ -333,10 +295,7 @@ export const isCrewTypeAvailable = (
}
const nationId = context.nation?.id ?? context.general.nationId;
const ownedCities =
nationId !== undefined
? context.cities.filter((city) => city.nationId === nationId)
: [];
const ownedCities = nationId !== undefined ? context.cities.filter((city) => city.nationId === nationId) : [];
const ownedCityMap = new Map<number, City>();
for (const city of ownedCities) {
ownedCityMap.set(city.id, city);
@@ -359,19 +318,12 @@ export const isCrewTypeAvailable = (
for (const requirement of crewType.requirements) {
switch (requirement.type) {
case 'ReqTech':
if (
tech <
(requirement as Extract<CrewTypeRequirement, { type: 'ReqTech' }>).tech
) {
if (tech < (requirement as Extract<CrewTypeRequirement, { type: 'ReqTech' }>).tech) {
return false;
}
break;
case 'ReqRegions': {
const req =
requirement as Extract<
CrewTypeRequirement,
{ type: 'ReqRegions' }
>;
const req = requirement as Extract<CrewTypeRequirement, { type: 'ReqRegions' }>;
const resolved = req.regions
.map((name: string) => regionMap[name])
.filter((id): id is number => typeof id === 'number');
@@ -381,11 +333,7 @@ export const isCrewTypeAvailable = (
break;
}
case 'ReqCities': {
const req =
requirement as Extract<
CrewTypeRequirement,
{ type: 'ReqCities' }
>;
const req = requirement as Extract<CrewTypeRequirement, { type: 'ReqCities' }>;
const resolved = req.cities
.map((name: string) => nameToId.get(name))
.filter((id): id is number => typeof id === 'number');
@@ -395,11 +343,7 @@ export const isCrewTypeAvailable = (
break;
}
case 'ReqCitiesWithCityLevel': {
const req =
requirement as Extract<
CrewTypeRequirement,
{ type: 'ReqCitiesWithCityLevel' }
>;
const req = requirement as Extract<CrewTypeRequirement, { type: 'ReqCitiesWithCityLevel' }>;
const resolved = req.cities
.map((name: string) => nameToId.get(name))
.filter((id): id is number => typeof id === 'number');
@@ -414,25 +358,15 @@ export const isCrewTypeAvailable = (
break;
}
case 'ReqHighLevelCities': {
const req =
requirement as Extract<
CrewTypeRequirement,
{ type: 'ReqHighLevelCities' }
>;
const count = ownedCities.filter(
(city) => city.level >= req.level
).length;
const req = requirement as Extract<CrewTypeRequirement, { type: 'ReqHighLevelCities' }>;
const count = ownedCities.filter((city) => city.level >= req.level).length;
if (count < req.count) {
return false;
}
break;
}
case 'ReqNationAux': {
const req =
requirement as Extract<
CrewTypeRequirement,
{ type: 'ReqNationAux' }
>;
const req = requirement as Extract<CrewTypeRequirement, { type: 'ReqNationAux' }>;
const value = aux[req.key];
if (!compareAuxValue(value, req.op, req.value)) {
return false;
@@ -440,10 +374,7 @@ export const isCrewTypeAvailable = (
break;
}
case 'ReqMinRelYear':
if (
relYear <
(requirement as Extract<CrewTypeRequirement, { type: 'ReqMinRelYear' }>).year
) {
if (relYear < (requirement as Extract<CrewTypeRequirement, { type: 'ReqMinRelYear' }>).year) {
return false;
}
break;