refactor: update each document individually during migrations
This commit is contained in:
parent
4646491fd4
commit
77fe22436e
10 changed files with 255 additions and 375 deletions
|
@ -2,24 +2,18 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import {
|
import { getSceneMigrator, migrateCollection, migrateCompendiums, getCompendiumMigrator } from "./migrationHelpers.js";
|
||||||
getCompendiumMigrator,
|
|
||||||
getSceneUpdateDataGetter,
|
|
||||||
migrateActors,
|
|
||||||
migrateCompendiums,
|
|
||||||
migrateScenes,
|
|
||||||
} from "./migrationHelpers";
|
|
||||||
|
|
||||||
/** @type {import("./migration").Migration["migrate"]} */
|
/** @type {import("./migration.js").Migration["migrate"]} */
|
||||||
async function migrate() {
|
async function migrate() {
|
||||||
await migrateActors(getActorUpdateData);
|
await migrateCollection(game.actors, migrateActor);
|
||||||
await migrateScenes(getSceneUpdateData);
|
await migrateCollection(game.scenes, migrateScene);
|
||||||
await migrateCompendiums(migrateCompendium);
|
await migrateCompendiums(migrateCompendium);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {import("./migrationHelpers").ActorUpdateDataGetter} */
|
/** @type {import('./migrationHelpers.js').Migrator<Actor>} */
|
||||||
function getActorUpdateData() {
|
async function migrateActor(actor) {
|
||||||
const updateData = {
|
await actor.update({
|
||||||
system: {
|
system: {
|
||||||
combatValues: [
|
combatValues: [
|
||||||
"hitPoints",
|
"hitPoints",
|
||||||
|
@ -35,14 +29,14 @@ function getActorUpdateData() {
|
||||||
return acc;
|
return acc;
|
||||||
}, {}),
|
}, {}),
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
return updateData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
|
const migrateScene = getSceneMigrator(migrateActor);
|
||||||
const migrateCompendium = getCompendiumMigrator({ getActorUpdateData, getSceneUpdateData });
|
|
||||||
|
|
||||||
/** @type {import("./migration").Migration} */
|
const migrateCompendium = getCompendiumMigrator({ migrateActor, migrateScene });
|
||||||
|
|
||||||
|
/** @type {import("./migration.js").Migration} */
|
||||||
export const migration = {
|
export const migration = {
|
||||||
migrate,
|
migrate,
|
||||||
migrateCompendium,
|
migrateCompendium,
|
||||||
|
|
|
@ -3,37 +3,36 @@
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getActorUpdateDataGetter,
|
getSceneMigrator,
|
||||||
getCompendiumMigrator,
|
migrateCollection,
|
||||||
getSceneUpdateDataGetter,
|
|
||||||
migrateActors,
|
|
||||||
migrateCompendiums,
|
migrateCompendiums,
|
||||||
migrateItems,
|
getCompendiumMigrator,
|
||||||
migrateScenes,
|
getActorMigrator,
|
||||||
} from "./migrationHelpers";
|
} from "./migrationHelpers.js";
|
||||||
|
|
||||||
/** @type {import("./migration").Migration["migrate"]} */
|
/** @type {import("./migration.js").Migration["migrate"]} */
|
||||||
async function migrate() {
|
async function migrate() {
|
||||||
await migrateItems(getItemUpdateData);
|
await migrateCollection(game.items, migrateItem);
|
||||||
await migrateActors(getActorUpdateData);
|
await migrateCollection(game.actors, migrateActor);
|
||||||
await migrateScenes(getSceneUpdateData);
|
await migrateCollection(game.scenes, migrateScene);
|
||||||
await migrateCompendiums(migrateCompendium);
|
await migrateCompendiums(migrateCompendium);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {import("./migrationHelpers").ItemUpdateDataGetter} */
|
/** @type {import('./migrationHelpers.js').Migrator<Item>} */
|
||||||
function getItemUpdateData(itemData) {
|
async function migrateItem(item) {
|
||||||
if (!["equipment", "trinket"].includes(itemData.type ?? "")) return undefined;
|
if (item.type === "equipment" || item.type === "trinket") {
|
||||||
return { type: itemData.type === "equipment" ? "loot" : "equipment" };
|
await item.update({ type: item.type === "equipment" ? "loot" : "equipment" });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData);
|
const migrateActor = getActorMigrator(migrateItem);
|
||||||
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
|
const migrateScene = getSceneMigrator(migrateActor);
|
||||||
const migrateCompendium = getCompendiumMigrator(
|
const migrateCompendium = getCompendiumMigrator(
|
||||||
{ getItemUpdateData, getActorUpdateData, getSceneUpdateData },
|
{ migrateItem, migrateActor, migrateScene },
|
||||||
{ migrateToTemplateEarly: false },
|
{ migrateToTemplateEarly: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
/** @type {import("./migration").Migration} */
|
/** @type {import("./migration.js").Migration} */
|
||||||
export const migration = {
|
export const migration = {
|
||||||
migrate,
|
migrate,
|
||||||
migrateCompendium,
|
migrateCompendium,
|
||||||
|
|
|
@ -3,41 +3,36 @@
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getActorUpdateDataGetter,
|
getSceneMigrator,
|
||||||
getCompendiumMigrator,
|
migrateCollection,
|
||||||
getSceneUpdateDataGetter,
|
|
||||||
migrateActors,
|
|
||||||
migrateCompendiums,
|
migrateCompendiums,
|
||||||
migrateItems,
|
getCompendiumMigrator,
|
||||||
migrateScenes,
|
getActorMigrator,
|
||||||
} from "./migrationHelpers";
|
} from "./migrationHelpers.js";
|
||||||
|
|
||||||
/** @type {import("./migration").Migration["migrate"]} */
|
/** @type {import("./migration.js").Migration["migrate"]} */
|
||||||
async function migrate() {
|
async function migrate() {
|
||||||
await migrateItems(getItemUpdateData);
|
await migrateCollection(game.items, migrateItem);
|
||||||
await migrateActors(getActorUpdateData);
|
await migrateCollection(game.actors, migrateActor);
|
||||||
await migrateScenes(getSceneUpdateData);
|
await migrateCollection(game.scenes, migrateScene);
|
||||||
await migrateCompendiums(migrateCompendium);
|
await migrateCompendiums(migrateCompendium);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {import("./migrationHelpers").ItemUpdateDataGetter} */
|
/** @type {import("./migrationHelpers.js").Migrator<Item>} */
|
||||||
function getItemUpdateData(itemData) {
|
async function migrateItem(item) {
|
||||||
if (!["loot"].includes(itemData.type ?? "")) return undefined;
|
if (item.type === "loot") {
|
||||||
return {
|
await item.update({ system: { "-=equipped": null } });
|
||||||
system: {
|
}
|
||||||
"-=equipped": null,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData);
|
const migrateActor = getActorMigrator(migrateItem);
|
||||||
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
|
const migrateScene = getSceneMigrator(migrateActor);
|
||||||
const migrateCompendium = getCompendiumMigrator(
|
const migrateCompendium = getCompendiumMigrator(
|
||||||
{ getItemUpdateData, getActorUpdateData },
|
{ migrateItem, migrateActor, migrateScene },
|
||||||
{ migrateToTemplateEarly: false },
|
{ migrateToTemplateEarly: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
/** @type {import("./migration").Migration} */
|
/** @type {import("./migration.js").Migration} */
|
||||||
export const migration = {
|
export const migration = {
|
||||||
migrate,
|
migrate,
|
||||||
migrateCompendium,
|
migrateCompendium,
|
||||||
|
|
|
@ -3,45 +3,44 @@
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getActorUpdateDataGetter,
|
getSceneMigrator,
|
||||||
getCompendiumMigrator,
|
migrateCollection,
|
||||||
getSceneUpdateDataGetter,
|
|
||||||
migrateActors,
|
|
||||||
migrateCompendiums,
|
migrateCompendiums,
|
||||||
migrateItems,
|
getCompendiumMigrator,
|
||||||
migrateScenes,
|
getActorMigrator,
|
||||||
} from "./migrationHelpers";
|
} from "./migrationHelpers.js";
|
||||||
|
|
||||||
/** @type {import("./migration").Migration["migrate"]} */
|
/** @type {import("./migration.js").Migration["migrate"]} */
|
||||||
async function migrate() {
|
async function migrate() {
|
||||||
await migrateItems(getItemUpdateData);
|
await migrateCollection(game.items, migrateItem);
|
||||||
await migrateActors(getActorUpdateData);
|
await migrateCollection(game.actors, migrateActor);
|
||||||
await migrateScenes(getSceneUpdateData);
|
await migrateCollection(game.scenes, migrateScene);
|
||||||
await migrateCompendiums(migrateCompendium);
|
await migrateCompendiums(migrateCompendium);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {import("./migrationHelpers").ItemUpdateDataGetter} */
|
/** @type {import('./migrationHelpers.js').Migrator<Item>} */
|
||||||
function getItemUpdateData(itemData) {
|
async function migrateItem(item) {
|
||||||
if (itemData.type !== "spell") return;
|
if (item.type === "spell") {
|
||||||
const cooldownDurationUnit = itemData.system?.cooldownDuration.unit;
|
const cooldownDurationUnit = item.system?.cooldownDuration.unit;
|
||||||
|
await item.update({
|
||||||
const updateData = {
|
system: {
|
||||||
system: {
|
"-=scrollPrice": null,
|
||||||
"-=scrollPrice": null,
|
minimumLevels: { healer: null, wizard: null, sorcerer: null },
|
||||||
minimumLevels: { healer: null, wizard: null, sorcerer: null },
|
cooldownDuration: {
|
||||||
cooldownDuration: {
|
unit: cooldownDurationUnit === "custom" ? "rounds" : cooldownDurationUnit,
|
||||||
unit: cooldownDurationUnit === "custom" ? "rounds" : cooldownDurationUnit,
|
},
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
return updateData;
|
return updateData;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData);
|
const migrateActor = getActorMigrator(migrateItem);
|
||||||
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
|
const migrateScene = getSceneMigrator(migrateActor);
|
||||||
const migrateCompendium = getCompendiumMigrator({ getItemUpdateData, getActorUpdateData, getSceneUpdateData });
|
const migrateCompendium = getCompendiumMigrator({ migrateItem, migrateActor, migrateScene });
|
||||||
|
|
||||||
/** @type {import("./migration").Migration} */
|
/** @type {import("./migration.js").Migration} */
|
||||||
export const migration = {
|
export const migration = {
|
||||||
migrate,
|
migrate,
|
||||||
migrateCompendium,
|
migrateCompendium,
|
||||||
|
|
|
@ -3,14 +3,12 @@
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getActorUpdateDataGetter,
|
getSceneMigrator,
|
||||||
getCompendiumMigrator,
|
migrateCollection,
|
||||||
getSceneUpdateDataGetter,
|
|
||||||
migrateActors,
|
|
||||||
migrateCompendiums,
|
migrateCompendiums,
|
||||||
migrateItems,
|
getCompendiumMigrator,
|
||||||
migrateScenes,
|
getActorMigrator,
|
||||||
} from "./migrationHelpers";
|
} from "./migrationHelpers.js";
|
||||||
|
|
||||||
const secondsPerRound = 5;
|
const secondsPerRound = 5;
|
||||||
const secondsPerMinute = 60;
|
const secondsPerMinute = 60;
|
||||||
|
@ -21,27 +19,22 @@ const hoursPerDay = 24;
|
||||||
const roundsPerDay = hoursPerDay / roundsPerHour;
|
const roundsPerDay = hoursPerDay / roundsPerHour;
|
||||||
const secondsPerDay = secondsPerMinute * minutesPerHour * hoursPerDay;
|
const secondsPerDay = secondsPerMinute * minutesPerHour * hoursPerDay;
|
||||||
|
|
||||||
/** @type {import("./migration").Migration["migrate"]} */
|
/** @type {import("./migration.js").Migration["migrate"]} */
|
||||||
async function migrate() {
|
async function migrate() {
|
||||||
await migrateItems(getItemUpdateData);
|
await migrateCollection(game.items, migrateItem);
|
||||||
await migrateActors(getActorUpdateData);
|
await migrateCollection(game.actors, migrateActor);
|
||||||
await migrateScenes(getSceneUpdateData);
|
await migrateCollection(game.scenes, migrateScene);
|
||||||
await migrateCompendiums(migrateCompendium);
|
await migrateCompendiums(migrateCompendium);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {import("./migrationHelpers").ItemUpdateDataGetter} */
|
/** @type {import('./migrationHelpers.js').Migrator<Item>} */
|
||||||
function getItemUpdateData(itemData) {
|
async function migrateItem(item) {
|
||||||
if (itemData.type !== "spell") return;
|
if (item.type === "spell") {
|
||||||
const cooldownDurationUnit = itemData.system?.cooldownDuration.unit;
|
const cooldownDurationUnit = item.system?.cooldownDuration.unit;
|
||||||
const cooldownDurationValue = itemData.system?.cooldownDuration.value;
|
const cooldownDurationValue = item.system?.cooldownDuration.value;
|
||||||
const cooldownDuration = migrateCooldownDuration(cooldownDurationValue, cooldownDurationUnit);
|
const cooldownDuration = migrateCooldownDuration(cooldownDurationValue, cooldownDurationUnit);
|
||||||
|
await item.update({ system: { cooldownDuration } });
|
||||||
const updateData = {
|
}
|
||||||
system: {
|
|
||||||
cooldownDuration,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return updateData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function migrateCooldownDuration(cooldownDurationValue = "", cooldownDurationUnit = "") {
|
function migrateCooldownDuration(cooldownDurationValue = "", cooldownDurationUnit = "") {
|
||||||
|
@ -114,11 +107,11 @@ function getRounds(unit, value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData);
|
const migrateActor = getActorMigrator(migrateItem);
|
||||||
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
|
const migrateScene = getSceneMigrator(migrateActor);
|
||||||
const migrateCompendium = getCompendiumMigrator({ getItemUpdateData, getActorUpdateData, getSceneUpdateData });
|
const migrateCompendium = getCompendiumMigrator({ migrateItem, migrateActor, migrateScene });
|
||||||
|
|
||||||
/** @type {import("./migration").Migration} */
|
/** @type {import("./migration.js").Migration} */
|
||||||
export const migration = {
|
export const migration = {
|
||||||
migrate,
|
migrate,
|
||||||
migrateCompendium,
|
migrateCompendium,
|
||||||
|
|
|
@ -3,42 +3,37 @@
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getActorUpdateDataGetter,
|
getSceneMigrator,
|
||||||
getCompendiumMigrator,
|
migrateCollection,
|
||||||
getSceneUpdateDataGetter,
|
|
||||||
migrateActors,
|
|
||||||
migrateCompendiums,
|
migrateCompendiums,
|
||||||
migrateItems,
|
getCompendiumMigrator,
|
||||||
migrateScenes,
|
getActorMigrator,
|
||||||
} from "./migrationHelpers";
|
} from "./migrationHelpers.js";
|
||||||
|
|
||||||
/** @type {import("./migration").Migration["migrate"]} */
|
/** @type {import("./migration.js").Migration["migrate"]} */
|
||||||
async function migrate() {
|
async function migrate() {
|
||||||
await migrateItems(getItemUpdateData);
|
await migrateCollection(game.items, migrateItem);
|
||||||
await migrateActors(getActorUpdateData);
|
await migrateCollection(game.actors, migrateActor);
|
||||||
await migrateScenes(getSceneUpdateData);
|
await migrateCollection(game.scenes, migrateScene);
|
||||||
await migrateCompendiums(migrateCompendium);
|
await migrateCompendiums(migrateCompendium);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {import("./migrationHelpers").ItemUpdateDataGetter} */
|
/** @type {import('./migrationHelpers.js').Migrator<Item>} */
|
||||||
function getItemUpdateData(itemData) {
|
async function migrateItem(item) {
|
||||||
if (itemData.type !== "spell") return;
|
if (item.type === "spell") {
|
||||||
const spellCategory = itemData.system?.spellCategory;
|
const spellCategory = item.system?.spellCategory;
|
||||||
const spellGroups = migrateSpellCategory(spellCategory);
|
const spellGroups = migrateSpellCategory(spellCategory);
|
||||||
|
const bonus = itemData.system?.bonus;
|
||||||
// @ts-expect-error bonus is removed with this migration
|
const spellModifier = migrateBonus(bonus);
|
||||||
const bonus = itemData.system?.bonus;
|
await item.update({
|
||||||
const spellModifier = migrateBonus(bonus);
|
system: {
|
||||||
|
spellGroups,
|
||||||
const updateData = {
|
"-=spellCategory": null,
|
||||||
system: {
|
spellModifier,
|
||||||
spellGroups,
|
"-=bonus": null,
|
||||||
"-=spellCategory": null,
|
},
|
||||||
spellModifier,
|
});
|
||||||
"-=bonus": null,
|
}
|
||||||
},
|
|
||||||
};
|
|
||||||
return updateData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,11 +111,11 @@ function migrateBonus(bonus) {
|
||||||
return spellModifier;
|
return spellModifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData);
|
const migrateActor = getActorMigrator(migrateItem);
|
||||||
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
|
const migrateScene = getSceneMigrator(migrateActor);
|
||||||
const migrateCompendium = getCompendiumMigrator({ getItemUpdateData, getActorUpdateData, getSceneUpdateData });
|
const migrateCompendium = getCompendiumMigrator({ migrateItem, migrateActor, migrateScene });
|
||||||
|
|
||||||
/** @type {import("./migration").Migration} */
|
/** @type {import("./migration.js").Migration} */
|
||||||
export const migration = {
|
export const migration = {
|
||||||
migrate,
|
migrate,
|
||||||
migrateCompendium,
|
migrateCompendium,
|
||||||
|
|
|
@ -3,39 +3,33 @@
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getActorUpdateDataGetter,
|
getSceneMigrator,
|
||||||
getCompendiumMigrator,
|
migrateCollection,
|
||||||
getSceneUpdateDataGetter,
|
|
||||||
migrateActors,
|
|
||||||
migrateCompendiums,
|
migrateCompendiums,
|
||||||
migrateItems,
|
getCompendiumMigrator,
|
||||||
migrateScenes,
|
getActorMigrator,
|
||||||
} from "./migrationHelpers";
|
} from "./migrationHelpers.js";
|
||||||
|
|
||||||
/** @type {import("./migration").Migration["migrate"]} */
|
/** @type {import("./migration.js").Migration["migrate"]} */
|
||||||
async function migrate() {
|
async function migrate() {
|
||||||
await migrateItems(getItemUpdateData);
|
await migrateCollection(game.items, migrateItem);
|
||||||
await migrateActors(getActorUpdateData);
|
await migrateCollection(game.actors, migrateActor);
|
||||||
await migrateScenes(getSceneUpdateData);
|
await migrateCollection(game.scenes, migrateScene);
|
||||||
await migrateCompendiums(migrateCompendium);
|
await migrateCompendiums(migrateCompendium);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {import("./migrationHelpers").ItemUpdateDataGetter} */
|
/** @type {import('./migrationHelpers.js').Migrator<Item>} */
|
||||||
function getItemUpdateData(itemData) {
|
async function migrateItem(item) {
|
||||||
if (itemData.type !== "spell") return;
|
if (item.type === "spell") {
|
||||||
|
await item.update({ system: { allowsDefense: false } });
|
||||||
return {
|
}
|
||||||
system: {
|
|
||||||
allowsDefense: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData);
|
const migrateActor = getActorMigrator(migrateItem);
|
||||||
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
|
const migrateScene = getSceneMigrator(migrateActor);
|
||||||
const migrateCompendium = getCompendiumMigrator({ getItemUpdateData, getActorUpdateData, getSceneUpdateData });
|
const migrateCompendium = getCompendiumMigrator({ migrateItem, migrateActor, migrateScene });
|
||||||
|
|
||||||
/** @type {import("./migration").Migration} */
|
/** @type {import("./migration.js").Migration} */
|
||||||
export const migration = {
|
export const migration = {
|
||||||
migrate,
|
migrate,
|
||||||
migrateCompendium,
|
migrateCompendium,
|
||||||
|
|
|
@ -3,28 +3,27 @@
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getActorUpdateDataGetter,
|
getSceneMigrator,
|
||||||
getCompendiumMigrator,
|
migrateCollection,
|
||||||
getItemUpdateDataGetter,
|
|
||||||
getSceneUpdateDataGetter,
|
|
||||||
migrateActors,
|
|
||||||
migrateCompendiums,
|
migrateCompendiums,
|
||||||
migrateItems,
|
getCompendiumMigrator,
|
||||||
migrateScenes,
|
getActorMigrator,
|
||||||
} from "./migrationHelpers";
|
getItemMigrator,
|
||||||
|
} from "./migrationHelpers.js";
|
||||||
|
|
||||||
/** @type {import("./migration").Migration["migrate"]} */
|
/** @type {import("./migration.js").Migration["migrate"]} */
|
||||||
async function migrate() {
|
async function migrate() {
|
||||||
await migrateItems(getItemUpdateData);
|
await migrateCollection(game.items, migrateItem);
|
||||||
await migrateActors(getActorUpdateData);
|
await migrateCollection(game.actors, migrateActor);
|
||||||
await migrateScenes(getSceneUpdateData);
|
await migrateCollection(game.scenes, migrateScene);
|
||||||
await migrateCompendiums(migrateCompendium);
|
await migrateCompendiums(migrateCompendium);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {import("./migrationHelpers").EffectUpdateDataGetter} */
|
/** @type {import('./migrationHelpers.js').Migrator<ActiveEffect>} */
|
||||||
function getEffectUpdateData(effectData) {
|
async function migrateActiveEffect(activeEffect) {
|
||||||
const data = foundry.utils.deepClone(effectData);
|
const data = activeEffect.toObject();
|
||||||
let hasUpdates = false;
|
let hasUpdates = false;
|
||||||
|
|
||||||
if ("changes" in data) {
|
if ("changes" in data) {
|
||||||
for (const change of data.changes) {
|
for (const change of data.changes) {
|
||||||
const newValue = change.value.replaceAll(/@data\./g, "@system.");
|
const newValue = change.value.replaceAll(/@data\./g, "@system.");
|
||||||
|
@ -45,16 +44,16 @@ function getEffectUpdateData(effectData) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasUpdates) {
|
if (hasUpdates) {
|
||||||
return data;
|
await activeEffect.update(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getItemUpdateData = getItemUpdateDataGetter(getEffectUpdateData);
|
const migrateItem = getItemMigrator(migrateActiveEffect);
|
||||||
const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData, getEffectUpdateData);
|
const migrateActor = getActorMigrator(migrateItem, migrateActiveEffect);
|
||||||
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
|
const migrateScene = getSceneMigrator(migrateActor);
|
||||||
const migrateCompendium = getCompendiumMigrator({ getItemUpdateData, getActorUpdateData, getSceneUpdateData });
|
const migrateCompendium = getCompendiumMigrator({ migrateItem, migrateActor, migrateScene });
|
||||||
|
|
||||||
/** @type {import("./migration").Migration} */
|
/** @type {import("./migration.js").Migration} */
|
||||||
export const migration = {
|
export const migration = {
|
||||||
migrate,
|
migrate,
|
||||||
migrateCompendium,
|
migrateCompendium,
|
||||||
|
|
|
@ -2,17 +2,17 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import { notifications } from "../ui/notifications";
|
import { notifications } from "../ui/notifications.js";
|
||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger.js";
|
||||||
import { getGame } from "../utils/utils";
|
import { getGame } from "../utils/utils.js";
|
||||||
import { migration as migration001 } from "./001";
|
import { migration as migration001 } from "./001.js";
|
||||||
import { migration as migration002 } from "./002";
|
import { migration as migration002 } from "./002.js";
|
||||||
import { migration as migration003 } from "./003";
|
import { migration as migration003 } from "./003.js";
|
||||||
import { migration as migration004 } from "./004";
|
import { migration as migration004 } from "./004.js";
|
||||||
import { migration as migration005 } from "./005";
|
import { migration as migration005 } from "./005.js";
|
||||||
import { migration as migration006 } from "./006";
|
import { migration as migration006 } from "./006.js";
|
||||||
import { migration as migration007 } from "./007";
|
import { migration as migration007 } from "./007.js";
|
||||||
import { migration as migration008 } from "./008";
|
import { migration as migration008 } from "./008.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform migrations.
|
* Perform migrations.
|
||||||
|
|
|
@ -2,82 +2,95 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import { DS4Actor } from "../documents/actor/actor";
|
import { DS4Actor } from "../documents/actor/actor.js";
|
||||||
import { DS4Item } from "../documents/item/item";
|
import { DS4Item } from "../documents/item/item.js";
|
||||||
import { logger } from "../utils/logger";
|
import { logger } from "../utils/logger.js";
|
||||||
import { getGame } from "../utils/utils";
|
import { getGame } from "../utils/utils.js";
|
||||||
|
|
||||||
/** @typedef {(effectData: object) => Record<string, unknown> | undefined} EffectUpdateDataGetter */
|
|
||||||
|
|
||||||
/** @typedef {(itemData: object) => Record<string, unknown> | undefined} ItemUpdateDataGetter */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrate world items.
|
* @template T
|
||||||
* @param {ItemUpdateDataGetter} getItemUpdateData A function for getting the update data for a given item data object
|
* @typedef {(document: T) => Promise<void>} Migrator
|
||||||
* @returns {Promise<void>} A promise that resolves once the migration is complete
|
|
||||||
*/
|
*/
|
||||||
export async function migrateItems(getItemUpdateData) {
|
|
||||||
for (const item of getGame().items ?? []) {
|
|
||||||
try {
|
|
||||||
const updateData = getItemUpdateData(item.toObject());
|
|
||||||
if (updateData) {
|
|
||||||
logger.info(`Migrating Item document ${item.name} (${item.id})`);
|
|
||||||
await item.update(updateData), { enforceTypes: false };
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
logger.error(`Error during migration of Item document ${item.name} (${item.id}), continuing anyways.`, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @typedef {(actorData: object>) => Record<string, unknown> | undefined} ActorUpdateDataGetter */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrate world actors.
|
* Migrate a collection.
|
||||||
* @param {ActorUpdateDataGetter} getActorUpdateData A function for getting the update data for a given actor data object
|
* @template T
|
||||||
|
* @param {WorldCollection} collection
|
||||||
|
* @param {Migrator<T>} migrateDocument
|
||||||
* @returns {Promise<void>} A promise that resolves once the migration is complete
|
* @returns {Promise<void>} A promise that resolves once the migration is complete
|
||||||
*/
|
*/
|
||||||
export async function migrateActors(getActorUpdateData) {
|
export async function migrateCollection(collection, migrateDocument) {
|
||||||
for (const actor of getGame().actors ?? []) {
|
const { documentName } = collection.constructor;
|
||||||
|
for (const document of collection) {
|
||||||
|
logger.info(`Migrating ${documentName} document ${document.name} (${document.id})`);
|
||||||
try {
|
try {
|
||||||
const updateData = getActorUpdateData(actor.toObject());
|
await migrateDocument(document);
|
||||||
if (updateData) {
|
|
||||||
logger.info(`Migrating Actor document ${actor.name} (${actor.id})`);
|
|
||||||
await actor.update(updateData);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error during migration of Actor document ${actor.name} (${actor.id}), continuing anyways.`,
|
`Error during migration of ${documentName} document ${document.name} (${document.id}), continuing anyways.`,
|
||||||
err,
|
err,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @typedef {(scene: Scene) => Record<string, unknown> | undefined} SceneUpdateDataGetter */
|
/**
|
||||||
|
* @param {Migrator<ActiveEffect>} [migrateActiveEffect]
|
||||||
|
* @returns {Migrator<Scene>}
|
||||||
|
*/
|
||||||
|
export function getItemMigrator(migrateActiveEffect) {
|
||||||
|
/**
|
||||||
|
* @param {Item} item
|
||||||
|
*/
|
||||||
|
return async (item) => {
|
||||||
|
if (migrateActiveEffect) {
|
||||||
|
for (const effect of item.effects) {
|
||||||
|
await migrateActiveEffect(effect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrate world scenes.
|
* @param {Migrator<Item>} [migrateItem]
|
||||||
* @param {SceneUpdateDataGetter} getSceneUpdateData A function for getting the update data for a given scene data object
|
* @param {Migrator<ActiveEffect>} [migrateActiveEffect]
|
||||||
* @returns {Promise<void>} A promise that resolves once the migration is complete
|
* @returns {Migrator<Scene>}
|
||||||
*/
|
*/
|
||||||
export async function migrateScenes(getSceneUpdateData) {
|
export function getActorMigrator(migrateItem, migrateActiveEffect) {
|
||||||
for (const scene of getGame().scenes ?? []) {
|
/**
|
||||||
try {
|
* @param {Actor} actor
|
||||||
const updateData = getSceneUpdateData(scene);
|
*/
|
||||||
if (updateData) {
|
return async (actor) => {
|
||||||
logger.info(`Migrating Scene document ${scene.name} (${scene.id})`);
|
if (migrateItem) {
|
||||||
await scene.update(updateData);
|
for (const item of actor.items) {
|
||||||
// We need to clear the old syntehtic actors from the cache
|
await migrateItem(item);
|
||||||
scene.tokens.forEach((t) => (t._actor = null));
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
logger.error(
|
|
||||||
`Error during migration of Scene document ${scene.name} (${scene.id}), continuing anyways.`,
|
|
||||||
err,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
if (migrateActiveEffect) {
|
||||||
|
for (const effect of actor.effects) {
|
||||||
|
await migrateActiveEffect(effect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Migrator<Actor>} [migrateActor]
|
||||||
|
* @returns {Migrator<Scene>}
|
||||||
|
*/
|
||||||
|
export function getSceneMigrator(migrateActor) {
|
||||||
|
/**
|
||||||
|
* @param {Scene} scene
|
||||||
|
*/
|
||||||
|
return async (scene) => {
|
||||||
|
if (migrateActor) {
|
||||||
|
for (const token of scene.tokens) {
|
||||||
|
if (!token.actorLink && token.actor) {
|
||||||
|
await migrateActor(token.actor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @typedef {(pack: CompendiumCollection) => Promise<void>} CompendiumMigrator */
|
/** @typedef {(pack: CompendiumCollection) => Promise<void>} CompendiumMigrator */
|
||||||
|
@ -96,118 +109,20 @@ export async function migrateCompendiums(migrateCompendium) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a function to create item update data based on the given function to update embedded documents.
|
* @typedef {object} Migrators
|
||||||
* @param {EffectUpdateDataGetter} [getEffectUpdateData] A function to generate effect update data
|
* @property {Migrator<Item>} [migrateItem]
|
||||||
* @returns {ItemUpdateDataGetter} A function to get item update data
|
* @property {Migrator<Actor>} [migrateActor]
|
||||||
*/
|
* @property {Migrator<Scene>} [migrateScene]
|
||||||
export function getItemUpdateDataGetter(getEffectUpdateData) {
|
|
||||||
return (itemData) => {
|
|
||||||
let hasEffectUpdates = false;
|
|
||||||
const effects = itemData.effects?.map((effectData) => {
|
|
||||||
const update = getEffectUpdateData(effectData);
|
|
||||||
if (update) {
|
|
||||||
hasEffectUpdates = true;
|
|
||||||
return foundry.utils.mergeObject(effectData, update, { inplace: false, performDeletions: true });
|
|
||||||
} else {
|
|
||||||
return effectData;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return hasEffectUpdates ? { effects } : undefined;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a function to create actor update data based on the given function to update embedded documents.
|
|
||||||
* @param {ItemUpdateDataGetter} [getItemUpdateData] A function to generate item update data
|
|
||||||
* @param {EffectUpdateDataGetter} [getEffectUpdateData] A function to generate effect update data
|
|
||||||
* @returns {ActorUpdateDataGetter} A function to get actor update data
|
|
||||||
*/
|
|
||||||
export function getActorUpdateDataGetter(getItemUpdateData, getEffectUpdateData) {
|
|
||||||
return (actorData) => {
|
|
||||||
let hasItemUpdates = false;
|
|
||||||
const items = actorData.items?.map((itemData) => {
|
|
||||||
const update = getItemUpdateData?.(itemData);
|
|
||||||
if (update) {
|
|
||||||
hasItemUpdates = true;
|
|
||||||
return foundry.utils.mergeObject(itemData, update, { inplace: false, performDeletions: true });
|
|
||||||
} else {
|
|
||||||
return itemData;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let hasEffectUpdates = false;
|
|
||||||
const effects = actorData.effects?.map((effectData) => {
|
|
||||||
const update = getEffectUpdateData?.(effectData);
|
|
||||||
if (update) {
|
|
||||||
hasEffectUpdates = true;
|
|
||||||
return foundry.utils.mergeObject(effectData, update, { inplace: false, performDeletions: true });
|
|
||||||
} else {
|
|
||||||
return effectData;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const result = {
|
|
||||||
items: hasItemUpdates ? items : undefined,
|
|
||||||
effects: hasEffectUpdates ? effects : undefined,
|
|
||||||
};
|
|
||||||
return hasItemUpdates | hasEffectUpdates ? result : undefined;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a function to create scene update data that adjusts the actors of the tokens of the scene according to the given function.
|
|
||||||
* @param {ActorUpdateDataGetter} [getItemUpdateData] The function to generate actor update data
|
|
||||||
* @returns {SceneUpdateDataGetter} A function to get scene update data
|
|
||||||
*/
|
|
||||||
export function getSceneUpdateDataGetter(getActorUpdateData) {
|
|
||||||
return (scene) => {
|
|
||||||
const tokens = scene.tokens.map((token) => {
|
|
||||||
const t = token.toObject();
|
|
||||||
if (!t.actorId || t.actorLink) {
|
|
||||||
t.actorData = {};
|
|
||||||
} else if (!getGame().actors?.has(t.actorId)) {
|
|
||||||
t.actorId = null;
|
|
||||||
t.actorData = {};
|
|
||||||
} else if (!t.actorLink) {
|
|
||||||
const actorData = foundry.utils.deepClone(t.actorData);
|
|
||||||
actorData.type = token.actor?.type;
|
|
||||||
const update = getActorUpdateData?.(actorData);
|
|
||||||
if (update !== undefined) {
|
|
||||||
["items", "effects"].forEach((embeddedName) => {
|
|
||||||
const embeddedUpdates = update[embeddedName];
|
|
||||||
if (!embeddedUpdates?.length) return;
|
|
||||||
const updates = new Map(embeddedUpdates.flatMap((u) => (u && u._id ? [[u._id, u]] : [])));
|
|
||||||
const originals = t.actorData[embeddedName];
|
|
||||||
if (!originals) return;
|
|
||||||
originals.forEach((original) => {
|
|
||||||
if (!original._id) return;
|
|
||||||
const update = updates.get(original._id);
|
|
||||||
if (update) foundry.utils.mergeObject(original, update, { performDeletions: true });
|
|
||||||
});
|
|
||||||
delete update[embeddedName];
|
|
||||||
});
|
|
||||||
foundry.utils.mergeObject(t.actorData, update);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
});
|
|
||||||
return { tokens };
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {object} UpdateDataGetters
|
|
||||||
* @property {ItemUpdateDataGetter} [getItemUpdateData]
|
|
||||||
* @property {ActorUpdateDataGetter} [getActorUpdateData]
|
|
||||||
* @property {SceneUpdateDataGetter} [getSceneUpdateData]
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a compendium migrator for the given update data getters.
|
* Get a compendium migrator for the given migrators.
|
||||||
* @param {UpdateDataGetters} [updateDataGetters={}] The functions to use for getting update data
|
* @param {Migrators} [migrators={}] The functions to use for getting update data
|
||||||
* @param {{migrateToTemplateEarly?: boolean}} [options={}] Additional options for the compendium migrator
|
* @param {{migrateToTemplateEarly?: boolean}} [options={}] Additional options for the compendium migrator
|
||||||
* @returns {CompendiumMigrator} The resulting compendium migrator
|
* @returns {CompendiumMigrator} The resulting compendium migrator
|
||||||
*/
|
*/
|
||||||
export function getCompendiumMigrator(
|
export function getCompendiumMigrator(
|
||||||
{ getItemUpdateData, getActorUpdateData, getSceneUpdateData } = {},
|
{ migrateItem, migrateActor, migrateScene } = {},
|
||||||
{ migrateToTemplateEarly = true } = {},
|
{ migrateToTemplateEarly = true } = {},
|
||||||
) {
|
) {
|
||||||
return async (pack) => {
|
return async (pack) => {
|
||||||
|
@ -224,15 +139,12 @@ export function getCompendiumMigrator(
|
||||||
for (const doc of documents) {
|
for (const doc of documents) {
|
||||||
try {
|
try {
|
||||||
logger.info(`Migrating document ${doc.name} (${doc.id}) in compendium ${pack.collection}`);
|
logger.info(`Migrating document ${doc.name} (${doc.id}) in compendium ${pack.collection}`);
|
||||||
if (doc instanceof DS4Item && getItemUpdateData) {
|
if (doc instanceof DS4Item && migrateItem) {
|
||||||
const updateData = getItemUpdateData(doc.toObject());
|
await migrateItem(doc);
|
||||||
updateData && (await doc.update(updateData));
|
} else if (doc instanceof DS4Actor && migrateActor) {
|
||||||
} else if (doc instanceof DS4Actor && getActorUpdateData) {
|
await migrateActor(doc);
|
||||||
const updateData = getActorUpdateData(doc.toObject());
|
} else if (doc instanceof Scene && migrateScene) {
|
||||||
updateData && (await doc.update(updateData));
|
await migrateScene(doc);
|
||||||
} else if (doc instanceof Scene && getSceneUpdateData) {
|
|
||||||
const updateData = getSceneUpdateData(doc);
|
|
||||||
updateData && (await doc.update(updateData));
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(
|
logger.error(
|
||||||
|
|
Loading…
Reference in a new issue