Skip to content

Commit ad93706

Browse files
authored
Fix JSON Schema (#10)
* refine exports * reduce unwanted ‘example’ suggestions * prune * improve compat
1 parent b006fda commit ad93706

33 files changed

Lines changed: 148 additions & 453 deletions

packages/forge-helpers/src/files/get-version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url";
44

55
/**
66
* Retrieves the JSON content of a schema file.
7-
* @param relativeFilePath - The relative path to the JSON schema file (e.g., "0.0.0/core.json").
7+
* @param relativeFilePath - The relative path to the JSON schema file (e.g., "0.0.0/ruleset.json").
88
* @returns The parsed JSON content of the file.
99
* @throws Will throw an error if the file cannot be read or parsed.
1010
*/

packages/forge-schema/scripts/generate-json-schema.ts

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,45 @@
11
import path from "node:path";
22
import { z } from "zod/v4";
3-
// import { jsonCollection } from "../src/json-collection.js";
4-
import { characterDocument } from "../src/models/doc-character.js";
5-
import { campaignRuleset } from "../src/models/ruleset-campaign.js";
6-
import { coreRuleset } from "../src/models/ruleset-core.js";
3+
import { campaign } from "../src/models/campaign.js";
4+
import { character } from "../src/models/character.js";
5+
import { ruleset } from "../src/models/ruleset.js";
76

8-
const characterDocumentSchema = z.toJSONSchema(characterDocument, {
9-
reused: "ref",
10-
});
11-
const campaignRulesetSchema = z.toJSONSchema(campaignRuleset, {
12-
reused: "ref",
13-
});
14-
const coreRulesetSchema = z.toJSONSchema(coreRuleset, { reused: "ref" });
15-
16-
const defaultSchema = z.toJSONSchema(z.globalRegistry, {
17-
target: "draft-2020-12",
18-
unrepresentable: "throw",
19-
cycles: "throw",
20-
reused: "ref",
21-
override(ctx) {
22-
ctx.jsonSchema.$id = ctx.jsonSchema.id;
7+
// Compose schema data and filenames
8+
const schemas = [
9+
{
10+
filename: "character.json",
11+
data: z.toJSONSchema(character, {
12+
unrepresentable: "throw",
13+
cycles: "throw",
14+
reused: "ref",
15+
override(ctx) {
16+
ctx.jsonSchema.$id = ctx.jsonSchema.id;
17+
},
18+
}),
19+
},
20+
{
21+
filename: "campaign.json",
22+
data: z.toJSONSchema(campaign, {
23+
unrepresentable: "throw",
24+
cycles: "throw",
25+
reused: "ref",
26+
override(ctx) {
27+
ctx.jsonSchema.$id = ctx.jsonSchema.id;
28+
},
29+
}),
2330
},
24-
});
31+
{
32+
filename: "ruleset.json",
33+
data: z.toJSONSchema(ruleset, {
34+
unrepresentable: "throw",
35+
cycles: "throw",
36+
reused: "ref",
37+
override(ctx) {
38+
ctx.jsonSchema.$id = ctx.jsonSchema.id;
39+
},
40+
}),
41+
},
42+
];
2543

2644
/**
2745
* Returns the version value from the package.json
@@ -65,14 +83,6 @@ const generateSchemas = async (): Promise<void> => {
6583

6684
const directory = await useDirectory(version);
6785

68-
// Compose schema data and filenames
69-
const schemas = [
70-
{ data: characterDocumentSchema, filename: "document-character.json" },
71-
{ data: campaignRulesetSchema, filename: "ruleset-campaign.json" },
72-
{ data: coreRulesetSchema, filename: "ruleset-core.json" },
73-
{ data: defaultSchema, filename: "schema.json" },
74-
];
75-
7686
// Dynamically import fs/promises for ESM compatibility
7787
const { writeFile } = await import("node:fs/promises");
7888

packages/forge-schema/src/models/artifact/ancestry.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,9 @@ export const ancestry = z
1212
.meta({
1313
title: "Ancestry",
1414
description: "The ancestry of a character",
15-
examples: [
16-
{
17-
_type: "ancestry",
18-
name: "Ribbet",
19-
description:
20-
"Ribbets resemble anthropomorphic frogs with protruding eyes, and webbed hands and feet.",
21-
primaryFeature: {
22-
name: "Amphibious",
23-
description: "You can breathe and move naturally under water.",
24-
},
25-
secondaryFeature: {
26-
name: "Long Tounge",
27-
description:
28-
"You can use your long tounge to grab onto things within close range. Mark a stress to use your tounge as a finesse close weapon that deals d12 physical damage using your proficiency.",
29-
},
30-
},
31-
],
3215
});
3316

3417
export const ancestryReference = createReference("heritage/ancestry").meta({
3518
id: "ReferenceAncestry",
3619
title: "Reference to an Ancestry",
37-
examples: [
38-
{
39-
_type: "reference",
40-
_key: "heritage/ancestry",
41-
value: "ribbet",
42-
},
43-
],
4420
});

packages/forge-schema/src/models/artifact/community.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,9 @@ export const community = z
1515
id: "Community",
1616
title: "Community",
1717
description: "A community that shaped a characters backstory",
18-
examples: [
19-
{
20-
_type: "community",
21-
name: "Highborn",
22-
description:
23-
"Being part of a highborn community means you're accustomed to a life of elegance, opulence, and prestige within the upper echelons of society.",
24-
feature: {
25-
name: "Privilege",
26-
description:
27-
"You have advantage on rolls to consort with nobles, negotiate prices, or leverage your reputation to get what you want.",
28-
},
29-
},
30-
],
3118
});
3219

3320
export const communityReference = createReference("heritage/community").meta({
3421
id: "ReferenceCommunity",
3522
title: "Reference to a Community",
36-
examples: [
37-
{
38-
_type: "reference",
39-
_key: "heritage/community",
40-
value: "highborn",
41-
},
42-
],
4323
});

packages/forge-schema/src/models/artifact/domain.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,9 @@ export const domain = z
1111
id: "Domain",
1212
title: "Domain",
1313
description: "A domain of a character class",
14-
examples: [
15-
{
16-
_type: "domain",
17-
name: "Arcana",
18-
description:
19-
"Arcana is the domain of innate and instinctual magic. Those who choose this path tap into the raw, enigmatic forces of the realms to manipulate both their own energy and the elements. Arcana offers wielders a volatile power, but it is incredibly potent when correctly channeled. The Arcana domain can be accessed by the Druid and Sorcerer classes.",
20-
},
21-
],
2214
});
2315

2416
export const domainReference = createReference("role/domain").meta({
2517
id: "ReferenceDomain",
2618
title: "Reference to a Domain",
27-
examples: [
28-
{
29-
_type: "reference",
30-
_key: "role/domain",
31-
value: "arcana",
32-
},
33-
],
3419
});

packages/forge-schema/src/models/artifact/inventory-armor.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,9 @@ export const inventoryArmor = z
1515
id: "Armor",
1616
title: "Armor",
1717
description: "A set of armor that can be equipped by a character",
18-
examples: [
19-
{
20-
_type: "inventoryArmor",
21-
name: "Full Plate Armor",
22-
description: null,
23-
baseThresholds: {
24-
_type: "damageThresholds",
25-
major: 8,
26-
severe: 17,
27-
},
28-
baseScore: 4,
29-
features: ["Very Heavy: -2 to Evasion"],
30-
},
31-
],
3218
});
3319

3420
export const inventoryArmorReference = createReference("item/armor").meta({
3521
id: "ReferenceArmor",
3622
title: "Reference to a piece of Armor",
37-
examples: [
38-
{
39-
_type: "reference",
40-
_key: "item/armor",
41-
value: "full-plate-armor",
42-
},
43-
],
4423
});

packages/forge-schema/src/models/artifact/inventory-thing.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,9 @@ export const inventoryThing = z
1111
id: "Thing",
1212
title: "Thing",
1313
description: "A thing that can be added to a character's inventory",
14-
examples: [
15-
{
16-
_type: "inventoryThing",
17-
name: "Suspicious looking potion",
18-
description: "The label is written in a language you don't recognize.",
19-
},
20-
],
2114
});
2215

2316
export const inventoryThingReference = createReference("item/thing").meta({
2417
id: "ReferenceThing",
2518
title: "Reference to a Thing",
26-
examples: [
27-
{
28-
_type: "reference",
29-
_key: "item/thing",
30-
value: "suspicious-looking-potion",
31-
},
32-
],
3319
});

packages/forge-schema/src/models/artifact/inventory-weapon.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,9 @@ export const inventoryWeapon = z
2020
id: "Weapon",
2121
title: "Weapon",
2222
description: "A weapon that can be equipped by a character",
23-
examples: [
24-
{
25-
_type: "inventoryWeapon",
26-
name: "Warhammer",
27-
trait: "Strength",
28-
range: "Melee",
29-
damageDice: "d8",
30-
damageType: "Physical",
31-
features: ["Versatile"],
32-
burden: "One-Handed",
33-
},
34-
],
3523
});
3624

3725
export const inventoryWeaponReference = createReference("item/weapon").meta({
3826
id: "ReferenceWeapon",
3927
title: "Reference to a Weapon",
40-
examples: [
41-
{
42-
_type: "reference",
43-
_key: "item/weapon",
44-
value: "warhammer",
45-
},
46-
],
4728
});

packages/forge-schema/src/models/artifact/role-class.ts

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -34,50 +34,9 @@ export const roleClass = z
3434
id: "Class",
3535
title: "Class",
3636
description: "A class of a character",
37-
examples: [
38-
{
39-
_type: "class",
40-
name: "Barbarian",
41-
domain: {
42-
_type: "reference",
43-
_key: "role/domain",
44-
value: "arcana",
45-
},
46-
initialEvasion: 10,
47-
initialHitPoints: 5,
48-
initialInventory: [
49-
{
50-
_type: "inventoryThing",
51-
name: "A romance novel or a letter never opened",
52-
description: null,
53-
},
54-
],
55-
features: [
56-
{
57-
name: "Rally",
58-
description:
59-
"Once per session, describe how you rally the party and give yourself and each of your allies a Rally Die. At level 1, your Rally Die is a d6. A PC can spend their Rally Die to roll it, adding the result to their action roll, reaction roll, damage roll, or to clear a number of Stress equal to the result. At the end of each session, clear all unspent Rally Dice. At level 5, your Rally Die increases to a d8.",
60-
},
61-
],
62-
hopeFeature: {
63-
name: "Make a Scene",
64-
description:
65-
"Spend 3 Hope to temporarily Distract a target within Close range, giving them a -2 penalty to their Difficulty.",
66-
},
67-
68-
subclasses: [],
69-
},
70-
],
7137
});
7238

7339
export const roleClassReference = createReference("role/class").meta({
7440
id: "ReferenceClass",
7541
title: "Reference to a Class",
76-
examples: [
77-
{
78-
_type: "reference",
79-
_key: "role/class",
80-
value: "barbarian",
81-
},
82-
],
8342
});

packages/forge-schema/src/models/artifact/role-subclass.ts

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -18,60 +18,9 @@ export const roleSubclass = z
1818
id: "Subclass",
1919
title: "Subclass",
2020
description: "A subclass of a class",
21-
examples: [
22-
{
23-
_type: "subclass",
24-
name: "Troubadour",
25-
description:
26-
"Play the Troubadour if you want to play music to bolster your allies.",
27-
spellTrait: "Presence",
28-
29-
foundationFeatures: [
30-
{
31-
_type: "feature",
32-
name: "Gifted Performer",
33-
description:
34-
"You can play three different types of songs, once each per long rest; describe how you perform for others to gain the listed benefit:",
35-
notes: [
36-
"Relaxing Song: You and all allies within Close range clear a Hit Point.",
37-
"Epic Song: Make a target within Close range temporarily Vulnerable.",
38-
"Heartbreaking Song: You and all allies within Close range gain a Hope.",
39-
],
40-
modifiers: null,
41-
},
42-
],
43-
specializationFeatures: [
44-
{
45-
_type: "feature",
46-
name: "Maestro",
47-
description:
48-
"Your rallying songs steel the courage of those who listen. When you give a Rally Die to an ally, they can gain a Hope or clear a Stress.",
49-
notes: null,
50-
modifiers: null,
51-
},
52-
],
53-
masteryFeatures: [
54-
{
55-
_type: "feature",
56-
name: "Virtuoso",
57-
description:
58-
"You are among the greatest of your craft and your skill is boundless. You can perform each of your “Gifted Performer” feature’s songs twice per long rest.",
59-
notes: null,
60-
modifiers: null,
61-
},
62-
],
63-
},
64-
],
6521
});
6622

6723
export const roleSubclassReference = createReference("role/subclass").meta({
6824
id: "ReferenceSubclass",
6925
title: "Reference to a Subclass",
70-
examples: [
71-
{
72-
_type: "reference",
73-
_key: "role/subclass",
74-
value: "troubadour",
75-
},
76-
],
7726
});

0 commit comments

Comments
 (0)