diff --git a/module/BladesRoll.js b/module/BladesRoll.js index 7b57faec..473de617 100644 --- a/module/BladesRoll.js +++ b/module/BladesRoll.js @@ -1526,7 +1526,7 @@ class BladesRoll extends DocumentSheet { async removeRollParticipant(rollSection, rollSubSection) { await this.clearFlagVal(`rollParticipantData.${rollSection}.${rollSubSection}`); } - async updateUserPermission(user, permission) { + async updateUserPermission(_user, _permission) { } get flagData() { @@ -1741,7 +1741,7 @@ class BladesRoll extends DocumentSheet { } return null; } - async applyConsequencesFromDialog(html) { + async applyConsequencesFromDialog(_html) { } get finalPosition() { diff --git a/module/core/utilities.js b/module/core/utilities.js index 2493cafa..47d4a5ef 100644 --- a/module/core/utilities.js +++ b/module/core/utilities.js @@ -167,7 +167,7 @@ function assertNonNullType(val, type) { if (val === undefined) { throw new Error(`Value ${valStr} is undefined!`); } - if (typeof type === "string") { + if (typeof type === "string") { if (typeof val !== type) { throw new Error(`Value ${valStr} is not a ${type}!`); } @@ -823,7 +823,8 @@ const partition = (obj, predicate = () => true) => [ objFilter(obj, predicate), objFilter(obj, (v, k) => !predicate(v, k)) ]; -function objMap(obj, keyFunc, valFunc) { +function objMap(obj, keyFunc, valFunc) { + // let valFuncTyped = valFunc; let keyFuncTyped = keyFunc; if (!valFuncTyped) { @@ -860,8 +861,9 @@ function objFindKey(obj, keyFunc, valFunc) { return validEntry[0]; } return false; -} -const objFilter = (obj, keyFunc, valFunc) => { +} +const objFilter = (obj, keyFunc, valFunc) => { + // if (!valFunc) { valFunc = keyFunc; keyFunc = false; @@ -874,7 +876,8 @@ const objFilter = (obj, keyFunc, valFunc) => { } const kFunc = keyFunc || (() => true); const vFunc = valFunc || (() => true); - return Object.fromEntries(Object.entries(obj).filter(([key, val]) => kFunc(key, val) && vFunc(val, key))); + return Object.fromEntries(Object.entries(obj) + .filter(([key, val]) => kFunc(key, val) && vFunc(val, key))); }; const objForEach = (obj, func) => { if (isArray(obj)) { @@ -885,13 +888,9 @@ const objForEach = (obj, func) => { } }; const objCompact = (obj, removeWhiteList = [undefined, null]) => objFilter(obj, (val) => !removeWhiteList.includes(val)); -function cloneArray(arr) { - return [...arr]; -} -function cloneObject(obj) { - return { ...obj }; -} const objClone = (obj, isStrictlySafe = false) => { + const cloneArray = (arr) => [...arr]; + const cloneObject = (o) => ({ ...o }); try { return JSON.parse(JSON.stringify(obj)); } @@ -921,10 +920,12 @@ function objMerge(target, source, { isMutatingOk = false, isStrictlySafe = false } for (const [key, val] of Object.entries(source)) { const targetVal = target[key]; + if (isReplacingArrays && isArray(targetVal) && isArray(val)) { target[key] = val; } else if (isConcatenatingArrays && isArray(targetVal) && isArray(val)) { + target[key].push(...val); } else if (val !== null && typeof val === "object") { diff --git a/ts/BladesRoll.ts b/ts/BladesRoll.ts index 1b559070..cf8e8055 100644 --- a/ts/BladesRoll.ts +++ b/ts/BladesRoll.ts @@ -73,8 +73,8 @@ function isValidConsequenceData(val: unknown, isRecurring = false): val is Blade } /** - * - * @param section + * Checks if the given section can contain BladesRollParticipant documents. + * @param {RollModSection} section */ function isParticipantSection(section: RollModSection): section is BladesRoll.RollParticipantSection & RollModSection { return [ @@ -85,8 +85,8 @@ function isParticipantSection(section: RollModSection): section is BladesRoll.Ro } /** - * - * @param subSection + * Checks if the given subSection can hold BladesRollParticipant documents. + * @param {string} subSection */ function isParticipantSubSection(subSection: string): subSection is BladesRoll.RollParticipantSubSection { if (subSection.startsWith("Group_")) { return true; } @@ -1475,8 +1475,8 @@ class BladesRoll extends DocumentSheet { return userIDs; /** - * - * @param participantData + * Generates BladesRollParticipant documents from the provided schema data. + * @param {BladesRoll.RollParticipantData} participantData */ function getParticipantDocs(participantData: BladesRoll.RollParticipantData) { return Object.values(flattenObject(participantData)) @@ -1499,9 +1499,9 @@ class BladesRoll extends DocumentSheet { } /** - * - * @param participantData - * @param unassignedIDs + * Returns the user ids of potential BladesRollParticipants defined in the provided data schema. + * @param {BladesRoll.RollParticipantData} participantData + * @param {string[]} unassignedIDs */ function getParticipantDocUserIDs( participantData: BladesRoll.RollParticipantData, @@ -1895,8 +1895,8 @@ class BladesRoll extends DocumentSheet { } async updateUserPermission( - user: User, - permission: RollPermissions + _user: User, + _permission: RollPermissions ) { /* Force-render roll with new permissions */ } @@ -2158,7 +2158,7 @@ class BladesRoll extends DocumentSheet { return null; } - async applyConsequencesFromDialog(html: JQuery|HTMLElement) { + async applyConsequencesFromDialog(_html: JQuery|HTMLElement) { /* Convert values of dialog input fields to flag data */ } diff --git a/ts/core/utilities.ts b/ts/core/utilities.ts index b6da0019..f5ec97a5 100644 --- a/ts/core/utilities.ts +++ b/ts/core/utilities.ts @@ -201,6 +201,7 @@ function assertNonNullType( // If the type is a string, compare the typeof the value to the type string. if (typeof type === "string") { + // eslint-disable-next-line valid-typeof if (typeof val !== type) { throw new Error(`Value ${valStr} is not a ${type}!`); } @@ -890,10 +891,10 @@ const replace = (obj: Index, checkTest: checkTest, repVal: unknown) => repKey = `${repKey}`; } if (typeof repVal === "function") { - // @ts-expect-error Hopefully just temporary to get this to compile: Need to figure out how to properly define testFunc (keyFunc/valFunc types?) + // @ts-expect-error Need to figure out how to properly define testFunc (keyFunc/valFunc types?) obj[repKey] = repVal(obj[repKey], repKey); } else { - // @ts-expect-error Hopefully just temporary to get this to compile: Need to figure out how to properly define testFunc (keyFunc/valFunc types?) + // @ts-expect-error Need to figure out how to properly define testFunc (keyFunc/valFunc types?) obj[repKey] = repVal; } return true; @@ -904,7 +905,8 @@ const replace = (obj: Index, checkTest: checkTest, repVal: unknown) => * @template T - The type of the input object or value. * @param {T} data The object or value to be cleaned. * @param {Array} [remVals] An array of values to be removed during the cleaning process. - * @returns {T | Partial | "KILL"} - The cleaned version of the input object or value. If marked for removal, returns "KILL". + * @returns {T | Partial | "KILL"} - The cleaned version of the input object or value. + * If marked for removal, returns "KILL". */ const objClean = (data: T, remVals: UncleanValues[] = [undefined, null, "", {}, []]): T | Partial | "KILL" => { const remStrings = remVals.map((rVal) => JSON.stringify(rVal)); @@ -929,7 +931,11 @@ const objClean = (data: T, remVals: UncleanValues[] = [undefined, null, "", { * @param items * @param key */ -export function toDict, V extends ValOf>(items: T[], key: K): V extends key ? Record : never { +export function toDict< + T extends List, + K extends string & KeyOf, + V extends ValOf +>(items: T[], key: K): V extends key ? Record : never { const dict = {} as Record; const mappedItems = items .map((data) => { @@ -950,8 +956,9 @@ export function toDict, V extends Va return dict; /** - * - * @param str + * Given a string that could have an index suffix, returns the string with + * the suffix incremented by one, or set to one if no suffix exists. + * @param {string} str */ function indexString(str: string) { if (/_\d+$/.test(str)) { @@ -971,14 +978,18 @@ const partition = (obj: Type[], predicate: testFunc = () => true) objFilter(obj, (v: unknown, k: string | number | undefined) => !predicate(v, k)) ]; /** - * - * @param obj - * @param keyFunc - * @param valFunc + * An object-equivalent Array.map() function, which accepts mapping functions to transform both keys and values. + * If only one function is provided, it's assumed to be mapping the values and will receive (v, k) args. + * @param {Index} obj + * @param {mapFunc|false} keyFunc + * @param {mapFunc} [valFunc] */ -function objMap(obj: Index, keyFunc: mapFunc | mapFunc | false, valFunc?: mapFunc): Index { - // An object-equivalent Array.map() function, which accepts mapping functions to transform both keys and values. - // If only one function is provided, it's assumed to be mapping the values and will receive (v, k) args. +function objMap( + obj: Index, + keyFunc: mapFunc | mapFunc | false, + valFunc?: mapFunc +): Index { + // let valFuncTyped: mapFunc | undefined = valFunc; let keyFuncTyped: mapFunc | false = keyFunc; @@ -1039,9 +1050,22 @@ function objFindKey>( // If no entries pass the test, return false return false; } -const objFilter = >(obj: Type, keyFunc: testFunc | testFunc | false, valFunc?: testFunc): Type => { - // An object-equivalent Array.filter() function, which accepts filter functions for both keys and/or values. - // If only one function is provided, it's assumed to be mapping the values and will receive (v, k) args. + +/** + * An object-equivalent Array.filter() function, which accepts filter functions for both keys and/or values. + * If only one function is provided, it's assumed to be mapping the values and will receive (v, k) args. + * + * @param {Type} obj The object to be searched. + * @param {testFunc | testFunc | false} keyFunc The testing function for keys. + * @param {testFunc} [valFunc] The testing function for values. + * @returns {Type} The filtered object. + */ +const objFilter = >( + obj: Type, + keyFunc: testFunc | testFunc | false, + valFunc?: testFunc +): Type => { + // if (!valFunc) { valFunc = keyFunc as testFunc; keyFunc = false; @@ -1052,7 +1076,10 @@ const objFilter = >(obj: Type, keyFunc: testFunc true); const vFunc = valFunc || (() => true); - return Object.fromEntries(Object.entries(obj).filter(([key, val]: [string, unknown]) => kFunc(key, val) && vFunc(val, key))) as Type; + return Object.fromEntries( + Object.entries(obj) + .filter(([key, val]: [string, unknown]) => kFunc(key, val) && vFunc(val, key)) + ) as Type; }; const objForEach = (obj: Index, func: valFunc): void => { // An object-equivalent Array.forEach() function, which accepts one function(val, key) to perform for each member. @@ -1063,25 +1090,14 @@ const objForEach = (obj: Index, func: valFunc): void => { } }; // Prunes an object of given set of values, [undefined, null] default -const objCompact = )>(obj: Type, removeWhiteList: unknown[] = [undefined, null]): Type => objFilter(obj, (val: unknown) => !removeWhiteList.includes(val)); - -/** - * - * @param arr - */ -function cloneArray(arr: T): T { - return [...arr] as T; -} - -/** - * - * @param obj - */ -function cloneObject(obj: T): T { - return {...obj}; -} +const objCompact = )>( + obj: Type, + removeWhiteList: unknown[] = [undefined, null] +): Type => objFilter(obj, (val: unknown) => !removeWhiteList.includes(val)); const objClone = (obj: T, isStrictlySafe = false): T => { + const cloneArray = (arr: aT): aT => [...arr] as aT; + const cloneObject = (o: oT): oT => ({...o}); try { return JSON.parse(JSON.stringify(obj)); } catch(err) { @@ -1096,13 +1112,22 @@ const objClone = (obj: T, isStrictlySafe = false): T => { * @param {Tx} target The target object to be merged. * @param {Ty} source The source object to be merged. * @param {object} options An object containing various options for the merge operation. - * @param options.isMutatingOk - * @param options.isStrictlySafe - * @param options.isConcatenatingArrays - * @param options.isReplacingArrays + * @param {boolean} options.isMutatingOk + * @param {boolean} options.isStrictlySafe + * @param {boolean} options.isConcatenatingArrays + * @param {boolean} options.isReplacingArrays * @returns {Tx & Ty} - The merged object. */ -function objMerge(target: Tx, source: Ty, {isMutatingOk = false, isStrictlySafe = false, isConcatenatingArrays = true, isReplacingArrays = false} = {}): Tx & Ty { +function objMerge( + target: Tx, + source: Ty, + { + isMutatingOk = false, + isStrictlySafe = false, + isConcatenatingArrays = true, + isReplacingArrays = false + } = {} +): Tx & Ty { // Clone the target if mutation is not allowed target = isMutatingOk ? target : objClone(target, isStrictlySafe); @@ -1125,19 +1150,25 @@ function objMerge(target: Tx, source: Ty, {isMutatingOk = false, isStric for (const [key, val] of Object.entries(source)) { const targetVal = target[key as KeyOf]; - // If replacing arrays is enabled and both target and source values are arrays, replace target value with source value + // If replacing arrays is enabled and both target and source values are + // arrays, replace target value with source value if (isReplacingArrays && isArray(targetVal) && isArray(val)) { target[key as KeyOf] = val as Tx[KeyOf]; } else if (isConcatenatingArrays && isArray(targetVal) && isArray(val)) { - // If concatenating arrays is enabled and both target and source values are arrays, concatenate source value to target value + // If concatenating arrays is enabled and both target and source values + // are arrays, concatenate source value to target value (target[key as KeyOf] as unknown[]).push(...val); } else if (val !== null && typeof val === "object") { // If source value is an object and not null, merge it into target value if (isUndefined(targetVal) && !(val instanceof Application)) { target[key as KeyOf] = new (Object.getPrototypeOf(val).constructor)(); } - target[key as KeyOf] = objMerge(target[key as KeyOf], val, {isMutatingOk: true, isStrictlySafe}); + target[key as KeyOf] = objMerge( + target[key as KeyOf], + val, + {isMutatingOk: true, isStrictlySafe} + ); } else { // For all other cases, assign source value to target target[key as KeyOf] = val as Tx[KeyOf]; @@ -1148,13 +1179,18 @@ function objMerge(target: Tx, source: Ty, {isMutatingOk = false, isStric return target as Tx & Ty; } /** - * Deep-compares two objects and returns an object containing only the keys and values in the second object that differ from the first. - * If the second object is missing a key or value contained in the first, it sets the value in the returned object to null, and prefixes the key with "-=". + * Deep-compares two objects and returns an object containing only the keys and values + * in the second object that differ from the first. + * If the second object is missing a key or value contained in the first, it sets the + * value in the returned object to null, and prefixes the key with "-=". * @param {Tx} obj1 The first object to be compared. * @param {Ty} obj2 The second object to be compared. * @returns {Record} - An object containing the differences between the two input objects. */ -function objDiff, Ty extends Record>(obj1: Tx, obj2: Ty): Record { +function objDiff< + Tx extends Record, + Ty extends Record +>(obj1: Tx, obj2: Ty): Record { const diff: Record = {}; const bothObj1AndObj2Keys = Object.keys(obj2).filter((key) => Object.hasOwn(obj2, key) && Object.hasOwn(obj1, key)); const onlyObj2Keys = Object.keys(obj2).filter((key) => Object.hasOwn(obj2, key) && !Object.hasOwn(obj1, key)); @@ -1364,7 +1400,12 @@ const drawCirclePath = (radius: number, origin: Point) => { // #endregion ░░░░[SVG]░░░░ // #region ░░░░░░░[Colors]░░░░ Color Manipulation ░░░░░░░ ~ -const getColorVals = (red?: string | number | number[], green?: number, blue?: number, alpha?: number): number[] | null => { +const getColorVals = ( + red?: string | number | number[], + green?: number, + blue?: number, + alpha?: number +): number[] | null => { if (isRGBColor(red)) { [red, green, blue, alpha] = red .replace(/[^\d.,]/g, "") @@ -1426,7 +1467,11 @@ const getContrastingColor = (...colorVals: [string] | number[]): RGBColor | null } return null; }; -const getRandomColor = () => getRGBString(gsap.utils.random(0, 255, 1), gsap.utils.random(0, 255, 1), gsap.utils.random(0, 255, 1)) as RGBColor; +const getRandomColor = () => getRGBString( + gsap.utils.random(0, 255, 1), + gsap.utils.random(0, 255, 1), + gsap.utils.random(0, 255, 1) +) as RGBColor; // #endregion ░░░░[Colors]░░░░ // #region ░░░░░░░[DOM]░░░░ DOM Manipulation ░░░░░░░ ~