diff --git a/.gitignore b/.gitignore
index 0fe1b64..00bd5a4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,11 @@
/unpacked/
-packed/*
+js5/*
/lib/
/temp/
/tmp/
config/xtea/*
-/indexes/
+indexes/*
+index/*
/logs/
@@ -26,4 +27,4 @@ yarn-error.log*
*.sln
*.sw?
-!packed/.gitkeep
\ No newline at end of file
+!js5/.gitkeep
diff --git a/README.md b/README.md
index 3325c10..7ea16f8 100644
--- a/README.md
+++ b/README.md
@@ -7,15 +7,13 @@
Node tools for managing and indexing the JS5 file store used with RuneJS.
## CLI Tools
-_@todo work in progress_
- `index`
- `unpack`
## Archives
-_@todo work in progress_
-### JS5 // Game Version 400+
+### JS5 File Store // Game Builds 400-604
| Key | Archive Name | Content Description | File Format | Build |
|----------------------------------:|:-----------------|:----------------------------------|:-----------:|:-----------------:|
@@ -33,8 +31,21 @@ _@todo work in progress_
| idx **9** | textures | Game Textures | | _400_+ |
| idx **10** | binary | Miscellaneous Binary Files | | _400_+ |
| idx **11** | midi_jingles | Shorter Midi Jingles | .mid | _400_+ |
-| | | | | |
| idx **12** | clientscripts | Client Script (CS2) Files | .cs2 | _435_+ |
| idx **13** | fontmetrics | Game Font Metrics | | _443_+ |
-| idx **14** | vorbis | Vorbis Sound Files | .ogg | _451_+ |
+| idx **14** | vorbis | Vorbis Sound Files | | _451_+ |
| idx **15** | midi_instruments | Midi Song Instruments | | _451_+ |
+| idx **16** | config_loc | Location Object Configs | | _489_+ |
+| idx **17** | config_enum | Enum Configs | | _489_+ |
+| idx **18** | config_npc | NPC Configs | | _489_+ |
+| idx **19** | config_obj | Item Object Configs | | _489_+ |
+| idx **20** | config_seq | Animation Sequence Configs | | _489_+ |
+| idx **21** | config_spot | Graphical Spot Animation Configs | | _489_+ |
+| idx **22** | config_var_bit | VarBit Configs | | _489_+ |
+| idx **23** | worldmapdata | In-Game World Map Data | | _493_+ |
+| idx **24** | quickchat | Quickchat Data | | _498_+ |
+| idx **25** | quickchat_global | Global Quickchat Data | | _498_+ |
+| idx **26** | materials | Materials | | _500_+ |
+| idx **27** | config_particle | Particle Configs | | _523_+ |
+| idx **28** | defaults | Defaults | | _537_+ |
+| idx **29** | billboards | Billboards | | _582_+ |
diff --git a/config/archives.json5 b/config/archives.json5
deleted file mode 100644
index ff5fe86..0000000
--- a/config/archives.json5
+++ /dev/null
@@ -1,129 +0,0 @@
-{
- // The main index of indexes
- main: {
- index: 255,
- compression: 'uncompressed',
- versioned: false
- },
-
- // Regular indexes
- anims: {
- index: 0,
- compression: 'bzip',
- versioned: true,
- flatten: true
- },
- bases: {
- index: 1,
- compression: 'gzip',
- versioned: true
- },
- config: {
- index: 2,
- compression: 'bzip',
- versioned: true,
- groupNames: {
- '.flu': 1, // Floor Underlays
- // 2?
- '.idk': 3, // Identity Kit
- '.flo': 4, // Floor Overlays
- '.inv': 5, // Inventory
- '.loc': 6, // Objects
- // 7?
- '.enum': 8, // Enums
- '.npc': 9, // Npcs
- '.obj': 10, // Items
- '.param': 11, // Script Parameters
- '.seq': 12, // Animation Sequences
- '.spotanim': 13, // Graphical "Spot" Animations
- '.var_bit': 14, // Bit Variables
- // 15?
- '.var_player': 16, // Player Variables
- // 17?
- '.area': 18,
- }
- },
- interfaces: {
- index: 3,
- compression: 'bzip',
- versioned: true,
- flatten: true
- },
- synth_sounds: {
- index: 4,
- compression: 'gzip',
- versioned: true,
- contentType: '.wav'
- },
- maps: {
- index: 5,
- compression: 'gzip',
- encryption: [ 'xtea', '^l[0-9]{1,3}_[0-9]{1,3}$' ],
- versioned: true,
- filesNamed: true
- },
- midi_songs: {
- index: 6,
- compression: 'gzip',
- versioned: false,
- contentType: '.mid',
- filesNamed: true
- },
- models: {
- index: 7,
- compression: 'gzip',
- versioned: true,
- contentType: '.dat'
- },
- sprites: {
- index: 8,
- compression: 'gzip',
- versioned: true,
- filesNamed: true
- },
- textures: {
- index: 9,
- compression: 'gzip',
- versioned: true
- },
- binary: {
- index: 10,
- compression: 'uncompressed',
- versioned: true,
- filesNamed: true
- },
- midi_jingles: {
- index: 11,
- compression: 'gzip',
- versioned: true,
- contentType: '.mid'
- },
- clientscripts: {
- index: 12,
- compression: 'gzip',
- versioned: true,
- contentType: '.cs2',
- filesNamed: true,
- build: 435
- },
- fontmetrics: {
- index: 13,
- compression: 'gzip',
- versioned: false,
- filesNamed: true,
- build: 443
- },
- vorbis: {
- index: 14,
- compression: 'gzip',
- versioned: true,
- contentType: '.ogg',
- build: 451
- },
- midi_instruments: {
- index: 15,
- compression: 'gzip',
- versioned: false,
- build: 451
- }
-}
diff --git a/config/js5-archives.json5 b/config/js5-archives.json5
new file mode 100644
index 0000000..977b5c9
--- /dev/null
+++ b/config/js5-archives.json5
@@ -0,0 +1,595 @@
+{
+ // The main index of indexes
+ main: {
+ key: 255
+ },
+
+ // Regular indexes
+ anims: {
+ key: 0,
+ flattenGroups: true
+ },
+ bases: {
+ key: 1
+ },
+ config: {
+ key: 2,
+ groupNames: {
+ '.flu': 1, // Floor Underlays
+ // 2?
+ '.idk': 3, // Identity Kit
+ '.flo': 4, // Floor Overlays
+ '.inv': 5, // Inventory
+ '.loc': 6, // Objects
+ // 7?
+ '.enum': 8, // Enums
+ '.npc': 9, // Npcs
+ '.obj': 10, // Items
+ '.param': 11, // Script Parameters
+ '.seq': 12, // Animation Sequences
+ '.spotanim': 13, // Graphical "Spot" Animations
+ '.var_bit': 14, // Bit Variables
+ // 15?
+ '.var_player': 16, // Player Variables
+ // 17?
+ '.area': 18,
+ }
+ },
+ interfaces: {
+ key: 3,
+ flattenGroups: true,
+ groupNames: {
+ '100guide_eggs_overlay': 0,
+ '100guide_flour_overlay': 1,
+ '100guide_inv_flour': 2,
+ '100guide_milk_overlay': 3,
+ 'tog_water_bowl': 4,
+ 'agilityarena_overlay': 5,
+ 'agilityarena_trade': 6,
+ 'ahoy_blackout': 7,
+ 'ahoy_islandmap': 8,
+ 'ahoy_runedraw': 9,
+ 'ahoy_windspeed': 10,
+ 'bank_deposit_box': 11,
+ 'bankpin_main': 13,
+ 'bankpin_settings': 14,
+ 'banner_padlock_keys': 15,
+ 'banner_anti_virus': 16,
+ 'banner_scamming': 21,
+ 'banner_security': 22,
+ 'banner_xmas': 23,
+ 'barrows_overlay': 24,
+ 'barrows_puzzle': 25,
+ 'blast_furnace_bar_stock': 28,
+ 'blast_furnace_plan_scroll': 29,
+ 'blast_furnace_temp_gauge': 30,
+ 'boardgames_challenge': 31,
+ 'boardgames_draughts': 32,
+ 'boardgames_draughts_options': 33,
+ 'boardgames_draughts_overlay': 34,
+ 'boardgames_draughts_view': 35,
+ 'boardgames_runelink': 36,
+ 'boardgames_runelink_options': 37,
+ 'boardgames_runelink_overlay': 38,
+ 'boardgames_runelink_view': 39,
+ 'boardgames_runesquares': 40,
+ 'boardgames_runesquares_options': 41,
+ 'boardgames_runesquares_overlay': 42,
+ 'boardgames_runesquares_view': 43,
+ 'boardgames_runeversi': 44,
+ 'boardgames_runeversi_options': 45,
+ 'boardgames_runeversi_overlay': 46,
+ 'boardgames_runeversi_view': 47,
+ 'bob_locator_amulet': 48,
+ 'burgh_map': 51,
+ 'canoe': 52,
+ 'canoe_stations_map': 53,
+ 'castlewars_catapult': 54,
+ 'castlewars_score': 55,
+ 'castlewars_shopside': 56,
+ 'castlewars_status_overlay': 57,
+ 'castlewars_status_overlay_saradomin': 58,
+ 'castlewars_status_overlay_zamorak': 59,
+ 'castlewars_trade': 60,
+ 'cat_naming': 61,
+ 'cave_goblin_markers': 62,
+ 'champions_scroll': 63,
+ 'chat1': 64,
+ 'chat2': 65,
+ 'chat3': 66,
+ 'chat4': 67,
+ 'chat_np1': 68,
+ 'chat_np2': 69,
+ 'chat_np3': 70,
+ 'chat_np4': 71,
+ 'confirm_destroy': 94,
+ 'sailing_transport_world_map': 95,
+ 'darkness_dark': 96,
+ 'darkness_light': 97,
+ 'darkness_medium': 98,
+ 'death_dice': 99,
+ 'deep_blue': 100,
+ 'pattern_next': 103,
+ 'stockmarket': 105,
+ 'stockside': 107,
+ 'stockcollect': 109,
+ 'dwarf_rock_book': 111,
+ 'dwarf_rock_cannon': 112,
+ 'dwarf_rock_schematics': 113,
+ 'dwarf_rock_schematics_control': 114,
+ 'enakh_film': 117,
+ 'enakh_smoke_overlay': 118,
+ 'fade_to_black': 120,
+ 'fade_to_light_blue': 121,
+ 'fade_to_white': 122,
+ 'fairy_certificate': 123,
+ 'farming_tools': 125,
+ 'farming_tools_side': 126,
+ 'favour_keyring': 127,
+ 'doubleobjbox': 131,
+ 'garden_list': 132,
+ 'garden_quiz': 133,
+ 'aide_compass': 135,
+ 'chatdefault': 137,
+ 'glidermap': 138,
+ 'gnomeball': 139,
+ 'horror_metaldoor': 142,
+ 'hauntedmine_controls': 144,
+ 'inventory': 149,
+ 'keldagrim_map': 150,
+ 'keldagrim_story1': 151,
+ 'keldagrim_titles': 152,
+ 'aide_death': 153,
+ 'leather_crafting': 154,
+ 'legends_mirror': 155,
+ 'quickchat_tutorial': 157,
+ 'rocko_kittens': 160,
+ 'smki_assignment': 161,
+ 'smki_learn': 163,
+ 'smki_buy': 164,
+ 'smki_smoke_overlay': 165,
+ 'rocko_cannonball': 166,
+ 'rocko_underwater': 167,
+ 'rocko_seagull': 168,
+ 'fade_from_black': 170,
+ 'chatlarge': 173,
+ 'wom_scroll': 174,
+ 'heat_overlay': 175,
+ 'fade_from_white': 177,
+ 'light2': 178,
+ 'light_blue': 179,
+ 'lightning_flash': 180,
+ 'logout': 182,
+ 'macro_combilock': 185,
+ 'macro_evil_bob': 186,
+ 'music_v3': 187,
+ 'macro_mime_emotes': 188,
+ 'macro_quizshow': 191,
+ 'magic': 192,
+ 'magic_zaros': 193,
+ 'magictraining_grave': 196,
+ 'magictraining_shop': 197,
+ 'magictraining_tele': 198,
+ 'mazetimer': 209,
+ 'message1': 210,
+ 'message2': 211,
+ 'message3': 212,
+ 'message4': 213,
+ 'message5': 214,
+ 'message_np1': 215,
+ 'message_np2': 216,
+ 'message_np3': 217,
+ 'message_np4': 218,
+ 'message_np5': 219,
+ 'messagescroll': 220,
+ 'messagescroll2': 221,
+ 'peng_emote': 223,
+ 'misc_shipjourney': 224,
+ 'mm_message': 225,
+ 'mole_mud': 226,
+ 'mourning_deathalter_list': 227,
+ 'multi2': 228,
+ 'multi2_chat': 229,
+ 'multi3': 230,
+ 'multi3_chat': 231,
+ 'multi4': 232,
+ 'multi4_chat': 233,
+ 'multi5': 234,
+ 'multi5_chat': 235,
+ 'multivar2': 236,
+ 'multivar4': 237,
+ 'multivar5': 238,
+ 'npcchat1': 241,
+ 'npcchat2': 242,
+ 'npcchat3': 243,
+ 'npcchat4': 244,
+ 'npcchat_np1': 245,
+ 'npcchat_np2': 246,
+ 'npcchat_np3': 247,
+ 'npcchat_np4': 248,
+ 'surok_letter1': 249,
+ 'surok_letter2': 250,
+ 'olaf2_lock_gate': 252,
+ 'olaf2_skull_puzzle': 253,
+ 'olaf2_treasuremap': 254,
+ 'area_task': 259,
+ 'dream_armour': 260,
+ 'options': 261,
+ 'pinball_interface': 263,
+ 'paint_cannon': 264,
+ 'clanwars_overlay': 265,
+ 'pest_rewards': 267,
+ 'prayer': 271,
+ 'priestperil_gravemonument': 272,
+ 'prisonpete': 273,
+ 'questjournal_v2': 274,
+ 'questjournal_scroll': 275,
+ 'ratcatcher_flute': 282,
+ 'ratcatcher_flute_music': 283,
+ 'ratcatcher_overlay': 284,
+ 'rd_combolock': 285,
+ 'regicide_still': 286,
+ 'roguesden_dials': 290,
+ 'roguesden_gear_select': 291,
+ 'roguesden_gears': 292,
+ 'roguesden_puzzle': 293,
+ 'rum_deal_title': 295,
+ 'sandstorm': 296,
+ 'seer_combolock': 298,
+ 'smithing_new': 300,
+ 'skill_cookmany': 307,
+ 'lotr_scroll': 308,
+ 'skill_multi1': 309,
+ 'slayer_staff_spells': 310,
+ 'smelting': 311,
+ 'smokeoverlay': 313,
+ 'soulbane_angerbar': 315,
+ 'soulbane_cut': 316,
+ 'soulbane_darkness': 317,
+ 'soulbane_scare': 318,
+ 'staff_spells': 319,
+ 'stats': 320,
+ 'swamp_boatjourney': 321,
+ 'swamp_boatjourney_back': 322,
+ 'tanner': 324,
+ 'target': 325,
+ 'teleport_other': 326,
+ 'cws_warning_11': 327,
+ 'temple_screen': 328,
+ 'templetrek_map': 329,
+ 'tradeconfirm': 334,
+ 'trademain': 335,
+ 'tradeside': 336,
+ 'trail_cluelong': 345,
+ 'trail_map01': 346,
+ 'trail_map02': 347,
+ 'trail_map03': 348,
+ 'trail_map04': 349,
+ 'trail_map05': 350,
+ 'trail_map06': 351,
+ 'trail_map07': 352,
+ 'trail_map08': 353,
+ 'trail_map09': 354,
+ 'trail_map10': 355,
+ 'trail_map11': 356,
+ 'trail_map12': 357,
+ 'trail_map13': 358,
+ 'trail_map14': 359,
+ 'trail_map15': 360,
+ 'trail_map16': 361,
+ 'trail_map17': 362,
+ 'trail_puzzle': 363,
+ 'trail_reward': 364,
+ 'trail_sextant': 365,
+ 'trawler_overlay': 366,
+ 'trawler_reward': 367,
+ 'trawler_start': 368,
+ 'tutorial_progress': 371,
+ 'tutorial_text': 372,
+ 'tzhaar_fightpit': 373,
+ 'welcome_screen': 378,
+ 'werewolf_goal': 379,
+ 'welcome_final_tex': 380,
+ 'wilderness_overlay': 381,
+ 'wilderness_warning': 382,
+ 'wom_telescope': 386,
+ 'wornitems': 387,
+ 'objdialog': 389,
+ 'poh_hangman': 393,
+ 'poh_house_options': 398,
+ 'poh_magic_tablets': 400,
+ 'poh_ranging': 401,
+ 'poh_sawmill': 403,
+ 'poh_scrying_pool': 404,
+ 'banner_poh': 405,
+ 'pest_mace': 406,
+ 'pest_lander_overlay': 407,
+ 'pest_status_overlay': 408,
+ 'mcannon_interface': 409,
+ 'warguild_defence': 410,
+ 'warguild_defence_mini': 411,
+ 'warguild_dummy': 412,
+ 'brew_telescope_overlay': 413,
+ 'brew_game_over': 414,
+ 'brew_overlay': 415,
+ 'brew_worktable': 416,
+ 'brew_tools': 417,
+ 'tutorial_text2': 421,
+ 'fairy2_certificate_broken': 423,
+ 'fairy2_message': 424,
+ 'scroll_godfather': 427,
+ 'ntk_overlay': 428,
+ 'magic_lunar': 430,
+ 'xbows_enchant_bolt': 432,
+ 'xbows_pouch': 433,
+ 'crafting_silver_casting': 438,
+ 'openurl': 445,
+ 'crafting_gold': 446,
+ 'banner_chatheads': 447,
+ 'brain_water_overlay': 448,
+ 'multivar3': 451,
+ 'myq3_statue_painting': 452,
+ 'myq3_blackout': 453,
+ 'myq3_boat_map': 454,
+ 'crafting_spinning': 459,
+ 'seaslug_boat_travel': 461,
+ 'kings_letter_v2': 463,
+ 'emotes': 464,
+ 'zep_balloon_map': 469,
+ 'zep_interface': 470,
+ 'zep_interface_side': 471,
+ 'anma_rgb': 480,
+ 'barbassault_horn': 484,
+ 'barbassault_over_att': 485,
+ 'barbassault_over_col': 486,
+ 'barbassault_over_def': 487,
+ 'barbassault_over_heal': 488,
+ 'barbassault_playerstat': 490,
+ 'barbassault_reward_shop': 491,
+ 'barbassault_timer_overlay': 494,
+ 'barbassault_turret': 495,
+ 'barbassault_tutorial': 496,
+ 'barbassault_wavecomplete': 497,
+ 'contact_scroll_blood': 498,
+ 'skill_guide_v2': 499,
+ 'poh_hangman_german': 507,
+ 'tol_homonculus_overlay': 508,
+ 'tol_cage_puzzle': 509,
+ 'tol_pressure_machine': 510,
+ 'tol_pipe_machine': 511,
+ 'inventory_ranging': 512,
+ 'inventory_wear': 513,
+ 'brain_cat_overlay': 514,
+ 'brain_gas_overlay': 515,
+ 'objbox': 519,
+ 'dream_cyrisus': 521,
+ 'dream_monster_stat': 522,
+ 'dream_player_stats': 523,
+ 'dream_title': 524,
+ 'vm_museum_map': 527,
+ 'vm_digsite': 528,
+ 'vm_kudos': 532,
+ 'vm_timeline': 534,
+ 'grim_tasklist': 538,
+ 'noexit': 539,
+ 'crafting_glass': 542,
+ 'dragon_slayer_qip_clouds': 543,
+ 'dragon_slayer_qip_cr_journey': 544,
+ 'dragon_slayer_qip_elvarg': 545,
+ 'dragon_slayer_qip_elvarg_fly': 546,
+ 'dragon_slayer_qip_map': 547,
+ 'toplevel': 548,
+ 'toplevel_full': 549,
+ 'friends2': 550,
+ 'ignore2': 551,
+ 'snapshot_main': 553,
+ 'multi2_mes': 557,
+ 'skill_multi6': 558,
+ 'pattern_cards': 559,
+ 'cws_warning_9': 560,
+ 'cws_warning_21': 561,
+ 'cws_warning_2': 562,
+ 'cws_warning_5': 563,
+ 'cws_warning_23': 564,
+ 'cws_warning_10': 565,
+ 'cws_warning_6': 566,
+ 'cws_warning_14': 567,
+ 'cws_warning_3': 568,
+ 'cws_warning_16': 569,
+ 'cws_warning_17': 570,
+ 'cws_warning_19': 571,
+ 'cws_warning_13': 572,
+ 'cws_warning_12': 573,
+ 'cws_warning_1': 574,
+ 'cws_warning_8': 576,
+ 'cws_warning_18': 577,
+ 'cws_warning_15': 578,
+ 'cws_warning_4': 579,
+ 'cws_warning_20': 580,
+ 'cws_warning_24': 581,
+ 'skill_multi1_small': 582,
+ 'cws_doomsayer': 583,
+ 'kr_king_statue': 584,
+ 'kr_pyramid_escape': 585,
+ 'kr_picklock': 588,
+ 'clanjoin': 589,
+ 'clansetup': 590,
+ 'cws_warning_25': 600,
+ 'godwars_overlay': 601,
+ 'shop_template': 620,
+ 'shop_template_side': 621,
+ 'banner_group': 622,
+ 'banner_group_assist': 623,
+ 'cws_warning_26': 627,
+ 'duel2_side': 628,
+ 'duel2_scoreboard': 632,
+ 'duel2_challengeoverlay': 638,
+ 'duel2_select_type': 640,
+ 'exchange_history': 643,
+ 'exchange_sets_side': 644,
+ 'exchange_itemsets': 645,
+ 'exchange_sand_timer': 646,
+ 'clanwars_viewing_orb': 649,
+ 'cws_warning_30': 650,
+ 'gravestone_shop': 652,
+ 'bounty_overlay': 653,
+ 'bounty_overlay_waiting': 656,
+ 'bounty_warning': 657,
+ 'lore_stats_side': 662,
+ 'lore_cats_side': 663,
+ 'lore_bank_side': 665,
+ 'equip_screen2': 667,
+ 'inventory_wear2': 670,
+ 'lore_bank': 671,
+ 'tutorial2_mesbox': 674,
+ 'cws_warning_27': 676,
+ 'cws_warning_28': 677,
+ 'cws_warning_29': 678,
+ 'banner_summoning': 679,
+ 'rabbit_shop': 686,
+ 'rabbit_overlay': 689,
+ 'banner_easter08': 715,
+ 'summoning_side': 722,
+ 'carpet_info': 723,
+ 'carpet_runesquares': 724,
+ 'carpet_runelink': 725,
+ 'carpet_runeversi': 726,
+ 'carpet_draughts': 727,
+ 'carpet_main': 728,
+ 'carpet_ticket': 729,
+ 'graphics_options': 742,
+ 'sound_options': 743,
+ 'loginscreen': 744,
+ 'statusicons': 745,
+ 'toplevel_fullscreen': 746,
+ 'topstat_lore': 747,
+ 'topstat_hitpoints': 748,
+ 'topstat_prayer': 749,
+ 'topstat_run': 750,
+ 'filterbuttons': 751,
+ 'chattop': 752,
+ 'pmchat': 754,
+ 'worldmap': 755,
+ 'boardgames_options': 756,
+ 'npcchatlarge': 757,
+ 'canoe_travel': 758,
+ 'tutorial2_objbox': 760,
+ 'bank_v2_main': 762,
+ 'bank_v2_side': 763,
+ 'tutorial2_switch_task': 765,
+ 'tutorial2_death': 766,
+ 'bank_v2_help': 767,
+ 'tutorial2_text': 769,
+ 'rcguild_side': 778,
+ 'rcguild_rewards': 779,
+ 'rcguild_map': 780,
+ 'rcguild_overlay': 781,
+ 'crcs_tightrope': 783,
+ 'crcs_side': 784,
+ 'crcs_rewards': 785,
+ 'crcs_equipment': 786,
+ 'crcs_scoreboard': 788,
+ 'clanwars_end': 790,
+ 'clanwars_setup': 791,
+ 'clanwars_setup_side': 792,
+ 'banner_halloween': 800,
+ 'quickchat_locked': 801,
+ 'sc_tutorial_overlay': 802,
+ 'sc_scores_border': 803,
+ 'sc_item_transfer': 805,
+ 'sc_remaining_clay': 806,
+ 'sc_scores': 810,
+ 'sc_reward_shop': 811,
+ 'sc_processing': 813,
+ 'luc2_chapter2': 814,
+ 'luc2_telescope_view': 816,
+ 'luc2_chapter3': 822,
+ 'luc2_chapter1': 826,
+ 'luc2_lucien_projectiles': 827
+ }
+ },
+ synth_sounds: {
+ key: 4,
+ contentType: '.wav'
+ },
+ maps: {
+ key: 5,
+ encryption: [ 'xtea', '^l[0-9]{1,3}_[0-9]{1,3}$' ]
+ },
+ midi_songs: {
+ key: 6,
+ contentType: '.mid'
+ },
+ models: {
+ key: 7,
+ contentType: '.dat'
+ },
+ sprites: {
+ key: 8
+ },
+ textures: {
+ key: 9
+ },
+ binary: {
+ key: 10
+ },
+ midi_jingles: {
+ key: 11,
+ contentType: '.mid'
+ },
+ clientscripts: {
+ key: 12,
+ contentType: '.cs2'
+ },
+ fontmetrics: {
+ key: 13
+ },
+ vorbis: {
+ key: 14
+ },
+ midi_instruments: {
+ key: 15
+ },
+ config_loc: {
+ key: 16
+ },
+ config_enum: {
+ key: 17
+ },
+ config_npc: {
+ key: 18
+ },
+ config_obj: {
+ key: 19
+ },
+ config_seq: {
+ key: 20
+ },
+ config_spot: {
+ key: 21
+ },
+ config_var_bit: {
+ key: 22
+ },
+ worldmapdata: {
+ key: 23
+ },
+ quickchat: {
+ key: 24
+ },
+ quickchat_global: {
+ key: 25
+ },
+ materials: {
+ key: 26
+ },
+ config_particle: {
+ key: 27
+ },
+ defaults: {
+ key: 28
+ },
+ billboards: {
+ key: 29
+ }
+}
diff --git a/config/name-hashes.json b/config/name-hashes.json
index a23a8e4..866426a 100644
--- a/config/name-hashes.json
+++ b/config/name-hashes.json
@@ -169062,5 +169062,185 @@
"-1081813035": "m199_198",
"-2824623370": "l199_198",
"-1081813034": "m199_199",
- "-2824623369": "l199_199"
+ "-2824623369": "l199_199",
+ "6133252": "45.dat",
+ "8297314": "data",
+ "19979093": "46.dat",
+ "33824934": "47.dat",
+ "47670775": "48.dat",
+ "53973365": "combaticons.dat",
+ "61516616": "49.dat",
+ "125902192": "backbase1.dat",
+ "139748033": "backbase2.dat",
+ "150819851": "idk.dat",
+ "204062206": "q8_full.dat",
+ "224847211": "0.dat",
+ "232787039": "sounds.dat",
+ "238693052": "1.dat",
+ "252137566": "model_version",
+ "252538893": "2.dat",
+ "266384734": "3.dat",
+ "280230575": "4.dat",
+ "294076416": "5.dat",
+ "305236077": "prayeroff.dat",
+ "307922257": "6.dat",
+ "321768098": "7.dat",
+ "335613939": "8.dat",
+ "349459780": "9.dat",
+ "383739196": "varp.dat",
+ "392041951": "prayeron.dat",
+ "449541346": "mod_icons.dat",
+ "529843337": "cross.dat",
+ "612871759": "mapdots.dat",
+ "661178691": "magicoff.dat",
+ "661681639": "staticons.dat",
+ "682978269": "loc.dat",
+ "682997061": "loc.idx",
+ "715169772": "anim_index",
+ "839488367": "mapscene.dat",
+ "886159288": "seq.dat",
+ "1018124075": "headicons_hint.dat",
+ "1043559214": "steelborder.dat",
+ "1152574301": "wornicons.dat",
+ "1165431679": "number_button.dat",
+ "1354546316": "backleft1.dat",
+ "1362520410": "mapedge.dat",
+ "1368392157": "backleft2.dat",
+ "1442199444": "rightarrow.dat",
+ "1464846521": "backvmid1.dat",
+ "1478692362": "backvmid2.dat",
+ "1489108188": "npc.dat",
+ "1489126980": "npc.idx",
+ "1492538203": "backvmid3.dat",
+ "1644583778": "mapback.dat",
+ "1648736955": "badenc.txt",
+ "1654911043": "p11_full.dat",
+ "1694123055": "prayerglow.dat",
+ "1694783164": "domainenc.txt",
+ "1698082440": "10.dat",
+ "1711928281": "11.dat",
+ "1725774122": "12.dat",
+ "1727594325": "magicoff2.dat",
+ "1739619963": "13.dat",
+ "1753465804": "14.dat",
+ "1758274153": "staticons2.dat",
+ "1766681864": "chatback.dat",
+ "1767311645": "15.dat",
+ "1781157486": "16.dat",
+ "1795003327": "17.dat",
+ "1808849168": "18.dat",
+ "1822695009": "19.dat",
+ "1889496696": "sideicons.dat",
+ "1915414053": "map_crc",
+ "1922934081": "leftarrow.dat",
+ "1955686745": "titlebutton.dat",
+ "1955804455": "mapmarker.dat",
+ "1986120039": "keys.dat",
+ "1987120305": "map_index",
+ "2025126712": "overlay_multiway.dat",
+ "2038060091": "headicons_pk.dat",
+ "2081559868": "miscgraphics.dat",
+ "-1929337337": "index.dat",
+ "-227242592": "p12_full.dat",
+ "-1124181286": "b12_full.dat",
+ "-566502255": "title.dat",
+ "-1752651416": "logo.dat",
+ "-1891508522": "titlebox.dat",
+ "-1668775416": "runes.dat",
+ "-1569261396": "flo.dat",
+ "-1667617738": "obj.dat",
+ "-1667598946": "obj.idx",
+ "-955170442": "spotanim.dat",
+ "-514869585": "varbit.dat",
+ "-1568083395": "invback.dat",
+ "-1623648789": "backhmid1.dat",
+ "-427405255": "compass.dat",
+ "-1204854137": "mapfunction.dat",
+ "-1502153170": "hitmarks.dat",
+ "-288954319": "headicons.dat",
+ "-1337835461": "headicons_prayer.dat",
+ "-1571073093": "scrollbar.dat",
+ "-1392068576": "redstone1.dat",
+ "-1378222735": "redstone2.dat",
+ "-1364376894": "redstone3.dat",
+ "-1593819477": "backright1.dat",
+ "-1579973636": "backright2.dat",
+ "-1102299012": "backtop1.dat",
+ "-1609802948": "backhmid2.dat",
+ "-1000916878": "tradebacking.dat",
+ "-716997548": "steelborder2.dat",
+ "-1868599050": "combatboxes.dat",
+ "-884827257": "sworddecor.dat",
+ "-952192193": "combaticons2.dat",
+ "-938346352": "combaticons3.dat",
+ "-1809621253": "miscgraphics3.dat",
+ "-869490323": "magicon.dat",
+ "-1448902313": "magicon2.dat",
+ "-1823467094": "miscgraphics2.dat",
+ "-416634290": "chest.dat",
+ "-58065069": "coins.dat",
+ "-351562801": "tex_brown.dat",
+ "-1811229622": "tex_red.dat",
+ "-797498902": "anim_version",
+ "-945480188": "midi_version",
+ "-923525801": "map_version",
+ "-1761598724": "model_crc",
+ "-40228664": "anim_crc",
+ "-1121254206": "midi_crc",
+ "-706585152": "model_index",
+ "-1691482954": "midi_index",
+ "-1752288555": "20.dat",
+ "-1738442714": "21.dat",
+ "-1724596873": "22.dat",
+ "-1710751032": "23.dat",
+ "-1696905191": "24.dat",
+ "-1683059350": "25.dat",
+ "-1669213509": "26.dat",
+ "-1655367668": "27.dat",
+ "-1641521827": "28.dat",
+ "-1627675986": "29.dat",
+ "-907692254": "30.dat",
+ "-893846413": "31.dat",
+ "-880000572": "32.dat",
+ "-866154731": "33.dat",
+ "-852308890": "34.dat",
+ "-838463049": "35.dat",
+ "-824617208": "36.dat",
+ "-810771367": "37.dat",
+ "-796925526": "38.dat",
+ "-783079685": "39.dat",
+ "-63095953": "40.dat",
+ "-49250112": "41.dat",
+ "-35404271": "42.dat",
+ "-21558430": "43.dat",
+ "-7712589": "44.dat",
+ "-573349193": "fragmentsenc.txt",
+ "-840867198": "tldlist.txt",
+ "150838643": "idk.idx",
+ "383757988": "varp.idx",
+ "886178080": "seq.idx",
+ "-955151650": "spotanim.idx",
+ "-514850793": "varbit.idx",
+ "-1569242604": "flo.idx",
+ "182685561": "mesanim.dat",
+ "182704353": "mesanim.idx",
+ "1029250116": "mes.dat",
+ "1029268908": "mes.idx",
+ "-1818025236": "param.dat",
+ "-1818006444": "param.idx",
+ "22834782": "gnomeball_buttons.dat",
+ "450862262": "overlay_duel.dat",
+ "523617556": "rightarrow_small.dat",
+ "819035239": "letter.dat",
+ "902321338": "pen.dat",
+ "1150791544": "key.dat",
+ "1451391714": "button_brown.dat",
+ "2004158547": "startgame.dat",
+ "-1004178375": "leftarrow_small.dat",
+ "-1857300557": "blackmark.dat",
+ "-888498683": "button_red.dat",
+ "-384541308": "titlescroll.dat",
+ "-90207845": "button_brown_big.dat",
+ "216316762": "hunt.dat",
+ "216335554": "hunt.idx"
}
diff --git a/packed/.gitkeep b/js5/.gitkeep
similarity index 100%
rename from packed/.gitkeep
rename to js5/.gitkeep
diff --git a/package-lock.json b/package-lock.json
index 8202072..2953e16 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,25 +1,34 @@
{
- "name": "@runejs/store",
- "version": "1.0.0-beta.1",
+ "name": "@runejs/filestore",
+ "version": "1.0.0-next.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
- "name": "@runejs/store",
- "version": "1.0.0-beta.1",
+ "name": "@runejs/filestore",
+ "version": "1.0.0-next.0",
"license": "GPL-3.0",
"dependencies": {
- "@runejs/common": "2.0.2-beta.2",
- "graceful-fs": "^4.2.0",
+ "@decorators/di": "^1.0.3",
+ "@decorators/express": "^2.6.0",
+ "@runejs/common": "3.0.0-beta.10",
+ "adm-zip": "^0.5.9",
+ "axios": "^0.27.2",
+ "compressjs": "^1.0.3",
+ "express": "^4.18.1",
+ "graceful-fs": ">=4.2.0",
"json5": "^2.2.0",
"reflect-metadata": "^0.1.13",
"sqlite": "^4.0.25",
- "tslib": "^2.3.1",
+ "tslib": ">=2.4.0",
"typeorm": "^0.2.44",
- "yargs": "^17.3.1"
+ "yargs": "^17.3.1",
+ "zlib": "^1.0.5"
},
"devDependencies": {
"@runejs/eslint-config": "^1.1.0",
+ "@types/adm-zip": "^0.5.0",
+ "@types/express": "^4.17.13",
"@types/graceful-fs": "^4.1.5",
"@types/node": "^16.11.26",
"@types/yargs": "^17.0.9",
@@ -30,93 +39,77 @@
"eslint": "^8.11.0",
"rimraf": "^3.0.2",
"source-map-support": "^0.5.21",
- "ts-node-dev": "^1.1.8",
- "typescript": "^4.5.5"
+ "ts-node-dev": "^2.0.0",
+ "typescript": "^4.7.4"
+ }
+ },
+ "node_modules/@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "0.3.9"
},
- "peerDependencies": {
- "@runejs/common": "2.0.2-beta.2",
- "graceful-fs": ">=4.2.0",
- "tslib": ">=2.3.0",
- "typescript": ">=4.5.0"
+ "engines": {
+ "node": ">=12"
}
},
- "../common/lib": {
- "name": "@runejs/common",
- "version": "2.0.2-beta.2",
- "extraneous": true,
- "license": "GPL-3.0",
+ "node_modules/@decorators/di": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@decorators/di/-/di-1.0.3.tgz",
+ "integrity": "sha512-wafyQo5lqGABT+Lh7Od9/qULg7DG/kZFU3mLUKZFuiV/KATYlnv198yQxaZUZerhUDoTl/cZKu9t4mJa0rZK4Q==",
"dependencies": {
- "compressjs": "^1.0.3",
- "js-yaml": "^3.14.1",
- "pino": "^6.14.0",
- "pino-pretty": "^4.8.0",
- "sonic-boom": "^2.6.0",
- "tslib": "^2.3.1"
+ "reflect-metadata": "0.1.13"
},
- "devDependencies": {
- "@runejs/eslint-config": "^1.0.0",
- "@types/node": "^16.11.26",
- "@types/pino": "^6.3.12",
- "@typescript-eslint/eslint-plugin": "^4.33.0",
- "@typescript-eslint/parser": "^4.33.0",
- "copyfiles": "^2.4.1",
- "eslint": "^7.32.0",
- "rimraf": "^3.0.2",
- "ts-node-dev": "^1.1.8",
- "typescript": "^4.5.5"
+ "engines": {
+ "node": ">=7.1.0"
+ }
+ },
+ "node_modules/@decorators/express": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@decorators/express/-/express-2.6.0.tgz",
+ "integrity": "sha512-th/LqSAHAAW1ob2CU6hxtsfnryGThmz0AmGP45rA3Yoi0Q7+FHAZVfH7NJSYHITai/uXjjOtZPPW/V0gFfbgUw==",
+ "engines": {
+ "node": ">=7.1.0"
},
"peerDependencies": {
- "tslib": ">=2.3.0",
- "typescript": ">=4.5.0"
+ "@decorators/di": ">=1.0.2",
+ "express": ">=4.16.3"
}
},
"node_modules/@eslint/eslintrc": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz",
- "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz",
+ "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==",
"dev": true,
"dependencies": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
- "espree": "^9.3.1",
- "globals": "^13.9.0",
+ "espree": "^9.4.0",
+ "globals": "^13.15.0",
"ignore": "^5.2.0",
"import-fresh": "^3.2.1",
"js-yaml": "^4.1.0",
- "minimatch": "^3.0.4",
+ "minimatch": "^3.1.2",
"strip-json-comments": "^3.1.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
- },
- "node_modules/@eslint/eslintrc/node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
- "dependencies": {
- "argparse": "^2.0.1"
},
- "bin": {
- "js-yaml": "bin/js-yaml.js"
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/@hapi/bourne": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz",
- "integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg=="
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.1.0.tgz",
+ "integrity": "sha512-i1BpaNDVLJdRBEKeJWkVO6tYX6DMFBuwMhSuWqLsY4ufeTKGVuV5rBsUhxPayXqnnWHgXUAmWK16H/ykO5Wj4Q=="
},
"node_modules/@humanwhocodes/config-array": {
- "version": "0.9.5",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
- "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz",
+ "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==",
"dev": true,
"dependencies": {
"@humanwhocodes/object-schema": "^1.2.1",
@@ -127,12 +120,68 @@
"node": ">=10.10.0"
}
},
+ "node_modules/@humanwhocodes/gitignore-to-minimatch": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz",
+ "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==",
+ "dev": true,
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
"node_modules/@humanwhocodes/object-schema": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "node_modules/@ledgerhq/compressjs": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/compressjs/-/compressjs-1.3.2.tgz",
+ "integrity": "sha512-gonFwAifRkSYDO7rt3NIBlvjvY8Nw+NM6LT1SuOBppuvoKbYtBViNh3EBPbP86+3Y4ux7DLUsNiUlqOgubJsdA==",
+ "dependencies": {
+ "commander": "^2.20.0"
+ }
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -169,20 +218,20 @@
}
},
"node_modules/@runejs/common": {
- "version": "2.0.2-beta.2",
- "resolved": "https://registry.npmjs.org/@runejs/common/-/common-2.0.2-beta.2.tgz",
- "integrity": "sha512-Xd9/Ws3ByAdI1R08Ye9fWqlS8SImjQw05Bsw0w46zcGyDx8N6jmeClf9Y/s4Akh9VZQuoAMFg2ANKsRK0MucNw==",
+ "version": "3.0.0-beta.10",
+ "resolved": "https://registry.npmjs.org/@runejs/common/-/common-3.0.0-beta.10.tgz",
+ "integrity": "sha512-4EnjDBlAfv26oHkSg6q6xAU7gfQj4QKKDUh/e0NJZ3DkwrQuimlNHEfprn7/Wl6wa4mzqJZl05MT2XRfGFhttQ==",
"dependencies": {
- "compressjs": "^1.0.3",
- "js-yaml": "^3.14.1",
+ "@ledgerhq/compressjs": "^1.3.2",
+ "buffer": "^6.0.3",
+ "dotenv": "^16.0.0",
+ "path": "^0.12.7",
"pino": "^6.14.0",
- "pino-pretty": "^4.8.0",
- "sonic-boom": "^2.6.0",
- "tslib": "^2.3.1"
+ "pino-pretty": "^6.0.0",
+ "zlib": "^1.0.5"
},
"peerDependencies": {
- "tslib": ">=2.3.0",
- "typescript": ">=4.5.0"
+ "tslib": ">=2.4.0"
}
},
"node_modules/@runejs/eslint-config": {
@@ -201,6 +250,81 @@
"resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.3.tgz",
"integrity": "sha512-O3uyB/JbkAEMZaP3YqyHH7TMnex7tWyCbCI4EfJdOCoN6HIhqdJBWTM6aCCiWQ/5f5wxjgU735QAIpJbjDvmzg=="
},
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
+ "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
+ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
+ "dev": true
+ },
+ "node_modules/@types/adm-zip": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.5.0.tgz",
+ "integrity": "sha512-FCJBJq9ODsQZUNURo5ILAQueuA8WJhRvuihS3ke2iI25mJlfV2LK8jG2Qj2z2AWg8U0FtWWqBHVRetceLskSaw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/body-parser": {
+ "version": "1.19.2",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
+ "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
+ "dev": true,
+ "dependencies": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.35",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
+ "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/express": {
+ "version": "4.17.13",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz",
+ "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==",
+ "dev": true,
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^4.17.18",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "node_modules/@types/express-serve-static-core": {
+ "version": "4.17.30",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz",
+ "integrity": "sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*"
+ }
+ },
"node_modules/@types/graceful-fs": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
@@ -211,21 +335,49 @@
}
},
"node_modules/@types/json-schema": {
- "version": "7.0.9",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
- "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+ "dev": true
+ },
+ "node_modules/@types/mime": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
+ "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==",
"dev": true
},
"node_modules/@types/node": {
- "version": "16.11.26",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.26.tgz",
- "integrity": "sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ==",
+ "version": "16.11.56",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.56.tgz",
+ "integrity": "sha512-aFcUkv7EddxxOa/9f74DINReQ/celqH8DiB3fRYgVDM2Xm5QJL8sl80QKuAnGvwAsMn+H3IFA6WCrQh1CY7m1A==",
+ "dev": true
+ },
+ "node_modules/@types/qs": {
+ "version": "6.9.7",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
+ "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
+ "dev": true
+ },
+ "node_modules/@types/range-parser": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
+ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
"dev": true
},
+ "node_modules/@types/serve-static": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz",
+ "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==",
+ "dev": true,
+ "dependencies": {
+ "@types/mime": "*",
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=",
+ "integrity": "sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==",
"dev": true
},
"node_modules/@types/strip-json-comments": {
@@ -235,18 +387,18 @@
"dev": true
},
"node_modules/@types/yargs": {
- "version": "17.0.9",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.9.tgz",
- "integrity": "sha512-Ci8+4/DOtkHRylcisKmVMtmVO5g7weUVCKcsu1sJvF1bn0wExTmbHmhFKj7AnEm0de800iovGhdSKzYnzbaHpg==",
+ "version": "17.0.12",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz",
+ "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==",
"dev": true,
"dependencies": {
"@types/yargs-parser": "*"
}
},
"node_modules/@types/yargs-parser": {
- "version": "20.2.1",
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz",
- "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==",
+ "version": "21.0.0",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
"dev": true
},
"node_modules/@types/zen-observable": {
@@ -255,19 +407,19 @@
"integrity": "sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw=="
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.14.0.tgz",
- "integrity": "sha512-ir0wYI4FfFUDfLcuwKzIH7sMVA+db7WYen47iRSaCGl+HMAZI9fpBwfDo45ZALD3A45ZGyHWDNLhbg8tZrMX4w==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.1.tgz",
+ "integrity": "sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "5.14.0",
- "@typescript-eslint/type-utils": "5.14.0",
- "@typescript-eslint/utils": "5.14.0",
- "debug": "^4.3.2",
+ "@typescript-eslint/scope-manager": "5.36.1",
+ "@typescript-eslint/type-utils": "5.36.1",
+ "@typescript-eslint/utils": "5.36.1",
+ "debug": "^4.3.4",
"functional-red-black-tree": "^1.0.1",
- "ignore": "^5.1.8",
+ "ignore": "^5.2.0",
"regexpp": "^3.2.0",
- "semver": "^7.3.5",
+ "semver": "^7.3.7",
"tsutils": "^3.21.0"
},
"engines": {
@@ -288,15 +440,15 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.14.0.tgz",
- "integrity": "sha512-aHJN8/FuIy1Zvqk4U/gcO/fxeMKyoSv/rS46UXMXOJKVsLQ+iYPuXNbpbH7cBLcpSbmyyFbwrniLx5+kutu1pw==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz",
+ "integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "5.14.0",
- "@typescript-eslint/types": "5.14.0",
- "@typescript-eslint/typescript-estree": "5.14.0",
- "debug": "^4.3.2"
+ "@typescript-eslint/scope-manager": "5.36.1",
+ "@typescript-eslint/types": "5.36.1",
+ "@typescript-eslint/typescript-estree": "5.36.1",
+ "debug": "^4.3.4"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -315,13 +467,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.14.0.tgz",
- "integrity": "sha512-LazdcMlGnv+xUc5R4qIlqH0OWARyl2kaP8pVCS39qSL3Pd1F7mI10DbdXeARcE62sVQE4fHNvEqMWsypWO+yEw==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz",
+ "integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.14.0",
- "@typescript-eslint/visitor-keys": "5.14.0"
+ "@typescript-eslint/types": "5.36.1",
+ "@typescript-eslint/visitor-keys": "5.36.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -332,13 +484,14 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.14.0.tgz",
- "integrity": "sha512-d4PTJxsqaUpv8iERTDSQBKUCV7Q5yyXjqXUl3XF7Sd9ogNLuKLkxz82qxokqQ4jXdTPZudWpmNtr/JjbbvUixw==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.1.tgz",
+ "integrity": "sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==",
"dev": true,
"dependencies": {
- "@typescript-eslint/utils": "5.14.0",
- "debug": "^4.3.2",
+ "@typescript-eslint/typescript-estree": "5.36.1",
+ "@typescript-eslint/utils": "5.36.1",
+ "debug": "^4.3.4",
"tsutils": "^3.21.0"
},
"engines": {
@@ -358,9 +511,9 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.14.0.tgz",
- "integrity": "sha512-BR6Y9eE9360LNnW3eEUqAg6HxS9Q35kSIs4rp4vNHRdfg0s+/PgHgskvu5DFTM7G5VKAVjuyaN476LCPrdA7Mw==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz",
+ "integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -371,17 +524,17 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.14.0.tgz",
- "integrity": "sha512-QGnxvROrCVtLQ1724GLTHBTR0lZVu13izOp9njRvMkCBgWX26PKvmMP8k82nmXBRD3DQcFFq2oj3cKDwr0FaUA==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz",
+ "integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.14.0",
- "@typescript-eslint/visitor-keys": "5.14.0",
- "debug": "^4.3.2",
- "globby": "^11.0.4",
+ "@typescript-eslint/types": "5.36.1",
+ "@typescript-eslint/visitor-keys": "5.36.1",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
"is-glob": "^4.0.3",
- "semver": "^7.3.5",
+ "semver": "^7.3.7",
"tsutils": "^3.21.0"
},
"engines": {
@@ -398,15 +551,15 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.14.0.tgz",
- "integrity": "sha512-EHwlII5mvUA0UsKYnVzySb/5EE/t03duUTweVy8Zqt3UQXBrpEVY144OTceFKaOe4xQXZJrkptCf7PjEBeGK4w==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.1.tgz",
+ "integrity": "sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
- "@typescript-eslint/scope-manager": "5.14.0",
- "@typescript-eslint/types": "5.14.0",
- "@typescript-eslint/typescript-estree": "5.14.0",
+ "@typescript-eslint/scope-manager": "5.36.1",
+ "@typescript-eslint/types": "5.36.1",
+ "@typescript-eslint/typescript-estree": "5.36.1",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
},
@@ -422,13 +575,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.14.0.tgz",
- "integrity": "sha512-yL0XxfzR94UEkjBqyymMLgCBdojzEuy/eim7N9/RIcTNxpJudAcqsU8eRyfzBbcEzGoPWfdM3AGak3cN08WOIw==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz",
+ "integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.14.0",
- "eslint-visitor-keys": "^3.0.0"
+ "@typescript-eslint/types": "5.36.1",
+ "eslint-visitor-keys": "^3.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -438,10 +591,22 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/acorn": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
- "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+ "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -459,6 +624,23 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
+ "node_modules/acorn-walk": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
+ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/adm-zip": {
+ "version": "0.5.9",
+ "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz",
+ "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==",
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -478,35 +660,37 @@
"node_modules/amdefine": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
- "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+ "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==",
"engines": {
"node": ">=0.4.2"
}
},
"node_modules/ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
- "devOptional": true,
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
"node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": {
- "color-convert": "^1.9.0"
+ "color-convert": "^2.0.1"
},
"engines": {
- "node": ">=4"
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="
},
"node_modules/anymatch": {
"version": "3.1.2",
@@ -522,29 +706,13 @@
}
},
"node_modules/app-root-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz",
- "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz",
+ "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==",
"engines": {
"node": ">= 6.0.0"
}
},
- "node_modules/aproba": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
- "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
- "devOptional": true
- },
- "node_modules/are-we-there-yet": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
- "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
- "devOptional": true,
- "dependencies": {
- "delegates": "^1.0.0",
- "readable-stream": "^2.0.6"
- }
- },
"node_modules/arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
@@ -552,17 +720,14 @@
"dev": true
},
"node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/args": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/args/-/args-5.0.1.tgz",
- "integrity": "sha512-1kqmFCFsPffavQFGt8OxJdIcETti99kySRUPMpOhaGjL6mRJn8HFU1OxKY5bMqfZKUwTQc1mZkAjmGYaVOHFtQ==",
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/args/-/args-5.0.3.tgz",
+ "integrity": "sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==",
"dependencies": {
"camelcase": "5.0.0",
"chalk": "2.4.2",
@@ -573,6 +738,17 @@
"node": ">= 6.0.0"
}
},
+ "node_modules/args/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/args/node_modules/chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -586,6 +762,51 @@
"node": ">=4"
}
},
+ "node_modules/args/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/args/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+ },
+ "node_modules/args/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/args/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/args/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+ },
"node_modules/array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -595,6 +816,11 @@
"node": ">=8"
}
},
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ },
"node_modules/atomic-sleep": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
@@ -603,10 +829,19 @@
"node": ">=8.0.0"
}
},
+ "node_modules/axios": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
+ "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
+ "dependencies": {
+ "follow-redirects": "^1.14.9",
+ "form-data": "^4.0.0"
+ }
+ },
"node_modules/balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/base64-js": {
"version": "1.5.1",
@@ -628,14 +863,14 @@
]
},
"node_modules/better-sqlite3": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-7.5.0.tgz",
- "integrity": "sha512-6FdG9DoytYGDhLW7VWW1vxjEz7xHkqK6LnaUQYA8d6GHNgZhu9PFX2xwKEEnSBRoT1J4PjTUPeg217ShxNmuPg==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-7.6.2.tgz",
+ "integrity": "sha512-S5zIU1Hink2AH4xPsN0W43T1/AJ5jrPh7Oy07ocuW/AKYYY02GWzz9NH0nbSMn/gw6fDZ5jZ1QsHt1BXAwJ6Lg==",
"devOptional": true,
"hasInstallScript": true,
"dependencies": {
"bindings": "^1.5.0",
- "prebuild-install": "^7.0.0"
+ "prebuild-install": "^7.1.0"
}
},
"node_modules/binary-extensions": {
@@ -667,6 +902,30 @@
"readable-stream": "^3.4.0"
}
},
+ "node_modules/bl/node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "devOptional": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
"node_modules/bl/node_modules/readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
@@ -681,13 +940,58 @@
"node": ">= 6"
}
},
- "node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "node_modules/bl/node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "devOptional": true,
"dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
+ "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.10.3",
+ "raw-body": "2.5.1",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/body-parser/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/body-parser/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
}
},
"node_modules/braces": {
@@ -703,10 +1007,9 @@
}
},
"node_modules/buffer": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
- "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
- "devOptional": true,
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
@@ -723,7 +1026,7 @@
],
"dependencies": {
"base64-js": "^1.3.1",
- "ieee754": "^1.1.13"
+ "ieee754": "^1.2.1"
}
},
"node_modules/buffer-from": {
@@ -732,6 +1035,26 @@
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true
},
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -750,9 +1073,9 @@
}
},
"node_modules/chalk": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
- "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -764,55 +1087,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/chalk/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/chalk/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/chalk/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
- "node_modules/chalk/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/chalk/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@@ -840,6 +1114,18 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/chownr": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
@@ -866,46 +1152,6 @@
"npm": ">=5.0.0"
}
},
- "node_modules/cli-highlight/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cli-highlight/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cli-highlight/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cli-highlight/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/cli-highlight/node_modules/yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
@@ -941,72 +1187,59 @@
"wrap-ansi": "^7.0.0"
}
},
- "node_modules/cliui/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cliui/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cliui/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
+ "color-name": "~1.1.4"
},
"engines": {
- "node": ">=8"
+ "node": ">=7.0.0"
}
},
- "node_modules/cliui/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/colorette": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz",
+ "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g=="
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
- "ansi-regex": "^5.0.1"
+ "delayed-stream": "~1.0.0"
},
"engines": {
- "node": ">=8"
+ "node": ">= 0.8"
}
},
- "node_modules/code-point-at": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
- "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
- "devOptional": true,
- "engines": {
- "node": ">=0.10.0"
- }
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
},
- "node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "node_modules/compressjs": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/compressjs/-/compressjs-1.0.3.tgz",
+ "integrity": "sha512-jpKJjBTretQACTGLNuvnozP1JdP2ZLrjdGdBgk/tz1VfXlUcBhhSZW6vEsuThmeot/yjvSrPQKEgfF3X2Lpi8Q==",
"dependencies": {
- "color-name": "1.1.3"
+ "amdefine": "~1.0.0",
+ "commander": "~2.8.1"
+ },
+ "bin": {
+ "compressjs": "bin/compressjs"
}
},
- "node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
- },
- "node_modules/commander": {
+ "node_modules/compressjs/node_modules/commander": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
- "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
+ "integrity": "sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==",
"dependencies": {
"graceful-readlink": ">= 1.0.0"
},
@@ -1014,28 +1247,42 @@
"node": ">= 0.6.x"
}
},
- "node_modules/compressjs": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/compressjs/-/compressjs-1.0.3.tgz",
- "integrity": "sha1-ldt03VuQOM+AvKMhqw7eJxtJWbY=",
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
"dependencies": {
- "amdefine": "~1.0.0",
- "commander": "~2.8.1"
+ "safe-buffer": "5.2.1"
},
- "bin": {
- "compressjs": "bin/compressjs"
+ "engines": {
+ "node": ">= 0.6"
}
},
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ "node_modules/content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "engines": {
+ "node": ">= 0.6"
+ }
},
- "node_modules/console-control-strings": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
- "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
- "devOptional": true
+ "node_modules/cookie": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
},
"node_modules/copyfiles": {
"version": "2.4.1",
@@ -1056,50 +1303,6 @@
"copyup": "copyfiles"
}
},
- "node_modules/copyfiles/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/copyfiles/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/copyfiles/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/copyfiles/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/copyfiles/node_modules/yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
@@ -1128,10 +1331,10 @@
}
},
"node_modules/core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
- "devOptional": true
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true
},
"node_modules/create-require": {
"version": "1.1.1",
@@ -1162,9 +1365,9 @@
}
},
"node_modules/debug": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
- "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
@@ -1207,11 +1410,39 @@
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true
},
- "node_modules/delegates": {
+ "node_modules/delayed-stream": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
- "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
- "devOptional": true
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
+ "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
+ "devOptional": true,
+ "engines": {
+ "node": ">=8"
+ }
},
"node_modules/diff": {
"version": "4.0.2",
@@ -1247,27 +1478,40 @@
}
},
"node_modules/dotenv": {
- "version": "8.6.0",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz",
- "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==",
+ "version": "16.0.2",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.2.tgz",
+ "integrity": "sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==",
"engines": {
- "node": ">=10"
+ "node": ">=12"
}
},
"node_modules/dynamic-dedupe": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz",
- "integrity": "sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE=",
+ "integrity": "sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==",
"dev": true,
"dependencies": {
"xtend": "^4.0.0"
}
},
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+ },
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
+ "node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -1284,22 +1528,33 @@
"node": ">=6"
}
},
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+ },
"node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
"engines": {
- "node": ">=0.8.0"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint": {
- "version": "8.11.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz",
- "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==",
+ "version": "8.23.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz",
+ "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==",
"dev": true,
"dependencies": {
- "@eslint/eslintrc": "^1.2.1",
- "@humanwhocodes/config-array": "^0.9.2",
+ "@eslint/eslintrc": "^1.3.1",
+ "@humanwhocodes/config-array": "^0.10.4",
+ "@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
+ "@humanwhocodes/module-importer": "^1.0.1",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@@ -1309,14 +1564,17 @@
"eslint-scope": "^7.1.1",
"eslint-utils": "^3.0.0",
"eslint-visitor-keys": "^3.3.0",
- "espree": "^9.3.1",
+ "espree": "^9.4.0",
"esquery": "^1.4.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
"file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
"functional-red-black-tree": "^1.0.1",
"glob-parent": "^6.0.1",
- "globals": "^13.6.0",
+ "globals": "^13.15.0",
+ "globby": "^11.1.0",
+ "grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
@@ -1325,14 +1583,13 @@
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
"lodash.merge": "^4.6.2",
- "minimatch": "^3.0.4",
+ "minimatch": "^3.1.2",
"natural-compare": "^1.4.0",
"optionator": "^0.9.1",
"regexpp": "^3.2.0",
"strip-ansi": "^6.0.1",
"strip-json-comments": "^3.1.0",
- "text-table": "^0.2.0",
- "v8-compile-cache": "^2.0.3"
+ "text-table": "^0.2.0"
},
"bin": {
"eslint": "bin/eslint.js"
@@ -1393,33 +1650,6 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
- "node_modules/eslint/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/eslint/node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
- },
- "node_modules/eslint/node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/eslint/node_modules/eslint-scope": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
@@ -1442,66 +1672,21 @@
"node": ">=4.0"
}
},
- "node_modules/eslint/node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/eslint/node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/eslint/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/espree": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz",
- "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==",
+ "version": "9.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz",
+ "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==",
"dev": true,
"dependencies": {
- "acorn": "^8.7.0",
- "acorn-jsx": "^5.3.1",
+ "acorn": "^8.8.0",
+ "acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
- "node_modules/esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "bin": {
- "esparse": "bin/esparse.js",
- "esvalidate": "bin/esvalidate.js"
},
- "engines": {
- "node": ">=4"
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/esquery": {
@@ -1564,6 +1749,14 @@
"node": ">=0.10.0"
}
},
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
@@ -1573,6 +1766,60 @@
"node": ">=6"
}
},
+ "node_modules/express": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
+ "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.0",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.5.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.2.0",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.10.3",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.18.0",
+ "serve-static": "1.15.0",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/express/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/express/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -1595,6 +1842,18 @@
"node": ">=8.6.0"
}
},
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -1604,13 +1863,13 @@
"node_modules/fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true
},
"node_modules/fast-redact": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.1.tgz",
- "integrity": "sha512-odVmjC8x8jNeMZ3C+rPMESzXVSEU8tSWSHv9HFxP2mm89G/1WwqhrerJDQm9Zus8X6aoRgQDThKqptdNA6bt+A==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.2.tgz",
+ "integrity": "sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==",
"engines": {
"node": ">=6"
}
@@ -1659,6 +1918,52 @@
"node": ">=8"
}
},
+ "node_modules/finalhandler": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
+ "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/finalhandler/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/finalhandler/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/flat-cache": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
@@ -1678,11 +1983,59 @@
"integrity": "sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw=="
},
"node_modules/flatted": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz",
- "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==",
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
+ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
"dev": true
},
+ "node_modules/follow-redirects": {
+ "version": "1.15.1",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
+ "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
@@ -1692,7 +2045,7 @@
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"node_modules/fsevents": {
"version": "2.3.2",
@@ -1711,31 +2064,14 @@
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
- "dev": true
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"node_modules/functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
- "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
"dev": true
},
- "node_modules/gauge": {
- "version": "2.7.4",
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
- "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
- "devOptional": true,
- "dependencies": {
- "aproba": "^1.0.3",
- "console-control-strings": "^1.0.0",
- "has-unicode": "^2.0.0",
- "object-assign": "^4.1.0",
- "signal-exit": "^3.0.0",
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wide-align": "^1.1.0"
- }
- },
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -1744,21 +2080,34 @@
"node": "6.* || 8.* || >= 10.*"
}
},
+ "node_modules/get-intrinsic": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+ "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
- "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
+ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
"devOptional": true
},
"node_modules/glob": {
- "version": "7.1.6",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
- "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
- "minimatch": "^3.0.4",
+ "minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
@@ -1770,21 +2119,21 @@
}
},
"node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
"dependencies": {
- "is-glob": "^4.0.1"
+ "is-glob": "^4.0.3"
},
"engines": {
- "node": ">= 6"
+ "node": ">=10.13.0"
}
},
"node_modules/globals": {
- "version": "13.12.1",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz",
- "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==",
+ "version": "13.17.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
+ "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
"dev": true,
"dependencies": {
"type-fest": "^0.20.2"
@@ -1817,20 +2166,25 @@
}
},
"node_modules/graceful-fs": {
- "version": "4.2.9",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
- "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ=="
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
},
"node_modules/graceful-readlink": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
- "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
+ "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w=="
+ },
+ "node_modules/grapheme-splitter": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+ "dev": true
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "dev": true,
"dependencies": {
"function-bind": "^1.1.1"
},
@@ -1839,18 +2193,23 @@
}
},
"node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"engines": {
- "node": ">=4"
+ "node": ">=8"
}
},
- "node_modules/has-unicode": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
- "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
- "devOptional": true
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
"node_modules/highlight.js": {
"version": "10.7.3",
@@ -1860,6 +2219,32 @@
"node": "*"
}
},
+ "node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -1907,7 +2292,7 @@
"node_modules/imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
"dev": true,
"engines": {
"node": ">=0.8.19"
@@ -1916,7 +2301,7 @@
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@@ -1933,6 +2318,14 @@
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"devOptional": true
},
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -1946,9 +2339,9 @@
}
},
"node_modules/is-core-module": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
- "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
+ "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
"dev": true,
"dependencies": {
"has": "^1.0.3"
@@ -1960,22 +2353,18 @@
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
- "devOptional": true,
- "dependencies": {
- "number-is-nan": "^1.0.0"
- },
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
"node_modules/is-glob": {
@@ -1999,41 +2388,40 @@
"node": ">=0.12.0"
}
},
- "node_modules/isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "devOptional": true
+ "node_modules/isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
+ "dev": true
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
},
"node_modules/jmespath": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
- "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=",
+ "integrity": "sha512-+kHj8HXArPfpPEKGLZ+kB5ONRTCiGQXo8RQYL0hH8t6pWXUBBK5KkkQmTNOwKK4LEsd0yTsgtjJVm4UBSZea4w==",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/joycon": {
- "version": "2.2.5",
- "resolved": "https://registry.npmjs.org/joycon/-/joycon-2.2.5.tgz",
- "integrity": "sha512-YqvUxoOcVPnCp0VU1/56f+iKSdvIRJYPznH22BdXV3xMk75SFXhWeJkZ8C9XxUWt1b5x2X1SxuFygW1U0FmkEQ==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
+ "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
"engines": {
- "node": ">=6"
+ "node": ">=10"
}
},
"node_modules/js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
+ "argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
@@ -2048,16 +2436,13 @@
"node_modules/json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
- "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true
},
"node_modules/json5": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
- "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
- "dependencies": {
- "minimist": "^1.2.5"
- },
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
+ "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"bin": {
"json5": "lib/cli.js"
},
@@ -2068,7 +2453,7 @@
"node_modules/leven": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
- "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=",
+ "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==",
"engines": {
"node": ">=0.10.0"
}
@@ -2086,6 +2471,21 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -2110,6 +2510,19 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true
},
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
+ },
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -2119,19 +2532,57 @@
"node": ">= 8"
}
},
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/micromatch": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
- "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
"dev": true,
"dependencies": {
- "braces": "^3.0.1",
- "picomatch": "^2.2.3"
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
},
"engines": {
"node": ">=8.6"
}
},
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/mimic-response": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
@@ -2145,9 +2596,9 @@
}
},
"node_modules/minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -2156,9 +2607,10 @@
}
},
"node_modules/minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
+ "devOptional": true
},
"node_modules/mkdirp": {
"version": "1.0.4",
@@ -2209,13 +2661,21 @@
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/node-abi": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.8.0.tgz",
- "integrity": "sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw==",
+ "version": "3.24.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.24.0.tgz",
+ "integrity": "sha512-YPG3Co0luSu6GwOBsmIdGW6Wx0NyNDLg/hriIyDllVsNwnI6UeqaWShxC3lbH4LtEQUgoLP3XR1ndXiDAWvmRw==",
"devOptional": true,
"dependencies": {
"semver": "^7.3.5"
@@ -2227,37 +2687,13 @@
"node_modules/noms": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz",
- "integrity": "sha1-2o69nzr51nYJGbJ9nNyAkqczKFk=",
+ "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==",
"dev": true,
"dependencies": {
"inherits": "^2.0.1",
"readable-stream": "~1.0.31"
}
},
- "node_modules/noms/node_modules/isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
- "dev": true
- },
- "node_modules/noms/node_modules/readable-stream": {
- "version": "1.0.34",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
- "dev": true,
- "dependencies": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "0.0.1",
- "string_decoder": "~0.10.x"
- }
- },
- "node_modules/noms/node_modules/string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
- "dev": true
- },
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -2267,39 +2703,37 @@
"node": ">=0.10.0"
}
},
- "node_modules/npmlog": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
- "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
- "devOptional": true,
- "dependencies": {
- "are-we-there-yet": "~1.1.2",
- "console-control-strings": "~1.1.0",
- "gauge": "~2.7.3",
- "set-blocking": "~2.0.0"
- }
- },
- "node_modules/number-is-nan": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
- "devOptional": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"engines": {
"node": ">=0.10.0"
}
},
+ "node_modules/object-inspect": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+ "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dependencies": {
"wrappy": "1"
}
@@ -2321,6 +2755,36 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -2351,10 +2815,36 @@
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
},
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path": {
+ "version": "0.12.7",
+ "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
+ "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==",
+ "dependencies": {
+ "process": "^0.11.1",
+ "util": "^0.10.3"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"engines": {
"node": ">=0.10.0"
}
@@ -2374,6 +2864,11 @@
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
+ "node_modules/path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
+ },
"node_modules/path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
@@ -2413,17 +2908,17 @@
}
},
"node_modules/pino-pretty": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-4.8.0.tgz",
- "integrity": "sha512-mhQfHG4rw5ZFpWL44m0Utjo4GC2+HMfdNvxyA8lLw0sIqn6fCf7uQe6dPckUcW/obly+OQHD7B/MTso6LNizYw==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-6.0.0.tgz",
+ "integrity": "sha512-jyeR2fXXWc68st1DTTM5NhkHlx8p+1fKZMfm84Jwq+jSw08IwAjNaZBZR6ts69hhPOfOjg/NiE1HYW7vBRPL3A==",
"dependencies": {
"@hapi/bourne": "^2.0.0",
"args": "^5.0.1",
- "chalk": "^4.0.0",
+ "colorette": "^1.3.0",
"dateformat": "^4.5.1",
"fast-safe-stringify": "^2.0.7",
"jmespath": "^0.15.0",
- "joycon": "^2.2.5",
+ "joycon": "^3.0.0",
"pump": "^3.0.0",
"readable-stream": "^3.6.0",
"rfdc": "^1.3.0",
@@ -2447,24 +2942,23 @@
"node": ">= 6"
}
},
+ "node_modules/pino-pretty/node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
"node_modules/pino-std-serializers": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz",
"integrity": "sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg=="
},
- "node_modules/pino/node_modules/sonic-boom": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz",
- "integrity": "sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==",
- "dependencies": {
- "atomic-sleep": "^1.0.0",
- "flatstr": "^1.0.12"
- }
- },
"node_modules/prebuild-install": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.0.1.tgz",
- "integrity": "sha512-QBSab31WqkyxpnMWQxubYAHR5S9B2+r81ucocew34Fkl98FhvKIF50jIJnNOBmAZfyNV7vE5T6gd3hTVWgY6tg==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
+ "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
"devOptional": true,
"dependencies": {
"detect-libc": "^2.0.0",
@@ -2474,7 +2968,6 @@
"mkdirp-classic": "^0.5.3",
"napi-build-utils": "^1.0.1",
"node-abi": "^3.3.0",
- "npmlog": "^4.0.1",
"pump": "^3.0.0",
"rc": "^1.2.7",
"simple-get": "^4.0.0",
@@ -2488,15 +2981,6 @@
"node": ">=10"
}
},
- "node_modules/prebuild-install/node_modules/detect-libc": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
- "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
- "devOptional": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -2506,17 +2990,37 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
- "devOptional": true
+ "dev": true
},
"node_modules/process-warning": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-1.0.0.tgz",
"integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q=="
},
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -2535,6 +3039,20 @@
"node": ">=6"
}
},
+ "node_modules/qs": {
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
+ "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
+ "dependencies": {
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -2560,6 +3078,28 @@
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
"integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="
},
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+ "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@@ -2578,25 +3118,22 @@
"node_modules/rc/node_modules/strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
"devOptional": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/readable-stream": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
- "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
- "devOptional": true,
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==",
+ "dev": true,
"dependencies": {
"core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
}
},
"node_modules/readdirp": {
@@ -2631,18 +3168,18 @@
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/resolve": {
- "version": "1.22.0",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
- "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==",
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
"dev": true,
"dependencies": {
- "is-core-module": "^2.8.1",
+ "is-core-module": "^2.9.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
@@ -2716,9 +3253,28 @@
}
},
"node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/sax": {
"version": "1.2.4",
@@ -2726,9 +3282,9 @@
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"node_modules/semver": {
- "version": "7.3.5",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
- "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"devOptional": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -2740,11 +3296,65 @@
"node": ">=10"
}
},
- "node_modules/set-blocking": {
+ "node_modules/send": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+ "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/send/node_modules/debug/node_modules/ms": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
- "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
- "devOptional": true
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/send/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
+ "node_modules/serve-static": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
+ "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+ "dependencies": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.18.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"node_modules/sha.js": {
"version": "2.4.11",
@@ -2779,11 +3389,18 @@
"node": ">=8"
}
},
- "node_modules/signal-exit": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
- "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
- "devOptional": true
+ "node_modules/side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
"node_modules/simple-concat": {
"version": "1.0.1",
@@ -2840,11 +3457,12 @@
}
},
"node_modules/sonic-boom": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.6.0.tgz",
- "integrity": "sha512-6xYZFRmDEtxGqfOKcDQ4cPLrNa0SPEDI+wlzDAHowXE6YV42NeXqg9mP2KkiM8JVu3lHfZ2iQKYlGOz+kTpphg==",
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz",
+ "integrity": "sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==",
"dependencies": {
- "atomic-sleep": "^1.0.0"
+ "atomic-sleep": "^1.0.0",
+ "flatstr": "^1.0.12"
}
},
"node_modules/source-map": {
@@ -2887,54 +3505,61 @@
"node": ">= 6"
}
},
- "node_modules/sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
+ "node_modules/split2/node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
},
"node_modules/sqlite": {
- "version": "4.0.25",
- "resolved": "https://registry.npmjs.org/sqlite/-/sqlite-4.0.25.tgz",
- "integrity": "sha512-gqCEcLF8FOTeW/na3SRYWLQkw2jZXgVj1DdgRJbm0jvrhnUgBIuNDUUm649AnBNDNHhI5XskwT8dvc8vearRLQ=="
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/sqlite/-/sqlite-4.1.2.tgz",
+ "integrity": "sha512-FlBG51gHbux5vPjwnoqFEghNGvnTMTbHyiI09U3qFTQs9AtWuwd4i++6+WCusCXKrVdIDLzfdGekrolr3m4U4A=="
+ },
+ "node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
},
"node_modules/string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dependencies": {
- "safe-buffer": "~5.1.0"
- }
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
+ "dev": true
},
"node_modules/string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
- "devOptional": true,
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dependencies": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
"node_modules/strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "devOptional": true,
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dependencies": {
- "ansi-regex": "^2.0.0"
+ "ansi-regex": "^5.0.1"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
"node_modules/strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
"dev": true,
"engines": {
"node": ">=4"
@@ -2952,14 +3577,14 @@
}
},
"node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dependencies": {
- "has-flag": "^3.0.0"
+ "has-flag": "^4.0.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=8"
}
},
"node_modules/supports-preserve-symlinks-flag": {
@@ -3016,10 +3641,19 @@
"node": ">= 6"
}
},
+ "node_modules/tar-stream/node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "devOptional": true,
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
"node_modules/text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
"node_modules/thenify": {
@@ -3033,7 +3667,7 @@
"node_modules/thenify-all": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
- "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
"dependencies": {
"thenify": ">= 3.1.0 < 4"
},
@@ -3051,6 +3685,42 @@
"xtend": "~4.0.1"
}
},
+ "node_modules/through2/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true
+ },
+ "node_modules/through2/node_modules/readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/through2/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "node_modules/through2/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -3063,6 +3733,14 @@
"node": ">=8.0"
}
},
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
"node_modules/tree-kill": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
@@ -3073,20 +3751,20 @@
}
},
"node_modules/ts-node-dev": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-1.1.8.tgz",
- "integrity": "sha512-Q/m3vEwzYwLZKmV6/0VlFxcZzVV/xcgOt+Tx/VjaaRHyiBcFlV0541yrT09QjzzCxlDZ34OzKjrFAynlmtflEg==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz",
+ "integrity": "sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==",
"dev": true,
"dependencies": {
"chokidar": "^3.5.1",
"dynamic-dedupe": "^0.3.0",
- "minimist": "^1.2.5",
+ "minimist": "^1.2.6",
"mkdirp": "^1.0.4",
"resolve": "^1.0.0",
"rimraf": "^2.6.1",
"source-map-support": "^0.5.12",
"tree-kill": "^1.2.2",
- "ts-node": "^9.0.0",
+ "ts-node": "^10.4.0",
"tsconfig": "^7.0.0"
},
"bin": {
@@ -3119,29 +3797,46 @@
}
},
"node_modules/ts-node-dev/node_modules/ts-node": {
- "version": "9.1.1",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz",
- "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==",
- "dev": true,
- "dependencies": {
+ "version": "10.9.1",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
+ "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
+ "dev": true,
+ "dependencies": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
- "source-map-support": "^0.5.17",
+ "v8-compile-cache-lib": "^3.0.1",
"yn": "3.1.1"
},
"bin": {
"ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-esm": "dist/bin-esm.js",
"ts-node-script": "dist/bin-script.js",
"ts-node-transpile-only": "dist/bin-transpile.js",
"ts-script": "dist/bin-script-deprecated.js"
},
- "engines": {
- "node": ">=10.0.0"
- },
"peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
"typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
}
},
"node_modules/tsconfig": {
@@ -3159,16 +3854,16 @@
"node_modules/tsconfig/node_modules/strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/tslib": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
- "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"node_modules/tsutils": {
"version": "3.21.0",
@@ -3194,7 +3889,7 @@
"node_modules/tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"devOptional": true,
"dependencies": {
"safe-buffer": "^5.0.1"
@@ -3227,10 +3922,22 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/typeorm": {
- "version": "0.2.44",
- "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.2.44.tgz",
- "integrity": "sha512-yFyb9Ts73vGaS/O06TvLpzvT5U/ngO31GeciNc0eoH7P1QcG8kVZdOy9FHJqkTeDmIljMRgWjbYUoMw53ZY7Xw==",
+ "version": "0.2.45",
+ "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.2.45.tgz",
+ "integrity": "sha512-c0rCO8VMJ3ER7JQ73xfk0zDnVv0WDjpsP6Q1m6CVKul7DB9iVdWLRjPzc8v2eaeBuomsbZ2+gTaYr8k1gm3bYA==",
"dependencies": {
"@sqltools/formatter": "^1.2.2",
"app-root-path": "^3.0.0",
@@ -3321,49 +4028,19 @@
}
}
},
- "node_modules/typeorm/node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
- },
- "node_modules/typeorm/node_modules/buffer": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
- "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "dependencies": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.2.1"
- }
- },
- "node_modules/typeorm/node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
+ "node_modules/typeorm/node_modules/dotenv": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz",
+ "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==",
+ "engines": {
+ "node": ">=10"
}
},
"node_modules/typescript": {
- "version": "4.5.5",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
- "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
+ "version": "4.8.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz",
+ "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==",
+ "dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -3372,6 +4049,14 @@
"node": ">=4.2.0"
}
},
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/untildify": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
@@ -3390,10 +4075,31 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/util": {
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
+ "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+ "dependencies": {
+ "inherits": "2.0.3"
+ }
+ },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+ },
+ "node_modules/util/node_modules/inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw=="
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
},
"node_modules/uuid": {
"version": "8.3.2",
@@ -3403,12 +4109,20 @@
"uuid": "dist/bin/uuid"
}
},
- "node_modules/v8-compile-cache": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
- "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
+ "node_modules/v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"dev": true
},
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -3424,15 +4138,6 @@
"node": ">= 8"
}
},
- "node_modules/wide-align": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
- "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
- "devOptional": true,
- "dependencies": {
- "string-width": "^1.0.2 || 2"
- }
- },
"node_modules/word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
@@ -3458,80 +4163,10 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
- "node_modules/wrap-ansi/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wrap-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
- "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wrap-ansi/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wrap-ansi/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/xml2js": {
"version": "0.4.23",
@@ -3577,68 +4212,28 @@
"devOptional": true
},
"node_modules/yargs": {
- "version": "17.3.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz",
- "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==",
+ "version": "17.5.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
+ "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
"dependencies": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
- "string-width": "^4.2.3",
- "y18n": "^5.0.5",
- "yargs-parser": "^21.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/yargs-parser": {
- "version": "21.0.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
- "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/yargs/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/yargs/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/yargs/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.0.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=12"
}
},
- "node_modules/yargs/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"engines": {
- "node": ">=8"
+ "node": ">=12"
}
},
"node_modules/yn": {
@@ -3650,6 +4245,18 @@
"node": ">=6"
}
},
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/zen-observable": {
"version": "0.8.15",
"resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz",
@@ -3663,52 +4270,67 @@
"@types/zen-observable": "0.8.3",
"zen-observable": "0.8.15"
}
+ },
+ "node_modules/zlib": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/zlib/-/zlib-1.0.5.tgz",
+ "integrity": "sha512-40fpE2II+Cd3k8HWTWONfeKE2jL+P42iWJ1zzps5W51qcTsOUKM5Q5m2PFb0CLxlmFAaUuUdJGc3OfZy947v0w==",
+ "hasInstallScript": true,
+ "engines": {
+ "node": ">=0.2.0"
+ }
}
},
"dependencies": {
+ "@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/trace-mapping": "0.3.9"
+ }
+ },
+ "@decorators/di": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@decorators/di/-/di-1.0.3.tgz",
+ "integrity": "sha512-wafyQo5lqGABT+Lh7Od9/qULg7DG/kZFU3mLUKZFuiV/KATYlnv198yQxaZUZerhUDoTl/cZKu9t4mJa0rZK4Q==",
+ "requires": {
+ "reflect-metadata": "0.1.13"
+ }
+ },
+ "@decorators/express": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/@decorators/express/-/express-2.6.0.tgz",
+ "integrity": "sha512-th/LqSAHAAW1ob2CU6hxtsfnryGThmz0AmGP45rA3Yoi0Q7+FHAZVfH7NJSYHITai/uXjjOtZPPW/V0gFfbgUw==",
+ "requires": {}
+ },
"@eslint/eslintrc": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz",
- "integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz",
+ "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
- "espree": "^9.3.1",
- "globals": "^13.9.0",
+ "espree": "^9.4.0",
+ "globals": "^13.15.0",
"ignore": "^5.2.0",
"import-fresh": "^3.2.1",
"js-yaml": "^4.1.0",
- "minimatch": "^3.0.4",
+ "minimatch": "^3.1.2",
"strip-json-comments": "^3.1.1"
- },
- "dependencies": {
- "argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
- },
- "js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
- "requires": {
- "argparse": "^2.0.1"
- }
- }
}
},
"@hapi/bourne": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz",
- "integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg=="
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.1.0.tgz",
+ "integrity": "sha512-i1BpaNDVLJdRBEKeJWkVO6tYX6DMFBuwMhSuWqLsY4ufeTKGVuV5rBsUhxPayXqnnWHgXUAmWK16H/ykO5Wj4Q=="
},
"@humanwhocodes/config-array": {
- "version": "0.9.5",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
- "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz",
+ "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==",
"dev": true,
"requires": {
"@humanwhocodes/object-schema": "^1.2.1",
@@ -3716,12 +4338,54 @@
"minimatch": "^3.0.4"
}
},
+ "@humanwhocodes/gitignore-to-minimatch": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz",
+ "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==",
+ "dev": true
+ },
+ "@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true
+ },
"@humanwhocodes/object-schema": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
+ "@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "dev": true
+ },
+ "@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+ "dev": true
+ },
+ "@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "@ledgerhq/compressjs": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/compressjs/-/compressjs-1.3.2.tgz",
+ "integrity": "sha512-gonFwAifRkSYDO7rt3NIBlvjvY8Nw+NM6LT1SuOBppuvoKbYtBViNh3EBPbP86+3Y4ux7DLUsNiUlqOgubJsdA==",
+ "requires": {
+ "commander": "^2.20.0"
+ }
+ },
"@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -3749,16 +4413,17 @@
}
},
"@runejs/common": {
- "version": "2.0.2-beta.2",
- "resolved": "https://registry.npmjs.org/@runejs/common/-/common-2.0.2-beta.2.tgz",
- "integrity": "sha512-Xd9/Ws3ByAdI1R08Ye9fWqlS8SImjQw05Bsw0w46zcGyDx8N6jmeClf9Y/s4Akh9VZQuoAMFg2ANKsRK0MucNw==",
+ "version": "3.0.0-beta.10",
+ "resolved": "https://registry.npmjs.org/@runejs/common/-/common-3.0.0-beta.10.tgz",
+ "integrity": "sha512-4EnjDBlAfv26oHkSg6q6xAU7gfQj4QKKDUh/e0NJZ3DkwrQuimlNHEfprn7/Wl6wa4mzqJZl05MT2XRfGFhttQ==",
"requires": {
- "compressjs": "^1.0.3",
- "js-yaml": "^3.14.1",
+ "@ledgerhq/compressjs": "^1.3.2",
+ "buffer": "^6.0.3",
+ "dotenv": "^16.0.0",
+ "path": "^0.12.7",
"pino": "^6.14.0",
- "pino-pretty": "^4.8.0",
- "sonic-boom": "^2.6.0",
- "tslib": "^2.3.1"
+ "pino-pretty": "^6.0.0",
+ "zlib": "^1.0.5"
}
},
"@runejs/eslint-config": {
@@ -3773,6 +4438,81 @@
"resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.3.tgz",
"integrity": "sha512-O3uyB/JbkAEMZaP3YqyHH7TMnex7tWyCbCI4EfJdOCoN6HIhqdJBWTM6aCCiWQ/5f5wxjgU735QAIpJbjDvmzg=="
},
+ "@tsconfig/node10": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
+ "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
+ "dev": true
+ },
+ "@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true
+ },
+ "@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true
+ },
+ "@tsconfig/node16": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
+ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
+ "dev": true
+ },
+ "@types/adm-zip": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.5.0.tgz",
+ "integrity": "sha512-FCJBJq9ODsQZUNURo5ILAQueuA8WJhRvuihS3ke2iI25mJlfV2LK8jG2Qj2z2AWg8U0FtWWqBHVRetceLskSaw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/body-parser": {
+ "version": "1.19.2",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
+ "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
+ "dev": true,
+ "requires": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/connect": {
+ "version": "3.4.35",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
+ "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/express": {
+ "version": "4.17.13",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz",
+ "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==",
+ "dev": true,
+ "requires": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^4.17.18",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "@types/express-serve-static-core": {
+ "version": "4.17.30",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz",
+ "integrity": "sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*"
+ }
+ },
"@types/graceful-fs": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
@@ -3783,21 +4523,49 @@
}
},
"@types/json-schema": {
- "version": "7.0.9",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
- "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+ "dev": true
+ },
+ "@types/mime": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
+ "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==",
"dev": true
},
"@types/node": {
- "version": "16.11.26",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.26.tgz",
- "integrity": "sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ==",
+ "version": "16.11.56",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.56.tgz",
+ "integrity": "sha512-aFcUkv7EddxxOa/9f74DINReQ/celqH8DiB3fRYgVDM2Xm5QJL8sl80QKuAnGvwAsMn+H3IFA6WCrQh1CY7m1A==",
+ "dev": true
+ },
+ "@types/qs": {
+ "version": "6.9.7",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
+ "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
"dev": true
},
+ "@types/range-parser": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
+ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
+ "dev": true
+ },
+ "@types/serve-static": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz",
+ "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==",
+ "dev": true,
+ "requires": {
+ "@types/mime": "*",
+ "@types/node": "*"
+ }
+ },
"@types/strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=",
+ "integrity": "sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==",
"dev": true
},
"@types/strip-json-comments": {
@@ -3807,18 +4575,18 @@
"dev": true
},
"@types/yargs": {
- "version": "17.0.9",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.9.tgz",
- "integrity": "sha512-Ci8+4/DOtkHRylcisKmVMtmVO5g7weUVCKcsu1sJvF1bn0wExTmbHmhFKj7AnEm0de800iovGhdSKzYnzbaHpg==",
+ "version": "17.0.12",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz",
+ "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
}
},
"@types/yargs-parser": {
- "version": "20.2.1",
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz",
- "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==",
+ "version": "21.0.0",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
"dev": true
},
"@types/zen-observable": {
@@ -3827,104 +4595,114 @@
"integrity": "sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw=="
},
"@typescript-eslint/eslint-plugin": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.14.0.tgz",
- "integrity": "sha512-ir0wYI4FfFUDfLcuwKzIH7sMVA+db7WYen47iRSaCGl+HMAZI9fpBwfDo45ZALD3A45ZGyHWDNLhbg8tZrMX4w==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.1.tgz",
+ "integrity": "sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==",
"dev": true,
"requires": {
- "@typescript-eslint/scope-manager": "5.14.0",
- "@typescript-eslint/type-utils": "5.14.0",
- "@typescript-eslint/utils": "5.14.0",
- "debug": "^4.3.2",
+ "@typescript-eslint/scope-manager": "5.36.1",
+ "@typescript-eslint/type-utils": "5.36.1",
+ "@typescript-eslint/utils": "5.36.1",
+ "debug": "^4.3.4",
"functional-red-black-tree": "^1.0.1",
- "ignore": "^5.1.8",
+ "ignore": "^5.2.0",
"regexpp": "^3.2.0",
- "semver": "^7.3.5",
+ "semver": "^7.3.7",
"tsutils": "^3.21.0"
}
},
"@typescript-eslint/parser": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.14.0.tgz",
- "integrity": "sha512-aHJN8/FuIy1Zvqk4U/gcO/fxeMKyoSv/rS46UXMXOJKVsLQ+iYPuXNbpbH7cBLcpSbmyyFbwrniLx5+kutu1pw==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz",
+ "integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==",
"dev": true,
"requires": {
- "@typescript-eslint/scope-manager": "5.14.0",
- "@typescript-eslint/types": "5.14.0",
- "@typescript-eslint/typescript-estree": "5.14.0",
- "debug": "^4.3.2"
+ "@typescript-eslint/scope-manager": "5.36.1",
+ "@typescript-eslint/types": "5.36.1",
+ "@typescript-eslint/typescript-estree": "5.36.1",
+ "debug": "^4.3.4"
}
},
"@typescript-eslint/scope-manager": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.14.0.tgz",
- "integrity": "sha512-LazdcMlGnv+xUc5R4qIlqH0OWARyl2kaP8pVCS39qSL3Pd1F7mI10DbdXeARcE62sVQE4fHNvEqMWsypWO+yEw==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz",
+ "integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.14.0",
- "@typescript-eslint/visitor-keys": "5.14.0"
+ "@typescript-eslint/types": "5.36.1",
+ "@typescript-eslint/visitor-keys": "5.36.1"
}
},
"@typescript-eslint/type-utils": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.14.0.tgz",
- "integrity": "sha512-d4PTJxsqaUpv8iERTDSQBKUCV7Q5yyXjqXUl3XF7Sd9ogNLuKLkxz82qxokqQ4jXdTPZudWpmNtr/JjbbvUixw==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.1.tgz",
+ "integrity": "sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==",
"dev": true,
"requires": {
- "@typescript-eslint/utils": "5.14.0",
- "debug": "^4.3.2",
+ "@typescript-eslint/typescript-estree": "5.36.1",
+ "@typescript-eslint/utils": "5.36.1",
+ "debug": "^4.3.4",
"tsutils": "^3.21.0"
}
},
"@typescript-eslint/types": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.14.0.tgz",
- "integrity": "sha512-BR6Y9eE9360LNnW3eEUqAg6HxS9Q35kSIs4rp4vNHRdfg0s+/PgHgskvu5DFTM7G5VKAVjuyaN476LCPrdA7Mw==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz",
+ "integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.14.0.tgz",
- "integrity": "sha512-QGnxvROrCVtLQ1724GLTHBTR0lZVu13izOp9njRvMkCBgWX26PKvmMP8k82nmXBRD3DQcFFq2oj3cKDwr0FaUA==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz",
+ "integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.14.0",
- "@typescript-eslint/visitor-keys": "5.14.0",
- "debug": "^4.3.2",
- "globby": "^11.0.4",
+ "@typescript-eslint/types": "5.36.1",
+ "@typescript-eslint/visitor-keys": "5.36.1",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
"is-glob": "^4.0.3",
- "semver": "^7.3.5",
+ "semver": "^7.3.7",
"tsutils": "^3.21.0"
}
},
"@typescript-eslint/utils": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.14.0.tgz",
- "integrity": "sha512-EHwlII5mvUA0UsKYnVzySb/5EE/t03duUTweVy8Zqt3UQXBrpEVY144OTceFKaOe4xQXZJrkptCf7PjEBeGK4w==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.1.tgz",
+ "integrity": "sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
- "@typescript-eslint/scope-manager": "5.14.0",
- "@typescript-eslint/types": "5.14.0",
- "@typescript-eslint/typescript-estree": "5.14.0",
+ "@typescript-eslint/scope-manager": "5.36.1",
+ "@typescript-eslint/types": "5.36.1",
+ "@typescript-eslint/typescript-estree": "5.36.1",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
}
},
"@typescript-eslint/visitor-keys": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.14.0.tgz",
- "integrity": "sha512-yL0XxfzR94UEkjBqyymMLgCBdojzEuy/eim7N9/RIcTNxpJudAcqsU8eRyfzBbcEzGoPWfdM3AGak3cN08WOIw==",
+ "version": "5.36.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz",
+ "integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.14.0",
- "eslint-visitor-keys": "^3.0.0"
+ "@typescript-eslint/types": "5.36.1",
+ "eslint-visitor-keys": "^3.3.0"
+ }
+ },
+ "accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "requires": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
}
},
"acorn": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
- "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+ "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
"dev": true
},
"acorn-jsx": {
@@ -3934,6 +4712,17 @@
"dev": true,
"requires": {}
},
+ "acorn-walk": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
+ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+ "dev": true
+ },
+ "adm-zip": {
+ "version": "0.5.9",
+ "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz",
+ "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg=="
+ },
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -3949,26 +4738,25 @@
"amdefine": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
- "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
+ "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg=="
},
"ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
- "devOptional": true
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"requires": {
- "color-convert": "^1.9.0"
+ "color-convert": "^2.0.1"
}
},
"any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="
},
"anymatch": {
"version": "3.1.2",
@@ -3981,25 +4769,9 @@
}
},
"app-root-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz",
- "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw=="
- },
- "aproba": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
- "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
- "devOptional": true
- },
- "are-we-there-yet": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
- "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
- "devOptional": true,
- "requires": {
- "delegates": "^1.0.0",
- "readable-stream": "^2.0.6"
- }
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz",
+ "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA=="
},
"arg": {
"version": "4.1.3",
@@ -4008,17 +4780,14 @@
"dev": true
},
"argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "requires": {
- "sprintf-js": "~1.0.2"
- }
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"args": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/args/-/args-5.0.1.tgz",
- "integrity": "sha512-1kqmFCFsPffavQFGt8OxJdIcETti99kySRUPMpOhaGjL6mRJn8HFU1OxKY5bMqfZKUwTQc1mZkAjmGYaVOHFtQ==",
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/args/-/args-5.0.3.tgz",
+ "integrity": "sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==",
"requires": {
"camelcase": "5.0.0",
"chalk": "2.4.2",
@@ -4026,6 +4795,14 @@
"mri": "1.1.4"
},
"dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -4035,24 +4812,74 @@
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
}
}
},
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+ },
"array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
"dev": true
},
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ },
"atomic-sleep": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
"integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="
},
+ "axios": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
+ "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
+ "requires": {
+ "follow-redirects": "^1.14.9",
+ "form-data": "^4.0.0"
+ }
+ },
"balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"base64-js": {
"version": "1.5.1",
@@ -4060,13 +4887,13 @@
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"better-sqlite3": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-7.5.0.tgz",
- "integrity": "sha512-6FdG9DoytYGDhLW7VWW1vxjEz7xHkqK6LnaUQYA8d6GHNgZhu9PFX2xwKEEnSBRoT1J4PjTUPeg217ShxNmuPg==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-7.6.2.tgz",
+ "integrity": "sha512-S5zIU1Hink2AH4xPsN0W43T1/AJ5jrPh7Oy07ocuW/AKYYY02GWzz9NH0nbSMn/gw6fDZ5jZ1QsHt1BXAwJ6Lg==",
"devOptional": true,
"requires": {
"bindings": "^1.5.0",
- "prebuild-install": "^7.0.0"
+ "prebuild-install": "^7.1.0"
}
},
"binary-extensions": {
@@ -4095,6 +4922,16 @@
"readable-stream": "^3.4.0"
},
"dependencies": {
+ "buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "devOptional": true,
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
@@ -4105,6 +4942,49 @@
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
+ },
+ "string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "devOptional": true,
+ "requires": {
+ "safe-buffer": "~5.2.0"
+ }
+ }
+ }
+ },
+ "body-parser": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
+ "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
+ "requires": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.10.3",
+ "raw-body": "2.5.1",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
}
}
},
@@ -4127,13 +5007,12 @@
}
},
"buffer": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
- "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
- "devOptional": true,
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"requires": {
"base64-js": "^1.3.1",
- "ieee754": "^1.1.13"
+ "ieee754": "^1.2.1"
}
},
"buffer-from": {
@@ -4142,6 +5021,20 @@
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true
},
+ "bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
+ },
+ "call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ }
+ },
"callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -4154,48 +5047,12 @@
"integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA=="
},
"chalk": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
- "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
}
},
"chokidar": {
@@ -4212,6 +5069,17 @@
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
+ },
+ "dependencies": {
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ }
}
},
"chownr": {
@@ -4231,36 +5099,8 @@
"parse5": "^5.1.1",
"parse5-htmlparser2-tree-adapter": "^6.0.0",
"yargs": "^16.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
- },
- "string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- }
- },
- "strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "requires": {
- "ansi-regex": "^5.0.1"
- }
- },
+ },
+ "dependencies": {
"yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
@@ -4290,84 +5130,85 @@
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^7.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
- },
- "string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- }
- },
- "strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "requires": {
- "ansi-regex": "^5.0.1"
- }
- }
}
},
- "code-point-at": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
- "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
- "devOptional": true
- },
"color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
- "color-name": "1.1.3"
+ "color-name": "~1.1.4"
}
},
"color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
- "commander": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
- "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
+ "colorette": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz",
+ "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g=="
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
- "graceful-readlink": ">= 1.0.0"
+ "delayed-stream": "~1.0.0"
}
},
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+ },
"compressjs": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/compressjs/-/compressjs-1.0.3.tgz",
- "integrity": "sha1-ldt03VuQOM+AvKMhqw7eJxtJWbY=",
+ "integrity": "sha512-jpKJjBTretQACTGLNuvnozP1JdP2ZLrjdGdBgk/tz1VfXlUcBhhSZW6vEsuThmeot/yjvSrPQKEgfF3X2Lpi8Q==",
"requires": {
"amdefine": "~1.0.0",
"commander": "~2.8.1"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
+ "integrity": "sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==",
+ "requires": {
+ "graceful-readlink": ">= 1.0.0"
+ }
+ }
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
- "console-control-strings": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
- "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
- "devOptional": true
+ "content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "requires": {
+ "safe-buffer": "5.2.1"
+ }
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ },
+ "cookie": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
},
"copyfiles": {
"version": "2.4.1",
@@ -4384,38 +5225,6 @@
"yargs": "^16.1.0"
},
"dependencies": {
- "ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true
- },
- "string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- }
- },
- "strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "requires": {
- "ansi-regex": "^5.0.1"
- }
- },
"yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
@@ -4440,10 +5249,10 @@
}
},
"core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
- "devOptional": true
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true
},
"create-require": {
"version": "1.1.1",
@@ -4468,9 +5277,9 @@
"integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA=="
},
"debug": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
- "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
@@ -4496,10 +5305,25 @@
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true
},
- "delegates": {
+ "delayed-stream": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
- "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
+ },
+ "depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
+ },
+ "destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
+ },
+ "detect-libc": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
+ "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
"devOptional": true
},
"diff": {
@@ -4527,24 +5351,34 @@
}
},
"dotenv": {
- "version": "8.6.0",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz",
- "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g=="
+ "version": "16.0.2",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.2.tgz",
+ "integrity": "sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA=="
},
"dynamic-dedupe": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz",
- "integrity": "sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE=",
+ "integrity": "sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==",
"dev": true,
"requires": {
"xtend": "^4.0.0"
}
},
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+ },
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
+ },
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -4558,19 +5392,27 @@
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
},
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+ },
"escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true
},
"eslint": {
- "version": "8.11.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz",
- "integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==",
+ "version": "8.23.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz",
+ "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==",
"dev": true,
"requires": {
- "@eslint/eslintrc": "^1.2.1",
- "@humanwhocodes/config-array": "^0.9.2",
+ "@eslint/eslintrc": "^1.3.1",
+ "@humanwhocodes/config-array": "^0.10.4",
+ "@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
+ "@humanwhocodes/module-importer": "^1.0.1",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@@ -4580,14 +5422,17 @@
"eslint-scope": "^7.1.1",
"eslint-utils": "^3.0.0",
"eslint-visitor-keys": "^3.3.0",
- "espree": "^9.3.1",
+ "espree": "^9.4.0",
"esquery": "^1.4.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
"file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
"functional-red-black-tree": "^1.0.1",
"glob-parent": "^6.0.1",
- "globals": "^13.6.0",
+ "globals": "^13.15.0",
+ "globby": "^11.1.0",
+ "grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
@@ -4596,34 +5441,15 @@
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
"lodash.merge": "^4.6.2",
- "minimatch": "^3.0.4",
+ "minimatch": "^3.1.2",
"natural-compare": "^1.4.0",
"optionator": "^0.9.1",
"regexpp": "^3.2.0",
"strip-ansi": "^6.0.1",
"strip-json-comments": "^3.1.0",
- "text-table": "^0.2.0",
- "v8-compile-cache": "^2.0.3"
+ "text-table": "^0.2.0"
},
"dependencies": {
- "ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true
- },
- "argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
- },
- "escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true
- },
"eslint-scope": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
@@ -4639,33 +5465,6 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true
- },
- "glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
- "requires": {
- "is-glob": "^4.0.3"
- }
- },
- "js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
- "requires": {
- "argparse": "^2.0.1"
- }
- },
- "strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "requires": {
- "ansi-regex": "^5.0.1"
- }
}
}
},
@@ -4703,21 +5502,16 @@
"dev": true
},
"espree": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz",
- "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==",
+ "version": "9.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz",
+ "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==",
"dev": true,
"requires": {
- "acorn": "^8.7.0",
- "acorn-jsx": "^5.3.1",
+ "acorn": "^8.8.0",
+ "acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^3.3.0"
}
},
- "esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
- },
"esquery": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
@@ -4764,12 +5558,70 @@
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
},
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
+ },
"expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
"devOptional": true
},
+ "express": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
+ "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
+ "requires": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.0",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.5.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.2.0",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.10.3",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.18.0",
+ "serve-static": "1.15.0",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ }
+ }
+ },
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -4787,6 +5639,17 @@
"glob-parent": "^5.1.2",
"merge2": "^1.3.0",
"micromatch": "^4.0.4"
+ },
+ "dependencies": {
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ }
}
},
"fast-json-stable-stringify": {
@@ -4798,13 +5661,13 @@
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true
},
"fast-redact": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.1.tgz",
- "integrity": "sha512-odVmjC8x8jNeMZ3C+rPMESzXVSEU8tSWSHv9HFxP2mm89G/1WwqhrerJDQm9Zus8X6aoRgQDThKqptdNA6bt+A=="
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.2.tgz",
+ "integrity": "sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw=="
},
"fast-safe-stringify": {
"version": "2.1.1",
@@ -4844,6 +5707,45 @@
"to-regex-range": "^5.0.1"
}
},
+ "finalhandler": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
+ "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ }
+ }
+ },
+ "find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
"flat-cache": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
@@ -4860,11 +5762,36 @@
"integrity": "sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw=="
},
"flatted": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz",
- "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==",
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
+ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
"dev": true
},
+ "follow-redirects": {
+ "version": "1.15.1",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
+ "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA=="
+ },
+ "form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
+ },
"fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
@@ -4874,7 +5801,7 @@
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"fsevents": {
"version": "2.3.2",
@@ -4886,68 +5813,61 @@
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
- "dev": true
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
- "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
"dev": true
},
- "gauge": {
- "version": "2.7.4",
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
- "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
- "devOptional": true,
- "requires": {
- "aproba": "^1.0.3",
- "console-control-strings": "^1.0.0",
- "has-unicode": "^2.0.0",
- "object-assign": "^4.1.0",
- "signal-exit": "^3.0.0",
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wide-align": "^1.1.0"
- }
- },
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
},
+ "get-intrinsic": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+ "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.3"
+ }
+ },
"github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
- "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
+ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
"devOptional": true
},
"glob": {
- "version": "7.1.6",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
- "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
- "minimatch": "^3.0.4",
+ "minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
"requires": {
- "is-glob": "^4.0.1"
+ "is-glob": "^4.0.3"
}
},
"globals": {
- "version": "13.12.1",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz",
- "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==",
+ "version": "13.17.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
+ "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
@@ -4968,40 +5888,64 @@
}
},
"graceful-fs": {
- "version": "4.2.9",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
- "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ=="
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
},
"graceful-readlink": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
- "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
+ "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w=="
+ },
+ "grapheme-splitter": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+ "dev": true
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "dev": true,
"requires": {
"function-bind": "^1.1.1"
}
},
"has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
- "has-unicode": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
- "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
- "devOptional": true
+ "has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
},
"highlight.js": {
"version": "10.7.3",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
"integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="
},
+ "http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "requires": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -5026,13 +5970,13 @@
"imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
"dev": true
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"requires": {
"once": "^1.3.0",
"wrappy": "1"
@@ -5049,6 +5993,11 @@
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"devOptional": true
},
+ "ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
+ },
"is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -5059,9 +6008,9 @@
}
},
"is-core-module": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
- "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
+ "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
"dev": true,
"requires": {
"has": "^1.0.3"
@@ -5070,17 +6019,13 @@
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true
},
"is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
- "devOptional": true,
- "requires": {
- "number-is-nan": "^1.0.0"
- }
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
"is-glob": {
"version": "4.0.3",
@@ -5098,34 +6043,33 @@
"dev": true
},
"isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "devOptional": true
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
+ "dev": true
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
},
"jmespath": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
- "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc="
+ "integrity": "sha512-+kHj8HXArPfpPEKGLZ+kB5ONRTCiGQXo8RQYL0hH8t6pWXUBBK5KkkQmTNOwKK4LEsd0yTsgtjJVm4UBSZea4w=="
},
"joycon": {
- "version": "2.2.5",
- "resolved": "https://registry.npmjs.org/joycon/-/joycon-2.2.5.tgz",
- "integrity": "sha512-YqvUxoOcVPnCp0VU1/56f+iKSdvIRJYPznH22BdXV3xMk75SFXhWeJkZ8C9XxUWt1b5x2X1SxuFygW1U0FmkEQ=="
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
+ "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw=="
},
"js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"requires": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
+ "argparse": "^2.0.1"
}
},
"json-schema-traverse": {
@@ -5137,21 +6081,18 @@
"json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
- "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true
},
"json5": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
- "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
- "requires": {
- "minimist": "^1.2.5"
- }
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
+ "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA=="
},
"leven": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
- "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA="
+ "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA=="
},
"levn": {
"version": "0.4.1",
@@ -5163,6 +6104,15 @@
"type-check": "~0.4.0"
}
},
+ "locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^5.0.0"
+ }
+ },
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -5184,20 +6134,53 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true
},
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
+ },
"merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"dev": true
},
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
+ },
"micromatch": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
- "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
"dev": true,
"requires": {
- "braces": "^3.0.1",
- "picomatch": "^2.2.3"
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ }
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
+ },
+ "mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
+ },
+ "mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "requires": {
+ "mime-db": "1.52.0"
}
},
"mimic-response": {
@@ -5207,17 +6190,18 @@
"devOptional": true
},
"minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
+ "devOptional": true
},
"mkdirp": {
"version": "1.0.4",
@@ -5259,52 +6243,31 @@
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
- "node-abi": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.8.0.tgz",
- "integrity": "sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw==",
- "devOptional": true,
- "requires": {
- "semver": "^7.3.5"
- }
+ "negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
},
- "noms": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz",
- "integrity": "sha1-2o69nzr51nYJGbJ9nNyAkqczKFk=",
- "dev": true,
- "requires": {
- "inherits": "^2.0.1",
- "readable-stream": "~1.0.31"
- },
- "dependencies": {
- "isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
- "dev": true
- },
- "readable-stream": {
- "version": "1.0.34",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "0.0.1",
- "string_decoder": "~0.10.x"
- }
- },
- "string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
- "dev": true
- }
+ "node-abi": {
+ "version": "3.24.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.24.0.tgz",
+ "integrity": "sha512-YPG3Co0luSu6GwOBsmIdGW6Wx0NyNDLg/hriIyDllVsNwnI6UeqaWShxC3lbH4LtEQUgoLP3XR1ndXiDAWvmRw==",
+ "devOptional": true,
+ "requires": {
+ "semver": "^7.3.5"
+ }
+ },
+ "noms": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz",
+ "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "readable-stream": "~1.0.31"
}
},
"normalize-path": {
@@ -5313,33 +6276,28 @@
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true
},
- "npmlog": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
- "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
- "devOptional": true,
- "requires": {
- "are-we-there-yet": "~1.1.2",
- "console-control-strings": "~1.1.0",
- "gauge": "~2.7.3",
- "set-blocking": "~2.0.0"
- }
- },
- "number-is-nan": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
- "devOptional": true
- },
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
+ },
+ "object-inspect": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+ "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
+ },
+ "on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"requires": {
"wrappy": "1"
}
@@ -5358,6 +6316,24 @@
"word-wrap": "^1.2.3"
}
},
+ "p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^3.0.2"
+ }
+ },
"parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -5387,10 +6363,30 @@
}
}
},
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
+ },
+ "path": {
+ "version": "0.12.7",
+ "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
+ "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==",
+ "requires": {
+ "process": "^0.11.1",
+ "util": "^0.10.3"
+ }
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
},
"path-key": {
"version": "3.1.1",
@@ -5404,6 +6400,11 @@
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
+ },
"path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
@@ -5428,31 +6429,20 @@
"process-warning": "^1.0.0",
"quick-format-unescaped": "^4.0.3",
"sonic-boom": "^1.0.2"
- },
- "dependencies": {
- "sonic-boom": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz",
- "integrity": "sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==",
- "requires": {
- "atomic-sleep": "^1.0.0",
- "flatstr": "^1.0.12"
- }
- }
}
},
"pino-pretty": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-4.8.0.tgz",
- "integrity": "sha512-mhQfHG4rw5ZFpWL44m0Utjo4GC2+HMfdNvxyA8lLw0sIqn6fCf7uQe6dPckUcW/obly+OQHD7B/MTso6LNizYw==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-6.0.0.tgz",
+ "integrity": "sha512-jyeR2fXXWc68st1DTTM5NhkHlx8p+1fKZMfm84Jwq+jSw08IwAjNaZBZR6ts69hhPOfOjg/NiE1HYW7vBRPL3A==",
"requires": {
"@hapi/bourne": "^2.0.0",
"args": "^5.0.1",
- "chalk": "^4.0.0",
+ "colorette": "^1.3.0",
"dateformat": "^4.5.1",
"fast-safe-stringify": "^2.0.7",
"jmespath": "^0.15.0",
- "joycon": "^2.2.5",
+ "joycon": "^3.0.0",
"pump": "^3.0.0",
"readable-stream": "^3.6.0",
"rfdc": "^1.3.0",
@@ -5469,6 +6459,14 @@
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
+ },
+ "string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "requires": {
+ "safe-buffer": "~5.2.0"
+ }
}
}
},
@@ -5478,9 +6476,9 @@
"integrity": "sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg=="
},
"prebuild-install": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.0.1.tgz",
- "integrity": "sha512-QBSab31WqkyxpnMWQxubYAHR5S9B2+r81ucocew34Fkl98FhvKIF50jIJnNOBmAZfyNV7vE5T6gd3hTVWgY6tg==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
+ "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
"devOptional": true,
"requires": {
"detect-libc": "^2.0.0",
@@ -5490,20 +6488,11 @@
"mkdirp-classic": "^0.5.3",
"napi-build-utils": "^1.0.1",
"node-abi": "^3.3.0",
- "npmlog": "^4.0.1",
"pump": "^3.0.0",
"rc": "^1.2.7",
"simple-get": "^4.0.0",
"tar-fs": "^2.0.0",
"tunnel-agent": "^0.6.0"
- },
- "dependencies": {
- "detect-libc": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
- "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
- "devOptional": true
- }
}
},
"prelude-ls": {
@@ -5512,17 +6501,31 @@
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="
+ },
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
- "devOptional": true
+ "dev": true
},
"process-warning": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-1.0.0.tgz",
"integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q=="
},
+ "proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "requires": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ }
+ },
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -5538,6 +6541,14 @@
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
},
+ "qs": {
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
+ "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
+ "requires": {
+ "side-channel": "^1.0.4"
+ }
+ },
"queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -5549,6 +6560,22 @@
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
"integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="
},
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
+ },
+ "raw-body": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+ "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "requires": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
"rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@@ -5564,24 +6591,21 @@
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
"devOptional": true
}
}
},
"readable-stream": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
- "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
- "devOptional": true,
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==",
+ "dev": true,
"requires": {
"core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
}
},
"readdirp": {
@@ -5607,15 +6631,15 @@
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
},
"resolve": {
- "version": "1.22.0",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
- "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==",
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
"dev": true,
"requires": {
- "is-core-module": "^2.8.1",
+ "is-core-module": "^2.9.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
}
@@ -5656,9 +6680,14 @@
}
},
"safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"sax": {
"version": "1.2.4",
@@ -5666,19 +6695,71 @@
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"semver": {
- "version": "7.3.5",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
- "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"devOptional": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
- "set-blocking": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
- "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
- "devOptional": true
+ "send": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+ "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ }
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
+ "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.18.0"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"sha.js": {
"version": "2.4.11",
@@ -5704,11 +6785,15 @@
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
- "signal-exit": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
- "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
- "devOptional": true
+ "side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "requires": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ }
},
"simple-concat": {
"version": "1.0.1",
@@ -5734,11 +6819,12 @@
"dev": true
},
"sonic-boom": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.6.0.tgz",
- "integrity": "sha512-6xYZFRmDEtxGqfOKcDQ4cPLrNa0SPEDI+wlzDAHowXE6YV42NeXqg9mP2KkiM8JVu3lHfZ2iQKYlGOz+kTpphg==",
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz",
+ "integrity": "sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==",
"requires": {
- "atomic-sleep": "^1.0.0"
+ "atomic-sleep": "^1.0.0",
+ "flatstr": "^1.0.12"
}
},
"source-map": {
@@ -5774,51 +6860,55 @@
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
+ },
+ "string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "requires": {
+ "safe-buffer": "~5.2.0"
+ }
}
}
},
- "sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
- },
"sqlite": {
- "version": "4.0.25",
- "resolved": "https://registry.npmjs.org/sqlite/-/sqlite-4.0.25.tgz",
- "integrity": "sha512-gqCEcLF8FOTeW/na3SRYWLQkw2jZXgVj1DdgRJbm0jvrhnUgBIuNDUUm649AnBNDNHhI5XskwT8dvc8vearRLQ=="
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/sqlite/-/sqlite-4.1.2.tgz",
+ "integrity": "sha512-FlBG51gHbux5vPjwnoqFEghNGvnTMTbHyiI09U3qFTQs9AtWuwd4i++6+WCusCXKrVdIDLzfdGekrolr3m4U4A=="
+ },
+ "statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
},
"string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "requires": {
- "safe-buffer": "~5.1.0"
- }
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
+ "dev": true
},
"string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
- "devOptional": true,
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
}
},
"strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "devOptional": true,
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"requires": {
- "ansi-regex": "^2.0.0"
+ "ansi-regex": "^5.0.1"
}
},
"strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
"dev": true
},
"strip-json-comments": {
@@ -5827,11 +6917,11 @@
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
},
"supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"requires": {
- "has-flag": "^3.0.0"
+ "has-flag": "^4.0.0"
}
},
"supports-preserve-symlinks-flag": {
@@ -5875,13 +6965,22 @@
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
+ },
+ "string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "devOptional": true,
+ "requires": {
+ "safe-buffer": "~5.2.0"
+ }
}
}
},
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
"thenify": {
@@ -5895,7 +6994,7 @@
"thenify-all": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
- "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
"requires": {
"thenify": ">= 3.1.0 < 4"
}
@@ -5908,6 +7007,44 @@
"requires": {
"readable-stream": "~2.3.6",
"xtend": "~4.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
}
},
"to-regex-range": {
@@ -5919,6 +7056,11 @@
"is-number": "^7.0.0"
}
},
+ "toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
+ },
"tree-kill": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
@@ -5926,20 +7068,20 @@
"dev": true
},
"ts-node-dev": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-1.1.8.tgz",
- "integrity": "sha512-Q/m3vEwzYwLZKmV6/0VlFxcZzVV/xcgOt+Tx/VjaaRHyiBcFlV0541yrT09QjzzCxlDZ34OzKjrFAynlmtflEg==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz",
+ "integrity": "sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==",
"dev": true,
"requires": {
"chokidar": "^3.5.1",
"dynamic-dedupe": "^0.3.0",
- "minimist": "^1.2.5",
+ "minimist": "^1.2.6",
"mkdirp": "^1.0.4",
"resolve": "^1.0.0",
"rimraf": "^2.6.1",
"source-map-support": "^0.5.12",
"tree-kill": "^1.2.2",
- "ts-node": "^9.0.0",
+ "ts-node": "^10.4.0",
"tsconfig": "^7.0.0"
},
"dependencies": {
@@ -5953,16 +7095,23 @@
}
},
"ts-node": {
- "version": "9.1.1",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz",
- "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==",
+ "version": "10.9.1",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
+ "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
"dev": true,
"requires": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
- "source-map-support": "^0.5.17",
+ "v8-compile-cache-lib": "^3.0.1",
"yn": "3.1.1"
}
}
@@ -5983,15 +7132,15 @@
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
"dev": true
}
}
},
"tslib": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
- "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
},
"tsutils": {
"version": "3.21.0",
@@ -6013,7 +7162,7 @@
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
"devOptional": true,
"requires": {
"safe-buffer": "^5.0.1"
@@ -6034,10 +7183,19 @@
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true
},
+ "type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ }
+ },
"typeorm": {
- "version": "0.2.44",
- "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.2.44.tgz",
- "integrity": "sha512-yFyb9Ts73vGaS/O06TvLpzvT5U/ngO31GeciNc0eoH7P1QcG8kVZdOy9FHJqkTeDmIljMRgWjbYUoMw53ZY7Xw==",
+ "version": "0.2.45",
+ "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.2.45.tgz",
+ "integrity": "sha512-c0rCO8VMJ3ER7JQ73xfk0zDnVv0WDjpsP6Q1m6CVKul7DB9iVdWLRjPzc8v2eaeBuomsbZ2+gTaYr8k1gm3bYA==",
"requires": {
"@sqltools/formatter": "^1.2.2",
"app-root-path": "^3.0.0",
@@ -6058,34 +7216,23 @@
"zen-observable-ts": "^1.0.0"
},
"dependencies": {
- "argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
- },
- "buffer": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
- "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
- "requires": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.2.1"
- }
- },
- "js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "requires": {
- "argparse": "^2.0.1"
- }
+ "dotenv": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz",
+ "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g=="
}
}
},
"typescript": {
- "version": "4.5.5",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
- "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA=="
+ "version": "4.8.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz",
+ "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==",
+ "dev": true
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
},
"untildify": {
"version": "4.0.0",
@@ -6102,22 +7249,47 @@
"punycode": "^2.1.0"
}
},
+ "util": {
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
+ "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+ "requires": {
+ "inherits": "2.0.3"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw=="
+ }
+ }
+ },
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
- "v8-compile-cache": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
- "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
+ "v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"dev": true
},
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
+ },
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -6127,15 +7299,6 @@
"isexe": "^2.0.0"
}
},
- "wide-align": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
- "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
- "devOptional": true,
- "requires": {
- "string-width": "^1.0.2 || 2"
- }
- },
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
@@ -6150,63 +7313,12 @@
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
- },
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
- },
- "string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- }
- },
- "strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "requires": {
- "ansi-regex": "^5.0.1"
- }
- }
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"xml2js": {
"version": "0.4.23",
@@ -6240,9 +7352,9 @@
"devOptional": true
},
"yargs": {
- "version": "17.3.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz",
- "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==",
+ "version": "17.5.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
+ "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
"requires": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
@@ -6251,42 +7363,12 @@
"string-width": "^4.2.3",
"y18n": "^5.0.5",
"yargs-parser": "^21.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
- },
- "string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- }
- },
- "strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "requires": {
- "ansi-regex": "^5.0.1"
- }
- }
}
},
"yargs-parser": {
- "version": "21.0.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
- "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg=="
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="
},
"yn": {
"version": "3.1.1",
@@ -6294,6 +7376,12 @@
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"dev": true
},
+ "yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true
+ },
"zen-observable": {
"version": "0.8.15",
"resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz",
@@ -6307,6 +7395,11 @@
"@types/zen-observable": "0.8.3",
"zen-observable": "0.8.15"
}
+ },
+ "zlib": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/zlib/-/zlib-1.0.5.tgz",
+ "integrity": "sha512-40fpE2II+Cd3k8HWTWONfeKE2jL+P42iWJ1zzps5W51qcTsOUKM5Q5m2PFb0CLxlmFAaUuUdJGc3OfZy947v0w=="
}
}
}
diff --git a/package.json b/package.json
index 27a502a..1676cee 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
- "name": "@runejs/store",
- "version": "1.0.0-beta.1",
+ "name": "@runejs/filestore",
+ "version": "1.0.0-next.0",
"description": "Tools for managing and indexing the asset file store used with RuneJS.",
"main": "./index.js",
"types": "./index.d.ts",
@@ -8,20 +8,20 @@
".": "./index.js",
"./config": "./config/index.js",
"./db": "./db/index.js",
- "./scripts": "./scripts/index.js",
- "./util": "./util/index.js",
- "./indexer": "./scripts/indexer.js",
- "./unpacker": "./scripts/unpacker.js"
+ "./file-system": "./file-system/index.js",
+ "./http": "./http/index.js",
+ "./openrs2": "./openrs2/index.js"
},
"scripts": {
"build": "tsc",
- "start": "ts-node-dev src/dev.ts",
+ "start": "ts-node-dev src/scripts/dev.ts",
"lint": "eslint --ext .ts src",
"lint:fix": "eslint --ext .ts src --fix",
- "unpack": "ts-node-dev src/scripts/unpacker.ts",
- "unpacker": "npm run unpack",
- "index": "ts-node-dev src/scripts/indexer.ts",
- "indexer": "npm run index",
+ "http": "ts-node-dev --max-old-space-size=2048 src/http/server.ts",
+ "namehash": "ts-node-dev --max-old-space-size=2048 src/scripts/name-hasher.ts",
+ "unpack": "ts-node-dev --max-old-space-size=2048 src/scripts/unpacker.ts",
+ "index": "ts-node-dev --max-old-space-size=2048 src/scripts/indexer.ts",
+ "builds": "ts-node-dev src/scripts/builds.ts",
"copy-documents": "copyfiles package.json README.md .npmignore LICENSE lib",
"package": "rimraf lib && npm i && npm run build && npm run copy-documents && cd lib && npm publish --dry-run",
"publish:next": "npm run package && cd lib && npm publish -tag next",
@@ -30,7 +30,7 @@
},
"repository": {
"type": "git",
- "url": "git+ssh://git@github.com/runejs/store.git"
+ "url": "git+ssh://git@github.com/runejs/filestore.git"
},
"keywords": [
"runejs",
@@ -44,27 +44,30 @@
"author": "Kikorono",
"license": "GPL-3.0",
"bugs": {
- "url": "https://github.com/runejs/store/issues"
- },
- "homepage": "https://github.com/runejs/store#readme",
- "peerDependencies": {
- "@runejs/common": "2.0.2-beta.2",
- "graceful-fs": ">=4.2.0",
- "tslib": ">=2.3.0",
- "typescript": ">=4.5.0"
+ "url": "https://github.com/runejs/filestore/issues"
},
+ "homepage": "https://github.com/runejs/filestore#readme",
"dependencies": {
- "@runejs/common": "2.0.2-beta.2",
- "graceful-fs": "^4.2.0",
+ "@decorators/di": "^1.0.3",
+ "@decorators/express": "^2.6.0",
+ "@runejs/common": "3.0.0-beta.10",
+ "adm-zip": "^0.5.9",
+ "axios": "^0.27.2",
+ "compressjs": "^1.0.3",
+ "express": "^4.18.1",
+ "graceful-fs": ">=4.2.0",
"json5": "^2.2.0",
"reflect-metadata": "^0.1.13",
"sqlite": "^4.0.25",
- "tslib": "^2.3.1",
+ "tslib": ">=2.4.0",
"typeorm": "^0.2.44",
- "yargs": "^17.3.1"
+ "yargs": "^17.3.1",
+ "zlib": "^1.0.5"
},
"devDependencies": {
"@runejs/eslint-config": "^1.1.0",
+ "@types/adm-zip": "^0.5.0",
+ "@types/express": "^4.17.13",
"@types/graceful-fs": "^4.1.5",
"@types/node": "^16.11.26",
"@types/yargs": "^17.0.9",
@@ -75,15 +78,7 @@
"eslint": "^8.11.0",
"rimraf": "^3.0.2",
"source-map-support": "^0.5.21",
- "ts-node-dev": "^1.1.8",
- "typescript": "^4.5.5"
- },
- "eslintConfig": {
- "extends": [
- "@runejs/eslint-config"
- ],
- "parserOptions": {
- "project": "./tsconfig.json"
- }
+ "ts-node-dev": "^2.0.0",
+ "typescript": "^4.7.4"
}
}
diff --git a/src/archive.ts b/src/archive.ts
deleted file mode 100644
index a0d3634..0000000
--- a/src/archive.ts
+++ /dev/null
@@ -1,448 +0,0 @@
-import { join } from 'path';
-import { existsSync, mkdirSync, rmSync } from 'graceful-fs';
-import { ByteBuffer, logger } from '@runejs/common';
-
-import { ArchiveFormat, FileState, FlatFile, Group } from './index';
-import { ArchiveIndexEntity } from './db';
-import { FileBreadcrumb, IndexedFile } from './indexed-file';
-import { ArchiveConfig } from './config';
-
-
-export class Archive extends IndexedFile {
-
- public readonly config: ArchiveConfig;
- public readonly groups: Map;
-
- private _missingEncryptionKeys: number;
-
- public constructor(index: ArchiveIndexEntity, config: ArchiveConfig, breadcrumb?: Partial) {
- super(index, breadcrumb);
-
- this.groups = new Map();
-
- config.filesNamed = config.filesNamed || false;
- config.versioned = config.versioned || false;
-
- this.config = config;
- this.encryption = this.config.encryption || 'none';
- this.compression = this.config.compression || 'none';
- }
-
- public override decode(decodeGroups: boolean = true): ByteBuffer | null {
- logger.info(`Decoding archive ${this.name}...`);
-
- this._missingEncryptionKeys = 0;
-
- this.unpack();
-
- logger.info(`Archive ${this.name} checksum: ${this.crc32}`);
-
- if(this.numericKey === 255) {
- return this.data;
- }
-
- this.decompress();
-
- if(!this._data?.length) {
- logger.error(`Error decompressing file data.`);
- return null;
- }
-
- const archiveData = this._data;
- const format = this.index.format = archiveData.get('byte', 'unsigned');
- const filesNamed = (archiveData.get('byte', 'unsigned') & 0x01) !== 0;
- const groupCount = this.index.groupCount = archiveData.get('short', 'unsigned');
-
- logger.info(`${groupCount} groups were found within the ${this.name} archive.`);
-
- if(filesNamed !== this.config.filesNamed) {
- logger.warn(`Archive file name flag mismatch; expected ${this.config.filesNamed} ` +
- `but received ${filesNamed}!`);
- }
-
- const groupIndices: number[] = new Array(groupCount);
- let accumulator = 0;
-
- for(let i = 0; i < groupCount; i++) {
- const delta = archiveData.get('short', 'unsigned');
- groupIndices[i] = accumulator += delta;
- const group = new Group(this.indexService.validateGroup({
- numericKey: groupIndices[i],
- name: String(groupIndices[i]),
- archive: this
- }), {
- store: this.store,
- archive: this
- });
-
- group.setState(FileState.encoded);
- this.set(groupIndices[i], group);
- }
-
- if(filesNamed) {
- for(const groupIndex of groupIndices) {
- const group = this.get(groupIndex);
- group.nameHash = group.index.nameHash = archiveData.get('int');
- group.name = group.index.name = this.store.findFileName(group.nameHash, String(group.nameHash));
- }
- }
-
- /* read the crc values */
- for(const groupIndex of groupIndices) {
- const group = this.get(groupIndex);
- group.crc32 = archiveData.get('int');
- }
-
- /* read the version numbers */
- for(const groupIndex of groupIndices) {
- const group = this.get(groupIndex);
- group.version = archiveData.get('int');
- }
-
- /* read the child count */
- const groupChildCounts: Map = new Map();
-
- for(const groupIndex of groupIndices) {
- // group file count
- groupChildCounts.set(groupIndex, archiveData.get('short', 'unsigned'));
- }
-
- /* read the file groupIndices */
- for(const groupIndex of groupIndices) {
- const group = this.get(groupIndex) as Group;
- const fileCount = groupChildCounts.get(groupIndex);
-
- accumulator = 0;
- for(let i = 0; i < fileCount; i++) {
- const delta = archiveData.get('short', 'unsigned');
- const childFileIndex = accumulator += delta;
- group.set(childFileIndex, new FlatFile(this.indexService.validateFile({
- numericKey: childFileIndex,
- name: String(childFileIndex),
- group, archive: this
- }), {
- store: this.store,
- archive: this,
- group: group
- }));
- }
- }
-
- /* read the child name hashes */
- if(filesNamed) {
- for(const groupIndex of groupIndices) {
- const fileGroup = this.get(groupIndex) as Group;
-
- for(const [ , childFile ] of fileGroup.files) {
- const nameHash = archiveData.get('int');
- if(childFile) {
- childFile.nameHash = childFile.index.nameHash = nameHash;
- childFile.name = childFile.index.name =
- this.store.findFileName(childFile.nameHash, String(childFile.nameHash));
- }
- }
- }
- }
-
- if(decodeGroups) {
- let successes = 0;
- let failures = 0;
-
- for(const [ , group ] of this.groups) {
- try {
- group.decode();
-
- if(group.data?.length && group.state === FileState.raw) {
- successes++;
- } else {
- failures++;
- }
- } catch(error) {
- logger.error(error);
- failures++;
- }
- }
-
- if(successes) {
- logger.info(`${groupCount} groups(s) were found, ` +
- `${successes} decompressed successfully.`);
- } else {
- logger.info(`${groupCount} groups(s) were found.`);
- }
-
- if(failures) {
- logger.error(`${failures} groups(s) failed to decompress.`);
- }
-
- if(this.missingEncryptionKeys) {
- logger.error(`Missing ${this.missingEncryptionKeys} XTEA decryption key(s).`);
- }
- } else {
- logger.info(`${groupCount} groups(s) were found.`);
- }
-
- this.setData(this._data, FileState.raw);
- return this._data ?? null;
- }
-
- public override encode(encodeGroups: boolean = true): ByteBuffer | null {
- if(this.numericKey === 255) {
- return this.store.encode();
- }
-
- const groups = this.groups;
- const groupCount = groups.size;
-
- // @TODO add sizes of all files instead of using a set amount here
- const buffer = new ByteBuffer(1000 * 1000);
-
- // Write index file header
- buffer.put(this.index.format ?? ArchiveFormat.original);
- buffer.put(this.config.filesNamed ? 1 : 0);
- buffer.put(groupCount, 'short');
-
- // Write file indexes
- let writtenFileIndex = 0;
- for(const [ , group ] of groups) {
- const val = group.numericKey;
- buffer.put(val - writtenFileIndex, 'short');
- writtenFileIndex = val;
- }
-
- // Write name hashes (if applicable)
- if(this.config.filesNamed) {
- for(const [ , file ] of groups) {
- buffer.put(file.nameHash ?? -1, 'int');
- }
- }
-
- // Write file crc values
- for(const [ , file ] of groups) {
- buffer.put(file.crc32 ?? -1, 'int');
- }
-
- // Write file version numbers
- for(const [ , ] of groups) {
- buffer.put(0, 'int');
- }
-
- // Write file group child counts
- for(const [ , group ] of groups) {
- buffer.put(group.files.size ?? 1, 'short');
- }
-
- // Write group file indices
- for(const [ , group ] of groups) {
- if(group.files.size > 1) {
- writtenFileIndex = 0;
-
- for(const [ , file ] of group.files) {
- const i = file.numericKey;
- buffer.put(i - writtenFileIndex, 'short');
- writtenFileIndex = i;
- }
- } else {
- buffer.put(0, 'short');
- }
- }
-
- // Write group file name hashes (if applicable)
- if(this.config.filesNamed) {
- for(const [ , group ] of groups) {
- if(group.files.size > 1) {
- for(const [ , file ] of group.files) {
- buffer.put(file.nameHash ?? -1, 'int');
- }
- } else {
- buffer.put(0, 'int');
- }
- }
- }
-
- const indexData = buffer?.flipWriter();
-
- if(indexData?.length) {
- this.setData(indexData, FileState.encoded);
- this.sha256 = this.index.sha256 = this.generateSha256();
- }
-
- if(encodeGroups) {
- this.groups.forEach(group => group.encode());
- }
-
- return this.data ?? null;
- }
-
- public override compress(compressGroups: boolean = true): ByteBuffer | null {
- if(compressGroups) {
- this.groups.forEach(group => group.compress());
- }
- return super.compress();
- }
-
- public override async read(compress: boolean = false, readDiskFiles: boolean = true): Promise {
- logger.info(`Reading archive ${this.name}...`);
-
- // Read in all groups within the archive
- const groupIndexes = await this.index.groups;
- for(const groupIndex of groupIndexes) {
- const group = new Group(groupIndex, {
- store: this.store,
- archive: this
- });
-
- this.groups.set(group.key, group);
- await group.read(false, readDiskFiles);
- }
-
- if(compress) {
- // Then compress them, if needed
- for(const [ , group ] of this.groups) {
- group.compress();
- }
- }
-
- logger.info(`${this.groups.size} groups(s) were loaded from the ${this.name} archive.`);
-
- this.encode();
-
- if(compress) {
- return this.compress();
- } else {
- return this._data;
- }
- }
-
- public override write(): void {
- if(!this.groups.size) {
- logger.error(`Error writing archive ${this.name || this.key}: Archive is empty.`);
- return;
- }
-
- const start = Date.now();
- logger.info(`Writing archive ${this.name || this.key}...`);
-
- const archivePath = this.outputPath;
-
- if(existsSync(archivePath)) {
- rmSync(archivePath, { recursive: true, force: true });
- }
-
- mkdirSync(archivePath, { recursive: true });
-
- Array.from(this.groups.values()).forEach(group => group.write());
-
- const end = Date.now();
- logger.info(`Archive ${this.name || this.key} written in ${(end - start) / 1000} seconds.`)
- }
-
- public async saveIndexData(saveGroups: boolean = true, saveFiles: boolean = true): Promise {
- if(!this.groups.size) {
- return;
- }
-
- logger.info(`Saving archive ${this.name} to index...`);
-
- await this.indexService.saveArchiveIndex(this);
-
- if(saveGroups) {
- await this.saveGroupIndexes(saveFiles);
- }
-
- logger.info(`Archive ${this.name} indexing complete.`);
- }
-
- public async saveGroupIndexes(saveFlatFiles: boolean = true): Promise {
- const groups = Array.from(this.groups.values());
-
- if(groups?.length) {
- logger.info(`Saving archive ${ this.name } group indexes...`);
- await this.indexService.saveGroupIndexes(groups);
- }
-
- if(saveFlatFiles) {
- await this.saveFlatFileIndexes();
- }
- }
-
- public async saveFlatFileIndexes(): Promise {
- if(this.config.flatten) {
- return;
- }
-
- const groups = Array.from(this.groups.values());
- const flatFiles = groups.filter(group => {
- if(!group?.files?.size || group?.index?.flatFile) {
- return false;
- }
- return group.files.size > 1;
- }).map(group => Array.from(group.files.values()))
- .reduce((a, v) => a.concat(v), []);
-
- if(flatFiles?.length) {
- logger.info(`Saving archive ${ this.name } flat file indexes...`);
- await this.indexService.saveFileIndexes(flatFiles);
- }
- }
-
- public has(groupKey: string): boolean;
- public has(groupKey: number): boolean;
- public has(groupKey: string | number): boolean;
- public has(groupKey: string | number): boolean {
- return this.groups.has(String(groupKey));
- }
-
- public get(groupKey: string): Group | null;
- public get(groupKey: number): Group | null;
- public get(groupKey: string | number): Group | null;
- public get(groupKey: string | number): Group | null {
- return this.groups.get(String(groupKey)) ?? null;
- }
-
- public set(groupKey: string, group: Group): void;
- public set(groupKey: number, group: Group): void;
- public set(groupKey: string | number, group: Group): void;
- public set(groupKey: string | number, group: Group): void {
- this.groups.set(String(groupKey), group);
- }
-
- public find(groupName: string): Archive | Group | FlatFile | null {
- const children = Array.from(this.groups.values());
- return children.find(child => child?.name === groupName) ?? null;
- }
-
- public incrementMissingEncryptionKeys(): void {
- this._missingEncryptionKeys++;
- }
-
- public get missingEncryptionKeys(): number {
- return this._missingEncryptionKeys;
- }
-
- public override get path(): string {
- if(!this.store?.path) {
- throw new Error(`Error generating archive path; Store path not provided for archive ${this.key}.`);
- }
- if(!this.name) {
- throw new Error(`Error generating archive path; Name not provided for archive ${this.key}.`);
- }
-
- return join(this.store.path, 'unpacked', this.name);
- }
-
- public override get outputPath(): string {
- if(!this.store?.outputPath) {
- throw new Error(`Error generating archive output path; Store output path not provided for archive ${this.key}.`);
- }
- if(!this.name) {
- throw new Error(`Error generating archive output path; Name not provided for archive ${this.key}.`);
- }
-
- return join(this.store.outputPath, this.name);
- }
-
- public get versioned(): boolean {
- return this.config.versioned;
- }
-
-}
diff --git a/src/config/archive-config.ts b/src/config/archive-config.ts
index 611e6d8..e714e44 100644
--- a/src/config/archive-config.ts
+++ b/src/config/archive-config.ts
@@ -1,16 +1,14 @@
-import { CompressionMethod } from '@runejs/common/compress';
import { EncryptionMethod } from '@runejs/common/encrypt';
export interface ArchiveConfig {
- index: number;
- name: string;
- versioned?: boolean;
- compression?: CompressionMethod;
- encryption?: EncryptionMethod | [ EncryptionMethod, string ];
+ key: number;
+}
+
+
+export interface Js5ArchiveConfig extends ArchiveConfig {
+ encryption?: [ EncryptionMethod, string ];
contentType?: string;
- filesNamed?: boolean;
- flatten?: boolean;
+ flattenGroups?: boolean;
groupNames?: { [key: string]: number };
- build?: number;
}
diff --git a/src/config/archive-flags.ts b/src/config/archive-flags.ts
new file mode 100644
index 0000000..4d3958b
--- /dev/null
+++ b/src/config/archive-flags.ts
@@ -0,0 +1,6 @@
+export const archiveFlags = (flags: number) => ({
+ groupNames: (flags & 0x01) !== 0,
+ whirlpoolDigests: (flags & 0x02) !== 0,
+ groupSizes: (flags & 0x04) !== 0,
+ decompressedCrcs: (flags & 0x08) !== 0,
+});
diff --git a/src/config/file-error.ts b/src/config/file-error.ts
new file mode 100644
index 0000000..c91a863
--- /dev/null
+++ b/src/config/file-error.ts
@@ -0,0 +1,3 @@
+export type FileError =
+ 'FILE_MISSING' |
+ 'MISSING_ENCRYPTION_KEYS';
diff --git a/src/config/file-type.ts b/src/config/file-type.ts
new file mode 100644
index 0000000..199e6d5
--- /dev/null
+++ b/src/config/file-type.ts
@@ -0,0 +1,11 @@
+export type Js5FileType =
+ 'FILE' |
+ 'GROUP' |
+ 'ARCHIVE' |
+ 'STORE';
+
+export type JagFileType =
+ 'FILE' |
+ 'ARCHIVE' |
+ 'STORE' |
+ 'CACHE';
diff --git a/src/config/index.ts b/src/config/index.ts
index 76f19cd..9fcabeb 100644
--- a/src/config/index.ts
+++ b/src/config/index.ts
@@ -1,2 +1,6 @@
export * from './archive-config';
export * from './archive-format';
+export * from './file-error';
+export * from './file-type';
+export * from './archive-flags';
+export * from './name-hasher';
diff --git a/src/config/name-hasher.ts b/src/config/name-hasher.ts
new file mode 100644
index 0000000..ba1d7b8
--- /dev/null
+++ b/src/config/name-hasher.ts
@@ -0,0 +1,98 @@
+import { join } from 'path';
+import { existsSync, readFileSync } from 'graceful-fs';
+import { logger } from '@runejs/common';
+
+
+export class NameHasher {
+
+ readonly configPath: string;
+ readonly fileNameHashes: Map;
+
+ constructor(configPath: string) {
+ this.configPath = configPath;
+ this.fileNameHashes = new Map();
+ this.loadFileNames();
+ }
+
+ hashJagFileName(fileName: string): number {
+ const INT_MAX = 2147483648;
+ let hash = 0;
+ fileName = fileName.toUpperCase();
+
+ for (let i = 0; i < fileName.length; i++) {
+ hash = hash * 61 + fileName.charCodeAt(i) - 32;
+
+ // Emulate Java's INT overflow-wrapping
+ while (hash > INT_MAX) {
+ const diff = hash - INT_MAX;
+ hash = -INT_MAX + diff;
+ }
+
+ while (hash < -INT_MAX) {
+ const diff = Math.abs(hash) - INT_MAX;
+ hash = INT_MAX - diff;
+ }
+ }
+
+ return hash;
+ }
+
+ hashJs5FileName(fileName: string): number {
+ if (!fileName) {
+ return 0;
+ }
+
+ let hash = 0;
+ for (let i = 0; i < fileName.length; i++) {
+ hash = fileName.charCodeAt(i) + ((hash << 5) - hash);
+ }
+
+ const nameHash = hash | 0;
+
+ this.fileNameHashes.set(nameHash, fileName);
+
+ return nameHash;
+ }
+
+ findFileName(nameHash: string | number | undefined, defaultName?: string | undefined): string | undefined {
+ if (!this.fileNameHashes.size) {
+ this.loadFileNames();
+ }
+
+ if (nameHash === undefined || nameHash === null) {
+ return defaultName;
+ }
+
+ if (typeof nameHash === 'string') {
+ nameHash = Number(nameHash);
+ }
+
+ if (isNaN(nameHash) || nameHash === -1 || nameHash === 0) {
+ return defaultName;
+ }
+
+ return this.fileNameHashes.get(nameHash) || defaultName;
+ }
+
+ loadFileNames(): void {
+ const configPath = join(this.configPath, 'name-hashes.json');
+ if (!existsSync(configPath)) {
+ logger.error(`Error loading file names: ${configPath} was not found.`);
+ return;
+ }
+
+ const nameTable = JSON.parse(
+ readFileSync(configPath, 'utf-8')
+ ) as { [key: string]: string };
+
+ Object.keys(nameTable).forEach(
+ nameHash => this.fileNameHashes.set(Number(nameHash), nameTable[nameHash])
+ );
+
+ if(!this.fileNameHashes.size) {
+ logger.error(`Error reading file name lookup table. ` +
+ `Please ensure that the ${configPath} file exists and is valid.`);
+ }
+ }
+
+}
diff --git a/src/db/archive-index.entity.ts b/src/db/archive-index.entity.ts
deleted file mode 100644
index 3ef8d8c..0000000
--- a/src/db/archive-index.entity.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany, PrimaryColumn } from 'typeorm';
-
-import { IndexEntity } from './index-entity';
-import { StoreIndexEntity } from './store-index.entity';
-import { GroupIndexEntity } from './group-index.entity';
-import { FileState } from '../file-state';
-
-
-@Entity('archive_index')
-@Index('archive_identifier', [ 'key', 'gameBuild' ], { unique: true })
-export class ArchiveIndexEntity extends IndexEntity {
-
- @PrimaryColumn('text', { name: 'game_build', nullable: false, unique: false })
- gameBuild: string;
-
- @Column('integer', { name: 'group_count', nullable: false, default: 0 })
- groupCount: number = 0;
-
- @Column('integer', { name: 'format', nullable: false, default: 5 })
- format: number = 5;
-
- @Column('text', { name: 'data_state', nullable: false })
- state: FileState;
-
- @ManyToOne(() => StoreIndexEntity, async store => store.archives,
- { primary: true, onDelete: 'CASCADE' })
- @JoinColumn({ name: 'game_build', referencedColumnName: 'gameBuild' })
- store: StoreIndexEntity;
-
- @OneToMany(() => GroupIndexEntity, group => group.archive,
- { cascade: true, lazy: true })
- groups: Promise | GroupIndexEntity[];
-
-}
diff --git a/src/db/file-index.entity.ts b/src/db/file-index.entity.ts
deleted file mode 100644
index 90ae874..0000000
--- a/src/db/file-index.entity.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import { Column, Entity, Index, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm';
-
-import { IndexEntity } from './index-entity';
-import { StoreIndexEntity } from './store-index.entity';
-import { ArchiveIndexEntity } from './archive-index.entity';
-import { GroupIndexEntity } from './group-index.entity';
-
-
-@Entity('file_index')
-@Index('file_identifier', [ 'key', 'gameBuild', 'archiveKey', 'groupKey' ], { unique: true })
-export class FileIndexEntity extends IndexEntity {
-
- @PrimaryColumn('text', { name: 'game_build', nullable: false, unique: false })
- gameBuild: string;
-
- @PrimaryColumn('integer', { name: 'archive_key', unique: false, nullable: false })
- archiveKey: number;
-
- @PrimaryColumn('integer', { name: 'group_key', unique: false, nullable: false })
- groupKey: number;
-
- @Column('integer', { name: 'name_hash', nullable: true, default: 0 })
- nameHash: number = 0;
-
- @Column('integer', { nullable: false, default: 0 })
- version: number = 0;
-
- @Column('integer', { name: 'stripe_count', nullable: false, default: 1 })
- stripeCount: number = 1;
-
- @Column('text', { nullable: true, default: null })
- stripes: string | null = null;
-
- @ManyToOne(() => StoreIndexEntity, async store => store.files,
- { primary: true, onDelete: 'CASCADE' })
- @JoinColumn({ name: 'game_build', referencedColumnName: 'gameBuild' })
- store: StoreIndexEntity;
-
- @ManyToOne(() => ArchiveIndexEntity, async archive => archive.groups,
- { primary: true, onDelete: 'CASCADE' })
- @JoinColumn([
- { name: 'archive_key', referencedColumnName: 'key' },
- { name: 'game_build', referencedColumnName: 'gameBuild' }
- ])
- archive: ArchiveIndexEntity;
-
- @ManyToOne(() => GroupIndexEntity, async group => group.files,
- { primary: true, onDelete: 'CASCADE' })
- @JoinColumn([
- { name: 'archive_key', referencedColumnName: 'archiveKey' },
- { name: 'group_key', referencedColumnName: 'key' },
- { name: 'game_build', referencedColumnName: 'gameBuild' }
- ])
- group: GroupIndexEntity;
-
-}
diff --git a/src/db/group-index.entity.ts b/src/db/group-index.entity.ts
deleted file mode 100644
index db87aca..0000000
--- a/src/db/group-index.entity.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany, PrimaryColumn } from 'typeorm';
-import { FileIndexEntity } from './file-index.entity';
-import { ArchiveIndexEntity } from './archive-index.entity';
-import { IndexEntity } from './index-entity';
-import { StoreIndexEntity } from './store-index.entity';
-import { FileState } from '../file-state';
-
-
-@Entity('group_index')
-@Index('group_identifier', [ 'key', 'gameBuild', 'archiveKey' ], { unique: true })
-export class GroupIndexEntity extends IndexEntity {
-
- @PrimaryColumn('text', { name: 'game_build', nullable: false, unique: false })
- gameBuild: string;
-
- @PrimaryColumn('integer', { name: 'archive_key', unique: false, nullable: false })
- archiveKey: number;
-
- @Column('boolean', { name: 'flat', nullable: false, default: false })
- flatFile: boolean = false;
-
- @Column('integer', { name: 'stripe_count', nullable: false, default: 1 })
- stripeCount: number = 1;
-
- @Column('text', { nullable: true, default: null })
- stripes: string | null = null;
-
- @Column('integer', { name: 'name_hash', nullable: true, default: 0 })
- nameHash: number = 0;
-
- @Column('integer', { nullable: false, default: 0 })
- version: number = 0;
-
- @Column('text', { name: 'data_state', nullable: false })
- state: FileState;
-
- @ManyToOne(() => StoreIndexEntity, async store => store.groups,
- { primary: true, onDelete: 'CASCADE' })
- @JoinColumn({ name: 'game_build', referencedColumnName: 'gameBuild' })
- store: StoreIndexEntity;
-
- @ManyToOne(() => ArchiveIndexEntity, async archive => archive.groups,
- { primary: true, onDelete: 'CASCADE' })
- @JoinColumn([
- { name: 'archive_key', referencedColumnName: 'key' },
- { name: 'game_build', referencedColumnName: 'gameBuild' }
- ])
- archive: ArchiveIndexEntity;
-
- @OneToMany(() => FileIndexEntity, fileIndex => fileIndex.group,
- { cascade: true, lazy: true })
- files: Promise | FileIndexEntity[];
-
-}
diff --git a/src/db/index-database.ts b/src/db/index-database.ts
new file mode 100644
index 0000000..e54b09d
--- /dev/null
+++ b/src/db/index-database.ts
@@ -0,0 +1,71 @@
+import { Connection, createConnection, LoggerOptions, Repository } from 'typeorm';
+import { join } from 'path';
+import { existsSync, mkdirSync } from 'graceful-fs';
+
+
+export abstract class IndexDatabase {
+
+ protected readonly gameBuild: string;
+ protected readonly databasePath: string;
+ protected readonly loggerOptions: LoggerOptions;
+
+ protected _connection: Connection;
+ protected _repository: Repository;
+
+ protected constructor(
+ gameBuild: string,
+ databasePath: string,
+ loggerOptions: LoggerOptions = 'all'
+ ) {
+ this.gameBuild = gameBuild;
+ this.databasePath = databasePath;
+ // [ 'error', 'warn' ], 'all', etc...
+ this.loggerOptions = loggerOptions;
+ }
+
+ abstract openConnection(): Promise;
+
+ abstract upsertIndexes(indexEntities: ENTITY[]): Promise;
+
+ async getIndexes(where: WHERE): Promise {
+ return await this.repository.find({
+ where: { ...where, gameBuild: this.gameBuild }
+ }) || [];
+ }
+
+ async getIndex(where: WHERE): Promise {
+ return await this.repository.findOne({
+ where: { ...where, gameBuild: this.gameBuild }
+ }) || null;
+ }
+
+ async saveIndexes(indexEntities: ENTITY[]): Promise {
+ await this.repository.save(indexEntities as any, {
+ chunk: 500,
+ transaction: false,
+ reload: false,
+ listeners: false,
+ });
+ }
+
+ async saveIndex(indexEntity: ENTITY): Promise {
+ return await this.repository.save(indexEntity as any);
+ }
+
+ async closeConnection(): Promise {
+ await this._connection.close();
+ }
+
+ get connection(): Connection {
+ return this._connection;
+ }
+
+ get repository(): Repository {
+ return this._repository;
+ }
+
+ get loaded(): boolean {
+ return !!this._connection;
+ }
+
+}
diff --git a/src/db/index-entity.ts b/src/db/index-entity.ts
deleted file mode 100644
index 2f40472..0000000
--- a/src/db/index-entity.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Column, CreateDateColumn, PrimaryColumn, UpdateDateColumn } from 'typeorm';
-import { FileState } from '../index';
-
-
-export abstract class IndexEntity {
-
- @PrimaryColumn('integer', { nullable: false, unique: false })
- key: number;
-
- @Column('text', { nullable: true, default: null })
- name: string | null = null;
-
- @Column('integer', { nullable: false, default: 0 })
- size: number = 0;
-
- @Column('integer', { nullable: true, default: null })
- crc32: number | null = null;
-
- @Column('text', { nullable: true, default: null })
- sha256: string | null = null;
-
- @Column('blob', { name: 'data', nullable: true, default: null })
- data: Buffer | null = null;
-
- @CreateDateColumn()
- created: Date;
-
- @UpdateDateColumn()
- updated: Date;
-
-}
diff --git a/src/db/index-service.ts b/src/db/index-service.ts
deleted file mode 100644
index c5425a0..0000000
--- a/src/db/index-service.ts
+++ /dev/null
@@ -1,435 +0,0 @@
-import { join } from 'path';
-import { existsSync, mkdirSync } from 'graceful-fs';
-import { Connection, createConnection, Repository } from 'typeorm';
-
-import { logger } from '@runejs/common';
-
-import { Archive, ArchiveFormat, FileState, FlatFile, Group, IndexedFile, IndexEntity, Store } from '../index';
-import { ArchiveIndexEntity, FileIndexEntity, GroupIndexEntity, StoreIndexEntity } from './index';
-
-
-const CHUNK_SIZE = 300; // 250
-
-
-export class IndexService {
-
- public readonly store: Store;
-
- private connection: Connection;
-
- public constructor(store: Store) {
- this.store = store;
- }
-
- public async load(): Promise {
- const indexPath = join(this.store.path, 'indexes');
-
- if(!existsSync(indexPath)) {
- mkdirSync(indexPath, { recursive: true });
- }
-
- this.connection = await createConnection({
- type: 'better-sqlite3',
- database: join(indexPath, `index_${this.store.gameBuild}.sqlite3`),
- entities: [ StoreIndexEntity, ArchiveIndexEntity, GroupIndexEntity, FileIndexEntity ],
- synchronize: true,
- // logging: [ 'error', 'warn' ],
- logging: 'all',
- name: 'index-service'
- });
- }
-
- public async getStoreIndex(): Promise {
- return await this.storeRepo.findOne({
- where: {
- gameBuild: this.store.gameBuild
- }
- }) || null;
- }
-
- public async saveStoreIndex(): Promise {
- let storeIndex = await this.getStoreIndex();
- let update = true;
-
- if(!storeIndex) {
- storeIndex = new StoreIndexEntity();
- update = false;
- }
-
- if(!storeIndex.gameBuild) {
- storeIndex.gameBuild = this.store.gameBuild;
- }
-
- if(!this.connection.isConnected) {
- logger.error(`The index database connection was closed prematurely.`);
- return null;
- }
-
- storeIndex.data = this.store.data?.toNodeBuffer() || null;
-
- delete storeIndex.archives;
- delete storeIndex.groups;
- delete storeIndex.files;
-
- let savedIndex: StoreIndexEntity;
-
- if(update) {
- const updateResult = await this.storeRepo.update({
- gameBuild: this.store.gameBuild
- }, storeIndex);
-
- if(!updateResult?.affected) {
- logger.error(`Main store entity update failed.`);
- return null;
- }
-
- savedIndex = await this.getStoreIndex();
- } else {
- savedIndex = await this.storeRepo.save(storeIndex);
- }
-
- if(savedIndex?.gameBuild !== this.store.gameBuild) {
- logger.error(`Error saving store index ${this.store.gameBuild}.`);
- return null;
- }
-
- logger.info(`Store index ${this.store.gameBuild} saved.`);
-
- return savedIndex;
- }
-
- public async getArchiveIndex(archive: Archive): Promise;
- public async getArchiveIndex(archiveKey: number): Promise;
- public async getArchiveIndex(archive: Archive | number): Promise {
- const key = typeof archive === 'number' ? archive : archive.numericKey;
- return await this.archiveRepo.findOne({
- where: {
- key, gameBuild: this.store.gameBuild
- },
- relations: [ 'groups' ]
- }) || null;
- }
-
- public async getArchiveIndexes(): Promise {
- return await this.archiveRepo.find({
- where: {
- gameBuild: this.store.gameBuild
- },
- order: {
- key: 'ASC'
- }
- }) || [];
- }
-
- public validateArchive(archive: Archive | Partial): ArchiveIndexEntity {
- const archiveIndex: ArchiveIndexEntity = archive.index ? archive.index : new ArchiveIndexEntity();
- if(!archive.index) {
- archive.index = archiveIndex;
- }
-
- this.updateEntityIndex(archive);
-
- archiveIndex.format = archiveIndex.format || ArchiveFormat.original;
- archiveIndex.gameBuild = this.store.gameBuild;
- archiveIndex.state = archive.state || FileState.unloaded;
- archiveIndex.groupCount = archive.groups?.size ?? 0;
-
- return archiveIndex;
- }
-
- public async saveArchiveIndex(archive: Archive): Promise {
- const archiveIndex = archive.index;
- const existingIndex = await this.archiveRepo.findOne({
- where: {
- key: archiveIndex.key,
- gameBuild: this.store.gameBuild
- }
- });
-
- let affected;
-
- if(existingIndex) {
- const { name, size, sha256, crc32, data, state } = archiveIndex;
- existingIndex.name = name;
- existingIndex.size = size;
- existingIndex.sha256 = sha256;
- existingIndex.crc32 = crc32;
- existingIndex.data = data;
- existingIndex.state = state;
-
- delete existingIndex.groups;
-
- const result = await this.archiveRepo.update({
- key: archiveIndex.key,
- gameBuild: this.store.gameBuild
- }, existingIndex);
-
- affected = result?.affected || 0;
- } else {
- delete archiveIndex.groups;
-
- const result = await this.archiveRepo.insert(archiveIndex);
- affected = result?.identifiers?.length || 0;
- }
-
- if(!affected) {
- logger.error(`Error updating archive ${archiveIndex.name} database index.`);
- } else {
- logger.info(`Archive ${archiveIndex.name} database index saved.`);
- }
-
- return await this.getArchiveIndex(archiveIndex.key);
- }
-
- public async getGroupIndex(group: Group): Promise;
- public async getGroupIndex(groupKey: number, archiveKey: number): Promise;
- public async getGroupIndex(group: Group | number, archive?: number): Promise {
- const key = typeof group === 'number' ? group : group.numericKey;
- const archiveKey = typeof group === 'number' ? archive : group.archive.numericKey;
-
- return await this.groupRepo.findOne({
- where: {
- key, archiveKey,
- gameBuild: this.store.gameBuild
- }
- }) || null;
- }
-
- public async getGroupIndexes(archive: ArchiveIndexEntity): Promise {
- return await this.groupRepo.find({
- where: {
- archiveKey: archive.key,
- gameBuild: this.store.gameBuild
- },
- order: {
- key: 'ASC'
- }
- }) || [];
- }
-
- public validateGroup(group: Group | Partial): GroupIndexEntity {
- const { stripes, archive, files } = group;
-
- const groupIndex: GroupIndexEntity = group.index ? group.index : new GroupIndexEntity();
- if(!group.index) {
- group.index = groupIndex;
- }
-
- this.updateEntityIndex(group);
-
- groupIndex.gameBuild = this.store.gameBuild;
- groupIndex.archiveKey = archive.numericKey;
- groupIndex.state = group.state;
- groupIndex.stripes = stripes?.length ? stripes.join(',') : null;
- groupIndex.stripeCount = stripes?.length || 1;
- groupIndex.flatFile = (files?.size === 1 || archive.config.flatten);
-
- return groupIndex;
- }
-
- public async saveGroupIndex(group: Group): Promise {
- if(!this.entityModified(group)) {
- return;
- }
- await this.groupRepo.upsert(this.validateGroup(group), []);
- }
-
- public async saveGroupIndexes(groups: Group[]): Promise {
- const groupIndexes = groups.filter(group => this.entityModified(group))
- .map(group => this.validateGroup(group));
-
- if(!groupIndexes.length) {
- logger.info(`No groups were modified.`);
- } else {
- await this.groupRepo.upsert(groupIndexes, []);
- }
- }
-
- public async getFileIndex(file: FlatFile): Promise {
- return await this.fileRepo.findOne({
- where: {
- key: file.numericKey,
- groupKey: file.group.numericKey,
- archiveKey: file.archive.numericKey,
- gameBuild: this.store.gameBuild
- }
- }) || null;
- }
-
- public async getFileIndexes(archiveOrGroup: ArchiveIndexEntity | GroupIndexEntity): Promise {
- if(archiveOrGroup instanceof ArchiveIndexEntity) {
- // Return all files for the specified archive
-
- return await this.fileRepo.find({
- where: {
- archiveKey: archiveOrGroup.key,
- gameBuild: this.store.gameBuild
- },
- order: {
- groupKey: 'ASC',
- key: 'ASC'
- }
- }) || [];
- } else {
- // Return all files for the specified group
-
- return await this.fileRepo.find({
- where: {
- groupKey: archiveOrGroup.key,
- archiveKey: archiveOrGroup.archiveKey,
- gameBuild: this.store.gameBuild
- },
- order: {
- key: 'ASC'
- }
- }) || [];
- }
- }
-
- public validateFile(file: FlatFile | Partial): FileIndexEntity {
- const { size, stripes, group, archive } = file;
-
- const fileIndex: FileIndexEntity = file.index ? file.index : new FileIndexEntity();
- if(!file.index) {
- file.index = fileIndex;
- }
-
- this.updateEntityIndex(file);
-
- fileIndex.gameBuild = this.store.gameBuild;
- fileIndex.store = this.store.index;
- fileIndex.archiveKey = archive.numericKey;
- fileIndex.archive = archive.index;
- fileIndex.groupKey = group.numericKey;
- fileIndex.group = group.index;
- fileIndex.stripes = stripes?.join(',') || String(size);
- fileIndex.stripeCount = fileIndex.stripes?.length || 1;
-
- return fileIndex;
- }
-
- public async saveFileIndex(file: FlatFile): Promise {
- if(!this.entityModified(file)) {
- return;
- }
- await this.fileRepo.upsert(this.validateFile(file), []);
- }
-
- public async saveFileIndexes(files: FlatFile[]): Promise {
- const flatFileIndexes = files.filter(file => this.entityModified(file))
- .map(file => this.validateFile(file));
-
- if(!flatFileIndexes.length) {
- logger.info(`No flat files were modified.`);
- } else {
- await this.fileRepo.upsert(flatFileIndexes, []);
- }
- }
-
- public entityModified(file: IndexedFile | Partial>): boolean {
- const index = file.index;
-
- if(file.numericKey !== index.key || file.name !== index.name) {
- return true;
- }
-
- if((index instanceof GroupIndexEntity || index instanceof FileIndexEntity) &&
- (file instanceof Group || file instanceof FlatFile)) {
- if(file.nameHash !== index.nameHash || file.version !== index.version) {
- return true;
- }
-
- if(file.archive.numericKey !== index.archiveKey) {
- return true;
- }
- }
-
- if((index instanceof ArchiveIndexEntity || index instanceof GroupIndexEntity) &&
- (file instanceof Archive || file instanceof Group)) {
- if(file.state !== index.state) {
- return true;
- }
- }
-
- if(index instanceof FileIndexEntity && file instanceof FlatFile) {
- if(file.group.numericKey !== index.groupKey) {
- return true;
- }
- }
-
- return file.size !== index.size || file.crc32 !== index.crc32 || file.sha256 !== index.sha256;
- }
-
- public updateEntityIndex(file: IndexedFile | Partial>): T {
- const index = file.index;
-
- if(!file.name && file.hasNameHash) {
- file.name = file.hasNameHash ?
- this.store.findFileName(file.nameHash, String(file.nameHash)) : file.key;
- } else if(!file.hasNameHash && file.named) {
- file.nameHash = this.store.hashFileName(file.name);
- } else {
- file.nameHash = -1;
- }
-
- if(index instanceof GroupIndexEntity || index instanceof FileIndexEntity) {
- index.version = file.version;
-
- if(file.archive?.config?.versioned && file.modified) {
- index.version = index.version ? index.version + 1 : 1;
- }
- }
-
- if(index.key === undefined || index.key === null) {
- index.key = file.numericKey;
- }
-
- if(index.name !== file.name) {
- index.name = file.name;
- }
-
- let dataModified = false;
-
- if(index.size !== file.size) {
- index.size = file.size;
- dataModified = true;
- }
-
- if(index.crc32 !== file.crc32) {
- index.crc32 = file.crc32;
- dataModified = true;
- }
-
- if(index.sha256 !== file.sha256) {
- index.sha256 = file.sha256;
- dataModified = true;
- }
-
- if(dataModified || !index.data?.length) {
- index.data = file.data?.length ? Buffer.from(file.data) : null;
- }
-
- return index;
- }
-
- public get loaded(): boolean {
- return !!this.connection;
- }
-
- public get storeRepo(): Repository {
- return this.connection.getRepository(StoreIndexEntity);
- }
-
- public get archiveRepo(): Repository {
- return this.connection.getRepository(ArchiveIndexEntity);
- }
-
- public get groupRepo(): Repository {
- return this.connection.getRepository(GroupIndexEntity);
- }
-
- public get fileRepo(): Repository {
- return this.connection.getRepository(FileIndexEntity);
- }
-
-}
diff --git a/src/db/index.ts b/src/db/index.ts
deleted file mode 100644
index 5c19b78..0000000
--- a/src/db/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export * from './store-index.entity';
-export * from './archive-index.entity';
-export * from './file-index.entity';
-export * from './group-index.entity';
-export * from './index-entity';
-export * from './index-service';
diff --git a/src/db/jag/content/jag-game-interface-entity.ts b/src/db/jag/content/jag-game-interface-entity.ts
new file mode 100644
index 0000000..8080683
--- /dev/null
+++ b/src/db/jag/content/jag-game-interface-entity.ts
@@ -0,0 +1,174 @@
+import { Column, Entity, PrimaryColumn } from 'typeorm';
+
+
+@Entity('jag_game_interface')
+export class JagGameInterfaceEntity {
+
+ @PrimaryColumn('integer', { nullable: false, unique: true })
+ id: number;
+
+ @Column('integer', { name: 'parent_id', nullable: false, default: -1 })
+ parentId: number = -1;
+
+ @Column('integer', { nullable: false })
+ type: number;
+
+ @Column('integer', { nullable: false })
+ actionType: number;
+
+ @Column('integer', { nullable: false })
+ contentType: number;
+
+ @Column('integer', { nullable: false })
+ width: number;
+
+ @Column('integer', { nullable: false })
+ height: number;
+
+ @Column('integer', { nullable: false })
+ alpha: number;
+
+ @Column('integer', { nullable: false })
+ hoveredPopup: number;
+
+ @Column('simple-json', { nullable: true })
+ conditionTypes?: number[];
+
+ @Column('simple-json', { nullable: true })
+ conditionValues?: number[];
+
+ @Column('simple-json', { nullable: true })
+ cs1Opcodes?: number[][];
+
+ @Column('integer', { nullable: true })
+ scrollLimit?: number;
+
+ @Column('boolean', { nullable: true })
+ hiddenUntilHovered?: boolean;
+
+ @Column('simple-json', { nullable: true })
+ children?: number[];
+
+ @Column('simple-json', { nullable: true })
+ childrenX?: number[];
+
+ @Column('simple-json', { nullable: true })
+ childrenY?: number[];
+
+ @Column('integer', { nullable: true })
+ unknownServerAttribute1?: number;
+
+ @Column('boolean', { nullable: true })
+ unknownServerAttribute2?: boolean;
+
+ @Column('simple-json', { nullable: true })
+ items?: number[];
+
+ @Column('simple-json', { nullable: true })
+ itemAmounts?: number[];
+
+ @Column('boolean', { nullable: true })
+ itemsSwappable?: boolean;
+
+ @Column('boolean', { nullable: true })
+ isInventory?: boolean;
+
+ @Column('boolean', { nullable: true })
+ itemsUsable?: boolean;
+
+ @Column('boolean', { nullable: true })
+ deleteDraggedItems?: boolean;
+
+ @Column('integer', { nullable: true })
+ itemSpritesPadX?: number;
+
+ @Column('integer', { nullable: true })
+ itemSpritesPadY?: number;
+
+ @Column('simple-json', { nullable: true })
+ images?: string[];
+
+ @Column('simple-json', { nullable: true })
+ imagesX?: number[];
+
+ @Column('simple-json', { nullable: true })
+ imagesY?: number[];
+
+ @Column('simple-json', { nullable: true })
+ options?: string[];
+
+ @Column('boolean', { nullable: true })
+ filled?: boolean;
+
+ @Column('boolean', { nullable: true })
+ textCentered?: boolean;
+
+ @Column('integer', { nullable: true })
+ fontType?: number;
+
+ @Column('boolean', { nullable: true })
+ textShadowed?: boolean;
+
+ @Column('text', { nullable: true })
+ disabledText?: string;
+
+ @Column('text', { nullable: true })
+ enabledText?: string;
+
+ @Column('integer', { nullable: true })
+ disabledColor?: number;
+
+ @Column('integer', { nullable: true })
+ enabledColor?: number;
+
+ @Column('integer', { nullable: true })
+ disabledHoverColor?: number;
+
+ @Column('integer', { nullable: true })
+ enabledHoverColor?: number;
+
+ @Column('text', { nullable: true })
+ disabledImage?: string;
+
+ @Column('text', { nullable: true })
+ enabledImage?: string;
+
+ @Column('integer', { nullable: true })
+ disabledModelType?: number;
+
+ @Column('integer', { nullable: true })
+ disabledModelId?: number;
+
+ @Column('integer', { nullable: true })
+ enabledModelType?: number;
+
+ @Column('integer', { nullable: true })
+ enabledModelId?: number;
+
+ @Column('integer', { nullable: true })
+ disabledAnimationId?: number;
+
+ @Column('integer', { nullable: true })
+ enabledAnimationId?: number;
+
+ @Column('integer', { nullable: true })
+ modelZoom?: number;
+
+ @Column('integer', { nullable: true })
+ modelRotationX?: number;
+
+ @Column('integer', { nullable: true })
+ modelRotationY?: number;
+
+ @Column('text', { nullable: true })
+ actionAdditions?: string;
+
+ @Column('text', { nullable: true })
+ actionText?: string;
+
+ @Column('integer', { nullable: true })
+ actionAttributes?: number;
+
+ @Column('text', { nullable: true })
+ tooltip?: string;
+}
diff --git a/src/db/jag/index.ts b/src/db/jag/index.ts
new file mode 100644
index 0000000..f9bde8e
--- /dev/null
+++ b/src/db/jag/index.ts
@@ -0,0 +1,4 @@
+export * from './jag-database';
+export * from './jag-index-entity';
+export * from './jag-data-entity';
+export * from './content/jag-game-interface-entity';
diff --git a/src/db/jag/jag-data-entity.ts b/src/db/jag/jag-data-entity.ts
new file mode 100644
index 0000000..23f2890
--- /dev/null
+++ b/src/db/jag/jag-data-entity.ts
@@ -0,0 +1,39 @@
+import { Column, CreateDateColumn, Entity, Index, PrimaryColumn, UpdateDateColumn } from 'typeorm';
+import { JagFileType } from '../../config';
+import { Buffer } from 'buffer';
+
+
+@Entity('jag_data')
+@Index('data_identifier', [
+ 'fileType', 'gameBuild', 'key', 'cacheKey', 'archiveKey', 'compressed'
+], { unique: true })
+export class JagDataEntity {
+
+ @PrimaryColumn('text', { name: 'file_type', nullable: false, unique: false })
+ fileType: JagFileType;
+
+ @PrimaryColumn('text', { name: 'game_build', nullable: false, unique: false })
+ gameBuild: string;
+
+ @PrimaryColumn('integer', { nullable: false, unique: false })
+ key: number;
+
+ @PrimaryColumn('integer', { name: 'cache_key', nullable: false, unique: false })
+ cacheKey: number;
+
+ @PrimaryColumn('integer', { name: 'archive_key', nullable: false, unique: false, default: -1 })
+ archiveKey: number = -1;
+
+ @PrimaryColumn('boolean', { nullable: false, default: false })
+ compressed: boolean = false;
+
+ @Column('blob', { name: 'buffer', nullable: true, default: null })
+ buffer: Buffer = null;
+
+ @CreateDateColumn()
+ created?: Date;
+
+ @UpdateDateColumn()
+ updated?: Date;
+
+}
diff --git a/src/db/jag/jag-database.ts b/src/db/jag/jag-database.ts
new file mode 100644
index 0000000..25bf72d
--- /dev/null
+++ b/src/db/jag/jag-database.ts
@@ -0,0 +1,184 @@
+import { IndexDatabase } from '../index-database';
+import { JagIndexEntity } from './jag-index-entity';
+import { Connection, createConnection, LoggerOptions, Repository } from 'typeorm';
+import { JagFileType } from '../../config';
+import { JagGameInterfaceEntity } from './content/jag-game-interface-entity';
+import { existsSync, mkdirSync } from 'graceful-fs';
+import { join } from 'path';
+import { JagDataEntity } from './jag-data-entity';
+
+
+export interface JagIndexEntityWhere {
+ fileType?: JagFileType;
+ key?: number;
+ name?: string;
+ cacheKey?: number;
+ archiveKey?: number;
+}
+
+
+export class JagDatabase extends IndexDatabase {
+
+ private _interfaceRepo: Repository;
+ private _dataRepo: Repository;
+
+ constructor(
+ gameBuild: string,
+ databasePath: string,
+ loggerOptions: LoggerOptions = 'all'
+ ) {
+ super(gameBuild, databasePath, loggerOptions);
+ }
+
+ override async openConnection(): Promise {
+ if(!existsSync(this.databasePath)) {
+ mkdirSync(this.databasePath, { recursive: true });
+ }
+
+ this._connection = await createConnection({
+ type: 'better-sqlite3',
+ database: join(this.databasePath, `${this.gameBuild}.index.sqlite3`),
+ entities: [
+ JagIndexEntity,
+ JagDataEntity,
+ JagGameInterfaceEntity
+ ],
+ synchronize: true,
+ logging: this.loggerOptions,
+ name: 'jag-repository'
+ });
+
+ this._repository = this._connection.getRepository(JagIndexEntity);
+ this._interfaceRepo = this._connection.getRepository(JagGameInterfaceEntity);
+ this._dataRepo = this._connection.getRepository(JagDataEntity);
+
+ return this._connection;
+ }
+
+ async getUncompressedData(where: JagIndexEntityWhere): Promise {
+ return this._dataRepo.findOne({
+ where: {
+ gameBuild: this.gameBuild,
+ compressed: false,
+ ...where
+ }
+ });
+ }
+
+ async getAllUncompressedData(where: JagIndexEntityWhere): Promise {
+ return this._dataRepo.find({
+ where: {
+ gameBuild: this.gameBuild,
+ compressed: false,
+ ...where
+ }
+ });
+ }
+
+ async saveUncompressedData(uncompressedDataEntity: JagDataEntity): Promise {
+ return this._dataRepo.save({ ...uncompressedDataEntity, compressed: false });
+ }
+
+ async saveAllUncompressedData(uncompressedDataEntities: JagDataEntity[]): Promise {
+ await this._dataRepo.save({ ...uncompressedDataEntities, compressed: false }, {
+ chunk: 500,
+ transaction: false,
+ reload: false,
+ listeners: false,
+ });
+ }
+
+ async upsertAllUncompressedData(uncompressedDataEntities: JagDataEntity[]): Promise {
+ const chunkSize = 100;
+ for (let i = 0; i < uncompressedDataEntities.length; i += chunkSize) {
+ const chunk = uncompressedDataEntities.slice(i, i + chunkSize).map(d => ({ ...d, compressed: false }));
+ await this._dataRepo.upsert(chunk, {
+ conflictPaths: [ 'fileType', 'gameBuild', 'key', 'cacheKey', 'archiveKey', 'compressed' ],
+ skipUpdateIfNoValuesChanged: true,
+ });
+ }
+ }
+
+ async getCompressedData(where: JagIndexEntityWhere): Promise {
+ return this._dataRepo.findOne({
+ where: {
+ gameBuild: this.gameBuild,
+ compressed: true,
+ ...where
+ }
+ });
+ }
+
+ async getAllCompressedData(where: JagIndexEntityWhere): Promise {
+ return this._dataRepo.find({
+ where: {
+ gameBuild: this.gameBuild,
+ compressed: true,
+ ...where
+ }
+ });
+ }
+
+ async saveCompressedData(compressedDataEntity: JagDataEntity): Promise {
+ return this._dataRepo.save({ ...compressedDataEntity, compressed: true });
+ }
+
+ async saveAllCompressedData(compressedDataEntities: JagDataEntity[]): Promise {
+ await this._dataRepo.save({ ...compressedDataEntities, compressed: true }, {
+ chunk: 500,
+ transaction: false,
+ reload: false,
+ listeners: false,
+ });
+ }
+
+ async upsertAllCompressedData(compressedDataEntities: JagDataEntity[]): Promise {
+ const chunkSize = 100;
+ for (let i = 0; i < compressedDataEntities.length; i += chunkSize) {
+ const chunk = compressedDataEntities.slice(i, i + chunkSize).map(d => ({ ...d, compressed: true }));
+ await this._dataRepo.upsert(chunk, {
+ conflictPaths: [ 'fileType', 'gameBuild', 'key', 'cacheKey', 'archiveKey', 'compressed' ],
+ skipUpdateIfNoValuesChanged: true,
+ });
+ }
+ }
+
+ override async upsertIndexes(indexEntities: JagIndexEntity[]): Promise {
+ const chunkSize = 100;
+ for (let i = 0; i < indexEntities.length; i += chunkSize) {
+ const chunk = indexEntities.slice(i, i + chunkSize);
+ await this.repository.upsert(chunk, {
+ conflictPaths: [ 'fileType', 'gameBuild', 'key', 'cacheKey', 'archiveKey' ],
+ skipUpdateIfNoValuesChanged: true,
+ });
+ }
+ }
+
+ async saveInterfaces(entities: JagGameInterfaceEntity[]): Promise {
+ await this.interfaceRepo.save(entities, {
+ reload: false,
+ listeners: false,
+ transaction: false,
+ chunk: 100,
+ });
+ }
+
+ async saveInterface(entity: JagGameInterfaceEntity): Promise {
+ return await this.interfaceRepo.save(entity);
+ }
+
+ async getInterface(id: number): Promise {
+ return await this.interfaceRepo.findOne({
+ where: { id }
+ });
+ }
+
+ get interfaceRepo(): Repository {
+ return this._interfaceRepo;
+ }
+
+ get dataRepo(): Repository {
+ return this._dataRepo;
+ }
+
+}
diff --git a/src/db/jag/jag-index-entity.ts b/src/db/jag/jag-index-entity.ts
new file mode 100644
index 0000000..2bfb18e
--- /dev/null
+++ b/src/db/jag/jag-index-entity.ts
@@ -0,0 +1,69 @@
+import { Column, CreateDateColumn, Entity, Index, PrimaryColumn, UpdateDateColumn } from 'typeorm';
+import { CompressionMethod } from '@runejs/common/compress';
+import { FileError, JagFileType } from '../../config';
+
+
+@Entity('jag_index')
+@Index('index_identifier', [
+ 'fileType', 'gameBuild', 'key', 'cacheKey', 'archiveKey'
+], { unique: true })
+export class JagIndexEntity {
+
+ @PrimaryColumn('text', { name: 'file_type', nullable: false, unique: false })
+ fileType: JagFileType;
+
+ @PrimaryColumn('text', { name: 'game_build', nullable: false, unique: false })
+ gameBuild: string;
+
+ @PrimaryColumn('integer', { nullable: false, unique: false })
+ key: number;
+
+ @PrimaryColumn('integer', { name: 'cache_key', nullable: false, unique: false })
+ cacheKey: number;
+
+ @PrimaryColumn('integer', { name: 'archive_key', nullable: false, unique: false, default: -1 })
+ archiveKey: number = -1;
+
+ @Column('text', { nullable: true, default: null })
+ name: string = null;
+
+ @Column('integer', { name: 'name_hash', nullable: true, default: -1 })
+ nameHash: number = -1;
+
+ @Column('integer', { nullable: false, default: -1 })
+ version: number = -1;
+
+ @Column('integer', { name: 'child_count', nullable: false, default: 0 })
+ childCount: number = 0;
+
+ @Column('integer', { nullable: false, default: -1 })
+ checksum: number = -1;
+
+ @Column('text', { name: 'sha_digest', nullable: true, default: null })
+ shaDigest: string = null;
+
+ @Column('integer', { name: 'file_size', nullable: false, default: 0 })
+ fileSize: number = 0;
+
+ @Column('text', { name: 'compression_method', nullable: true, default: 'none' })
+ compressionMethod: CompressionMethod = 'none';
+
+ @Column('integer', { name: 'compressed_checksum', nullable: false, default: -1 })
+ compressedChecksum: number = -1;
+
+ @Column('text', { name: 'compressed_sha_digest', nullable: true, default: null })
+ compressedShaDigest: string = null;
+
+ @Column('integer', { name: 'compressed_file_size', nullable: false, default: 0 })
+ compressedFileSize: number = 0;
+
+ @Column('text', { name: 'file_error', nullable: true, default: null })
+ fileError: FileError = null;
+
+ @CreateDateColumn()
+ created?: Date;
+
+ @UpdateDateColumn()
+ updated?: Date;
+
+}
diff --git a/src/db/js5/index.ts b/src/db/js5/index.ts
new file mode 100644
index 0000000..010d69c
--- /dev/null
+++ b/src/db/js5/index.ts
@@ -0,0 +1,3 @@
+export * from './js5-database';
+export * from './js5-index-entity';
+export * from './js5-data-entity';
diff --git a/src/db/js5/js5-data-entity.ts b/src/db/js5/js5-data-entity.ts
new file mode 100644
index 0000000..c770f4a
--- /dev/null
+++ b/src/db/js5/js5-data-entity.ts
@@ -0,0 +1,39 @@
+import { Column, CreateDateColumn, Entity, Index, PrimaryColumn, UpdateDateColumn } from 'typeorm';
+import { Js5FileType } from '../../config';
+import { Buffer } from 'buffer';
+
+
+@Entity('js5_data')
+@Index('data_identifier', [
+ 'fileType', 'gameBuild', 'key', 'archiveKey', 'groupKey', 'compressed'
+], { unique: true })
+export class Js5DataEntity {
+
+ @PrimaryColumn('text', { name: 'file_type', nullable: false, unique: false })
+ fileType: Js5FileType;
+
+ @PrimaryColumn('text', { name: 'game_build', nullable: false, unique: false })
+ gameBuild: string;
+
+ @PrimaryColumn('integer', { nullable: false, unique: false })
+ key: number;
+
+ @PrimaryColumn('integer', { name: 'archive_key', nullable: false, unique: false, default: -1 })
+ archiveKey: number = -1;
+
+ @PrimaryColumn('integer', { name: 'group_key', nullable: false, unique: false, default: -1 })
+ groupKey: number = -1;
+
+ @PrimaryColumn('boolean', { nullable: false, default: false })
+ compressed: boolean = false;
+
+ @Column('blob', { name: 'buffer', nullable: true, default: null })
+ buffer: Buffer = null;
+
+ @CreateDateColumn()
+ created?: Date;
+
+ @UpdateDateColumn()
+ updated?: Date;
+
+}
diff --git a/src/db/js5/js5-database.ts b/src/db/js5/js5-database.ts
new file mode 100644
index 0000000..f1fc5d6
--- /dev/null
+++ b/src/db/js5/js5-database.ts
@@ -0,0 +1,154 @@
+import { join } from 'path';
+import { existsSync, mkdirSync } from 'graceful-fs';
+import { Connection, createConnection, LoggerOptions, Repository } from 'typeorm';
+import { IndexDatabase } from '../index-database';
+import { Js5IndexEntity } from './js5-index-entity';
+import { Js5FileType } from '../../config';
+import { Js5DataEntity } from './js5-data-entity';
+
+
+export interface Js5IndexEntityWhere {
+ fileType?: Js5FileType;
+ key?: number;
+ name?: string;
+ archiveKey?: number;
+ groupKey?: number;
+}
+
+
+export class Js5Database extends IndexDatabase {
+
+ private _dataRepo: Repository;
+
+ constructor(
+ gameBuild: string,
+ databasePath: string,
+ loggerOptions: LoggerOptions = 'all'
+ ) {
+ super(gameBuild, databasePath, loggerOptions);
+ }
+
+ override async openConnection(): Promise {
+ if(!existsSync(this.databasePath)) {
+ mkdirSync(this.databasePath, { recursive: true });
+ }
+
+ this._connection = await createConnection({
+ type: 'better-sqlite3',
+ database: join(this.databasePath, `${this.gameBuild}.index.sqlite3`),
+ entities: [ Js5IndexEntity, Js5DataEntity ],
+ synchronize: true,
+ logging: this.loggerOptions,
+ name: 'js5-repository'
+ });
+
+ this._repository = this._connection.getRepository(Js5IndexEntity);
+ this._dataRepo = this._connection.getRepository(Js5DataEntity);
+
+ return this._connection;
+ }
+
+ async getUncompressedData(where: Js5IndexEntityWhere): Promise {
+ return this._dataRepo.findOne({
+ where: {
+ gameBuild: this.gameBuild,
+ compressed: false,
+ ...where
+ }
+ });
+ }
+
+ async getAllUncompressedData(where: Js5IndexEntityWhere): Promise {
+ return this._dataRepo.find({
+ where: {
+ gameBuild: this.gameBuild,
+ compressed: false,
+ ...where
+ }
+ });
+ }
+
+ async saveUncompressedData(uncompressedDataEntity: Js5DataEntity): Promise {
+ return this._dataRepo.save({ ...uncompressedDataEntity, compressed: false });
+ }
+
+ async saveAllUncompressedData(uncompressedDataEntities: Js5DataEntity[]): Promise {
+ await this._dataRepo.save({ ...uncompressedDataEntities, compressed: false }, {
+ chunk: 500,
+ transaction: false,
+ reload: false,
+ listeners: false,
+ });
+ }
+
+ async upsertAllUncompressedData(uncompressedDataEntities: Js5DataEntity[]): Promise {
+ const chunkSize = 100;
+ for (let i = 0; i < uncompressedDataEntities.length; i += chunkSize) {
+ const chunk = uncompressedDataEntities.slice(i, i + chunkSize).map(d => ({ ...d, compressed: false }));
+ await this._dataRepo.upsert(chunk, {
+ conflictPaths: [ 'fileType', 'gameBuild', 'key', 'archiveKey', 'groupKey', 'compressed' ],
+ skipUpdateIfNoValuesChanged: true,
+ });
+ }
+ }
+
+ async getCompressedData(where: Js5IndexEntityWhere): Promise {
+ return this._dataRepo.findOne({
+ where: {
+ gameBuild: this.gameBuild,
+ compressed: true,
+ ...where
+ }
+ });
+ }
+
+ async getAllCompressedData(where: Js5IndexEntityWhere): Promise {
+ return this._dataRepo.find({
+ where: {
+ gameBuild: this.gameBuild,
+ compressed: true,
+ ...where
+ }
+ });
+ }
+
+ async saveCompressedData(compressedDataEntity: Js5DataEntity): Promise {
+ return this._dataRepo.save({ ...compressedDataEntity, compressed: true });
+ }
+
+ async saveAllCompressedData(compressedDataEntities: Js5DataEntity[]): Promise {
+ await this._dataRepo.save({ ...compressedDataEntities, compressed: true }, {
+ chunk: 500,
+ transaction: false,
+ reload: false,
+ listeners: false,
+ });
+ }
+
+ async upsertAllCompressedData(compressedDataEntities: Js5DataEntity[]): Promise {
+ const chunkSize = 100;
+ for (let i = 0; i < compressedDataEntities.length; i += chunkSize) {
+ const chunk = compressedDataEntities.slice(i, i + chunkSize).map(d => ({ ...d, compressed: true }));
+ await this._dataRepo.upsert(chunk, {
+ conflictPaths: [ 'fileType', 'gameBuild', 'key', 'archiveKey', 'groupKey', 'compressed' ],
+ skipUpdateIfNoValuesChanged: true,
+ });
+ }
+ }
+
+ override async upsertIndexes(indexEntities: Js5IndexEntity[]): Promise {
+ const chunkSize = 100;
+ for (let i = 0; i < indexEntities.length; i += chunkSize) {
+ const chunk = indexEntities.slice(i, i + chunkSize);
+ await this.repository.upsert(chunk, {
+ conflictPaths: [ 'fileType', 'gameBuild', 'key', 'archiveKey', 'groupKey' ],
+ skipUpdateIfNoValuesChanged: true,
+ });
+ }
+ }
+
+ get dataRepo(): Repository {
+ return this._dataRepo;
+ }
+
+}
diff --git a/src/db/js5/js5-index-entity.ts b/src/db/js5/js5-index-entity.ts
new file mode 100644
index 0000000..db3bf9b
--- /dev/null
+++ b/src/db/js5/js5-index-entity.ts
@@ -0,0 +1,85 @@
+import { Column, CreateDateColumn, Entity, Index, PrimaryColumn, UpdateDateColumn } from 'typeorm';
+import { CompressionMethod } from '@runejs/common/compress';
+import { FileError, Js5FileType } from '../../config';
+import { Buffer } from 'buffer';
+
+
+@Entity('js5_index')
+@Index('index_identifier', [
+ 'fileType', 'gameBuild', 'key', 'archiveKey', 'groupKey'
+], { unique: true })
+export class Js5IndexEntity {
+
+ @PrimaryColumn('text', { name: 'file_type', nullable: false, unique: false })
+ fileType: Js5FileType;
+
+ @PrimaryColumn('text', { name: 'game_build', nullable: false, unique: false })
+ gameBuild: string;
+
+ @PrimaryColumn('integer', { nullable: false, unique: false })
+ key: number;
+
+ @PrimaryColumn('integer', { name: 'archive_key', nullable: false, unique: false, default: -1 })
+ archiveKey: number = -1;
+
+ @PrimaryColumn('integer', { name: 'group_key', nullable: false, unique: false, default: -1 })
+ groupKey: number = -1;
+
+ @Column('text', { nullable: true, default: null })
+ name: string = null;
+
+ @Column('integer', { name: 'name_hash', nullable: true, default: -1 })
+ nameHash: number = -1;
+
+ @Column('integer', { nullable: false, default: -1 })
+ version: number = -1;
+
+ @Column('integer', { name: 'child_count', nullable: false, default: 0 })
+ childCount: number = 0;
+
+ @Column('integer', { nullable: false, default: -1 })
+ checksum: number = -1;
+
+ @Column('text', { name: 'sha_digest', nullable: true, default: null })
+ shaDigest: string = null;
+
+ @Column('blob', { name: 'whirlpool_digest', nullable: true, default: null })
+ whirlpoolDigest: Buffer = null;
+
+ @Column('integer', { name: 'file_size', nullable: false, default: 0 })
+ fileSize: number = 0;
+
+ @Column('text', { name: 'compression_method', nullable: true, default: 'none' })
+ compressionMethod: CompressionMethod = 'none';
+
+ @Column('integer', { name: 'compressed_checksum', nullable: false, default: -1 })
+ compressedChecksum: number = -1;
+
+ @Column('text', { name: 'compressed_sha_digest', nullable: true, default: null })
+ compressedShaDigest: string = null;
+
+ @Column('integer', { name: 'compressed_file_size', nullable: false, default: 0 })
+ compressedFileSize: number = 0;
+
+ @Column('boolean', { nullable: true, default: false })
+ encrypted: boolean = false;
+
+ @Column('integer', { name: 'stripe_count', nullable: true, default: null })
+ stripeCount: number = null;
+
+ @Column('text', { nullable: true, default: null })
+ stripes: string | null = null;
+
+ @Column('integer', { nullable: true, default: null })
+ archiveFormat: number = null;
+
+ @Column('text', { name: 'file_error', nullable: true, default: null })
+ fileError: FileError = null;
+
+ @CreateDateColumn()
+ created?: Date;
+
+ @UpdateDateColumn()
+ updated?: Date;
+
+}
diff --git a/src/db/store-index.entity.ts b/src/db/store-index.entity.ts
deleted file mode 100644
index 94541ba..0000000
--- a/src/db/store-index.entity.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { Column, CreateDateColumn, Entity, OneToMany, PrimaryColumn, UpdateDateColumn } from 'typeorm';
-
-import { ArchiveIndexEntity } from './archive-index.entity';
-import { GroupIndexEntity } from './group-index.entity';
-import { FileIndexEntity } from './file-index.entity';
-
-
-@Entity('store_index')
-export class StoreIndexEntity {
-
- @PrimaryColumn('text', { name: 'game_build', nullable: false, unique: true })
- gameBuild: string;
-
- @OneToMany(() => ArchiveIndexEntity, archive => archive.store, { lazy: true })
- archives: Promise | ArchiveIndexEntity[];
-
- @OneToMany(() => GroupIndexEntity, group => group.store, { lazy: true })
- groups: Promise | GroupIndexEntity[];
-
- @OneToMany(() => FileIndexEntity, file => file.store, { lazy: true })
- files: Promise | FileIndexEntity[];
-
- @Column('blob', { name: 'data', nullable: true, default: null })
- data: Buffer | null = null;
-
- @CreateDateColumn()
- created: Date;
-
- @UpdateDateColumn()
- updated: Date;
-
-}
diff --git a/src/dev.ts b/src/dev.ts
deleted file mode 100644
index 244f61f..0000000
--- a/src/dev.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { Store } from './index';
-import { join } from 'path';
-
-
-const store = Store.create(435);
-
diff --git a/src/file-state.ts b/src/file-state.ts
deleted file mode 100644
index 4f96e8e..0000000
--- a/src/file-state.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-export enum FileState {
- /**
- * File is not yet registered.
- */
- unloaded = 'unloaded',
-
- /**
- * File has been registered but not read into memory.
- */
- loaded = 'loaded',
-
- /**
- * File `data` is encrypted.
- * Encryption formats: xtea
- */
- encrypted = 'encrypted',
-
- /**
- * File `data` has been decrypted.
- * Encryption formats: xtea
- */
- decrypted = 'decrypted',
-
- /**
- * File `data` is compressed.
- * Compression formats: bzip, gzip
- */
- compressed = 'compressed',
-
- /**
- * File `data` is encoded for the JS5 format.
- */
- encoded = 'encoded',
-
- /**
- * File `data` is in raw binary form, uncompressed and unencrypted.
- */
- raw = 'raw',
-
- /**
- * The file was found, but is empty.
- */
- empty = 'empty',
-
- /**
- * The file was found, but is corrupted.
- */
- corrupt = 'corrupt',
-
- /**
- * The file was not found.
- */
- missing = 'missing'
-}
diff --git a/src/file-system/file-store-base.ts b/src/file-system/file-store-base.ts
new file mode 100644
index 0000000..850ef49
--- /dev/null
+++ b/src/file-system/file-store-base.ts
@@ -0,0 +1,35 @@
+import { join } from 'path';
+import { Crc32 } from '@runejs/common/crc32';
+
+import { NameHasher } from '../config';
+import { IndexDatabase } from '../db/index-database';
+
+
+export abstract class FileStoreBase> {
+
+ readonly gameBuild: string;
+ readonly fileStorePath: string;
+ readonly nameHasher: NameHasher;
+
+ protected _database: DATABASE;
+
+ protected constructor(gameBuild: string | number, storePath: string) {
+ this.gameBuild = String(gameBuild);
+ this.fileStorePath = storePath;
+ this.nameHasher = new NameHasher(join(storePath, 'config'));
+ Crc32.init();
+ }
+
+ abstract openDatabase(): Promise;
+
+ abstract load(): void | Promise;
+
+ async closeDatabase(): Promise {
+ await this._database.closeConnection();
+ }
+
+ get database(): DATABASE {
+ return this._database;
+ }
+
+}
diff --git a/src/file-system/index.ts b/src/file-system/index.ts
new file mode 100644
index 0000000..5802b7a
--- /dev/null
+++ b/src/file-system/index.ts
@@ -0,0 +1,4 @@
+export * from './file-store-base';
+export * from './packed';
+export * from './jag';
+export * from './js5';
diff --git a/src/file-system/jag/content/animations/animations.ts b/src/file-system/jag/content/animations/animations.ts
new file mode 100644
index 0000000..6cef9d4
--- /dev/null
+++ b/src/file-system/jag/content/animations/animations.ts
@@ -0,0 +1,98 @@
+import { JagFileStore } from '../../jag-file-store';
+import { Buffer } from 'buffer';
+import { ByteBuffer, logger } from '@runejs/common';
+import { JagCache } from '../../jag-cache';
+
+
+export interface AnimationFile {
+ key: number;
+ version: number;
+ checksum: number;
+ data?: Buffer;
+}
+
+
+export class Animations {
+
+ readonly jagStore: JagFileStore;
+ readonly animations: Map;
+ readonly animationsIndex: JagCache;
+
+ versionListDecoded: boolean = false;
+
+ constructor(jagStore: JagFileStore) {
+ this.jagStore = jagStore;
+ this.animations = new Map();
+ this.animationsIndex = this.jagStore.getCache('animations');
+ }
+
+ decodeVersionList(): void {
+ const archiveIndex = this.jagStore.getCache('archives');
+ if (!archiveIndex) {
+ throw new Error(`Archive Index is not loaded!`);
+ }
+
+ const versionListArchive = archiveIndex.getArchive('versionlist.jag');
+ if (!versionListArchive) {
+ throw new Error(`versionlist.jag archive is not loaded!`);
+ }
+
+ const animVersionList = versionListArchive.getFile('anim_version');
+ const animChecksumList = versionListArchive.getFile('anim_crc');
+ const animIndexList = versionListArchive.getFile('anim_index');
+
+ if (!animVersionList?.data?.buffer?.length) {
+ throw new Error(`anim_version file is not loaded!`);
+ }
+ if (!animChecksumList?.data?.buffer?.length) {
+ throw new Error(`anim_crc file is not loaded!`);
+ }
+ if (!animIndexList?.data?.buffer?.length) {
+ throw new Error(`anim_index file is not loaded!`);
+ }
+
+ this.animations.clear();
+
+ const versionData = new ByteBuffer(animVersionList.data.buffer);
+ const checksumData = new ByteBuffer(animVersionList.data.buffer);
+ const indexData = new ByteBuffer(animVersionList.data.buffer);
+ const animCount = versionData.length / 2;
+
+ for (let i = 0; i < animCount; i++) {
+ const version = versionData.get('short', 'unsigned');
+ const checksum = checksumData.get('int');
+ const key = indexData.get('short', 'unsigned');
+
+ this.animations.set(key, {
+ key, version, checksum
+ });
+ }
+
+ this.versionListDecoded = true;
+ }
+
+ decodeAll(): void {
+ if (!this.versionListDecoded) {
+ this.decodeVersionList();
+ }
+
+ for (const [ animKey, ] of this.animationsIndex.files) {
+ this.decode(animKey);
+ }
+ }
+
+ decode(animKey: number): AnimationFile | null {
+ const animFile = this.animationsIndex.getFile(animKey);
+
+ if (!animFile?.data?.buffer?.length) {
+ logger.warn(`Animation ${animKey} is empty or missing.`);
+ return null;
+ }
+
+ const animData = new ByteBuffer(animFile.data.buffer);
+
+ //@todo stopped here - 12/08/22 - Kiko
+ return null;
+ }
+
+}
diff --git a/src/file-system/jag/content/archives/interfaces/jag-interface-archive.ts b/src/file-system/jag/content/archives/interfaces/jag-interface-archive.ts
new file mode 100644
index 0000000..37eff86
--- /dev/null
+++ b/src/file-system/jag/content/archives/interfaces/jag-interface-archive.ts
@@ -0,0 +1,278 @@
+import { Buffer } from 'buffer';
+import { ByteBuffer, logger } from '@runejs/common';
+import { JagFileStore } from '../../../jag-file-store';
+import { JagGameInterfaceEntity } from '../../../../../db/jag';
+
+
+export class JagInterfaceArchive {
+
+ readonly jagStore: JagFileStore;
+ readonly interfaces: Map;
+
+ constructor(jagStore: JagFileStore) {
+ this.jagStore = jagStore;
+ this.interfaces = new Map();
+ }
+
+ decode(data: ByteBuffer): JagGameInterfaceEntity {
+ const inter = new JagGameInterfaceEntity();
+ inter.id = data.get('short', 'unsigned');
+
+ if (inter.id === 65535) {
+ inter.parentId = data.get('short', 'unsigned');
+ inter.id = data.get('short', 'unsigned');
+ }
+
+ const type = inter.type = data.get('byte', 'unsigned');
+ inter.actionType = data.get('byte', 'unsigned');
+ inter.contentType = data.get('short', 'unsigned');
+ const width = inter.width = data.get('short', 'unsigned');
+ const height = inter.height = data.get('short', 'unsigned');
+ inter.alpha = data.get('byte', 'unsigned');
+
+ // hoveredPopup = u_short, but only a single u_byte is written if there is no hovered popup
+ // use u_smart_short ?
+ inter.hoveredPopup = data.get('byte', 'unsigned');
+ if (inter.hoveredPopup !== 0) {
+ inter.hoveredPopup = (inter.hoveredPopup - 1 << 8) +
+ data.get('byte', 'unsigned'); // why?
+ } else {
+ inter.hoveredPopup = -1;
+ }
+
+ const conditionCount = data.get('byte', 'unsigned');
+
+ if (conditionCount > 0) {
+ inter.conditionTypes = new Array(conditionCount);
+ inter.conditionValues = new Array(conditionCount);
+
+ for (let i = 0; i < conditionCount; i++) {
+ inter.conditionTypes[i] = data.get('byte', 'unsigned');
+ inter.conditionValues[i] = data.get('short', 'unsigned');
+ }
+ }
+
+ const cs1OpcodeCount = data.get('byte', 'unsigned');
+
+ if (cs1OpcodeCount > 0) {
+ inter.cs1Opcodes = new Array(cs1OpcodeCount);
+
+ for (let i = 0; i < cs1OpcodeCount; i++) {
+ const cs1BlockCount = data.get('short', 'unsigned');
+ inter.cs1Opcodes[i] = new Array(cs1BlockCount);
+
+ for (let j = 0; j < cs1BlockCount; j++) {
+ inter.cs1Opcodes[i][j] = data.get('short', 'unsigned');
+ }
+ }
+ }
+
+ if (type === 0) {
+ inter.scrollLimit = data.get('short', 'unsigned');
+ inter.hiddenUntilHovered = data.get('byte', 'unsigned') === 1;
+
+ const childCount = data.get('short', 'unsigned');
+
+ inter.children = new Array(childCount);
+ inter.childrenX = new Array(childCount);
+ inter.childrenY = new Array(childCount);
+
+ for (let i = 0; i < childCount; i++) {
+ inter.children[i] = data.get('short', 'unsigned');
+ inter.childrenX[i] = data.get('short');
+ inter.childrenY[i] = data.get('short');
+ }
+ }
+
+ if (type === 1) {
+ inter.unknownServerAttribute1 = data.get('short', 'unsigned');
+ inter.unknownServerAttribute2 = data.get('byte', 'unsigned') === 1;
+ }
+
+ if (type === 2) {
+ inter.items = new Array(width * height);
+ inter.itemAmounts = new Array(width * height);
+ inter.itemsSwappable = data.get('byte', 'unsigned') === 1;
+ inter.isInventory = data.get('byte', 'unsigned') === 1;
+ inter.itemsUsable = data.get('byte', 'unsigned') === 1;
+ inter.deleteDraggedItems = data.get('byte', 'unsigned') === 1;
+ inter.itemSpritesPadX = data.get('byte', 'unsigned');
+ inter.itemSpritesPadY = data.get('byte', 'unsigned');
+ inter.images = new Array(20);
+ inter.imagesX = new Array(20);
+ inter.imagesY = new Array(20);
+
+ for (let i = 0; i < 20; i++) {
+ const hasSprite = data.get('byte', 'unsigned') === 1;
+ if (hasSprite) {
+ inter.imagesX[i] = data.get('short');
+ inter.imagesY[i] = data.get('short');
+ inter.images[i] = data.getString(10);
+ }
+ }
+
+ inter.options = new Array(5);
+
+ for (let i = 0; i < 5; i++) {
+ inter.options[i] = data.getString(10);
+ }
+ }
+
+ if (type === 3) {
+ inter.filled = data.get('byte', 'unsigned') === 1;
+ }
+
+ if (type === 4 || type === 1) {
+ inter.textCentered = data.get('byte', 'unsigned') === 1;
+ inter.fontType = data.get('byte', 'unsigned');
+ inter.textShadowed = data.get('byte', 'unsigned') === 1;
+ }
+
+ if (type === 4) {
+ inter.disabledText = data.getString(10);
+ inter.enabledText = data.getString(10);
+ }
+
+ if (inter.type === 1 || inter.type === 3 || inter.type === 4) {
+ inter.disabledColor = data.get('int');
+ }
+
+ if (inter.type === 3 || inter.type === 4) {
+ inter.enabledColor = data.get('int');
+ inter.disabledHoverColor = data.get('int');
+ inter.enabledHoverColor = data.get('int');
+ }
+
+ if (inter.type === 5) {
+ inter.disabledImage = data.getString(10);
+ inter.enabledImage = data.getString(10);
+ }
+
+ if (inter.type === 6) {
+ let identifier = data.get('byte', 'unsigned');
+
+ if (identifier !== 0) {
+ inter.disabledModelType = 1;
+ inter.disabledModelId = (identifier - 1 << 8) + data.get('byte', 'unsigned');
+ }
+
+ identifier = data.get('byte', 'unsigned');
+
+ if (identifier !== 0) {
+ inter.enabledModelType = 1;
+ inter.enabledModelId = (identifier - 1 << 8) + data.get('byte', 'unsigned');
+ }
+
+ identifier = data.get('byte', 'unsigned');
+
+ if (identifier !== 0) {
+ inter.disabledAnimationId = (identifier - 1 << 8) + data.get('byte', 'unsigned');
+ } else {
+ inter.disabledAnimationId = -1;
+ }
+
+ identifier = data.get('byte', 'unsigned');
+
+ if (identifier !== 0) {
+ inter.enabledAnimationId = (identifier - 1 << 8) + data.get('byte', 'unsigned');
+ } else {
+ inter.enabledAnimationId = -1;
+ }
+
+ inter.modelZoom = data.get('short', 'unsigned');
+ inter.modelRotationX = data.get('short', 'unsigned');
+ inter.modelRotationY = data.get('short', 'unsigned');
+ }
+
+ if (inter.type === 7) {
+ inter.items = new Array(width * height);
+ inter.itemAmounts = new Array(width * height);
+ inter.textCentered = data.get('byte', 'unsigned') === 1;
+ inter.fontType = data.get('byte', 'unsigned');
+ inter.textShadowed = data.get('byte', 'unsigned') === 1;
+ inter.disabledColor = data.get('int');
+ inter.itemSpritesPadX = data.get('short');
+ inter.itemSpritesPadY = data.get('short');
+ inter.isInventory = data.get('byte', 'unsigned') === 1;
+ inter.options = new Array(5);
+
+ for (let i = 0; i < 5; i++) {
+ inter.options[i] = data.getString(10);
+ }
+ }
+
+ if (inter.type === 8) {
+ inter.disabledText = data.getString(10);
+ }
+
+ if (inter.actionType === 2 || inter.type === 2) {
+ inter.actionAdditions = data.getString(10);
+ inter.actionText = data.getString(10);
+ inter.actionAttributes = data.get('short', 'unsigned');
+ }
+
+ if (inter.actionType === 1 || inter.actionType === 4 || inter.actionType === 5 || inter.actionType === 6) {
+ inter.tooltip = data.getString(10);
+ }
+
+ return inter;
+ }
+
+ async decodeAll(): Promise {
+ const archive = this.jagStore.getCache('archives')
+ .getArchive('interface.jag');
+
+ if (!archive) {
+ throw new Error('interface.jag archive is not loaded!');
+ }
+
+ const dataFile = archive.getFile('data');
+
+ await dataFile.loadUncompressedData();
+
+ if (!dataFile?.data?.buffer?.length) {
+ throw new Error('interface.jag data file is not loaded!');
+ }
+
+ const data = new ByteBuffer(dataFile.data.buffer);
+ this.interfaces.clear();
+
+ data.get('short', 'unsigned'); // interface count
+
+ while (data.readerIndex < data.length) {
+ try {
+ const gameInterface = this.decode(data);
+ this.interfaces.set(gameInterface.id, gameInterface);
+ } catch (e) {
+ logger.error(e);
+ break;
+ }
+ }
+ }
+
+ encode(gameInterface: JagGameInterfaceEntity): Buffer | null {
+ // @todo stubbed - 15/08/22 - Kiko
+ return null;
+ }
+
+ encodeAll(): Buffer | null {
+ // @todo stubbed - 15/08/22 - Kiko
+ return null;
+ }
+
+ toJS5(gameInterface: JagGameInterfaceEntity): null {
+ // @todo stubbed - 15/08/22 - Kiko
+ return null;
+ }
+
+ async loadAll(): Promise {
+ const entities = (await this.jagStore.database.interfaceRepo.find())
+ .sort((a, b) => a.id - b.id);
+ entities.forEach(entity => this.interfaces.set(entity.id, entity));
+ }
+
+ async saveAll(): Promise {
+ await this.jagStore.database.saveInterfaces(Array.from(this.interfaces.values()));
+ }
+
+}
diff --git a/src/file-system/jag/index.ts b/src/file-system/jag/index.ts
new file mode 100644
index 0000000..33001e8
--- /dev/null
+++ b/src/file-system/jag/index.ts
@@ -0,0 +1,6 @@
+export * from './jag';
+export * from './jag-file-base';
+export * from './jag-file-store';
+export * from './jag-archive';
+export * from './jag-file';
+export * from './jag-cache';
diff --git a/src/file-system/jag/jag-archive.ts b/src/file-system/jag/jag-archive.ts
new file mode 100644
index 0000000..93bef94
--- /dev/null
+++ b/src/file-system/jag/jag-archive.ts
@@ -0,0 +1,81 @@
+import { JagFileStore } from './jag-file-store';
+import { archives, caches } from './jag';
+import { JagFile } from './jag-file';
+import { JagFileBase } from './jag-file-base';
+
+
+export class JagArchive extends JagFileBase {
+
+ readonly files: Map;
+
+ constructor(
+ jagStore: JagFileStore,
+ archiveKey: number,
+ ) {
+ super(jagStore, 'ARCHIVE', archiveKey, caches.archives, -1);
+ const archiveNames = Object.keys(archives);
+ for (const name of archiveNames) {
+ if (archives[name] === archiveKey) {
+ this.index.name = name;
+ }
+ }
+ this.files = new Map();
+ }
+
+ async upsertFileIndexes(): Promise {
+ const fileIndexes = Array.from(this.files.values()).map(file => file.index);
+ await this.fileStore.database.upsertIndexes(fileIndexes);
+ }
+
+ async loadFileIndexes(): Promise {
+ const fileIndexes = await this.fileStore.database.getIndexes({
+ fileType: 'FILE',
+ cacheKey: this.index.cacheKey,
+ archiveKey: this.index.key,
+ });
+
+ if (!fileIndexes?.length) {
+ return;
+ }
+
+ for (const fileIndex of fileIndexes) {
+ const fileKey = fileIndex.key;
+
+ if (!this.files.has(fileKey)) {
+ const file = new JagFile(this.fileStore, fileKey, this.index.cacheKey, this.index.key);
+ file.index = fileIndex;
+ this.files.set(fileKey, file);
+ }
+ }
+ }
+
+ async upsertFileData(): Promise {
+ const files = Array.from(this.files.values());
+ const uncompressed = files.map(file => file.data).filter(data => data?.buffer && data?.buffer?.length !== 0);
+ const compressed = files.map(file => file.compressedData).filter(data => data?.buffer && data?.buffer?.length !== 0);
+ if (uncompressed.length) {
+ await this.fileStore.database.upsertAllUncompressedData(uncompressed);
+ }
+ if (compressed.length) {
+ await this.fileStore.database.upsertAllCompressedData(compressed);
+ }
+ }
+
+ getFile(fileKey: number): JagFile | null;
+ getFile(fileName: string): JagFile | null;
+ getFile(fileKeyOrName: number | string): JagFile | null;
+ getFile(fileKeyOrName: number | string): JagFile | null {
+ if (typeof fileKeyOrName === 'string') {
+ return Array.from(this.files.values()).find(
+ file => file?.index?.name === fileKeyOrName
+ ) || null;
+ } else {
+ return this.files.get(fileKeyOrName) || null;
+ }
+ }
+
+ setFile(fileKey: number, file: JagFile): void {
+ this.files.set(fileKey, file);
+ }
+
+}
diff --git a/src/file-system/jag/jag-cache.ts b/src/file-system/jag/jag-cache.ts
new file mode 100644
index 0000000..ed896d0
--- /dev/null
+++ b/src/file-system/jag/jag-cache.ts
@@ -0,0 +1,118 @@
+import { JagFileStore } from './jag-file-store';
+import { JagFileIndex, caches } from './jag';
+import { JagArchive } from './jag-archive';
+import { JagFile } from './jag-file';
+import { JagFileBase } from './jag-file-base';
+
+
+export class JagCache extends JagFileBase {
+
+ readonly files: Map;
+
+ fileIndexes: JagFileIndex[];
+
+ constructor(jagStore: JagFileStore, cacheKey: number) {
+ super(jagStore, 'CACHE', cacheKey);
+ const indexNames = Object.keys(caches);
+ for (const name of indexNames) {
+ if (caches[name] === cacheKey) {
+ this.index.name = name;
+ }
+ }
+ this.files = new Map();
+ }
+
+ async upsertFileIndexes(): Promise {
+ const fileIndexes = Array.from(this.files.values()).map(file => file.index);
+ await this.fileStore.database.upsertIndexes(fileIndexes);
+ }
+
+ async loadFileIndexes(): Promise {
+ const fileIndexes = await this.fileStore.database.getIndexes({
+ cacheKey: this.index.key,
+ archiveKey: -1,
+ });
+
+ if (!fileIndexes?.length) {
+ return;
+ }
+
+ for (const fileIndex of fileIndexes) {
+ const fileKey = fileIndex.key;
+
+ if (!this.files.has(fileKey)) {
+ let file: JagFileBase;
+
+ if (fileIndex.fileType === 'ARCHIVE') {
+ file = new JagArchive(this.fileStore, fileKey);
+ } else {
+ file = new JagFile(this.fileStore, fileKey, this.index.key, -1);
+ }
+
+ file.index = fileIndex;
+ this.files.set(fileKey, file);
+ }
+ }
+ }
+
+ async upsertFileData(): Promise {
+ const files = Array.from(this.files.values());
+ const uncompressed = files.map(file => file.data).filter(data => data?.buffer && data?.buffer?.length !== 0);
+ const compressed = files.map(file => file.compressedData).filter(data => data?.buffer && data?.buffer?.length !== 0);
+ if (uncompressed.length) {
+ await this.fileStore.database.upsertAllUncompressedData(uncompressed);
+ }
+ if (compressed.length) {
+ await this.fileStore.database.upsertAllCompressedData(compressed);
+ }
+ }
+
+ createArchive(archiveKey: number): JagArchive {
+ const archive = new JagArchive(this.fileStore, archiveKey);
+ this.setArchive(archiveKey, archive);
+ return archive;
+ }
+
+ getArchive(archiveKey: number): JagArchive | null;
+ getArchive(archiveName: string): JagArchive | null;
+ getArchive(archiveKeyOrName: number | string): JagArchive | null;
+ getArchive(archiveKeyOrName: number | string): JagArchive | null {
+ let archive: JagFile | JagArchive | null;
+
+ if (typeof archiveKeyOrName === 'string') {
+ archive = Array.from(this.files.values()).find(
+ file => file?.index?.name === archiveKeyOrName
+ ) || null;
+ } else {
+ archive = this.files.get(archiveKeyOrName) || null;
+ }
+
+ return (archive && archive instanceof JagArchive) ? archive : null;
+ }
+
+ setArchive(archiveKey: number, archive: JagArchive): void {
+ this.files.set(archiveKey, archive);
+ }
+
+ getFile(fileKey: number): JagFile | null;
+ getFile(fileName: string): JagFile | null;
+ getFile(fileKeyOrName: number | string): JagFile | null;
+ getFile(fileKeyOrName: number | string): JagFile | null {
+ let file: JagFile | JagArchive | null;
+
+ if (typeof fileKeyOrName === 'string') {
+ file = Array.from(this.files.values()).find(
+ file => file?.index?.name === fileKeyOrName
+ ) || null;
+ } else {
+ file = this.files.get(fileKeyOrName) || null;
+ }
+
+ return (file && file instanceof JagFile) ? file : null;
+ }
+
+ setFile(fileKey: number, file: JagFile): void {
+ this.files.set(fileKey, file);
+ }
+
+}
diff --git a/src/file-system/jag/jag-file-base.ts b/src/file-system/jag/jag-file-base.ts
new file mode 100644
index 0000000..c91617e
--- /dev/null
+++ b/src/file-system/jag/jag-file-base.ts
@@ -0,0 +1,241 @@
+import { JagFileType } from '../../config';
+import { logger } from '@runejs/common';
+import { Buffer } from 'buffer';
+import { Crc32 } from '@runejs/common/crc32';
+import { createHash } from 'crypto';
+import { JagFileStore } from './jag-file-store';
+import { JagDataEntity, JagIndexEntity } from '../../db/jag';
+
+
+export abstract class JagFileBase {
+
+ readonly fileStore: JagFileStore;
+
+ index: JagIndexEntity;
+ data: JagDataEntity;
+ compressedData: JagDataEntity;
+
+ protected constructor(
+ fileStore: JagFileStore,
+ fileType: JagFileType,
+ key: number,
+ cacheKey: number = -1,
+ archiveKey: number = -1,
+ ) {
+ this.fileStore = fileStore;
+ this.index = new JagIndexEntity();
+ this.data = new JagDataEntity();
+ this.compressedData = new JagDataEntity();
+ this.compressedData.compressed = true;
+ this.data.gameBuild = this.compressedData.gameBuild = this.index.gameBuild = fileStore.gameBuild;
+ this.data.fileType = this.compressedData.fileType = this.index.fileType = fileType;
+ this.data.key = this.compressedData.key = this.index.key = key;
+ this.data.cacheKey = this.compressedData.cacheKey = this.index.cacheKey = cacheKey;
+ this.data.archiveKey = this.compressedData.archiveKey = this.index.archiveKey = archiveKey;
+ }
+
+ validate(trackChanges: boolean = true): void {
+ const data = this.data.buffer;
+ const compressedData = this.compressedData.buffer;
+ const {
+ checksum, shaDigest, fileSize,
+ compressedChecksum, compressedShaDigest, compressedFileSize,
+ name, nameHash, compressionMethod,
+ } = this.index;
+ let fileModified: boolean = false;
+
+ const currentChecksum = this.generateChecksum(data);
+ const currentShaDigest = this.generateShaDigest(data);
+ const currentFileSize = data?.length || 0;
+
+ const currentCompressedChecksum = this.generateChecksum(compressedData);
+ const currentCompressedShaDigest = this.generateShaDigest(compressedData);
+ const currentCompressedFileSize = compressedData?.length || 0;
+
+ if (name && nameHash === -1) {
+ // nameHash not set
+ this.index.nameHash = this.fileStore.nameHasher.hashJs5FileName(name);
+ }
+
+ if (nameHash !== -1 && !name) {
+ // name not set
+ const lookupTableName = this.fileStore.nameHasher.findFileName(nameHash);
+ if (lookupTableName) {
+ this.index.name = lookupTableName;
+ }
+ }
+
+ if (checksum !== currentChecksum) {
+ // uncompressed crc32 mismatch
+ this.index.checksum = currentChecksum;
+ fileModified = true;
+ }
+
+ if (shaDigest !== currentShaDigest) {
+ // uncompressed sha256 mismatch
+ this.index.shaDigest = currentShaDigest;
+ fileModified = true;
+ }
+
+ if (fileSize !== currentFileSize) {
+ // uncompressed file size mismatch
+ this.index.fileSize = currentFileSize;
+ fileModified = true;
+ }
+
+ if (compressedChecksum !== currentCompressedChecksum) {
+ // compressed crc32 mismatch
+ this.index.compressedChecksum = currentCompressedChecksum;
+ fileModified = true;
+ }
+
+ if (compressedShaDigest !== currentCompressedShaDigest) {
+ // compressed sha256 mismatch
+ this.index.compressedShaDigest = currentCompressedShaDigest;
+ fileModified = true;
+ }
+
+ if (compressedFileSize !== currentCompressedFileSize) {
+ // compressed file size mismatch
+ this.index.compressedFileSize = currentCompressedFileSize;
+ fileModified = true;
+ }
+
+ if ((!this.index.compressionMethod || this.index.compressionMethod === 'none' || this.index.compressedFileSize === fileSize)
+ && this.compressedData?.buffer?.length) {
+ // File has no compression, clear the compressed data buffer so that we do not create a
+ // duplicate data entity record for it
+ this.compressedData.buffer = null;
+ this.index.compressedFileSize = 0;
+ this.index.compressedChecksum = -1;
+ this.index.compressedShaDigest = null;
+ }
+
+ if (fileModified && trackChanges) {
+ logger.info(`File ${this.index.name || this.index.key} has been modified.`);
+ this.index.version++;
+ }
+ }
+
+ async saveUncompressedData(): Promise {
+ if (!this.data?.buffer?.length) {
+ // Do not save a record for files with missing or empty data
+ return null;
+ }
+
+ this.data = await this.fileStore.database.saveUncompressedData(this.data);
+ return this.data;
+ }
+
+ async loadUncompressedData(): Promise {
+ const entity = await this.fileStore.database.getUncompressedData({
+ fileType: this.index.fileType,
+ key: this.index.key,
+ archiveKey: this.index.archiveKey,
+ cacheKey: this.index.cacheKey,
+ });
+
+ if (entity) {
+ this.data = entity;
+ }
+
+ return this.data;
+ }
+
+ async getUncompressedData(): Promise {
+ if (this.data?.buffer?.length) {
+ return this.data.buffer;
+ }
+
+ const uncompressedData = await this.loadUncompressedData();
+ if (uncompressedData?.buffer?.length) {
+ return uncompressedData.buffer;
+ }
+
+ return null;
+ }
+
+ async saveCompressedData(): Promise {
+ if (!this.compressedData?.buffer?.length) {
+ // Do not save a record for files with missing or empty data
+ return null;
+ }
+
+ this.compressedData = await this.fileStore.database.saveCompressedData(this.compressedData);
+ return this.compressedData;
+ }
+
+ async loadCompressedData(): Promise {
+ const entity = await this.fileStore.database.getCompressedData({
+ fileType: this.index.fileType,
+ key: this.index.key,
+ archiveKey: this.index.archiveKey,
+ cacheKey: this.index.cacheKey,
+ });
+
+ if (entity) {
+ this.compressedData = entity;
+ }
+
+ return this.compressedData;
+ }
+
+ async getCompressedData(): Promise {
+ if (!this.index) {
+ await this.loadIndex();
+ }
+
+ if (!this.index.compressionMethod || this.index.compressionMethod === 'none') {
+ return this.getUncompressedData();
+ }
+
+ if (this.compressedData?.buffer?.length) {
+ return this.compressedData.buffer;
+ }
+
+ const compressedData = await this.loadCompressedData();
+ if (compressedData?.buffer?.length) {
+ return compressedData.buffer;
+ }
+
+ return null;
+ }
+
+ async saveIndex(): Promise {
+ this.validate();
+ this.index = await this.fileStore.database.saveIndex(this.index);
+ return this.index;
+ }
+
+ async loadIndex(): Promise {
+ const indexEntity = await this.fileStore.database.getIndex({
+ fileType: this.index.fileType,
+ key: this.index.key,
+ cacheKey: this.index.cacheKey,
+ archiveKey: this.index.archiveKey,
+ });
+
+ if (indexEntity) {
+ this.index = indexEntity;
+ }
+
+ return this.index;
+ }
+
+ generateChecksum(data: Buffer): number {
+ if (!data?.length) {
+ return -1;
+ }
+
+ return Crc32.update(0, data.length, data);
+ }
+
+ generateShaDigest(data: Buffer): string {
+ if (!data?.length) {
+ return null;
+ }
+
+ return createHash('sha256').update(data).digest('hex');
+ }
+
+}
diff --git a/src/file-system/jag/jag-file-store.ts b/src/file-system/jag/jag-file-store.ts
new file mode 100644
index 0000000..501013e
--- /dev/null
+++ b/src/file-system/jag/jag-file-store.ts
@@ -0,0 +1,114 @@
+import { join } from 'path';
+import { logger } from '@runejs/common';
+import { FileStoreBase } from '../file-store-base';
+import { Jag, caches } from './jag';
+import { JagCache } from './jag-cache';
+import { JagDatabase } from '../../db/jag';
+import { JagArchive } from './jag-archive';
+
+
+export class JagFileStore extends FileStoreBase {
+
+ readonly jag: Jag;
+ readonly caches: Map;
+
+ constructor(gameBuild: string | number, storePath: string = './') {
+ super(gameBuild, storePath);
+ this.jag = new Jag(this);
+ this.caches = new Map();
+ }
+
+ override async openDatabase(): Promise {
+ this._database = new JagDatabase(
+ this.gameBuild,
+ join(this.fileStorePath, 'index'),
+ [ 'error', 'warn' ],
+ );
+ await this._database.openConnection();
+ return this._database;
+ }
+
+ override async load(
+ loadCacheEntities: boolean = false,
+ loadCacheChildEntities: boolean = false,
+ loadArchiveChildEntities: boolean = false,
+ ): Promise {
+ logger.info(`Loading JAG store for build ${this.gameBuild}...`);
+ await this.openDatabase();
+
+ if (loadCacheEntities) {
+ await this.loadCacheEntities(loadCacheChildEntities, loadArchiveChildEntities);
+ }
+ }
+
+ /**
+ * Load all cache entities for this file store.
+ * @param loadCacheChildEntities Whether or not to load cache child file entities.
+ * Defaults to `false`.
+ * @param loadArchiveChildEntities Whether or not to load archive child file entities.
+ * Only works if `loadCacheChildEntities` is also set to `true`. Defaults to `false`.
+ */
+ async loadCacheEntities(
+ loadCacheChildEntities: boolean = false,
+ loadArchiveChildEntities: boolean = false,
+ ): Promise {
+ if (!this.caches.size) {
+ const cacheNames = Object.keys(caches);
+ for (const cacheName of cacheNames) {
+ this.createCache(caches[cacheName]);
+ }
+ }
+
+ for (const [ , cache ] of this.caches) {
+ await cache.loadIndex();
+ }
+
+ if (loadCacheChildEntities) {
+ logger.info(`Loading cache file entities...`);
+
+ for (const [ , cache ] of this.caches) {
+ await cache.loadFileIndexes();
+ }
+
+ if (loadArchiveChildEntities) {
+ logger.info(`Loading archive file entities...`);
+
+ const archiveIndex = this.getCache('archives');
+
+ for (const [ , file ] of archiveIndex.files) {
+ const archive = file as JagArchive;
+ await archive.loadFileIndexes();
+ }
+ }
+ }
+ }
+
+ createCache(cacheKey: number): void {
+ this.setCache(cacheKey, new JagCache(this, cacheKey));
+ }
+
+ getCache(cacheKey: number): JagCache | null;
+ getCache(cacheName: string): JagCache | null;
+ getCache(cacheKeyOrName: number | string): JagCache | null;
+ getCache(cacheKeyOrName: number | string): JagCache | null {
+ if (typeof cacheKeyOrName === 'string') {
+ return Array.from(this.caches.values()).find(
+ i => i?.index?.name === cacheKeyOrName
+ ) || null;
+ } else {
+ return this.caches.get(cacheKeyOrName) || null;
+ }
+ }
+
+ setCache(cacheKey: number, cache: JagCache): void;
+ setCache(cacheName: string, cache: JagCache): void;
+ setCache(cacheKeyOrName: number | string, cache: JagCache): void;
+ setCache(cacheKeyOrName: number | string, cache: JagCache): void {
+ if (typeof cacheKeyOrName === 'string') {
+ this.caches.set(caches[cacheKeyOrName], cache);
+ } else {
+ this.caches.set(cacheKeyOrName, cache);
+ }
+ }
+
+}
diff --git a/src/file-system/jag/jag-file.ts b/src/file-system/jag/jag-file.ts
new file mode 100644
index 0000000..bc7fff5
--- /dev/null
+++ b/src/file-system/jag/jag-file.ts
@@ -0,0 +1,11 @@
+import { JagFileStore } from './jag-file-store';
+import { JagFileBase } from './jag-file-base';
+
+
+export class JagFile extends JagFileBase {
+
+ constructor(jagStore: JagFileStore, fileKey: number, cacheKey: number, archiveKey: number = -1) {
+ super(jagStore, 'FILE', fileKey, cacheKey, archiveKey);
+ }
+
+}
diff --git a/src/file-system/jag/jag.ts b/src/file-system/jag/jag.ts
new file mode 100644
index 0000000..d918a96
--- /dev/null
+++ b/src/file-system/jag/jag.ts
@@ -0,0 +1,362 @@
+import { join } from 'path';
+import { existsSync, readdirSync, readFileSync, statSync } from 'graceful-fs';
+import { Buffer } from 'buffer';
+import { logger } from '@runejs/common';
+import { ByteBuffer } from '@runejs/common/buffer';
+import { Bzip2, Gzip } from '@runejs/common/compress';
+import { JagFileStore } from './jag-file-store';
+import { JagFile } from './jag-file';
+import { JagArchive } from './jag-archive';
+import { JagFileBase } from './jag-file-base';
+import { PackedCacheFile } from '../packed';
+
+
+const dataFileName = 'main_file_cache.dat';
+const indexFileNamePrefix = 'main_file_cache.idx';
+
+
+export const caches = {
+ archives: 0,
+ models: 1,
+ animations: 2,
+ midi: 3,
+ maps: 4,
+};
+
+
+export const archives = {
+ 'empty.jag': 0,
+ 'title.jag': 1,
+ 'config.jag': 2,
+ 'interface.jag': 3,
+ 'media.jag': 4,
+ 'versionlist.jag': 5,
+ 'textures.jag': 6,
+ 'wordenc.jag': 7,
+ 'sounds.jag': 8,
+};
+
+
+export interface JagFileIndex {
+ fileSize: number;
+ sectorNumber: number;
+}
+
+
+export interface JagSectorHeader {
+ fileKey: number;
+ filePartNumber: number;
+ sectorNumber: number;
+ cacheKey: number;
+}
+
+
+export class Jag {
+
+ readonly jagStore: JagFileStore;
+
+ private indexFiles: Map;
+ private dataFile: ByteBuffer;
+
+ constructor(jagStore: JagFileStore) {
+ this.jagStore = jagStore;
+ this.indexFiles = new Map();
+ }
+
+ readOpenRS2PackedCacheFiles(cacheFiles: PackedCacheFile[]): void {
+ const dataFileBuffer = cacheFiles.find(file => file.name === dataFileName)?.data || null;
+ if (!dataFileBuffer?.length) {
+ throw new Error(`The main ${ dataFileName } data file could not be found.`);
+ }
+
+ this.dataFile = new ByteBuffer(dataFileBuffer);
+ this.indexFiles.clear();
+
+ for (const cacheFile of cacheFiles) {
+ const fileName = cacheFile?.name;
+
+ if (!fileName?.length || fileName === dataFileName) {
+ continue;
+ }
+
+ if (!fileName.startsWith(indexFileNamePrefix)) {
+ continue;
+ }
+
+ if (!cacheFile?.data?.length) {
+ logger.error(`Index file ${ fileName } is empty!`);
+ continue;
+ }
+
+ const indexString = fileName.substring(fileName.indexOf('.idx') + 4);
+ const indexKey = Number(indexString);
+
+ if (isNaN(indexKey)) {
+ logger.error(`Index file ${ fileName } does not have a valid extension.`);
+ }
+
+ this.indexFiles.set(indexKey, new ByteBuffer(cacheFile.data));
+ this.jagStore.createCache(indexKey);
+ }
+
+ logger.info(`JAG store files loaded for game build ${this.jagStore.gameBuild}.`);
+ }
+
+ readLocalPackedCacheFiles(): void {
+ const jagStorePath = join(this.jagStore.fileStorePath, 'jag');
+
+ if (!existsSync(jagStorePath)) {
+ throw new Error(`${jagStorePath} could not be found.`);
+ }
+
+ const stats = statSync(jagStorePath);
+ if (!stats?.isDirectory()) {
+ throw new Error(`${jagStorePath} is not a valid directory.`);
+ }
+
+ const storeFileNames = readdirSync(jagStorePath);
+ const dataFileName = 'main_file_cache.dat';
+
+ if (storeFileNames.indexOf(dataFileName) === -1) {
+ throw new Error(`The main ${dataFileName} data file could not be found.`);
+ }
+
+ const indexFilePrefix = 'main_file_cache.idx';
+ const dataFilePath = join(jagStorePath, dataFileName);
+
+ this.dataFile = new ByteBuffer(readFileSync(dataFilePath));
+ this.indexFiles = new Map();
+
+ for (const fileName of storeFileNames) {
+ if (!fileName?.length || fileName === dataFileName) {
+ continue;
+ }
+
+ if (!fileName.startsWith(indexFilePrefix)) {
+ continue;
+ }
+
+ const indexString = fileName.substring(fileName.indexOf('.idx') + 4);
+ const indexKey = Number(indexString);
+
+ if (isNaN(indexKey)) {
+ logger.error(`Index file ${fileName} does not have a valid extension.`);
+ }
+
+ this.indexFiles.set(indexKey, new ByteBuffer(readFileSync(join(jagStorePath, fileName))));
+ this.jagStore.createCache(indexKey);
+ }
+
+ logger.info(`JAG store files loaded for game build ${this.jagStore.gameBuild}.`);
+ }
+
+ decodeCache(indexName: string): void {
+ logger.info(`Decoding JAG cache index ${indexName}...`);
+
+ const cacheKey = caches[indexName];
+ const indexFile = this.indexFiles.get(cacheKey);
+ const fileCount = indexFile.length / 6;
+
+ logger.info(`${fileCount} file indexes found.`);
+
+ const cache = this.jagStore.getCache(cacheKey);
+ cache.fileIndexes = new Array(fileCount);
+ cache.index.childCount = fileCount;
+ cache.index.compressionMethod = 'none';
+ cache.data.buffer = indexFile.toNodeBuffer();
+
+ for (let fileKey = 0; fileKey < fileCount; fileKey++) {
+ const fileSize = indexFile.get('int24', 'unsigned');
+ const sectorPos = indexFile.get('int24', 'unsigned');
+ cache.fileIndexes[fileKey] = {
+ fileSize, sectorNumber: sectorPos
+ };
+
+ let file: JagFileBase;
+
+ if (indexName === 'archives') {
+ file = new JagArchive(this.jagStore, fileKey);
+ } else {
+ file = new JagFile(this.jagStore, fileKey, cacheKey);
+ }
+
+ cache.files.set(fileKey, file);
+ }
+
+ cache.validate(false);
+
+ logger.info(`Cache index ${indexName} has been decoded.`);
+ }
+
+ unpack(file: JagArchive | JagFile): Buffer | null {
+ const fileIndexData = this.jagStore.getCache(file.index.cacheKey);
+ const { fileSize, sectorNumber } = fileIndexData.fileIndexes[file.index.key];
+ const fileData = new ByteBuffer(fileSize);
+ const sectorDataLength = 512;
+ const sectorLength = 520;
+ let remainingData = fileSize;
+ let currentSectorNumber = sectorNumber;
+ let cycles = 0;
+
+ while (remainingData > 0) {
+ let readableSectorData = sectorLength;
+ let remaining = this.dataFile.readable - currentSectorNumber * sectorLength;
+
+ if (remaining < sectorLength) {
+ readableSectorData = remaining;
+ }
+
+ const block = this.dataFile.getSlice(currentSectorNumber * sectorLength, readableSectorData);
+
+ const sectorFileKey = block.get('short', 'unsigned');
+ const sectorFilePartNumber = block.get('short', 'unsigned');
+ const sectorNumber = block.get('int24', 'unsigned');
+ const sectorCacheKey = block.get('byte', 'unsigned');
+
+ readableSectorData -= 8;
+
+ let bytesThisCycle = remainingData;
+
+ if (bytesThisCycle > sectorDataLength) {
+ bytesThisCycle = sectorDataLength;
+ }
+
+ block.copy(
+ fileData,
+ fileData.writerIndex,
+ block.readerIndex,
+ block.readerIndex + readableSectorData
+ );
+
+ fileData.writerIndex = fileData.writerIndex + bytesThisCycle;
+ remainingData -= bytesThisCycle;
+
+ if (cycles !== sectorFilePartNumber) {
+ logger.error(`Error extracting JAG file ${ file.index.key }, file data is corrupted.`);
+ return null;
+ }
+
+ if (remainingData > 0) {
+ // saved index keys have 1 added to them for some reason
+ if (sectorCacheKey !== file.index.cacheKey + 1) {
+ logger.error(`Index key mismatch, expected cache ${ file.index.cacheKey } but found ${ sectorCacheKey }`);
+ return null;
+ }
+
+ if (sectorFileKey !== file.index.key) {
+ logger.error(`File index mismatch, expected ${ file.index.key } but found ${ sectorFileKey }.`);
+ return null;
+ }
+ }
+
+ cycles++;
+ currentSectorNumber = sectorNumber;
+ }
+
+ if (!(file instanceof JagArchive)) {
+ file.index.compressionMethod = 'gzip';
+ }
+
+ if (fileData.length) {
+ file.compressedData.buffer = fileData.toNodeBuffer();
+
+ if (!(file instanceof JagArchive)) {
+ file.data.buffer = Gzip.decompress(fileData);
+ }
+ } else {
+ file.compressedData.buffer = null;
+ file.index.fileError = 'FILE_MISSING';
+ }
+
+ if (!(file instanceof JagArchive)) {
+ file.validate(false);
+ }
+
+ return file.compressedData.buffer;
+ }
+
+ decodeArchive(archive: JagArchive): Buffer | null {
+ if (!archive.compressedData?.buffer?.length) {
+ return null;
+ }
+
+ let archiveData = new ByteBuffer(archive.compressedData.buffer);
+
+ const uncompressed = archiveData.get('int24', 'unsigned');
+ const compressed = archiveData.get('int24', 'unsigned');
+
+ if (uncompressed !== compressed) {
+ const compressedData = archiveData.getSlice(archiveData.readerIndex, archiveData.length - archiveData.readerIndex);
+ const decompressedData = Bzip2.decompress(compressedData);
+ archiveData = new ByteBuffer(decompressedData);
+ archive.data.buffer = decompressedData;
+ archive.index.compressionMethod = 'bzip2';
+ } else {
+ archive.data.buffer = archiveData.toNodeBuffer();
+ archive.index.compressionMethod = 'none';
+ }
+
+ const fileCount = archiveData.get('short', 'unsigned');
+ archive.index.childCount = fileCount;
+ archive.files.clear();
+
+ const fileDataOffsets: number[] = new Array(fileCount);
+ let fileDataOffset = archiveData.readerIndex + fileCount * 10;
+
+ // Read archive file headers
+ for (let fileKey = 0; fileKey < fileCount; fileKey++) {
+ const fileNameHash = archiveData.get('int');
+ const fileName = this.jagStore.nameHasher.findFileName(fileNameHash);
+ const decompressedFileLength = archiveData.get('int24', 'unsigned');
+ const compressedFileLength = archiveData.get('int24', 'unsigned');
+ fileDataOffsets[fileKey] = fileDataOffset;
+ fileDataOffset += compressedFileLength;
+
+ const file = new JagFile(this.jagStore, fileKey, archive.index.cacheKey, archive.index.key);
+ file.index.nameHash = fileNameHash;
+ file.index.name = fileName;
+ file.index.fileSize = decompressedFileLength;
+ file.index.compressedFileSize = compressedFileLength;
+
+ archive.files.set(fileKey, file);
+ }
+
+ // Read archive file data
+ for (const [ fileKey, file ] of archive.files) {
+ try {
+ const fileDataOffset = fileDataOffsets[fileKey];
+ const fileData = Buffer.alloc(file.index.compressedFileSize);
+ archiveData.copy(fileData, 0, fileDataOffset);
+ file.compressedData.buffer = fileData;
+ } catch (error) {
+ logger.error(`Error reading archive ${archive.index.name } file ${fileKey}`, error);
+ }
+ }
+
+ // Decompress archive file data (if needed)
+ for (const [ fileKey, file ] of archive.files) {
+ try {
+ const { compressedFileSize, fileSize } = file.index;
+ if (file.compressedData?.buffer?.length && compressedFileSize !== fileSize) {
+ file.data.buffer = Bzip2.decompress(file.compressedData.buffer);
+ file.index.compressionMethod = 'bzip2';
+ } else {
+ file.data.buffer = file.compressedData.buffer;
+ file.index.compressionMethod = 'none';
+ }
+ } catch (error) {
+ logger.error(`Error decompressing archive ${archive.index.name } file ${fileKey}`, error);
+ }
+ }
+
+ // Validate each file
+ for (const [ , file ] of archive.files) {
+ file.validate(false);
+ }
+
+ archive.validate(false);
+
+ return archive.data.buffer;
+ }
+
+}
diff --git a/src/file-system/js5/content/config/config-file.ts b/src/file-system/js5/content/config/config-file.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/file-system/js5/content/config/js5-game-items.ts b/src/file-system/js5/content/config/js5-game-items.ts
new file mode 100644
index 0000000..f76c0f7
--- /dev/null
+++ b/src/file-system/js5/content/config/js5-game-items.ts
@@ -0,0 +1,158 @@
+import { Js5FileStore } from '../../js5-file-store';
+import { ByteBuffer } from '@runejs/common';
+
+
+export class Js5GameItem {
+ id: number;
+ inventoryModelId: number;
+ name: string;
+ modelZoom: number;
+ modelRotationX: number;
+ modelRotationY: number;
+ modelOffsetX: number;
+ modelOffsetY: number;
+ unknownServerAttribute1: number;
+ stackable: boolean = false;
+ value: number;
+ members: boolean = false;
+ maleModelId1: number;
+ maleModelOffset: number;
+ maleModelId2: number;
+ femaleModelId1: number;
+ femaleModelOffset: number;
+ femaleModelId2: number;
+ groundOptions: string[];
+ interfaceOptions: string[];
+ originalModelColors: number[];
+ modifiedModelColors: number[];
+ maleModelId3: number;
+ femaleModelId3: number;
+ maleDialogueModelId1: number;
+ femaleDialogueModelId1: number;
+ maleDialogueModelId2: number;
+ femaleDialogueModelId2: number;
+ modelRotationZ: number;
+ noteId: number;
+ noteTemplateId: number;
+ stackIds: number[];
+ stackAmounts: number[];
+ modelScaleX: number;
+ modelScaleY: number;
+ modelScaleZ: number;
+ lightingModifier: number;
+ shadowModifier: number;
+ teamIndex: number;
+}
+
+export class Js5GameItems {
+
+ readonly js5Store: Js5FileStore;
+ readonly items: Map;
+
+ constructor(js5Store: Js5FileStore) {
+ this.js5Store = js5Store;
+ this.items = new Map();
+ }
+
+ decode(id: number, data: ByteBuffer): Js5GameItem {
+ const item = new Js5GameItem();
+ item.id = id;
+
+ while (true) {
+ const o = data.get('byte', 'u');
+
+ if (o === 0) {
+ break; // eof
+ } else if (o === 1) {
+ item.inventoryModelId = data.get('short', 'u');
+ } else if (o === 2) {
+ item.name = data.getString();
+ } else if (o === 4) {
+ // case 3 was item description prior to build 400
+ item.modelZoom = data.get('short', 'u');
+ } else if (o === 5) {
+ item.modelRotationX = data.get('short', 'u');
+ } else if (o === 6) {
+ item.modelRotationY = data.get('short', 'u');
+ } else if (o === 7) {
+ // client subtracts 65536 if the value is over 32767
+ // so this should be a SIGNED short then, right?...
+ item.modelOffsetX = data.get('short', 'u');
+ } else if (o === 8) {
+ // client subtracts 65536 if the value is over 32767
+ // so this should be a SIGNED short then, right?...
+ item.modelOffsetY = data.get('short', 'u');
+ } else if (o === 10) {
+ // case 9 missing - what was it (if anything)?
+ item.unknownServerAttribute1 = data.get('short', 'u');
+ } else if (o === 11) {
+ item.stackable = true;
+ } else if (o === 12) {
+ item.value = data.get('int');
+ } else if (o === 16) {
+ // cases 13-15 missing - what were they (if anything)?
+ item.members = true;
+ } else if (o === 23) {
+ // cases 17-22 missing - what were they (if anything)?
+ item.maleModelId1 = data.get('short', 'u');
+ item.maleModelOffset = data.get('byte');
+ } else if (o === 24) {
+ item.maleModelId2 = data.get('short', 'u');
+ } else if (o === 25) {
+ item.femaleModelId1 = data.get('short', 'u');
+ item.femaleModelOffset = data.get('byte');
+ } else if (o === 26) {
+ item.femaleModelId2 = data.get('short', 'u');
+ } else if (o >= 30 && o < 35) {
+ // cases 27-29 missing - what were they (if anything)?
+ if (!item.groundOptions) {
+ item.groundOptions = new Array(5);
+ }
+
+ item.groundOptions[o - 30] = data.getString();
+ } else if (o >= 35 && o < 40) {
+ if (!item.interfaceOptions) {
+ item.interfaceOptions = new Array(5);
+ }
+
+ item.interfaceOptions[o - 35] = data.getString();
+ } else if (o === 40) {
+ const colorCount = data.get('byte', 'u');
+ item.originalModelColors = new Array(colorCount);
+ item.modifiedModelColors = new Array(colorCount);
+ for (let i = 0; i < colorCount; i++) {
+ item.originalModelColors[i] = data.get('short', 'u');
+ item.modifiedModelColors[i] = data.get('short', 'u');
+ }
+ } else if (o === 78) {
+ // cases 41-77 missing - what were they (if anything)?
+ item.maleModelId3 = data.get('short', 'u');
+ } else if (o === 79) {
+ item.femaleModelId3 = data.get('short', 'u');
+ } else if (o === 90) {
+ item.maleDialogueModelId1 = data.get('short', 'u');
+ } else if (o === 91) {
+ item.femaleDialogueModelId1 = data.get('short', 'u');
+ } else if (o === 92) {
+ item.maleDialogueModelId2 = data.get('short', 'u');
+ } else if (o === 93) {
+ item.femaleDialogueModelId2 = data.get('short', 'u');
+ } else if (o === 95) {
+ // case 94 missing - what was it (if anything)?
+ item.modelRotationZ = data.get('short', 'u');
+ } else if (o === 97) {
+ // case 96 missing - what was it (if anything)?
+ item.noteId = data.get('short', 'u');
+ } else if (o === 98) {
+ item.noteTemplateId = data.get('short', 'u');
+ } // @todo stopped here - 24/08/22 - Kiko
+ }
+
+ return item;
+ }
+
+ decodeAll(): void {
+
+ }
+
+}
diff --git a/src/file-system/js5/index.ts b/src/file-system/js5/index.ts
new file mode 100644
index 0000000..0832e68
--- /dev/null
+++ b/src/file-system/js5/index.ts
@@ -0,0 +1,6 @@
+export * from './js5';
+export * from './js5-file-base';
+export * from './js5-file-store';
+export * from './js5-archive';
+export * from './js5-group';
+export * from './js5-file';
diff --git a/src/file-system/js5/js5-archive.ts b/src/file-system/js5/js5-archive.ts
new file mode 100644
index 0000000..aa724e5
--- /dev/null
+++ b/src/file-system/js5/js5-archive.ts
@@ -0,0 +1,129 @@
+import { Js5FileStore } from './js5-file-store';
+import { Js5Group } from './js5-group';
+import { logger } from '@runejs/common';
+import { Js5FileBase } from './js5-file-base';
+import { Js5ArchiveConfig } from '../../config';
+import { Js5IndexEntity } from '../../db/js5';
+
+
+export class Js5Archive extends Js5FileBase {
+
+ readonly groups: Map;
+ readonly config: Js5ArchiveConfig;
+
+ constructor(
+ fileStore: Js5FileStore,
+ archiveKey: number,
+ ) {
+ super(fileStore, 'ARCHIVE', archiveKey, 255, -1);
+ this.config = fileStore.getArchiveConfig(archiveKey);
+ this.index.name = fileStore.getArchiveName(archiveKey);
+ this.groups = new Map();
+ }
+
+ override validate(trackChanges: boolean = true): void {
+ super.validate(trackChanges);
+
+ let archiveModified: boolean = false;
+
+ const { childCount } = this.index;
+ const newChildCount = this.groups.size;
+
+ if (childCount !== newChildCount) {
+ this.index.childCount = newChildCount;
+ archiveModified = true;
+ }
+
+ if (archiveModified && trackChanges) {
+ logger.info(`Archive ${this.index.name || this.index.key} child count has changed.`);
+ this.index.version++;
+ }
+ }
+
+ async upsertGroupIndexes(): Promise {
+ const groupIndexes = Array.from(this.groups.values()).map(group => group.index);
+ await this.fileStore.database.upsertIndexes(groupIndexes);
+ }
+
+ async loadGroupIndexes(): Promise {
+ const groupIndexes = await this.fileStore.database.getIndexes({
+ fileType: 'GROUP',
+ archiveKey: this.index.key,
+ });
+
+ if (!groupIndexes?.length) {
+ return;
+ }
+
+ for (const groupIndex of groupIndexes) {
+ const groupKey = groupIndex.key;
+
+ if (!this.groups.has(groupKey)) {
+ const group = new Js5Group(this.fileStore, groupKey, this);
+ group.index = groupIndex;
+ this.groups.set(groupKey, group);
+ }
+ }
+ }
+
+ async upsertGroupData(): Promise {
+ const groups = Array.from(this.groups.values());
+ const uncompressed = groups.map(group => group.data).filter(data => data?.buffer && data?.buffer?.length !== 0);
+ const compressed = groups.map(group => group.compressedData).filter(data => data?.buffer && data?.buffer?.length !== 0);
+ if (uncompressed.length) {
+ await this.fileStore.database.upsertAllUncompressedData(uncompressed);
+ }
+ if (compressed.length) {
+ await this.fileStore.database.upsertAllCompressedData(compressed);
+ }
+ }
+
+ async getGroup(groupKey: number): Promise;
+ async getGroup(groupName: string): Promise;
+ async getGroup(groupIdentifier: number | string): Promise;
+ async getGroup(groupIdentifier: number | string): Promise {
+ let group: Js5Group;
+
+ if (typeof groupIdentifier === 'string') {
+ group = Array.from(this.groups.values()).find(
+ group => group?.index?.name === groupIdentifier
+ ) || null;
+ } else {
+ group = this.groups.get(groupIdentifier) || null;
+ }
+
+ if (!group?.index) {
+ let groupEntity: Js5IndexEntity;
+
+ if (typeof groupIdentifier === 'number' || /^\d*$/.test(groupIdentifier)) {
+ const groupKey = typeof groupIdentifier === 'string' ? parseInt(groupIdentifier, 10) : groupIdentifier;
+ groupEntity = await this.fileStore.database.getIndex({
+ fileType: 'GROUP',
+ archiveKey: this.index.key,
+ key: groupKey
+ });
+ } else {
+ groupEntity = await this.fileStore.database.getIndex({
+ fileType: 'GROUP',
+ archiveKey: this.index.key,
+ name: String(groupIdentifier)
+ });
+ }
+
+ if (!group) {
+ group = new Js5Group(this.fileStore, groupEntity.key, this);
+ group.index = groupEntity;
+ this.groups.set(groupEntity.key, group);
+ } else {
+ group.index = groupEntity;
+ }
+ }
+
+ return group;
+ }
+
+ setGroup(groupKey: number, group: Js5Group): void {
+ this.groups.set(groupKey, group);
+ }
+
+}
diff --git a/src/file-system/js5/js5-file-base.ts b/src/file-system/js5/js5-file-base.ts
new file mode 100644
index 0000000..a4cae9c
--- /dev/null
+++ b/src/file-system/js5/js5-file-base.ts
@@ -0,0 +1,249 @@
+import { Buffer } from 'buffer';
+import { createHash } from 'crypto';
+import { logger } from '@runejs/common';
+import { Crc32 } from '@runejs/common/crc32';
+import { Js5FileStore } from './js5-file-store';
+import { Js5FileType } from '../../config';
+import { Js5IndexEntity, Js5DataEntity } from '../../db/js5';
+
+
+export abstract class Js5FileBase {
+
+ readonly fileStore: Js5FileStore;
+
+ index: Js5IndexEntity;
+ data: Js5DataEntity;
+ compressedData: Js5DataEntity;
+
+ protected constructor(
+ fileStore: Js5FileStore,
+ fileType: Js5FileType,
+ key: number,
+ archiveKey: number = -1,
+ groupKey: number = -1,
+ ) {
+ this.fileStore = fileStore;
+ this.index = new Js5IndexEntity();
+ this.data = new Js5DataEntity();
+ this.compressedData = new Js5DataEntity();
+ this.compressedData.compressed = true;
+ this.data.gameBuild = this.compressedData.gameBuild = this.index.gameBuild = fileStore.gameBuild;
+ this.data.fileType = this.compressedData.fileType = this.index.fileType = fileType;
+ this.data.key = this.compressedData.key = this.index.key = key;
+ this.data.archiveKey = this.compressedData.archiveKey = this.index.archiveKey = archiveKey;
+ this.data.groupKey = this.compressedData.groupKey = this.index.groupKey = groupKey;
+ }
+
+ validate(trackChanges: boolean = true): void {
+ const data = this.data.buffer;
+ const compressedData = this.compressedData.buffer;
+ const {
+ checksum, shaDigest, fileSize,
+ compressedChecksum, compressedShaDigest, compressedFileSize,
+ name, nameHash, compressionMethod
+ } = this.index;
+ let fileModified: boolean = false;
+
+ const currentChecksum = this.generateChecksum(data);
+ const currentShaDigest = this.generateShaDigest(data);
+ const currentFileSize = data?.length || 0;
+
+ const currentCompressedChecksum = this.generateChecksum(compressedData);
+ const currentCompressedShaDigest = this.generateShaDigest(compressedData);
+ const currentCompressedFileSize = compressedData?.length || 0;
+
+ if (name && nameHash === -1) {
+ // nameHash not set
+ this.index.nameHash = this.fileStore.nameHasher.hashJs5FileName(name);
+ }
+
+ if (nameHash !== -1 && !name) {
+ // name not set
+ const lookupTableName = this.fileStore.findFileName(this);
+ if (lookupTableName) {
+ this.index.name = lookupTableName;
+ }
+ }
+
+ if (checksum !== currentChecksum) {
+ // uncompressed crc32 mismatch
+ this.index.checksum = currentChecksum;
+ fileModified = true;
+ }
+
+ if (shaDigest !== currentShaDigest) {
+ // uncompressed sha256 mismatch
+ this.index.shaDigest = currentShaDigest;
+ fileModified = true;
+ }
+
+ if (fileSize !== currentFileSize) {
+ // uncompressed file size mismatch
+ this.index.fileSize = currentFileSize;
+ fileModified = true;
+ }
+
+ if (compressedChecksum !== currentCompressedChecksum) {
+ // compressed crc32 mismatch
+ this.index.compressedChecksum = currentCompressedChecksum;
+ fileModified = true;
+ }
+
+ if (compressedShaDigest !== currentCompressedShaDigest) {
+ // compressed sha256 mismatch
+ this.index.compressedShaDigest = currentCompressedShaDigest;
+ fileModified = true;
+ }
+
+ if (compressedFileSize !== currentCompressedFileSize) {
+ // compressed file size mismatch
+ this.index.compressedFileSize = currentCompressedFileSize;
+ fileModified = true;
+ }
+
+ if ((!this.index.compressionMethod || this.index.compressionMethod === 'none' || this.index.compressedFileSize === fileSize)
+ && this.compressedData?.buffer?.length) {
+ // File has no compression, clear the compressed data buffer so that we do not create a
+ // duplicate data entity record for it
+ this.compressedData.buffer = null;
+ this.index.compressedFileSize = 0;
+ this.index.compressedChecksum = -1;
+ this.index.compressedShaDigest = null;
+ }
+
+ if (fileModified && trackChanges) {
+ logger.info(`File ${this.index.name || this.index.key} has been modified.`);
+ this.index.version++;
+ }
+ }
+
+ async saveUncompressedData(): Promise {
+ if (!this.data?.buffer?.length) {
+ // Do not save a record for files with missing or empty data
+ return null;
+ }
+
+ this.data = await this.fileStore.database.saveUncompressedData(this.data);
+ return this.data;
+ }
+
+ async loadUncompressedData(): Promise {
+ const entity = await this.fileStore.database.getUncompressedData({
+ fileType: this.index.fileType,
+ key: this.index.key,
+ archiveKey: this.index.archiveKey,
+ groupKey: this.index.groupKey,
+ });
+
+ if (entity) {
+ this.data = entity;
+ }
+
+ return this.data;
+ }
+
+ async getUncompressedData(): Promise {
+ if (this.data?.buffer?.length) {
+ return this.data.buffer;
+ }
+
+ const uncompressedData = await this.loadUncompressedData();
+ if (uncompressedData?.buffer?.length) {
+ return uncompressedData.buffer;
+ }
+
+ return null;
+ }
+
+ async saveCompressedData(): Promise {
+ if (!this.compressedData?.buffer?.length) {
+ // Do not save a record for files with missing or empty data
+ return null;
+ }
+
+ this.compressedData = await this.fileStore.database.saveCompressedData(this.compressedData);
+ return this.compressedData;
+ }
+
+ async loadCompressedData(): Promise {
+ const entity = await this.fileStore.database.getCompressedData({
+ fileType: this.index.fileType,
+ key: this.index.key,
+ archiveKey: this.index.archiveKey,
+ groupKey: this.index.groupKey,
+ });
+
+ if (entity) {
+ this.compressedData = entity;
+ }
+
+ return this.compressedData;
+ }
+
+ async getCompressedData(): Promise {
+ if (!this.index) {
+ await this.loadIndex();
+ }
+
+ if (!this.index.compressionMethod || this.index.compressionMethod === 'none') {
+ return this.getUncompressedData();
+ }
+
+ if (this.compressedData?.buffer?.length) {
+ return this.compressedData.buffer;
+ }
+
+ const compressedData = await this.loadCompressedData();
+ if (compressedData?.buffer?.length) {
+ return compressedData.buffer;
+ }
+
+ return null;
+ }
+
+ async saveIndex(): Promise {
+ this.validate();
+ this.index = await this.fileStore.database.saveIndex(this.index);
+ return this.index;
+ }
+
+ async loadIndex(): Promise {
+ const indexEntity = await this.fileStore.database.getIndex({
+ fileType: this.index.fileType,
+ key: this.index.key,
+ archiveKey: this.index.archiveKey,
+ groupKey: this.index.groupKey,
+ });
+
+ if (indexEntity) {
+ this.index = indexEntity;
+ }
+
+ return this.index;
+ }
+
+ generateChecksum(data: Buffer): number {
+ if (!data?.length) {
+ return -1;
+ }
+
+ return Crc32.update(0, data.length, data);
+ }
+
+ generateShaDigest(data: Buffer): string {
+ if (!data?.length) {
+ return null;
+ }
+
+ return createHash('sha256').update(data).digest('hex');
+ }
+
+ get stripes(): number[] {
+ if (!this.index?.stripes) {
+ return [];
+ }
+
+ return this.index.stripes.split(',').map(n => Number(n));
+ }
+
+}
diff --git a/src/file-system/js5/js5-file-store.ts b/src/file-system/js5/js5-file-store.ts
new file mode 100644
index 0000000..fd16a7f
--- /dev/null
+++ b/src/file-system/js5/js5-file-store.ts
@@ -0,0 +1,240 @@
+import JSON5 from 'json5';
+import { join } from 'path';
+import { existsSync, readFileSync } from 'graceful-fs';
+import { Js5ArchiveConfig } from '../../config';
+import { JS5 } from './js5';
+import { Js5Archive } from './js5-archive';
+import { FileStoreBase } from '../file-store-base';
+import { logger } from '../../../../common';
+import { Js5Database, Js5IndexEntity } from '../../db/js5';
+import { Js5File } from './js5-file';
+import { Js5FileBase } from './js5-file-base';
+
+
+export class Js5FileStore extends FileStoreBase{
+
+ readonly js5: JS5;
+ readonly archives: Map;
+
+ private _archiveConfig: { [key: string]: Js5ArchiveConfig };
+ private _loaded: boolean = false;
+
+ constructor(gameBuild: string | number, storePath: string = './') {
+ super(gameBuild, storePath);
+ this.archives = new Map();
+ this.loadArchiveConfig();
+ this.js5 = new JS5(this);
+ }
+
+ override async openDatabase(): Promise {
+ this._database = new Js5Database(
+ this.gameBuild,
+ join(this.fileStorePath, 'index'),
+ [ 'error', 'warn' ],
+ );
+ await this._database.openConnection();
+ return this._database;
+ }
+
+ override async load(
+ loadArchiveEntities: boolean = false,
+ loadArchiveChildEntities: boolean = false,
+ loadGroupChildEntities: boolean = false,
+ ): Promise {
+ if (this._loaded) {
+ return;
+ }
+
+ await this.js5.loadEncryptionKeys();
+ await this.openDatabase();
+
+ if (loadArchiveEntities) {
+ await this.loadArchiveEntities(loadArchiveChildEntities, loadGroupChildEntities);
+ }
+
+ this._loaded = true;
+ }
+
+ /**
+ * Load all archive entities for this file store.
+ * @param loadArchiveChildEntities Whether or not to load group entities under each archive.
+ * Defaults to `false`.
+ * @param loadGroupChildEntities Whether or not to load flat file entities under each group.
+ * Only works if `loadArchiveChildEntities` is also set to `true`. Defaults to `false`.
+ */
+ async loadArchiveEntities(
+ loadArchiveChildEntities: boolean = false,
+ loadGroupChildEntities: boolean = false,
+ ): Promise {
+ if (!this.archives.size) {
+ const archiveEntities = await this.database.getIndexes({
+ fileType: 'ARCHIVE'
+ });
+
+ for (const entity of archiveEntities) {
+ const archive = this.createArchive(entity.key);
+ archive.index = entity;
+ }
+ } else {
+ for (const [ , archive ] of this.archives) {
+ await archive.loadIndex();
+ }
+ }
+
+ if (loadArchiveChildEntities) {
+ for (const [ , archive ] of this.archives) {
+ await archive.loadGroupIndexes();
+ }
+
+ if (loadGroupChildEntities) {
+ // Bulk load grouped files to save computing time
+ const files = await this.database.getIndexes({
+ fileType: 'FILE',
+ });
+
+ for (const fileEntity of files) {
+ const archive = await this.getArchive(fileEntity.archiveKey);
+ const group = await archive.getGroup(fileEntity.groupKey);
+ const file = new Js5File(this, fileEntity.key, group);
+ file.index = fileEntity;
+ group.setFile(fileEntity.key, file);
+ }
+ }
+ }
+ }
+
+ loadArchiveConfig(): void {
+ const configPath = join(this.fileStorePath, 'config', 'js5-archives.json5');
+
+ if (!existsSync(configPath)) {
+ logger.error(`Error loading file store: ${configPath} was not found.`);
+ return;
+ }
+
+ this._archiveConfig = JSON5.parse(
+ readFileSync(configPath, 'utf-8')
+ ) as { [key: string]: Js5ArchiveConfig };
+
+ if (!Object.values(this._archiveConfig)?.length) {
+ throw new Error(`Error reading archive configuration file. ` +
+ `Please ensure that the ${configPath} file exists and is valid.`);
+ }
+ }
+
+ findFileName(file: Js5FileBase): string | null {
+ const nameHash = file.index.nameHash || -1;
+
+ if (nameHash !== -1) {
+ return this.nameHasher.findFileName(nameHash, file.index.name || String(file.index.nameHash) || String(file.index.key));
+ }
+
+ const { key, groupKey, archiveKey, fileType } = file.index;
+
+ const archiveConfig = this.getArchiveConfig(fileType === 'ARCHIVE' ? key : archiveKey);
+
+ if (archiveConfig) {
+ if (fileType === 'GROUP' && archiveConfig.groupNames) {
+ const groupNames = Array.from(Object.entries(archiveConfig.groupNames));
+ return groupNames.find(([ , k ]) => k === key)?.[0] || null;
+ } else if (fileType === 'ARCHIVE') {
+ const configs = Array.from(Object.entries(this.archiveConfig));
+ return configs.find(([ , config ]) => config.key === archiveKey)?.[0] || null;
+ } else if (fileType === 'FILE') {
+ // @todo 2/9/22 - Kiko
+ }
+ }
+
+ return null;
+ }
+
+ createArchive(archiveKey: number): Js5Archive {
+ const archive = new Js5Archive(this, archiveKey);
+ this.setArchive(archiveKey, archive);
+ return archive;
+ }
+
+ async getArchive(archiveKey: number): Promise;
+ async getArchive(archiveName: string): Promise;
+ async getArchive(archiveIdentifier: number | string): Promise;
+ async getArchive(archiveIdentifier: number | string): Promise {
+ let archive: Js5Archive;
+
+ if (typeof archiveIdentifier === 'string') {
+ archive = Array.from(this.archives.values()).find(
+ a => a?.index?.name === archiveIdentifier
+ ) || null;
+ } else {
+ archive = this.archives.get(archiveIdentifier) || null;
+ }
+
+ if (!archive?.index) {
+ let archiveEntity: Js5IndexEntity;
+
+ if (typeof archiveIdentifier === 'number' || /^\d*$/.test(archiveIdentifier)) {
+ const archiveKey = typeof archiveIdentifier === 'string' ? parseInt(archiveIdentifier, 10) : archiveIdentifier;
+ archiveEntity = await this.database.getIndex({
+ fileType: 'ARCHIVE',
+ key: archiveKey
+ });
+ } else {
+ archiveEntity = await this.database.getIndex({
+ fileType: 'ARCHIVE',
+ name: String(archiveIdentifier)
+ });
+ }
+
+ if (!archive) {
+ archive = new Js5Archive(this, archiveEntity.key);
+ archive.index = archiveEntity;
+ this.archives.set(archiveEntity.key, archive);
+ } else {
+ archive.index = archiveEntity;
+ }
+ }
+
+ return archive;
+ }
+
+ setArchive(archiveKey: number, archive: Js5Archive): void;
+ setArchive(archiveName: string, archive: Js5Archive): void;
+ setArchive(archiveKeyOrName: number | string, archive: Js5Archive): void;
+ setArchive(archiveKeyOrName: number | string, archive: Js5Archive): void {
+ if (typeof archiveKeyOrName === 'string') {
+ const archiveConfig = this.getArchiveConfig(archiveKeyOrName);
+ if (archiveConfig) {
+ this.archives.set(archiveConfig.key, archive);
+ } else {
+ logger.error(`Archive ${ archiveKeyOrName } configuration was not found.`);
+ }
+ } else {
+ this.archives.set(archiveKeyOrName, archive);
+ }
+ }
+
+ getArchiveConfig(archiveKey: number): Js5ArchiveConfig | null;
+ getArchiveConfig(archiveName: string): Js5ArchiveConfig | null;
+ getArchiveConfig(archiveKeyOrName: number | string): Js5ArchiveConfig | null;
+ getArchiveConfig(archiveKeyOrName: number | string): Js5ArchiveConfig | null {
+ if (typeof archiveKeyOrName === 'string') {
+ return this._archiveConfig[archiveKeyOrName] || null;
+ } else {
+ return Object.values(this._archiveConfig).find(c => c.key === archiveKeyOrName) || null;
+ }
+ }
+
+ getArchiveName(archiveKey: number): string | null {
+ const archiveEntries = Object.entries(this._archiveConfig);
+ for (const [ name, config ] of archiveEntries) {
+ if (config.key === archiveKey) {
+ return name;
+ }
+ }
+
+ return null;
+ }
+
+ get archiveConfig(): { [key: string]: Js5ArchiveConfig } {
+ return this._archiveConfig;
+ }
+
+}
diff --git a/src/file-system/js5/js5-file.ts b/src/file-system/js5/js5-file.ts
new file mode 100644
index 0000000..c4fd8e1
--- /dev/null
+++ b/src/file-system/js5/js5-file.ts
@@ -0,0 +1,22 @@
+import { Js5FileStore } from './js5-file-store';
+import { Js5Archive } from './js5-archive';
+import { Js5Group } from './js5-group';
+import { Js5FileBase } from './js5-file-base';
+
+
+export class Js5File extends Js5FileBase {
+
+ readonly archive: Js5Archive;
+ readonly group: Js5Group;
+
+ constructor(
+ fileStore: Js5FileStore,
+ fileKey: number,
+ group: Js5Group,
+ ) {
+ super(fileStore, 'FILE', fileKey, group.archive.index.key, group.index.key);
+ this.archive = group.archive;
+ this.group = group;
+ }
+
+}
diff --git a/src/file-system/js5/js5-group.ts b/src/file-system/js5/js5-group.ts
new file mode 100644
index 0000000..53ea6d5
--- /dev/null
+++ b/src/file-system/js5/js5-group.ts
@@ -0,0 +1,132 @@
+import { Js5FileStore } from './js5-file-store';
+import { Js5Archive } from './js5-archive';
+import { Js5File } from './js5-file';
+import { logger } from '@runejs/common';
+import { Js5FileBase } from './js5-file-base';
+import { Js5IndexEntity } from '../../db/js5';
+
+
+export class Js5Group extends Js5FileBase {
+
+ readonly archive: Js5Archive;
+ readonly files: Map;
+
+ constructor(
+ fileStore: Js5FileStore,
+ groupKey: number,
+ archive: Js5Archive,
+ ) {
+ super(fileStore, 'GROUP', groupKey, archive.index.key);
+ this.archive = archive;
+ this.files = new Map();
+ }
+
+ override validate(trackChanges: boolean = true): void {
+ super.validate(trackChanges);
+
+ let groupModified: boolean = false;
+
+ const { childCount } = this.index;
+ const newChildCount = this.files.size;
+
+ if (childCount !== newChildCount) {
+ this.index.childCount = newChildCount;
+ groupModified = true;
+ }
+
+ if (groupModified && trackChanges) {
+ logger.info(`Group ${this.index.name || this.index.key} child count has changed.`);
+ this.index.version++;
+ }
+ }
+
+ async upsertFileIndexes(): Promise {
+ const fileIndexes = Array.from(this.files.values()).map(file => file.index);
+ await this.fileStore.database.upsertIndexes(fileIndexes);
+ }
+
+ async loadFileIndexes(): Promise {
+ const fileIndexes = await this.fileStore.database.getIndexes({
+ fileType: 'FILE',
+ archiveKey: this.archive.index.key,
+ groupKey: this.index.key,
+ });
+
+ if (!fileIndexes?.length) {
+ return;
+ }
+
+ for (const fileIndex of fileIndexes) {
+ const fileKey = fileIndex.key;
+
+ if (!this.files.has(fileKey)) {
+ const file = new Js5File(this.fileStore, fileKey, this);
+ file.index = fileIndex;
+ this.files.set(fileKey, file);
+ }
+ }
+ }
+
+ async upsertFileData(): Promise {
+ const files = Array.from(this.files.values());
+ const uncompressed = files.map(group => group.data).filter(data => data?.buffer && data?.buffer?.length !== 0);
+ const compressed = files.map(group => group.compressedData).filter(data => data?.buffer && data?.buffer?.length !== 0);
+ if (uncompressed.length) {
+ await this.fileStore.database.upsertAllUncompressedData(uncompressed);
+ }
+ if (compressed.length) {
+ await this.fileStore.database.upsertAllCompressedData(compressed);
+ }
+ }
+
+ async getFile(fileKey: number): Promise;
+ async getFile(fileName: string): Promise;
+ async getFile(fileIdentifier: number | string): Promise;
+ async getFile(fileIdentifier: number | string): Promise {
+ let file: Js5File;
+
+ if (typeof fileIdentifier === 'string') {
+ file = Array.from(this.files.values()).find(
+ file => file?.index?.name === fileIdentifier
+ ) || null;
+ } else {
+ file = this.files.get(fileIdentifier) || null;
+ }
+
+ if (!file?.index) {
+ let fileEntity: Js5IndexEntity;
+
+ if (typeof fileIdentifier === 'number' || /^\d*$/.test(fileIdentifier)) {
+ const fileKey = typeof fileIdentifier === 'string' ? parseInt(fileIdentifier, 10) : fileIdentifier;
+ fileEntity = await this.fileStore.database.getIndex({
+ fileType: 'GROUP',
+ archiveKey: this.index.archiveKey,
+ groupKey: this.index.key,
+ key: fileKey
+ });
+ } else {
+ fileEntity = await this.fileStore.database.getIndex({
+ fileType: 'GROUP',
+ archiveKey: this.index.archiveKey,
+ groupKey: this.index.key,
+ name: String(fileIdentifier)
+ });
+ }
+
+ if (!file) {
+ file = new Js5File(this.fileStore, fileEntity.key, this);
+ file.index = fileEntity;
+ this.files.set(fileEntity.key, file);
+ } else {
+ file.index = fileEntity;
+ }
+ }
+
+ return file;
+ }
+
+ setFile(fileKey: number, file: Js5File): void {
+ this.files.set(fileKey, file);
+ }
+
+}
diff --git a/src/file-system/js5/js5.ts b/src/file-system/js5/js5.ts
new file mode 100644
index 0000000..e9a209e
--- /dev/null
+++ b/src/file-system/js5/js5.ts
@@ -0,0 +1,886 @@
+import { join } from 'path';
+import { Buffer } from 'buffer';
+import { existsSync, readdirSync, readFileSync, statSync } from 'graceful-fs';
+
+import { logger } from '@runejs/common';
+import { ByteBuffer } from '@runejs/common/buffer';
+import { getCompressionMethod, Gzip, Bzip2 } from '@runejs/common/compress';
+import { Xtea, XteaKeys, XteaConfig } from '@runejs/common/encrypt';
+
+import { Js5FileStore, Js5Archive, Js5Group, Js5File } from '.';
+import { archiveFlags, ArchiveFormat } from '../../config';
+import { getXteaKeysByBuild } from '../../openrs2';
+import { PackedCacheFile } from '../packed';
+
+
+const dataFileName = 'main_file_cache.dat2';
+const indexFileNamePrefix = 'main_file_cache.idx';
+const mainIndexFileName = `${ indexFileNamePrefix }255`;
+
+
+export class JS5 {
+
+ readonly fileStore: Js5FileStore;
+
+ localEncryptionKeys: Map;
+ openRS2EncryptionKeys: XteaConfig[];
+
+ private mainIndexFile: ByteBuffer;
+ private indexFiles: Map;
+ private dataFile: ByteBuffer;
+
+ constructor(fileStore: Js5FileStore) {
+ this.fileStore = fileStore;
+ this.indexFiles = new Map();
+ }
+
+ readOpenRS2CacheFiles(cacheFiles: PackedCacheFile[]): void {
+ const dataFileBuffer = cacheFiles.find(file => file.name === dataFileName)?.data || null;
+ if (!dataFileBuffer?.length) {
+ throw new Error(`The main ${ dataFileName } data file could not be found.`);
+ }
+
+ const mainIndexFileBuffer = cacheFiles.find(file => file.name === mainIndexFileName)?.data || null;
+ if (!mainIndexFileBuffer?.length) {
+ throw new Error(`The main ${ mainIndexFileName } index file could not be found.`);
+ }
+
+ this.dataFile = new ByteBuffer(dataFileBuffer);
+ this.mainIndexFile = new ByteBuffer(mainIndexFileBuffer);
+ this.indexFiles.clear();
+
+ for (const cacheFile of cacheFiles) {
+ const fileName = cacheFile?.name;
+
+ if (!fileName?.length || fileName === mainIndexFileName || fileName === dataFileName) {
+ continue;
+ }
+
+ if (!fileName.startsWith(indexFileNamePrefix)) {
+ continue;
+ }
+
+ if (!cacheFile?.data?.length) {
+ logger.error(`Index file ${ fileName } is empty!`);
+ continue;
+ }
+
+ const indexString = fileName.substring(fileName.indexOf('.idx') + 4);
+ const archiveKey = Number(indexString);
+
+ if (isNaN(archiveKey)) {
+ logger.error(`Index file ${ fileName } does not have a valid extension.`);
+ }
+
+ this.indexFiles.set(archiveKey, new ByteBuffer(cacheFile.data));
+ this.fileStore.createArchive(archiveKey);
+ }
+
+ logger.info(`JS5 store file loaded for game build ${ this.fileStore.gameBuild }.`);
+ }
+
+ readLocalCacheFiles(): void {
+ const js5StorePath = join(this.fileStore.fileStorePath, 'js5');
+
+ if (!existsSync(js5StorePath)) {
+ throw new Error(`${ js5StorePath } could not be found.`);
+ }
+
+ const stats = statSync(js5StorePath);
+ if (!stats?.isDirectory()) {
+ throw new Error(`${ js5StorePath } is not a valid directory.`);
+ }
+
+ const storeFileNames = readdirSync(js5StorePath);
+
+ if (storeFileNames.indexOf(dataFileName) === -1) {
+ throw new Error(`The main ${ dataFileName } data file could not be found.`);
+ }
+
+ if (storeFileNames.indexOf(mainIndexFileName) === -1) {
+ throw new Error(`The main ${ mainIndexFileName } index file could not be found.`);
+ }
+
+ const dataFilePath = join(js5StorePath, dataFileName);
+ const mainIndexFilePath = join(js5StorePath, mainIndexFileName);
+
+ this.dataFile = new ByteBuffer(readFileSync(dataFilePath));
+ this.mainIndexFile = new ByteBuffer(readFileSync(mainIndexFilePath));
+ this.indexFiles.clear();
+
+ for (const fileName of storeFileNames) {
+ if (!fileName?.length || fileName === mainIndexFileName || fileName === dataFileName) {
+ continue;
+ }
+
+ if (!fileName.startsWith(indexFileNamePrefix)) {
+ continue;
+ }
+
+ const indexString = fileName.substring(fileName.indexOf('.idx') + 4);
+ const archiveKey = Number(indexString);
+
+ if (isNaN(archiveKey)) {
+ logger.error(`Index file ${ fileName } does not have a valid extension.`);
+ }
+
+ this.indexFiles.set(archiveKey, new ByteBuffer(readFileSync(join(js5StorePath, fileName))));
+ this.fileStore.createArchive(archiveKey);
+ }
+
+ logger.info(`JS5 store file loaded for game build ${ this.fileStore.gameBuild }.`);
+ }
+
+ unpack(file: Js5Group | Js5Archive): Buffer | null {
+ const fileIndex = file.index;
+ const fileKey = fileIndex.key;
+ const archiveKey: number = file instanceof Js5Archive ? 255 : file.archive.index.key;
+ const archiveName: string = file instanceof Js5Archive ? 'main' : file.archive.index.name;
+
+ const indexChannel: ByteBuffer = archiveKey !== 255 ?
+ this.indexFiles.get(archiveKey) : this.mainIndexFile;
+
+ if (archiveKey === 255 && fileKey === 255) {
+ return null;
+ }
+
+ const indexDataLength = 6;
+ const dataChannel = this.dataFile;
+
+ indexChannel.readerIndex = 0;
+ dataChannel.readerIndex = 0;
+
+ let pointer = fileKey * indexDataLength;
+
+ if (pointer < 0 || pointer >= indexChannel.length) {
+ logger.error(`File ${ fileKey } was not found within the ${ archiveName } archive index file.`);
+ return null;
+ }
+
+ const fileIndexData = new ByteBuffer(indexDataLength);
+ indexChannel.copy(fileIndexData, 0, pointer, pointer + indexDataLength);
+
+ if (fileIndexData.readable !== indexDataLength) {
+ logger.error(`Error extracting JS5 file ${ fileKey }: the end of the data stream was reached.`);
+ return null;
+ }
+
+ fileIndex.fileSize = fileIndexData.get('int24', 'unsigned');
+ const sectorNumber = fileIndexData.get('int24', 'unsigned');
+
+ if (fileIndex.fileSize <= 0) {
+ logger.warn(`JS5 file ${ fileKey } is empty or has been removed.`);
+ return null;
+ }
+
+ const data = new ByteBuffer(fileIndex.fileSize);
+ const sectorDataLength = 512;
+ const sectorLength = 520;
+
+ let sector = 0;
+ let remainingData = fileIndex.fileSize;
+ pointer = sectorNumber * sectorLength;
+
+ do {
+ const temp = new ByteBuffer(sectorLength);
+ dataChannel.copy(temp, 0, pointer, pointer + sectorLength);
+
+ if (temp.readable !== sectorLength) {
+ logger.error(`Error reading stripe for packed file ${ fileKey }, the end of the data stream was reached.`);
+ return null;
+ }
+
+ const sectorFileKey = temp.get('short', 'unsigned');
+ const sectorFilePartNumber = temp.get('short', 'unsigned');
+ const sectorNumber = temp.get('int24', 'unsigned');
+ const sectorIndexKey = temp.get('byte', 'unsigned');
+
+ const sectorData = new ByteBuffer(sectorDataLength);
+ temp.copy(sectorData, 0, temp.readerIndex, temp.readerIndex + sectorDataLength);
+
+ if (remainingData > sectorDataLength) {
+ sectorData.copy(data, data.writerIndex, 0, sectorDataLength);
+ data.writerIndex = (data.writerIndex + sectorDataLength);
+ remainingData -= sectorDataLength;
+
+ if (sectorIndexKey !== archiveKey) {
+ logger.error(`Archive index mismatch, expected archive ${ archiveKey } but found ${ sectorFileKey }`);
+ return null;
+ }
+
+ if (sectorFileKey !== fileKey) {
+ logger.error(`File index mismatch, expected ${ fileKey } but found ${ sectorFileKey }.`);
+ return null;
+ }
+
+ if (sectorFilePartNumber !== sector++) {
+ logger.error(`Error extracting JS5 file ${ fileKey }, file data is corrupted.`);
+ return null;
+ }
+
+ pointer = sectorNumber * sectorLength;
+ } else {
+ sectorData.copy(data, data.writerIndex, 0, remainingData);
+ data.writerIndex = (data.writerIndex + remainingData);
+ remainingData = 0;
+ }
+ } while (remainingData > 0);
+
+ if (data.length) {
+ file.compressedData.buffer = data.toNodeBuffer();
+ } else {
+ file.compressedData.buffer = null;
+ fileIndex.fileError = 'FILE_MISSING';
+ }
+
+ return file.compressedData.buffer;
+ }
+
+ readCompressedFileHeader(file: Js5Group | Js5Archive): { compressedLength: number, readerIndex: number } {
+ const fileDetails = file.index;
+
+ if (!file.compressedData.buffer?.length) {
+ return { compressedLength: 0, readerIndex: 0 };
+ }
+
+ const compressedData = new ByteBuffer(file.compressedData.buffer);
+
+ fileDetails.compressionMethod = getCompressionMethod(
+ compressedData.get('byte', 'unsigned'));
+
+ const compressedLength = compressedData.get('int', 'unsigned');
+ const readerIndex = compressedData.readerIndex;
+
+ return { compressedLength, readerIndex };
+ }
+
+ decrypt(file: Js5Group | Js5Archive): Buffer {
+ const fileDetails = file.index;
+ const fileName = fileDetails.name;
+
+ if (!file.compressedData.buffer?.length) {
+ logger.error(`Error decrypting file ${ fileName || fileDetails.key }, file data not found.`,
+ `Please ensure that the file has been unpacked from an existing JS5 file store using JS5.unpack(file);`);
+ return null;
+ }
+
+ const archiveName = file instanceof Js5Archive ? 'main' : file.archive.index.name;
+ const archiveConfig = this.fileStore.archiveConfig[archiveName];
+
+ if (archiveConfig.encryption) {
+ const [ encryption, pattern ] = archiveConfig.encryption;
+ const patternRegex = new RegExp(pattern);
+
+ // Only XTEA encryption is supported at this time
+ if (encryption !== 'xtea' || !patternRegex.test(fileName)) {
+ // FileBase name does not match the pattern, data should be unencrypted
+ return file.compressedData.buffer;
+ }
+ } else {
+ return file.compressedData.buffer;
+ }
+
+ const gameBuild = this.fileStore.gameBuild;
+ let keySets: XteaKeys[] = [];
+
+ const loadedKeys = this.getEncryptionKeys(fileName);
+ if (loadedKeys) {
+ if (!Array.isArray(loadedKeys)) {
+ keySets = [ loadedKeys ];
+ } else {
+ keySets = loadedKeys;
+ }
+ }
+
+ try {
+ const { compressedLength, readerIndex } = this.readCompressedFileHeader(file);
+ const encryptedData = new ByteBuffer(file.compressedData.buffer);
+ const keySet = keySets.find(keySet => keySet.gameBuild === gameBuild);
+
+ if (Xtea.validKeys(keySet?.key)) {
+ const dataCopy = encryptedData.clone();
+ dataCopy.readerIndex = readerIndex;
+
+ let lengthOffset = readerIndex;
+ if (dataCopy.length - (compressedLength + readerIndex + 4) >= 2) {
+ lengthOffset += 2;
+ }
+
+ const decryptedData = Xtea.decrypt(dataCopy, keySet.key, dataCopy.length - lengthOffset);
+
+ if (decryptedData?.length) {
+ decryptedData.copy(dataCopy, readerIndex, 0);
+ dataCopy.readerIndex = readerIndex;
+ file.compressedData.buffer = dataCopy.toNodeBuffer();
+ fileDetails.encrypted = false;
+ file.validate(false);
+ return file.compressedData.buffer;
+ } else {
+ logger.warn(`Invalid XTEA decryption keys found for file ` +
+ `${ fileName || fileDetails.key } using game build ${ gameBuild }.`);
+ fileDetails.fileError = 'MISSING_ENCRYPTION_KEYS';
+ }
+ } else {
+ logger.warn(`No XTEA decryption keys found for file ` +
+ `${ fileName || fileDetails.key } using game build ${ gameBuild }.`);
+ fileDetails.fileError = 'MISSING_ENCRYPTION_KEYS';
+ }
+ } catch (err) {
+ logger.error(err);
+ }
+
+ return null;
+ }
+
+ decompress(file: Js5Group | Js5Archive): Buffer | null {
+ const fileDetails = file.index;
+
+ if (!file.compressedData.buffer?.length) {
+ return null;
+ }
+
+ if (!this.decrypt(file)) {
+ fileDetails.encrypted = true;
+ return null;
+ }
+
+ let data: Buffer;
+
+ try {
+ const { compressedLength, readerIndex } = this.readCompressedFileHeader(file);
+
+ // JS5.decrypt will set compressedData to the new decrypted data after completion
+ const compressedData = new ByteBuffer(file.compressedData.buffer);
+ compressedData.readerIndex = readerIndex;
+
+ if (fileDetails.compressionMethod === 'none') {
+ // Uncompressed file
+ data = Buffer.alloc(compressedLength);
+ compressedData.copy(data, 0, compressedData.readerIndex, compressedLength);
+ compressedData.readerIndex = (compressedData.readerIndex + compressedLength);
+ } else {
+ // BZIP or GZIP compressed file
+ const decompressedLength = compressedData.get('int', 'unsigned');
+ if (decompressedLength < 0) {
+ const errorPrefix = `Unable to decompress file ${ fileDetails.name || fileDetails.key }:`;
+ if (fileDetails.fileError === 'FILE_MISSING') {
+ logger.error(`${ errorPrefix } Missing file data.`);
+ } else {
+ logger.error(`${ errorPrefix } Missing or invalid XTEA key.`);
+ fileDetails.fileError = 'MISSING_ENCRYPTION_KEYS';
+ }
+ } else {
+ const fileData = new ByteBuffer(compressedLength);
+
+ compressedData.copy(fileData, 0, compressedData.readerIndex);
+
+ data = fileDetails.compressionMethod === 'bzip2' ?
+ Bzip2.decompress(fileData) :
+ Gzip.decompress(fileData);
+
+ compressedData.readerIndex = compressedData.readerIndex + compressedLength;
+
+ if (data.length !== decompressedLength) {
+ logger.error(`Compression length mismatch.`);
+ data = null;
+ }
+ }
+ }
+
+ if (data?.length) {
+ // Read the file footer, if it has one
+ if (compressedData.readable >= 2) {
+ fileDetails.version = compressedData.get('short', 'unsigned');
+ }
+ }
+ } catch (error) {
+ logger.error(`Error decompressing file ${ fileDetails.name || fileDetails.key }: ` +
+ `${ error?.message ?? error }`);
+ data = null;
+ }
+
+ file.data.buffer = data;
+ file.validate(false);
+ return file.data.buffer;
+ }
+
+ async decodeGroup(group: Js5Group): Promise {
+ const groupDetails = group.index;
+ const { key: groupKey, name: groupName } = groupDetails;
+ const files = group.files;
+
+ if (!group.data.buffer) {
+ this.decompress(group);
+
+ if (!group.data.buffer) {
+ if (!groupDetails.fileError) {
+ logger.warn(`Unable to decode group ${ groupName || groupKey }.`);
+ }
+ return;
+ }
+ }
+
+ const data = new ByteBuffer(group.data.buffer);
+
+ if (groupDetails.childCount === 1) {
+ return;
+ }
+
+ data.readerIndex = (data.length - 1); // EOF - 1 byte
+
+ groupDetails.stripeCount = data.get('byte', 'unsigned');
+
+ data.readerIndex = (data.length - 1 - groupDetails.stripeCount *
+ groupDetails.childCount * 4); // Stripe data footer
+
+ if (data.readerIndex < 0) {
+ logger.error(`Invalid reader index of ${ data.readerIndex } for group ` +
+ `${ groupName || groupKey }.`);
+ return;
+ }
+
+ const fileSizeMap = new Map();
+ const fileStripeMap = new Map();
+ const fileDataMap = new Map();
+
+ for (const [ flatFileKey, ] of files) {
+ fileSizeMap.set(flatFileKey, 0);
+ fileStripeMap.set(flatFileKey, new Array(groupDetails.stripeCount));
+ }
+
+ for (let stripe = 0; stripe < groupDetails.stripeCount; stripe++) {
+ let currentLength = 0;
+
+ for (const [ flatFileKey, ] of files) {
+ const delta = data.get('int');
+ currentLength += delta;
+
+ const fileStripes = fileStripeMap.get(flatFileKey);
+ const size = fileSizeMap.get(flatFileKey) + currentLength;
+
+ fileStripes[stripe] = currentLength;
+ fileSizeMap.set(flatFileKey, size + currentLength);
+ }
+ }
+
+ for (const [ flatFileKey, file ] of files) {
+ file.index.fileSize = fileSizeMap.get(flatFileKey);
+ file.index.stripeCount = groupDetails.stripeCount;
+ file.index.stripes = fileStripeMap.get(flatFileKey).join(',');
+ fileDataMap.set(flatFileKey, new ByteBuffer(file.index.fileSize));
+ }
+
+ data.readerIndex = 0;
+
+ for (let stripe = 0; stripe < groupDetails.stripeCount; stripe++) {
+ for (const [ fileIndex, ] of files) {
+ let stripeLength = fileStripeMap.get(fileIndex)[stripe];
+ let sourceEnd: number = data.readerIndex + stripeLength;
+
+ if (data.readerIndex + stripeLength >= data.length) {
+ sourceEnd = data.length;
+ stripeLength = (data.readerIndex + stripeLength) - data.length;
+ }
+
+ const stripeData = data.getSlice(data.readerIndex, stripeLength);
+ const fileData = fileDataMap.get(fileIndex);
+
+ fileData.putBytes(stripeData);
+
+ data.readerIndex = sourceEnd;
+ }
+ }
+
+ for (const [ fileIndex, file ] of files) {
+ file.data.buffer = fileDataMap.get(fileIndex).toNodeBuffer();
+ file.validate(false);
+ }
+
+ group.validate(false);
+ }
+
+ async decodeArchive(archive: Js5Archive): Promise {
+ const archiveDetails = archive.index;
+
+ if (archiveDetails.key === 255) {
+ return;
+ }
+
+ const archiveName = archiveDetails.name;
+
+ logger.info(`Decoding archive ${ archiveName }...`);
+
+ if (!archive.data.buffer) {
+ this.decompress(archive);
+
+ if (!archive.data.buffer) {
+ logger.error(`Unable to decode archive ${ archiveName }.`);
+ return;
+ }
+ }
+
+ const archiveData = new ByteBuffer(archive.data.buffer);
+ const format = archiveDetails.archiveFormat = archiveData.get('byte', 'unsigned');
+ const mainDataType = format >= ArchiveFormat.smart ? 'smart_int' : 'short';
+ archiveDetails.version = format >= ArchiveFormat.versioned ? archiveData.get('int') : 0;
+ const flags = archiveFlags(archiveData.get('byte', 'unsigned'));
+ const groupCount = archiveData.get(mainDataType, 'unsigned');
+ const groups: Js5Group[] = new Array(groupCount);
+ let accumulator = 0;
+
+ logger.info(`${ groupCount } groups were found within the ${ archiveName } archive.`);
+
+ // Group index keys
+ for (let i = 0; i < groupCount; i++) {
+ const delta = archiveData.get(mainDataType, 'unsigned');
+ const groupKey = accumulator += delta;
+ const group = groups[i] = new Js5Group(this.fileStore, groupKey, archive);
+ archive.setGroup(groupKey, group);
+ }
+
+ // Group name hashes
+ if (flags.groupNames) {
+ for (const group of groups) {
+ group.index.nameHash = archiveData.get('int');
+ group.index.name = this.fileStore.findFileName(group);
+ }
+ }
+
+ // Compressed file data CRC32 checksums
+ for (const group of groups) {
+ group.index.compressedChecksum = archiveData.get('int');
+ }
+
+ // Decompressed file data CRC32 checksums
+ if (flags.decompressedCrcs) {
+ for (const group of groups) {
+ group.index.checksum = archiveData.get('int');
+ }
+ }
+
+ // File data whirlpool digests
+ if (flags.whirlpoolDigests) {
+ for (const group of groups) {
+ group.index.whirlpoolDigest = Buffer.alloc(512);
+ archiveData.getBytes(group.index.whirlpoolDigest, 512);
+ }
+ }
+
+ // Group file sizes
+ if (flags.groupSizes) {
+ for (const group of groups) {
+ group.index.compressedFileSize = archiveData.get('int');
+ group.index.fileSize = archiveData.get('int');
+ }
+ }
+
+ // Group version numbers
+ for (const group of groups) {
+ group.index.version = archiveData.get('int');
+ }
+
+ // Group child file counts
+ for (let i = 0; i < groupCount; i++) {
+ groups[i].index.childCount = archiveData.get('short', 'unsigned');
+ }
+
+ // Grouped file index keys
+ for (const group of groups) {
+ const fileCount = group.index.childCount || 0;
+ accumulator = 0;
+
+ for (let i = 0; i < fileCount; i++) {
+ const delta = archiveData.get(mainDataType, 'unsigned');
+ const childFileIndex = accumulator += delta;
+ const flatFile = new Js5File(this.fileStore, childFileIndex, group);
+ group.setFile(childFileIndex, flatFile);
+ }
+ }
+
+ // Grouped file names
+ if (flags.groupNames) {
+ for (const group of groups) {
+ for (const [ , flatFile ] of group.files) {
+ flatFile.index.nameHash = archiveData.get('int');
+ flatFile.index.name = this.fileStore.findFileName(flatFile);
+ }
+ }
+ }
+
+ archive.validate(false);
+ }
+
+ // @todo stubbed - 21/07/22 - Kiko
+ decodeMainIndex(): Buffer | null {
+ return null;
+ }
+
+ // @todo stubbed - 21/07/22 - Kiko
+ pack(file: Js5Group | Js5Archive): Buffer | null {
+ return null;
+ }
+
+ // @todo stubbed - 21/07/22 - Kiko
+ encrypt(file: Js5Group | Js5Archive): Buffer | null {
+ return null;
+ }
+
+ compress(file: Js5Group | Js5Archive): Buffer | null {
+ const fileDetails = file.index;
+
+ if (!file.data.buffer?.length) {
+ return null;
+ }
+
+ const decompressedData = new ByteBuffer(file.data.buffer);
+ let data: ByteBuffer;
+
+ if (fileDetails.compressionMethod === 'none') {
+ // uncompressed files
+ data = new ByteBuffer(decompressedData.length + 5);
+
+ // indicate that no file compression is applied
+ data.put(0);
+
+ // write the uncompressed file length
+ data.put(decompressedData.length, 'int');
+
+ // write the uncompressed file data
+ data.putBytes(decompressedData);
+ } else {
+ // compressed Bzip2 or Gzip file
+
+ const compressedData: Buffer = fileDetails.compressionMethod === 'bzip2' ?
+ Bzip2.compress(decompressedData) :
+ Gzip.compress(decompressedData);
+
+ const compressedLength: number = compressedData.length;
+
+ data = new ByteBuffer(compressedData.length + 9);
+
+ // indicate which type of file compression was used (1 or 2)
+ data.put(fileDetails.compressionMethod === 'bzip2' ? 1 : 2);
+
+ // write the compressed file length
+ data.put(compressedLength, 'int');
+
+ // write the uncompressed file length
+ data.put(decompressedData.length, 'int');
+
+ // write the compressed file data
+ data.putBytes(compressedData);
+ }
+
+ if (data?.length) {
+ file.compressedData.buffer = data.toNodeBuffer();
+ }
+
+ return file.compressedData.buffer;
+ }
+
+ encodeGroup(group: Js5Group): Buffer | null {
+ const { files: fileMap, index, stripes } = group;
+ const fileCount = fileMap.size;
+
+ // Single-file group
+ if (fileCount <= 1) {
+ group.data.buffer = fileMap.get(0)?.data?.buffer || null;
+ return group.data.buffer;
+ }
+
+ // Multi-file group
+ const files = Array.from(fileMap.values());
+ const fileSizes = files.map(file => file.index.fileSize);
+ const stripeCount = stripes?.length ?? 1;
+
+ // Size of all individual files + 1 int per file containing it's size
+ // + 1 at the end for the total group stripe count
+ const groupSize = fileSizes.reduce(
+ (a, c) => a + c) + (stripeCount * fileCount * 4
+ ) + 1;
+
+ const groupBuffer = new ByteBuffer(groupSize);
+
+ // Write child file data
+ for (let stripe = 0; stripe < stripeCount; stripe++) {
+ files.forEach(file => {
+ const fileData = file.data.buffer;
+ if (!fileData?.length) {
+ return;
+ }
+
+ const fileBuffer = new ByteBuffer(fileData);
+ const stripeSize = file.stripes?.[stripe] ?? 0;
+
+ if (stripeSize) {
+ const stripeData = fileBuffer.getSlice(fileBuffer.readerIndex, stripeSize);
+ fileBuffer.readerIndex = fileBuffer.readerIndex + stripeSize;
+ groupBuffer.putBytes(stripeData);
+ }
+ });
+ }
+
+ // Write child file stripe lengths
+ for (let stripe = 0; stripe < stripeCount; stripe++) {
+ let prevSize = 0;
+ files.forEach(file => {
+ const fileData = file.data.buffer;
+ if (!fileData?.length) {
+ return;
+ }
+
+ const stripeLength = file.stripes?.[stripe] ?? 0;
+ groupBuffer.put(stripeLength - prevSize, 'int');
+ prevSize = stripeLength;
+ });
+ }
+
+ // Write group child file stripe count
+ groupBuffer.put(stripeCount, 'byte');
+
+ if (groupBuffer.length) {
+ group.data.buffer = groupBuffer.toNodeBuffer();
+ } else {
+ group.data.buffer = null;
+ }
+
+ return group.data.buffer;
+ }
+
+ // @todo support newer archive fields & formats - 21/07/22 - Kiko
+ encodeArchive(archive: Js5Archive): Buffer | null {
+ const { groups: groupMap, index } = archive;
+ const groups = Array.from(groupMap.values());
+ const groupCount = groups.length;
+ const filesNamed = groups.filter(group => group.index.name !== null).length !== 0;
+ let lastFileKey = 0;
+
+ // @todo calculate the proper size instead of using a set amount here - 21/07/22 - Kiko
+ const buffer = new ByteBuffer(1000 * 1000);
+
+ // Write archive index file header
+ buffer.put(index.archiveFormat ?? ArchiveFormat.original);
+ buffer.put(filesNamed ? 1 : 0);
+ buffer.put(groupCount, 'short');
+
+ // Write group keys
+ groups.forEach(group => {
+ buffer.put(group.index.key - lastFileKey, 'short');
+ lastFileKey = group.index.key;
+ });
+
+ // Write group names (if applicable)
+ if (filesNamed) {
+ groups.forEach(group => buffer.put(group.index.nameHash ?? -1, 'int'));
+ }
+
+ // Write uncompressed crc values
+ groups.forEach(group => buffer.put(group.index.checksum ?? -1, 'int'));
+
+ // Write group version numbers
+ groups.forEach(group => buffer.put(group.index.version, 'int'));
+
+ // Write group child file counts
+ groups.forEach(group => buffer.put(group.files?.size ?? 1, 'short'));
+
+ // Write group child file keys
+ groups.forEach(group => {
+ if (group.files.size > 1) {
+ lastFileKey = 0;
+
+ group.files.forEach(file => {
+ buffer.put(file.index.key - lastFileKey, 'short');
+ lastFileKey = file.index.key;
+ });
+ } else {
+ buffer.put(0, 'short');
+ }
+ });
+
+ // Write group child file names (if applicable)
+ if (filesNamed) {
+ groups.forEach(group => {
+ if (group.files.size > 1) {
+ lastFileKey = 0;
+
+ group.files.forEach(file =>
+ buffer.put(file.index.nameHash ?? -1, 'int'));
+ } else {
+ buffer.put(0, 'int');
+ }
+ });
+ }
+
+ const archiveIndexData = buffer?.flipWriter();
+
+ if (archiveIndexData?.length) {
+ archive.data.buffer = archiveIndexData.toNodeBuffer();
+ } else {
+ archive.data.buffer = null;
+ }
+
+ return archive.data.buffer;
+ }
+
+ encodeMainIndex(): ByteBuffer {
+ const archiveCount = this.fileStore.archives.size;
+ const fileSize = 4 * archiveCount;
+
+ const data = new ByteBuffer(fileSize + 31);
+
+ data.put(0);
+ data.put(fileSize, 'int');
+
+ for (let archiveIndex = 0; archiveIndex < archiveCount; archiveIndex++) {
+ data.put(this.fileStore.archives.get(archiveIndex).index.checksum, 'int');
+ }
+
+ this.mainIndexFile = data;
+ return this.mainIndexFile;
+ }
+
+ getEncryptionKeys(fileName: string): XteaKeys | XteaKeys[] | null {
+ if (this.openRS2EncryptionKeys?.length) {
+ const fileKeys = this.openRS2EncryptionKeys.find(file => file.name === fileName);
+ if (fileKeys) {
+ return {
+ gameBuild: this.fileStore.gameBuild,
+ key: fileKeys.key
+ };
+ }
+ }
+
+ const keySets = this.localEncryptionKeys?.get(fileName);
+ if (!keySets) {
+ return null;
+ }
+
+ if (this.fileStore.gameBuild !== undefined) {
+ return keySets.find(keySet => keySet.gameBuild === this.fileStore.gameBuild) ?? null;
+ }
+
+ return keySets;
+ }
+
+ async loadEncryptionKeys(): Promise {
+ if (/^\d+$/.test(this.fileStore.gameBuild)) {
+ const openRS2Keys = await getXteaKeysByBuild(parseInt(this.fileStore.gameBuild, 10));
+
+ if (openRS2Keys?.length) {
+ logger.info(`XTEA keys found for build ${ this.fileStore.gameBuild } on OpenRS2.org.`);
+ this.openRS2EncryptionKeys = openRS2Keys;
+ return;
+ }
+ }
+
+ logger.warn(`XTEA keys not found for build ${ this.fileStore.gameBuild } on OpenRS2.org, using local XTEA key files instead.`);
+ const configPath = join(this.fileStore.fileStorePath, 'config', 'xtea');
+ this.localEncryptionKeys = Xtea.loadKeys(configPath);
+
+ if (!this.localEncryptionKeys.size) {
+ throw new Error(`Error reading encryption key lookup table. ` +
+ `Please ensure that the ${ configPath } file exists and is valid.`);
+ }
+ }
+
+}
diff --git a/src/file-system/packed/index.ts b/src/file-system/packed/index.ts
new file mode 100644
index 0000000..6c17315
--- /dev/null
+++ b/src/file-system/packed/index.ts
@@ -0,0 +1,2 @@
+export * from './packed-cache-format';
+export * from './packed-cache-file';
diff --git a/src/file-system/packed/packed-cache-file.ts b/src/file-system/packed/packed-cache-file.ts
new file mode 100644
index 0000000..128c341
--- /dev/null
+++ b/src/file-system/packed/packed-cache-file.ts
@@ -0,0 +1,7 @@
+import { Buffer } from 'buffer';
+
+
+export interface PackedCacheFile {
+ name: string;
+ data: Buffer;
+}
diff --git a/src/file-system/packed/packed-cache-format.ts b/src/file-system/packed/packed-cache-format.ts
new file mode 100644
index 0000000..a07c955
--- /dev/null
+++ b/src/file-system/packed/packed-cache-format.ts
@@ -0,0 +1,12 @@
+import { PackedCacheFile } from './packed-cache-file';
+
+
+export const getPackedCacheFormat = (cacheFiles: PackedCacheFile[]): 'jag' | 'js5' | 'unknown' => {
+ if (cacheFiles.find(file => file.name === 'main_file_cache.idx255')) {
+ return 'js5';
+ } else if (cacheFiles.find(file => file.name === 'main_file_cache.dat')) {
+ return 'jag';
+ }
+
+ return 'unknown';
+};
diff --git a/src/flat-file.ts b/src/flat-file.ts
deleted file mode 100644
index 272a4f3..0000000
--- a/src/flat-file.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-import { join } from 'path';
-import { existsSync, readFileSync } from 'graceful-fs';
-import { ByteBuffer, logger } from '@runejs/common';
-
-import { FileIndexEntity } from './db';
-import { FileBreadcrumb, IndexedFile } from './indexed-file';
-import { FileState } from './file-state';
-import { isSet } from './util';
-
-
-export class FlatFile extends IndexedFile {
-
- public stripes: number[] = [];
- public stripeCount: number = 1;
-
- public constructor(index: FileIndexEntity, breadcrumb?: Partial) {
- super(index, breadcrumb);
-
- if(isSet(index.stripes)) {
- this.stripes = index.stripes.split(',').map(n => Number(n));
- }
- if(isSet(index.stripeCount)) {
- this.stripeCount = index.stripeCount;
- }
- if(isSet(index.version)) {
- this.version = index.version;
- }
- if(isSet(index.nameHash)) {
- this.nameHash = index.nameHash;
- }
- }
-
- public override read(compress: boolean = false): ByteBuffer | null | Promise {
- if(!this.group) {
- throw new Error(`Flat file ${this.key} could not be read as it does not belong to any known groups.`);
- }
-
- const filePath = this.path;
-
- if(!existsSync(filePath)) {
- logger.error(`File not found: ${filePath}`);
- this.setState(FileState.missing);
- return null;
- }
-
- let data: Buffer | null = null;
-
- try {
- data = readFileSync(filePath);
- } catch(error) {
- logger.error(`Error reading file ${this.name || this.key } at ${filePath}:`, error);
- data = null;
- }
-
- if(!data) {
- this.setState(FileState.corrupt);
- } else if(!data.length) {
- this.setState(FileState.empty);
- } else {
- const fileData = new ByteBuffer(data);
-
- if(!this.name) {
- this.name = this.group.name || this.key;
- }
-
- if(!this.nameHash) {
- this.nameHash = this.group.nameHash || undefined;
- }
-
- if(!this.stripes) {
- const stripeStr = this.index.stripes;
- if(stripeStr?.length) {
- this.stripes = stripeStr.split(',')?.map(s => Number(s)) ?? undefined;
- }
- }
-
- if(!this.crc32) {
- this.crc32 = this.index.crc32 ?? 0;
- }
-
- if(!this.sha256) {
- this.sha256 = this.index.sha256 ?? undefined;
- }
-
- this.setData(fileData, FileState.raw);
-
- if(this.size !== this.index.size || this.sha256 !== this.generateSha256()) {
- this._modified = true;
- }
-
- return fileData;
- }
-
- logger.error(`Error reading file data: ${filePath}`);
- return null;
- }
-
- public override get path(): string {
- const groupPath = this.group?.path || null;
- if(!groupPath) {
- throw new Error(`Error generating file path; File ${this.key} has not been added to a group.`);
- }
-
- if(this.group.fileCount === 1 || this.archive?.config?.flatten) {
- return groupPath + this.type;
- } else {
- return join(groupPath, String(this.name || this.key)) + this.type;
- }
- }
-
- public override get outputPath(): string {
- const groupOutputPath = this.group?.outputPath || null;
- if(!groupOutputPath) {
- throw new Error(`Error generating file output path; File ${this.key} has not been added to a group.`);
- }
-
- if(this.group.fileCount === 1 || this.archive?.config?.flatten) {
- return groupOutputPath + this.type;
- } else {
- return join(groupOutputPath, String(this.name || this.key) + this.type);
- }
- }
-
-}
diff --git a/src/group.ts b/src/group.ts
deleted file mode 100644
index 39590fb..0000000
--- a/src/group.ts
+++ /dev/null
@@ -1,336 +0,0 @@
-import { join } from 'path';
-import { existsSync, mkdirSync, readdirSync, rmSync, statSync } from 'graceful-fs';
-import { ByteBuffer, logger } from '@runejs/common';
-
-import { FlatFile } from './flat-file';
-import { GroupIndexEntity } from './db';
-import { FileBreadcrumb, IndexedFile } from './indexed-file';
-import { FileState } from './file-state';
-import { isSet } from './util';
-
-
-export class Group extends IndexedFile {
-
- public readonly files: Map = new Map();
- public readonly fileSizes: Map = new Map();
-
- public stripes: number[] = [];
- public stripeCount: number = 1;
-
- private _fileCount: number = 0;
-
- public constructor(index: GroupIndexEntity, breadcrumb?: Partial) {
- super(index, breadcrumb);
-
- if(isSet(index.stripes)) {
- this.stripes = index.stripes.split(',').map(n => Number(n));
- }
- if(isSet(index.stripeCount)) {
- this.stripeCount = index.stripeCount;
- }
- if(isSet(index.version)) {
- this.version = index.version;
- }
- if(isSet(index.nameHash)) {
- this.nameHash = index.nameHash;
- }
- }
-
- public override decode(): ByteBuffer | null {
- this.unpack();
- this.decompress();
-
- if(this._fileCount === 1) {
- const flatFile: FlatFile = Array.from(this.files.values())[0];
- flatFile.name = this.name;
- flatFile.nameHash = this.nameHash;
- flatFile.sha256 = this.sha256;
- flatFile.crc32 = this.crc32;
- flatFile.encryption = this.encryption;
- flatFile.setData(this._data, this.state);
- } else {
- const dataLength = this._data?.length || 0;
-
- if(!dataLength || dataLength <= 0) {
- logger.error(`Error decoding group ${this.key}`);
- return null;
- }
-
- this._data.readerIndex = (dataLength - 1); // EOF
-
- this.stripeCount = this._data.get('byte', 'unsigned');
-
- this._data.readerIndex = (dataLength - 1 - this.stripeCount * this.files.size * 4); // Stripe data footer
-
- if(this._data.readerIndex < 0) {
- logger.error(`Invalid reader index of ${this._data.readerIndex} for group ${this.archive.name}:${this.key}.`);
- return null;
- }
-
- for(let stripe = 0; stripe < this.stripeCount; stripe++) {
- let currentLength = 0;
- for(const [ fileIndex, file ] of this.files) {
- const delta = this._data.get('int');
- currentLength += delta;
-
- if(!file.stripes?.length) {
- file.stripes = new Array(this.stripeCount);
- }
-
- let size = 0;
- if(!this.fileSizes.has(fileIndex)) {
- this.fileSizes.set(fileIndex, 0);
- } else {
- size = this.fileSizes.get(fileIndex);
- }
-
- file.stripes[stripe] = currentLength;
- this.fileSizes.set(fileIndex, size + currentLength);
- }
- }
-
- for(const [ fileIndex, file ] of this.files) {
- const fileSize = this.fileSizes.get(fileIndex) || 0;
- file.setData(new ByteBuffer(fileSize), FileState.raw);
- file.size = fileSize;
- }
-
- this._data.readerIndex = 0;
-
- for(let stripe = 0; stripe < this.stripeCount; stripe++) {
- for(const [ , file ] of this.files) {
- let stripeLength = file.stripes[stripe];
- let sourceEnd: number = this._data.readerIndex + stripeLength;
-
- if(this._data.readerIndex + stripeLength >= this._data.length) {
- sourceEnd = this._data.length;
- stripeLength = (this._data.readerIndex + stripeLength) - this._data.length;
- }
-
- const stripeData = this._data.getSlice(this._data.readerIndex, stripeLength);
-
- file.data.putBytes(stripeData);
-
- this._data.readerIndex = sourceEnd;
- }
- }
-
- this.files.forEach(file => file.generateSha256());
- }
-
- this.setData(this._data, FileState.raw);
- this._fileCount = this.files.size;
- return this._data ?? null;
- }
-
- public override encode(): ByteBuffer | null {
- // Single-file group
- if(this._fileCount === 1) {
- const flatFile = Array.from(this.files.values())[0];
- this.setData(flatFile.data ?? new ByteBuffer([]), FileState.encoded);
- return this._data;
- }
-
- // Multi-file group
- const fileData: ByteBuffer[] = Array.from(this.files.values()).map(file => file?.data ?? new ByteBuffer(0));
- const fileSizes = fileData.map(data => data.length);
- const fileCount = this._fileCount;
- const stripeCount = this.stripes?.length ?? 1;
-
- if(!stripeCount) {
- return null;
- }
-
- // Size of all individual files + 1 int per file containing it's size
- // + 1 at the end for the total group stripe count
- const groupSize = fileSizes.reduce((a, c) => a + c) + (stripeCount * fileCount * 4) + 1;
- const groupBuffer = new ByteBuffer(groupSize);
-
- fileData.forEach(data => data.readerIndex = 0);
-
- // Write file content stripes
- for(let stripe = 0; stripe < stripeCount; stripe++) {
- for(const [ , file ] of this.files) {
- if(!file?.data?.length) {
- continue;
- }
-
- const stripeSize = file.stripes[stripe];
-
- if(stripeSize) {
- const stripeData = file.data.getSlice(file.data.readerIndex, stripeSize);
- file.data.readerIndex = file.data.readerIndex + stripeSize;
- groupBuffer.putBytes(stripeData);
- }
- }
- }
-
- for(let stripe = 0; stripe < stripeCount; stripe++) {
- let prevSize = 0;
- for(const [ , file ] of this.files) {
- if(!file?.data?.length) {
- continue;
- }
-
- const stripeSize = file.stripes[stripe] ?? 0;
- groupBuffer.put(stripeSize - prevSize, 'int');
- prevSize = stripeSize;
- }
- }
-
- groupBuffer.put(this.stripes?.length ?? 1, 'byte');
-
- this.setData(groupBuffer.flipWriter(), FileState.encoded);
- return this._data;
- }
-
- public override async read(compress: boolean = false, readDiskFiles: boolean = true): Promise {
- if(!this.index) {
- logger.error(`Error reading group ${this.name} files: Group is not indexed, please re-index the ` +
- `${this.archive.name} archive.`);
- return null;
- }
-
- if(this.index.data?.length) {
- this.setData(this.index.data, FileState.compressed);
- }
-
- let indexedFiles = await this.index.files;
-
- if(!indexedFiles?.length) {
- // Single file indexes are not stored to save on DB space and read/write times
- // So if a group has no children, assume it is a single-file group and create a single index for it
- const { name, nameHash, version, size, crc32, sha256, stripes, stripeCount, archive, state } = this;
- indexedFiles = this.index.files = [ this.indexService.validateFile({
- numericKey: 0, name, nameHash, version, size, crc32, sha256, stripes, stripeCount,
- group: this, archive
- }) ];
- }
-
- let childFileCount = 1;
-
- const groupPath = this.path;
-
- if(this.archive.versioned) {
- this.version = this.index.version;
- }
-
- if(existsSync(groupPath) && statSync(groupPath).isDirectory()) {
- childFileCount = readdirSync(groupPath).length ?? 1;
- }
-
- if(indexedFiles.length !== childFileCount) {
- this._modified = true;
- }
-
- this._fileCount = childFileCount;
-
- this.files.clear();
- this.fileSizes.clear();
-
- // Load the group's files
- for(const fileIndexData of indexedFiles) {
- const file = new FlatFile(fileIndexData, {
- group: this, archive: this.archive, store: this.store
- });
-
- this.files.set(file.key, file);
- this.fileSizes.set(file.key, fileIndexData.size);
- }
-
- this.stripeCount = (this.index as GroupIndexEntity).stripeCount || 1;
-
- // Read the content of each file within the group
- if(readDiskFiles) {
- Array.from(this.files.values()).forEach(file => file.read(compress));
-
- if(this._fileCount === 1) {
- // Single file group, set the group data to match the flat file data
- const file = this.files.get('0');
- this.setData(file.data, file.state);
- }
- }
-
- this.encode();
-
- const originalDigest = this.sha256;
- this.generateSha256();
-
- if(this.sha256 && originalDigest !== this.sha256) {
- // logger.info(`Detected changes in file ${this.archive.name}:${groupName}.`);
- this.index.sha256 = this.sha256;
- this._modified = true;
- }
-
- if(compress && this.state !== FileState.compressed) {
- this.compress();
- }
-
- return this._data;
- }
-
- public override write(): void {
- if(!this._fileCount) {
- logger.error(`Error writing group ${this.name}: Group is empty.`);
- return;
- }
-
- // logger.info(`Writing group ${this.name}...`);
-
- const groupPath = this.outputPath;
-
- if(existsSync(groupPath)) {
- rmSync(groupPath, { recursive: true, force: true });
- }
-
- if(this.files.size > 1 && !this.archive.config.flatten) {
- mkdirSync(groupPath, { recursive: true });
- }
-
- if(!this.archive.config.flatten) {
- Array.from(this.files.values()).forEach(file => file.write());
- } else {
- super.write();
- }
- }
-
- public has(fileIndex: string | number): boolean {
- return this.files.has(String(fileIndex));
- }
-
- public get(fileIndex: string | number): FlatFile | null {
- return this.files.get(String(fileIndex)) ?? null;
- }
-
- public set(fileIndex: string | number, file: FlatFile): void {
- this.files.set(String(fileIndex), file);
- this._fileCount = this.files.size;
- }
-
- public override get path(): string {
- const archivePath = this.archive?.path || null;
- if(!archivePath) {
- throw new Error(`Error generating group path; Archive path not provided to group ${this.key}.`);
- }
-
- return join(archivePath, String(this.name || this.key));
- }
-
- public override get outputPath(): string {
- const archiveOutputPath = this.archive?.outputPath || null;
- if(!archiveOutputPath) {
- throw new Error(`Error generating group output path; Archive output path not provided to group ${this.key}.`);
- }
-
- const groupPath = join(archiveOutputPath, String(this.name || this.key));
- return this.archive.config.flatten ? groupPath + this.type : groupPath;
- }
-
- public get fileCount(): number {
- return this._fileCount;
- }
-
- public get type(): string {
- return this.archive?.config?.contentType ?? '';
- }
-}
diff --git a/src/http/config.ts b/src/http/config.ts
new file mode 100644
index 0000000..712c0ae
--- /dev/null
+++ b/src/http/config.ts
@@ -0,0 +1,4 @@
+import { InjectionToken } from '@decorators/di';
+
+
+export const FILESTORE_DIR = new InjectionToken('FILESTORE_DIR');
diff --git a/src/http/index.ts b/src/http/index.ts
new file mode 100644
index 0000000..34b746c
--- /dev/null
+++ b/src/http/index.ts
@@ -0,0 +1,3 @@
+export * from './server';
+export * from './js5/js5.service';
+export * from './js5/js5.controller';
diff --git a/src/http/js5/js5.controller.ts b/src/http/js5/js5.controller.ts
new file mode 100644
index 0000000..cf6a18a
--- /dev/null
+++ b/src/http/js5/js5.controller.ts
@@ -0,0 +1,132 @@
+import { Response as ExpressResponse } from 'express';
+import { Controller, Get, Params, Response } from '@decorators/express';
+import { Js5Service } from './js5.service';
+import { Inject } from '@decorators/di';
+
+
+@Controller('/js5')
+export class Js5Controller {
+
+ constructor(@Inject(Js5Service) private js5Service: Js5Service) {
+ }
+
+ @Get('/:gameBuild/archives/:archiveIdentifier/groups/:groupIdentifier/files/:fileIdentifier/data')
+ async getArchiveGroupFileData(
+ @Response() res: ExpressResponse,
+ @Params('gameBuild') gameBuild: string | number,
+ @Params('archiveIdentifier') archiveIdentifier: string | number,
+ @Params('groupIdentifier') groupIdentifier: string | number,
+ @Params('fileIdentifier') fileIdentifier: string | number
+ ) {
+ const data = await this.js5Service.getArchiveGroupFileData(gameBuild, archiveIdentifier, groupIdentifier, fileIdentifier);
+
+ res.writeHead(200, {
+ 'Content-Type': 'arraybuffer',
+ 'Content-Length': data.length,
+ 'Content-disposition': `attachment; filename=${fileIdentifier}`
+ });
+
+ res.end(data);
+ }
+
+ @Get('/:gameBuild/archives/:archiveIdentifier/groups/:groupIdentifier/files/:fileIdentifier')
+ async getArchiveGroupFile(
+ @Response() res: ExpressResponse,
+ @Params('gameBuild') gameBuild: string | number,
+ @Params('archiveIdentifier') archiveIdentifier: string | number,
+ @Params('groupIdentifier') groupIdentifier: string | number,
+ @Params('fileIdentifier') fileIdentifier: string | number
+ ) {
+ res.send(await this.js5Service.getArchiveGroupFile(gameBuild, archiveIdentifier, groupIdentifier, fileIdentifier));
+ }
+
+ @Get('/:gameBuild/archives/:archiveIdentifier/groups/:groupIdentifier/files')
+ async getArchiveGroupFileList(
+ @Response() res: ExpressResponse,
+ @Params('gameBuild') gameBuild: string | number,
+ @Params('archiveIdentifier') archiveIdentifier: string | number,
+ @Params('groupIdentifier') groupIdentifier: string | number
+ ) {
+ res.send(await this.js5Service.getArchiveGroupFileList(gameBuild, archiveIdentifier, groupIdentifier));
+ }
+
+ @Get('/:gameBuild/archives/:archiveIdentifier/groups/:groupIdentifier/data')
+ async getArchiveGroupData(
+ @Response() res: ExpressResponse,
+ @Params('gameBuild') gameBuild: string | number,
+ @Params('archiveIdentifier') archiveIdentifier: string | number,
+ @Params('groupIdentifier') groupIdentifier: string | number
+ ) {
+ const data = await this.js5Service.getArchiveGroupData(gameBuild, archiveIdentifier, groupIdentifier);
+
+ res.writeHead(200, {
+ 'Content-Type': 'arraybuffer',
+ 'Content-Length': data.length,
+ 'Content-disposition': `attachment; filename=${groupIdentifier}`
+ });
+
+ res.end(data);
+ }
+
+ @Get('/:gameBuild/archives/:archiveIdentifier/groups/:groupIdentifier')
+ async getArchiveGroup(
+ @Response() res: ExpressResponse,
+ @Params('gameBuild') gameBuild: string | number,
+ @Params('archiveIdentifier') archiveIdentifier: string | number,
+ @Params('groupIdentifier') groupIdentifier: string | number
+ ) {
+ res.send(await this.js5Service.getArchiveGroup(gameBuild, archiveIdentifier, groupIdentifier));
+ }
+
+ @Get('/:gameBuild/archives/:archiveIdentifier/groups')
+ async getArchiveGroupList(
+ @Response() res: ExpressResponse,
+ @Params('gameBuild') gameBuild: string | number,
+ @Params('archiveIdentifier') archiveIdentifier: string | number
+ ) {
+ res.send(await this.js5Service.getArchiveGroupList(gameBuild, archiveIdentifier));
+ }
+
+ @Get('/:gameBuild/archives/:archiveIdentifier/data')
+ async getArchiveData(
+ @Response() res: ExpressResponse,
+ @Params('gameBuild') gameBuild: string | number,
+ @Params('archiveIdentifier') archiveIdentifier: string | number
+ ) {
+ const data = await this.js5Service.getArchiveData(gameBuild, archiveIdentifier);
+
+ res.writeHead(200, {
+ 'Content-Type': 'arraybuffer',
+ 'Content-Length': data.length,
+ 'Content-disposition': `attachment; filename=${archiveIdentifier}`
+ });
+
+ res.end(data);
+ }
+
+ @Get('/:gameBuild/archives/:archiveIdentifier')
+ async getArchive(
+ @Response() res: ExpressResponse,
+ @Params('gameBuild') gameBuild: string | number,
+ @Params('archiveIdentifier') archiveIdentifier: string | number
+ ) {
+ res.send(await this.js5Service.getArchive(gameBuild, archiveIdentifier));
+ }
+
+ @Get('/:gameBuild/archives')
+ async getArchiveList(
+ @Response() res: ExpressResponse,
+ @Params('gameBuild') gameBuild: string | number
+ ) {
+ res.send(await this.js5Service.getArchiveList(gameBuild));
+ }
+
+ @Get('/:gameBuild/archive-config')
+ async getArchiveConfig(
+ @Response() res: ExpressResponse,
+ @Params('gameBuild') gameBuild: string | number
+ ) {
+ res.send(await this.js5Service.getArchiveConfig(gameBuild));
+ }
+
+}
diff --git a/src/http/js5/js5.service.ts b/src/http/js5/js5.service.ts
new file mode 100644
index 0000000..4157911
--- /dev/null
+++ b/src/http/js5/js5.service.ts
@@ -0,0 +1,137 @@
+import { Inject, Injectable } from '@decorators/di';
+import { FILESTORE_DIR } from '../config';
+import { Js5FileStore } from '../../file-system';
+import { Js5IndexEntity } from '../../db/js5';
+import { logger } from '@runejs/common';
+import { Buffer } from 'buffer';
+import { Js5ArchiveConfig } from '../../config';
+
+
+@Injectable()
+export class Js5Service {
+
+ readonly stores: Map;
+
+ constructor(
+ @Inject(FILESTORE_DIR) private fileStoreDir: string
+ ) {
+ this.stores = new Map();
+ logger.info('Js5Service initialized');
+ }
+
+ async getArchiveGroupFileData(
+ gameBuild: string | number,
+ archiveIdentifier: string | number,
+ groupIdentifier: string | number,
+ fileIdentifier: string | number
+ ): Promise {
+ const fileStore = await this.getFileStore(gameBuild);
+ const archive = await fileStore.getArchive(archiveIdentifier);
+ const group = await archive.getGroup(groupIdentifier);
+ const file = await group.getFile(fileIdentifier);
+ return file.getCompressedData();
+ }
+
+ async getArchiveGroupFile(
+ gameBuild: string | number,
+ archiveIdentifier: string | number,
+ groupIdentifier: string | number,
+ fileIdentifier: string | number
+ ): Promise {
+ const fileStore = await this.getFileStore(gameBuild);
+ const archive = await fileStore.getArchive(archiveIdentifier);
+ const group = await archive.getGroup(groupIdentifier);
+ const file = await group.getFile(fileIdentifier);
+ return file.index;
+ }
+
+ async getArchiveGroupFileList(
+ gameBuild: string | number,
+ archiveIdentifier: string | number,
+ groupIdentifier: string | number
+ ): Promise {
+ const fileStore = await this.getFileStore(gameBuild);
+ const archive = await fileStore.getArchive(archiveIdentifier);
+ const group = await archive.getGroup(groupIdentifier);
+
+ await group.loadFileIndexes();
+
+ return Array.from(group.files.values()).map(file => file.index);
+ }
+
+ async getArchiveGroupData(
+ gameBuild: string | number,
+ archiveIdentifier: string | number,
+ groupIdentifier: string | number
+ ): Promise {
+ const fileStore = await this.getFileStore(gameBuild);
+ const archive = await fileStore.getArchive(archiveIdentifier);
+ const group = await archive.getGroup(groupIdentifier);
+ return group.getCompressedData();
+ }
+
+ async getArchiveGroup(
+ gameBuild: string | number,
+ archiveIdentifier: string | number,
+ groupIdentifier: string | number
+ ): Promise {
+ const fileStore = await this.getFileStore(gameBuild);
+ const archive = await fileStore.getArchive(archiveIdentifier);
+ const group = await archive.getGroup(groupIdentifier);
+ return group.index;
+ }
+
+ async getArchiveGroupList(
+ gameBuild: string | number,
+ archiveIdentifier: string | number
+ ): Promise {
+ const fileStore = await this.getFileStore(gameBuild);
+ const archive = await fileStore.getArchive(archiveIdentifier);
+
+ await archive.loadGroupIndexes();
+
+ return Array.from(archive.groups.values()).map(group => group.index);
+ }
+
+ async getArchiveData(
+ gameBuild: string | number,
+ archiveIdentifier: string | number
+ ): Promise {
+ const fileStore = await this.getFileStore(gameBuild);
+ const archive = await fileStore.getArchive(archiveIdentifier);
+ return archive.getCompressedData();
+ }
+
+ async getArchive(
+ gameBuild: string | number,
+ archiveIdentifier: string | number
+ ): Promise {
+ const fileStore = await this.getFileStore(gameBuild);
+ const archive = await fileStore.getArchive(archiveIdentifier);
+ return archive.index;
+ }
+
+ async getArchiveList(gameBuild: string | number): Promise {
+ const fileStore = await this.getFileStore(gameBuild);
+ return Array.from(fileStore.archives.values()).map(archive => archive.index);
+ }
+
+ async getArchiveConfig(gameBuild): Promise<{ [key: string]: Js5ArchiveConfig }> {
+ const fileStore = await this.getFileStore(gameBuild);
+ return fileStore.archiveConfig;
+ }
+
+ async getFileStore(gameBuild: string | number): Promise {
+ if (this.stores.has(gameBuild)) {
+ return this.stores.get(gameBuild);
+ }
+
+ const fileStore = new Js5FileStore(gameBuild, this.fileStoreDir);
+ await fileStore.load(true);
+
+ this.stores.set(gameBuild, fileStore);
+
+ return fileStore;
+ }
+
+}
diff --git a/src/http/server.ts b/src/http/server.ts
new file mode 100644
index 0000000..beffcfb
--- /dev/null
+++ b/src/http/server.ts
@@ -0,0 +1,56 @@
+import express from 'express';
+import { Container } from '@decorators/di';
+import { attachControllers } from '@decorators/express';
+import { logger } from '@runejs/common';
+import { ArgumentOptions, ScriptExecutor } from '../scripts/script-executor';
+import { FILESTORE_DIR } from './config';
+import { Js5Controller } from './js5/js5.controller';
+
+
+interface ServerOptions {
+ dir: string;
+ port: number;
+}
+
+
+const serverArgumentOptions: ArgumentOptions = {
+ dir: {
+ alias: 'd',
+ type: 'string',
+ default: './',
+ description: `The store root directory. Defaults to the current location.`
+ },
+ port: {
+ alias: 'p',
+ type: 'number',
+ default: 8080,
+ description: `The port from which the HTTP server will be accessed. Defaults to 8080.`
+ },
+};
+
+
+new ScriptExecutor().executeScript(serverArgumentOptions, async (
+ { dir, port }
+) => {
+ const app = express();
+
+ app.use((req, res, next) => {
+ res.header('Access-Control-Allow-Origin', '*');
+ res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
+ next();
+ });
+
+ app.set('json spaces', 4);
+ app.set('port', port);
+
+ Container.provide([
+ { provide: FILESTORE_DIR, useValue: dir },
+ ]);
+
+ attachControllers(app, [ Js5Controller ]);
+
+ app.listen(port, async () => {
+ logger.info(`HTTP server listening at port ${port}.`);
+ });
+});
+
diff --git a/src/index.ts b/src/index.ts
deleted file mode 100644
index 00d2b30..0000000
--- a/src/index.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export * from './indexed-file';
-export * from './flat-file';
-export * from './group';
-export * from './archive';
-export * from './store';
-export * from './file-state';
-export * from './util';
-export * from './db';
-export * from './config';
-
diff --git a/src/indexed-file.ts b/src/indexed-file.ts
deleted file mode 100644
index 0cd75d4..0000000
--- a/src/indexed-file.ts
+++ /dev/null
@@ -1,502 +0,0 @@
-import { writeFileSync } from 'graceful-fs';
-import { createHash } from 'crypto';
-import { ByteBuffer, logger } from '@runejs/common';
-import { Bzip2, CompressionMethod, getCompressionMethod, Gzip } from '@runejs/common/compress';
-import { EncryptionMethod, Xtea, XteaKeys } from '@runejs/common/encrypt';
-import { Crc32 } from '@runejs/common/crc32';
-
-import { IndexEntity, IndexService } from './db';
-import { Store } from './store';
-import { Archive } from './archive';
-import { Group } from './group';
-import { isSet } from './util';
-import { FileState } from './file-state';
-
-
-export interface FileBreadcrumb {
- store: Store;
- archive: Archive;
- group: Group;
-}
-
-
-export abstract class IndexedFile {
-
- public readonly key: string;
- public readonly store: Store;
- public readonly archive: Archive;
- public readonly group: Group;
-
- public index: T;
- public name: string = '';
- public nameHash: number = -1;
- public version: number = 0;
- public size: number = 0;
- public crc32: number = -1;
- public sha256: string = '';
- public encryption: EncryptionMethod | [ EncryptionMethod, string ] = 'none';
- public compression: CompressionMethod = 'none';
- public state: FileState = FileState.unloaded;
-
- protected _data: ByteBuffer | null = null;
- protected _modified: boolean = false;
-
- protected constructor(index: T, breadcrumb?: Partial) {
- this.index = index;
- this.key = String(index.key);
-
- if(isSet(index.name)) {
- this.name = index.name;
- }
- if(isSet(index.size)) {
- this.size = index.size;
- }
- if(isSet(index.crc32)) {
- this.crc32 = index.crc32;
- }
- if(isSet(index.sha256)) {
- this.sha256 = index.sha256;
- }
- if(isSet(index['state'])) {
- this.state = FileState[index['state']];
- }
-
- if(breadcrumb) {
- const { store, archive, group } = breadcrumb;
-
- if(isSet(store)) {
- this.store = store;
- }
- if(isSet(archive)) {
- this.archive = archive;
- }
- if(isSet(group)) {
- this.group = group;
- }
- }
-
- // Attempt to infer the archive or store that this file belongs to, if not provided in the options
-
- if(!this.archive) {
- if(this.group?.archive) {
- this.archive = this.group.archive;
- }
- }
-
- if(!this.store) {
- if(this.archive?.store) {
- this.store = this.archive.store;
- } else if(this.group?.store) {
- this.store = this.group.store;
- }
- }
-
- this.encryption = this.archive?.config?.encryption || 'none';
- this.compression = this.archive?.config?.compression || 'none';
- }
-
- public unpack(): ByteBuffer | null {
- const archiveKey: number = this.archive ? this.archive.numericKey : 255;
- const fileKey = this.numericKey;
- const archiveName: string = this.archive ? this.archive.name : 'main';
- const indexChannel: ByteBuffer = archiveKey !== 255 ?
- this.store.js5ArchiveIndexes.get(String(archiveKey)) : this.store.js5MainIndex;
-
- if(archiveKey === 255 && fileKey === 255) {
- return null;
- }
-
- const indexDataLength = 6;
- const dataChannel = this.store.js5MainArchiveData;
-
- indexChannel.readerIndex = 0;
- dataChannel.readerIndex = 0;
-
- let pointer = fileKey * indexDataLength;
-
- if(pointer < 0 || pointer >= indexChannel.length) {
- logger.error(`File ${fileKey} was not found within the ${archiveName} archive index file.`);
- return null;
- }
-
- const fileIndexData = new ByteBuffer(indexDataLength);
- indexChannel.copy(fileIndexData, 0, pointer, pointer + indexDataLength);
-
- if(fileIndexData.readable !== indexDataLength) {
- logger.error(`Error extracting JS5 file ${fileKey}: the end of the data stream was reached.`);
- return null;
- }
-
- this.size = fileIndexData.get('int24', 'unsigned');
- const stripeCount = fileIndexData.get('int24', 'unsigned');
-
- if(this.size <= 0) {
- logger.warn(`Extracted JS5 file ${fileKey} has a recorded size of 0, no file data will be extracted.`);
- return null;
- }
-
- const data = new ByteBuffer(this.size);
- const stripeDataLength = 512;
- const stripeLength = 520;
-
- let stripe = 0;
- let remaining = this.size;
- pointer = stripeCount * stripeLength;
-
- do {
- const temp = new ByteBuffer(stripeLength);
- dataChannel.copy(temp, 0, pointer, pointer + stripeLength);
-
- if(temp.readable !== stripeLength) {
- logger.error(`Error reading stripe for packed file ${fileKey}, the end of the data stream was reached.`);
- return null;
- }
-
- const stripeFileIndex = temp.get('short', 'unsigned');
- const currentStripe = temp.get('short', 'unsigned');
- const nextStripe = temp.get('int24', 'unsigned');
- const stripeArchiveIndex = temp.get('byte', 'unsigned');
- const stripeData = new ByteBuffer(stripeDataLength);
- temp.copy(stripeData, 0, temp.readerIndex, temp.readerIndex + stripeDataLength);
-
- if(remaining > stripeDataLength) {
- stripeData.copy(data, data.writerIndex, 0, stripeDataLength);
- data.writerIndex = (data.writerIndex + stripeDataLength);
- remaining -= stripeDataLength;
-
- if(stripeArchiveIndex !== archiveKey) {
- logger.error(`Archive index mismatch, expected archive ${archiveKey} but found archive ${stripeFileIndex}`);
- return null;
- }
-
- if(stripeFileIndex !== fileKey) {
- logger.error(`File index mismatch, expected ${fileKey} but found ${stripeFileIndex}.`);
- return null;
- }
-
- if(currentStripe !== stripe++) {
- logger.error(`Error extracting JS5 file ${fileKey}, file data is corrupted.`);
- return null;
- }
-
- pointer = nextStripe * stripeLength;
- } else {
- stripeData.copy(data, data.writerIndex, 0, remaining);
- data.writerIndex = (data.writerIndex + remaining);
- remaining = 0;
- }
- } while(remaining > 0);
-
- if(data?.length) {
- this.setData(data, FileState.compressed);
- } else {
- this.setData(null, FileState.missing);
- }
-
- return data?.length ? data : null;
- }
-
- public pack(): ByteBuffer | null {
- return this._data; // @TODO needed for full re-packing of the data file
- }
-
- public decode(): ByteBuffer | null {
- return this._data; // stubbed
- }
-
- public encode(): ByteBuffer | null {
- return this._data; // stubbed
- }
-
- public decompress(): ByteBuffer | null {
- if(!this._data?.length) {
- return null;
- }
-
- this._data.readerIndex = 0;
-
- this.compression = getCompressionMethod(this._data.get('byte', 'unsigned'));
- const compressedLength = this._data.get('int', 'unsigned');
-
- const readerIndex = this._data.readerIndex;
-
- const compressedData = this.decrypt();
- compressedData.readerIndex = readerIndex;
- let data: ByteBuffer;
-
- if(this.compression === 'none') {
- // Uncompressed file
- data = new ByteBuffer(compressedLength);
- compressedData.copy(data, 0, compressedData.readerIndex, compressedLength);
- compressedData.readerIndex = (compressedData.readerIndex + compressedLength);
- } else {
- // BZIP or GZIP compressed file
- const decompressedLength = compressedData.get('int', 'unsigned');
- if(decompressedLength < 0) {
- logger.error(this.encryption === 'xtea' ? `Missing or invalid XTEA key.` :
- `Invalid decompressed file length: ${decompressedLength}`);
- } else {
- const decompressedData = new ByteBuffer(this.compression === 'bzip' ?
- decompressedLength : (compressedData.length - compressedData.readerIndex + 2));
-
- compressedData.copy(decompressedData, 0, compressedData.readerIndex);
-
- try {
- data = this.compression === 'bzip' ? Bzip2.decompress(decompressedData) : Gzip.decompress(decompressedData);
-
- compressedData.readerIndex = compressedData.readerIndex + compressedLength;
-
- if(data.length !== decompressedLength) {
- logger.error(`Compression length mismatch.`);
- data = null;
- }
- } catch(error) {
- if(this.state === FileState.encrypted) {
- logger.error(`Unable to decrypt file ${this.name || this.key}.`);
- this.archive?.incrementMissingEncryptionKeys();
- } else {
- logger.error(`Unable to decompress file ${this.name || this.key}: ${error?.message ?? error}`);
- }
- data = null;
- }
- }
- }
-
- // Read the file footer, if it has one
- if(compressedData.readable >= 2) {
- this.version = compressedData.get('short', 'unsigned');
- }
-
- if((data?.length ?? 0) > 0) {
- this.setData(data, FileState.encoded);
- }
-
- return this._data ?? null;
- }
-
- public compress(): ByteBuffer | null {
- if(!this._data?.length) {
- return null;
- }
-
- const decompressedData = this._data;
- let data: ByteBuffer;
-
- if(this.compression === 'none') {
- // uncompressed files
- data = new ByteBuffer(decompressedData.length + 5);
-
- // indicate that no file compression is applied
- data.put(0);
-
- // write the uncompressed file length
- data.put(decompressedData.length, 'int');
-
- // write the uncompressed file data
- data.putBytes(decompressedData);
- } else {
- // compressed Bzip2 or Gzip file
-
- const compressedData: ByteBuffer = this.compression === 'bzip' ?
- Bzip2.compress(decompressedData) : Gzip.compress(decompressedData);
-
- const compressedLength: number = compressedData.length;
-
- data = new ByteBuffer(compressedData.length + 9);
-
- // indicate which type of file compression was used (1 or 2)
- data.put(this.compression === 'bzip' ? 1 : 2);
-
- // write the compressed file length
- data.put(compressedLength, 'int');
-
- // write the uncompressed file length
- data.put(decompressedData.length, 'int');
-
- // write the compressed file data
- data.putBytes(compressedData);
- }
-
- return this.setData(data, FileState.compressed);
- }
-
- public decrypt(): ByteBuffer {
- if(this.state === FileState.encrypted) {
- // if(this.archive?.config?.encryption) {
- // File name must match the given pattern to be encrypted
- if(!this.name) {
- throw new Error(`Error decrypting file ${this.key}: File name not found.`);
- }
-
- if(Array.isArray(this.archive.config.encryption)) {
- const [ encryption, pattern ] = this.archive.config.encryption;
- const patternRegex = new RegExp(pattern);
-
- // Only XTEA encryption is supported for v1.0.0
- if(encryption !== 'xtea' || !patternRegex.test(this.name)) {
- // File name does not match the pattern, data should be unencrypted
- this.setState(FileState.decrypted);
- return this._data;
- }
- } else if(this.archive.config.encryption !== 'xtea') {
- // Only XTEA encryption is supported for v1.0.0
- this.setState(FileState.decrypted);
- return this._data;
- }
- }
-
- const gameBuild = this.store.gameBuild ?? null;
-
- // XTEA requires that we know which game build is running so that we pick the correct keystore file
- if(!gameBuild) {
- if(this.store && !this.store.gameBuildMissing) {
- this.store.setGameBuildMissing();
- logger.warn(`Game build must be supplied to decompress XTEA encrypted files.`,
- `Please provide the game build using the --build argument.`);
- }
-
- this.setState(FileState.decrypted);
- return this._data;
- }
-
- let keySets: XteaKeys[] = [];
-
- const loadedKeys = this.store.getEncryptionKeys(this.name);
- if(loadedKeys) {
- if(!Array.isArray(loadedKeys)) {
- keySets = [ loadedKeys ];
- } else {
- keySets = loadedKeys;
- }
- }
-
- this._data.readerIndex = 0;
-
- this.compression = getCompressionMethod(this._data.get('byte', 'unsigned'));
- const compressedLength = this._data.get('int', 'unsigned');
-
- const readerIndex = this._data.readerIndex;
-
- const keySet = keySets.find(keySet => keySet.gameBuild === gameBuild);
-
- if(Xtea.validKeys(keySet?.key)) {
- const dataCopy = this._data.clone();
- dataCopy.readerIndex = readerIndex;
-
- let lengthOffset = readerIndex;
- if(dataCopy.length - (compressedLength + readerIndex + 4) >= 2) {
- lengthOffset += 2;
- }
-
- const decryptedData = Xtea.decrypt(dataCopy, keySet.key, dataCopy.length - lengthOffset);
-
- if(decryptedData?.length) {
- decryptedData.copy(dataCopy, readerIndex, 0);
- dataCopy.readerIndex = readerIndex;
- this.setState(FileState.decrypted);
- return dataCopy;
- } else {
- logger.warn(`Invalid XTEA decryption keys found for file ${this.name || this.key} using game build ${gameBuild}.`);
- }
- } else {
- // logger.warn(`No XTEA decryption keys found for file ${this.name || this.fileKey} using game build ${gameBuild}.`);
- }
-
- return this._data;
- }
-
- public read(compress?: boolean): ByteBuffer | null | Promise {
- if(this.state === FileState.unloaded) {
- this.setState(FileState.loaded);
- }
-
- return this._data;
- }
-
- public write(): void {
- if(this._data?.length) {
- writeFileSync(this.outputPath, Buffer.from(this._data));
- }
- }
-
- public setData(data: Buffer, state: FileState): ByteBuffer | null;
- public setData(data: ByteBuffer, state: FileState): ByteBuffer | null;
- public setData(data: ByteBuffer | Buffer, state: FileState): ByteBuffer | null;
- public setData(data: ByteBuffer | Buffer, state: FileState): ByteBuffer | null {
- this.size = data?.length ?? 0;
-
- if(this.size) {
- this._data = new ByteBuffer(data);
- this._data.readerIndex = 0;
- this._data.writerIndex = 0;
- } else {
- this._data = null;
- }
-
- this.state = state;
-
- if(state === FileState.compressed) {
- this.generateCrc32();
- } else if(state === FileState.raw || state === FileState.encoded) {
- this.generateSha256();
- }
-
- return this._data;
- }
-
- public generateCrc32(): number {
- this.crc32 = this._data?.length ? Crc32.update(0, this.size, Buffer.from(this._data)) : -1;
- return this.crc32;
- }
-
- public generateSha256(): string {
- this.sha256 = this._data?.length ? createHash('sha256')
- .update(Buffer.from(this._data)).digest('hex') : '';
- return this.sha256;
- }
-
- public setState(fileState: FileState): void {
- this.state = fileState;
- }
-
- public abstract get path(): string;
-
- public abstract get outputPath(): string;
-
- public get numericKey(): number {
- return Number(this.key);
- }
-
- public get named(): boolean {
- if(!this.name) {
- return false;
- }
-
- return !/^\d+$/.test(this.name);
- }
-
- public get hasNameHash(): boolean {
- return isSet(this.nameHash) && !isNaN(this.nameHash) && this.nameHash !== -1;
- }
-
- public get data(): ByteBuffer {
- return this._data;
- }
-
- public get indexService(): IndexService {
- return this.store.indexService;
- }
-
- public get type(): string {
- return this.archive?.config?.contentType ?? '';
- }
-
- public get empty(): boolean {
- return (this._data?.length ?? 0) !== 0;
- }
-
- public get modified(): boolean {
- return this.index.crc32 !== this.crc32 || this.index.sha256 !== this.sha256 || this.index.size !== this.size;
- }
-
-}
diff --git a/src/openrs2/index.ts b/src/openrs2/index.ts
new file mode 100644
index 0000000..227d6fa
--- /dev/null
+++ b/src/openrs2/index.ts
@@ -0,0 +1 @@
+export * from './openrs2';
diff --git a/src/openrs2/openrs2.ts b/src/openrs2/openrs2.ts
new file mode 100644
index 0000000..5c716c3
--- /dev/null
+++ b/src/openrs2/openrs2.ts
@@ -0,0 +1,170 @@
+import axios from 'axios';
+import AdmZip from 'adm-zip';
+import { Buffer } from 'buffer';
+import { logger } from '@runejs/common';
+import { XteaConfig } from '@runejs/common/encrypt';
+import { PackedCacheFile } from '../file-system/packed';
+
+
+const openRS2Endpoint = 'https://archive.openrs2.org';
+
+
+export interface OpenRS2BuildNumber {
+ major: number;
+ minor: number | null;
+}
+
+
+export interface OpenRS2Cache {
+ id: number;
+ scope: 'runescape' | string;
+ game: 'runescape' | 'darkscape' | string;
+ environment: 'live' | 'beta' | string;
+ language: 'en' | 'de' | 'fr' | 'pt' | string;
+ builds: OpenRS2BuildNumber[];
+ timestamp: Date; // ISO 8601 format
+ sources: string[];
+ valid_indexes: number | null;
+ indexes: number | null;
+ valid_groups: number | null;
+ groups: number | null;
+ valid_keys: number | null;
+ keys: number | null;
+ size: number | null;
+ blocks: number | null;
+ disk_store_valid: boolean | null;
+}
+
+
+export const getOpenRS2CacheList = async (): Promise => {
+ const response = await axios.get(
+ `${ openRS2Endpoint }/caches.json`
+ );
+ return response.data;
+};
+
+
+export const getAvailableBuilds = async (
+ scope: string = 'runescape',
+ game: string = 'runescape'
+): Promise => {
+ const cacheList = (await getOpenRS2CacheList())
+ .filter(cacheDetails =>
+ // Filter out caches by desired scope and game
+ cacheDetails.scope === scope && cacheDetails.game === game
+ )
+ .map(cacheDetails => {
+ // Map cache list to a list of build numbers
+
+ if (!cacheDetails?.builds?.length) {
+ return [ -1 ];
+ }
+
+ // Map the build number arrays to actual numbers
+ return cacheDetails.builds.map(build => {
+ if (!build) {
+ return -1;
+ }
+
+ if (build.minor !== null && build.minor > 0) {
+ return parseFloat(build.major + '.' + build.minor);
+ } else {
+ return build.major;
+ }
+ });
+ })
+ // Flatten the array
+ .flat()
+ // Filter out anything less than or equal to 0
+ .filter(buildNumber => buildNumber > 0)
+ // Sort the list of numbers
+ .sort((a, b) => a - b);
+
+ // Remove any duplicates
+ return [ ...new Set(cacheList) ];
+};
+
+
+export const getOpenRS2CacheDetailsByBuild = async (
+ build: number,
+): Promise => {
+ return (await getOpenRS2CacheList())?.find(
+ c => c.scope === 'runescape' && c.game === 'runescape' && c.builds.find(b => b.major === build)
+ ) || null;
+};
+
+
+export const getOpenRS2CacheFilesById = async (
+ id: number,
+ scope: string = 'runescape'
+): Promise => {
+ const response = await axios.get(
+ `${ openRS2Endpoint }/caches/${ scope }/${ id }/disk.zip`,
+ { responseType: 'arraybuffer' }
+ );
+
+ if (!response?.data) {
+ return [];
+ }
+
+ const zip = new AdmZip(Buffer.from(response.data, 'binary'));
+ return zip.getEntries().map(entry => ({
+ name: entry.name,
+ data: entry.getData()
+ }));
+};
+
+
+export const getOpenRS2CacheFilesByBuild = async (
+ build: number
+): Promise => {
+ logger.info(`Searching OpenRS2 for build ${ build }...`);
+
+ const cacheList = (await getOpenRS2CacheList())
+ ?.filter(c => c.scope === 'runescape' && c.game === 'runescape') || [];
+
+ const desiredCacheInfo = cacheList.find(cacheDetails => {
+ for (const b of cacheDetails.builds) {
+ if (b.major === build) {
+ return true;
+ }
+ }
+
+ return false;
+ });
+
+ if (desiredCacheInfo) {
+ logger.info(`Build ${ build } was found within the OpenRS2 archive, fetching data...`);
+
+ const cacheFiles = await getOpenRS2CacheFilesById(desiredCacheInfo.id);
+ return cacheFiles?.length ? cacheFiles : null;
+ } else {
+ logger.error(`Build ${ build } was not found within the OpenRS2.org archive.`);
+ }
+
+ return null;
+};
+
+
+export const getXteaKeysById = async (
+ id: number,
+ scope: string = 'runescape'
+): Promise => {
+ const response = await axios.get(
+ `${ openRS2Endpoint }/caches/${ scope }/${ id }/keys.json`
+ );
+
+ return response?.data || [];
+};
+
+
+export const getXteaKeysByBuild = async (
+ build: number
+): Promise => {
+ const cacheDetails = await getOpenRS2CacheDetailsByBuild(build);
+ if (!cacheDetails) {
+ return [];
+ }
+
+ return await getXteaKeysById(cacheDetails.id, cacheDetails.scope);
+};
diff --git a/src/scripts/builds.ts b/src/scripts/builds.ts
new file mode 100644
index 0000000..9900fc4
--- /dev/null
+++ b/src/scripts/builds.ts
@@ -0,0 +1,70 @@
+import { ScriptExecutor, ArgumentOptions } from './script-executor';
+import {
+ getAvailableBuilds
+} from '../openrs2';
+import { logger } from '@runejs/common';
+
+
+interface BuildsOptions {
+ scope: string;
+ game: string;
+ range?: number;
+}
+
+
+const buildsArgumentOptions: ArgumentOptions = {
+ scope: {
+ alias: 's',
+ type: 'string',
+ default: 'runescape',
+ description: `The scope to search for available builds for within OpenRS2.org. Defaults to 'runescape'.`
+ },
+ game: {
+ alias: 'g',
+ type: 'string',
+ default: 'runescape',
+ description: `The game to search for available builds for within OpenRS2.org. Defaults to 'runescape'.`
+ },
+ range: {
+ alias: 'r',
+ type: 'number',
+ description: `The lower number range of builds to search for, ie '400' to return builds between 400-499. Returns all build ranges by default.`
+ },
+};
+
+
+const buildsScript = async (
+ { scope, game, range }
+) => {
+ if (range && range % 100 !== 0) {
+ logger.error(`Invalid range of ${ range }: Range must be a multiple of 100.`);
+ return;
+ }
+
+ const availableBuilds = await getAvailableBuilds(scope, game);
+ let msg = `Available builds on OpenRS2.org with scope ${ scope } and game ${ game }`;
+
+ if (range) {
+ msg += ` for build range ${ range } - ${ range + 99 }`;
+ }
+
+ logger.info(`${ msg }:`);
+
+ let lastHundred = 0;
+
+ for (const buildNumber of availableBuilds) {
+ const lower100 = Math.floor(buildNumber / 100) * 100;
+
+ if (!range || range === lower100) {
+ if (lastHundred !== lower100) {
+ logger.info(`[ ${ lower100 } - ${ lower100 + 99 } ]`);
+ lastHundred = lower100;
+ }
+
+ logger.info(String(buildNumber));
+ }
+ }
+};
+
+
+new ScriptExecutor().executeScript(buildsArgumentOptions, buildsScript);
diff --git a/src/scripts/dev.ts b/src/scripts/dev.ts
new file mode 100644
index 0000000..090d34d
--- /dev/null
+++ b/src/scripts/dev.ts
@@ -0,0 +1,60 @@
+import { writeFileSync, existsSync, mkdirSync } from 'fs';
+import { logger } from '@runejs/common';
+import { JagInterfaceArchive } from '../file-system/jag/content/archives/interfaces/jag-interface-archive';
+import { join } from 'path';
+import { Js5FileStore, JagFileStore } from '../file-system';
+
+
+const saveInterfaces = async (store: JagFileStore) => {
+ logger.info(`Decoding game interfaces...`);
+
+ const interfaceArchive = new JagInterfaceArchive(store);
+
+ await interfaceArchive.decodeAll();
+
+ logger.info(`${interfaceArchive.interfaces.size} interfaces decoded. Saving interface entities...`);
+
+ await interfaceArchive.saveAll();
+};
+
+
+const dumpInterfaceFile = (store: JagFileStore) => {
+ const archive = store.getCache('archives')
+ .getArchive('interface.jag');
+
+ if (!archive) {
+ throw new Error('interface.jag archive is not loaded!');
+ }
+
+ const dataFile = archive.getFile('data');
+ const binaryData = dataFile?.data?.buffer;
+ if (!binaryData?.length) {
+ throw new Error('interface.jag data file is not loaded!');
+ }
+
+ const outputDir = join('.', 'unpacked', 'jag', 'interface.jag');
+ if (!existsSync(outputDir)) {
+ mkdirSync(outputDir, { recursive: true });
+ }
+
+ const outputFile = join(outputDir, 'data');
+
+ logger.info(`Writing file ${outputFile}`);
+
+ writeFileSync(outputFile, binaryData);
+};
+
+
+const dev = async () => {
+ const start = Date.now();
+
+ const store = new JagFileStore(327);
+ await store.load(true, true, true);
+
+ await saveInterfaces(store);
+
+ const end = Date.now();
+ logger.info(`Operations completed in ${(end - start) / 1000} seconds.`);
+};
+
+dev().catch(console.error);
diff --git a/src/scripts/index.ts b/src/scripts/index.ts
deleted file mode 100644
index 5848b19..0000000
--- a/src/scripts/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './script-executor';
diff --git a/src/scripts/indexer.ts b/src/scripts/indexer.ts
index 114e786..e8ebb81 100644
--- a/src/scripts/indexer.ts
+++ b/src/scripts/indexer.ts
@@ -1,117 +1,349 @@
-import { join } from 'path';
-import { existsSync, mkdirSync } from 'graceful-fs';
import { logger } from '@runejs/common';
-
-import { Store, StoreFormat } from '../index';
-import { ScriptExecutor, ArgumentOptions } from './index';
+import { ScriptExecutor, ArgumentOptions } from './script-executor';
+import { Js5FileStore } from '../file-system/js5';
+import { archives, caches, JagArchive, JagFileStore } from '../file-system/jag';
+import {
+ getOpenRS2CacheFilesByBuild,
+} from '../openrs2';
+import { PackedCacheFile, getPackedCacheFormat } from '../file-system/packed';
+import {
+ JagInterfaceArchive
+} from '../file-system/jag/content/archives/interfaces/jag-interface-archive';
interface IndexerOptions {
dir: string;
- format: StoreFormat | 'flat' | 'js5';
+ format: 'flat' | 'packed';
archive: string;
build: string;
}
const indexerArgumentOptions: ArgumentOptions = {
+ archive: {
+ alias: 'a',
+ type: 'string',
+ default: 'main',
+ description: `The archive to index. Defaults to 'main', which will index all store archives one by one. Specify an archive name to index a single archive.`
+ },
+ build: {
+ alias: 'b',
+ type: 'string',
+ default: '435',
+ description: `The game build (revision) that the store should belong to, also known as the game build number. Defaults to '435', a game build from late October, 2006.`
+ },
dir: {
- alias: 'd', type: 'string', default: './',
+ alias: 'd',
+ type: 'string',
+ default: './',
description: `The store root directory. Defaults to the current location.`
},
format: {
- alias: 'f', type: 'string', default: 'unpacked', choices: [ 'unpacked', 'packed', 'flat', 'js5' ],
- description: `The format of the store to index, either 'unpacked' (flat files) or 'packed' (JS5 format). Defaults to 'unpacked'.`
+ alias: 'f',
+ type: 'string',
+ default: 'packed',
+ choices: [ 'packed', 'flat' ],
+ description: `The format of the store to index, either 'packed' (JAG or JS5 format) or 'flat' (flat files). Defaults to 'packed'.`
},
- archive: {
- alias: 'a', type: 'string', default: 'main',
- description: `The archive to index. Defaults to 'main', which will index all store archives one by one. Specify an archive name to index a single archive.`
+ source: {
+ alias: 's',
+ type: 'string',
+ default: 'openrs2',
+ choices: [ 'openrs2', 'local' ],
+ description: `The store source location - either 'openrs2' to pull cache and xtea files from OpenRS2.org or 'local' for caches and xtea files stored locally.`
},
- build: {
- alias: 'b', type: 'string', default: '435',
- description: `The game build (revision) that the store should belong to, also known as the game build number. Defaults to '435', a game build from late October, 2006.`
+};
+
+
+const indexJS5Store = async (store: Js5FileStore) => {
+ logger.info(`Unpacking archives from JS5 store...`);
+
+ for (const [ , archive ] of store.archives) {
+ store.js5.unpack(archive);
+ }
+
+ logger.info(`Decoding JS5 archives...`);
+
+ for (const [ , archive ] of store.archives) {
+ await store.js5.decodeArchive(archive);
+ }
+
+ logger.info(`Saving archive indexes...`);
+
+ for (const [ , archive ] of store.archives) {
+ await archive.saveIndex();
+ }
+
+ logger.info(`Unpacking groups from JS5 store...`);
+
+ for (const [ , archive ] of store.archives) {
+ for (const [ , group ] of archive.groups) {
+ store.js5.unpack(group);
+ }
+
+ logger.info(`Finished unpacking archive ${ archive.index.name } groups.`);
+ }
+
+ logger.info(`Decoding JS5 groups...`);
+
+ for (const [ , archive ] of store.archives) {
+ for (const [ , group ] of archive.groups) {
+ await store.js5.decodeGroup(group);
+ }
+
+ logger.info(`Finished decoding archive ${ archive.index.name } groups.`);
+ }
+
+ logger.info(`Saving group indexes...`);
+
+ for (const [ , archive ] of store.archives) {
+ await archive.upsertGroupIndexes();
+ }
+
+ logger.info(`Saving flat file indexes...`);
+
+ for (const [ , archive ] of store.archives) {
+ for (const [ , group ] of archive.groups) {
+ await group.upsertFileIndexes();
+ }
+ }
+
+ logger.info(`Saving archive data...`);
+
+ for (const [ , archive ] of store.archives) {
+ await archive.saveUncompressedData();
+ await archive.saveCompressedData();
+ }
+
+ logger.info(`Saving group data...`);
+
+ for (const [ , archive ] of store.archives) {
+ await archive.upsertGroupData();
+ }
+
+ logger.info(`Saving flat file data...`);
+
+ for (const [ , archive ] of store.archives) {
+ for (const [ , group ] of archive.groups) {
+ await group.upsertFileData();
+ }
+ }
+};
+
+
+const indexJS5Archive = async (store: Js5FileStore, archiveName: string) => {
+ const archive = await store.getArchive(archiveName);
+
+ if (!archive) {
+ logger.error(`Archive ${ archiveName } was not found.`);
+ return;
+ }
+
+ logger.info(`Unpacking archive ${ archiveName } from JS5 store...`);
+
+ store.js5.unpack(archive);
+
+ logger.info(`Decoding archive ${ archiveName }...`);
+
+ await store.js5.decodeArchive(archive);
+
+ logger.info(`Saving archive ${ archiveName } index...`);
+
+ await archive.saveIndex();
+
+ logger.info(`Unpacking groups from archive ${ archiveName }...`);
+
+ for (const [ , group ] of archive.groups) {
+ store.js5.unpack(group);
+ }
+
+ logger.info(`Decoding archive ${ archiveName } groups...`);
+
+ for (const [ , group ] of archive.groups) {
+ await store.js5.decodeGroup(group);
+ }
+
+ logger.info(`Saving group indexes...`);
+
+ await archive.upsertGroupIndexes();
+
+ logger.info(`Saving flat file indexes...`);
+
+ for (const [ , group ] of archive.groups) {
+ await group.upsertFileIndexes();
+ }
+
+ logger.info(`Saving archive ${ archiveName } data...`);
+
+ await archive.saveUncompressedData();
+ await archive.saveCompressedData();
+
+ logger.info(`Saving group data...`);
+
+ await archive.upsertGroupData();
+
+ logger.info(`Saving flat file data...`);
+
+ for (const [ , group ] of archive.groups) {
+ await group.upsertFileData();
}
};
-async function indexFiles(store: Store, args: IndexerOptions): Promise {
- const argDebugString = args ? Array.from(Object.entries(args))
- .map(([ key, val ]) => `${key} = ${val}`).join(', ') : '';
+const indexJagStore = async (store: JagFileStore) => {
+ logger.info(`Decoding JAG store indexes...`);
- const { archive: archiveName } = args;
+ const indexNames = Object.keys(caches);
+ for (const indexName of indexNames) {
+ store.jag.decodeCache(indexName);
+ }
+
+ logger.info(`Saving JAG caches...`);
- let format = args.format;
- if(format === 'js5') {
- format = 'packed';
- } else if(format === 'flat') {
- format = 'unpacked';
+ for (const [ , cache ] of store.caches) {
+ await cache.saveIndex();
}
- if(format === 'packed') {
- store.loadPackedStore();
- } else {
- const outputDir = store.outputPath;
- if(!existsSync(outputDir)) {
- mkdirSync(outputDir, { recursive: true });
+ for (const [, cache ] of store.caches) {
+ logger.info(`Unpacking JAG files for index ${cache.index.name}...`);
+
+ for (const [ , file ] of cache.files) {
+ store.jag.unpack(file);
}
}
- if(archiveName === 'main') {
- logger.info(`Indexing ${format} store with arguments:`, argDebugString);
+ logger.info(`Decoding JAG archives...`);
- if(format === 'unpacked') {
- await store.read();
- } else if(format === 'packed') {
- store.decode(true);
+ const archiveIndex = store.getCache(caches.archives);
+
+ for (const [ , archive ] of archiveIndex.files) {
+ if (archive instanceof JagArchive) {
+ logger.info(`Decoding archive ${archive.index.name}...`);
+ store.jag.decodeArchive(archive);
}
+ }
- store.encode(true);
- store.compress(true);
+ logger.info(`Saving JAG file indexes...`);
- await store.saveIndexData(true, true, true);
- } else {
- logger.info(`Indexing ${format} archive ${archiveName} with arguments:`, argDebugString);
+ for (const [, index ] of store.caches) {
+ await index.upsertFileIndexes();
+ }
- const archive = store.find(archiveName);
+ logger.info(`Saving JAG archive file indexes...`);
- if(format === 'unpacked') {
- await archive.read(false);
- } else if(format === 'packed') {
- archive.decode();
+ for (const [ , archive ] of archiveIndex.files) {
+ if (archive instanceof JagArchive) {
+ await archive.upsertFileIndexes();
}
+ }
- archive.encode(true);
- archive.compress(true);
+ logger.info(`Saving JAG cache data...`);
- await store.saveIndexData(false, false, false);
- await archive.saveIndexData(true, true);
+ for (const [ , cache ] of store.caches) {
+ await cache.saveCompressedData();
+ await cache.saveUncompressedData();
}
-}
+ logger.info(`Saving JAG cache file data...`);
-new ScriptExecutor().executeScript(indexerArgumentOptions, async (terminal, args) => {
- const start = Date.now();
- logger.info(`Indexing store...`);
+ for (const [ , cache ] of store.caches) {
+ await cache.upsertFileData();
+ }
- const { build, dir } = args;
+ logger.info(`Saving JAG archive file data...`);
- const logDir = join(dir, 'logs');
+ for (const [ , archive ] of archiveIndex.files) {
+ if (archive instanceof JagArchive) {
+ await archive.upsertFileData();
+ }
+ }
+
+ const saveInterfaces = async (store: JagFileStore) => {
+ logger.info(`Decoding game interfaces...`);
+
+ const interfaceArchive = new JagInterfaceArchive(store);
+
+ await interfaceArchive.decodeAll();
+
+ logger.info(`${interfaceArchive.interfaces.size} interfaces decoded. Saving interface entities...`);
+
+ await interfaceArchive.saveAll();
+ };
+
+ await saveInterfaces(store);
+};
+
+
+const indexJagArchive = async (store: JagFileStore, archiveName: string) => {
+ // @todo 18/07/22 - Kiko
+};
+
+
+const indexerScript = async (
+ { build, dir, format, archive: archiveName, source }
+) => {
+ const start = Date.now();
+ const numericBuildNumber: number = /^\d+$/.test(build) ? parseInt(build, 10) : -1;
+ let cacheFiles: PackedCacheFile[] | 'local' = 'local';
- if(!existsSync(logDir)) {
- mkdirSync(logDir, { recursive: true });
+ if (source === 'openrs2') {
+ if (numericBuildNumber) {
+ const openRS2CacheFiles = await getOpenRS2CacheFilesByBuild(numericBuildNumber);
+ if (!openRS2CacheFiles?.length) {
+ return;
+ }
+
+ cacheFiles = openRS2CacheFiles;
+ } else {
+ logger.error(`A numeric build number must be used in order to pull cache information from OpenRS2.org.`);
+ return;
+ }
}
- logger.destination(join(logDir, `index_${build}.log`));
+ const storeType = cacheFiles !== 'local' ? getPackedCacheFormat(cacheFiles) : 'flat';
+
+ logger.info(`Indexing ${ storeType === 'flat' ? storeType : storeType.toUpperCase() } file store...`);
+
+ if (storeType === 'js5') {
+ const store = new Js5FileStore(numericBuildNumber !== -1 ? numericBuildNumber : build, dir);
+ await store.load();
+
+ if (cacheFiles === 'local') {
+ store.js5.readLocalCacheFiles();
+ } else {
+ store.js5.readOpenRS2CacheFiles(cacheFiles);
+ }
+
+ if (archiveName === 'main') {
+ await indexJS5Store(store);
+ } else {
+ await indexJS5Archive(store, archiveName);
+ }
+
+ await store.closeDatabase();
+ } else if (storeType === 'jag') {
+ const store = new JagFileStore(numericBuildNumber !== -1 ? numericBuildNumber : build, dir);
+ await store.load();
- const store = await Store.create(build, dir);
+ if (cacheFiles === 'local') {
+ store.jag.readLocalPackedCacheFiles();
+ } else {
+ store.jag.readOpenRS2PackedCacheFiles(cacheFiles);
+ }
- await indexFiles(store, args);
+ if (archiveName === 'main') {
+ await indexJagStore(store);
+ } else {
+ await indexJagArchive(store, archiveName);
+ }
- logger.boom.flushSync();
- logger.boom.end();
+ await store.closeDatabase();
+ } else if (format === 'flat') {
+ // @todo 18/07/22 - Kiko
+ }
+
+ logger.info(`Indexing completed in ${ (Date.now() - start) / 1000 } seconds.`);
+};
- const end = Date.now();
- logger.info(`Indexing completed in ${(end - start) / 1000} seconds.`);
- process.exit(0);
-});
+new ScriptExecutor().executeScript(indexerArgumentOptions, indexerScript);
diff --git a/src/scripts/name-hasher.ts b/src/scripts/name-hasher.ts
new file mode 100644
index 0000000..e352606
--- /dev/null
+++ b/src/scripts/name-hasher.ts
@@ -0,0 +1,169 @@
+import { logger } from '@runejs/common';
+import { NameHasher } from '../config';
+import { join } from 'path';
+
+
+// @todo optimize this thing - 08/08/22 - Kiko
+const bruteForcer = async () => {
+ const hashes = [
+ 216335554,
+ 216316762,
+ ];
+
+ const validChars = [
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
+ 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
+ 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '_', '-'
+ ];
+
+ const validCharCodes = validChars.map(s => s.charCodeAt(0));
+
+ const INT_MAX = 2147483648;
+
+ // Emulate Java's INT overflow-wrapping
+ const int32 = (value: number): number => {
+ while (value > INT_MAX) {
+ const diff = value - INT_MAX;
+ value = -INT_MAX + diff;
+ }
+
+ while (value < -INT_MAX) {
+ const diff = Math.abs(value) - INT_MAX;
+ value = INT_MAX - diff;
+ }
+
+ return value;
+ }
+
+ const addToHash = (s: string, hash: number): number => {
+ for (let j = 0; j < s.length; j++) {
+ hash = int32((hash * 61 + s.charCodeAt(j)) - 32);
+ }
+
+ return hash;
+ };
+
+ const getMatch = (hash: number): number => {
+ for (let i = 0; i < hashes.length; i++) {
+ if (hashes[i] === hash) {
+ return i;
+ }
+ }
+
+ return -1;
+ };
+
+ const getHashForName = (dataName: string): number => {
+ let dataNameHash = 0;
+ for (let j = 0; j < dataName.length; j++) {
+ dataNameHash = int32((dataNameHash * 61 + dataName.charCodeAt(j)) - 32);
+ }
+ return dataNameHash;
+ };
+
+ const createString = (...charCodes: number[]): string => {
+ let result = '';
+ for (const charCode of charCodes) {
+ const i = validCharCodes.indexOf(charCode);
+ result += validChars[i];
+ }
+
+ return result;
+ };
+
+ const bruteForceHash = (): void => {
+ let l1hash;
+ let l2hash;
+ let l3hash;
+ let l4hash;
+ let l5hash;
+ let l6hash;
+ let l7hash;
+ let l8hash;
+ let l9hash;
+ let hash;
+
+ for (const c1 of validCharCodes) {
+ l1hash = c1 - 32;
+ for (const c2 of validCharCodes) {
+ l2hash = int32(l1hash * 61 + c2 - 32);
+ for (const c3 of validCharCodes) {
+ l3hash = int32(l2hash * 61 + c3 - 32);
+ for (const c4 of validCharCodes) {
+ l4hash = int32(l3hash * 61 + c4 - 32);
+ const resultString = createString(c1, c2, c3, c4);
+ hash = addToHash(".DAT", l4hash);
+ if (getMatch(hash) !== -1) {
+ logger.info(resultString + '.DAT : ' + hash);
+ }
+
+ hash = addToHash(".IDX", l4hash);
+ if (getMatch(hash) !== -1) {
+ logger.info(resultString + '.IDX : ' + hash);
+ }
+ if (getMatch(l4hash) !== -1) {
+ logger.info(resultString + ' : ' + hash);
+ }
+ // for (const c5 of validCharCodes) {
+ // l5hash = int32(l4hash * 61 + c5 - 32);
+ // for (const c6 of validCharCodes) {
+ // l6hash = int32(l5hash * 61 + c6 - 32);
+ // for (const c7 of validCharCodes) {
+ // l7hash = int32(l6hash * 61 + c7 - 32);
+ // for (const c8 of validCharCodes) {
+ // l8hash = int32(l7hash * 61 + c8 - 32);
+ // for (const c9 of validCharCodes) {
+ // l9hash = int32(l8hash * 61 + c9 - 32);
+ // hash = addToHash(".DAT", l9hash);
+ // const resultString = createString(c1, c2, c3, c4, c5, c6, c7, c8, c9);
+ // if (getMatch(hash) !== -1) {
+ // logger.info(resultString + '.DAT : ' + hash);
+ // }
+ //
+ // hash = addToHash(".IDX", l9hash);
+ // if (getMatch(hash) !== -1) {
+ // logger.info(resultString + '.IDX : ' + hash);
+ // }
+ // if (getMatch(l9hash) !== -1) {
+ // logger.info(resultString + ' : ' + hash);
+ // }
+ // }
+ // }
+ // }
+ // }
+ // }
+ }
+ }
+ }
+ }
+ }
+
+ bruteForceHash();
+};
+
+
+const nameHasher = async () => {
+ const start = Date.now();
+
+ const hasher = new NameHasher(join('.', 'config'));
+
+ const fileNames = [
+ 'hunt.dat',
+ 'hunt.idx',
+ ];
+
+ const keyValueMap: { [key: string]: string } = {};
+
+ for (const fileName of fileNames) {
+ keyValueMap[String(hasher.hashJagFileName(fileName))] = fileName;
+ }
+
+ console.log(JSON.stringify(keyValueMap, null, 4));
+
+ const end = Date.now();
+ logger.info(`Operations completed in ${(end - start) / 1000} seconds.`);
+};
+
+nameHasher().catch(console.error);
diff --git a/src/scripts/script-executor.ts b/src/scripts/script-executor.ts
index 29796c5..3ffc161 100644
--- a/src/scripts/script-executor.ts
+++ b/src/scripts/script-executor.ts
@@ -11,11 +11,13 @@ export class ScriptExecutor {
return yargs(process.argv.slice(2)).options(argumentOptions).argv as any as T;
}
- public executeScript(argumentOptions: ArgumentOptions,
- executor: (terminalInterface: ScriptExecutor, args: T) => Promise): void {
- (async function(terminal: ScriptExecutor, args: T) {
- await executor(terminal, args);
- }(this, this.getArguments(argumentOptions)));
+ public executeScript(
+ argumentOptions: ArgumentOptions,
+ script: (args: T) => Promise
+ ): void {
+ (async function(args: T) {
+ await script(args);
+ }(this.getArguments(argumentOptions)));
}
}
diff --git a/src/scripts/unpacker.ts b/src/scripts/unpacker.ts
index c5947db..388e29b 100644
--- a/src/scripts/unpacker.ts
+++ b/src/scripts/unpacker.ts
@@ -1,9 +1,7 @@
import { join } from 'path';
import { existsSync, readdirSync, statSync, mkdirSync } from 'graceful-fs';
import { logger } from '@runejs/common';
-
-import { Store } from '../index';
-import { ScriptExecutor, ArgumentOptions } from './index';
+import { ArgumentOptions, ScriptExecutor } from './script-executor';
interface UnpackOptions {
@@ -34,63 +32,59 @@ const unpackerArgumentOptions: ArgumentOptions = {
};
-async function unpackFiles(store: Store, args: UnpackOptions): Promise {
+/*async function unpackFiles(store: Store, args: UnpackOptions): Promise {
const argDebugString = args ? Array.from(Object.entries(args))
.map(([ key, val ]) => `${key} = ${val}`).join(', ') : '';
const { archive: archiveName, debug } = args;
- try {
- store.loadPackedStore();
-
- if(archiveName === 'main') {
- logger.info(`Unpacking JS5 file store with arguments:`, argDebugString);
+ store.loadPackedStore();
- store.decode(true);
+ if(archiveName === 'main') {
+ logger.info(`Unpacking JS5 file store with arguments:`, argDebugString);
- store.encode(true);
- store.compress(true);
+ store.decode(true);
- if(!debug) {
- store.write();
- } else {
- logger.info(`Flat file store writing is disabled in debug mode.`);
- }
+ store.encode(true);
+ store.compress(true);
- logger.info(`Decoding completed.`);
-
- await store.saveIndexData(true, true, true);
+ if(!debug) {
+ store.write();
} else {
- logger.info(`Unpacking JS5 archive with arguments:`, argDebugString);
+ logger.info(`Flat file store writing is disabled in debug mode.`);
+ }
- const a = store.find(archiveName);
+ logger.info(`Decoding completed.`);
- if(!a) {
- throw new Error(`Archive ${ a } was not found.`);
- }
+ await store.saveIndexData(true, true, true);
+ } else {
+ logger.info(`Unpacking JS5 archive with arguments:`, argDebugString);
- a.decode(true);
+ const a = store.find(archiveName);
- a.encode(true);
- a.compress(true);
+ if(!a) {
+ throw new Error(`Archive ${ a } was not found.`);
+ }
- if(!debug) {
- a.write();
- } else {
- logger.info(`Archive writing is disabled in debug mode.`);
- }
+ a.decode(true);
- logger.info(`Decoding completed.`);
+ a.encode(true);
+ a.compress(true);
- await a.saveIndexData(true, true);
+ if(!debug) {
+ a.write();
+ } else {
+ logger.info(`Archive writing is disabled in debug mode.`);
}
- } catch(error) {
- logger.error(error);
+
+ logger.info(`Decoding completed.`);
+
+ await a.saveIndexData(true, true);
}
-}
+}*/
-new ScriptExecutor().executeScript(unpackerArgumentOptions, async (terminal, args) => {
+new ScriptExecutor().executeScript(unpackerArgumentOptions, async (args) => {
const start = Date.now();
logger.info(`Unpacking JS5 store...`);
@@ -102,9 +96,7 @@ new ScriptExecutor().executeScript(unpackerArgumentOptions, async
mkdirSync(logDir, { recursive: true });
}
- logger.destination(join(logDir, `unpack_${ build }.log`));
-
- const store = await Store.create(build, dir);
+ /*const store = await Store.create(build, dir);
const js5Dir = join(dir, 'packed');
@@ -122,11 +114,6 @@ new ScriptExecutor().executeScript(unpackerArgumentOptions, async
}
}
- logger.boom.flushSync();
- logger.boom.end();
-
const end = Date.now();
- logger.info(`Unpacking completed in ${(end - start) / 1000} seconds.`);
-
- process.exit(0);
+ logger.info(`Unpacking completed in ${(end - start) / 1000} seconds.`);*/
});
diff --git a/src/store.ts b/src/store.ts
deleted file mode 100644
index d6526e7..0000000
--- a/src/store.ts
+++ /dev/null
@@ -1,526 +0,0 @@
-import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync } from 'graceful-fs';
-import { join } from 'path';
-import JSON5 from 'json5';
-import { ByteBuffer, logger } from '@runejs/common';
-import { Xtea, XteaKeys } from '@runejs/common/encrypt';
-import { Crc32 } from '@runejs/common/crc32';
-
-import { Archive, FileState } from './index';
-import { ArchiveIndexEntity, IndexService, StoreIndexEntity } from './db';
-import { ArchiveConfig } from './config';
-
-
-export type StoreFormat = 'unpacked' | 'packed';
-
-export interface StoreOptions {
- outputPath?: string | undefined;
-}
-
-
-export class Store {
-
- public readonly archives: Map = new Map();
- public readonly fileNameHashes: Map = new Map();
- public readonly indexService: IndexService;
-
- private _js5MainIndex: ByteBuffer;
- private _js5ArchiveIndexes: Map;
- private _js5MainArchiveData: ByteBuffer;
-
- private _index: StoreIndexEntity;
- private _mainArchive: Archive;
- private _data: ByteBuffer;
- private _compressed: boolean = false;
- private _js5Encoded: boolean = false;
- private _path: string;
- private _outputPath: string;
- private _archiveConfig: { [key: string]: ArchiveConfig };
- private _encryptionKeys: Map;
- private _gameBuild: string;
- private _gameBuildMissing: boolean;
-
- protected constructor(gameBuild: string, path: string, outputPath?: string) {
- this._gameBuild = gameBuild;
- this._path = path;
- this._outputPath = outputPath ? outputPath : join(path, 'unpacked');
- this.indexService = new IndexService(this);
- this.loadArchiveConfig();
- Crc32.init();
- }
-
- public static async create(gameBuild: string, path: string = './', options?: StoreOptions): Promise {
- const store = new Store(gameBuild, path, options?.outputPath);
-
- await store.indexService.load();
-
- store._index = await store.indexService.getStoreIndex();
-
- if(!store._index) {
- store._index = new StoreIndexEntity();
- store._index.gameBuild = gameBuild;
- }
-
- store.loadEncryptionKeys();
- store.loadFileNames();
-
- store.archives.clear();
-
- const archiveConfigs = Object.entries(store.archiveConfig);
- const mainArchiveConfig = Array.from(Object.values(store.archiveConfig)).find(a => a.index === 255);
-
- if(!mainArchiveConfig) {
- throw new Error(`Main archive (index 255) configuration was not found. ` +
- `Please configure the main archive using the archives.json5 file within the store config directory.`)
- }
-
- const mainArchiveIndex = new ArchiveIndexEntity();
- mainArchiveIndex.key = 255;
- mainArchiveIndex.gameBuild = gameBuild;
- mainArchiveIndex.name = 'main';
- store._mainArchive = new Archive(mainArchiveIndex, mainArchiveConfig, { store });
-
- let archiveIndexes = await store.indexService.getArchiveIndexes();
-
- if(!archiveIndexes?.length) {
- archiveIndexes = new Array(archiveConfigs.length);
- }
-
- for(const [ name, config ] of archiveConfigs) {
- if(config.index === 255) {
- continue;
- }
-
- if(config.build) {
- let revision: number;
- if(gameBuild.includes('_')) {
- revision = Number(gameBuild.substring(gameBuild.indexOf('_') + 1));
- } else {
- revision = Number(gameBuild);
- }
- if(revision < config.build) {
- logger.info(`Skipping archive ${name} as it is not available in this game build.`);
- continue;
- }
- }
-
- let archiveIndex = archiveIndexes.find(a => a?.key === config.index);
- if(!archiveIndex) {
- archiveIndex = store.indexService.validateArchive({
- numericKey: config.index,
- name,
- nameHash: store.hashFileName(name),
- config
- });
- }
-
- const archive = new Archive(archiveIndex, config, {
- store, archive: store._mainArchive
- });
-
- store.archives.set(archive.key, archive);
-
- // Bulk-fetch the archive's groups
- const groups = archiveIndex.groups = await store.indexService.getGroupIndexes(archiveIndex);
-
- // Bulk-fetch the archive's files and sort them into the appropriate groups
- const archiveFileIndexes = await store.indexService.getFileIndexes(archiveIndex);
- for(const fileIndex of archiveFileIndexes) {
- const group = groups.find(group => group.key === fileIndex.groupKey);
- if(!group) {
- continue;
- }
-
- if(!Array.isArray(group.files) || !group.files?.length) {
- group.files = [ fileIndex ];
- } else {
- group.files.push(fileIndex);
- }
- }
- }
-
- return store;
- }
-
- public loadPackedStore(): void {
- const js5StorePath = join(this.path, 'packed');
-
- if(!existsSync(js5StorePath)) {
- throw new Error(`${js5StorePath} could not be found.`);
- }
-
- const stats = statSync(js5StorePath);
- if(!stats?.isDirectory()) {
- throw new Error(`${js5StorePath} is not a valid directory.`);
- }
-
- const storeFileNames = readdirSync(js5StorePath);
- const dataFile = 'main_file_cache.dat2';
- const mainIndexFile = 'main_file_cache.idx255';
-
- if(storeFileNames.indexOf(dataFile) === -1) {
- throw new Error(`The main ${dataFile} data file could not be found.`);
- }
-
- if(storeFileNames.indexOf(mainIndexFile) === -1) {
- throw new Error(`The main ${mainIndexFile} index file could not be found.`);
- }
-
- const indexFilePrefix = 'main_file_cache.idx';
- const dataFilePath = join(js5StorePath, dataFile);
- const mainIndexFilePath = join(js5StorePath, mainIndexFile);
-
- this._js5MainArchiveData = new ByteBuffer(readFileSync(dataFilePath));
- this._js5MainIndex = new ByteBuffer(readFileSync(mainIndexFilePath));
- this._js5ArchiveIndexes = new Map();
-
- for(const fileName of storeFileNames) {
- if(!fileName?.length || fileName === mainIndexFile || fileName === dataFile) {
- continue;
- }
-
- if(!fileName.startsWith(indexFilePrefix)) {
- continue;
- }
-
- const index = fileName.substring(fileName.indexOf('.idx') + 4);
- const numericIndex = Number(index);
-
- if(isNaN(numericIndex)) {
- logger.error(`Index file ${fileName} does not have a valid extension.`);
- }
-
- if(!this.has(index)) {
- logger.warn(`Archive ${index} was found within the JS5 store, but is not configured for flat file store use.`,
- `Please add the archive to the archives.json5 configuration file to load it properly.`);
- continue;
- }
-
- this._js5ArchiveIndexes.set(index, new ByteBuffer(readFileSync(join(js5StorePath, fileName))));
- }
-
- logger.info(`Packed store loaded for game build ${this.gameBuild}.`);
- }
-
- public pack(): void {
- // @TODO
- }
-
- public decode(decodeGroups: boolean = true): ByteBuffer | null {
- this.archives.forEach(archive => archive.decode(decodeGroups));
- return null;
- }
-
- public encode(encodeGroups: boolean = true): ByteBuffer {
- const fileSize = 4 * this.archiveCount;
-
- this._data = new ByteBuffer(fileSize + 31);
-
- this._data.put(0);
- this._data.put(fileSize, 'int');
-
- for(let archiveIndex = 0; archiveIndex < this.archiveCount; archiveIndex++) {
- this._data.put(this.get(archiveIndex).index.crc32, 'int');
- }
-
- this.mainArchive.setData(this._data, FileState.encoded);
- this.mainArchive.index.data = this.index.data = this._data.toNodeBuffer();
-
- if(encodeGroups) {
- this.archives.forEach(archive => archive.encode(true));
- }
-
- return this.data;
- }
-
- public compress(compressGroups: boolean = true): ByteBuffer | null {
- this.archives.forEach(archive => archive.compress(compressGroups));
-
- this._compressed = true;
- return this._data;
- }
-
- public async read(compress: boolean = false, readDiskFiles: boolean = true): Promise {
- this._js5Encoded = false;
- this._compressed = false;
-
- for(const [ , archive ] of this.archives) {
- await archive.read(false, readDiskFiles);
- }
-
- if(compress) {
- this.compress();
- }
-
- return this.encode();
- }
-
- public write(): void {
- if(!this.archives.size) {
- throw new Error(`Archives not loaded, please load a flat file store or a JS5 store.`);
- }
-
- const start = Date.now();
- logger.info(`Writing flat file store...`);
-
- try {
- if(existsSync(this.outputPath)) {
- rmSync(this.outputPath, { recursive: true, force: true });
- }
-
- mkdirSync(this.outputPath, { recursive: true });
- } catch(error) {
- logger.error(`Error clearing file store output path (${this.outputPath}):`, error);
- return;
- }
-
- try {
- logger.info(`Writing archive contents to disk...`);
- this.archives.forEach(archive => archive.write());
- logger.info(`Archives written.`);
- } catch(error) {
- logger.error(`Error writing archives:`, error);
- return;
- }
-
- const end = Date.now();
- logger.info(`Flat file store written in ${(end - start) / 1000} seconds.`);
- }
-
- public async saveIndexData(saveArchives: boolean = true, saveGroups: boolean = true, saveFiles: boolean = true): Promise {
- try {
- await this.indexService.saveStoreIndex();
- logger.info(`File store index saved.`);
- } catch(error) {
- logger.error(`Error indexing file store:`, error);
- return;
- }
-
- if(saveArchives) {
- logger.info(`Indexing archives...`);
-
- for(const [ , archive ] of this.archives) {
- try {
- await archive.saveIndexData(false);
- } catch(error) {
- logger.error(`Error indexing archive:`, error);
- return;
- }
- }
- }
-
- if(saveGroups) {
- logger.info(`Indexing archive groups...`);
-
- for(const [ , archive ] of this.archives) {
- try {
- await archive.saveGroupIndexes(false);
- } catch(error) {
- logger.error(`Error indexing group:`, error);
- return;
- }
- }
- }
-
- if(saveFiles) {
- logger.info(`Indexing archive files...`);
-
- for(const [ , archive ] of this.archives) {
- try {
- await archive.saveFlatFileIndexes();
- } catch(error) {
- logger.error(`Error indexing flat file:`, error);
- return;
- }
- }
- }
- }
-
- public find(archiveName: string): Archive {
- return Array.from(this.archives.values()).find(child => child?.name === archiveName) ?? null;
- }
-
- public get(archiveKey: string): Archive | null;
- public get(archiveKey: number): Archive | null;
- public get(archiveKey: string | number): Archive | null;
- public get(archiveKey: string | number): Archive | null {
- return this.archives.get(String(archiveKey)) ?? null;
- }
-
- public set(archiveKey: string, archive: Archive): void;
- public set(archiveKey: number, archive: Archive): void;
- public set(archiveKey: string | number, archive: Archive): void;
- public set(archiveKey: string | number, archive: Archive): void {
- this.archives.set(String(archiveKey), archive);
- }
-
- public has(archiveKey: string | number): boolean {
- return this.archives.has(String(archiveKey));
- }
-
- public loadArchiveConfig(): void {
- const configPath = join(this.path, 'config', 'archives.json5');
- if(!existsSync(configPath)) {
- logger.error(`Error loading store: ${configPath} was not found.`);
- return;
- }
-
- this._archiveConfig = JSON5.parse(readFileSync(configPath, 'utf-8')) as { [key: string]: ArchiveConfig };
-
- if(!Object.values(this._archiveConfig)?.length) {
- throw new Error(`Error reading archive configuration file. ` +
- `Please ensure that the ${configPath} file exists and is valid.`);
- }
- }
-
- public getEncryptionKeys(fileName: string): XteaKeys | XteaKeys[] | null {
- if(!this.encryptionKeys.size) {
- this.loadEncryptionKeys();
- }
-
- const keySets = this.encryptionKeys.get(fileName);
- if(!keySets) {
- return null;
- }
-
- if(this.gameBuild !== undefined) {
- return keySets.find(keySet => keySet.gameBuild === this.gameBuild) ?? null;
- }
-
- return keySets;
- }
-
- public loadEncryptionKeys(): void {
- const configPath = join(this.path, 'config', 'xtea');
- this._encryptionKeys = Xtea.loadKeys(configPath);
-
- if(!this.encryptionKeys.size) {
- throw new Error(`Error reading encryption key lookup table. ` +
- `Please ensure that the ${configPath} file exists and is valid.`);
- }
- }
-
- public hashFileName(fileName: string): number {
- if(!fileName) {
- return 0;
- }
-
- let hash = 0;
- for(let i = 0; i < fileName.length; i++) {
- hash = fileName.charCodeAt(i) + ((hash << 5) - hash);
- }
-
- return hash | 0;
- }
-
- public findFileName(nameHash: string | number | undefined, defaultName?: string | undefined): string | undefined {
- if(!this.fileNameHashes.size) {
- this.loadFileNames();
- }
-
- if(nameHash === undefined || nameHash === null) {
- return defaultName;
- }
-
- if(typeof nameHash === 'string') {
- nameHash = Number(nameHash);
- }
-
- if(isNaN(nameHash) || nameHash === -1 || nameHash === 0) {
- return defaultName;
- }
-
- return this.fileNameHashes.get(nameHash) || defaultName;
- }
-
- public loadFileNames(): void {
- const configPath = join(this.path, 'config', 'name-hashes.json');
- if(!existsSync(configPath)) {
- logger.error(`Error loading file names: ${configPath} was not found.`);
- return;
- }
-
- const nameTable = JSON.parse(readFileSync(configPath, 'utf-8')) as { [key: string]: string };
- Object.keys(nameTable).forEach(nameHash => this.fileNameHashes.set(Number(nameHash), nameTable[nameHash]));
-
- if(!this.fileNameHashes.size) {
- throw new Error(`Error reading file name lookup table. ` +
- `Please ensure that the ${configPath} file exists and is valid.`);
- }
- }
-
- public setGameBuildMissing(): void {
- this._gameBuildMissing = true;
- }
-
- public get archiveCount(): number {
- return this.archives?.size || 0;
- }
-
- public get js5MainIndex(): ByteBuffer {
- if(!this._js5MainIndex?.length || !this._js5MainArchiveData?.length) {
- this.decode();
- }
-
- return this._js5MainIndex;
- }
-
- public get js5ArchiveIndexes(): Map {
- if(!this._js5MainIndex?.length || !this._js5MainArchiveData?.length) {
- this.decode();
- }
-
- return this._js5ArchiveIndexes;
- }
-
- public get js5MainArchiveData(): ByteBuffer {
- if(!this._js5MainIndex?.length || !this._js5MainArchiveData?.length) {
- this.decode();
- }
-
- return this._js5MainArchiveData;
- }
-
- public get index(): StoreIndexEntity {
- return this._index;
- }
-
- public get mainArchive(): Archive {
- return this._mainArchive;
- }
-
- public get data(): ByteBuffer {
- return this._data;
- }
-
- public get compressed(): boolean {
- return this._compressed;
- }
-
- public get js5Encoded(): boolean {
- return this._js5Encoded;
- }
-
- public get path(): string {
- return this._path;
- }
-
- public get outputPath(): string {
- return this._outputPath;
- }
-
- public get gameBuild(): string {
- return this._gameBuild;
- }
-
- public get archiveConfig(): { [p: string]: ArchiveConfig } {
- return this._archiveConfig;
- }
-
- public get encryptionKeys(): Map {
- return this._encryptionKeys;
- }
-
- public get gameBuildMissing(): boolean {
- return this._gameBuildMissing;
- }
-}
diff --git a/src/util/index.ts b/src/util/index.ts
deleted file mode 100644
index 32737a8..0000000
--- a/src/util/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export const isSet = (variable: any): boolean =>
- variable !== undefined && variable !== null;