Update migrations for 0.8.x
This commit is contained in:
parent
c46c2c4a0a
commit
b694f20e1c
7 changed files with 277 additions and 449 deletions
|
@ -5,9 +5,9 @@
|
||||||
import { getGame } from "./helpers";
|
import { getGame } from "./helpers";
|
||||||
import logger from "./logger";
|
import logger from "./logger";
|
||||||
import { migrate as migrate001 } from "./migrations/001";
|
import { migrate as migrate001 } from "./migrations/001";
|
||||||
// import { migrate as migrate002 } from "./migrations/002";
|
import { migrate as migrate002 } from "./migrations/002";
|
||||||
// import { migrate as migrate003 } from "./migrations/003";
|
import { migrate as migrate003 } from "./migrations/003";
|
||||||
// import { migrate as migrate004 } from "./migrations/004";
|
import { migrate as migrate004 } from "./migrations/004";
|
||||||
import notifications from "./ui/notifications";
|
import notifications from "./ui/notifications";
|
||||||
|
|
||||||
async function migrate(): Promise<void> {
|
async function migrate(): Promise<void> {
|
||||||
|
@ -78,7 +78,7 @@ function getTargetMigrationVersion(): number {
|
||||||
return migrations.length;
|
return migrations.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
const migrations: Array<() => Promise<void>> = [migrate001 /* migrate002, migrate003, migrate004 */];
|
const migrations: Array<() => Promise<void>> = [migrate001, migrate002, migrate003, migrate004];
|
||||||
|
|
||||||
function isFirstWorldStart(migrationVersion: number): boolean {
|
function isFirstWorldStart(migrationVersion: number): boolean {
|
||||||
return migrationVersion < 0;
|
return migrationVersion < 0;
|
||||||
|
|
|
@ -2,15 +2,18 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import { getGame } from "../helpers";
|
import {
|
||||||
import logger from "../logger";
|
getCompendiumMigrator,
|
||||||
|
getSceneUpdateDataGetter,
|
||||||
|
migrateActors,
|
||||||
|
migrateCompendiums,
|
||||||
|
migrateScenes,
|
||||||
|
} from "./migrationHelpers";
|
||||||
|
|
||||||
export async function migrate(): Promise<void> {
|
export async function migrate(): Promise<void> {
|
||||||
for (const a of getGame().actors?.contents ?? []) {
|
await migrateActors(getActorUpdateData);
|
||||||
const updateData = getActorUpdateData();
|
await migrateScenes(getSceneUpdateData);
|
||||||
logger.info(`Migrating actor ${a.name}`);
|
await migrateCompendiums(migrateCompendium);
|
||||||
await a.update(updateData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActorUpdateData(): Record<string, unknown> {
|
function getActorUpdateData(): Record<string, unknown> {
|
||||||
|
@ -33,3 +36,6 @@ function getActorUpdateData(): Record<string, unknown> {
|
||||||
};
|
};
|
||||||
return updateData;
|
return updateData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
|
||||||
|
const migrateCompendium = getCompendiumMigrator({ getActorUpdateData, getSceneUpdateData });
|
||||||
|
|
|
@ -2,153 +2,33 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import logger from "../logger";
|
import {
|
||||||
|
getActorUpdateDataGetter,
|
||||||
|
getCompendiumMigrator,
|
||||||
|
getSceneUpdateDataGetter,
|
||||||
|
migrateActors,
|
||||||
|
migrateCompendiums,
|
||||||
|
migrateItems,
|
||||||
|
migrateScenes,
|
||||||
|
} from "./migrationHelpers";
|
||||||
|
|
||||||
// export async function migrate(): Promise<void> {
|
export async function migrate(): Promise<void> {
|
||||||
// await migrateItems();
|
await migrateItems(getItemUpdateData);
|
||||||
// await migrateActors();
|
await migrateActors(getActorUpdateData);
|
||||||
// await migrateScenes();
|
await migrateScenes(getSceneUpdateData);
|
||||||
// await migrateCompendiums();
|
await migrateCompendiums(migrateCompendium);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// async function migrateItems() {
|
function getItemUpdateData(
|
||||||
// for (const item of getGame().items?.contents ?? []) {
|
itemData: Partial<foundry.data.ItemData["_source"]>,
|
||||||
// try {
|
): DeepPartial<foundry.data.ItemData["_source"]> | undefined {
|
||||||
// const updateData = getItemUpdateData(item.toObject());
|
if (!["equipment", "trinket"].includes(itemData.type ?? "")) return undefined;
|
||||||
// if (updateData) {
|
return { type: itemData.type === "equipment" ? ("loot" as const) : ("equipment" as const) };
|
||||||
// logger.info(`Migrating Item entity ${item.name} (${item.id})`);
|
}
|
||||||
// await item.update(updateData), { enforceTypes: false };
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// err.message = `Error during migration of Item entity ${item.name} (${item.id}), continuing anyways.`;
|
|
||||||
// logger.error(err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function getItemUpdateData(itemData: foundry.data.ItemData["_source"]) {
|
const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData);
|
||||||
// if (!["equipment", "trinket"].includes(itemData.type ?? "")) return undefined;
|
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
|
||||||
// return { type: itemData.type === "equipment" ? ("loot" as const) : ("equipment" as const) };
|
const migrateCompendium = getCompendiumMigrator(
|
||||||
// }
|
{ getItemUpdateData, getActorUpdateData, getSceneUpdateData },
|
||||||
|
{ migrateToTemplateEarly: false },
|
||||||
// async function migrateActors() {
|
);
|
||||||
// for (const actor of getGame().actors?.contents ?? []) {
|
|
||||||
// try {
|
|
||||||
// const updateData = getActorUpdateData(actor.toObject());
|
|
||||||
// if (updateData) {
|
|
||||||
// logger.info(`Migrating Actor entity ${actor.name} (${actor.id})`);
|
|
||||||
// await actor.update(updateData);
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// err.message = `Error during migration of Actor entity ${actor.name} (${actor.id}), continuing anyways.`;
|
|
||||||
// logger.error(err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function getActorUpdateData(actorData: foundry.data.ActorData["_source"]) {
|
|
||||||
// let hasItemUpdates = false;
|
|
||||||
// const items = actorData.items.map((itemData: foundry.data.ItemData["_source"]) => {
|
|
||||||
// const update = itemData ? getItemUpdateData(itemData) : undefined;
|
|
||||||
// if (update) {
|
|
||||||
// hasItemUpdates = true;
|
|
||||||
// return { ...itemData, ...update };
|
|
||||||
// } else {
|
|
||||||
// return itemData;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// return hasItemUpdates ? { items } : undefined;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function migrateScenes() {
|
|
||||||
// for (const scene of getGame().scenes?.contents ?? []) {
|
|
||||||
// try {
|
|
||||||
// const updateData = getSceneUpdateData(scene.toObject());
|
|
||||||
// if (updateData) {
|
|
||||||
// logger.info(`Migrating Scene entity ${scene.name} (${scene.id})`);
|
|
||||||
// await scene.update(updateData);
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// err.message = `Error during migration of Scene document ${scene.name} (${scene.id}), continuing anyways.`;
|
|
||||||
// logger.error(err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function getSceneUpdateData(scene: Scene) {
|
|
||||||
// let hasTokenUpdates = false;
|
|
||||||
// // TODO: Continue from here
|
|
||||||
// const tokens = scene.tokens.map((tokenData: foundry.data.TokenData["_source"]) => {
|
|
||||||
// if (!tokenData.actorId || tokenData.actorLink) {
|
|
||||||
// tokenData.actorData = {};
|
|
||||||
// } else if (!getGame().actors?.has(tokenData.actorId)) {
|
|
||||||
// tokenData.actorId = null;
|
|
||||||
// tokenData.actorData = {};
|
|
||||||
// } else if (!tokenData.actorLink) {
|
|
||||||
// const actorData = duplicate(tokenData.actorData);
|
|
||||||
// actorData.type = token.actor?.type;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (!tokenData.actorId || tokenData.actorLink || tokenData.actorData.data) {
|
|
||||||
// tokenData.actorData = {};
|
|
||||||
// hasTokenUpdates = true;
|
|
||||||
// return tokenData;
|
|
||||||
// }
|
|
||||||
// const token = new Token(tokenData);
|
|
||||||
// if (!token.actor) {
|
|
||||||
// tokenData.actorId = null as unknown as string;
|
|
||||||
// tokenData.actorData = {};
|
|
||||||
// hasTokenUpdates = true;
|
|
||||||
// } else if (!tokenData.actorLink) {
|
|
||||||
// const actorUpdateData = getActorUpdateData(token.data.actorData);
|
|
||||||
// tokenData.actorData = mergeObject(token.data.actorData, actorUpdateData);
|
|
||||||
// hasTokenUpdates = true;
|
|
||||||
// }
|
|
||||||
// return tokenData;
|
|
||||||
// });
|
|
||||||
// if (!hasTokenUpdates) return undefined;
|
|
||||||
// return hasTokenUpdates ? { tokens } : undefined;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function migrateCompendiums() {
|
|
||||||
// for (const compendium of getGame().packs ?? []) {
|
|
||||||
// if (compendium.metadata.package !== "world") continue;
|
|
||||||
// if (!["Actor", "Item", "Scene"].includes(compendium.metadata.entity)) continue;
|
|
||||||
// await migrateCompendium(compendium);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function migrateCompendium(compendium: Compendium) {
|
|
||||||
// const entityName = compendium.metadata.entity;
|
|
||||||
// if (!["Actor", "Item", "Scene"].includes(entityName)) return;
|
|
||||||
// const wasLocked = compendium.locked;
|
|
||||||
// await compendium.configure({ locked: false });
|
|
||||||
|
|
||||||
// const content = await compendium.getContent();
|
|
||||||
|
|
||||||
// for (const entity of content) {
|
|
||||||
// try {
|
|
||||||
// const getUpdateData = (entity: Entity) => {
|
|
||||||
// switch (entityName) {
|
|
||||||
// case "Item":
|
|
||||||
// return getItemUpdateData(entity._data);
|
|
||||||
// case "Actor":
|
|
||||||
// return getActorUpdateData(entity._data);
|
|
||||||
// case "Scene":
|
|
||||||
// return getSceneUpdateData(entity._data as Scene.Data);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// const updateData = getUpdateData(entity);
|
|
||||||
// if (updateData) {
|
|
||||||
// logger.info(`Migrating entity ${entity.name} (${entity.id}) in compendium ${compendium.collection}`);
|
|
||||||
// await compendium.updateEntity({ ...updateData, _id: entity._id });
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// err.message = `Error during migration of entity ${entity.name} (${entity.id}) in compendium ${compendium.collection}, continuing anyways.`;
|
|
||||||
// logger.error(err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// await compendium.migrate({});
|
|
||||||
// await compendium.configure({ locked: wasLocked });
|
|
||||||
// }
|
|
||||||
|
|
|
@ -2,146 +2,33 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import logger from "../logger";
|
import {
|
||||||
|
getActorUpdateDataGetter,
|
||||||
|
getCompendiumMigrator,
|
||||||
|
getSceneUpdateDataGetter,
|
||||||
|
migrateActors,
|
||||||
|
migrateCompendiums,
|
||||||
|
migrateItems,
|
||||||
|
migrateScenes,
|
||||||
|
} from "./migrationHelpers";
|
||||||
|
|
||||||
// export async function migrate(): Promise<void> {
|
export async function migrate(): Promise<void> {
|
||||||
// await migrateItems();
|
await migrateItems(getItemUpdateData);
|
||||||
// await migrateActors();
|
await migrateActors(getActorUpdateData);
|
||||||
// await migrateScenes();
|
await migrateScenes(getSceneUpdateData);
|
||||||
// await migrateCompendiums();
|
await migrateCompendiums(migrateCompendium);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// async function migrateItems() {
|
function getItemUpdateData(itemData: Partial<foundry.data.ItemData["_source"]>) {
|
||||||
// for (const item of getGame().items?.entities ?? []) {
|
if (!["loot"].includes(itemData.type ?? "")) return undefined;
|
||||||
// try {
|
return {
|
||||||
// const updateData = getItemUpdateData(item._data);
|
"-=data.equipped": null,
|
||||||
// if (updateData) {
|
};
|
||||||
// logger.info(`Migrating Item entity ${item.name} (${item.id})`);
|
}
|
||||||
// await item.update(updateData), { enforceTypes: false };
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// err.message = `Error during migration of Item entity ${item.name} (${item.id}), continuing anyways.`;
|
|
||||||
// logger.error(err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function getItemUpdateData(itemData: DeepPartial<Item.Data>) {
|
const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData);
|
||||||
// if (!["loot"].includes(itemData.type ?? "")) return undefined;
|
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
|
||||||
// return {
|
const migrateCompendium = getCompendiumMigrator(
|
||||||
// data: {
|
{ getItemUpdateData, getActorUpdateData },
|
||||||
// "-=equipped": null,
|
{ migrateToTemplateEarly: false },
|
||||||
// },
|
);
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function migrateActors() {
|
|
||||||
// for (const actor of getGame().actors?.entities ?? []) {
|
|
||||||
// try {
|
|
||||||
// const updateData = getActorUpdateData(actor._data);
|
|
||||||
// if (updateData) {
|
|
||||||
// logger.info(`Migrating Actor entity ${actor.name} (${actor.id})`);
|
|
||||||
// await actor.update(updateData, { enforceTypes: false });
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// err.message = `Error during migration of Actor entity ${actor.name} (${actor.id}), continuing anyways.`;
|
|
||||||
// logger.error(err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function getActorUpdateData(actorData: DeepPartial<Actor.Data>) {
|
|
||||||
// let hasItemUpdates = false;
|
|
||||||
// const items = actorData.items?.map((itemData) => {
|
|
||||||
// const update = itemData ? getItemUpdateData(itemData) : undefined;
|
|
||||||
// if (update) {
|
|
||||||
// hasItemUpdates = true;
|
|
||||||
// return mergeObject(itemData, update, { enforceTypes: false, inplace: false });
|
|
||||||
// } else {
|
|
||||||
// return itemData;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// return hasItemUpdates ? { items } : undefined;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function migrateScenes() {
|
|
||||||
// for (const scene of getGame().scenes?.entities ?? []) {
|
|
||||||
// try {
|
|
||||||
// const updateData = getSceneUpdateData(scene._data);
|
|
||||||
// if (updateData) {
|
|
||||||
// logger.info(`Migrating Scene entity ${scene.name} (${scene.id})`);
|
|
||||||
// await scene.update(updateData, { enforceTypes: false });
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// err.message = `Error during migration of Scene entity ${scene.name} (${scene.id}), continuing anyways.`;
|
|
||||||
// logger.error(err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function getSceneUpdateData(sceneData: Scene.Data) {
|
|
||||||
// let hasTokenUpdates = false;
|
|
||||||
// const tokens = sceneData.tokens.map((tokenData) => {
|
|
||||||
// if (!tokenData.actorId || tokenData.actorLink || tokenData.actorData.data) {
|
|
||||||
// tokenData.actorData = {};
|
|
||||||
// hasTokenUpdates = true;
|
|
||||||
// return tokenData;
|
|
||||||
// }
|
|
||||||
// const token = new Token(tokenData);
|
|
||||||
// if (!token.actor) {
|
|
||||||
// tokenData.actorId = null as unknown as string;
|
|
||||||
// tokenData.actorData = {};
|
|
||||||
// hasTokenUpdates = true;
|
|
||||||
// } else if (!tokenData.actorLink) {
|
|
||||||
// const actorUpdateData = getActorUpdateData(token.data.actorData);
|
|
||||||
// tokenData.actorData = mergeObject(token.data.actorData, actorUpdateData);
|
|
||||||
// hasTokenUpdates = true;
|
|
||||||
// }
|
|
||||||
// return tokenData;
|
|
||||||
// });
|
|
||||||
// if (!hasTokenUpdates) return undefined;
|
|
||||||
// return hasTokenUpdates ? { tokens } : undefined;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function migrateCompendiums() {
|
|
||||||
// for (const compendium of getGame().packs ?? []) {
|
|
||||||
// if (compendium.metadata.package !== "world") continue;
|
|
||||||
// if (!["Actor", "Item", "Scene"].includes(compendium.metadata.entity)) continue;
|
|
||||||
// await migrateCompendium(compendium);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function migrateCompendium(compendium: Compendium) {
|
|
||||||
// const entityName = compendium.metadata.entity;
|
|
||||||
// if (!["Actor", "Item", "Scene"].includes(entityName)) return;
|
|
||||||
// const wasLocked = compendium.locked;
|
|
||||||
// await compendium.configure({ locked: false });
|
|
||||||
|
|
||||||
// const content = await compendium.getContent();
|
|
||||||
|
|
||||||
// for (const entity of content) {
|
|
||||||
// try {
|
|
||||||
// const getUpdateData = (entity: Entity) => {
|
|
||||||
// switch (entityName) {
|
|
||||||
// case "Item":
|
|
||||||
// return getItemUpdateData(entity._data);
|
|
||||||
// case "Actor":
|
|
||||||
// return getActorUpdateData(entity._data);
|
|
||||||
// case "Scene":
|
|
||||||
// return getSceneUpdateData(entity._data as Scene.Data);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// const updateData = getUpdateData(entity);
|
|
||||||
// if (updateData) {
|
|
||||||
// logger.info(`Migrating entity ${entity.name} (${entity.id}) in compendium ${compendium.collection}`);
|
|
||||||
// await compendium.updateEntity({ ...updateData, _id: entity._id });
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// err.message = `Error during migration of entity ${entity.name} (${entity.id}) in compendium ${compendium.collection}, continuing anyways.`;
|
|
||||||
// logger.error(err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// await compendium.migrate({});
|
|
||||||
// await compendium.configure({ locked: wasLocked });
|
|
||||||
// }
|
|
||||||
|
|
|
@ -2,157 +2,38 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import { DS4SpellDataSourceData } from "../item/item-data-source";
|
import {
|
||||||
import logger from "../logger";
|
getActorUpdateDataGetter,
|
||||||
|
getCompendiumMigrator,
|
||||||
|
getSceneUpdateDataGetter,
|
||||||
|
migrateActors,
|
||||||
|
migrateCompendiums,
|
||||||
|
migrateItems,
|
||||||
|
migrateScenes,
|
||||||
|
} from "./migrationHelpers";
|
||||||
|
|
||||||
// export async function migrate(): Promise<void> {
|
export async function migrate(): Promise<void> {
|
||||||
// await migrateItems();
|
await migrateItems(getItemUpdateData);
|
||||||
// await migrateActors();
|
await migrateActors(getActorUpdateData);
|
||||||
// await migrateScenes();
|
await migrateScenes(getSceneUpdateData);
|
||||||
// await migrateCompendiums();
|
await migrateCompendiums(migrateCompendium);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// async function migrateItems() {
|
function getItemUpdateData(itemData: Partial<foundry.data.ItemData["_source"]>) {
|
||||||
// for (const item of getGame().items?.entities ?? []) {
|
if (itemData.type !== "spell") return;
|
||||||
// try {
|
const updateData: Record<string, unknown> = {
|
||||||
// const updateData = getItemUpdateData(item._data);
|
"-=data.scrollPrice": null,
|
||||||
// if (updateData) {
|
"data.minimumLevels": { healer: null, wizard: null, sorcerer: null },
|
||||||
// logger.info(`Migrating Item entity ${item.name} (${item.id})`);
|
};
|
||||||
// await item.update(updateData), { enforceTypes: false };
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// err.message = `Error during migration of Item entity ${item.name} (${item.id}), continuing anyways.`;
|
|
||||||
// logger.error(err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function getItemUpdateData(itemData: DeepPartial<Item.Data>) {
|
const cooldownDurationUnit: string | undefined = itemData.data?.cooldownDuration.unit;
|
||||||
// if (!["spell"].includes(itemData.type ?? "")) return undefined;
|
|
||||||
// const updateData: Record<string, unknown> = {
|
|
||||||
// "-=data.scrollPrice": null,
|
|
||||||
// "data.minimumLevels": { healer: null, wizard: null, sorcerer: null },
|
|
||||||
// };
|
|
||||||
// if (((itemData.data as DS4SpellDataSourceData).cooldownDuration.unit as string) === "custom") {
|
|
||||||
// updateData["data.cooldownDuration.unit"] = "rounds";
|
|
||||||
// }
|
|
||||||
// return updateData;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function migrateActors() {
|
if (cooldownDurationUnit === "custom") {
|
||||||
// for (const actor of getGame().actors?.entities ?? []) {
|
updateData["data.cooldownDuration.unit"] = "rounds";
|
||||||
// try {
|
}
|
||||||
// const updateData = getActorUpdateData(actor._data);
|
return updateData;
|
||||||
// if (updateData) {
|
}
|
||||||
// logger.info(`Migrating Actor entity ${actor.name} (${actor.id})`);
|
|
||||||
// await actor.update(updateData, { enforceTypes: false });
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// err.message = `Error during migration of Actor entity ${actor.name} (${actor.id}), continuing anyways.`;
|
|
||||||
// logger.error(err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function getActorUpdateData(actorData: DeepPartial<Actor.Data>) {
|
const getActorUpdateData = getActorUpdateDataGetter(getItemUpdateData);
|
||||||
// let hasItemUpdates = false;
|
const getSceneUpdateData = getSceneUpdateDataGetter(getActorUpdateData);
|
||||||
// const items = actorData.items?.map((itemData) => {
|
const migrateCompendium = getCompendiumMigrator({ getItemUpdateData, getActorUpdateData, getSceneUpdateData });
|
||||||
// const update = itemData ? getItemUpdateData(itemData) : undefined;
|
|
||||||
// if (update) {
|
|
||||||
// hasItemUpdates = true;
|
|
||||||
// return mergeObject(itemData, update, { enforceTypes: false, inplace: false });
|
|
||||||
// } else {
|
|
||||||
// return itemData;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// const updateData: Record<string, unknown> = {};
|
|
||||||
// if (actorData.type === "character") {
|
|
||||||
// updateData["data.slayerPoints"] = { value: 0 };
|
|
||||||
// }
|
|
||||||
// if (hasItemUpdates) {
|
|
||||||
// updateData["items"] = items;
|
|
||||||
// }
|
|
||||||
// return updateData;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function migrateScenes() {
|
|
||||||
// for (const scene of getGame().scenes?.entities ?? []) {
|
|
||||||
// try {
|
|
||||||
// const updateData = getSceneUpdateData(scene._data);
|
|
||||||
// if (updateData) {
|
|
||||||
// logger.info(`Migrating Scene entity ${scene.name} (${scene.id})`);
|
|
||||||
// await scene.update(updateData, { enforceTypes: false });
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// err.message = `Error during migration of Scene entity ${scene.name} (${scene.id}), continuing anyways.`;
|
|
||||||
// logger.error(err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function getSceneUpdateData(sceneData: Scene.Data) {
|
|
||||||
// let hasTokenUpdates = false;
|
|
||||||
// const tokens = sceneData.tokens.map((tokenData) => {
|
|
||||||
// if (!tokenData.actorId || tokenData.actorLink || tokenData.actorData.data) {
|
|
||||||
// tokenData.actorData = {};
|
|
||||||
// hasTokenUpdates = true;
|
|
||||||
// return tokenData;
|
|
||||||
// }
|
|
||||||
// const token = new Token(tokenData);
|
|
||||||
// if (!token.actor) {
|
|
||||||
// tokenData.actorId = null as unknown as string;
|
|
||||||
// tokenData.actorData = {};
|
|
||||||
// hasTokenUpdates = true;
|
|
||||||
// } else if (!tokenData.actorLink) {
|
|
||||||
// const actorUpdateData = getActorUpdateData(token.data.actorData);
|
|
||||||
// tokenData.actorData = mergeObject(token.data.actorData, actorUpdateData);
|
|
||||||
// hasTokenUpdates = true;
|
|
||||||
// }
|
|
||||||
// return tokenData;
|
|
||||||
// });
|
|
||||||
// if (!hasTokenUpdates) return undefined;
|
|
||||||
// return hasTokenUpdates ? { tokens } : undefined;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function migrateCompendiums() {
|
|
||||||
// for (const compendium of getGame().packs ?? []) {
|
|
||||||
// if (compendium.metadata.package !== "world") continue;
|
|
||||||
// if (!["Actor", "Item", "Scene"].includes(compendium.metadata.entity)) continue;
|
|
||||||
// await migrateCompendium(compendium);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function migrateCompendium(compendium: Compendium) {
|
|
||||||
// const entityName = compendium.metadata.entity;
|
|
||||||
// if (!["Actor", "Item", "Scene"].includes(entityName)) return;
|
|
||||||
// const wasLocked = compendium.locked;
|
|
||||||
// await compendium.configure({ locked: false });
|
|
||||||
// await compendium.migrate({});
|
|
||||||
|
|
||||||
// const content = await compendium.getContent();
|
|
||||||
|
|
||||||
// for (const entity of content) {
|
|
||||||
// try {
|
|
||||||
// const getUpdateData = (entity: Entity) => {
|
|
||||||
// switch (entityName) {
|
|
||||||
// case "Item":
|
|
||||||
// return getItemUpdateData(entity._data);
|
|
||||||
// case "Actor":
|
|
||||||
// return getActorUpdateData(entity._data);
|
|
||||||
// case "Scene":
|
|
||||||
// return getSceneUpdateData(entity._data as Scene.Data);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// const updateData = getUpdateData(entity);
|
|
||||||
// if (updateData) {
|
|
||||||
// logger.info(`Migrating entity ${entity.name} (${entity.id}) in compendium ${compendium.collection}`);
|
|
||||||
// await compendium.updateEntity({ ...updateData, _id: entity._id });
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// err.message = `Error during migration of entity ${entity.name} (${entity.id}) in compendium ${compendium.collection}, continuing anyways.`;
|
|
||||||
// logger.error(err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// await compendium.configure({ locked: wasLocked });
|
|
||||||
// }
|
|
||||||
|
|
174
src/module/migrations/migrationHelpers.ts
Normal file
174
src/module/migrations/migrationHelpers.ts
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
import { DS4Actor } from "../actor/actor";
|
||||||
|
import { getGame } from "../helpers";
|
||||||
|
import { DS4Item } from "../item/item";
|
||||||
|
import logger from "../logger";
|
||||||
|
|
||||||
|
type ItemUpdateDataGetter = (
|
||||||
|
itemData: Partial<foundry.data.ItemData["_source"]>,
|
||||||
|
) => DeepPartial<foundry.data.ItemData["_source"]> | Record<string, unknown> | undefined;
|
||||||
|
|
||||||
|
export async function migrateItems(getItemUpdateData: ItemUpdateDataGetter): Promise<void> {
|
||||||
|
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) {
|
||||||
|
err.message = `Error during migration of Item document ${item.name} (${item.id}), continuing anyways.`;
|
||||||
|
logger.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActorUpdateDataGetter = (
|
||||||
|
itemData: Partial<foundry.data.ActorData["_source"]>,
|
||||||
|
) => DeepPartial<foundry.data.ActorData["_source"]> | undefined;
|
||||||
|
|
||||||
|
export async function migrateActors(getActorUpdateData: ActorUpdateDataGetter): Promise<void> {
|
||||||
|
for (const actor of getGame().actors ?? []) {
|
||||||
|
try {
|
||||||
|
const updateData = getActorUpdateData(actor.toObject());
|
||||||
|
if (updateData) {
|
||||||
|
logger.info(`Migrating Actor entity ${actor.name} (${actor.id})`);
|
||||||
|
await actor.update(updateData);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
err.message = `Error during migration of Actor entity ${actor.name} (${actor.id}), continuing anyways.`;
|
||||||
|
logger.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type SceneUpdateDataGetter = (
|
||||||
|
sceneData: foundry.documents.BaseScene["data"],
|
||||||
|
) => DeepPartial<foundry.documents.BaseScene["data"]["_source"]>;
|
||||||
|
|
||||||
|
export async function migrateScenes(getSceneUpdateData: SceneUpdateDataGetter): Promise<void> {
|
||||||
|
for (const scene of getGame().scenes ?? []) {
|
||||||
|
try {
|
||||||
|
const updateData = getSceneUpdateData(scene.data);
|
||||||
|
if (updateData) {
|
||||||
|
logger.info(`Migrating Scene document ${scene.name} (${scene.id})`);
|
||||||
|
await scene.update(updateData);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
err.message = `Error during migration of Scene document ${scene.name} (${scene.id}), continuing anyways.`;
|
||||||
|
logger.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type CompendiumMigrator = (compendium: CompendiumCollection<CompendiumCollection.Metadata>) => Promise<void>;
|
||||||
|
|
||||||
|
export async function migrateCompendiums(migrateCompendium: CompendiumMigrator): Promise<void> {
|
||||||
|
for (const compendium of getGame().packs ?? []) {
|
||||||
|
if (compendium.metadata.package !== "world") continue;
|
||||||
|
if (!["Actor", "Item", "Scene"].includes(compendium.metadata.entity)) continue;
|
||||||
|
await migrateCompendium(compendium);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getActorUpdateDataGetter(getItemUpdateData: ItemUpdateDataGetter): ActorUpdateDataGetter {
|
||||||
|
return (
|
||||||
|
actorData: Partial<foundry.data.ActorData["_source"]>,
|
||||||
|
): DeepPartial<foundry.data.ActorData["_source"]> | undefined => {
|
||||||
|
let hasItemUpdates = false;
|
||||||
|
const items = actorData.items?.map((itemData) => {
|
||||||
|
const update = getItemUpdateData(itemData);
|
||||||
|
if (update) {
|
||||||
|
hasItemUpdates = true;
|
||||||
|
return { ...itemData, ...update };
|
||||||
|
} else {
|
||||||
|
return itemData;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return hasItemUpdates ? { items } : undefined;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSceneUpdateDataGetter(getActorUpdateData: ActorUpdateDataGetter): SceneUpdateDataGetter {
|
||||||
|
return (sceneData: foundry.documents.BaseScene["data"]) => {
|
||||||
|
const tokens = (sceneData.tokens as Collection<TokenDocument>).map((token: TokenDocument) => {
|
||||||
|
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" as const, "effects" as const].forEach((embeddedName) => {
|
||||||
|
const embeddedUpdates = update[embeddedName];
|
||||||
|
if (embeddedUpdates === undefined || update[embeddedName]?.length !== 0) 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) mergeObject(original, update);
|
||||||
|
});
|
||||||
|
delete update[embeddedName];
|
||||||
|
});
|
||||||
|
mergeObject(t.actorData, update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
});
|
||||||
|
return { tokens };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCompendiumMigrator(
|
||||||
|
{
|
||||||
|
getItemUpdateData,
|
||||||
|
getActorUpdateData,
|
||||||
|
getSceneUpdateData,
|
||||||
|
}: {
|
||||||
|
getItemUpdateData?: ItemUpdateDataGetter;
|
||||||
|
getActorUpdateData?: ActorUpdateDataGetter;
|
||||||
|
getSceneUpdateData?: SceneUpdateDataGetter;
|
||||||
|
} = {},
|
||||||
|
{ migrateToTemplateEarly = true } = {},
|
||||||
|
) {
|
||||||
|
return async (compendium: CompendiumCollection<CompendiumCollection.Metadata>): Promise<void> => {
|
||||||
|
const entityName = compendium.metadata.entity;
|
||||||
|
if (!["Actor", "Item", "Scene"].includes(entityName)) return;
|
||||||
|
const wasLocked = compendium.locked;
|
||||||
|
await compendium.configure({ locked: false });
|
||||||
|
if (migrateToTemplateEarly) {
|
||||||
|
await compendium.migrate();
|
||||||
|
}
|
||||||
|
|
||||||
|
const documents = await compendium.getDocuments();
|
||||||
|
|
||||||
|
for (const doc of documents) {
|
||||||
|
try {
|
||||||
|
logger.info(`Migrating document ${doc.name} (${doc.id}) in compendium ${compendium.collection}`);
|
||||||
|
if (doc instanceof DS4Item && getItemUpdateData) {
|
||||||
|
const updateData = getItemUpdateData(doc.toObject());
|
||||||
|
updateData && (await doc.update(updateData));
|
||||||
|
} else if (doc instanceof DS4Actor && getActorUpdateData) {
|
||||||
|
const updateData = getActorUpdateData(doc.toObject());
|
||||||
|
updateData && (await doc.update(updateData));
|
||||||
|
} else if (doc instanceof Scene && getSceneUpdateData) {
|
||||||
|
const updateData = getSceneUpdateData(doc.data);
|
||||||
|
updateData && (await doc.update(updateData));
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
err.message = `Error during migration of document ${doc.name} (${doc.id}) in compendium ${compendium.collection}, continuing anyways.`;
|
||||||
|
logger.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!migrateToTemplateEarly) {
|
||||||
|
await compendium.migrate();
|
||||||
|
}
|
||||||
|
await compendium.configure({ locked: wasLocked });
|
||||||
|
};
|
||||||
|
}
|
|
@ -673,7 +673,7 @@ __metadata:
|
||||||
|
|
||||||
"@league-of-foundry-developers/foundry-vtt-types@https://github.com/League-of-Foundry-Developers/foundry-vtt-types.git#foundry-0.8.x":
|
"@league-of-foundry-developers/foundry-vtt-types@https://github.com/League-of-Foundry-Developers/foundry-vtt-types.git#foundry-0.8.x":
|
||||||
version: 0.7.9-6
|
version: 0.7.9-6
|
||||||
resolution: "@league-of-foundry-developers/foundry-vtt-types@https://github.com/League-of-Foundry-Developers/foundry-vtt-types.git#commit=22688f7be9f9c2605c3376e365e12b6084d59b85"
|
resolution: "@league-of-foundry-developers/foundry-vtt-types@https://github.com/League-of-Foundry-Developers/foundry-vtt-types.git#commit=b111674a20165ac827a0b5db48791d8502d82e43"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/jquery": ~3.5.5
|
"@types/jquery": ~3.5.5
|
||||||
"@types/simple-peer": ~9.11.0
|
"@types/simple-peer": ~9.11.0
|
||||||
|
@ -683,7 +683,7 @@ __metadata:
|
||||||
socket.io-client: 4.1.2
|
socket.io-client: 4.1.2
|
||||||
tinymce: 5.8.1
|
tinymce: 5.8.1
|
||||||
typescript: ^4.1.6
|
typescript: ^4.1.6
|
||||||
checksum: bba8fb7081e7cd1c43a5af841820232629a9034e7075d733558b261b5d488fd166dcf9501158cd49e29a7a2e9b7b4ebf6f4aef76b1d740a253455a7432308a77
|
checksum: 028b563649d22583d57e80fed7323dfad7dbd8e31cfa054cbb9747041729c9f7dea098f5a245dd54f493be42556cc50f7d5ab5799d01662a74a88d65c97f36ac
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue