feat: zod 라이브러리 업데이트 및 JSON 스키마 정의 개선

This commit is contained in:
2026-01-18 08:19:22 +00:00
parent 81594a25c3
commit 116993b3ad
12 changed files with 754 additions and 53 deletions
+1 -3
View File
@@ -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"
}
}
@@ -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({
+1 -1
View File
@@ -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",
@@ -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<void> => {
const writeSchema = async (relativePath: string, schema: unknown): Promise<void> => {
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<void> => {
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) => {
@@ -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);
+1 -2
View File
@@ -15,6 +15,5 @@
"noUnusedLocals": true,
"noUnusedParameters": true
},
"include": ["src"],
"references": [{ "path": "../logic" }]
"include": ["src"]
}
+3 -18
View File
@@ -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: {}
+183 -4
View File
@@ -1,7 +1,186 @@
{
"$ref": "#/definitions/MapResource",
"definitions": {
"MapResource": {}
"$schema": "http://json-schema.org/draft-07/schema#",
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"$schema": "http://json-schema.org/draft-07/schema#"
"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"
}
}
}
]
}
+148 -4
View File
@@ -1,7 +1,151 @@
{
"$ref": "#/definitions/ScenarioResource",
"definitions": {
"ScenarioResource": {}
"$schema": "http://json-schema.org/draft-07/schema#",
"anyOf": [
{
"type": "object",
"properties": {
"stat": {
"type": "object",
"properties": {
"total": {
"type": "number"
},
"$schema": "http://json-schema.org/draft-07/schema#"
"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": {}
}
]
}
+20 -4
View File
@@ -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"
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
"nation": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"general",
"nation"
],
"additionalProperties": false
}
+383 -4
View File
@@ -1,7 +1,386 @@
{
"$ref": "#/definitions/UnitSetDefinition",
"definitions": {
"UnitSetDefinition": {}
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"id": {
"type": "string"
},
"$schema": "http://json-schema.org/draft-07/schema#"
"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": {}
}
},
"required": [
"id",
"name"
],
"additionalProperties": false
}
+2
View File
@@ -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"],