diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bbc3ad0..af2400a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -image: node:latest +image: node:lts stages: - prepare diff --git a/package-lock.json b/package-lock.json index e397102..27f7412 100644 --- a/package-lock.json +++ b/package-lock.json @@ -571,23 +571,14 @@ "integrity": "sha512-MI8YmxFS+jMkIziycT5ickBWK1sZwDwy16mgH/j99Mcom6zRG/NimNGQ3vJV0uX5G6g/hEw0FG3w3b3sT5OUGw==", "dev": true }, - "@types/tinymce": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@types/tinymce/-/tinymce-4.6.0.tgz", - "integrity": "sha512-zpW6p/O1CXW9OrDnc+3tlFSGr1+TpTYgudc2vYXgk1KeWwwbK+t3p8cecb1fj0NJN987oMxSoQP13iabBd2fsA==", - "dev": true, - "requires": { - "@types/jquery": "*" - } - }, "@typescript-eslint/eslint-plugin": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.14.2.tgz", - "integrity": "sha512-uMGfG7GFYK/nYutK/iqYJv6K/Xuog/vrRRZX9aEP4Zv1jsYXuvFUMDFLhUnc8WFv3D2R5QhNQL3VYKmvLS5zsQ==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.15.0.tgz", + "integrity": "sha512-DJgdGZW+8CFUTz5C/dnn4ONcUm2h2T0itWD85Ob5/V27Ndie8hUoX5HKyGssvR8sUMkAIlUc/AMK67Lqa3kBIQ==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "4.14.2", - "@typescript-eslint/scope-manager": "4.14.2", + "@typescript-eslint/experimental-utils": "4.15.0", + "@typescript-eslint/scope-manager": "4.15.0", "debug": "^4.1.1", "functional-red-black-tree": "^1.0.1", "lodash": "^4.17.15", @@ -597,70 +588,69 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.14.2.tgz", - "integrity": "sha512-mV9pmET4C2y2WlyHmD+Iun8SAEqkLahHGBkGqDVslHkmoj3VnxnGP4ANlwuxxfq1BsKdl/MPieDbohCEQgKrwA==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.15.0.tgz", + "integrity": "sha512-V4vaDWvxA2zgesg4KPgEGiomWEBpJXvY4ZX34Y3qxK8LUm5I87L+qGIOTd9tHZOARXNRt9pLbblSKiYBlGMawg==", "dev": true, "requires": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.14.2", - "@typescript-eslint/types": "4.14.2", - "@typescript-eslint/typescript-estree": "4.14.2", + "@typescript-eslint/scope-manager": "4.15.0", + "@typescript-eslint/types": "4.15.0", + "@typescript-eslint/typescript-estree": "4.15.0", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" } }, "@typescript-eslint/parser": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.14.2.tgz", - "integrity": "sha512-ipqSP6EuUsMu3E10EZIApOJgWSpcNXeKZaFeNKQyzqxnQl8eQCbV+TSNsl+s2GViX2d18m1rq3CWgnpOxDPgHg==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.15.0.tgz", + "integrity": "sha512-L6Dtbq8Bc7g2aZwnIBETpmUa9XDKCMzKVwAArnGp5Mn7PRNFjf3mUzq8UeBjL3K8t311hvevnyqXAMSmxO8Gpg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.14.2", - "@typescript-eslint/types": "4.14.2", - "@typescript-eslint/typescript-estree": "4.14.2", + "@typescript-eslint/scope-manager": "4.15.0", + "@typescript-eslint/types": "4.15.0", + "@typescript-eslint/typescript-estree": "4.15.0", "debug": "^4.1.1" } }, "@typescript-eslint/scope-manager": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.14.2.tgz", - "integrity": "sha512-cuV9wMrzKm6yIuV48aTPfIeqErt5xceTheAgk70N1V4/2Ecj+fhl34iro/vIssJlb7XtzcaD07hWk7Jk0nKghg==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.15.0.tgz", + "integrity": "sha512-CSNBZnCC2jEA/a+pR9Ljh8Y+5TY5qgbPz7ICEk9WCpSEgT6Pi7H2RIjxfrrbUXvotd6ta+i27sssKEH8Azm75g==", "dev": true, "requires": { - "@typescript-eslint/types": "4.14.2", - "@typescript-eslint/visitor-keys": "4.14.2" + "@typescript-eslint/types": "4.15.0", + "@typescript-eslint/visitor-keys": "4.15.0" } }, "@typescript-eslint/types": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.14.2.tgz", - "integrity": "sha512-LltxawRW6wXy4Gck6ZKlBD05tCHQUj4KLn4iR69IyRiDHX3d3NCAhO+ix5OR2Q+q9bjCrHE/HKt+riZkd1At8Q==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.15.0.tgz", + "integrity": "sha512-su4RHkJhS+iFwyqyXHcS8EGPlUVoC+XREfy5daivjLur9JP8GhvTmDipuRpcujtGC4M+GYhUOJCPDE3rC5NJrg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.14.2.tgz", - "integrity": "sha512-ESiFl8afXxt1dNj8ENEZT12p+jl9PqRur+Y19m0Z/SPikGL6rqq4e7Me60SU9a2M28uz48/8yct97VQYaGl0Vg==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.15.0.tgz", + "integrity": "sha512-jG6xTmcNbi6xzZq0SdWh7wQ9cMb2pqXaUp6bUZOMsIlu5aOlxGxgE/t6L/gPybybQGvdguajXGkZKSndZJpksA==", "dev": true, "requires": { - "@typescript-eslint/types": "4.14.2", - "@typescript-eslint/visitor-keys": "4.14.2", + "@typescript-eslint/types": "4.15.0", + "@typescript-eslint/visitor-keys": "4.15.0", "debug": "^4.1.1", "globby": "^11.0.1", "is-glob": "^4.0.1", - "lodash": "^4.17.15", "semver": "^7.3.2", "tsutils": "^3.17.1" } }, "@typescript-eslint/visitor-keys": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.14.2.tgz", - "integrity": "sha512-KBB+xLBxnBdTENs/rUgeUKO0UkPBRs2vD09oMRRIkj5BEN8PX1ToXV532desXfpQnZsYTyLLviS7JrPhdL154w==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.15.0.tgz", + "integrity": "sha512-RnDtJwOwFucWFAMjG3ghCG/ikImFJFEg20DI7mn4pHEx3vC48lIAoyjhffvfHmErRDboUPC7p9Z2il4CLb7qxA==", "dev": true, "requires": { - "@typescript-eslint/types": "4.14.2", + "@typescript-eslint/types": "4.15.0", "eslint-visitor-keys": "^2.0.0" } }, @@ -1462,9 +1452,9 @@ } }, "bl": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.4.tgz", - "integrity": "sha512-7tdr4EpSd7jJ6tuQ21vu2ke8w7pNEstzj1O8wwq6sNNzO3UDi5MA8Gny/gquCj7r2C6fHudg8tKRGyjRgmvNxQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, "requires": { "buffer": "^5.5.0", @@ -3175,19 +3165,17 @@ } }, "foundry-vtt-types": { - "version": "github:League-of-Foundry-Developers/foundry-vtt-types#f1c321dcfe460595123765ababe5b8772d5df966", + "version": "github:League-of-Foundry-Developers/foundry-vtt-types#095cba6c567b86b11e61fdf6c96892949e5d5ad1", "from": "github:League-of-Foundry-Developers/foundry-vtt-types#foundry-0.7.9", "dev": true, "requires": { "@types/howler": "2.2.1", "@types/jquery": "3.5.1", - "@types/node": "^14.14.21", "@types/socket.io-client": "^1.4.33", - "@types/tinymce": "^4.5.24", "handlebars": "4.7.6", "pixi.js": "5.3.4", - "typescript": "^4.1.3", - "utility-types": "^3.10.0" + "tinymce": "5.6.2", + "typescript": "^4.1.4" } }, "fragment-cache": { @@ -3577,9 +3565,9 @@ } }, "graceful-fs": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.5.tgz", - "integrity": "sha512-kBBSQbz2K0Nyn+31j/w36fUfxkBW9/gfwRWdUY1ULReH3iokVJgddZAFcD1D0xlgTmFxJCbUkUclAlc6/IDJkw==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, "gulp": { @@ -6107,6 +6095,12 @@ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", "dev": true }, + "queue-microtask": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.2.tgz", + "integrity": "sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg==", + "dev": true + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -6536,10 +6530,13 @@ } }, "run-parallel": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", - "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } }, "rxjs": { "version": "6.6.3", @@ -6572,9 +6569,9 @@ "dev": true }, "sass": { - "version": "1.32.6", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.6.tgz", - "integrity": "sha512-1bcDHDcSqeFtMr0JXI3xc/CXX6c4p0wHHivJdru8W7waM7a1WjKMm4m/Z5sY7CbVw4Whi2Chpcw6DFfSWwGLzQ==", + "version": "1.32.7", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.7.tgz", + "integrity": "sha512-C8Z4bjqGWnsYa11o8hpKAuoyFdRhrSHcYjCr+XAWVPSIQqC8mp2f5Dx4em0dKYehPzg5XSekmCjqJnEZbIls9A==", "dev": true, "requires": { "chokidar": ">=2.0.0 <4.0.0" @@ -7288,9 +7285,9 @@ }, "dependencies": { "ajv": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.4.tgz", - "integrity": "sha512-xzzzaqgEQfmuhbhAoqjJ8T/1okb6gAzXn/eQRNpAN1AEUoHJTNF9xCDRTtf/s3SKldtZfa+RJeTs+BQq+eZ/sw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.1.0.tgz", + "integrity": "sha512-svS9uILze/cXbH0z2myCK2Brqprx/+JJYK5pHicT/GQiBfzzhUVAIT6MwqJg8y4xV/zoGsUeuPuwtoiKSGE15g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -7386,6 +7383,12 @@ "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", "dev": true }, + "tinymce": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-5.6.2.tgz", + "integrity": "sha512-z7zvM5seOPiW86/vqf08kStwW5Zs5U9oQfuqh2rTj4jEcT2QzxT0v72i2zw3W6rbTLldkAej6edFZphj5ee5zg==", + "dev": true + }, "to-absolute-glob": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", @@ -7543,9 +7546,9 @@ "dev": true }, "typescript": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", - "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.5.tgz", + "integrity": "sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA==", "dev": true }, "uglify-js": { @@ -7719,12 +7722,6 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "utility-types": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", - "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==", - "dev": true - }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", diff --git a/src/lang/de.json b/src/lang/de.json index 391571e..71d5f2a 100644 --- a/src/lang/de.json +++ b/src/lang/de.json @@ -200,6 +200,9 @@ "DS4.RollDialogCancelButton": "Abbrechen", "DS4.ErrorUnexpectedHtmlType": "Typfehler: Erwartet wurde '{exType}', tatsächlich erhalten wurde '{realType}'.", "DS4.ErrorCouldNotFindForm": "Konnte HTML Element '{htmlElement}' nicht finden.", + "DS4.ErrorActorDoesNotHaveItem": "Der Aktor '{actor}' hat kein Item mit der ID '{id}'.", + "DS4.ErrorUnexpectedError": "Es gab einen unerwarteten Fehler im Dungeonslayers 4 System. Für mehr Details schauen Sie bitte in die Konsole (F12).", + "DS4.ErrorItemDoesNotHaveEffect": "Das Item '{item}' hat keinen Effekt mit der ID '{id}'.", "DS4.RollDialogTargetLabel": "Probenwert", "DS4.RollDialogModifierLabel": "SL-Modifikator", "DS4.RollDialogCoupLabel": "Immersieg bis", diff --git a/src/lang/en.json b/src/lang/en.json index e1d15a5..4506977 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -199,7 +199,10 @@ "DS4.RollDialogOkButton": "Ok", "DS4.RollDialogCancelButton": "Cancel", "DS4.ErrorUnexpectedHtmlType": "Type Error: Expected '{exType}' but got '{realType}'.", - "DS4.ErrorCouldNotFindForm": "Could not find html element '{htmlElement}'.", + "DS4.ErrorCouldNotFindForm": "Could not find HTML element '{htmlElement}'.", + "DS4.ErrorActorDoesNotHaveItem": "The actor '{actor}' does not have any item with the id '{id}'.", + "DS4.ErrorUnexpectedError": "There was an unexpected error in the Dungeonslayers 4 system. For more details, please take a look at the console (F12).", + "DS4.ErrorItemDoesNotHaveEffect": "The item '{item}' does not have any effect with the id '{id}'.", "DS4.RollDialogTargetLabel": "Check Target Number", "DS4.RollDialogModifierLabel": "Game Master Modifier", "DS4.RollDialogCoupLabel": "Coup to", diff --git a/src/module/actor/sheets/actor-sheet.ts b/src/module/actor/sheets/actor-sheet.ts index 66c381b..4ab9e44 100644 --- a/src/module/actor/sheets/actor-sheet.ts +++ b/src/module/actor/sheets/actor-sheet.ts @@ -72,8 +72,15 @@ export class DS4ActorSheet extends ActorSheet> { // Update Inventory Item html.find(".item-edit").on("click", (ev) => { const li = $(ev.currentTarget).parents(".item"); - const item = this.actor.getOwnedItem(li.data("itemId")); - item.sheet?.render(true); + const id = li.data("itemId"); + const item = this.actor.getOwnedItem(id); + if (!item) { + throw new Error(game.i18n.format("DS4.ErrorActorDoesNotHaveItem", { id, actor: this.actor.name })); + } + if (!item.sheet) { + throw new Error(game.i18n.localize("DS4.ErrorUnexpectedError")); + } + item.sheet.render(true); }); // Delete Inventory Item diff --git a/src/module/item/item-sheet.ts b/src/module/item/item-sheet.ts index 9a00a0a..41a5862 100644 --- a/src/module/item/item-sheet.ts +++ b/src/module/item/item-sheet.ts @@ -91,8 +91,12 @@ export class DS4ItemSheet extends ItemSheet> { case "create": return this._createActiveEffect(); case "edit": - const effect = this.item.effects.get(li.data("effectId")); - return effect?.sheet.render(true); + const id = li.data("effectId"); + const effect = this.item.effects.get(id); + if (!effect) { + throw new Error(game.i18n.format("DS4.ErrorItemDoesNotHaveEffect", { id, item: this.item.name })); + } + return effect.sheet.render(true); case "delete": { return this.item.deleteEmbeddedEntity("ActiveEffect", li.data("effectId")); } diff --git a/src/module/ui/notifications.ts b/src/module/ui/notifications.ts new file mode 100644 index 0000000..cb6a301 --- /dev/null +++ b/src/module/ui/notifications.ts @@ -0,0 +1,37 @@ +const notifications = { + info: (message: string, { permanent = false }: { permanent?: boolean } = {}): void => { + if (ui.notifications) { + ui.notifications.info(message, { permanent }); + } else { + console.info(message); + } + }, + warn: (message: string, { permanent = false }: { permanent?: boolean } = {}): void => { + if (ui.notifications) { + ui.notifications.warn(message, { permanent }); + } else { + console.log(message); + } + }, + error: (message: string, { permanent = false }: { permanent?: boolean } = {}): void => { + if (ui.notifications) { + ui.notifications.error(message, { permanent }); + } else { + console.warn(message); + } + }, + notify: ( + message: string, + type: "info" | "warning" | "error" = "info", + { permanent = false }: { permanent?: boolean } = {}, + ): void => { + if (ui.notifications) { + ui.notifications.notify(message, type, { permanent }); + } else { + const log = { info: console.info, warning: console.warn, error: console.error }[type]; + log(message); + } + }, +}; + +export default notifications;