diff --git a/package.json b/package.json index 03eb6e0..68f3c82 100644 --- a/package.json +++ b/package.json @@ -29,11 +29,9 @@ "globals": "^17.0.0", "prettier": "^3.7.4", "tsdown": "^0.18.4", - "tsx": "^4.21.0", "turbo": "^2.7.2", "typescript": "^5.9.3", "typescript-eslint": "^8.51.0", - "vue-eslint-parser": "^10.2.0", - "zod-to-json-schema": "^3.25.1" + "vue-eslint-parser": "^10.2.0" } } diff --git a/packages/logic/src/resources/unitSetSchema.ts b/packages/logic/src/resources/unitSetSchema.ts index cdaff9f..3359f8a 100644 --- a/packages/logic/src/resources/unitSetSchema.ts +++ b/packages/logic/src/resources/unitSetSchema.ts @@ -19,7 +19,7 @@ export const CrewTypeRequirementSchema = z.union([ z.object({ type: z.literal('ReqChief') }), z.object({ type: z.literal('ReqNotChief') }), z.object({ type: z.literal('Impossible') }), - z.looseObject({ type: z.string() }), + z.object({ type: z.string() }).passthrough(), ]); export const CrewTypeDefinitionInputSchema = z.object({ diff --git a/packages/tools-scripts/package.json b/packages/tools-scripts/package.json index 673d267..560812a 100644 --- a/packages/tools-scripts/package.json +++ b/packages/tools-scripts/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@sammo-ts/logic": "workspace:*", - "zod-to-json-schema": "^3.25.1" + "zod": "^4.3.5" }, "devDependencies": { "tsx": "^4.21.0", diff --git a/packages/tools-scripts/src/generate-resource-schemas.ts b/packages/tools-scripts/src/generate-resource-schemas.ts index 43f231f..efc52ea 100644 --- a/packages/tools-scripts/src/generate-resource-schemas.ts +++ b/packages/tools-scripts/src/generate-resource-schemas.ts @@ -2,32 +2,31 @@ import fs from 'node:fs/promises'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import type { ZodTypeAny } from 'zod'; -import { zodToJsonSchema } from 'zod-to-json-schema'; +import { z } from 'zod'; import { MapResourceSchema, ScenarioResourceSchema, TurnCommandProfileInputSchema, UnitSetDefinitionInputSchema, -} from '@sammo-ts/logic'; +} from '@sammo-ts/logic/resources'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const REPO_ROOT = path.resolve(__dirname, '..', '..', '..'); const RESOURCE_ROOT = path.join(REPO_ROOT, 'resources'); -const writeSchema = async (relativePath: string, schema: ZodTypeAny, name: string): Promise => { +const writeSchema = async (relativePath: string, schema: unknown): Promise => { const outputPath = path.join(RESOURCE_ROOT, relativePath); - const jsonSchema = zodToJsonSchema(schema, { name, target: 'jsonSchema7' }); + const jsonSchema = z.toJSONSchema(schema, { target: 'draft-07' }); const serialized = `${JSON.stringify(jsonSchema, null, 4)}\n`; await fs.writeFile(outputPath, serialized, 'utf8'); }; const main = async (): Promise => { - await writeSchema(path.join('map', 'schema.json'), MapResourceSchema, 'MapResource'); - await writeSchema(path.join('scenario', 'schema.json'), ScenarioResourceSchema, 'ScenarioResource'); - await writeSchema(path.join('unitset', 'schema.json'), UnitSetDefinitionInputSchema, 'UnitSetDefinition'); - await writeSchema(path.join('turn-commands', 'schema.json'), TurnCommandProfileInputSchema, 'TurnCommandProfile'); + await writeSchema(path.join('map', 'schema.json'), MapResourceSchema); + await writeSchema(path.join('scenario', 'schema.json'), ScenarioResourceSchema); + await writeSchema(path.join('unitset', 'schema.json'), UnitSetDefinitionInputSchema); + await writeSchema(path.join('turn-commands', 'schema.json'), TurnCommandProfileInputSchema); }; main().catch((error) => { diff --git a/packages/tools-scripts/src/validate-resources.ts b/packages/tools-scripts/src/validate-resources.ts index e498527..3344783 100644 --- a/packages/tools-scripts/src/validate-resources.ts +++ b/packages/tools-scripts/src/validate-resources.ts @@ -7,7 +7,7 @@ import { ScenarioResourceSchema, TurnCommandProfileInputSchema, UnitSetDefinitionInputSchema, -} from '@sammo-ts/logic'; +} from '@sammo-ts/logic/resources'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); diff --git a/packages/tools-scripts/tsconfig.json b/packages/tools-scripts/tsconfig.json index 9e2913a..9b42f91 100644 --- a/packages/tools-scripts/tsconfig.json +++ b/packages/tools-scripts/tsconfig.json @@ -15,6 +15,5 @@ "noUnusedLocals": true, "noUnusedParameters": true }, - "include": ["src"], - "references": [{ "path": "../logic" }] + "include": ["src"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f005474..9f5617d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,9 +41,6 @@ importers: tsdown: specifier: ^0.18.4 version: 0.18.4(synckit@0.11.11)(typescript@5.9.3)(vue-tsc@3.2.2(typescript@5.9.3)) - tsx: - specifier: ^4.21.0 - version: 4.21.0 turbo: specifier: ^2.7.2 version: 2.7.2 @@ -56,9 +53,6 @@ importers: vue-eslint-parser: specifier: ^10.2.0 version: 10.2.0(eslint@9.39.2(jiti@2.6.1)) - zod-to-json-schema: - specifier: ^3.25.1 - version: 3.25.1(zod@4.3.5) app/game-api: dependencies: @@ -406,9 +400,9 @@ importers: '@sammo-ts/logic': specifier: workspace:* version: link:../logic - zod-to-json-schema: - specifier: ^3.25.1 - version: 3.25.1(zod@4.3.5) + zod: + specifier: ^4.3.5 + version: 4.3.5 devDependencies: tsx: specifier: ^4.21.0 @@ -3452,11 +3446,6 @@ packages: zeptomatch@2.0.2: resolution: {integrity: sha512-H33jtSKf8Ijtb5BW6wua3G5DhnFjbFML36eFu+VdOoVY4HD9e7ggjqdM6639B+L87rjnR6Y+XeRzBXZdy52B/g==} - zod-to-json-schema@3.25.1: - resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} - peerDependencies: - zod: ^3.25 || ^4 - zod@4.3.4: resolution: {integrity: sha512-Zw/uYiiyF6pUT1qmKbZziChgNPRu+ZRneAsMUDU6IwmXdWt5JwcUfy2bvLOCUtz5UniaN/Zx5aFttZYbYc7O/A==} @@ -6307,10 +6296,6 @@ snapshots: dependencies: grammex: 3.1.12 - zod-to-json-schema@3.25.1(zod@4.3.5): - dependencies: - zod: 4.3.5 - zod@4.3.4: {} zod@4.3.5: {} diff --git a/resources/map/schema.json b/resources/map/schema.json index d3a6890..65332b4 100644 --- a/resources/map/schema.json +++ b/resources/map/schema.json @@ -1,7 +1,186 @@ { - "$ref": "#/definitions/MapResource", - "definitions": { - "MapResource": {} - }, - "$schema": "http://json-schema.org/draft-07/schema#" + "$schema": "http://json-schema.org/draft-07/schema#", + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "cities": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "name": { + "type": "string" + }, + "level": { + "type": "number" + }, + "region": { + "type": "number" + }, + "position": { + "type": "object", + "properties": { + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "additionalProperties": false + }, + "connections": { + "type": "array", + "items": { + "type": "number" + } + }, + "max": { + "type": "object", + "properties": { + "population": { + "type": "number" + }, + "agriculture": { + "type": "number" + }, + "commerce": { + "type": "number" + }, + "security": { + "type": "number" + }, + "defence": { + "type": "number" + }, + "wall": { + "type": "number" + } + }, + "required": [ + "population", + "agriculture", + "commerce", + "security", + "defence", + "wall" + ], + "additionalProperties": false + }, + "initial": { + "type": "object", + "properties": { + "population": { + "type": "number" + }, + "agriculture": { + "type": "number" + }, + "commerce": { + "type": "number" + }, + "security": { + "type": "number" + }, + "defence": { + "type": "number" + }, + "wall": { + "type": "number" + } + }, + "required": [ + "population", + "agriculture", + "commerce", + "security", + "defence", + "wall" + ], + "additionalProperties": false + }, + "meta": { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": {} + } + }, + "required": [ + "id", + "name", + "level", + "region", + "position", + "connections", + "max", + "initial" + ], + "additionalProperties": false + } + }, + "defaults": { + "type": "object", + "properties": { + "trust": { + "type": "number" + }, + "trade": { + "type": "number" + }, + "supplyState": { + "type": "number" + }, + "frontState": { + "type": "number" + } + }, + "additionalProperties": false + }, + "meta": { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": {} + } + }, + "required": [ + "id", + "name", + "cities" + ], + "additionalProperties": false + }, + { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": { + "type": "string" + } + } + } + ] } diff --git a/resources/scenario/schema.json b/resources/scenario/schema.json index a14fb07..00b7c81 100644 --- a/resources/scenario/schema.json +++ b/resources/scenario/schema.json @@ -1,7 +1,151 @@ { - "$ref": "#/definitions/ScenarioResource", - "definitions": { - "ScenarioResource": {} - }, - "$schema": "http://json-schema.org/draft-07/schema#" + "$schema": "http://json-schema.org/draft-07/schema#", + "anyOf": [ + { + "type": "object", + "properties": { + "stat": { + "type": "object", + "properties": { + "total": { + "type": "number" + }, + "min": { + "type": "number" + }, + "max": { + "type": "number" + }, + "npcTotal": { + "type": "number" + }, + "npcMax": { + "type": "number" + }, + "npcMin": { + "type": "number" + }, + "chiefMin": { + "type": "number" + } + }, + "additionalProperties": false + }, + "iconPath": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "startYear": { + "type": "number" + }, + "life": { + "type": "number" + }, + "fiction": { + "type": "number" + }, + "history": { + "type": "array", + "items": { + "type": "string" + } + }, + "iconPath": { + "type": "string" + }, + "stat": { + "type": "object", + "properties": { + "total": { + "type": "number" + }, + "min": { + "type": "number" + }, + "max": { + "type": "number" + }, + "npcTotal": { + "type": "number" + }, + "npcMax": { + "type": "number" + }, + "npcMin": { + "type": "number" + }, + "chiefMin": { + "type": "number" + } + }, + "additionalProperties": false + }, + "map": { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": {} + }, + "const": { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": {} + }, + "nation": { + "type": "array", + "items": {} + }, + "diplomacy": { + "type": "array", + "items": {} + }, + "general": { + "type": "array", + "items": {} + }, + "general_ex": { + "type": "array", + "items": {} + }, + "general_neutral": { + "type": "array", + "items": {} + }, + "cities": { + "type": "array", + "items": {} + }, + "events": { + "type": "array", + "items": {} + }, + "initialEvents": { + "type": "array", + "items": {} + }, + "initialActions": { + "type": "array", + "items": {} + }, + "ignoreDefaultEvents": { + "type": "boolean" + } + }, + "required": [ + "title" + ], + "additionalProperties": {} + } + ] } diff --git a/resources/turn-commands/schema.json b/resources/turn-commands/schema.json index f1e2737..ed43b98 100644 --- a/resources/turn-commands/schema.json +++ b/resources/turn-commands/schema.json @@ -1,7 +1,23 @@ { - "$ref": "#/definitions/TurnCommandProfile", - "definitions": { - "TurnCommandProfile": {} + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "general": { + "type": "array", + "items": { + "type": "string" + } + }, + "nation": { + "type": "array", + "items": { + "type": "string" + } + } }, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": [ + "general", + "nation" + ], + "additionalProperties": false } diff --git a/resources/unitset/schema.json b/resources/unitset/schema.json index 8470aa3..2aaced9 100644 --- a/resources/unitset/schema.json +++ b/resources/unitset/schema.json @@ -1,7 +1,386 @@ { - "$ref": "#/definitions/UnitSetDefinition", - "definitions": { - "UnitSetDefinition": {} + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "defaultCrewTypeId": { + "type": "number" + }, + "armTypes": { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": { + "type": "string" + } + }, + "crewTypes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "armType": { + "type": "number" + }, + "name": { + "type": "string" + }, + "attack": { + "type": "number" + }, + "defence": { + "type": "number" + }, + "speed": { + "type": "number" + }, + "avoid": { + "type": "number" + }, + "magicCoef": { + "type": "number" + }, + "cost": { + "type": "number" + }, + "rice": { + "type": "number" + }, + "requirements": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "ReqTech" + }, + "tech": { + "type": "number" + } + }, + "required": [ + "type", + "tech" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "ReqRegions" + }, + "regions": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "type", + "regions" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "ReqCities" + }, + "cities": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "type", + "cities" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "ReqCitiesWithCityLevel" + }, + "level": { + "type": "number" + }, + "cities": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "type", + "level", + "cities" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "ReqHighLevelCities" + }, + "level": { + "type": "number" + }, + "count": { + "type": "number" + } + }, + "required": [ + "type", + "level", + "count" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "ReqNationAux" + }, + "key": { + "type": "string" + }, + "op": { + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ] + } + }, + "required": [ + "type", + "key", + "op", + "value" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "ReqMinRelYear" + }, + "year": { + "type": "number" + } + }, + "required": [ + "type", + "year" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "ReqChief" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "ReqNotChief" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "Impossible" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": {} + } + ] + } + }, + "attackCoef": { + "anyOf": [ + { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": { + "type": "number" + } + }, + { + "type": "array", + "items": { + "type": "number" + } + } + ] + }, + "defenceCoef": { + "anyOf": [ + { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": { + "type": "number" + } + }, + { + "type": "array", + "items": { + "type": "number" + } + } + ] + }, + "info": { + "type": "array", + "items": { + "type": "string" + } + }, + "initSkillTrigger": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ] + }, + "phaseSkillTrigger": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ] + }, + "iActionList": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "id", + "armType", + "name", + "attack", + "defence", + "speed", + "avoid", + "magicCoef", + "cost", + "rice", + "requirements", + "attackCoef", + "defenceCoef", + "info", + "initSkillTrigger", + "phaseSkillTrigger", + "iActionList" + ], + "additionalProperties": false + } + }, + "meta": { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": {} + } }, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": [ + "id", + "name" + ], + "additionalProperties": false } diff --git a/tsconfig.paths.json b/tsconfig.paths.json index 834d1db..50c574a 100644 --- a/tsconfig.paths.json +++ b/tsconfig.paths.json @@ -9,6 +9,8 @@ "@sammo-ts/infra/*": ["packages/infra/src/*"], "@sammo-ts/logic": ["packages/logic/src/index.ts"], "@sammo-ts/logic/*": ["packages/logic/src/*"], + "@sammo-ts/logic/resources": ["packages/logic/src/resources/index.ts"], + "@sammo-ts/logic/resources/*": ["packages/logic/src/resources/*"], "@sammo-ts/gateway-api": ["app/gateway-api/src/index.ts"], "@sammo-ts/gateway-api/*": ["app/gateway-api/src/*"], "@sammo-ts/game-api": ["app/game-api/src/index.ts"],