diff --git a/client/components/combobox.jsx b/client/components/combobox.jsx index 651a31516..16122eafd 100644 --- a/client/components/combobox.jsx +++ b/client/components/combobox.jsx @@ -16,6 +16,7 @@ const Combobox = createReactClass({ suggestMethod : 'includes', filterOn : [] // should allow as array to filter on multiple attributes, or even custom filter }, + valuePatterns: /.+/ }; }, getInitialState : function() { @@ -74,6 +75,7 @@ const Combobox = createReactClass({ type='text' onChange={(e)=>this.handleInput(e)} value={this.state.value || ''} + pattern={this.props.valuePatterns} placeholder={this.props.placeholder} onBlur={(e)=>{ if(!e.target.checkValidity()){ @@ -82,6 +84,12 @@ const Combobox = createReactClass({ }); } }} + onKeyDown={(e)=>{ + if (e.key === "Enter") { + e.preventDefault(); + this.props.onEntry(e); + } + }} /> diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 0b538f2b5..721340079 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -10,8 +10,6 @@ import TagInput from '../tagInput/tagInput.jsx'; import Themes from 'themes/themes.json'; import validations from './validations.js'; -const SYSTEMS = ['5e', '4e', '3.5e', 'Pathfinder']; - import homebreweryThumbnail from '../../thumbnail.png'; const callIfExists = (val, fn, ...args)=>{ @@ -33,7 +31,6 @@ const MetadataEditor = createReactClass({ tags : [], published : false, authors : [], - systems : [], renderer : 'legacy', theme : '5ePHB', lang : 'en' @@ -91,15 +88,6 @@ const MetadataEditor = createReactClass({ } }, - handleSystem : function(system, e){ - if(e.target.checked){ - this.props.metadata.systems.push(system); - } else { - this.props.metadata.systems = _.without(this.props.metadata.systems, system); - } - this.props.onChange(this.props.metadata); - }, - handleRenderer : function(renderer, e){ if(e.target.checked){ this.props.metadata.renderer = renderer; @@ -155,18 +143,6 @@ const MetadataEditor = createReactClass({ }); }, - renderSystems : function(){ - return _.map(SYSTEMS, (val)=>{ - return ; - }); - }, - renderPublish : function(){ if(this.props.metadata.published){ return - - ); + const stopEditing = (index)=>{ + setTagList((prev)=>prev.map((t, i)=>(i === index ? { ...t, editing: false, draft: '' } : t))); }; - const renderWriteTag = (context, index)=>{ + const suggestionOptions = tagSuggestionList.map((tag)=>{ + const tagType = tag.split(':'); + + let classes = 'item'; + switch (tagType[0]) { + case 'type': + classes = 'item type'; + break; + case 'group': + classes = 'item group'; + break; + case 'meta': + classes = 'item meta'; + break; + case 'system': + classes = 'item system'; + break; + default: + classes = 'item'; + break; + } + return ( - handleInputKeyDown({ evt, value: context.value, index: index })} - autoFocus - /> +
+ {tag} +
); - }; + }); return ( -
- +
+ {label && } +
    - {tagList.map((context, index)=>{ return context.editing ? renderWriteTag(context, index) : renderReadTag(context, index); })} + {tagList.map((t, i)=>t.editing ? ( + setTagList((prev)=>prev.map((tag, idx)=>(idx === i ? { ...tag, draft: e.target.value } : tag)), + ) + } + onKeyDown={(e)=>{ + if(e.key === 'Enter') { + e.preventDefault(); + submitTag(t.draft, i); // submit draft + setTagList((prev)=>prev.map((tag, idx)=>(idx === i ? { ...tag, draft: '' } : tag)), + ); + } + if(e.key === 'Escape') { + stopEditing(i); + e.target.blur(); + } + }} + autoFocus + /> + ) : ( +
  • editTag(i)}> + {t.value} + +
  • + ), + )}
- setTempInputText(e.target.value)} - onKeyDown={(evt)=>handleInputKeyDown({ evt, value: null, options: { clear: true } })} + submitTag(value)} + onEntry={(e)=>{ + if(e.key === 'Enter') { + console.log('submit'); + e.preventDefault(); + submitTag(e.target.value); + } + }} /> + {smallText.length !== 0 && {smallText}}
); diff --git a/client/homebrew/editor/tagInput/tagInput.less b/client/homebrew/editor/tagInput/tagInput.less index e69de29bb..3165b3935 100644 --- a/client/homebrew/editor/tagInput/tagInput.less +++ b/client/homebrew/editor/tagInput/tagInput.less @@ -0,0 +1,22 @@ +.list input { + border-radius: 5px; +} + +.tagInput-dropdown { + .dropdown-options { + .item { + &.type { + background-color: #00800035; + } + &.group { + background-color: #50505035; + } + &.meta { + background-color: #00008035; + } + &.system { + background-color: #80000035; + } + } + } +} diff --git a/client/homebrew/editor/tagInput/tagSuggestionList.js b/client/homebrew/editor/tagInput/tagSuggestionList.js new file mode 100644 index 000000000..6b8e4060e --- /dev/null +++ b/client/homebrew/editor/tagInput/tagSuggestionList.js @@ -0,0 +1,1980 @@ +export default [ + "meta:Theme", + "5e", + "Subclass", + "meta:theme", + "subclass", + "Class", + "Homebrew", + "Race", + "Dungeons and Dragons", + "theme", + "Daggerheart", + "2024", + "One Piece", + "One Piece DND", + "Luffy", + "Dungeons and Devil Fruits", + "Strawhats", + "Template", + "Campaign Frame", + "class", + "Players Handbook", + "dnd", + "osr", + "Dungeon Masters Guide", + "shadowdark", + "dragonbane", + "PHB", + "example", + "Devil Fruits", + "system:pf2e", + "DnD", + "DMG", + "system:dnd5.5", + "Monster", + "homebrew", + "race", + "template", + "Warlock", + "monster", + "Fighter", + "warlock", + "druid", + "sorcerer", + "D&D", + "Magic Item", + "Barbarian", + "Artificer", + "2014", + "system:descent into avernus", + "Sorcerer", + "Adventure", + "Paladin", + "Ranger", + "user help", + "fighter", + "5th Edition", + "Spells", + "Monk", + "Spell", + "NPC", + "Cleric", + "spell", + "Rogue", + "css", + "Item", + "artificer", + "magic item", + "Rules", + "barbarian", + "wizard", + "russian", + "DnD5e", + "Wizard", + "paladin", + "bastionland", + "spells", + "Devil Fruit", + "Bard", + "5.5e", + "rogue", + "Tabletop System", + "Haki", + "Druid", + "mystic bastionland", + "item", + "Lore", + "bard", + "monk", + "system:dnd5e", + "world", + "ranger", + "WIP", + "cleric", + "Dragon", + "Naruto", + "Creature", + "snippet", + "npc", + "DeS", + "Magic", + "guide", + "v3", + "Beast", + "Classe", + "onering", + "Monsters", + "Races", + "Weapon", + "adventure", + "Subclasses", + "stat block", + "weapon", + "Species", + "DONE", + "archetype", + "RPG", + "Hollow Knight", + "5e'24", + "Martial", + "DND", + "Classe Nova", + "Curse of Strahd", + "Boss", + "Hollowed Kingdoms", + "baldurs mouth", + "5.24", + "Homewbrew", + "Encyclopedia", + "Revised", + "OneWorldHD", + "knight", + "DPS", + "srd", + "Undead", + "items", + "DnD 5e", + "Guide", + "Compendium", + "Feat", + "newspaper", + "magic", + "TTRPG", + "descent into avernus", + "reference", + "system:D&D 5e24", + "feat", + "Magic Items", + "Campaign", + "resource", + "Feats", + "Anime", + "dd5", + "races", + "Monstrosity", + "DM Screen", + "2024 Rules", + "Rework", + "Character Build", + "Done", + "5e 2024", + "Construct", + "myth", + "magic items", + "creature", + "Legendary", + "Strahd", + "background", + "Player", + "style", + "Legacy", + "Player Handbook", + "martial", + "Character", + "Dungeons & Dragons", + "Table", + "reddit", + "monsters", + "OneDND", + "dragon", + "Suporte", + "Soulbound", + "Expanded Handbook", + "bestiary", + "Humanoid", + "system:dnd", + "Oredell", + "system:class", + "V3", + "system:5e", + "5e'14", + "Age of Sigmar", + "Items", + "Eberron", + "horror", + "dnd5e", + "star wars", + "Background", + "compendium", + "revision", + "Elemental", + "character", + "Marcial", + "SW5e", + "notes", + "DM", + "Fey", + "one-shot", + "resources", + "NEW", + "campaign", + "wondrous item", + "Setting", + "Archive", + "NIMRE", + "Tanque", + "Jogavel", + "Dnd 5e", + "LotM", + "setting", + "revised", + "Warhammer", + "rework", + "Conjurador", + "GMBinder", + "ItemSet", + "NPCs", + "classes", + "CR 2", + "AetherSail", + "undead", + "Artifact", + "cards", + "Example", + "Guides", + "Theme", + "Swamp", + "CR 1", + "patron", + "Extra", + "concept", + "final fantasy", + "Aberration", + "Elder Scrolls", + "rules", + "meta:gratis", + "Dice Pool", + "Cue", + "dark", + "type:Style", + "rpg", + "meta:free", + "summoner", + "OC", + "rare", + "Fleshing Out", + "francais", + "Dnd", + "Creatures", + "Sims 4", + "sous-classe", + "ffxiv", + "Underdark", + "add-on", + "weapons", + "Subrace", + "dungeons and dragons", + "Naruto 5e", + "Lafari", + "Very Rare", + "d6", + "red", + "Equipment", + "CR 3", + "Patron", + "5E", + "objet magique", + "spellcaster", + "feats", + "5.24e", + "system:d&d5e", + "Rare", + "Thudnfer", + "daggerheart", + "CR 1/2", + "Archetype", + "dnd 5e", + "Pathfinder", + "lineage", + "Celestial", + "Support", + "species", + "ARCHIVED", + "Horror", + "humanoid", + "Subclase", + "book:PHB E&E", + "final fantasy xiv", + "Jungle", + "Feywild", + "Fiend", + "subclasses", + "HB", + "Legacy Challenge", + "Project Horizon", + "vampire", + "WoW", + "DND 5e", + "Weapons", + "system:book clone", + "CoS", + "N5e", + "Summon", + "Spellcaster", + "Koretra", + "Voidborn", + "one shot", + "Templates", + "tables", + "Iphexar", + "Shattered Obelisk", + "Sword Coast", + "elemental", + "lore", + "character sheet", + "discord", + "BetterMonsters", + "players", + "group:simple skans", + "Coastal", + "Forest", + "Unearthed Arcana", + "Old", + "Collection", + "Ancestry", + "Caevash", + "Strixhaven", + "Limbus Company", + "Daydreams & Deviants", + "Statblocks", + "Urban", + "Classes", + "familiar", + "Blood", + "oneshot", + "n5e", + "wip", + "masks", + "Planeshifted", + "Carrioss", + "avernus", + "object", + "1", + "Ruins", + "Anime Character", + "wild shape", + "mask", + "dj9 game", + "Handbook", + "Curse", + "oath", + "Midralis", + "Appendix", + "5.5", + "tales of the valiant", + "player classes", + "Caster", + "Large", + "Fateforge", + "Cursed", + "beast", + "Pathfinder 2e", + "Design", + "Uncommon", + "Endeur", + "Elemental Water", + "SCC", + "sci-fi", + "Dragons", + "human", + "Gods", + "Medium", + "System", + "Help", + "Handout", + "Skyrim", + "BnB", + "draft", + "PC", + "Variant", + "syntax", + "OneShot", + "Clase", + "UESTRPG", + "Savannah", + "Reef", + "CR 5", + "Forgotten Realms", + "collection", + "Combat", + "Historia", + "artifact", + "Expansion", + "Attunement", + "Variant Rules", + "d&d", + "Party Build", + "Evocation", + "homerule", + "Forbidden West", + "how-to", + "tov", + "Mystical Item", + "CR 4", + "Necromancer", + "General Rules", + "Needs Update", + "stat blocks", + "DC Comics", + "Sword", + "Armor", + "blood hunter", + "Blood Hunter", + "Meio Conjurador", + "Mydia", + "3rd Party", + "N5E", + "Delvebound", + "Ocean", + "Subterranean", + "half-caster", + "Demon", + "Fire", + "meta:Template", + "Character Sheet", + "PF2e", + "png", + "fantasy", + "Setting Guide", + "Style", + "Cor", + "legacy", + "Minion", + "meta:khaoz age", + "Book", + "magical item", + "immersion", + "reminder cards", + "Regras", + "Durnovar", + "2025", + "Camp1", + "Abyss", + "armor", + "construct", + "firearms", + "Backgrounds", + "Companion", + "Melee", + "fey", + "Incomplete", + "Vampire", + "Bestiary", + "Worldbuilding", + "History", + "Conjuration", + "necromancy", + "dragons", + "ancestry", + "Mech", + "PbtA", + "COS", + "One Shot", + "Factions", + "Transmutation", + "Spellcasting", + "card", + "Ardh", + "redveil", + "conditions", + "elturel", + "rhye", + "group:James Haeck", + "CaelYuu", + "system:5.24e", + "system:GM Binder", + "Grassland", + "melee", + "Potions", + "anime", + "D&D 5e", + "Healer", + "Gambling", + "Lightning", + "fighting style", + "support", + "Style Template", + "mtg", + "NSFW", + "aventura", + "Manuals", + "plant", + "Incarnate", + "Crafting", + "DnDBeyond", + "Monster Girl", + "Monster Girl Encyclopedia", + "pet", + "npcs", + "Stat Block", + "Styleguide", + "mitologia", + "Objeto maravilloso", + "vaesen rpg", + "dnd-2024", + "Class Handbook", + "Space", + "Taiga", + "CR 6", + "Pact Boon", + "race/ancestry", + "Necromancy", + "cantrip", + "LoL", + "Raza", + "handout", + "Mechanic", + "Conversion", + "Wondrous Item", + "Familiar", + "necromancer", + "uncommon", + "curse", + "Campaign Setting", + "Tetra", + "1e", + "module", + "Evolving", + "boiling sea", + "deck", + "OSR", + "RU", + "VL", + "Underdeep", + "Deep Ocean", + "Giant", + "statblock", + "combat", + "Time", + "5E24", + "session zero", + "elf", + "tank", + "sorcerous origin", + "Drakkenheim", + "Tavern", + "Domain", + "healer", + "Valenor", + "blood", + "Oath", + "spooky", + "fire", + "meta:5e24 Style", + "Notes", + "City", + "Conjurador Completo", + "prop", + "Dotherys", + "Rietuma 3.0", + "5e24", + "Library of Ruina", + "español", + "Project Echo", + "battle of Japan", + "Plant", + "Badlands", + "Neverwinter", + "Fantasy", + "Beastfolk", + "Unarmed", + "Cold", + "Damage", + "attunement", + "Hurthud", + "3rd Level", + "spelljammer", + "mostro", + "Custom", + "PT-BR", + "Alternative Realms", + "The Foot", + "boss", + "demo", + "Supplement", + "FitD", + "classe", + "5.14", + "Copy", + "DnD5e24", + "X-Men", + "TNA", + "CR 8", + "Desert", + "CR 7", + "arme", + "random", + "spellcasting", + "Deprecated", + "Cards", + "finished", + "Ben 10", + "equipment", + "Geography", + "Games", + "For Players", + "Faerun", + "scroll", + "Faction", + "Alchemist", + "drow", + "Lineage", + "mix-blend-mode", + "columns", + "User Help", + "Reami Dimenticati", + "Класс", + "D100", + "nsfw", + "hucaen", + "v1.0", + "Cortex", + "Fallout", + "ww5e", + "MAGIC", + "DnD2024", + "ToV", + "D&D2024", + "The Backrooms", + "Freshwater", + "D20", + "Dragonborn", + "custom", + "sword", + "Dungeons and Dragons 5e", + "Water", + "legendary", + "Dungeon", + "Ravenloft", + "aberration", + "Longsword", + "transmutation", + "Fairy Tail", + "Character background", + "Exandria", + "Updated", + "pitch", + "Half-Caster", + "Complete", + "Money", + "player", + "forgotten-realms", + "Festival", + "Casino", + "SCAG", + "Currency", + "North", + "Toril", + "Scourged Land of Valenor", + "Oota", + "parchment", + "Literature", + "Serrith", + "PNJ", + "Divinity Original Sin 2", + "Wild", + "videogame", + "magic the gathering", + "sweetblossom", + "GMscreen", + "MandM", + "D&D 5.24", + "Camp2", + "Remaster", + "riassunti", + "type:Resource", + "system:D&D", + "tag:Class", + "Excelsior", + "Stat Blocks", + "Sci-Fi", + "Ooze", + "CR 1/8", + "sublclass", + "chart", + "Mountains", + "guns", + "Nature", + "Orc", + "Poison", + "Devil", + "fiend", + "DC", + "pt-br", + "ABnB", + "One-Shot", + "strahd", + "Ring", + "Theme song", + "orc", + "summon", + "Psion", + "Psionics", + "Dungeon Master", + "vehicle", + "DM only", + "Demigod", + "Antica Energia", + "Pirates", + "Sourcebook", + "devil", + "Cantrip", + "mystery", + "MtG", + "conversion", + "Festivals", + "Casinos", + "Taverns", + "Betting", + "Drinking", + "phandelver", + "Warhammer 40k", + "mutant", + "styling", + "FATE", + "Lone Wolf", + "icon", + "New Dawn", + "Magic Set", + "Paladin Subclass", + "Alter Class", + "difficulty classses", + "combat tables", + "phb", + "Project Moon", + "Undertomes", + "EGO", + "Campagne 1", + "Constelação", + "Arvore I", + "Fim da Jornada", + "greek god", + "dwarf", + "Firearms", + "3.5e", + "generator", + "Elf", + "meta: Scenario", + "enchantment", + "buff", + "ITW", + "Tank", + "Archived", + "Martial Archetype", + "caster", + "BR", + "Knight", + "Utility", + "SWADE", + "Star Wars", + "pc", + "Mystic", + "Useful", + "Netherdeep", + "crafting", + "Sapient Undead", + "Maverick", + "Revision", + "Resource", + "Humblewood", + "one piece", + "Bag of Holding", + "medium", + "lightning", + "backgrounds", + "4th Level", + "path", + "BREAK-RPG", + "dark fantasy", + "Players", + "poison", + "psionic", + "gazook89", + "homebrew subclass", + "wild-wasteland", + "CWD", + "Paid", + "Tales of the Valiant", + "Dreadhold", + "arma", + "system:Mutants and Masterminds", + "#Tiefschlaf", + "Brew", + "Myra", + "Swashbuckler", + "dead by daylight", + "Exceptional", + "COD Zombies", + "Hills", + "Tundra", + "type:Campaign", + "wild magic", + "Food", + "Death", + "homebrew rules", + "Remake", + "Witcher", + "water", + "Pet", + "book", + "AAH", + "pact", + "Ice", + "Character Creation", + "animal", + "Pokemon", + "clase", + "5e14", + "DBZ", + "CLONE", + "Evil", + "Tarsere", + "Mythology", + "pf2e", + "Magical", + "type:race", + "Sorcerous Origin", + "Information", + "styles", + "Module", + "gish", + "frames", + "DeltaGreen", + "Magic item", + "food", + "chef", + "basics", + "giant", + "Brew Creation", + "One-shot", + "ttrpg", + "Path", + "Don't Starve", + "MGE", + "firearm", + "DnDBehindTheScreen", + "store", + "The Artisan", + "timeline", + "college", + "dev", + "dungeon of the dead three", + "Cradle", + "Dnd5e", + "dungeon", + "Amaranthine", + "Regno di Oltremare", + "bestia", + "rewrite", + "WiP", + "Subclasse", + "mutants and masterminds", + "The Embrace", + "meta:documentation", + "Mutants And Masterminds", + "khedoria", + "Encounter Pack", + "giorni", + "Statblock", + "Enemies", + "Goblinoids", + "Heavens", + "system:2e", + "Vaalbara", + "Dwarf", + "airos", + "table", + "Artificer Specialization", + "Buff", + "Book 1", + "Ranged", + "cypher", + "utilities", + "40k", + "Psychic", + "Fear", + "steampunk", + "shadow", + "subclase", + "Barbarian Subclass", + "Elements", + "pact boon", + "Clan", + "Fly", + "solo", + "sourcebook", + "Marvel Comics", + "compilation", + "Firearm", + "sidekick", + "infusions", + "Mechanics", + "Summoner", + "Aasimar", + "Human", + "Vehicle", + "Shadow", + "Clone", + "custom css", + "ocean", + "sotdl", + "bandit", + "Wind", + "Printer Friendly", + "Obsolete", + "mechanics", + "illusion", + "5th edition", + "League of Legends", + "Vestige", + "dungeons", + "Dungeons", + "and", + "Elden Ring", + "L5R", + "d20", + "Poisons", + "d15", + "Dungeons And Dragons", + "MTG", + "divine", + "characters", + "witch", + "Anime Homebrew", + "Zombie", + "thunder", + "Jujutsu Kaisen", + "campagne", + "Deadlands", + "spell list", + "1 Person", + "Ritual", + "screen", + "nature", + "Divination", + "Compattare", + "dtrpg", + "quick ref", + "Mago", + "Illivia", + "Shonen", + "Core Deities", + "green ronin", + "Bless", + "D&D5e", + "version:0.1.0", + "curato", + "system:Ord", + "Images", + "Sealed Artifact", + "Giants", + "CR 9", + "CR 11", + "CR 0", + "CR 14", + "Shadowfell", + "Tier 1", + "d100", + "Elemental Air", + "artificiel", + "Cultist", + "Cyberpunk", + "Huge", + "Warrior", + "Gun", + "quest", + "LYRA", + "Music", + "Tiefling", + "Master", + "Witch", + "Linnorm", + "1st-level", + "Mount", + "Animal", + "Comics", + "Superhero", + "creatures", + "Hunter", + "Control", + "Dragon Ball", + "Dragon Ball Z", + "Dagger", + "questingforamonster", + "ICRPG", + "Booklet", + "f and t", + "common", + "Chaos", + "spellblade", + "Constitution", + "artisan", + "arcane", + "Released", + "ring", + "runes", + "gun", + "Supportive Material", + "The Witcher", + "Desarmado", + "Monster Monday", + "Bleach", + "Demon Slayer", + "mice", + "worldbuilding", + "Necrotic", + "ability score", + "demon", + "Armybook Shivatiano", + "warrior", + "Fighter Subclass", + "system", + "whisperveil", + "psychic", + "warhammer", + "Aventura", + "Culture", + "Material", + "meta:npc", + "shops", + "magic weapon", + "nhera", + "Dark Fantasy", + "Regles", + "Wonderous Item", + "Features", + "pokemon", + "Ghosts of Saltmarsh", + "monstrosity", + "DL TWW", + "companion", + "alternate layout", + "Tutorials", + "Kitsune", + "don", + "heroique", + "mini campaign", + "drago", + "Aquatic", + "tool", + "handmade", + "released", + "Spellblade", + "pregen", + "level 2", + "Baldurs gate 3", + "My Hero", + "Technically a subclass", + "5.24e Remastered Subclasses", + "dinosaurs", + "5E.2024", + "Razas", + "Horizon", + "Clothing", + "+2", + "castellano", + "pentacle prophecy", + "tag:Spells", + "gruppo A", + "Rpg", + "razze", + "type:Adventure", + "unfinished", + "3.5", + "gunslinger", + "BBEG", + "Arcane", + "component", + "Bow", + "backstory", + "phandalin", + "Skills", + "Pact", + "Elemental Earth", + "Joke", + "invocation", + "martial class", + "Super Villain", + "Eldritch", + "Elemental Fire", + "Homebrew Class", + "eldritch", + "cyberpunk", + "Player Race", + "Class Mod", + "Heatcoast", + "meta:Guide", + "Yemao", + "evil", + "Named NPC", + "CLASS", + "Angel", + "vecna", + "PT", + "PTBR", + "Ancient", + "Small", + "WotC Style", + "5e Homebrew", + "1st Level", + "dagger", + "Brancalonia", + "encounter", + "cat", + "primal path", + "Ambientazione", + "Magie", + "candlekeep", + "Ongoing", + "Oneshot", + "Wondrous", + "Janbrewery", + "Tattoos", + "5e (2014)", + "concentration", + "very rare", + "Set", + "Kobold", + "martial archetype", + "God", + "blog", + "New Gate", + "Healing", + "OneDnD", + "Incantesimi", + "Player Options", + "contest", + "pirate", + "Manuel", + "Alchimie", + "Herboristerie", + "Ingredients", + "starlost", + "Campaign 1", + "Abandoned", + "Previous Editions", + "Enchantment", + "Tools", + "Oblivion", + "domain", + "5th Level", + "DnD Beyond", + "Reference", + "Sorcerer Subclass", + "Dragon Magazine", + "feature", + "german", + "conjuration", + "strixhaven", + "Sentient", + "JJK", + "10 Generations", + "character creation", + "LevelUp", + "pallid grove", + "primer", + "Requires Attunement", + "College", + "Aesthetic", + "critter", + "home game", + "spanish", + "stats", + "Lairon", + "Hunters Guild", + "original setting", + "Bosses", + "Radiant Citadel", + "actions", + "Reworked", + "Elystera", + "Wyvern", + "vikings", + "thief", + "enemies", + "Obsession", + "Yi Sang", + "aberrazione", + "Limbus", + "animals", + "minecraft", + "mice of legend", + "osric", + "20 Minutes Till Dawn", + "campaign frame", + "latigo", + "DH", + "Eldritch Invocation", + "system:daggerheart", + "100ni", + "meta:Sheet", + "fa-solid fa-sheet-plastic:Ficha", + "tag:Berean", + "AD&D", + "B/X", + "The Codex Of Anomalous Entities", + "monster manual", + "Polar Waters", + "CR 12", + "CR 10", + "blood magic", + "Gunslinger", + "grimoire", + "Drakes", + "Japanese", + "subrace", + "ooze", + "Stats", + "Half Caster", + "Sea", + "time", + "Brawler", + "Session 0", + "Halloween", + "Runeterra", + "Divine", + "Random", + "Lifestar", + "arcane trickster", + "Paddy4530", + "evocation", + "light", + "Steampunk", + "shaman", + "Primal Path", + "monk subclass", + "Full Caster", + "World", + "Planning", + "spirit", + "Nova Era", + "abjuration", + "Christmas", + "Critical Role", + "Gish", + "Bandit", + "Monster Manual", + "party member", + "mgazt", + "Playable Race", + "Donjon.bin.sh", + "Final Fantasy", + "Roleplay", + "monstre", + "fairy", + "frame", + "Minecraft", + "Stealth", + "Manual", + "half caster", + "Storm", + "Sorcery", + "format work", + "Kingdom Hearts", + "hexblade", + "block", + "page layouts", + "Monk Subclass", + "FinyaFluKaiKolja", + "Radiant", + "group:playtest", + "Korrahir", + "noble", + "exorcist", + "xapien", + "Raven Queen", + "markdown", + "damage", + "Alchemy", + "morrigan", + "genasi", + "ZNH", + "folklore", + "Fate", + "hechicero", + "Air", + "Magic Weapon", + "Anime DND 5e", + "Dragon Ball Z TTRPG", + "Dragon Ball Z RPG", + "Dragon Ball Z DND", + "Dragon Ball Z 5e", + "samurai", + "Goblin", + "Base Sheet", + "Shackled City Adventure Path", + "Natureza", + "control", + "Normarch", + "Reddit", + "Genshin Impact", + "Abjuration", + "Myr", + "Flight", + "Vampyre", + "nightmare", + "Lycan", + "Occult", + "circle", + "Christmas Special", + "DoDD", + "Character Options", + "traduction", + "Characters", + "Gear", + "system:sf2e", + "drakkenheim", + "downtime", + "amulet", + "Feiticeiros e Maldicoes", + "Tecnica amaldicoada", + "prorpg", + "enemy", + "No Mercy", + "rain world", + "slugcat", + "fly", + "meta:User Guide", + "Fallout TTRPG", + "regles", + "Ill Tides", + "Light-hearted", + "Vastria", + "school", + "Fillible Online", + "Mezgarr", + "Berserk", + "invocations", + "Classe Refeita", + "Auroboros", + "bosses", + "fabula ultima", + "Shagya", + "wild", + "DnD 2024", + "KaiburrKathHound", + "Barbarian Path", + "fauna", + "5E.2014", + "system:curse of strahd", + "Unofficial", + "how to", + "Glaive", + "A5E", + "pt", + "Consumible", + "Realmers'", + "Versatile Lineage", + "Shichibukai", + "2024e", + "Rencontre", + "tag:Spell List", + "elementalist", + "noncaster", + "blasphemous", + "Mordhiem", + "Wildfrost", + "#Regelwerk", + "Rewrite", + "Maldición de Strahd", + "Scion", + "Entities", + "Hoarwyrm", + "Player utility", + "CR 1/4", + "Temperate Forest", + "Demons", + "Drow", + "type:rules", + "fay", + "2e", + "familier", + "supplement", + "Amberwar", + "slime", + "Lycanthropy", + "meta: Terres de Leyt", + "Strong", + "AAH Vol. 1", + "Force", + "Jump", + "Aboleths", + "lol", + "location", + "small", + "customizable", + "Modern", + "Sky", + "portugues", + "Hero", + "Villain", + "element", + "Tyranny of Dragons", + "Adventure Guide", + "New Class", + "Witchlight", + "Shardblade", + "Plateaux", + "WOTC", + "Snippet", + "Terra", + "Otherworldly Patron", + "ritual", + "hag", + "Cyberpunk 2077", + "tavern", + "Artificer Specialist", + "Werewolf", + "Boesia", + "vampiric", + "monastic tradition", + "Gothic", + "celestial", + "Unfinished", + "Core", + "Arcane Tradition", + "Troll", + "Origin", + "Draconic", + "dj9 member", + "test", + "Hag", + "gem", + "Invocations", + "Dark Sun", + "aarkhen", + "How to", + "ravenloft", + "faerie", + "Playtest", + "Shaman", + "dead", + "Tomba Aniquilacio", + "Pacto", + "fullcaster", + "Electric", + "Ability Score", + "4D", + "pathfinder", + "insect", + "hook", + "page layout", + "healing", + "Lineages", + "Flying", + "Martial Arts", + "journal", + "Aide de jeu", + "hunter", + "headers", + "Dark Souls", + "courtyard", + "crossroads", + "Quest", + "CotF", + "defense", + "Semryss", + "invoked class", + "Session Notes", + "goblin", + "infernal", + "fate", + "oni", + "spellbook", + "Summoning", + "slut", + "whore", + "Greyhawk", + "Mobility", + "Reddit Remake", + "Guild", + "Cosmic Mart", + "7th Level", + "dragonborn", + "curse of strahd", + "Ranger Subclass", + "dossier", + "dossie", + "de", + "pnpde", + "Plane Shift", + "halloween", + "group:aventura", + "9th Level", + "tome", + "cold", + "acid", + "deprecated", + "mind flayer", + "MECHA", + "EssentialsKit", + "2d6", + "ToD", + "Work In Progress", + "Bond", + "Versatile", + "Dead", + "SYWTBAGM", + "summoning", + "english", + "Eilistraee", + "Draft", + "DoD", + "map", + "Frightened", + "Psychic Damage", + "eberron", + "recompensa", + "wizard subclass", + "teiran", + "Saltmarsh", + "jp setting", + "Illithid", + "Longbow", + "hell", + "Monarch", + "type:feat", + "reglas", + "cooking", + "Abenteuer", + "reloaded", + "incompleto", + "mecanica", + "Location", + "Grimlores Grimoire", + "2024 Subclass", + "Chiesa di Toleno", + "finalfantasy", + "The Undertomes", + "Lobotomy Corporation", + "SDHTA", + "D&D 2024", + "other", + "ally", + "images", + "Player's Guide", + "Avalon Sword", + "Cael'Yuu", + "dnd-2014", + "Regelwerk", + "Español", + "br", + "dnd 5.0", + "monstro", + "grand cemetery", + "Phoenix", + "dnd 2024", + "Bloodhunter", + "Sintonizacion", + "dungeons & dragons", + "Fix", + "Rulebook", + "Shadowdark", + "heroic", + "HFW", + "Earthdawn", + "24e", + "cormyr", + "suzail", + "dc20", + "tag:Rules", + "The Griffon's Saddlebag", + "LOTM", + "tag:Adventure", + "drunken master", + "eldritch invocation", + "Персонаж", + "Orcs", + "Lizardfolk", + "Frostfell", + "CR 17", + "Shapechanger", + "Farmland", + "Mages", + "Any", + "CR 13", + "Earth", + "Mountain", + "Drake", + "transformation", + "GM", + "Lich", + "lovecraft", + "unique", + "Optional Rules", + "int", + "creator", + "Primal", + "simple", + "golem", + "Void", + "Armour", + "spellsword", + "General", + "Asian", + "Bringers of chaos", + "Optional Feature", + "subraces", + "Galanoth", + "barbarian subclass", + "felhearth", + "modular", + "Vampires", + "wysteria", + "adaptation", + "beasts", + "naruto", + "ninja", + "Psionic", + "Guns", + "Crystal", + "Guardian", + "NonProfit", + "Mimic", + "languages", + "Epic Boons", + "Primer", + "Icewind Dale", + "joke", + "lycan", + "CR3", + "Armors", + "ff7", + "materia", + "final fantasy 7 remake", + "esper", + "ff7 remake", + "gargantuan", + "Frog", + "CR5", + "blank", + "monster hunter", + "league of legends", + "french", + "Pokémon", + "kobold", + "soul", + "ffxi", + "d10", + "Roman", + "Cute", + "DD5", + "variant", + "tree", + "fr", + "Scenario", + "lycanthrope", + "druide", + "staff", + "eios", + "arkheneios", + "Runic", + "Work", + "Ukrainian", + "cover-page", + "mage", + "deities", + "gods", + "Boss Fight", + "Lair", + "WBTW", + "roguish archetype", + "Character Option", + "Shortsword", + "Illrigger", + "Bloodborne", + "cr6", + "Priest", + "Hamon", + "Toonkind", + "rol", + "Strength", + "forgotten realms", + "Spanish", + "Conclave", + "Electro", + "Magical Tattoos", + "Matt Mercer", + "Wildemount", + "Mighty Nien", + "Campaign 2", + "Resistances", + "Bug", + "impression", + "PF", + "Magnus Archives", + "ice", + "speed", + "Generic NPC", + "Titanic", + "Ink Friendly", + "bleed", + "elder scrolls", + "Immortal", + "LMOP", + "Travel", + "Olphus", + "3d6", + "heist", + "World History", + "ghost", + "genie", + "kids on bikes", + "Russia", + "conclave", + "overhaul", + "manual", + "Adventures In Eden", + "Downtime", + "hamon", + "cloak", + "shadowfell", + "Hellfire", + "Paladin Oath", + "Genshin", + "Nation", + "air", + "Magical Item", + "War", + "Original", + "Monstrous Compendium", + "Calamity", + "Warden", + "Apocalypse", + "shield", + "AC", + "expansion", + "Concentration", + "charm", + "Weave", + "lycanthropy", + "raza", + "far realm", + "fighter subclass", + "ita", + "Pirate", + "Laranja", + "Grapple", + "EastByForce", + "hobgoblin", + "oneshot-notes", + "Holy", + "optional", + "type:cenario", + "group:core", + "The Brewery", + "Alcance", + "Morrowind", + "Indigo", + "Divino", + "2nd Level", + "Sub-Class", + "cantrips", + "Cloak", + "battle master", + "Dark", + "Puzzle", + "Lucky", + "consumable", + "rebalance", + "Shove", + "Area Control", + "Vanguard", + "funny", + "e5", + "Dragonlance", + "psion", + "initiative", + "Tactician", + "Inspiration", + "artificier", + "way", + "inspired", + "historia", + "Medusa", + "2 part", + "holy", + "gift", + "Nimble", + "mostri", + "phoenix", + "travel", + "Class Template", + "Intimidation", + "constructs", + "P666", + "Formatting", + "Divinity", + "Rod", + "Language", + "yokai", + "rune", + "western", + "vampires", + "flying", + "cute", + "Enemy", + "boon", + "Tables", + "ShadowFight", + "meta: Theme", + "SCS", + "vanthampur villa", + "CoA", + "shop", + "destiny", + "magical weapon", + "Arcane Arcade", + "XP to Level 3", + "Dice Average RPG", + "Pip-Boy", + "Dragon Heist", + "session notes", + "tattoo", + "flick", + "P6:66", + "Comic Character", + "experiment", + "Minerva", + "type:Spellbook", + "Realmfall", + "Wand", + "halfling", + "sw5e", + "implementar AP", + "Mask", + "Gazook89", + "Weltenrauch-Chroniken", + "MiA", + "Made in Abyss", + "français", + "fae", + "Lemuria", + "Mork Borg", + "guerrier", + "prunus", + "condition", + "pf2", + "tr", + "costrutto", + "German", + "project moon", + "5r", + "galles", + "Project moon", + "Yisang", + "Spicebush", + "player-accessible", + "Especie", + "Westmarch", + "a", + "Cart", + "Magus", + "group:Mchael Galvis", + "tip", + "werewolf", + "mundane", + "garrett", + "unarmed", + "Arcane Odyssey", + "Tomb of Divinity", + "pets", + "Video Game", + "4 part", + "pbta", + "Druids", + "multiclass", + "manuale", + "mimic", + "plane shift", + "Dotes", + "Hechizos", + "Infernal", + "Enhanced", + "done", + "Mission report", + "Blanks", + "Masks", + "Ultimate Ability", + "shadow-slave", + "Advertising", + "transform", + "Fullmetal Alchemist", + "Fullmetal Alchemist Brotherhood", + "tag:TAoF&F", + "Dwarves", + "Humans", + "Nine Hells", + "Devils", + "Archons", + "CR 15", + "Troglodytes", + "Goliath", + "retired", + "boots", + "ranged", + "shields", + "Zhentarim", + "World of Warcraft", + "Frontline", + "Guildmaster's Guide to Ravnica", + "Dungeons & Dragons 5e", + "beholder", + "NEEDS FIXING", + "mechanic", + "Loot", + "champion", + "Runes", + "Shield", + "Punch", + "Sniper", + "Magical Girl", + "NotDND", + "story", + "Sleep", + "Bard College", + "Illusion", + "Thunder", + "Defender", + "Genasi", + "troll", + "Gehenna", + "Yugoloth", + "social", + "Player Class", + "homebrew class", + "CR 16", + "Ghost", + "Kobolds", + "Trolls", + "Yuan-Ti", + "Elder Scrolls Offline", + "armure", + "Mage", + "CR 18", + "Technology", + "Mystery", + "darkness", + "Airship", + "New Campaign", + "Warframe", + "Wizard Subclass", + "Gold", + "Candor", + "Overhaul", + "Dragon Knight", + "Enoreth", + "Artifacts", + "New", + "AMMO", + "Campagne", + "Valbise", + "Subclasseptember", + "Mecha", + "Yu-Gi-Oh", + "Goblinoid", + "underwater", + "SW5E", + "bardo" +] \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 06d4331b7..db6143f52 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@babel/preset-react": "^7.28.5", "@babel/runtime": "^7.28.4", "@dmsnell/diff-match-patch": "^1.1.0", - "@googleapis/drive": "^19.2.0", + "@googleapis/drive": "^20.1.0", "@sanity/diff-match-patch": "^3.2.0", "body-parser": "^2.2.0", "classnames": "^2.5.1", @@ -50,7 +50,7 @@ "marked-variables": "^1.0.5", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^9.1.5", + "mongoose": "^9.2.1", "nanoid": "5.1.6", "nconf": "^0.13.0", "react": "^18.3.1", @@ -94,23 +94,120 @@ "license": "MIT" }, "node_modules/@asamuzakjp/css-color": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.1.tgz", - "integrity": "sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.2.tgz", + "integrity": "sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==", "dev": true, "license": "MIT", "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-color-parser": "^3.1.0", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "lru-cache": "^11.2.4" + "@csstools/css-calc": "^3.0.0", + "@csstools/css-color-parser": "^4.0.1", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.2.5" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/@csstools/css-calc": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz", + "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/@csstools/css-color-parser": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.1.tgz", + "integrity": "sha512-vYwO15eRBEkeF6xjAno/KQ61HacNhfQuuU/eGwH67DplL0zD5ZixUa563phQvUelA07yDczIXdtmYojCphKJcw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.0.1", + "@csstools/css-calc": "^3.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "peer": true, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "peer": true, + "engines": { + "node": ">=20.19.0" } }, "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -118,9 +215,9 @@ } }, "node_modules/@asamuzakjp/dom-selector": { - "version": "6.7.7", - "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.7.tgz", - "integrity": "sha512-8CO/UQ4tzDd7ula+/CVimJIVWez99UJlbMyIgk8xOnhAVPKLnBZmUFYVgugS441v2ZqUq5EnSh6B0Ua0liSFAA==", + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", + "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", "dev": true, "license": "MIT", "dependencies": { @@ -128,13 +225,13 @@ "bidi-js": "^1.0.3", "css-tree": "^3.1.0", "is-potential-custom-element-name": "^1.0.1", - "lru-cache": "^11.2.5" + "lru-cache": "^11.2.6" } }, "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -203,9 +300,9 @@ } }, "node_modules/@babel/generator": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.0.tgz", - "integrity": "sha512-vSH118/wwM/pLR38g/Sgk05sNtro6TlTJKuiMXDaZqPUfjTFcudpCOt00IhOfj+1BFAX+UFAlzCU+6WXr3GLFQ==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "license": "MIT", "dependencies": { "@babel/parser": "^7.29.0", @@ -1931,6 +2028,19 @@ "dev": true, "license": "MIT" }, + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" + } + }, "node_modules/@cacheable/memory": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.7.tgz", @@ -1973,14 +2083,14 @@ } }, "node_modules/@cacheable/utils": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.3.3.tgz", - "integrity": "sha512-JsXDL70gQ+1Vc2W/KUFfkAJzgb4puKwwKehNLuB+HrNKWf91O736kGfxn4KujXCCSuh6mRRL4XEB0PkAFjWS0A==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.3.4.tgz", + "integrity": "sha512-knwKUJEYgIfwShABS1BX6JyJJTglAFcEU7EXqzTdiGCXur4voqkiJkdgZIQtWNFhynzDWERcTYv/sETMu3uJWA==", "dev": true, "license": "MIT", "dependencies": { "hashery": "^1.3.0", - "keyv": "^5.5.5" + "keyv": "^5.6.0" } }, "node_modules/@cacheable/utils/node_modules/keyv": { @@ -1994,9 +2104,9 @@ } }, "node_modules/@csstools/color-helpers": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.1.tgz", + "integrity": "sha512-NmXRccUJMk2AWA5A7e5a//3bCIMyOu2hAtdRYrhPPHjDxINuCwX1w6rnIZ4xjLcp0ayv6h8Pc3X0eJUGiAAXHQ==", "dev": true, "funding": [ { @@ -2010,59 +2120,7 @@ ], "license": "MIT-0", "engines": { - "node": ">=18" - } - }, - "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-color-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/color-helpers": "^5.1.0", - "@csstools/css-calc": "^2.1.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "node": ">=20.19.0" } }, "node_modules/@csstools/css-parser-algorithms": { @@ -2090,9 +2148,9 @@ } }, "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.0.26", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.26.tgz", - "integrity": "sha512-6boXK0KkzT5u5xOgF6TKB+CLq9SOpEGmkZw0g5n9/7yg85wab3UzSxB8TxhLJ31L4SGJ6BCFRw/iftTha1CJXA==", + "version": "1.0.27", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.27.tgz", + "integrity": "sha512-sxP33Jwg1bviSUXAV43cVYdmjt2TLnLXNqCWl9xmxHawWVjGz/kEbdkr7F9pxJNBN2Mh+dq0crgItbW6tQvyow==", "dev": true, "funding": [ { @@ -2383,9 +2441,9 @@ } }, "node_modules/@exodus/bytes": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.11.0.tgz", - "integrity": "sha512-wO3vd8nsEHdumsXrjGO/v4p6irbg7hy9kvIeR6i2AwylZSk4HJdWgL0FNaVquW1+AweJcdvU1IEpuIWk/WaPnA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.14.1.tgz", + "integrity": "sha512-OhkBFWI6GcRMUroChZiopRiSp2iAMvEBK47NhJooDqz1RERO4QuZIZnjP63TXX8GAiLABkYmX+fuQsdJ1dd2QQ==", "dev": true, "license": "MIT", "engines": { @@ -2401,9 +2459,9 @@ } }, "node_modules/@googleapis/drive": { - "version": "19.2.1", - "resolved": "https://registry.npmjs.org/@googleapis/drive/-/drive-19.2.1.tgz", - "integrity": "sha512-BM2r8B9dTo1zdi+fEPa62GgVjwP2EfaYoD1rTLYlA0SoWhNsaX/PKLBLEjEwkxZuIIQ12y57HZQjti6Jgudwtg==", + "version": "20.1.0", + "resolved": "https://registry.npmjs.org/@googleapis/drive/-/drive-20.1.0.tgz", + "integrity": "sha512-8/gapeLuZ3igooEGLE1AL3Zp5fjqigZQNmyjehb4QF7JVJh6FXF+72AcQGGsFypwJb2S68HIuQFomHBw4RJSOg==", "license": "Apache-2.0", "dependencies": { "googleapis-common": "^8.0.0" @@ -2927,9 +2985,9 @@ "license": "MIT" }, "node_modules/@mongodb-js/saslprep": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.5.tgz", - "integrity": "sha512-k64Lbyb7ycCSXHSLzxVdb2xsKGPMvYZfCICXvDsI8Z65CeWQzTEKS4YmGbnqw+U9RBvLPTsB6UCmwkgsDTGWIw==", + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.6.tgz", + "integrity": "sha512-y+x3H1xBZd38n10NZF/rEBlvDOOMQ6LKUTHqr8R9VkJ+mmQOYtJFxIlkkK8fZrtOiL6VixbOBWMbZGBdal3Z1g==", "license": "MIT", "dependencies": { "sparse-bitfield": "^3.0.3" @@ -3187,9 +3245,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.0.tgz", - "integrity": "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==", + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz", + "integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3236,14 +3294,14 @@ "license": "MIT" }, "node_modules/@typescript-eslint/project-service": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.54.0.tgz", - "integrity": "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", + "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.54.0", - "@typescript-eslint/types": "^8.54.0", + "@typescript-eslint/tsconfig-utils": "^8.56.0", + "@typescript-eslint/types": "^8.56.0", "debug": "^4.4.3" }, "engines": { @@ -3258,14 +3316,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.54.0.tgz", - "integrity": "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", + "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0" + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3276,9 +3334,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.54.0.tgz", - "integrity": "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", + "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", "dev": true, "license": "MIT", "engines": { @@ -3293,9 +3351,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.54.0.tgz", - "integrity": "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", + "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", "dev": true, "license": "MIT", "engines": { @@ -3307,16 +3365,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.54.0.tgz", - "integrity": "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", + "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.54.0", - "@typescript-eslint/tsconfig-utils": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/project-service": "8.56.0", + "@typescript-eslint/tsconfig-utils": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "debug": "^4.4.3", "minimatch": "^9.0.5", "semver": "^7.7.3", @@ -3361,9 +3419,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -3374,16 +3432,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.54.0.tgz", - "integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", + "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0" + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3393,19 +3451,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.54.0.tgz", - "integrity": "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", + "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.56.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3415,6 +3473,19 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", + "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", @@ -4912,9 +4983,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001767", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001767.tgz", - "integrity": "sha512-34+zUAMhSH+r+9eKmYG+k2Rpt8XttfE4yXAjoZvkAPs15xcYQhyBYdalJ65BzivAvGRMViEjy6oKr/S91loekQ==", + "version": "1.0.30001770", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz", + "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==", "funding": [ { "type": "opencollective", @@ -5142,9 +5213,9 @@ } }, "node_modules/codemirror": { - "version": "5.65.20", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.20.tgz", - "integrity": "sha512-i5dLDDxwkFCbhjvL2pNjShsojoL3XHyDwsGv1jqETUoW+lzpBKKqNTUWgQwVAOa0tUm4BwekT455ujafi8payA==", + "version": "5.65.21", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.21.tgz", + "integrity": "sha512-6teYk0bA0nR3QP0ihGMoxuKzpl5W80FpnHpBJpgy66NK3cZv5b/d/HY8PnRvfSsCG1MTfr92u2WUl+wT0E40mQ==", "license": "MIT" }, "node_modules/collect-v8-coverage": { @@ -5523,13 +5594,13 @@ } }, "node_modules/css-functions-list": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", - "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.3.3.tgz", + "integrity": "sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==", "dev": true, "license": "MIT", "engines": { - "node": ">=12 || >=16" + "node": ">=12" } }, "node_modules/css-tree": { @@ -5560,25 +5631,25 @@ } }, "node_modules/cssstyle": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", - "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-6.0.1.tgz", + "integrity": "sha512-IoJs7La+oFp/AB033wBStxNOJt4+9hHMxsXUPANcoXL2b3W4DZKghlJ2cI/eyeRZIQ9ysvYEorVhjrcYctWbog==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^4.1.1", - "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "@asamuzakjp/css-color": "^4.1.2", + "@csstools/css-syntax-patches-for-csstree": "^1.0.26", "css-tree": "^3.1.0", - "lru-cache": "^11.2.4" + "lru-cache": "^11.2.5" }, "engines": { "node": ">=20" } }, "node_modules/cssstyle/node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -6338,9 +6409,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "29.12.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.12.2.tgz", - "integrity": "sha512-IIRg0IZ5yuERfzOZrKuNScxk9yeuKo0M4Urx7RZcthK5HE/8gJUY518bdi7picLRBJVctjOW3yVx0zyBp4Cq+g==", + "version": "29.15.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.0.tgz", + "integrity": "sha512-ZCGr7vTH2WSo2hrK5oM2RULFmMruQ7W3cX7YfwoTiPfzTGTFBMmrVIz45jZHd++cGKj/kWf02li/RhTGcANJSA==", "dev": true, "license": "MIT", "dependencies": { @@ -6351,7 +6422,7 @@ }, "peerDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0", - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "jest": "*", "typescript": ">=4.8.4 <6.0.0" }, @@ -6401,19 +6472,25 @@ } }, "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "version": "2.0.0-next.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", + "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8786,9 +8863,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -9362,9 +9439,9 @@ } }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -9508,17 +9585,18 @@ } }, "node_modules/jsdom": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.0.0.tgz", - "integrity": "sha512-KDYJgZ6T2TKdU8yBfYueq5EPG/EylMsBvCaenWMJb2OXmjgczzwveRCoJ+Hgj1lXPDyasvrgneSn4GBuR1hYyA==", + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.1.0.tgz", + "integrity": "sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "@acemir/cssom": "^0.9.31", - "@asamuzakjp/dom-selector": "^6.7.6", + "@asamuzakjp/dom-selector": "^6.8.1", + "@bramus/specificity": "^2.4.2", "@exodus/bytes": "^1.11.0", - "cssstyle": "^5.3.7", + "cssstyle": "^6.0.1", "data-urls": "^7.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", @@ -9529,7 +9607,7 @@ "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^6.0.0", - "undici": "^7.20.0", + "undici": "^7.21.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.1", "whatwg-mimetype": "^5.0.0", @@ -9721,9 +9799,9 @@ } }, "node_modules/kareem": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-3.0.0.tgz", - "integrity": "sha512-RKhaOBSPN8L7y4yAgNhDT2602G5FD6QbOIISbjN9D6mjHPeqeg7K+EB5IGSU5o81/X2Gzm3ICnAvQW3x3OP8HA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-3.2.0.tgz", + "integrity": "sha512-VS8MWZz/cT+SqBCpVfNN4zoVz5VskR3N4+sTmUXme55e9avQHntpwpNq0yjnosISXqwJ3AQVjlbI4Dyzv//JtA==", "license": "Apache-2.0", "engines": { "node": ">=18.0.0" @@ -9958,9 +10036,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -10482,12 +10560,12 @@ } }, "node_modules/mongoose": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-9.1.5.tgz", - "integrity": "sha512-N6gypEO+wLmZp8kCYNQmrEWxVMT0KhyHvVttBZoKA/1ngY7aUsBjqHzCPtDgz+i8JAnqMOiEKmuJIDEQu1b9Dw==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-9.2.1.tgz", + "integrity": "sha512-fmNLwgct5km7iL1MqvTMncarR1E1TIw2lmc9A4UoDVdS7AQe95K+DnRK0qATkSUdwUC9V/5wlDcqnkQQjbSRkA==", "license": "MIT", "dependencies": { - "kareem": "3.0.0", + "kareem": "3.2.0", "mongodb": "~7.0", "mpath": "0.9.0", "mquery": "6.0.0", @@ -10868,6 +10946,25 @@ "node": ">=10.5.0" } }, + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/node-fetch": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", @@ -11859,9 +11956,9 @@ } }, "node_modules/qs": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", - "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -13616,9 +13713,9 @@ } }, "node_modules/stylelint-config-recess-order": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recess-order/-/stylelint-config-recess-order-7.6.0.tgz", - "integrity": "sha512-c3LXX4a8UEtrMD/KigK4I7LFexbM2p/eSTqnix5dmmvydEqX3dzrRt981h8giSEhA51vxdCEefQc3umH60i2bA==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/stylelint-config-recess-order/-/stylelint-config-recess-order-7.6.1.tgz", + "integrity": "sha512-ac0H/Iy2chh1YBADrua87G+nJCmG/SdG7gjnoLvtfpN0D+RuNfuADawfbCKvm0LMp5hvuRFNkJsu6xNoLM5ToA==", "dev": true, "license": "ISC", "peerDependencies": { @@ -13915,9 +14012,9 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { @@ -14097,22 +14194,22 @@ } }, "node_modules/tldts": { - "version": "7.0.21", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.21.tgz", - "integrity": "sha512-Plu6V8fF/XU6d2k8jPtlQf5F4Xx2hAin4r2C2ca7wR8NK5MbRTo9huLUWRe28f3Uk8bYZfg74tit/dSjc18xnw==", + "version": "7.0.23", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.23.tgz", + "integrity": "sha512-ASdhgQIBSay0R/eXggAkQ53G4nTJqTXqC2kbaBbdDwM7SkjyZyO0OaaN1/FH7U/yCeqOHDwFO5j8+Os/IS1dXw==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^7.0.21" + "tldts-core": "^7.0.23" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "7.0.21", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.21.tgz", - "integrity": "sha512-oVOMdHvgjqyzUZH1rOESgJP1uNe2bVrfK0jUHHmiM2rpEiRbf3j4BrsIc6JigJRbHGanQwuZv/R+LTcHsw+bLA==", + "version": "7.0.23", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.23.tgz", + "integrity": "sha512-0g9vrtDQLrNIiCj22HSe9d4mLVG3g5ph5DZ8zCKBr4OtrspmNB6ss7hVyzArAeE88ceZocIEGkyW1Ime7fxPtQ==", "dev": true, "license": "MIT" }, @@ -14529,9 +14626,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.20.0.tgz", - "integrity": "sha512-MJZrkjyd7DeC+uPZh+5/YaMDxFiiEEaDgbUSVMXayofAkDWF1088CDo+2RPg7B1BuS1qf1vgNE7xqwPxE0DuSQ==", + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz", + "integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index b12edd6be..7004ec51d 100644 --- a/package.json +++ b/package.json @@ -61,10 +61,11 @@ "server" ], "transformIgnorePatterns": [ - "node_modules/(?!(nanoid|@exodus/bytes|parse5)/)" + "node_modules/(?!(nanoid|@exodus/bytes|parse5|@asamuzakjp|@csstools)/)" ], "transform": { - "^.+\\.js$": "babel-jest" + "^.+\\.[jt]s$": "babel-jest", + "^.+\\.mjs$": "babel-jest" }, "coveragePathIgnorePatterns": [ "build/*" @@ -94,7 +95,7 @@ "@babel/preset-react": "^7.28.5", "@babel/runtime": "^7.28.4", "@dmsnell/diff-match-patch": "^1.1.0", - "@googleapis/drive": "^19.2.0", + "@googleapis/drive": "^20.1.0", "@sanity/diff-match-patch": "^3.2.0", "body-parser": "^2.2.0", "classnames": "^2.5.1", @@ -128,7 +129,7 @@ "marked-variables": "^1.0.5", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", - "mongoose": "^9.1.5", + "mongoose": "^9.2.1", "nanoid": "5.1.6", "nconf": "^0.13.0", "react": "^18.3.1", @@ -151,7 +152,7 @@ "globals": "^16.4.0", "jest": "^30.2.0", "jest-expect-message": "^1.1.3", - "jsdom": "^28.0.0", + "jsdom": "^28.1.0", "jsdom-global": "^3.0.2", "postcss-less": "^6.0.0", "stylelint": "^16.25.0", diff --git a/server/admin.api.spec.js b/server/admin.api.spec.js index e156c6c8f..cb25dd67d 100644 --- a/server/admin.api.spec.js +++ b/server/admin.api.spec.js @@ -1,4 +1,5 @@ /*eslint max-lines: ["warn", {"max": 1000, "skipBlankLines": true, "skipComments": true}]*/ +import mongoose from 'mongoose'; import supertest from 'supertest'; import HBApp from './app.js'; import { model as NotificationModel } from './notifications.model.js'; @@ -8,8 +9,19 @@ import { model as HomebrewModel } from './homebrew.model.js'; // Mimic https responses to avoid being redirected all the time const app = supertest.agent(HBApp).set('X-Forwarded-Proto', 'https'); +let dbState; + describe('Tests for admin api', ()=>{ + beforeEach(()=>{ + // Mock DB ready (for dbCheck middleware) + dbState = mongoose.connection.readyState; + mongoose.connection.readyState = 1; + }); + afterEach(()=>{ + // Restore DB ready state + mongoose.connection.readyState = dbState; + jest.resetAllMocks(); });