Skip to content

Commit

Permalink
Move system.schema property to system._migration (foundryvtt#8482)
Browse files Browse the repository at this point in the history
  • Loading branch information
stwlam committed Oct 5, 2023
1 parent 81264ec commit 9929707
Show file tree
Hide file tree
Showing 20 changed files with 128 additions and 88 deletions.
6 changes: 3 additions & 3 deletions build/lib/compendium-pack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,10 @@ class CompendiumPack {
docSource.effects = [];
docSource.flags.core = { sourceId: this.#sourceIdOf(docSource._id!, { docType: "Actor" }) };
this.#assertSizeValid(docSource);
docSource.system.schema = { version: MigrationRunnerBase.LATEST_SCHEMA_VERSION, lastMigration: null };
docSource.system._migration = { version: MigrationRunnerBase.LATEST_SCHEMA_VERSION, previous: null };
for (const item of docSource.items) {
item.effects = [];
item.system.schema = { version: MigrationRunnerBase.LATEST_SCHEMA_VERSION, lastMigration: null };
item.system._migration = { version: MigrationRunnerBase.LATEST_SCHEMA_VERSION, previous: null };
CompendiumPack.convertUUIDs(item, { to: "ids", map: CompendiumPack.#namesToIds.Item });
}
}
Expand All @@ -262,7 +262,7 @@ class CompendiumPack {
docSource.effects = [];
docSource.flags.core = { sourceId: this.#sourceIdOf(docSource._id, { docType: "Item" }) };
docSource.system.slug = sluggify(docSource.name);
docSource.system.schema = { version: MigrationRunnerBase.LATEST_SCHEMA_VERSION, lastMigration: null };
docSource.system._migration = { version: MigrationRunnerBase.LATEST_SCHEMA_VERSION, previous: null };

if (isPhysicalData(docSource)) {
docSource.system.equipped = { carryType: "worn" };
Expand Down
2 changes: 1 addition & 1 deletion build/lib/extractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ class PackExtractor {
docSource.name = docSource.name.trim();
delete (docSource as { ownership?: unknown }).ownership;
delete (docSource as { effects?: unknown }).effects;
delete (docSource.system as { schema?: unknown }).schema;
delete (docSource.system as { _migrations?: unknown })._migrations;
}

if (isActorSource(docSource)) {
Expand Down
6 changes: 3 additions & 3 deletions build/run-migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,15 +209,15 @@ async function migrate() {
}

const updatedActor = await migrationRunner.getUpdatedActor(source, migrationRunner.migrations);
delete (updatedActor.system as { schema?: unknown }).schema;
delete (updatedActor.system as { _migrations?: unknown })._migrations;
pruneFlags(source);
pruneFlags(updatedActor);
for (const item of source.items) {
pruneFlags(item);
}

for (const updatedItem of updatedActor.items) {
delete (updatedItem.system as { schema?: unknown }).schema;
delete (updatedItem.system as { _migrations?: unknown })._migrations;
if (updatedItem.type === "consumable" && !updatedItem.system.spell) {
delete (updatedItem.system as { spell?: unknown }).spell;
}
Expand All @@ -229,7 +229,7 @@ async function migrate() {
source.system.slug = sluggify(source.name);
const updatedItem = await migrationRunner.getUpdatedItem(source, migrationRunner.migrations);
delete (source.system as { slug?: unknown }).slug;
delete (updatedItem.system as { schema?: unknown }).schema;
delete (updatedItem.system as { _migrations?: unknown })._migrations;
delete (updatedItem.system as { slug?: unknown }).slug;
if (updatedItem.type === "consumable" && !updatedItem.system.spell) {
delete (updatedItem.system as { spell?: unknown }).spell;
Expand Down
2 changes: 1 addition & 1 deletion src/module/actor/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ class ActorPF2e<TParent extends TokenDocumentPF2e | null = TokenDocumentPF2e | n

/** The recorded schema version of this actor, updated after each data migration */
get schemaVersion(): number | null {
return Number(this.system.schema?.version) || null;
return Number(this.system._migration?.version ?? this.system.schema?.version) || null;
}

/** Get an active GM or, failing that, a player who can update this actor */
Expand Down
3 changes: 1 addition & 2 deletions src/module/actor/creature/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,10 +372,9 @@ abstract class CreaturePF2e<

protected override prepareSynthetics(): void {
super.prepareSynthetics();
const { customModifiers } = this.system;

// Custom modifiers
for (const [selector, modifiers] of Object.entries(customModifiers)) {
for (const [selector, modifiers] of Object.entries(this.system.customModifiers)) {
const syntheticModifiers = (this.synthetics.modifiers[selector] ??= []);
syntheticModifiers.push(...modifiers.map((m) => () => m));
}
Expand Down
6 changes: 4 additions & 2 deletions src/module/actor/data/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { StatisticModifier } from "@actor/modifiers.ts";
import { ActorAlliance, AttributeString, SkillLongForm } from "@actor/types.ts";
import type { ConsumablePF2e, MeleePF2e, WeaponPF2e } from "@item";
import { ItemSourcePF2e } from "@item/data/index.ts";
import { DocumentSchemaRecord, Rarity, Size, ValueAndMaybeMax, ZeroToTwo } from "@module/data.ts";
import { MigrationRecord, Rarity, Size, ValueAndMaybeMax, ZeroToTwo } from "@module/data.ts";
import { AutoChangeEntry } from "@module/rules/rule-element/ae-like.ts";
import { AttackRollParams, DamageRollParams, RollParameters } from "@module/system/rolls.ts";
import type { CheckRoll } from "@system/check/roll.ts";
Expand Down Expand Up @@ -44,7 +44,9 @@ interface ActorSystemSource {
traits?: ActorTraitsSource<string>;

/** A record of this actor's current world schema version as well a log of the last migration to occur */
schema: DocumentSchemaRecord;
_migration: MigrationRecord;
/** Legacy location of `MigrationRecord` */
schema?: Readonly<{ version: number | null; lastMigration: object | null }>;
}

interface ActorAttributesSource {
Expand Down
32 changes: 20 additions & 12 deletions src/module/actor/familiar/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { StatisticTraceData } from "@system/statistic/index.ts";

type FamiliarSource = BaseCreatureSource<"familiar", FamiliarSystemSource>;

interface FamiliarSystemSource extends Pick<CreatureSystemSource, "schema"> {
interface FamiliarSystemSource extends CreatureSystemSource {
details: FamiliarDetailsSource;
attributes: FamiliarAttributesSource;
master: {
Expand All @@ -22,12 +22,20 @@ interface FamiliarSystemSource extends Pick<CreatureSystemSource, "schema"> {
};

customModifiers?: never;

resources?: never;

saves?: never;
skills?: never;
traits?: never;
}

interface FamiliarAttributesSource {
hp: { value: number };
initiative?: never;
immunities?: never;
weaknesses?: never;
resistances?: never;
}

interface FamiliarDetailsSource extends CreatureDetailsSource {
creature: {
value: string;
Expand All @@ -49,15 +57,15 @@ interface FamiliarSystemData extends Omit<FamiliarSystemSource, SourceOmission>,
traits: FamiliarTraitsData;
}

type SourceOmission = "attributes" | "customModifiers" | "details" | "toggles" | "resources" | "traits";

interface FamiliarAttributesSource {
hp: { value: number };
initiative?: never;
immunities?: never;
weaknesses?: never;
resistances?: never;
}
type SourceOmission =
| "attributes"
| "customModifiers"
| "details"
| "toggles"
| "resources"
| "saves"
| "skills"
| "traits";

interface FamiliarAttributes extends CreatureAttributes {
ac: { value: number; breakdown: string; check?: number };
Expand Down
6 changes: 3 additions & 3 deletions src/module/actor/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@ async function migrateActorSource(source: PreCreate<ActorSourcePF2e>): Promise<A

if (!["flags", "items", "system"].some((k) => k in source)) {
// The actor has no migratable data: set schema version and return early
source.system = { schema: { version: MigrationRunnerBase.LATEST_SCHEMA_VERSION } };
source.system = { _migration: { version: MigrationRunnerBase.LATEST_SCHEMA_VERSION } };
}

const lowestSchemaVersion = Math.min(
source.system?.schema?.version ?? MigrationRunnerBase.LATEST_SCHEMA_VERSION,
...(source.items ?? []).map((i) => i!.system?.schema?.version ?? MigrationRunnerBase.LATEST_SCHEMA_VERSION)
source.system?._migration?.version ?? MigrationRunnerBase.LATEST_SCHEMA_VERSION,
...(source.items ?? []).map((i) => i!.system?._migration?.version ?? MigrationRunnerBase.LATEST_SCHEMA_VERSION)
);
const tokenDefaults = deepClone(game.settings.get("core", "defaultToken"));
const actor = new ActorProxyPF2e(mergeObject({ prototypeToken: tokenDefaults }, source));
Expand Down
20 changes: 9 additions & 11 deletions src/module/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,23 +66,21 @@ function goesToEleven(value: number): value is ZeroToEleven {
}

/** The tracked schema data of actors and items */
interface NewDocumentSchemaRecord {
interface NewDocumentMigrationRecord {
version: null;
lastMigration: null;
previous: null;
}

interface MigratedDocumentSchemaRecord {
interface MigratedDocumentMigrationRecord {
version: number;
lastMigration: {
version: {
schema: number | null;
system?: string;
foundry?: string;
};
previous: {
schema: number | null;
system?: string;
foundry?: string;
} | null;
}

type DocumentSchemaRecord = NewDocumentSchemaRecord | MigratedDocumentSchemaRecord;
type MigrationRecord = NewDocumentMigrationRecord | MigratedDocumentMigrationRecord;

export const PROFICIENCY_RANKS = ["untrained", "trained", "expert", "master", "legendary"] as const;

Expand Down Expand Up @@ -138,11 +136,11 @@ type EnfolderableDocumentPF2e =

export { RARITIES, SIZES, SIZE_SLUGS, goesToEleven };
export type {
DocumentSchemaRecord,
EnfolderableDocumentPF2e,
LabeledNumber,
LabeledString,
LabeledValue,
MigrationRecord,
OneToFive,
OneToFour,
OneToTen,
Expand Down
6 changes: 3 additions & 3 deletions src/module/doc-helpers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ActorPF2e } from "@actor";
import { ItemPF2e } from "@item";
import type { TokenDocumentPF2e } from "@scene/index.ts";
import { isObject } from "@util";
import { CombatantPF2e } from "./encounter/index.ts";
import { MigrationList, MigrationRunner } from "./migration/index.ts";
import { MigrationRunnerBase } from "./migration/runner/base.ts";
import { CombatantPF2e } from "./encounter/index.ts";
import type { TokenDocumentPF2e } from "@scene/index.ts";

/** Ensure that the import JSON is actually importable and that the data is fully migrated */
async function preImportJSON<TDocument extends ActorPF2e | ItemPF2e>(
Expand All @@ -22,7 +22,7 @@ async function preImportJSON<TDocument extends ActorPF2e | ItemPF2e>(
}
if (!isObject(source.system)) return null;

const sourceSchemaVersion = Number(source.system?.schema?.version) || 0;
const sourceSchemaVersion = Number(source.system?._migration?.version) || 0;
const worldSchemaVersion = MigrationRunnerBase.LATEST_SCHEMA_VERSION;
if (foundry.utils.isNewerVersion(sourceSchemaVersion, worldSchemaVersion)) {
// Refuse to import if the schema version on the document is higher than the system schema verson;
Expand Down
4 changes: 2 additions & 2 deletions src/module/item/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class ItemPF2e<TParent extends ActorPF2e | null = ActorPF2e | null> extends Item

/** The recorded schema version of this item, updated after each data migration */
get schemaVersion(): number | null {
return Number(this.system.schema?.version) || null;
return Number(this.system._migration?.version ?? this.system.schema?.version) || null;
}

get description(): string {
Expand Down Expand Up @@ -451,7 +451,7 @@ class ItemPF2e<TParent extends ActorPF2e | null = ActorPF2e | null> extends Item

if (!Object.keys(source).some((k) => k.startsWith("flags") || k.startsWith("system"))) {
// The item has no migratable data: set schema version and skip
source.system = { schema: { version: MigrationRunnerBase.LATEST_SCHEMA_VERSION } };
source.system = { _migration: { version: MigrationRunnerBase.LATEST_SCHEMA_VERSION } };
continue;
}
const item = new CONFIG.Item.documentClass(source);
Expand Down
8 changes: 6 additions & 2 deletions src/module/item/data/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ActionTrait } from "@item/ability/types.ts";
import { KingmakerTrait } from "@item/campaign-feature/types.ts";
import { NPCAttackTrait } from "@item/melee/data.ts";
import { PhysicalItemTrait } from "@item/physical/data.ts";
import { DocumentSchemaRecord, OneToThree, Rarity } from "@module/data.ts";
import { MigrationRecord, OneToThree, Rarity } from "@module/data.ts";
import { RuleElementSource } from "@module/rules/index.ts";
import { ItemType } from "./index.ts";

Expand Down Expand Up @@ -87,7 +87,11 @@ interface ItemSystemSource {
};
rules: RuleElementSource[];
slug: string | null;
schema: DocumentSchemaRecord;

/** A record of this actor's current world schema version as well a log of the last migration to occur */
_migration: MigrationRecord;
/** Legacy location of `MigrationRecord` */
schema?: Readonly<{ version: number | null; lastMigration: object | null }>;
}

type ItemSystemData = ItemSystemSource;
Expand Down
2 changes: 1 addition & 1 deletion src/module/item/physical/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ abstract class PhysicalItemPF2e<TParent extends ActorPF2e | null = ActorPF2e | n
thisData.quantity = otherData.quantity;
thisData.equipped = otherData.equipped;
thisData.containerId = otherData.containerId;
thisData.schema = otherData.schema;
thisData._migration = otherData._migration;
thisData.identification = otherData.identification;

return R.equals(thisData, otherData);
Expand Down
1 change: 1 addition & 0 deletions src/module/migration/migrations/711-heritage-items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ export class Migration711HeritageItems extends MigrationBase {
description: feature.system.description,
rules: feature.system.rules,
schema: feature.system.schema,
_migration: { version: null, previous: null },
slug: feature.system.slug,
ancestry: ancestryReference,
traits: {
Expand Down
29 changes: 29 additions & 0 deletions src/module/migration/migrations/872-move-schema-property.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { ActorSystemSource } from "@actor/data/base.ts";
import { ActorSourcePF2e } from "@actor/data/index.ts";
import { ItemSystemSource } from "@item/data/base.ts";
import { ItemSourcePF2e } from "@item/data/index.ts";
import { isObject } from "@util";
import { MigrationBase } from "../base.ts";

/** Remove the `schema` property and create a new `_migration` one */
export class Migration872MoveSchemaProperty extends MigrationBase {
static override version = 0.872;

#mvSchema(systemData: (ItemSystemSource | ActorSystemSource) & { "-=schema"?: null }): void {
const migrations = (systemData._migration ??= { version: null, previous: null });
if ("schema" in systemData) {
systemData["-=schema"] = null;
if (isObject<{ version: unknown }>(systemData.schema) && typeof systemData.schema.version === "number") {
migrations.version = systemData.schema.version;
}
}
}

override async updateActor(source: ActorSourcePF2e): Promise<void> {
this.#mvSchema(source.system);
}

override async updateItem(source: ItemSourcePF2e): Promise<void> {
this.#mvSchema(source.system);
}
}
1 change: 1 addition & 0 deletions src/module/migration/migrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,4 @@ export { Migration868StrikeRERange } from "./868-strike-re-range.ts";
export { Migration869RefreshMightyBulwark } from "./869-refresh-mighty-bulwark.ts";
export { Migration870MartialToProficiencies } from "./870-martial-to-proficiencies.ts";
export { Migration871MigrateRollActionMacroParams } from "./871-migrate-rollactionmacro-params.ts";
export { Migration872MoveSchemaProperty } from "./872-move-schema-property.ts";
30 changes: 14 additions & 16 deletions src/module/migration/runner/base.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ActorSourcePF2e } from "@actor/data/index.ts";
import { ItemSourcePF2e } from "@item/data/index.ts";
import { DocumentSchemaRecord } from "@module/data.ts";
import { MigrationRecord } from "@module/data.ts";
import { MigrationBase } from "@module/migration/base.ts";
import type { ScenePF2e, TokenDocumentPF2e } from "@scene";

Expand All @@ -13,7 +13,7 @@ interface CollectionDiff<T extends foundry.documents.ActiveEffectSource | ItemSo
export class MigrationRunnerBase {
migrations: MigrationBase[];

static LATEST_SCHEMA_VERSION = 0.871;
static LATEST_SCHEMA_VERSION = 0.872;

static MINIMUM_SAFE_VERSION = 0.618;

Expand Down Expand Up @@ -88,11 +88,11 @@ export class MigrationRunnerBase {
// Don't set schema record on compendium JSON
if ("game" in globalThis) {
const latestMigration = migrations.slice(-1)[0];
currentActor.system.schema ??= { version: null, lastMigration: null };
this.#updateSchemaRecord(currentActor.system.schema, latestMigration);
currentActor.system._migration ??= { version: null, previous: null };
this.#updateMigrationRecord(currentActor.system._migration, latestMigration);
for (const itemSource of currentActor.items) {
itemSource.system.schema ??= { version: null, lastMigration: null };
this.#updateSchemaRecord(itemSource.system.schema, latestMigration);
itemSource.system._migration ??= { version: null, previous: null };
this.#updateMigrationRecord(itemSource.system._migration, latestMigration);
}
}

Expand All @@ -117,7 +117,7 @@ export class MigrationRunnerBase {
}
}

if (migrations.length > 0) this.#updateSchemaRecord(current.system.schema, migrations.slice(-1)[0]);
if (migrations.length > 0) this.#updateMigrationRecord(current.system._migration, migrations.slice(-1)[0]);

return current;
}
Expand Down Expand Up @@ -201,17 +201,15 @@ export class MigrationRunnerBase {
return current;
}

#updateSchemaRecord(schema: DocumentSchemaRecord, latestMigration: MigrationBase): void {
#updateMigrationRecord(migrations: MigrationRecord, latestMigration: MigrationBase): void {
if (!("game" in globalThis && latestMigration)) return;

const fromVersion = typeof schema.version === "number" ? schema.version : null;
schema.version = latestMigration.version;
schema.lastMigration = {
version: {
schema: fromVersion,
foundry: "game" in globalThis ? game.version : undefined,
system: "game" in globalThis ? game.system.version : undefined,
},
const fromVersion = typeof migrations.version === "number" ? migrations.version : null;
migrations.version = latestMigration.version;
migrations.previous = {
schema: fromVersion,
foundry: game.version,
system: game.system.version,
};
}
}
Loading

0 comments on commit 9929707

Please sign in to comment.