refactor!: use tsondb and optolith-database-schema
The database schema is used to generate some types from the schema definitions.
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
gen
|
||||
node_modules
|
||||
lib
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
semi: false
|
||||
arrowParens: avoid
|
||||
printWidth: 100
|
||||
@@ -1,21 +0,0 @@
|
||||
// @ts-check
|
||||
import { dirname, join } from "node:path"
|
||||
import { fileURLToPath } from "node:url"
|
||||
import { jsonSchema } from "optolith-tsjsonschemamd/renderers"
|
||||
|
||||
const rootDir = dirname(fileURLToPath(import.meta.url))
|
||||
const sourceDir = join(rootDir, "src")
|
||||
const schemaDir = join(rootDir, "schema")
|
||||
|
||||
/** @type {import("optolith-tsjsonschemamd").GeneratorOptions} */
|
||||
export default {
|
||||
sourceDir: sourceDir,
|
||||
outputs: [
|
||||
{
|
||||
targetDir: schemaDir,
|
||||
renderer: jsonSchema({ spec: "Draft_07", allowAdditionalProperties: true }),
|
||||
}
|
||||
],
|
||||
clean: true,
|
||||
verbose: false
|
||||
}
|
||||
Generated
+1047
-22
File diff suppressed because it is too large
Load Diff
+12
-9
@@ -9,14 +9,14 @@
|
||||
"CHANGELOG.md"
|
||||
],
|
||||
"scripts": {
|
||||
"build:ts": "tsc",
|
||||
"watch:ts": "tsc -w",
|
||||
"build:schema": "otjsmd",
|
||||
"watch:schema": "otjsmd -w"
|
||||
"build": "tsc",
|
||||
"watch": "tsc -w",
|
||||
"generate": "tsondb generate"
|
||||
},
|
||||
"exports": {
|
||||
".": "./lib/character.js",
|
||||
"./schema": "./schema/character.schema.json"
|
||||
".": "./lib/index.js",
|
||||
"./gen": "./gen/types.d.ts",
|
||||
"./gen/schema": "./gen/types.schema.json"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -28,10 +28,13 @@
|
||||
"url": "https://github.com/Optolith/character-schema/issues"
|
||||
},
|
||||
"homepage": "https://github.com/Optolith/character-schema#readme",
|
||||
"dependencies": {
|
||||
"optolith-database-schema": "^0.26.2",
|
||||
"tsondb": "^0.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@optolith/ts-json-definition-transpiler": "^0.11.3",
|
||||
"@types/node": "^22.13.8",
|
||||
"typescript": "^5.8.2"
|
||||
"@types/node": "^25.0.3",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,89 @@
|
||||
import { SelectOptionIdentifier } from "optolith-database-schema/types/_IdentifierGroup"
|
||||
import {
|
||||
Array,
|
||||
Enum,
|
||||
EnumCase,
|
||||
IncludeIdentifier,
|
||||
Integer,
|
||||
Object as Object_,
|
||||
Optional,
|
||||
Required,
|
||||
String,
|
||||
TypeAlias,
|
||||
} from "tsondb/schema/def"
|
||||
import { UUIDv4 } from "./utils.js"
|
||||
|
||||
export const TinyActivatable = TypeAlias(import.meta.filename, {
|
||||
name: "TinyActivatable",
|
||||
comment: "A tiny activatable item reference.",
|
||||
type: () =>
|
||||
Object_({
|
||||
id: Required({
|
||||
comment: "The identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const Activatable = TypeAlias(import.meta.filename, {
|
||||
name: "Activatable",
|
||||
comment:
|
||||
"An activatable item reference. Activatables are advantages, disadvantages and special abilities.",
|
||||
type: () =>
|
||||
Object_({
|
||||
id: Required({
|
||||
comment: "The identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const ActivatableInstance = TypeAlias(import.meta.filename, {
|
||||
name: "ActivatableInstance",
|
||||
comment: "An instance of an activatable item.",
|
||||
type: () =>
|
||||
Object_({
|
||||
options: Optional({
|
||||
comment:
|
||||
"One or multiple options for the activatable. The meaning depends on the activatable.",
|
||||
type: Array(IncludeIdentifier(ActivatableInstanceOption), { minItems: 1 }),
|
||||
}),
|
||||
level: Optional({
|
||||
comment: "The instance level (if the activatable has levels).",
|
||||
type: Integer({ minimum: 1 }),
|
||||
}),
|
||||
custom_adventure_points_value: Optional({
|
||||
comment: "If provided, a custom adventure points value has been set for this instance.",
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const ActivatableInstanceOption = Enum(import.meta.filename, {
|
||||
name: "ActivatableInstanceOption",
|
||||
comment: "An activatable option, either predefined or custom.",
|
||||
values: () => ({
|
||||
Predefined: EnumCase({
|
||||
comment: "A predefined option.",
|
||||
type: IncludeIdentifier(ReferencedErasedSelectOptionIdentifier),
|
||||
}),
|
||||
Custom: EnumCase({
|
||||
comment: "A custom option.",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
const ReferencedErasedSelectOptionIdentifier = Enum(import.meta.filename, {
|
||||
name: "ReferencedErasedSelectOptionIdentifier",
|
||||
values: () =>
|
||||
Object.fromEntries(
|
||||
Object.keys(SelectOptionIdentifier.type.value.values).map(name => [
|
||||
name,
|
||||
EnumCase({ type: IncludeIdentifier(UUIDv4) }),
|
||||
])
|
||||
) as Record<
|
||||
keyof typeof SelectOptionIdentifier.type.value.values,
|
||||
EnumCase<IncludeIdentifier<[], typeof UUIDv4>>
|
||||
>,
|
||||
})
|
||||
@@ -0,0 +1,92 @@
|
||||
import { Integer, Object, Required, TypeAlias } from "tsondb/schema/def"
|
||||
import { READ_ONLY_NOTE } from "./utils.js"
|
||||
|
||||
export const AdventurePoints = TypeAlias(import.meta.filename, {
|
||||
name: "AdventurePoints",
|
||||
comment: "An object storing all kinds of basic and calculated adventure points.",
|
||||
type: () =>
|
||||
Object({
|
||||
total: Required({
|
||||
comment: "Total adventure points.",
|
||||
type: Integer({ minimum: 1 }),
|
||||
}),
|
||||
available: Required({
|
||||
comment: "Adventure points available." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spent: Required({
|
||||
comment: "Adventure points spent." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnAdvantages: Required({
|
||||
comment: "Adventure points spent on advantages." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnMagicalAdvantages: Required({
|
||||
comment: "Adventure points spent on magical advantages." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnBlessedAdvantages: Required({
|
||||
comment: "Adventure points spent on blessed advantages." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnDisadvantages: Required({
|
||||
comment: "Adventure points spent on disadvantages." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnMagicalAisadvantages: Required({
|
||||
comment: "Adventure points spent on magical disadvantages." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnBlessedDisadvantages: Required({
|
||||
comment: "Adventure points spent on blessed disadvantages." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnRace: Required({
|
||||
comment: "Adventure points spent on race." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnAttributes: Required({
|
||||
comment: "Adventure points spent on attributes." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnSkills: Required({
|
||||
comment: "Adventure points spent on skills." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnCombatTechniques: Required({
|
||||
comment: "Adventure points spent on combat techniques." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnSpells: Required({
|
||||
comment: "Adventure points spent on spells, rituals and its enhancements." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnCantrips: Required({
|
||||
comment: "Adventure points spent on cantrips." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnMagicalActions: Required({
|
||||
comment: "Adventure points spent on all kinds of magical actions." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnMiturgicalChants: Required({
|
||||
comment:
|
||||
"Adventure points spent on liturgical chant, ceremonies and its enhancements." +
|
||||
READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnBlessings: Required({
|
||||
comment: "Adventure points spent on blessings." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnSpecialAbilities: Required({
|
||||
comment: "Adventure points spent on all kinds of special abilities." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
spentOnEnergies: Required({
|
||||
comment: "Adventure points spent on adding and buying back energy points." + READ_ONLY_NOTE,
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Integer, Object, Required, TypeAlias } from "tsondb/schema/def"
|
||||
|
||||
export const Purse = TypeAlias(import.meta.filename, {
|
||||
name: "Purse",
|
||||
comment: "The money the character owns.",
|
||||
type: () =>
|
||||
Object({
|
||||
kreutzers: Required({
|
||||
comment: "The number of kreutzers the character owns.",
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
halers: Required({
|
||||
comment: "The number of halers the character owns.",
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
silverthalers: Required({
|
||||
comment: "The number of silverthalers the character owns.",
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
ducats: Required({
|
||||
comment: "The number of ducats the character owns.",
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
+237
-1358
File diff suppressed because it is too large
Load Diff
+103
@@ -0,0 +1,103 @@
|
||||
import {
|
||||
Boolean,
|
||||
IncludeIdentifier,
|
||||
Object,
|
||||
Optional,
|
||||
Required,
|
||||
String,
|
||||
TypeAlias,
|
||||
} from "tsondb/schema/def"
|
||||
import { READ_ONLY_NOTE, UUIDv4 } from "./utils.js"
|
||||
|
||||
export const ExperienceLevel = TypeAlias(import.meta.filename, {
|
||||
name: "ExperienceLevel",
|
||||
comment:
|
||||
"An object storing the identifiers of the experience level the character started at and the current experience level, derived from total adventure points.",
|
||||
type: () =>
|
||||
Object({
|
||||
start: Required({
|
||||
comment: "The start experience level identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
current: Required({
|
||||
comment: "The current experience level identifier." + READ_ONLY_NOTE,
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const Race = TypeAlias(import.meta.filename, {
|
||||
name: "Race",
|
||||
comment: "An object storing the identifiers of the race and its optional race variant.",
|
||||
type: () =>
|
||||
Object({
|
||||
base: Required({
|
||||
comment: "The base race.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
variant: Optional({
|
||||
comment: "The race variant.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
selectedAttributeAdjustment: Required({
|
||||
comment: "The identifier of the attribute adjustment that has been selected from the race.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const Culture = TypeAlias(import.meta.filename, {
|
||||
name: "Culture",
|
||||
comment:
|
||||
"An object storing the identifier of the culture and if the cultural package has been applied.",
|
||||
type: () =>
|
||||
Object({
|
||||
base: Required({
|
||||
comment: "The culture identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
isCulturalPackageApplied: Required({
|
||||
comment:
|
||||
"Describes whether the cultural package has been applied when creating the character.",
|
||||
type: Boolean(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const Profession = TypeAlias(import.meta.filename, {
|
||||
name: "Profession",
|
||||
comment:
|
||||
"An object storing the identifiers of the profession, its instance and its optional profession variant.",
|
||||
type: () =>
|
||||
Object({
|
||||
package: Required({
|
||||
comment:
|
||||
"The profession instance identifier. Profession instances are versions of the same profession but slightly different values, such as in extension rule books existing professions might get an additional style special ability.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
variant: Optional({
|
||||
comment: "The profession variant identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
customName: Optional({
|
||||
comment: "A custom name for the profession, if provided.",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const Curriculum = TypeAlias(import.meta.filename, {
|
||||
name: "Curriculum",
|
||||
comment: "An object storing the identifiers of the curriculum and it’s optional lesson package.",
|
||||
type: () =>
|
||||
Object({
|
||||
educationalInstitution: Required({
|
||||
comment: "The educational institution's curriculum identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
lessonPackage: Optional({
|
||||
comment: "The lesson package identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -0,0 +1,90 @@
|
||||
import { Integer, Object, Required, TypeAlias } from "tsondb/schema/def"
|
||||
import { READ_ONLY_NOTE } from "./utils.js"
|
||||
|
||||
export const DerivedCharacteristic = TypeAlias(import.meta.filename, {
|
||||
name: "DerivedCharacteristic",
|
||||
comment: "A derived characteristic with its calculated parts.",
|
||||
type: () =>
|
||||
Object({
|
||||
base: Required({
|
||||
comment: "The base value." + READ_ONLY_NOTE,
|
||||
type: Integer(),
|
||||
}),
|
||||
modifier: Required({
|
||||
comment:
|
||||
"The modifier depending on relevant advantages, disadvantages and special abilities." +
|
||||
READ_ONLY_NOTE,
|
||||
type: Integer(),
|
||||
}),
|
||||
value: Required({
|
||||
comment: "The (final) value." + READ_ONLY_NOTE,
|
||||
type: Integer(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const Energy = TypeAlias(import.meta.filename, {
|
||||
name: "Energy",
|
||||
comment:
|
||||
"A derived characteristic representing an energy where points can be purchased and permanently lost.",
|
||||
type: () =>
|
||||
Object({
|
||||
base: Required({
|
||||
comment: "The base value." + READ_ONLY_NOTE,
|
||||
type: Integer(),
|
||||
}),
|
||||
modifier: Required({
|
||||
comment:
|
||||
"The modifier depending on relevant advantages, disadvantages and special abilities." +
|
||||
READ_ONLY_NOTE,
|
||||
type: Integer(),
|
||||
}),
|
||||
purchased: Required({
|
||||
comment: "The number of points purchased.",
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
permanently_lost: Required({
|
||||
comment: "The number of points permanently lost.",
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
maximum: Required({
|
||||
comment: "The (final) maximum." + READ_ONLY_NOTE,
|
||||
type: Integer(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const EnergyWithBuyBack = TypeAlias(import.meta.filename, {
|
||||
name: "EnergyWithBuyBack",
|
||||
comment:
|
||||
"A derived characteristic representing an energy where points can be purchased and permanently lost, with the option to buy back lost points.",
|
||||
type: () =>
|
||||
Object({
|
||||
base: Required({
|
||||
comment: "The base value." + READ_ONLY_NOTE,
|
||||
type: Integer(),
|
||||
}),
|
||||
modifier: Required({
|
||||
comment:
|
||||
"The modifier depending on relevant advantages, disadvantages and special abilities." +
|
||||
READ_ONLY_NOTE,
|
||||
type: Integer(),
|
||||
}),
|
||||
purchased: Required({
|
||||
comment: "The number of points purchased.",
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
permanently_lost: Required({
|
||||
comment: "The number of points permanently lost.",
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
permanently_lost_bought_back: Required({
|
||||
comment: "The number of permanently lost points that have been bought back.",
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
maximum: Required({
|
||||
comment: "The (final) maximum." + READ_ONLY_NOTE,
|
||||
type: Integer(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -0,0 +1,16 @@
|
||||
import * as TSONDB from "tsondb/schema"
|
||||
import { Character } from "./character.js"
|
||||
|
||||
export const Schema = TSONDB.Schema([Character])
|
||||
|
||||
export * from "./activatables.js"
|
||||
export * from "./adventurePoints.js"
|
||||
export * from "./belongings.js"
|
||||
export * from "./character.js"
|
||||
export * from "./creation.js"
|
||||
export * from "./derivedCharacteristics.js"
|
||||
export * from "./personalData.js"
|
||||
export * from "./rated.js"
|
||||
export * from "./rules.js"
|
||||
export * from "./sex.js"
|
||||
export { UUIDv4 } from "./utils.js"
|
||||
@@ -0,0 +1,87 @@
|
||||
import {
|
||||
Enum,
|
||||
EnumCase,
|
||||
IncludeIdentifier,
|
||||
Object,
|
||||
Optional,
|
||||
Required,
|
||||
String,
|
||||
TypeAlias,
|
||||
} from "tsondb/schema/def"
|
||||
import { UUIDv4 } from "./utils.js"
|
||||
|
||||
export const PersonalData = TypeAlias(import.meta.filename, {
|
||||
name: "PersonalData",
|
||||
comment: "Personal data such as hair color and place of birth.",
|
||||
type: () =>
|
||||
Object({
|
||||
sex: Required({
|
||||
comment:
|
||||
"The character’s sex. It does not have to be binary, although it always must be specified how to handle it in the context of binary sex prerequisites. You can also provide a custom sex with a custom name.",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
family: Optional({
|
||||
comment: "The family names and/or family members.",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
placeOfBirth: Optional({
|
||||
comment: "The place where the character was born.",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
dateOfBirth: Optional({
|
||||
comment: "The date when the character was born.",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
age: Optional({
|
||||
comment: "The age of the character.",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
hairColor: Optional({
|
||||
comment: "The hair color of the character.",
|
||||
type: IncludeIdentifier(Color),
|
||||
}),
|
||||
eyeColor: Optional({
|
||||
comment: "The eye color of the character.",
|
||||
type: IncludeIdentifier(Color),
|
||||
}),
|
||||
size: Optional({
|
||||
comment: "The size of the character.",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
weight: Optional({
|
||||
comment: "The weight of the character.",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
title: Optional({
|
||||
comment: "The character’s title(s).",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
socialStatus: Optional({
|
||||
comment: "The social status.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
characteristics: Optional({
|
||||
comment: "The character’s characteristics.",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
otherInfo: Optional({
|
||||
comment: "Other information about the character.",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
const Color = Enum(import.meta.filename, {
|
||||
name: "Color",
|
||||
comment: "A color, either predefined or custom.",
|
||||
values: () => ({
|
||||
Predefined: EnumCase({
|
||||
comment: "A predefined color.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
Custom: EnumCase({
|
||||
comment: "A custom color.",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -0,0 +1,89 @@
|
||||
import { Array, IncludeIdentifier, Integer, Object, Required, TypeAlias } from "tsondb/schema/def"
|
||||
import { UUIDv4 } from "./utils.js"
|
||||
|
||||
export const Attribute = TypeAlias(import.meta.filename, {
|
||||
name: "Attribute",
|
||||
comment: "An attribute with its value.",
|
||||
type: () =>
|
||||
Object({
|
||||
id: Required({
|
||||
comment: "The attribute identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
value: Required({
|
||||
comment: "The attribute value.",
|
||||
type: Integer({ minimum: 9 }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const Skill = TypeAlias(import.meta.filename, {
|
||||
name: "Skill",
|
||||
comment: "A skill with its rating.",
|
||||
type: () =>
|
||||
Object({
|
||||
id: Required({
|
||||
comment: "The skill identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
value: Required({
|
||||
comment: "The skill rating.",
|
||||
type: Integer({ minimum: 1 }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const CombatTechnique = TypeAlias(import.meta.filename, {
|
||||
name: "CombatTechnique",
|
||||
comment: "A combat technique with its rating.",
|
||||
type: () =>
|
||||
Object({
|
||||
id: Required({
|
||||
comment: "The combat technique identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
value: Required({
|
||||
comment: "The combat technique rating.",
|
||||
type: Integer({ minimum: 7 }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const ActivatableRated = TypeAlias(import.meta.filename, {
|
||||
name: "ActivatableRated",
|
||||
comment: "An activatable item with its rating.",
|
||||
type: () =>
|
||||
Object({
|
||||
id: Required({
|
||||
comment: "The skill identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
value: Required({
|
||||
comment: "The skill rating.",
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const ActivatableRatedWithEnhancements = TypeAlias(import.meta.filename, {
|
||||
name: "ActivatableRatedWithEnhancements",
|
||||
comment: "An activatable item with its rating and purchased enhancements.",
|
||||
type: () =>
|
||||
Object({
|
||||
id: Required({
|
||||
comment: "The skill identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
value: Required({
|
||||
comment: "The skill rating.",
|
||||
type: Integer({ minimum: 0 }),
|
||||
}),
|
||||
enhancements: Required({
|
||||
comment: "Purchased enhancements.",
|
||||
type: Array(IncludeIdentifier(UUIDv4), {
|
||||
minItems: 1,
|
||||
uniqueItems: true,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -0,0 +1,65 @@
|
||||
import {
|
||||
Array,
|
||||
Boolean,
|
||||
IncludeIdentifier,
|
||||
Object,
|
||||
Optional,
|
||||
Required,
|
||||
TypeAlias,
|
||||
} from "tsondb/schema/def"
|
||||
import { UUIDv4 } from "./utils.js"
|
||||
|
||||
export const Rules = TypeAlias(import.meta.filename, {
|
||||
name: "Rules",
|
||||
comment: "The rules settings for the character.",
|
||||
type: () =>
|
||||
Object({
|
||||
includeAllPublications: Required({
|
||||
comment:
|
||||
"Whether the character makes use of all publications except for publications with adult content and adventures, which have to be specified explicitly using `includePublications`.",
|
||||
type: Boolean(),
|
||||
}),
|
||||
includePublications: Required({
|
||||
comment:
|
||||
"Explicitly used publications. If `includeAllPublications` is set to `true`, only affects publications that are not covered by `includeAllPublications`.",
|
||||
type: Array(IncludeIdentifier(UUIDv4)),
|
||||
}),
|
||||
focusRules: Required({
|
||||
comment: "Active focus rules.",
|
||||
type: Array(IncludeIdentifier(FocusRule)),
|
||||
}),
|
||||
optionalRules: Required({
|
||||
comment: "Active optional rules. Each optional rule may have one or more options selected.",
|
||||
type: Array(IncludeIdentifier(OptionalRule)),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const FocusRule = TypeAlias(import.meta.filename, {
|
||||
name: "FocusRule",
|
||||
comment: "An active focus rule.",
|
||||
type: () =>
|
||||
Object({
|
||||
id: Required({
|
||||
comment: "The focus rule identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const OptionalRule = TypeAlias(import.meta.filename, {
|
||||
name: "OptionalRule",
|
||||
comment: "An active optional rule. An optional rule may have one or more options selected.",
|
||||
type: () =>
|
||||
Object({
|
||||
id: Required({
|
||||
comment: "The optional rule identifier.",
|
||||
type: IncludeIdentifier(UUIDv4),
|
||||
}),
|
||||
options: Optional({
|
||||
comment:
|
||||
"An array of one or more options. The exact meaning of each option varies based on the optional rule.",
|
||||
type: Array(IncludeIdentifier(UUIDv4), { minItems: 1 }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
import {
|
||||
Boolean,
|
||||
Enum,
|
||||
EnumCase,
|
||||
IncludeIdentifier,
|
||||
Object,
|
||||
Required,
|
||||
String,
|
||||
TypeAlias,
|
||||
} from "tsondb/schema/def"
|
||||
|
||||
export const Sex = Enum(import.meta.filename, {
|
||||
name: "Sex",
|
||||
comment:
|
||||
"The character’s sex. It does not have to be binary, although it always must be specified how to handle it in the context of binary sex prerequisites. You can also provide a custom sex with a custom name.",
|
||||
values: () => ({
|
||||
Male: EnumCase({ type: null }),
|
||||
Female: EnumCase({ type: null }),
|
||||
BalThani: EnumCase({ type: IncludeIdentifier(NonBinarySex) }),
|
||||
Tsajana: EnumCase({ type: IncludeIdentifier(NonBinarySex) }),
|
||||
Custom: EnumCase({ type: IncludeIdentifier(CustomSex) }),
|
||||
}),
|
||||
})
|
||||
|
||||
export const NonBinarySex = TypeAlias(import.meta.filename, {
|
||||
name: "NonBinarySex",
|
||||
comment: "A non-binary sex option.",
|
||||
type: () =>
|
||||
Object({
|
||||
binaryHandling: Required({
|
||||
comment: "Defines how a sex should be treated when checking prerequisites.",
|
||||
type: IncludeIdentifier(BinaryHandling),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const CustomSex = TypeAlias(import.meta.filename, {
|
||||
name: "CustomSex",
|
||||
comment: "A custom non-binary sex option.",
|
||||
type: () =>
|
||||
Object({
|
||||
name: Required({
|
||||
comment: "The custom sex name.",
|
||||
type: String({ minLength: 1 }),
|
||||
}),
|
||||
binaryHandling: Required({
|
||||
comment: "Defines how a sex should be treated when checking prerequisites.",
|
||||
type: IncludeIdentifier(BinaryHandling),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
export const BinaryHandling = TypeAlias(import.meta.filename, {
|
||||
name: "BinaryHandling",
|
||||
comment: "Defines how a sex should be treated when checking prerequisites.",
|
||||
type: () =>
|
||||
Object({
|
||||
asMale: Required({
|
||||
comment: "Defines if the sex should be treated as male when checking prerequisites.",
|
||||
type: Boolean(),
|
||||
}),
|
||||
asFemale: Required({
|
||||
comment: "Defines if the sex should be treated as female when checking prerequisites.",
|
||||
type: Boolean(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
@@ -0,0 +1,13 @@
|
||||
import { String, TypeAlias } from "tsondb/schema/def"
|
||||
|
||||
export const READ_ONLY_NOTE =
|
||||
"\n\n*Note: This value is read-only and recalculated by Optolith. Setting it to a different value will not influence calculation in Optolith.*"
|
||||
|
||||
export const UUIDv4 = TypeAlias(import.meta.filename, {
|
||||
name: "UUIDv4",
|
||||
comment: "An UUIDv4 identifier of an entry in the Optolith database.",
|
||||
type: () =>
|
||||
String({
|
||||
pattern: /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/,
|
||||
}),
|
||||
})
|
||||
@@ -0,0 +1,19 @@
|
||||
import { join } from "node:path"
|
||||
import type { GenerationConfig } from "tsondb/config"
|
||||
import { JsonSchemaOutput } from "tsondb/renderer/jsonschema"
|
||||
import { TypeScriptOutput } from "tsondb/renderer/ts"
|
||||
import { Schema } from "./lib/index.js"
|
||||
|
||||
const config: GenerationConfig = {
|
||||
schema: Schema,
|
||||
outputs: [
|
||||
TypeScriptOutput({
|
||||
targetPath: join(import.meta.dirname, "gen", "types.d.ts"),
|
||||
}),
|
||||
JsonSchemaOutput({
|
||||
targetPath: join(import.meta.dirname, "gen", "types.schema.json"),
|
||||
}),
|
||||
],
|
||||
}
|
||||
|
||||
export default config
|
||||
Reference in New Issue
Block a user