Merge branch 'main' into refactor/typed-action-protocol
# Conflicts: # docs/developer/index.md
This commit is contained in:
@@ -17,9 +17,11 @@ export const ScenarioDefaultsInputSchema = z.object({
|
||||
iconPath: z.string().optional(),
|
||||
});
|
||||
|
||||
export const ScenarioDefinitionInputSchema = z
|
||||
export const ScenarioExtendsInputSchema = z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]);
|
||||
|
||||
const ScenarioBodyInputSchema = z
|
||||
.object({
|
||||
title: z.string(),
|
||||
extends: ScenarioExtendsInputSchema.optional(),
|
||||
startYear: z.number().optional(),
|
||||
life: z.number().optional(),
|
||||
fiction: z.number().optional(),
|
||||
@@ -41,7 +43,20 @@ export const ScenarioDefinitionInputSchema = z
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
export const ScenarioResourceSchema = z.union([ScenarioDefaultsInputSchema, ScenarioDefinitionInputSchema]);
|
||||
export const ScenarioDefinitionInputSchema = ScenarioBodyInputSchema.extend({
|
||||
title: z.string(),
|
||||
});
|
||||
|
||||
export const ScenarioFragmentInputSchema = ScenarioBodyInputSchema.extend({
|
||||
title: z.never().optional(),
|
||||
});
|
||||
|
||||
export const ScenarioResourceSchema = z.union([
|
||||
ScenarioDefaultsInputSchema,
|
||||
ScenarioDefinitionInputSchema,
|
||||
ScenarioFragmentInputSchema,
|
||||
]);
|
||||
|
||||
export type ScenarioDefaultsInput = z.infer<typeof ScenarioDefaultsInputSchema>;
|
||||
export type ScenarioDefinitionInput = z.infer<typeof ScenarioDefinitionInputSchema>;
|
||||
export type ScenarioFragmentInput = z.infer<typeof ScenarioFragmentInputSchema>;
|
||||
|
||||
@@ -4,6 +4,8 @@ import { fileURLToPath } from 'node:url';
|
||||
|
||||
import {
|
||||
MapResourceSchema,
|
||||
ScenarioDefinitionInputSchema,
|
||||
ScenarioFragmentInputSchema,
|
||||
ScenarioResourceSchema,
|
||||
TurnCommandProfileInputSchema,
|
||||
UnitSetDefinitionInputSchema,
|
||||
@@ -23,10 +25,17 @@ const RESOURCE_SCHEMAS: Record<string, (value: unknown) => void> = {
|
||||
|
||||
const listJsonFiles = async (dirPath: string): Promise<string[]> => {
|
||||
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
||||
return entries
|
||||
.filter((entry) => entry.isFile() && entry.name.endsWith('.json'))
|
||||
.map((entry) => entry.name)
|
||||
.sort((a, b) => a.localeCompare(b));
|
||||
const files = await Promise.all(
|
||||
entries.map(async (entry): Promise<string[]> => {
|
||||
if (entry.isDirectory()) {
|
||||
return (await listJsonFiles(path.join(dirPath, entry.name))).map((fileName) =>
|
||||
path.join(entry.name, fileName)
|
||||
);
|
||||
}
|
||||
return entry.isFile() && entry.name.endsWith('.json') ? [entry.name] : [];
|
||||
})
|
||||
);
|
||||
return files.flat().sort((a, b) => a.localeCompare(b));
|
||||
};
|
||||
|
||||
const validateFolder = async (folder: string): Promise<string[]> => {
|
||||
@@ -50,7 +59,13 @@ const validateFolder = async (folder: string): Promise<string[]> => {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
schema(parsed);
|
||||
if (folder === 'scenario' && /^scenario_\d+\.json$/.test(fileName)) {
|
||||
ScenarioDefinitionInputSchema.parse(parsed);
|
||||
} else if (folder === 'scenario' && fileName.startsWith(`extensions${path.sep}`)) {
|
||||
ScenarioFragmentInputSchema.parse(parsed);
|
||||
} else {
|
||||
schema(parsed);
|
||||
}
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
errors.push(`${path.relative(REPO_ROOT, filePath)}: ${message}`);
|
||||
|
||||
Reference in New Issue
Block a user