From 746363bfd347b7dca628945750152d49006fa48d Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Fri, 28 Apr 2023 11:59:52 -0700 Subject: [PATCH 001/118] Remove accidentally committed keys and update .gitignore to prevent them being added again --- .gitignore | 1 + .../keys/is-signing-key-10C452043E09C5A22FC8D97669868B8F.json | 1 - .../keys/is-signing-key-1417AE0BAF26F393609EF30FA355D06C.json | 1 - .../keys/is-signing-key-22178AEDB80CD0A41DF6874FE93F794D.json | 1 - .../keys/is-signing-key-3139DF3FF07C8E3881CFA9743F89A787.json | 1 - .../keys/is-signing-key-870FA7120249C21C30ADE458B07918C1.json | 1 - .../keys/is-signing-key-B0B34AEB91E2638F61EB9A5543F3940F.json | 1 - .../keys/is-signing-key-CFE19FEED1112F0740C7CEAAE490834F.json | 1 - 8 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 src/Services/Identity/Identity.API/keys/is-signing-key-10C452043E09C5A22FC8D97669868B8F.json delete mode 100644 src/Services/Identity/Identity.API/keys/is-signing-key-1417AE0BAF26F393609EF30FA355D06C.json delete mode 100644 src/Services/Identity/Identity.API/keys/is-signing-key-22178AEDB80CD0A41DF6874FE93F794D.json delete mode 100644 src/Services/Identity/Identity.API/keys/is-signing-key-3139DF3FF07C8E3881CFA9743F89A787.json delete mode 100644 src/Services/Identity/Identity.API/keys/is-signing-key-870FA7120249C21C30ADE458B07918C1.json delete mode 100644 src/Services/Identity/Identity.API/keys/is-signing-key-B0B34AEB91E2638F61EB9A5543F3940F.json delete mode 100644 src/Services/Identity/Identity.API/keys/is-signing-key-CFE19FEED1112F0740C7CEAAE490834F.json diff --git a/.gitignore b/.gitignore index 8b7a2cbb9..2810d6b1c 100644 --- a/.gitignore +++ b/.gitignore @@ -282,3 +282,4 @@ src/**/app.yaml src/**/inf.yaml .angular/ +/src/Services/Identity/Identity.API/keys/*.json diff --git a/src/Services/Identity/Identity.API/keys/is-signing-key-10C452043E09C5A22FC8D97669868B8F.json b/src/Services/Identity/Identity.API/keys/is-signing-key-10C452043E09C5A22FC8D97669868B8F.json deleted file mode 100644 index 09d78ff83..000000000 --- a/src/Services/Identity/Identity.API/keys/is-signing-key-10C452043E09C5A22FC8D97669868B8F.json +++ /dev/null @@ -1 +0,0 @@ -{"Version":1,"Id":"10C452043E09C5A22FC8D97669868B8F","Created":"2022-11-30T12:03:40.1630635Z","Algorithm":"RS256","IsX509Certificate":false,"Data":"CfDJ8JmnWj_BpdBDujWYr1NmSawi1hoBHaFG7R1_Hu0pSObE9SiTNg1Wm83zVA3-oCwbntipelQt_gpZ3KH-NMBYdleYt4Gzhpvf4uchFNFzvdnx1X9jpWQi9WCmUm3cVNfzNG2eIKzrVLAoiaWLuDDG9XT-u2ojWIuKRKH7zEBMGrqCDQiVHZlBuqH_qzpWUQn-qKYEkFRcm05OmMYXJA0AquXimdOl1V_BcagZOpNVzG3C5t7lZTsTrm7FpD5zMdyZxL2VJJjRy5fUZbIQIjbQdTGYJaROhj-Sc4h2MgyrMNYJ-TQZKci_5ZoN-GJfjdaB-3UHDk_uFrVk9WpAYEWw0rw-I05tMu8vVxlE2jAnEGaVWEqS0f_Bz53MkDQb2YEleekTwaLJM1JZF791NTaG7oDXHSetSeo7UngHt3D9Ls2FHnZwV-B5mvzZju_-U7inwsoKXjZeqzQfQMs2IsIgiXJJkS20PObmosEbq7LkT97qRrinGicY0pA2zIcDmLiywYzWpsP6Rjw7epDaDlPu2J9BZ93Ni-slfTkNdn2SvAfE2dsJmV7Pz5tMEE-0mBlSMbcrs8TuVQayYPm2dm-sZLCv-iQu0rrvGcJ-lLPliby69du5oFU6WKpo52X4Du9tcM-5prBLWRVt_gcq16zBY_f8ieNnq6b0C_9chaztCevTQAouiSk7ni3zjJo3RuG1wPUts2tLT4sjY6IK2Zbhsvi-negegn91cFA0MzdOaD2Ca2GWN2L2kRrDWioVz_P4ztVFIU3SrgjW6stOGNreRvOB8txUCexJuUP0rb85pOa8rxPCkk1Iw8BjjRdirhvU3bvqhml6i2_iqNTAxpx89A6LRUuOYvYiwJersfhOF9F-FfOVGNxxfm1AKKnUBDfgLWDAw1r8PBeV6huAqUSIwaN5PcQJcdsfER9FeP9_CJqDgNGaL-psm2NQDaVV2Vx4m3GqWQhKMlk90zee5XNe1wobBS0XW_GQYieWWhH5t0pyzJi0QvpFyMAz1mcGXQs-TiHoU142FlFQojIu3_Ynf2RHOOByWDM9krMKMn6ZTnLWgBXnWtMefXqYNEhlACtP8lIXBxcbI2wFeBgRmaQA2DtEEjlymZ4RTaiQEuVC6B_wtTTVVFx3CL-TM62Xs-FOWTYafzKqGsHKzVWnB3fZqjDh4DNwb_A4mkfxoyb2UI9W4P7BJmbV5tOktYudVAFLt3XL7uNhBYLDSOjL_n8bixTg-sLUyO1H5-IxYQJciZdAro4yGO7r40FTYpZfTyvlr3RqFMDhBEPu_nSx9lPKrgpei0DmqYWw_cHJ3mPR1HDUE_i8Prlyzsyf9F-pYV4HMyupetXeXxMAIULnB52SE7uYfSUZHC25Ffo_tif8zMPo2ZKiMpc42BZ0cBptkPKUCvkR-Cq3pFnqXkKADWh1LLBP09hZtOjXqkFdsIFZq5KfRE6UVIyMJ91L-OSHOnggdjScFJzPlgEteUbydKSlPEBkicIs-uXXe8Tk8KZg2CfUU2WnziP0-VgymbTomKR5xz36kJqMjP2VYp6Xy-t3joQEqPE50ntT0AYUFJb6NZt5stHQz76-WecPnA6ZSA3aJec7NlLrxwM6BMGDyBZpbkgWtWFJdGWz6m9j4RKuyZBnyOXzYZU8FDNpDu6FVEymUkYxEhUnpIl7PZWuiZGADwj9-Bpzg0To8jMJ-jgx8w3RDzb5DoM6-jh0IJ5vecn8lSfRzHcOu48CLY5mTuHFr93YKiQCK06DS8VY3kI1b8irtdvmY-IvUCyCJlpzBYh8vFrS2PdJYsRVWuGJraxMiHYP_zH5r4Q4z27p6vt0Rbm0S4Fm1I9z4Hmaa4igF1mnktuTMizyxKWTsh3DjbsB_6W_lNU62RqJAt_IGr69MIphVY6ZOcbLx2I8p0z4yWpuYJey2BmRQPQeCZ-Tb9HtHESxTBFxupYul8619OJWA7RfLl-xv43X81OZnaxE9wLVFs5uEowKoEOzl_K5nxOw4igCiWYWufaFMMrZSu-0ni9RVSwytOPiEbGV0XOcVnB_lHDz1ymvDI4u1rfOVkehwB_wFBeRJRSEymzoD-bgRox-a1qLJNhOsdm9WUdZF3MHbmmA8NpyqU5qOTTqCvY-FXdJHL_OHmq1nDVHCJvcwLqUfPFMfFAi0MZQEhRndeQWYGdRGOhmvtwbRX-Hryz2HKXber1ixUvY3-XCxjzSyZdn845UzpKBdsgwAwY-LFzlgNQGEKHzsZUl8MSeqx3iO2QwDwC5eV4gNWBC5QBw0NAloBmdnQ84sSWydPViOYW1CinUQAnZsW2Z-0Xw0FP4fbS4HvulNBMIxE_mfJsHny4YZu_463zGR0SrV2hEFSiXuwSx27K6xSyPRB26__t8w37AeFYXtavqr9rB5GXnEJRQkW-i5lDnhtA93uRjfNzVhUpcTK-ROm3h7b4UrUTaK_IMLXxoYEjOFm8-cw1ZGHu3","DataProtected":true} \ No newline at end of file diff --git a/src/Services/Identity/Identity.API/keys/is-signing-key-1417AE0BAF26F393609EF30FA355D06C.json b/src/Services/Identity/Identity.API/keys/is-signing-key-1417AE0BAF26F393609EF30FA355D06C.json deleted file mode 100644 index 47ee8034b..000000000 --- a/src/Services/Identity/Identity.API/keys/is-signing-key-1417AE0BAF26F393609EF30FA355D06C.json +++ /dev/null @@ -1 +0,0 @@ -{"Version":1,"Id":"1417AE0BAF26F393609EF30FA355D06C","Created":"2022-11-30T15:12:36.3392917Z","Algorithm":"RS256","IsX509Certificate":false,"Data":"CfDJ8Etya4tS5j5DiLTWt2Gh6S_0SY7Shff7x3C-zhStPviP80hTMRjXNVXCumUQnwoKrJ48OLZhHuU7wgSxqXaAT3hk35KvO_KOhz5pV_sWLPOogHC-hpQTIzSEbXzyfEIkliqVgW3AfpLbuDTZY4Hj8hu-OM0waYEjCQkIv-PrftxX7JU4KCT1rxZBUrDJN_mKCQEGWy0LGLVsLV8dKyLMSvJsIz3HJh4sngzist-XVaPxat2eMPqVOJEWkbUf6VqwJOnssR-ZOS9b63YZPhihUcz6J0T5Y2aWIyZfZwSkuh8DiL9_wzKSRTmplaY1tzeq_-FhbkgwtLX9VDbeesx_HGL_Pxj5SG5aprfZ7DN2FBr70m7olb-bEl8jOm0w7ot0QGwxHft53Nf9piLEyQp4hsReq-PNwCirzFNkQ5aM6Kwvwitkop_Ab8gpzfwiEw-uVyPN_gpkrt099MQrdtljc9gXHKuXr4321pgcbwO6Ua-amRcF_9uYSCVBdIhwmpaQAgMmI-0uI-5Ph7H23ZV2zR1epClkiR2t5RWOtXNgLqoupXyBjDWrse3al-CsdnkofmtY0bqr2ZdNd_EKFxqn7Gf5-dNuPJEboDUdwvjUpWYIzMlq6_3q9KP012SbimkqMgz3-3jDBw_xe43DvZd2CnWFTDQSuD0m7DTf2GVL0DlasQNYQgO1T7xN7hgScsXmzhJNUx7iz2ze5BMqWV3vw6P6ny4sj_QA4KAi0zxl7sPgPo2p-65MWlbZy646ZYlm-jDD9dfORdo9nmURg3ITYNVUREtVg4IcEzPVDBMnV-NEf3T3vHD1V49yVhovA9oAHj4uTye-bbLUIhoLPCZ5GfR8AEHE4IhL0JyjuaWilp1qNEXAhziwZUELenYAf74wEzMvSSobEWL5Hq-ApMdRePBjjeGrIobS6KuE7b3HVsYwJt9pWvmVCYZ-nQCDAOIFcgH5kifkHu6NEi23Jk7a5hmgq1kVJXr5xcli9B-bHu1mO1kl0gXsqJcGpfetcw8bEtwO8F_6kdkmW3RXLa3rvrnkigPJJtn4sm_3ee1dqFYarJlXHPugwuyzfEPXNiT1HCcDhQYlrYxfKSzmlhjthGn14W2ZYtb3YVCXUFReA8V20rs4ec7VTdjuKCPgA8bk3xKevr6aETF9I65hbI0pIFQ9_cJHkl9a3BZL-X5qSH2s3_rvPupVuP6mu-Y1pUEGp4p5XjZc0CqsLm-W6MsUKmBgeCiokmUGfs5P_Riv9ZuvlHyYcwj2qmgf4MDkmhThfisook1nrPomO1lByHMRHx8rwbVQQXHPKMI32WZxfpRQiuAERonMvLBd2P2UOutqe6t7qy_gbeM0WNEcKb08UowSxGUFnEH6Vk1Dx9Vzye2tw7ej-EsT39hudhe_59nd9IYvx1o547N1cI_ASDVn3ibVQU_BWLrSK-HIqGaA52F_hthPGpMjVBO8xtLXHiyxqI-gh9iLq0vpvMeFQjyLSmFjKQifMEVaATAF9h2TJTc0yqkIVN9y77LvkUDoFvi96zGSYDyIf6rtiF_E1GnAwu-6Le16bj9npI-FcNmh-DRIvA6LepbSXs27rVMjQdK6dOPDavu5Y9IM5bg0pndKek0orZzkbaFwxTxmM08AhKlyN6PPiIqcZ7i456FQDhqMTUEeBEShsOJy4573e0GA-J1sHvzVQYiKDlzvgYD-zh79OxnJXlq22BNrWsQ6pqXfXgB5UIvhUTrmcrUtv3uw6GcAyl76ySgfs3Hb9Mpk0aeUdI-xyMuxxJvz1w1NffcuXPsxf3VosZO8vkofjVSO8lGtzarScy-abFGD9UA-S7xGvz0rqRSAEnpxe4AZ5eBfs_VmTy21RYJqxPbrYWcjrRdQjxERhND70wiuLkF1pivUQ-bohP3w0EfV0fJoSoH9HthQ9_aY2ASJnv82BX_lPRdEgYVh1RYWziVGB_6WWkch8BLrUzXezJZcfQHGuEQYzVB17RQIhCqFo7GexmHkFB40punvvS1gUZOQLiqSu8UvJ27F5KNLpkgDy8q0pDWewRGmZ5J09aMlJE6e08u_gPrA9G52SWXvdkX8CRvPn-xOLsBfb1_84QBhB1PuSKeptNLjgMufTdfUkGrL_b3fTo4AgLz7VuKrAMNYjwCTLr4e6towu-JJ08Fr3c8igbWApP6yNiVbE1W1mX66jaRfyw3jiVAP2ytEH_0kLOE3BDFkepIopwGtkQ2ultqFHxr_-oSadSpP3g4dLt1GfQ7fjzYkYAkstXxgYgGGe7Q-mwQM1dR8RnE0jFvQnTKi-Oc_pj0h91HgRK_ASQrqrgOf9JN6McbVlE3VbEKvFfOKP8ukFa6i8n7tk1H0B8bX5iy4m_b3i3MbQmQ16gkZ2ECW29-bA4vWz6-R3LZ3kf2hHAJzv8U6cG71KLVgWSBxIyRJE-cSiBPxtM1hGT1qcJvpAVWvowkcO9Anng3lrfgnGaYh","DataProtected":true} \ No newline at end of file diff --git a/src/Services/Identity/Identity.API/keys/is-signing-key-22178AEDB80CD0A41DF6874FE93F794D.json b/src/Services/Identity/Identity.API/keys/is-signing-key-22178AEDB80CD0A41DF6874FE93F794D.json deleted file mode 100644 index 07609260d..000000000 --- a/src/Services/Identity/Identity.API/keys/is-signing-key-22178AEDB80CD0A41DF6874FE93F794D.json +++ /dev/null @@ -1 +0,0 @@ -{"Version":1,"Id":"22178AEDB80CD0A41DF6874FE93F794D","Created":"2022-11-29T07:52:44.7571677Z","Algorithm":"RS256","IsX509Certificate":false,"Data":"CfDJ8E4RSuU_s2BGnQ_I0J1Xz9YiYIkBDFNHHGo4A20gtVeWqoNIQNxtP1p0JacgjeZkGl9NlE2-7qD02Vs9NIZ_IfOHW71XkfBIuIp5JvnwMi-X42Qw1F6UTQKNlYNvk1Fh27a6tM-mQgxysayCdDLlJWoRJYKDPDkUO03rZVkWDD2r6QNcMNtYhjM7oxy2yiw479PIeIldPOk73cPqp_k4oMPTRWwS04dX8fpQNA_3d2PoV1sw8-Hbmspiv3PO-umUGU2OFcN243cP9aaGXDoR-RgEbCn225WuHAWTe3tf39zVDtbAWDnRTNEX_jCNBItSaFOdMerDKD28PXTnWXuoMKyZ1_8ETZk0CDMAMVktqOatYrx0JHisG8vJbHtzxIvQrZL1YqoAN_qraVLgTl99WIZv56rYSb3RbNSzqB7yNn1Y_YAobXVbqJCaqqVG6uEaQxQ4WRI78sit630anIlKP7vccOtJH_bspQlPisNVrpCWiGo0D0IzNsZXLNPkc9kUbJKGc3xgE5H-z9kbk3sOecVH_iQy4b6fJ0IrDGz9fIhu2UI0-_lUE6sQ0g-NAA9kW68vD6PVSytiag7tFVV0olRPhaiBkSRuNGKjqsPmlPtkpzVxuTxSj19YxoC200cFARZq68qjxZ7ugdHQGlqd6bKFjj6NWCfG3Sbub1HpTkPnEUIR6ic8EfUrbu18MlOh-7bnIJkIuz0Nr5zZ9tPgiJCdGPjNo47z4i-kPWiNhS9k1sJqg60dgCT3onC2Uft4F4dnQpIKb28Fli9qkTDOg9gObEr9W19tMJvEPAhWJSl6HSmIJ-TElrW7nNCdS-H7PIlGWIvP6f0CCzrlgtsfMh8TK0B-Vpv5ky9D67L03IA7VfrhHss5mEkoz2s5-yefn2Wo5uMTxy53O4GIS8j3lF0ufUIBjGqR5q6IyEQUyU79OA5A7A3gJx78Cb-OEK3GixhYwjXYOw1YcguMZo_rGsq-EnjPoVBuZfdwyEIZ847gVwDzFsh0FHZIi2vVxXZ3tNGjJI2TXxNx7nyXuBxERgCPI3C5OeK2Uy8e3ooZCqPICKS9xEnICZteEcSYkRFmvPX6O1pZMKWoiyzGe-bhuBiotTB3yGIVlkhMyqNni2hQHoR5b1CX4YaGBMT_fdtW4uhvYLhLnGR69aal2ffIhiFJMfB_ByI8sALzgsn5jW-zOAmtiEOaPs1O9FqPf1x3Wk2YuoyujgHjHi9SSUz1hAJRmsyCmcYsMdGjMd-wnk83dsdMMeNANTKJHlZP5-__XA8emO-sloHrCiHpALX-JB5RQ1BGVD-dPiTlM0MYeTLdt7y5HRKSAbsOCnnF1vzV8y8NkUgpKVLTPRsJaoNYqik4Wpoa2d2ez-gXrG9S-pAByXHyTHiVDVNyqUTDMI0s8Fm_6_QwJTkgGEV6dR6r89Rzq70FFjdKB5RygRLhRdF2Be8blyExHI3HQg8_S9fcZ3zCybjatlNuNCgNZTTelC1UzWSEql3HqeqiMWIi9Kr8GNl59OIGm2lm9KNoyvcFHlQVQ33lw4akd5Z7aYu_HcdpBhMcEr9CuN6yQPhbCDOVhsMkqzXGzpwC2ezFnALAkbj9P44vRU9p0FEKFDNn_pQimVTLQJoU5Taf1n70CxYcPgM9BU3JPL9VUb9rDS3bHA7XQoO6878k6PkLbJ6GcfIJitaRZL5TkAUJUywH-a5xADVo-1_k3ADJYhOTbwxsYU96Kuhw8FOIToBH8CtLnqJLoJ8iwVPjB9LSsHPhmR7Rsi-x7Oi5JeugLctOvBn1sq7x_hHQKPVHA5LvtQ6Y719bOgPKLybQSCebe0ordUIsPAZMq-OvLj1sPS8PvfvZBDkyUA04avHm5kgT6RJF7ARUI1vMNLijm-_dxxrzY2bj6FHT340iFDURFePLdSM-Ctu3X-gLXKqPzQ6MBBQS0pyC3GkuX7J_GhPOZ-yXvRJmvIEoDAVEvjUQc57Ud6nyS_C_ljLmIoHghJiTJxNOOjR5pucb9Vljxm_BGPZwMi6-bTbD454ESbZ1kyvOAG73PjnPoQSaEYyM3XLW3XgJ9R4dnYDk31zHpQebodqwcFsXzxV43yi7zPrJSMzaFnC3-uPQ7qH4xs9puX5RL4q4lSCUKAB82TMtCJ0xHwj4DYqsJQt9jUAz1IZbgbChq8d0EPe6y2yg38LZs50r6DD0f-VgF1fyup_1ORM1Ub6gRyWxIBZLyLFY6uLvzPhVQaBsDitK2ku-9ELv9frr0j-BPNNCBpNRQyJCbZwOcovJ3gn9w1TAJ4cXGxzJWRGVnJY0e_tJ5ZMwRrn4E6LwhKXK9N2lBU7-2RQxEU79sTRz12SV9v8Az51MlUHzjWZp8p2bttpkQKMeoIkIVu31t88Dn7MOZkwR5DQ8b1_tNV_3Nbqyc9OUUFTSrpfEJeU6VRrUilgvBq78lSov4q1tbKxp4OjhxdNv9NxfYCL11kTZVB_h","DataProtected":true} \ No newline at end of file diff --git a/src/Services/Identity/Identity.API/keys/is-signing-key-3139DF3FF07C8E3881CFA9743F89A787.json b/src/Services/Identity/Identity.API/keys/is-signing-key-3139DF3FF07C8E3881CFA9743F89A787.json deleted file mode 100644 index 30deeccf4..000000000 --- a/src/Services/Identity/Identity.API/keys/is-signing-key-3139DF3FF07C8E3881CFA9743F89A787.json +++ /dev/null @@ -1 +0,0 @@ -{"Version":1,"Id":"3139DF3FF07C8E3881CFA9743F89A787","Created":"2022-12-13T11:30:03.9474661Z","Algorithm":"RS256","IsX509Certificate":false,"Data":"CfDJ8LWRXnsATcxOsVa-h-Gywwx7S1URlnPkv5vJtTle9xG_ytf2YXKlRsyey8qFhmrfLZ9uixxUmHTLywyrhUV6-gdvwyirWsUU8qn3SNe4rlPgNYHESkjYwWHERmwrMQIjRell8Xnot5UU1tfIvdpX9AbruzjEuAtYg668fBiXv338XfZ-2DW2RlYxT2TsPAak5ZsGXuIojYCLC3S4uGRz8AhSoko_DSl2KXQqXsqJWTNqAmiEHkVtHeFzc_o2gJIbegzqi7l4F2jDxM0-gkkRZYk6AZlN25wYb90xYaM82bKbzEnqPhLEIkuM-3QTGnjLZIF9jFp1qftq6dDm0feovXXM3SQCsgQPvZ6rKHR_8f-Z072t8PiRxDTgVQKywQ5bCS3u3Mq89hOZf_o_IBNT4uO_hDBqv4eFhj_AAy1Kk2K_QJZhF94bPLsujkkoFjWlNXvm6-Layr9chiY7ZQGxb5QtJr03Y5CT7w6hO2LsdsYEyJLs4kWBdlILT5FjrB4LCVHJlVDGxPBNuGzZL75rSGDa38FCKsUhoBvu7T5XFTm37FaBYrgY7MASQrlHQjGPwyRrjGe-M2ZwTCrtd_MwAHJnJsLoYs6SLQLpQa4sII2qgjRr2UmfDlXP12E6wJrpWfSL6QV13CoCy4hEko4LAy4tG2Yz0HzsqFzPYL142UeJC5z-d9JNdJr9Ya8TqVc7biOJCdY47jeOF5wJpM_BWTzT584w5HRs_1LVNsmjm9l6w1v5I04uNxbpopfRS0B1J2NPS3bfpS2lGuQlyPsZJwNgkZNwxDwCQMa8cgwREnaKWXOeKNksWmS6-ve2M5DguPaKVYF30AyJ1ECqWLX-CLJScBym-ZwVM-2pdfKw3pucfXXUqsXK1lTZSWi7A8gFtnsUZFUC2lkltBT80xuw7f9ojIfoYZjGSwl1mwM5LN5IuwUyppToU7vct9GueMaBjNP5bTrWS1XwiU_oOJbjIx8gNdN-DWNG8-5VmdgXoaJDcd_ZRLaM2XpWcpB5R2MwodIe3HGdpieTDxdqh9Nd1TzQO3FivfxcW0K21CQC-xYaRsx8Ii3djek6k90C304VFRF_QLe4lTOIaAjxxDSFVKbn8tVOZyINRI3FRAXOOaVBoGR1Wsn7bXVGNGbM5eN6wCPOzE-g5_489Sq2MWgczq33_GHW8rGc840OXiqJVu7fL4LVIuG7hPzaVZD3Q-jCu3xG3rYmr2ophVP3HNhl7QDgtpHLYNAIdzZNXz7ROKJU7ws0uZq34plYnLhXEzNe8ntV1N3qCbv1lMk7RjfffZxRwE0OM0mbIC--SPqKG_Cm0cD2k04vS36N9mr1LCmDNiFQRcOqzqxgk8mJdl0Vna-IYycviWyUBs63y6n7bDU3RAifVTSVPUrrrAIMTT5uk4ZVLbO_tGKvKWaSsi7TMypJXd993tut8SPwCl8iNZS3qPwIUXx8IpStnAmJmqcWLZcldZa1bfOWqXW2s22xLNgexft7Xosp-gPNPsICPwtux_tXN-XbbgopGnWgrsyrXctm95OcfEUOVYna73ZA5cukdUbfftGVBitwe7DkG1Jb3MJLZbo2ykiqW71mLgDqvQ2KD_PHw410v-51jsXkUPNknyeSuHiRXomo2HqUf-y0xvx2S73v58yM39XadMJUMYrQlw9lnWBqCDcYoutAVakgWAXSPYELDX2BbmpZsa099h6HlKJptmSLqp2D3J7fHGGWZpdBr9hxVQ56TkMDUNCEd5W1Bc5ecT7b1R5u6IuM16A5aEGOa_phaGuqc9cUhD0UmRBDO6FE-LbfjCnzhjroAOYEujJloOcAYEAL1zx3wUHd_-0hVkmffPWC_Wu2uV8EyQQwlj8bVgCEz6R6bqxl8TN5993C2joikVDCcFYSi8RingP-ItGC5TVTxx0kWweImuBA9s6eoqUZ7TMLKOAQHTxjx5g8mBkLs94RVWhChIUif513Br0aJGxwjBvhN_NBWDFJSbP-l581YNCrmALfS4IX2jeV81bnOAAde53Yplaski3eoR2Z3daNdAJNVqOBe32gHf1eTwDCXrgqd5wYsXxW_YJ-P2kKN2CpuPE-so6tdoCLqFmXu4-3q3vGGE_nVvp-MnhHwLP50U6-h7_MDh105qlIxduM91AT7I3XPTQGrOeIv_eBrng3vULA_ohah-OzbPxpPmYSNFS8YUlGChhPgmMWHKnaYbirh-Df4rc6sK5OFEyRVlCzeKon8hFsmwIEEk7uAR2AysF1PJWjoObQkM-3vqJphkTBBYsZEmngjvQlV8TnGY6P0GRe5gNOaT0BZ71SIlKQY1iLq5NmzEGM1iIOEJI-JA3VHhXs2mw7WDKpsE_k5kbFDlgdachB778jMTSs8xWjESxyidPz-tjqvWaDg482VjoOVYBQOGyUuFRMKVJ9xZBE03nVLG29cKVCNJ_KylBUy0O4LkHskJRzrbZE_HlcoCafl1z1","DataProtected":true} \ No newline at end of file diff --git a/src/Services/Identity/Identity.API/keys/is-signing-key-870FA7120249C21C30ADE458B07918C1.json b/src/Services/Identity/Identity.API/keys/is-signing-key-870FA7120249C21C30ADE458B07918C1.json deleted file mode 100644 index acb1883a8..000000000 --- a/src/Services/Identity/Identity.API/keys/is-signing-key-870FA7120249C21C30ADE458B07918C1.json +++ /dev/null @@ -1 +0,0 @@ -{"Version":1,"Id":"870FA7120249C21C30ADE458B07918C1","Created":"2022-11-30T09:59:58.1299062Z","Algorithm":"RS256","IsX509Certificate":false,"Data":"CfDJ8BCNHSqqa79Fqw5EoSNNrOMZDqq5p81RZsuqUc9iuvF_3nm9RHjc2lAsu-T8AjFPxhbWkSNnQAU7JGWpNh_TU1XK9-Skieb68wO2lUFauCBnoNf7R7JEpuw7zdjkInQZFOF1hBzhL0qKszqhM8-2gz2Q2V5c8Ng0C_2CzHNqCsyhTHBD8NgXfzpxdym7V8HZSS4SkJ3QpKLH-VMXRFssCM7PXEimNWBN2yky4IW5_fRgYgRkkCaXCU43ayGxLyBe_J6DzZ1fefO7ZBne2b8HaVVQaAEQDTlsFUxNqDLcAO-k6q3FoL9ZW2gm82a8ra1mSJTbEeAacNK5oE22urnovVF1GPwTVnnXMi_9eloBqyTM5xtTQPYbVlOkZl5pgRjKOY_Mc62Ix9p9hoH-gCfDHw2Q9X34JT1ymzBdYqtgTmWoY548-ZkX6v3AEpkhmsMdKMyNSdz-SJfasTqKkp4JkqGR-gXW17HOtxHmaOPg0ZRuQ4Dx_YHuQr98UQPMUktYL_kF_76FevNyfy5eyN6eawHNGwhXzn0YdyCjaRV1LXfD-4LqqJBhExUSyCtG0Pq0qjZ0ySAuKi72-0532XNRJ1gh7CxlfRdeLDID4ffs1cgmfODFv1k1JElYihqqGwXMwx-SfgpM9eo4j6jqd0kdAgj3n4ZsJKQMCDOGv84Gfhnw7dxlIL0e-D0sKKc6f7KagNFJCbt0LZ492IWzIPIGp5lXQwhrDPECjdNvBv0jhC6yMzZQZlVQXX6MYue_qzXb45TK23j8HjlgYPCip9eqH1NBA1MWkHykA6ZkdZ29eCCMuO-m8zB_Z_7YdEdzGcViK25T2q8qo_0BMzAzdrEJ3rOYOly7wzsoESn6aKr2U1b4qh-fljOwQrYqoSzuiu5l4QY1qVG4ZR3VMjV2lo3LEbMayA6Sis38LQy_ulUKGdOi4KeyNSlbL44wN48gDM86kNPkTM2kVoJc6RRZ5zptnGyXgAsuknHaF5EX48Ihxt2AFU_pVgKGnrx4XkYkxMEwbInoL19WgaKZyLAXjwtUG3FSOPdWswUqbcDNoetfY21Y9yWZsZ0rUTUa3x9rLzRP-H9NGbK_Yf8j75lpdx2sFUvJyyxZ2KEoq74bS-Zg203Q3jhz_RVJi8M3R0oRQHh2I-wUimdAHQ9JQu-M-VAtVLG6DVrY4vyhdv2JxIPyLrRTJPVhMDEqKqUcbm0VJE8MJOb3C6hdFrrzcM8AAkxGhYHh2vlJu0MAa8y7U0lHm8mcrNqsjPahAFvVMwUPkxaXFSYwJDdnBfODquWHt6reE9GwQw-ZFvigPGmY3SWMZiEBK-2Zkz9NglOKEgnojT6xcAbdaeEDadvY-Qriej8rMBZ3F-2IHYNMM4J2MkbexgloQgS6UWx7Nx1ln-pI-uHCDUmwsb5bl05Jma4_DXMsIjzinc2u-CvpEUXe1KmDddh7NYSrUv5RjaZfxgzjYCW3gSynFRGNfy57PaX7R7VV9pn3IRMKsbdWKlA957M2tDqmgkzC2M8KZAJRFmw_tCVk-swjPjyFmXUgsdLs0oX8OSAh4JX8DWvK42wHerh4gbjX_N7mYWh38e4-jMvyZ5Zdqf-2phj21z9uZla1mCsncjDDPJy7sVCrlJasgPLgtCD5j0lxp3wdAjvx2I4q6CKNcP8-MapHABe2TIgMmEf2VOJv42yrO99q49OwkopbyhMf-0-drAOo7Tw7eKHH7S174LfEKewCMmj2BVaM_I-rTgU28Be8pfbl6jTmj-9WCvuBbBiCtvhpeOApuMbJkc43As4QV031W9DEQpB520DWUdAHjvNkUMo0QDBLm7Zx4xzeO3Ei35Xw8_w9OjZBCZw3kalIbZAL9MlsyfFXczbZXMZnzkccPTwTK2SgS5lq1Ic07YB_uqY52CwYlpjbRP3ygM2mVCLTB921NhXKh9-Md4oJ9ieaDUNyNPch2MLQluKmyIH0sumgBkyn1k17IM4qN3EXRSsUiqa-FBU-PFa1gVIf_dhdnLI_GOPGEYBmZYTrk8J8HK2-wIi5shGDOB-WjBaAWbymdMmPhifRKiDKdOmPVArGptSyrM_5UvHF189Jl0ABxEWcsW6DScgw72GtcXxhDQligdcjanZHNVGEnfwFN604v68G42IC7clOVAno7cgaapHXXYSadEqVzP_Q4d-d-obG0v44yMu3WSdfhmJ8GC-8jS3b16q5_vTfyim5VFmLdG0PX1L9--QYop1Rns-64a5Dz8T8MmyrtgRXBAMfXC84R7N8I7SgRbsSo2pgMzRafCOpYWqfUlNcPjqQXSPj8oEt0iz0DBq9ui1dK0JiiOGOO9uOdswQP2r_cVlF-QvTszcyy1hn6QHCdsfqojSi70jmyhpBa5Vgba7nyP_qbJCtYiZwk7RLWT-jZ47BwZzEK73UXoAYCc8NT5HsIW8KFuManq8Mau7BLNj6WhXJOKmbP0oD88LMj3TeEvZ3","DataProtected":true} \ No newline at end of file diff --git a/src/Services/Identity/Identity.API/keys/is-signing-key-B0B34AEB91E2638F61EB9A5543F3940F.json b/src/Services/Identity/Identity.API/keys/is-signing-key-B0B34AEB91E2638F61EB9A5543F3940F.json deleted file mode 100644 index ddcb78b6d..000000000 --- a/src/Services/Identity/Identity.API/keys/is-signing-key-B0B34AEB91E2638F61EB9A5543F3940F.json +++ /dev/null @@ -1 +0,0 @@ -{"Version":1,"Id":"B0B34AEB91E2638F61EB9A5543F3940F","Created":"2022-11-30T11:21:15.586844Z","Algorithm":"RS256","IsX509Certificate":false,"Data":"CfDJ8Fzd_R2KZDdMrJulCrd4GFTnFtf9LeKAfSemG0-9e385u01WZOrLNU5PPCNSRvcQKMERaUvLDcAsYIsqdKPJ14QGDgSTlxggwrR50kCv3494z5uCvWOvWqYc3KKzhR-7e-mXViY4m2oYHpGaVCITKXYwCRYxO-P0mSdr6D7W-846cfdst47_rjIxxeMajL1suYSYe_sz_nz8ooKW8ZH_kl5M9cI0waB2XFviIP3f08pz_eyneKqy7tCc3ruSNiUzfUBAF7fBHDcyPrE2h4AKaXG1PT-I6JOFVj9lAgv_1ACSqTVEjJiRWfFIfft3sQ-chSv1yxy7b8GvhIsKKEn-OqXCnYr5pFW7VPagt7pf9IQdivU7I4m4zSyW0bjIWXdCL3sXQAChiDpvRCFqFfsiH4lWmI4X8Aq8Tz1_LkbicHW5-ZxeZpvgPlg6t77xqFIxFtixqdc1XxifVwJR5GwrFcbcI9VpnlBomkBSUFMslW9NxGwSztgnYatkQuiXTzdqFoOr5d4YGPEHe_Oc3h9yDyUxgBdJK30sSx1Dwki94CeQNBS7PisGbu5q60MbsyFQ2S6kBogReQdURLW326NkgOBJ27jHk3ccx24WfFuuDzquE7xetxvnX4AV0oKOudMClsOv4Wr1aMm98p4VimUQkAneFImQszK1-zSQfxeElamoYy-4h1P2V_A5siSmfKpDs1q2ja3C62lBr0YSx822O-QF4XI0id6GOZiCc_9v52B_teTlgMq6L54EjqDM-h6ERkPvoqNFL0fWz3ktOBPCQm56YrSyyaXNKG2TwL4AMLsaQ9us5SXnJ7UpiY_7ls4SVm_h3btoQcokOiO247mYo4-BRq4pCsFHNBsCReiKlJH8G8fwrujWcu_U7NdVWgmUgmcsIh9mfommuOdBdVQdP8CYZM8od1NBIIifIoj51WuZXtb9Wr4QVIddEjAQrYnexJAozF9TeBVfjhDkIIA2-b8yBGqNl5VrF4bo3b3LLm1rbq5vzfKN6pKzs2sDGple6kZn_t0Ym5fmf8iWXLzMnRyasEDuXX0-Vg9WxiWyXzHsUY-SZEfEXs_WfuzBZb9NP1JvrB_w33cUfgl9Sa6RD56O5F1YAR3WxiCiWGnlSnqpaiiyTb4NVr8N0qQl9xOz9KCSaN8H2WKgCML2DdjW5_O8Zea2EPpSf1NGB1G-Nm-9HWAn8xDAei5x8kzTIxka6Jb8GO6Rdffk7wwuYMoB4ZYuiuL1q-rqvaU5GffQWMjGz-yH-WCivVFCosvJgk9340K0bDl97CULs43LF3nQFcmuLQoW-fasNYk5ZAXYA8bjn9eYm-hWbsfA402c3iZKKZVcLAU-jPAr44Z1P9PbT-xwooGTKKnZuR55l24T3p4hDatpazlObRd27kPtSLgbXPkNKbru9N8--JUhoEeFGC8E01gCn9256wlpIO1hk9a-P87t7zJWdYkl9Uo8Poz_Hfm9Uaml55BWSghfXlB99hULUmpnPwyOVJnRhGOrnr6ys_2l6bCW-gZlWS7oevQ_BuJBcCXVuRYQPbVtH9ZZSKF-S-uczbtfzhJfH29tCNsHzAukVHFiIwHqzhLHNu1gX5COGzYdN57p7DXGkJXGJUipczm2ZAfI9g-Kgvy6MaXScuwaobPobL5AH5WG1CclEb8kg_08rnQsDfvNhmsAJE7dN1GjpA46fP2bJ09T4hfNdmW-IZbeQaDMGc_8RpoADdUY81swXUgrL56UxoCFxqifXtskbzxF5Z1ad4qRYNlqU_zMbxjSZTsSizNja4pmsx1O2NAhvN31bSoA8PWpLLz37Lq-craDpXW6-mIySm3NQWxTLx2hsk4i29-dD6AjUX2aDLEng4JLKLWKLcH_ulkujNP0oXdkXcGikLqFwUKG8_lEWV_ROlXUVlmwNf9WaohIX8caCK2CF_tyEkCxEjZIBzw5xazq7_zNbI66rXfqBHxDKqrdM3UJYBNFMk2LLyEGD4TetGu4RzBDt2r4rXatSXQh9a662LYlCXxlElP8xfH7BudBa9KgV0FQOdHQ4sm9chHiT9JPQX6bHwf_imYHmTyMV3cIN7f7bACLji-5hFf7if8ANbhY7zer9-rQWR9Wy-vYUyUaSWCWRXHQC2eXL0XklBNnv3vK1nFOcaeC5R0GGULfMnBluyClu2Z67OCsAzQqi-_aacxQVN91SNmAfUbVCrPgBTbQY_1u64fEMc8ZcL52xwT0qgCSvBPCNDEJ8YDVVd8L8eLX0hg7rV8SgCnAl5qG74BCdkmhCMLB-OiwGZxZ9s94yGdjX9jA4D70uOgn5t9OhpboX3OoRK40Xged6zCBEhUd9MilD9o-BtEPeAHloKqMrvrVDE4l9R739pjhgOfvXqGIytXD-bKlMZAY7dnJ4vu4GjVvhHfzxTV3zu_nAV8j3n41_knCe2RyCm9j74YZejnRC15ADqItTDmTre8_iS6hTOrVO9FP","DataProtected":true} \ No newline at end of file diff --git a/src/Services/Identity/Identity.API/keys/is-signing-key-CFE19FEED1112F0740C7CEAAE490834F.json b/src/Services/Identity/Identity.API/keys/is-signing-key-CFE19FEED1112F0740C7CEAAE490834F.json deleted file mode 100644 index ca414c2b2..000000000 --- a/src/Services/Identity/Identity.API/keys/is-signing-key-CFE19FEED1112F0740C7CEAAE490834F.json +++ /dev/null @@ -1 +0,0 @@ -{"Version":1,"Id":"CFE19FEED1112F0740C7CEAAE490834F","Created":"2022-11-29T07:38:58.7490696Z","Algorithm":"RS256","IsX509Certificate":false,"Data":"CfDJ8PyEV1YRvftHv5uH-VZQ5M7m2ypM-2X7o3A9EvjXNQQsFD50DwqX3UR8e4cDEITQrBowxyPPRXo_bTgEnifJjx1kdzA3q0L-FPJqCOjh6AaRqUg_TlnhvbEgG1HYoBZTAwvhi6g3h86RFPU4juwhOWHcD1vzCgW1vfJ9VFXXq3F-FSfbpdykS5bLn5hUdg3zgNWh7zZXOIFxgNkelR7lGMfF6hquTQMbCRhtDg0-N8O8m7M0JaNsB6_H6v-Z2RlYzH0R0B0Ka2fH3uPnudPrd1RIP4BONzMorJpDFZP9TF0DY9sJhkcHEhKDZlRlwI_Z-e0z8WeW183Gg_HSV23wO4B5R8ldXRSioqWyUuQfoYplUanuNeccblBe7hxQw9fhsanHGgbiuBjuypXarZmlVlbFO2zPKl46Vj8YZTxopOFOi4ALcNlUzGgPG5lwPjDfXEyAp7_ipMIW84UVfwqnPZFE1FASpFx1BPif-huoAaXw2GF4HJ2QVqfxkr_Gn8isrzBOT3fqmeZ1n0HNOc8VxCSdScbBSKFMnxNSgPQSexHGSKnXpvXF0OL6R8oqHoi8TNfYFitGE_qED6wCjQ77qMXOUVXB18kW7nJYqph2u1BH1PykRWaWDlnh3H7fKWRhO0ejaTJWl7oSLllYzi99yL5JvudDCjI0QdfbMz7o3SrdrZbIKQcbTPPgl_cfNneP4QA6MSlJFbG3bc3q8IUPhISrZHO_s7SsoX0BiP-AHcA7M_WrkAQYLkTMsBuO3x6N-bWjtTouqzHY7-h5ZYHqvk7Mg-jlgJjFjgKRDOJFiDorbf-5nvxjl3eLV8rjX7ML9KqjD-ZUjMsDt79lpjCi6B2EFqbiGT35I67hC6a7l8gPjwLKB7Oc8h4YggwyS1eLCq3CgmfMqlIAeAqLL7nVwDPReW-pirHix92q2tSkKCuz5UV5jphmDAnRFQmICaIinoSsBtjb1RlonM-yklDO-jdR5r0ZEFb8ZCssSojhfqEi5mcK3xJsyzM_Inzg71zAHCUl5cuBhbWekBeHiqb2p5ar9guCK_h7zmga1ZZTqfWAGzxHrHkHb6XiK_wLlwBjJEoGhgHfi0UzUECddK2DVwEuTsXhNDJ8CgB2oWNhIHgnlNxL_JA6_bY8BnGtcOKnEuaKpR6rXEZit2Jcr-1-Q8YJ29tVNubphYm2ZMrDTGdAVE8ODftey6BIN_HmBELf6a7x-Cd5DPrW46iVqlOuBqmjxjZ4HHTS08HHGSD4_xj2vNaWl8rIbE4BbDq9V_qyP548KLNbGqSIed38DDcbsRMIuac8po95Z3q6NUf2JR0mCOEizdrszZOW9sGVlO-WReaTkpNN8MaKYoUy6k84IxwPPv-Tov0yMdTN-jp7H2HaTOGDvEb72swcW39huoAbXwjZdrpFQjTD9_cnNrVdclDGN_yix_i8-vQDQlQ9Ronpk2NvAdnrmEzQ6w7D7PqAe5c4YJfn_0z45ERm9zBwCMCbw8lP_Yi3nwTbqGtFqAoXTSZ8vR5_UxQLqxsJy6U6gK4Es68-hnD-YR5p3CzBXxSEgV7_qvW2gly5VCB-1yoD8dTVInogMhOzDZD71gmpJURgKXX9WN92yq-YB24E8koOXdbxTvSblIVTxwDqQ7lb81y68HmZVSRLk3zhxbkEkjI1kkB8uzlArbXljN7LnxyXHU81DDeufVK5_myoIMA5NpSwEKxAkmCoF7p642qBwo90k0q0AvJVmoy8xpCRiJyLDR8wYHFsed3T99jvvvV7GyA4SG5Tt-ST5kKFKvOOwT_WrOg-ao5cz6Br8_YL2xW5dB231R4ZxfJlmrJY9WcuTQMZrWnYOOSj_5u2I4sgcnp7nrRF1l2xnieiym5ef23a-rSMBZi_leN6BAma6N1M7tu1N8cEw7wd_6FV6hqrcKFPGNm4HE5M-pmoWvzjBTo25rh_4atG5uEmDgmhmY6qiZc1eso__Fz29uJ4792kkpdGyPAcV8igzPMdKts1KiO9ThrDRH25Knwxa1tOWwezkeId-OuZRwC4LhGuZseww5TxzQtyN8mMWbLDPCmWya56F-i0jag4i-r2Z26VEmhpSywbACetljEsaVDJF2ZdIrIFJqjYLa9zhcKbD9GZPHZt0HKilXDp8DomCQHHWsIapwCiG6WLGOhVc0-0VJ28dBqIowyCQScefePKIIk7Oa0T4UzPXcXiXYNQktHGs9VrF2ux4De-SbxDRdJy1IRSH8_NQ4SFtUelO8IG27B_8Ywbonn9yRsoojmuS-fXPuWSJMHDjPcSYwJqQyxjfPjGCLsnQWRZCNT5Ft6cfcSDRZWoCqKK2qLfqcGs-FR71HM0G6ipAuVI_2IyfalS-fXqTPCncyFsOqp4BRhhxLFu8UxTZ5-HQyKH3fX75mZCD21d9RObyWv8g2T0HtEBLEf2eR8I8zCUcOf98asCoT2CU4AtOhVwqrE2u1qNKupc5Nvw","DataProtected":true} \ No newline at end of file From d91da036658aaefdff1775114bf6c56e7bc6c476 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Fri, 28 Apr 2023 12:00:30 -0700 Subject: [PATCH 002/118] Fix IncludeScopes setting in appsettings.json for WebSPA --- src/Web/WebSPA/appsettings.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Web/WebSPA/appsettings.json b/src/Web/WebSPA/appsettings.json index c40149026..f02404452 100644 --- a/src/Web/WebSPA/appsettings.json +++ b/src/Web/WebSPA/appsettings.json @@ -10,7 +10,9 @@ "IsClusterEnv": "False", "ActivateCampaignDetailFunction": false, "Logging": { - "IncludeScopes": false, + "Console": { + "IncludeScopes": false + }, "LogLevel": { "Default": "Debug", "System": "Information", From 109853983d9dbf504e143d164cbbea02cd79463f Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Fri, 28 Apr 2023 12:23:22 -0700 Subject: [PATCH 003/118] Remove gRPC generated code from global usings etc --- .../aggregator/GlobalUsings.cs | 3 +- .../aggregator/Services/OrderingService.cs | 10 +- .../Mobile.Bff.Shopping/aggregator/Startup.cs | 2 +- .../aggregator/GlobalUsings.cs | 3 +- .../Web.Bff.Shopping/aggregator/Program.cs | 5 +- .../aggregator/Services/OrderingService.cs | 10 +- .../Catalog/Catalog.API/Catalog.API.csproj | 8 +- ...ionBehaviour.cs => TransactionBehavior.cs} | 8 +- .../Commands/CreateOrderCommand.cs | 17 +-- .../Commands/CreateOrderDraftCommand.cs | 1 - .../CreateOrderDraftCommandHandler.cs | 18 ++- .../Commands/IdentifiedCommandHandler.cs | 10 +- ...StockConfirmedOrderStatusCommandHandler.cs | 4 +- ...tStockRejectedOrderStatusCommandHandler.cs | 4 +- .../OrderCancelledDomainEventHandler.cs | 2 +- .../OrderShippedDomainEventHandler.cs | 2 +- ...dToAwaitingValidationDomainEventHandler.cs | 2 +- ...erStatusChangedToPaidDomainEventHandler.cs | 10 +- ...angedToStockConfirmedDomainEventHandler.cs | 2 +- ...tomerWhenOrderStartedDomainEventHandler.cs | 2 +- ...PaymentMethodVerifiedDomainEventHandler.cs | 2 +- ...egateWhenOrderStartedDomainEventHandler.cs | 6 +- ...erStockConfirmedIntegrationEventHandler.cs | 2 +- .../Extensions/BasketItemExtensions.cs | 3 +- .../Ordering/Ordering.API/GlobalUsings.cs | 7 +- .../Ordering.API/Grpc/OrderingService.cs | 8 +- .../AutofacModules/ApplicationModule.cs | 18 --- .../AutofacModules/MediatorModule.cs | 20 --- ...grationEventLogContextDesignTimeFactory.cs | 2 +- .../Ordering/Ordering.API/Ordering.API.csproj | 3 +- src/Services/Ordering/Ordering.API/Program.cs | 128 +++++++++++++----- .../Ordering.FunctionalTests.csproj | 10 -- .../Ordering/Ordering.SignalrHub/Program.cs | 3 +- .../IdentifiedCommandHandlerTest.cs | 4 +- .../Application/OrdersWebApiTest.cs | 8 +- .../Application.FunctionalTests.csproj | 6 - src/eShopOnContainers-ServicesAndWebApps.sln | 1 + 37 files changed, 175 insertions(+), 179 deletions(-) rename src/Services/Ordering/Ordering.API/Application/Behaviors/{TransactionBehaviour.cs => TransactionBehavior.cs} (87%) rename src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/{OrderCancelled => }/OrderCancelledDomainEventHandler.cs (97%) rename src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/{OrderShipped => }/OrderShippedDomainEventHandler.cs (97%) rename src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/{OrderGracePeriodConfirmed => }/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs (97%) rename src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/{OrderPaid => }/OrderStatusChangedToPaidDomainEventHandler.cs (90%) rename src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/{OrderStockConfirmed => }/OrderStatusChangedToStockConfirmedDomainEventHandler.cs (97%) rename src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/{OrderStartedEvent => }/SendEmailToCustomerWhenOrderStartedDomainEventHandler.cs (88%) rename src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/{BuyerAndPaymentMethodVerified => }/UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler.cs (96%) rename src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/{OrderStartedEvent => }/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs (92%) diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/GlobalUsings.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/GlobalUsings.cs index 37ac7ade9..2fbd09b57 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/GlobalUsings.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/GlobalUsings.cs @@ -2,7 +2,6 @@ global using Grpc.Core.Interceptors; global using Grpc.Core; global using GrpcBasket; -global using GrpcOrdering; global using HealthChecks.UI.Client; global using Microsoft.AspNetCore.Authentication.JwtBearer; global using Microsoft.AspNetCore.Authentication; @@ -38,4 +37,4 @@ global using System.Text.Json; global using System.Threading.Tasks; global using System.Threading; global using System; -global using Microsoft.IdentityModel.Tokens; \ No newline at end of file +global using Microsoft.IdentityModel.Tokens; diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderingService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderingService.cs index 2a7de50a7..6d46a706f 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderingService.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/OrderingService.cs @@ -2,10 +2,10 @@ public class OrderingService : IOrderingService { - private readonly OrderingGrpc.OrderingGrpcClient _orderingGrpcClient; + private readonly GrpcOrdering.OrderingGrpc.OrderingGrpcClient _orderingGrpcClient; private readonly ILogger _logger; - public OrderingService(OrderingGrpc.OrderingGrpcClient orderingGrpcClient, ILogger logger) + public OrderingService(GrpcOrdering.OrderingGrpc.OrderingGrpcClient orderingGrpcClient, ILogger logger) { _orderingGrpcClient = orderingGrpcClient; _logger = logger; @@ -48,14 +48,14 @@ public class OrderingService : IOrderingService return data; } - private CreateOrderDraftCommand MapToOrderDraftCommand(BasketData basketData) + private GrpcOrdering.CreateOrderDraftCommand MapToOrderDraftCommand(BasketData basketData) { - var command = new CreateOrderDraftCommand + var command = new GrpcOrdering.CreateOrderDraftCommand { BuyerId = basketData.BuyerId, }; - basketData.Items.ForEach(i => command.Items.Add(new BasketItem + basketData.Items.ForEach(i => command.Items.Add(new GrpcOrdering.BasketItem { Id = i.Id, OldUnitPrice = (double)i.OldUnitPrice, diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs index a7b5335c5..55b25cd62 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs @@ -198,7 +198,7 @@ public static class ServiceCollectionExtensions services.AddScoped(); - services.AddGrpcClient((services, options) => + services.AddGrpcClient((services, options) => { var orderingApi = services.GetRequiredService>().Value.GrpcOrdering; options.Address = new Uri(orderingApi); diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/GlobalUsings.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/GlobalUsings.cs index 75525a2a5..9aff586f4 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/GlobalUsings.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/GlobalUsings.cs @@ -2,7 +2,6 @@ global using Grpc.Core.Interceptors; global using Grpc.Core; global using GrpcBasket; -global using GrpcOrdering; global using HealthChecks.UI.Client; global using Microsoft.AspNetCore.Authentication; global using Microsoft.AspNetCore.Authorization; @@ -38,4 +37,4 @@ global using System.Threading.Tasks; global using System.Threading; global using System; global using Microsoft.IdentityModel.Tokens; -global using Serilog.Context; \ No newline at end of file +global using Serilog.Context; diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs index b589ec3cc..dc792b866 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs @@ -1,5 +1,4 @@ -var appName = "Web.Shopping.HttpAggregator"; -var builder = WebApplication.CreateBuilder(args); +var builder = WebApplication.CreateBuilder(args); builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration)); builder.Services.AddHealthChecks() @@ -197,7 +196,7 @@ public static class ServiceCollectionExtensions services.AddScoped(); - services.AddGrpcClient((services, options) => + services.AddGrpcClient((services, options) => { var orderingApi = services.GetRequiredService>().Value.GrpcOrdering; options.Address = new Uri(orderingApi); diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderingService.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderingService.cs index afa86b31b..c9398179f 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderingService.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Services/OrderingService.cs @@ -2,10 +2,10 @@ public class OrderingService : IOrderingService { - private readonly OrderingGrpc.OrderingGrpcClient _orderingGrpcClient; + private readonly GrpcOrdering.OrderingGrpc.OrderingGrpcClient _orderingGrpcClient; private readonly ILogger _logger; - public OrderingService(OrderingGrpc.OrderingGrpcClient orderingGrpcClient, ILogger logger) + public OrderingService(GrpcOrdering.OrderingGrpc.OrderingGrpcClient orderingGrpcClient, ILogger logger) { _orderingGrpcClient = orderingGrpcClient; _logger = logger; @@ -48,14 +48,14 @@ public class OrderingService : IOrderingService return data; } - private CreateOrderDraftCommand MapToOrderDraftCommand(BasketData basketData) + private GrpcOrdering.CreateOrderDraftCommand MapToOrderDraftCommand(BasketData basketData) { - var command = new CreateOrderDraftCommand + var command = new GrpcOrdering.CreateOrderDraftCommand { BuyerId = basketData.BuyerId, }; - basketData.Items.ForEach(i => command.Items.Add(new BasketItem + basketData.Items.ForEach(i => command.Items.Add(new GrpcOrdering.BasketItem { Id = i.Id, OldUnitPrice = (double)i.OldUnitPrice, diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index 60d6addfd..7d778716b 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -14,7 +14,7 @@ - Always + PreserveNewest PreserveNewest @@ -25,10 +25,8 @@ PreserveNewest - - - - + + PreserveNewest diff --git a/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehaviour.cs b/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehavior.cs similarity index 87% rename from src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehaviour.cs rename to src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehavior.cs index e9deb1cf7..6974c3cf9 100644 --- a/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehaviour.cs +++ b/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehavior.cs @@ -2,15 +2,15 @@ using Microsoft.Extensions.Logging; -public class TransactionBehaviour : IPipelineBehavior where TRequest : IRequest +public class TransactionBehavior : IPipelineBehavior where TRequest : IRequest { - private readonly ILogger> _logger; + private readonly ILogger> _logger; private readonly OrderingContext _dbContext; private readonly IOrderingIntegrationEventService _orderingIntegrationEventService; - public TransactionBehaviour(OrderingContext dbContext, + public TransactionBehavior(OrderingContext dbContext, IOrderingIntegrationEventService orderingIntegrationEventService, - ILogger> logger) + ILogger> logger) { _dbContext = dbContext ?? throw new ArgumentException(nameof(OrderingContext)); _orderingIntegrationEventService = orderingIntegrationEventService ?? throw new ArgumentException(nameof(orderingIntegrationEventService)); diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs index fb16306ee..6ff6bc40f 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommand.cs @@ -10,6 +10,7 @@ // https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/how-to-implement-a-lightweight-class-with-auto-implemented-properties using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models; +using Microsoft.eShopOnContainers.Services.Ordering.API.Extensions; [DataContract] public class CreateOrderCommand @@ -80,21 +81,5 @@ public class CreateOrderCommand CardSecurityNumber = cardSecurityNumber; CardTypeId = cardTypeId; } - - - public record OrderItemDTO - { - public int ProductId { get; init; } - - public string ProductName { get; init; } - - public decimal UnitPrice { get; init; } - - public decimal Discount { get; init; } - - public int Units { get; init; } - - public string PictureUrl { get; init; } - } } diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommand.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommand.cs index 4866212d9..caa6fb285 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommand.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommand.cs @@ -3,7 +3,6 @@ using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models; public class CreateOrderDraftCommand : IRequest { - public string BuyerId { get; private set; } public IEnumerable Items { get; private set; } diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommandHandler.cs index be3860d5c..aaf982c29 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderDraftCommandHandler.cs @@ -1,6 +1,6 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; -using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand; +using Microsoft.eShopOnContainers.Services.Ordering.API.Extensions; using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; // Regular CommandHandler @@ -42,5 +42,19 @@ public record OrderDraftDTO Total = order.GetTotal() }; } +} + +public record OrderItemDTO +{ + public int ProductId { get; init; } + + public string ProductName { get; init; } -} \ No newline at end of file + public decimal UnitPrice { get; init; } + + public decimal Discount { get; init; } + + public int Units { get; init; } + + public string PictureUrl { get; init; } +} diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs index 38c8a356d..43f6c8dcc 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs @@ -6,7 +6,7 @@ /// /// Type of the command handler that performs the operation if request is not duplicated /// Return value of the inner command handler -public class IdentifiedCommandHandler : IRequestHandler, R> +public abstract class IdentifiedCommandHandler : IRequestHandler, R> where T : IRequest { private readonly IMediator _mediator; @@ -18,19 +18,17 @@ public class IdentifiedCommandHandler : IRequestHandler> logger) { + ArgumentNullException.ThrowIfNull(logger); _mediator = mediator; _requestManager = requestManager; - _logger = logger ?? throw new System.ArgumentNullException(nameof(logger)); + _logger = logger; } /// /// Creates the result value to return if a previous request was found /// /// - protected virtual R CreateResultForDuplicateRequest() - { - return default(R); - } + protected abstract R CreateResultForDuplicateRequest(); /// /// This method handles the command. It just ensures that no other request exists with the same ID, and if this is the case diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs index df87db63c..371e1540d 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs @@ -34,9 +34,9 @@ public class SetStockConfirmedOrderStatusCommandHandler : IRequestHandler +public class SetStockConfirmedOrderStatusIdentifiedCommandHandler : IdentifiedCommandHandler { - public SetStockConfirmedOrderStatusIdenfifiedCommandHandler( + public SetStockConfirmedOrderStatusIdentifiedCommandHandler( IMediator mediator, IRequestManager requestManager, ILogger> logger) diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/SetStockRejectedOrderStatusCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/SetStockRejectedOrderStatusCommandHandler.cs index fcef729e6..59247db0d 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/SetStockRejectedOrderStatusCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/SetStockRejectedOrderStatusCommandHandler.cs @@ -35,9 +35,9 @@ public class SetStockRejectedOrderStatusCommandHandler : IRequestHandler +public class SetStockRejectedOrderStatusIdentifiedCommandHandler : IdentifiedCommandHandler { - public SetStockRejectedOrderStatusIdenfifiedCommandHandler( + public SetStockRejectedOrderStatusIdentifiedCommandHandler( IMediator mediator, IRequestManager requestManager, ILogger> logger) diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelled/OrderCancelledDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelledDomainEventHandler.cs similarity index 97% rename from src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelled/OrderCancelledDomainEventHandler.cs rename to src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelledDomainEventHandler.cs index dd954c2ff..e53a233d9 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelled/OrderCancelledDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelledDomainEventHandler.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderCancelled; +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; public class OrderCancelledDomainEventHandler : INotificationHandler diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderShipped/OrderShippedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderShippedDomainEventHandler.cs similarity index 97% rename from src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderShipped/OrderShippedDomainEventHandler.cs rename to src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderShippedDomainEventHandler.cs index 445c7e04f..aba9d8923 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderShipped/OrderShippedDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderShippedDomainEventHandler.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderShipped; +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; public class OrderShippedDomainEventHandler : INotificationHandler diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderGracePeriodConfirmed/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs similarity index 97% rename from src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderGracePeriodConfirmed/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs rename to src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs index 56ae38bba..e280d06c3 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderGracePeriodConfirmed/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderGracePeriodConfirmed; +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; public class OrderStatusChangedToAwaitingValidationDomainEventHandler : INotificationHandler diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderPaid/OrderStatusChangedToPaidDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToPaidDomainEventHandler.cs similarity index 90% rename from src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderPaid/OrderStatusChangedToPaidDomainEventHandler.cs rename to src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToPaidDomainEventHandler.cs index 2f2cf8e38..e5cc83a75 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderPaid/OrderStatusChangedToPaidDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToPaidDomainEventHandler.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderPaid; +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; public class OrderStatusChangedToPaidDomainEventHandler : INotificationHandler @@ -10,10 +10,10 @@ public class OrderStatusChangedToPaidDomainEventHandler public OrderStatusChangedToPaidDomainEventHandler( - IOrderRepository orderRepository, ILoggerFactory logger, + IOrderRepository orderRepository, + ILoggerFactory logger, IBuyerRepository buyerRepository, - IOrderingIntegrationEventService orderingIntegrationEventService - ) + IOrderingIntegrationEventService orderingIntegrationEventService) { _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); @@ -24,7 +24,7 @@ public class OrderStatusChangedToPaidDomainEventHandler public async Task Handle(OrderStatusChangedToPaidDomainEvent orderStatusChangedToPaidDomainEvent, CancellationToken cancellationToken) { _logger.CreateLogger() - .LogTrace("Order with Id: {OrderId} has been successfully updated to status {Status} ({Id})", + .LogInformation("Order with Id: {OrderId} has been successfully updated to status {Status} ({Id})", orderStatusChangedToPaidDomainEvent.OrderId, nameof(OrderStatus.Paid), OrderStatus.Paid.Id); var order = await _orderRepository.GetAsync(orderStatusChangedToPaidDomainEvent.OrderId); diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToStockConfirmedDomainEventHandler.cs similarity index 97% rename from src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs rename to src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToStockConfirmedDomainEventHandler.cs index 142b6449d..00548c802 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToStockConfirmedDomainEventHandler.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderStockConfirmed; +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; public class OrderStatusChangedToStockConfirmedDomainEventHandler : INotificationHandler diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/SendEmailToCustomerWhenOrderStartedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/SendEmailToCustomerWhenOrderStartedDomainEventHandler.cs similarity index 88% rename from src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/SendEmailToCustomerWhenOrderStartedDomainEventHandler.cs rename to src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/SendEmailToCustomerWhenOrderStartedDomainEventHandler.cs index 720b656d6..7350c16cd 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/SendEmailToCustomerWhenOrderStartedDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/SendEmailToCustomerWhenOrderStartedDomainEventHandler.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderStartedEvent; +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; public class SendEmailToCustomerWhenOrderStartedDomainEventHandler //: IAsyncNotificationHandler diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/BuyerAndPaymentMethodVerified/UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler.cs similarity index 96% rename from src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/BuyerAndPaymentMethodVerified/UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler.cs rename to src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler.cs index 919a78a45..5202bf50f 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/BuyerAndPaymentMethodVerified/UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.BuyerAndPaymentMethodVerified; +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; public class UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler : INotificationHandler diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs similarity index 92% rename from src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs rename to src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs index da5037259..9940c5114 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStartedEvent/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderStartedEvent; +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; public class ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler : INotificationHandler @@ -22,9 +22,9 @@ public class ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler public async Task Handle(OrderStartedDomainEvent orderStartedEvent, CancellationToken cancellationToken) { - var cardTypeId = (orderStartedEvent.CardTypeId != 0) ? orderStartedEvent.CardTypeId : 1; + var cardTypeId = orderStartedEvent.CardTypeId != 0 ? orderStartedEvent.CardTypeId : 1; var buyer = await _buyerRepository.FindAsync(orderStartedEvent.UserId); - bool buyerOriginallyExisted = (buyer == null) ? false : true; + var buyerOriginallyExisted = buyer == null ? false : true; if (!buyerOriginallyExisted) { diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs index 0c9557a5b..e5ed967a9 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs @@ -1,4 +1,4 @@ -namespace Ordering.API.Application.IntegrationEvents.EventHandling; +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.EventHandling; public class OrderStockConfirmedIntegrationEventHandler : IIntegrationEventHandler diff --git a/src/Services/Ordering/Ordering.API/Extensions/BasketItemExtensions.cs b/src/Services/Ordering/Ordering.API/Extensions/BasketItemExtensions.cs index 0f6122a13..4bf4f7575 100644 --- a/src/Services/Ordering/Ordering.API/Extensions/BasketItemExtensions.cs +++ b/src/Services/Ordering/Ordering.API/Extensions/BasketItemExtensions.cs @@ -1,6 +1,7 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models; +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Extensions; using System.Collections.Generic; +using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models; using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand; public static class BasketItemExtensions diff --git a/src/Services/Ordering/Ordering.API/GlobalUsings.cs b/src/Services/Ordering/Ordering.API/GlobalUsings.cs index 67ab88d35..e1cca922a 100644 --- a/src/Services/Ordering/Ordering.API/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.API/GlobalUsings.cs @@ -32,16 +32,15 @@ global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Se global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Behaviors; global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; -global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderStartedEvent; -global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules; -global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events; +global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents; +global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events; +global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.EventHandling; global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models; global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries; global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Validations; global using Microsoft.eShopOnContainers.Services.Ordering.API.Controllers; global using Microsoft.eShopOnContainers.Services.Ordering.API.Extensions; -global using GrpcOrdering; global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.ActionResults; global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Filters; global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services; diff --git a/src/Services/Ordering/Ordering.API/Grpc/OrderingService.cs b/src/Services/Ordering/Ordering.API/Grpc/OrderingService.cs index 969a09d46..28f1a183d 100644 --- a/src/Services/Ordering/Ordering.API/Grpc/OrderingService.cs +++ b/src/Services/Ordering/Ordering.API/Grpc/OrderingService.cs @@ -1,4 +1,9 @@ -namespace GrpcOrdering; +using GrpcOrdering; + +using OrderDraftDTO = GrpcOrdering.OrderDraftDTO; +using CreateOrderDraftCommand = GrpcOrdering.CreateOrderDraftCommand; +using BasketItem = GrpcOrdering.BasketItem; +using OrderItemDTO = GrpcOrdering.OrderItemDTO; public class OrderingService : OrderingGrpc.OrderingGrpcBase { @@ -25,7 +30,6 @@ public class OrderingService : OrderingGrpc.OrderingGrpcBase createOrderDraftCommand.BuyerId, this.MapBasketItems(createOrderDraftCommand.Items)); - var data = await _mediator.Send(command); if (data != null) diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs index 1ab775042..451b2b7d8 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs @@ -15,24 +15,6 @@ public class ApplicationModule protected override void Load(ContainerBuilder builder) { - builder.Register(c => new OrderQueries(QueriesConnectionString)) - .As() - .InstancePerLifetimeScope(); - - builder.RegisterType() - .As() - .InstancePerLifetimeScope(); - - builder.RegisterType() - .As() - .InstancePerLifetimeScope(); - - builder.RegisterType() - .As() - .InstancePerLifetimeScope(); - - builder.RegisterAssemblyTypes(typeof(CreateOrderCommandHandler).GetTypeInfo().Assembly) - .AsClosedTypesOf(typeof(IIntegrationEventHandler<>)); } } diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs index 5aa77e06c..c343d8290 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs @@ -4,26 +4,6 @@ public class MediatorModule : Autofac.Module { protected override void Load(ContainerBuilder builder) { - builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly) - .AsImplementedInterfaces(); - - // Register all the Command classes (they implement IRequestHandler) in assembly holding the Commands - builder.RegisterAssemblyTypes(typeof(CreateOrderCommand).GetTypeInfo().Assembly) - .AsClosedTypesOf(typeof(IRequestHandler<,>)); - - // Register the DomainEventHandler classes (they implement INotificationHandler<>) in assembly holding the Domain Events - builder.RegisterAssemblyTypes(typeof(ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler).GetTypeInfo().Assembly) - .AsClosedTypesOf(typeof(INotificationHandler<>)); - - // Register the Command's Validators (Validators based on FluentValidation library) - builder - .RegisterAssemblyTypes(typeof(CreateOrderCommandValidator).GetTypeInfo().Assembly) - .Where(t => t.IsClosedTypeOf(typeof(IValidator<>))) - .AsImplementedInterfaces(); - - builder.RegisterGeneric(typeof(LoggingBehavior<,>)).As(typeof(IPipelineBehavior<,>)); - builder.RegisterGeneric(typeof(ValidatorBehavior<,>)).As(typeof(IPipelineBehavior<,>)); - builder.RegisterGeneric(typeof(TransactionBehaviour<,>)).As(typeof(IPipelineBehavior<,>)); } } diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextDesignTimeFactory.cs b/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextDesignTimeFactory.cs index 3195d9714..52fe8f27a 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextDesignTimeFactory.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextDesignTimeFactory.cs @@ -1,4 +1,4 @@ -namespace Catalog.API.Infrastructure.IntegrationEventMigrations +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.IntegrationEventMigrations { public class IntegrationEventLogContextDesignTimeFactory : IDesignTimeDbContextFactory { diff --git a/src/Services/Ordering/Ordering.API/Ordering.API.csproj b/src/Services/Ordering/Ordering.API/Ordering.API.csproj index 573ce2665..991dd07be 100644 --- a/src/Services/Ordering/Ordering.API/Ordering.API.csproj +++ b/src/Services/Ordering/Ordering.API/Ordering.API.csproj @@ -6,7 +6,8 @@ $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; ..\..\..\..\docker-compose.dcproj false - true + true + Microsoft.eShopOnContainers.Services.Ordering.API diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index a1a00bb31..8e3e8aa50 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -1,15 +1,5 @@ -using Autofac.Core; -using Microsoft.Azure.Amqp.Framing; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; +var builder = WebApplication.CreateBuilder(args); -var appName = "Ordering.API"; -var builder = WebApplication.CreateBuilder(new WebApplicationOptions -{ - Args = args, - ApplicationName = typeof(Program).Assembly.FullName, - ContentRootPath = Directory.GetCurrentDirectory() -}); if (builder.Configuration.GetValue("UseVault", false)) { TokenCredential credential = new ClientSecretCredential( @@ -18,24 +8,22 @@ if (builder.Configuration.GetValue("UseVault", false)) builder.Configuration["Vault:ClientSecret"]); builder.Configuration.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential); } -builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()); -builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); -builder.Configuration.AddEnvironmentVariables(); + builder.WebHost.ConfigureKestrel(options => { - var ports = GetDefinedPorts(builder.Configuration); - options.Listen(IPAddress.Any, ports.httpPort, listenOptions => + var httpPort = builder.Configuration.GetValue("PORT", 80); + options.Listen(IPAddress.Any, httpPort, listenOptions => { listenOptions.Protocols = HttpProtocols.Http1AndHttp2; }); - options.Listen(IPAddress.Any, ports.grpcPort, listenOptions => + var grpcPort = builder.Configuration.GetValue("GRPC_PORT", 5001); + options.Listen(IPAddress.Any, grpcPort, listenOptions => { listenOptions.Protocols = HttpProtocols.Http2; }); - }); -builder.WebHost.CaptureStartupErrors(false); + builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration)); builder.Services .AddGrpc(options => @@ -58,8 +46,81 @@ builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); // Register your own things directly with Autofac here. Don't // call builder.Populate(), that happens in AutofacServiceProviderFactory // for you. -builder.Host.ConfigureContainer(conbuilder => conbuilder.RegisterModule(new MediatorModule())); -builder.Host.ConfigureContainer(conbuilder => conbuilder.RegisterModule(new ApplicationModule(builder.Configuration["ConnectionString"]))); + +var services = builder.Services; + + services.AddMediatR(cfg => + { + cfg.RegisterServicesFromAssemblyContaining(typeof(Program)); + + cfg.AddOpenBehavior(typeof(LoggingBehavior<,>)); + cfg.AddOpenBehavior(typeof(ValidatorBehavior<,>)); + cfg.AddOpenBehavior(typeof(TransactionBehavior<,>)); + }); + +/* + // Register all the command handlers. + services.AddSingleton, CancelOrderCommandHandler>(); + services.AddSingleton, bool>, CancelOrderIdentifiedCommandHandler>(); + + services.AddSingleton, CreateOrderCommandHandler>(); + services.AddSingleton, bool>, CreateOrderIdentifiedCommandHandler>(); + + services.AddSingleton, CreateOrderDraftCommandHandler>(); + + services.AddSingleton, bool>, SetAwaitingValidationIdentifiedOrderStatusCommandHandler>(); + services.AddSingleton, SetAwaitingValidationOrderStatusCommandHandler>(); + + services.AddSingleton, bool>, SetPaidIdentifiedOrderStatusCommandHandler>(); + services.AddSingleton, SetPaidOrderStatusCommandHandler>(); + + services.AddSingleton, bool>, SetStockConfirmedOrderStatusIdentifiedCommandHandler>(); + services.AddSingleton, SetStockConfirmedOrderStatusCommandHandler>(); + + services.AddSingleton, bool>, SetStockRejectedOrderStatusIdentifiedCommandHandler>(); + services.AddSingleton, SetStockRejectedOrderStatusCommandHandler>(); + + services.AddSingleton, bool>, ShipOrderIdentifiedCommandHandler>(); + services.AddSingleton, ShipOrderCommandHandler>(); + + // Register the DomainEventHandler classes (they implement INotificationHandler<>) in assembly holding the Domain Events + services.AddSingleton, OrderCancelledDomainEventHandler>(); + services.AddSingleton, OrderShippedDomainEventHandler>(); + services.AddSingleton, OrderStatusChangedToAwaitingValidationDomainEventHandler>(); + services.AddSingleton, OrderStatusChangedToPaidDomainEventHandler>(); + services.AddSingleton, OrderStatusChangedToStockConfirmedDomainEventHandler>(); + services.AddSingleton, UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler>(); + services.AddSingleton, ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler>(); +*/ + + // Register the command validators for the validator behavior (validators based on FluentValidation library) + services.AddSingleton, CancelOrderCommandValidator>(); + services.AddSingleton, CreateOrderCommandValidator>(); + services.AddSingleton>, IdentifiedCommandValidator>(); + services.AddSingleton, ShipOrderCommandValidator>(); + +/* + // Build the MediatR pipeline + services.AddSingleton(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>)); + services.AddSingleton(typeof(IPipelineBehavior<,>), typeof(ValidatorBehavior<,>)); + services.AddSingleton(typeof(IPipelineBehavior<,>), typeof(TransactionBehavior<,>)); +*/ + +var queriesConnectionString = builder.Configuration["ConnectionString"]; + +services.AddScoped(sp => new OrderQueries(queriesConnectionString)); +services.AddScoped(); +services.AddScoped(); +services.AddScoped(); + +// Add integration event handlers. +services.AddSingleton, GracePeriodConfirmedIntegrationEventHandler>(); +services.AddSingleton, OrderPaymentFailedIntegrationEventHandler>(); +services.AddSingleton, OrderPaymentSucceededIntegrationEventHandler>(); +services.AddSingleton, OrderStockConfirmedIntegrationEventHandler>(); +services.AddSingleton, OrderStockRejectedIntegrationEventHandler>(); +services.AddSingleton, UserCheckoutAcceptedIntegrationEventHandler>(); + var app = builder.Build(); if (app.Environment.IsDevelopment()) { @@ -166,18 +227,13 @@ Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) .ReadFrom.Configuration(configuration) .CreateLogger(); } -(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config) -{ - var grpcPort = config.GetValue("GRPC_PORT", 5001); - var port = config.GetValue("PORT", 80); - return (port, grpcPort); -} + public partial class Program { - - public static string Namespace = typeof(Program).Assembly.GetName().Name; + private static string Namespace = typeof(Program).Assembly.GetName().Name; public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1); } + static class CustomExtensionsMethods { public static IServiceCollection AddApplicationInsights(this IServiceCollection services, IConfiguration configuration) @@ -393,11 +449,10 @@ static class CustomExtensionsMethods { var serviceBusPersisterConnection = sp.GetRequiredService(); var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); + var eventBusSubscriptionsManager = sp.GetRequiredService(); string subscriptionName = configuration["SubscriptionClientName"]; - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, sp, subscriptionName); + return new EventBusServiceBus(serviceBusPersisterConnection, logger, eventBusSubscriptionsManager, sp, subscriptionName); }); } else @@ -407,15 +462,14 @@ static class CustomExtensionsMethods var subscriptionClientName = configuration["SubscriptionClientName"]; var rabbitMQPersistentConnection = sp.GetRequiredService(); var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); + var eventBusSubscriptionsManager = sp.GetRequiredService(); - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) + if (!int.TryParse(configuration["EventBusRetryCount"], out var retryCount)) { - retryCount = int.Parse(configuration["EventBusRetryCount"]); + retryCount = 5; } - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubcriptionsManager, subscriptionClientName, retryCount); + return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubscriptionsManager, subscriptionClientName, retryCount); }); } diff --git a/src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj b/src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj index 662bfa1f0..89f8910a2 100644 --- a/src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj +++ b/src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj @@ -6,16 +6,6 @@ false - - - - - - - Always - - - diff --git a/src/Services/Ordering/Ordering.SignalrHub/Program.cs b/src/Services/Ordering/Ordering.SignalrHub/Program.cs index ffbb5b8dc..03288fe33 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Program.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Program.cs @@ -1,5 +1,4 @@ -var appName = "Ordering.SignalrHub"; -var builder = WebApplication.CreateBuilder(new WebApplicationOptions +var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, ApplicationName = typeof(Program).Assembly.FullName, diff --git a/src/Services/Ordering/Ordering.UnitTests/Application/IdentifiedCommandHandlerTest.cs b/src/Services/Ordering/Ordering.UnitTests/Application/IdentifiedCommandHandlerTest.cs index 1b7d38864..37755202c 100644 --- a/src/Services/Ordering/Ordering.UnitTests/Application/IdentifiedCommandHandlerTest.cs +++ b/src/Services/Ordering/Ordering.UnitTests/Application/IdentifiedCommandHandlerTest.cs @@ -27,7 +27,7 @@ public class IdentifiedCommandHandlerTest .Returns(Task.FromResult(true)); //Act - var handler = new IdentifiedCommandHandler(_mediator.Object, _requestManager.Object, _loggerMock.Object); + var handler = new CreateOrderIdentifiedCommandHandler(_mediator.Object, _requestManager.Object, _loggerMock.Object); var cltToken = new System.Threading.CancellationToken(); var result = await handler.Handle(fakeOrderCmd, cltToken); @@ -50,7 +50,7 @@ public class IdentifiedCommandHandlerTest .Returns(Task.FromResult(true)); //Act - var handler = new IdentifiedCommandHandler(_mediator.Object, _requestManager.Object, _loggerMock.Object); + var handler = new CreateOrderIdentifiedCommandHandler(_mediator.Object, _requestManager.Object, _loggerMock.Object); var cltToken = new System.Threading.CancellationToken(); var result = await handler.Handle(fakeOrderCmd, cltToken); diff --git a/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs b/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs index cfa14a3ec..748701891 100644 --- a/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs +++ b/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs @@ -29,7 +29,7 @@ public class OrdersWebApiTest var actionResult = await orderController.CancelOrderAsync(new CancelOrderCommand(1), Guid.NewGuid().ToString()) as OkResult; //Assert - Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); + Assert.Equal((int)System.Net.HttpStatusCode.OK, actionResult.StatusCode); } @@ -45,7 +45,7 @@ public class OrdersWebApiTest var actionResult = await orderController.CancelOrderAsync(new CancelOrderCommand(1), String.Empty) as BadRequestResult; //Assert - Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.BadRequest); + Assert.Equal((int)System.Net.HttpStatusCode.BadRequest, actionResult.StatusCode); } [Fact] @@ -60,7 +60,7 @@ public class OrdersWebApiTest var actionResult = await orderController.ShipOrderAsync(new ShipOrderCommand(1), Guid.NewGuid().ToString()) as OkResult; //Assert - Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); + Assert.Equal((int)System.Net.HttpStatusCode.OK, actionResult.StatusCode); } @@ -76,7 +76,7 @@ public class OrdersWebApiTest var actionResult = await orderController.ShipOrderAsync(new ShipOrderCommand(1), String.Empty) as BadRequestResult; //Assert - Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.BadRequest); + Assert.Equal((int)System.Net.HttpStatusCode.BadRequest, actionResult.StatusCode); } [Fact] diff --git a/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj b/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj index 712a3ecfb..3825af1b5 100644 --- a/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj +++ b/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj @@ -20,12 +20,6 @@ - - PreserveNewest - - - PreserveNewest - Always diff --git a/src/eShopOnContainers-ServicesAndWebApps.sln b/src/eShopOnContainers-ServicesAndWebApps.sln index ccb68566d..68f32a4bf 100644 --- a/src/eShopOnContainers-ServicesAndWebApps.sln +++ b/src/eShopOnContainers-ServicesAndWebApps.sln @@ -9,6 +9,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AF739CD-81D8-428D-A08A-0A58372DEBF6}" ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig .env = .env Directory.Packages.props = Directory.Packages.props NuGet.config = NuGet.config From d62ebcb7916f20c94da0f8e447960c72e8f00334 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Fri, 28 Apr 2023 12:23:37 -0700 Subject: [PATCH 004/118] Fix IncludeScopes --- .../Mobile.Bff.Shopping/aggregator/appsettings.json | 3 ++- .../Mobile.Bff.Shopping/aggregator/appsettings.localhost.json | 3 ++- .../Web.Bff.Shopping/aggregator/appsettings.Development.json | 3 ++- src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json | 3 ++- src/Services/Basket/Basket.FunctionalTests/appsettings.json | 4 +++- src/Services/Payment/Payment.API/appsettings.Development.json | 4 +++- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json index 26bb0ac7a..e240b78f9 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json @@ -1,12 +1,13 @@ { "Logging": { - "IncludeScopes": false, "Debug": { + "IncludeScopes": false, "LogLevel": { "Default": "Warning" } }, "Console": { + "IncludeScopes": false, "LogLevel": { "Default": "Warning" } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json index 86fd1541d..9f033c482 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json @@ -11,13 +11,14 @@ "IdentityUrlExternal": "http://localhost:5105", "IdentityUrl": "http://localhost:5105", "Logging": { - "IncludeScopes": false, "Debug": { + "IncludeScopes": false, "LogLevel": { "Default": "Debug" } }, "Console": { + "IncludeScopes": false, "LogLevel": { "Default": "Debug" } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.Development.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.Development.json index 19b8c1529..9480db9c1 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.Development.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.Development.json @@ -1,12 +1,13 @@ { "Logging": { - "IncludeScopes": false, "Debug": { + "IncludeScopes": false, "LogLevel": { "Default": "Debug" } }, "Console": { + "IncludeScopes": false, "LogLevel": { "Default": "Debug" } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json index 26bb0ac7a..e240b78f9 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json @@ -1,12 +1,13 @@ { "Logging": { - "IncludeScopes": false, "Debug": { + "IncludeScopes": false, "LogLevel": { "Default": "Warning" } }, "Console": { + "IncludeScopes": false, "LogLevel": { "Default": "Warning" } diff --git a/src/Services/Basket/Basket.FunctionalTests/appsettings.json b/src/Services/Basket/Basket.FunctionalTests/appsettings.json index 8b9ec4d3c..d4fc14254 100644 --- a/src/Services/Basket/Basket.FunctionalTests/appsettings.json +++ b/src/Services/Basket/Basket.FunctionalTests/appsettings.json @@ -1,6 +1,8 @@ { "Logging": { - "IncludeScopes": false, + "Console": { + "IncludeScopes": false + }, "LogLevel": { "Default": "Debug", "System": "Information", diff --git a/src/Services/Payment/Payment.API/appsettings.Development.json b/src/Services/Payment/Payment.API/appsettings.Development.json index fa8ce71a9..e2f168cc8 100644 --- a/src/Services/Payment/Payment.API/appsettings.Development.json +++ b/src/Services/Payment/Payment.API/appsettings.Development.json @@ -1,6 +1,8 @@ { "Logging": { - "IncludeScopes": false, + "Console": { + "IncludeScopes": false + }, "LogLevel": { "Default": "Debug", "System": "Information", From 91247ec52e4baae1a2f6b43bbc2a715f5bd9499e Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Fri, 28 Apr 2023 14:49:57 -0700 Subject: [PATCH 005/118] BAD MISC - playing with tests --- .../Controllers/BasketController.cs | 2 +- src/Services/Basket/Basket.API/Program.cs | 31 +++++------ .../Base/AutoAuthorizeMiddleware.cs | 1 + .../Base/HttpClientExtensions.cs | 13 ----- .../Basket.FunctionalTests/BasketScenarios.cs | 54 ++++++++++++++----- .../HttpClientExtensions.cs | 11 ---- .../OrderingScenarios.cs | 14 +++-- src/Services/Payment/Payment.API/Program.cs | 24 +-------- .../Application.FunctionalTests.csproj | 2 +- .../Extensions/HttpClientExtensions.cs | 11 ---- .../GlobalUsings.cs | 3 -- .../Services/Ordering/OrderingScenarios.cs | 21 ++++++-- src/Web/WebMVC/Services/BasketService.cs | 2 +- 13 files changed, 88 insertions(+), 101 deletions(-) delete mode 100644 src/Services/Basket/Basket.FunctionalTests/Base/HttpClientExtensions.cs delete mode 100644 src/Services/Ordering/Ordering.FunctionalTests/HttpClientExtensions.cs delete mode 100644 src/Tests/Services/Application.FunctionalTests/Extensions/HttpClientExtensions.cs diff --git a/src/Services/Basket/Basket.API/Controllers/BasketController.cs b/src/Services/Basket/Basket.API/Controllers/BasketController.cs index 5468bbc15..302fc0768 100644 --- a/src/Services/Basket/Basket.API/Controllers/BasketController.cs +++ b/src/Services/Basket/Basket.API/Controllers/BasketController.cs @@ -1,7 +1,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers; [Route("api/v1/[controller]")] -[Authorize] +//[Authorize] [ApiController] public class BasketController : ControllerBase { diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index 9554841ec..8f98a3e04 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -1,9 +1,4 @@ -using Autofac.Core; -using Microsoft.Azure.Amqp.Framing; -using Microsoft.Extensions.Configuration; - -var appName = "Basket.API"; -var builder = WebApplication.CreateBuilder(new WebApplicationOptions +var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, ApplicationName = typeof(Program).Assembly.FullName, @@ -63,6 +58,7 @@ JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); var identityUrl = builder.Configuration.GetValue("IdentityUrl"); +/* builder.Services.AddAuthentication("Bearer").AddJwtBearer(options => { options.Authority = identityUrl; @@ -78,6 +74,7 @@ builder.Services.AddAuthorization(options => policy.RequireClaim("scope", "basket"); }); }); +*/ builder.Services.AddCustomHealthCheck(builder.Configuration); @@ -164,7 +161,6 @@ builder.WebHost.UseKestrel(options => }); }); -builder.WebHost.CaptureStartupErrors(false); builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration)); builder.WebHost.UseFailing(options => { @@ -172,6 +168,7 @@ builder.WebHost.UseFailing(options => options.NotFilteredPaths.AddRange(new[] { "/hc", "/liveness" }); }); var app = builder.Build(); +app.MapGet("hello", () => "hello"); if (app.Environment.IsDevelopment()) { @@ -196,13 +193,19 @@ app.UseSwagger() setup.OAuthAppName("Basket Swagger UI"); }); +app.Use(del => ctx => +{ + ctx.Response.StatusCode = 200; + ctx.Response.WriteAsync("hello"); + return Task.CompletedTask; + //return del(ctx); +}); app.UseRouting(); app.UseCors("CorsPolicy"); -app.UseAuthentication(); -app.UseAuthorization(); +//app.UseAuthentication(); +//app.UseAuthorization(); app.UseStaticFiles(); - app.MapGrpcService(); app.MapDefaultControllerRoute(); app.MapControllers(); @@ -271,6 +274,7 @@ Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) var port = config.GetValue("PORT", 80); return (port, grpcPort); } + void ConfigureEventBus(IApplicationBuilder app) { var eventBus = app.ApplicationServices.GetRequiredService(); @@ -278,18 +282,15 @@ void ConfigureEventBus(IApplicationBuilder app) eventBus.Subscribe(); eventBus.Subscribe(); } + public partial class Program { - - public static string Namespace = typeof(Program).Assembly.GetName().Name; + private static string Namespace = typeof(Program).Assembly.GetName().Name; public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1); } - public static class CustomExtensionMethods { - - public static IServiceCollection RegisterEventBus(this IServiceCollection services, IConfiguration configuration) { if (configuration.GetValue("AzureServiceBusEnabled")) diff --git a/src/Services/Basket/Basket.FunctionalTests/Base/AutoAuthorizeMiddleware.cs b/src/Services/Basket/Basket.FunctionalTests/Base/AutoAuthorizeMiddleware.cs index 6343dbe68..551e3069e 100644 --- a/src/Services/Basket/Basket.FunctionalTests/Base/AutoAuthorizeMiddleware.cs +++ b/src/Services/Basket/Basket.FunctionalTests/Base/AutoAuthorizeMiddleware.cs @@ -18,6 +18,7 @@ class AutoAuthorizeMiddleware identity.AddClaim(new Claim("sub", IDENTITY_ID)); identity.AddClaim(new Claim("unique_name", IDENTITY_ID)); identity.AddClaim(new Claim(ClaimTypes.Name, IDENTITY_ID)); + identity.AddClaim(new Claim("scope", "basket")); httpContext.User.AddIdentity(identity); diff --git a/src/Services/Basket/Basket.FunctionalTests/Base/HttpClientExtensions.cs b/src/Services/Basket/Basket.FunctionalTests/Base/HttpClientExtensions.cs deleted file mode 100644 index 45910df14..000000000 --- a/src/Services/Basket/Basket.FunctionalTests/Base/HttpClientExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Basket.FunctionalTests.Base; - -static class HttpClientExtensions -{ - public static HttpClient CreateIdempotentClient(this TestServer server) - { - var client = server.CreateClient(); - - client.DefaultRequestHeaders.Add("x-requestid", Guid.NewGuid().ToString()); - - return client; - } -} diff --git a/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs b/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs index f727b999e..cff801e15 100644 --- a/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs +++ b/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs @@ -1,15 +1,43 @@ -namespace Basket.FunctionalTests; +using System.Linq; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.Hosting; -public class BasketScenarios - : BasketScenarioBase +namespace Basket.FunctionalTests; + +public class TestWebApplicationFactory : WebApplicationFactory where TProgram : class +{ + protected override void ConfigureWebHost(IWebHostBuilder builder) + { + base.ConfigureWebHost(builder); + builder.Configure(app => + { + app.UseMiddleware(); + }); + } + + protected override IHost CreateHost(IHostBuilder builder) + { + return base.CreateHost(builder); + } +} + +public class BasketScenarios : BasketScenarioBase, IClassFixture> { + private readonly TestWebApplicationFactory _factory; + private readonly HttpClient _httpClient; + + public BasketScenarios(TestWebApplicationFactory factory) + { + _factory = factory; + _httpClient = _factory.CreateClient(); + } + [Fact] public async Task Post_basket_and_response_ok_status_code() { - using var server = CreateServer(); var content = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json"); - var response = await server.CreateClient() - .PostAsync(Post.Basket, content); + var uri = "/api/v1/basket/"; + var response = await _httpClient.PostAsync(uri, content); response.EnsureSuccessStatusCode(); } @@ -17,25 +45,25 @@ public class BasketScenarios [Fact] public async Task Get_basket_and_response_ok_status_code() { - using var server = CreateServer(); - var response = await server.CreateClient() + var response = await _httpClient .GetAsync(Get.GetBasket(1)); - response.EnsureSuccessStatusCode(); } [Fact] public async Task Send_Checkout_basket_and_response_ok_status_code() { - using var server = CreateServer(); var contentBasket = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json"); - await server.CreateClient() + await _httpClient .PostAsync(Post.Basket, contentBasket); - var contentCheckout = new StringContent(BuildCheckout(), UTF8Encoding.UTF8, "application/json"); + var contentCheckout = new StringContent(BuildCheckout(), UTF8Encoding.UTF8, "application/json") + { + Headers = { { "x-requestid", Guid.NewGuid().ToString() } } + }; - var response = await server.CreateIdempotentClient() + var response = await _httpClient .PostAsync(Post.CheckoutOrder, contentCheckout); response.EnsureSuccessStatusCode(); diff --git a/src/Services/Ordering/Ordering.FunctionalTests/HttpClientExtensions.cs b/src/Services/Ordering/Ordering.FunctionalTests/HttpClientExtensions.cs deleted file mode 100644 index a4a0dd9c2..000000000 --- a/src/Services/Ordering/Ordering.FunctionalTests/HttpClientExtensions.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ordering.FunctionalTests; - -static class HttpClientExtensions -{ - public static HttpClient CreateIdempotentClient(this TestServer server) - { - var client = server.CreateClient(); - client.DefaultRequestHeaders.Add("x-requestid", Guid.NewGuid().ToString()); - return client; - } -} diff --git a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs index 6c7ed17a9..252cc02ff 100644 --- a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs +++ b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs @@ -23,8 +23,11 @@ namespace Ordering.FunctionalTests public async Task Cancel_order_no_order_created_bad_request_response() { using var server = CreateServer(); - var content = new StringContent(BuildOrder(), UTF8Encoding.UTF8, "application/json"); - var response = await server.CreateIdempotentClient() + var content = new StringContent(BuildOrder(), UTF8Encoding.UTF8, "application/json") + { + Headers = { { "x-requestid", Guid.NewGuid().ToString() } } + }; + var response = await server.CreateClient() .PutAsync(Put.CancelOrder, content); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); @@ -34,8 +37,11 @@ namespace Ordering.FunctionalTests public async Task Ship_order_no_order_created_bad_request_response() { using var server = CreateServer(); - var content = new StringContent(BuildOrder(), UTF8Encoding.UTF8, "application/json"); - var response = await server.CreateIdempotentClient() + var content = new StringContent(BuildOrder(), UTF8Encoding.UTF8, "application/json") + { + Headers = { { "x-requestid", Guid.NewGuid().ToString() } } + }; + var response = await server.CreateClient() .PutAsync(Put.ShipOrder, content); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); diff --git a/src/Services/Payment/Payment.API/Program.cs b/src/Services/Payment/Payment.API/Program.cs index acfc73217..e6f92f4e3 100644 --- a/src/Services/Payment/Payment.API/Program.cs +++ b/src/Services/Payment/Payment.API/Program.cs @@ -1,5 +1,4 @@ -var appName = "Payment.API"; -var builder = WebApplication.CreateBuilder(new WebApplicationOptions +var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, ApplicationName = typeof(Program).Assembly.FullName, @@ -165,27 +164,6 @@ Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) .CreateLogger(); } -IConfiguration GetConfiguration() -{ - var builder = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) - .AddEnvironmentVariables(); - - var config = builder.Build(); - - if (config.GetValue("UseVault", false)) - { - TokenCredential credential = new ClientSecretCredential( - config["Vault:TenantId"], - config["Vault:ClientId"], - config["Vault:ClientSecret"]); - builder.AddAzureKeyVault(new Uri($"https://{config["Vault:Name"]}.vault.azure.net/"), credential); - } - - return builder.Build(); -} - public partial class Program { public static string Namespace = typeof(Program).Assembly.GetName().Name; diff --git a/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj b/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj index 3825af1b5..8ea12ff3c 100644 --- a/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj +++ b/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj @@ -41,7 +41,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/src/Tests/Services/Application.FunctionalTests/Extensions/HttpClientExtensions.cs b/src/Tests/Services/Application.FunctionalTests/Extensions/HttpClientExtensions.cs deleted file mode 100644 index b17edce91..000000000 --- a/src/Tests/Services/Application.FunctionalTests/Extensions/HttpClientExtensions.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace FunctionalTests.Extensions; - -static class HttpClientExtensions -{ - public static HttpClient CreateIdempotentClient(this TestServer server) - { - var client = server.CreateClient(); - client.DefaultRequestHeaders.Add("x-requestid", Guid.NewGuid().ToString()); - return client; - } -} diff --git a/src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs b/src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs index dd46c8aca..b09d08dd0 100644 --- a/src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs +++ b/src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs @@ -8,14 +8,11 @@ global using Microsoft.AspNetCore.Hosting; global using Microsoft.Extensions.Configuration; global using System.IO; global using System.Reflection; -global using FunctionalTests.Middleware; -global using Microsoft.AspNetCore.Builder; global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; -global using FunctionalTests.Extensions; global using FunctionalTests.Services.Basket; global using Microsoft.eShopOnContainers.Services.Basket.API.Model; global using Microsoft.eShopOnContainers.WebMVC.ViewModels; diff --git a/src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenarios.cs b/src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenarios.cs index 46291b81a..35ee35f1a 100644 --- a/src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenarios.cs +++ b/src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenarios.cs @@ -11,21 +11,32 @@ public class OrderingScenarios : OrderingScenariosBase var cityExpected = $"city-{Guid.NewGuid()}"; var orderStatusExpected = "cancelled"; - var basketClient = basketServer.CreateIdempotentClient(); - var orderClient = orderServer.CreateIdempotentClient(); + var basketClient = basketServer.CreateClient(); + var orderClient = orderServer.CreateClient(); // GIVEN a basket is created - var contentBasket = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json"); + var contentBasket = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json") + { + Headers = { { "x-requestid", Guid.NewGuid().ToString() } } + }; await basketClient.PostAsync(BasketScenariosBase.Post.CreateBasket, contentBasket); // AND basket checkout is sent - await basketClient.PostAsync(BasketScenariosBase.Post.CheckoutOrder, new StringContent(BuildCheckout(cityExpected), UTF8Encoding.UTF8, "application/json")); + await basketClient.PostAsync( + BasketScenariosBase.Post.CheckoutOrder, + new StringContent(BuildCheckout(cityExpected), UTF8Encoding.UTF8, "application/json") + { + Headers = { { "x-requestid", Guid.NewGuid().ToString() } } + }); // WHEN Order is created in Ordering.api var newOrder = await TryGetNewOrderCreated(cityExpected, orderClient); // AND Order is cancelled in Ordering.api - await orderClient.PutAsync(OrderingScenariosBase.Put.CancelOrder, new StringContent(BuildCancelOrder(newOrder.OrderNumber), UTF8Encoding.UTF8, "application/json")); + await orderClient.PutAsync(OrderingScenariosBase.Put.CancelOrder, new StringContent(BuildCancelOrder(newOrder.OrderNumber), UTF8Encoding.UTF8, "application/json") + { + Headers = { { "x-requestid", Guid.NewGuid().ToString() } } + }); // AND the requested order is retrieved var order = await TryGetOrder(newOrder.OrderNumber, orderClient); diff --git a/src/Web/WebMVC/Services/BasketService.cs b/src/Web/WebMVC/Services/BasketService.cs index 4833b3408..952cdb187 100644 --- a/src/Web/WebMVC/Services/BasketService.cs +++ b/src/Web/WebMVC/Services/BasketService.cs @@ -53,7 +53,7 @@ public class BasketService : IBasketService var uri = API.Basket.CheckoutBasket(_basketByPassUrl); var basketContent = new StringContent(JsonSerializer.Serialize(basket), Encoding.UTF8, "application/json"); - _logger.LogInformation("Uri chechout {uri}", uri); + _logger.LogInformation("Uri checkout {uri}", uri); var response = await _apiClient.PostAsync(uri, basketContent); From f3d28431668eecf0744211ab8da03457d8ed9c5d Mon Sep 17 00:00:00 2001 From: David Fowler Date: Mon, 1 May 2023 16:31:57 -0700 Subject: [PATCH 006/118] Make tests work --- .../Basket/Basket.API/Basket.API.csproj | 6 - .../Controllers/BasketController.cs | 4 +- .../Basket.API/Controllers/HomeController.cs | 11 - .../Basket.API/CustomExtensionMethods.cs | 105 +- src/Services/Basket/Basket.API/Program.cs | 179 +- .../TestHttpResponseTrailersFeature.cs | 6 - src/Services/Basket/Basket.API/web.config | 17 - .../Base/BasketScenarioBase.cs | 37 +- .../Basket.FunctionalTests/BasketScenarios.cs | 31 +- src/Web/WebSPA/Client/yarn.lock | 14538 +++++++++------- 10 files changed, 8188 insertions(+), 6746 deletions(-) delete mode 100644 src/Services/Basket/Basket.API/Controllers/HomeController.cs delete mode 100644 src/Services/Basket/Basket.API/TestHttpResponseTrailersFeature.cs delete mode 100644 src/Services/Basket/Basket.API/web.config diff --git a/src/Services/Basket/Basket.API/Basket.API.csproj b/src/Services/Basket/Basket.API/Basket.API.csproj index 74283d316..f6f36ba88 100644 --- a/src/Services/Basket/Basket.API/Basket.API.csproj +++ b/src/Services/Basket/Basket.API/Basket.API.csproj @@ -7,12 +7,6 @@ true - - - PreserveNewest - - - diff --git a/src/Services/Basket/Basket.API/Controllers/BasketController.cs b/src/Services/Basket/Basket.API/Controllers/BasketController.cs index 302fc0768..54c13a982 100644 --- a/src/Services/Basket/Basket.API/Controllers/BasketController.cs +++ b/src/Services/Basket/Basket.API/Controllers/BasketController.cs @@ -1,7 +1,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers; [Route("api/v1/[controller]")] -//[Authorize] +[Authorize] [ApiController] public class BasketController : ControllerBase { @@ -56,7 +56,7 @@ public class BasketController : ControllerBase return BadRequest(); } - var userName = this.HttpContext.User.FindFirst(x => x.Type == ClaimTypes.Name).Value; + var userName = User.FindFirst(x => x.Type == ClaimTypes.Name).Value; var eventMessage = new UserCheckoutAcceptedIntegrationEvent(userId, userName, basketCheckout.City, basketCheckout.Street, basketCheckout.State, basketCheckout.Country, basketCheckout.ZipCode, basketCheckout.CardNumber, basketCheckout.CardHolderName, diff --git a/src/Services/Basket/Basket.API/Controllers/HomeController.cs b/src/Services/Basket/Basket.API/Controllers/HomeController.cs deleted file mode 100644 index 8b2b7c2e7..000000000 --- a/src/Services/Basket/Basket.API/Controllers/HomeController.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers; - -public class HomeController : Controller -{ - // GET: // - public IActionResult Index() - { - return new RedirectResult("~/swagger"); - } -} - diff --git a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs index 8fcbf0c28..cdec6a100 100644 --- a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs +++ b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs @@ -2,6 +2,32 @@ public static class CustomExtensionMethods { + public static ConfigurationManager AddKeyVault(this ConfigurationManager configuration) + { + if (configuration.GetValue("UseVault", false)) + { + var credential = new ClientSecretCredential( + configuration["Vault:TenantId"], + configuration["Vault:ClientId"], + configuration["Vault:ClientSecret"]); + + configuration.AddAzureKeyVault(new Uri($"https://{configuration["Vault:Name"]}.vault.azure.net/"), credential); + } + + return configuration; + } + + public static IServiceCollection AddRedis(this IServiceCollection services) + { + return services.AddSingleton(sp => + { + var settings = sp.GetRequiredService>().Value; + var configuration = ConfigurationOptions.Parse(settings.ConnectionString, true); + + return ConnectionMultiplexer.Connect(configuration); + }); + } + public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) { var hcBuilder = services.AddHealthChecks(); @@ -34,4 +60,81 @@ public static class CustomExtensionMethods return services; } -} \ No newline at end of file + + public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) + { + if (configuration.GetValue("AzureServiceBusEnabled", false)) + { + services.AddSingleton(sp => + { + var serviceBusConnectionString = configuration["EventBusConnection"]; + + return new DefaultServiceBusPersisterConnection(serviceBusConnectionString); + }); + + services.AddSingleton(sp => + { + var serviceBusPersisterConnection = sp.GetRequiredService(); + var logger = sp.GetRequiredService>(); + var eventBusSubscriptionsManager = sp.GetRequiredService(); + string subscriptionName = configuration["SubscriptionClientName"]; + + return new EventBusServiceBus(serviceBusPersisterConnection, logger, + eventBusSubscriptionsManager, sp, subscriptionName); + }); + } + else + { + services.AddSingleton(sp => + { + var logger = sp.GetRequiredService>(); + + var factory = new ConnectionFactory() + { + HostName = configuration["EventBusConnection"], + DispatchConsumersAsync = true + }; + + if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) + { + factory.UserName = configuration["EventBusUserName"]; + } + + if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) + { + factory.Password = configuration["EventBusPassword"]; + } + + var retryCount = 5; + if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) + { + retryCount = int.Parse(configuration["EventBusRetryCount"]); + } + + return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); + }); + + services.AddSingleton(sp => + { + var subscriptionClientName = configuration["SubscriptionClientName"]; + var rabbitMQPersistentConnection = sp.GetRequiredService(); + var logger = sp.GetRequiredService>(); + var eventBusSubscriptionsManager = sp.GetRequiredService(); + + var retryCount = 5; + if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) + { + retryCount = int.Parse(configuration["EventBusRetryCount"]); + } + + return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubscriptionsManager, subscriptionClientName, retryCount); + }); + } + + services.AddSingleton(); + + services.AddTransient(); + services.AddTransient(); + return services; + } +} diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index 8f98a3e04..cb22a464f 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -1,32 +1,21 @@ -var builder = WebApplication.CreateBuilder(new WebApplicationOptions -{ - Args = args, - ApplicationName = typeof(Program).Assembly.FullName, - ContentRootPath = Directory.GetCurrentDirectory() -}); -if (builder.Configuration.GetValue("UseVault", false)) -{ - TokenCredential credential = new ClientSecretCredential( - builder.Configuration["Vault:TenantId"], - builder.Configuration["Vault:ClientId"], - builder.Configuration["Vault:ClientSecret"]); - builder.Configuration.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential); -} +var builder = WebApplication.CreateBuilder(args); + +builder.Configuration.AddKeyVault(); builder.Services.AddGrpc(options => { options.EnableDetailedErrors = true; }); + builder.Services.AddApplicationInsightsTelemetry(builder.Configuration); builder.Services.AddApplicationInsightsKubernetesEnricher(); + builder.Services.AddControllers(options => { options.Filters.Add(typeof(HttpGlobalExceptionFilter)); options.Filters.Add(typeof(ValidateModelStateFilter)); +}); -}) // Added for functional tests - .AddApplicationPart(typeof(BasketController).Assembly) - .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true); builder.Services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo @@ -43,8 +32,8 @@ builder.Services.AddSwaggerGen(options => { Implicit = new OpenApiOAuthFlow() { - AuthorizationUrl = new Uri($"{builder.Configuration.GetValue("IdentityUrlExternal")}/connect/authorize"), - TokenUrl = new Uri($"{builder.Configuration.GetValue("IdentityUrlExternal")}/connect/token"), + AuthorizationUrl = new Uri($"{builder.Configuration["IdentityUrlExternal"]}/connect/authorize"), + TokenUrl = new Uri($"{builder.Configuration["IdentityUrlExternal"]}/connect/token"), Scopes = new Dictionary() { { "basket", "Basket API" } } } } @@ -56,16 +45,16 @@ builder.Services.AddSwaggerGen(options => // prevent from mapping "sub" claim to nameidentifier. JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); -var identityUrl = builder.Configuration.GetValue("IdentityUrl"); +var identityUrl = builder.Configuration["IdentityUrl"]; -/* -builder.Services.AddAuthentication("Bearer").AddJwtBearer(options => +builder.Services.AddAuthentication().AddJwtBearer(options => { options.Authority = identityUrl; options.RequireHttpsMetadata = false; options.Audience = "basket"; options.TokenValidationParameters.ValidateAudience = false; }); + builder.Services.AddAuthorization(options => { options.AddPolicy("ApiScope", policy => @@ -74,79 +63,20 @@ builder.Services.AddAuthorization(options => policy.RequireClaim("scope", "basket"); }); }); -*/ builder.Services.AddCustomHealthCheck(builder.Configuration); builder.Services.Configure(builder.Configuration); -builder.Services.AddSingleton(sp => -{ - var settings = sp.GetRequiredService>().Value; - var configuration = ConfigurationOptions.Parse(settings.ConnectionString, true); - - return ConnectionMultiplexer.Connect(configuration); -}); +builder.Services.AddRedis(); +builder.Services.AddEventBus(builder.Configuration); -if (builder.Configuration.GetValue("AzureServiceBusEnabled")) -{ - builder.Services.AddSingleton(sp => - { - var serviceBusConnectionString = builder.Configuration["EventBusConnection"]; - - return new DefaultServiceBusPersisterConnection(serviceBusConnectionString); - }); -} -else -{ - builder.Services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - var factory = new ConnectionFactory() - { - HostName = builder.Configuration["EventBusConnection"], - DispatchConsumersAsync = true - }; - - if (!string.IsNullOrEmpty(builder.Configuration["EventBusUserName"])) - { - factory.UserName = builder.Configuration["EventBusUserName"]; - } - - if (!string.IsNullOrEmpty(builder.Configuration["EventBusPassword"])) - { - factory.Password = builder.Configuration["EventBusPassword"]; - } - - var retryCount = 5; - if (!string.IsNullOrEmpty(builder.Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(builder.Configuration["EventBusRetryCount"]); - } +builder.Services.AddHttpContextAccessor(); - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); -} -builder.Services.RegisterEventBus(builder.Configuration); -builder.Services.AddCors(options => -{ - options.AddPolicy("CorsPolicy", - builder => builder - .SetIsOriginAllowed((host) => true) - .AllowAnyMethod() - .AllowAnyHeader() - .AllowCredentials()); -}); -builder.Services.AddSingleton(); builder.Services.AddTransient(); builder.Services.AddTransient(); -builder.Services.AddOptions(); -builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()); -builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); -builder.Configuration.AddEnvironmentVariables(); builder.WebHost.UseKestrel(options => { var ports = GetDefinedPorts(builder.Configuration); @@ -159,22 +89,19 @@ builder.WebHost.UseKestrel(options => { listenOptions.Protocols = HttpProtocols.Http2; }); - }); + builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration)); builder.WebHost.UseFailing(options => { options.ConfigPath = "/Failing"; options.NotFilteredPaths.AddRange(new[] { "/hc", "/liveness" }); }); + var app = builder.Build(); app.MapGet("hello", () => "hello"); -if (app.Environment.IsDevelopment()) -{ - app.UseDeveloperExceptionPage(); -} -else +if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); } @@ -185,30 +112,18 @@ if (!string.IsNullOrEmpty(pathBase)) app.UsePathBase(pathBase); } -app.UseSwagger() - .UseSwaggerUI(setup => - { - setup.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Basket.API V1"); - setup.OAuthClientId("basketswaggerui"); - setup.OAuthAppName("Basket Swagger UI"); - }); +app.UseSwagger(); -app.Use(del => ctx => +app.UseSwaggerUI(setup => { - ctx.Response.StatusCode = 200; - ctx.Response.WriteAsync("hello"); - return Task.CompletedTask; - //return del(ctx); + setup.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Basket.API V1"); + setup.OAuthClientId("basketswaggerui"); + setup.OAuthAppName("Basket Swagger UI"); }); -app.UseRouting(); -app.UseCors("CorsPolicy"); -//app.UseAuthentication(); -//app.UseAuthorization(); -app.UseStaticFiles(); app.MapGrpcService(); -app.MapDefaultControllerRoute(); app.MapControllers(); + app.MapGet("/_proto/", async ctx => { ctx.Response.ContentType = "text/plain"; @@ -223,16 +138,20 @@ app.MapGet("/_proto/", async ctx => } } }); + app.MapHealthChecks("/hc", new HealthCheckOptions() { Predicate = _ => true, ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse }); + app.MapHealthChecks("/liveness", new HealthCheckOptions { Predicate = r => r.Name.Contains("self") }); + ConfigureEventBus(app); + try { Log.Information("Configuring web host ({ApplicationContext})...", Program.AppName); @@ -288,47 +207,3 @@ public partial class Program private static string Namespace = typeof(Program).Assembly.GetName().Name; public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1); } - -public static class CustomExtensionMethods -{ - public static IServiceCollection RegisterEventBus(this IServiceCollection services, IConfiguration configuration) - { - if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubscriptionsManager = sp.GetRequiredService(); - string subscriptionName = configuration["SubscriptionClientName"]; - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubscriptionsManager, sp, subscriptionName); - }); - } - else - { - services.AddSingleton(sp => - { - var subscriptionClientName = configuration["SubscriptionClientName"]; - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubscriptionsManager = sp.GetRequiredService(); - - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubscriptionsManager, subscriptionClientName, retryCount); - }); - } - - services.AddSingleton(); - - services.AddTransient(); - services.AddTransient(); - return services; - } -} diff --git a/src/Services/Basket/Basket.API/TestHttpResponseTrailersFeature.cs b/src/Services/Basket/Basket.API/TestHttpResponseTrailersFeature.cs deleted file mode 100644 index b1cfef87b..000000000 --- a/src/Services/Basket/Basket.API/TestHttpResponseTrailersFeature.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Basket.API; - -internal class TestHttpResponseTrailersFeature : IHttpResponseTrailersFeature -{ - public IHeaderDictionary Trailers { get; set; } -} diff --git a/src/Services/Basket/Basket.API/web.config b/src/Services/Basket/Basket.API/web.config deleted file mode 100644 index a2cf1fe26..000000000 --- a/src/Services/Basket/Basket.API/web.config +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs index 5fe08bb58..8ec90a2ee 100644 --- a/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs +++ b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs @@ -1,6 +1,9 @@ -namespace Basket.FunctionalTests.Base; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.Hosting; -public class BasketScenarioBase +namespace Basket.FunctionalTests.Base; + +public class BasketScenarioBase : WebApplicationFactory { private const string ApiUrlBase = "api/v1/basket"; @@ -33,4 +36,34 @@ public class BasketScenarioBase public static string Basket = $"{ApiUrlBase}/"; public static string CheckoutOrder = $"{ApiUrlBase}/checkout"; } + + protected override IHost CreateHost(IHostBuilder builder) + { + builder.ConfigureServices(services => + { + services.AddSingleton(); + }); + + builder.ConfigureAppConfiguration(c => + { + var directory = Path.GetDirectoryName(typeof(BasketScenarioBase).Assembly.Location)!; + + c.AddJsonFile(Path.Combine(directory, "appsettings.json"), optional: false); + }); + + return base.CreateHost(builder); + } + + private class AuthStartupFilter : IStartupFilter + { + public Action Configure(Action next) + { + return app => + { + app.UseMiddleware(); + + next(app); + }; + } + } } diff --git a/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs b/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs index cff801e15..8726e6627 100644 --- a/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs +++ b/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs @@ -1,35 +1,12 @@ -using System.Linq; -using Microsoft.AspNetCore.Mvc.Testing; -using Microsoft.Extensions.Hosting; +namespace Basket.FunctionalTests; -namespace Basket.FunctionalTests; - -public class TestWebApplicationFactory : WebApplicationFactory where TProgram : class -{ - protected override void ConfigureWebHost(IWebHostBuilder builder) - { - base.ConfigureWebHost(builder); - builder.Configure(app => - { - app.UseMiddleware(); - }); - } - - protected override IHost CreateHost(IHostBuilder builder) - { - return base.CreateHost(builder); - } -} - -public class BasketScenarios : BasketScenarioBase, IClassFixture> +public class BasketScenarios : BasketScenarioBase { - private readonly TestWebApplicationFactory _factory; private readonly HttpClient _httpClient; - public BasketScenarios(TestWebApplicationFactory factory) + public BasketScenarios() { - _factory = factory; - _httpClient = _factory.CreateClient(); + _httpClient = CreateClient(); } [Fact] diff --git a/src/Web/WebSPA/Client/yarn.lock b/src/Web/WebSPA/Client/yarn.lock index 4acb1c9a8..ea3d10fa5 100644 --- a/src/Web/WebSPA/Client/yarn.lock +++ b/src/Web/WebSPA/Client/yarn.lock @@ -2,23 +2,26 @@ # yarn lockfile v1 -"@ampproject/remapping@2.2.0", "@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz" +"@ampproject/remapping@^2.1.0", "@ampproject/remapping@2.2.0": + "integrity" "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==" + "resolved" "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz" + "version" "2.2.0" dependencies: "@jridgewell/gen-mapping" "^0.1.0" "@jridgewell/trace-mapping" "^0.3.9" "@angular-devkit/architect@0.1502.0": - version "0.1502.0" - resolved "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1502.0.tgz" + "integrity" "sha512-/HmyAQhb4BNbcVRL2uaLwrJAAeYVUD42Bipoq8+kUNzoRv9QqJTIOx+2fSsmwBk8C+Jx3184UD3SfUmEnFPt4g==" + "resolved" "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1502.0.tgz" + "version" "0.1502.0" dependencies: "@angular-devkit/core" "15.2.0" - rxjs "6.6.7" + "rxjs" "6.6.7" "@angular-devkit/build-angular@^15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-15.2.0.tgz" + "integrity" "sha512-scEZSBlVPWk7cFEoIVjW3T84it6ZPB4AU/U+dLuIvBT1P0V7R4Kctp8J219eAKsxrjTdD6hvYKXSP2uBFoqgng==" + "resolved" "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-15.2.0.tgz" + "version" "15.2.0" dependencies: "@ampproject/remapping" "2.2.0" "@angular-devkit/architect" "0.1502.0" @@ -36,195 +39,223 @@ "@babel/template" "7.20.7" "@discoveryjs/json-ext" "0.5.7" "@ngtools/webpack" "15.2.0" - ansi-colors "4.1.3" - autoprefixer "10.4.13" - babel-loader "9.1.2" - babel-plugin-istanbul "6.1.1" - browserslist "4.21.5" - cacache "17.0.4" - chokidar "3.5.3" - copy-webpack-plugin "11.0.0" - critters "0.0.16" - css-loader "6.7.3" - esbuild-wasm "0.17.8" - glob "8.1.0" - https-proxy-agent "5.0.1" - inquirer "8.2.4" - jsonc-parser "3.2.0" - karma-source-map-support "1.4.0" - less "4.1.3" - less-loader "11.1.0" - license-webpack-plugin "4.0.2" - loader-utils "3.2.1" - magic-string "0.29.0" - mini-css-extract-plugin "2.7.2" - open "8.4.1" - ora "5.4.1" - parse5-html-rewriting-stream "7.0.0" - piscina "3.2.0" - postcss "8.4.21" - postcss-loader "7.0.2" - resolve-url-loader "5.0.0" - rxjs "6.6.7" - sass "1.58.1" - sass-loader "13.2.0" - semver "7.3.8" - source-map-loader "4.0.1" - source-map-support "0.5.21" - terser "5.16.3" - text-table "0.2.0" - tree-kill "1.2.2" - tslib "2.5.0" - webpack "5.75.0" - webpack-dev-middleware "6.0.1" - webpack-dev-server "4.11.1" - webpack-merge "5.8.0" - webpack-subresource-integrity "5.1.0" + "ansi-colors" "4.1.3" + "autoprefixer" "10.4.13" + "babel-loader" "9.1.2" + "babel-plugin-istanbul" "6.1.1" + "browserslist" "4.21.5" + "cacache" "17.0.4" + "chokidar" "3.5.3" + "copy-webpack-plugin" "11.0.0" + "critters" "0.0.16" + "css-loader" "6.7.3" + "esbuild-wasm" "0.17.8" + "glob" "8.1.0" + "https-proxy-agent" "5.0.1" + "inquirer" "8.2.4" + "jsonc-parser" "3.2.0" + "karma-source-map-support" "1.4.0" + "less" "4.1.3" + "less-loader" "11.1.0" + "license-webpack-plugin" "4.0.2" + "loader-utils" "3.2.1" + "magic-string" "0.29.0" + "mini-css-extract-plugin" "2.7.2" + "open" "8.4.1" + "ora" "5.4.1" + "parse5-html-rewriting-stream" "7.0.0" + "piscina" "3.2.0" + "postcss" "8.4.21" + "postcss-loader" "7.0.2" + "resolve-url-loader" "5.0.0" + "rxjs" "6.6.7" + "sass" "1.58.1" + "sass-loader" "13.2.0" + "semver" "7.3.8" + "source-map-loader" "4.0.1" + "source-map-support" "0.5.21" + "terser" "5.16.3" + "text-table" "0.2.0" + "tree-kill" "1.2.2" + "tslib" "2.5.0" + "webpack" "5.75.0" + "webpack-dev-middleware" "6.0.1" + "webpack-dev-server" "4.11.1" + "webpack-merge" "5.8.0" + "webpack-subresource-integrity" "5.1.0" optionalDependencies: - esbuild "0.17.8" + "esbuild" "0.17.8" "@angular-devkit/build-webpack@0.1502.0": - version "0.1502.0" - resolved "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1502.0.tgz" + "integrity" "sha512-5xlHsuTZUaSvX+5/wfhbhr+CFVUSsLVNhiu3E4i9Qkyyb9Imj+KFZEuiy17p4fkYSUV7IXiQ34G5Axi5UCcnxQ==" + "resolved" "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1502.0.tgz" + "version" "0.1502.0" dependencies: "@angular-devkit/architect" "0.1502.0" - rxjs "6.6.7" + "rxjs" "6.6.7" "@angular-devkit/core@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular-devkit/core/-/core-15.2.0.tgz" + "integrity" "sha512-kUE5XvQzn+fiEvFqIk8x0q4hvRD+dKfAMM7p0uPQ69O9cj2b8c01oDvLOskvwhIJOnKTxnK/1d2gFQLupPci4A==" + "resolved" "https://registry.npmjs.org/@angular-devkit/core/-/core-15.2.0.tgz" + "version" "15.2.0" dependencies: - ajv "8.12.0" - ajv-formats "2.1.1" - jsonc-parser "3.2.0" - rxjs "6.6.7" - source-map "0.7.4" + "ajv" "8.12.0" + "ajv-formats" "2.1.1" + "jsonc-parser" "3.2.0" + "rxjs" "6.6.7" + "source-map" "0.7.4" -"@angular-devkit/schematics@15.2.0", "@angular-devkit/schematics@^15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-15.2.0.tgz" +"@angular-devkit/schematics@^15.2.0", "@angular-devkit/schematics@15.2.0": + "integrity" "sha512-LrsbQWaMRrLPBCgTOw7F+BvA4mjCljC+42NmiId/GXdU9FljEw/Ly1+u7LJREnE1yYqGQeR8zd8xjgIS0mTc3A==" + "resolved" "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-15.2.0.tgz" + "version" "15.2.0" dependencies: "@angular-devkit/core" "15.2.0" - jsonc-parser "3.2.0" - magic-string "0.29.0" - ora "5.4.1" - rxjs "6.6.7" + "jsonc-parser" "3.2.0" + "magic-string" "0.29.0" + "ora" "5.4.1" + "rxjs" "6.6.7" "@angular/animations@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular/animations/-/animations-15.2.0.tgz" + "integrity" "sha512-Hh/ijBlHsFlr6vR7e9KZgFpdQf+ebr3uIDDRsVHjRkt8utsv3CpUcJkb75UyTv+Ok5gYmfsI1Lj1CDYujyA0Fg==" + "resolved" "https://registry.npmjs.org/@angular/animations/-/animations-15.2.0.tgz" + "version" "15.2.0" dependencies: - tslib "^2.3.0" + "tslib" "^2.3.0" "@angular/cli@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular/cli/-/cli-15.2.0.tgz" + "integrity" "sha512-Zy1kmcvqoQf316eirfxkS5vb8/3B9btZf0YvZH/hDHmAyzAs8cwfirU+ClhwLLb/T9i7HnB0YS+Pdz0XaQa/jQ==" + "resolved" "https://registry.npmjs.org/@angular/cli/-/cli-15.2.0.tgz" + "version" "15.2.0" dependencies: "@angular-devkit/architect" "0.1502.0" "@angular-devkit/core" "15.2.0" "@angular-devkit/schematics" "15.2.0" "@schematics/angular" "15.2.0" "@yarnpkg/lockfile" "1.1.0" - ansi-colors "4.1.3" - ini "3.0.1" - inquirer "8.2.4" - jsonc-parser "3.2.0" - npm-package-arg "10.1.0" - npm-pick-manifest "8.0.1" - open "8.4.1" - ora "5.4.1" - pacote "15.1.0" - resolve "1.22.1" - semver "7.3.8" - symbol-observable "4.0.0" - yargs "17.6.2" - -"@angular/common@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular/common/-/common-15.2.0.tgz" - dependencies: - tslib "^2.3.0" - -"@angular/compiler-cli@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-15.2.0.tgz" + "ansi-colors" "4.1.3" + "ini" "3.0.1" + "inquirer" "8.2.4" + "jsonc-parser" "3.2.0" + "npm-package-arg" "10.1.0" + "npm-pick-manifest" "8.0.1" + "open" "8.4.1" + "ora" "5.4.1" + "pacote" "15.1.0" + "resolve" "1.22.1" + "semver" "7.3.8" + "symbol-observable" "4.0.0" + "yargs" "17.6.2" + +"@angular/common@^15.0.0", "@angular/common@>=14.0.0-0", "@angular/common@15.2.0": + "integrity" "sha512-B+e5pbkvlwlSwlQjtDrYQq+Xs62mScWm1plEZRHQm3cjBhA0RFT3MiUa/YNaHv8VoGjlrOm1rdJVEVQQxroZTg==" + "resolved" "https://registry.npmjs.org/@angular/common/-/common-15.2.0.tgz" + "version" "15.2.0" + dependencies: + "tslib" "^2.3.0" + +"@angular/compiler-cli@^15.0.0", "@angular/compiler-cli@15.2.0": + "integrity" "sha512-ETnRBdY/LGcmDRQ9GQc9KyCd1kuRnj+Y9luq2dCTMysP+NgylmYoGDsJOsDKm6SzPo+B4PSAyHX2J4CVQFHpPg==" + "resolved" "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-15.2.0.tgz" + "version" "15.2.0" dependencies: "@babel/core" "7.19.3" "@jridgewell/sourcemap-codec" "^1.4.14" - chokidar "^3.0.0" - convert-source-map "^1.5.1" - dependency-graph "^0.11.0" - magic-string "^0.27.0" - reflect-metadata "^0.1.2" - semver "^7.0.0" - tslib "^2.3.0" - yargs "^17.2.1" + "chokidar" "^3.0.0" + "convert-source-map" "^1.5.1" + "dependency-graph" "^0.11.0" + "magic-string" "^0.27.0" + "reflect-metadata" "^0.1.2" + "semver" "^7.0.0" + "tslib" "^2.3.0" + "yargs" "^17.2.1" "@angular/compiler@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular/compiler/-/compiler-15.2.0.tgz" + "integrity" "sha512-bGMc8xBs/3l5Ab2PmGGifuWVLxCzmYQPXeBYrwpmy+aYCwGzuVKxQp6L1UjA0OZNra7Am8bu4mOsLSR9ENdX6w==" + "resolved" "https://registry.npmjs.org/@angular/compiler/-/compiler-15.2.0.tgz" + "version" "15.2.0" dependencies: - tslib "^2.3.0" + "tslib" "^2.3.0" -"@angular/core@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular/core/-/core-15.2.0.tgz" +"@angular/core@^15.0.0", "@angular/core@>=14.0.0-0", "@angular/core@15.2.0": + "integrity" "sha512-UNHNcW3NqzMbG5gMjzXhb4xHrJcZq8rFdLwTLntB0oo2I/WxQFVlxz28nrW+Y09DbJf02MCASBLxD9If/6eT3g==" + "resolved" "https://registry.npmjs.org/@angular/core/-/core-15.2.0.tgz" + "version" "15.2.0" dependencies: - tslib "^2.3.0" + "tslib" "^2.3.0" -"@angular/forms@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular/forms/-/forms-15.2.0.tgz" +"@angular/forms@^15.0.0", "@angular/forms@15.2.0": + "integrity" "sha512-a93ysagAhbbyNbWM1yjWcPZaZBNrNjZ6SNIQYyelqySeShStXlKrDxYY5q7G/qqGpQzg2YF5qCIOOQxJJA9//g==" + "resolved" "https://registry.npmjs.org/@angular/forms/-/forms-15.2.0.tgz" + "version" "15.2.0" dependencies: - tslib "^2.3.0" + "tslib" "^2.3.0" "@angular/language-service@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular/language-service/-/language-service-15.2.0.tgz" + "integrity" "sha512-Gwg/IWPiBZ+LE0hHxtQGvQuJ+A7YehL6p0k26ClP0HS7Wy0ERRD9+ITGh5SnhKTKVMRwOb4HYcLp0N5W3yTajw==" + "resolved" "https://registry.npmjs.org/@angular/language-service/-/language-service-15.2.0.tgz" + "version" "15.2.0" + +"@angular/localize@^15.0.0": + "integrity" "sha512-0k79RsZgV/OB4LqYsu0oM2S9+NCG2hhl1TsM9yVFglKJ8q3VYS58TMrPtj2eugNn4pOCDA5/PVHtmSTEZolCyA==" + "resolved" "https://registry.npmjs.org/@angular/localize/-/localize-15.2.0.tgz" + "version" "15.2.0" + dependencies: + "@babel/core" "7.19.3" + "glob" "8.1.0" + "yargs" "^17.2.1" "@angular/platform-browser-dynamic@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-15.2.0.tgz" + "integrity" "sha512-OErEz/AX9S6I+RJUrFS/r9mF0rJGF1bhAvPjNvyc4mL+ai9JWZB6JgrZPzEz3v0nXG8SsAvnB1wJdKCp90Ed2g==" + "resolved" "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-15.2.0.tgz" + "version" "15.2.0" dependencies: - tslib "^2.3.0" + "tslib" "^2.3.0" -"@angular/platform-browser@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.2.0.tgz" +"@angular/platform-browser@>=14.0.0-0", "@angular/platform-browser@15.2.0": + "integrity" "sha512-+FB+KMoRHktF/MR7hn8ofubVLpu3+KZpudupKlxthPSL2KPMJn6h00ewrJDv3W+MtpqphqCjQSLmKpzw2UKKug==" + "resolved" "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.2.0.tgz" + "version" "15.2.0" dependencies: - tslib "^2.3.0" + "tslib" "^2.3.0" -"@angular/platform-server@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular/platform-server/-/platform-server-15.2.0.tgz" +"@angular/platform-server@^15.0.0", "@angular/platform-server@15.2.0": + "integrity" "sha512-tWB6/2ONxHiFmclBTdKBTFfNmOTiiZ0fvzeNO3oEhn2MGDUpScXL2sqOvUneof8FY50bECH8I8/ERAm78auFbw==" + "resolved" "https://registry.npmjs.org/@angular/platform-server/-/platform-server-15.2.0.tgz" + "version" "15.2.0" dependencies: - domino "^2.1.2" - tslib "^2.3.0" - xhr2 "^0.2.0" + "domino" "^2.1.2" + "tslib" "^2.3.0" + "xhr2" "^0.2.0" "@angular/router@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@angular/router/-/router-15.2.0.tgz" + "integrity" "sha512-FPmGP7DmJtzqgmM7FMs8bfe3vX0r6cdI4zbHMEVv7Zbn/yApgAzAsX7MXJYy7Oi45S6ZTH7SIVHVYVAqay1NVQ==" + "resolved" "https://registry.npmjs.org/@angular/router/-/router-15.2.0.tgz" + "version" "15.2.0" dependencies: - tslib "^2.3.0" + "tslib" "^2.3.0" "@assemblyscript/loader@^0.10.1": - version "0.10.1" - resolved "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz" + "integrity" "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==" + "resolved" "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz" + "version" "0.10.1" "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz" + "integrity" "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==" + "resolved" "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/highlight" "^7.18.6" "@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.1", "@babel/compat-data@^7.20.5": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz" + "integrity" "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==" + "resolved" "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz" + "version" "7.21.0" -"@babel/core@7.19.3", "@babel/core@^7.12.3": - version "7.19.3" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz" +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.13.0", "@babel/core@^7.4.0-0", "@babel/core@7.19.3": + "integrity" "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==" + "resolved" "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz" + "version" "7.19.3" dependencies: "@ampproject/remapping" "^2.1.0" "@babel/code-frame" "^7.18.6" @@ -236,15 +267,16 @@ "@babel/template" "^7.18.10" "@babel/traverse" "^7.19.3" "@babel/types" "^7.19.3" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" + "convert-source-map" "^1.7.0" + "debug" "^4.1.0" + "gensync" "^1.0.0-beta.2" + "json5" "^2.2.1" + "semver" "^6.3.0" "@babel/core@7.20.12": - version "7.20.12" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz" + "integrity" "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==" + "resolved" "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz" + "version" "7.20.12" dependencies: "@ampproject/remapping" "^2.1.0" "@babel/code-frame" "^7.18.6" @@ -256,55 +288,61 @@ "@babel/template" "^7.20.7" "@babel/traverse" "^7.20.12" "@babel/types" "^7.20.7" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.2" - semver "^6.3.0" + "convert-source-map" "^1.7.0" + "debug" "^4.1.0" + "gensync" "^1.0.0-beta.2" + "json5" "^2.2.2" + "semver" "^6.3.0" -"@babel/generator@7.20.14", "@babel/generator@^7.19.3", "@babel/generator@^7.20.7": - version "7.20.14" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz" +"@babel/generator@^7.19.3", "@babel/generator@^7.20.7", "@babel/generator@7.20.14": + "integrity" "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==" + "resolved" "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz" + "version" "7.20.14" dependencies: "@babel/types" "^7.20.7" "@jridgewell/gen-mapping" "^0.3.2" - jsesc "^2.5.1" + "jsesc" "^2.5.1" "@babel/generator@^7.21.1": - version "7.21.1" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz" + "integrity" "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==" + "resolved" "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz" + "version" "7.21.1" dependencies: "@babel/types" "^7.21.0" "@jridgewell/gen-mapping" "^0.3.2" "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" + "jsesc" "^2.5.1" -"@babel/helper-annotate-as-pure@7.18.6", "@babel/helper-annotate-as-pure@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz" +"@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@7.18.6": + "integrity" "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==" + "resolved" "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/types" "^7.18.6" "@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz" + "integrity" "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==" + "resolved" "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz" + "version" "7.18.9" dependencies: "@babel/helper-explode-assignable-expression" "^7.18.6" "@babel/types" "^7.18.9" "@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.3", "@babel/helper-compilation-targets@^7.20.0", "@babel/helper-compilation-targets@^7.20.7": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz" + "integrity" "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==" + "resolved" "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz" + "version" "7.20.7" dependencies: "@babel/compat-data" "^7.20.5" "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.21.3" - lru-cache "^5.1.1" - semver "^6.3.0" + "browserslist" "^4.21.3" + "lru-cache" "^5.1.1" + "semver" "^6.3.0" "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz" + "integrity" "sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==" + "resolved" "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz" + "version" "7.21.0" dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" "@babel/helper-environment-visitor" "^7.18.9" @@ -316,61 +354,70 @@ "@babel/helper-split-export-declaration" "^7.18.6" "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.0.tgz" + "integrity" "sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg==" + "resolved" "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.0.tgz" + "version" "7.21.0" dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" - regexpu-core "^5.3.1" + "regexpu-core" "^5.3.1" "@babel/helper-define-polyfill-provider@^0.3.3": - version "0.3.3" - resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz" + "integrity" "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==" + "resolved" "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz" + "version" "0.3.3" dependencies: "@babel/helper-compilation-targets" "^7.17.7" "@babel/helper-plugin-utils" "^7.16.7" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" + "debug" "^4.1.1" + "lodash.debounce" "^4.0.8" + "resolve" "^1.14.2" + "semver" "^6.1.2" "@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz" + "integrity" "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==" + "resolved" "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz" + "version" "7.18.9" "@babel/helper-explode-assignable-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz" + "integrity" "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==" + "resolved" "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/types" "^7.18.6" "@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0", "@babel/helper-function-name@^7.21.0": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz" + "integrity" "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==" + "resolved" "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz" + "version" "7.21.0" dependencies: "@babel/template" "^7.20.7" "@babel/types" "^7.21.0" "@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz" + "integrity" "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==" + "resolved" "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/types" "^7.18.6" "@babel/helper-member-expression-to-functions@^7.20.7", "@babel/helper-member-expression-to-functions@^7.21.0": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz" + "integrity" "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==" + "resolved" "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz" + "version" "7.21.0" dependencies: "@babel/types" "^7.21.0" "@babel/helper-module-imports@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz" + "integrity" "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==" + "resolved" "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/types" "^7.18.6" "@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.0", "@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.2": - version "7.21.2" - resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz" + "integrity" "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==" + "resolved" "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz" + "version" "7.21.2" dependencies: "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-module-imports" "^7.18.6" @@ -382,18 +429,21 @@ "@babel/types" "^7.21.2" "@babel/helper-optimise-call-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz" + "integrity" "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==" + "resolved" "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/types" "^7.18.6" "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.20.2" - resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz" + "integrity" "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==" + "resolved" "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz" + "version" "7.20.2" "@babel/helper-remap-async-to-generator@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz" + "integrity" "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==" + "resolved" "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz" + "version" "7.18.9" dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" "@babel/helper-environment-visitor" "^7.18.9" @@ -401,8 +451,9 @@ "@babel/types" "^7.18.9" "@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.20.7": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz" + "integrity" "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==" + "resolved" "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz" + "version" "7.20.7" dependencies: "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-member-expression-to-functions" "^7.20.7" @@ -412,38 +463,45 @@ "@babel/types" "^7.20.7" "@babel/helper-simple-access@^7.20.2": - version "7.20.2" - resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz" + "integrity" "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==" + "resolved" "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz" + "version" "7.20.2" dependencies: "@babel/types" "^7.20.2" "@babel/helper-skip-transparent-expression-wrappers@^7.20.0": - version "7.20.0" - resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz" + "integrity" "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==" + "resolved" "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz" + "version" "7.20.0" dependencies: "@babel/types" "^7.20.0" -"@babel/helper-split-export-declaration@7.18.6", "@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz" +"@babel/helper-split-export-declaration@^7.18.6", "@babel/helper-split-export-declaration@7.18.6": + "integrity" "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==" + "resolved" "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/types" "^7.18.6" "@babel/helper-string-parser@^7.19.4": - version "7.19.4" - resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz" + "integrity" "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" + "resolved" "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz" + "version" "7.19.4" "@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz" + "integrity" "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + "resolved" "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz" + "version" "7.19.1" "@babel/helper-validator-option@^7.18.6": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz" + "integrity" "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==" + "resolved" "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz" + "version" "7.21.0" "@babel/helper-wrap-function@^7.18.9": - version "7.20.5" - resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz" + "integrity" "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==" + "resolved" "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz" + "version" "7.20.5" dependencies: "@babel/helper-function-name" "^7.19.0" "@babel/template" "^7.18.10" @@ -451,42 +509,48 @@ "@babel/types" "^7.20.5" "@babel/helpers@^7.19.0", "@babel/helpers@^7.20.7": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz" + "integrity" "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==" + "resolved" "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz" + "version" "7.21.0" dependencies: "@babel/template" "^7.20.7" "@babel/traverse" "^7.21.0" "@babel/types" "^7.21.0" "@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz" + "integrity" "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==" + "resolved" "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" + "chalk" "^2.0.0" + "js-tokens" "^4.0.0" "@babel/parser@^7.14.7", "@babel/parser@^7.19.3", "@babel/parser@^7.20.7", "@babel/parser@^7.21.2": - version "7.21.2" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz" + "integrity" "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==" + "resolved" "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz" + "version" "7.21.2" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz" + "integrity" "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz" + "integrity" "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz" + "version" "7.20.7" dependencies: "@babel/helper-plugin-utils" "^7.20.2" "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" "@babel/plugin-proposal-optional-chaining" "^7.20.7" -"@babel/plugin-proposal-async-generator-functions@7.20.7", "@babel/plugin-proposal-async-generator-functions@^7.20.1": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz" +"@babel/plugin-proposal-async-generator-functions@^7.20.1", "@babel/plugin-proposal-async-generator-functions@7.20.7": + "integrity" "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz" + "version" "7.20.7" dependencies: "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-plugin-utils" "^7.20.2" @@ -494,65 +558,74 @@ "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-proposal-class-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz" + "integrity" "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-create-class-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-proposal-class-static-block@^7.18.6": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz" + "integrity" "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz" + "version" "7.21.0" dependencies: "@babel/helper-create-class-features-plugin" "^7.21.0" "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-proposal-dynamic-import@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz" + "integrity" "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-proposal-export-namespace-from@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz" + "integrity" "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz" + "version" "7.18.9" dependencies: "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" "@babel/plugin-proposal-json-strings@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz" + "integrity" "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-proposal-logical-assignment-operators@^7.18.9": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz" + "integrity" "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz" + "version" "7.20.7" dependencies: "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz" + "integrity" "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" "@babel/plugin-proposal-numeric-separator@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz" + "integrity" "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-numeric-separator" "^7.10.4" "@babel/plugin-proposal-object-rest-spread@^7.20.2": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz" + "integrity" "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz" + "version" "7.20.7" dependencies: "@babel/compat-data" "^7.20.5" "@babel/helper-compilation-targets" "^7.20.7" @@ -561,30 +634,34 @@ "@babel/plugin-transform-parameters" "^7.20.7" "@babel/plugin-proposal-optional-catch-binding@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz" + "integrity" "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" "@babel/plugin-proposal-optional-chaining@^7.18.9", "@babel/plugin-proposal-optional-chaining@^7.20.7": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz" + "integrity" "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz" + "version" "7.21.0" dependencies: "@babel/helper-plugin-utils" "^7.20.2" "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-proposal-private-methods@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz" + "integrity" "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-create-class-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-proposal-private-property-in-object@^7.18.6": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz" + "integrity" "sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz" + "version" "7.21.0" dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" "@babel/helper-create-class-features-plugin" "^7.21.0" @@ -592,131 +669,152 @@ "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz" + "integrity" "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==" + "resolved" "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" + "integrity" "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" + "version" "7.8.4" dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-class-properties@^7.12.13": - version "7.12.13" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" + "integrity" "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" + "version" "7.12.13" dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz" + "integrity" "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz" + "version" "7.14.5" dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz" + "integrity" "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz" + "version" "7.8.3" dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz" + "integrity" "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz" + "version" "7.8.3" dependencies: "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-import-assertions@^7.20.0": - version "7.20.0" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz" + "integrity" "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz" + "version" "7.20.0" dependencies: "@babel/helper-plugin-utils" "^7.19.0" "@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" + "integrity" "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" + "version" "7.8.3" dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": - version "7.10.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" + "integrity" "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" + "version" "7.10.4" dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" + "integrity" "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" + "version" "7.8.3" dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz" + "integrity" "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz" + "version" "7.10.4" dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" + "integrity" "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" + "version" "7.8.3" dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" + "integrity" "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" + "version" "7.8.3" dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" + "integrity" "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" + "version" "7.8.3" dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz" + "integrity" "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz" + "version" "7.14.5" dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-top-level-await@^7.14.5": - version "7.14.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz" + "integrity" "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz" + "version" "7.14.5" dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-transform-arrow-functions@^7.18.6": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz" + "integrity" "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz" + "version" "7.20.7" dependencies: "@babel/helper-plugin-utils" "^7.20.2" -"@babel/plugin-transform-async-to-generator@7.20.7", "@babel/plugin-transform-async-to-generator@^7.18.6": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz" +"@babel/plugin-transform-async-to-generator@^7.18.6", "@babel/plugin-transform-async-to-generator@7.20.7": + "integrity" "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz" + "version" "7.20.7" dependencies: "@babel/helper-module-imports" "^7.18.6" "@babel/helper-plugin-utils" "^7.20.2" "@babel/helper-remap-async-to-generator" "^7.18.9" "@babel/plugin-transform-block-scoped-functions@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz" + "integrity" "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-block-scoping@^7.20.2": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz" + "integrity" "sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz" + "version" "7.21.0" dependencies: "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-classes@^7.20.2": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz" + "integrity" "sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz" + "version" "7.21.0" dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" "@babel/helper-compilation-targets" "^7.20.7" @@ -726,85 +824,97 @@ "@babel/helper-plugin-utils" "^7.20.2" "@babel/helper-replace-supers" "^7.20.7" "@babel/helper-split-export-declaration" "^7.18.6" - globals "^11.1.0" + "globals" "^11.1.0" "@babel/plugin-transform-computed-properties@^7.18.9": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz" + "integrity" "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz" + "version" "7.20.7" dependencies: "@babel/helper-plugin-utils" "^7.20.2" "@babel/template" "^7.20.7" "@babel/plugin-transform-destructuring@^7.20.2": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz" + "integrity" "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz" + "version" "7.20.7" dependencies: "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz" + "integrity" "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-duplicate-keys@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz" + "integrity" "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz" + "version" "7.18.9" dependencies: "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-transform-exponentiation-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz" + "integrity" "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-for-of@^7.18.8": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz" + "integrity" "sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz" + "version" "7.21.0" dependencies: "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-function-name@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz" + "integrity" "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz" + "version" "7.18.9" dependencies: "@babel/helper-compilation-targets" "^7.18.9" "@babel/helper-function-name" "^7.18.9" "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-transform-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz" + "integrity" "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz" + "version" "7.18.9" dependencies: "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-transform-member-expression-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz" + "integrity" "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-modules-amd@^7.19.6": - version "7.20.11" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz" + "integrity" "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz" + "version" "7.20.11" dependencies: "@babel/helper-module-transforms" "^7.20.11" "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-modules-commonjs@^7.19.6": - version "7.21.2" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz" + "integrity" "sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz" + "version" "7.21.2" dependencies: "@babel/helper-module-transforms" "^7.21.2" "@babel/helper-plugin-utils" "^7.20.2" "@babel/helper-simple-access" "^7.20.2" "@babel/plugin-transform-modules-systemjs@^7.19.6": - version "7.20.11" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz" + "integrity" "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz" + "version" "7.20.11" dependencies: "@babel/helper-hoist-variables" "^7.18.6" "@babel/helper-module-transforms" "^7.20.11" @@ -812,115 +922,132 @@ "@babel/helper-validator-identifier" "^7.19.1" "@babel/plugin-transform-modules-umd@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz" + "integrity" "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-module-transforms" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-named-capturing-groups-regex@^7.19.1": - version "7.20.5" - resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz" + "integrity" "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz" + "version" "7.20.5" dependencies: "@babel/helper-create-regexp-features-plugin" "^7.20.5" "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-new-target@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz" + "integrity" "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-object-super@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz" + "integrity" "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/helper-replace-supers" "^7.18.6" "@babel/plugin-transform-parameters@^7.20.1", "@babel/plugin-transform-parameters@^7.20.7": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz" + "integrity" "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz" + "version" "7.20.7" dependencies: "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-property-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz" + "integrity" "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-regenerator@^7.18.6": - version "7.20.5" - resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz" + "integrity" "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz" + "version" "7.20.5" dependencies: "@babel/helper-plugin-utils" "^7.20.2" - regenerator-transform "^0.15.1" + "regenerator-transform" "^0.15.1" "@babel/plugin-transform-reserved-words@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz" + "integrity" "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-runtime@7.19.6": - version "7.19.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz" + "integrity" "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz" + "version" "7.19.6" dependencies: "@babel/helper-module-imports" "^7.18.6" "@babel/helper-plugin-utils" "^7.19.0" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - semver "^6.3.0" + "babel-plugin-polyfill-corejs2" "^0.3.3" + "babel-plugin-polyfill-corejs3" "^0.6.0" + "babel-plugin-polyfill-regenerator" "^0.4.1" + "semver" "^6.3.0" "@babel/plugin-transform-shorthand-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz" + "integrity" "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-spread@^7.19.0": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz" + "integrity" "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz" + "version" "7.20.7" dependencies: "@babel/helper-plugin-utils" "^7.20.2" "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" "@babel/plugin-transform-sticky-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz" + "integrity" "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-template-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz" + "integrity" "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz" + "version" "7.18.9" dependencies: "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-transform-typeof-symbol@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz" + "integrity" "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz" + "version" "7.18.9" dependencies: "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-transform-unicode-escapes@^7.18.10": - version "7.18.10" - resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz" + "integrity" "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz" + "version" "7.18.10" dependencies: "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-transform-unicode-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz" + "integrity" "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==" + "resolved" "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz" + "version" "7.18.6" dependencies: "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" "@babel/preset-env@7.20.2": - version "7.20.2" - resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz" + "integrity" "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==" + "resolved" "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz" + "version" "7.20.2" dependencies: "@babel/compat-data" "^7.20.1" "@babel/helper-compilation-targets" "^7.20.0" @@ -992,43 +1119,48 @@ "@babel/plugin-transform-unicode-regex" "^7.18.6" "@babel/preset-modules" "^0.1.5" "@babel/types" "^7.20.2" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - core-js-compat "^3.25.1" - semver "^6.3.0" + "babel-plugin-polyfill-corejs2" "^0.3.3" + "babel-plugin-polyfill-corejs3" "^0.6.0" + "babel-plugin-polyfill-regenerator" "^0.4.1" + "core-js-compat" "^3.25.1" + "semver" "^6.3.0" "@babel/preset-modules@^0.1.5": - version "0.1.5" - resolved "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz" + "integrity" "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==" + "resolved" "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz" + "version" "0.1.5" dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" "@babel/plugin-transform-dotall-regex" "^7.4.4" "@babel/types" "^7.4.4" - esutils "^2.0.2" + "esutils" "^2.0.2" "@babel/regjsgen@^0.8.0": - version "0.8.0" - resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz" + "integrity" "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + "resolved" "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz" + "version" "0.8.0" -"@babel/runtime@7.20.13", "@babel/runtime@^7.8.4": - version "7.20.13" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz" +"@babel/runtime@^7.8.4", "@babel/runtime@7.20.13": + "integrity" "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==" + "resolved" "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz" + "version" "7.20.13" dependencies: - regenerator-runtime "^0.13.11" + "regenerator-runtime" "^0.13.11" -"@babel/template@7.20.7", "@babel/template@^7.18.10", "@babel/template@^7.20.7": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz" +"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@7.20.7": + "integrity" "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==" + "resolved" "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz" + "version" "7.20.7" dependencies: "@babel/code-frame" "^7.18.6" "@babel/parser" "^7.20.7" "@babel/types" "^7.20.7" "@babel/traverse@^7.19.3", "@babel/traverse@^7.20.12", "@babel/traverse@^7.20.5", "@babel/traverse@^7.20.7", "@babel/traverse@^7.21.0", "@babel/traverse@^7.21.2": - version "7.21.2" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz" + "integrity" "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==" + "resolved" "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz" + "version" "7.21.2" dependencies: "@babel/code-frame" "^7.18.6" "@babel/generator" "^7.21.1" @@ -1038,345 +1170,302 @@ "@babel/helper-split-export-declaration" "^7.18.6" "@babel/parser" "^7.21.2" "@babel/types" "^7.21.2" - debug "^4.1.0" - globals "^11.1.0" + "debug" "^4.1.0" + "globals" "^11.1.0" "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.3", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.2", "@babel/types@^7.4.4": - version "7.21.2" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz" + "integrity" "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==" + "resolved" "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz" + "version" "7.21.2" dependencies: "@babel/helper-string-parser" "^7.19.4" "@babel/helper-validator-identifier" "^7.19.1" - to-fast-properties "^2.0.0" + "to-fast-properties" "^2.0.0" "@colors/colors@1.5.0": - version "1.5.0" - resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz" + "integrity" "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==" + "resolved" "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz" + "version" "1.5.0" "@discoveryjs/json-ext@0.5.7": - version "0.5.7" - resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz" - -"@esbuild/android-arm64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.8.tgz#b3d5b65a3b2e073a6c7ee36b1f3c30c8f000315b" - -"@esbuild/android-arm@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.8.tgz#c41e496af541e175369d48164d0cf01a5f656cf6" - -"@esbuild/android-x64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.8.tgz#080fa67c29be77f5a3ca5ee4cc78d5bf927e3a3b" - -"@esbuild/darwin-arm64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.8.tgz#053622bf9a82f43d5c075b7818e02618f7b4a397" - -"@esbuild/darwin-x64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.8.tgz#8a1aadb358d537d8efad817bb1a5bff91b84734b" - -"@esbuild/freebsd-arm64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.8.tgz#e6738d0081ba0721a5c6c674e84c6e7fcea61989" - -"@esbuild/freebsd-x64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.8.tgz#1855e562f2b730f4483f6e94086e9e2597feb4c3" - -"@esbuild/linux-arm64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.8.tgz#481da38952721a3fdb77c17a36ceaacc4270b5c5" - -"@esbuild/linux-arm@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.8.tgz#18127072b270bb6321c6d11be20bfd30e0d6ad17" - -"@esbuild/linux-ia32@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.8.tgz#ee400af7b3bc69e8ca2e593ca35156ffb9abd54f" - -"@esbuild/linux-loong64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.8.tgz#8c509d8a454693d39824b83b3f66c400872fce82" - -"@esbuild/linux-mips64el@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.8.tgz#f2b0d36e63fb26bc3f95b203b6a80638292101ca" - -"@esbuild/linux-ppc64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.8.tgz#1e628be003e036e90423716028cc884fe5ba25bd" - -"@esbuild/linux-riscv64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.8.tgz#419a815cb4c3fb9f1b78ef5295f5b48b8bf6427a" - -"@esbuild/linux-s390x@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.8.tgz#291c49ae5c3d11d226352755c0835911fe1a9e5c" - -"@esbuild/linux-x64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.8.tgz#03199d91c76faf80bd54104f5cbf0a489bc39f6a" - -"@esbuild/netbsd-x64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.8.tgz#b436d767e1b21852f9ed212e2bb57f77203b0ae2" - -"@esbuild/openbsd-x64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.8.tgz#d1481d8539e21d4729cd04a0450a26c2c8789e89" - -"@esbuild/sunos-x64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.8.tgz#2cfb8126e079b2c00fd1bf095541e9f5c47877e4" - -"@esbuild/win32-arm64@0.17.8": - version "0.17.8" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.8.tgz#7c6ecfd097ca23b82119753bf7072bbaefe51e3a" - -"@esbuild/win32-ia32@0.17.8": - version "0.17.8" - resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.8.tgz" + "integrity" "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==" + "resolved" "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz" + "version" "0.5.7" "@esbuild/win32-x64@0.17.8": - version "0.17.8" - resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.8.tgz" + "integrity" "sha512-1iuezdyDNngPnz8rLRDO2C/ZZ/emJLb72OsZeqQ6gL6Avko/XCXZw+NuxBSNhBAP13Hie418V7VMt9et1FMvpg==" + "resolved" "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.8.tgz" + "version" "0.17.8" "@eslint/eslintrc@^1.2.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz" - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.3.1" - globals "^13.9.0" - ignore "^4.0.6" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^5.1.0" - strip-json-comments "^3.1.1" + "integrity" "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==" + "resolved" "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz" + "version" "1.2.0" + dependencies: + "ajv" "^6.12.4" + "debug" "^4.3.2" + "espree" "^9.3.1" + "globals" "^13.9.0" + "ignore" "^4.0.6" + "import-fresh" "^3.2.1" + "js-yaml" "^4.1.0" + "minimatch" "^5.1.0" + "strip-json-comments" "^3.1.1" "@gar/promisify@^1.1.3": - version "1.1.3" - resolved "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz" + "integrity" "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==" + "resolved" "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz" + "version" "1.1.3" "@humanwhocodes/config-array@^0.9.2": - version "0.9.5" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz" + "integrity" "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==" + "resolved" "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz" + "version" "0.9.5" dependencies: "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^5.1.0" + "debug" "^4.1.1" + "minimatch" "^5.1.0" "@humanwhocodes/object-schema@^1.2.1": - 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==" + "resolved" "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" + "version" "1.2.1" "@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" + "integrity" "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==" + "resolved" "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" + "version" "1.1.0" dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" + "camelcase" "^5.3.1" + "find-up" "^4.1.0" + "get-package-type" "^0.1.0" + "js-yaml" "^3.13.1" + "resolve-from" "^5.0.0" "@istanbuljs/schema@^0.1.2": - version "0.1.3" - resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" + "integrity" "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" + "resolved" "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" + "version" "0.1.3" "@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz" + "integrity" "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==" + "resolved" "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz" + "version" "0.1.1" dependencies: "@jridgewell/set-array" "^1.0.0" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.2" - resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz" + "integrity" "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==" + "resolved" "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz" + "version" "0.3.2" dependencies: "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" "@jridgewell/resolve-uri@3.1.0": - version "3.1.0" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" + "integrity" "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + "resolved" "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" + "version" "3.1.0" "@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" + "integrity" "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + "resolved" "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" + "version" "1.1.2" "@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz" + "integrity" "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==" + "resolved" "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz" + "version" "0.3.2" dependencies: "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14": - version "1.4.14" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@1.4.14": + "integrity" "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "resolved" "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" + "version" "1.4.14" "@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz" + "integrity" "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==" + "resolved" "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz" + "version" "0.3.17" dependencies: "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" "@leichtgewicht/ip-codec@^2.0.1": - version "2.0.4" - resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz" + "integrity" "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + "resolved" "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz" + "version" "2.0.4" "@microsoft/signalr@3.0.1": - version "3.0.1" - resolved "https://registry.npmjs.org/@microsoft/signalr/-/signalr-3.0.1.tgz" + "integrity" "sha512-tRhqAmf5SyK02VXM6noj6DjSgt0i8yDqspHdLqdqsSrjMh4/inrwjI/BqLVE8zLD3mHp+eGHeSnlLTUVe024vA==" + "resolved" "https://registry.npmjs.org/@microsoft/signalr/-/signalr-3.0.1.tgz" + "version" "3.0.1" dependencies: - eventsource "^2.0.2" - request "^2.88.0" - ws "^6.0.0" + "eventsource" "^2.0.2" + "request" "^2.88.0" + "ws" "^6.0.0" "@ng-bootstrap/ng-bootstrap@14.0.1": - version "14.0.1" - resolved "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-14.0.1.tgz" + "integrity" "sha512-JF4U4IIix+g6VBFfG8stf0Un5K//ypoN+pTuRs6kjUhsHBsa2m7yKE6bCe3fMhatFZFr2fcSswDzRUnAUiHhWg==" + "resolved" "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-14.0.1.tgz" + "version" "14.0.1" dependencies: - tslib "^2.3.0" + "tslib" "^2.3.0" "@ngtools/webpack@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@ngtools/webpack/-/webpack-15.2.0.tgz" + "integrity" "sha512-jrpIOsEQxkWf5RnKn1izAixO+/hh6GkKmMl+hCv4rnn98XlKDmNRhG2KEIHJZF/3IEcAv9HVlIETRnLoVyJeeQ==" + "resolved" "https://registry.npmjs.org/@ngtools/webpack/-/webpack-15.2.0.tgz" + "version" "15.2.0" "@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + "integrity" "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==" + "resolved" "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + "version" "2.1.5" dependencies: "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" + "run-parallel" "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": + "integrity" "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + "resolved" "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" + "version" "2.0.5" "@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" + "integrity" "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==" + "resolved" "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" + "version" "1.2.8" dependencies: "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" + "fastq" "^1.6.0" "@npmcli/fs@^2.1.0": - version "2.1.2" - resolved "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz" + "integrity" "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==" + "resolved" "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz" + "version" "2.1.2" dependencies: "@gar/promisify" "^1.1.3" - semver "^7.3.5" + "semver" "^7.3.5" "@npmcli/fs@^3.1.0": - version "3.1.0" - resolved "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz" + "integrity" "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==" + "resolved" "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz" + "version" "3.1.0" dependencies: - semver "^7.3.5" + "semver" "^7.3.5" "@npmcli/git@^4.0.0": - version "4.0.3" - resolved "https://registry.npmjs.org/@npmcli/git/-/git-4.0.3.tgz" + "integrity" "sha512-8cXNkDIbnXPVbhXMmQ7/bklCAjtmPaXfI9aEM4iH+xSuEHINLMHhlfESvVwdqmHJRJkR48vNJTSUvoF6GRPSFA==" + "resolved" "https://registry.npmjs.org/@npmcli/git/-/git-4.0.3.tgz" + "version" "4.0.3" dependencies: "@npmcli/promise-spawn" "^6.0.0" - lru-cache "^7.4.4" - mkdirp "^1.0.4" - npm-pick-manifest "^8.0.0" - proc-log "^3.0.0" - promise-inflight "^1.0.1" - promise-retry "^2.0.1" - semver "^7.3.5" - which "^3.0.0" + "lru-cache" "^7.4.4" + "mkdirp" "^1.0.4" + "npm-pick-manifest" "^8.0.0" + "proc-log" "^3.0.0" + "promise-inflight" "^1.0.1" + "promise-retry" "^2.0.1" + "semver" "^7.3.5" + "which" "^3.0.0" "@npmcli/installed-package-contents@^2.0.1": - version "2.0.1" - resolved "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.1.tgz" + "integrity" "sha512-GIykAFdOVK31Q1/zAtT5MbxqQL2vyl9mvFJv+OGu01zxbhL3p0xc8gJjdNGX1mWmUT43aEKVO2L6V/2j4TOsAA==" + "resolved" "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.1.tgz" + "version" "2.0.1" dependencies: - npm-bundled "^3.0.0" - npm-normalize-package-bin "^3.0.0" + "npm-bundled" "^3.0.0" + "npm-normalize-package-bin" "^3.0.0" "@npmcli/move-file@^2.0.0": - version "2.0.1" - resolved "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz" + "integrity" "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==" + "resolved" "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz" + "version" "2.0.1" dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" + "mkdirp" "^1.0.4" + "rimraf" "^3.0.2" "@npmcli/node-gyp@^3.0.0": - version "3.0.0" - resolved "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz" + "integrity" "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==" + "resolved" "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz" + "version" "3.0.0" "@npmcli/promise-spawn@^6.0.0", "@npmcli/promise-spawn@^6.0.1": - version "6.0.2" - resolved "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz" + "integrity" "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==" + "resolved" "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz" + "version" "6.0.2" dependencies: - which "^3.0.0" + "which" "^3.0.0" "@npmcli/run-script@^6.0.0": - version "6.0.0" - resolved "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.0.tgz" + "integrity" "sha512-ql+AbRur1TeOdl1FY+RAwGW9fcr4ZwiVKabdvm93mujGREVuVLbdkXRJDrkTXSdCjaxYydr1wlA2v67jxWG5BQ==" + "resolved" "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.0.tgz" + "version" "6.0.0" dependencies: "@npmcli/node-gyp" "^3.0.0" "@npmcli/promise-spawn" "^6.0.0" - node-gyp "^9.0.0" - read-package-json-fast "^3.0.0" - which "^3.0.0" + "node-gyp" "^9.0.0" + "read-package-json-fast" "^3.0.0" + "which" "^3.0.0" -"@popperjs/core@2.11.6": - version "2.11.6" - resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz" +"@popperjs/core@^2.11.6", "@popperjs/core@2.11.6": + "integrity" "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" + "resolved" "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz" + "version" "2.11.6" "@schematics/angular@15.2.0": - version "15.2.0" - resolved "https://registry.npmjs.org/@schematics/angular/-/angular-15.2.0.tgz" + "integrity" "sha512-KnsG7xyEbjg+6zflANkdynXdS3wi9rSCg+8Y7erKdygD90O/JcT68PcanvTU2GfawDkBtvAR5VMURw2TIfCTnw==" + "resolved" "https://registry.npmjs.org/@schematics/angular/-/angular-15.2.0.tgz" + "version" "15.2.0" dependencies: "@angular-devkit/core" "15.2.0" "@angular-devkit/schematics" "15.2.0" - jsonc-parser "3.2.0" + "jsonc-parser" "3.2.0" "@sindresorhus/is@^4.6.0": - version "4.6.0" - resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz" + "integrity" "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" + "resolved" "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz" + "version" "4.6.0" "@socket.io/component-emitter@~3.1.0": - version "3.1.0" - resolved "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz" + "integrity" "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + "resolved" "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz" + "version" "3.1.0" "@szmarczak/http-timer@^5.0.1": - version "5.0.1" - resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz" + "integrity" "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==" + "resolved" "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz" + "version" "5.0.1" dependencies: - defer-to-connect "^2.0.1" + "defer-to-connect" "^2.0.1" "@tootallnate/once@2": - version "2.0.0" - resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" + "integrity" "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" + "resolved" "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" + "version" "2.0.0" "@types/body-parser@*": - version "1.19.2" - resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz" + "integrity" "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==" + "resolved" "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz" + "version" "1.19.2" dependencies: "@types/connect" "*" "@types/node" "*" "@types/bonjour@^3.5.9": - version "3.5.10" - resolved "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz" + "integrity" "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==" + "resolved" "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz" + "version" "3.5.10" dependencies: "@types/node" "*" "@types/cacheable-request@^6.0.2": - version "6.0.3" - resolved "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz" + "integrity" "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==" + "resolved" "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz" + "version" "6.0.3" dependencies: "@types/http-cache-semantics" "*" "@types/keyv" "^3.1.4" @@ -1384,75 +1473,88 @@ "@types/responselike" "^1.0.0" "@types/color-convert@*": - version "2.0.0" - resolved "https://registry.npmjs.org/@types/color-convert/-/color-convert-2.0.0.tgz" + "integrity" "sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==" + "resolved" "https://registry.npmjs.org/@types/color-convert/-/color-convert-2.0.0.tgz" + "version" "2.0.0" dependencies: "@types/color-name" "*" "@types/color-name@*": - version "1.1.1" - resolved "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz" + "integrity" "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + "resolved" "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz" + "version" "1.1.1" "@types/color@^3.0.1": - version "3.0.3" - resolved "https://registry.npmjs.org/@types/color/-/color-3.0.3.tgz" + "integrity" "sha512-X//qzJ3d3Zj82J9sC/C18ZY5f43utPbAJ6PhYt/M7uG6etcF6MRpKdN880KBy43B0BMzSfeT96MzrsNjFI3GbA==" + "resolved" "https://registry.npmjs.org/@types/color/-/color-3.0.3.tgz" + "version" "3.0.3" dependencies: "@types/color-convert" "*" "@types/connect-history-api-fallback@^1.3.5": - version "1.3.5" - resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz" + "integrity" "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==" + "resolved" "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz" + "version" "1.3.5" dependencies: "@types/express-serve-static-core" "*" "@types/node" "*" "@types/connect@*": - version "3.4.35" - resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz" + "integrity" "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==" + "resolved" "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz" + "version" "3.4.35" dependencies: "@types/node" "*" "@types/cookie@^0.4.1": - version "0.4.1" - resolved "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz" + "integrity" "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + "resolved" "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz" + "version" "0.4.1" "@types/core-js@2.5.0": - version "2.5.0" - resolved "https://registry.npmjs.org/@types/core-js/-/core-js-2.5.0.tgz" + "integrity" "sha512-qjkHL3wF0JMHMqgm/kmL8Pf8rIiqvueEiZ0g6NVTcBX1WN46GWDr+V5z+gsHUeL0n8TfAmXnYmF7ajsxmBp4PQ==" + "resolved" "https://registry.npmjs.org/@types/core-js/-/core-js-2.5.0.tgz" + "version" "2.5.0" "@types/cors@^2.8.12": - version "2.8.12" - resolved "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz" + "integrity" "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" + "resolved" "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz" + "version" "2.8.12" "@types/eslint-scope@^3.7.3": - version "3.7.4" - resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz" + "integrity" "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==" + "resolved" "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz" + "version" "3.7.4" dependencies: "@types/eslint" "*" "@types/estree" "*" "@types/eslint@*": - version "8.21.1" - resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.1.tgz" + "integrity" "sha512-rc9K8ZpVjNcLs8Fp0dkozd5Pt2Apk1glO4Vgz8ix1u6yFByxfqo5Yavpy65o+93TAe24jr7v+eSBtFLvOQtCRQ==" + "resolved" "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.1.tgz" + "version" "8.21.1" dependencies: "@types/estree" "*" "@types/json-schema" "*" "@types/estree@*", "@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz" + "integrity" "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" + "resolved" "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz" + "version" "0.0.51" "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": - version "4.17.28" - resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz" + "integrity" "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==" + "resolved" "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz" + "version" "4.17.28" dependencies: "@types/node" "*" "@types/qs" "*" "@types/range-parser" "*" "@types/express@*", "@types/express@^4.17.13": - version "4.17.13" - resolved "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz" + "integrity" "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==" + "resolved" "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz" + "version" "4.17.13" dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "^4.17.18" @@ -1460,136 +1562,163 @@ "@types/serve-static" "*" "@types/hammerjs@2.0.35": - version "2.0.35" - resolved "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.35.tgz" + "integrity" "sha512-4mUIMSZ2U4UOWq1b+iV7XUTE4w+Kr3x+Zb/Qz5ROO6BTZLw2c8/ftjq0aRgluguLs4KRuBnrOy/s389HVn1/zA==" + "resolved" "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.35.tgz" + "version" "2.0.35" "@types/http-cache-semantics@*": - version "4.0.1" - resolved "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz" + "integrity" "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" + "resolved" "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz" + "version" "4.0.1" "@types/http-proxy@^1.17.8": - version "1.17.8" - resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz" + "integrity" "sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==" + "resolved" "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz" + "version" "1.17.8" dependencies: "@types/node" "*" "@types/jasmine@~3.6.0": - version "3.6.11" - resolved "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.11.tgz" + "integrity" "sha512-S6pvzQDvMZHrkBz2Mcn/8Du7cpr76PlRJBAoHnSDNbulULsH5dp0Gns+WRyNX5LHejz/ljxK4/vIHK/caHt6SQ==" + "resolved" "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.11.tgz" + "version" "3.6.11" "@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - 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==" + "resolved" "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz" + "version" "7.0.9" "@types/keyv@^3.1.4": - version "3.1.4" - resolved "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz" + "integrity" "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==" + "resolved" "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz" + "version" "3.1.4" dependencies: "@types/node" "*" "@types/mime@^1": - version "1.3.2" - resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz" + "integrity" "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + "resolved" "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz" + "version" "1.3.2" -"@types/node@*", "@types/node@>=10.0.0", "@types/node@^12.11.1": - version "12.20.15" - resolved "https://registry.npmjs.org/@types/node/-/node-12.20.15.tgz" +"@types/node@*", "@types/node@^12.11.1", "@types/node@>=10.0.0": + "integrity" "sha512-F6S4Chv4JicJmyrwlDkxUdGNSplsQdGwp1A0AJloEVDirWdZOAiRHhovDlsFkKUrquUXhz1imJhXHsf59auyAg==" + "resolved" "https://registry.npmjs.org/@types/node/-/node-12.20.15.tgz" + "version" "12.20.15" "@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" + "integrity" "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + "resolved" "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" + "version" "4.0.0" "@types/protractor@4.0.0": - version "4.0.0" - resolved "https://registry.npmjs.org/@types/protractor/-/protractor-4.0.0.tgz" + "integrity" "sha1-EZFYRbONSD9wYNdOyOLu7kNXOZk=" + "resolved" "https://registry.npmjs.org/@types/protractor/-/protractor-4.0.0.tgz" + "version" "4.0.0" dependencies: - protractor "*" + "protractor" "*" "@types/q@^0.0.32": - version "0.0.32" - resolved "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz" + "integrity" "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=" + "resolved" "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz" + "version" "0.0.32" "@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==" + "resolved" "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" + "version" "6.9.7" "@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==" + "resolved" "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz" + "version" "1.2.4" "@types/responselike@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz" + "integrity" "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==" + "resolved" "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz" + "version" "1.0.0" dependencies: "@types/node" "*" "@types/retry@^0.12.0": - version "0.12.1" - resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz" + "integrity" "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==" + "resolved" "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz" + "version" "0.12.1" -"@types/selenium-webdriver@3.0.10", "@types/selenium-webdriver@^3.0.0": - version "3.0.10" - resolved "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.10.tgz" +"@types/selenium-webdriver@^3.0.0", "@types/selenium-webdriver@3.0.10": + "integrity" "sha512-ikB0JHv6vCR1KYUQAzTO4gi/lXLElT4Tx+6De2pc/OZwizE9LRNiTa+U8TBFKBD/nntPnr/MPSHSnOTybjhqNA==" + "resolved" "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.10.tgz" + "version" "3.0.10" "@types/serve-index@^1.9.1": - version "1.9.1" - resolved "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz" + "integrity" "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==" + "resolved" "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz" + "version" "1.9.1" dependencies: "@types/express" "*" "@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.13.10" - resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz" + "integrity" "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==" + "resolved" "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz" + "version" "1.13.10" dependencies: "@types/mime" "^1" "@types/node" "*" "@types/sockjs@^0.3.33": - version "0.3.33" - resolved "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz" + "integrity" "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==" + "resolved" "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz" + "version" "0.3.33" dependencies: "@types/node" "*" "@types/ws@^8.5.1": - version "8.5.2" - resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.2.tgz" + "integrity" "sha512-VXI82ykONr5tacHEojnErTQk+KQSoYbW1NB6iz6wUwrNd+BqfkfggQNoNdCqhJSzbNumShPERbM+Pc5zpfhlbw==" + "resolved" "https://registry.npmjs.org/@types/ws/-/ws-8.5.2.tgz" + "version" "8.5.2" dependencies: "@types/node" "*" "@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz" + "integrity" "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz" + "version" "1.11.1" dependencies: "@webassemblyjs/helper-numbers" "1.11.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.1" "@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz" + "integrity" "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz" + "version" "1.11.1" "@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz" + "integrity" "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz" + "version" "1.11.1" "@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz" + "integrity" "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz" + "version" "1.11.1" "@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz" + "integrity" "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz" + "version" "1.11.1" dependencies: "@webassemblyjs/floating-point-hex-parser" "1.11.1" "@webassemblyjs/helper-api-error" "1.11.1" "@xtuc/long" "4.2.2" "@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz" + "integrity" "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz" + "version" "1.11.1" "@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz" + "integrity" "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz" + "version" "1.11.1" dependencies: "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/helper-buffer" "1.11.1" @@ -1597,24 +1726,28 @@ "@webassemblyjs/wasm-gen" "1.11.1" "@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz" + "integrity" "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz" + "version" "1.11.1" dependencies: "@xtuc/ieee754" "^1.2.0" "@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz" + "integrity" "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz" + "version" "1.11.1" dependencies: "@xtuc/long" "4.2.2" "@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz" + "integrity" "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz" + "version" "1.11.1" "@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz" + "integrity" "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz" + "version" "1.11.1" dependencies: "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/helper-buffer" "1.11.1" @@ -1626,8 +1759,9 @@ "@webassemblyjs/wast-printer" "1.11.1" "@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz" + "integrity" "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz" + "version" "1.11.1" dependencies: "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.1" @@ -1636,8 +1770,9 @@ "@webassemblyjs/utf8" "1.11.1" "@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz" + "integrity" "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz" + "version" "1.11.1" dependencies: "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/helper-buffer" "1.11.1" @@ -1645,8 +1780,9 @@ "@webassemblyjs/wasm-parser" "1.11.1" "@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz" + "integrity" "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz" + "version" "1.11.1" dependencies: "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/helper-api-error" "1.11.1" @@ -1656,5668 +1792,6973 @@ "@webassemblyjs/utf8" "1.11.1" "@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz" + "integrity" "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==" + "resolved" "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz" + "version" "1.11.1" dependencies: "@webassemblyjs/ast" "1.11.1" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz" + "integrity" "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + "resolved" "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz" + "version" "1.2.0" "@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" + "integrity" "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + "resolved" "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" + "version" "4.2.2" "@yarnpkg/lockfile@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz" + "integrity" "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" + "resolved" "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz" + "version" "1.1.0" + +"abab@^2.0.6": + "integrity" "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" + "resolved" "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz" + "version" "2.0.6" + +"abbrev@^1.0.0", "abbrev@1": + "integrity" "sha1-kbR5JYinc4wl813W9jdSovh3YTU=" + "resolved" "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz" + "version" "1.0.9" + +"accepts@~1.3.4", "accepts@~1.3.5", "accepts@~1.3.8": + "integrity" "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==" + "resolved" "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" + "version" "1.3.8" + dependencies: + "mime-types" "~2.1.34" + "negotiator" "0.6.3" + +"acorn-dynamic-import@4.0.0": + "integrity" "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==" + "resolved" "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz" + "version" "4.0.0" + +"acorn-import-assertions@^1.7.6": + "integrity" "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==" + "resolved" "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz" + "version" "1.8.0" + +"acorn-jsx@^5.3.1": + "integrity" "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" + "resolved" "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" + "version" "5.3.2" + +"acorn@^6.0.0", "acorn@^6.0.0 || ^7.0.0 || ^8.0.0", "acorn@^6.4.1": + "integrity" "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" + "resolved" "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz" + "version" "6.4.2" + +"acorn@^8.5.0": + "integrity" "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==" + "resolved" "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" + "version" "8.8.2" + +"acorn@^8.7.0": + "integrity" "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" + "resolved" "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz" + "version" "8.7.0" + +"acorn@^8", "acorn@^8.7.1": + "integrity" "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==" + "resolved" "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" + "version" "8.8.2" + +"adjust-sourcemap-loader@^4.0.0": + "integrity" "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==" + "resolved" "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "loader-utils" "^2.0.0" + "regex-parser" "^2.2.11" + +"adm-zip@^0.4.9": + "integrity" "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==" + "resolved" "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz" + "version" "0.4.16" + +"agent-base@^4.3.0": + "integrity" "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==" + "resolved" "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz" + "version" "4.3.0" + dependencies: + "es6-promisify" "^5.0.0" + +"agent-base@^6.0.2", "agent-base@6": + "integrity" "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==" + "resolved" "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" + "version" "6.0.2" + dependencies: + "debug" "4" + +"agentkeepalive@^4.2.1": + "integrity" "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==" + "resolved" "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz" + "version" "4.2.1" + dependencies: + "debug" "^4.1.0" + "depd" "^1.1.2" + "humanize-ms" "^1.2.1" + +"aggregate-error@^3.0.0": + "integrity" "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==" + "resolved" "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "clean-stack" "^2.0.0" + "indent-string" "^4.0.0" + +"ajv-formats@^2.1.1", "ajv-formats@2.1.1": + "integrity" "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==" + "resolved" "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" + "version" "2.1.1" + dependencies: + "ajv" "^8.0.0" + +"ajv-keywords@^3.5.2": + "integrity" "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + "resolved" "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" + "version" "3.5.2" + +"ajv-keywords@^5.0.0": + "integrity" "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==" + "resolved" "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz" + "version" "5.1.0" + dependencies: + "fast-deep-equal" "^3.1.3" + +"ajv@^6.10.0", "ajv@^6.12.3", "ajv@^6.12.4", "ajv@^6.12.5", "ajv@^6.9.1": + "integrity" "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==" + "resolved" "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + "version" "6.12.6" + dependencies: + "fast-deep-equal" "^3.1.1" + "fast-json-stable-stringify" "^2.0.0" + "json-schema-traverse" "^0.4.1" + "uri-js" "^4.2.2" + +"ajv@^8.0.0": + "integrity" "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==" + "resolved" "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz" + "version" "8.10.0" + dependencies: + "fast-deep-equal" "^3.1.1" + "json-schema-traverse" "^1.0.0" + "require-from-string" "^2.0.2" + "uri-js" "^4.2.2" + +"ajv@^8.8.0", "ajv@^8.8.2": + "integrity" "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==" + "resolved" "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" + "version" "8.12.0" + dependencies: + "fast-deep-equal" "^3.1.1" + "json-schema-traverse" "^1.0.0" + "require-from-string" "^2.0.2" + "uri-js" "^4.2.2" + +"ajv@8.12.0": + "integrity" "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==" + "resolved" "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" + "version" "8.12.0" + dependencies: + "fast-deep-equal" "^3.1.1" + "json-schema-traverse" "^1.0.0" + "require-from-string" "^2.0.2" + "uri-js" "^4.2.2" + +"ansi-align@^2.0.0": + "integrity" "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=" + "resolved" "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "string-width" "^2.0.0" + +"ansi-colors@4.1.3": + "integrity" "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==" + "resolved" "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" + "version" "4.1.3" + +"ansi-escapes@^4.2.1": + "integrity" "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==" + "resolved" "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" + "version" "4.3.2" + dependencies: + "type-fest" "^0.21.3" + +"ansi-html-community@^0.0.8": + "integrity" "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==" + "resolved" "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + "version" "0.0.8" + +"ansi-regex@^2.0.0": + "integrity" "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" + "version" "2.1.1" + +"ansi-regex@^3.0.0": + "integrity" "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==" + "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz" + "version" "3.0.1" + +"ansi-regex@^5.0.0": + "integrity" "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + "version" "5.0.1" + +"ansi-regex@^5.0.1": + "integrity" "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + "version" "5.0.1" + +"ansi-styles@^2.2.1": + "integrity" "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" + "version" "2.2.1" + +"ansi-styles@^3.2.1": + "integrity" "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==" + "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + "version" "3.2.1" + dependencies: + "color-convert" "^1.9.0" + +"ansi-styles@^4.0.0": + "integrity" "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==" + "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + "version" "4.3.0" + dependencies: + "color-convert" "^2.0.1" + +"ansi-styles@^4.1.0": + "integrity" "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==" + "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + "version" "4.3.0" + dependencies: + "color-convert" "^2.0.1" + +"anymatch@^2.0.0": + "integrity" "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==" + "resolved" "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "micromatch" "^3.1.4" + "normalize-path" "^2.1.1" + +"anymatch@~3.1.2": + "integrity" "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==" + "resolved" "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" + "version" "3.1.3" + dependencies: + "normalize-path" "^3.0.0" + "picomatch" "^2.0.4" + +"app-root-path@^3.0.0": + "integrity" "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==" + "resolved" "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz" + "version" "3.0.0" -abab@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz" - -abbrev@1, abbrev@^1.0.0: - version "1.0.9" - resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz" - -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" +"aproba@^1.0.3 || ^2.0.0": + "integrity" "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + "resolved" "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz" + "version" "2.0.0" + +"are-we-there-yet@^3.0.0": + "integrity" "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==" + "resolved" "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "delegates" "^1.0.0" + "readable-stream" "^3.6.0" + +"argparse@^1.0.7": + "integrity" "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==" + "resolved" "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" + "version" "1.0.10" + dependencies: + "sprintf-js" "~1.0.2" + +"argparse@^2.0.1": + "integrity" "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "resolved" "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + "version" "2.0.1" + +"aria-query@^3.0.0": + "integrity" "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=" + "resolved" "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "ast-types-flow" "0.0.7" + "commander" "^2.11.0" + +"arr-diff@^4.0.0": + "integrity" "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + "resolved" "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz" + "version" "4.0.0" + +"arr-flatten@^1.1.0": + "integrity" "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + "resolved" "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz" + "version" "1.1.0" + +"arr-union@^3.1.0": + "integrity" "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + "resolved" "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz" + "version" "3.1.0" + +"array-flatten@^2.1.2": + "integrity" "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + "resolved" "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz" + "version" "2.1.2" + +"array-flatten@1.1.1": + "integrity" "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "resolved" "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" + "version" "1.1.1" + +"array-union@^1.0.1": + "integrity" "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=" + "resolved" "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz" + "version" "1.0.2" + dependencies: + "array-uniq" "^1.0.1" + +"array-uniq@^1.0.1": + "integrity" "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + "resolved" "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" + "version" "1.0.3" + +"array-unique@^0.3.2": + "integrity" "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + "resolved" "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz" + "version" "0.3.2" + +"arrify@^1.0.0": + "integrity" "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + "resolved" "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + "version" "1.0.1" + +"asn1@~0.2.3": + "integrity" "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==" + "resolved" "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz" + "version" "0.2.4" + dependencies: + "safer-buffer" "~2.1.0" + +"assert-plus@^1.0.0", "assert-plus@1.0.0": + "integrity" "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "resolved" "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + "version" "1.0.0" + +"assign-symbols@^1.0.0": + "integrity" "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + "resolved" "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz" + "version" "1.0.0" + +"ast-types-flow@0.0.7": + "integrity" "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" + "resolved" "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz" + "version" "0.0.7" + +"async-each@^1.0.1": + "integrity" "sha1-GdOGodntxufByF04iu28xW0zYC0=" + "resolved" "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz" + "version" "1.0.1" + +"async-limiter@~1.0.0": + "integrity" "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + "resolved" "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz" + "version" "1.0.0" + +"asynckit@^0.4.0": + "integrity" "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "resolved" "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + "version" "0.4.0" + +"atob@^2.1.1": + "integrity" "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + "resolved" "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz" + "version" "2.1.2" + +"autoprefixer@10.4.13": + "integrity" "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==" + "resolved" "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz" + "version" "10.4.13" + dependencies: + "browserslist" "^4.21.4" + "caniuse-lite" "^1.0.30001426" + "fraction.js" "^4.2.0" + "normalize-range" "^0.1.2" + "picocolors" "^1.0.0" + "postcss-value-parser" "^4.2.0" + +"aws-sign2@~0.7.0": + "integrity" "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "resolved" "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" + "version" "0.7.0" + +"aws4@^1.8.0": + "integrity" "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + "resolved" "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz" + "version" "1.8.0" + +"axobject-query@2.0.2": + "integrity" "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==" + "resolved" "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz" + "version" "2.0.2" + dependencies: + "ast-types-flow" "0.0.7" + +"babel-loader@9.1.2": + "integrity" "sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==" + "resolved" "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz" + "version" "9.1.2" + dependencies: + "find-cache-dir" "^3.3.2" + "schema-utils" "^4.0.0" + +"babel-plugin-istanbul@6.1.1": + "integrity" "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==" + "resolved" "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz" + "version" "6.1.1" dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -acorn-dynamic-import@4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz" - -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz" - -acorn-jsx@^5.3.1: - version "5.3.2" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" - -acorn@^6.4.1: - version "6.4.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz" - -acorn@^8.5.0, acorn@^8.7.0, acorn@^8.7.1: - version "8.8.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + "istanbul-lib-instrument" "^5.0.4" + "test-exclude" "^6.0.0" -adjust-sourcemap-loader@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz" +"babel-plugin-polyfill-corejs2@^0.3.3": + "integrity" "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==" + "resolved" "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz" + "version" "0.3.3" dependencies: - loader-utils "^2.0.0" - regex-parser "^2.2.11" - -adm-zip@^0.4.9: - version "0.4.16" - resolved "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz" + "@babel/compat-data" "^7.17.7" + "@babel/helper-define-polyfill-provider" "^0.3.3" + "semver" "^6.1.1" -agent-base@6, agent-base@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" +"babel-plugin-polyfill-corejs3@^0.6.0": + "integrity" "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==" + "resolved" "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz" + "version" "0.6.0" dependencies: - debug "4" + "@babel/helper-define-polyfill-provider" "^0.3.3" + "core-js-compat" "^3.25.1" -agent-base@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz" +"babel-plugin-polyfill-regenerator@^0.4.1": + "integrity" "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==" + "resolved" "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz" + "version" "0.4.1" dependencies: - es6-promisify "^5.0.0" + "@babel/helper-define-polyfill-provider" "^0.3.3" -agentkeepalive@^4.2.1: - version "4.2.1" - resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz" +"balanced-match@^1.0.0": + "integrity" "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" + "version" "1.0.0" + +"base@^0.11.1": + "integrity" "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==" + "resolved" "https://registry.npmjs.org/base/-/base-0.11.2.tgz" + "version" "0.11.2" + dependencies: + "cache-base" "^1.0.1" + "class-utils" "^0.3.5" + "component-emitter" "^1.2.1" + "define-property" "^1.0.0" + "isobject" "^3.0.1" + "mixin-deep" "^1.2.0" + "pascalcase" "^0.1.1" + +"base64-js@^1.2.0", "base64-js@^1.3.1": + "integrity" "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + "resolved" "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + "version" "1.5.1" + +"base64id@~2.0.0", "base64id@2.0.0": + "integrity" "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + "resolved" "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz" + "version" "2.0.0" + +"batch@0.6.1": + "integrity" "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + "resolved" "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" + "version" "0.6.1" + +"bcrypt-pbkdf@^1.0.0": + "integrity" "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=" + "resolved" "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" + "version" "1.0.2" + dependencies: + "tweetnacl" "^0.14.3" + +"big.js@^5.2.2": + "integrity" "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + "resolved" "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz" + "version" "5.2.2" + +"binary-extensions@^1.0.0": + "integrity" "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=" + "resolved" "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz" + "version" "1.11.0" + +"binary-extensions@^2.0.0": + "integrity" "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "resolved" "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" + "version" "2.2.0" + +"bl@^4.1.0": + "integrity" "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==" + "resolved" "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" + "version" "4.1.0" + dependencies: + "buffer" "^5.5.0" + "inherits" "^2.0.4" + "readable-stream" "^3.4.0" + +"blocking-proxy@^1.0.0": + "integrity" "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==" + "resolved" "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "minimist" "^1.2.6" + +"body-parser@^1.19.0", "body-parser@1.20.1": + "integrity" "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==" + "resolved" "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz" + "version" "1.20.1" + 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.11.0" + "raw-body" "2.5.1" + "type-is" "~1.6.18" + "unpipe" "1.0.0" + +"bonjour-service@^1.0.11": + "integrity" "sha512-LVRinRB3k1/K0XzZ2p58COnWvkQknIY6sf0zF2rpErvcJXpMBttEPQSxK+HEXSS9VmpZlDoDnQWv8ftJT20B0Q==" + "resolved" "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.0.tgz" + "version" "1.1.0" + dependencies: + "array-flatten" "^2.1.2" + "dns-equal" "^1.0.0" + "fast-deep-equal" "^3.1.3" + "multicast-dns" "^7.2.5" + +"boolbase@^1.0.0": + "integrity" "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + "resolved" "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" + "version" "1.0.0" + +"bootstrap@5.2.3": + "integrity" "sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==" + "resolved" "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.3.tgz" + "version" "5.2.3" + +"boxen@^1.2.1": + "integrity" "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==" + "resolved" "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz" + "version" "1.3.0" + dependencies: + "ansi-align" "^2.0.0" + "camelcase" "^4.0.0" + "chalk" "^2.0.1" + "cli-boxes" "^1.0.0" + "string-width" "^2.0.0" + "term-size" "^1.2.0" + "widest-line" "^2.0.0" + +"brace-expansion@^2.0.1": + "integrity" "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==" + "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "balanced-match" "^1.0.0" + +"braces@^2.3.1", "braces@^2.3.2": + "integrity" "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==" + "resolved" "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz" + "version" "2.3.2" + dependencies: + "arr-flatten" "^1.1.0" + "array-unique" "^0.3.2" + "extend-shallow" "^2.0.1" + "fill-range" "^4.0.0" + "isobject" "^3.0.1" + "repeat-element" "^1.1.2" + "snapdragon" "^0.8.1" + "snapdragon-node" "^2.0.1" + "split-string" "^3.0.2" + "to-regex" "^3.0.1" + +"braces@^3.0.1": + "integrity" "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==" + "resolved" "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "fill-range" "^7.0.1" + +"braces@^3.0.2", "braces@~3.0.2": + "integrity" "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==" + "resolved" "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "fill-range" "^7.0.1" + +"browserslist@^4.14.5", "browserslist@^4.21.3", "browserslist@^4.21.4", "browserslist@^4.21.5", "browserslist@>= 4.21.0", "browserslist@4.21.5": + "integrity" "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==" + "resolved" "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz" + "version" "4.21.5" + dependencies: + "caniuse-lite" "^1.0.30001449" + "electron-to-chromium" "^1.4.284" + "node-releases" "^2.0.8" + "update-browserslist-db" "^1.0.10" + +"browserstack@^1.5.1": + "integrity" "sha512-GxtFjpIaKdbAyzHfFDKixKO8IBT7wR3NjbzrGc78nNs/Ciys9wU3/nBtsqsWv5nDSrdI5tz0peKuzCPuNXNUiw==" + "resolved" "https://registry.npmjs.org/browserstack/-/browserstack-1.6.1.tgz" + "version" "1.6.1" + dependencies: + "https-proxy-agent" "^2.2.1" + +"buffer-from@^1.0.0", "buffer-from@^1.1.0": + "integrity" "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "resolved" "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz" + "version" "1.1.1" + +"buffer@^5.5.0": + "integrity" "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==" + "resolved" "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" + "version" "5.7.1" + dependencies: + "base64-js" "^1.3.1" + "ieee754" "^1.1.13" + +"builtin-modules@^1.1.1": + "integrity" "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + "resolved" "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz" + "version" "1.1.1" + +"builtins@^5.0.0": + "integrity" "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==" + "resolved" "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz" + "version" "5.0.1" + dependencies: + "semver" "^7.0.0" + +"bytes@3.0.0": + "integrity" "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + "resolved" "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" + "version" "3.0.0" + +"bytes@3.1.2": + "integrity" "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + "resolved" "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + "version" "3.1.2" + +"cacache@^16.1.0": + "integrity" "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==" + "resolved" "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz" + "version" "16.1.3" dependencies: - debug "^4.1.0" - depd "^1.1.2" - humanize-ms "^1.2.1" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" + "@npmcli/fs" "^2.1.0" + "@npmcli/move-file" "^2.0.0" + "chownr" "^2.0.0" + "fs-minipass" "^2.1.0" + "glob" "^8.0.1" + "infer-owner" "^1.0.4" + "lru-cache" "^7.7.1" + "minipass" "^3.1.6" + "minipass-collect" "^1.0.2" + "minipass-flush" "^1.0.5" + "minipass-pipeline" "^1.2.4" + "mkdirp" "^1.0.4" + "p-map" "^4.0.0" + "promise-inflight" "^1.0.1" + "rimraf" "^3.0.2" + "ssri" "^9.0.0" + "tar" "^6.1.11" + "unique-filename" "^2.0.0" + +"cacache@^17.0.0", "cacache@17.0.4": + "integrity" "sha512-Z/nL3gU+zTUjz5pCA5vVjYM8pmaw2kxM7JEiE0fv3w77Wj+sFbi70CrBruUWH0uNcEdvLDixFpgA2JM4F4DBjA==" + "resolved" "https://registry.npmjs.org/cacache/-/cacache-17.0.4.tgz" + "version" "17.0.4" dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv-formats@2.1.1, ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" + "@npmcli/fs" "^3.1.0" + "fs-minipass" "^3.0.0" + "glob" "^8.0.1" + "lru-cache" "^7.7.1" + "minipass" "^4.0.0" + "minipass-collect" "^1.0.2" + "minipass-flush" "^1.0.5" + "minipass-pipeline" "^1.2.4" + "p-map" "^4.0.0" + "promise-inflight" "^1.0.1" + "ssri" "^10.0.0" + "tar" "^6.1.11" + "unique-filename" "^3.0.0" + +"cache-base@^1.0.1": + "integrity" "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==" + "resolved" "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "collection-visit" "^1.0.0" + "component-emitter" "^1.2.1" + "get-value" "^2.0.6" + "has-value" "^1.0.0" + "isobject" "^3.0.1" + "set-value" "^2.0.0" + "to-object-path" "^0.3.0" + "union-value" "^1.0.0" + "unset-value" "^1.0.0" + +"cacheable-lookup@^6.0.4": + "integrity" "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==" + "resolved" "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz" + "version" "6.1.0" + +"cacheable-request@^7.0.2": + "integrity" "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==" + "resolved" "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz" + "version" "7.0.2" + dependencies: + "clone-response" "^1.0.2" + "get-stream" "^5.1.0" + "http-cache-semantics" "^4.0.0" + "keyv" "^4.0.0" + "lowercase-keys" "^2.0.0" + "normalize-url" "^6.0.1" + "responselike" "^2.0.0" + +"call-bind@^1.0.0": + "integrity" "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==" + "resolved" "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" + "version" "1.0.2" + dependencies: + "function-bind" "^1.1.1" + "get-intrinsic" "^1.0.2" + +"callsites@^3.0.0": + "integrity" "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + "resolved" "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + "version" "3.1.0" + +"camelcase@^4.0.0": + "integrity" "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + "resolved" "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz" + "version" "4.1.0" + +"camelcase@^5.0.0": + "integrity" "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "resolved" "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + "version" "5.3.1" + +"camelcase@^5.3.1": + "integrity" "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "resolved" "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + "version" "5.3.1" + +"caniuse-lite@^1.0.30001426", "caniuse-lite@^1.0.30001449": + "integrity" "sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA==" + "resolved" "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz" + "version" "1.0.30001457" + +"caseless@~0.12.0": + "integrity" "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "resolved" "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" + "version" "0.12.0" + +"chalk@^1.1.1", "chalk@^1.1.3": + "integrity" "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=" + "resolved" "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" + "version" "1.1.3" + dependencies: + "ansi-styles" "^2.2.1" + "escape-string-regexp" "^1.0.2" + "has-ansi" "^2.0.0" + "strip-ansi" "^3.0.0" + "supports-color" "^2.0.0" + +"chalk@^2.0.0": + "integrity" "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==" + "resolved" "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + "version" "2.4.2" + dependencies: + "ansi-styles" "^3.2.1" + "escape-string-regexp" "^1.0.5" + "supports-color" "^5.3.0" + +"chalk@^2.0.1": + "integrity" "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==" + "resolved" "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz" + "version" "2.4.1" + dependencies: + "ansi-styles" "^3.2.1" + "escape-string-regexp" "^1.0.5" + "supports-color" "^5.3.0" + +"chalk@^2.3.0", "chalk@^2.4.0": + "integrity" "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==" + "resolved" "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + "version" "2.4.2" + dependencies: + "ansi-styles" "^3.2.1" + "escape-string-regexp" "^1.0.5" + "supports-color" "^5.3.0" + +"chalk@^4.0.0": + "integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==" + "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + "version" "4.1.2" + dependencies: + "ansi-styles" "^4.1.0" + "supports-color" "^7.1.0" + +"chalk@^4.1.0": + "integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==" + "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + "version" "4.1.2" + dependencies: + "ansi-styles" "^4.1.0" + "supports-color" "^7.1.0" + +"chalk@^4.1.1": + "integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==" + "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + "version" "4.1.2" + dependencies: + "ansi-styles" "^4.1.0" + "supports-color" "^7.1.0" + +"chardet@^0.7.0": + "integrity" "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + "resolved" "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz" + "version" "0.7.0" + +"chokidar@^2.1.8": + "integrity" "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==" + "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz" + "version" "2.1.8" + dependencies: + "anymatch" "^2.0.0" + "async-each" "^1.0.1" + "braces" "^2.3.2" + "glob-parent" "~5.1.2" + "inherits" "^2.0.3" + "is-binary-path" "^1.0.0" + "is-glob" "^4.0.0" + "normalize-path" "^3.0.0" + "path-is-absolute" "^1.0.0" + "readdirp" "^2.2.1" + "upath" "^1.1.1" + optionalDependencies: + "fsevents" "^1.2.7" + +"chokidar@^3.0.0": + "integrity" "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==" + "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" + "version" "3.5.3" + dependencies: + "anymatch" "~3.1.2" + "braces" "~3.0.2" + "glob-parent" "~5.1.2" + "is-binary-path" "~2.1.0" + "is-glob" "~4.0.1" + "normalize-path" "~3.0.0" + "readdirp" "~3.6.0" + optionalDependencies: + "fsevents" "~2.3.2" + +"chokidar@^3.5.1": + "integrity" "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==" + "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" + "version" "3.5.3" + dependencies: + "anymatch" "~3.1.2" + "braces" "~3.0.2" + "glob-parent" "~5.1.2" + "is-binary-path" "~2.1.0" + "is-glob" "~4.0.1" + "normalize-path" "~3.0.0" + "readdirp" "~3.6.0" + optionalDependencies: + "fsevents" "~2.3.2" + +"chokidar@^3.5.2", "chokidar@3.5.3": + "integrity" "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==" + "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" + "version" "3.5.3" + dependencies: + "anymatch" "~3.1.2" + "braces" "~3.0.2" + "glob-parent" "~5.1.2" + "is-binary-path" "~2.1.0" + "is-glob" "~4.0.1" + "normalize-path" "~3.0.0" + "readdirp" "~3.6.0" + optionalDependencies: + "fsevents" "~2.3.2" + +"chokidar@^3.5.3": + "integrity" "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==" + "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" + "version" "3.5.3" + dependencies: + "anymatch" "~3.1.2" + "braces" "~3.0.2" + "glob-parent" "~5.1.2" + "is-binary-path" "~2.1.0" + "is-glob" "~4.0.1" + "normalize-path" "~3.0.0" + "readdirp" "~3.6.0" + optionalDependencies: + "fsevents" "~2.3.2" + +"chokidar@>=3.0.0 <4.0.0": + "integrity" "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==" + "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" + "version" "3.5.3" + dependencies: + "anymatch" "~3.1.2" + "braces" "~3.0.2" + "glob-parent" "~5.1.2" + "is-binary-path" "~2.1.0" + "is-glob" "~4.0.1" + "normalize-path" "~3.0.0" + "readdirp" "~3.6.0" + optionalDependencies: + "fsevents" "~2.3.2" + +"chownr@^2.0.0": + "integrity" "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + "resolved" "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" + "version" "2.0.0" + +"chrome-trace-event@^1.0.2": + "integrity" "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" + "resolved" "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz" + "version" "1.0.3" + +"ci-info@^1.5.0": + "integrity" "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==" + "resolved" "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz" + "version" "1.6.0" + +"class-utils@^0.3.5": + "integrity" "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==" + "resolved" "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz" + "version" "0.3.6" + dependencies: + "arr-union" "^3.1.0" + "define-property" "^0.2.5" + "isobject" "^3.0.0" + "static-extend" "^0.1.1" + +"clean-stack@^2.0.0": + "integrity" "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + "resolved" "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" + "version" "2.2.0" + +"cli-boxes@^1.0.0": + "integrity" "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" + "resolved" "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz" + "version" "1.0.0" + +"cli-cursor@^3.1.0": + "integrity" "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==" + "resolved" "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "restore-cursor" "^3.1.0" + +"cli-spinners@^2.5.0": + "integrity" "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==" + "resolved" "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz" + "version" "2.7.0" + +"cli-width@^3.0.0": + "integrity" "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" + "resolved" "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz" + "version" "3.0.0" + +"cliui@^6.0.0": + "integrity" "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==" + "resolved" "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "string-width" "^4.2.0" + "strip-ansi" "^6.0.0" + "wrap-ansi" "^6.2.0" + +"cliui@^7.0.2": + "integrity" "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==" + "resolved" "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" + "version" "7.0.4" + dependencies: + "string-width" "^4.2.0" + "strip-ansi" "^6.0.0" + "wrap-ansi" "^7.0.0" + +"cliui@^8.0.1": + "integrity" "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==" + "resolved" "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + "version" "8.0.1" + dependencies: + "string-width" "^4.2.0" + "strip-ansi" "^6.0.1" + "wrap-ansi" "^7.0.0" + +"clone-deep@^4.0.1": + "integrity" "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==" + "resolved" "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" + "version" "4.0.1" + dependencies: + "is-plain-object" "^2.0.4" + "kind-of" "^6.0.2" + "shallow-clone" "^3.0.0" + +"clone-response@^1.0.2": + "integrity" "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==" + "resolved" "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz" + "version" "1.0.3" + dependencies: + "mimic-response" "^1.0.0" + +"clone@^1.0.2": + "integrity" "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==" + "resolved" "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" + "version" "1.0.4" + +"codelyzer@^6.0.2": + "integrity" "sha512-v3+E0Ucu2xWJMOJ2fA/q9pDT/hlxHftHGPUay1/1cTgyPV5JTHFdO9hqo837Sx2s9vKBMTt5gO+lhF95PO6J+g==" + "resolved" "https://registry.npmjs.org/codelyzer/-/codelyzer-6.0.2.tgz" + "version" "6.0.2" dependencies: - ajv "^8.0.0" - -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" - -ajv-keywords@^5.0.0: - version "5.1.0" - resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz" + "@angular/compiler" "15.2.0" + "@angular/core" "15.2.0" + "app-root-path" "^3.0.0" + "aria-query" "^3.0.0" + "axobject-query" "2.0.2" + "css-selector-tokenizer" "^0.7.1" + "cssauron" "^1.4.0" + "damerau-levenshtein" "^1.0.4" + "rxjs" "^6.5.3" + "semver-dsl" "^1.0.1" + "source-map" "^0.5.7" + "sprintf-js" "^1.1.2" + "tslib" "^1.10.0" + "zone.js" "~0.10.3" + +"collection-visit@^1.0.0": + "integrity" "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=" + "resolved" "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "map-visit" "^1.0.0" + "object-visit" "^1.0.0" + +"color-convert@^1.9.0", "color-convert@^1.9.3": + "integrity" "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==" + "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + "version" "1.9.3" + dependencies: + "color-name" "1.1.3" + +"color-convert@^2.0.1": + "integrity" "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==" + "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "color-name" "~1.1.4" + +"color-name@^1.0.0", "color-name@1.1.3": + "integrity" "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + "version" "1.1.3" + +"color-name@~1.1.4": + "integrity" "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + "version" "1.1.4" + +"color-string@^1.6.0": + "integrity" "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==" + "resolved" "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" + "version" "1.9.1" + dependencies: + "color-name" "^1.0.0" + "simple-swizzle" "^0.2.2" + +"color-support@^1.1.3": + "integrity" "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + "resolved" "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz" + "version" "1.1.3" + +"color@^3.1.2": + "integrity" "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==" + "resolved" "https://registry.npmjs.org/color/-/color-3.2.1.tgz" + "version" "3.2.1" + dependencies: + "color-convert" "^1.9.3" + "color-string" "^1.6.0" + +"colorette@^2.0.10": + "integrity" "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" + "resolved" "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz" + "version" "2.0.19" + +"colors@1.4.0": + "integrity" "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + "resolved" "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz" + "version" "1.4.0" + +"combined-stream@~1.0.6", "combined-stream@1.0.6": + "integrity" "sha1-cj599ugBrFYTETp+RFqbactjKBg=" + "resolved" "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz" + "version" "1.0.6" + dependencies: + "delayed-stream" "~1.0.0" + +"commander@^2.11.0", "commander@^2.12.1", "commander@^2.20.0", "commander@^2.8.1": + "integrity" "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "resolved" "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + "version" "2.20.3" + +"commondir@^1.0.1": + "integrity" "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + "resolved" "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" + "version" "1.0.1" + +"component-emitter@^1.2.1": + "integrity" "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + "resolved" "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz" + "version" "1.2.1" + +"compressible@~2.0.16": + "integrity" "sha512-JQfEOdnI7dASwCuSPWIeVYwc/zMsu/+tRhoUvEfXz2gxOA2DNjmG5vhtFdBlhWPPGo+RdT9S3tgc/uH5qgDiiA==" + "resolved" "https://registry.npmjs.org/compressible/-/compressible-2.0.16.tgz" + "version" "2.0.16" + dependencies: + "mime-db" ">= 1.38.0 < 2" + +"compression@^1.7.4": + "integrity" "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==" + "resolved" "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz" + "version" "1.7.4" + dependencies: + "accepts" "~1.3.5" + "bytes" "3.0.0" + "compressible" "~2.0.16" + "debug" "2.6.9" + "on-headers" "~1.0.2" + "safe-buffer" "5.1.2" + "vary" "~1.1.2" + +"configstore@^3.0.0": + "integrity" "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==" + "resolved" "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz" + "version" "3.1.2" + dependencies: + "dot-prop" "^4.1.0" + "graceful-fs" "^4.1.2" + "make-dir" "^1.0.0" + "unique-string" "^1.0.0" + "write-file-atomic" "^2.0.0" + "xdg-basedir" "^3.0.0" + +"connect-history-api-fallback@^2.0.0": + "integrity" "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==" + "resolved" "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz" + "version" "2.0.0" + +"connect@^3.7.0": + "integrity" "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==" + "resolved" "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz" + "version" "3.7.0" + dependencies: + "debug" "2.6.9" + "finalhandler" "1.1.2" + "parseurl" "~1.3.3" + "utils-merge" "1.0.1" + +"console-control-strings@^1.1.0": + "integrity" "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + "resolved" "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" + "version" "1.1.0" + +"content-disposition@0.5.4": + "integrity" "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==" + "resolved" "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" + "version" "0.5.4" + dependencies: + "safe-buffer" "5.2.1" + +"content-type@~1.0.4": + "integrity" "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + "resolved" "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz" + "version" "1.0.4" + +"convert-source-map@^1.5.1", "convert-source-map@^1.7.0": + "integrity" "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==" + "resolved" "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz" + "version" "1.8.0" + dependencies: + "safe-buffer" "~5.1.1" + +"cookie-signature@1.0.6": + "integrity" "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "resolved" "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" + "version" "1.0.6" + +"cookie@~0.4.1": + "integrity" "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + "resolved" "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz" + "version" "0.4.1" + +"cookie@0.5.0": + "integrity" "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + "resolved" "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" + "version" "0.5.0" + +"copy-anything@^2.0.1": + "integrity" "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==" + "resolved" "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz" + "version" "2.0.6" + dependencies: + "is-what" "^3.14.1" + +"copy-descriptor@^0.1.0": + "integrity" "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + "resolved" "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz" + "version" "0.1.1" + +"copy-webpack-plugin@11.0.0": + "integrity" "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==" + "resolved" "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz" + "version" "11.0.0" + dependencies: + "fast-glob" "^3.2.11" + "glob-parent" "^6.0.1" + "globby" "^13.1.1" + "normalize-path" "^3.0.0" + "schema-utils" "^4.0.0" + "serialize-javascript" "^6.0.0" + +"core-js-compat@^3.25.1": + "integrity" "sha512-myzPgE7QodMg4nnd3K1TDoES/nADRStM8Gpz0D6nhkwbmwEnE0ZGJgoWsvQ722FR8D7xS0n0LV556RcEicjTyg==" + "resolved" "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.28.0.tgz" + "version" "3.28.0" + dependencies: + "browserslist" "^4.21.5" + +"core-js@^3.14.0": + "integrity" "sha512-vVl8j8ph6tRS3B8qir40H7yw7voy17xL0piAjlbBUsH7WIfzoedL/ZOr1OV9FyZQLWXsayOJyV4tnRyXR85/ag==" + "resolved" "https://registry.npmjs.org/core-js/-/core-js-3.20.3.tgz" + "version" "3.20.3" + +"core-util-is@~1.0.0", "core-util-is@1.0.2": + "integrity" "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "resolved" "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + "version" "1.0.2" + +"cors@~2.8.5": + "integrity" "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==" + "resolved" "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" + "version" "2.8.5" + dependencies: + "object-assign" "^4" + "vary" "^1" + +"cosmiconfig@^7.0.0": + "integrity" "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==" + "resolved" "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" + "version" "7.1.0" dependencies: - fast-deep-equal "^3.1.3" - -ajv@8.12.0, ajv@^8.8.0: - version "8.12.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" + "@types/parse-json" "^4.0.0" + "import-fresh" "^3.2.1" + "parse-json" "^5.0.0" + "path-type" "^4.0.0" + "yaml" "^1.10.0" + +"critters@0.0.16": + "integrity" "sha512-JwjgmO6i3y6RWtLYmXwO5jMd+maZt8Tnfu7VVISmEWyQqfLpB8soBswf8/2bu6SBXxtKA68Al3c+qIG1ApT68A==" + "resolved" "https://registry.npmjs.org/critters/-/critters-0.0.16.tgz" + "version" "0.0.16" + dependencies: + "chalk" "^4.1.0" + "css-select" "^4.2.0" + "parse5" "^6.0.1" + "parse5-htmlparser2-tree-adapter" "^6.0.1" + "postcss" "^8.3.7" + "pretty-bytes" "^5.3.0" + +"cross-spawn@^5.0.1": + "integrity" "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=" + "resolved" "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz" + "version" "5.1.0" + dependencies: + "lru-cache" "^4.0.1" + "shebang-command" "^1.2.0" + "which" "^1.2.9" + +"cross-spawn@^7.0.2": + "integrity" "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==" + "resolved" "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + "version" "7.0.3" + dependencies: + "path-key" "^3.1.0" + "shebang-command" "^2.0.0" + "which" "^2.0.1" + +"cross-spawn@^7.0.3": + "integrity" "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==" + "resolved" "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + "version" "7.0.3" + dependencies: + "path-key" "^3.1.0" + "shebang-command" "^2.0.0" + "which" "^2.0.1" + +"crypto-random-string@^1.0.0": + "integrity" "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" + "resolved" "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz" + "version" "1.0.0" + +"css-loader@6.7.3": + "integrity" "sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ==" + "resolved" "https://registry.npmjs.org/css-loader/-/css-loader-6.7.3.tgz" + "version" "6.7.3" + dependencies: + "icss-utils" "^5.1.0" + "postcss" "^8.4.19" + "postcss-modules-extract-imports" "^3.0.0" + "postcss-modules-local-by-default" "^4.0.0" + "postcss-modules-scope" "^3.0.0" + "postcss-modules-values" "^4.0.0" + "postcss-value-parser" "^4.2.0" + "semver" "^7.3.8" + +"css-select@^4.2.0": + "integrity" "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==" + "resolved" "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz" + "version" "4.3.0" + dependencies: + "boolbase" "^1.0.0" + "css-what" "^6.0.1" + "domhandler" "^4.3.1" + "domutils" "^2.8.0" + "nth-check" "^2.0.1" + +"css-selector-tokenizer@^0.7.1": + "integrity" "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==" + "resolved" "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz" + "version" "0.7.3" + dependencies: + "cssesc" "^3.0.0" + "fastparse" "^1.1.2" + +"css-what@^6.0.1": + "integrity" "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" + "resolved" "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" + "version" "6.1.0" + +"cssauron@^1.4.0": + "integrity" "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=" + "resolved" "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz" + "version" "1.4.0" + dependencies: + "through" "X.X.X" + +"cssesc@^3.0.0": + "integrity" "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + "resolved" "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" + "version" "3.0.0" + +"custom-event@~1.0.0": + "integrity" "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=" + "resolved" "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz" + "version" "1.0.1" + +"damerau-levenshtein@^1.0.4": + "integrity" "sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw==" + "resolved" "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz" + "version" "1.0.7" + +"dashdash@^1.12.0": + "integrity" "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=" + "resolved" "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz" + "version" "1.14.1" + dependencies: + "assert-plus" "^1.0.0" + +"date-format@^4.0.3": + "integrity" "sha512-7P3FyqDcfeznLZp2b+OMitV9Sz2lUnsT87WaTat9nVwqsBkTzPG3lPLNwW3en6F4pHUiWzr6vb8CLhjdK9bcxQ==" + "resolved" "https://registry.npmjs.org/date-format/-/date-format-4.0.3.tgz" + "version" "4.0.3" + +"debug@^2.2.0": + "integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==" + "resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + "version" "2.6.9" + dependencies: + "ms" "2.0.0" + +"debug@^2.3.3": + "integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==" + "resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + "version" "2.6.9" + dependencies: + "ms" "2.0.0" + +"debug@^3.1.0": + "integrity" "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==" + "resolved" "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz" + "version" "3.1.0" dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + "ms" "2.0.0" + +"debug@^3.2.6": + "integrity" "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==" + "resolved" "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + "version" "3.2.7" dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" + "ms" "^2.1.1" -ajv@^8.0.0: - version "8.10.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz" +"debug@^4.1.0": + "integrity" "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==" + "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + "version" "4.3.4" dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" + "ms" "2.1.2" -ansi-align@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz" +"debug@^4.1.1": + "integrity" "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==" + "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + "version" "4.3.4" dependencies: - string-width "^2.0.0" + "ms" "2.1.2" -ansi-colors@4.1.3: - version "4.1.3" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" - -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" +"debug@^4.3.2": + "integrity" "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==" + "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" + "version" "4.3.3" dependencies: - type-fest "^0.21.3" - -ansi-html-community@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" - -ansi-regex@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" + "ms" "2.1.2" -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" +"debug@^4.3.3": + "integrity" "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==" + "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" + "version" "4.3.3" dependencies: - color-convert "^1.9.0" + "ms" "2.1.2" -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" +"debug@~4.3.1": + "integrity" "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==" + "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + "version" "4.3.4" dependencies: - color-convert "^2.0.1" + "ms" "2.1.2" -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz" +"debug@~4.3.2": + "integrity" "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==" + "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" + "version" "4.3.3" dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" + "ms" "2.1.2" -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" +"debug@2.6.9": + "integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==" + "resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + "version" "2.6.9" dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" + "ms" "2.0.0" -app-root-path@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz" - -"aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz" - -are-we-there-yet@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz" +"debug@4": + "integrity" "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==" + "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + "version" "4.3.4" dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" + "ms" "2.1.2" -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" - dependencies: - sprintf-js "~1.0.2" +"decamelize@^1.2.0": + "integrity" "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + "resolved" "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" + "version" "1.2.0" -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" +"decode-uri-component@^0.2.0": + "integrity" "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" + "resolved" "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz" + "version" "0.2.2" -aria-query@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz" +"decompress-response@^6.0.0": + "integrity" "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==" + "resolved" "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz" + "version" "6.0.0" dependencies: - ast-types-flow "0.0.7" - commander "^2.11.0" + "mimic-response" "^3.1.0" -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz" +"deep-extend@^0.6.0": + "integrity" "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + "resolved" "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz" + "version" "0.6.0" -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz" +"deep-is@^0.1.3": + "integrity" "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + "resolved" "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" + "version" "0.1.4" -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz" - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" - -array-flatten@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz" - -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz" +"default-gateway@^6.0.3": + "integrity" "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==" + "resolved" "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz" + "version" "6.0.3" + dependencies: + "execa" "^5.0.0" + +"defaults@^1.0.3": + "integrity" "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==" + "resolved" "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz" + "version" "1.0.4" + dependencies: + "clone" "^1.0.2" + +"defer-to-connect@^2.0.1": + "integrity" "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" + "resolved" "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz" + "version" "2.0.1" + +"define-lazy-prop@^2.0.0": + "integrity" "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==" + "resolved" "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz" + "version" "2.0.0" + +"define-property@^0.2.5": + "integrity" "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=" + "resolved" "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz" + "version" "0.2.5" + dependencies: + "is-descriptor" "^0.1.0" + +"define-property@^1.0.0": + "integrity" "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=" + "resolved" "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "is-descriptor" "^1.0.0" + +"define-property@^2.0.2": + "integrity" "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==" + "resolved" "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz" + "version" "2.0.2" + dependencies: + "is-descriptor" "^1.0.2" + "isobject" "^3.0.1" + +"del@^2.2.0": + "integrity" "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=" + "resolved" "https://registry.npmjs.org/del/-/del-2.2.2.tgz" + "version" "2.2.2" + dependencies: + "globby" "^5.0.0" + "is-path-cwd" "^1.0.0" + "is-path-in-cwd" "^1.0.0" + "object-assign" "^4.0.1" + "pify" "^2.0.0" + "pinkie-promise" "^2.0.0" + "rimraf" "^2.2.8" + +"delayed-stream@~1.0.0": + "integrity" "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "resolved" "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + "version" "1.0.0" + +"delegates@^1.0.0": + "integrity" "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + "resolved" "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" + "version" "1.0.0" + +"depd@^1.1.2", "depd@~1.1.2": + "integrity" "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "resolved" "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" + "version" "1.1.2" + +"depd@2.0.0": + "integrity" "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + "resolved" "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" + "version" "2.0.0" + +"dependency-graph@^0.11.0": + "integrity" "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==" + "resolved" "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz" + "version" "0.11.0" + +"destroy@1.2.0": + "integrity" "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + "resolved" "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" + "version" "1.2.0" + +"detect-node@^2.0.4": + "integrity" "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==" + "resolved" "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz" + "version" "2.0.4" + +"di@^0.0.1": + "integrity" "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=" + "resolved" "https://registry.npmjs.org/di/-/di-0.0.1.tgz" + "version" "0.0.1" + +"diff@^3.1.0": + "integrity" "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + "resolved" "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" + "version" "3.5.0" + +"diff@^4.0.1": + "integrity" "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + "resolved" "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" + "version" "4.0.2" + +"dir-glob@^3.0.1": + "integrity" "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==" + "resolved" "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "path-type" "^4.0.0" + +"dns-equal@^1.0.0": + "integrity" "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" + "resolved" "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz" + "version" "1.0.0" + +"dns-packet@^5.2.2": + "integrity" "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==" + "resolved" "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz" + "version" "5.4.0" dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz" - -arrify@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + "@leichtgewicht/ip-codec" "^2.0.1" -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz" +"doctrine@^3.0.0": + "integrity" "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==" + "resolved" "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "esutils" "^2.0.2" + +"dom-serialize@^2.2.1": + "integrity" "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=" + "resolved" "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz" + "version" "2.2.1" + dependencies: + "custom-event" "~1.0.0" + "ent" "~2.2.0" + "extend" "^3.0.0" + "void-elements" "^2.0.0" + +"dom-serializer@^1.0.1": + "integrity" "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==" + "resolved" "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz" + "version" "1.4.1" + dependencies: + "domelementtype" "^2.0.1" + "domhandler" "^4.2.0" + "entities" "^2.0.0" + +"domelementtype@^2.0.1", "domelementtype@^2.2.0": + "integrity" "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + "resolved" "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" + "version" "2.3.0" + +"domhandler@^4.2.0", "domhandler@^4.3.1": + "integrity" "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==" + "resolved" "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz" + "version" "4.3.1" + dependencies: + "domelementtype" "^2.2.0" + +"domino@^2.1.2": + "integrity" "sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ==" + "resolved" "https://registry.npmjs.org/domino/-/domino-2.1.6.tgz" + "version" "2.1.6" + +"domutils@^2.8.0": + "integrity" "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==" + "resolved" "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz" + "version" "2.8.0" + dependencies: + "dom-serializer" "^1.0.1" + "domelementtype" "^2.2.0" + "domhandler" "^4.2.0" + +"dot-prop@^4.1.0": + "integrity" "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==" + "resolved" "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz" + "version" "4.2.1" + dependencies: + "is-obj" "^1.0.0" + +"ecc-jsbn@~0.1.1": + "integrity" "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=" + "resolved" "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" + "version" "0.1.2" + dependencies: + "jsbn" "~0.1.0" + "safer-buffer" "^2.1.0" + +"ee-first@1.1.1": + "integrity" "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "resolved" "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + "version" "1.1.1" + +"electron-to-chromium@^1.4.284": + "integrity" "sha512-qyTx2aDFjEni4UnRWEME9ubd2Xc9c0zerTUl/ZinvD4QPsF0S7kJTV/Es/lPCTkNX6smyYar+z/n8Cl6pFr8yQ==" + "resolved" "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.308.tgz" + "version" "1.4.308" + +"emoji-regex@^8.0.0": + "integrity" "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + "version" "8.0.0" + +"emojis-list@^3.0.0": + "integrity" "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" + "resolved" "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz" + "version" "3.0.0" + +"encodeurl@~1.0.2": + "integrity" "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "resolved" "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" + "version" "1.0.2" + +"encoding@^0.1.0", "encoding@^0.1.13": + "integrity" "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==" + "resolved" "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" + "version" "0.1.13" + dependencies: + "iconv-lite" "^0.6.2" + +"end-of-stream@^1.1.0": + "integrity" "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==" + "resolved" "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz" + "version" "1.4.1" + dependencies: + "once" "^1.4.0" + +"engine.io-parser@~5.0.3": + "integrity" "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==" + "resolved" "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz" + "version" "5.0.4" + +"engine.io@~6.2.0": + "integrity" "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==" + "resolved" "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz" + "version" "6.2.1" dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz" - -ast-types-flow@0.0.7: - version "0.0.7" - resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz" - -async-each@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz" - -async-limiter@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + "accepts" "~1.3.4" + "base64id" "2.0.0" + "cookie" "~0.4.1" + "cors" "~2.8.5" + "debug" "~4.3.1" + "engine.io-parser" "~5.0.3" + "ws" "~8.2.3" + +"enhanced-resolve@^5.10.0": + "integrity" "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==" + "resolved" "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz" + "version" "5.12.0" + dependencies: + "graceful-fs" "^4.2.4" + "tapable" "^2.2.0" + +"ent@~2.2.0": + "integrity" "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" + "resolved" "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz" + "version" "2.2.0" + +"entities@^2.0.0": + "integrity" "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + "resolved" "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" + "version" "2.2.0" + +"entities@^4.3.0", "entities@^4.4.0": + "integrity" "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==" + "resolved" "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz" + "version" "4.4.0" + +"env-paths@^2.2.0": + "integrity" "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" + "resolved" "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" + "version" "2.2.1" + +"err-code@^2.0.2": + "integrity" "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" + "resolved" "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz" + "version" "2.0.3" + +"errno@^0.1.1": + "integrity" "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==" + "resolved" "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz" + "version" "0.1.8" + dependencies: + "prr" "~1.0.1" + +"error-ex@^1.3.1": + "integrity" "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==" + "resolved" "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + "version" "1.3.2" + dependencies: + "is-arrayish" "^0.2.1" + +"es-module-lexer@^0.9.0": + "integrity" "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" + "resolved" "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz" + "version" "0.9.3" + +"es6-promise@^4.0.3": + "integrity" "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + "resolved" "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" + "version" "4.2.8" + +"es6-promisify@^5.0.0": + "integrity" "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=" + "resolved" "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "es6-promise" "^4.0.3" + +"esbuild-wasm@0.17.8": + "integrity" "sha512-zCmpxv95E0FuCmvdw1K836UHnj4EdiQnFfjTby35y3LAjRPtXMj3sbHDRHjbD8Mqg5lTwq3knacr/1qIFU51CQ==" + "resolved" "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.17.8.tgz" + "version" "0.17.8" + +"esbuild@0.17.8": + "integrity" "sha512-g24ybC3fWhZddZK6R3uD2iF/RIPnRpwJAqLov6ouX3hMbY4+tKolP0VMF3zuIYCaXun+yHwS5IPQ91N2BT191g==" + "resolved" "https://registry.npmjs.org/esbuild/-/esbuild-0.17.8.tgz" + "version" "0.17.8" + optionalDependencies: + "@esbuild/android-arm" "0.17.8" + "@esbuild/android-arm64" "0.17.8" + "@esbuild/android-x64" "0.17.8" + "@esbuild/darwin-arm64" "0.17.8" + "@esbuild/darwin-x64" "0.17.8" + "@esbuild/freebsd-arm64" "0.17.8" + "@esbuild/freebsd-x64" "0.17.8" + "@esbuild/linux-arm" "0.17.8" + "@esbuild/linux-arm64" "0.17.8" + "@esbuild/linux-ia32" "0.17.8" + "@esbuild/linux-loong64" "0.17.8" + "@esbuild/linux-mips64el" "0.17.8" + "@esbuild/linux-ppc64" "0.17.8" + "@esbuild/linux-riscv64" "0.17.8" + "@esbuild/linux-s390x" "0.17.8" + "@esbuild/linux-x64" "0.17.8" + "@esbuild/netbsd-x64" "0.17.8" + "@esbuild/openbsd-x64" "0.17.8" + "@esbuild/sunos-x64" "0.17.8" + "@esbuild/win32-arm64" "0.17.8" + "@esbuild/win32-ia32" "0.17.8" + "@esbuild/win32-x64" "0.17.8" -atob@^2.1.1: - version "2.1.2" - resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz" +"escalade@^3.1.1": + "integrity" "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "resolved" "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + "version" "3.1.1" -autoprefixer@10.4.13: - version "10.4.13" - resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz" - dependencies: - browserslist "^4.21.4" - caniuse-lite "^1.0.30001426" - fraction.js "^4.2.0" - normalize-range "^0.1.2" - picocolors "^1.0.0" - postcss-value-parser "^4.2.0" +"escape-html@~1.0.3": + "integrity" "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "resolved" "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" + "version" "1.0.3" -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" +"escape-string-regexp@^1.0.2", "escape-string-regexp@^1.0.5": + "integrity" "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + "version" "1.0.5" -aws4@^1.8.0: - version "1.8.0" - resolved "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz" +"escape-string-regexp@^4.0.0": + "integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + "version" "4.0.0" -axobject-query@2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz" +"eslint-scope@^7.1.1": + "integrity" "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==" + "resolved" "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz" + "version" "7.1.1" dependencies: - ast-types-flow "0.0.7" + "esrecurse" "^4.3.0" + "estraverse" "^5.2.0" -babel-loader@9.1.2: - version "9.1.2" - resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz" +"eslint-scope@5.1.1": + "integrity" "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==" + "resolved" "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" + "version" "5.1.1" dependencies: - find-cache-dir "^3.3.2" - schema-utils "^4.0.0" + "esrecurse" "^4.3.0" + "estraverse" "^4.1.1" -babel-plugin-istanbul@6.1.1: - version "6.1.1" - resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz" +"eslint-utils@^3.0.0": + "integrity" "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==" + "resolved" "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" + "version" "3.0.0" dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^5.0.4" - test-exclude "^6.0.0" + "eslint-visitor-keys" "^2.0.0" -babel-plugin-polyfill-corejs2@^0.3.3: - version "0.3.3" - resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz" - dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.3.3" - semver "^6.1.1" +"eslint-visitor-keys@^2.0.0": + "integrity" "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" + "resolved" "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" + "version" "2.1.0" -babel-plugin-polyfill-corejs3@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz" - dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - core-js-compat "^3.25.1" +"eslint-visitor-keys@^3.3.0": + "integrity" "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==" + "resolved" "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz" + "version" "3.3.0" -babel-plugin-polyfill-regenerator@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz" +"eslint@>=5", "eslint@8.10.0": + "integrity" "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==" + "resolved" "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz" + "version" "8.10.0" dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" - -base64-js@^1.2.0, base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" - -base64id@2.0.0, base64id@~2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz" - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz" - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" - dependencies: - tweetnacl "^0.14.3" - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz" - -binary-extensions@^1.0.0: - version "1.11.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz" - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" - -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - dependencies: - file-uri-to-path "1.0.0" - -bl@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -blocking-proxy@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz" - dependencies: - minimist "^1.2.6" - -body-parser@1.20.1, body-parser@^1.19.0: - version "1.20.1" - resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz" - 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.11.0" - raw-body "2.5.1" - type-is "~1.6.18" - unpipe "1.0.0" - -bonjour-service@^1.0.11: - version "1.1.0" - resolved "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.0.tgz" - dependencies: - array-flatten "^2.1.2" - dns-equal "^1.0.0" - fast-deep-equal "^3.1.3" - multicast-dns "^7.2.5" - -boolbase@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" - -bootstrap@5.2.3: - version "5.2.3" - resolved "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.3.tgz" - -boxen@^1.2.1: - version "1.3.0" - resolved "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz" - dependencies: - ansi-align "^2.0.0" - camelcase "^4.0.0" - chalk "^2.0.1" - cli-boxes "^1.0.0" - string-width "^2.0.0" - term-size "^1.2.0" - widest-line "^2.0.0" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" - dependencies: - balanced-match "^1.0.0" - -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz" - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - dependencies: - fill-range "^7.0.1" - -browserslist@4.21.5, browserslist@^4.14.5, browserslist@^4.21.3, browserslist@^4.21.4, browserslist@^4.21.5: - version "4.21.5" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz" - dependencies: - caniuse-lite "^1.0.30001449" - electron-to-chromium "^1.4.284" - node-releases "^2.0.8" - update-browserslist-db "^1.0.10" - -browserstack@^1.5.1: - version "1.6.1" - resolved "https://registry.npmjs.org/browserstack/-/browserstack-1.6.1.tgz" - dependencies: - https-proxy-agent "^2.2.1" - -buffer-from@^1.0.0, buffer-from@^1.1.0: - version "1.1.1" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz" - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz" - -builtins@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz" - dependencies: - semver "^7.0.0" - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" - -cacache@17.0.4, cacache@^17.0.0: - version "17.0.4" - resolved "https://registry.npmjs.org/cacache/-/cacache-17.0.4.tgz" + "@eslint/eslintrc" "^1.2.0" + "@humanwhocodes/config-array" "^0.9.2" + "ajv" "^6.10.0" + "chalk" "^4.0.0" + "cross-spawn" "^7.0.2" + "debug" "^4.3.2" + "doctrine" "^3.0.0" + "escape-string-regexp" "^4.0.0" + "eslint-scope" "^7.1.1" + "eslint-utils" "^3.0.0" + "eslint-visitor-keys" "^3.3.0" + "espree" "^9.3.1" + "esquery" "^1.4.0" + "esutils" "^2.0.2" + "fast-deep-equal" "^3.1.3" + "file-entry-cache" "^6.0.1" + "functional-red-black-tree" "^1.0.1" + "glob-parent" "^6.0.1" + "globals" "^13.6.0" + "ignore" "^5.2.0" + "import-fresh" "^3.0.0" + "imurmurhash" "^0.1.4" + "is-glob" "^4.0.0" + "js-yaml" "^4.1.0" + "json-stable-stringify-without-jsonify" "^1.0.1" + "levn" "^0.4.1" + "lodash.merge" "^4.6.2" + "minimatch" "^5.1.0" + "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" + +"espree@^9.3.1": + "integrity" "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==" + "resolved" "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz" + "version" "9.3.1" + dependencies: + "acorn" "^8.7.0" + "acorn-jsx" "^5.3.1" + "eslint-visitor-keys" "^3.3.0" + +"esprima@^4.0.0": + "integrity" "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + "resolved" "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" + "version" "4.0.1" + +"esquery@^1.4.0": + "integrity" "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==" + "resolved" "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" + "version" "1.4.0" + dependencies: + "estraverse" "^5.1.0" + +"esrecurse@^4.3.0": + "integrity" "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==" + "resolved" "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" + "version" "4.3.0" + dependencies: + "estraverse" "^5.2.0" + +"estraverse@^4.1.1": + "integrity" "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + "resolved" "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz" + "version" "4.2.0" + +"estraverse@^5.1.0": + "integrity" "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + "resolved" "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" + "version" "5.2.0" + +"estraverse@^5.2.0": + "integrity" "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + "resolved" "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" + "version" "5.3.0" + +"esutils@^2.0.2": + "integrity" "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + "resolved" "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz" + "version" "2.0.2" + +"etag@~1.8.1": + "integrity" "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + "resolved" "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" + "version" "1.8.1" + +"eventemitter-asyncresource@^1.0.0": + "integrity" "sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==" + "resolved" "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz" + "version" "1.0.0" + +"eventemitter3@^4.0.0": + "integrity" "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + "resolved" "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" + "version" "4.0.7" + +"events@^3.2.0": + "integrity" "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + "resolved" "https://registry.npmjs.org/events/-/events-3.3.0.tgz" + "version" "3.3.0" + +"eventsource@^2.0.2": + "integrity" "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==" + "resolved" "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz" + "version" "2.0.2" + dependencies: + "original" "^1.0.0" + +"execa@^0.7.0": + "integrity" "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=" + "resolved" "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz" + "version" "0.7.0" + dependencies: + "cross-spawn" "^5.0.1" + "get-stream" "^3.0.0" + "is-stream" "^1.1.0" + "npm-run-path" "^2.0.0" + "p-finally" "^1.0.0" + "signal-exit" "^3.0.0" + "strip-eof" "^1.0.0" + +"execa@^5.0.0": + "integrity" "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==" + "resolved" "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" + "version" "5.1.1" + dependencies: + "cross-spawn" "^7.0.3" + "get-stream" "^6.0.0" + "human-signals" "^2.1.0" + "is-stream" "^2.0.0" + "merge-stream" "^2.0.0" + "npm-run-path" "^4.0.1" + "onetime" "^5.1.2" + "signal-exit" "^3.0.3" + "strip-final-newline" "^2.0.0" + +"exit@^0.1.2": + "integrity" "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + "resolved" "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" + "version" "0.1.2" + +"expand-brackets@^2.1.4": + "integrity" "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=" + "resolved" "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz" + "version" "2.1.4" + dependencies: + "debug" "^2.3.3" + "define-property" "^0.2.5" + "extend-shallow" "^2.0.1" + "posix-character-classes" "^0.1.0" + "regex-not" "^1.0.0" + "snapdragon" "^0.8.1" + "to-regex" "^3.0.1" + +"express@^4.17.3": + "integrity" "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==" + "resolved" "https://registry.npmjs.org/express/-/express-4.18.2.tgz" + "version" "4.18.2" + dependencies: + "accepts" "~1.3.8" + "array-flatten" "1.1.1" + "body-parser" "1.20.1" + "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.11.0" + "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" + +"extend-shallow@^2.0.1": + "integrity" "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=" + "resolved" "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "is-extendable" "^0.1.0" + +"extend-shallow@^3.0.0", "extend-shallow@^3.0.2": + "integrity" "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=" + "resolved" "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "assign-symbols" "^1.0.0" + "is-extendable" "^1.0.1" + +"extend@^3.0.0", "extend@~3.0.2": + "integrity" "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "resolved" "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" + "version" "3.0.2" + +"external-editor@^3.0.3": + "integrity" "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==" + "resolved" "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "chardet" "^0.7.0" + "iconv-lite" "^0.4.24" + "tmp" "^0.0.33" + +"extglob@^2.0.4": + "integrity" "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==" + "resolved" "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz" + "version" "2.0.4" + dependencies: + "array-unique" "^0.3.2" + "define-property" "^1.0.0" + "expand-brackets" "^2.1.4" + "extend-shallow" "^2.0.1" + "fragment-cache" "^0.2.1" + "regex-not" "^1.0.0" + "snapdragon" "^0.8.1" + "to-regex" "^3.0.1" + +"extsprintf@^1.2.0", "extsprintf@1.3.0": + "integrity" "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "resolved" "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" + "version" "1.3.0" + +"fast-deep-equal@^3.1.1", "fast-deep-equal@^3.1.3": + "integrity" "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "resolved" "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + "version" "3.1.3" + +"fast-glob@^3.2.11": + "integrity" "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==" + "resolved" "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" + "version" "3.2.12" dependencies: - "@npmcli/fs" "^3.1.0" - fs-minipass "^3.0.0" - glob "^8.0.1" - lru-cache "^7.7.1" - minipass "^4.0.0" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - p-map "^4.0.0" - promise-inflight "^1.0.1" - ssri "^10.0.0" - tar "^6.1.11" - unique-filename "^3.0.0" - -cacache@^16.1.0: - version "16.1.3" - resolved "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz" + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + "glob-parent" "^5.1.2" + "merge2" "^1.3.0" + "micromatch" "^4.0.4" + +"fast-json-stable-stringify@^2.0.0": + "integrity" "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "resolved" "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + "version" "2.1.0" + +"fast-levenshtein@^2.0.6": + "integrity" "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + "resolved" "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + "version" "2.0.6" + +"fast-xml-parser@^3.19.0": + "integrity" "sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg==" + "resolved" "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz" + "version" "3.19.0" + +"fastparse@^1.1.2": + "integrity" "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==" + "resolved" "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz" + "version" "1.1.2" + +"fastq@^1.6.0": + "integrity" "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==" + "resolved" "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" + "version" "1.15.0" + dependencies: + "reusify" "^1.0.4" + +"faye-websocket@^0.11.3": + "integrity" "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==" + "resolved" "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz" + "version" "0.11.4" + dependencies: + "websocket-driver" ">=0.5.1" + +"figures@^3.0.0": + "integrity" "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==" + "resolved" "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz" + "version" "3.2.0" + dependencies: + "escape-string-regexp" "^1.0.5" + +"file-entry-cache@^6.0.1": + "integrity" "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==" + "resolved" "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" + "version" "6.0.1" + dependencies: + "flat-cache" "^3.0.4" + +"file-loader@*", "file-loader@^6.2.0": + "integrity" "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==" + "resolved" "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz" + "version" "6.2.0" + dependencies: + "loader-utils" "^2.0.0" + "schema-utils" "^3.0.0" + +"fill-range@^4.0.0": + "integrity" "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=" + "resolved" "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "extend-shallow" "^2.0.1" + "is-number" "^3.0.0" + "repeat-string" "^1.6.1" + "to-regex-range" "^2.1.0" + +"fill-range@^7.0.1": + "integrity" "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==" + "resolved" "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + "version" "7.0.1" + dependencies: + "to-regex-range" "^5.0.1" + +"finalhandler@1.1.2": + "integrity" "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==" + "resolved" "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz" + "version" "1.1.2" + dependencies: + "debug" "2.6.9" + "encodeurl" "~1.0.2" + "escape-html" "~1.0.3" + "on-finished" "~2.3.0" + "parseurl" "~1.3.3" + "statuses" "~1.5.0" + "unpipe" "~1.0.0" + +"finalhandler@1.2.0": + "integrity" "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==" + "resolved" "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" + "version" "1.2.0" + 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" + +"find-cache-dir@^3.3.2": + "integrity" "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==" + "resolved" "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz" + "version" "3.3.2" + dependencies: + "commondir" "^1.0.1" + "make-dir" "^3.0.2" + "pkg-dir" "^4.1.0" + +"find-up@^4.0.0", "find-up@^4.1.0": + "integrity" "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==" + "resolved" "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + "version" "4.1.0" + dependencies: + "locate-path" "^5.0.0" + "path-exists" "^4.0.0" + +"flat-cache@^3.0.4": + "integrity" "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==" + "resolved" "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" + "version" "3.0.4" + dependencies: + "flatted" "^3.1.0" + "rimraf" "^3.0.2" + +"flatted@^3.1.0", "flatted@^3.2.4": + "integrity" "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==" + "resolved" "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz" + "version" "3.2.5" + +"follow-redirects@^1.0.0": + "integrity" "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==" + "resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz" + "version" "1.14.8" + +"font-awesome@4.7.0": + "integrity" "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" + "resolved" "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz" + "version" "4.7.0" + +"for-in@^1.0.2": + "integrity" "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + "resolved" "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" + "version" "1.0.2" + +"forever-agent@~0.6.1": + "integrity" "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "resolved" "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" + "version" "0.6.1" + +"form-data-encoder@1.7.1": + "integrity" "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==" + "resolved" "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz" + "version" "1.7.1" + +"form-data@~2.3.2": + "integrity" "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=" + "resolved" "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz" + "version" "2.3.2" + dependencies: + "asynckit" "^0.4.0" + "combined-stream" "1.0.6" + "mime-types" "^2.1.12" + +"forwarded@0.2.0": + "integrity" "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + "resolved" "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" + "version" "0.2.0" + +"fraction.js@^4.2.0": + "integrity" "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==" + "resolved" "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz" + "version" "4.2.0" + +"fragment-cache@^0.2.1": + "integrity" "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=" + "resolved" "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz" + "version" "0.2.1" + dependencies: + "map-cache" "^0.2.2" + +"fresh@0.5.2": + "integrity" "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + "resolved" "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" + "version" "0.5.2" + +"front-matter@2.1.2": + "integrity" "sha1-91mDufL0E75ljJPf172M5AePXNs=" + "resolved" "https://registry.npmjs.org/front-matter/-/front-matter-2.1.2.tgz" + "version" "2.1.2" + dependencies: + "js-yaml" "^3.4.6" + +"fs-extra@^10.0.0": + "integrity" "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==" + "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz" + "version" "10.0.0" + dependencies: + "graceful-fs" "^4.2.0" + "jsonfile" "^6.0.1" + "universalify" "^2.0.0" + +"fs-extra@^3.0.1": + "integrity" "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=" + "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "graceful-fs" "^4.1.2" + "jsonfile" "^3.0.0" + "universalify" "^0.1.0" + +"fs-minipass@^2.0.0": + "integrity" "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==" + "resolved" "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "minipass" "^3.0.0" + +"fs-minipass@^2.1.0": + "integrity" "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==" + "resolved" "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "minipass" "^3.0.0" + +"fs-minipass@^3.0.0": + "integrity" "sha512-MhaJDcFRTuLidHrIttu0RDGyyXs/IYHVmlcxfLAEFIWjc1vdLAkdwT7Ace2u7DbitWC0toKMl5eJZRYNVreIMw==" + "resolved" "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "minipass" "^4.0.0" + +"fs-monkey@^1.0.3": + "integrity" "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" + "resolved" "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz" + "version" "1.0.3" + +"fs.realpath@^1.0.0": + "integrity" "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + "version" "1.0.0" + +"function-bind@^1.1.1": + "integrity" "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "resolved" "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + "version" "1.1.1" + +"functional-red-black-tree@^1.0.1": + "integrity" "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + "resolved" "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" + "version" "1.0.1" + +"gauge@^4.0.3": + "integrity" "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==" + "resolved" "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz" + "version" "4.0.4" + dependencies: + "aproba" "^1.0.3 || ^2.0.0" + "color-support" "^1.1.3" + "console-control-strings" "^1.1.0" + "has-unicode" "^2.0.1" + "signal-exit" "^3.0.7" + "string-width" "^4.2.3" + "strip-ansi" "^6.0.1" + "wide-align" "^1.1.5" + +"gensync@^1.0.0-beta.2": + "integrity" "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + "resolved" "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" + "version" "1.0.0-beta.2" + +"get-caller-file@^2.0.1", "get-caller-file@^2.0.5": + "integrity" "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + "resolved" "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + "version" "2.0.5" + +"get-intrinsic@^1.0.2": + "integrity" "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==" + "resolved" "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" + "version" "1.1.1" + dependencies: + "function-bind" "^1.1.1" + "has" "^1.0.3" + "has-symbols" "^1.0.1" + +"get-package-type@^0.1.0": + "integrity" "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + "resolved" "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" + "version" "0.1.0" + +"get-stream@^3.0.0": + "integrity" "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + "resolved" "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz" + "version" "3.0.0" + +"get-stream@^5.1.0": + "integrity" "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==" + "resolved" "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" + "version" "5.2.0" + dependencies: + "pump" "^3.0.0" + +"get-stream@^6.0.0": + "integrity" "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" + "resolved" "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" + "version" "6.0.1" + +"get-stream@^6.0.1": + "integrity" "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" + "resolved" "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" + "version" "6.0.1" + +"get-value@^2.0.3", "get-value@^2.0.6": + "integrity" "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + "resolved" "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" + "version" "2.0.6" + +"getpass@^0.1.1": + "integrity" "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=" + "resolved" "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz" + "version" "0.1.7" + dependencies: + "assert-plus" "^1.0.0" + +"glob-parent@^5.1.2", "glob-parent@~5.1.2": + "integrity" "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==" + "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + "version" "5.1.2" + dependencies: + "is-glob" "^4.0.1" + +"glob-parent@^6.0.1": + "integrity" "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==" + "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" + "version" "6.0.2" + dependencies: + "is-glob" "^4.0.3" + +"glob-to-regexp@^0.4.1": + "integrity" "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + "resolved" "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" + "version" "0.4.1" + +"glob@^7.0.0", "glob@^7.0.3", "glob@^7.0.6", "glob@^7.1.1", "glob@^7.1.3", "glob@^7.1.4", "glob@~7.1.1": + "integrity" "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==" + "resolved" "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz" + "version" "7.1.7" + dependencies: + "fs.realpath" "^1.0.0" + "inflight" "^1.0.4" + "inherits" "2" + "minimatch" "^5.1.0" + "once" "^1.3.0" + "path-is-absolute" "^1.0.0" + +"glob@^7.1.7": + "integrity" "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==" + "resolved" "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" + "version" "7.2.0" + dependencies: + "fs.realpath" "^1.0.0" + "inflight" "^1.0.4" + "inherits" "2" + "minimatch" "^5.1.0" + "once" "^1.3.0" + "path-is-absolute" "^1.0.0" + +"glob@^8.0.1": + "integrity" "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==" + "resolved" "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz" + "version" "8.1.0" + dependencies: + "fs.realpath" "^1.0.0" + "inflight" "^1.0.4" + "inherits" "2" + "minimatch" "^5.0.1" + "once" "^1.3.0" + +"glob@8.1.0": + "integrity" "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==" + "resolved" "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz" + "version" "8.1.0" + dependencies: + "fs.realpath" "^1.0.0" + "inflight" "^1.0.4" + "inherits" "2" + "minimatch" "^5.0.1" + "once" "^1.3.0" + +"global-dirs@^0.1.0": + "integrity" "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=" + "resolved" "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz" + "version" "0.1.1" + dependencies: + "ini" "^1.3.4" + +"globals@^11.1.0": + "integrity" "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + "resolved" "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" + "version" "11.12.0" + +"globals@^13.6.0", "globals@^13.9.0": + "integrity" "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==" + "resolved" "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz" + "version" "13.12.1" + dependencies: + "type-fest" "^0.20.2" + +"globby@^13.1.1": + "integrity" "sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==" + "resolved" "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz" + "version" "13.1.3" + dependencies: + "dir-glob" "^3.0.1" + "fast-glob" "^3.2.11" + "ignore" "^5.2.0" + "merge2" "^1.4.1" + "slash" "^4.0.0" + +"globby@^5.0.0": + "integrity" "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=" + "resolved" "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "array-union" "^1.0.1" + "arrify" "^1.0.0" + "glob" "^7.0.3" + "object-assign" "^4.0.1" + "pify" "^2.0.0" + "pinkie-promise" "^2.0.0" + +"globule@^1.0.0": + "integrity" "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==" + "resolved" "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz" + "version" "1.2.1" + dependencies: + "glob" "~7.1.1" + "lodash" "~4.17.10" + "minimatch" "~5.1.0" + +"gonzales-pe-sl@^4.2.3": + "integrity" "sha1-aoaLw4BkXxQf7rBCxvl/zHG1n+Y=" + "resolved" "https://registry.npmjs.org/gonzales-pe-sl/-/gonzales-pe-sl-4.2.3.tgz" + "version" "4.2.3" + dependencies: + "minimist" "1.2.6" + +"got@12.1.0": + "integrity" "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==" + "resolved" "https://registry.npmjs.org/got/-/got-12.1.0.tgz" + "version" "12.1.0" dependencies: - "@npmcli/fs" "^2.1.0" - "@npmcli/move-file" "^2.0.0" - chownr "^2.0.0" - fs-minipass "^2.1.0" - glob "^8.0.1" - infer-owner "^1.0.4" - lru-cache "^7.7.1" - minipass "^3.1.6" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - mkdirp "^1.0.4" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^9.0.0" - tar "^6.1.11" - unique-filename "^2.0.0" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz" - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -cacheable-lookup@^6.0.4: - version "6.1.0" - resolved "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz" - -cacheable-request@^7.0.2: - version "7.0.2" - resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz" - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^4.0.0" - lowercase-keys "^2.0.0" - normalize-url "^6.0.1" - responselike "^2.0.0" - -call-bind@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" - -camelcase@^4.0.0: - version "4.1.0" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz" - -camelcase@^5.0.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" - -caniuse-lite@^1.0.30001426, caniuse-lite@^1.0.30001449: - version "1.0.30001457" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" - -chalk@^1.1.1, chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.0: - version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^2.0.1: - version "2.4.1" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz" - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz" - -chokidar@3.5.3, "chokidar@>=3.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.5.1, chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chokidar@^2.1.8: - version "2.1.8" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz" - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "~5.1.2" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" + "@sindresorhus/is" "^4.6.0" + "@szmarczak/http-timer" "^5.0.1" + "@types/cacheable-request" "^6.0.2" + "@types/responselike" "^1.0.0" + "cacheable-lookup" "^6.0.4" + "cacheable-request" "^7.0.2" + "decompress-response" "^6.0.0" + "form-data-encoder" "1.7.1" + "get-stream" "^6.0.1" + "http2-wrapper" "^2.1.10" + "lowercase-keys" "^3.0.0" + "p-cancelable" "^3.0.0" + "responselike" "^2.0.0" + +"graceful-fs@^4.1.11", "graceful-fs@^4.1.2", "graceful-fs@^4.1.6", "graceful-fs@^4.2.0", "graceful-fs@^4.2.4", "graceful-fs@^4.2.6", "graceful-fs@^4.2.9": + "integrity" "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" + "resolved" "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz" + "version" "4.2.9" + +"handle-thing@^2.0.0": + "integrity" "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==" + "resolved" "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz" + "version" "2.0.0" + +"handlebars@^4.7.7": + "integrity" "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==" + "resolved" "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz" + "version" "4.7.7" + dependencies: + "minimist" "^1.2.6" + "neo-async" "^2.6.0" + "source-map" "^0.6.1" + "wordwrap" "^1.0.0" optionalDependencies: - fsevents "^1.2.7" - -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" - -chrome-trace-event@^1.0.2: - version "1.0.3" - resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz" - -ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz" - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" - -cli-boxes@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz" - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" - dependencies: - restore-cursor "^3.1.0" - -cli-spinners@^2.5.0: - version "2.7.0" - resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz" - -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz" - -cliui@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz" - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^6.2.0" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" + "uglify-js" "^3.1.4" + +"har-schema@^2.0.0": + "integrity" "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "resolved" "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" + "version" "2.0.0" + +"har-validator@~5.1.0": + "integrity" "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==" + "resolved" "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz" + "version" "5.1.5" + dependencies: + "ajv" "^6.12.3" + "har-schema" "^2.0.0" + +"has-ansi@^2.0.0": + "integrity" "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=" + "resolved" "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "ansi-regex" "^2.0.0" + +"has-flag@^3.0.0": + "integrity" "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + "version" "3.0.0" + +"has-flag@^4.0.0": + "integrity" "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + "version" "4.0.0" + +"has-symbols@^1.0.1": + "integrity" "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "resolved" "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz" + "version" "1.0.2" + +"has-unicode@^2.0.1": + "integrity" "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + "resolved" "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" + "version" "2.0.1" + +"has-value@^0.3.1": + "integrity" "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=" + "resolved" "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz" + "version" "0.3.1" + dependencies: + "get-value" "^2.0.3" + "has-values" "^0.1.4" + "isobject" "^2.0.0" + +"has-value@^1.0.0": + "integrity" "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=" + "resolved" "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "get-value" "^2.0.6" + "has-values" "^1.0.0" + "isobject" "^3.0.0" + +"has-values@^0.1.4": + "integrity" "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + "resolved" "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz" + "version" "0.1.4" + +"has-values@^1.0.0": + "integrity" "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=" + "resolved" "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "is-number" "^3.0.0" + "kind-of" "^4.0.0" + +"has@^1.0.3": + "integrity" "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==" + "resolved" "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + "version" "1.0.3" + dependencies: + "function-bind" "^1.1.1" + +"hdr-histogram-js@^2.0.1": + "integrity" "sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g==" + "resolved" "https://registry.npmjs.org/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz" + "version" "2.0.3" dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + "@assemblyscript/loader" "^0.10.1" + "base64-js" "^1.2.0" + "pako" "^1.0.3" + +"hdr-histogram-percentiles-obj@^3.0.0": + "integrity" "sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==" + "resolved" "https://registry.npmjs.org/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz" + "version" "3.0.0" + +"hosted-git-info@^6.0.0": + "integrity" "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==" + "resolved" "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz" + "version" "6.1.1" + dependencies: + "lru-cache" "^7.5.1" + +"hpack.js@^2.1.6": + "integrity" "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=" + "resolved" "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz" + "version" "2.1.6" + dependencies: + "inherits" "^2.0.1" + "obuf" "^1.0.0" + "readable-stream" "^2.0.1" + "wbuf" "^1.1.0" + +"html-entities@^2.3.2": + "integrity" "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==" + "resolved" "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz" + "version" "2.3.2" + +"http-cache-semantics@^4.0.0", "http-cache-semantics@^4.1.0", "http-cache-semantics@^4.1.1": + "integrity" "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + "resolved" "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz" + "version" "4.1.1" + +"http-deceiver@^1.2.7": + "integrity" "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" + "resolved" "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" + "version" "1.2.7" + +"http-errors@~1.6.2": + "integrity" "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=" + "resolved" "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" + "version" "1.6.3" + dependencies: + "depd" "~1.1.2" + "inherits" "2.0.3" + "setprototypeof" "1.1.0" + "statuses" ">= 1.4.0 < 2" + +"http-errors@2.0.0": + "integrity" "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==" + "resolved" "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "depd" "2.0.0" + "inherits" "2.0.4" + "setprototypeof" "1.2.0" + "statuses" "2.0.1" + "toidentifier" "1.0.1" + +"http-parser-js@>=0.5.1": + "integrity" "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==" + "resolved" "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz" + "version" "0.5.5" + +"http-proxy-agent@^5.0.0": + "integrity" "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==" + "resolved" "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz" + "version" "5.0.0" dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" + "@tootallnate/once" "2" + "agent-base" "6" + "debug" "4" -clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" +"http-proxy-middleware@^2.0.3": + "integrity" "sha512-1bloEwnrHMnCoO/Gcwbz7eSVvW50KPES01PecpagI+YLNLci4AcuKJrujW4Mc3sBLpFxMSlsLNHS5Nl/lvrTPA==" + "resolved" "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.3.tgz" + "version" "2.0.3" dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -clone-response@^1.0.2: - version "1.0.3" - resolved "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz" + "@types/http-proxy" "^1.17.8" + "http-proxy" "^1.18.1" + "is-glob" "^4.0.1" + "is-plain-obj" "^3.0.0" + "micromatch" "^4.0.2" + +"http-proxy@^1.18.1": + "integrity" "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==" + "resolved" "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz" + "version" "1.18.1" + dependencies: + "eventemitter3" "^4.0.0" + "follow-redirects" "^1.0.0" + "requires-port" "^1.0.0" + +"http-signature@~1.2.0": + "integrity" "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=" + "resolved" "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz" + "version" "1.2.0" + dependencies: + "assert-plus" "^1.0.0" + "jsprim" "^1.2.2" + "sshpk" "^1.7.0" + +"http2-wrapper@^2.1.10": + "integrity" "sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==" + "resolved" "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz" + "version" "2.1.11" + dependencies: + "quick-lru" "^5.1.1" + "resolve-alpn" "^1.2.0" + +"https-proxy-agent@^2.2.1": + "integrity" "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==" + "resolved" "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz" + "version" "2.2.4" + dependencies: + "agent-base" "^4.3.0" + "debug" "^3.1.0" + +"https-proxy-agent@^5.0.0", "https-proxy-agent@5.0.1": + "integrity" "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==" + "resolved" "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" + "version" "5.0.1" + dependencies: + "agent-base" "6" + "debug" "4" + +"human-signals@^2.1.0": + "integrity" "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" + "resolved" "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" + "version" "2.1.0" + +"humanize-ms@^1.2.1": + "integrity" "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==" + "resolved" "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz" + "version" "1.2.1" + dependencies: + "ms" "^2.0.0" + +"iconv-lite@^0.4.24", "iconv-lite@0.4.24": + "integrity" "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==" + "resolved" "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" + "version" "0.4.24" + dependencies: + "safer-buffer" ">= 2.1.2 < 3" + +"iconv-lite@^0.6.2": + "integrity" "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==" + "resolved" "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + "version" "0.6.3" + dependencies: + "safer-buffer" ">= 2.1.2 < 3.0.0" + +"iconv-lite@^0.6.3": + "integrity" "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==" + "resolved" "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + "version" "0.6.3" + dependencies: + "safer-buffer" ">= 2.1.2 < 3.0.0" + +"icss-utils@^5.0.0", "icss-utils@^5.1.0": + "integrity" "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==" + "resolved" "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz" + "version" "5.1.0" + +"ieee754@^1.1.13": + "integrity" "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + "resolved" "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + "version" "1.2.1" + +"ignore-by-default@^1.0.1": + "integrity" "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" + "resolved" "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz" + "version" "1.0.1" + +"ignore-walk@^6.0.0": + "integrity" "sha512-/c8MxUAqpRccq+LyDOecwF+9KqajueJHh8fz7g3YqjMZt+NSfJzx05zrKiXwa2sKwFCzaiZ5qUVfRj0pmxixEA==" + "resolved" "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.1.tgz" + "version" "6.0.1" + dependencies: + "minimatch" "^6.1.6" + +"ignore@^4.0.6": + "integrity" "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + "resolved" "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" + "version" "4.0.6" + +"ignore@^5.2.0": + "integrity" "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" + "resolved" "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" + "version" "5.2.0" + +"image-size@~0.5.0": + "integrity" "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==" + "resolved" "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz" + "version" "0.5.5" + +"immediate@~3.0.5": + "integrity" "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" + "resolved" "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz" + "version" "3.0.6" + +"immutable@^4.0.0": + "integrity" "sha512-WDxL3Hheb1JkRN3sQkyujNlL/xRjAo3rJtaU5xeufUauG66JdMr32bLj4gF+vWl84DIA3Zxw7tiAjneYzRRw+w==" + "resolved" "https://registry.npmjs.org/immutable/-/immutable-4.2.4.tgz" + "version" "4.2.4" + +"import-fresh@^3.0.0", "import-fresh@^3.2.1": + "integrity" "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==" + "resolved" "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" + "version" "3.3.0" + dependencies: + "parent-module" "^1.0.0" + "resolve-from" "^4.0.0" + +"import-lazy@^2.1.0": + "integrity" "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + "resolved" "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz" + "version" "2.1.0" + +"imurmurhash@^0.1.4": + "integrity" "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "resolved" "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + "version" "0.1.4" + +"indent-string@^4.0.0": + "integrity" "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + "resolved" "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" + "version" "4.0.0" + +"infer-owner@^1.0.4": + "integrity" "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + "resolved" "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz" + "version" "1.0.4" + +"inflight@^1.0.4": + "integrity" "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=" + "resolved" "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + "version" "1.0.6" + dependencies: + "once" "^1.3.0" + "wrappy" "1" + +"inherits@^2.0.1", "inherits@^2.0.3", "inherits@~2.0.3", "inherits@2", "inherits@2.0.3": + "integrity" "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + "version" "2.0.3" + +"inherits@^2.0.4": + "integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + "version" "2.0.4" + +"inherits@2.0.4": + "integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + "version" "2.0.4" + +"ini@^1.3.4", "ini@~1.3.0": + "integrity" "sha512-IZUoxEjNjubzrmvzZU4lKP7OnYmX72XRl3sqkfJhBKweKi5rnGi5+IUdlj/H1M+Ip5JQ1WzaDMOBRY90Ajc5jg==" + "resolved" "https://registry.npmjs.org/ini/-/ini-1.3.6.tgz" + "version" "1.3.6" + +"ini@3.0.1": + "integrity" "sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==" + "resolved" "https://registry.npmjs.org/ini/-/ini-3.0.1.tgz" + "version" "3.0.1" + +"inquirer@8.2.4": + "integrity" "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==" + "resolved" "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz" + "version" "8.2.4" + dependencies: + "ansi-escapes" "^4.2.1" + "chalk" "^4.1.1" + "cli-cursor" "^3.1.0" + "cli-width" "^3.0.0" + "external-editor" "^3.0.3" + "figures" "^3.0.0" + "lodash" "^4.17.21" + "mute-stream" "0.0.8" + "ora" "^5.4.1" + "run-async" "^2.4.0" + "rxjs" "^7.5.5" + "string-width" "^4.1.0" + "strip-ansi" "^6.0.0" + "through" "^2.3.6" + "wrap-ansi" "^7.0.0" + +"interpret@^1.0.0": + "integrity" "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + "resolved" "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz" + "version" "1.4.0" + +"ip@^2.0.0": + "integrity" "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + "resolved" "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz" + "version" "2.0.0" + +"ipaddr.js@^2.0.1": + "integrity" "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==" + "resolved" "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz" + "version" "2.0.1" + +"ipaddr.js@1.9.1": + "integrity" "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + "resolved" "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" + "version" "1.9.1" + +"is-accessor-descriptor@^0.1.6": + "integrity" "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=" + "resolved" "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz" + "version" "0.1.6" + dependencies: + "kind-of" "^3.0.2" + +"is-accessor-descriptor@^1.0.0": + "integrity" "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==" + "resolved" "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "kind-of" "^6.0.0" + +"is-arrayish@^0.2.1": + "integrity" "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "resolved" "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + "version" "0.2.1" + +"is-arrayish@^0.3.1": + "integrity" "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + "resolved" "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz" + "version" "0.3.2" + +"is-binary-path@^1.0.0": + "integrity" "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=" + "resolved" "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "binary-extensions" "^1.0.0" + +"is-binary-path@~2.1.0": + "integrity" "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==" + "resolved" "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "binary-extensions" "^2.0.0" + +"is-buffer@^1.1.5": + "integrity" "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + "resolved" "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" + "version" "1.1.6" + +"is-ci@^1.0.10": + "integrity" "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==" + "resolved" "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz" + "version" "1.2.1" + dependencies: + "ci-info" "^1.5.0" + +"is-core-module@^2.8.1", "is-core-module@^2.9.0": + "integrity" "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==" + "resolved" "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz" + "version" "2.11.0" + dependencies: + "has" "^1.0.3" + +"is-data-descriptor@^0.1.4": + "integrity" "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=" + "resolved" "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz" + "version" "0.1.4" + dependencies: + "kind-of" "^3.0.2" + +"is-data-descriptor@^1.0.0": + "integrity" "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==" + "resolved" "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "kind-of" "^6.0.0" + +"is-descriptor@^0.1.0": + "integrity" "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==" + "resolved" "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz" + "version" "0.1.6" + dependencies: + "is-accessor-descriptor" "^0.1.6" + "is-data-descriptor" "^0.1.4" + "kind-of" "^5.0.0" + +"is-descriptor@^1.0.0": + "integrity" "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==" + "resolved" "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz" + "version" "1.0.2" + dependencies: + "is-accessor-descriptor" "^1.0.0" + "is-data-descriptor" "^1.0.0" + "kind-of" "^6.0.2" + +"is-descriptor@^1.0.2": + "integrity" "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==" + "resolved" "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz" + "version" "1.0.2" + dependencies: + "is-accessor-descriptor" "^1.0.0" + "is-data-descriptor" "^1.0.0" + "kind-of" "^6.0.2" + +"is-docker@^2.0.0", "is-docker@^2.1.1": + "integrity" "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" + "resolved" "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" + "version" "2.2.1" + +"is-extendable@^0.1.0", "is-extendable@^0.1.1": + "integrity" "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + "resolved" "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" + "version" "0.1.1" + +"is-extendable@^1.0.1": + "integrity" "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==" + "resolved" "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "is-plain-object" "^2.0.4" + +"is-extglob@^2.1.1": + "integrity" "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "resolved" "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + "version" "2.1.1" + +"is-fullwidth-code-point@^2.0.0": + "integrity" "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "resolved" "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" + "version" "2.0.0" + +"is-fullwidth-code-point@^3.0.0": + "integrity" "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "resolved" "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + "version" "3.0.0" + +"is-glob@^4.0.0", "is-glob@^4.0.1", "is-glob@^4.0.3", "is-glob@~4.0.1": + "integrity" "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==" + "resolved" "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + "version" "4.0.3" + dependencies: + "is-extglob" "^2.1.1" + +"is-installed-globally@^0.1.0": + "integrity" "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=" + "resolved" "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz" + "version" "0.1.0" + dependencies: + "global-dirs" "^0.1.0" + "is-path-inside" "^1.0.0" + +"is-interactive@^1.0.0": + "integrity" "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==" + "resolved" "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz" + "version" "1.0.0" + +"is-lambda@^1.0.1": + "integrity" "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==" + "resolved" "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz" + "version" "1.0.1" + +"is-npm@^1.0.0": + "integrity" "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" + "resolved" "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz" + "version" "1.0.0" + +"is-number@^3.0.0": + "integrity" "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=" + "resolved" "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "kind-of" "^3.0.2" + +"is-number@^7.0.0": + "integrity" "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "resolved" "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + "version" "7.0.0" + +"is-obj@^1.0.0": + "integrity" "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + "resolved" "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz" + "version" "1.0.1" + +"is-path-cwd@^1.0.0": + "integrity" "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" + "resolved" "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz" + "version" "1.0.0" + +"is-path-in-cwd@^1.0.0": + "integrity" "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==" + "resolved" "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "is-path-inside" "^1.0.0" + +"is-path-inside@^1.0.0": + "integrity" "sha1-jvW33lBDej/cprToZe96pVy0gDY=" + "resolved" "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "path-is-inside" "^1.0.1" + +"is-plain-obj@^3.0.0": + "integrity" "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" + "resolved" "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz" + "version" "3.0.0" + +"is-plain-object@^2.0.3", "is-plain-object@^2.0.4": + "integrity" "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==" + "resolved" "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" + "version" "2.0.4" + dependencies: + "isobject" "^3.0.1" + +"is-stream@^1.1.0": + "integrity" "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + "resolved" "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz" + "version" "1.1.0" + +"is-stream@^2.0.0": + "integrity" "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + "resolved" "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + "version" "2.0.1" + +"is-svg@>=4.2.2": + "integrity" "sha512-h2CGs+yPUyvkgTJQS9cJzo9lYK06WgRiXUqBBHtglSzVKAuH4/oWsqk7LGfbSa1hGk9QcZ0SyQtVggvBA8LZXA==" + "resolved" "https://registry.npmjs.org/is-svg/-/is-svg-4.3.1.tgz" + "version" "4.3.1" + dependencies: + "fast-xml-parser" "^3.19.0" + +"is-typedarray@~1.0.0": + "integrity" "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "resolved" "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" + "version" "1.0.0" + +"is-unicode-supported@^0.1.0": + "integrity" "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + "resolved" "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + "version" "0.1.0" + +"is-what@^3.14.1": + "integrity" "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==" + "resolved" "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz" + "version" "3.14.1" + +"is-windows@^1.0.2": + "integrity" "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + "resolved" "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" + "version" "1.0.2" + +"is-wsl@^2.2.0": + "integrity" "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==" + "resolved" "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" + "version" "2.2.0" + dependencies: + "is-docker" "^2.0.0" + +"isarray@~1.0.0", "isarray@1.0.0": + "integrity" "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "resolved" "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + "version" "1.0.0" + +"isbinaryfile@^4.0.8": + "integrity" "sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==" + "resolved" "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz" + "version" "4.0.8" + +"isexe@^2.0.0": + "integrity" "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "resolved" "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + "version" "2.0.0" + +"isobject@^2.0.0": + "integrity" "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=" + "resolved" "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "isarray" "1.0.0" + +"isobject@^3.0.0", "isobject@^3.0.1": + "integrity" "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "resolved" "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" + "version" "3.0.1" + +"isomorphic-fetch@3.0.0": + "integrity" "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==" + "resolved" "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "node-fetch" "^2.6.1" + "whatwg-fetch" "^3.4.1" + +"isstream@~0.1.2": + "integrity" "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "resolved" "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" + "version" "0.1.2" + +"istanbul-lib-coverage@^3.2.0": + "integrity" "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==" + "resolved" "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz" + "version" "3.2.0" + +"istanbul-lib-instrument@^5.0.4": + "integrity" "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==" + "resolved" "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz" + "version" "5.2.1" dependencies: - mimic-response "^1.0.0" - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + "istanbul-lib-coverage" "^3.2.0" + "semver" "^6.3.0" -codelyzer@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/codelyzer/-/codelyzer-6.0.2.tgz" - dependencies: - "@angular/compiler" "15.2.0" - "@angular/core" "15.2.0" - app-root-path "^3.0.0" - aria-query "^3.0.0" - axobject-query "2.0.2" - css-selector-tokenizer "^0.7.1" - cssauron "^1.4.0" - damerau-levenshtein "^1.0.4" - rxjs "^6.5.3" - semver-dsl "^1.0.1" - source-map "^0.5.7" - sprintf-js "^1.1.2" - tslib "^1.10.0" - zone.js "~0.10.3" - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz" - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0, color-convert@^1.9.3: - version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - dependencies: - color-name "~1.1.4" - -color-name@1.1.3, color-name@^1.0.0: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - -color-string@^1.6.0: - version "1.9.1" - resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" +"jasmine-core@^4.0.0", "jasmine-core@^4.1.0", "jasmine-core@4.5.0": + "integrity" "sha512-9PMzyvhtocxb3aXJVOPqBDswdgyAeSB81QnLop4npOpbqnheaTEwPc9ZloQeVswugPManznQBjD8kWDTjlnHuw==" + "resolved" "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.5.0.tgz" + "version" "4.5.0" -color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz" +"jasmine-core@~2.8.0": + "integrity" "sha512-SNkOkS+/jMZvLhuSx1fjhcNWUC/KG6oVyFUGkSBEr9n1axSNduWU8GlI7suaHXr4yxjet6KjrUZxUTE5WzzWwQ==" + "resolved" "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz" + "version" "2.8.0" -color@^3.1.2: - version "3.2.1" - resolved "https://registry.npmjs.org/color/-/color-3.2.1.tgz" +"jasmine-spec-reporter@7.0.0": + "integrity" "sha512-OtC7JRasiTcjsaCBPtMO0Tl8glCejM4J4/dNuOJdA8lBjz4PmWjYQ6pzb0uzpBNAWJMDudYuj9OdXJWqM2QTJg==" + "resolved" "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-7.0.0.tgz" + "version" "7.0.0" dependencies: - color-convert "^1.9.3" - color-string "^1.6.0" - -colorette@^2.0.10: - version "2.0.19" - resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz" + "colors" "1.4.0" -colors@1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz" - -combined-stream@1.0.6, combined-stream@~1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz" +"jasmine@2.8.0": + "integrity" "sha1-awicChFXax8W3xG4AUbZHU6Lij4=" + "resolved" "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz" + "version" "2.8.0" dependencies: - delayed-stream "~1.0.0" + "exit" "^0.1.2" + "glob" "^7.0.6" + "jasmine-core" "~2.8.0" -commander@^2.11.0, commander@^2.12.1, commander@^2.20.0, commander@^2.8.1: - version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" - -component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz" - -compressible@~2.0.16: - version "2.0.16" - resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.16.tgz" - dependencies: - mime-db ">= 1.38.0 < 2" +"jasminewd2@^2.1.0": + "integrity" "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=" + "resolved" "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz" + "version" "2.2.0" -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz" +"jest-worker@^27.4.5": + "integrity" "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==" + "resolved" "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz" + "version" "27.5.1" dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" + "@types/node" "*" + "merge-stream" "^2.0.0" + "supports-color" "^8.0.0" + +"jquery@3.5.0": + "integrity" "sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ==" + "resolved" "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz" + "version" "3.5.0" + +"js-tokens@^4.0.0": + "integrity" "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "resolved" "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + "version" "4.0.0" + +"js-yaml@^3.13.1", "js-yaml@^3.4.6", "js-yaml@^3.5.4": + "integrity" "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==" + "resolved" "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz" + "version" "3.13.1" + dependencies: + "argparse" "^1.0.7" + "esprima" "^4.0.0" + +"js-yaml@^4.1.0": + "integrity" "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==" + "resolved" "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + "version" "4.1.0" + dependencies: + "argparse" "^2.0.1" + +"jsbn@~0.1.0": + "integrity" "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "resolved" "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" + "version" "0.1.1" + +"jsesc@^2.5.1": + "integrity" "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "resolved" "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" + "version" "2.5.2" + +"jsesc@~0.5.0": + "integrity" "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" + "resolved" "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" + "version" "0.5.0" + +"json-buffer@3.0.1": + "integrity" "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + "resolved" "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" + "version" "3.0.1" + +"json-parse-even-better-errors@^2.3.0", "json-parse-even-better-errors@^2.3.1": + "integrity" "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + "resolved" "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" + "version" "2.3.1" + +"json-parse-even-better-errors@^3.0.0": + "integrity" "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==" + "resolved" "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz" + "version" "3.0.0" + +"json-schema-traverse@^0.4.1": + "integrity" "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "resolved" "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + "version" "0.4.1" + +"json-schema-traverse@^1.0.0": + "integrity" "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "resolved" "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" + "version" "1.0.0" + +"json-schema@0.4.0": + "integrity" "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + "resolved" "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" + "version" "0.4.0" + +"json-stable-stringify-without-jsonify@^1.0.1": + "integrity" "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + "resolved" "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" + "version" "1.0.1" + +"json-stringify-safe@~5.0.1": + "integrity" "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "resolved" "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + "version" "5.0.1" + +"json5@^2.1.0", "json5@^2.1.2", "json5@^2.2.1", "json5@^2.2.2": + "integrity" "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + "resolved" "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + "version" "2.2.3" + +"jsonc-parser@3.2.0": + "integrity" "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" + "resolved" "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz" + "version" "3.2.0" + +"jsonfile@^3.0.0": + "integrity" "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=" + "resolved" "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz" + "version" "3.0.1" + optionalDependencies: + "graceful-fs" "^4.1.6" -configstore@^3.0.0: - version "3.1.2" - resolved "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz" +"jsonfile@^6.0.1": + "integrity" "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==" + "resolved" "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" + "version" "6.1.0" dependencies: - dot-prop "^4.1.0" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - unique-string "^1.0.0" - write-file-atomic "^2.0.0" - xdg-basedir "^3.0.0" + "universalify" "^2.0.0" + optionalDependencies: + "graceful-fs" "^4.1.6" -connect-history-api-fallback@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz" +"jsonparse@^1.3.1": + "integrity" "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==" + "resolved" "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" + "version" "1.3.1" -connect@^3.7.0: - version "3.7.0" - resolved "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz" +"jsprim@^1.2.2": + "integrity" "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==" + "resolved" "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz" + "version" "1.4.2" dependencies: - debug "2.6.9" - finalhandler "1.1.2" - parseurl "~1.3.3" - utils-merge "1.0.1" + "assert-plus" "1.0.0" + "extsprintf" "1.3.0" + "json-schema" "0.4.0" + "verror" "1.10.0" -console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" +"jszip@^3.1.3": + "integrity" "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==" + "resolved" "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz" + "version" "3.10.1" dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz" + "lie" "~3.3.0" + "pako" "~1.0.2" + "readable-stream" "~2.3.6" + "setimmediate" "^1.0.5" -convert-source-map@^1.5.1, convert-source-map@^1.7.0: - version "1.8.0" - resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz" +"karma-chrome-launcher@^3.1.1": + "integrity" "sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==" + "resolved" "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz" + "version" "3.1.1" dependencies: - safe-buffer "~5.1.1" + "which" "^1.2.1" -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" - -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" - -cookie@~0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz" - -copy-anything@^2.0.1: - version "2.0.6" - resolved "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz" +"karma-cli@^2.0.0": + "integrity" "sha512-1Kb28UILg1ZsfqQmeELbPzuEb5C6GZJfVIk0qOr8LNYQuYWmAaqP16WpbpKEjhejDrDYyYOwwJXSZO6u7q5Pvw==" + "resolved" "https://registry.npmjs.org/karma-cli/-/karma-cli-2.0.0.tgz" + "version" "2.0.0" dependencies: - is-what "^3.14.1" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz" + "resolve" "^1.3.3" -copy-webpack-plugin@11.0.0: - version "11.0.0" - resolved "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz" - dependencies: - fast-glob "^3.2.11" - glob-parent "^6.0.1" - globby "^13.1.1" - normalize-path "^3.0.0" - schema-utils "^4.0.0" - serialize-javascript "^6.0.0" +"karma-jasmine-html-reporter@^2.0.0": + "integrity" "sha512-SB8HNNiazAHXM1vGEzf8/tSyEhkfxuDdhYdPBX2Mwgzt0OuF2gicApQ+uvXLID/gXyJQgvrM9+1/2SxZFUUDIA==" + "resolved" "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.0.0.tgz" + "version" "2.0.0" -core-js-compat@^3.25.1: - version "3.28.0" - resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.28.0.tgz" +"karma-jasmine@^5.0.0", "karma-jasmine@5.1.0": + "integrity" "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==" + "resolved" "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz" + "version" "5.1.0" dependencies: - browserslist "^4.21.5" - -core-js@^3.14.0: - version "3.20.3" - resolved "https://registry.npmjs.org/core-js/-/core-js-3.20.3.tgz" + "jasmine-core" "^4.1.0" -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - -cors@~2.8.5: - version "2.8.5" - resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" +"karma-source-map-support@1.4.0": + "integrity" "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==" + "resolved" "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz" + "version" "1.4.0" dependencies: - object-assign "^4" - vary "^1" + "source-map-support" "^0.5.5" -cosmiconfig@^7.0.0: - version "7.1.0" - resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" +"karma@^6.0.0", "karma@^6.3.0", "karma@6.4.1": + "integrity" "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==" + "resolved" "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz" + "version" "6.4.1" dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -critters@0.0.16: - version "0.0.16" - resolved "https://registry.npmjs.org/critters/-/critters-0.0.16.tgz" - dependencies: - chalk "^4.1.0" - css-select "^4.2.0" - parse5 "^6.0.1" - parse5-htmlparser2-tree-adapter "^6.0.1" - postcss "^8.3.7" - pretty-bytes "^5.3.0" - -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz" + "@colors/colors" "1.5.0" + "body-parser" "^1.19.0" + "braces" "^3.0.2" + "chokidar" "^3.5.1" + "connect" "^3.7.0" + "di" "^0.0.1" + "dom-serialize" "^2.2.1" + "glob" "^7.1.7" + "graceful-fs" "^4.2.6" + "http-proxy" "^1.18.1" + "isbinaryfile" "^4.0.8" + "lodash" "^4.17.21" + "log4js" "^6.4.1" + "mime" "^2.5.2" + "minimatch" "^5.1.0" + "mkdirp" "^0.5.5" + "qjobs" "^1.2.0" + "range-parser" "^1.2.1" + "rimraf" "^3.0.2" + "socket.io" "^4.4.1" + "source-map" "^0.6.1" + "tmp" "^0.2.1" + "ua-parser-js" "^0.7.30" + "yargs" "^16.1.1" + +"keyv@^4.0.0": + "integrity" "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==" + "resolved" "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz" + "version" "4.5.2" + dependencies: + "json-buffer" "3.0.1" + +"kind-of@^3.0.2": + "integrity" "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=" + "resolved" "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" + "version" "3.2.2" + dependencies: + "is-buffer" "^1.1.5" + +"kind-of@^3.0.3": + "integrity" "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=" + "resolved" "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" + "version" "3.2.2" + dependencies: + "is-buffer" "^1.1.5" + +"kind-of@^3.2.0": + "integrity" "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=" + "resolved" "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" + "version" "3.2.2" + dependencies: + "is-buffer" "^1.1.5" + +"kind-of@^4.0.0": + "integrity" "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=" + "resolved" "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "is-buffer" "^1.1.5" + +"kind-of@^5.0.0": + "integrity" "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + "resolved" "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" + "version" "5.1.0" + +"kind-of@^6.0.0", "kind-of@^6.0.2": + "integrity" "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + "resolved" "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" + "version" "6.0.3" + +"klona@^2.0.4", "klona@^2.0.5": + "integrity" "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==" + "resolved" "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz" + "version" "2.0.6" + +"known-css-properties@^0.3.0": + "integrity" "sha512-QMQcnKAiQccfQTqtBh/qwquGZ2XK/DXND1jrcN9M8gMMy99Gwla7GQjndVUsEqIaRyP6bsFRuhwRj5poafBGJQ==" + "resolved" "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.3.0.tgz" + "version" "0.3.0" + +"latest-version@^3.0.0": + "integrity" "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=" + "resolved" "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "package-json" "^4.0.0" + +"less-loader@11.1.0": + "integrity" "sha512-C+uDBV7kS7W5fJlUjq5mPBeBVhYpTIm5gB09APT9o3n/ILeaXVsiSFTbZpTJCJwQ/Crczfn3DmfQFwxYusWFug==" + "resolved" "https://registry.npmjs.org/less-loader/-/less-loader-11.1.0.tgz" + "version" "11.1.0" + dependencies: + "klona" "^2.0.4" + +"less@^3.5.0 || ^4.0.0", "less@4.1.3": + "integrity" "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==" + "resolved" "https://registry.npmjs.org/less/-/less-4.1.3.tgz" + "version" "4.1.3" + dependencies: + "copy-anything" "^2.0.1" + "parse-node-version" "^1.0.1" + "tslib" "^2.3.0" + optionalDependencies: + "errno" "^0.1.1" + "graceful-fs" "^4.1.2" + "image-size" "~0.5.0" + "make-dir" "^2.1.0" + "mime" "^1.4.1" + "needle" "^3.1.0" + "source-map" "~0.6.0" + +"levn@^0.4.1": + "integrity" "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==" + "resolved" "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" + "version" "0.4.1" + dependencies: + "prelude-ls" "^1.2.1" + "type-check" "~0.4.0" + +"license-webpack-plugin@4.0.2": + "integrity" "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==" + "resolved" "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz" + "version" "4.0.2" + dependencies: + "webpack-sources" "^3.0.0" + +"lie@~3.3.0": + "integrity" "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==" + "resolved" "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz" + "version" "3.3.0" + dependencies: + "immediate" "~3.0.5" + +"lines-and-columns@^1.1.6": + "integrity" "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + "resolved" "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" + "version" "1.2.4" + +"loader-runner@^4.2.0": + "integrity" "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==" + "resolved" "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz" + "version" "4.3.0" + +"loader-utils@^2.0.0": + "integrity" "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==" + "resolved" "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz" + "version" "2.0.4" + dependencies: + "big.js" "^5.2.2" + "emojis-list" "^3.0.0" + "json5" "^2.1.2" + +"loader-utils@3.2.1": + "integrity" "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==" + "resolved" "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz" + "version" "3.2.1" + +"locate-path@^5.0.0": + "integrity" "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==" + "resolved" "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "p-locate" "^4.1.0" + +"lodash.capitalize@^4.1.0": + "integrity" "sha1-+CbJtOKoUR2E46yinbBeGk87cqk=" + "resolved" "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz" + "version" "4.2.1" + +"lodash.debounce@^4.0.8": + "integrity" "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + "resolved" "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" + "version" "4.0.8" + +"lodash.kebabcase@^4.0.0": + "integrity" "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=" + "resolved" "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz" + "version" "4.1.1" + +"lodash.merge@^4.6.2": + "integrity" "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + "resolved" "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" + "version" "4.6.2" + +"lodash@^4.17.21", "lodash@~4.17.10": + "integrity" "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + "version" "4.17.21" + +"log-symbols@^4.1.0": + "integrity" "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==" + "resolved" "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + "version" "4.1.0" + dependencies: + "chalk" "^4.1.0" + "is-unicode-supported" "^0.1.0" + +"log4js@^6.4.1": + "integrity" "sha512-iUiYnXqAmNKiIZ1XSAitQ4TmNs8CdZYTAWINARF3LjnsLN8tY5m0vRwd6uuWj/yNY0YHxeZodnbmxKFUOM2rMg==" + "resolved" "https://registry.npmjs.org/log4js/-/log4js-6.4.1.tgz" + "version" "6.4.1" + dependencies: + "date-format" "^4.0.3" + "debug" "^4.3.3" + "flatted" "^3.2.4" + "rfdc" "^1.3.0" + "streamroller" "^3.0.2" + +"lowercase-keys@^2.0.0": + "integrity" "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + "resolved" "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" + "version" "2.0.0" + +"lowercase-keys@^3.0.0": + "integrity" "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==" + "resolved" "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz" + "version" "3.0.0" + +"lru-cache@^4.0.1": + "integrity" "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==" + "resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz" + "version" "4.1.3" + dependencies: + "pseudomap" "^1.0.2" + "yallist" "^2.1.2" + +"lru-cache@^5.1.1": + "integrity" "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==" + "resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" + "version" "5.1.1" + dependencies: + "yallist" "^3.0.2" + +"lru-cache@^6.0.0": + "integrity" "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==" + "resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "yallist" "^4.0.0" + +"lru-cache@^7.4.4": + "integrity" "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==" + "resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-7.17.0.tgz" + "version" "7.17.0" + +"lru-cache@^7.5.1": + "integrity" "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==" + "resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-7.17.0.tgz" + "version" "7.17.0" + +"lru-cache@^7.7.1": + "integrity" "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==" + "resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-7.17.0.tgz" + "version" "7.17.0" + +"lunr@^2.3.9": + "integrity" "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" + "resolved" "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz" + "version" "2.3.9" + +"magic-string@^0.27.0": + "integrity" "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==" + "resolved" "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz" + "version" "0.27.0" dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" + "@jridgewell/sourcemap-codec" "^1.4.13" -cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" +"magic-string@0.29.0": + "integrity" "sha512-WcfidHrDjMY+eLjlU+8OvwREqHwpgCeKVBUpQ3OhYYuvfaYCUgcbuBzappNzZvg/v8onU3oQj+BYpkOJe9Iw4Q==" + "resolved" "https://registry.npmjs.org/magic-string/-/magic-string-0.29.0.tgz" + "version" "0.29.0" dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-random-string@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz" + "@jridgewell/sourcemap-codec" "^1.4.13" -css-loader@6.7.3: - version "6.7.3" - resolved "https://registry.npmjs.org/css-loader/-/css-loader-6.7.3.tgz" +"make-dir@^1.0.0": + "integrity" "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==" + "resolved" "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz" + "version" "1.3.0" + dependencies: + "pify" "^3.0.0" + +"make-dir@^2.1.0": + "integrity" "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==" + "resolved" "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "pify" "^4.0.1" + "semver" "^5.6.0" + +"make-dir@^3.0.2": + "integrity" "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==" + "resolved" "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "semver" "^6.0.0" + +"make-error@^1.1.1": + "integrity" "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==" + "resolved" "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz" + "version" "1.3.4" + +"make-fetch-happen@^10.0.3": + "integrity" "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==" + "resolved" "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz" + "version" "10.2.1" + dependencies: + "agentkeepalive" "^4.2.1" + "cacache" "^16.1.0" + "http-cache-semantics" "^4.1.0" + "http-proxy-agent" "^5.0.0" + "https-proxy-agent" "^5.0.0" + "is-lambda" "^1.0.1" + "lru-cache" "^7.7.1" + "minipass" "^3.1.6" + "minipass-collect" "^1.0.2" + "minipass-fetch" "^2.0.3" + "minipass-flush" "^1.0.5" + "minipass-pipeline" "^1.2.4" + "negotiator" "^0.6.3" + "promise-retry" "^2.0.1" + "socks-proxy-agent" "^7.0.0" + "ssri" "^9.0.0" + +"make-fetch-happen@^11.0.0": + "integrity" "sha512-oPLh5m10lRNNZDjJ2kP8UpboUx2uFXVaVweVe/lWut4iHWcQEmfqSVJt2ihZsFI8HbpwyyocaXbCAWf0g1ukIA==" + "resolved" "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.0.3.tgz" + "version" "11.0.3" + dependencies: + "agentkeepalive" "^4.2.1" + "cacache" "^17.0.0" + "http-cache-semantics" "^4.1.1" + "http-proxy-agent" "^5.0.0" + "https-proxy-agent" "^5.0.0" + "is-lambda" "^1.0.1" + "lru-cache" "^7.7.1" + "minipass" "^4.0.0" + "minipass-fetch" "^3.0.0" + "minipass-flush" "^1.0.5" + "minipass-pipeline" "^1.2.4" + "negotiator" "^0.6.3" + "promise-retry" "^2.0.1" + "socks-proxy-agent" "^7.0.0" + "ssri" "^10.0.0" + +"make-fetch-happen@^11.0.1": + "integrity" "sha512-oPLh5m10lRNNZDjJ2kP8UpboUx2uFXVaVweVe/lWut4iHWcQEmfqSVJt2ihZsFI8HbpwyyocaXbCAWf0g1ukIA==" + "resolved" "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.0.3.tgz" + "version" "11.0.3" + dependencies: + "agentkeepalive" "^4.2.1" + "cacache" "^17.0.0" + "http-cache-semantics" "^4.1.1" + "http-proxy-agent" "^5.0.0" + "https-proxy-agent" "^5.0.0" + "is-lambda" "^1.0.1" + "lru-cache" "^7.7.1" + "minipass" "^4.0.0" + "minipass-fetch" "^3.0.0" + "minipass-flush" "^1.0.5" + "minipass-pipeline" "^1.2.4" + "negotiator" "^0.6.3" + "promise-retry" "^2.0.1" + "socks-proxy-agent" "^7.0.0" + "ssri" "^10.0.0" + +"map-cache@^0.2.2": + "integrity" "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + "resolved" "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" + "version" "0.2.2" + +"map-visit@^1.0.0": + "integrity" "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=" + "resolved" "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "object-visit" "^1.0.0" + +"marked@4.2.12": + "integrity" "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==" + "resolved" "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz" + "version" "4.2.12" + +"media-typer@0.3.0": + "integrity" "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "resolved" "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" + "version" "0.3.0" + +"memfs@^3.4.12", "memfs@^3.4.3": + "integrity" "sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==" + "resolved" "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz" + "version" "3.4.13" + dependencies: + "fs-monkey" "^1.0.3" + +"merge-descriptors@1.0.1": + "integrity" "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "resolved" "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" + "version" "1.0.1" + +"merge-stream@^2.0.0": + "integrity" "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + "resolved" "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + "version" "2.0.0" + +"merge@2.1.1": + "integrity" "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==" + "resolved" "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz" + "version" "2.1.1" + +"merge2@^1.3.0", "merge2@^1.4.1": + "integrity" "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + "resolved" "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" + "version" "1.4.1" + +"methods@~1.1.2": + "integrity" "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "resolved" "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" + "version" "1.1.2" + +"micromatch@^3.1.10", "micromatch@^3.1.4": + "integrity" "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==" + "resolved" "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz" + "version" "3.1.10" + dependencies: + "arr-diff" "^4.0.0" + "array-unique" "^0.3.2" + "braces" "^2.3.1" + "define-property" "^2.0.2" + "extend-shallow" "^3.0.2" + "extglob" "^2.0.4" + "fragment-cache" "^0.2.1" + "kind-of" "^6.0.2" + "nanomatch" "^1.2.9" + "object.pick" "^1.3.0" + "regex-not" "^1.0.0" + "snapdragon" "^0.8.1" + "to-regex" "^3.0.2" + +"micromatch@^4.0.2": + "integrity" "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==" + "resolved" "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz" + "version" "4.0.4" + dependencies: + "braces" "^3.0.1" + "picomatch" "^2.2.3" + +"micromatch@^4.0.4": + "integrity" "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==" + "resolved" "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" + "version" "4.0.5" + dependencies: + "braces" "^3.0.2" + "picomatch" "^2.3.1" + +"mime-db@>= 1.38.0 < 2", "mime-db@1.51.0": + "integrity" "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + "resolved" "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz" + "version" "1.51.0" + +"mime-types@^2.1.12", "mime-types@^2.1.27", "mime-types@^2.1.31", "mime-types@~2.1.17", "mime-types@~2.1.19", "mime-types@~2.1.24", "mime-types@~2.1.34": + "integrity" "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==" + "resolved" "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz" + "version" "2.1.34" + dependencies: + "mime-db" "1.51.0" + +"mime@^1.4.1": + "integrity" "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + "resolved" "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + "version" "1.6.0" + +"mime@^2.5.2": + "integrity" "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" + "resolved" "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" + "version" "2.6.0" + +"mime@1.6.0": + "integrity" "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + "resolved" "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + "version" "1.6.0" + +"mimic-fn@^2.1.0": + "integrity" "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + "resolved" "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + "version" "2.1.0" + +"mimic-response@^1.0.0": + "integrity" "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + "resolved" "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz" + "version" "1.0.1" + +"mimic-response@^3.1.0": + "integrity" "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + "resolved" "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz" + "version" "3.1.0" + +"mini-css-extract-plugin@2.7.2": + "integrity" "sha512-EdlUizq13o0Pd+uCp+WO/JpkLvHRVGt97RqfeGhXqAcorYo1ypJSpkV+WDT0vY/kmh/p7wRdJNJtuyK540PXDw==" + "resolved" "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.2.tgz" + "version" "2.7.2" + dependencies: + "schema-utils" "^4.0.0" + +"minimalistic-assert@^1.0.0": + "integrity" "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + "resolved" "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" + "version" "1.0.1" + +"minimatch@^5.0.1": + "integrity" "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==" + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" + "version" "5.1.6" + dependencies: + "brace-expansion" "^2.0.1" + +"minimatch@^5.1.0", "minimatch@~5.1.0": + "integrity" "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==" + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz" + "version" "5.1.0" + dependencies: + "brace-expansion" "^2.0.1" + +"minimatch@^6.1.0": + "integrity" "sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==" + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz" + "version" "6.2.0" + dependencies: + "brace-expansion" "^2.0.1" + +"minimatch@^6.1.6": + "integrity" "sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==" + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz" + "version" "6.2.0" + dependencies: + "brace-expansion" "^2.0.1" + +"minimist@^1.2.6", "minimist@1.2.6": + "integrity" "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "resolved" "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz" + "version" "1.2.6" + +"minipass-collect@^1.0.2": + "integrity" "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==" + "resolved" "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz" + "version" "1.0.2" dependencies: - icss-utils "^5.1.0" - postcss "^8.4.19" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.2.0" - semver "^7.3.8" + "minipass" "^3.0.0" + +"minipass-fetch@^2.0.3": + "integrity" "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==" + "resolved" "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz" + "version" "2.1.2" + dependencies: + "minipass" "^3.1.6" + "minipass-sized" "^1.0.3" + "minizlib" "^2.1.2" + optionalDependencies: + "encoding" "^0.1.13" -css-select@^4.2.0: - version "4.3.0" - resolved "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz" +"minipass-fetch@^3.0.0": + "integrity" "sha512-t9/wowtf7DYkwz8cfMSt0rMwiyNIBXf5CKZ3S5ZMqRqMYT0oLTp0x1WorMI9WTwvaPg21r1JbFxJMum8JrLGfw==" + "resolved" "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.1.tgz" + "version" "3.0.1" dependencies: - boolbase "^1.0.0" - css-what "^6.0.1" - domhandler "^4.3.1" - domutils "^2.8.0" - nth-check "^2.0.1" + "minipass" "^4.0.0" + "minipass-sized" "^1.0.3" + "minizlib" "^2.1.2" + optionalDependencies: + "encoding" "^0.1.13" -css-selector-tokenizer@^0.7.1: - version "0.7.3" - resolved "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz" +"minipass-flush@^1.0.5": + "integrity" "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==" + "resolved" "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz" + "version" "1.0.5" dependencies: - cssesc "^3.0.0" - fastparse "^1.1.2" + "minipass" "^3.0.0" -css-what@^6.0.1: - version "6.1.0" - resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" - -cssauron@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz" +"minipass-json-stream@^1.0.1": + "integrity" "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==" + "resolved" "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz" + "version" "1.0.1" dependencies: - through X.X.X - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" - -custom-event@~1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz" - -damerau-levenshtein@^1.0.4: - version "1.0.7" - resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz" + "jsonparse" "^1.3.1" + "minipass" "^3.0.0" + +"minipass-pipeline@^1.2.4": + "integrity" "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==" + "resolved" "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz" + "version" "1.2.4" + dependencies: + "minipass" "^3.0.0" + +"minipass-sized@^1.0.3": + "integrity" "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==" + "resolved" "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz" + "version" "1.0.3" + dependencies: + "minipass" "^3.0.0" + +"minipass@^3.0.0", "minipass@^3.1.1", "minipass@^3.1.6": + "integrity" "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==" + "resolved" "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" + "version" "3.3.6" + dependencies: + "yallist" "^4.0.0" + +"minipass@^4.0.0": + "integrity" "sha512-ExlilAIS7zJ2EWUMaVXi14H+FnZ18kr17kFkGemMqBx6jW0m8P6XfqwYVPEG53ENlgsED+alVP9ZxC3JzkK23Q==" + "resolved" "https://registry.npmjs.org/minipass/-/minipass-4.2.0.tgz" + "version" "4.2.0" + +"minizlib@^2.1.1", "minizlib@^2.1.2": + "integrity" "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==" + "resolved" "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" + "version" "2.1.2" + dependencies: + "minipass" "^3.0.0" + "yallist" "^4.0.0" + +"mixin-deep@^1.2.0": + "integrity" "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==" + "resolved" "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz" + "version" "1.3.2" + dependencies: + "for-in" "^1.0.2" + "is-extendable" "^1.0.1" + +"mkdirp@^0.5.1", "mkdirp@^0.5.3", "mkdirp@^0.5.5": + "integrity" "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==" + "resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" + "version" "0.5.6" + dependencies: + "minimist" "^1.2.6" + +"mkdirp@^1.0.3": + "integrity" "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + "resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + "version" "1.0.4" + +"mkdirp@^1.0.4": + "integrity" "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + "resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + "version" "1.0.4" + +"ms@^2.0.0", "ms@2.0.0": + "integrity" "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "resolved" "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + "version" "2.0.0" + +"ms@^2.1.1": + "integrity" "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + "version" "2.1.3" + +"ms@2.1.2": + "integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + "version" "2.1.2" + +"ms@2.1.3": + "integrity" "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + "version" "2.1.3" + +"multicast-dns@^7.2.5": + "integrity" "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==" + "resolved" "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz" + "version" "7.2.5" + dependencies: + "dns-packet" "^5.2.2" + "thunky" "^1.0.2" + +"mute-stream@0.0.8": + "integrity" "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + "resolved" "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" + "version" "0.0.8" + +"nanoid@^3.3.4": + "integrity" "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + "resolved" "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz" + "version" "3.3.4" + +"nanomatch@^1.2.9": + "integrity" "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==" + "resolved" "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz" + "version" "1.2.13" + dependencies: + "arr-diff" "^4.0.0" + "array-unique" "^0.3.2" + "define-property" "^2.0.2" + "extend-shallow" "^3.0.2" + "fragment-cache" "^0.2.1" + "is-windows" "^1.0.2" + "kind-of" "^6.0.2" + "object.pick" "^1.3.0" + "regex-not" "^1.0.0" + "snapdragon" "^0.8.1" + "to-regex" "^3.0.1" + +"natural-compare@^1.4.0": + "integrity" "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + "resolved" "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + "version" "1.4.0" + +"needle@^3.1.0": + "integrity" "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==" + "resolved" "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz" + "version" "3.2.0" + dependencies: + "debug" "^3.2.6" + "iconv-lite" "^0.6.3" + "sax" "^1.2.4" + +"negotiator@^0.6.3", "negotiator@0.6.3": + "integrity" "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + "resolved" "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" + "version" "0.6.3" + +"neo-async@^2.6.0", "neo-async@^2.6.2": + "integrity" "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + "resolved" "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" + "version" "2.6.2" + +"ngx-toastr@15.2.2": + "integrity" "sha512-srdxKKf1+B/7z11M4Ty7bnkme2xjdUcnP/t7mNG/2gRM1h0P/7Lbz71FIQHuKZOCdnGdXjsT6OXU0dRvNyrkyg==" + "resolved" "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-15.2.2.tgz" + "version" "15.2.2" + dependencies: + "tslib" "^2.3.0" + +"node-fetch@^2.6.1": + "integrity" "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==" + "resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" + "version" "2.6.7" + dependencies: + "whatwg-url" "^5.0.0" + +"node-forge@^1": + "integrity" "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" + "resolved" "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz" + "version" "1.3.1" + +"node-gyp@^9.0.0": + "integrity" "sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==" + "resolved" "https://registry.npmjs.org/node-gyp/-/node-gyp-9.3.1.tgz" + "version" "9.3.1" + dependencies: + "env-paths" "^2.2.0" + "glob" "^7.1.4" + "graceful-fs" "^4.2.6" + "make-fetch-happen" "^10.0.3" + "nopt" "^6.0.0" + "npmlog" "^6.0.0" + "rimraf" "^3.0.2" + "semver" "^7.3.5" + "tar" "^6.1.2" + "which" "^2.0.2" + +"node-releases@^2.0.8": + "integrity" "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==" + "resolved" "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz" + "version" "2.0.10" + +"nodemon@^1.18.7": + "integrity" "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==" + "resolved" "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz" + "version" "1.19.4" + dependencies: + "chokidar" "^2.1.8" + "debug" "^3.2.6" + "ignore-by-default" "^1.0.1" + "minimatch" "^5.1.0" + "pstree.remy" "^1.1.7" + "semver" "^5.7.1" + "supports-color" "^5.5.0" + "touch" "^3.1.0" + "undefsafe" "^2.0.2" + "update-notifier" "^2.5.0" + +"nopt@^6.0.0": + "integrity" "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==" + "resolved" "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "abbrev" "^1.0.0" + +"nopt@~1.0.10": + "integrity" "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=" + "resolved" "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz" + "version" "1.0.10" + dependencies: + "abbrev" "1" + +"normalize-package-data@^5.0.0": + "integrity" "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==" + "resolved" "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "hosted-git-info" "^6.0.0" + "is-core-module" "^2.8.1" + "semver" "^7.3.5" + "validate-npm-package-license" "^3.0.4" + +"normalize-path@^2.1.1": + "integrity" "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=" + "resolved" "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz" + "version" "2.1.1" + dependencies: + "remove-trailing-separator" "^1.0.1" + +"normalize-path@^3.0.0", "normalize-path@~3.0.0": + "integrity" "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + "resolved" "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + "version" "3.0.0" + +"normalize-range@^0.1.2": + "integrity" "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" + "resolved" "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" + "version" "0.1.2" + +"normalize-url@^6.0.1": + "integrity" "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" + "resolved" "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz" + "version" "6.1.0" + +"normalize.css@8.0.0": + "integrity" "sha512-iXcbM3NWr0XkNyfiSBsoPezi+0V92P9nj84yVV1/UZxRUrGczgX/X91KMAGM0omWLY2+2Q1gKD/XRn4gQRDB2A==" + "resolved" "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.0.tgz" + "version" "8.0.0" + +"npm-bundled@^3.0.0": + "integrity" "sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==" + "resolved" "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "npm-normalize-package-bin" "^3.0.0" + +"npm-install-checks@^6.0.0": + "integrity" "sha512-SBU9oFglRVZnfElwAtF14NivyulDqF1VKqqwNsFW9HDcbHMAPHpRSsVFgKuwFGq/hVvWZExz62Th0kvxn/XE7Q==" + "resolved" "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "semver" "^7.1.1" + +"npm-normalize-package-bin@^3.0.0": + "integrity" "sha512-g+DPQSkusnk7HYXr75NtzkIP4+N81i3RPsGFidF3DzHd9MT9wWngmqoeg/fnHFz5MNdtG4w03s+QnhewSLTT2Q==" + "resolved" "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.0.tgz" + "version" "3.0.0" + +"npm-package-arg@^10.0.0", "npm-package-arg@10.1.0": + "integrity" "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==" + "resolved" "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz" + "version" "10.1.0" + dependencies: + "hosted-git-info" "^6.0.0" + "proc-log" "^3.0.0" + "semver" "^7.3.5" + "validate-npm-package-name" "^5.0.0" + +"npm-packlist@^7.0.0": + "integrity" "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==" + "resolved" "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz" + "version" "7.0.4" + dependencies: + "ignore-walk" "^6.0.0" + +"npm-pick-manifest@^8.0.0", "npm-pick-manifest@8.0.1": + "integrity" "sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA==" + "resolved" "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz" + "version" "8.0.1" + dependencies: + "npm-install-checks" "^6.0.0" + "npm-normalize-package-bin" "^3.0.0" + "npm-package-arg" "^10.0.0" + "semver" "^7.3.5" + +"npm-registry-fetch@^14.0.0": + "integrity" "sha512-YaeRbVNpnWvsGOjX2wk5s85XJ7l1qQBGAp724h8e2CZFFhMSuw9enom7K1mWVUtvXO1uUSFIAPofQK0pPN0ZcA==" + "resolved" "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.3.tgz" + "version" "14.0.3" + dependencies: + "make-fetch-happen" "^11.0.0" + "minipass" "^4.0.0" + "minipass-fetch" "^3.0.0" + "minipass-json-stream" "^1.0.1" + "minizlib" "^2.1.2" + "npm-package-arg" "^10.0.0" + "proc-log" "^3.0.0" + +"npm-run-path@^2.0.0": + "integrity" "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=" + "resolved" "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz" + "version" "2.0.2" + dependencies: + "path-key" "^2.0.0" + +"npm-run-path@^4.0.1": + "integrity" "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==" + "resolved" "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + "version" "4.0.1" + dependencies: + "path-key" "^3.0.0" + +"npm-watch@0.5.0": + "integrity" "sha512-Rww9iNlmsVhcpUTDoKfUlbfmEtTZ3T3gUZBW/VjuL4ct/nwV0XlwBDOxR0ECJ/cLF8PF1wPVa/IrinI6K5ECQQ==" + "resolved" "https://registry.npmjs.org/npm-watch/-/npm-watch-0.5.0.tgz" + "version" "0.5.0" + dependencies: + "nodemon" "^1.18.7" + "through2" "^2.0.0" + +"npmlog@^6.0.0": + "integrity" "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==" + "resolved" "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz" + "version" "6.0.2" + dependencies: + "are-we-there-yet" "^3.0.0" + "console-control-strings" "^1.1.0" + "gauge" "^4.0.3" + "set-blocking" "^2.0.0" + +"nth-check@^2.0.1": + "integrity" "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==" + "resolved" "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" + "version" "2.1.1" + dependencies: + "boolbase" "^1.0.0" + +"oauth-sign@~0.9.0": + "integrity" "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + "resolved" "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" + "version" "0.9.0" + +"object-assign@^4", "object-assign@^4.0.1": + "integrity" "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "resolved" "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + "version" "4.1.1" + +"object-copy@^0.1.0": + "integrity" "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=" + "resolved" "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz" + "version" "0.1.0" + dependencies: + "copy-descriptor" "^0.1.0" + "define-property" "^0.2.5" + "kind-of" "^3.0.3" + +"object-inspect@^1.9.0": + "integrity" "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + "resolved" "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz" + "version" "1.12.2" + +"object-visit@^1.0.0": + "integrity" "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=" + "resolved" "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "isobject" "^3.0.0" + +"object.pick@^1.3.0": + "integrity" "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=" + "resolved" "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz" + "version" "1.3.0" + dependencies: + "isobject" "^3.0.1" + +"obuf@^1.0.0", "obuf@^1.1.2": + "integrity" "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + "resolved" "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" + "version" "1.1.2" + +"on-finished@~2.3.0": + "integrity" "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=" + "resolved" "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" + "version" "2.3.0" + dependencies: + "ee-first" "1.1.1" + +"on-finished@2.4.1": + "integrity" "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==" + "resolved" "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" + "version" "2.4.1" + dependencies: + "ee-first" "1.1.1" + +"on-headers@~1.0.2": + "integrity" "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + "resolved" "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" + "version" "1.0.2" + +"once@^1.3.0", "once@^1.3.1", "once@^1.4.0": + "integrity" "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=" + "resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + "version" "1.4.0" + dependencies: + "wrappy" "1" + +"onetime@^5.1.0", "onetime@^5.1.2": + "integrity" "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==" + "resolved" "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + "version" "5.1.2" + dependencies: + "mimic-fn" "^2.1.0" + +"onigasm@^2.2.5": + "integrity" "sha512-F+th54mPc0l1lp1ZcFMyL/jTs2Tlq4SqIHKIXGZOR/VkHkF9A7Fr5rRr5+ZG/lWeRsyrClLYRq7s/yFQ/XhWCA==" + "resolved" "https://registry.npmjs.org/onigasm/-/onigasm-2.2.5.tgz" + "version" "2.2.5" + dependencies: + "lru-cache" "^5.1.1" + +"open@^8.0.9", "open@8.4.1": + "integrity" "sha512-/4b7qZNhv6Uhd7jjnREh1NjnPxlTq+XNWPG88Ydkj5AILcA5m3ajvcg57pB24EQjKv0dK62XnDqk9c/hkIG5Kg==" + "resolved" "https://registry.npmjs.org/open/-/open-8.4.1.tgz" + "version" "8.4.1" + dependencies: + "define-lazy-prop" "^2.0.0" + "is-docker" "^2.1.1" + "is-wsl" "^2.2.0" + +"optionator@^0.9.1": + "integrity" "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==" + "resolved" "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" + "version" "0.9.1" + dependencies: + "deep-is" "^0.1.3" + "fast-levenshtein" "^2.0.6" + "levn" "^0.4.1" + "prelude-ls" "^1.2.1" + "type-check" "^0.4.0" + "word-wrap" "^1.2.3" + +"ora@^5.4.1", "ora@5.4.1": + "integrity" "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==" + "resolved" "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz" + "version" "5.4.1" + dependencies: + "bl" "^4.1.0" + "chalk" "^4.1.0" + "cli-cursor" "^3.1.0" + "cli-spinners" "^2.5.0" + "is-interactive" "^1.0.0" + "is-unicode-supported" "^0.1.0" + "log-symbols" "^4.1.0" + "strip-ansi" "^6.0.0" + "wcwidth" "^1.0.1" + +"original@^1.0.0": + "integrity" "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==" + "resolved" "https://registry.npmjs.org/original/-/original-1.0.2.tgz" + "version" "1.0.2" + dependencies: + "url-parse" "^1.4.3" + +"os-tmpdir@~1.0.1", "os-tmpdir@~1.0.2": + "integrity" "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + "resolved" "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" + "version" "1.0.2" + +"p-cancelable@^3.0.0": + "integrity" "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==" + "resolved" "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz" + "version" "3.0.0" + +"p-finally@^1.0.0": + "integrity" "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + "resolved" "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" + "version" "1.0.0" + +"p-limit@^2.2.0": + "integrity" "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==" + "resolved" "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz" + "version" "2.2.2" + dependencies: + "p-try" "^2.0.0" + +"p-locate@^4.1.0": + "integrity" "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==" + "resolved" "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + "version" "4.1.0" + dependencies: + "p-limit" "^2.2.0" + +"p-map@^4.0.0": + "integrity" "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==" + "resolved" "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "aggregate-error" "^3.0.0" + +"p-retry@^4.5.0": + "integrity" "sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==" + "resolved" "https://registry.npmjs.org/p-retry/-/p-retry-4.6.1.tgz" + "version" "4.6.1" dependencies: - assert-plus "^1.0.0" + "@types/retry" "^0.12.0" + "retry" "^0.13.1" -date-format@^4.0.3: - version "4.0.3" - resolved "https://registry.npmjs.org/date-format/-/date-format-4.0.3.tgz" +"p-try@^2.0.0": + "integrity" "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + "resolved" "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + "version" "2.2.0" -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" +"package-json@^4.0.0": + "integrity" "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=" + "resolved" "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz" + "version" "4.0.1" dependencies: - ms "2.0.0" + "got" "12.1.0" + "registry-auth-token" "^3.0.1" + "registry-url" "^3.0.3" + "semver" "^5.1.0" -debug@4, debug@^4.1.0, debug@^4.1.1, debug@~4.3.1: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" +"pacote@15.1.0": + "integrity" "sha512-FFcjtIl+BQNfeliSm7MZz5cpdohvUV1yjGnqgVM4UnVF7JslRY0ImXAygdaCDV0jjUADEWu4y5xsDV8brtrTLg==" + "resolved" "https://registry.npmjs.org/pacote/-/pacote-15.1.0.tgz" + "version" "15.1.0" dependencies: - ms "2.1.2" - -debug@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz" + "@npmcli/git" "^4.0.0" + "@npmcli/installed-package-contents" "^2.0.1" + "@npmcli/promise-spawn" "^6.0.1" + "@npmcli/run-script" "^6.0.0" + "cacache" "^17.0.0" + "fs-minipass" "^3.0.0" + "minipass" "^4.0.0" + "npm-package-arg" "^10.0.0" + "npm-packlist" "^7.0.0" + "npm-pick-manifest" "^8.0.0" + "npm-registry-fetch" "^14.0.0" + "proc-log" "^3.0.0" + "promise-retry" "^2.0.1" + "read-package-json" "^6.0.0" + "read-package-json-fast" "^3.0.0" + "sigstore" "^1.0.0" + "ssri" "^10.0.0" + "tar" "^6.1.11" + +"pako@^1.0.3", "pako@~1.0.2": + "integrity" "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + "resolved" "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz" + "version" "1.0.11" + +"parent-module@^1.0.0": + "integrity" "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==" + "resolved" "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "callsites" "^3.0.0" + +"parse-json@^5.0.0": + "integrity" "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==" + "resolved" "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + "version" "5.2.0" dependencies: - ms "2.0.0" - -debug@^3.2.6: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + "@babel/code-frame" "^7.0.0" + "error-ex" "^1.3.1" + "json-parse-even-better-errors" "^2.3.0" + "lines-and-columns" "^1.1.6" + +"parse-node-version@^1.0.1": + "integrity" "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==" + "resolved" "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz" + "version" "1.0.1" + +"parse5-html-rewriting-stream@7.0.0": + "integrity" "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==" + "resolved" "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz" + "version" "7.0.0" + dependencies: + "entities" "^4.3.0" + "parse5" "^7.0.0" + "parse5-sax-parser" "^7.0.0" + +"parse5-htmlparser2-tree-adapter@^6.0.1": + "integrity" "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==" + "resolved" "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz" + "version" "6.0.1" + dependencies: + "parse5" "^6.0.1" + +"parse5-sax-parser@^7.0.0": + "integrity" "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==" + "resolved" "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz" + "version" "7.0.0" + dependencies: + "parse5" "^7.0.0" + +"parse5@^6.0.1": + "integrity" "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + "resolved" "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" + "version" "6.0.1" + +"parse5@^7.0.0": + "integrity" "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==" + "resolved" "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz" + "version" "7.1.2" + dependencies: + "entities" "^4.4.0" + +"parseurl@~1.3.2", "parseurl@~1.3.3": + "integrity" "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + "resolved" "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" + "version" "1.3.3" + +"pascalcase@^0.1.1": + "integrity" "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + "resolved" "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz" + "version" "0.1.1" + +"path-exists@^4.0.0": + "integrity" "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "resolved" "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + "version" "4.0.0" + +"path-is-absolute@^1.0.0": + "integrity" "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "resolved" "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + "version" "1.0.1" + +"path-is-inside@^1.0.1": + "integrity" "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + "resolved" "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz" + "version" "1.0.2" + +"path-key@^2.0.0": + "integrity" "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + "resolved" "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz" + "version" "2.0.1" + +"path-key@^3.0.0", "path-key@^3.1.0": + "integrity" "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + "resolved" "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + "version" "3.1.1" + +"path-parse@^1.0.7": + "integrity" "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "resolved" "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + "version" "1.0.7" + +"path-to-regexp@0.1.7": + "integrity" "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "resolved" "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" + "version" "0.1.7" + +"path-type@^4.0.0": + "integrity" "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + "resolved" "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" + "version" "4.0.0" + +"performance-now@^2.1.0": + "integrity" "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "resolved" "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" + "version" "2.1.0" + +"picocolors@^1.0.0": + "integrity" "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "resolved" "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" + "version" "1.0.0" + +"picomatch@^2.0.4", "picomatch@^2.2.1", "picomatch@^2.2.3", "picomatch@^2.3.1": + "integrity" "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + "resolved" "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + "version" "2.3.1" + +"pify@^2.0.0": + "integrity" "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + "resolved" "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" + "version" "2.3.0" + +"pify@^3.0.0": + "integrity" "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + "resolved" "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" + "version" "3.0.0" + +"pify@^4.0.1": + "integrity" "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + "resolved" "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" + "version" "4.0.1" + +"pinkie-promise@^2.0.0": + "integrity" "sha1-ITXW36ejWMBprJsXh3YogihFD/o=" + "resolved" "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "pinkie" "^2.0.0" + +"pinkie@^2.0.0": + "integrity" "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + "resolved" "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" + "version" "2.0.4" + +"piscina@3.2.0": + "integrity" "sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA==" + "resolved" "https://registry.npmjs.org/piscina/-/piscina-3.2.0.tgz" + "version" "3.2.0" + dependencies: + "eventemitter-asyncresource" "^1.0.0" + "hdr-histogram-js" "^2.0.1" + "hdr-histogram-percentiles-obj" "^3.0.0" + optionalDependencies: + "nice-napi" "^1.0.2" + +"pkg-dir@^4.1.0": + "integrity" "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==" + "resolved" "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" + "version" "4.2.0" + dependencies: + "find-up" "^4.0.0" + +"popper.js@1.16.1": + "integrity" "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" + "resolved" "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz" + "version" "1.16.1" + +"posix-character-classes@^0.1.0": + "integrity" "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + "resolved" "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz" + "version" "0.1.1" + +"postcss-loader@7.0.2": + "integrity" "sha512-fUJzV/QH7NXUAqV8dWJ9Lg4aTkDCezpTS5HgJ2DvqznexTbSTxgi/dTECvTZ15BwKTtk8G/bqI/QTu2HPd3ZCg==" + "resolved" "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.0.2.tgz" + "version" "7.0.2" + dependencies: + "cosmiconfig" "^7.0.0" + "klona" "^2.0.5" + "semver" "^7.3.8" + +"postcss-modules-extract-imports@^3.0.0": + "integrity" "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==" + "resolved" "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz" + "version" "3.0.0" + +"postcss-modules-local-by-default@^4.0.0": + "integrity" "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==" + "resolved" "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "icss-utils" "^5.0.0" + "postcss-selector-parser" "^6.0.2" + "postcss-value-parser" "^4.1.0" + +"postcss-modules-scope@^3.0.0": + "integrity" "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==" + "resolved" "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "postcss-selector-parser" "^6.0.4" + +"postcss-modules-values@^4.0.0": + "integrity" "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==" + "resolved" "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "icss-utils" "^5.0.0" + +"postcss-selector-parser@^6.0.2", "postcss-selector-parser@^6.0.4": + "integrity" "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==" + "resolved" "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz" + "version" "6.0.11" + dependencies: + "cssesc" "^3.0.0" + "util-deprecate" "^1.0.2" + +"postcss-value-parser@^4.1.0", "postcss-value-parser@^4.2.0": + "integrity" "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + "resolved" "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" + "version" "4.2.0" + +"postcss@^7.0.0 || ^8.0.1", "postcss@^8.1.0", "postcss@^8.2.14", "postcss@^8.3.7", "postcss@^8.4.19", "postcss@8.4.21": + "integrity" "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==" + "resolved" "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz" + "version" "8.4.21" + dependencies: + "nanoid" "^3.3.4" + "picocolors" "^1.0.0" + "source-map-js" "^1.0.2" + +"preact-render-to-string@^5.1.10": + "integrity" "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==" + "resolved" "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz" + "version" "5.2.6" + dependencies: + "pretty-format" "^3.8.0" + +"preact@^10.5.3", "preact@>=10": + "integrity" "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==" + "resolved" "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz" + "version" "10.12.1" + +"prelude-ls@^1.2.1": + "integrity" "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + "resolved" "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" + "version" "1.2.1" + +"pretty-bytes@^5.3.0": + "integrity" "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==" + "resolved" "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz" + "version" "5.6.0" + +"pretty-format@^3.8.0": + "integrity" "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" + "resolved" "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz" + "version" "3.8.0" + +"proc-log@^3.0.0": + "integrity" "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==" + "resolved" "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz" + "version" "3.0.0" + +"process-nextick-args@~2.0.0": + "integrity" "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "resolved" "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz" + "version" "2.0.0" + +"promise-inflight@^1.0.1": + "integrity" "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" + "resolved" "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz" + "version" "1.0.1" + +"promise-retry@^2.0.1": + "integrity" "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==" + "resolved" "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "err-code" "^2.0.2" + "retry" "^0.12.0" + +"protractor@*", "protractor@^7.0.0", "protractor@~7.0.0": + "integrity" "sha512-UqkFjivi4GcvUQYzqGYNe0mLzfn5jiLmO8w9nMhQoJRLhy2grJonpga2IWhI6yJO30LibWXJJtA4MOIZD2GgZw==" + "resolved" "https://registry.npmjs.org/protractor/-/protractor-7.0.0.tgz" + "version" "7.0.0" dependencies: - ms "^2.1.1" - -debug@^4.3.2, debug@^4.3.3, debug@~4.3.2: - version "4.3.3" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" + "@types/q" "^0.0.32" + "@types/selenium-webdriver" "^3.0.0" + "blocking-proxy" "^1.0.0" + "browserstack" "^1.5.1" + "chalk" "^1.1.3" + "glob" "^7.0.3" + "jasmine" "2.8.0" + "jasminewd2" "^2.1.0" + "q" "1.4.1" + "saucelabs" "^1.5.0" + "selenium-webdriver" "3.6.0" + "source-map-support" "~0.4.0" + "webdriver-js-extender" "2.1.0" + "webdriver-manager" "^12.1.7" + "yargs" "^15.3.1" + +"proxy-addr@~2.0.7": + "integrity" "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==" + "resolved" "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" + "version" "2.0.7" + dependencies: + "forwarded" "0.2.0" + "ipaddr.js" "1.9.1" + +"prr@~1.0.1": + "integrity" "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==" + "resolved" "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz" + "version" "1.0.1" + +"pseudomap@^1.0.2": + "integrity" "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "resolved" "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz" + "version" "1.0.2" + +"psl@^1.1.24": + "integrity" "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" + "resolved" "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz" + "version" "1.1.29" + +"pstree.remy@^1.1.7": + "integrity" "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==" + "resolved" "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz" + "version" "1.1.7" + +"pump@^3.0.0": + "integrity" "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==" + "resolved" "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "end-of-stream" "^1.1.0" + "once" "^1.3.1" + +"punycode@^1.4.1": + "integrity" "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "resolved" "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" + "version" "1.4.1" + +"punycode@^2.1.0": + "integrity" "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "resolved" "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" + "version" "2.1.1" + +"q@^1.4.1", "q@1.4.1": + "integrity" "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=" + "resolved" "https://registry.npmjs.org/q/-/q-1.4.1.tgz" + "version" "1.4.1" + +"qjobs@^1.2.0": + "integrity" "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==" + "resolved" "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz" + "version" "1.2.0" + +"qs@~6.5.2": + "integrity" "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" + "resolved" "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz" + "version" "6.5.3" + +"qs@6.11.0": + "integrity" "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==" + "resolved" "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" + "version" "6.11.0" + dependencies: + "side-channel" "^1.0.4" + +"querystringify@^2.1.1": + "integrity" "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + "resolved" "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz" + "version" "2.2.0" + +"queue-microtask@^1.2.2": + "integrity" "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + "resolved" "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" + "version" "1.2.3" + +"quick-lru@^5.1.1": + "integrity" "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" + "resolved" "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" + "version" "5.1.1" + +"randombytes@^2.1.0": + "integrity" "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==" + "resolved" "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "safe-buffer" "^5.1.0" + +"range-parser@^1.2.1", "range-parser@~1.2.1": + "integrity" "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + "resolved" "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + "version" "1.2.1" + +"raw-body@2.5.1": + "integrity" "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==" + "resolved" "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" + "version" "2.5.1" + dependencies: + "bytes" "3.1.2" + "http-errors" "2.0.0" + "iconv-lite" "0.4.24" + "unpipe" "1.0.0" + +"rc@^1.0.1", "rc@^1.1.6": + "integrity" "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==" + "resolved" "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz" + "version" "1.2.8" + dependencies: + "deep-extend" "^0.6.0" + "ini" "~1.3.0" + "minimist" "^1.2.6" + "strip-json-comments" "~2.0.1" + +"read-package-json-fast@^3.0.0": + "integrity" "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==" + "resolved" "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "json-parse-even-better-errors" "^3.0.0" + "npm-normalize-package-bin" "^3.0.0" + +"read-package-json@^6.0.0": + "integrity" "sha512-b/9jxWJ8EwogJPpv99ma+QwtqB7FSl3+V6UXS7Aaay8/5VwMY50oIFooY1UKXMWpfNCM6T/PoGqa5GD1g9xf9w==" + "resolved" "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "glob" "^8.0.1" + "json-parse-even-better-errors" "^3.0.0" + "normalize-package-data" "^5.0.0" + "npm-normalize-package-bin" "^3.0.0" + +"readable-stream@^2.0.1", "readable-stream@^2.0.2", "readable-stream@^2.1.5", "readable-stream@~2.3.6": + "integrity" "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==" + "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz" + "version" "2.3.6" + 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" + +"readable-stream@^3.0.6": + "integrity" "sha512-RV20kLjdmpZuTF1INEb9IA3L68Nmi+Ri7ppZqo78wj//Pn62fCoJyV9zalccNzDD/OuJpMG4f+pfMl8+L6QdGw==" + "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-3.2.0.tgz" + "version" "3.2.0" + dependencies: + "inherits" "^2.0.3" + "string_decoder" "^1.1.1" + "util-deprecate" "^1.0.1" + +"readable-stream@^3.4.0": + "integrity" "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==" + "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" + "version" "3.6.0" + dependencies: + "inherits" "^2.0.3" + "string_decoder" "^1.1.1" + "util-deprecate" "^1.0.1" + +"readable-stream@^3.6.0": + "integrity" "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==" + "resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz" + "version" "3.6.1" + dependencies: + "inherits" "^2.0.3" + "string_decoder" "^1.1.1" + "util-deprecate" "^1.0.1" + +"readdirp@^2.2.1": + "integrity" "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==" + "resolved" "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz" + "version" "2.2.1" + dependencies: + "graceful-fs" "^4.1.11" + "micromatch" "^3.1.10" + "readable-stream" "^2.0.2" + +"readdirp@~3.6.0": + "integrity" "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==" + "resolved" "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" + "version" "3.6.0" + dependencies: + "picomatch" "^2.2.1" + +"rechoir@^0.6.2": + "integrity" "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==" + "resolved" "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz" + "version" "0.6.2" + dependencies: + "resolve" "^1.1.6" + +"reflect-metadata@^0.1.2": + "integrity" "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + "resolved" "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz" + "version" "0.1.13" + +"regenerate-unicode-properties@^10.1.0": + "integrity" "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==" + "resolved" "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz" + "version" "10.1.0" + dependencies: + "regenerate" "^1.4.2" + +"regenerate@^1.4.2": + "integrity" "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + "resolved" "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz" + "version" "1.4.2" + +"regenerator-runtime@^0.13.11": + "integrity" "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "resolved" "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" + "version" "0.13.11" + +"regenerator-transform@^0.15.1": + "integrity" "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==" + "resolved" "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz" + "version" "0.15.1" dependencies: - ms "2.1.2" - -decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" - -decode-uri-component@^0.2.0: - version "0.2.2" - resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz" + "@babel/runtime" "^7.8.4" -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz" +"regex-not@^1.0.0", "regex-not@^1.0.2": + "integrity" "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==" + "resolved" "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz" + "version" "1.0.2" dependencies: - mimic-response "^3.1.0" + "extend-shallow" "^3.0.2" + "safe-regex" "^1.1.0" -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz" +"regex-parser@^2.2.11": + "integrity" "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" + "resolved" "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz" + "version" "2.2.11" -deep-is@^0.1.3: - version "0.1.4" - resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" +"regexpp@^3.2.0": + "integrity" "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" + "resolved" "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" + "version" "3.2.0" -default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz" +"regexpu-core@^5.3.1": + "integrity" "sha512-nCOzW2V/X15XpLsK2rlgdwrysrBq+AauCn+omItIz4R1pIcmeot5zvjdmOBRLzEH/CkC6IxMJVmxDe3QcMuNVQ==" + "resolved" "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.1.tgz" + "version" "5.3.1" dependencies: - execa "^5.0.0" - -defaults@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz" - dependencies: - clone "^1.0.2" - -defer-to-connect@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz" + "@babel/regjsgen" "^0.8.0" + "regenerate" "^1.4.2" + "regenerate-unicode-properties" "^10.1.0" + "regjsparser" "^0.9.1" + "unicode-match-property-ecmascript" "^2.0.0" + "unicode-match-property-value-ecmascript" "^2.1.0" + +"registry-auth-token@^3.0.1": + "integrity" "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==" + "resolved" "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz" + "version" "3.3.2" + dependencies: + "rc" "^1.1.6" + "safe-buffer" "^5.0.1" + +"registry-url@^3.0.3": + "integrity" "sha1-PU74cPc93h138M+aOBQyRE4XSUI=" + "resolved" "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "rc" "^1.0.1" + +"regjsparser@^0.9.1": + "integrity" "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==" + "resolved" "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz" + "version" "0.9.1" + dependencies: + "jsesc" "~0.5.0" + +"remove-trailing-separator@^1.0.1": + "integrity" "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + "resolved" "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz" + "version" "1.1.0" + +"repeat-element@^1.1.2": + "integrity" "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + "resolved" "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz" + "version" "1.1.3" + +"repeat-string@^1.6.1": + "integrity" "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + "resolved" "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" + "version" "1.6.1" + +"request@^2.87.0", "request@^2.88.0": + "integrity" "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==" + "resolved" "https://registry.npmjs.org/request/-/request-2.88.0.tgz" + "version" "2.88.0" + dependencies: + "aws-sign2" "~0.7.0" + "aws4" "^1.8.0" + "caseless" "~0.12.0" + "combined-stream" "~1.0.6" + "extend" "~3.0.2" + "forever-agent" "~0.6.1" + "form-data" "~2.3.2" + "har-validator" "~5.1.0" + "http-signature" "~1.2.0" + "is-typedarray" "~1.0.0" + "isstream" "~0.1.2" + "json-stringify-safe" "~5.0.1" + "mime-types" "~2.1.19" + "oauth-sign" "~0.9.0" + "performance-now" "^2.1.0" + "qs" "~6.5.2" + "safe-buffer" "^5.1.2" + "tough-cookie" "~2.4.3" + "tunnel-agent" "^0.6.0" + "uuid" "^3.3.2" + +"require-directory@^2.1.1": + "integrity" "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + "resolved" "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + "version" "2.1.1" + +"require-from-string@^2.0.2": + "integrity" "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + "resolved" "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" + "version" "2.0.2" + +"require-main-filename@^2.0.0": + "integrity" "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + "resolved" "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz" + "version" "2.0.0" + +"requires-port@^1.0.0": + "integrity" "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + "resolved" "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" + "version" "1.0.0" + +"resolve-alpn@^1.2.0": + "integrity" "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + "resolved" "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz" + "version" "1.2.1" + +"resolve-from@^4.0.0": + "integrity" "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + "resolved" "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" + "version" "4.0.0" + +"resolve-from@^5.0.0": + "integrity" "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + "resolved" "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" + "version" "5.0.0" + +"resolve-url-loader@5.0.0": + "integrity" "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==" + "resolved" "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "adjust-sourcemap-loader" "^4.0.0" + "convert-source-map" "^1.7.0" + "loader-utils" "^2.0.0" + "postcss" "^8.2.14" + "source-map" "0.6.1" + +"resolve-url@^0.2.1": + "integrity" "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + "resolved" "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz" + "version" "0.2.1" + +"resolve@^1.1.6", "resolve@^1.14.2", "resolve@^1.3.2", "resolve@^1.3.3", "resolve@1.22.1": + "integrity" "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==" + "resolved" "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz" + "version" "1.22.1" + dependencies: + "is-core-module" "^2.9.0" + "path-parse" "^1.0.7" + "supports-preserve-symlinks-flag" "^1.0.0" + +"responselike@^2.0.0": + "integrity" "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==" + "resolved" "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "lowercase-keys" "^2.0.0" + +"restore-cursor@^3.1.0": + "integrity" "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==" + "resolved" "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "onetime" "^5.1.0" + "signal-exit" "^3.0.2" + +"ret@~0.1.10": + "integrity" "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + "resolved" "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" + "version" "0.1.15" + +"retry@^0.12.0": + "integrity" "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==" + "resolved" "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" + "version" "0.12.0" + +"retry@^0.13.1": + "integrity" "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" + "resolved" "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz" + "version" "0.13.1" + +"reusify@^1.0.4": + "integrity" "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + "resolved" "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" + "version" "1.0.4" + +"rfdc@^1.3.0": + "integrity" "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + "resolved" "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" + "version" "1.3.0" + +"rimraf@^2.2.8", "rimraf@^2.5.2", "rimraf@^2.5.4": + "integrity" "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==" + "resolved" "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" + "version" "2.7.1" + dependencies: + "glob" "^7.1.3" + +"rimraf@^3.0.0", "rimraf@^3.0.2": + "integrity" "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==" + "resolved" "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "glob" "^7.1.3" + +"run-async@^2.4.0": + "integrity" "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" + "resolved" "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz" + "version" "2.4.1" + +"run-parallel@^1.1.9": + "integrity" "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==" + "resolved" "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" + "version" "1.2.0" + dependencies: + "queue-microtask" "^1.2.2" + +"rxjs-compat@^6.5.2": + "integrity" "sha512-szN4fK+TqBPOFBcBcsR0g2cmTTUF/vaFEOZNuSdfU8/pGFnNmmn2u8SystYXG1QMrjOPBc6XTKHMVfENDf6hHw==" + "resolved" "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.6.7.tgz" + "version" "6.6.7" + +"rxjs-tslint@^0.1.8": + "integrity" "sha512-4MNcco1pugjNyjkUkvJ9ngJSMCuwmyc1g6EkEYzlTK0PrZxm8xVaBeBz5aPLE3AzldQbYkOErOVAayUlzQkjAg==" + "resolved" "https://registry.npmjs.org/rxjs-tslint/-/rxjs-tslint-0.1.8.tgz" + "version" "0.1.8" + dependencies: + "chalk" "^2.4.0" + "tslint" "^5.9.1" + "tsutils" "^2.25.0" + "typescript" ">=2.8.3" + "yargs" "^15.3.1" + +"rxjs@^6.5.2", "rxjs@^6.5.3", "rxjs@^6.5.3 || ^7.4.0", "rxjs@6.6.7": + "integrity" "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==" + "resolved" "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz" + "version" "6.6.7" + dependencies: + "tslib" "^1.9.0" + +"rxjs@^7.5.5": + "integrity" "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==" + "resolved" "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz" + "version" "7.8.0" + dependencies: + "tslib" "^2.1.0" + +"safe-buffer@^5.0.1", "safe-buffer@^5.1.0", "safe-buffer@^5.1.2", "safe-buffer@>=5.1.0", "safe-buffer@~5.1.0", "safe-buffer@~5.1.1", "safe-buffer@5.1.2": + "integrity" "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + "version" "5.1.2" + +"safe-buffer@5.2.1": + "integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + "version" "5.2.1" + +"safe-regex@^1.1.0": + "integrity" "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=" + "resolved" "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz" + "version" "1.1.0" + dependencies: + "ret" "~0.1.10" + +"safer-buffer@^2.0.2", "safer-buffer@^2.1.0", "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", "safer-buffer@~2.1.0": + "integrity" "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "resolved" "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + "version" "2.1.2" + +"sass-lint@^1.13.1": + "integrity" "sha512-DSyah8/MyjzW2BWYmQWekYEKir44BpLqrCFsgs9iaWiVTcwZfwXHF586hh3D1n+/9ihUNMfd8iHAyb9KkGgs7Q==" + "resolved" "https://registry.npmjs.org/sass-lint/-/sass-lint-1.13.1.tgz" + "version" "1.13.1" + dependencies: + "commander" "^2.8.1" + "eslint" "8.10.0" + "front-matter" "2.1.2" + "fs-extra" "^3.0.1" + "glob" "^7.0.0" + "globule" "^1.0.0" + "gonzales-pe-sl" "^4.2.3" + "js-yaml" "^3.5.4" + "known-css-properties" "^0.3.0" + "lodash.capitalize" "^4.1.0" + "lodash.kebabcase" "^4.0.0" + "merge" "2.1.1" + "path-is-absolute" "^1.0.0" + "util" "^0.10.3" + +"sass-loader@13.2.0": + "integrity" "sha512-JWEp48djQA4nbZxmgC02/Wh0eroSUutulROUusYJO9P9zltRbNN80JCBHqRGzjd4cmZCa/r88xgfkjGD0TXsHg==" + "resolved" "https://registry.npmjs.org/sass-loader/-/sass-loader-13.2.0.tgz" + "version" "13.2.0" + dependencies: + "klona" "^2.0.4" + "neo-async" "^2.6.2" + +"sass@^1.3.0", "sass@1.58.1": + "integrity" "sha512-bnINi6nPXbP1XNRaranMFEBZWUfdW/AF16Ql5+ypRxfTvCRTTKrLsMIakyDcayUt2t/RZotmL4kgJwNH5xO+bg==" + "resolved" "https://registry.npmjs.org/sass/-/sass-1.58.1.tgz" + "version" "1.58.1" + dependencies: + "chokidar" ">=3.0.0 <4.0.0" + "immutable" "^4.0.0" + "source-map-js" ">=0.6.2 <2.0.0" + +"saucelabs@^1.5.0": + "integrity" "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==" + "resolved" "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz" + "version" "1.5.0" + dependencies: + "https-proxy-agent" "^2.2.1" + +"sax@^1.2.4", "sax@>=0.6.0": + "integrity" "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + "resolved" "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" + "version" "1.2.4" + +"schema-utils@^3.0.0": + "integrity" "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==" + "resolved" "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz" + "version" "3.1.1" dependencies: - is-descriptor "^0.1.0" + "@types/json-schema" "^7.0.8" + "ajv" "^6.12.5" + "ajv-keywords" "^3.5.2" -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz" +"schema-utils@^3.1.0": + "integrity" "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==" + "resolved" "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz" + "version" "3.1.1" dependencies: - is-descriptor "^1.0.0" + "@types/json-schema" "^7.0.8" + "ajv" "^6.12.5" + "ajv-keywords" "^3.5.2" -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz" +"schema-utils@^3.1.1": + "integrity" "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==" + "resolved" "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz" + "version" "3.1.1" dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" + "@types/json-schema" "^7.0.8" + "ajv" "^6.12.5" + "ajv-keywords" "^3.5.2" -del@^2.2.0: - version "2.2.2" - resolved "https://registry.npmjs.org/del/-/del-2.2.2.tgz" +"schema-utils@^4.0.0": + "integrity" "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==" + "resolved" "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz" + "version" "4.0.0" dependencies: - globby "^5.0.0" - is-path-cwd "^1.0.0" - is-path-in-cwd "^1.0.0" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - rimraf "^2.2.8" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" - -depd@^1.1.2, depd@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" - -dependency-graph@^0.11.0: - version "0.11.0" - resolved "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz" - -destroy@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" - -detect-node@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz" - -di@^0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/di/-/di-0.0.1.tgz" - -diff@^3.1.0: - version "3.5.0" - resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" + "@types/json-schema" "^7.0.9" + "ajv" "^8.8.0" + "ajv-formats" "^2.1.1" + "ajv-keywords" "^5.0.0" + +"select-hose@^2.0.0": + "integrity" "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" + "resolved" "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" + "version" "2.0.0" + +"selenium-webdriver@^3.0.1", "selenium-webdriver@3.6.0": + "integrity" "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==" + "resolved" "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz" + "version" "3.6.0" + dependencies: + "jszip" "^3.1.3" + "rimraf" "^2.5.4" + "tmp" "0.0.30" + "xml2js" "^0.4.17" + +"selfsigned@^2.1.1": + "integrity" "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==" + "resolved" "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz" + "version" "2.1.1" + dependencies: + "node-forge" "^1" + +"semver-diff@^2.0.0": + "integrity" "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=" + "resolved" "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "semver" "^5.0.3" + +"semver-dsl@^1.0.1": + "integrity" "sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=" + "resolved" "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "semver" "^5.3.0" + +"semver@^5.0.3", "semver@^5.1.0", "semver@^5.3.0", "semver@^5.6.0", "semver@^5.7.1": + "integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" + "version" "5.7.1" + +"semver@^6.0.0": + "integrity" "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "resolved" "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + "version" "6.3.0" + +"semver@^6.1.1": + "integrity" "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "resolved" "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + "version" "6.3.0" + +"semver@^6.1.2": + "integrity" "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "resolved" "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + "version" "6.3.0" + +"semver@^6.3.0": + "integrity" "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "resolved" "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + "version" "6.3.0" + +"semver@^7.0.0": + "integrity" "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==" + "resolved" "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz" + "version" "7.3.8" + dependencies: + "lru-cache" "^6.0.0" + +"semver@^7.1.1": + "integrity" "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==" + "resolved" "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz" + "version" "7.3.8" + dependencies: + "lru-cache" "^6.0.0" + +"semver@^7.3.5": + "integrity" "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==" + "resolved" "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz" + "version" "7.3.8" + dependencies: + "lru-cache" "^6.0.0" + +"semver@^7.3.8": + "integrity" "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==" + "resolved" "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz" + "version" "7.3.8" + dependencies: + "lru-cache" "^6.0.0" + +"semver@7.3.8": + "integrity" "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==" + "resolved" "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz" + "version" "7.3.8" + dependencies: + "lru-cache" "^6.0.0" + +"send@0.18.0": + "integrity" "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==" + "resolved" "https://registry.npmjs.org/send/-/send-0.18.0.tgz" + "version" "0.18.0" + 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" + +"serialize-javascript@^6.0.0": + "integrity" "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==" + "resolved" "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz" + "version" "6.0.1" + dependencies: + "randombytes" "^2.1.0" + +"serve-index@^1.9.1": + "integrity" "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=" + "resolved" "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz" + "version" "1.9.1" + dependencies: + "accepts" "~1.3.4" + "batch" "0.6.1" + "debug" "2.6.9" + "escape-html" "~1.0.3" + "http-errors" "~1.6.2" + "mime-types" "~2.1.17" + "parseurl" "~1.3.2" + +"serve-static@1.15.0": + "integrity" "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==" + "resolved" "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" + "version" "1.15.0" + dependencies: + "encodeurl" "~1.0.2" + "escape-html" "~1.0.3" + "parseurl" "~1.3.3" + "send" "0.18.0" + +"set-blocking@^2.0.0": + "integrity" "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "resolved" "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" + "version" "2.0.0" + +"set-value@^2.0.0": + "integrity" "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==" + "resolved" "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "extend-shallow" "^2.0.1" + "is-extendable" "^0.1.1" + "is-plain-object" "^2.0.3" + "split-string" "^3.0.1" + +"set-value@^2.0.1": + "integrity" "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==" + "resolved" "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "extend-shallow" "^2.0.1" + "is-extendable" "^0.1.1" + "is-plain-object" "^2.0.3" + "split-string" "^3.0.1" + +"setimmediate@^1.0.5": + "integrity" "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + "resolved" "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" + "version" "1.0.5" + +"setprototypeof@1.1.0": + "integrity" "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + "resolved" "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" + "version" "1.1.0" + +"setprototypeof@1.2.0": + "integrity" "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "resolved" "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + "version" "1.2.0" + +"shallow-clone@^3.0.0": + "integrity" "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==" + "resolved" "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "kind-of" "^6.0.2" + +"shebang-command@^1.2.0": + "integrity" "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=" + "resolved" "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz" + "version" "1.2.0" + dependencies: + "shebang-regex" "^1.0.0" + +"shebang-command@^2.0.0": + "integrity" "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==" + "resolved" "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "shebang-regex" "^3.0.0" + +"shebang-regex@^1.0.0": + "integrity" "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + "resolved" "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz" + "version" "1.0.0" + +"shebang-regex@^3.0.0": + "integrity" "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + "resolved" "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + "version" "3.0.0" + +"shelljs@^0.8.4": + "integrity" "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==" + "resolved" "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz" + "version" "0.8.5" + dependencies: + "glob" "^7.0.0" + "interpret" "^1.0.0" + "rechoir" "^0.6.2" + +"shiki-languages@^0.2.7": + "integrity" "sha512-REmakh7pn2jCn9GDMRSK36oDgqhh+rSvJPo77sdWTOmk44C5b0XlYPwJZcFOMJWUZJE0c7FCbKclw4FLwUKLRw==" + "resolved" "https://registry.npmjs.org/shiki-languages/-/shiki-languages-0.2.7.tgz" + "version" "0.2.7" + dependencies: + "vscode-textmate" "^5.2.0" + +"shiki-themes@^0.2.7": + "integrity" "sha512-ZMmboDYw5+SEpugM8KGUq3tkZ0vXg+k60XX6NngDK7gc1Sv6YLUlanpvG3evm57uKJvfXsky/S5MzSOTtYKLjA==" + "resolved" "https://registry.npmjs.org/shiki-themes/-/shiki-themes-0.2.7.tgz" + "version" "0.2.7" + dependencies: + "json5" "^2.1.0" + "vscode-textmate" "^5.2.0" + +"shiki@^0.2.6": + "integrity" "sha512-bwVc7cdtYYHEO9O+XJ8aNOskKRfaQd5Y4ovLRfbQkmiLSUaR+bdlssbZUUhbQ0JAFMYcTcJ5tjG5KtnufttDHQ==" + "resolved" "https://registry.npmjs.org/shiki/-/shiki-0.2.7.tgz" + "version" "0.2.7" + dependencies: + "onigasm" "^2.2.5" + "shiki-languages" "^0.2.7" + "shiki-themes" "^0.2.7" + "vscode-textmate" "^5.2.0" + +"side-channel@^1.0.4": + "integrity" "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==" + "resolved" "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" + "version" "1.0.4" + dependencies: + "call-bind" "^1.0.0" + "get-intrinsic" "^1.0.2" + "object-inspect" "^1.9.0" + +"signal-exit@^3.0.0", "signal-exit@^3.0.2", "signal-exit@^3.0.3", "signal-exit@^3.0.7": + "integrity" "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + "resolved" "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + "version" "3.0.7" + +"sigstore@^1.0.0": + "integrity" "sha512-e+qfbn/zf1+rCza/BhIA//Awmf0v1pa5HQS8Xk8iXrn9bgytytVLqYD0P7NSqZ6IELTgq+tcDvLPkQjNHyWLNg==" + "resolved" "https://registry.npmjs.org/sigstore/-/sigstore-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "make-fetch-happen" "^11.0.1" + "tuf-js" "^1.0.0" + +"simple-swizzle@^0.2.2": + "integrity" "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==" + "resolved" "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz" + "version" "0.2.2" + dependencies: + "is-arrayish" "^0.3.1" + +"slash@^4.0.0": + "integrity" "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==" + "resolved" "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz" + "version" "4.0.0" + +"smart-buffer@^4.2.0": + "integrity" "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + "resolved" "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" + "version" "4.2.0" + +"snapdragon-node@^2.0.1": + "integrity" "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==" + "resolved" "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz" + "version" "2.1.1" + dependencies: + "define-property" "^1.0.0" + "isobject" "^3.0.0" + "snapdragon-util" "^3.0.1" + +"snapdragon-util@^3.0.1": + "integrity" "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==" + "resolved" "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "kind-of" "^3.2.0" + +"snapdragon@^0.8.1": + "integrity" "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==" + "resolved" "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz" + "version" "0.8.2" + dependencies: + "base" "^0.11.1" + "debug" "^2.2.0" + "define-property" "^0.2.5" + "extend-shallow" "^2.0.1" + "map-cache" "^0.2.2" + "source-map" "^0.5.6" + "source-map-resolve" "^0.5.0" + "use" "^3.1.0" + +"socket.io-adapter@~2.4.0": + "integrity" "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==" + "resolved" "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz" + "version" "2.4.0" + +"socket.io-parser@~4.2.0": + "integrity" "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==" + "resolved" "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz" + "version" "4.2.1" dependencies: - path-type "^4.0.0" - -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz" + "@socket.io/component-emitter" "~3.1.0" + "debug" "~4.3.1" + +"socket.io@^4.4.1": + "integrity" "sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg==" + "resolved" "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz" + "version" "4.5.3" + dependencies: + "accepts" "~1.3.4" + "base64id" "~2.0.0" + "debug" "~4.3.2" + "engine.io" "~6.2.0" + "socket.io-adapter" "~2.4.0" + "socket.io-parser" "~4.2.0" + +"sockjs@^0.3.24": + "integrity" "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==" + "resolved" "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz" + "version" "0.3.24" + dependencies: + "faye-websocket" "^0.11.3" + "uuid" "^8.3.2" + "websocket-driver" "^0.7.4" + +"socks-proxy-agent@^7.0.0": + "integrity" "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==" + "resolved" "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz" + "version" "7.0.0" + dependencies: + "agent-base" "^6.0.2" + "debug" "^4.3.3" + "socks" "^2.6.2" + +"socks@^2.6.2": + "integrity" "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==" + "resolved" "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz" + "version" "2.7.1" + dependencies: + "ip" "^2.0.0" + "smart-buffer" "^4.2.0" + +"source-map-js@^1.0.2", "source-map-js@>=0.6.2 <2.0.0": + "integrity" "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + "resolved" "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" + "version" "1.0.2" + +"source-map-loader@4.0.1": + "integrity" "sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==" + "resolved" "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz" + "version" "4.0.1" + dependencies: + "abab" "^2.0.6" + "iconv-lite" "^0.6.3" + "source-map-js" "^1.0.2" + +"source-map-resolve@^0.5.0": + "integrity" "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==" + "resolved" "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz" + "version" "0.5.2" + dependencies: + "atob" "^2.1.1" + "decode-uri-component" "^0.2.0" + "resolve-url" "^0.2.1" + "source-map-url" "^0.4.0" + "urix" "^0.1.0" + +"source-map-support@^0.5.5", "source-map-support@^0.5.6", "source-map-support@~0.5.20", "source-map-support@0.5.21": + "integrity" "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==" + "resolved" "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" + "version" "0.5.21" + dependencies: + "buffer-from" "^1.0.0" + "source-map" "^0.6.0" + +"source-map-support@~0.4.0": + "integrity" "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==" + "resolved" "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz" + "version" "0.4.18" + dependencies: + "source-map" "^0.5.6" + +"source-map-url@^0.4.0": + "integrity" "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + "resolved" "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz" + "version" "0.4.0" + +"source-map@^0.5.6", "source-map@^0.5.7": + "integrity" "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" + "version" "0.5.7" + +"source-map@^0.6.0": + "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + "version" "0.6.1" + +"source-map@^0.6.1": + "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + "version" "0.6.1" + +"source-map@~0.6.0": + "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + "version" "0.6.1" + +"source-map@0.6.1": + "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + "version" "0.6.1" + +"source-map@0.7.4": + "integrity" "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" + "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" + "version" "0.7.4" + +"spdx-correct@^3.0.0": + "integrity" "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==" + "resolved" "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz" + "version" "3.1.1" + dependencies: + "spdx-expression-parse" "^3.0.0" + "spdx-license-ids" "^3.0.0" + +"spdx-exceptions@^2.1.0": + "integrity" "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + "resolved" "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" + "version" "2.3.0" + +"spdx-expression-parse@^3.0.0": + "integrity" "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==" + "resolved" "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "spdx-exceptions" "^2.1.0" + "spdx-license-ids" "^3.0.0" + +"spdx-license-ids@^3.0.0": + "integrity" "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==" + "resolved" "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz" + "version" "3.0.12" + +"spdy-transport@^3.0.0": + "integrity" "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==" + "resolved" "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "debug" "^4.1.0" + "detect-node" "^2.0.4" + "hpack.js" "^2.1.6" + "obuf" "^1.1.2" + "readable-stream" "^3.0.6" + "wbuf" "^1.7.3" + +"spdy@^4.0.2": + "integrity" "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==" + "resolved" "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz" + "version" "4.0.2" + dependencies: + "debug" "^4.1.0" + "handle-thing" "^2.0.0" + "http-deceiver" "^1.2.7" + "select-hose" "^2.0.0" + "spdy-transport" "^3.0.0" + +"split-string@^3.0.1", "split-string@^3.0.2": + "integrity" "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==" + "resolved" "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "extend-shallow" "^3.0.0" + +"sprintf-js@^1.1.2": + "integrity" "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" + "resolved" "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz" + "version" "1.1.2" + +"sprintf-js@~1.0.2": + "integrity" "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + "resolved" "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + "version" "1.0.3" + +"sshpk@^1.7.0": + "integrity" "sha1-xvxhZIo9nE52T9P8306hBeSSupg=" + "resolved" "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz" + "version" "1.14.2" + dependencies: + "asn1" "~0.2.3" + "assert-plus" "^1.0.0" + "dashdash" "^1.12.0" + "getpass" "^0.1.1" + "safer-buffer" "^2.0.2" + optionalDependencies: + "bcrypt-pbkdf" "^1.0.0" + "ecc-jsbn" "~0.1.1" + "jsbn" "~0.1.0" + "tweetnacl" "~0.14.0" -dns-packet@^5.2.2: - version "5.4.0" - resolved "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz" +"ssri@^10.0.0", "ssri@>=8.0.1": + "integrity" "sha512-WVy6di9DlPOeBWEjMScpNipeSX2jIZBGEn5Uuo8Q7aIuFEuDX0pw8RxcOjlD1TWP4obi24ki7m/13+nFpcbXrw==" + "resolved" "https://registry.npmjs.org/ssri/-/ssri-10.0.1.tgz" + "version" "10.0.1" dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" + "minipass" "^4.0.0" -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" +"ssri@^9.0.0": + "integrity" "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==" + "resolved" "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz" + "version" "9.0.1" dependencies: - esutils "^2.0.2" + "minipass" "^3.1.1" -dom-serialize@^2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz" +"static-extend@^0.1.1": + "integrity" "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=" + "resolved" "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz" + "version" "0.1.2" dependencies: - custom-event "~1.0.0" - ent "~2.2.0" - extend "^3.0.0" - void-elements "^2.0.0" + "define-property" "^0.2.5" + "object-copy" "^0.1.0" -dom-serializer@^1.0.1: - version "1.4.1" - resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz" - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.0" - entities "^2.0.0" +"statuses@>= 1.4.0 < 2": + "integrity" "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + "resolved" "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz" + "version" "1.4.0" + +"statuses@~1.5.0": + "integrity" "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + "resolved" "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" + "version" "1.5.0" + +"statuses@2.0.1": + "integrity" "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + "resolved" "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + "version" "2.0.1" + +"streamroller@^3.0.2": + "integrity" "sha512-ur6y5S5dopOaRXBuRIZ1u6GC5bcEXHRZKgfBjfCglMhmIf+roVCECjvkEYzNQOXIN2/JPnkMPW/8B3CZoKaEPA==" + "resolved" "https://registry.npmjs.org/streamroller/-/streamroller-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "date-format" "^4.0.3" + "debug" "^4.1.1" + "fs-extra" "^10.0.0" -domelementtype@^2.0.1, domelementtype@^2.2.0: - version "2.3.0" - resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" +"string_decoder@^1.1.1", "string_decoder@~1.1.1": + "integrity" "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==" + "resolved" "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + "version" "1.1.1" + dependencies: + "safe-buffer" "~5.1.0" -domhandler@^4.2.0, domhandler@^4.3.1: - version "4.3.1" - resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz" +"string-width@^1.0.2 || 2 || 3 || 4", "string-width@^4.1.0", "string-width@^4.2.0", "string-width@^4.2.3": + "integrity" "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==" + "resolved" "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + "version" "4.2.3" dependencies: - domelementtype "^2.2.0" + "emoji-regex" "^8.0.0" + "is-fullwidth-code-point" "^3.0.0" + "strip-ansi" "^6.0.1" -domino@^2.1.2: - version "2.1.6" - resolved "https://registry.npmjs.org/domino/-/domino-2.1.6.tgz" +"string-width@^2.0.0": + "integrity" "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==" + "resolved" "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" + "version" "2.1.1" + dependencies: + "is-fullwidth-code-point" "^2.0.0" + "strip-ansi" "^4.0.0" -domutils@^2.8.0: - version "2.8.0" - resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz" +"string-width@^2.1.1": + "integrity" "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==" + "resolved" "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" + "version" "2.1.1" + dependencies: + "is-fullwidth-code-point" "^2.0.0" + "strip-ansi" "^4.0.0" + +"strip-ansi@^3.0.0": + "integrity" "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=" + "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "ansi-regex" "^2.0.0" + +"strip-ansi@^4.0.0": + "integrity" "sha1-qEeQIusaw2iocTibY1JixQXuNo8=" + "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "ansi-regex" "^3.0.0" + +"strip-ansi@^6.0.0": + "integrity" "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==" + "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + "version" "6.0.1" + dependencies: + "ansi-regex" "^5.0.1" + +"strip-ansi@^6.0.1": + "integrity" "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==" + "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + "version" "6.0.1" + dependencies: + "ansi-regex" "^5.0.1" + +"strip-eof@^1.0.0": + "integrity" "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + "resolved" "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz" + "version" "1.0.0" + +"strip-final-newline@^2.0.0": + "integrity" "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + "resolved" "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + "version" "2.0.0" + +"strip-json-comments@^3.1.0", "strip-json-comments@^3.1.1": + "integrity" "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + "resolved" "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + "version" "3.1.1" + +"strip-json-comments@~2.0.1": + "integrity" "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + "resolved" "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" + "version" "2.0.1" + +"supports-color@^2.0.0": + "integrity" "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" + "version" "2.0.0" + +"supports-color@^5.3.0": + "integrity" "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==" + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + "version" "5.5.0" dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.2.0" + "has-flag" "^3.0.0" + +"supports-color@^5.5.0": + "integrity" "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==" + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + "version" "5.5.0" + dependencies: + "has-flag" "^3.0.0" -dot-prop@^4.1.0: - version "4.2.1" - resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz" +"supports-color@^7.1.0": + "integrity" "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==" + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + "version" "7.2.0" dependencies: - is-obj "^1.0.0" + "has-flag" "^4.0.0" -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" +"supports-color@^8.0.0": + "integrity" "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==" + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + "version" "8.1.1" dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + "has-flag" "^4.0.0" + +"supports-preserve-symlinks-flag@^1.0.0": + "integrity" "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + "resolved" "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" + "version" "1.0.0" -electron-to-chromium@^1.4.284: - version "1.4.308" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.308.tgz" +"symbol-observable@4.0.0": + "integrity" "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==" + "resolved" "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz" + "version" "4.0.0" -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" +"tapable@^2.1.1", "tapable@^2.2.0": + "integrity" "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" + "resolved" "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" + "version" "2.2.1" -emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz" - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" - -encoding@^0.1.13: - version "0.1.13" - resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" +"tar@^6.1.11", "tar@^6.1.2": + "integrity" "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==" + "resolved" "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz" + "version" "6.1.13" + dependencies: + "chownr" "^2.0.0" + "fs-minipass" "^2.0.0" + "minipass" "^4.0.0" + "minizlib" "^2.1.1" + "mkdirp" "^1.0.3" + "yallist" "^4.0.0" + +"term-size@^1.2.0": + "integrity" "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=" + "resolved" "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz" + "version" "1.2.0" + dependencies: + "execa" "^0.7.0" + +"terser-webpack-plugin@^5.1.3": + "integrity" "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==" + "resolved" "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz" + "version" "5.3.6" dependencies: - iconv-lite "^0.6.2" + "@jridgewell/trace-mapping" "^0.3.14" + "jest-worker" "^27.4.5" + "schema-utils" "^3.1.1" + "serialize-javascript" "^6.0.0" + "terser" "^5.14.1" -end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz" +"terser@^5.14.1", "terser@5.16.3": + "integrity" "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==" + "resolved" "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz" + "version" "5.16.3" dependencies: - once "^1.4.0" - -engine.io-parser@~5.0.3: - version "5.0.4" - resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz" + "@jridgewell/source-map" "^0.3.2" + "acorn" "^8.5.0" + "commander" "^2.20.0" + "source-map-support" "~0.5.20" -engine.io@~6.2.0: - version "6.2.1" - resolved "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz" +"test-exclude@^6.0.0": + "integrity" "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==" + "resolved" "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" + "version" "6.0.0" dependencies: - "@types/cookie" "^0.4.1" - "@types/cors" "^2.8.12" - "@types/node" ">=10.0.0" - accepts "~1.3.4" - base64id "2.0.0" - cookie "~0.4.1" - cors "~2.8.5" - debug "~4.3.1" - engine.io-parser "~5.0.3" - ws "~8.2.3" + "@istanbuljs/schema" "^0.1.2" + "glob" "^7.1.4" + "minimatch" "^5.1.0" -enhanced-resolve@^5.10.0: - version "5.12.0" - resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz" +"text-table@^0.2.0", "text-table@0.2.0": + "integrity" "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "resolved" "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + "version" "0.2.0" + +"through@^2.3.6", "through@X.X.X": + "integrity" "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "resolved" "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + "version" "2.3.8" + +"through2@^2.0.0": + "integrity" "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=" + "resolved" "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz" + "version" "2.0.3" + dependencies: + "readable-stream" "^2.1.5" + "xtend" "~4.0.1" + +"thunky@^1.0.2": + "integrity" "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==" + "resolved" "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz" + "version" "1.0.3" + +"tmp@^0.0.33": + "integrity" "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==" + "resolved" "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" + "version" "0.0.33" + dependencies: + "os-tmpdir" "~1.0.2" + +"tmp@^0.2.1": + "integrity" "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==" + "resolved" "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" + "version" "0.2.1" + dependencies: + "rimraf" "^3.0.0" + +"tmp@0.0.30": + "integrity" "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=" + "resolved" "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz" + "version" "0.0.30" + dependencies: + "os-tmpdir" "~1.0.1" + +"to-fast-properties@^2.0.0": + "integrity" "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + "resolved" "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + "version" "2.0.0" + +"to-object-path@^0.3.0": + "integrity" "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=" + "resolved" "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz" + "version" "0.3.0" + dependencies: + "kind-of" "^3.0.2" + +"to-regex-range@^2.1.0": + "integrity" "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=" + "resolved" "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz" + "version" "2.1.1" + dependencies: + "is-number" "^3.0.0" + "repeat-string" "^1.6.1" + +"to-regex-range@^5.0.1": + "integrity" "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==" + "resolved" "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + "version" "5.0.1" + dependencies: + "is-number" "^7.0.0" + +"to-regex@^3.0.1", "to-regex@^3.0.2": + "integrity" "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==" + "resolved" "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "define-property" "^2.0.2" + "extend-shallow" "^3.0.2" + "regex-not" "^1.0.2" + "safe-regex" "^1.1.0" + +"toidentifier@1.0.1": + "integrity" "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + "resolved" "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + "version" "1.0.1" + +"touch@^3.1.0": + "integrity" "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==" + "resolved" "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "nopt" "~1.0.10" + +"tough-cookie@~2.4.3": + "integrity" "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==" + "resolved" "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz" + "version" "2.4.3" + dependencies: + "psl" "^1.1.24" + "punycode" "^1.4.1" + +"tr46@~0.0.3": + "integrity" "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "resolved" "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" + "version" "0.0.3" + +"tree-kill@1.2.2": + "integrity" "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" + "resolved" "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz" + "version" "1.2.2" + +"ts-helpers@1.1.2": + "integrity" "sha1-/Gm+nx87rtAfsaDvjUz+dIgU2DU=" + "resolved" "https://registry.npmjs.org/ts-helpers/-/ts-helpers-1.1.2.tgz" + "version" "1.1.2" + +"ts-node@~7.0.1": + "integrity" "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==" + "resolved" "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz" + "version" "7.0.1" + dependencies: + "arrify" "^1.0.0" + "buffer-from" "^1.1.0" + "diff" "^3.1.0" + "make-error" "^1.1.1" + "minimist" "^1.2.6" + "mkdirp" "^0.5.1" + "source-map-support" "^0.5.6" + "yn" "^2.0.0" + +"tslib@^1.10.0": + "integrity" "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "resolved" "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + "version" "1.14.1" + +"tslib@^1.13.0": + "integrity" "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "resolved" "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + "version" "1.14.1" + +"tslib@^1.8.0": + "integrity" "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "resolved" "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + "version" "1.14.1" + +"tslib@^1.8.1": + "integrity" "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "resolved" "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + "version" "1.14.1" + +"tslib@^1.9.0": + "integrity" "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "resolved" "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + "version" "1.14.1" + +"tslib@^2.0.0", "tslib@^2.1.0", "tslib@^2.3.0", "tslib@2.5.0": + "integrity" "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + "resolved" "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz" + "version" "2.5.0" + +"tslint@^5.0.0 || ^6.0.0", "tslint@~6.1.0": + "integrity" "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==" + "resolved" "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz" + "version" "6.1.3" dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -ent@~2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz" - -entities@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" - -entities@^4.3.0, entities@^4.4.0: - version "4.4.0" - resolved "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz" - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" - -err-code@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz" - -errno@^0.1.1: - version "0.1.8" - resolved "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz" + "@babel/code-frame" "^7.0.0" + "builtin-modules" "^1.1.1" + "chalk" "^2.3.0" + "commander" "^2.12.1" + "diff" "^4.0.1" + "glob" "^7.1.1" + "js-yaml" "^3.13.1" + "minimatch" "^5.1.0" + "mkdirp" "^0.5.3" + "resolve" "^1.3.2" + "semver" "^5.3.0" + "tslib" "^1.13.0" + "tsutils" "^2.29.0" + +"tslint@^5.9.1": + "integrity" "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==" + "resolved" "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz" + "version" "5.20.1" dependencies: - prr "~1.0.1" - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + "@babel/code-frame" "^7.0.0" + "builtin-modules" "^1.1.1" + "chalk" "^2.3.0" + "commander" "^2.12.1" + "diff" "^4.0.1" + "glob" "^7.1.1" + "js-yaml" "^3.13.1" + "minimatch" "^5.1.0" + "mkdirp" "^0.5.1" + "resolve" "^1.3.2" + "semver" "^5.3.0" + "tslib" "^1.8.0" + "tsutils" "^2.29.0" + +"tsutils@^2.25.0", "tsutils@^2.29.0": + "integrity" "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==" + "resolved" "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz" + "version" "2.29.0" + dependencies: + "tslib" "^1.8.1" + +"tuf-js@^1.0.0": + "integrity" "sha512-1dxsQwESDzACJjTdYHQ4wJ1f/of7jALWKfJEHSBWUQB/5UTJUx9SW6GHXp4mZ1KvdBRJCpGjssoPFGi4hvw8/A==" + "resolved" "https://registry.npmjs.org/tuf-js/-/tuf-js-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "make-fetch-happen" "^11.0.1" + "minimatch" "^6.1.0" + +"tunnel-agent@^0.6.0": + "integrity" "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=" + "resolved" "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" + "version" "0.6.0" + dependencies: + "safe-buffer" "^5.0.1" + +"tweetnacl@^0.14.3", "tweetnacl@~0.14.0": + "integrity" "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "resolved" "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" + "version" "0.14.5" + +"type-check@^0.4.0", "type-check@~0.4.0": + "integrity" "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==" + "resolved" "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" + "version" "0.4.0" + dependencies: + "prelude-ls" "^1.2.1" + +"type-fest@^0.20.2": + "integrity" "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + "resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" + "version" "0.20.2" + +"type-fest@^0.21.3": + "integrity" "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + "resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" + "version" "0.21.3" + +"type-is@~1.6.18": + "integrity" "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==" + "resolved" "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" + "version" "1.6.18" + dependencies: + "media-typer" "0.3.0" + "mime-types" "~2.1.24" + +"typed-assert@^1.0.8": + "integrity" "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==" + "resolved" "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz" + "version" "1.0.9" + +"typedoc@1.0.0-dev.4": + "integrity" "sha512-F+zuR8i6th/FTlcUBov9xSlIWNOBi36E2l/zgqlLXNyeMhxDS81OuKXimmn3eSZC4t2XZNJmJyk6uo6zKm7+Dg==" + "resolved" "https://registry.npmjs.org/typedoc/-/typedoc-1.0.0-dev.4.tgz" + "version" "1.0.0-dev.4" dependencies: - is-arrayish "^0.2.1" - -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz" - -es6-promise@^4.0.3: - version "4.2.8" - resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" - -es6-promisify@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz" - dependencies: - es6-promise "^4.0.3" - -esbuild-wasm@0.17.8: - version "0.17.8" - resolved "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.17.8.tgz" - -esbuild@0.17.8: - version "0.17.8" - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.17.8.tgz" - optionalDependencies: - "@esbuild/android-arm" "0.17.8" - "@esbuild/android-arm64" "0.17.8" - "@esbuild/android-x64" "0.17.8" - "@esbuild/darwin-arm64" "0.17.8" - "@esbuild/darwin-x64" "0.17.8" - "@esbuild/freebsd-arm64" "0.17.8" - "@esbuild/freebsd-x64" "0.17.8" - "@esbuild/linux-arm" "0.17.8" - "@esbuild/linux-arm64" "0.17.8" - "@esbuild/linux-ia32" "0.17.8" - "@esbuild/linux-loong64" "0.17.8" - "@esbuild/linux-mips64el" "0.17.8" - "@esbuild/linux-ppc64" "0.17.8" - "@esbuild/linux-riscv64" "0.17.8" - "@esbuild/linux-s390x" "0.17.8" - "@esbuild/linux-x64" "0.17.8" - "@esbuild/netbsd-x64" "0.17.8" - "@esbuild/openbsd-x64" "0.17.8" - "@esbuild/sunos-x64" "0.17.8" - "@esbuild/win32-arm64" "0.17.8" - "@esbuild/win32-ia32" "0.17.8" - "@esbuild/win32-x64" "0.17.8" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - -eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^7.1.1: - version "7.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz" - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" - -eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz" - -eslint@8.10.0: - version "8.10.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz" - dependencies: - "@eslint/eslintrc" "^1.2.0" - "@humanwhocodes/config-array" "^0.9.2" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.1.1" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.3.0" - espree "^9.3.1" - esquery "^1.4.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" - globals "^13.6.0" - ignore "^5.2.0" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^5.1.0" - 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" - -espree@^9.3.1: - version "9.3.1" - resolved "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz" - dependencies: - acorn "^8.7.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^3.3.0" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" - -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.2.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz" - -estraverse@^5.1.0: - version "5.2.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" - -estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - -esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz" - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" - -eventemitter-asyncresource@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz" - -eventemitter3@^4.0.0: - version "4.0.7" - resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" - -events@^3.2.0: - version "3.3.0" - resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" - -eventsource@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz" - dependencies: - original "^1.0.0" - -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz" - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz" - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -express@^4.17.3: - version "4.18.2" - resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.1" - 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.11.0" - 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" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz" - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@^3.0.0, extend@~3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz" - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz" - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0, extsprintf@^1.2.0: - version "1.3.0" - resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" - -fast-glob@^3.2.11: - version "3.2.12" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" - -fast-xml-parser@^3.19.0: - version "3.19.0" - resolved "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz" - -fastparse@^1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz" - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" - dependencies: - reusify "^1.0.4" - -faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz" - dependencies: - websocket-driver ">=0.5.1" - -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz" - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" - dependencies: - flat-cache "^3.0.4" - -file-loader@^6.2.0: - version "6.2.0" - resolved "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz" - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz" - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - dependencies: - to-regex-range "^5.0.1" - -finalhandler@1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz" - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" - 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" - -find-cache-dir@^3.3.2: - version "3.3.2" - resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz" - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0, flatted@^3.2.4: - version "3.2.5" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz" - -follow-redirects@^1.0.0: - version "1.14.8" - resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz" - -font-awesome@4.7.0: - version "4.7.0" - resolved "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" - -form-data-encoder@1.7.1: - version "1.7.1" - resolved "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz" - -form-data@~2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz" - dependencies: - asynckit "^0.4.0" - combined-stream "1.0.6" - mime-types "^2.1.12" - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" - -fraction.js@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz" - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz" - dependencies: - map-cache "^0.2.2" - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" - -front-matter@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/front-matter/-/front-matter-2.1.2.tgz" - dependencies: - js-yaml "^3.4.6" - -fs-extra@^10.0.0: - version "10.0.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz" - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^3.0.0" - universalify "^0.1.0" - -fs-minipass@^2.0.0, fs-minipass@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" - dependencies: - minipass "^3.0.0" - -fs-minipass@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.1.tgz" - dependencies: - minipass "^4.0.0" - -fs-monkey@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - -fsevents@^1.2.7: - version "1.2.13" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" - -gauge@^4.0.3: - version "4.0.4" - resolved "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz" - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^3.0.7" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" - -get-caller-file@^2.0.1, get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" - -get-intrinsic@^1.0.2: - version "1.1.1" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz" - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" - dependencies: - pump "^3.0.0" - -get-stream@^6.0.0, get-stream@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz" - dependencies: - assert-plus "^1.0.0" - -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.1: - version "6.0.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" - dependencies: - is-glob "^4.0.3" - -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" - -glob@8.1.0, glob@^8.0.1: - version "8.1.0" - resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -glob@^7.0.0, glob@^7.0.3, glob@^7.0.6, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@~7.1.1: - version "7.1.7" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.1.0" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.7: - version "7.2.0" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.1.0" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-dirs@^0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz" - dependencies: - ini "^1.3.4" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" - -globals@^13.6.0, globals@^13.9.0: - version "13.12.1" - resolved "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz" - dependencies: - type-fest "^0.20.2" - -globby@^13.1.1: - version "13.1.3" - resolved "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz" - dependencies: - dir-glob "^3.0.1" - fast-glob "^3.2.11" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^4.0.0" - -globby@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz" - dependencies: - array-union "^1.0.1" - arrify "^1.0.0" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -globule@^1.0.0: - version "1.2.1" - resolved "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz" - dependencies: - glob "~7.1.1" - lodash "~4.17.10" - minimatch "~5.1.0" - -gonzales-pe-sl@^4.2.3: - version "4.2.3" - resolved "https://registry.npmjs.org/gonzales-pe-sl/-/gonzales-pe-sl-4.2.3.tgz" - dependencies: - minimist "1.2.6" - -got@12.1.0: - version "12.1.0" - resolved "https://registry.npmjs.org/got/-/got-12.1.0.tgz" - dependencies: - "@sindresorhus/is" "^4.6.0" - "@szmarczak/http-timer" "^5.0.1" - "@types/cacheable-request" "^6.0.2" - "@types/responselike" "^1.0.0" - cacheable-lookup "^6.0.4" - cacheable-request "^7.0.2" - decompress-response "^6.0.0" - form-data-encoder "1.7.1" - get-stream "^6.0.1" - http2-wrapper "^2.1.10" - lowercase-keys "^3.0.0" - p-cancelable "^3.0.0" - responselike "^2.0.0" - -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.9" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz" - -handle-thing@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz" - -handlebars@^4.7.7: - version "4.7.7" - resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz" - dependencies: - minimist "^1.2.6" - neo-async "^2.6.0" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" - -har-validator@~5.1.0: - version "5.1.5" - resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz" - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" - dependencies: - ansi-regex "^2.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - -has-symbols@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz" - -has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz" - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz" - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz" - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz" - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - dependencies: - function-bind "^1.1.1" - -hdr-histogram-js@^2.0.1: - version "2.0.3" - resolved "https://registry.npmjs.org/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz" - dependencies: - "@assemblyscript/loader" "^0.10.1" - base64-js "^1.2.0" - pako "^1.0.3" - -hdr-histogram-percentiles-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz" - -hosted-git-info@^6.0.0: - version "6.1.1" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz" - dependencies: - lru-cache "^7.5.1" - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz" - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -html-entities@^2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz" - -http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz" - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-parser-js@>=0.5.1: - version "0.5.5" - resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz" - -http-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz" - dependencies: - "@tootallnate/once" "2" - agent-base "6" - debug "4" - -http-proxy-middleware@^2.0.3: - version "2.0.3" - resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.3.tgz" - dependencies: - "@types/http-proxy" "^1.17.8" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - -http-proxy@^1.18.1: - version "1.18.1" - resolved "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz" - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz" - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -http2-wrapper@^2.1.10: - version "2.1.11" - resolved "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz" - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.2.0" - -https-proxy-agent@5.0.1, https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" - dependencies: - agent-base "6" - debug "4" - -https-proxy-agent@^2.2.1: - version "2.2.4" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz" - dependencies: - agent-base "^4.3.0" - debug "^3.1.0" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" - -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz" - dependencies: - ms "^2.0.0" - -iconv-lite@0.4.24, iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@^0.6.2, iconv-lite@^0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -icss-utils@^5.0.0, icss-utils@^5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz" - -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" - -ignore-by-default@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz" - -ignore-walk@^6.0.0: - version "6.0.1" - resolved "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.1.tgz" - dependencies: - minimatch "^6.1.6" - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" - -ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" - -image-size@~0.5.0: - version "0.5.5" - resolved "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz" - -immediate@~3.0.5: - version "3.0.6" - resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz" - -immutable@^4.0.0: - version "4.2.4" - resolved "https://registry.npmjs.org/immutable/-/immutable-4.2.4.tgz" - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" - -infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" - -inherits@2.0.4, inherits@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - -ini@3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/ini/-/ini-3.0.1.tgz" - -ini@^1.3.4, ini@~1.3.0: - version "1.3.6" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.6.tgz" - -inquirer@8.2.4: - version "8.2.4" - resolved "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz" - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.1" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.21" - mute-stream "0.0.8" - ora "^5.4.1" - run-async "^2.4.0" - rxjs "^7.5.5" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - wrap-ansi "^7.0.0" - -interpret@^1.0.0: - version "1.4.0" - resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz" - -ip@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz" - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" - -ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz" - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz" - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz" - dependencies: - kind-of "^6.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz" - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz" - dependencies: - binary-extensions "^1.0.0" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" - dependencies: - binary-extensions "^2.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" - -is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz" - dependencies: - ci-info "^1.5.0" - -is-core-module@^2.8.1, is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz" - dependencies: - has "^1.0.3" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz" - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz" - dependencies: - kind-of "^6.0.0" - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz" - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz" - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz" - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" - dependencies: - is-extglob "^2.1.1" - -is-installed-globally@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz" - dependencies: - global-dirs "^0.1.0" - is-path-inside "^1.0.0" - -is-interactive@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz" - -is-lambda@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz" - -is-npm@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz" - dependencies: - kind-of "^3.0.2" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" - -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz" - -is-path-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz" - -is-path-in-cwd@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz" - dependencies: - is-path-inside "^1.0.0" - -is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz" - dependencies: - path-is-inside "^1.0.1" - -is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz" - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" - dependencies: - isobject "^3.0.1" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz" - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" - -is-svg@>=4.2.2: - version "4.3.1" - resolved "https://registry.npmjs.org/is-svg/-/is-svg-4.3.1.tgz" - dependencies: - fast-xml-parser "^3.19.0" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" - -is-what@^3.14.1: - version "3.14.1" - resolved "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz" - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" - dependencies: - is-docker "^2.0.0" - -isarray@1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - -isbinaryfile@^4.0.8: - version "4.0.8" - resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz" - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" - -isomorphic-fetch@3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz" - dependencies: - node-fetch "^2.6.1" - whatwg-fetch "^3.4.1" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" - -istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz" - -istanbul-lib-instrument@^5.0.4: - version "5.2.1" - resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz" - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^6.3.0" - -jasmine-core@4.5.0, jasmine-core@^4.1.0: - version "4.5.0" - resolved "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.5.0.tgz" - -jasmine-core@~2.8.0: - version "2.8.0" - resolved "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz" - -jasmine-spec-reporter@7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-7.0.0.tgz" - dependencies: - colors "1.4.0" - -jasmine@2.8.0: - version "2.8.0" - resolved "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz" - dependencies: - exit "^0.1.2" - glob "^7.0.6" - jasmine-core "~2.8.0" - -jasminewd2@^2.1.0: - version "2.2.0" - resolved "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz" - -jest-worker@^27.4.5: - version "27.5.1" - resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz" - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jquery@3.5.0: - version "3.5.0" - resolved "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz" - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" - -js-yaml@^3.13.1, js-yaml@^3.4.6, js-yaml@^3.5.4: - version "3.13.1" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - dependencies: - argparse "^2.0.1" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" - -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" - -json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" - -json-parse-even-better-errors@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz" - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" - -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" - -json5@^2.1.0, json5@^2.1.2, json5@^2.2.1, json5@^2.2.2: - version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" - -jsonc-parser@3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz" - -jsonfile@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonparse@^1.3.1: - version "1.3.1" - resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" - -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz" - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" - -jszip@^3.1.3: - version "3.10.1" - resolved "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz" - dependencies: - lie "~3.3.0" - pako "~1.0.2" - readable-stream "~2.3.6" - setimmediate "^1.0.5" - -karma-chrome-launcher@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz" - dependencies: - which "^1.2.1" - -karma-cli@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/karma-cli/-/karma-cli-2.0.0.tgz" - dependencies: - resolve "^1.3.3" - -karma-jasmine-html-reporter@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.0.0.tgz" - -karma-jasmine@5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz" - dependencies: - jasmine-core "^4.1.0" - -karma-source-map-support@1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz" - dependencies: - source-map-support "^0.5.5" - -karma@6.4.1: - version "6.4.1" - resolved "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz" - dependencies: - "@colors/colors" "1.5.0" - body-parser "^1.19.0" - braces "^3.0.2" - chokidar "^3.5.1" - connect "^3.7.0" - di "^0.0.1" - dom-serialize "^2.2.1" - glob "^7.1.7" - graceful-fs "^4.2.6" - http-proxy "^1.18.1" - isbinaryfile "^4.0.8" - lodash "^4.17.21" - log4js "^6.4.1" - mime "^2.5.2" - minimatch "^5.1.0" - mkdirp "^0.5.5" - qjobs "^1.2.0" - range-parser "^1.2.1" - rimraf "^3.0.2" - socket.io "^4.4.1" - source-map "^0.6.1" - tmp "^0.2.1" - ua-parser-js "^0.7.30" - yargs "^16.1.1" - -keyv@^4.0.0: - version "4.5.2" - resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz" - dependencies: - json-buffer "3.0.1" - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz" - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" - -klona@^2.0.4, klona@^2.0.5: - version "2.0.6" - resolved "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz" - -known-css-properties@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.3.0.tgz" - -latest-version@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz" - dependencies: - package-json "^4.0.0" - -less-loader@11.1.0: - version "11.1.0" - resolved "https://registry.npmjs.org/less-loader/-/less-loader-11.1.0.tgz" - dependencies: - klona "^2.0.4" - -less@4.1.3: - version "4.1.3" - resolved "https://registry.npmjs.org/less/-/less-4.1.3.tgz" - dependencies: - copy-anything "^2.0.1" - parse-node-version "^1.0.1" - tslib "^2.3.0" - optionalDependencies: - errno "^0.1.1" - graceful-fs "^4.1.2" - image-size "~0.5.0" - make-dir "^2.1.0" - mime "^1.4.1" - needle "^3.1.0" - source-map "~0.6.0" - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -license-webpack-plugin@4.0.2: - version "4.0.2" - resolved "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz" - dependencies: - webpack-sources "^3.0.0" - -lie@~3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz" - dependencies: - immediate "~3.0.5" - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" - -loader-runner@^4.2.0: - version "4.3.0" - resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz" - -loader-utils@3.2.1: - version "3.2.1" - resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz" - -loader-utils@^2.0.0: - version "2.0.4" - resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz" - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" - dependencies: - p-locate "^4.1.0" - -lodash.capitalize@^4.1.0: - version "4.2.1" - resolved "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz" - -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" - -lodash.kebabcase@^4.0.0: - version "4.1.1" - resolved "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz" - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" - -lodash@^4.17.21, lodash@~4.17.10: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" - -log-symbols@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -log4js@^6.4.1: - version "6.4.1" - resolved "https://registry.npmjs.org/log4js/-/log4js-6.4.1.tgz" - dependencies: - date-format "^4.0.3" - debug "^4.3.3" - flatted "^3.2.4" - rfdc "^1.3.0" - streamroller "^3.0.2" - -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" - -lowercase-keys@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz" - -lru-cache@^4.0.1: - version "4.1.3" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz" - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - dependencies: - yallist "^4.0.0" - -lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: - version "7.17.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.17.0.tgz" - -lunr@^2.3.9: - version "2.3.9" - resolved "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz" - -magic-string@0.29.0: - version "0.29.0" - resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.29.0.tgz" - dependencies: - "@jridgewell/sourcemap-codec" "^1.4.13" - -magic-string@^0.27.0: - version "0.27.0" - resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz" - dependencies: - "@jridgewell/sourcemap-codec" "^1.4.13" - -make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz" - dependencies: - pify "^3.0.0" - -make-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz" - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -make-dir@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" - dependencies: - semver "^6.0.0" - -make-error@^1.1.1: - version "1.3.4" - resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz" - -make-fetch-happen@^10.0.3: - version "10.2.1" - resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz" - dependencies: - agentkeepalive "^4.2.1" - cacache "^16.1.0" - http-cache-semantics "^4.1.0" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^3.1.6" - minipass-collect "^1.0.2" - minipass-fetch "^2.0.3" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^9.0.0" - -make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1: - version "11.0.3" - resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.0.3.tgz" - dependencies: - agentkeepalive "^4.2.1" - cacache "^17.0.0" - http-cache-semantics "^4.1.1" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^4.0.0" - minipass-fetch "^3.0.0" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^10.0.0" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz" - dependencies: - object-visit "^1.0.0" - -marked@4.2.12: - version "4.2.12" - resolved "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" - -memfs@^3.4.12, memfs@^3.4.3: - version "3.4.13" - resolved "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz" - dependencies: - fs-monkey "^1.0.3" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" - -merge@2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz" - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" - -micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -micromatch@^4.0.2: - version "4.0.4" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz" - dependencies: - braces "^3.0.1" - picomatch "^2.2.3" - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.51.0, "mime-db@>= 1.38.0 < 2": - version "1.51.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz" - -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.34" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz" - dependencies: - mime-db "1.51.0" - -mime@1.6.0, mime@^1.4.1: - version "1.6.0" - resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" - -mime@^2.5.2: - version "2.6.0" - resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" - -mimic-response@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz" - -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz" - -mini-css-extract-plugin@2.7.2: - version "2.7.2" - resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.2.tgz" - dependencies: - schema-utils "^4.0.0" - -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" - -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" - dependencies: - brace-expansion "^2.0.1" - -minimatch@^5.1.0, minimatch@~5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz" - dependencies: - brace-expansion "^2.0.1" - -minimatch@^6.1.0, minimatch@^6.1.6: - version "6.2.0" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz" - dependencies: - brace-expansion "^2.0.1" - -minimist@1.2.6, minimist@^1.2.6: - version "1.2.6" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz" - -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz" - dependencies: - minipass "^3.0.0" - -minipass-fetch@^2.0.3: - version "2.1.2" - resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz" - dependencies: - minipass "^3.1.6" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - -minipass-fetch@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.1.tgz" - dependencies: - minipass "^4.0.0" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz" - dependencies: - minipass "^3.0.0" - -minipass-json-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz" - dependencies: - jsonparse "^1.3.1" - minipass "^3.0.0" - -minipass-pipeline@^1.2.4: - version "1.2.4" - resolved "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz" - dependencies: - minipass "^3.0.0" - -minipass-sized@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz" - dependencies: - minipass "^3.0.0" - -minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: - version "3.3.6" - resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" - dependencies: - yallist "^4.0.0" - -minipass@^4.0.0: - version "4.2.0" - resolved "https://registry.npmjs.org/minipass/-/minipass-4.2.0.tgz" - -minizlib@^2.1.1, minizlib@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz" - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5: - version "0.5.6" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" - dependencies: - minimist "^1.2.6" - -mkdirp@^1.0.3, mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" - -ms@2.0.0, ms@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - -multicast-dns@^7.2.5: - version "7.2.5" - resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz" - dependencies: - dns-packet "^5.2.2" - thunky "^1.0.2" - -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" - -nan@^2.12.1: - version "2.17.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" - -nanoid@^3.3.4: - version "3.3.4" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz" - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" - -needle@^3.1.0: - version "3.2.0" - resolved "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz" - dependencies: - debug "^3.2.6" - iconv-lite "^0.6.3" - sax "^1.2.4" - -negotiator@0.6.3, negotiator@^0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" - -neo-async@^2.6.0, neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" - -ngx-toastr@15.2.2: - version "15.2.2" - resolved "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-15.2.2.tgz" - dependencies: - tslib "^2.3.0" - -nice-napi@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nice-napi/-/nice-napi-1.0.2.tgz#dc0ab5a1eac20ce548802fc5686eaa6bc654927b" - dependencies: - node-addon-api "^3.0.0" - node-gyp-build "^4.2.2" - -node-addon-api@^3.0.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" - -node-fetch@^2.6.1: - version "2.6.7" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" - dependencies: - whatwg-url "^5.0.0" - -node-forge@^1: - version "1.3.1" - resolved "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz" - -node-gyp-build@^4.2.2: - version "4.6.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" - -node-gyp@^9.0.0: - version "9.3.1" - resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-9.3.1.tgz" - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^10.0.3" - nopt "^6.0.0" - npmlog "^6.0.0" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.2" - which "^2.0.2" - -node-releases@^2.0.8: - version "2.0.10" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz" - -nodemon@^1.18.7: - version "1.19.4" - resolved "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz" - dependencies: - chokidar "^2.1.8" - debug "^3.2.6" - ignore-by-default "^1.0.1" - minimatch "^5.1.0" - pstree.remy "^1.1.7" - semver "^5.7.1" - supports-color "^5.5.0" - touch "^3.1.0" - undefsafe "^2.0.2" - update-notifier "^2.5.0" - -nopt@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz" - dependencies: - abbrev "^1.0.0" - -nopt@~1.0.10: - version "1.0.10" - resolved "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz" - dependencies: - abbrev "1" - -normalize-package-data@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz" - dependencies: - hosted-git-info "^6.0.0" - is-core-module "^2.8.1" - semver "^7.3.5" - validate-npm-package-license "^3.0.4" - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz" - dependencies: - remove-trailing-separator "^1.0.1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" - -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" - -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz" - -normalize.css@8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.0.tgz" - -npm-bundled@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.0.tgz" - dependencies: - npm-normalize-package-bin "^3.0.0" - -npm-install-checks@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.0.0.tgz" - dependencies: - semver "^7.1.1" - -npm-normalize-package-bin@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.0.tgz" - -npm-package-arg@10.1.0, npm-package-arg@^10.0.0: - version "10.1.0" - resolved "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz" - dependencies: - hosted-git-info "^6.0.0" - proc-log "^3.0.0" - semver "^7.3.5" - validate-npm-package-name "^5.0.0" - -npm-packlist@^7.0.0: - version "7.0.4" - resolved "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz" - dependencies: - ignore-walk "^6.0.0" - -npm-pick-manifest@8.0.1, npm-pick-manifest@^8.0.0: - version "8.0.1" - resolved "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz" - dependencies: - npm-install-checks "^6.0.0" - npm-normalize-package-bin "^3.0.0" - npm-package-arg "^10.0.0" - semver "^7.3.5" - -npm-registry-fetch@^14.0.0: - version "14.0.3" - resolved "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.3.tgz" - dependencies: - make-fetch-happen "^11.0.0" - minipass "^4.0.0" - minipass-fetch "^3.0.0" - minipass-json-stream "^1.0.1" - minizlib "^2.1.2" - npm-package-arg "^10.0.0" - proc-log "^3.0.0" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz" - dependencies: - path-key "^2.0.0" - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" - dependencies: - path-key "^3.0.0" - -npm-watch@0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/npm-watch/-/npm-watch-0.5.0.tgz" - dependencies: - nodemon "^1.18.7" - through2 "^2.0.0" - -npmlog@^6.0.0: - version "6.0.2" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz" - dependencies: - are-we-there-yet "^3.0.0" - console-control-strings "^1.1.0" - gauge "^4.0.3" - set-blocking "^2.0.0" - -nth-check@^2.0.1: - version "2.1.1" - resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" - dependencies: - boolbase "^1.0.0" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" - -object-assign@^4, object-assign@^4.0.1: - version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz" - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz" - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz" - dependencies: - isobject "^3.0.0" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz" - dependencies: - isobject "^3.0.1" - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" - dependencies: - ee-first "1.1.1" - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" - dependencies: - wrappy "1" - -onetime@^5.1.0, onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" - dependencies: - mimic-fn "^2.1.0" - -onigasm@^2.2.5: - version "2.2.5" - resolved "https://registry.npmjs.org/onigasm/-/onigasm-2.2.5.tgz" - dependencies: - lru-cache "^5.1.1" - -open@8.4.1, open@^8.0.9: - version "8.4.1" - resolved "https://registry.npmjs.org/open/-/open-8.4.1.tgz" - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -ora@5.4.1, ora@^5.4.1: - version "5.4.1" - resolved "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz" - dependencies: - bl "^4.1.0" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.5.0" - is-interactive "^1.0.0" - is-unicode-supported "^0.1.0" - log-symbols "^4.1.0" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - -original@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/original/-/original-1.0.2.tgz" - dependencies: - url-parse "^1.4.3" - -os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" - -p-cancelable@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" - -p-limit@^2.2.0: - version "2.2.2" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz" - dependencies: - p-try "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" - dependencies: - p-limit "^2.2.0" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" - dependencies: - aggregate-error "^3.0.0" - -p-retry@^4.5.0: - version "4.6.1" - resolved "https://registry.npmjs.org/p-retry/-/p-retry-4.6.1.tgz" - dependencies: - "@types/retry" "^0.12.0" - retry "^0.13.1" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" - -package-json@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz" - dependencies: - got "12.1.0" - registry-auth-token "^3.0.1" - registry-url "^3.0.3" - semver "^5.1.0" - -pacote@15.1.0: - version "15.1.0" - resolved "https://registry.npmjs.org/pacote/-/pacote-15.1.0.tgz" - dependencies: - "@npmcli/git" "^4.0.0" - "@npmcli/installed-package-contents" "^2.0.1" - "@npmcli/promise-spawn" "^6.0.1" - "@npmcli/run-script" "^6.0.0" - cacache "^17.0.0" - fs-minipass "^3.0.0" - minipass "^4.0.0" - npm-package-arg "^10.0.0" - npm-packlist "^7.0.0" - npm-pick-manifest "^8.0.0" - npm-registry-fetch "^14.0.0" - proc-log "^3.0.0" - promise-retry "^2.0.1" - read-package-json "^6.0.0" - read-package-json-fast "^3.0.0" - sigstore "^1.0.0" - ssri "^10.0.0" - tar "^6.1.11" - -pako@^1.0.3, pako@~1.0.2: - version "1.0.11" - resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" - dependencies: - callsites "^3.0.0" - -parse-json@^5.0.0: - version "5.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parse-node-version@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz" - -parse5-html-rewriting-stream@7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz" - dependencies: - entities "^4.3.0" - parse5 "^7.0.0" - parse5-sax-parser "^7.0.0" - -parse5-htmlparser2-tree-adapter@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz" - dependencies: - parse5 "^6.0.1" - -parse5-sax-parser@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz" - dependencies: - parse5 "^7.0.0" - -parse5@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" - -parse5@^7.0.0: - version "7.1.2" - resolved "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz" - dependencies: - entities "^4.4.0" - -parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz" - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - -path-is-inside@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz" - -path-key@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz" - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" - -piscina@3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/piscina/-/piscina-3.2.0.tgz" - dependencies: - eventemitter-asyncresource "^1.0.0" - hdr-histogram-js "^2.0.1" - hdr-histogram-percentiles-obj "^3.0.0" - optionalDependencies: - nice-napi "^1.0.2" - -pkg-dir@^4.1.0: - version "4.2.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" - dependencies: - find-up "^4.0.0" - -popper.js@1.16.1: - version "1.16.1" - resolved "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz" - -postcss-loader@7.0.2: - version "7.0.2" - resolved "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.0.2.tgz" - dependencies: - cosmiconfig "^7.0.0" - klona "^2.0.5" - semver "^7.3.8" - -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz" - -postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz" - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - -postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz" - dependencies: - postcss-selector-parser "^6.0.4" - -postcss-modules-values@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz" - dependencies: - icss-utils "^5.0.0" - -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.0.11" - resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz" - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" - -postcss@8.4.21, postcss@^8.2.14, postcss@^8.3.7, postcss@^8.4.19: - version "8.4.21" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz" - dependencies: - nanoid "^3.3.4" - picocolors "^1.0.0" - source-map-js "^1.0.2" - -preact-render-to-string@^5.1.10: - version "5.2.6" - resolved "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz" - dependencies: - pretty-format "^3.8.0" - -preact@^10.5.3: - version "10.12.1" - resolved "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" - -pretty-bytes@^5.3.0: - version "5.6.0" - resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz" - -pretty-format@^3.8.0: - version "3.8.0" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz" - -proc-log@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz" - -process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz" - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz" - -promise-retry@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz" - dependencies: - err-code "^2.0.2" - retry "^0.12.0" - -protractor@*, protractor@~7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/protractor/-/protractor-7.0.0.tgz" - dependencies: - "@types/q" "^0.0.32" - "@types/selenium-webdriver" "^3.0.0" - blocking-proxy "^1.0.0" - browserstack "^1.5.1" - chalk "^1.1.3" - glob "^7.0.3" - jasmine "2.8.0" - jasminewd2 "^2.1.0" - q "1.4.1" - saucelabs "^1.5.0" - selenium-webdriver "3.6.0" - source-map-support "~0.4.0" - webdriver-js-extender "2.1.0" - webdriver-manager "^12.1.7" - yargs "^15.3.1" - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz" - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz" - -psl@^1.1.24: - version "1.1.29" - resolved "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz" - -pstree.remy@^1.1.7: - version "1.1.7" - resolved "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" - -q@1.4.1, q@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/q/-/q-1.4.1.tgz" - -qjobs@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz" - -qs@6.11.0: - version "6.11.0" - resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" - dependencies: - side-channel "^1.0.4" - -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz" - -querystringify@^2.1.1: - version "2.2.0" - resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz" - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" - -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" - dependencies: - safe-buffer "^5.1.0" - -range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" - -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -rc@^1.0.1, rc@^1.1.6: - version "1.2.8" - resolved "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz" - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.6" - strip-json-comments "~2.0.1" - -read-package-json-fast@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz" - dependencies: - json-parse-even-better-errors "^3.0.0" - npm-normalize-package-bin "^3.0.0" - -read-package-json@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.0.tgz" - dependencies: - glob "^8.0.1" - json-parse-even-better-errors "^3.0.0" - normalize-package-data "^5.0.0" - npm-normalize-package-bin "^3.0.0" - -readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz" - 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" - -readable-stream@^3.0.6: - version "3.2.0" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.2.0.tgz" - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^3.4.0: - version "3.6.0" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^3.6.0: - version "3.6.1" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz" - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz" - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" - dependencies: - picomatch "^2.2.1" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz" - dependencies: - resolve "^1.1.6" - -reflect-metadata@^0.1.2: - version "0.1.13" - resolved "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz" - -regenerate-unicode-properties@^10.1.0: - version "10.1.0" - resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz" - dependencies: - regenerate "^1.4.2" - -regenerate@^1.4.2: - version "1.4.2" - resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz" - -regenerator-runtime@^0.13.11: - version "0.13.11" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" - -regenerator-transform@^0.15.1: - version "0.15.1" - resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz" - dependencies: - "@babel/runtime" "^7.8.4" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz" - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regex-parser@^2.2.11: - version "2.2.11" - resolved "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz" - -regexpp@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" - -regexpu-core@^5.3.1: - version "5.3.1" - resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.1.tgz" - dependencies: - "@babel/regjsgen" "^0.8.0" - regenerate "^1.4.2" - regenerate-unicode-properties "^10.1.0" - regjsparser "^0.9.1" - unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.1.0" - -registry-auth-token@^3.0.1: - version "3.3.2" - resolved "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz" - dependencies: - rc "^1.1.6" - safe-buffer "^5.0.1" - -registry-url@^3.0.3: - version "3.1.0" - resolved "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz" - dependencies: - rc "^1.0.1" - -regjsparser@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz" - dependencies: - jsesc "~0.5.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz" - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz" - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" - -request@^2.87.0, request@^2.88.0: - version "2.88.0" - resolved "https://registry.npmjs.org/request/-/request-2.88.0.tgz" - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.0" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.4.3" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz" - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" - -resolve-alpn@^1.2.0: - version "1.2.1" - resolved "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz" - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" - -resolve-url-loader@5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz" - dependencies: - adjust-sourcemap-loader "^4.0.0" - convert-source-map "^1.7.0" - loader-utils "^2.0.0" - postcss "^8.2.14" - source-map "0.6.1" - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz" - -resolve@1.22.1, resolve@^1.1.6, resolve@^1.14.2, resolve@^1.3.2, resolve@^1.3.3: - version "1.22.1" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz" - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -responselike@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz" - dependencies: - lowercase-keys "^2.0.0" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" - -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" - -rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" - -rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4: - version "2.7.1" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" - dependencies: - glob "^7.1.3" - -rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - dependencies: - glob "^7.1.3" - -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" - dependencies: - queue-microtask "^1.2.2" - -rxjs-compat@^6.5.2: - version "6.6.7" - resolved "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.6.7.tgz" - -rxjs-tslint@^0.1.8: - version "0.1.8" - resolved "https://registry.npmjs.org/rxjs-tslint/-/rxjs-tslint-0.1.8.tgz" - dependencies: - chalk "^2.4.0" - tslint "^5.9.1" - tsutils "^2.25.0" - typescript ">=2.8.3" - yargs "^15.3.1" - -rxjs@6.6.7, rxjs@^6.5.2, rxjs@^6.5.3: - version "6.6.7" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz" - dependencies: - tslib "^1.9.0" - -rxjs@^7.5.5: - version "7.8.0" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz" - dependencies: - tslib "^2.1.0" - -safe-buffer@5.1.2, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - -safe-buffer@5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz" - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" - -sass-lint@^1.13.1: - version "1.13.1" - resolved "https://registry.npmjs.org/sass-lint/-/sass-lint-1.13.1.tgz" - dependencies: - commander "^2.8.1" - eslint "8.10.0" - front-matter "2.1.2" - fs-extra "^3.0.1" - glob "^7.0.0" - globule "^1.0.0" - gonzales-pe-sl "^4.2.3" - js-yaml "^3.5.4" - known-css-properties "^0.3.0" - lodash.capitalize "^4.1.0" - lodash.kebabcase "^4.0.0" - merge "2.1.1" - path-is-absolute "^1.0.0" - util "^0.10.3" - -sass-loader@13.2.0: - version "13.2.0" - resolved "https://registry.npmjs.org/sass-loader/-/sass-loader-13.2.0.tgz" - dependencies: - klona "^2.0.4" - neo-async "^2.6.2" - -sass@1.58.1: - version "1.58.1" - resolved "https://registry.npmjs.org/sass/-/sass-1.58.1.tgz" - dependencies: - chokidar ">=3.0.0 <4.0.0" - immutable "^4.0.0" - source-map-js ">=0.6.2 <2.0.0" - -saucelabs@^1.5.0: - version "1.5.0" - resolved "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz" - dependencies: - https-proxy-agent "^2.2.1" - -sax@>=0.6.0, sax@^1.2.4: - version "1.2.4" - resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" - -schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz" - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz" - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.8.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" - -selenium-webdriver@3.6.0, selenium-webdriver@^3.0.1: - version "3.6.0" - resolved "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz" - dependencies: - jszip "^3.1.3" - rimraf "^2.5.4" - tmp "0.0.30" - xml2js "^0.4.17" - -selfsigned@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz" - dependencies: - node-forge "^1" - -semver-diff@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz" - dependencies: - semver "^5.0.3" - -semver-dsl@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz" - dependencies: - semver "^5.3.0" - -semver@7.3.8, semver@^7.0.0, semver@^7.1.1, semver@^7.3.5, semver@^7.3.8: - version "7.3.8" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz" - dependencies: - lru-cache "^6.0.0" - -semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.6.0, semver@^5.7.1: - version "5.7.1" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" - -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" - -send@0.18.0: - version "0.18.0" - resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" - 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" - -serialize-javascript@^6.0.0: - version "6.0.1" - resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz" - dependencies: - randombytes "^2.1.0" - -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz" - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz" - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" - dependencies: - kind-of "^6.0.2" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz" - dependencies: - shebang-regex "^1.0.0" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" - -shelljs@^0.8.4: - version "0.8.5" - resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz" - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -shiki-languages@^0.2.7: - version "0.2.7" - resolved "https://registry.npmjs.org/shiki-languages/-/shiki-languages-0.2.7.tgz" - dependencies: - vscode-textmate "^5.2.0" - -shiki-themes@^0.2.7: - version "0.2.7" - resolved "https://registry.npmjs.org/shiki-themes/-/shiki-themes-0.2.7.tgz" - dependencies: - json5 "^2.1.0" - vscode-textmate "^5.2.0" - -shiki@^0.2.6: - version "0.2.7" - resolved "https://registry.npmjs.org/shiki/-/shiki-0.2.7.tgz" - dependencies: - onigasm "^2.2.5" - shiki-languages "^0.2.7" - shiki-themes "^0.2.7" - vscode-textmate "^5.2.0" - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" - -sigstore@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/sigstore/-/sigstore-1.0.0.tgz" - dependencies: - make-fetch-happen "^11.0.1" - tuf-js "^1.0.0" - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz" - dependencies: - is-arrayish "^0.3.1" - -slash@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz" - -smart-buffer@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz" - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz" - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz" - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -socket.io-adapter@~2.4.0: - version "2.4.0" - resolved "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz" - -socket.io-parser@~4.2.0: - version "4.2.1" - resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz" - dependencies: - "@socket.io/component-emitter" "~3.1.0" - debug "~4.3.1" - -socket.io@^4.4.1: - version "4.5.3" - resolved "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz" - dependencies: - accepts "~1.3.4" - base64id "~2.0.0" - debug "~4.3.2" - engine.io "~6.2.0" - socket.io-adapter "~2.4.0" - socket.io-parser "~4.2.0" - -sockjs@^0.3.24: - version "0.3.24" - resolved "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz" - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - -socks-proxy-agent@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz" - dependencies: - agent-base "^6.0.2" - debug "^4.3.3" - socks "^2.6.2" - -socks@^2.6.2: - version "2.7.1" - resolved "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz" - dependencies: - ip "^2.0.0" - smart-buffer "^4.2.0" - -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" - -source-map-loader@4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz" - dependencies: - abab "^2.0.6" - iconv-lite "^0.6.3" - source-map-js "^1.0.2" - -source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz" - dependencies: - atob "^2.1.1" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@0.5.21, source-map-support@^0.5.5, source-map-support@^0.5.6, source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-support@~0.4.0: - version "0.4.18" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz" - dependencies: - source-map "^0.5.6" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz" - -source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: - version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - -source-map@0.7.4: - version "0.7.4" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" - -source-map@^0.5.6, source-map@^0.5.7: - version "0.5.7" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz" - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.12" - resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz" - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz" - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz" - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz" - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@^1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" - -sshpk@^1.7.0: - version "1.14.2" - resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz" - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - safer-buffer "^2.0.2" - optionalDependencies: - bcrypt-pbkdf "^1.0.0" - ecc-jsbn "~0.1.1" - jsbn "~0.1.0" - tweetnacl "~0.14.0" - -ssri@>=8.0.1, ssri@^10.0.0: - version "10.0.1" - resolved "https://registry.npmjs.org/ssri/-/ssri-10.0.1.tgz" - dependencies: - minipass "^4.0.0" - -ssri@^9.0.0: - version "9.0.1" - resolved "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz" - dependencies: - minipass "^3.1.1" - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz" - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" - -"statuses@>= 1.4.0 < 2": - version "1.4.0" - resolved "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz" - -statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" - -streamroller@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/streamroller/-/streamroller-3.0.2.tgz" - dependencies: - date-format "^4.0.3" - debug "^4.1.1" - fs-extra "^10.0.0" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^2.0.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string_decoder@^1.1.1, string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - dependencies: - ansi-regex "^5.0.1" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz" - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" - -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" - -supports-color@^5.3.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" - -symbol-observable@4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz" - -tapable@^2.1.1, tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" - -tar@^6.1.11, tar@^6.1.2: - version "6.1.13" - resolved "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz" - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^4.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -term-size@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz" - dependencies: - execa "^0.7.0" - -terser-webpack-plugin@^5.1.3: - version "5.3.6" - resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz" - dependencies: - "@jridgewell/trace-mapping" "^0.3.14" - jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - terser "^5.14.1" - -terser@5.16.3, terser@^5.14.1: - version "5.16.3" - resolved "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz" - dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" - commander "^2.20.0" - source-map-support "~0.5.20" - -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^5.1.0" - -text-table@0.2.0, text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" - -through2@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz" - dependencies: - readable-stream "^2.1.5" - xtend "~4.0.1" - -through@X.X.X, through@^2.3.6: - version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" - -thunky@^1.0.2: - version "1.0.3" - resolved "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz" - -tmp@0.0.30: - version "0.0.30" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz" - dependencies: - os-tmpdir "~1.0.1" - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" - dependencies: - os-tmpdir "~1.0.2" - -tmp@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" - dependencies: - rimraf "^3.0.0" - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz" - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz" - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" - dependencies: - is-number "^7.0.0" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz" - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" - -touch@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz" - dependencies: - nopt "~1.0.10" - -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz" - dependencies: - psl "^1.1.24" - punycode "^1.4.1" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" - -tree-kill@1.2.2: - version "1.2.2" - resolved "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz" - -ts-helpers@1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/ts-helpers/-/ts-helpers-1.1.2.tgz" - -ts-node@~7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz" - dependencies: - arrify "^1.0.0" - buffer-from "^1.1.0" - diff "^3.1.0" - make-error "^1.1.1" - minimist "^1.2.6" - mkdirp "^0.5.1" - source-map-support "^0.5.6" - yn "^2.0.0" - -tslib@2.5.0, tslib@^2.0.0, tslib@^2.1.0, tslib@^2.3.0: - version "2.5.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz" - -tslib@^1.10.0, tslib@^1.13.0, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: - version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" - -tslint@^5.9.1: - version "5.20.1" - resolved "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz" - dependencies: - "@babel/code-frame" "^7.0.0" - builtin-modules "^1.1.1" - chalk "^2.3.0" - commander "^2.12.1" - diff "^4.0.1" - glob "^7.1.1" - js-yaml "^3.13.1" - minimatch "^5.1.0" - mkdirp "^0.5.1" - resolve "^1.3.2" - semver "^5.3.0" - tslib "^1.8.0" - tsutils "^2.29.0" - -tslint@~6.1.0: - version "6.1.3" - resolved "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz" - dependencies: - "@babel/code-frame" "^7.0.0" - builtin-modules "^1.1.1" - chalk "^2.3.0" - commander "^2.12.1" - diff "^4.0.1" - glob "^7.1.1" - js-yaml "^3.13.1" - minimatch "^5.1.0" - mkdirp "^0.5.3" - resolve "^1.3.2" - semver "^5.3.0" - tslib "^1.13.0" - tsutils "^2.29.0" - -tsutils@^2.25.0, tsutils@^2.29.0: - version "2.29.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz" - dependencies: - tslib "^1.8.1" - -tuf-js@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/tuf-js/-/tuf-js-1.0.0.tgz" - dependencies: - make-fetch-happen "^11.0.1" - minimatch "^6.1.0" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" - dependencies: - prelude-ls "^1.2.1" - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typed-assert@^1.0.8: - version "1.0.9" - resolved "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz" - -typedoc@1.0.0-dev.4: - version "1.0.0-dev.4" - resolved "https://registry.npmjs.org/typedoc/-/typedoc-1.0.0-dev.4.tgz" - dependencies: - "@types/color" "^3.0.1" - color "^3.1.2" - lunr "^2.3.9" - marked "4.2.12" - minimatch "^5.1.0" - preact "^10.5.3" - preact-render-to-string "^5.1.10" - shelljs "^0.8.4" - shiki "^0.2.6" - -typescript@4.9.5, typescript@>=2.8.3: - version "4.9.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" - -ua-parser-js@^0.7.30: - version "0.7.33" - resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.33.tgz" - -uglify-js@^3.1.4: - version "3.13.9" - resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.9.tgz" - -undefsafe@^2.0.2: - version "2.0.5" - resolved "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz" - -unicode-canonical-property-names-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz" - -unicode-match-property-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz" - dependencies: - unicode-canonical-property-names-ecmascript "^2.0.0" - unicode-property-aliases-ecmascript "^2.0.0" - -unicode-match-property-value-ecmascript@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz" - -unicode-property-aliases-ecmascript@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz" - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz" - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -unique-filename@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz" - dependencies: - unique-slug "^3.0.0" - -unique-filename@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz" - dependencies: - unique-slug "^4.0.0" - -unique-slug@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz" - dependencies: - imurmurhash "^0.1.4" - -unique-slug@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz" - dependencies: - imurmurhash "^0.1.4" - -unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz" - dependencies: - crypto-random-string "^1.0.0" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz" - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.1.1: - version "1.2.0" - resolved "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz" - -update-browserslist-db@^1.0.10: - version "1.0.10" - resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz" - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - -update-notifier@^2.5.0: - version "2.5.0" - resolved "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz" - dependencies: - boxen "^1.2.1" - chalk "^2.0.1" - configstore "^3.0.0" - import-lazy "^2.1.0" - is-ci "^1.0.10" - is-installed-globally "^0.1.0" - is-npm "^1.0.0" - latest-version "^3.0.0" - semver-diff "^2.0.0" - xdg-basedir "^3.0.0" - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz" - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz" - -url-loader@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz" - dependencies: - loader-utils "^2.0.0" - mime-types "^2.1.27" - schema-utils "^3.0.0" - -url-parse@^1.4.3: - version "1.5.10" - resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz" - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz" - -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - -util@^0.10.3: - version "0.10.4" - resolved "https://registry.npmjs.org/util/-/util-0.10.4.tgz" - dependencies: - inherits "2.0.3" - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" - -uuid@^3.3.2: - version "3.3.2" - resolved "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz" - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" - -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" - -validate-npm-package-license@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -validate-npm-package-name@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz" - dependencies: - builtins "^5.0.0" - -vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz" - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -void-elements@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz" - -vscode-textmate@^5.2.0: - version "5.5.0" - resolved "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.5.0.tgz" - -watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz" - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz" - dependencies: - minimalistic-assert "^1.0.0" - -wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz" - dependencies: - defaults "^1.0.3" - -webdriver-js-extender@2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz" + "@types/color" "^3.0.1" + "color" "^3.1.2" + "lunr" "^2.3.9" + "marked" "4.2.12" + "minimatch" "^5.1.0" + "preact" "^10.5.3" + "preact-render-to-string" "^5.1.10" + "shelljs" "^0.8.4" + "shiki" "^0.2.6" + +"typescript@>=1.8.0 <2.1.0 || >=1.9.0-dev || >=2.0.0-dev || || >=2.1.0-dev", "typescript@>=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev", "typescript@>=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev", "typescript@>=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev", "typescript@>=2.8.3", "typescript@>=4.0.0", "typescript@>=4.8.2 <5.0", "typescript@4.9.5": + "integrity" "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==" + "resolved" "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" + "version" "4.9.5" + +"ua-parser-js@^0.7.30": + "integrity" "sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==" + "resolved" "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.33.tgz" + "version" "0.7.33" + +"uglify-js@^3.1.4": + "integrity" "sha512-wZbyTQ1w6Y7fHdt8sJnHfSIuWeDgk6B5rCb4E/AM6QNNPbOMIZph21PW5dRB3h7Df0GszN+t7RuUH6sWK5bF0g==" + "resolved" "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.9.tgz" + "version" "3.13.9" + +"undefsafe@^2.0.2": + "integrity" "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + "resolved" "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz" + "version" "2.0.5" + +"unicode-canonical-property-names-ecmascript@^2.0.0": + "integrity" "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" + "resolved" "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz" + "version" "2.0.0" + +"unicode-match-property-ecmascript@^2.0.0": + "integrity" "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==" + "resolved" "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "unicode-canonical-property-names-ecmascript" "^2.0.0" + "unicode-property-aliases-ecmascript" "^2.0.0" + +"unicode-match-property-value-ecmascript@^2.1.0": + "integrity" "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" + "resolved" "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz" + "version" "2.1.0" + +"unicode-property-aliases-ecmascript@^2.0.0": + "integrity" "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==" + "resolved" "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz" + "version" "2.1.0" + +"union-value@^1.0.0": + "integrity" "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==" + "resolved" "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "arr-union" "^3.1.0" + "get-value" "^2.0.6" + "is-extendable" "^0.1.1" + "set-value" "^2.0.1" + +"unique-filename@^2.0.0": + "integrity" "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==" + "resolved" "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "unique-slug" "^3.0.0" + +"unique-filename@^3.0.0": + "integrity" "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==" + "resolved" "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "unique-slug" "^4.0.0" + +"unique-slug@^3.0.0": + "integrity" "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==" + "resolved" "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "imurmurhash" "^0.1.4" + +"unique-slug@^4.0.0": + "integrity" "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==" + "resolved" "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "imurmurhash" "^0.1.4" + +"unique-string@^1.0.0": + "integrity" "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=" + "resolved" "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "crypto-random-string" "^1.0.0" + +"universalify@^0.1.0": + "integrity" "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "resolved" "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" + "version" "0.1.2" + +"universalify@^2.0.0": + "integrity" "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + "resolved" "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" + "version" "2.0.0" + +"unpipe@~1.0.0", "unpipe@1.0.0": + "integrity" "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "resolved" "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + "version" "1.0.0" + +"unset-value@^1.0.0": + "integrity" "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=" + "resolved" "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz" + "version" "1.0.0" + dependencies: + "has-value" "^0.3.1" + "isobject" "^3.0.0" + +"upath@^1.1.1": + "integrity" "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" + "resolved" "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz" + "version" "1.2.0" + +"update-browserslist-db@^1.0.10": + "integrity" "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==" + "resolved" "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz" + "version" "1.0.10" + dependencies: + "escalade" "^3.1.1" + "picocolors" "^1.0.0" + +"update-notifier@^2.5.0": + "integrity" "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==" + "resolved" "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz" + "version" "2.5.0" + dependencies: + "boxen" "^1.2.1" + "chalk" "^2.0.1" + "configstore" "^3.0.0" + "import-lazy" "^2.1.0" + "is-ci" "^1.0.10" + "is-installed-globally" "^0.1.0" + "is-npm" "^1.0.0" + "latest-version" "^3.0.0" + "semver-diff" "^2.0.0" + "xdg-basedir" "^3.0.0" + +"uri-js@^4.2.2": + "integrity" "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==" + "resolved" "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz" + "version" "4.2.2" + dependencies: + "punycode" "^2.1.0" + +"urix@^0.1.0": + "integrity" "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + "resolved" "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz" + "version" "0.1.0" + +"url-loader@^4.1.1": + "integrity" "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==" + "resolved" "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz" + "version" "4.1.1" + dependencies: + "loader-utils" "^2.0.0" + "mime-types" "^2.1.27" + "schema-utils" "^3.0.0" + +"url-parse@^1.4.3": + "integrity" "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==" + "resolved" "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz" + "version" "1.5.10" + dependencies: + "querystringify" "^2.1.1" + "requires-port" "^1.0.0" + +"use@^3.1.0": + "integrity" "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + "resolved" "https://registry.npmjs.org/use/-/use-3.1.1.tgz" + "version" "3.1.1" + +"util-deprecate@^1.0.1", "util-deprecate@^1.0.2", "util-deprecate@~1.0.1": + "integrity" "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "resolved" "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + "version" "1.0.2" + +"util@^0.10.3": + "integrity" "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==" + "resolved" "https://registry.npmjs.org/util/-/util-0.10.4.tgz" + "version" "0.10.4" + dependencies: + "inherits" "2.0.3" + +"utils-merge@1.0.1": + "integrity" "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "resolved" "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" + "version" "1.0.1" + +"uuid@^3.3.2": + "integrity" "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "resolved" "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz" + "version" "3.3.2" + +"uuid@^8.3.2": + "integrity" "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + "resolved" "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" + "version" "8.3.2" + +"v8-compile-cache@^2.0.3": + "integrity" "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" + "resolved" "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" + "version" "2.3.0" + +"validate-npm-package-license@^3.0.4": + "integrity" "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==" + "resolved" "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" + "version" "3.0.4" + dependencies: + "spdx-correct" "^3.0.0" + "spdx-expression-parse" "^3.0.0" + +"validate-npm-package-name@^5.0.0": + "integrity" "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==" + "resolved" "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "builtins" "^5.0.0" + +"vary@^1", "vary@~1.1.2": + "integrity" "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "resolved" "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" + "version" "1.1.2" + +"verror@1.10.0": + "integrity" "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=" + "resolved" "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz" + "version" "1.10.0" + dependencies: + "assert-plus" "^1.0.0" + "core-util-is" "1.0.2" + "extsprintf" "^1.2.0" + +"void-elements@^2.0.0": + "integrity" "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=" + "resolved" "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz" + "version" "2.0.1" + +"vscode-textmate@^5.2.0": + "integrity" "sha512-jToQkPGMNKn0eyKyitYeINJF0NoD240aYyKPIWJv5W2jfPt++jIRg0OSergubtGhbw6SoefkvBYEpX7TsfoSUQ==" + "resolved" "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.5.0.tgz" + "version" "5.5.0" + +"watchpack@^2.4.0": + "integrity" "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==" + "resolved" "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz" + "version" "2.4.0" + dependencies: + "glob-to-regexp" "^0.4.1" + "graceful-fs" "^4.1.2" + +"wbuf@^1.1.0", "wbuf@^1.7.3": + "integrity" "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==" + "resolved" "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz" + "version" "1.7.3" + dependencies: + "minimalistic-assert" "^1.0.0" + +"wcwidth@^1.0.1": + "integrity" "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==" + "resolved" "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "defaults" "^1.0.3" + +"webdriver-js-extender@2.1.0": + "integrity" "sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==" + "resolved" "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz" + "version" "2.1.0" dependencies: "@types/selenium-webdriver" "^3.0.0" - selenium-webdriver "^3.0.1" - -webdriver-manager@^12.1.7: - version "12.1.8" - resolved "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.8.tgz" - dependencies: - adm-zip "^0.4.9" - chalk "^1.1.1" - del "^2.2.0" - glob "^7.0.3" - ini "^1.3.4" - minimist "^1.2.6" - q "^1.4.1" - request "^2.87.0" - rimraf "^2.5.2" - semver "^5.3.0" - xml2js "^0.4.17" - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" - -webpack-dev-middleware@6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.0.1.tgz" - dependencies: - colorette "^2.0.10" - memfs "^3.4.12" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-dev-middleware@^5.3.1: - version "5.3.3" - resolved "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz" - dependencies: - colorette "^2.0.10" - memfs "^3.4.3" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-dev-server@4.11.1, webpack-dev-server@^4.11.1: - version "4.11.1" - resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz" + "selenium-webdriver" "^3.0.1" + +"webdriver-manager@^12.1.7": + "integrity" "sha512-qJR36SXG2VwKugPcdwhaqcLQOD7r8P2Xiv9sfNbfZrKBnX243iAkOueX1yAmeNgIKhJ3YAT/F2gq6IiEZzahsg==" + "resolved" "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.8.tgz" + "version" "12.1.8" + dependencies: + "adm-zip" "^0.4.9" + "chalk" "^1.1.1" + "del" "^2.2.0" + "glob" "^7.0.3" + "ini" "^1.3.4" + "minimist" "^1.2.6" + "q" "^1.4.1" + "request" "^2.87.0" + "rimraf" "^2.5.2" + "semver" "^5.3.0" + "xml2js" "^0.4.17" + +"webidl-conversions@^3.0.0": + "integrity" "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" + "version" "3.0.1" + +"webpack-dev-middleware@^5.3.1": + "integrity" "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==" + "resolved" "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz" + "version" "5.3.3" + dependencies: + "colorette" "^2.0.10" + "memfs" "^3.4.3" + "mime-types" "^2.1.31" + "range-parser" "^1.2.1" + "schema-utils" "^4.0.0" + +"webpack-dev-middleware@6.0.1": + "integrity" "sha512-PZPZ6jFinmqVPJZbisfggDiC+2EeGZ1ZByyMP5sOFJcPPWSexalISz+cvm+j+oYPT7FIJyxT76esjnw9DhE5sw==" + "resolved" "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.0.1.tgz" + "version" "6.0.1" + dependencies: + "colorette" "^2.0.10" + "memfs" "^3.4.12" + "mime-types" "^2.1.31" + "range-parser" "^1.2.1" + "schema-utils" "^4.0.0" + +"webpack-dev-server@^4.0.0", "webpack-dev-server@^4.11.1", "webpack-dev-server@4.11.1": + "integrity" "sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==" + "resolved" "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz" + "version" "4.11.1" dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" @@ -7326,339 +8767,392 @@ webpack-dev-server@4.11.1, webpack-dev-server@^4.11.1: "@types/serve-static" "^1.13.10" "@types/sockjs" "^0.3.33" "@types/ws" "^8.5.1" - ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^2.0.0" - default-gateway "^6.0.3" - express "^4.17.3" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.1.1" - serve-index "^1.9.1" - sockjs "^0.3.24" - spdy "^4.0.2" - webpack-dev-middleware "^5.3.1" - ws "^8.4.2" - -webpack-merge@5.8.0: - version "5.8.0" - resolved "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz" - dependencies: - clone-deep "^4.0.1" - wildcard "^2.0.0" - -webpack-sources@^3.0.0, webpack-sources@^3.2.3: - version "3.2.3" - resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" - -webpack-subresource-integrity@5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz" - dependencies: - typed-assert "^1.0.8" - -webpack@5.75.0: - version "5.75.0" - resolved "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz" + "ansi-html-community" "^0.0.8" + "bonjour-service" "^1.0.11" + "chokidar" "^3.5.3" + "colorette" "^2.0.10" + "compression" "^1.7.4" + "connect-history-api-fallback" "^2.0.0" + "default-gateway" "^6.0.3" + "express" "^4.17.3" + "graceful-fs" "^4.2.6" + "html-entities" "^2.3.2" + "http-proxy-middleware" "^2.0.3" + "ipaddr.js" "^2.0.1" + "open" "^8.0.9" + "p-retry" "^4.5.0" + "rimraf" "^3.0.2" + "schema-utils" "^4.0.0" + "selfsigned" "^2.1.1" + "serve-index" "^1.9.1" + "sockjs" "^0.3.24" + "spdy" "^4.0.2" + "webpack-dev-middleware" "^5.3.1" + "ws" "^8.4.2" + +"webpack-merge@5.8.0": + "integrity" "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==" + "resolved" "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz" + "version" "5.8.0" + dependencies: + "clone-deep" "^4.0.1" + "wildcard" "^2.0.0" + +"webpack-sources@^3.0.0", "webpack-sources@^3.2.3": + "integrity" "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==" + "resolved" "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" + "version" "3.2.3" + +"webpack-subresource-integrity@5.1.0": + "integrity" "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==" + "resolved" "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz" + "version" "5.1.0" + dependencies: + "typed-assert" "^1.0.8" + +"webpack@^4.0.0 || ^5.0.0", "webpack@^4.37.0 || ^5.0.0", "webpack@^5.0.0", "webpack@^5.1.0", "webpack@^5.12.0", "webpack@^5.30.0", "webpack@^5.54.0", "webpack@^5.72.1", "webpack@^5.76.0", "webpack@>=5": + "integrity" "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==" + "resolved" "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz" + "version" "5.76.0" dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/wasm-edit" "1.11.1" "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.7.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" - json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.4.0" - webpack-sources "^3.2.3" - -webpack@^5.76.0: - version "5.76.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c" + "acorn" "^8.7.1" + "acorn-import-assertions" "^1.7.6" + "browserslist" "^4.14.5" + "chrome-trace-event" "^1.0.2" + "enhanced-resolve" "^5.10.0" + "es-module-lexer" "^0.9.0" + "eslint-scope" "5.1.1" + "events" "^3.2.0" + "glob-to-regexp" "^0.4.1" + "graceful-fs" "^4.2.9" + "json-parse-even-better-errors" "^2.3.1" + "loader-runner" "^4.2.0" + "mime-types" "^2.1.27" + "neo-async" "^2.6.2" + "schema-utils" "^3.1.0" + "tapable" "^2.1.1" + "terser-webpack-plugin" "^5.1.3" + "watchpack" "^2.4.0" + "webpack-sources" "^3.2.3" + +"webpack@5.75.0": + "integrity" "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==" + "resolved" "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz" + "version" "5.75.0" dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/wasm-edit" "1.11.1" "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.7.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" - json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.4.0" - webpack-sources "^3.2.3" - -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz" - -whatwg-fetch@^3.4.1: - version "3.6.2" - resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz" - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz" - -which@^1.2.1, which@^1.2.9: - version "1.3.1" - resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" - dependencies: - isexe "^2.0.0" - -which@^2.0.1, which@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" - dependencies: - isexe "^2.0.0" - -which@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/which/-/which-3.0.0.tgz" - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - -widest-line@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz" - dependencies: - string-width "^2.1.1" - -wildcard@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz" - -word-wrap@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" - -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" - -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - -write-file-atomic@^2.0.0: - version "2.3.0" - resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz" - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -ws@^6.0.0: - version "6.2.2" - resolved "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz" - dependencies: - async-limiter "~1.0.0" - -ws@^8.4.2: - version "8.5.0" - resolved "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz" - -ws@~8.2.3: - version "8.2.3" - resolved "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz" - -xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz" - -xhr2@^0.2.0: - version "0.2.1" - resolved "https://registry.npmjs.org/xhr2/-/xhr2-0.2.1.tgz" - -xml2js@^0.4.17: - version "0.4.23" - resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz" - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - -xmlbuilder@~11.0.0: - version "11.0.1" - resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz" - -xtend@~4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" - -y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz" - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz" - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - -yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" - -yargs-parser@^18.1.2: - version "18.1.3" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz" - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" - -yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" - -yargs@17.6.2: - version "17.6.2" - resolved "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz" - dependencies: - cliui "^8.0.1" - 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.1.1" - -yargs@^15.3.1: - version "15.4.1" - resolved "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz" - dependencies: - cliui "^6.0.0" - decamelize "^1.2.0" - find-up "^4.1.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^4.2.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^18.1.2" - -yargs@^16.1.1: - version "16.2.0" - resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^17.2.1: - version "17.7.1" - resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz" - dependencies: - cliui "^8.0.1" - 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.1.1" - -yn@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz" - -zone.js@~0.10.3: - version "0.10.3" - resolved "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz" - -zone.js@~0.11.4: - version "0.11.8" - resolved "https://registry.npmjs.org/zone.js/-/zone.js-0.11.8.tgz" - dependencies: - tslib "^2.3.0" + "acorn" "^8.7.1" + "acorn-import-assertions" "^1.7.6" + "browserslist" "^4.14.5" + "chrome-trace-event" "^1.0.2" + "enhanced-resolve" "^5.10.0" + "es-module-lexer" "^0.9.0" + "eslint-scope" "5.1.1" + "events" "^3.2.0" + "glob-to-regexp" "^0.4.1" + "graceful-fs" "^4.2.9" + "json-parse-even-better-errors" "^2.3.1" + "loader-runner" "^4.2.0" + "mime-types" "^2.1.27" + "neo-async" "^2.6.2" + "schema-utils" "^3.1.0" + "tapable" "^2.1.1" + "terser-webpack-plugin" "^5.1.3" + "watchpack" "^2.4.0" + "webpack-sources" "^3.2.3" + +"websocket-driver@^0.7.4", "websocket-driver@>=0.5.1": + "integrity" "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==" + "resolved" "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" + "version" "0.7.4" + dependencies: + "http-parser-js" ">=0.5.1" + "safe-buffer" ">=5.1.0" + "websocket-extensions" ">=0.1.1" + +"websocket-extensions@>=0.1.1": + "integrity" "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" + "resolved" "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz" + "version" "0.1.4" + +"whatwg-fetch@^3.4.1": + "integrity" "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" + "resolved" "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz" + "version" "3.6.2" + +"whatwg-url@^5.0.0": + "integrity" "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=" + "resolved" "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "tr46" "~0.0.3" + "webidl-conversions" "^3.0.0" + +"which-module@^2.0.0": + "integrity" "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + "resolved" "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz" + "version" "2.0.0" + +"which@^1.2.1", "which@^1.2.9": + "integrity" "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==" + "resolved" "https://registry.npmjs.org/which/-/which-1.3.1.tgz" + "version" "1.3.1" + dependencies: + "isexe" "^2.0.0" + +"which@^2.0.1": + "integrity" "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==" + "resolved" "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + "version" "2.0.2" + dependencies: + "isexe" "^2.0.0" + +"which@^2.0.2": + "integrity" "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==" + "resolved" "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + "version" "2.0.2" + dependencies: + "isexe" "^2.0.0" + +"which@^3.0.0": + "integrity" "sha512-nla//68K9NU6yRiwDY/Q8aU6siKlSs64aEC7+IV56QoAuyQT2ovsJcgGYGyqMOmI/CGN1BOR6mM5EN0FBO+zyQ==" + "resolved" "https://registry.npmjs.org/which/-/which-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "isexe" "^2.0.0" + +"wide-align@^1.1.5": + "integrity" "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==" + "resolved" "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" + "version" "1.1.5" + dependencies: + "string-width" "^1.0.2 || 2 || 3 || 4" + +"widest-line@^2.0.0": + "integrity" "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==" + "resolved" "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "string-width" "^2.1.1" + +"wildcard@^2.0.0": + "integrity" "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" + "resolved" "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz" + "version" "2.0.0" + +"word-wrap@^1.2.3": + "integrity" "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + "resolved" "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" + "version" "1.2.3" + +"wordwrap@^1.0.0": + "integrity" "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + "resolved" "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" + "version" "1.0.0" + +"wrap-ansi@^6.2.0": + "integrity" "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==" + "resolved" "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" + "version" "6.2.0" + dependencies: + "ansi-styles" "^4.0.0" + "string-width" "^4.1.0" + "strip-ansi" "^6.0.0" + +"wrap-ansi@^7.0.0": + "integrity" "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==" + "resolved" "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + "version" "7.0.0" + dependencies: + "ansi-styles" "^4.0.0" + "string-width" "^4.1.0" + "strip-ansi" "^6.0.0" + +"wrappy@1": + "integrity" "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + "version" "1.0.2" + +"write-file-atomic@^2.0.0": + "integrity" "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==" + "resolved" "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz" + "version" "2.3.0" + dependencies: + "graceful-fs" "^4.1.11" + "imurmurhash" "^0.1.4" + "signal-exit" "^3.0.2" + +"ws@^6.0.0": + "integrity" "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==" + "resolved" "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz" + "version" "6.2.2" + dependencies: + "async-limiter" "~1.0.0" + +"ws@^8.4.2": + "integrity" "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==" + "resolved" "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz" + "version" "8.5.0" + +"ws@~8.2.3": + "integrity" "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==" + "resolved" "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz" + "version" "8.2.3" + +"xdg-basedir@^3.0.0": + "integrity" "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" + "resolved" "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz" + "version" "3.0.0" + +"xhr2@^0.2.0": + "integrity" "sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==" + "resolved" "https://registry.npmjs.org/xhr2/-/xhr2-0.2.1.tgz" + "version" "0.2.1" + +"xml2js@^0.4.17": + "integrity" "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==" + "resolved" "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz" + "version" "0.4.23" + dependencies: + "sax" ">=0.6.0" + "xmlbuilder" "~11.0.0" + +"xmlbuilder@~11.0.0": + "integrity" "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + "resolved" "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz" + "version" "11.0.1" + +"xtend@~4.0.1": + "integrity" "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "resolved" "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + "version" "4.0.1" + +"y18n@^4.0.0": + "integrity" "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + "resolved" "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz" + "version" "4.0.3" + +"y18n@^5.0.5": + "integrity" "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + "resolved" "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + "version" "5.0.8" + +"yallist@^2.1.2": + "integrity" "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + "resolved" "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz" + "version" "2.1.2" + +"yallist@^3.0.2": + "integrity" "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "resolved" "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" + "version" "3.1.1" + +"yallist@^4.0.0": + "integrity" "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "resolved" "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + "version" "4.0.0" + +"yaml@^1.10.0": + "integrity" "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + "resolved" "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" + "version" "1.10.2" + +"yargs-parser@^18.1.2": + "integrity" "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==" + "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz" + "version" "18.1.3" + dependencies: + "camelcase" "^5.0.0" + "decamelize" "^1.2.0" + +"yargs-parser@^20.2.2": + "integrity" "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" + "version" "20.2.9" + +"yargs-parser@^21.1.1": + "integrity" "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + "version" "21.1.1" + +"yargs@^15.3.1": + "integrity" "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==" + "resolved" "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz" + "version" "15.4.1" + dependencies: + "cliui" "^6.0.0" + "decamelize" "^1.2.0" + "find-up" "^4.1.0" + "get-caller-file" "^2.0.1" + "require-directory" "^2.1.1" + "require-main-filename" "^2.0.0" + "set-blocking" "^2.0.0" + "string-width" "^4.2.0" + "which-module" "^2.0.0" + "y18n" "^4.0.0" + "yargs-parser" "^18.1.2" + +"yargs@^16.1.1": + "integrity" "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==" + "resolved" "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" + "version" "16.2.0" + dependencies: + "cliui" "^7.0.2" + "escalade" "^3.1.1" + "get-caller-file" "^2.0.5" + "require-directory" "^2.1.1" + "string-width" "^4.2.0" + "y18n" "^5.0.5" + "yargs-parser" "^20.2.2" + +"yargs@^17.2.1": + "integrity" "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==" + "resolved" "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz" + "version" "17.7.1" + dependencies: + "cliui" "^8.0.1" + "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.1.1" + +"yargs@17.6.2": + "integrity" "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==" + "resolved" "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz" + "version" "17.6.2" + dependencies: + "cliui" "^8.0.1" + "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.1.1" + +"yn@^2.0.0": + "integrity" "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=" + "resolved" "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz" + "version" "2.0.0" + +"zone.js@~0.10.3": + "integrity" "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==" + "resolved" "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz" + "version" "0.10.3" + +"zone.js@~0.11.4", "zone.js@~0.11.4 || ~0.12.0": + "integrity" "sha512-82bctBg2hKcEJ21humWIkXRlLBBmrc3nN7DFh5LGGhcyycO2S7FN8NmdvlcKaGFDNVL4/9kFLmwmInTavdJERA==" + "resolved" "https://registry.npmjs.org/zone.js/-/zone.js-0.11.8.tgz" + "version" "0.11.8" + dependencies: + "tslib" "^2.3.0" From 746e5da7fac7e477e9e41dc7ac2d103c5d75a4c5 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Mon, 1 May 2023 16:37:27 -0700 Subject: [PATCH 007/118] Make more tests pass --- .../Base/BasketScenarioBase.cs | 17 ----------------- .../RedisBasketRepositoryTests.cs | 7 ++----- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs index 8ec90a2ee..06336c5aa 100644 --- a/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs +++ b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs @@ -6,23 +6,6 @@ namespace Basket.FunctionalTests.Base; public class BasketScenarioBase : WebApplicationFactory { private const string ApiUrlBase = "api/v1/basket"; - - public TestServer CreateServer() - { - var path = Assembly.GetAssembly(typeof(BasketScenarioBase)) - .Location; - - var hostBuilder = new WebHostBuilder() - .UseContentRoot(Path.GetDirectoryName(path)) - .ConfigureAppConfiguration(cb => - { - cb.AddJsonFile("appsettings.json", optional: false) - .AddEnvironmentVariables(); - }); - - return new TestServer(hostBuilder); - } - public static class Get { public static string GetBasket(int id) diff --git a/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs b/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs index 0a0cb11fa..99683aee4 100644 --- a/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs +++ b/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs @@ -9,8 +9,7 @@ namespace Basket.FunctionalTests [Fact] public async Task UpdateBasket_return_and_add_basket() { - using var server = CreateServer(); - var redis = server.Host.Services.GetRequiredService(); + var redis = Services.GetRequiredService(); var redisBasketRepository = BuildBasketRepository(redis); @@ -29,9 +28,7 @@ namespace Basket.FunctionalTests [Fact] public async Task Delete_Basket_return_null() { - - using var server = CreateServer(); - var redis = server.Host.Services.GetRequiredService(); + var redis = Services.GetRequiredService(); var redisBasketRepository = BuildBasketRepository(redis); From d4c2f17c365bd962a2cf4a06d2032f154c4c80b8 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Mon, 1 May 2023 16:40:13 -0700 Subject: [PATCH 008/118] Remove whitespace --- .../Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs b/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs index 99683aee4..217a85ec2 100644 --- a/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs +++ b/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs @@ -21,8 +21,6 @@ namespace Basket.FunctionalTests Assert.NotNull(basket); Assert.Single(basket.Items); - - } [Fact] From 233b6e56c1cac0fcdd2d81483f417c784b1f568e Mon Sep 17 00:00:00 2001 From: David Fowler Date: Mon, 1 May 2023 16:55:20 -0700 Subject: [PATCH 009/118] Fixed catalog functional tests --- .../Extensions/WebHostExtensions.cs | 22 ++++++------ .../CatalogScenarioBase.cs | 34 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Services/Catalog/Catalog.API/Extensions/WebHostExtensions.cs b/src/Services/Catalog/Catalog.API/Extensions/WebHostExtensions.cs index 588ca7a35..d4a452aed 100644 --- a/src/Services/Catalog/Catalog.API/Extensions/WebHostExtensions.cs +++ b/src/Services/Catalog/Catalog.API/Extensions/WebHostExtensions.cs @@ -2,23 +2,23 @@ public static class WebHostExtensions { - public static bool IsInKubernetes(this IWebHost host) + public static bool IsInKubernetes(this IServiceProvider services) { - var cfg = host.Services.GetService(); + var cfg = services.GetService(); var orchestratorType = cfg.GetValue("OrchestratorType"); return orchestratorType?.ToUpper() == "K8S"; } - public static IWebHost MigrateDbContext(this IWebHost host, Action seeder) where TContext : DbContext + public static IServiceProvider MigrateDbContext(this IServiceProvider services, Action seeder) where TContext : DbContext { - var underK8s = host.IsInKubernetes(); + var underK8s = services.IsInKubernetes(); - using var scope = host.Services.CreateScope(); - var services = scope.ServiceProvider; + using var scope = services.CreateScope(); + var scopedServices = scope.ServiceProvider; - var logger = services.GetRequiredService>(); + var logger = scopedServices.GetRequiredService>(); - var context = services.GetService(); + var context = scopedServices.GetService(); try { @@ -26,7 +26,7 @@ public static class WebHostExtensions if (underK8s) { - InvokeSeeder(seeder, context, services); + InvokeSeeder(seeder, context, scopedServices); } else { @@ -42,7 +42,7 @@ public static class WebHostExtensions //migration can't fail for network related exception. The retry options for DbContext only //apply to transient exceptions // Note that this is NOT applied when running some orchestrators (let the orchestrator to recreate the failing service) - retry.Execute(() => InvokeSeeder(seeder, context, services)); + retry.Execute(() => InvokeSeeder(seeder, context, scopedServices)); } logger.LogInformation("Migrated database associated with context {DbContextName}", typeof(TContext).Name); @@ -56,7 +56,7 @@ public static class WebHostExtensions } } - return host; + return services; } private static void InvokeSeeder(Action seeder, TContext context, IServiceProvider services) diff --git a/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs b/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs index 562dc000d..224896537 100644 --- a/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs +++ b/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs @@ -1,24 +1,12 @@ +using Microsoft.AspNetCore.Mvc.Testing; + namespace Catalog.FunctionalTests; -public class CatalogScenariosBase +public class CatalogScenariosBase : WebApplicationFactory { public TestServer CreateServer() { - var path = Assembly.GetAssembly(typeof(CatalogScenariosBase)) - .Location; - - var hostBuilder = new WebHostBuilder() - .UseContentRoot(Path.GetDirectoryName(path)) - .ConfigureAppConfiguration(cb => - { - cb.AddJsonFile("appsettings.json", optional: false) - .AddEnvironmentVariables(); - }); - - - var testServer = new TestServer(hostBuilder); - - testServer.Host + Services .MigrateDbContext((context, services) => { var env = services.GetService(); @@ -31,7 +19,19 @@ public class CatalogScenariosBase }) .MigrateDbContext((_, __) => { }); - return testServer; + return Server; + } + + protected override IHost CreateHost(IHostBuilder builder) + { + builder.ConfigureAppConfiguration(c => + { + var directory = Path.GetDirectoryName(typeof(CatalogScenariosBase).Assembly.Location)!; + + c.AddJsonFile(Path.Combine(directory, "appsettings.json"), optional: false); + }); + + return base.CreateHost(builder); } public static class Get From c7edd50b380a88b34cbff9d900f45830d85020e5 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Mon, 1 May 2023 17:32:57 -0700 Subject: [PATCH 010/118] Fix ordering and basked scenarios --- .../WebHostExtensions.cs | 22 +++--- .../Base/BasketScenarioBase.cs | 6 ++ .../Basket.FunctionalTests.csproj | 4 -- .../Basket.FunctionalTests/BasketScenarios.cs | 21 +++--- src/Services/Ordering/Ordering.API/Program.cs | 11 +-- .../Ordering.FunctionalTests.csproj | 7 +- .../OrderingScenarioBase.cs | 67 ++++++++++++------- .../OrderingScenarios.cs | 4 +- 8 files changed, 84 insertions(+), 58 deletions(-) diff --git a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs index 3c7fc105a..aff7df81b 100644 --- a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs +++ b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs @@ -10,21 +10,21 @@ namespace Microsoft.AspNetCore.Hosting { public static class IWebHostExtensions { - public static bool IsInKubernetes(this IWebHost webHost) + public static bool IsInKubernetes(this IServiceProvider services) { - var cfg = webHost.Services.GetService(); + var cfg = services.GetService(); var orchestratorType = cfg.GetValue("OrchestratorType"); return orchestratorType?.ToUpper() == "K8S"; } - public static IWebHost MigrateDbContext(this IWebHost webHost, Action seeder) where TContext : DbContext + public static IServiceProvider MigrateDbContext(this IServiceProvider services, Action seeder) where TContext : DbContext { - var underK8s = webHost.IsInKubernetes(); + var underK8s = services.IsInKubernetes(); - using var scope = webHost.Services.CreateScope(); - var services = scope.ServiceProvider; - var logger = services.GetRequiredService>(); - var context = services.GetService(); + using var scope = services.CreateScope(); + var scopeServices = scope.ServiceProvider; + var logger = scopeServices.GetRequiredService>(); + var context = scopeServices.GetService(); try { @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Hosting if (underK8s) { - InvokeSeeder(seeder, context, services); + InvokeSeeder(seeder, context, scopeServices); } else { @@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Hosting //migration can't fail for network related exception. The retry options for DbContext only //apply to transient exceptions // Note that this is NOT applied when running some orchestrators (let the orchestrator to recreate the failing service) - retry.Execute(() => InvokeSeeder(seeder, context, services)); + retry.Execute(() => InvokeSeeder(seeder, context, scopeServices)); } logger.LogInformation("Migrated database associated with context {DbContextName}", typeof(TContext).Name); @@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Hosting } } - return webHost; + return services; } private static void InvokeSeeder(Action seeder, TContext context, IServiceProvider services) diff --git a/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs index 06336c5aa..d763a336e 100644 --- a/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs +++ b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs @@ -6,6 +6,12 @@ namespace Basket.FunctionalTests.Base; public class BasketScenarioBase : WebApplicationFactory { private const string ApiUrlBase = "api/v1/basket"; + + public TestServer CreateServer() + { + return Server; + } + public static class Get { public static string GetBasket(int id) diff --git a/src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj b/src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj index f7ccc5df6..d91ecd779 100644 --- a/src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj +++ b/src/Services/Basket/Basket.FunctionalTests/Basket.FunctionalTests.csproj @@ -6,10 +6,6 @@ false - - - - PreserveNewest diff --git a/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs b/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs index 8726e6627..794ca7b1e 100644 --- a/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs +++ b/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs @@ -1,20 +1,15 @@ namespace Basket.FunctionalTests; -public class BasketScenarios : BasketScenarioBase +public class BasketScenarios : + BasketScenarioBase { - private readonly HttpClient _httpClient; - - public BasketScenarios() - { - _httpClient = CreateClient(); - } - [Fact] public async Task Post_basket_and_response_ok_status_code() { + using var server = CreateServer(); var content = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json"); var uri = "/api/v1/basket/"; - var response = await _httpClient.PostAsync(uri, content); + var response = await server.CreateClient().PostAsync(uri, content); response.EnsureSuccessStatusCode(); } @@ -22,7 +17,8 @@ public class BasketScenarios : BasketScenarioBase [Fact] public async Task Get_basket_and_response_ok_status_code() { - var response = await _httpClient + using var server = CreateServer(); + var response = await server.CreateClient() .GetAsync(Get.GetBasket(1)); response.EnsureSuccessStatusCode(); } @@ -30,9 +26,10 @@ public class BasketScenarios : BasketScenarioBase [Fact] public async Task Send_Checkout_basket_and_response_ok_status_code() { + using var server = CreateServer(); var contentBasket = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json"); - await _httpClient + await server.CreateClient() .PostAsync(Post.Basket, contentBasket); var contentCheckout = new StringContent(BuildCheckout(), UTF8Encoding.UTF8, "application/json") @@ -40,7 +37,7 @@ public class BasketScenarios : BasketScenarioBase Headers = { { "x-requestid", Guid.NewGuid().ToString() } } }; - var response = await _httpClient + var response = await server.CreateClient() .PostAsync(Post.CheckoutOrder, contentCheckout); response.EnsureSuccessStatusCode(); diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index 8e3e8aa50..0649ea2dc 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -331,7 +331,7 @@ static class CustomExtensionsMethods public static IServiceCollection AddCustomSwagger(this IServiceCollection services, IConfiguration configuration) { - services.AddSwaggerGen(options => + return services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo { @@ -339,6 +339,9 @@ static class CustomExtensionsMethods Version = "v1", Description = "The Ordering Service HTTP API" }); + + var identityUrl = configuration["IdentityUrlExternal"]; + options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2, @@ -346,8 +349,8 @@ static class CustomExtensionsMethods { Implicit = new OpenApiOAuthFlow() { - AuthorizationUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize"), - TokenUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/token"), + AuthorizationUrl = new Uri($"{identityUrl}/connect/authorize"), + TokenUrl = new Uri($"{identityUrl}/connect/token"), Scopes = new Dictionary() { { "orders", "Ordering API" } @@ -355,9 +358,9 @@ static class CustomExtensionsMethods } } }); + options.OperationFilter(); }); - return services; } public static IServiceCollection AddCustomIntegrations(this IServiceCollection services, IConfiguration configuration) diff --git a/src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj b/src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj index 89f8910a2..f0b75f017 100644 --- a/src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj +++ b/src/Services/Ordering/Ordering.FunctionalTests/Ordering.FunctionalTests.csproj @@ -6,6 +6,12 @@ false + + + PreserveNewest + + + @@ -18,7 +24,6 @@ - diff --git a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs index a0b31568b..81832f32e 100644 --- a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs +++ b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs @@ -1,36 +1,42 @@ -namespace Ordering.FunctionalTests; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.Hosting; -public class OrderingScenarioBase +namespace Ordering.FunctionalTests; + +public class OrderingScenarioBase : WebApplicationFactory { public TestServer CreateServer() { - var path = Assembly.GetAssembly(typeof(OrderingScenarioBase)) - .Location; + Services.MigrateDbContext((context, services) => + { + var env = services.GetService(); + var settings = services.GetService>(); + var logger = services.GetService>(); - var hostBuilder = new WebHostBuilder() - .UseContentRoot(Path.GetDirectoryName(path)) - .ConfigureAppConfiguration(cb => - { - cb.AddJsonFile("appsettings.json", optional: false) - .AddEnvironmentVariables(); - }); + new OrderingContextSeed() + .SeedAsync(context, env, settings, logger) + .Wait(); + }) + .MigrateDbContext((_, __) => { }); + + return Server; + } - var testServer = new TestServer(hostBuilder); + protected override IHost CreateHost(IHostBuilder builder) + { + builder.ConfigureServices(servies => + { + servies.AddSingleton(); + }); - testServer.Host - .MigrateDbContext((context, services) => - { - var env = services.GetService(); - var settings = services.GetService>(); - var logger = services.GetService>(); + builder.ConfigureAppConfiguration(c => + { + var directory = Path.GetDirectoryName(typeof(OrderingScenarioBase).Assembly.Location)!; - new OrderingContextSeed() - .SeedAsync(context, env, settings, logger) - .Wait(); - }) - .MigrateDbContext((_, __) => { }); + c.AddJsonFile(Path.Combine(directory, "appsettings.json"), optional: false); + }); - return testServer; + return base.CreateHost(builder); } public static class Get @@ -48,4 +54,17 @@ public class OrderingScenarioBase public static string CancelOrder = "api/v1/orders/cancel"; public static string ShipOrder = "api/v1/orders/ship"; } + + private class AuthStartupFilter : IStartupFilter + { + public Action Configure(Action next) + { + return app => + { + app.UseMiddleware(); + + next(app); + }; + } + } } diff --git a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs index 252cc02ff..4ed21ba1b 100644 --- a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs +++ b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs @@ -1,7 +1,6 @@ using System.Net; using System.Text; using System.Text.Json; -using WebMVC.Services.ModelDTOs; using Xunit; namespace Ordering.FunctionalTests @@ -16,6 +15,7 @@ namespace Ordering.FunctionalTests var response = await server.CreateClient() .GetAsync(Get.Orders); + var s = await response.Content.ReadAsStringAsync(); response.EnsureSuccessStatusCode(); } @@ -49,7 +49,7 @@ namespace Ordering.FunctionalTests string BuildOrder() { - var order = new OrderDTO() + var order = new { OrderNumber = "-1" }; From e7e0eed9cc0888c6fd7154a8552a779743d9a070 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Mon, 1 May 2023 17:43:48 -0700 Subject: [PATCH 011/118] Fixed remaining tests - Lots of duplication zomg --- src/Services/Webhooks/Webhooks.API/Program.cs | 9 +-- .../Application.FunctionalTests.csproj | 7 +++ .../GlobalUsings.cs | 5 ++ .../Services/Basket/BasketScenariosBase.cs | 50 +++++++++++----- .../Services/Catalog/CatalogScenariosBase.cs | 58 ++++++++++--------- .../Ordering/OrderingScenariosBase.cs | 56 ++++++++++++------ 6 files changed, 123 insertions(+), 62 deletions(-) diff --git a/src/Services/Webhooks/Webhooks.API/Program.cs b/src/Services/Webhooks/Webhooks.API/Program.cs index 027814057..bc5d6c29f 100644 --- a/src/Services/Webhooks/Webhooks.API/Program.cs +++ b/src/Services/Webhooks/Webhooks.API/Program.cs @@ -1,6 +1,7 @@ -CreateWebHostBuilder(args).Build() - .MigrateDbContext((_, __) => { }) - .Run(); +// TODO: Don't do this twice... +var host = CreateWebHostBuilder(args).Build(); +host.Services.MigrateDbContext((_, __) => { }); +host.Run(); IWebHostBuilder CreateWebHostBuilder(string[] args) => @@ -16,4 +17,4 @@ IWebHostBuilder CreateWebHostBuilder(string[] args) => builder.AddConsole(); builder.AddDebug(); builder.AddAzureWebAppDiagnostics(); - }); \ No newline at end of file + }); diff --git a/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj b/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj index 8ea12ff3c..dab397d78 100644 --- a/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj +++ b/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj @@ -35,10 +35,17 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + diff --git a/src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs b/src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs index b09d08dd0..493b29f63 100644 --- a/src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs +++ b/src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs @@ -26,3 +26,8 @@ global using Microsoft.eShopOnContainers.Services.Ordering.API; global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure; global using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; global using FunctionalTests.Services.Catalog; + +// This is a bit of a hack, since we need to differentiate each of these app's program +global using BasketProgram = Microsoft.eShopOnContainers.Services.Basket.API.BasketSettings; +global using CatalogProgram = Microsoft.eShopOnContainers.Services.Catalog.API.CatalogSettings; +global using OrderingProgram = Microsoft.eShopOnContainers.Services.Ordering.API.OrderingSettings; diff --git a/src/Tests/Services/Application.FunctionalTests/Services/Basket/BasketScenariosBase.cs b/src/Tests/Services/Application.FunctionalTests/Services/Basket/BasketScenariosBase.cs index 0cb668b8a..88ab903bf 100644 --- a/src/Tests/Services/Application.FunctionalTests/Services/Basket/BasketScenariosBase.cs +++ b/src/Tests/Services/Application.FunctionalTests/Services/Basket/BasketScenariosBase.cs @@ -1,24 +1,35 @@ -namespace FunctionalTests.Services.Basket; +using FunctionalTests.Middleware; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.Hosting; -public class BasketScenariosBase +namespace FunctionalTests.Services.Basket; + +public class BasketScenariosBase : WebApplicationFactory { private const string ApiUrlBase = "api/v1/basket"; - public TestServer CreateServer() { - var path = Assembly.GetAssembly(typeof(BasketScenariosBase)) - .Location; + return Server; + } - var hostBuilder = new WebHostBuilder() - .UseContentRoot(Path.GetDirectoryName(path)) - .ConfigureAppConfiguration(cb => - { - cb.AddJsonFile("Services/Basket/appsettings.json", optional: false) - .AddEnvironmentVariables(); - }); - return new TestServer(hostBuilder); + protected override IHost CreateHost(IHostBuilder builder) + { + builder.ConfigureServices(servies => + { + servies.AddSingleton(); + }); + + builder.ConfigureAppConfiguration(c => + { + var directory = Path.GetDirectoryName(typeof(BasketScenariosBase).Assembly.Location)!; + + c.AddJsonFile(Path.Combine(directory, "Services/Basket/appsettings.json"), optional: false); + }); + + return base.CreateHost(builder); } public static class Get @@ -39,4 +50,17 @@ public class BasketScenariosBase public static string CreateBasket = $"{ApiUrlBase}/"; public static string CheckoutOrder = $"{ApiUrlBase}/checkout"; } + + private class AuthStartupFilter : IStartupFilter + { + public Action Configure(Action next) + { + return app => + { + app.UseMiddleware(); + + next(app); + }; + } + } } diff --git a/src/Tests/Services/Application.FunctionalTests/Services/Catalog/CatalogScenariosBase.cs b/src/Tests/Services/Application.FunctionalTests/Services/Catalog/CatalogScenariosBase.cs index 0fcf32e3c..830d24d97 100644 --- a/src/Tests/Services/Application.FunctionalTests/Services/Catalog/CatalogScenariosBase.cs +++ b/src/Tests/Services/Application.FunctionalTests/Services/Catalog/CatalogScenariosBase.cs @@ -1,37 +1,39 @@ namespace FunctionalTests.Services.Catalog; + +using FunctionalTests.Services.Ordering; +using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.eShopOnContainers.Services.Catalog.API; +using Microsoft.Extensions.Hosting; -public class CatalogScenariosBase +public class CatalogScenariosBase : WebApplicationFactory { public TestServer CreateServer() { - var path = Assembly.GetAssembly(typeof(CatalogScenariosBase)) - .Location; - - var hostBuilder = new WebHostBuilder() - .UseContentRoot(Path.GetDirectoryName(path)) - .ConfigureAppConfiguration(cb => - { - cb.AddJsonFile("Services/Catalog/appsettings.json", optional: false) - .AddEnvironmentVariables(); - }); - - var testServer = new TestServer(hostBuilder); - - testServer.Host - .MigrateDbContext((context, services) => - { - var env = services.GetService(); - var settings = services.GetService>(); - var logger = services.GetService>(); - - new CatalogContextSeed() - .SeedAsync(context, env, settings, logger) - .Wait(); - }) - .MigrateDbContext((_, __) => { }); - - return testServer; + Services.MigrateDbContext((context, services) => + { + var env = services.GetService(); + var settings = services.GetService>(); + var logger = services.GetService>(); + + new CatalogContextSeed() + .SeedAsync(context, env, settings, logger) + .Wait(); + }) + .MigrateDbContext((_, __) => { }); + + return Server; + } + + protected override IHost CreateHost(IHostBuilder builder) + { + builder.ConfigureAppConfiguration(c => + { + var directory = Path.GetDirectoryName(typeof(CatalogScenariosBase).Assembly.Location)!; + + c.AddJsonFile(Path.Combine(directory, "Services/Catalog/appsettings.json"), optional: false); + }); + + return base.CreateHost(builder); } public static class Get diff --git a/src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenariosBase.cs b/src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenariosBase.cs index 3d419eb83..906cf70a5 100644 --- a/src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenariosBase.cs +++ b/src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenariosBase.cs @@ -1,23 +1,15 @@ -namespace FunctionalTests.Services.Ordering; +using FunctionalTests.Middleware; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.Hosting; -public class OrderingScenariosBase +namespace FunctionalTests.Services.Ordering; + +public class OrderingScenariosBase : WebApplicationFactory { public TestServer CreateServer() { - var path = Assembly.GetAssembly(typeof(OrderingScenariosBase)) - .Location; - - var hostBuilder = new WebHostBuilder() - .UseContentRoot(Path.GetDirectoryName(path)) - .ConfigureAppConfiguration(cb => - { - cb.AddJsonFile("Services/Ordering/appsettings.json", optional: false) - .AddEnvironmentVariables(); - }); - - var testServer = new TestServer(hostBuilder); - - testServer.Host + Services .MigrateDbContext((context, services) => { var env = services.GetService(); @@ -30,7 +22,24 @@ public class OrderingScenariosBase }) .MigrateDbContext((_, __) => { }); - return testServer; + return Server; + } + + protected override IHost CreateHost(IHostBuilder builder) + { + builder.ConfigureServices(servies => + { + servies.AddSingleton(); + }); + + builder.ConfigureAppConfiguration(c => + { + var directory = Path.GetDirectoryName(typeof(OrderingScenariosBase).Assembly.Location)!; + + c.AddJsonFile(Path.Combine(directory, "Services/Ordering/appsettings.json"), optional: false); + }); + + return base.CreateHost(builder); } public static class Get @@ -60,4 +69,17 @@ public class OrderingScenariosBase return $"api/v1/orders/{id}"; } } + + private class AuthStartupFilter : IStartupFilter + { + public Action Configure(Action next) + { + return app => + { + app.UseMiddleware(); + + next(app); + }; + } + } } From 9af6d6342d4bd08f3ca8dbd34f7733a0613b7045 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 2 May 2023 08:00:17 -0700 Subject: [PATCH 012/118] Initial attempt at making a common service configuration --- .../Basket/Basket.API/Basket.API.csproj | 7 +- .../Basket.API/CustomExtensionMethods.cs | 129 +----- src/Services/Basket/Basket.API/Program.cs | 162 ++----- .../Basket/Basket.API/appsettings.json | 9 +- .../AuthorizeCheckOperationFilter.cs | 38 ++ .../Services.Common/CommonExtensions.cs | 398 ++++++++++++++++++ .../Services.Common/Services.Common.csproj | 64 +++ src/eShopOnContainers-ServicesAndWebApps.sln | 54 +++ 8 files changed, 595 insertions(+), 266 deletions(-) create mode 100644 src/Services/Services.Common/AuthorizeCheckOperationFilter.cs create mode 100644 src/Services/Services.Common/CommonExtensions.cs create mode 100644 src/Services/Services.Common/Services.Common.csproj diff --git a/src/Services/Basket/Basket.API/Basket.API.csproj b/src/Services/Basket/Basket.API/Basket.API.csproj index f6f36ba88..a6512c614 100644 --- a/src/Services/Basket/Basket.API/Basket.API.csproj +++ b/src/Services/Basket/Basket.API/Basket.API.csproj @@ -46,8 +46,9 @@ - - - + + + + diff --git a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs index cdec6a100..2dccd89f6 100644 --- a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs +++ b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs @@ -2,23 +2,12 @@ public static class CustomExtensionMethods { - public static ConfigurationManager AddKeyVault(this ConfigurationManager configuration) - { - if (configuration.GetValue("UseVault", false)) - { - var credential = new ClientSecretCredential( - configuration["Vault:TenantId"], - configuration["Vault:ClientId"], - configuration["Vault:ClientSecret"]); - - configuration.AddAzureKeyVault(new Uri($"https://{configuration["Vault:Name"]}.vault.azure.net/"), credential); - } - - return configuration; - } - public static IServiceCollection AddRedis(this IServiceCollection services) { + // { + // "ConnectionString": "..." + // } + return services.AddSingleton(sp => { var settings = sp.GetRequiredService>().Value; @@ -27,114 +16,4 @@ public static class CustomExtensionMethods return ConnectionMultiplexer.Connect(configuration); }); } - - public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) - { - var hcBuilder = services.AddHealthChecks(); - - hcBuilder.AddCheck("self", () => HealthCheckResult.Healthy()); - - hcBuilder - .AddRedis( - configuration["ConnectionString"], - name: "redis-check", - tags: new string[] { "redis" }); - - if (configuration.GetValue("AzureServiceBusEnabled")) - { - hcBuilder - .AddAzureServiceBusTopic( - configuration["EventBusConnection"], - topicName: "eshop_event_bus", - name: "basket-servicebus-check", - tags: new string[] { "servicebus" }); - } - else - { - hcBuilder - .AddRabbitMQ( - $"amqp://{configuration["EventBusConnection"]}", - name: "basket-rabbitmqbus-check", - tags: new string[] { "rabbitmqbus" }); - } - - return services; - } - - public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) - { - if (configuration.GetValue("AzureServiceBusEnabled", false)) - { - services.AddSingleton(sp => - { - var serviceBusConnectionString = configuration["EventBusConnection"]; - - return new DefaultServiceBusPersisterConnection(serviceBusConnectionString); - }); - - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubscriptionsManager = sp.GetRequiredService(); - string subscriptionName = configuration["SubscriptionClientName"]; - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubscriptionsManager, sp, subscriptionName); - }); - } - else - { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - var factory = new ConnectionFactory() - { - HostName = configuration["EventBusConnection"], - DispatchConsumersAsync = true - }; - - if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) - { - factory.UserName = configuration["EventBusUserName"]; - } - - if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) - { - factory.Password = configuration["EventBusPassword"]; - } - - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); - - services.AddSingleton(sp => - { - var subscriptionClientName = configuration["SubscriptionClientName"]; - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubscriptionsManager = sp.GetRequiredService(); - - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubscriptionsManager, subscriptionClientName, retryCount); - }); - } - - services.AddSingleton(); - - services.AddTransient(); - services.AddTransient(); - return services; - } } diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index cb22a464f..0844d32b3 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -1,104 +1,52 @@ -var builder = WebApplication.CreateBuilder(args); +using Services.Common; + +var builder = WebApplication.CreateBuilder(args); builder.Configuration.AddKeyVault(); +builder.Services.AddApplicationInsights(builder.Configuration); + builder.Services.AddGrpc(options => { options.EnableDetailedErrors = true; }); -builder.Services.AddApplicationInsightsTelemetry(builder.Configuration); -builder.Services.AddApplicationInsightsKubernetesEnricher(); - builder.Services.AddControllers(options => { options.Filters.Add(typeof(HttpGlobalExceptionFilter)); options.Filters.Add(typeof(ValidateModelStateFilter)); }); -builder.Services.AddSwaggerGen(options => -{ - options.SwaggerDoc("v1", new OpenApiInfo - { - Title = "eShopOnContainers - Basket HTTP API", - Version = "v1", - Description = "The Basket Service HTTP API" - }); - - options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme - { - Type = SecuritySchemeType.OAuth2, - Flows = new OpenApiOAuthFlows() - { - Implicit = new OpenApiOAuthFlow() - { - AuthorizationUrl = new Uri($"{builder.Configuration["IdentityUrlExternal"]}/connect/authorize"), - TokenUrl = new Uri($"{builder.Configuration["IdentityUrlExternal"]}/connect/token"), - Scopes = new Dictionary() { { "basket", "Basket API" } } - } - } - }); - - options.OperationFilter(); -}); +builder.Services.AddDefaultOpenApi(builder.Configuration); -// prevent from mapping "sub" claim to nameidentifier. -JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); +builder.Services.AddDefaultAuthentication(builder.Configuration); -var identityUrl = builder.Configuration["IdentityUrl"]; +builder.Services.AddDefaultHealthChecks(builder.Configuration); -builder.Services.AddAuthentication().AddJwtBearer(options => -{ - options.Authority = identityUrl; - options.RequireHttpsMetadata = false; - options.Audience = "basket"; - options.TokenValidationParameters.ValidateAudience = false; -}); +builder.Host.UseDefaultSerilog(builder.Configuration, AppName); + +builder.WebHost.UseDefaultPorts(builder.Configuration); -builder.Services.AddAuthorization(options => +builder.WebHost.UseFailing(options => { - options.AddPolicy("ApiScope", policy => - { - policy.RequireAuthenticatedUser(); - policy.RequireClaim("scope", "basket"); - }); + options.ConfigPath = "/Failing"; + options.NotFilteredPaths.AddRange(new[] { "/hc", "/liveness" }); }); -builder.Services.AddCustomHealthCheck(builder.Configuration); +builder.Services.AddEventBus(builder.Configuration); builder.Services.Configure(builder.Configuration); builder.Services.AddRedis(); -builder.Services.AddEventBus(builder.Configuration); - -builder.Services.AddHttpContextAccessor(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); -builder.WebHost.UseKestrel(options => -{ - var ports = GetDefinedPorts(builder.Configuration); - options.Listen(IPAddress.Any, ports.httpPort, listenOptions => - { - listenOptions.Protocols = HttpProtocols.Http1AndHttp2; - }); - - options.Listen(IPAddress.Any, ports.grpcPort, listenOptions => - { - listenOptions.Protocols = HttpProtocols.Http2; - }); -}); - -builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration)); -builder.WebHost.UseFailing(options => -{ - options.ConfigPath = "/Failing"; - options.NotFilteredPaths.AddRange(new[] { "/hc", "/liveness" }); -}); - var app = builder.Build(); + app.MapGet("hello", () => "hello"); if (!app.Environment.IsDevelopment()) @@ -112,59 +60,31 @@ if (!string.IsNullOrEmpty(pathBase)) app.UsePathBase(pathBase); } -app.UseSwagger(); - -app.UseSwaggerUI(setup => -{ - setup.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Basket.API V1"); - setup.OAuthClientId("basketswaggerui"); - setup.OAuthAppName("Basket Swagger UI"); -}); +app.UseDefaultOpenApi(builder.Configuration); app.MapGrpcService(); app.MapControllers(); -app.MapGet("/_proto/", async ctx => -{ - ctx.Response.ContentType = "text/plain"; - using var fs = new FileStream(Path.Combine(app.Environment.ContentRootPath, "Proto", "basket.proto"), FileMode.Open, FileAccess.Read); - using var sr = new StreamReader(fs); - while (!sr.EndOfStream) - { - var line = await sr.ReadLineAsync(); - if (line != "/* >>" || line != "<< */") - { - await ctx.Response.WriteAsync(line); - } - } -}); +app.MapDefaultHealthChecks(); -app.MapHealthChecks("/hc", new HealthCheckOptions() -{ - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse -}); - -app.MapHealthChecks("/liveness", new HealthCheckOptions -{ - Predicate = r => r.Name.Contains("self") -}); +var eventBus = app.Services.GetRequiredService(); -ConfigureEventBus(app); +eventBus.Subscribe(); +eventBus.Subscribe(); try { - Log.Information("Configuring web host ({ApplicationContext})...", Program.AppName); + Log.Information("Configuring web host ({ApplicationContext})...", AppName); - Log.Information("Starting web host ({ApplicationContext})...", Program.AppName); + Log.Information("Starting web host ({ApplicationContext})...", AppName); await app.RunAsync(); return 0; } catch (Exception ex) { - Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName); + Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", AppName); return 1; } finally @@ -172,36 +92,6 @@ finally Log.CloseAndFlush(); } -Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) -{ - var seqServerUrl = configuration["Serilog:SeqServerUrl"]; - var logstashUrl = configuration["Serilog:LogstashgUrl"]; - return new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("ApplicationContext", Program.AppName) - .Enrich.FromLogContext() - .WriteTo.Console() - .WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl) - .WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl, null) - .ReadFrom.Configuration(configuration) - .CreateLogger(); -} - -(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config) -{ - var grpcPort = config.GetValue("GRPC_PORT", 5001); - var port = config.GetValue("PORT", 80); - return (port, grpcPort); -} - -void ConfigureEventBus(IApplicationBuilder app) -{ - var eventBus = app.ApplicationServices.GetRequiredService(); - - eventBus.Subscribe(); - eventBus.Subscribe(); -} - public partial class Program { private static string Namespace = typeof(Program).Assembly.GetName().Name; diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json index 295294308..928ea904f 100644 --- a/src/Services/Basket/Basket.API/appsettings.json +++ b/src/Services/Basket/Basket.API/appsettings.json @@ -16,11 +16,16 @@ "Protocols": "Http2" } }, - "SubscriptionClientName": "Basket", + "EventBus": { + "SubscriptionClientName": "Basket", + "ConnectionString": "your-event-bus-connection-string", + "UserName": "your-event-bus-username", + "Password": "your-event-bus-password", + "RetryCount": 5 + }, "ApplicationInsights": { "InstrumentationKey": "" }, - "EventBusRetryCount": 5, "UseVault": false, "Vault": { "Name": "eshop", diff --git a/src/Services/Services.Common/AuthorizeCheckOperationFilter.cs b/src/Services/Services.Common/AuthorizeCheckOperationFilter.cs new file mode 100644 index 000000000..7e8d0d2ef --- /dev/null +++ b/src/Services/Services.Common/AuthorizeCheckOperationFilter.cs @@ -0,0 +1,38 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.Configuration; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; + +namespace Services.Common; +internal class AuthorizeCheckOperationFilter : IOperationFilter +{ + public AuthorizeCheckOperationFilter(IConfiguration configuration) + { + + } + + public void Apply(OpenApiOperation operation, OperationFilterContext context) + { + // Check for authorize attribute + var hasAuthorize = context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType().Any() || + context.MethodInfo.GetCustomAttributes(true).OfType().Any(); + + if (!hasAuthorize) return; + + operation.Responses.TryAdd("401", new OpenApiResponse { Description = "Unauthorized" }); + operation.Responses.TryAdd("403", new OpenApiResponse { Description = "Forbidden" }); + + var oAuthScheme = new OpenApiSecurityScheme + { + Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" } + }; + + operation.Security = new List + { + new() + { + [ oAuthScheme ] = new [] { "basketapi" } + } + }; + } +} diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs new file mode 100644 index 000000000..31610ac95 --- /dev/null +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -0,0 +1,398 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Net; +using Azure.Identity; +using HealthChecks.UI.Client; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Routing; +using Microsoft.AspNetCore.Server.Kestrel.Core; +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; +using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; +using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.OpenApi.Models; +using RabbitMQ.Client; +using Serilog; + +namespace Services.Common; + +public static class CommonExtensions +{ + public static WebApplicationBuilder AddServiceDefaults(this WebApplicationBuilder builder) + { + // Shared configuration via key vault + builder.Configuration.AddKeyVault(); + + // Shared app insights configuration + builder.Services.AddApplicationInsights(builder.Configuration); + + // Default health checks assume the event bus and self health checks + builder.Services.AddDefaultHealthChecks(builder.Configuration); + + // Configure the default logging for this application + builder.Host.UseDefaultSerilog(builder.Configuration, builder.Environment.ApplicationName); + + // Configure the default ports for this service (http and grpc ports read from configuration) + builder.WebHost.UseDefaultPorts(builder.Configuration); + + // Customizations for this application + + // Add the event bus + builder.Services.AddEventBus(builder.Configuration); + + builder.Services.AddDefaultAuthentication(builder.Configuration); + + builder.Services.AddDefaultOpenApi(builder.Configuration); + + // Add the accessor + builder.Services.AddHttpContextAccessor(); + + return builder; + } + + public static WebApplication UseServiceDefaults(this WebApplication app) + { + var pathBase = app.Configuration["PATH_BASE"]; + + if (!string.IsNullOrEmpty(pathBase)) + { + app.UsePathBase(pathBase); + } + + app.UseDefaultOpenApi(app.Configuration); + + app.MapDefaultHealthChecks(); + + return app; + } + + public static IApplicationBuilder UseDefaultOpenApi(this IApplicationBuilder app, IConfiguration configuration) + { + app.UseSwagger(); + app.UseSwaggerUI(setup => + { + var pathBase = configuration["PATH_BASE"]; + var openApiSection = configuration.GetRequiredSection("OpenApi"); + var authSection = openApiSection.GetRequiredSection("Auth"); + var endpointSection = openApiSection.GetRequiredSection("Endpoint"); + + var swaggerUrl = endpointSection["Url"] ?? $"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json"; + + setup.SwaggerEndpoint(swaggerUrl, endpointSection.GetRequiredValue("Name")); + setup.OAuthClientId(authSection.GetRequiredValue("ClientId")); + setup.OAuthAppName(authSection.GetRequiredValue("AppName")); + }); + + return app; + } + + public static IServiceCollection AddDefaultOpenApi(this IServiceCollection services, IConfiguration configuration) => + services.AddSwaggerGen(options => + { + var openApi = configuration.GetRequiredSection("OpenApi"); + + /// { + /// "OpenApi": { + /// "Endpoint: { + /// "Name": + /// }, + /// "Document": { + /// "Title": .. + /// "Version": .. + /// "Description": .. + /// }, + /// "Auth": { + /// "ClientId": .., + /// "AppName": .. + /// } + /// } + /// } + + var version = openApi.GetRequiredValue("Version") ?? "v1"; + + options.SwaggerDoc(version, new OpenApiInfo + { + Title = openApi.GetRequiredValue("Title"), + Version = version, + Description = openApi.GetRequiredValue("Description") + }); + + var identityUrlExternal = configuration.GetRequiredValue("IdentityUrlExternal"); + var scopes = openApi.GetRequiredSection("Scopes").AsEnumerable().ToDictionary(p => p.Key, p => p.Value); + + options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme + { + Type = SecuritySchemeType.OAuth2, + Flows = new OpenApiOAuthFlows() + { + Implicit = new OpenApiOAuthFlow() + { + AuthorizationUrl = new Uri($"{identityUrlExternal}/connect/authorize"), + TokenUrl = new Uri($"{identityUrlExternal}/connect/token"), + Scopes = openApi.GetRequiredSection("Scopes").AsEnumerable().ToDictionary(p => p.Key, p => p.Value), + } + } + }); + + options.OperationFilter(); + }); + + public static IServiceCollection AddDefaultAuthentication(this IServiceCollection services, IConfiguration configuration) + { + // prevent from mapping "sub" claim to nameidentifier. + JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); + + services.AddAuthentication().AddJwtBearer(options => + { + var identityUrl = configuration.GetRequiredValue("IdentityUrl"); + var audience = configuration.GetRequiredValue("Audience"); + + options.Authority = identityUrl; + options.RequireHttpsMetadata = false; + options.Audience = audience; + options.TokenValidationParameters.ValidateAudience = false; + }); + + services.AddAuthorization(options => + { + var scope = configuration.GetRequiredValue("Scope"); + + options.AddPolicy("ApiScope", policy => + { + policy.RequireAuthenticatedUser(); + policy.RequireClaim("scope", scope); + }); + }); + + return services; + } + + public static IWebHostBuilder UseDefaultPorts(this IWebHostBuilder builder, IConfiguration configuration) + { + builder.UseKestrel(options => + { + var (httpPort, grpcPort) = GetDefinedPorts(configuration); + + options.Listen(IPAddress.Any, httpPort, listenOptions => + { + listenOptions.Protocols = HttpProtocols.Http1AndHttp2; + }); + + options.Listen(IPAddress.Any, grpcPort, listenOptions => + { + listenOptions.Protocols = HttpProtocols.Http2; + }); + }); + + return builder; + } + + public static ConfigurationManager AddKeyVault(this ConfigurationManager configuration) + { + if (configuration.GetValue("UseVault", false)) + { + // { + // "Vault": { + // "Name": "myvault", + // "TenantId": "mytenantid", + // "ClientId": "myclientid", + // } + // } + + var vaultSection = configuration.GetRequiredSection("Vault"); + + var credential = new ClientSecretCredential( + vaultSection.GetRequiredValue("TenantId"), + vaultSection.GetRequiredValue("ClientId"), + vaultSection.GetRequiredValue("ClientSecret")); + + var name = vaultSection.GetRequiredValue("Name"); + + configuration.AddAzureKeyVault(new Uri($"https://{name}.vault.azure.net/"), credential); + } + + return configuration; + } + + public static IServiceCollection AddApplicationInsights(this IServiceCollection services, IConfiguration configuration) + { + services.AddApplicationInsightsTelemetry(configuration); + services.AddApplicationInsightsKubernetesEnricher(); + return services; + } + + public static IHealthChecksBuilder AddDefaultHealthChecks(this IServiceCollection services, IConfiguration configuration) + { + var hcBuilder = services.AddHealthChecks(); + + // Health check for the application itself + hcBuilder.AddCheck("self", () => HealthCheckResult.Healthy()); + + // { + // "EventBus": { + // "ProviderName": "ServiceBus | RabbitMQ", + // "ConnectionString": "Endpoint=sb://eshop-eventbus.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=..." + // } + // } + + var eventBusSection = configuration.GetRequiredSection("EventBus"); + var eventBusConnectionString = eventBusSection.GetRequiredValue("ConnectionString"); + + return eventBusSection.GetRequiredValue("ProviderName").ToLowerInvariant() switch + { + "servicebus" => hcBuilder.AddAzureServiceBusTopic( + eventBusConnectionString, + topicName: "eshop_event_bus", + name: "servicebus-check", + tags: new string[] { "servicebus" }), + + _ => hcBuilder.AddRabbitMQ( + $"amqp://{eventBusConnectionString}", + name: "rabbitmqbus-check", + tags: new string[] { "rabbitmqbus" }) + }; + } + + public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) + { + // { + // "EventBus": { + // "ProviderName": "ServiceBus | RabbitMQ", + // "ConnectionString": "...", + // ... + // } + // } + + // { + // "EventBus": { + // "ProviderName": "ServiceBus", + // "ConnectionString": "Endpoint=sb://eshop-eventbus.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=..." + // "SubscriptionClientName": "eshop_event_bus" + // } + // } + + // { + // "EventBus": { + // "ProviderName": "RabbitMQ", + // "ConnectionString": "...", + // "SubscriptionClientName": "...", + // "UserName": "...", + // "Password": "...", + // "RetryCount": 1 + // } + // } + + var eventBusSection = configuration.GetRequiredSection("EventBus"); + if (string.Equals(eventBusSection["ProviderName"], "ServiceBus", StringComparison.OrdinalIgnoreCase)) + { + services.AddSingleton(sp => + { + var serviceBusConnectionString = eventBusSection.GetRequiredValue("ConnectionString"); + + return new DefaultServiceBusPersisterConnection(serviceBusConnectionString); + }); + + services.AddSingleton(sp => + { + var serviceBusPersisterConnection = sp.GetRequiredService(); + var logger = sp.GetRequiredService>(); + var eventBusSubscriptionsManager = sp.GetRequiredService(); + string subscriptionName = eventBusSection.GetRequiredValue("SubscriptionClientName"); + + return new EventBusServiceBus(serviceBusPersisterConnection, logger, + eventBusSubscriptionsManager, sp, subscriptionName); + }); + } + else + { + services.AddSingleton(sp => + { + var logger = sp.GetRequiredService>(); + + var factory = new ConnectionFactory() + { + HostName = eventBusSection.GetRequiredValue("ConnectionString"), + DispatchConsumersAsync = true + }; + + if (!string.IsNullOrEmpty(eventBusSection["UserName"])) + { + factory.UserName = eventBusSection["UserName"]; + } + + if (!string.IsNullOrEmpty(eventBusSection["Password"])) + { + factory.Password = eventBusSection["Password"]; + } + + var retryCount = eventBusSection.GetValue("RetryCount", 5); + + return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); + }); + + services.AddSingleton(sp => + { + var subscriptionClientName = eventBusSection.GetRequiredValue("SubscriptionClientName"); + var rabbitMQPersistentConnection = sp.GetRequiredService(); + var logger = sp.GetRequiredService>(); + var eventBusSubscriptionsManager = sp.GetRequiredService(); + var retryCount = eventBusSection.GetValue("RetryCount", 5); + + return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubscriptionsManager, subscriptionClientName, retryCount); + }); + } + + services.AddSingleton(); + return services; + } + + public static void UseDefaultSerilog(this IHostBuilder builder, IConfiguration configuration, string name) + { + builder.UseSerilog(CreateSerilogLogger(configuration)); + + Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) + { + var seqServerUrl = configuration["Serilog:SeqServerUrl"]; + var logstashUrl = configuration["Serilog:LogstashgUrl"]; + return new LoggerConfiguration() + .MinimumLevel.Verbose() + .Enrich.WithProperty("ApplicationContext", name) + .Enrich.FromLogContext() + .WriteTo.Console() + .WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl) + .WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl, null) + .ReadFrom.Configuration(configuration) + .CreateLogger(); + } + } + + public static void MapDefaultHealthChecks(this IEndpointRouteBuilder routes) + { + routes.MapHealthChecks("/hc", new HealthCheckOptions() + { + Predicate = _ => true, + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse + }); + + routes.MapHealthChecks("/liveness", new HealthCheckOptions + { + Predicate = r => r.Name.Contains("self") + }); + } + + static (int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config) + { + var grpcPort = config.GetValue("GRPC_PORT", 5001); + var port = config.GetValue("PORT", 80); + return (port, grpcPort); + } + + private static string GetRequiredValue(this IConfiguration configuration, string name) => + configuration[name] ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Key + ":" + name : name)}"); +} diff --git a/src/Services/Services.Common/Services.Common.csproj b/src/Services/Services.Common/Services.Common.csproj new file mode 100644 index 000000000..0eb7de774 --- /dev/null +++ b/src/Services/Services.Common/Services.Common.csproj @@ -0,0 +1,64 @@ + + + + net7.0 + enable + enable + + + + + + + + + + + + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/eShopOnContainers-ServicesAndWebApps.sln b/src/eShopOnContainers-ServicesAndWebApps.sln index 68f32a4bf..65aff4d0e 100644 --- a/src/eShopOnContainers-ServicesAndWebApps.sln +++ b/src/eShopOnContainers-ServicesAndWebApps.sln @@ -122,6 +122,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{373D8AA1 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBus.Tests", "BuildingBlocks\EventBus\EventBus.Tests\EventBus.Tests.csproj", "{95D735BE-2899-4495-BE3F-2600E93B4E3C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Services.Common", "Services\Services.Common\Services.Common.csproj", "{CD430CE4-D5E0-4C96-84F5-AEC9162651B5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{42B85D0F-2ED6-4C00-91FA-103DACC3D5E2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -1480,6 +1484,54 @@ Global {95D735BE-2899-4495-BE3F-2600E93B4E3C}.Release|x64.Build.0 = Release|Any CPU {95D735BE-2899-4495-BE3F-2600E93B4E3C}.Release|x86.ActiveCfg = Release|Any CPU {95D735BE-2899-4495-BE3F-2600E93B4E3C}.Release|x86.Build.0 = Release|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.AppStore|ARM.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.AppStore|iPhone.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.AppStore|x64.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.AppStore|x64.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.AppStore|x86.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.AppStore|x86.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Debug|ARM.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Debug|ARM.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Debug|iPhone.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Debug|x64.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Debug|x64.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Debug|x86.ActiveCfg = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Debug|x86.Build.0 = Debug|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|Any CPU.Build.0 = Release|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|ARM.ActiveCfg = Release|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|ARM.Build.0 = Release|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|iPhone.ActiveCfg = Release|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|iPhone.Build.0 = Release|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|x64.ActiveCfg = Release|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|x64.Build.0 = Release|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|x86.ActiveCfg = Release|Any CPU + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1536,6 +1588,8 @@ Global {B62E859F-825E-4C8B-93EC-5966EACFD026} = {798BFC44-2CCD-45FA-B37A-5173B03C2B30} {373D8AA1-36BE-49EC-89F0-6CB736666285} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} {95D735BE-2899-4495-BE3F-2600E93B4E3C} = {373D8AA1-36BE-49EC-89F0-6CB736666285} + {CD430CE4-D5E0-4C96-84F5-AEC9162651B5} = {42B85D0F-2ED6-4C00-91FA-103DACC3D5E2} + {42B85D0F-2ED6-4C00-91FA-103DACC3D5E2} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9} From 00fc3d8a65e76f3a3c6cd428a0224bbfa772bcaf Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 2 May 2023 08:11:55 -0700 Subject: [PATCH 013/118] More defaults --- src/Services/Basket/Basket.API/Program.cs | 31 ++----------------- .../Services.Common/CommonExtensions.cs | 5 +++ 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index 0844d32b3..7bdc8709f 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -2,9 +2,7 @@ var builder = WebApplication.CreateBuilder(args); -builder.Configuration.AddKeyVault(); - -builder.Services.AddApplicationInsights(builder.Configuration); +builder.AddServiceDefaults(); builder.Services.AddGrpc(options => { @@ -17,24 +15,12 @@ builder.Services.AddControllers(options => options.Filters.Add(typeof(ValidateModelStateFilter)); }); -builder.Services.AddDefaultOpenApi(builder.Configuration); - -builder.Services.AddDefaultAuthentication(builder.Configuration); - -builder.Services.AddDefaultHealthChecks(builder.Configuration); - -builder.Host.UseDefaultSerilog(builder.Configuration, AppName); - -builder.WebHost.UseDefaultPorts(builder.Configuration); - builder.WebHost.UseFailing(options => { options.ConfigPath = "/Failing"; options.NotFilteredPaths.AddRange(new[] { "/hc", "/liveness" }); }); -builder.Services.AddEventBus(builder.Configuration); - builder.Services.Configure(builder.Configuration); builder.Services.AddRedis(); @@ -49,24 +35,11 @@ var app = builder.Build(); app.MapGet("hello", () => "hello"); -if (!app.Environment.IsDevelopment()) -{ - app.UseExceptionHandler("/Home/Error"); -} - -var pathBase = app.Configuration["PATH_BASE"]; -if (!string.IsNullOrEmpty(pathBase)) -{ - app.UsePathBase(pathBase); -} - -app.UseDefaultOpenApi(builder.Configuration); +app.UseServiceDefaults(); app.MapGrpcService(); app.MapControllers(); -app.MapDefaultHealthChecks(); - var eventBus = app.Services.GetRequiredService(); eventBus.Subscribe(); diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index 31610ac95..770d2b41f 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -58,6 +58,11 @@ public static class CommonExtensions public static WebApplication UseServiceDefaults(this WebApplication app) { + if (!app.Environment.IsDevelopment()) + { + app.UseExceptionHandler("/Home/Error"); + } + var pathBase = app.Configuration["PATH_BASE"]; if (!string.IsNullOrEmpty(pathBase)) From 3fee612e685b9ad538e5949d48f02ad3fac3b546 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 2 May 2023 10:51:50 -0700 Subject: [PATCH 014/118] More tweaks --- .../Basket/Basket.API/Basket.API.csproj | 6 +++--- .../Basket.API/CustomExtensionMethods.cs | 11 +++-------- src/Services/Basket/Basket.API/GlobalUsings.cs | 18 +----------------- src/Services/Basket/Basket.API/Program.cs | 6 ++---- .../Basket/Basket.API/appsettings.json | 3 +++ .../Basket.FunctionalTests/appsettings.json | 10 +++++++--- 6 files changed, 19 insertions(+), 35 deletions(-) diff --git a/src/Services/Basket/Basket.API/Basket.API.csproj b/src/Services/Basket/Basket.API/Basket.API.csproj index a6512c614..c9d7929a8 100644 --- a/src/Services/Basket/Basket.API/Basket.API.csproj +++ b/src/Services/Basket/Basket.API/Basket.API.csproj @@ -46,9 +46,9 @@ - - - + + + diff --git a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs index 2dccd89f6..67ee876b0 100644 --- a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs +++ b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs @@ -2,18 +2,13 @@ public static class CustomExtensionMethods { - public static IServiceCollection AddRedis(this IServiceCollection services) + public static IServiceCollection AddRedis(this IServiceCollection services, IConfiguration configuration) { - // { - // "ConnectionString": "..." - // } - return services.AddSingleton(sp => { - var settings = sp.GetRequiredService>().Value; - var configuration = ConfigurationOptions.Parse(settings.ConnectionString, true); + var redisConfig = ConfigurationOptions.Parse(configuration.GetConnectionString("redis"), true); - return ConnectionMultiplexer.Connect(configuration); + return ConnectionMultiplexer.Connect(redisConfig); }); } } diff --git a/src/Services/Basket/Basket.API/GlobalUsings.cs b/src/Services/Basket/Basket.API/GlobalUsings.cs index 73978e20c..a24875d35 100644 --- a/src/Services/Basket/Basket.API/GlobalUsings.cs +++ b/src/Services/Basket/Basket.API/GlobalUsings.cs @@ -1,7 +1,4 @@ -global using Autofac.Extensions.DependencyInjection; -global using Autofac; -global using Azure.Core; -global using Azure.Identity; +global using Autofac; global using Basket.API.Infrastructure.ActionResults; global using Basket.API.Infrastructure.Exceptions; global using Basket.API.Infrastructure.Filters; @@ -11,24 +8,15 @@ global using Basket.API.IntegrationEvents.Events; global using Basket.API.Model; global using Grpc.Core; global using GrpcBasket; -global using HealthChecks.UI.Client; global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; -global using Microsoft.AspNetCore.Diagnostics.HealthChecks; global using Microsoft.AspNetCore.Hosting; -global using Microsoft.AspNetCore.Http.Features; global using Microsoft.AspNetCore.Http; global using Microsoft.AspNetCore.Mvc.Authorization; global using Microsoft.AspNetCore.Mvc.Filters; global using Microsoft.AspNetCore.Mvc; -global using Microsoft.AspNetCore.Server.Kestrel.Core; -global using Microsoft.AspNetCore; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; -global using Microsoft.eShopOnContainers.Services.Basket.API.Controllers; global using Microsoft.eShopOnContainers.Services.Basket.API.Infrastructure.Repositories; global using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.EventHandling; global using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Events; @@ -37,19 +25,15 @@ global using Microsoft.eShopOnContainers.Services.Basket.API.Services; global using Microsoft.eShopOnContainers.Services.Basket.API; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Diagnostics.HealthChecks; global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; -global using Microsoft.Extensions.Options; global using Microsoft.OpenApi.Models; -global using RabbitMQ.Client; global using Serilog.Context; global using Serilog; global using StackExchange.Redis; global using Swashbuckle.AspNetCore.SwaggerGen; global using System.Collections.Generic; global using System.ComponentModel.DataAnnotations; -global using System.IdentityModel.Tokens.Jwt; global using System.IO; global using System.Linq; global using System.Net; diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index 7bdc8709f..be35fd3fc 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -21,9 +21,7 @@ builder.WebHost.UseFailing(options => options.NotFilteredPaths.AddRange(new[] { "/hc", "/liveness" }); }); -builder.Services.Configure(builder.Configuration); - -builder.Services.AddRedis(); +builder.Services.AddRedis(builder.Configuration); builder.Services.AddTransient(); builder.Services.AddTransient(); @@ -33,7 +31,7 @@ builder.Services.AddTransient(); var app = builder.Build(); -app.MapGet("hello", () => "hello"); +app.MapGet("/", () => Results.Redirect("/swagger")); app.UseServiceDefaults(); diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json index 928ea904f..66c41a889 100644 --- a/src/Services/Basket/Basket.API/appsettings.json +++ b/src/Services/Basket/Basket.API/appsettings.json @@ -16,6 +16,9 @@ "Protocols": "Http2" } }, + "ConnectionStrings": { + "Redis": "127.0.0.1" + }, "EventBus": { "SubscriptionClientName": "Basket", "ConnectionString": "your-event-bus-connection-string", diff --git a/src/Services/Basket/Basket.FunctionalTests/appsettings.json b/src/Services/Basket/Basket.FunctionalTests/appsettings.json index d4fc14254..6817e5902 100644 --- a/src/Services/Basket/Basket.FunctionalTests/appsettings.json +++ b/src/Services/Basket/Basket.FunctionalTests/appsettings.json @@ -11,9 +11,13 @@ }, "IdentityUrl": "http://localhost:5105", "IdentityUrlExternal": "http://localhost:5105", - "ConnectionString": "127.0.0.1", + "ConnectionStrings": { + "Redis": "127.0.0.1" + }, + "EventBus": { + "ConnectionString": "localhost", + "SubscriptionClientName": "Basket" + }, "isTest": "true", - "EventBusConnection": "localhost", - "SubscriptionClientName": "Basket", "SuppressCheckForUnhandledSecurityMetadata": true } From 8a40e9fb48415c46ab112c2f67a8e6c913c72bc6 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 2 May 2023 11:11:13 -0700 Subject: [PATCH 015/118] More schema --- src/Services/Basket/Basket.API/Program.cs | 6 ----- .../Basket/Basket.API/appsettings.json | 5 +++++ .../Services.Common/CommonExtensions.cs | 22 ++++++++++++++++--- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index be35fd3fc..3a8091fff 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -15,12 +15,6 @@ builder.Services.AddControllers(options => options.Filters.Add(typeof(ValidateModelStateFilter)); }); -builder.WebHost.UseFailing(options => -{ - options.ConfigPath = "/Failing"; - options.NotFilteredPaths.AddRange(new[] { "/hc", "/liveness" }); -}); - builder.Services.AddRedis(builder.Configuration); builder.Services.AddTransient(); diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json index 66c41a889..738586f04 100644 --- a/src/Services/Basket/Basket.API/appsettings.json +++ b/src/Services/Basket/Basket.API/appsettings.json @@ -19,6 +19,11 @@ "ConnectionStrings": { "Redis": "127.0.0.1" }, + "Identity": { + "Url": "", + "Auidence": "basket", + "Scope": "basket" + }, "EventBus": { "SubscriptionClientName": "Basket", "ConnectionString": "your-event-bus-connection-string", diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index 770d2b41f..7048af39f 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -150,13 +150,29 @@ public static class CommonExtensions public static IServiceCollection AddDefaultAuthentication(this IServiceCollection services, IConfiguration configuration) { + // { + // "Identity": { + // "Url": "http://identity", + // "Audience": "basket", + // "Scope": "basket" + // } + // } + + var identitySection = configuration.GetSection("Identity"); + + if (identitySection is null) + { + // No identity section, so no authentication + return services; + } + // prevent from mapping "sub" claim to nameidentifier. JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); services.AddAuthentication().AddJwtBearer(options => { - var identityUrl = configuration.GetRequiredValue("IdentityUrl"); - var audience = configuration.GetRequiredValue("Audience"); + var identityUrl = identitySection.GetRequiredValue("Url"); + var audience = identitySection.GetRequiredValue("Audience"); options.Authority = identityUrl; options.RequireHttpsMetadata = false; @@ -166,7 +182,7 @@ public static class CommonExtensions services.AddAuthorization(options => { - var scope = configuration.GetRequiredValue("Scope"); + var scope = identitySection.GetRequiredValue("Scope"); options.AddPolicy("ApiScope", policy => { From 57a93f63f0c31a929944c6439b97dc453f42ece7 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 2 May 2023 21:15:43 -0700 Subject: [PATCH 016/118] More customization --- .../Services.Common/CommonExtensions.cs | 51 ++++++++++++++----- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index 7048af39f..bc623801e 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -82,6 +82,18 @@ public static class CommonExtensions app.UseSwagger(); app.UseSwaggerUI(setup => { + /// { + /// "OpenApi": { + /// "Endpoint: { + /// "Name": + /// }, + /// "Auth": { + /// "ClientId": .., + /// "AppName": .. + /// } + /// } + /// } + var pathBase = configuration["PATH_BASE"]; var openApiSection = configuration.GetRequiredSection("OpenApi"); var authSection = openApiSection.GetRequiredSection("Auth"); @@ -104,31 +116,42 @@ public static class CommonExtensions /// { /// "OpenApi": { - /// "Endpoint: { - /// "Name": - /// }, /// "Document": { /// "Title": .. /// "Version": .. /// "Description": .. - /// }, - /// "Auth": { - /// "ClientId": .., - /// "AppName": .. /// } /// } /// } + var document = openApi.GetRequiredSection("Document"); - var version = openApi.GetRequiredValue("Version") ?? "v1"; + var version = document.GetRequiredValue("Version") ?? "v1"; options.SwaggerDoc(version, new OpenApiInfo { - Title = openApi.GetRequiredValue("Title"), + Title = document.GetRequiredValue("Title"), Version = version, - Description = openApi.GetRequiredValue("Description") + Description = document.GetRequiredValue("Description") }); - var identityUrlExternal = configuration.GetRequiredValue("IdentityUrlExternal"); + var identitySection = configuration.GetSection("Identity"); + + if (identitySection is null) + { + // No identity section, so no authentication open api definition + return; + } + + // { + // "Identity": { + // "ExternalUrl": "http://identity", + // "Scopes": { + // "basket": "Basket API" + // } + // } + // } + + var identityUrlExternal = identitySection.GetRequiredValue("ExternalUrl"); var scopes = openApi.GetRequiredSection("Scopes").AsEnumerable().ToDictionary(p => p.Key, p => p.Value); options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme @@ -140,7 +163,7 @@ public static class CommonExtensions { AuthorizationUrl = new Uri($"{identityUrlExternal}/connect/authorize"), TokenUrl = new Uri($"{identityUrlExternal}/connect/token"), - Scopes = openApi.GetRequiredSection("Scopes").AsEnumerable().ToDictionary(p => p.Key, p => p.Value), + Scopes = scopes, } } }); @@ -258,7 +281,7 @@ public static class CommonExtensions // { // "EventBus": { // "ProviderName": "ServiceBus | RabbitMQ", - // "ConnectionString": "Endpoint=sb://eshop-eventbus.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=..." + // "ConnectionString": "..." // } // } @@ -293,7 +316,7 @@ public static class CommonExtensions // { // "EventBus": { // "ProviderName": "ServiceBus", - // "ConnectionString": "Endpoint=sb://eshop-eventbus.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=..." + // "ConnectionString": "..." // "SubscriptionClientName": "eshop_event_bus" // } // } From 9d52426a495a7a0b12b6c3b71d53bc654a3705db Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 2 May 2023 21:22:06 -0700 Subject: [PATCH 017/118] Use default logger --- src/Services/Basket/Basket.API/Program.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index 3a8091fff..e7dd796e2 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -39,23 +39,19 @@ eventBus.Subscribe Date: Tue, 2 May 2023 22:02:05 -0700 Subject: [PATCH 018/118] Configure so tests work again --- .../Basket/Basket.API/appsettings.json | 23 +++++++++++---- .../Basket.FunctionalTests/BasketScenarios.cs | 1 - .../Basket.FunctionalTests/appsettings.json | 6 ++-- .../Services.Common/CommonExtensions.cs | 28 +++++++++++++------ 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json index 738586f04..6cf67a4a4 100644 --- a/src/Services/Basket/Basket.API/appsettings.json +++ b/src/Services/Basket/Basket.API/appsettings.json @@ -16,19 +16,30 @@ "Protocols": "Http2" } }, + "OpenApi": { + "Endpoint": { + "Name": "" + }, + "Document": { + "Name": "Basket API", + "Description": "Basket API", + "Title": "Basket API", + "Version": "v1" + } + }, "ConnectionStrings": { "Redis": "127.0.0.1" }, "Identity": { - "Url": "", - "Auidence": "basket", - "Scope": "basket" + "Audience": "basket", + "Scope": "basket", + "Scopes": { + "basket": "Basket API" + } }, "EventBus": { "SubscriptionClientName": "Basket", - "ConnectionString": "your-event-bus-connection-string", - "UserName": "your-event-bus-username", - "Password": "your-event-bus-password", + "ConnectionString": "localhost", "RetryCount": 5 }, "ApplicationInsights": { diff --git a/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs b/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs index 794ca7b1e..4a96207a4 100644 --- a/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs +++ b/src/Services/Basket/Basket.FunctionalTests/BasketScenarios.cs @@ -10,7 +10,6 @@ public class BasketScenarios : var content = new StringContent(BuildBasket(), UTF8Encoding.UTF8, "application/json"); var uri = "/api/v1/basket/"; var response = await server.CreateClient().PostAsync(uri, content); - response.EnsureSuccessStatusCode(); } diff --git a/src/Services/Basket/Basket.FunctionalTests/appsettings.json b/src/Services/Basket/Basket.FunctionalTests/appsettings.json index 6817e5902..364a58def 100644 --- a/src/Services/Basket/Basket.FunctionalTests/appsettings.json +++ b/src/Services/Basket/Basket.FunctionalTests/appsettings.json @@ -9,8 +9,10 @@ "Microsoft": "Information" } }, - "IdentityUrl": "http://localhost:5105", - "IdentityUrlExternal": "http://localhost:5105", + "Identity": { + "ExternalUrl": "http://localhost:5105", + "Url": "http://localhost:5105" + }, "ConnectionStrings": { "Redis": "127.0.0.1" }, diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index bc623801e..a26e59722 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -96,14 +96,18 @@ public static class CommonExtensions var pathBase = configuration["PATH_BASE"]; var openApiSection = configuration.GetRequiredSection("OpenApi"); - var authSection = openApiSection.GetRequiredSection("Auth"); + var authSection = openApiSection.GetSection("Auth"); var endpointSection = openApiSection.GetRequiredSection("Endpoint"); var swaggerUrl = endpointSection["Url"] ?? $"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json"; setup.SwaggerEndpoint(swaggerUrl, endpointSection.GetRequiredValue("Name")); - setup.OAuthClientId(authSection.GetRequiredValue("ClientId")); - setup.OAuthAppName(authSection.GetRequiredValue("AppName")); + + if (authSection.Exists()) + { + setup.OAuthClientId(authSection.GetRequiredValue("ClientId")); + setup.OAuthAppName(authSection.GetRequiredValue("AppName")); + } }); return app; @@ -136,7 +140,7 @@ public static class CommonExtensions var identitySection = configuration.GetSection("Identity"); - if (identitySection is null) + if (!identitySection.Exists()) { // No identity section, so no authentication open api definition return; @@ -152,7 +156,7 @@ public static class CommonExtensions // } var identityUrlExternal = identitySection.GetRequiredValue("ExternalUrl"); - var scopes = openApi.GetRequiredSection("Scopes").AsEnumerable().ToDictionary(p => p.Key, p => p.Value); + var scopes = identitySection.GetRequiredSection("Scopes").AsEnumerable().ToDictionary(p => p.Key, p => p.Value); options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { @@ -183,7 +187,7 @@ public static class CommonExtensions var identitySection = configuration.GetSection("Identity"); - if (identitySection is null) + if (!identitySection.Exists()) { // No identity section, so no authentication return services; @@ -266,6 +270,14 @@ public static class CommonExtensions public static IServiceCollection AddApplicationInsights(this IServiceCollection services, IConfiguration configuration) { + var appInsightsSection = configuration.GetSection("ApplicationInsights"); + + // No instrumentation key, so no application insights + if (string.IsNullOrEmpty(appInsightsSection["InstrumentationKey"])) + { + return services; + } + services.AddApplicationInsightsTelemetry(configuration); services.AddApplicationInsightsKubernetesEnricher(); return services; @@ -288,7 +300,7 @@ public static class CommonExtensions var eventBusSection = configuration.GetRequiredSection("EventBus"); var eventBusConnectionString = eventBusSection.GetRequiredValue("ConnectionString"); - return eventBusSection.GetRequiredValue("ProviderName").ToLowerInvariant() switch + return eventBusSection["ProviderName"]?.ToLowerInvariant() switch { "servicebus" => hcBuilder.AddAzureServiceBusTopic( eventBusConnectionString, @@ -438,5 +450,5 @@ public static class CommonExtensions } private static string GetRequiredValue(this IConfiguration configuration, string name) => - configuration[name] ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Key + ":" + name : name)}"); + configuration[name] ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":" + name : name)}"); } From d1372cba64be6c35a118034cbc58190ed98cfcee Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 2 May 2023 22:30:06 -0700 Subject: [PATCH 019/118] First pass at making the catalog API use the common service helpers --- .../Catalog/Catalog.API/Catalog.API.csproj | 1 + .../Catalog.API/CustomExtensionMethods.cs | 89 +++++ src/Services/Catalog/Catalog.API/Program.cs | 375 ++---------------- .../Catalog/Catalog.API/appsettings.json | 21 +- 4 files changed, 138 insertions(+), 348 deletions(-) create mode 100644 src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index 7d778716b..63ae7ce25 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -79,6 +79,7 @@ + diff --git a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs new file mode 100644 index 000000000..7b3633a12 --- /dev/null +++ b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs @@ -0,0 +1,89 @@ +public static class CustomExtensionMethods +{ + public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) + { + var hcBuilder = services.AddHealthChecks(); + + hcBuilder + .AddSqlServer( + configuration.GetConnectionString("Application"), + name: "CatalogDB-check", + tags: new string[] { "catalogdb" }); + + var accountName = configuration["AzureStorageAccountName"]; + var accountKey = configuration["AzureStorageAccountKey"]; + + if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey)) + { + hcBuilder + .AddAzureBlobStorage( + $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net", + name: "catalog-storage-check", + tags: new string[] { "catalogstorage" }); + } + + return services; + } + + public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration) + { + services.AddEntityFrameworkSqlServer() + .AddDbContext(options => + { + options.UseSqlServer(configuration["ConnectionString"], + sqlServerOptionsAction: sqlOptions => + { + sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name); + //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency + sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); + }); + }); + + services.AddDbContext(options => + { + options.UseSqlServer(configuration["ConnectionString"], + sqlServerOptionsAction: sqlOptions => + { + sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name); + //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency + sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); + }); + }); + + return services; + } + + public static IServiceCollection AddCustomOptions(this IServiceCollection services, IConfiguration configuration) + { + services.Configure(configuration); + services.Configure(options => + { + options.InvalidModelStateResponseFactory = context => + { + var problemDetails = new ValidationProblemDetails(context.ModelState) + { + Instance = context.HttpContext.Request.Path, + Status = StatusCodes.Status400BadRequest, + Detail = "Please refer to the errors property for additional details." + }; + + return new BadRequestObjectResult(problemDetails) + { + ContentTypes = { "application/problem+json", "application/problem+xml" } + }; + }; + }); + + return services; + } + + public static IServiceCollection AddIntegrationServices(this IServiceCollection services) + { + services.AddTransient>( + sp => (DbConnection c) => new IntegrationEventLogService(c)); + + services.AddTransient(); + + return services; + } +} diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index 9c919dbc1..f8fd8b4ab 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -1,117 +1,56 @@ -var builder = WebApplication.CreateBuilder(new WebApplicationOptions -{ - Args = args, - ApplicationName = typeof(Program).Assembly.FullName, - ContentRootPath = Directory.GetCurrentDirectory(), - WebRootPath = "Pics", -}); -if (builder.Configuration.GetValue("UseVault", false)) -{ - TokenCredential credential = new ClientSecretCredential( - builder.Configuration["Vault:TenantId"], - builder.Configuration["Vault:ClientId"], - builder.Configuration["Vault:ClientSecret"]); - //builder.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential); -} -builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); -builder.WebHost.UseKestrel(options => -{ - var ports = GetDefinedPorts(builder.Configuration); - options.Listen(IPAddress.Any, ports.httpPort, listenOptions => - { - listenOptions.Protocols = HttpProtocols.Http1AndHttp2; - }); - options.Listen(IPAddress.Any, ports.grpcPort, listenOptions => - { - listenOptions.Protocols = HttpProtocols.Http2; - }); +using Services.Common; -}); -builder.Services.AddAppInsight(builder.Configuration); -builder.Services.AddGrpc().Services - .AddCustomMVC(builder.Configuration) - .AddCustomDbContext(builder.Configuration) - .AddCustomOptions(builder.Configuration) - .AddCustomHealthCheck(builder.Configuration) - .AddIntegrationServices(builder.Configuration) - .AddEventBus(builder.Configuration) - .AddSwagger(builder.Configuration); +var builder = WebApplication.CreateBuilder(args); -var app = builder.Build(); +builder.AddServiceDefaults(); -if (app.Environment.IsDevelopment()) +builder.Services.AddControllers(options => { - app.UseDeveloperExceptionPage(); -} -else -{ - app.UseExceptionHandler("/Home/Error"); -} + options.Filters.Add(typeof(HttpGlobalExceptionFilter)); +}) +.AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true); -var pathBase = app.Configuration["PATH_BASE"]; -if (!string.IsNullOrEmpty(pathBase)) -{ - app.UsePathBase(pathBase); -} +builder.Services.AddGrpc(); + +builder.Services.AddCustomDbContext(builder.Configuration); +builder.Services.AddCustomOptions(builder.Configuration); +builder.Services.AddCustomHealthCheck(builder.Configuration); +builder.Services.AddIntegrationServices(); -app.UseSwagger() - .UseSwaggerUI(c => - { - c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Catalog.API V1"); - }); +builder.Services.AddTransient(); +builder.Services.AddTransient(); + +var app = builder.Build(); + +app.UseServiceDefaults(); -app.UseRouting(); -app.UseCors("CorsPolicy"); app.MapDefaultControllerRoute(); app.MapControllers(); + app.UseFileServer(new FileServerOptions { FileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "Pics")), RequestPath = "/pics" }); -app.UseStaticFiles(new StaticFileOptions -{ - FileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "Pics")), - RequestPath = "/pics" -}); -app.MapGet("/_proto/", async ctx => -{ - ctx.Response.ContentType = "text/plain"; - using var fs = new FileStream(Path.Combine(app.Environment.ContentRootPath, "Proto", "catalog.proto"), FileMode.Open, FileAccess.Read); - using var sr = new StreamReader(fs); - while (!sr.EndOfStream) - { - var line = await sr.ReadLineAsync(); - if (line != "/* >>" || line != "<< */") - { - await ctx.Response.WriteAsync(line); - } - } -}); + app.MapGrpcService(); -app.MapHealthChecks("/hc", new HealthCheckOptions() -{ - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse -}); -app.MapHealthChecks("/liveness", new HealthCheckOptions -{ - Predicate = r => r.Name.Contains("self") -}); -ConfigureEventBus(app); +var eventBus = app.Services.GetRequiredService(); + +eventBus.Subscribe(); +eventBus.Subscribe(); try { - Log.Information("Configuring web host ({ApplicationContext})...", Program.AppName); + app.Logger.LogInformation("Configuring web host ({ApplicationContext})...", AppName); + using var scope = app.Services.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); - var env = app.Services.GetService(); var settings = app.Services.GetService>(); var logger = app.Services.GetService>(); await context.Database.MigrateAsync(); - await new CatalogContextSeed().SeedAsync(context, env, settings, logger); + await new CatalogContextSeed().SeedAsync(context, app.Environment, settings, logger); var integEventContext = scope.ServiceProvider.GetRequiredService(); await integEventContext.Database.MigrateAsync(); app.Logger.LogInformation("Starting web host ({ApplicationName})...", AppName); @@ -121,268 +60,12 @@ try } catch (Exception ex) { - Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName); + app.Logger.LogCritical(ex, "Program terminated unexpectedly ({ApplicationContext})!", AppName); return 1; } -finally -{ - Log.CloseAndFlush(); -} -void ConfigureEventBus(IApplicationBuilder app) -{ - var eventBus = app.ApplicationServices.GetRequiredService(); - eventBus.Subscribe(); - eventBus.Subscribe(); -} - -(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config) -{ - var grpcPort = config.GetValue("GRPC_PORT", 81); - var port = config.GetValue("PORT", 80); - return (port, grpcPort); -} public partial class Program { public static string Namespace = typeof(Program).Assembly.GetName().Name; public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1); } - -public static class CustomExtensionMethods -{ - public static IServiceCollection AddAppInsight(this IServiceCollection services, IConfiguration configuration) - { - services.AddApplicationInsightsTelemetry(configuration); - services.AddApplicationInsightsKubernetesEnricher(); - - return services; - } - - public static IServiceCollection AddCustomMVC(this IServiceCollection services, IConfiguration configuration) - { - services.AddControllers(options => - { - options.Filters.Add(typeof(HttpGlobalExceptionFilter)); - }) - .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true); - - services.AddCors(options => - { - options.AddPolicy("CorsPolicy", - builder => builder - .SetIsOriginAllowed((host) => true) - .AllowAnyMethod() - .AllowAnyHeader() - .AllowCredentials()); - }); - - return services; - } - - public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) - { - var accountName = configuration.GetValue("AzureStorageAccountName"); - var accountKey = configuration.GetValue("AzureStorageAccountKey"); - - var hcBuilder = services.AddHealthChecks(); - - hcBuilder - .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddSqlServer( - configuration["ConnectionString"], - name: "CatalogDB-check", - tags: new string[] { "catalogdb" }); - - if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey)) - { - hcBuilder - .AddAzureBlobStorage( - $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net", - name: "catalog-storage-check", - tags: new string[] { "catalogstorage" }); - } - - if (configuration.GetValue("AzureServiceBusEnabled")) - { - hcBuilder - .AddAzureServiceBusTopic( - configuration["EventBusConnection"], - topicName: "eshop_event_bus", - name: "catalog-servicebus-check", - tags: new string[] { "servicebus" }); - } - else - { - hcBuilder - .AddRabbitMQ( - $"amqp://{configuration["EventBusConnection"]}", - name: "catalog-rabbitmqbus-check", - tags: new string[] { "rabbitmqbus" }); - } - - return services; - } - - public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration) - { - services.AddEntityFrameworkSqlServer() - .AddDbContext(options => - { - options.UseSqlServer(configuration["ConnectionString"], - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name); - //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency - sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - }); - }); - - services.AddDbContext(options => - { - options.UseSqlServer(configuration["ConnectionString"], - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name); - //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency - sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - }); - }); - - return services; - } - - public static IServiceCollection AddCustomOptions(this IServiceCollection services, IConfiguration configuration) - { - services.Configure(configuration); - services.Configure(options => - { - options.InvalidModelStateResponseFactory = context => - { - var problemDetails = new ValidationProblemDetails(context.ModelState) - { - Instance = context.HttpContext.Request.Path, - Status = StatusCodes.Status400BadRequest, - Detail = "Please refer to the errors property for additional details." - }; - - return new BadRequestObjectResult(problemDetails) - { - ContentTypes = { "application/problem+json", "application/problem+xml" } - }; - }; - }); - - return services; - } - - public static IServiceCollection AddSwagger(this IServiceCollection services, IConfiguration configuration) - { - services.AddSwaggerGen(options => - { - options.SwaggerDoc("v1", new OpenApiInfo - { - Title = "eShopOnContainers - Catalog HTTP API", - Version = "v1", - Description = "The Catalog Microservice HTTP API. This is a Data-Driven/CRUD microservice sample" - }); - }); - - return services; - - } - - public static IServiceCollection AddIntegrationServices(this IServiceCollection services, IConfiguration configuration) - { - services.AddTransient>( - sp => (DbConnection c) => new IntegrationEventLogService(c)); - - services.AddTransient(); - - if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var settings = sp.GetRequiredService>().Value; - var serviceBusConnection = settings.EventBusConnection; - - return new DefaultServiceBusPersisterConnection(serviceBusConnection); - }); - } - else - { - services.AddSingleton(sp => - { - var settings = sp.GetRequiredService>().Value; - var logger = sp.GetRequiredService>(); - - var factory = new ConnectionFactory() - { - HostName = configuration["EventBusConnection"], - DispatchConsumersAsync = true - }; - - if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) - { - factory.UserName = configuration["EventBusUserName"]; - } - - if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) - { - factory.Password = configuration["EventBusPassword"]; - } - - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); - } - - return services; - } - - public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) - { - if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - string subscriptionName = configuration["SubscriptionClientName"]; - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, sp, subscriptionName); - }); - - } - else - { - services.AddSingleton(sp => - { - var subscriptionClientName = configuration["SubscriptionClientName"]; - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubcriptionsManager, subscriptionClientName, retryCount); - }); - } - - services.AddSingleton(); - services.AddTransient(); - services.AddTransient(); - - return services; - } -} diff --git a/src/Services/Catalog/Catalog.API/appsettings.json b/src/Services/Catalog/Catalog.API/appsettings.json index f8342fe8d..eac02f2fc 100644 --- a/src/Services/Catalog/Catalog.API/appsettings.json +++ b/src/Services/Catalog/Catalog.API/appsettings.json @@ -18,13 +18,30 @@ "ApplicationInsights": { "InstrumentationKey": "" }, - "EventBusRetryCount": 5, "UseVault": false, "Vault": { "Name": "eshop", "ClientId": "your-client-id", "ClientSecret": "your-client-secret" + }, + "OpenApi": { + "Endpoint": { + "Name": "" + }, + "Document": { + "Name": "Catalog.API V1", + "Description": "The Catalog Microservice HTTP API. This is a Data-Driven/CRUD microservice sample", + "Title": "eShopOnContainers - Catalog HTTP API", + "Version": "v1" + } + }, + "ConnectionStrings": { + "Application": "" + }, + "EventBus": { + "SubscriptionClientName": "Basket", + "ConnectionString": "localhost", + "RetryCount": 5 } - } From f46b03cb36026734fb57718a15c3d299f49ef02e Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 2 May 2023 22:31:40 -0700 Subject: [PATCH 020/118] Use before Map --- src/Services/Catalog/Catalog.API/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index f8fd8b4ab..38bb07a4f 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -24,15 +24,15 @@ var app = builder.Build(); app.UseServiceDefaults(); -app.MapDefaultControllerRoute(); -app.MapControllers(); - app.UseFileServer(new FileServerOptions { FileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "Pics")), RequestPath = "/pics" }); +app.MapDefaultControllerRoute(); +app.MapControllers(); + app.MapGrpcService(); var eventBus = app.Services.GetRequiredService(); From 794c546d2ee311128f8137e7560dd47e82d491eb Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 2 May 2023 22:48:11 -0700 Subject: [PATCH 021/118] Fix the catalog tests --- .../Basket/Basket.API/appsettings.json | 24 +++++++++---------- .../Catalog.API/CustomExtensionMethods.cs | 24 +++++++++++++------ .../Catalog/Catalog.API/appsettings.json | 5 ++-- .../Catalog.FunctionalTests/appsettings.json | 12 +++++++--- 4 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json index 6cf67a4a4..46a21d4c2 100644 --- a/src/Services/Basket/Basket.API/appsettings.json +++ b/src/Services/Basket/Basket.API/appsettings.json @@ -16,14 +16,23 @@ "Protocols": "Http2" } }, + "ApplicationInsights": { + "InstrumentationKey": "" + }, + "UseVault": false, + "Vault": { + "Name": "eshop", + "ClientId": "your-client-id", + "ClientSecret": "your-client-secret" + }, "OpenApi": { "Endpoint": { "Name": "" }, "Document": { - "Name": "Basket API", - "Description": "Basket API", - "Title": "Basket API", + "Name": "Basket.API V1", + "Description": "The Basket Service HTTP API", + "Title": "eShopOnContainers - Basket HTTP API", "Version": "v1" } }, @@ -41,14 +50,5 @@ "SubscriptionClientName": "Basket", "ConnectionString": "localhost", "RetryCount": 5 - }, - "ApplicationInsights": { - "InstrumentationKey": "" - }, - "UseVault": false, - "Vault": { - "Name": "eshop", - "ClientId": "your-client-id", - "ClientSecret": "your-client-secret" } } diff --git a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs index 7b3633a12..e30200d5f 100644 --- a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs +++ b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs @@ -4,11 +4,14 @@ { var hcBuilder = services.AddHealthChecks(); - hcBuilder - .AddSqlServer( - configuration.GetConnectionString("Application"), - name: "CatalogDB-check", - tags: new string[] { "catalogdb" }); + if (configuration.GetConnectionString("CatalogDB") is string connectionString) + { + hcBuilder + .AddSqlServer( + connectionString, + name: "CatalogDB-check", + tags: new string[] { "catalogdb" }); + } var accountName = configuration["AzureStorageAccountName"]; var accountKey = configuration["AzureStorageAccountKey"]; @@ -30,7 +33,9 @@ services.AddEntityFrameworkSqlServer() .AddDbContext(options => { - options.UseSqlServer(configuration["ConnectionString"], + var connectionString = configuration.GetRequiredConnectionString("CatalogDB"); + + options.UseSqlServer(connectionString, sqlServerOptionsAction: sqlOptions => { sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name); @@ -41,7 +46,9 @@ services.AddDbContext(options => { - options.UseSqlServer(configuration["ConnectionString"], + var connectionString = configuration.GetRequiredConnectionString("CatalogDB"); + + options.UseSqlServer(connectionString, sqlServerOptionsAction: sqlOptions => { sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name); @@ -86,4 +93,7 @@ return services; } + + private static string GetRequiredConnectionString(this IConfiguration configuration, string name) => + configuration.GetConnectionString(name) ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":ConnectionStrings:" + name : "ConnectionStrings:" + name)}"); } diff --git a/src/Services/Catalog/Catalog.API/appsettings.json b/src/Services/Catalog/Catalog.API/appsettings.json index eac02f2fc..dda8c7a17 100644 --- a/src/Services/Catalog/Catalog.API/appsettings.json +++ b/src/Services/Catalog/Catalog.API/appsettings.json @@ -14,7 +14,6 @@ }, "AzureServiceBusEnabled": false, "AzureStorageEnabled": false, - "SubscriptionClientName": "Catalog", "ApplicationInsights": { "InstrumentationKey": "" }, @@ -36,10 +35,10 @@ } }, "ConnectionStrings": { - "Application": "" + "CatalogDB": "" }, "EventBus": { - "SubscriptionClientName": "Basket", + "SubscriptionClientName": "Catalog", "ConnectionString": "localhost", "RetryCount": 5 } diff --git a/src/Services/Catalog/Catalog.FunctionalTests/appsettings.json b/src/Services/Catalog/Catalog.FunctionalTests/appsettings.json index 708598b8a..2f05bebc8 100644 --- a/src/Services/Catalog/Catalog.FunctionalTests/appsettings.json +++ b/src/Services/Catalog/Catalog.FunctionalTests/appsettings.json @@ -1,9 +1,15 @@ { - "ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true", "ExternalCatalogBaseUrl": "http://localhost:5101", "IdentityUrl": "http://localhost:5105", "isTest": "true", - "EventBusConnection": "localhost", "PicBaseUrl": "http://localhost:5101/api/v1/catalog/items/[0]/pic/", - "SubscriptionClientName": "Catalog" + + "ConnectionStrings": { + "CatalogDb": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true" + }, + + "EventBus": { + "SubscriptionClientName": "Catalog", + "ConnectionString": "localhost" + } } From c565a8f7991feb45f05706b53ca88299f374ed26 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 2 May 2023 22:53:15 -0700 Subject: [PATCH 022/118] Unify configuration --- .../Catalog.API/CustomExtensionMethods.cs | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs index e30200d5f..60b717dfe 100644 --- a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs +++ b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs @@ -1,4 +1,6 @@ -public static class CustomExtensionMethods +using Microsoft.EntityFrameworkCore.Infrastructure; + +public static class CustomExtensionMethods { public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) { @@ -30,31 +32,28 @@ public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration) { + void ConfigureSqlOptions(SqlServerDbContextOptionsBuilder sqlOptions) + { + sqlOptions.MigrationsAssembly(typeof(Program).FullName); + + // Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency + + sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); + }; + services.AddEntityFrameworkSqlServer() .AddDbContext(options => { var connectionString = configuration.GetRequiredConnectionString("CatalogDB"); - options.UseSqlServer(connectionString, - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name); - //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency - sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - }); + options.UseSqlServer(connectionString, ConfigureSqlOptions); }); services.AddDbContext(options => { var connectionString = configuration.GetRequiredConnectionString("CatalogDB"); - options.UseSqlServer(connectionString, - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name); - //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency - sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - }); + options.UseSqlServer(connectionString, ConfigureSqlOptions); }); return services; @@ -63,6 +62,8 @@ public static IServiceCollection AddCustomOptions(this IServiceCollection services, IConfiguration configuration) { services.Configure(configuration); + + // TODO: Move to the new problem details middleware services.Configure(options => { options.InvalidModelStateResponseFactory = context => @@ -95,5 +96,5 @@ } private static string GetRequiredConnectionString(this IConfiguration configuration, string name) => - configuration.GetConnectionString(name) ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":ConnectionStrings:" + name : "ConnectionStrings:" + name)}"); + configuration.GetConnectionString(name) ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":ConnectionStrings:" + name : "ConnectionStrings:" + name)}"); } From d4319bdd47b2329c5976de464fe397adb116a805 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 2 May 2023 22:56:40 -0700 Subject: [PATCH 023/118] Redirect to swagger --- .../Catalog.API/Controllers/HomeController.cs | 11 ----------- .../Catalog/Catalog.API/GlobalUsings.cs | 19 ++----------------- src/Services/Catalog/Catalog.API/Program.cs | 2 ++ 3 files changed, 4 insertions(+), 28 deletions(-) delete mode 100644 src/Services/Catalog/Catalog.API/Controllers/HomeController.cs diff --git a/src/Services/Catalog/Catalog.API/Controllers/HomeController.cs b/src/Services/Catalog/Catalog.API/Controllers/HomeController.cs deleted file mode 100644 index cd86a2966..000000000 --- a/src/Services/Catalog/Catalog.API/Controllers/HomeController.cs +++ /dev/null @@ -1,11 +0,0 @@ -// For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860 -namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers; - -public class HomeController : Controller -{ - // GET: // - public IActionResult Index() - { - return new RedirectResult("~/swagger"); - } -} diff --git a/src/Services/Catalog/Catalog.API/GlobalUsings.cs b/src/Services/Catalog/Catalog.API/GlobalUsings.cs index 277288adc..19d407fbb 100644 --- a/src/Services/Catalog/Catalog.API/GlobalUsings.cs +++ b/src/Services/Catalog/Catalog.API/GlobalUsings.cs @@ -1,7 +1,4 @@ -global using Azure.Core; -global using Azure.Identity; -global using Autofac.Extensions.DependencyInjection; -global using Autofac; +global using Autofac; global using Microsoft.eShopOnContainers.Services.Catalog.API.Extensions; global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.ActionResults; global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.Exceptions; @@ -12,8 +9,6 @@ global using Microsoft.AspNetCore.Http; global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.Mvc.Filters; global using Microsoft.AspNetCore.Mvc; -global using Microsoft.AspNetCore.Server.Kestrel.Core; -global using Microsoft.AspNetCore; global using Microsoft.Extensions.Logging; global using Microsoft.EntityFrameworkCore.Design; global using Microsoft.EntityFrameworkCore.Metadata.Builders; @@ -37,7 +32,6 @@ global using Microsoft.Extensions.Options; global using Polly.Retry; global using Polly; global using Serilog.Context; -global using Serilog; global using System.Collections.Generic; global using System.Data.Common; global using System.Data.SqlClient; @@ -50,14 +44,5 @@ global using System.Text.RegularExpressions; global using System.Threading.Tasks; global using System; global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.Filters; -global using HealthChecks.UI.Client; -global using Microsoft.AspNetCore.Diagnostics.HealthChecks; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling; -global using Microsoft.Extensions.Diagnostics.HealthChecks; -global using Microsoft.OpenApi.Models; -global using RabbitMQ.Client; -global using System.Reflection; -global using Microsoft.Extensions.FileProviders; \ No newline at end of file +global using Microsoft.Extensions.FileProviders; diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index 38bb07a4f..2aa679c1e 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -30,6 +30,8 @@ app.UseFileServer(new FileServerOptions RequestPath = "/pics" }); +app.MapGet("/", () => Results.Redirect("/swagger")); + app.MapDefaultControllerRoute(); app.MapControllers(); From 366019aaa32157720edc5d06cd99281480c1740a Mon Sep 17 00:00:00 2001 From: David Fowler Date: Wed, 3 May 2023 07:33:44 -0700 Subject: [PATCH 024/118] Use the assembly name instead of the type name --- .../Catalog/Catalog.API/CustomExtensionMethods.cs | 10 +++++----- src/Services/Catalog/Catalog.API/Program.cs | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs index 60b717dfe..4524c150b 100644 --- a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs +++ b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs @@ -2,7 +2,7 @@ public static class CustomExtensionMethods { - public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) { var hcBuilder = services.AddHealthChecks(); @@ -30,11 +30,11 @@ public static class CustomExtensionMethods return services; } - public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddDbContexts(this IServiceCollection services, IConfiguration configuration) { - void ConfigureSqlOptions(SqlServerDbContextOptionsBuilder sqlOptions) + static void ConfigureSqlOptions(SqlServerDbContextOptionsBuilder sqlOptions) { - sqlOptions.MigrationsAssembly(typeof(Program).FullName); + sqlOptions.MigrationsAssembly(typeof(Program).Assembly.FullName); // Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency @@ -59,7 +59,7 @@ public static class CustomExtensionMethods return services; } - public static IServiceCollection AddCustomOptions(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddApplicationOptions(this IServiceCollection services, IConfiguration configuration) { services.Configure(configuration); diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index 2aa679c1e..858a2b127 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -12,9 +12,9 @@ builder.Services.AddControllers(options => builder.Services.AddGrpc(); -builder.Services.AddCustomDbContext(builder.Configuration); -builder.Services.AddCustomOptions(builder.Configuration); -builder.Services.AddCustomHealthCheck(builder.Configuration); +builder.Services.AddDbContexts(builder.Configuration); +builder.Services.AddApplicationOptions(builder.Configuration); +builder.Services.AddHealthChecks(builder.Configuration); builder.Services.AddIntegrationServices(); builder.Services.AddTransient(); From 4e743ef66604fed3e8fd1f47b58cd0c78b23e60e Mon Sep 17 00:00:00 2001 From: David Fowler Date: Wed, 3 May 2023 07:41:00 -0700 Subject: [PATCH 025/118] Not needed --- src/Services/Catalog/Catalog.API/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index 858a2b127..01287d8be 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -32,7 +32,6 @@ app.UseFileServer(new FileServerOptions app.MapGet("/", () => Results.Redirect("/swagger")); -app.MapDefaultControllerRoute(); app.MapControllers(); app.MapGrpcService(); From 48f640088b65f91c305c4575c70a9dc235048e0a Mon Sep 17 00:00:00 2001 From: David Fowler Date: Wed, 3 May 2023 07:52:44 -0700 Subject: [PATCH 026/118] More clean up --- .../Auth/Client/enable-token-client.js | 28 - .../Auth/Client/oidc-token-manager.js | 8896 ----------------- .../Basket/Basket.API/Auth/Client/popup.html | 13 - ...orizationHeaderParameterOperationFilter.cs | 25 - .../Basket/Basket.API/GlobalUsings.cs | 28 +- .../FailingMiddlewareAppBuilderExtensions.cs | 18 - .../AuthorizeCheckOperationFilter.cs | 29 - .../Middlewares/FailingMiddleware.cs | 90 - .../Middlewares/FailingOptions.cs | 10 - .../Middlewares/FailingStartupFilter.cs | 20 - .../FailingWebHostBuilderExtensions.cs | 14 - .../Catalog/Catalog.API/Catalog.API.csproj | 1 - .../Catalog/Catalog.API/GlobalUsings.cs | 53 +- 13 files changed, 37 insertions(+), 9188 deletions(-) delete mode 100644 src/Services/Basket/Basket.API/Auth/Client/enable-token-client.js delete mode 100644 src/Services/Basket/Basket.API/Auth/Client/oidc-token-manager.js delete mode 100644 src/Services/Basket/Basket.API/Auth/Client/popup.html delete mode 100644 src/Services/Basket/Basket.API/Auth/Server/AuthorizationHeaderParameterOperationFilter.cs delete mode 100644 src/Services/Basket/Basket.API/Infrastructure/Exceptions/FailingMiddlewareAppBuilderExtensions.cs delete mode 100644 src/Services/Basket/Basket.API/Infrastructure/Middlewares/AuthorizeCheckOperationFilter.cs delete mode 100644 src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingMiddleware.cs delete mode 100644 src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingOptions.cs delete mode 100644 src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingStartupFilter.cs delete mode 100644 src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingWebHostBuilderExtensions.cs diff --git a/src/Services/Basket/Basket.API/Auth/Client/enable-token-client.js b/src/Services/Basket/Basket.API/Auth/Client/enable-token-client.js deleted file mode 100644 index 3c207e7ea..000000000 --- a/src/Services/Basket/Basket.API/Auth/Client/enable-token-client.js +++ /dev/null @@ -1,28 +0,0 @@ -(function ($, swaggerUi) { - $(function () { - var settings = { - authority: 'https://localhost:5105', - client_id: 'js', - popup_redirect_uri: window.location.protocol - + '//' - + window.location.host - + '/tokenclient/popup.html', - - response_type: 'id_token token', - scope: 'openid profile basket', - - filter_protocol_claims: true - }, - manager = new OidcTokenManager(settings), - $inputApiKey = $('#input_apiKey'); - - $inputApiKey.on('dblclick', function () { - manager.openPopupForTokenAsync() - .then(function () { - $inputApiKey.val(manager.access_token).change(); - }, function (error) { - console.error(error); - }); - }); - }); -})(jQuery, window.swaggerUi); \ No newline at end of file diff --git a/src/Services/Basket/Basket.API/Auth/Client/oidc-token-manager.js b/src/Services/Basket/Basket.API/Auth/Client/oidc-token-manager.js deleted file mode 100644 index a6f3f29e5..000000000 --- a/src/Services/Basket/Basket.API/Auth/Client/oidc-token-manager.js +++ /dev/null @@ -1,8896 +0,0 @@ -(function () { - - // globals - var _promiseFactory; - var _httpRequest; -/* -CryptoJS v3.1.2 -code.google.com/p/crypto-js -(c) 2009-2013 by Jeff Mott. All rights reserved. -code.google.com/p/crypto-js/wiki/License -*/ -/** - * CryptoJS core components. - */ -var CryptoJS = CryptoJS || (function (Math, undefined) { - /** - * CryptoJS namespace. - */ - var C = {}; - - /** - * Library namespace. - */ - var C_lib = C.lib = {}; - - /** - * Base object for prototypal inheritance. - */ - var Base = C_lib.Base = (function () { - function F() {} - - return { - /** - * Creates a new object that inherits from this object. - * - * @param {Object} overrides Properties to copy into the new object. - * - * @return {Object} The new object. - * - * @static - * - * @example - * - * var MyType = CryptoJS.lib.Base.extend({ - * field: 'value', - * - * method: function () { - * } - * }); - */ - extend: function (overrides) { - // Spawn - F.prototype = this; - var subtype = new F(); - - // Augment - if (overrides) { - subtype.mixIn(overrides); - } - - // Create default initializer - if (!subtype.hasOwnProperty('init')) { - subtype.init = function () { - subtype.$super.init.apply(this, arguments); - }; - } - - // Initializer's prototype is the subtype object - subtype.init.prototype = subtype; - - // Reference supertype - subtype.$super = this; - - return subtype; - }, - - /** - * Extends this object and runs the init method. - * Arguments to create() will be passed to init(). - * - * @return {Object} The new object. - * - * @static - * - * @example - * - * var instance = MyType.create(); - */ - create: function () { - var instance = this.extend(); - instance.init.apply(instance, arguments); - - return instance; - }, - - /** - * Initializes a newly created object. - * Override this method to add some logic when your objects are created. - * - * @example - * - * var MyType = CryptoJS.lib.Base.extend({ - * init: function () { - * // ... - * } - * }); - */ - init: function () { - }, - - /** - * Copies properties into this object. - * - * @param {Object} properties The properties to mix in. - * - * @example - * - * MyType.mixIn({ - * field: 'value' - * }); - */ - mixIn: function (properties) { - for (var propertyName in properties) { - if (properties.hasOwnProperty(propertyName)) { - this[propertyName] = properties[propertyName]; - } - } - - // IE won't copy toString using the loop above - if (properties.hasOwnProperty('toString')) { - this.toString = properties.toString; - } - }, - - /** - * Creates a copy of this object. - * - * @return {Object} The clone. - * - * @example - * - * var clone = instance.clone(); - */ - clone: function () { - return this.init.prototype.extend(this); - } - }; - }()); - - /** - * An array of 32-bit words. - * - * @property {Array} words The array of 32-bit words. - * @property {number} sigBytes The number of significant bytes in this word array. - */ - var WordArray = C_lib.WordArray = Base.extend({ - /** - * Initializes a newly created word array. - * - * @param {Array} words (Optional) An array of 32-bit words. - * @param {number} sigBytes (Optional) The number of significant bytes in the words. - * - * @example - * - * var wordArray = CryptoJS.lib.WordArray.create(); - * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); - * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); - */ - init: function (words, sigBytes) { - words = this.words = words || []; - - if (sigBytes != undefined) { - this.sigBytes = sigBytes; - } else { - this.sigBytes = words.length * 4; - } - }, - - /** - * Converts this word array to a string. - * - * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex - * - * @return {string} The stringified word array. - * - * @example - * - * var string = wordArray + ''; - * var string = wordArray.toString(); - * var string = wordArray.toString(CryptoJS.enc.Utf8); - */ - toString: function (encoder) { - return (encoder || Hex).stringify(this); - }, - - /** - * Concatenates a word array to this word array. - * - * @param {WordArray} wordArray The word array to append. - * - * @return {WordArray} This word array. - * - * @example - * - * wordArray1.concat(wordArray2); - */ - concat: function (wordArray) { - // Shortcuts - var thisWords = this.words; - var thatWords = wordArray.words; - var thisSigBytes = this.sigBytes; - var thatSigBytes = wordArray.sigBytes; - - // Clamp excess bits - this.clamp(); - - // Concat - if (thisSigBytes % 4) { - // Copy one byte at a time - for (var i = 0; i < thatSigBytes; i++) { - var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; - thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); - } - } else if (thatWords.length > 0xffff) { - // Copy one word at a time - for (var i = 0; i < thatSigBytes; i += 4) { - thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2]; - } - } else { - // Copy all words at once - thisWords.push.apply(thisWords, thatWords); - } - this.sigBytes += thatSigBytes; - - // Chainable - return this; - }, - - /** - * Removes insignificant bits. - * - * @example - * - * wordArray.clamp(); - */ - clamp: function () { - // Shortcuts - var words = this.words; - var sigBytes = this.sigBytes; - - // Clamp - words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); - words.length = Math.ceil(sigBytes / 4); - }, - - /** - * Creates a copy of this word array. - * - * @return {WordArray} The clone. - * - * @example - * - * var clone = wordArray.clone(); - */ - clone: function () { - var clone = Base.clone.call(this); - clone.words = this.words.slice(0); - - return clone; - }, - - /** - * Creates a word array filled with random bytes. - * - * @param {number} nBytes The number of random bytes to generate. - * - * @return {WordArray} The random word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.lib.WordArray.random(16); - */ - random: function (nBytes) { - var words = []; - for (var i = 0; i < nBytes; i += 4) { - words.push((Math.random() * 0x100000000) | 0); - } - - return new WordArray.init(words, nBytes); - } - }); - - /** - * Encoder namespace. - */ - var C_enc = C.enc = {}; - - /** - * Hex encoding strategy. - */ - var Hex = C_enc.Hex = { - /** - * Converts a word array to a hex string. - * - * @param {WordArray} wordArray The word array. - * - * @return {string} The hex string. - * - * @static - * - * @example - * - * var hexString = CryptoJS.enc.Hex.stringify(wordArray); - */ - stringify: function (wordArray) { - // Shortcuts - var words = wordArray.words; - var sigBytes = wordArray.sigBytes; - - // Convert - var hexChars = []; - for (var i = 0; i < sigBytes; i++) { - var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; - hexChars.push((bite >>> 4).toString(16)); - hexChars.push((bite & 0x0f).toString(16)); - } - - return hexChars.join(''); - }, - - /** - * Converts a hex string to a word array. - * - * @param {string} hexStr The hex string. - * - * @return {WordArray} The word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.enc.Hex.parse(hexString); - */ - parse: function (hexStr) { - // Shortcut - var hexStrLength = hexStr.length; - - // Convert - var words = []; - for (var i = 0; i < hexStrLength; i += 2) { - words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); - } - - return new WordArray.init(words, hexStrLength / 2); - } - }; - - /** - * Latin1 encoding strategy. - */ - var Latin1 = C_enc.Latin1 = { - /** - * Converts a word array to a Latin1 string. - * - * @param {WordArray} wordArray The word array. - * - * @return {string} The Latin1 string. - * - * @static - * - * @example - * - * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); - */ - stringify: function (wordArray) { - // Shortcuts - var words = wordArray.words; - var sigBytes = wordArray.sigBytes; - - // Convert - var latin1Chars = []; - for (var i = 0; i < sigBytes; i++) { - var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; - latin1Chars.push(String.fromCharCode(bite)); - } - - return latin1Chars.join(''); - }, - - /** - * Converts a Latin1 string to a word array. - * - * @param {string} latin1Str The Latin1 string. - * - * @return {WordArray} The word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); - */ - parse: function (latin1Str) { - // Shortcut - var latin1StrLength = latin1Str.length; - - // Convert - var words = []; - for (var i = 0; i < latin1StrLength; i++) { - words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); - } - - return new WordArray.init(words, latin1StrLength); - } - }; - - /** - * UTF-8 encoding strategy. - */ - var Utf8 = C_enc.Utf8 = { - /** - * Converts a word array to a UTF-8 string. - * - * @param {WordArray} wordArray The word array. - * - * @return {string} The UTF-8 string. - * - * @static - * - * @example - * - * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); - */ - stringify: function (wordArray) { - try { - return decodeURIComponent(escape(Latin1.stringify(wordArray))); - } catch (e) { - throw new Error('Malformed UTF-8 data'); - } - }, - - /** - * Converts a UTF-8 string to a word array. - * - * @param {string} utf8Str The UTF-8 string. - * - * @return {WordArray} The word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); - */ - parse: function (utf8Str) { - return Latin1.parse(unescape(encodeURIComponent(utf8Str))); - } - }; - - /** - * Abstract buffered block algorithm template. - * - * The property blockSize must be implemented in a concrete subtype. - * - * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 - */ - var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ - /** - * Resets this block algorithm's data buffer to its initial state. - * - * @example - * - * bufferedBlockAlgorithm.reset(); - */ - reset: function () { - // Initial values - this._data = new WordArray.init(); - this._nDataBytes = 0; - }, - - /** - * Adds new data to this block algorithm's buffer. - * - * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. - * - * @example - * - * bufferedBlockAlgorithm._append('data'); - * bufferedBlockAlgorithm._append(wordArray); - */ - _append: function (data) { - // Convert string to WordArray, else assume WordArray already - if (typeof data == 'string') { - data = Utf8.parse(data); - } - - // Append - this._data.concat(data); - this._nDataBytes += data.sigBytes; - }, - - /** - * Processes available data blocks. - * - * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. - * - * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. - * - * @return {WordArray} The processed data. - * - * @example - * - * var processedData = bufferedBlockAlgorithm._process(); - * var processedData = bufferedBlockAlgorithm._process(!!'flush'); - */ - _process: function (doFlush) { - // Shortcuts - var data = this._data; - var dataWords = data.words; - var dataSigBytes = data.sigBytes; - var blockSize = this.blockSize; - var blockSizeBytes = blockSize * 4; - - // Count blocks ready - var nBlocksReady = dataSigBytes / blockSizeBytes; - if (doFlush) { - // Round up to include partial blocks - nBlocksReady = Math.ceil(nBlocksReady); - } else { - // Round down to include only full blocks, - // less the number of blocks that must remain in the buffer - nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); - } - - // Count words ready - var nWordsReady = nBlocksReady * blockSize; - - // Count bytes ready - var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); - - // Process blocks - if (nWordsReady) { - for (var offset = 0; offset < nWordsReady; offset += blockSize) { - // Perform concrete-algorithm logic - this._doProcessBlock(dataWords, offset); - } - - // Remove processed words - var processedWords = dataWords.splice(0, nWordsReady); - data.sigBytes -= nBytesReady; - } - - // Return processed words - return new WordArray.init(processedWords, nBytesReady); - }, - - /** - * Creates a copy of this object. - * - * @return {Object} The clone. - * - * @example - * - * var clone = bufferedBlockAlgorithm.clone(); - */ - clone: function () { - var clone = Base.clone.call(this); - clone._data = this._data.clone(); - - return clone; - }, - - _minBufferSize: 0 - }); - - /** - * Abstract hasher template. - * - * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) - */ - var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ - /** - * Configuration options. - */ - cfg: Base.extend(), - - /** - * Initializes a newly created hasher. - * - * @param {Object} cfg (Optional) The configuration options to use for this hash computation. - * - * @example - * - * var hasher = CryptoJS.algo.SHA256.create(); - */ - init: function (cfg) { - // Apply config defaults - this.cfg = this.cfg.extend(cfg); - - // Set initial values - this.reset(); - }, - - /** - * Resets this hasher to its initial state. - * - * @example - * - * hasher.reset(); - */ - reset: function () { - // Reset data buffer - BufferedBlockAlgorithm.reset.call(this); - - // Perform concrete-hasher logic - this._doReset(); - }, - - /** - * Updates this hasher with a message. - * - * @param {WordArray|string} messageUpdate The message to append. - * - * @return {Hasher} This hasher. - * - * @example - * - * hasher.update('message'); - * hasher.update(wordArray); - */ - update: function (messageUpdate) { - // Append - this._append(messageUpdate); - - // Update the hash - this._process(); - - // Chainable - return this; - }, - - /** - * Finalizes the hash computation. - * Note that the finalize operation is effectively a destructive, read-once operation. - * - * @param {WordArray|string} messageUpdate (Optional) A final message update. - * - * @return {WordArray} The hash. - * - * @example - * - * var hash = hasher.finalize(); - * var hash = hasher.finalize('message'); - * var hash = hasher.finalize(wordArray); - */ - finalize: function (messageUpdate) { - // Final message update - if (messageUpdate) { - this._append(messageUpdate); - } - - // Perform concrete-hasher logic - var hash = this._doFinalize(); - - return hash; - }, - - blockSize: 512/32, - - /** - * Creates a shortcut function to a hasher's object interface. - * - * @param {Hasher} hasher The hasher to create a helper for. - * - * @return {Function} The shortcut function. - * - * @static - * - * @example - * - * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); - */ - _createHelper: function (hasher) { - return function (message, cfg) { - return new hasher.init(cfg).finalize(message); - }; - }, - - /** - * Creates a shortcut function to the HMAC's object interface. - * - * @param {Hasher} hasher The hasher to use in this HMAC helper. - * - * @return {Function} The shortcut function. - * - * @static - * - * @example - * - * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); - */ - _createHmacHelper: function (hasher) { - return function (message, key) { - return new C_algo.HMAC.init(hasher, key).finalize(message); - }; - } - }); - - /** - * Algorithm namespace. - */ - var C_algo = C.algo = {}; - - return C; -}(Math)); - -/* -CryptoJS v3.1.2 -code.google.com/p/crypto-js -(c) 2009-2013 by Jeff Mott. All rights reserved. -code.google.com/p/crypto-js/wiki/License -*/ -(function () { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var WordArray = C_lib.WordArray; - var Hasher = C_lib.Hasher; - var C_algo = C.algo; - - // Reusable object - var W = []; - - /** - * SHA-1 hash algorithm. - */ - var SHA1 = C_algo.SHA1 = Hasher.extend({ - _doReset: function () { - this._hash = new WordArray.init([ - 0x67452301, 0xefcdab89, - 0x98badcfe, 0x10325476, - 0xc3d2e1f0 - ]); - }, - - _doProcessBlock: function (M, offset) { - // Shortcut - var H = this._hash.words; - - // Working variables - var a = H[0]; - var b = H[1]; - var c = H[2]; - var d = H[3]; - var e = H[4]; - - // Computation - for (var i = 0; i < 80; i++) { - if (i < 16) { - W[i] = M[offset + i] | 0; - } else { - var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; - W[i] = (n << 1) | (n >>> 31); - } - - var t = ((a << 5) | (a >>> 27)) + e + W[i]; - if (i < 20) { - t += ((b & c) | (~b & d)) + 0x5a827999; - } else if (i < 40) { - t += (b ^ c ^ d) + 0x6ed9eba1; - } else if (i < 60) { - t += ((b & c) | (b & d) | (c & d)) - 0x70e44324; - } else /* if (i < 80) */ { - t += (b ^ c ^ d) - 0x359d3e2a; - } - - e = d; - d = c; - c = (b << 30) | (b >>> 2); - b = a; - a = t; - } - - // Intermediate hash value - H[0] = (H[0] + a) | 0; - H[1] = (H[1] + b) | 0; - H[2] = (H[2] + c) | 0; - H[3] = (H[3] + d) | 0; - H[4] = (H[4] + e) | 0; - }, - - _doFinalize: function () { - // Shortcuts - var data = this._data; - var dataWords = data.words; - - var nBitsTotal = this._nDataBytes * 8; - var nBitsLeft = data.sigBytes * 8; - - // Add padding - dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); - dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); - dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; - data.sigBytes = dataWords.length * 4; - - // Hash final blocks - this._process(); - - // Return final computed hash - return this._hash; - }, - - clone: function () { - var clone = Hasher.clone.call(this); - clone._hash = this._hash.clone(); - - return clone; - } - }); - - /** - * Shortcut function to the hasher's object interface. - * - * @param {WordArray|string} message The message to hash. - * - * @return {WordArray} The hash. - * - * @static - * - * @example - * - * var hash = CryptoJS.SHA1('message'); - * var hash = CryptoJS.SHA1(wordArray); - */ - C.SHA1 = Hasher._createHelper(SHA1); - - /** - * Shortcut function to the HMAC's object interface. - * - * @param {WordArray|string} message The message to hash. - * @param {WordArray|string} key The secret key. - * - * @return {WordArray} The HMAC. - * - * @static - * - * @example - * - * var hmac = CryptoJS.HmacSHA1(message, key); - */ - C.HmacSHA1 = Hasher._createHmacHelper(SHA1); -}()); - -/* -CryptoJS v3.1.2 -code.google.com/p/crypto-js -(c) 2009-2013 by Jeff Mott. All rights reserved. -code.google.com/p/crypto-js/wiki/License -*/ -(function (Math) { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var WordArray = C_lib.WordArray; - var Hasher = C_lib.Hasher; - var C_algo = C.algo; - - // Initialization and round constants tables - var H = []; - var K = []; - - // Compute constants - (function () { - function isPrime(n) { - var sqrtN = Math.sqrt(n); - for (var factor = 2; factor <= sqrtN; factor++) { - if (!(n % factor)) { - return false; - } - } - - return true; - } - - function getFractionalBits(n) { - return ((n - (n | 0)) * 0x100000000) | 0; - } - - var n = 2; - var nPrime = 0; - while (nPrime < 64) { - if (isPrime(n)) { - if (nPrime < 8) { - H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2)); - } - K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3)); - - nPrime++; - } - - n++; - } - }()); - - // Reusable object - var W = []; - - /** - * SHA-256 hash algorithm. - */ - var SHA256 = C_algo.SHA256 = Hasher.extend({ - _doReset: function () { - this._hash = new WordArray.init(H.slice(0)); - }, - - _doProcessBlock: function (M, offset) { - // Shortcut - var H = this._hash.words; - - // Working variables - var a = H[0]; - var b = H[1]; - var c = H[2]; - var d = H[3]; - var e = H[4]; - var f = H[5]; - var g = H[6]; - var h = H[7]; - - // Computation - for (var i = 0; i < 64; i++) { - if (i < 16) { - W[i] = M[offset + i] | 0; - } else { - var gamma0x = W[i - 15]; - var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^ - ((gamma0x << 14) | (gamma0x >>> 18)) ^ - (gamma0x >>> 3); - - var gamma1x = W[i - 2]; - var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^ - ((gamma1x << 13) | (gamma1x >>> 19)) ^ - (gamma1x >>> 10); - - W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]; - } - - var ch = (e & f) ^ (~e & g); - var maj = (a & b) ^ (a & c) ^ (b & c); - - var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22)); - var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25)); - - var t1 = h + sigma1 + ch + K[i] + W[i]; - var t2 = sigma0 + maj; - - h = g; - g = f; - f = e; - e = (d + t1) | 0; - d = c; - c = b; - b = a; - a = (t1 + t2) | 0; - } - - // Intermediate hash value - H[0] = (H[0] + a) | 0; - H[1] = (H[1] + b) | 0; - H[2] = (H[2] + c) | 0; - H[3] = (H[3] + d) | 0; - H[4] = (H[4] + e) | 0; - H[5] = (H[5] + f) | 0; - H[6] = (H[6] + g) | 0; - H[7] = (H[7] + h) | 0; - }, - - _doFinalize: function () { - // Shortcuts - var data = this._data; - var dataWords = data.words; - - var nBitsTotal = this._nDataBytes * 8; - var nBitsLeft = data.sigBytes * 8; - - // Add padding - dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); - dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); - dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; - data.sigBytes = dataWords.length * 4; - - // Hash final blocks - this._process(); - - // Return final computed hash - return this._hash; - }, - - clone: function () { - var clone = Hasher.clone.call(this); - clone._hash = this._hash.clone(); - - return clone; - } - }); - - /** - * Shortcut function to the hasher's object interface. - * - * @param {WordArray|string} message The message to hash. - * - * @return {WordArray} The hash. - * - * @static - * - * @example - * - * var hash = CryptoJS.SHA256('message'); - * var hash = CryptoJS.SHA256(wordArray); - */ - C.SHA256 = Hasher._createHelper(SHA256); - - /** - * Shortcut function to the HMAC's object interface. - * - * @param {WordArray|string} message The message to hash. - * @param {WordArray|string} key The secret key. - * - * @return {WordArray} The HMAC. - * - * @static - * - * @example - * - * var hmac = CryptoJS.HmacSHA256(message, key); - */ - C.HmacSHA256 = Hasher._createHmacHelper(SHA256); -}(Math)); - -/* -CryptoJS v3.1.2 -code.google.com/p/crypto-js -(c) 2009-2013 by Jeff Mott. All rights reserved. -code.google.com/p/crypto-js/wiki/License -*/ -(function (undefined) { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var Base = C_lib.Base; - var X32WordArray = C_lib.WordArray; - - /** - * x64 namespace. - */ - var C_x64 = C.x64 = {}; - - /** - * A 64-bit word. - */ - var X64Word = C_x64.Word = Base.extend({ - /** - * Initializes a newly created 64-bit word. - * - * @param {number} high The high 32 bits. - * @param {number} low The low 32 bits. - * - * @example - * - * var x64Word = CryptoJS.x64.Word.create(0x00010203, 0x04050607); - */ - init: function (high, low) { - this.high = high; - this.low = low; - } - - /** - * Bitwise NOTs this word. - * - * @return {X64Word} A new x64-Word object after negating. - * - * @example - * - * var negated = x64Word.not(); - */ - // not: function () { - // var high = ~this.high; - // var low = ~this.low; - - // return X64Word.create(high, low); - // }, - - /** - * Bitwise ANDs this word with the passed word. - * - * @param {X64Word} word The x64-Word to AND with this word. - * - * @return {X64Word} A new x64-Word object after ANDing. - * - * @example - * - * var anded = x64Word.and(anotherX64Word); - */ - // and: function (word) { - // var high = this.high & word.high; - // var low = this.low & word.low; - - // return X64Word.create(high, low); - // }, - - /** - * Bitwise ORs this word with the passed word. - * - * @param {X64Word} word The x64-Word to OR with this word. - * - * @return {X64Word} A new x64-Word object after ORing. - * - * @example - * - * var ored = x64Word.or(anotherX64Word); - */ - // or: function (word) { - // var high = this.high | word.high; - // var low = this.low | word.low; - - // return X64Word.create(high, low); - // }, - - /** - * Bitwise XORs this word with the passed word. - * - * @param {X64Word} word The x64-Word to XOR with this word. - * - * @return {X64Word} A new x64-Word object after XORing. - * - * @example - * - * var xored = x64Word.xor(anotherX64Word); - */ - // xor: function (word) { - // var high = this.high ^ word.high; - // var low = this.low ^ word.low; - - // return X64Word.create(high, low); - // }, - - /** - * Shifts this word n bits to the left. - * - * @param {number} n The number of bits to shift. - * - * @return {X64Word} A new x64-Word object after shifting. - * - * @example - * - * var shifted = x64Word.shiftL(25); - */ - // shiftL: function (n) { - // if (n < 32) { - // var high = (this.high << n) | (this.low >>> (32 - n)); - // var low = this.low << n; - // } else { - // var high = this.low << (n - 32); - // var low = 0; - // } - - // return X64Word.create(high, low); - // }, - - /** - * Shifts this word n bits to the right. - * - * @param {number} n The number of bits to shift. - * - * @return {X64Word} A new x64-Word object after shifting. - * - * @example - * - * var shifted = x64Word.shiftR(7); - */ - // shiftR: function (n) { - // if (n < 32) { - // var low = (this.low >>> n) | (this.high << (32 - n)); - // var high = this.high >>> n; - // } else { - // var low = this.high >>> (n - 32); - // var high = 0; - // } - - // return X64Word.create(high, low); - // }, - - /** - * Rotates this word n bits to the left. - * - * @param {number} n The number of bits to rotate. - * - * @return {X64Word} A new x64-Word object after rotating. - * - * @example - * - * var rotated = x64Word.rotL(25); - */ - // rotL: function (n) { - // return this.shiftL(n).or(this.shiftR(64 - n)); - // }, - - /** - * Rotates this word n bits to the right. - * - * @param {number} n The number of bits to rotate. - * - * @return {X64Word} A new x64-Word object after rotating. - * - * @example - * - * var rotated = x64Word.rotR(7); - */ - // rotR: function (n) { - // return this.shiftR(n).or(this.shiftL(64 - n)); - // }, - - /** - * Adds this word with the passed word. - * - * @param {X64Word} word The x64-Word to add with this word. - * - * @return {X64Word} A new x64-Word object after adding. - * - * @example - * - * var added = x64Word.add(anotherX64Word); - */ - // add: function (word) { - // var low = (this.low + word.low) | 0; - // var carry = (low >>> 0) < (this.low >>> 0) ? 1 : 0; - // var high = (this.high + word.high + carry) | 0; - - // return X64Word.create(high, low); - // } - }); - - /** - * An array of 64-bit words. - * - * @property {Array} words The array of CryptoJS.x64.Word objects. - * @property {number} sigBytes The number of significant bytes in this word array. - */ - var X64WordArray = C_x64.WordArray = Base.extend({ - /** - * Initializes a newly created word array. - * - * @param {Array} words (Optional) An array of CryptoJS.x64.Word objects. - * @param {number} sigBytes (Optional) The number of significant bytes in the words. - * - * @example - * - * var wordArray = CryptoJS.x64.WordArray.create(); - * - * var wordArray = CryptoJS.x64.WordArray.create([ - * CryptoJS.x64.Word.create(0x00010203, 0x04050607), - * CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f) - * ]); - * - * var wordArray = CryptoJS.x64.WordArray.create([ - * CryptoJS.x64.Word.create(0x00010203, 0x04050607), - * CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f) - * ], 10); - */ - init: function (words, sigBytes) { - words = this.words = words || []; - - if (sigBytes != undefined) { - this.sigBytes = sigBytes; - } else { - this.sigBytes = words.length * 8; - } - }, - - /** - * Converts this 64-bit word array to a 32-bit word array. - * - * @return {CryptoJS.lib.WordArray} This word array's data as a 32-bit word array. - * - * @example - * - * var x32WordArray = x64WordArray.toX32(); - */ - toX32: function () { - // Shortcuts - var x64Words = this.words; - var x64WordsLength = x64Words.length; - - // Convert - var x32Words = []; - for (var i = 0; i < x64WordsLength; i++) { - var x64Word = x64Words[i]; - x32Words.push(x64Word.high); - x32Words.push(x64Word.low); - } - - return X32WordArray.create(x32Words, this.sigBytes); - }, - - /** - * Creates a copy of this word array. - * - * @return {X64WordArray} The clone. - * - * @example - * - * var clone = x64WordArray.clone(); - */ - clone: function () { - var clone = Base.clone.call(this); - - // Clone "words" array - var words = clone.words = this.words.slice(0); - - // Clone each X64Word object - var wordsLength = words.length; - for (var i = 0; i < wordsLength; i++) { - words[i] = words[i].clone(); - } - - return clone; - } - }); -}()); -/* -CryptoJS v3.1.2 -code.google.com/p/crypto-js -(c) 2009-2013 by Jeff Mott. All rights reserved. -code.google.com/p/crypto-js/wiki/License -*/ -(function () { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var Hasher = C_lib.Hasher; - var C_x64 = C.x64; - var X64Word = C_x64.Word; - var X64WordArray = C_x64.WordArray; - var C_algo = C.algo; - - function X64Word_create() { - return X64Word.create.apply(X64Word, arguments); - } - - // Constants - var K = [ - X64Word_create(0x428a2f98, 0xd728ae22), X64Word_create(0x71374491, 0x23ef65cd), - X64Word_create(0xb5c0fbcf, 0xec4d3b2f), X64Word_create(0xe9b5dba5, 0x8189dbbc), - X64Word_create(0x3956c25b, 0xf348b538), X64Word_create(0x59f111f1, 0xb605d019), - X64Word_create(0x923f82a4, 0xaf194f9b), X64Word_create(0xab1c5ed5, 0xda6d8118), - X64Word_create(0xd807aa98, 0xa3030242), X64Word_create(0x12835b01, 0x45706fbe), - X64Word_create(0x243185be, 0x4ee4b28c), X64Word_create(0x550c7dc3, 0xd5ffb4e2), - X64Word_create(0x72be5d74, 0xf27b896f), X64Word_create(0x80deb1fe, 0x3b1696b1), - X64Word_create(0x9bdc06a7, 0x25c71235), X64Word_create(0xc19bf174, 0xcf692694), - X64Word_create(0xe49b69c1, 0x9ef14ad2), X64Word_create(0xefbe4786, 0x384f25e3), - X64Word_create(0x0fc19dc6, 0x8b8cd5b5), X64Word_create(0x240ca1cc, 0x77ac9c65), - X64Word_create(0x2de92c6f, 0x592b0275), X64Word_create(0x4a7484aa, 0x6ea6e483), - X64Word_create(0x5cb0a9dc, 0xbd41fbd4), X64Word_create(0x76f988da, 0x831153b5), - X64Word_create(0x983e5152, 0xee66dfab), X64Word_create(0xa831c66d, 0x2db43210), - X64Word_create(0xb00327c8, 0x98fb213f), X64Word_create(0xbf597fc7, 0xbeef0ee4), - X64Word_create(0xc6e00bf3, 0x3da88fc2), X64Word_create(0xd5a79147, 0x930aa725), - X64Word_create(0x06ca6351, 0xe003826f), X64Word_create(0x14292967, 0x0a0e6e70), - X64Word_create(0x27b70a85, 0x46d22ffc), X64Word_create(0x2e1b2138, 0x5c26c926), - X64Word_create(0x4d2c6dfc, 0x5ac42aed), X64Word_create(0x53380d13, 0x9d95b3df), - X64Word_create(0x650a7354, 0x8baf63de), X64Word_create(0x766a0abb, 0x3c77b2a8), - X64Word_create(0x81c2c92e, 0x47edaee6), X64Word_create(0x92722c85, 0x1482353b), - X64Word_create(0xa2bfe8a1, 0x4cf10364), X64Word_create(0xa81a664b, 0xbc423001), - X64Word_create(0xc24b8b70, 0xd0f89791), X64Word_create(0xc76c51a3, 0x0654be30), - X64Word_create(0xd192e819, 0xd6ef5218), X64Word_create(0xd6990624, 0x5565a910), - X64Word_create(0xf40e3585, 0x5771202a), X64Word_create(0x106aa070, 0x32bbd1b8), - X64Word_create(0x19a4c116, 0xb8d2d0c8), X64Word_create(0x1e376c08, 0x5141ab53), - X64Word_create(0x2748774c, 0xdf8eeb99), X64Word_create(0x34b0bcb5, 0xe19b48a8), - X64Word_create(0x391c0cb3, 0xc5c95a63), X64Word_create(0x4ed8aa4a, 0xe3418acb), - X64Word_create(0x5b9cca4f, 0x7763e373), X64Word_create(0x682e6ff3, 0xd6b2b8a3), - X64Word_create(0x748f82ee, 0x5defb2fc), X64Word_create(0x78a5636f, 0x43172f60), - X64Word_create(0x84c87814, 0xa1f0ab72), X64Word_create(0x8cc70208, 0x1a6439ec), - X64Word_create(0x90befffa, 0x23631e28), X64Word_create(0xa4506ceb, 0xde82bde9), - X64Word_create(0xbef9a3f7, 0xb2c67915), X64Word_create(0xc67178f2, 0xe372532b), - X64Word_create(0xca273ece, 0xea26619c), X64Word_create(0xd186b8c7, 0x21c0c207), - X64Word_create(0xeada7dd6, 0xcde0eb1e), X64Word_create(0xf57d4f7f, 0xee6ed178), - X64Word_create(0x06f067aa, 0x72176fba), X64Word_create(0x0a637dc5, 0xa2c898a6), - X64Word_create(0x113f9804, 0xbef90dae), X64Word_create(0x1b710b35, 0x131c471b), - X64Word_create(0x28db77f5, 0x23047d84), X64Word_create(0x32caab7b, 0x40c72493), - X64Word_create(0x3c9ebe0a, 0x15c9bebc), X64Word_create(0x431d67c4, 0x9c100d4c), - X64Word_create(0x4cc5d4be, 0xcb3e42b6), X64Word_create(0x597f299c, 0xfc657e2a), - X64Word_create(0x5fcb6fab, 0x3ad6faec), X64Word_create(0x6c44198c, 0x4a475817) - ]; - - // Reusable objects - var W = []; - (function () { - for (var i = 0; i < 80; i++) { - W[i] = X64Word_create(); - } - }()); - - /** - * SHA-512 hash algorithm. - */ - var SHA512 = C_algo.SHA512 = Hasher.extend({ - _doReset: function () { - this._hash = new X64WordArray.init([ - new X64Word.init(0x6a09e667, 0xf3bcc908), new X64Word.init(0xbb67ae85, 0x84caa73b), - new X64Word.init(0x3c6ef372, 0xfe94f82b), new X64Word.init(0xa54ff53a, 0x5f1d36f1), - new X64Word.init(0x510e527f, 0xade682d1), new X64Word.init(0x9b05688c, 0x2b3e6c1f), - new X64Word.init(0x1f83d9ab, 0xfb41bd6b), new X64Word.init(0x5be0cd19, 0x137e2179) - ]); - }, - - _doProcessBlock: function (M, offset) { - // Shortcuts - var H = this._hash.words; - - var H0 = H[0]; - var H1 = H[1]; - var H2 = H[2]; - var H3 = H[3]; - var H4 = H[4]; - var H5 = H[5]; - var H6 = H[6]; - var H7 = H[7]; - - var H0h = H0.high; - var H0l = H0.low; - var H1h = H1.high; - var H1l = H1.low; - var H2h = H2.high; - var H2l = H2.low; - var H3h = H3.high; - var H3l = H3.low; - var H4h = H4.high; - var H4l = H4.low; - var H5h = H5.high; - var H5l = H5.low; - var H6h = H6.high; - var H6l = H6.low; - var H7h = H7.high; - var H7l = H7.low; - - // Working variables - var ah = H0h; - var al = H0l; - var bh = H1h; - var bl = H1l; - var ch = H2h; - var cl = H2l; - var dh = H3h; - var dl = H3l; - var eh = H4h; - var el = H4l; - var fh = H5h; - var fl = H5l; - var gh = H6h; - var gl = H6l; - var hh = H7h; - var hl = H7l; - - // Rounds - for (var i = 0; i < 80; i++) { - // Shortcut - var Wi = W[i]; - - // Extend message - if (i < 16) { - var Wih = Wi.high = M[offset + i * 2] | 0; - var Wil = Wi.low = M[offset + i * 2 + 1] | 0; - } else { - // Gamma0 - var gamma0x = W[i - 15]; - var gamma0xh = gamma0x.high; - var gamma0xl = gamma0x.low; - var gamma0h = ((gamma0xh >>> 1) | (gamma0xl << 31)) ^ ((gamma0xh >>> 8) | (gamma0xl << 24)) ^ (gamma0xh >>> 7); - var gamma0l = ((gamma0xl >>> 1) | (gamma0xh << 31)) ^ ((gamma0xl >>> 8) | (gamma0xh << 24)) ^ ((gamma0xl >>> 7) | (gamma0xh << 25)); - - // Gamma1 - var gamma1x = W[i - 2]; - var gamma1xh = gamma1x.high; - var gamma1xl = gamma1x.low; - var gamma1h = ((gamma1xh >>> 19) | (gamma1xl << 13)) ^ ((gamma1xh << 3) | (gamma1xl >>> 29)) ^ (gamma1xh >>> 6); - var gamma1l = ((gamma1xl >>> 19) | (gamma1xh << 13)) ^ ((gamma1xl << 3) | (gamma1xh >>> 29)) ^ ((gamma1xl >>> 6) | (gamma1xh << 26)); - - // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] - var Wi7 = W[i - 7]; - var Wi7h = Wi7.high; - var Wi7l = Wi7.low; - - var Wi16 = W[i - 16]; - var Wi16h = Wi16.high; - var Wi16l = Wi16.low; - - var Wil = gamma0l + Wi7l; - var Wih = gamma0h + Wi7h + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0); - var Wil = Wil + gamma1l; - var Wih = Wih + gamma1h + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0); - var Wil = Wil + Wi16l; - var Wih = Wih + Wi16h + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0); - - Wi.high = Wih; - Wi.low = Wil; - } - - var chh = (eh & fh) ^ (~eh & gh); - var chl = (el & fl) ^ (~el & gl); - var majh = (ah & bh) ^ (ah & ch) ^ (bh & ch); - var majl = (al & bl) ^ (al & cl) ^ (bl & cl); - - var sigma0h = ((ah >>> 28) | (al << 4)) ^ ((ah << 30) | (al >>> 2)) ^ ((ah << 25) | (al >>> 7)); - var sigma0l = ((al >>> 28) | (ah << 4)) ^ ((al << 30) | (ah >>> 2)) ^ ((al << 25) | (ah >>> 7)); - var sigma1h = ((eh >>> 14) | (el << 18)) ^ ((eh >>> 18) | (el << 14)) ^ ((eh << 23) | (el >>> 9)); - var sigma1l = ((el >>> 14) | (eh << 18)) ^ ((el >>> 18) | (eh << 14)) ^ ((el << 23) | (eh >>> 9)); - - // t1 = h + sigma1 + ch + K[i] + W[i] - var Ki = K[i]; - var Kih = Ki.high; - var Kil = Ki.low; - - var t1l = hl + sigma1l; - var t1h = hh + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0); - var t1l = t1l + chl; - var t1h = t1h + chh + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0); - var t1l = t1l + Kil; - var t1h = t1h + Kih + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0); - var t1l = t1l + Wil; - var t1h = t1h + Wih + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0); - - // t2 = sigma0 + maj - var t2l = sigma0l + majl; - var t2h = sigma0h + majh + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0); - - // Update working variables - hh = gh; - hl = gl; - gh = fh; - gl = fl; - fh = eh; - fl = el; - el = (dl + t1l) | 0; - eh = (dh + t1h + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0; - dh = ch; - dl = cl; - ch = bh; - cl = bl; - bh = ah; - bl = al; - al = (t1l + t2l) | 0; - ah = (t1h + t2h + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0; - } - - // Intermediate hash value - H0l = H0.low = (H0l + al); - H0.high = (H0h + ah + ((H0l >>> 0) < (al >>> 0) ? 1 : 0)); - H1l = H1.low = (H1l + bl); - H1.high = (H1h + bh + ((H1l >>> 0) < (bl >>> 0) ? 1 : 0)); - H2l = H2.low = (H2l + cl); - H2.high = (H2h + ch + ((H2l >>> 0) < (cl >>> 0) ? 1 : 0)); - H3l = H3.low = (H3l + dl); - H3.high = (H3h + dh + ((H3l >>> 0) < (dl >>> 0) ? 1 : 0)); - H4l = H4.low = (H4l + el); - H4.high = (H4h + eh + ((H4l >>> 0) < (el >>> 0) ? 1 : 0)); - H5l = H5.low = (H5l + fl); - H5.high = (H5h + fh + ((H5l >>> 0) < (fl >>> 0) ? 1 : 0)); - H6l = H6.low = (H6l + gl); - H6.high = (H6h + gh + ((H6l >>> 0) < (gl >>> 0) ? 1 : 0)); - H7l = H7.low = (H7l + hl); - H7.high = (H7h + hh + ((H7l >>> 0) < (hl >>> 0) ? 1 : 0)); - }, - - _doFinalize: function () { - // Shortcuts - var data = this._data; - var dataWords = data.words; - - var nBitsTotal = this._nDataBytes * 8; - var nBitsLeft = data.sigBytes * 8; - - // Add padding - dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); - dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 30] = Math.floor(nBitsTotal / 0x100000000); - dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 31] = nBitsTotal; - data.sigBytes = dataWords.length * 4; - - // Hash final blocks - this._process(); - - // Convert hash to 32-bit word array before returning - var hash = this._hash.toX32(); - - // Return final computed hash - return hash; - }, - - clone: function () { - var clone = Hasher.clone.call(this); - clone._hash = this._hash.clone(); - - return clone; - }, - - blockSize: 1024/32 - }); - - /** - * Shortcut function to the hasher's object interface. - * - * @param {WordArray|string} message The message to hash. - * - * @return {WordArray} The hash. - * - * @static - * - * @example - * - * var hash = CryptoJS.SHA512('message'); - * var hash = CryptoJS.SHA512(wordArray); - */ - C.SHA512 = Hasher._createHelper(SHA512); - - /** - * Shortcut function to the HMAC's object interface. - * - * @param {WordArray|string} message The message to hash. - * @param {WordArray|string} key The secret key. - * - * @return {WordArray} The HMAC. - * - * @static - * - * @example - * - * var hmac = CryptoJS.HmacSHA512(message, key); - */ - C.HmacSHA512 = Hasher._createHmacHelper(SHA512); -}()); - - -/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/ - */ -var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -var b64pad="="; - -function hex2b64(h) { - var i; - var c; - var ret = ""; - for(i = 0; i+3 <= h.length; i+=3) { - c = parseInt(h.substring(i,i+3),16); - ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); - } - if(i+1 == h.length) { - c = parseInt(h.substring(i,i+1),16); - ret += b64map.charAt(c << 2); - } - else if(i+2 == h.length) { - c = parseInt(h.substring(i,i+2),16); - ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); - } - if (b64pad) while((ret.length & 3) > 0) ret += b64pad; - return ret; -} - -// convert a base64 string to hex -function b64tohex(s) { - var ret = "" - var i; - var k = 0; // b64 state, 0-3 - var slop; - var v; - for(i = 0; i < s.length; ++i) { - if(s.charAt(i) == b64pad) break; - v = b64map.indexOf(s.charAt(i)); - if(v < 0) continue; - if(k == 0) { - ret += int2char(v >> 2); - slop = v & 3; - k = 1; - } - else if(k == 1) { - ret += int2char((slop << 2) | (v >> 4)); - slop = v & 0xf; - k = 2; - } - else if(k == 2) { - ret += int2char(slop); - ret += int2char(v >> 2); - slop = v & 3; - k = 3; - } - else { - ret += int2char((slop << 2) | (v >> 4)); - ret += int2char(v & 0xf); - k = 0; - } - } - if(k == 1) - ret += int2char(slop << 2); - return ret; -} - -// convert a base64 string to a byte/number array -function b64toBA(s) { - //piggyback on b64tohex for now, optimize later - var h = b64tohex(s); - var i; - var a = new Array(); - for(i = 0; 2*i < h.length; ++i) { - a[i] = parseInt(h.substring(2*i,2*i+2),16); - } - return a; -} -/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/ - */ -// Copyright (c) 2005 Tom Wu -// All Rights Reserved. -// See "LICENSE" for details. - -// Basic JavaScript BN library - subset useful for RSA encryption. - -// Bits per digit -var dbits; - -// JavaScript engine analysis -var canary = 0xdeadbeefcafe; -var j_lm = ((canary&0xffffff)==0xefcafe); - -// (public) Constructor -function BigInteger(a,b,c) { - if(a != null) - if("number" == typeof a) this.fromNumber(a,b,c); - else if(b == null && "string" != typeof a) this.fromString(a,256); - else this.fromString(a,b); -} - -// return new, unset BigInteger -function nbi() { return new BigInteger(null); } - -// am: Compute w_j += (x*this_i), propagate carries, -// c is initial carry, returns final carry. -// c < 3*dvalue, x < 2*dvalue, this_i < dvalue -// We need to select the fastest one that works in this environment. - -// am1: use a single mult and divide to get the high bits, -// max digit bits should be 26 because -// max internal value = 2*dvalue^2-2*dvalue (< 2^53) -function am1(i,x,w,j,c,n) { - while(--n >= 0) { - var v = x*this[i++]+w[j]+c; - c = Math.floor(v/0x4000000); - w[j++] = v&0x3ffffff; - } - return c; -} -// am2 avoids a big mult-and-extract completely. -// Max digit bits should be <= 30 because we do bitwise ops -// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) -function am2(i,x,w,j,c,n) { - var xl = x&0x7fff, xh = x>>15; - while(--n >= 0) { - var l = this[i]&0x7fff; - var h = this[i++]>>15; - var m = xh*l+h*xl; - l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); - c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); - w[j++] = l&0x3fffffff; - } - return c; -} -// Alternately, set max digit bits to 28 since some -// browsers slow down when dealing with 32-bit numbers. -function am3(i,x,w,j,c,n) { - var xl = x&0x3fff, xh = x>>14; - while(--n >= 0) { - var l = this[i]&0x3fff; - var h = this[i++]>>14; - var m = xh*l+h*xl; - l = xl*l+((m&0x3fff)<<14)+w[j]+c; - c = (l>>28)+(m>>14)+xh*h; - w[j++] = l&0xfffffff; - } - return c; -} -if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { - BigInteger.prototype.am = am2; - dbits = 30; -} -else if(j_lm && (navigator.appName != "Netscape")) { - BigInteger.prototype.am = am1; - dbits = 26; -} -else { // Mozilla/Netscape seems to prefer am3 - BigInteger.prototype.am = am3; - dbits = 28; -} - -BigInteger.prototype.DB = dbits; -BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; - r.t = this.t; - r.s = this.s; -} - -// (protected) set from integer value x, -DV <= x < DV -function bnpFromInt(x) { - this.t = 1; - this.s = (x<0)?-1:0; - if(x > 0) this[0] = x; - else if(x < -1) this[0] = x+this.DV; - else this.t = 0; -} - -// return bigint initialized to value -function nbv(i) { var r = nbi(); r.fromInt(i); return r; } - -// (protected) set from string and radix -function bnpFromString(s,b) { - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 256) k = 8; // byte array - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else { this.fromRadix(s,b); return; } - this.t = 0; - this.s = 0; - var i = s.length, mi = false, sh = 0; - while(--i >= 0) { - var x = (k==8)?s[i]&0xff:intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-") mi = true; - continue; - } - mi = false; - if(sh == 0) - this[this.t++] = x; - else if(sh+k > this.DB) { - this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); - } - else - this[this.t-1] |= x<= this.DB) sh -= this.DB; - } - if(k == 8 && (s[0]&0x80) != 0) { - this.s = -1; - if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; -} - -// (public) return string representation in given radix -function bnToString(b) { - if(this.s < 0) return "-"+this.negate().toString(b); - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else return this.toRadix(b); - var km = (1< 0) { - if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } - while(i >= 0) { - if(p < k) { - d = (this[i]&((1<>(p+=this.DB-k); - } - else { - d = (this[i]>>(p-=k))&km; - if(p <= 0) { p += this.DB; --i; } - } - if(d > 0) m = true; - if(m) r += int2char(d); - } - } - return m?r:"0"; -} - -// (public) -this -function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } - -// (public) |this| -function bnAbs() { return (this.s<0)?this.negate():this; } - -// (public) return + if this > a, - if this < a, 0 if equal -function bnCompareTo(a) { - var r = this.s-a.s; - if(r != 0) return r; - var i = this.t; - r = i-a.t; - if(r != 0) return (this.s<0)?-r:r; - while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; - return 0; -} - -// returns bit length of the integer x -function nbits(x) { - var r = 1, t; - if((t=x>>>16) != 0) { x = t; r += 16; } - if((t=x>>8) != 0) { x = t; r += 8; } - if((t=x>>4) != 0) { x = t; r += 4; } - if((t=x>>2) != 0) { x = t; r += 2; } - if((t=x>>1) != 0) { x = t; r += 1; } - return r; -} - -// (public) return the number of bits in "this" -function bnBitLength() { - if(this.t <= 0) return 0; - return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); -} - -// (protected) r = this << n*DB -function bnpDLShiftTo(n,r) { - var i; - for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; - for(i = n-1; i >= 0; --i) r[i] = 0; - r.t = this.t+n; - r.s = this.s; -} - -// (protected) r = this >> n*DB -function bnpDRShiftTo(n,r) { - for(var i = n; i < this.t; ++i) r[i-n] = this[i]; - r.t = Math.max(this.t-n,0); - r.s = this.s; -} - -// (protected) r = this << n -function bnpLShiftTo(n,r) { - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<= 0; --i) { - r[i+ds+1] = (this[i]>>cbs)|c; - c = (this[i]&bm)<= 0; --i) r[i] = 0; - r[ds] = c; - r.t = this.t+ds+1; - r.s = this.s; - r.clamp(); -} - -// (protected) r = this >> n -function bnpRShiftTo(n,r) { - r.s = this.s; - var ds = Math.floor(n/this.DB); - if(ds >= this.t) { r.t = 0; return; } - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<>bs; - for(var i = ds+1; i < this.t; ++i) { - r[i-ds-1] |= (this[i]&bm)<>bs; - } - if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; - } - if(a.t < this.t) { - c -= a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c -= a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c -= a.s; - } - r.s = (c<0)?-1:0; - if(c < -1) r[i++] = this.DV+c; - else if(c > 0) r[i++] = c; - r.t = i; - r.clamp(); -} - -// (protected) r = this * a, r != this,a (HAC 14.12) -// "this" should be the larger one if appropriate. -function bnpMultiplyTo(a,r) { - var x = this.abs(), y = a.abs(); - var i = x.t; - r.t = i+y.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); - r.s = 0; - r.clamp(); - if(this.s != a.s) BigInteger.ZERO.subTo(r,r); -} - -// (protected) r = this^2, r != this (HAC 14.16) -function bnpSquareTo(r) { - var x = this.abs(); - var i = r.t = 2*x.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < x.t-1; ++i) { - var c = x.am(i,x[i],r,2*i,0,1); - if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { - r[i+x.t] -= x.DV; - r[i+x.t+1] = 1; - } - } - if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); - r.s = 0; - r.clamp(); -} - -// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) -// r != q, this != m. q or r may be null. -function bnpDivRemTo(m,q,r) { - var pm = m.abs(); - if(pm.t <= 0) return; - var pt = this.abs(); - if(pt.t < pm.t) { - if(q != null) q.fromInt(0); - if(r != null) this.copyTo(r); - return; - } - if(r == null) r = nbi(); - var y = nbi(), ts = this.s, ms = m.s; - var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus - if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } - else { pm.copyTo(y); pt.copyTo(r); } - var ys = y.t; - var y0 = y[ys-1]; - if(y0 == 0) return; - var yt = y0*(1<1)?y[ys-2]>>this.F2:0); - var d1 = this.FV/yt, d2 = (1<= 0) { - r[r.t++] = 1; - r.subTo(t,r); - } - BigInteger.ONE.dlShiftTo(ys,t); - t.subTo(y,y); // "negative" y so we can replace sub with am later - while(y.t < ys) y[y.t++] = 0; - while(--j >= 0) { - // Estimate quotient digit - var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); - if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out - y.dlShiftTo(j,t); - r.subTo(t,r); - while(r[i] < --qd) r.subTo(t,r); - } - } - if(q != null) { - r.drShiftTo(ys,q); - if(ts != ms) BigInteger.ZERO.subTo(q,q); - } - r.t = ys; - r.clamp(); - if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder - if(ts < 0) BigInteger.ZERO.subTo(r,r); -} - -// (public) this mod a -function bnMod(a) { - var r = nbi(); - this.abs().divRemTo(a,null,r); - if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); - return r; -} - -// Modular reduction using "classic" algorithm -function Classic(m) { this.m = m; } -function cConvert(x) { - if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); - else return x; -} -function cRevert(x) { return x; } -function cReduce(x) { x.divRemTo(this.m,null,x); } -function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } -function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -Classic.prototype.convert = cConvert; -Classic.prototype.revert = cRevert; -Classic.prototype.reduce = cReduce; -Classic.prototype.mulTo = cMulTo; -Classic.prototype.sqrTo = cSqrTo; - -// (protected) return "-1/this % 2^DB"; useful for Mont. reduction -// justification: -// xy == 1 (mod m) -// xy = 1+km -// xy(2-xy) = (1+km)(1-km) -// x[y(2-xy)] = 1-k^2m^2 -// x[y(2-xy)] == 1 (mod m^2) -// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 -// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. -// JS multiply "overflows" differently from C/C++, so care is needed here. -function bnpInvDigit() { - if(this.t < 1) return 0; - var x = this[0]; - if((x&1) == 0) return 0; - var y = x&3; // y == 1/x mod 2^2 - y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 - y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 - y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 - // last step - calculate inverse mod DV directly; - // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints - y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits - // we really want the negative inverse, and -DV < y < DV - return (y>0)?this.DV-y:-y; -} - -// Montgomery reduction -function Montgomery(m) { - this.m = m; - this.mp = m.invDigit(); - this.mpl = this.mp&0x7fff; - this.mph = this.mp>>15; - this.um = (1<<(m.DB-15))-1; - this.mt2 = 2*m.t; -} - -// xR mod m -function montConvert(x) { - var r = nbi(); - x.abs().dlShiftTo(this.m.t,r); - r.divRemTo(this.m,null,r); - if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); - return r; -} - -// x/R mod m -function montRevert(x) { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; -} - -// x = x/R mod m (HAC 14.32) -function montReduce(x) { - while(x.t <= this.mt2) // pad x so am has enough room later - x[x.t++] = 0; - for(var i = 0; i < this.m.t; ++i) { - // faster way of calculating u0 = x[i]*mp mod DV - var j = x[i]&0x7fff; - var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; - // use am to combine the multiply-shift-add into one call - j = i+this.m.t; - x[j] += this.m.am(0,u0,x,i,0,this.m.t); - // propagate carry - while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } - } - x.clamp(); - x.drShiftTo(this.m.t,x); - if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = "x^2/R mod m"; x != r -function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = "xy/R mod m"; x,y != r -function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Montgomery.prototype.convert = montConvert; -Montgomery.prototype.revert = montRevert; -Montgomery.prototype.reduce = montReduce; -Montgomery.prototype.mulTo = montMulTo; -Montgomery.prototype.sqrTo = montSqrTo; - -// (protected) true iff this is even -function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } - -// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) -function bnpExp(e,z) { - if(e > 0xffffffff || e < 1) return BigInteger.ONE; - var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; - g.copyTo(r); - while(--i >= 0) { - z.sqrTo(r,r2); - if((e&(1< 0) z.mulTo(r2,g,r); - else { var t = r; r = r2; r2 = t; } - } - return z.revert(r); -} - -// (public) this^e % m, 0 <= e < 2^32 -function bnModPowInt(e,m) { - var z; - if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); - return this.exp(e,z); -} - -// protected -BigInteger.prototype.copyTo = bnpCopyTo; -BigInteger.prototype.fromInt = bnpFromInt; -BigInteger.prototype.fromString = bnpFromString; -BigInteger.prototype.clamp = bnpClamp; -BigInteger.prototype.dlShiftTo = bnpDLShiftTo; -BigInteger.prototype.drShiftTo = bnpDRShiftTo; -BigInteger.prototype.lShiftTo = bnpLShiftTo; -BigInteger.prototype.rShiftTo = bnpRShiftTo; -BigInteger.prototype.subTo = bnpSubTo; -BigInteger.prototype.multiplyTo = bnpMultiplyTo; -BigInteger.prototype.squareTo = bnpSquareTo; -BigInteger.prototype.divRemTo = bnpDivRemTo; -BigInteger.prototype.invDigit = bnpInvDigit; -BigInteger.prototype.isEven = bnpIsEven; -BigInteger.prototype.exp = bnpExp; - -// public -BigInteger.prototype.toString = bnToString; -BigInteger.prototype.negate = bnNegate; -BigInteger.prototype.abs = bnAbs; -BigInteger.prototype.compareTo = bnCompareTo; -BigInteger.prototype.bitLength = bnBitLength; -BigInteger.prototype.mod = bnMod; -BigInteger.prototype.modPowInt = bnModPowInt; - -// "constants" -BigInteger.ZERO = nbv(0); -BigInteger.ONE = nbv(1); -/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/ - */ -// Copyright (c) 2005-2009 Tom Wu -// All Rights Reserved. -// See "LICENSE" for details. - -// Extended JavaScript BN functions, required for RSA private ops. - -// Version 1.1: new BigInteger("0", 10) returns "proper" zero -// Version 1.2: square() API, isProbablePrime fix - -// (public) -function bnClone() { var r = nbi(); this.copyTo(r); return r; } - -// (public) return value as integer -function bnIntValue() { - if(this.s < 0) { - if(this.t == 1) return this[0]-this.DV; - else if(this.t == 0) return -1; - } - else if(this.t == 1) return this[0]; - else if(this.t == 0) return 0; - // assumes 16 < DB < 32 - return ((this[1]&((1<<(32-this.DB))-1))<>24; } - -// (public) return value as short (assumes DB>=16) -function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } - -// (protected) return x s.t. r^x < DV -function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } - -// (public) 0 if this == 0, 1 if this > 0 -function bnSigNum() { - if(this.s < 0) return -1; - else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; - else return 1; -} - -// (protected) convert to radix string -function bnpToRadix(b) { - if(b == null) b = 10; - if(this.signum() == 0 || b < 2 || b > 36) return "0"; - var cs = this.chunkSize(b); - var a = Math.pow(b,cs); - var d = nbv(a), y = nbi(), z = nbi(), r = ""; - this.divRemTo(d,y,z); - while(y.signum() > 0) { - r = (a+z.intValue()).toString(b).substr(1) + r; - y.divRemTo(d,y,z); - } - return z.intValue().toString(b) + r; -} - -// (protected) convert from radix string -function bnpFromRadix(s,b) { - this.fromInt(0); - if(b == null) b = 10; - var cs = this.chunkSize(b); - var d = Math.pow(b,cs), mi = false, j = 0, w = 0; - for(var i = 0; i < s.length; ++i) { - var x = intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-" && this.signum() == 0) mi = true; - continue; - } - w = b*w+x; - if(++j >= cs) { - this.dMultiply(d); - this.dAddOffset(w,0); - j = 0; - w = 0; - } - } - if(j > 0) { - this.dMultiply(Math.pow(b,j)); - this.dAddOffset(w,0); - } - if(mi) BigInteger.ZERO.subTo(this,this); -} - -// (protected) alternate constructor -function bnpFromNumber(a,b,c) { - if("number" == typeof b) { - // new BigInteger(int,int,RNG) - if(a < 2) this.fromInt(1); - else { - this.fromNumber(a,c); - if(!this.testBit(a-1)) // force MSB set - this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); - if(this.isEven()) this.dAddOffset(1,0); // force odd - while(!this.isProbablePrime(b)) { - this.dAddOffset(2,0); - if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); - } - } - } - else { - // new BigInteger(int,RNG) - var x = new Array(), t = a&7; - x.length = (a>>3)+1; - b.nextBytes(x); - if(t > 0) x[0] &= ((1< 0) { - if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) - r[k++] = d|(this.s<<(this.DB-p)); - while(i >= 0) { - if(p < 8) { - d = (this[i]&((1<>(p+=this.DB-8); - } - else { - d = (this[i]>>(p-=8))&0xff; - if(p <= 0) { p += this.DB; --i; } - } - if((d&0x80) != 0) d |= -256; - if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; - if(k > 0 || d != this.s) r[k++] = d; - } - } - return r; -} - -function bnEquals(a) { return(this.compareTo(a)==0); } -function bnMin(a) { return(this.compareTo(a)<0)?this:a; } -function bnMax(a) { return(this.compareTo(a)>0)?this:a; } - -// (protected) r = this op a (bitwise) -function bnpBitwiseTo(a,op,r) { - var i, f, m = Math.min(a.t,this.t); - for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); - if(a.t < this.t) { - f = a.s&this.DM; - for(i = m; i < this.t; ++i) r[i] = op(this[i],f); - r.t = this.t; - } - else { - f = this.s&this.DM; - for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); - r.t = a.t; - } - r.s = op(this.s,a.s); - r.clamp(); -} - -// (public) this & a -function op_and(x,y) { return x&y; } -function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } - -// (public) this | a -function op_or(x,y) { return x|y; } -function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } - -// (public) this ^ a -function op_xor(x,y) { return x^y; } -function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } - -// (public) this & ~a -function op_andnot(x,y) { return x&~y; } -function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } - -// (public) ~this -function bnNot() { - var r = nbi(); - for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; - r.t = this.t; - r.s = ~this.s; - return r; -} - -// (public) this << n -function bnShiftLeft(n) { - var r = nbi(); - if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); - return r; -} - -// (public) this >> n -function bnShiftRight(n) { - var r = nbi(); - if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); - return r; -} - -// return index of lowest 1-bit in x, x < 2^31 -function lbit(x) { - if(x == 0) return -1; - var r = 0; - if((x&0xffff) == 0) { x >>= 16; r += 16; } - if((x&0xff) == 0) { x >>= 8; r += 8; } - if((x&0xf) == 0) { x >>= 4; r += 4; } - if((x&3) == 0) { x >>= 2; r += 2; } - if((x&1) == 0) ++r; - return r; -} - -// (public) returns index of lowest 1-bit (or -1 if none) -function bnGetLowestSetBit() { - for(var i = 0; i < this.t; ++i) - if(this[i] != 0) return i*this.DB+lbit(this[i]); - if(this.s < 0) return this.t*this.DB; - return -1; -} - -// return number of 1 bits in x -function cbit(x) { - var r = 0; - while(x != 0) { x &= x-1; ++r; } - return r; -} - -// (public) return number of set bits -function bnBitCount() { - var r = 0, x = this.s&this.DM; - for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); - return r; -} - -// (public) true iff nth bit is set -function bnTestBit(n) { - var j = Math.floor(n/this.DB); - if(j >= this.t) return(this.s!=0); - return((this[j]&(1<<(n%this.DB)))!=0); -} - -// (protected) this op (1<>= this.DB; - } - if(a.t < this.t) { - c += a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c += a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += a.s; - } - r.s = (c<0)?-1:0; - if(c > 0) r[i++] = c; - else if(c < -1) r[i++] = this.DV+c; - r.t = i; - r.clamp(); -} - -// (public) this + a -function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } - -// (public) this - a -function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } - -// (public) this * a -function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } - -// (public) this^2 -function bnSquare() { var r = nbi(); this.squareTo(r); return r; } - -// (public) this / a -function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } - -// (public) this % a -function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } - -// (public) [this/a,this%a] -function bnDivideAndRemainder(a) { - var q = nbi(), r = nbi(); - this.divRemTo(a,q,r); - return new Array(q,r); -} - -// (protected) this *= n, this >= 0, 1 < n < DV -function bnpDMultiply(n) { - this[this.t] = this.am(0,n-1,this,0,0,this.t); - ++this.t; - this.clamp(); -} - -// (protected) this += n << w words, this >= 0 -function bnpDAddOffset(n,w) { - if(n == 0) return; - while(this.t <= w) this[this.t++] = 0; - this[w] += n; - while(this[w] >= this.DV) { - this[w] -= this.DV; - if(++w >= this.t) this[this.t++] = 0; - ++this[w]; - } -} - -// A "null" reducer -function NullExp() {} -function nNop(x) { return x; } -function nMulTo(x,y,r) { x.multiplyTo(y,r); } -function nSqrTo(x,r) { x.squareTo(r); } - -NullExp.prototype.convert = nNop; -NullExp.prototype.revert = nNop; -NullExp.prototype.mulTo = nMulTo; -NullExp.prototype.sqrTo = nSqrTo; - -// (public) this^e -function bnPow(e) { return this.exp(e,new NullExp()); } - -// (protected) r = lower n words of "this * a", a.t <= n -// "this" should be the larger one if appropriate. -function bnpMultiplyLowerTo(a,n,r) { - var i = Math.min(this.t+a.t,n); - r.s = 0; // assumes a,this >= 0 - r.t = i; - while(i > 0) r[--i] = 0; - var j; - for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); - for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); - r.clamp(); -} - -// (protected) r = "this * a" without lower n words, n > 0 -// "this" should be the larger one if appropriate. -function bnpMultiplyUpperTo(a,n,r) { - --n; - var i = r.t = this.t+a.t-n; - r.s = 0; // assumes a,this >= 0 - while(--i >= 0) r[i] = 0; - for(i = Math.max(n-this.t,0); i < a.t; ++i) - r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); - r.clamp(); - r.drShiftTo(1,r); -} - -// Barrett modular reduction -function Barrett(m) { - // setup Barrett - this.r2 = nbi(); - this.q3 = nbi(); - BigInteger.ONE.dlShiftTo(2*m.t,this.r2); - this.mu = this.r2.divide(m); - this.m = m; -} - -function barrettConvert(x) { - if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); - else if(x.compareTo(this.m) < 0) return x; - else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } -} - -function barrettRevert(x) { return x; } - -// x = x mod m (HAC 14.42) -function barrettReduce(x) { - x.drShiftTo(this.m.t-1,this.r2); - if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } - this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); - this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); - while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); - x.subTo(this.r2,x); - while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = x^2 mod m; x != r -function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = x*y mod m; x,y != r -function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Barrett.prototype.convert = barrettConvert; -Barrett.prototype.revert = barrettRevert; -Barrett.prototype.reduce = barrettReduce; -Barrett.prototype.mulTo = barrettMulTo; -Barrett.prototype.sqrTo = barrettSqrTo; - -// (public) this^e % m (HAC 14.85) -function bnModPow(e,m) { - var i = e.bitLength(), k, r = nbv(1), z; - if(i <= 0) return r; - else if(i < 18) k = 1; - else if(i < 48) k = 3; - else if(i < 144) k = 4; - else if(i < 768) k = 5; - else k = 6; - if(i < 8) - z = new Classic(m); - else if(m.isEven()) - z = new Barrett(m); - else - z = new Montgomery(m); - - // precomputation - var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { - var g2 = nbi(); - z.sqrTo(g[1],g2); - while(n <= km) { - g[n] = nbi(); - z.mulTo(g2,g[n-2],g[n]); - n += 2; - } - } - - var j = e.t-1, w, is1 = true, r2 = nbi(), t; - i = nbits(e[j])-1; - while(j >= 0) { - if(i >= k1) w = (e[j]>>(i-k1))&km; - else { - w = (e[j]&((1<<(i+1))-1))<<(k1-i); - if(j > 0) w |= e[j-1]>>(this.DB+i-k1); - } - - n = k; - while((w&1) == 0) { w >>= 1; --n; } - if((i -= n) < 0) { i += this.DB; --j; } - if(is1) { // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r); - is1 = false; - } - else { - while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } - if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } - z.mulTo(r2,g[w],r); - } - - while(j >= 0 && (e[j]&(1< 0) { - x.rShiftTo(g,x); - y.rShiftTo(g,y); - } - while(x.signum() > 0) { - if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); - if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); - if(x.compareTo(y) >= 0) { - x.subTo(y,x); - x.rShiftTo(1,x); - } - else { - y.subTo(x,y); - y.rShiftTo(1,y); - } - } - if(g > 0) y.lShiftTo(g,y); - return y; -} - -// (protected) this % n, n < 2^26 -function bnpModInt(n) { - if(n <= 0) return 0; - var d = this.DV%n, r = (this.s<0)?n-1:0; - if(this.t > 0) - if(d == 0) r = this[0]%n; - else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; - return r; -} - -// (public) 1/this % m (HAC 14.61) -function bnModInverse(m) { - var ac = m.isEven(); - if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; - var u = m.clone(), v = this.clone(); - var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); - while(u.signum() != 0) { - while(u.isEven()) { - u.rShiftTo(1,u); - if(ac) { - if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } - a.rShiftTo(1,a); - } - else if(!b.isEven()) b.subTo(m,b); - b.rShiftTo(1,b); - } - while(v.isEven()) { - v.rShiftTo(1,v); - if(ac) { - if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } - c.rShiftTo(1,c); - } - else if(!d.isEven()) d.subTo(m,d); - d.rShiftTo(1,d); - } - if(u.compareTo(v) >= 0) { - u.subTo(v,u); - if(ac) a.subTo(c,a); - b.subTo(d,b); - } - else { - v.subTo(u,v); - if(ac) c.subTo(a,c); - d.subTo(b,d); - } - } - if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; - if(d.compareTo(m) >= 0) return d.subtract(m); - if(d.signum() < 0) d.addTo(m,d); else return d; - if(d.signum() < 0) return d.add(m); else return d; -} - -var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; -var lplim = (1<<26)/lowprimes[lowprimes.length-1]; - -// (public) test primality with certainty >= 1-.5^t -function bnIsProbablePrime(t) { - var i, x = this.abs(); - if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { - for(i = 0; i < lowprimes.length; ++i) - if(x[0] == lowprimes[i]) return true; - return false; - } - if(x.isEven()) return false; - i = 1; - while(i < lowprimes.length) { - var m = lowprimes[i], j = i+1; - while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; - m = x.modInt(m); - while(i < j) if(m%lowprimes[i++] == 0) return false; - } - return x.millerRabin(t); -} - -// (protected) true if probably prime (HAC 4.24, Miller-Rabin) -function bnpMillerRabin(t) { - var n1 = this.subtract(BigInteger.ONE); - var k = n1.getLowestSetBit(); - if(k <= 0) return false; - var r = n1.shiftRight(k); - t = (t+1)>>1; - if(t > lowprimes.length) t = lowprimes.length; - var a = nbi(); - for(var i = 0; i < t; ++i) { - //Pick bases at random, instead of starting at 2 - a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); - var y = a.modPow(r,this); - if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1; - while(j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2,this); - if(y.compareTo(BigInteger.ONE) == 0) return false; - } - if(y.compareTo(n1) != 0) return false; - } - } - return true; -} - -// protected -BigInteger.prototype.chunkSize = bnpChunkSize; -BigInteger.prototype.toRadix = bnpToRadix; -BigInteger.prototype.fromRadix = bnpFromRadix; -BigInteger.prototype.fromNumber = bnpFromNumber; -BigInteger.prototype.bitwiseTo = bnpBitwiseTo; -BigInteger.prototype.changeBit = bnpChangeBit; -BigInteger.prototype.addTo = bnpAddTo; -BigInteger.prototype.dMultiply = bnpDMultiply; -BigInteger.prototype.dAddOffset = bnpDAddOffset; -BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; -BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; -BigInteger.prototype.modInt = bnpModInt; -BigInteger.prototype.millerRabin = bnpMillerRabin; - -// public -BigInteger.prototype.clone = bnClone; -BigInteger.prototype.intValue = bnIntValue; -BigInteger.prototype.byteValue = bnByteValue; -BigInteger.prototype.shortValue = bnShortValue; -BigInteger.prototype.signum = bnSigNum; -BigInteger.prototype.toByteArray = bnToByteArray; -BigInteger.prototype.equals = bnEquals; -BigInteger.prototype.min = bnMin; -BigInteger.prototype.max = bnMax; -BigInteger.prototype.and = bnAnd; -BigInteger.prototype.or = bnOr; -BigInteger.prototype.xor = bnXor; -BigInteger.prototype.andNot = bnAndNot; -BigInteger.prototype.not = bnNot; -BigInteger.prototype.shiftLeft = bnShiftLeft; -BigInteger.prototype.shiftRight = bnShiftRight; -BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; -BigInteger.prototype.bitCount = bnBitCount; -BigInteger.prototype.testBit = bnTestBit; -BigInteger.prototype.setBit = bnSetBit; -BigInteger.prototype.clearBit = bnClearBit; -BigInteger.prototype.flipBit = bnFlipBit; -BigInteger.prototype.add = bnAdd; -BigInteger.prototype.subtract = bnSubtract; -BigInteger.prototype.multiply = bnMultiply; -BigInteger.prototype.divide = bnDivide; -BigInteger.prototype.remainder = bnRemainder; -BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; -BigInteger.prototype.modPow = bnModPow; -BigInteger.prototype.modInverse = bnModInverse; -BigInteger.prototype.pow = bnPow; -BigInteger.prototype.gcd = bnGCD; -BigInteger.prototype.isProbablePrime = bnIsProbablePrime; - -// JSBN-specific extension -BigInteger.prototype.square = bnSquare; - -// BigInteger interfaces not implemented in jsbn: - -// BigInteger(int signum, byte[] magnitude) -// double doubleValue() -// float floatValue() -// int hashCode() -// long longValue() -// static BigInteger valueOf(long val) -/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/ - */ -// Depends on jsbn.js and rng.js - -// Version 1.1: support utf-8 encoding in pkcs1pad2 - -// convert a (hex) string to a bignum object -function parseBigInt(str,r) { - return new BigInteger(str,r); -} - -function linebrk(s,n) { - var ret = ""; - var i = 0; - while(i + n < s.length) { - ret += s.substring(i,i+n) + "\n"; - i += n; - } - return ret + s.substring(i,s.length); -} - -function byte2Hex(b) { - if(b < 0x10) - return "0" + b.toString(16); - else - return b.toString(16); -} - -// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint -function pkcs1pad2(s,n) { - if(n < s.length + 11) { // TODO: fix for utf-8 - alert("Message too long for RSA"); - return null; - } - var ba = new Array(); - var i = s.length - 1; - while(i >= 0 && n > 0) { - var c = s.charCodeAt(i--); - if(c < 128) { // encode using utf-8 - ba[--n] = c; - } - else if((c > 127) && (c < 2048)) { - ba[--n] = (c & 63) | 128; - ba[--n] = (c >> 6) | 192; - } - else { - ba[--n] = (c & 63) | 128; - ba[--n] = ((c >> 6) & 63) | 128; - ba[--n] = (c >> 12) | 224; - } - } - ba[--n] = 0; - var rng = new SecureRandom(); - var x = new Array(); - while(n > 2) { // random non-zero pad - x[0] = 0; - while(x[0] == 0) rng.nextBytes(x); - ba[--n] = x[0]; - } - ba[--n] = 2; - ba[--n] = 0; - return new BigInteger(ba); -} - -// PKCS#1 (OAEP) mask generation function -function oaep_mgf1_arr(seed, len, hash) -{ - var mask = '', i = 0; - - while (mask.length < len) - { - mask += hash(String.fromCharCode.apply(String, seed.concat([ - (i & 0xff000000) >> 24, - (i & 0x00ff0000) >> 16, - (i & 0x0000ff00) >> 8, - i & 0x000000ff]))); - i += 1; - } - - return mask; -} - -var SHA1_SIZE = 20; - -// PKCS#1 (OAEP) pad input string s to n bytes, and return a bigint -function oaep_pad(s, n, hash) -{ - if (s.length + 2 * SHA1_SIZE + 2 > n) - { - throw "Message too long for RSA"; - } - - var PS = '', i; - - for (i = 0; i < n - s.length - 2 * SHA1_SIZE - 2; i += 1) - { - PS += '\x00'; - } - - var DB = rstr_sha1('') + PS + '\x01' + s; - var seed = new Array(SHA1_SIZE); - new SecureRandom().nextBytes(seed); - - var dbMask = oaep_mgf1_arr(seed, DB.length, hash || rstr_sha1); - var maskedDB = []; - - for (i = 0; i < DB.length; i += 1) - { - maskedDB[i] = DB.charCodeAt(i) ^ dbMask.charCodeAt(i); - } - - var seedMask = oaep_mgf1_arr(maskedDB, seed.length, rstr_sha1); - var maskedSeed = [0]; - - for (i = 0; i < seed.length; i += 1) - { - maskedSeed[i + 1] = seed[i] ^ seedMask.charCodeAt(i); - } - - return new BigInteger(maskedSeed.concat(maskedDB)); -} - -// "empty" RSA key constructor -function RSAKey() { - this.n = null; - this.e = 0; - this.d = null; - this.p = null; - this.q = null; - this.dmp1 = null; - this.dmq1 = null; - this.coeff = null; -} - -// Set the public key fields N and e from hex strings -function RSASetPublic(N,E) { - this.isPublic = true; - if (typeof N !== "string") - { - this.n = N; - this.e = E; - } - else if(N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - } - else - alert("Invalid RSA public key"); -} - -// Perform raw public operation on "x": return x^e (mod n) -function RSADoPublic(x) { - return x.modPowInt(this.e, this.n); -} - -// Return the PKCS#1 RSA encryption of "text" as an even-length hex string -function RSAEncrypt(text) { - var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); - if(m == null) return null; - var c = this.doPublic(m); - if(c == null) return null; - var h = c.toString(16); - if((h.length & 1) == 0) return h; else return "0" + h; -} - -// Return the PKCS#1 OAEP RSA encryption of "text" as an even-length hex string -function RSAEncryptOAEP(text, hash) { - var m = oaep_pad(text, (this.n.bitLength()+7)>>3, hash); - if(m == null) return null; - var c = this.doPublic(m); - if(c == null) return null; - var h = c.toString(16); - if((h.length & 1) == 0) return h; else return "0" + h; -} - -// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string -//function RSAEncryptB64(text) { -// var h = this.encrypt(text); -// if(h) return hex2b64(h); else return null; -//} - -// protected -RSAKey.prototype.doPublic = RSADoPublic; - -// public -RSAKey.prototype.setPublic = RSASetPublic; -RSAKey.prototype.encrypt = RSAEncrypt; -RSAKey.prototype.encryptOAEP = RSAEncryptOAEP; -//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; - -RSAKey.prototype.type = "RSA"; -/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/ - */ -// Depends on rsa.js and jsbn2.js - -// Version 1.1: support utf-8 decoding in pkcs1unpad2 - -// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext -function pkcs1unpad2(d,n) { - var b = d.toByteArray(); - var i = 0; - while(i < b.length && b[i] == 0) ++i; - if(b.length-i != n-1 || b[i] != 2) - return null; - ++i; - while(b[i] != 0) - if(++i >= b.length) return null; - var ret = ""; - while(++i < b.length) { - var c = b[i] & 255; - if(c < 128) { // utf-8 decode - ret += String.fromCharCode(c); - } - else if((c > 191) && (c < 224)) { - ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63)); - ++i; - } - else { - ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63)); - i += 2; - } - } - return ret; -} - -// PKCS#1 (OAEP) mask generation function -function oaep_mgf1_str(seed, len, hash) -{ - var mask = '', i = 0; - - while (mask.length < len) - { - mask += hash(seed + String.fromCharCode.apply(String, [ - (i & 0xff000000) >> 24, - (i & 0x00ff0000) >> 16, - (i & 0x0000ff00) >> 8, - i & 0x000000ff])); - i += 1; - } - - return mask; -} - -var SHA1_SIZE = 20; - -// Undo PKCS#1 (OAEP) padding and, if valid, return the plaintext -function oaep_unpad(d, n, hash) -{ - d = d.toByteArray(); - - var i; - - for (i = 0; i < d.length; i += 1) - { - d[i] &= 0xff; - } - - while (d.length < n) - { - d.unshift(0); - } - - d = String.fromCharCode.apply(String, d); - - if (d.length < 2 * SHA1_SIZE + 2) - { - throw "Cipher too short"; - } - - var maskedSeed = d.substr(1, SHA1_SIZE) - var maskedDB = d.substr(SHA1_SIZE + 1); - - var seedMask = oaep_mgf1_str(maskedDB, SHA1_SIZE, hash || rstr_sha1); - var seed = [], i; - - for (i = 0; i < maskedSeed.length; i += 1) - { - seed[i] = maskedSeed.charCodeAt(i) ^ seedMask.charCodeAt(i); - } - - var dbMask = oaep_mgf1_str(String.fromCharCode.apply(String, seed), - d.length - SHA1_SIZE, rstr_sha1); - - var DB = []; - - for (i = 0; i < maskedDB.length; i += 1) - { - DB[i] = maskedDB.charCodeAt(i) ^ dbMask.charCodeAt(i); - } - - DB = String.fromCharCode.apply(String, DB); - - if (DB.substr(0, SHA1_SIZE) !== rstr_sha1('')) - { - throw "Hash mismatch"; - } - - DB = DB.substr(SHA1_SIZE); - - var first_one = DB.indexOf('\x01'); - var last_zero = (first_one != -1) ? DB.substr(0, first_one).lastIndexOf('\x00') : -1; - - if (last_zero + 1 != first_one) - { - throw "Malformed data"; - } - - return DB.substr(first_one + 1); -} - -// Set the private key fields N, e, and d from hex strings -function RSASetPrivate(N,E,D) { - this.isPrivate = true; - if (typeof N !== "string") - { - this.n = N; - this.e = E; - this.d = D; - } - else if(N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - this.d = parseBigInt(D,16); - } - else - alert("Invalid RSA private key"); -} - -// Set the private key fields N, e, d and CRT params from hex strings -function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) { - this.isPrivate = true; - if (N == null) throw "RSASetPrivateEx N == null"; - if (E == null) throw "RSASetPrivateEx E == null"; - if (N.length == 0) throw "RSASetPrivateEx N.length == 0"; - if (E.length == 0) throw "RSASetPrivateEx E.length == 0"; - - if (N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - this.d = parseBigInt(D,16); - this.p = parseBigInt(P,16); - this.q = parseBigInt(Q,16); - this.dmp1 = parseBigInt(DP,16); - this.dmq1 = parseBigInt(DQ,16); - this.coeff = parseBigInt(C,16); - } else { - alert("Invalid RSA private key in RSASetPrivateEx"); - } -} - -// Generate a new random private key B bits long, using public expt E -function RSAGenerate(B,E) { - var rng = new SecureRandom(); - var qs = B>>1; - this.e = parseInt(E,16); - var ee = new BigInteger(E,16); - for(;;) { - for(;;) { - this.p = new BigInteger(B-qs,1,rng); - if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break; - } - for(;;) { - this.q = new BigInteger(qs,1,rng); - if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break; - } - if(this.p.compareTo(this.q) <= 0) { - var t = this.p; - this.p = this.q; - this.q = t; - } - var p1 = this.p.subtract(BigInteger.ONE); // p1 = p - 1 - var q1 = this.q.subtract(BigInteger.ONE); // q1 = q - 1 - var phi = p1.multiply(q1); - if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) { - this.n = this.p.multiply(this.q); // this.n = p * q - this.d = ee.modInverse(phi); // this.d = - this.dmp1 = this.d.mod(p1); // this.dmp1 = d mod (p - 1) - this.dmq1 = this.d.mod(q1); // this.dmq1 = d mod (q - 1) - this.coeff = this.q.modInverse(this.p); // this.coeff = (q ^ -1) mod p - break; - } - } - this.isPrivate = true; -} - -// Perform raw private operation on "x": return x^d (mod n) -function RSADoPrivate(x) { - if(this.p == null || this.q == null) - return x.modPow(this.d, this.n); - - // TODO: re-calculate any missing CRT params - var xp = x.mod(this.p).modPow(this.dmp1, this.p); // xp=cp? - var xq = x.mod(this.q).modPow(this.dmq1, this.q); // xq=cq? - - while(xp.compareTo(xq) < 0) - xp = xp.add(this.p); - // NOTE: - // xp.subtract(xq) => cp -cq - // xp.subtract(xq).multiply(this.coeff).mod(this.p) => (cp - cq) * u mod p = h - // xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq) => cq + (h * q) = M - return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq); -} - -// Return the PKCS#1 RSA decryption of "ctext". -// "ctext" is an even-length hex string and the output is a plain string. -function RSADecrypt(ctext) { - var c = parseBigInt(ctext, 16); - var m = this.doPrivate(c); - if(m == null) return null; - return pkcs1unpad2(m, (this.n.bitLength()+7)>>3); -} - -// Return the PKCS#1 OAEP RSA decryption of "ctext". -// "ctext" is an even-length hex string and the output is a plain string. -function RSADecryptOAEP(ctext, hash) { - var c = parseBigInt(ctext, 16); - var m = this.doPrivate(c); - if(m == null) return null; - return oaep_unpad(m, (this.n.bitLength()+7)>>3, hash); -} - -// Return the PKCS#1 RSA decryption of "ctext". -// "ctext" is a Base64-encoded string and the output is a plain string. -//function RSAB64Decrypt(ctext) { -// var h = b64tohex(ctext); -// if(h) return this.decrypt(h); else return null; -//} - -// protected -RSAKey.prototype.doPrivate = RSADoPrivate; - -// public -RSAKey.prototype.setPrivate = RSASetPrivate; -RSAKey.prototype.setPrivateEx = RSASetPrivateEx; -RSAKey.prototype.generate = RSAGenerate; -RSAKey.prototype.decrypt = RSADecrypt; -RSAKey.prototype.decryptOAEP = RSADecryptOAEP; -//RSAKey.prototype.b64_decrypt = RSAB64Decrypt; -/*! rsapem-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license - */ -// -// rsa-pem.js - adding function for reading/writing PKCS#1 PEM private key -// to RSAKey class. -// -// version: 1.1.1 (2013-Apr-12) -// -// Copyright (c) 2010-2013 Kenji Urushima (kenji.urushima@gmail.com) -// -// This software is licensed under the terms of the MIT License. -// http://kjur.github.com/jsrsasign/license/ -// -// The above copyright and license notice shall be -// included in all copies or substantial portions of the Software. -// -// -// Depends on: -// -// -// -// _RSApem_pemToBase64(sPEM) -// -// removing PEM header, PEM footer and space characters including -// new lines from PEM formatted RSA private key string. -// - -/** - * @fileOverview - * @name rsapem-1.1.js - * @author Kenji Urushima kenji.urushima@gmail.com - * @version 1.1 - * @license MIT License - */ -function _rsapem_pemToBase64(sPEMPrivateKey) { - var s = sPEMPrivateKey; - s = s.replace("-----BEGIN RSA PRIVATE KEY-----", ""); - s = s.replace("-----END RSA PRIVATE KEY-----", ""); - s = s.replace(/[ \n]+/g, ""); - return s; -} - -function _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey) { - var a = new Array(); - var v1 = ASN1HEX.getStartPosOfV_AtObj(hPrivateKey, 0); - var n1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, v1); - var e1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, n1); - var d1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, e1); - var p1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, d1); - var q1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, p1); - var dp1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, q1); - var dq1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dp1); - var co1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dq1); - a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1); - return a; -} - -function _rsapem_getHexValueArrayOfChildrenFromHex(hPrivateKey) { - var posArray = _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey); - var v = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[0]); - var n = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[1]); - var e = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[2]); - var d = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[3]); - var p = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[4]); - var q = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[5]); - var dp = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[6]); - var dq = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[7]); - var co = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[8]); - var a = new Array(); - a.push(v, n, e, d, p, q, dp, dq, co); - return a; -} - -/** - * read RSA private key from a ASN.1 hexadecimal string - * @name readPrivateKeyFromASN1HexString - * @memberOf RSAKey# - * @function - * @param {String} keyHex ASN.1 hexadecimal string of PKCS#1 private key. - * @since 1.1.1 - */ -function _rsapem_readPrivateKeyFromASN1HexString(keyHex) { - var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex); - this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); -} - -/** - * read PKCS#1 private key from a string - * @name readPrivateKeyFromPEMString - * @memberOf RSAKey# - * @function - * @param {String} keyPEM string of PKCS#1 private key. - */ -function _rsapem_readPrivateKeyFromPEMString(keyPEM) { - var keyB64 = _rsapem_pemToBase64(keyPEM); - var keyHex = b64tohex(keyB64) // depends base64.js - var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex); - this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); -} - -RSAKey.prototype.readPrivateKeyFromPEMString = _rsapem_readPrivateKeyFromPEMString; -RSAKey.prototype.readPrivateKeyFromASN1HexString = _rsapem_readPrivateKeyFromASN1HexString; -/*! rsasign-1.2.7.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license - */ -var _RE_HEXDECONLY=new RegExp("");_RE_HEXDECONLY.compile("[^0-9a-f]","gi");function _rsasign_getHexPaddedDigestInfoForString(d,e,a){var b=function(f){return KJUR.crypto.Util.hashString(f,a)};var c=b(d);return KJUR.crypto.Util.getPaddedDigestInfoHex(c,a,e)}function _zeroPaddingOfSignature(e,d){var c="";var a=d/4-e.length;for(var b=0;b>24,(d&16711680)>>16,(d&65280)>>8,d&255]))));d+=1}return b}function _rsasign_signStringPSS(e,a,d){var c=function(f){return KJUR.crypto.Util.hashHex(f,a)};var b=c(rstrtohex(e));if(d===undefined){d=-1}return this.signWithMessageHashPSS(b,a,d)}function _rsasign_signWithMessageHashPSS(l,a,k){var b=hextorstr(l);var g=b.length;var m=this.n.bitLength()-1;var c=Math.ceil(m/8);var d;var o=function(i){return KJUR.crypto.Util.hashHex(i,a)};if(k===-1||k===undefined){k=g}else{if(k===-2){k=c-g-2}else{if(k<-2){throw"invalid salt length"}}}if(c<(g+k+2)){throw"data too long"}var f="";if(k>0){f=new Array(k);new SecureRandom().nextBytes(f);f=String.fromCharCode.apply(String,f)}var n=hextorstr(o(rstrtohex("\x00\x00\x00\x00\x00\x00\x00\x00"+b+f)));var j=[];for(d=0;d>(8*c-m))&255;q[0]&=~p;for(d=0;dthis.n.bitLength()){return 0}var i=this.doPublic(b);var e=i.toString(16).replace(/^1f+00/,"");var g=_rsasign_getAlgNameAndHashFromHexDisgestInfo(e);if(g.length==0){return false}var d=g[0];var h=g[1];var a=function(k){return KJUR.crypto.Util.hashString(k,d)};var c=a(f);return(h==c)}function _rsasign_verifyWithMessageHash(e,a){a=a.replace(_RE_HEXDECONLY,"");a=a.replace(/[ \n]+/g,"");var b=parseBigInt(a,16);if(b.bitLength()>this.n.bitLength()){return 0}var h=this.doPublic(b);var g=h.toString(16).replace(/^1f+00/,"");var c=_rsasign_getAlgNameAndHashFromHexDisgestInfo(g);if(c.length==0){return false}var d=c[0];var f=c[1];return(f==e)}function _rsasign_verifyStringPSS(c,b,a,f){var e=function(g){return KJUR.crypto.Util.hashHex(g,a)};var d=e(rstrtohex(c));if(f===undefined){f=-1}return this.verifyWithMessageHashPSS(d,b,a,f)}function _rsasign_verifyWithMessageHashPSS(f,s,l,c){var k=new BigInteger(s,16);if(k.bitLength()>this.n.bitLength()){return false}var r=function(i){return KJUR.crypto.Util.hashHex(i,l)};var j=hextorstr(f);var h=j.length;var g=this.n.bitLength()-1;var m=Math.ceil(g/8);var q;if(c===-1||c===undefined){c=h}else{if(c===-2){c=m-h-2}else{if(c<-2){throw"invalid salt length"}}}if(m<(h+c+2)){throw"data too long"}var a=this.doPublic(k).toByteArray();for(q=0;q>(8*m-g))&255;if((d.charCodeAt(0)&p)!==0){throw"bits beyond keysize not zero"}var n=pss_mgf1_str(e,d.length,r);var o=[];for(q=0;qMIT License - */ - -/* - * MEMO: - * f('3082025b02...', 2) ... 82025b ... 3bytes - * f('020100', 2) ... 01 ... 1byte - * f('0203001...', 2) ... 03 ... 1byte - * f('02818003...', 2) ... 8180 ... 2bytes - * f('3080....0000', 2) ... 80 ... -1 - * - * Requirements: - * - ASN.1 type octet length MUST be 1. - * (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...) - */ - -/** - * ASN.1 DER encoded hexadecimal string utility class - * @name ASN1HEX - * @class ASN.1 DER encoded hexadecimal string utility class - * @since jsrsasign 1.1 - */ -var ASN1HEX = new function() { - /** - * get byte length for ASN.1 L(length) bytes - * @name getByteLengthOfL_AtObj - * @memberOf ASN1HEX - * @function - * @param {String} s hexadecimal string of ASN.1 DER encoded data - * @param {Number} pos string index - * @return byte length for ASN.1 L(length) bytes - */ - this.getByteLengthOfL_AtObj = function(s, pos) { - if (s.substring(pos + 2, pos + 3) != '8') return 1; - var i = parseInt(s.substring(pos + 3, pos + 4)); - if (i == 0) return -1; // length octet '80' indefinite length - if (0 < i && i < 10) return i + 1; // including '8?' octet; - return -2; // malformed format - }; - - /** - * get hexadecimal string for ASN.1 L(length) bytes - * @name getHexOfL_AtObj - * @memberOf ASN1HEX - * @function - * @param {String} s hexadecimal string of ASN.1 DER encoded data - * @param {Number} pos string index - * @return {String} hexadecimal string for ASN.1 L(length) bytes - */ - this.getHexOfL_AtObj = function(s, pos) { - var len = this.getByteLengthOfL_AtObj(s, pos); - if (len < 1) return ''; - return s.substring(pos + 2, pos + 2 + len * 2); - }; - - // getting ASN.1 length value at the position 'idx' of - // hexa decimal string 's'. - // - // f('3082025b02...', 0) ... 82025b ... ??? - // f('020100', 0) ... 01 ... 1 - // f('0203001...', 0) ... 03 ... 3 - // f('02818003...', 0) ... 8180 ... 128 - /** - * get integer value of ASN.1 length for ASN.1 data - * @name getIntOfL_AtObj - * @memberOf ASN1HEX - * @function - * @param {String} s hexadecimal string of ASN.1 DER encoded data - * @param {Number} pos string index - * @return ASN.1 L(length) integer value - */ - this.getIntOfL_AtObj = function(s, pos) { - var hLength = this.getHexOfL_AtObj(s, pos); - if (hLength == '') return -1; - var bi; - if (parseInt(hLength.substring(0, 1)) < 8) { - bi = new BigInteger(hLength, 16); - } else { - bi = new BigInteger(hLength.substring(2), 16); - } - return bi.intValue(); - }; - - /** - * get ASN.1 value starting string position for ASN.1 object refered by index 'idx'. - * @name getStartPosOfV_AtObj - * @memberOf ASN1HEX - * @function - * @param {String} s hexadecimal string of ASN.1 DER encoded data - * @param {Number} pos string index - */ - this.getStartPosOfV_AtObj = function(s, pos) { - var l_len = this.getByteLengthOfL_AtObj(s, pos); - if (l_len < 0) return l_len; - return pos + (l_len + 1) * 2; - }; - - /** - * get hexadecimal string of ASN.1 V(value) - * @name getHexOfV_AtObj - * @memberOf ASN1HEX - * @function - * @param {String} s hexadecimal string of ASN.1 DER encoded data - * @param {Number} pos string index - * @return {String} hexadecimal string of ASN.1 value. - */ - this.getHexOfV_AtObj = function(s, pos) { - var pos1 = this.getStartPosOfV_AtObj(s, pos); - var len = this.getIntOfL_AtObj(s, pos); - return s.substring(pos1, pos1 + len * 2); - }; - - /** - * get hexadecimal string of ASN.1 TLV at - * @name getHexOfTLV_AtObj - * @memberOf ASN1HEX - * @function - * @param {String} s hexadecimal string of ASN.1 DER encoded data - * @param {Number} pos string index - * @return {String} hexadecimal string of ASN.1 TLV. - * @since 1.1 - */ - this.getHexOfTLV_AtObj = function(s, pos) { - var hT = s.substr(pos, 2); - var hL = this.getHexOfL_AtObj(s, pos); - var hV = this.getHexOfV_AtObj(s, pos); - return hT + hL + hV; - }; - - /** - * get next sibling starting index for ASN.1 object string - * @name getPosOfNextSibling_AtObj - * @memberOf ASN1HEX - * @function - * @param {String} s hexadecimal string of ASN.1 DER encoded data - * @param {Number} pos string index - * @return next sibling starting index for ASN.1 object string - */ - this.getPosOfNextSibling_AtObj = function(s, pos) { - var pos1 = this.getStartPosOfV_AtObj(s, pos); - var len = this.getIntOfL_AtObj(s, pos); - return pos1 + len * 2; - }; - - /** - * get array of indexes of child ASN.1 objects - * @name getPosArrayOfChildren_AtObj - * @memberOf ASN1HEX - * @function - * @param {String} s hexadecimal string of ASN.1 DER encoded data - * @param {Number} start string index of ASN.1 object - * @return {Array of Number} array of indexes for childen of ASN.1 objects - */ - this.getPosArrayOfChildren_AtObj = function(h, pos) { - var a = new Array(); - var p0 = this.getStartPosOfV_AtObj(h, pos); - a.push(p0); - - var len = this.getIntOfL_AtObj(h, pos); - var p = p0; - var k = 0; - while (1) { - var pNext = this.getPosOfNextSibling_AtObj(h, p); - if (pNext == null || (pNext - p0 >= (len * 2))) break; - if (k >= 200) break; - - a.push(pNext); - p = pNext; - - k++; - } - - return a; - }; - - /** - * get string index of nth child object of ASN.1 object refered by h, idx - * @name getNthChildIndex_AtObj - * @memberOf ASN1HEX - * @function - * @param {String} h hexadecimal string of ASN.1 DER encoded data - * @param {Number} idx start string index of ASN.1 object - * @param {Number} nth for child - * @return {Number} string index of nth child. - * @since 1.1 - */ - this.getNthChildIndex_AtObj = function(h, idx, nth) { - var a = this.getPosArrayOfChildren_AtObj(h, idx); - return a[nth]; - }; - - // ========== decendant methods ============================== - /** - * get string index of nth child object of ASN.1 object refered by h, idx - * @name getDecendantIndexByNthList - * @memberOf ASN1HEX - * @function - * @param {String} h hexadecimal string of ASN.1 DER encoded data - * @param {Number} currentIndex start string index of ASN.1 object - * @param {Array of Number} nthList array list of nth - * @return {Number} string index refered by nthList - * @since 1.1 - * @example - * The "nthList" is a index list of structured ASN.1 object - * reference. Here is a sample structure and "nthList"s which - * refers each objects. - * - * SQUENCE - - * SEQUENCE - [0] - * IA5STRING 000 - [0, 0] - * UTF8STRING 001 - [0, 1] - * SET - [1] - * IA5STRING 010 - [1, 0] - * UTF8STRING 011 - [1, 1] - */ - this.getDecendantIndexByNthList = function(h, currentIndex, nthList) { - if (nthList.length == 0) { - return currentIndex; - } - var firstNth = nthList.shift(); - var a = this.getPosArrayOfChildren_AtObj(h, currentIndex); - return this.getDecendantIndexByNthList(h, a[firstNth], nthList); - }; - - /** - * get hexadecimal string of ASN.1 TLV refered by current index and nth index list. - * @name getDecendantHexTLVByNthList - * @memberOf ASN1HEX - * @function - * @param {String} h hexadecimal string of ASN.1 DER encoded data - * @param {Number} currentIndex start string index of ASN.1 object - * @param {Array of Number} nthList array list of nth - * @return {Number} hexadecimal string of ASN.1 TLV refered by nthList - * @since 1.1 - */ - this.getDecendantHexTLVByNthList = function(h, currentIndex, nthList) { - var idx = this.getDecendantIndexByNthList(h, currentIndex, nthList); - return this.getHexOfTLV_AtObj(h, idx); - }; - - /** - * get hexadecimal string of ASN.1 V refered by current index and nth index list. - * @name getDecendantHexVByNthList - * @memberOf ASN1HEX - * @function - * @param {String} h hexadecimal string of ASN.1 DER encoded data - * @param {Number} currentIndex start string index of ASN.1 object - * @param {Array of Number} nthList array list of nth - * @return {Number} hexadecimal string of ASN.1 V refered by nthList - * @since 1.1 - */ - this.getDecendantHexVByNthList = function(h, currentIndex, nthList) { - var idx = this.getDecendantIndexByNthList(h, currentIndex, nthList); - return this.getHexOfV_AtObj(h, idx); - }; -}; - -/* - * @since asn1hex 1.1.4 - */ -ASN1HEX.getVbyList = function(h, currentIndex, nthList, checkingTag) { - var idx = this.getDecendantIndexByNthList(h, currentIndex, nthList); - if (idx === undefined) { - throw "can't find nthList object"; - } - if (checkingTag !== undefined) { - if (h.substr(idx, 2) != checkingTag) { - throw "checking tag doesn't match: " + - h.substr(idx,2) + "!=" + checkingTag; - } - } - return this.getHexOfV_AtObj(h, idx); -}; - -/** - * get OID string from hexadecimal encoded value - * @name hextooidstr - * @memberOf ASN1HEX - * @function - * @param {String} hex hexadecmal string of ASN.1 DER encoded OID value - * @return {String} OID string (ex. '1.2.3.4.567') - * @since asn1hex 1.1.5 - */ -ASN1HEX.hextooidstr = function(hex) { - var zeroPadding = function(s, len) { - if (s.length >= len) return s; - return new Array(len - s.length + 1).join('0') + s; - }; - - var a = []; - - // a[0], a[1] - var hex0 = hex.substr(0, 2); - var i0 = parseInt(hex0, 16); - a[0] = new String(Math.floor(i0 / 40)); - a[1] = new String(i0 % 40); - - // a[2]..a[n] - var hex1 = hex.substr(2); - var b = []; - for (var i = 0; i < hex1.length / 2; i++) { - b.push(parseInt(hex1.substr(i * 2, 2), 16)); - } - var c = []; - var cbin = ""; - for (var i = 0; i < b.length; i++) { - if (b[i] & 0x80) { - cbin = cbin + zeroPadding((b[i] & 0x7f).toString(2), 7); - } else { - cbin = cbin + zeroPadding((b[i] & 0x7f).toString(2), 7); - c.push(new String(parseInt(cbin, 2))); - cbin = ""; - } - } - - var s = a.join("."); - if (c.length > 0) s = s + "." + c.join("."); - return s; -}; - -/*! x509-1.1.3.js (c) 2012-2014 Kenji Urushima | kjur.github.com/jsrsasign/license - */ -/* - * x509.js - X509 class to read subject public key from certificate. - * - * Copyright (c) 2010-2014 Kenji Urushima (kenji.urushima@gmail.com) - * - * This software is licensed under the terms of the MIT License. - * http://kjur.github.com/jsrsasign/license - * - * The above copyright and license notice shall be - * included in all copies or substantial portions of the Software. - */ - -/** - * @fileOverview - * @name x509-1.1.js - * @author Kenji Urushima kenji.urushima@gmail.com - * @version x509 1.1.3 (2014-May-17) - * @since jsrsasign 1.x.x - * @license MIT License - */ - -/* - * Depends: - * base64.js - * rsa.js - * asn1hex.js - */ - -/** - * X.509 certificate class.
- * @class X.509 certificate class - * @property {RSAKey} subjectPublicKeyRSA Tom Wu's RSAKey object - * @property {String} subjectPublicKeyRSA_hN hexadecimal string for modulus of RSA public key - * @property {String} subjectPublicKeyRSA_hE hexadecimal string for public exponent of RSA public key - * @property {String} hex hexacedimal string for X.509 certificate. - * @author Kenji Urushima - * @version 1.0.1 (08 May 2012) - * @see 'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/ - */ -function X509() { - this.subjectPublicKeyRSA = null; - this.subjectPublicKeyRSA_hN = null; - this.subjectPublicKeyRSA_hE = null; - this.hex = null; - - // ===== get basic fields from hex ===================================== - - /** - * get hexadecimal string of serialNumber field of certificate.
- * @name getSerialNumberHex - * @memberOf X509# - * @function - */ - this.getSerialNumberHex = function() { - return ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 1]); - }; - - /** - * get hexadecimal string of issuer field TLV of certificate.
- * @name getIssuerHex - * @memberOf X509# - * @function - */ - this.getIssuerHex = function() { - return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]); - }; - - /** - * get string of issuer field of certificate.
- * @name getIssuerString - * @memberOf X509# - * @function - */ - this.getIssuerString = function() { - return X509.hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3])); - }; - - /** - * get hexadecimal string of subject field of certificate.
- * @name getSubjectHex - * @memberOf X509# - * @function - */ - this.getSubjectHex = function() { - return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]); - }; - - /** - * get string of subject field of certificate.
- * @name getSubjectString - * @memberOf X509# - * @function - */ - this.getSubjectString = function() { - return X509.hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5])); - }; - - /** - * get notBefore field string of certificate.
- * @name getNotBefore - * @memberOf X509# - * @function - */ - this.getNotBefore = function() { - var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 0]); - s = s.replace(/(..)/g, "%$1"); - s = decodeURIComponent(s); - return s; - }; - - /** - * get notAfter field string of certificate.
- * @name getNotAfter - * @memberOf X509# - * @function - */ - this.getNotAfter = function() { - var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 1]); - s = s.replace(/(..)/g, "%$1"); - s = decodeURIComponent(s); - return s; - }; - - // ===== read certificate public key ========================== - - // ===== read certificate ===================================== - /** - * read PEM formatted X.509 certificate from string.
- * @name readCertPEM - * @memberOf X509# - * @function - * @param {String} sCertPEM string for PEM formatted X.509 certificate - */ - this.readCertPEM = function(sCertPEM) { - var hCert = X509.pemToHex(sCertPEM); - var a = X509.getPublicKeyHexArrayFromCertHex(hCert); - var rsa = new RSAKey(); - rsa.setPublic(a[0], a[1]); - this.subjectPublicKeyRSA = rsa; - this.subjectPublicKeyRSA_hN = a[0]; - this.subjectPublicKeyRSA_hE = a[1]; - this.hex = hCert; - }; - - this.readCertPEMWithoutRSAInit = function(sCertPEM) { - var hCert = X509.pemToHex(sCertPEM); - var a = X509.getPublicKeyHexArrayFromCertHex(hCert); - this.subjectPublicKeyRSA.setPublic(a[0], a[1]); - this.subjectPublicKeyRSA_hN = a[0]; - this.subjectPublicKeyRSA_hE = a[1]; - this.hex = hCert; - }; -}; - -X509.pemToBase64 = function(sCertPEM) { - var s = sCertPEM; - s = s.replace("-----BEGIN CERTIFICATE-----", ""); - s = s.replace("-----END CERTIFICATE-----", ""); - s = s.replace(/[ \n]+/g, ""); - return s; -}; - -X509.pemToHex = function(sCertPEM) { - var b64Cert = X509.pemToBase64(sCertPEM); - var hCert = b64tohex(b64Cert); - return hCert; -}; - -// NOTE: Without BITSTRING encapsulation. -X509.getSubjectPublicKeyPosFromCertHex = function(hCert) { - var pInfo = X509.getSubjectPublicKeyInfoPosFromCertHex(hCert); - if (pInfo == -1) return -1; - var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pInfo); - if (a.length != 2) return -1; - var pBitString = a[1]; - if (hCert.substring(pBitString, pBitString + 2) != '03') return -1; - var pBitStringV = ASN1HEX.getStartPosOfV_AtObj(hCert, pBitString); - - if (hCert.substring(pBitStringV, pBitStringV + 2) != '00') return -1; - return pBitStringV + 2; -}; - -// NOTE: privateKeyUsagePeriod field of X509v2 not supported. -// NOTE: v1 and v3 supported -X509.getSubjectPublicKeyInfoPosFromCertHex = function(hCert) { - var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0); - var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pTbsCert); - if (a.length < 1) return -1; - if (hCert.substring(a[0], a[0] + 10) == "a003020102") { // v3 - if (a.length < 6) return -1; - return a[6]; - } else { - if (a.length < 5) return -1; - return a[5]; - } -}; - -X509.getPublicKeyHexArrayFromCertHex = function(hCert) { - var p = X509.getSubjectPublicKeyPosFromCertHex(hCert); - var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, p); - if (a.length != 2) return []; - var hN = ASN1HEX.getHexOfV_AtObj(hCert, a[0]); - var hE = ASN1HEX.getHexOfV_AtObj(hCert, a[1]); - if (hN != null && hE != null) { - return [hN, hE]; - } else { - return []; - } -}; - -X509.getHexTbsCertificateFromCert = function(hCert) { - var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0); - return pTbsCert; -}; - -X509.getPublicKeyHexArrayFromCertPEM = function(sCertPEM) { - var hCert = X509.pemToHex(sCertPEM); - var a = X509.getPublicKeyHexArrayFromCertHex(hCert); - return a; -}; - -X509.hex2dn = function(hDN) { - var s = ""; - var a = ASN1HEX.getPosArrayOfChildren_AtObj(hDN, 0); - for (var i = 0; i < a.length; i++) { - var hRDN = ASN1HEX.getHexOfTLV_AtObj(hDN, a[i]); - s = s + "/" + X509.hex2rdn(hRDN); - } - return s; -}; - -X509.hex2rdn = function(hRDN) { - var hType = ASN1HEX.getDecendantHexTLVByNthList(hRDN, 0, [0, 0]); - var hValue = ASN1HEX.getDecendantHexVByNthList(hRDN, 0, [0, 1]); - var type = ""; - try { type = X509.DN_ATTRHEX[hType]; } catch (ex) { type = hType; } - hValue = hValue.replace(/(..)/g, "%$1"); - var value = decodeURIComponent(hValue); - return type + "=" + value; -}; - -X509.DN_ATTRHEX = { - "0603550406": "C", - "060355040a": "O", - "060355040b": "OU", - "0603550403": "CN", - "0603550405": "SN", - "0603550408": "ST", - "0603550407": "L", -}; - -/** - * get RSAKey/ECDSA public key object from PEM certificate string - * @name getPublicKeyFromCertPEM - * @memberOf X509 - * @function - * @param {String} sCertPEM PEM formatted RSA/ECDSA/DSA X.509 certificate - * @return returns RSAKey/KJUR.crypto.{ECDSA,DSA} object of public key - * @since x509 1.1.1 - * @description - * NOTE: DSA is also supported since x509 1.1.2. - */ -X509.getPublicKeyFromCertPEM = function(sCertPEM) { - var info = X509.getPublicKeyInfoPropOfCertPEM(sCertPEM); - - if (info.algoid == "2a864886f70d010101") { // RSA - var aRSA = KEYUTIL.parsePublicRawRSAKeyHex(info.keyhex); - var key = new RSAKey(); - key.setPublic(aRSA.n, aRSA.e); - return key; - } else if (info.algoid == "2a8648ce3d0201") { // ECC - var curveName = KJUR.crypto.OID.oidhex2name[info.algparam]; - var key = new KJUR.crypto.ECDSA({'curve': curveName, 'info': info.keyhex}); - key.setPublicKeyHex(info.keyhex); - return key; - } else if (info.algoid == "2a8648ce380401") { // DSA 1.2.840.10040.4.1 - var p = ASN1HEX.getVbyList(info.algparam, 0, [0], "02"); - var q = ASN1HEX.getVbyList(info.algparam, 0, [1], "02"); - var g = ASN1HEX.getVbyList(info.algparam, 0, [2], "02"); - var y = ASN1HEX.getHexOfV_AtObj(info.keyhex, 0); - y = y.substr(2); - var key = new KJUR.crypto.DSA(); - key.setPublic(new BigInteger(p, 16), - new BigInteger(q, 16), - new BigInteger(g, 16), - new BigInteger(y, 16)); - return key; - } else { - throw "unsupported key"; - } -}; - -/** - * get public key information from PEM certificate - * @name getPublicKeyInfoPropOfCertPEM - * @memberOf X509 - * @function - * @param {String} sCertPEM string of PEM formatted certificate - * @return {Hash} hash of information for public key - * @since x509 1.1.1 - * @description - * Resulted associative array has following properties: - *
    - *
  • algoid - hexadecimal string of OID of asymmetric key algorithm
  • - *
  • algparam - hexadecimal string of OID of ECC curve name or null
  • - *
  • keyhex - hexadecimal string of key in the certificate
  • - *
- * @since x509 1.1.1 - */ -X509.getPublicKeyInfoPropOfCertPEM = function(sCertPEM) { - var result = {}; - result.algparam = null; - var hCert = X509.pemToHex(sCertPEM); - - // 1. Certificate ASN.1 - var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, 0); - if (a1.length != 3) - throw "malformed X.509 certificate PEM (code:001)"; // not 3 item of seq Cert - - // 2. tbsCertificate - if (hCert.substr(a1[0], 2) != "30") - throw "malformed X.509 certificate PEM (code:002)"; // tbsCert not seq - - var a2 = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a1[0]); - - // 3. subjectPublicKeyInfo - if (a2.length < 7) - throw "malformed X.509 certificate PEM (code:003)"; // no subjPubKeyInfo - - var a3 = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a2[6]); - - if (a3.length != 2) - throw "malformed X.509 certificate PEM (code:004)"; // not AlgId and PubKey - - // 4. AlgId - var a4 = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a3[0]); - - if (a4.length != 2) - throw "malformed X.509 certificate PEM (code:005)"; // not 2 item in AlgId - - result.algoid = ASN1HEX.getHexOfV_AtObj(hCert, a4[0]); - - if (hCert.substr(a4[1], 2) == "06") { // EC - result.algparam = ASN1HEX.getHexOfV_AtObj(hCert, a4[1]); - } else if (hCert.substr(a4[1], 2) == "30") { // DSA - result.algparam = ASN1HEX.getHexOfTLV_AtObj(hCert, a4[1]); - } - - // 5. Public Key Hex - if (hCert.substr(a3[1], 2) != "03") - throw "malformed X.509 certificate PEM (code:006)"; // not bitstring - - var unusedBitAndKeyHex = ASN1HEX.getHexOfV_AtObj(hCert, a3[1]); - result.keyhex = unusedBitAndKeyHex.substr(2); - - return result; -}; - -/* - X509.prototype.readCertPEM = _x509_readCertPEM; - X509.prototype.readCertPEMWithoutRSAInit = _x509_readCertPEMWithoutRSAInit; - X509.prototype.getSerialNumberHex = _x509_getSerialNumberHex; - X509.prototype.getIssuerHex = _x509_getIssuerHex; - X509.prototype.getSubjectHex = _x509_getSubjectHex; - X509.prototype.getIssuerString = _x509_getIssuerString; - X509.prototype.getSubjectString = _x509_getSubjectString; - X509.prototype.getNotBefore = _x509_getNotBefore; - X509.prototype.getNotAfter = _x509_getNotAfter; -*/ -/*! crypto-1.1.5.js (c) 2013 Kenji Urushima | kjur.github.com/jsrsasign/license - */ -/* - * crypto.js - Cryptographic Algorithm Provider class - * - * Copyright (c) 2013 Kenji Urushima (kenji.urushima@gmail.com) - * - * This software is licensed under the terms of the MIT License. - * http://kjur.github.com/jsrsasign/license - * - * The above copyright and license notice shall be - * included in all copies or substantial portions of the Software. - */ - -/** - * @fileOverview - * @name crypto-1.1.js - * @author Kenji Urushima kenji.urushima@gmail.com - * @version 1.1.5 (2013-Oct-06) - * @since jsrsasign 2.2 - * @license MIT License - */ - -/** - * kjur's class library name space - * @name KJUR - * @namespace kjur's class library name space - */ -if (typeof KJUR == "undefined" || !KJUR) KJUR = {}; -/** - * kjur's cryptographic algorithm provider library name space - *

- * This namespace privides following crytpgrahic classes. - *

    - *
  • {@link KJUR.crypto.MessageDigest} - Java JCE(cryptograhic extension) style MessageDigest class
  • - *
  • {@link KJUR.crypto.Signature} - Java JCE(cryptograhic extension) style Signature class
  • - *
  • {@link KJUR.crypto.Util} - cryptographic utility functions and properties
  • - *
- * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2. - *

- * @name KJUR.crypto - * @namespace - */ -if (typeof KJUR.crypto == "undefined" || !KJUR.crypto) KJUR.crypto = {}; - -/** - * static object for cryptographic function utilities - * @name KJUR.crypto.Util - * @class static object for cryptographic function utilities - * @property {Array} DIGESTINFOHEAD PKCS#1 DigestInfo heading hexadecimal bytes for each hash algorithms - * @property {Array} DEFAULTPROVIDER associative array of default provider name for each hash and signature algorithms - * @description - */ -KJUR.crypto.Util = new function() { - this.DIGESTINFOHEAD = { - 'sha1': "3021300906052b0e03021a05000414", - 'sha224': "302d300d06096086480165030402040500041c", - 'sha256': "3031300d060960864801650304020105000420", - 'sha384': "3041300d060960864801650304020205000430", - 'sha512': "3051300d060960864801650304020305000440", - 'md2': "3020300c06082a864886f70d020205000410", - 'md5': "3020300c06082a864886f70d020505000410", - 'ripemd160': "3021300906052b2403020105000414", - }; - - /* - * @since crypto 1.1.1 - */ - this.DEFAULTPROVIDER = { - 'md5': 'cryptojs', - 'sha1': 'cryptojs', - 'sha224': 'cryptojs', - 'sha256': 'cryptojs', - 'sha384': 'cryptojs', - 'sha512': 'cryptojs', - 'ripemd160': 'cryptojs', - 'hmacmd5': 'cryptojs', - 'hmacsha1': 'cryptojs', - 'hmacsha224': 'cryptojs', - 'hmacsha256': 'cryptojs', - 'hmacsha384': 'cryptojs', - 'hmacsha512': 'cryptojs', - 'hmacripemd160': 'cryptojs', - - 'MD5withRSA': 'cryptojs/jsrsa', - 'SHA1withRSA': 'cryptojs/jsrsa', - 'SHA224withRSA': 'cryptojs/jsrsa', - 'SHA256withRSA': 'cryptojs/jsrsa', - 'SHA384withRSA': 'cryptojs/jsrsa', - 'SHA512withRSA': 'cryptojs/jsrsa', - 'RIPEMD160withRSA': 'cryptojs/jsrsa', - - 'MD5withECDSA': 'cryptojs/jsrsa', - 'SHA1withECDSA': 'cryptojs/jsrsa', - 'SHA224withECDSA': 'cryptojs/jsrsa', - 'SHA256withECDSA': 'cryptojs/jsrsa', - 'SHA384withECDSA': 'cryptojs/jsrsa', - 'SHA512withECDSA': 'cryptojs/jsrsa', - 'RIPEMD160withECDSA': 'cryptojs/jsrsa', - - 'SHA1withDSA': 'cryptojs/jsrsa', - 'SHA224withDSA': 'cryptojs/jsrsa', - 'SHA256withDSA': 'cryptojs/jsrsa', - - 'MD5withRSAandMGF1': 'cryptojs/jsrsa', - 'SHA1withRSAandMGF1': 'cryptojs/jsrsa', - 'SHA224withRSAandMGF1': 'cryptojs/jsrsa', - 'SHA256withRSAandMGF1': 'cryptojs/jsrsa', - 'SHA384withRSAandMGF1': 'cryptojs/jsrsa', - 'SHA512withRSAandMGF1': 'cryptojs/jsrsa', - 'RIPEMD160withRSAandMGF1': 'cryptojs/jsrsa', - }; - - /* - * @since crypto 1.1.2 - */ - this.CRYPTOJSMESSAGEDIGESTNAME = { - 'md5': 'CryptoJS.algo.MD5', - 'sha1': 'CryptoJS.algo.SHA1', - 'sha224': 'CryptoJS.algo.SHA224', - 'sha256': 'CryptoJS.algo.SHA256', - 'sha384': 'CryptoJS.algo.SHA384', - 'sha512': 'CryptoJS.algo.SHA512', - 'ripemd160': 'CryptoJS.algo.RIPEMD160' - }; - - /** - * get hexadecimal DigestInfo - * @name getDigestInfoHex - * @memberOf KJUR.crypto.Util - * @function - * @param {String} hHash hexadecimal hash value - * @param {String} alg hash algorithm name (ex. 'sha1') - * @return {String} hexadecimal string DigestInfo ASN.1 structure - */ - this.getDigestInfoHex = function(hHash, alg) { - if (typeof this.DIGESTINFOHEAD[alg] == "undefined") - throw "alg not supported in Util.DIGESTINFOHEAD: " + alg; - return this.DIGESTINFOHEAD[alg] + hHash; - }; - - /** - * get PKCS#1 padded hexadecimal DigestInfo - * @name getPaddedDigestInfoHex - * @memberOf KJUR.crypto.Util - * @function - * @param {String} hHash hexadecimal hash value of message to be signed - * @param {String} alg hash algorithm name (ex. 'sha1') - * @param {Integer} keySize key bit length (ex. 1024) - * @return {String} hexadecimal string of PKCS#1 padded DigestInfo - */ - this.getPaddedDigestInfoHex = function(hHash, alg, keySize) { - var hDigestInfo = this.getDigestInfoHex(hHash, alg); - var pmStrLen = keySize / 4; // minimum PM length - - if (hDigestInfo.length + 22 > pmStrLen) // len(0001+ff(*8)+00+hDigestInfo)=22 - throw "key is too short for SigAlg: keylen=" + keySize + "," + alg; - - var hHead = "0001"; - var hTail = "00" + hDigestInfo; - var hMid = ""; - var fLen = pmStrLen - hHead.length - hTail.length; - for (var i = 0; i < fLen; i += 2) { - hMid += "ff"; - } - var hPaddedMessage = hHead + hMid + hTail; - return hPaddedMessage; - }; - - /** - * get hexadecimal hash of string with specified algorithm - * @name hashString - * @memberOf KJUR.crypto.Util - * @function - * @param {String} s input string to be hashed - * @param {String} alg hash algorithm name - * @return {String} hexadecimal string of hash value - * @since 1.1.1 - */ - this.hashString = function(s, alg) { - var md = new KJUR.crypto.MessageDigest({'alg': alg}); - return md.digestString(s); - }; - - /** - * get hexadecimal hash of hexadecimal string with specified algorithm - * @name hashHex - * @memberOf KJUR.crypto.Util - * @function - * @param {String} sHex input hexadecimal string to be hashed - * @param {String} alg hash algorithm name - * @return {String} hexadecimal string of hash value - * @since 1.1.1 - */ - this.hashHex = function(sHex, alg) { - var md = new KJUR.crypto.MessageDigest({'alg': alg}); - return md.digestHex(sHex); - }; - - /** - * get hexadecimal SHA1 hash of string - * @name sha1 - * @memberOf KJUR.crypto.Util - * @function - * @param {String} s input string to be hashed - * @return {String} hexadecimal string of hash value - * @since 1.0.3 - */ - this.sha1 = function(s) { - var md = new KJUR.crypto.MessageDigest({'alg':'sha1', 'prov':'cryptojs'}); - return md.digestString(s); - }; - - /** - * get hexadecimal SHA256 hash of string - * @name sha256 - * @memberOf KJUR.crypto.Util - * @function - * @param {String} s input string to be hashed - * @return {String} hexadecimal string of hash value - * @since 1.0.3 - */ - this.sha256 = function(s) { - var md = new KJUR.crypto.MessageDigest({'alg':'sha256', 'prov':'cryptojs'}); - return md.digestString(s); - }; - - this.sha256Hex = function(s) { - var md = new KJUR.crypto.MessageDigest({'alg':'sha256', 'prov':'cryptojs'}); - return md.digestHex(s); - }; - - /** - * get hexadecimal SHA512 hash of string - * @name sha512 - * @memberOf KJUR.crypto.Util - * @function - * @param {String} s input string to be hashed - * @return {String} hexadecimal string of hash value - * @since 1.0.3 - */ - this.sha512 = function(s) { - var md = new KJUR.crypto.MessageDigest({'alg':'sha512', 'prov':'cryptojs'}); - return md.digestString(s); - }; - - this.sha512Hex = function(s) { - var md = new KJUR.crypto.MessageDigest({'alg':'sha512', 'prov':'cryptojs'}); - return md.digestHex(s); - }; - - /** - * get hexadecimal MD5 hash of string - * @name md5 - * @memberOf KJUR.crypto.Util - * @function - * @param {String} s input string to be hashed - * @return {String} hexadecimal string of hash value - * @since 1.0.3 - */ - this.md5 = function(s) { - var md = new KJUR.crypto.MessageDigest({'alg':'md5', 'prov':'cryptojs'}); - return md.digestString(s); - }; - - /** - * get hexadecimal RIPEMD160 hash of string - * @name ripemd160 - * @memberOf KJUR.crypto.Util - * @function - * @param {String} s input string to be hashed - * @return {String} hexadecimal string of hash value - * @since 1.0.3 - */ - this.ripemd160 = function(s) { - var md = new KJUR.crypto.MessageDigest({'alg':'ripemd160', 'prov':'cryptojs'}); - return md.digestString(s); - }; - - /* - * @since 1.1.2 - */ - this.getCryptoJSMDByName = function(s) { - - }; -}; - -/** - * MessageDigest class which is very similar to java.security.MessageDigest class - * @name KJUR.crypto.MessageDigest - * @class MessageDigest class which is very similar to java.security.MessageDigest class - * @param {Array} params parameters for constructor - * @description - *
- * Currently this supports following algorithm and providers combination: - *
    - *
  • md5 - cryptojs
  • - *
  • sha1 - cryptojs
  • - *
  • sha224 - cryptojs
  • - *
  • sha256 - cryptojs
  • - *
  • sha384 - cryptojs
  • - *
  • sha512 - cryptojs
  • - *
  • ripemd160 - cryptojs
  • - *
  • sha256 - sjcl (NEW from crypto.js 1.0.4)
  • - *
- * @example - * // CryptoJS provider sample - * <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/core.js"></script> - * <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/sha1.js"></script> - * <script src="crypto-1.0.js"></script> - * var md = new KJUR.crypto.MessageDigest({alg: "sha1", prov: "cryptojs"}); - * md.updateString('aaa') - * var mdHex = md.digest() - * - * // SJCL(Stanford JavaScript Crypto Library) provider sample - * <script src="http://bitwiseshiftleft.github.io/sjcl/sjcl.js"></script> - * <script src="crypto-1.0.js"></script> - * var md = new KJUR.crypto.MessageDigest({alg: "sha256", prov: "sjcl"}); // sjcl supports sha256 only - * md.updateString('aaa') - * var mdHex = md.digest() - */ -KJUR.crypto.MessageDigest = function(params) { - var md = null; - var algName = null; - var provName = null; - - /** - * set hash algorithm and provider - * @name setAlgAndProvider - * @memberOf KJUR.crypto.MessageDigest - * @function - * @param {String} alg hash algorithm name - * @param {String} prov provider name - * @description - * @example - * // for SHA1 - * md.setAlgAndProvider('sha1', 'cryptojs'); - * // for RIPEMD160 - * md.setAlgAndProvider('ripemd160', 'cryptojs'); - */ - this.setAlgAndProvider = function(alg, prov) { - if (alg != null && prov === undefined) prov = KJUR.crypto.Util.DEFAULTPROVIDER[alg]; - - // for cryptojs - if (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(alg) != -1 && - prov == 'cryptojs') { - try { - this.md = eval(KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[alg]).create(); - } catch (ex) { - throw "setAlgAndProvider hash alg set fail alg=" + alg + "/" + ex; - } - this.updateString = function(str) { - this.md.update(str); - }; - this.updateHex = function(hex) { - var wHex = CryptoJS.enc.Hex.parse(hex); - this.md.update(wHex); - }; - this.digest = function() { - var hash = this.md.finalize(); - return hash.toString(CryptoJS.enc.Hex); - }; - this.digestString = function(str) { - this.updateString(str); - return this.digest(); - }; - this.digestHex = function(hex) { - this.updateHex(hex); - return this.digest(); - }; - } - if (':sha256:'.indexOf(alg) != -1 && - prov == 'sjcl') { - try { - this.md = new sjcl.hash.sha256(); - } catch (ex) { - throw "setAlgAndProvider hash alg set fail alg=" + alg + "/" + ex; - } - this.updateString = function(str) { - this.md.update(str); - }; - this.updateHex = function(hex) { - var baHex = sjcl.codec.hex.toBits(hex); - this.md.update(baHex); - }; - this.digest = function() { - var hash = this.md.finalize(); - return sjcl.codec.hex.fromBits(hash); - }; - this.digestString = function(str) { - this.updateString(str); - return this.digest(); - }; - this.digestHex = function(hex) { - this.updateHex(hex); - return this.digest(); - }; - } - }; - - /** - * update digest by specified string - * @name updateString - * @memberOf KJUR.crypto.MessageDigest - * @function - * @param {String} str string to update - * @description - * @example - * md.updateString('New York'); - */ - this.updateString = function(str) { - throw "updateString(str) not supported for this alg/prov: " + this.algName + "/" + this.provName; - }; - - /** - * update digest by specified hexadecimal string - * @name updateHex - * @memberOf KJUR.crypto.MessageDigest - * @function - * @param {String} hex hexadecimal string to update - * @description - * @example - * md.updateHex('0afe36'); - */ - this.updateHex = function(hex) { - throw "updateHex(hex) not supported for this alg/prov: " + this.algName + "/" + this.provName; - }; - - /** - * completes hash calculation and returns hash result - * @name digest - * @memberOf KJUR.crypto.MessageDigest - * @function - * @description - * @example - * md.digest() - */ - this.digest = function() { - throw "digest() not supported for this alg/prov: " + this.algName + "/" + this.provName; - }; - - /** - * performs final update on the digest using string, then completes the digest computation - * @name digestString - * @memberOf KJUR.crypto.MessageDigest - * @function - * @param {String} str string to final update - * @description - * @example - * md.digestString('aaa') - */ - this.digestString = function(str) { - throw "digestString(str) not supported for this alg/prov: " + this.algName + "/" + this.provName; - }; - - /** - * performs final update on the digest using hexadecimal string, then completes the digest computation - * @name digestHex - * @memberOf KJUR.crypto.MessageDigest - * @function - * @param {String} hex hexadecimal string to final update - * @description - * @example - * md.digestHex('0f2abd') - */ - this.digestHex = function(hex) { - throw "digestHex(hex) not supported for this alg/prov: " + this.algName + "/" + this.provName; - }; - - if (params !== undefined) { - if (params['alg'] !== undefined) { - this.algName = params['alg']; - if (params['prov'] === undefined) - this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName]; - this.setAlgAndProvider(this.algName, this.provName); - } - } -}; - -/** - * Mac(Message Authentication Code) class which is very similar to java.security.Mac class - * @name KJUR.crypto.Mac - * @class Mac class which is very similar to java.security.Mac class - * @param {Array} params parameters for constructor - * @description - *
- * Currently this supports following algorithm and providers combination: - *
    - *
  • hmacmd5 - cryptojs
  • - *
  • hmacsha1 - cryptojs
  • - *
  • hmacsha224 - cryptojs
  • - *
  • hmacsha256 - cryptojs
  • - *
  • hmacsha384 - cryptojs
  • - *
  • hmacsha512 - cryptojs
  • - *
- * NOTE: HmacSHA224 and HmacSHA384 issue was fixed since jsrsasign 4.1.4. - * Please use 'ext/cryptojs-312-core-fix*.js' instead of 'core.js' of original CryptoJS - * to avoid those issue. - * @example - * var mac = new KJUR.crypto.Mac({alg: "HmacSHA1", prov: "cryptojs", "pass": "pass"}); - * mac.updateString('aaa') - * var macHex = md.doFinal() - */ -KJUR.crypto.Mac = function(params) { - var mac = null; - var pass = null; - var algName = null; - var provName = null; - var algProv = null; - - this.setAlgAndProvider = function(alg, prov) { - if (alg == null) alg = "hmacsha1"; - - alg = alg.toLowerCase(); - if (alg.substr(0, 4) != "hmac") { - throw "setAlgAndProvider unsupported HMAC alg: " + alg; - } - - if (prov === undefined) prov = KJUR.crypto.Util.DEFAULTPROVIDER[alg]; - this.algProv = alg + "/" + prov; - - var hashAlg = alg.substr(4); - - // for cryptojs - if (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(hashAlg) != -1 && - prov == 'cryptojs') { - try { - var mdObj = eval(KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[hashAlg]); - this.mac = CryptoJS.algo.HMAC.create(mdObj, this.pass); - } catch (ex) { - throw "setAlgAndProvider hash alg set fail hashAlg=" + hashAlg + "/" + ex; - } - this.updateString = function(str) { - this.mac.update(str); - }; - this.updateHex = function(hex) { - var wHex = CryptoJS.enc.Hex.parse(hex); - this.mac.update(wHex); - }; - this.doFinal = function() { - var hash = this.mac.finalize(); - return hash.toString(CryptoJS.enc.Hex); - }; - this.doFinalString = function(str) { - this.updateString(str); - return this.doFinal(); - }; - this.doFinalHex = function(hex) { - this.updateHex(hex); - return this.doFinal(); - }; - } - }; - - /** - * update digest by specified string - * @name updateString - * @memberOf KJUR.crypto.Mac - * @function - * @param {String} str string to update - * @description - * @example - * md.updateString('New York'); - */ - this.updateString = function(str) { - throw "updateString(str) not supported for this alg/prov: " + this.algProv; - }; - - /** - * update digest by specified hexadecimal string - * @name updateHex - * @memberOf KJUR.crypto.Mac - * @function - * @param {String} hex hexadecimal string to update - * @description - * @example - * md.updateHex('0afe36'); - */ - this.updateHex = function(hex) { - throw "updateHex(hex) not supported for this alg/prov: " + this.algProv; - }; - - /** - * completes hash calculation and returns hash result - * @name doFinal - * @memberOf KJUR.crypto.Mac - * @function - * @description - * @example - * md.digest() - */ - this.doFinal = function() { - throw "digest() not supported for this alg/prov: " + this.algProv; - }; - - /** - * performs final update on the digest using string, then completes the digest computation - * @name doFinalString - * @memberOf KJUR.crypto.Mac - * @function - * @param {String} str string to final update - * @description - * @example - * md.digestString('aaa') - */ - this.doFinalString = function(str) { - throw "digestString(str) not supported for this alg/prov: " + this.algProv; - }; - - /** - * performs final update on the digest using hexadecimal string, - * then completes the digest computation - * @name doFinalHex - * @memberOf KJUR.crypto.Mac - * @function - * @param {String} hex hexadecimal string to final update - * @description - * @example - * md.digestHex('0f2abd') - */ - this.doFinalHex = function(hex) { - throw "digestHex(hex) not supported for this alg/prov: " + this.algProv; - }; - - if (params !== undefined) { - if (params['pass'] !== undefined) { - this.pass = params['pass']; - } - if (params['alg'] !== undefined) { - this.algName = params['alg']; - if (params['prov'] === undefined) - this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName]; - this.setAlgAndProvider(this.algName, this.provName); - } - } -}; - -/** - * Signature class which is very similar to java.security.Signature class - * @name KJUR.crypto.Signature - * @class Signature class which is very similar to java.security.Signature class - * @param {Array} params parameters for constructor - * @property {String} state Current state of this signature object whether 'SIGN', 'VERIFY' or null - * @description - *
- * As for params of constructor's argument, it can be specify following attributes: - *
    - *
  • alg - signature algorithm name (ex. {MD5,SHA1,SHA224,SHA256,SHA384,SHA512,RIPEMD160}with{RSA,ECDSA,DSA})
  • - *
  • provider - currently 'cryptojs/jsrsa' only
  • - *
- *

SUPPORTED ALGORITHMS AND PROVIDERS

- * This Signature class supports following signature algorithm and provider names: - *
    - *
  • MD5withRSA - cryptojs/jsrsa
  • - *
  • SHA1withRSA - cryptojs/jsrsa
  • - *
  • SHA224withRSA - cryptojs/jsrsa
  • - *
  • SHA256withRSA - cryptojs/jsrsa
  • - *
  • SHA384withRSA - cryptojs/jsrsa
  • - *
  • SHA512withRSA - cryptojs/jsrsa
  • - *
  • RIPEMD160withRSA - cryptojs/jsrsa
  • - *
  • MD5withECDSA - cryptojs/jsrsa
  • - *
  • SHA1withECDSA - cryptojs/jsrsa
  • - *
  • SHA224withECDSA - cryptojs/jsrsa
  • - *
  • SHA256withECDSA - cryptojs/jsrsa
  • - *
  • SHA384withECDSA - cryptojs/jsrsa
  • - *
  • SHA512withECDSA - cryptojs/jsrsa
  • - *
  • RIPEMD160withECDSA - cryptojs/jsrsa
  • - *
  • MD5withRSAandMGF1 - cryptojs/jsrsa
  • - *
  • SHA1withRSAandMGF1 - cryptojs/jsrsa
  • - *
  • SHA224withRSAandMGF1 - cryptojs/jsrsa
  • - *
  • SHA256withRSAandMGF1 - cryptojs/jsrsa
  • - *
  • SHA384withRSAandMGF1 - cryptojs/jsrsa
  • - *
  • SHA512withRSAandMGF1 - cryptojs/jsrsa
  • - *
  • RIPEMD160withRSAandMGF1 - cryptojs/jsrsa
  • - *
  • SHA1withDSA - cryptojs/jsrsa
  • - *
  • SHA224withDSA - cryptojs/jsrsa
  • - *
  • SHA256withDSA - cryptojs/jsrsa
  • - *
- * Here are supported elliptic cryptographic curve names and their aliases for ECDSA: - *
    - *
  • secp256k1
  • - *
  • secp256r1, NIST P-256, P-256, prime256v1
  • - *
  • secp384r1, NIST P-384, P-384
  • - *
- * NOTE1: DSA signing algorithm is also supported since crypto 1.1.5. - *

EXAMPLES

- * @example - * // RSA signature generation - * var sig = new KJUR.crypto.Signature({"alg": "SHA1withRSA"}); - * sig.init(prvKeyPEM); - * sig.updateString('aaa'); - * var hSigVal = sig.sign(); - * - * // DSA signature validation - * var sig2 = new KJUR.crypto.Signature({"alg": "SHA1withDSA"}); - * sig2.init(certPEM); - * sig.updateString('aaa'); - * var isValid = sig2.verify(hSigVal); - * - * // ECDSA signing - * var sig = new KJUR.crypto.Signature({'alg':'SHA1withECDSA'}); - * sig.init(prvKeyPEM); - * sig.updateString('aaa'); - * var sigValueHex = sig.sign(); - * - * // ECDSA verifying - * var sig2 = new KJUR.crypto.Signature({'alg':'SHA1withECDSA'}); - * sig.init(certPEM); - * sig.updateString('aaa'); - * var isValid = sig.verify(sigValueHex); - */ -KJUR.crypto.Signature = function(params) { - var prvKey = null; // RSAKey/KJUR.crypto.{ECDSA,DSA} object for signing - var pubKey = null; // RSAKey/KJUR.crypto.{ECDSA,DSA} object for verifying - - var md = null; // KJUR.crypto.MessageDigest object - var sig = null; - var algName = null; - var provName = null; - var algProvName = null; - var mdAlgName = null; - var pubkeyAlgName = null; // rsa,ecdsa,rsaandmgf1(=rsapss) - var state = null; - var pssSaltLen = -1; - var initParams = null; - - var sHashHex = null; // hex hash value for hex - var hDigestInfo = null; - var hPaddedDigestInfo = null; - var hSign = null; - - this._setAlgNames = function() { - if (this.algName.match(/^(.+)with(.+)$/)) { - this.mdAlgName = RegExp.$1.toLowerCase(); - this.pubkeyAlgName = RegExp.$2.toLowerCase(); - } - }; - - this._zeroPaddingOfSignature = function(hex, bitLength) { - var s = ""; - var nZero = bitLength / 4 - hex.length; - for (var i = 0; i < nZero; i++) { - s = s + "0"; - } - return s + hex; - }; - - /** - * set signature algorithm and provider - * @name setAlgAndProvider - * @memberOf KJUR.crypto.Signature - * @function - * @param {String} alg signature algorithm name - * @param {String} prov provider name - * @description - * @example - * md.setAlgAndProvider('SHA1withRSA', 'cryptojs/jsrsa'); - */ - this.setAlgAndProvider = function(alg, prov) { - this._setAlgNames(); - if (prov != 'cryptojs/jsrsa') - throw "provider not supported: " + prov; - - if (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(this.mdAlgName) != -1) { - try { - this.md = new KJUR.crypto.MessageDigest({'alg':this.mdAlgName}); - } catch (ex) { - throw "setAlgAndProvider hash alg set fail alg=" + - this.mdAlgName + "/" + ex; - } - - this.init = function(keyparam, pass) { - var keyObj = null; - try { - if (pass === undefined) { - keyObj = KEYUTIL.getKey(keyparam); - } else { - keyObj = KEYUTIL.getKey(keyparam, pass); - } - } catch (ex) { - throw "init failed:" + ex; - } - - if (keyObj.isPrivate === true) { - this.prvKey = keyObj; - this.state = "SIGN"; - } else if (keyObj.isPublic === true) { - this.pubKey = keyObj; - this.state = "VERIFY"; - } else { - throw "init failed.:" + keyObj; - } - }; - - this.initSign = function(params) { - if (typeof params['ecprvhex'] == 'string' && - typeof params['eccurvename'] == 'string') { - this.ecprvhex = params['ecprvhex']; - this.eccurvename = params['eccurvename']; - } else { - this.prvKey = params; - } - this.state = "SIGN"; - }; - - this.initVerifyByPublicKey = function(params) { - if (typeof params['ecpubhex'] == 'string' && - typeof params['eccurvename'] == 'string') { - this.ecpubhex = params['ecpubhex']; - this.eccurvename = params['eccurvename']; - } else if (params instanceof KJUR.crypto.ECDSA) { - this.pubKey = params; - } else if (params instanceof RSAKey) { - this.pubKey = params; - } - this.state = "VERIFY"; - }; - - this.initVerifyByCertificatePEM = function(certPEM) { - var x509 = new X509(); - x509.readCertPEM(certPEM); - this.pubKey = x509.subjectPublicKeyRSA; - this.state = "VERIFY"; - }; - - this.updateString = function(str) { - this.md.updateString(str); - }; - this.updateHex = function(hex) { - this.md.updateHex(hex); - }; - - this.sign = function() { - this.sHashHex = this.md.digest(); - if (typeof this.ecprvhex != "undefined" && - typeof this.eccurvename != "undefined") { - var ec = new KJUR.crypto.ECDSA({'curve': this.eccurvename}); - this.hSign = ec.signHex(this.sHashHex, this.ecprvhex); - } else if (this.pubkeyAlgName == "rsaandmgf1") { - this.hSign = this.prvKey.signWithMessageHashPSS(this.sHashHex, - this.mdAlgName, - this.pssSaltLen); - } else if (this.pubkeyAlgName == "rsa") { - this.hSign = this.prvKey.signWithMessageHash(this.sHashHex, - this.mdAlgName); - } else if (this.prvKey instanceof KJUR.crypto.ECDSA) { - this.hSign = this.prvKey.signWithMessageHash(this.sHashHex); - } else if (this.prvKey instanceof KJUR.crypto.DSA) { - this.hSign = this.prvKey.signWithMessageHash(this.sHashHex); - } else { - throw "Signature: unsupported public key alg: " + this.pubkeyAlgName; - } - return this.hSign; - }; - this.signString = function(str) { - this.updateString(str); - return this.sign(); - }; - this.signHex = function(hex) { - this.updateHex(hex); - return this.sign(); - }; - this.verify = function(hSigVal) { - this.sHashHex = this.md.digest(); - if (typeof this.ecpubhex != "undefined" && - typeof this.eccurvename != "undefined") { - var ec = new KJUR.crypto.ECDSA({curve: this.eccurvename}); - return ec.verifyHex(this.sHashHex, hSigVal, this.ecpubhex); - } else if (this.pubkeyAlgName == "rsaandmgf1") { - return this.pubKey.verifyWithMessageHashPSS(this.sHashHex, hSigVal, - this.mdAlgName, - this.pssSaltLen); - } else if (this.pubkeyAlgName == "rsa") { - return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal); - } else if (this.pubKey instanceof KJUR.crypto.ECDSA) { - return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal); - } else if (this.pubKey instanceof KJUR.crypto.DSA) { - return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal); - } else { - throw "Signature: unsupported public key alg: " + this.pubkeyAlgName; - } - }; - } - }; - - /** - * Initialize this object for signing or verifying depends on key - * @name init - * @memberOf KJUR.crypto.Signature - * @function - * @param {Object} key specifying public or private key as plain/encrypted PKCS#5/8 PEM file, certificate PEM or {@link RSAKey}, {@link KJUR.crypto.DSA} or {@link KJUR.crypto.ECDSA} object - * @param {String} pass (OPTION) passcode for encrypted private key - * @since crypto 1.1.3 - * @description - * This method is very useful initialize method for Signature class since - * you just specify key then this method will automatically initialize it - * using {@link KEYUTIL.getKey} method. - * As for 'key', following argument type are supported: - *
signing
- *
    - *
  • PEM formatted PKCS#8 encrypted RSA/ECDSA private key concluding "BEGIN ENCRYPTED PRIVATE KEY"
  • - *
  • PEM formatted PKCS#5 encrypted RSA/DSA private key concluding "BEGIN RSA/DSA PRIVATE KEY" and ",ENCRYPTED"
  • - *
  • PEM formatted PKCS#8 plain RSA/ECDSA private key concluding "BEGIN PRIVATE KEY"
  • - *
  • PEM formatted PKCS#5 plain RSA/DSA private key concluding "BEGIN RSA/DSA PRIVATE KEY" without ",ENCRYPTED"
  • - *
  • RSAKey object of private key
  • - *
  • KJUR.crypto.ECDSA object of private key
  • - *
  • KJUR.crypto.DSA object of private key
  • - *
- *
verification
- *
    - *
  • PEM formatted PKCS#8 RSA/EC/DSA public key concluding "BEGIN PUBLIC KEY"
  • - *
  • PEM formatted X.509 certificate with RSA/EC/DSA public key concluding - * "BEGIN CERTIFICATE", "BEGIN X509 CERTIFICATE" or "BEGIN TRUSTED CERTIFICATE".
  • - *
  • RSAKey object of public key
  • - *
  • KJUR.crypto.ECDSA object of public key
  • - *
  • KJUR.crypto.DSA object of public key
  • - *
- * @example - * sig.init(sCertPEM) - */ - this.init = function(key, pass) { - throw "init(key, pass) not supported for this alg:prov=" + - this.algProvName; - }; - - /** - * Initialize this object for verifying with a public key - * @name initVerifyByPublicKey - * @memberOf KJUR.crypto.Signature - * @function - * @param {Object} param RSAKey object of public key or associative array for ECDSA - * @since 1.0.2 - * @deprecated from crypto 1.1.5. please use init() method instead. - * @description - * Public key information will be provided as 'param' parameter and the value will be - * following: - *
    - *
  • {@link RSAKey} object for RSA verification
  • - *
  • associative array for ECDSA verification - * (ex. {'ecpubhex': '041f..', 'eccurvename': 'secp256r1'}) - *
  • - *
- * @example - * sig.initVerifyByPublicKey(rsaPrvKey) - */ - this.initVerifyByPublicKey = function(rsaPubKey) { - throw "initVerifyByPublicKey(rsaPubKeyy) not supported for this alg:prov=" + - this.algProvName; - }; - - /** - * Initialize this object for verifying with a certficate - * @name initVerifyByCertificatePEM - * @memberOf KJUR.crypto.Signature - * @function - * @param {String} certPEM PEM formatted string of certificate - * @since 1.0.2 - * @deprecated from crypto 1.1.5. please use init() method instead. - * @description - * @example - * sig.initVerifyByCertificatePEM(certPEM) - */ - this.initVerifyByCertificatePEM = function(certPEM) { - throw "initVerifyByCertificatePEM(certPEM) not supported for this alg:prov=" + - this.algProvName; - }; - - /** - * Initialize this object for signing - * @name initSign - * @memberOf KJUR.crypto.Signature - * @function - * @param {Object} param RSAKey object of public key or associative array for ECDSA - * @deprecated from crypto 1.1.5. please use init() method instead. - * @description - * Private key information will be provided as 'param' parameter and the value will be - * following: - *
    - *
  • {@link RSAKey} object for RSA signing
  • - *
  • associative array for ECDSA signing - * (ex. {'ecprvhex': '1d3f..', 'eccurvename': 'secp256r1'})
  • - *
- * @example - * sig.initSign(prvKey) - */ - this.initSign = function(prvKey) { - throw "initSign(prvKey) not supported for this alg:prov=" + this.algProvName; - }; - - /** - * Updates the data to be signed or verified by a string - * @name updateString - * @memberOf KJUR.crypto.Signature - * @function - * @param {String} str string to use for the update - * @description - * @example - * sig.updateString('aaa') - */ - this.updateString = function(str) { - throw "updateString(str) not supported for this alg:prov=" + this.algProvName; - }; - - /** - * Updates the data to be signed or verified by a hexadecimal string - * @name updateHex - * @memberOf KJUR.crypto.Signature - * @function - * @param {String} hex hexadecimal string to use for the update - * @description - * @example - * sig.updateHex('1f2f3f') - */ - this.updateHex = function(hex) { - throw "updateHex(hex) not supported for this alg:prov=" + this.algProvName; - }; - - /** - * Returns the signature bytes of all data updates as a hexadecimal string - * @name sign - * @memberOf KJUR.crypto.Signature - * @function - * @return the signature bytes as a hexadecimal string - * @description - * @example - * var hSigValue = sig.sign() - */ - this.sign = function() { - throw "sign() not supported for this alg:prov=" + this.algProvName; - }; - - /** - * performs final update on the sign using string, then returns the signature bytes of all data updates as a hexadecimal string - * @name signString - * @memberOf KJUR.crypto.Signature - * @function - * @param {String} str string to final update - * @return the signature bytes of a hexadecimal string - * @description - * @example - * var hSigValue = sig.signString('aaa') - */ - this.signString = function(str) { - throw "digestString(str) not supported for this alg:prov=" + this.algProvName; - }; - - /** - * performs final update on the sign using hexadecimal string, then returns the signature bytes of all data updates as a hexadecimal string - * @name signHex - * @memberOf KJUR.crypto.Signature - * @function - * @param {String} hex hexadecimal string to final update - * @return the signature bytes of a hexadecimal string - * @description - * @example - * var hSigValue = sig.signHex('1fdc33') - */ - this.signHex = function(hex) { - throw "digestHex(hex) not supported for this alg:prov=" + this.algProvName; - }; - - /** - * verifies the passed-in signature. - * @name verify - * @memberOf KJUR.crypto.Signature - * @function - * @param {String} str string to final update - * @return {Boolean} true if the signature was verified, otherwise false - * @description - * @example - * var isValid = sig.verify('1fbcefdca4823a7(snip)') - */ - this.verify = function(hSigVal) { - throw "verify(hSigVal) not supported for this alg:prov=" + this.algProvName; - }; - - this.initParams = params; - - if (params !== undefined) { - if (params['alg'] !== undefined) { - this.algName = params['alg']; - if (params['prov'] === undefined) { - this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName]; - } else { - this.provName = params['prov']; - } - this.algProvName = this.algName + ":" + this.provName; - this.setAlgAndProvider(this.algName, this.provName); - this._setAlgNames(); - } - - if (params['psssaltlen'] !== undefined) this.pssSaltLen = params['psssaltlen']; - - if (params['prvkeypem'] !== undefined) { - if (params['prvkeypas'] !== undefined) { - throw "both prvkeypem and prvkeypas parameters not supported"; - } else { - try { - var prvKey = new RSAKey(); - prvKey.readPrivateKeyFromPEMString(params['prvkeypem']); - this.initSign(prvKey); - } catch (ex) { - throw "fatal error to load pem private key: " + ex; - } - } - } - } -}; - -/** - * static object for cryptographic function utilities - * @name KJUR.crypto.OID - * @class static object for cryptography related OIDs - * @property {Array} oidhex2name key value of hexadecimal OID and its name - * (ex. '2a8648ce3d030107' and 'secp256r1') - * @since crypto 1.1.3 - * @description - */ - - -KJUR.crypto.OID = new function() { - this.oidhex2name = { - '2a864886f70d010101': 'rsaEncryption', - '2a8648ce3d0201': 'ecPublicKey', - '2a8648ce380401': 'dsa', - '2a8648ce3d030107': 'secp256r1', - '2b8104001f': 'secp192k1', - '2b81040021': 'secp224r1', - '2b8104000a': 'secp256k1', - '2b81040023': 'secp521r1', - '2b81040022': 'secp384r1', - '2a8648ce380403': 'SHA1withDSA', // 1.2.840.10040.4.3 - '608648016503040301': 'SHA224withDSA', // 2.16.840.1.101.3.4.3.1 - '608648016503040302': 'SHA256withDSA', // 2.16.840.1.101.3.4.3.2 - }; -}; - -/*! base64x-1.1.3 (c) 2012-2014 Kenji Urushima | kjur.github.com/jsjws/license - */ -/* - * base64x.js - Base64url and supplementary functions for Tom Wu's base64.js library - * - * version: 1.1.3 (2014 May 25) - * - * Copyright (c) 2012-2014 Kenji Urushima (kenji.urushima@gmail.com) - * - * This software is licensed under the terms of the MIT License. - * http://kjur.github.com/jsjws/license/ - * - * The above copyright and license notice shall be - * included in all copies or substantial portions of the Software. - * - * DEPENDS ON: - * - base64.js - Tom Wu's Base64 library - */ - -/** - * Base64URL and supplementary functions for Tom Wu's base64.js library.
- * This class is just provide information about global functions - * defined in 'base64x.js'. The 'base64x.js' script file provides - * global functions for converting following data each other. - *
    - *
  • (ASCII) String
  • - *
  • UTF8 String including CJK, Latin and other characters
  • - *
  • byte array
  • - *
  • hexadecimal encoded String
  • - *
  • Full URIComponent encoded String (such like "%69%94")
  • - *
  • Base64 encoded String
  • - *
  • Base64URL encoded String
  • - *
- * All functions in 'base64x.js' are defined in {@link _global_} and not - * in this class. - * - * @class Base64URL and supplementary functions for Tom Wu's base64.js library - * @author Kenji Urushima - * @version 1.1 (07 May 2012) - * @requires base64.js - * @see 'jwjws'(JWS JavaScript Library) home page http://kjur.github.com/jsjws/ - * @see 'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/ - */ -function Base64x() { -} - -// ==== string / byte array ================================ -/** - * convert a string to an array of character codes - * @param {String} s - * @return {Array of Numbers} - */ -function stoBA(s) { - var a = new Array(); - for (var i = 0; i < s.length; i++) { - a[i] = s.charCodeAt(i); - } - return a; -} - -/** - * convert an array of character codes to a string - * @param {Array of Numbers} a array of character codes - * @return {String} s - */ -function BAtos(a) { - var s = ""; - for (var i = 0; i < a.length; i++) { - s = s + String.fromCharCode(a[i]); - } - return s; -} - -// ==== byte array / hex ================================ -/** - * convert an array of bytes(Number) to hexadecimal string.
- * @param {Array of Numbers} a array of bytes - * @return {String} hexadecimal string - */ -function BAtohex(a) { - var s = ""; - for (var i = 0; i < a.length; i++) { - var hex1 = a[i].toString(16); - if (hex1.length == 1) hex1 = "0" + hex1; - s = s + hex1; - } - return s; -} - -// ==== string / hex ================================ -/** - * convert a ASCII string to a hexadecimal string of ASCII codes.
- * NOTE: This can't be used for non ASCII characters. - * @param {s} s ASCII string - * @return {String} hexadecimal string - */ -function stohex(s) { - return BAtohex(stoBA(s)); -} - -// ==== string / base64 ================================ -/** - * convert a ASCII string to a Base64 encoded string.
- * NOTE: This can't be used for non ASCII characters. - * @param {s} s ASCII string - * @return {String} Base64 encoded string - */ -function stob64(s) { - return hex2b64(stohex(s)); -} - -// ==== string / base64url ================================ -/** - * convert a ASCII string to a Base64URL encoded string.
- * NOTE: This can't be used for non ASCII characters. - * @param {s} s ASCII string - * @return {String} Base64URL encoded string - */ -function stob64u(s) { - return b64tob64u(hex2b64(stohex(s))); -} - -/** - * convert a Base64URL encoded string to a ASCII string.
- * NOTE: This can't be used for Base64URL encoded non ASCII characters. - * @param {s} s Base64URL encoded string - * @return {String} ASCII string - */ -function b64utos(s) { - return BAtos(b64toBA(b64utob64(s))); -} - -// ==== base64 / base64url ================================ -/** - * convert a Base64 encoded string to a Base64URL encoded string.
- * Example: "ab+c3f/==" → "ab-c3f_" - * @param {String} s Base64 encoded string - * @return {String} Base64URL encoded string - */ -function b64tob64u(s) { - s = s.replace(/\=/g, ""); - s = s.replace(/\+/g, "-"); - s = s.replace(/\//g, "_"); - return s; -} - -/** - * convert a Base64URL encoded string to a Base64 encoded string.
- * Example: "ab-c3f_" → "ab+c3f/==" - * @param {String} s Base64URL encoded string - * @return {String} Base64 encoded string - */ -function b64utob64(s) { - if (s.length % 4 == 2) s = s + "=="; - else if (s.length % 4 == 3) s = s + "="; - s = s.replace(/-/g, "+"); - s = s.replace(/_/g, "/"); - return s; -} - -// ==== hex / base64url ================================ -/** - * convert a hexadecimal string to a Base64URL encoded string.
- * @param {String} s hexadecimal string - * @return {String} Base64URL encoded string - */ -function hextob64u(s) { - return b64tob64u(hex2b64(s)); -} - -/** - * convert a Base64URL encoded string to a hexadecimal string.
- * @param {String} s Base64URL encoded string - * @return {String} hexadecimal string - */ -function b64utohex(s) { - return b64tohex(b64utob64(s)); -} - -var utf8tob64u, b64utoutf8; - -if (typeof Buffer === 'function') -{ - utf8tob64u = function (s) - { - return b64tob64u(new Buffer(s, 'utf8').toString('base64')); - }; - - b64utoutf8 = function (s) - { - return new Buffer(b64utob64(s), 'base64').toString('utf8'); - }; -} -else -{ -// ==== utf8 / base64url ================================ -/** - * convert a UTF-8 encoded string including CJK or Latin to a Base64URL encoded string.
- * @param {String} s UTF-8 encoded string - * @return {String} Base64URL encoded string - * @since 1.1 - */ - utf8tob64u = function (s) - { - return hextob64u(uricmptohex(encodeURIComponentAll(s))); - }; - -/** - * convert a Base64URL encoded string to a UTF-8 encoded string including CJK or Latin.
- * @param {String} s Base64URL encoded string - * @return {String} UTF-8 encoded string - * @since 1.1 - */ - b64utoutf8 = function (s) - { - return decodeURIComponent(hextouricmp(b64utohex(s))); - }; -} - -// ==== utf8 / base64url ================================ -/** - * convert a UTF-8 encoded string including CJK or Latin to a Base64 encoded string.
- * @param {String} s UTF-8 encoded string - * @return {String} Base64 encoded string - * @since 1.1.1 - */ -function utf8tob64(s) { - return hex2b64(uricmptohex(encodeURIComponentAll(s))); -} - -/** - * convert a Base64 encoded string to a UTF-8 encoded string including CJK or Latin.
- * @param {String} s Base64 encoded string - * @return {String} UTF-8 encoded string - * @since 1.1.1 - */ -function b64toutf8(s) { - return decodeURIComponent(hextouricmp(b64tohex(s))); -} - -// ==== utf8 / hex ================================ -/** - * convert a UTF-8 encoded string including CJK or Latin to a hexadecimal encoded string.
- * @param {String} s UTF-8 encoded string - * @return {String} hexadecimal encoded string - * @since 1.1.1 - */ -function utf8tohex(s) { - return uricmptohex(encodeURIComponentAll(s)); -} - -/** - * convert a hexadecimal encoded string to a UTF-8 encoded string including CJK or Latin.
- * Note that when input is improper hexadecimal string as UTF-8 string, this function returns - * 'null'. - * @param {String} s hexadecimal encoded string - * @return {String} UTF-8 encoded string or null - * @since 1.1.1 - */ -function hextoutf8(s) { - return decodeURIComponent(hextouricmp(s)); -} - -/** - * convert a hexadecimal encoded string to raw string including non printable characters.
- * @param {String} s hexadecimal encoded string - * @return {String} raw string - * @since 1.1.2 - * @example - * hextorstr("610061") → "a\x00a" - */ -function hextorstr(sHex) { - var s = ""; - for (var i = 0; i < sHex.length - 1; i += 2) { - s += String.fromCharCode(parseInt(sHex.substr(i, 2), 16)); - } - return s; -} - -/** - * convert a raw string including non printable characters to hexadecimal encoded string.
- * @param {String} s raw string - * @return {String} hexadecimal encoded string - * @since 1.1.2 - * @example - * rstrtohex("a\x00a") → "610061" - */ -function rstrtohex(s) { - var result = ""; - for (var i = 0; i < s.length; i++) { - result += ("0" + s.charCodeAt(i).toString(16)).slice(-2); - } - return result; -} - -// ==== hex / b64nl ======================================= - -/* - * since base64x 1.1.3 - */ -function hextob64(s) { - return hex2b64(s); -} - -/* - * since base64x 1.1.3 - */ -function hextob64nl(s) { - var b64 = hextob64(s); - var b64nl = b64.replace(/(.{64})/g, "$1\r\n"); - b64nl = b64nl.replace(/\r\n$/, ''); - return b64nl; -} - -/* - * since base64x 1.1.3 - */ -function b64nltohex(s) { - var b64 = s.replace(/[^0-9A-Za-z\/+=]*/g, ''); - var hex = b64tohex(b64); - return hex; -} - -// ==== URIComponent / hex ================================ -/** - * convert a URLComponent string such like "%67%68" to a hexadecimal string.
- * @param {String} s URIComponent string such like "%67%68" - * @return {String} hexadecimal string - * @since 1.1 - */ -function uricmptohex(s) { - return s.replace(/%/g, ""); -} - -/** - * convert a hexadecimal string to a URLComponent string such like "%67%68".
- * @param {String} s hexadecimal string - * @return {String} URIComponent string such like "%67%68" - * @since 1.1 - */ -function hextouricmp(s) { - return s.replace(/(..)/g, "%$1"); -} - -// ==== URIComponent ================================ -/** - * convert UTFa hexadecimal string to a URLComponent string such like "%67%68".
- * Note that these "0-9A-Za-z!'()*-._~" characters will not - * converted to "%xx" format by builtin 'encodeURIComponent()' function. - * However this 'encodeURIComponentAll()' function will convert - * all of characters into "%xx" format. - * @param {String} s hexadecimal string - * @return {String} URIComponent string such like "%67%68" - * @since 1.1 - */ -function encodeURIComponentAll(u8) { - var s = encodeURIComponent(u8); - var s2 = ""; - for (var i = 0; i < s.length; i++) { - if (s[i] == "%") { - s2 = s2 + s.substr(i, 3); - i = i + 2; - } else { - s2 = s2 + "%" + stohex(s[i]); - } - } - return s2; -} - -// ==== new lines ================================ -/** - * convert all DOS new line("\r\n") to UNIX new line("\n") in - * a String "s". - * @param {String} s string - * @return {String} converted string - */ -function newline_toUnix(s) { - s = s.replace(/\r\n/mg, "\n"); - return s; -} - -/** - * convert all UNIX new line("\r\n") to DOS new line("\n") in - * a String "s". - * @param {String} s string - * @return {String} converted string - */ -function newline_toDos(s) { - s = s.replace(/\r\n/mg, "\n"); - s = s.replace(/\n/mg, "\r\n"); - return s; -} - -/*! Mike Samuel (c) 2009 | code.google.com/p/json-sans-eval - */ -// This source code is free for use in the public domain. -// NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - -// http://code.google.com/p/json-sans-eval/ - -/** - * Parses a string of well-formed JSON text. - * - * If the input is not well-formed, then behavior is undefined, but it is - * deterministic and is guaranteed not to modify any object other than its - * return value. - * - * This does not use `eval` so is less likely to have obscure security bugs than - * json2.js. - * It is optimized for speed, so is much faster than json_parse.js. - * - * This library should be used whenever security is a concern (when JSON may - * come from an untrusted source), speed is a concern, and erroring on malformed - * JSON is *not* a concern. - * - * Pros Cons - * +-----------------------+-----------------------+ - * json_sans_eval.js | Fast, secure | Not validating | - * +-----------------------+-----------------------+ - * json_parse.js | Validating, secure | Slow | - * +-----------------------+-----------------------+ - * json2.js | Fast, some validation | Potentially insecure | - * +-----------------------+-----------------------+ - * - * json2.js is very fast, but potentially insecure since it calls `eval` to - * parse JSON data, so an attacker might be able to supply strange JS that - * looks like JSON, but that executes arbitrary javascript. - * If you do have to use json2.js with untrusted data, make sure you keep - * your version of json2.js up to date so that you get patches as they're - * released. - * - * @param {string} json per RFC 4627 - * @param {function (this:Object, string, *):*} opt_reviver optional function - * that reworks JSON objects post-parse per Chapter 15.12 of EcmaScript3.1. - * If supplied, the function is called with a string key, and a value. - * The value is the property of 'this'. The reviver should return - * the value to use in its place. So if dates were serialized as - * {@code { "type": "Date", "time": 1234 }}, then a reviver might look like - * {@code - * function (key, value) { - * if (value && typeof value === 'object' && 'Date' === value.type) { - * return new Date(value.time); - * } else { - * return value; - * } - * }}. - * If the reviver returns {@code undefined} then the property named by key - * will be deleted from its container. - * {@code this} is bound to the object containing the specified property. - * @return {Object|Array} - * @author Mike Samuel - */ -var jsonParse = (function () { - var number - = '(?:-?\\b(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b)'; - var oneChar = '(?:[^\\0-\\x08\\x0a-\\x1f\"\\\\]' - + '|\\\\(?:[\"/\\\\bfnrt]|u[0-9A-Fa-f]{4}))'; - var string = '(?:\"' + oneChar + '*\")'; - - // Will match a value in a well-formed JSON file. - // If the input is not well-formed, may match strangely, but not in an unsafe - // way. - // Since this only matches value tokens, it does not match whitespace, colons, - // or commas. - var jsonToken = new RegExp( - '(?:false|true|null|[\\{\\}\\[\\]]' - + '|' + number - + '|' + string - + ')', 'g'); - - // Matches escape sequences in a string literal - var escapeSequence = new RegExp('\\\\(?:([^u])|u(.{4}))', 'g'); - - // Decodes escape sequences in object literals - var escapes = { - '"': '"', - '/': '/', - '\\': '\\', - 'b': '\b', - 'f': '\f', - 'n': '\n', - 'r': '\r', - 't': '\t' - }; - function unescapeOne(_, ch, hex) { - return ch ? escapes[ch] : String.fromCharCode(parseInt(hex, 16)); - } - - // A non-falsy value that coerces to the empty string when used as a key. - var EMPTY_STRING = new String(''); - var SLASH = '\\'; - - // Constructor to use based on an open token. - var firstTokenCtors = { '{': Object, '[': Array }; - - var hop = Object.hasOwnProperty; - - return function (json, opt_reviver) { - // Split into tokens - var toks = json.match(jsonToken); - // Construct the object to return - var result; - var tok = toks[0]; - var topLevelPrimitive = false; - if ('{' === tok) { - result = {}; - } else if ('[' === tok) { - result = []; - } else { - // The RFC only allows arrays or objects at the top level, but the JSON.parse - // defined by the EcmaScript 5 draft does allow strings, booleans, numbers, and null - // at the top level. - result = []; - topLevelPrimitive = true; - } - - // If undefined, the key in an object key/value record to use for the next - // value parsed. - var key; - // Loop over remaining tokens maintaining a stack of uncompleted objects and - // arrays. - var stack = [result]; - for (var i = 1 - topLevelPrimitive, n = toks.length; i < n; ++i) { - tok = toks[i]; - - var cont; - switch (tok.charCodeAt(0)) { - default: // sign or digit - cont = stack[0]; - cont[key || cont.length] = +(tok); - key = void 0; - break; - case 0x22: // '"' - tok = tok.substring(1, tok.length - 1); - if (tok.indexOf(SLASH) !== -1) { - tok = tok.replace(escapeSequence, unescapeOne); - } - cont = stack[0]; - if (!key) { - if (cont instanceof Array) { - key = cont.length; - } else { - key = tok || EMPTY_STRING; // Use as key for next value seen. - break; - } - } - cont[key] = tok; - key = void 0; - break; - case 0x5b: // '[' - cont = stack[0]; - stack.unshift(cont[key || cont.length] = []); - key = void 0; - break; - case 0x5d: // ']' - stack.shift(); - break; - case 0x66: // 'f' - cont = stack[0]; - cont[key || cont.length] = false; - key = void 0; - break; - case 0x6e: // 'n' - cont = stack[0]; - cont[key || cont.length] = null; - key = void 0; - break; - case 0x74: // 't' - cont = stack[0]; - cont[key || cont.length] = true; - key = void 0; - break; - case 0x7b: // '{' - cont = stack[0]; - stack.unshift(cont[key || cont.length] = {}); - key = void 0; - break; - case 0x7d: // '}' - stack.shift(); - break; - } - } - // Fail if we've got an uncompleted object. - if (topLevelPrimitive) { - if (stack.length !== 1) { throw new Error(); } - result = result[0]; - } else { - if (stack.length) { throw new Error(); } - } - - if (opt_reviver) { - // Based on walk as implemented in http://www.json.org/json2.js - var walk = function (holder, key) { - var value = holder[key]; - if (value && typeof value === 'object') { - var toDelete = null; - for (var k in value) { - if (hop.call(value, k) && value !== holder) { - // Recurse to properties first. This has the effect of causing - // the reviver to be called on the object graph depth-first. - - // Since 'this' is bound to the holder of the property, the - // reviver can access sibling properties of k including ones - // that have not yet been revived. - - // The value returned by the reviver is used in place of the - // current value of property k. - // If it returns undefined then the property is deleted. - var v = walk(value, k); - if (v !== void 0) { - value[k] = v; - } else { - // Deleting properties inside the loop has vaguely defined - // semantics in ES3 and ES3.1. - if (!toDelete) { toDelete = []; } - toDelete.push(k); - } - } - } - if (toDelete) { - for (var i = toDelete.length; --i >= 0;) { - delete value[toDelete[i]]; - } - } - } - return opt_reviver.call(holder, key, value); - }; - result = walk({ '': result }, ''); - } - - return result; - }; -})(); - -/*! jws-3.0.2 (c) 2013 Kenji Urushima | kjur.github.com/jsjws/license - */ -/* - * jws.js - JSON Web Signature Class - * - * version: 3.0.2 (2013 Sep 24) - * - * Copyright (c) 2010-2013 Kenji Urushima (kenji.urushima@gmail.com) - * - * This software is licensed under the terms of the MIT License. - * http://kjur.github.com/jsjws/license/ - * - * The above copyright and license notice shall be - * included in all copies or substantial portions of the Software. - */ - -/** - * @fileOverview - * @name jws-3.0.js - * @author Kenji Urushima kenji.urushima@gmail.com - * @version 3.0.1 (2013-Sep-24) - * @since jsjws 1.0 - * @license MIT License - */ - -if (typeof KJUR == "undefined" || !KJUR) KJUR = {}; -if (typeof KJUR.jws == "undefined" || !KJUR.jws) KJUR.jws = {}; - -/** - * JSON Web Signature(JWS) class.
- * @name KJUR.jws.JWS - * @class JSON Web Signature(JWS) class - * @property {Dictionary} parsedJWS This property is set after JWS signature verification.
- * Following "parsedJWS_*" properties can be accessed as "parsedJWS.*" because of - * JsDoc restriction. - * @property {String} parsedJWS_headB64U string of Encrypted JWS Header - * @property {String} parsedJWS_payloadB64U string of Encrypted JWS Payload - * @property {String} parsedJWS_sigvalB64U string of Encrypted JWS signature value - * @property {String} parsedJWS_si string of Signature Input - * @property {String} parsedJWS_sigvalH hexadecimal string of JWS signature value - * @property {String} parsedJWS_sigvalBI BigInteger(defined in jsbn.js) object of JWS signature value - * @property {String} parsedJWS_headS string of decoded JWS Header - * @property {String} parsedJWS_headS string of decoded JWS Payload - * @requires base64x.js, json-sans-eval.js and jsrsasign library - * @see 'jwjws'(JWS JavaScript Library) home page http://kjur.github.com/jsjws/ - * @see 'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/ - * @see IETF I-D JSON Web Algorithms (JWA) - * @since jsjws 1.0 - * @description - *

Supported Algorithms

- * Here is supported algorithm names for {@link KJUR.jws.JWS.sign} and {@link KJUR.jws.JWS.verify} - * methods. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
alg valuespec requirementjsjws support
HS256REQUIREDSUPPORTED
HS384OPTIONALSUPPORTED
HS512OPTIONALSUPPORTED
RS256RECOMMENDEDSUPPORTED
RS384OPTIONALSUPPORTED
RS512OPTIONALSUPPORTED
ES256RECOMMENDED+SUPPORTED
ES384OPTIONALSUPPORTED
ES512OPTIONAL-
PS256OPTIONALSUPPORTED
PS384OPTIONALSUPPORTED
PS512OPTIONALSUPPORTED
noneREQUIREDSUPPORTED
- * NOTE: HS384 is supported since jsjws 3.0.2 with jsrsasign 4.1.4. - */ -KJUR.jws.JWS = function() { - - // === utility ============================================================= - - /** - * parse JWS string and set public property 'parsedJWS' dictionary.
- * @name parseJWS - * @memberOf KJUR.jws.JWS - * @function - * @param {String} sJWS JWS signature string to be parsed. - * @throws if sJWS is not comma separated string such like "Header.Payload.Signature". - * @throws if JWS Header is a malformed JSON string. - * @since jws 1.1 - */ - this.parseJWS = function(sJWS, sigValNotNeeded) { - if ((this.parsedJWS !== undefined) && - (sigValNotNeeded || (this.parsedJWS.sigvalH !== undefined))) { - return; - } - if (sJWS.match(/^([^.]+)\.([^.]+)\.([^.]+)$/) == null) { - throw "JWS signature is not a form of 'Head.Payload.SigValue'."; - } - var b6Head = RegExp.$1; - var b6Payload = RegExp.$2; - var b6SigVal = RegExp.$3; - var sSI = b6Head + "." + b6Payload; - this.parsedJWS = {}; - this.parsedJWS.headB64U = b6Head; - this.parsedJWS.payloadB64U = b6Payload; - this.parsedJWS.sigvalB64U = b6SigVal; - this.parsedJWS.si = sSI; - - if (!sigValNotNeeded) { - var hSigVal = b64utohex(b6SigVal); - var biSigVal = parseBigInt(hSigVal, 16); - this.parsedJWS.sigvalH = hSigVal; - this.parsedJWS.sigvalBI = biSigVal; - } - - var sHead = b64utoutf8(b6Head); - var sPayload = b64utoutf8(b6Payload); - this.parsedJWS.headS = sHead; - this.parsedJWS.payloadS = sPayload; - - if (!KJUR.jws.JWS.isSafeJSONString(sHead, this.parsedJWS, 'headP')) - throw "malformed JSON string for JWS Head: " + sHead; - }; - - // ==== JWS Validation ========================================================= - function _getSignatureInputByString(sHead, sPayload) { - return utf8tob64u(sHead) + "." + utf8tob64u(sPayload); - }; - - function _getHashBySignatureInput(sSignatureInput, sHashAlg) { - var hashfunc = function(s) { return KJUR.crypto.Util.hashString(s, sHashAlg); }; - if (hashfunc == null) throw "hash function not defined in jsrsasign: " + sHashAlg; - return hashfunc(sSignatureInput); - }; - - function _jws_verifySignature(sHead, sPayload, hSig, hN, hE) { - var sSignatureInput = _getSignatureInputByString(sHead, sPayload); - var biSig = parseBigInt(hSig, 16); - return _rsasign_verifySignatureWithArgs(sSignatureInput, biSig, hN, hE); - }; - - /** - * verify JWS signature with naked RSA public key.
- * This only supports "RS256" and "RS512" algorithm. - * @name verifyJWSByNE - * @memberOf KJUR.jws.JWS - * @function - * @param {String} sJWS JWS signature string to be verified - * @param {String} hN hexadecimal string for modulus of RSA public key - * @param {String} hE hexadecimal string for public exponent of RSA public key - * @return {String} returns 1 when JWS signature is valid, otherwise returns 0 - * @throws if sJWS is not comma separated string such like "Header.Payload.Signature". - * @throws if JWS Header is a malformed JSON string. - * @deprecated from 3.0.0 please move to {@link KJUR.jws.JWS.verify} - */ - this.verifyJWSByNE = function(sJWS, hN, hE) { - this.parseJWS(sJWS); - return _rsasign_verifySignatureWithArgs(this.parsedJWS.si, this.parsedJWS.sigvalBI, hN, hE); - }; - - /** - * verify JWS signature with RSA public key.
- * This only supports "RS256", "RS512", "PS256" and "PS512" algorithms. - * @name verifyJWSByKey - * @memberOf KJUR.jws.JWS - * @function - * @param {String} sJWS JWS signature string to be verified - * @param {RSAKey} key RSA public key - * @return {Boolean} returns true when JWS signature is valid, otherwise returns false - * @throws if sJWS is not comma separated string such like "Header.Payload.Signature". - * @throws if JWS Header is a malformed JSON string. - * @deprecated from 3.0.0 please move to {@link KJUR.jws.JWS.verify} - */ - this.verifyJWSByKey = function(sJWS, key) { - this.parseJWS(sJWS); - var hashAlg = _jws_getHashAlgFromParsedHead(this.parsedJWS.headP); - var isPSS = this.parsedJWS.headP['alg'].substr(0, 2) == "PS"; - - if (key.hashAndVerify) { - return key.hashAndVerify(hashAlg, - new Buffer(this.parsedJWS.si, 'utf8').toString('base64'), - b64utob64(this.parsedJWS.sigvalB64U), - 'base64', - isPSS); - } else if (isPSS) { - return key.verifyStringPSS(this.parsedJWS.si, - this.parsedJWS.sigvalH, hashAlg); - } else { - return key.verifyString(this.parsedJWS.si, - this.parsedJWS.sigvalH); - } - }; - - /** - * verify JWS signature by PEM formatted X.509 certificate.
- * This only supports "RS256" and "RS512" algorithm. - * @name verifyJWSByPemX509Cert - * @memberOf KJUR.jws.JWS - * @function - * @param {String} sJWS JWS signature string to be verified - * @param {String} sPemX509Cert string of PEM formatted X.509 certificate - * @return {String} returns 1 when JWS signature is valid, otherwise returns 0 - * @throws if sJWS is not comma separated string such like "Header.Payload.Signature". - * @throws if JWS Header is a malformed JSON string. - * @since 1.1 - * @deprecated from 3.0.0 please move to {@link KJUR.jws.JWS.verify} - */ - this.verifyJWSByPemX509Cert = function(sJWS, sPemX509Cert) { - this.parseJWS(sJWS); - var x509 = new X509(); - x509.readCertPEM(sPemX509Cert); - return x509.subjectPublicKeyRSA.verifyString(this.parsedJWS.si, this.parsedJWS.sigvalH); - }; - - // ==== JWS Generation ========================================================= - function _jws_getHashAlgFromParsedHead(head) { - var sigAlg = head["alg"]; - var hashAlg = ""; - - if (sigAlg != "RS256" && sigAlg != "RS512" && - sigAlg != "PS256" && sigAlg != "PS512") - throw "JWS signature algorithm not supported: " + sigAlg; - if (sigAlg.substr(2) == "256") hashAlg = "sha256"; - if (sigAlg.substr(2) == "512") hashAlg = "sha512"; - return hashAlg; - }; - - function _jws_getHashAlgFromHead(sHead) { - return _jws_getHashAlgFromParsedHead(jsonParse(sHead)); - }; - - function _jws_generateSignatureValueBySI_NED(sHead, sPayload, sSI, hN, hE, hD) { - var rsa = new RSAKey(); - rsa.setPrivate(hN, hE, hD); - - var hashAlg = _jws_getHashAlgFromHead(sHead); - var sigValue = rsa.signString(sSI, hashAlg); - return sigValue; - }; - - function _jws_generateSignatureValueBySI_Key(sHead, sPayload, sSI, key, head) { - var hashAlg = null; - if (typeof head == "undefined") { - hashAlg = _jws_getHashAlgFromHead(sHead); - } else { - hashAlg = _jws_getHashAlgFromParsedHead(head); - } - - var isPSS = head['alg'].substr(0, 2) == "PS"; - - if (key.hashAndSign) { - return b64tob64u(key.hashAndSign(hashAlg, sSI, 'binary', 'base64', isPSS)); - } else if (isPSS) { - return hextob64u(key.signStringPSS(sSI, hashAlg)); - } else { - return hextob64u(key.signString(sSI, hashAlg)); - } - }; - - function _jws_generateSignatureValueByNED(sHead, sPayload, hN, hE, hD) { - var sSI = _getSignatureInputByString(sHead, sPayload); - return _jws_generateSignatureValueBySI_NED(sHead, sPayload, sSI, hN, hE, hD); - }; - - /** - * generate JWS signature by Header, Payload and a naked RSA private key.
- * This only supports "RS256" and "RS512" algorithm. - * @name generateJWSByNED - * @memberOf KJUR.jws.JWS - * @function - * @param {String} sHead string of JWS Header - * @param {String} sPayload string of JWS Payload - * @param {String} hN hexadecimal string for modulus of RSA public key - * @param {String} hE hexadecimal string for public exponent of RSA public key - * @param {String} hD hexadecimal string for private exponent of RSA private key - * @return {String} JWS signature string - * @throws if sHead is a malformed JSON string. - * @throws if supported signature algorithm was not specified in JSON Header. - * @deprecated from 3.0.0 please move to {@link KJUR.jws.JWS.sign} - */ - this.generateJWSByNED = function(sHead, sPayload, hN, hE, hD) { - if (!KJUR.jws.JWS.isSafeJSONString(sHead)) throw "JWS Head is not safe JSON string: " + sHead; - var sSI = _getSignatureInputByString(sHead, sPayload); - var hSigValue = _jws_generateSignatureValueBySI_NED(sHead, sPayload, sSI, hN, hE, hD); - var b64SigValue = hextob64u(hSigValue); - - this.parsedJWS = {}; - this.parsedJWS.headB64U = sSI.split(".")[0]; - this.parsedJWS.payloadB64U = sSI.split(".")[1]; - this.parsedJWS.sigvalB64U = b64SigValue; - - return sSI + "." + b64SigValue; - }; - - /** - * generate JWS signature by Header, Payload and a RSA private key.
- * This only supports "RS256", "RS512", "PS256" and "PS512" algorithms. - * @name generateJWSByKey - * @memberOf KJUR.jws.JWS - * @function - * @param {String} sHead string of JWS Header - * @param {String} sPayload string of JWS Payload - * @param {RSAKey} RSA private key - * @return {String} JWS signature string - * @throws if sHead is a malformed JSON string. - * @throws if supported signature algorithm was not specified in JSON Header. - * @deprecated from 3.0.0 please move to {@link KJUR.jws.JWS.sign} - */ - this.generateJWSByKey = function(sHead, sPayload, key) { - var obj = {}; - if (!KJUR.jws.JWS.isSafeJSONString(sHead, obj, 'headP')) - throw "JWS Head is not safe JSON string: " + sHead; - var sSI = _getSignatureInputByString(sHead, sPayload); - var b64SigValue = _jws_generateSignatureValueBySI_Key(sHead, sPayload, sSI, key, obj.headP); - - this.parsedJWS = {}; - this.parsedJWS.headB64U = sSI.split(".")[0]; - this.parsedJWS.payloadB64U = sSI.split(".")[1]; - this.parsedJWS.sigvalB64U = b64SigValue; - - return sSI + "." + b64SigValue; - }; - - // === sign with PKCS#1 RSA private key ===================================================== - function _jws_generateSignatureValueBySI_PemPrvKey(sHead, sPayload, sSI, sPemPrvKey) { - var rsa = new RSAKey(); - rsa.readPrivateKeyFromPEMString(sPemPrvKey); - var hashAlg = _jws_getHashAlgFromHead(sHead); - var sigValue = rsa.signString(sSI, hashAlg); - return sigValue; - }; - - /** - * generate JWS signature by Header, Payload and a PEM formatted PKCS#1 RSA private key.
- * This only supports "RS256" and "RS512" algorithm. - * @name generateJWSByP1PrvKey - * @memberOf KJUR.jws.JWS - * @function - * @param {String} sHead string of JWS Header - * @param {String} sPayload string of JWS Payload - * @param {String} string for sPemPrvKey PEM formatted PKCS#1 RSA private key
- * Heading and trailing space characters in PEM key will be ignored. - * @return {String} JWS signature string - * @throws if sHead is a malformed JSON string. - * @throws if supported signature algorithm was not specified in JSON Header. - * @since 1.1 - * @deprecated from 3.0.0 please move to {@link KJUR.jws.JWS.sign} - */ - this.generateJWSByP1PrvKey = function(sHead, sPayload, sPemPrvKey) { - if (!KJUR.jws.JWS.isSafeJSONString(sHead)) throw "JWS Head is not safe JSON string: " + sHead; - var sSI = _getSignatureInputByString(sHead, sPayload); - var hSigValue = _jws_generateSignatureValueBySI_PemPrvKey(sHead, sPayload, sSI, sPemPrvKey); - var b64SigValue = hextob64u(hSigValue); - - this.parsedJWS = {}; - this.parsedJWS.headB64U = sSI.split(".")[0]; - this.parsedJWS.payloadB64U = sSI.split(".")[1]; - this.parsedJWS.sigvalB64U = b64SigValue; - - return sSI + "." + b64SigValue; - }; -}; - -// === major static method ======================================================== - -/** - * generate JWS signature by specified key
- * @name sign - * @memberOf KJUR.jws.JWS - * @function - * @static - * @param {String} alg JWS algorithm name to sign and force set to sHead or null - * @param {String} sHead string of JWS Header - * @param {String} sPayload string of JWS Payload - * @param {String} key string of private key or key object to sign - * @param {String} pass (OPTION)passcode to use encrypted private key - * @return {String} JWS signature string - * @since jws 3.0.0 - * @see jsrsasign KJUR.crypto.Signature method - * @see jsrsasign KJUR.crypto.Mac method - * @description - * This method supports following algorithms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
alg valuespec requirementjsjws support
HS256REQUIREDSUPPORTED
HS384OPTIONAL-
HS512OPTIONALSUPPORTED
RS256RECOMMENDEDSUPPORTED
RS384OPTIONALSUPPORTED
RS512OPTIONALSUPPORTED
ES256RECOMMENDED+SUPPORTED
ES384OPTIONALSUPPORTED
ES512OPTIONAL-
PS256OPTIONALSUPPORTED
PS384OPTIONALSUPPORTED
PS512OPTIONALSUPPORTED
noneREQUIREDSUPPORTED
- *
- *
NOTE1: - *
salt length of RSAPSS signature is the same as the hash algorithm length - * because of IETF JOSE ML discussion. - *
NOTE2: - *
The reason of HS384 unsupport is - * CryptoJS HmacSHA384 bug. - *
- */ -KJUR.jws.JWS.sign = function(alg, sHeader, sPayload, key, pass) { - var ns1 = KJUR.jws.JWS; - - if (! ns1.isSafeJSONString(sHeader)) - throw "JWS Head is not safe JSON string: " + sHead; - - var pHeader = ns1.readSafeJSONString(sHeader); - - // 1. use alg if defined in sHeader - if ((alg == '' || alg == null) && - pHeader['alg'] !== undefined) { - alg = pHeader['alg']; - } - - // 2. set alg in sHeader if undefined - if ((alg != '' && alg != null) && - pHeader['alg'] === undefined) { - pHeader['alg'] = alg; - sHeader = JSON.stringify(pHeader); - } - - // 3. set signature algorithm like SHA1withRSA - var sigAlg = null; - if (ns1.jwsalg2sigalg[alg] === undefined) { - throw "unsupported alg name: " + alg; - } else { - sigAlg = ns1.jwsalg2sigalg[alg]; - } - - var uHeader = utf8tob64u(sHeader); - var uPayload = utf8tob64u(sPayload); - var uSignatureInput = uHeader + "." + uPayload - - // 4. sign - var hSig = ""; - if (sigAlg.substr(0, 4) == "Hmac") { - if (key === undefined) - throw "hexadecimal key shall be specified for HMAC"; - var mac = new KJUR.crypto.Mac({'alg': sigAlg, 'pass': hextorstr(key)}); - mac.updateString(uSignatureInput); - hSig = mac.doFinal(); - } else if (sigAlg.indexOf("withECDSA") != -1) { - var sig = new KJUR.crypto.Signature({'alg': sigAlg}); - sig.init(key, pass); - sig.updateString(uSignatureInput); - hASN1Sig = sig.sign(); - hSig = KJUR.crypto.ECDSA.asn1SigToConcatSig(hASN1Sig); - } else if (sigAlg != "none") { - var sig = new KJUR.crypto.Signature({'alg': sigAlg}); - sig.init(key, pass); - sig.updateString(uSignatureInput); - hSig = sig.sign(); - } - - var uSig = hextob64u(hSig); - return uSignatureInput + "." + uSig; -}; - -/** - * verify JWS signature by specified key or certificate
- * @name verify - * @memberOf KJUR.jws.JWS - * @function - * @static - * @param {String} sJWS string of JWS signature to verify - * @param {String} key string of public key, certificate or key object to verify - * @return {Boolean} true if the signature is valid otherwise false - * @since jws 3.0.0 - * @see jsrsasign KJUR.crypto.Signature method - * @see jsrsasign KJUR.crypto.Mac method - */ -KJUR.jws.JWS.verify = function(sJWS, key) { - var jws = KJUR.jws.JWS; - var a = sJWS.split("."); - var uHeader = a[0]; - var uPayload = a[1]; - var uSignatureInput = uHeader + "." + uPayload; - var hSig = b64utohex(a[2]); - - var pHeader = jws.readSafeJSONString(b64utoutf8(a[0])); - var alg = null; - if (pHeader.alg === undefined) { - throw "algorithm not specified in header"; - } else { - alg = pHeader.alg; - } - - var sigAlg = null; - if (jws.jwsalg2sigalg[pHeader.alg] === undefined) { - throw "unsupported alg name: " + alg; - } else { - sigAlg = jws.jwsalg2sigalg[alg]; - } - - // x. verify - if (sigAlg == "none") { - return true; - } else if (sigAlg.substr(0, 4) == "Hmac") { - if (key === undefined) - throw "hexadecimal key shall be specified for HMAC"; - var mac = new KJUR.crypto.Mac({'alg': sigAlg, 'pass': hextorstr(key)}); - mac.updateString(uSignatureInput); - hSig2 = mac.doFinal(); - return hSig == hSig2; - } else if (sigAlg.indexOf("withECDSA") != -1) { - var hASN1Sig = null; - try { - hASN1Sig = KJUR.crypto.ECDSA.concatSigToASN1Sig(hSig); - } catch (ex) { - return false; - } - var sig = new KJUR.crypto.Signature({'alg': sigAlg}); - sig.init(key) - sig.updateString(uSignatureInput); - return sig.verify(hASN1Sig); - } else { - var sig = new KJUR.crypto.Signature({'alg': sigAlg}); - sig.init(key) - sig.updateString(uSignatureInput); - return sig.verify(hSig); - } -}; - -/* - * @since jws 3.0.0 - */ -KJUR.jws.JWS.jwsalg2sigalg = { - "HS256": "HmacSHA256", - //"HS384": "HmacSHA384", // unsupported because of CryptoJS bug - "HS512": "HmacSHA512", - "RS256": "SHA256withRSA", - "RS384": "SHA384withRSA", - "RS512": "SHA512withRSA", - "ES256": "SHA256withECDSA", - "ES384": "SHA384withECDSA", - //"ES512": "SHA512withECDSA", // unsupported because of jsrsasign's bug - "PS256": "SHA256withRSAandMGF1", - "PS384": "SHA384withRSAandMGF1", - "PS512": "SHA512withRSAandMGF1", - "none": "none", -}; - -// === utility static method ====================================================== - -/** - * check whether a String "s" is a safe JSON string or not.
- * If a String "s" is a malformed JSON string or an other object type - * this returns 0, otherwise this returns 1. - * @name isSafeJSONString - * @memberOf KJUR.jws.JWS - * @function - * @static - * @param {String} s JSON string - * @return {Number} 1 or 0 - */ -KJUR.jws.JWS.isSafeJSONString = function(s, h, p) { - var o = null; - try { - o = jsonParse(s); - if (typeof o != "object") return 0; - if (o.constructor === Array) return 0; - if (h) h[p] = o; - return 1; - } catch (ex) { - return 0; - } -}; - -/** - * read a String "s" as JSON object if it is safe.
- * If a String "s" is a malformed JSON string or not JSON string, - * this returns null, otherwise returns JSON object. - * @name readSafeJSONString - * @memberOf KJUR.jws.JWS - * @function - * @static - * @param {String} s JSON string - * @return {Object} JSON object or null - * @since 1.1.1 - */ -KJUR.jws.JWS.readSafeJSONString = function(s) { - var o = null; - try { - o = jsonParse(s); - if (typeof o != "object") return null; - if (o.constructor === Array) return null; - return o; - } catch (ex) { - return null; - } -}; - -/** - * get Encoed Signature Value from JWS string.
- * @name getEncodedSignatureValueFromJWS - * @memberOf KJUR.jws.JWS - * @function - * @static - * @param {String} sJWS JWS signature string to be verified - * @return {String} string of Encoded Signature Value - * @throws if sJWS is not comma separated string such like "Header.Payload.Signature". - */ -KJUR.jws.JWS.getEncodedSignatureValueFromJWS = function(sJWS) { - if (sJWS.match(/^[^.]+\.[^.]+\.([^.]+)$/) == null) { - throw "JWS signature is not a form of 'Head.Payload.SigValue'."; - } - return RegExp.$1; -}; - -/** - * IntDate class for time representation for JSON Web Token(JWT) - * @class KJUR.jws.IntDate class - * @name KJUR.jws.IntDate - * @since jws 3.0.1 - * @description - * Utility class for IntDate which is integer representation of UNIX origin time - * used in JSON Web Token(JWT). - */ -KJUR.jws.IntDate = function() { -}; - -/** - * @name get - * @memberOf KJUR.jws.IntDate - * @function - * @static - * @param {String} s string of time representation - * @return {Integer} UNIX origin time in seconds for argument 's' - * @since jws 3.0.1 - * @throws "unsupported format: s" when malformed format - * @description - * This method will accept following representation of time. - *
    - *
  • now - current time
  • - *
  • now + 1hour - after 1 hour from now
  • - *
  • now + 1day - after 1 day from now
  • - *
  • now + 1month - after 30 days from now
  • - *
  • now + 1year - after 365 days from now
  • - *
  • YYYYmmDDHHMMSSZ - UTC time (ex. 20130828235959Z)
  • - *
  • number - UNIX origin time (seconds from 1970-01-01 00:00:00) (ex. 1377714748)
  • - *
- */ -KJUR.jws.IntDate.get = function(s) { - if (s == "now") { - return KJUR.jws.IntDate.getNow(); - } else if (s == "now + 1hour") { - return KJUR.jws.IntDate.getNow() + 60 * 60; - } else if (s == "now + 1day") { - return KJUR.jws.IntDate.getNow() + 60 * 60 * 24; - } else if (s == "now + 1month") { - return KJUR.jws.IntDate.getNow() + 60 * 60 * 24 * 30; - } else if (s == "now + 1year") { - return KJUR.jws.IntDate.getNow() + 60 * 60 * 24 * 365; - } else if (s.match(/Z$/)) { - return KJUR.jws.IntDate.getZulu(s); - } else if (s.match(/^[0-9]+$/)) { - return parseInt(s); - } - throw "unsupported format: " + s; -}; - -KJUR.jws.IntDate.getZulu = function(s) { - if (a = s.match(/(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z/)) { - var year = parseInt(RegExp.$1); - var month = parseInt(RegExp.$2) - 1; - var day = parseInt(RegExp.$3); - var hour = parseInt(RegExp.$4); - var min = parseInt(RegExp.$5); - var sec = parseInt(RegExp.$6); - var d = new Date(Date.UTC(year, month, day, hour, min, sec)); - return ~~(d / 1000); - } - throw "unsupported format: " + s; -}; - -/* - * @since jws 3.0.1 - */ -KJUR.jws.IntDate.getNow = function() { - var d = ~~(new Date() / 1000); - return d; -}; - -/* - * @since jws 3.0.1 - */ -KJUR.jws.IntDate.intDate2UTCString = function(intDate) { - var d = new Date(intDate * 1000); - return d.toUTCString(); -}; - -/* - * @since jws 3.0.1 - */ -KJUR.jws.IntDate.intDate2Zulu = function(intDate) { - var d = new Date(intDate * 1000); - var year = ("0000" + d.getUTCFullYear()).slice(-4); - var mon = ("00" + (d.getUTCMonth() + 1)).slice(-2); - var day = ("00" + d.getUTCDate()).slice(-2); - var hour = ("00" + d.getUTCHours()).slice(-2); - var min = ("00" + d.getUTCMinutes()).slice(-2); - var sec = ("00" + d.getUTCSeconds()).slice(-2); - return year + mon + day + hour + min + sec + "Z"; -}; - -/*! - * @overview es6-promise - a tiny implementation of Promises/A+. - * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE - * @version 3.0.2 - */ - -(function() { - "use strict"; - function lib$es6$promise$utils$$objectOrFunction(x) { - return typeof x === 'function' || (typeof x === 'object' && x !== null); - } - - function lib$es6$promise$utils$$isFunction(x) { - return typeof x === 'function'; - } - - function lib$es6$promise$utils$$isMaybeThenable(x) { - return typeof x === 'object' && x !== null; - } - - var lib$es6$promise$utils$$_isArray; - if (!Array.isArray) { - lib$es6$promise$utils$$_isArray = function (x) { - return Object.prototype.toString.call(x) === '[object Array]'; - }; - } else { - lib$es6$promise$utils$$_isArray = Array.isArray; - } - - var lib$es6$promise$utils$$isArray = lib$es6$promise$utils$$_isArray; - var lib$es6$promise$asap$$len = 0; - var lib$es6$promise$asap$$toString = {}.toString; - var lib$es6$promise$asap$$vertxNext; - var lib$es6$promise$asap$$customSchedulerFn; - - var lib$es6$promise$asap$$asap = function asap(callback, arg) { - lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len] = callback; - lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len + 1] = arg; - lib$es6$promise$asap$$len += 2; - if (lib$es6$promise$asap$$len === 2) { - // If len is 2, that means that we need to schedule an async flush. - // If additional callbacks are queued before the queue is flushed, they - // will be processed by this flush that we are scheduling. - if (lib$es6$promise$asap$$customSchedulerFn) { - lib$es6$promise$asap$$customSchedulerFn(lib$es6$promise$asap$$flush); - } else { - lib$es6$promise$asap$$scheduleFlush(); - } - } - } - - function lib$es6$promise$asap$$setScheduler(scheduleFn) { - lib$es6$promise$asap$$customSchedulerFn = scheduleFn; - } - - function lib$es6$promise$asap$$setAsap(asapFn) { - lib$es6$promise$asap$$asap = asapFn; - } - - var lib$es6$promise$asap$$browserWindow = (typeof window !== 'undefined') ? window : undefined; - var lib$es6$promise$asap$$browserGlobal = lib$es6$promise$asap$$browserWindow || {}; - var lib$es6$promise$asap$$BrowserMutationObserver = lib$es6$promise$asap$$browserGlobal.MutationObserver || lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver; - var lib$es6$promise$asap$$isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]'; - - // test for web worker but not in IE10 - var lib$es6$promise$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' && - typeof importScripts !== 'undefined' && - typeof MessageChannel !== 'undefined'; - - // node - function lib$es6$promise$asap$$useNextTick() { - // node version 0.10.x displays a deprecation warning when nextTick is used recursively - // see https://github.com/cujojs/when/issues/410 for details - return function() { - process.nextTick(lib$es6$promise$asap$$flush); - }; - } - - // vertx - function lib$es6$promise$asap$$useVertxTimer() { - return function() { - lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush); - }; - } - - function lib$es6$promise$asap$$useMutationObserver() { - var iterations = 0; - var observer = new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush); - var node = document.createTextNode(''); - observer.observe(node, { characterData: true }); - - return function() { - node.data = (iterations = ++iterations % 2); - }; - } - - // web worker - function lib$es6$promise$asap$$useMessageChannel() { - var channel = new MessageChannel(); - channel.port1.onmessage = lib$es6$promise$asap$$flush; - return function () { - channel.port2.postMessage(0); - }; - } - - function lib$es6$promise$asap$$useSetTimeout() { - return function() { - setTimeout(lib$es6$promise$asap$$flush, 1); - }; - } - - var lib$es6$promise$asap$$queue = new Array(1000); - function lib$es6$promise$asap$$flush() { - for (var i = 0; i < lib$es6$promise$asap$$len; i+=2) { - var callback = lib$es6$promise$asap$$queue[i]; - var arg = lib$es6$promise$asap$$queue[i+1]; - - callback(arg); - - lib$es6$promise$asap$$queue[i] = undefined; - lib$es6$promise$asap$$queue[i+1] = undefined; - } - - lib$es6$promise$asap$$len = 0; - } - - function lib$es6$promise$asap$$attemptVertx() { - try { - var r = require; - var vertx = r('vertx'); - lib$es6$promise$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext; - return lib$es6$promise$asap$$useVertxTimer(); - } catch(e) { - return lib$es6$promise$asap$$useSetTimeout(); - } - } - - var lib$es6$promise$asap$$scheduleFlush; - // Decide what async method to use to triggering processing of queued callbacks: - if (lib$es6$promise$asap$$isNode) { - lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useNextTick(); - } else if (lib$es6$promise$asap$$BrowserMutationObserver) { - lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMutationObserver(); - } else if (lib$es6$promise$asap$$isWorker) { - lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMessageChannel(); - } else if (lib$es6$promise$asap$$browserWindow === undefined && typeof require === 'function') { - lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$attemptVertx(); - } else { - lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useSetTimeout(); - } - - function lib$es6$promise$$internal$$noop() {} - - var lib$es6$promise$$internal$$PENDING = void 0; - var lib$es6$promise$$internal$$FULFILLED = 1; - var lib$es6$promise$$internal$$REJECTED = 2; - - var lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject(); - - function lib$es6$promise$$internal$$selfFulfillment() { - return new TypeError("You cannot resolve a promise with itself"); - } - - function lib$es6$promise$$internal$$cannotReturnOwn() { - return new TypeError('A promises callback cannot return that same promise.'); - } - - function lib$es6$promise$$internal$$getThen(promise) { - try { - return promise.then; - } catch(error) { - lib$es6$promise$$internal$$GET_THEN_ERROR.error = error; - return lib$es6$promise$$internal$$GET_THEN_ERROR; - } - } - - function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) { - try { - then.call(value, fulfillmentHandler, rejectionHandler); - } catch(e) { - return e; - } - } - - function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) { - lib$es6$promise$asap$$asap(function(promise) { - var sealed = false; - var error = lib$es6$promise$$internal$$tryThen(then, thenable, function(value) { - if (sealed) { return; } - sealed = true; - if (thenable !== value) { - lib$es6$promise$$internal$$resolve(promise, value); - } else { - lib$es6$promise$$internal$$fulfill(promise, value); - } - }, function(reason) { - if (sealed) { return; } - sealed = true; - - lib$es6$promise$$internal$$reject(promise, reason); - }, 'Settle: ' + (promise._label || ' unknown promise')); - - if (!sealed && error) { - sealed = true; - lib$es6$promise$$internal$$reject(promise, error); - } - }, promise); - } - - function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) { - if (thenable._state === lib$es6$promise$$internal$$FULFILLED) { - lib$es6$promise$$internal$$fulfill(promise, thenable._result); - } else if (thenable._state === lib$es6$promise$$internal$$REJECTED) { - lib$es6$promise$$internal$$reject(promise, thenable._result); - } else { - lib$es6$promise$$internal$$subscribe(thenable, undefined, function(value) { - lib$es6$promise$$internal$$resolve(promise, value); - }, function(reason) { - lib$es6$promise$$internal$$reject(promise, reason); - }); - } - } - - function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable) { - if (maybeThenable.constructor === promise.constructor) { - lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable); - } else { - var then = lib$es6$promise$$internal$$getThen(maybeThenable); - - if (then === lib$es6$promise$$internal$$GET_THEN_ERROR) { - lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error); - } else if (then === undefined) { - lib$es6$promise$$internal$$fulfill(promise, maybeThenable); - } else if (lib$es6$promise$utils$$isFunction(then)) { - lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then); - } else { - lib$es6$promise$$internal$$fulfill(promise, maybeThenable); - } - } - } - - function lib$es6$promise$$internal$$resolve(promise, value) { - if (promise === value) { - lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFulfillment()); - } else if (lib$es6$promise$utils$$objectOrFunction(value)) { - lib$es6$promise$$internal$$handleMaybeThenable(promise, value); - } else { - lib$es6$promise$$internal$$fulfill(promise, value); - } - } - - function lib$es6$promise$$internal$$publishRejection(promise) { - if (promise._onerror) { - promise._onerror(promise._result); - } - - lib$es6$promise$$internal$$publish(promise); - } - - function lib$es6$promise$$internal$$fulfill(promise, value) { - if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; } - - promise._result = value; - promise._state = lib$es6$promise$$internal$$FULFILLED; - - if (promise._subscribers.length !== 0) { - lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, promise); - } - } - - function lib$es6$promise$$internal$$reject(promise, reason) { - if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; } - promise._state = lib$es6$promise$$internal$$REJECTED; - promise._result = reason; - - lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publishRejection, promise); - } - - function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) { - var subscribers = parent._subscribers; - var length = subscribers.length; - - parent._onerror = null; - - subscribers[length] = child; - subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment; - subscribers[length + lib$es6$promise$$internal$$REJECTED] = onRejection; - - if (length === 0 && parent._state) { - lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, parent); - } - } - - function lib$es6$promise$$internal$$publish(promise) { - var subscribers = promise._subscribers; - var settled = promise._state; - - if (subscribers.length === 0) { return; } - - var child, callback, detail = promise._result; - - for (var i = 0; i < subscribers.length; i += 3) { - child = subscribers[i]; - callback = subscribers[i + settled]; - - if (child) { - lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail); - } else { - callback(detail); - } - } - - promise._subscribers.length = 0; - } - - function lib$es6$promise$$internal$$ErrorObject() { - this.error = null; - } - - var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject(); - - function lib$es6$promise$$internal$$tryCatch(callback, detail) { - try { - return callback(detail); - } catch(e) { - lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e; - return lib$es6$promise$$internal$$TRY_CATCH_ERROR; - } - } - - function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) { - var hasCallback = lib$es6$promise$utils$$isFunction(callback), - value, error, succeeded, failed; - - if (hasCallback) { - value = lib$es6$promise$$internal$$tryCatch(callback, detail); - - if (value === lib$es6$promise$$internal$$TRY_CATCH_ERROR) { - failed = true; - error = value.error; - value = null; - } else { - succeeded = true; - } - - if (promise === value) { - lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn()); - return; - } - - } else { - value = detail; - succeeded = true; - } - - if (promise._state !== lib$es6$promise$$internal$$PENDING) { - // noop - } else if (hasCallback && succeeded) { - lib$es6$promise$$internal$$resolve(promise, value); - } else if (failed) { - lib$es6$promise$$internal$$reject(promise, error); - } else if (settled === lib$es6$promise$$internal$$FULFILLED) { - lib$es6$promise$$internal$$fulfill(promise, value); - } else if (settled === lib$es6$promise$$internal$$REJECTED) { - lib$es6$promise$$internal$$reject(promise, value); - } - } - - function lib$es6$promise$$internal$$initializePromise(promise, resolver) { - try { - resolver(function resolvePromise(value){ - lib$es6$promise$$internal$$resolve(promise, value); - }, function rejectPromise(reason) { - lib$es6$promise$$internal$$reject(promise, reason); - }); - } catch(e) { - lib$es6$promise$$internal$$reject(promise, e); - } - } - - function lib$es6$promise$enumerator$$Enumerator(Constructor, input) { - var enumerator = this; - - enumerator._instanceConstructor = Constructor; - enumerator.promise = new Constructor(lib$es6$promise$$internal$$noop); - - if (enumerator._validateInput(input)) { - enumerator._input = input; - enumerator.length = input.length; - enumerator._remaining = input.length; - - enumerator._init(); - - if (enumerator.length === 0) { - lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result); - } else { - enumerator.length = enumerator.length || 0; - enumerator._enumerate(); - if (enumerator._remaining === 0) { - lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result); - } - } - } else { - lib$es6$promise$$internal$$reject(enumerator.promise, enumerator._validationError()); - } - } - - lib$es6$promise$enumerator$$Enumerator.prototype._validateInput = function(input) { - return lib$es6$promise$utils$$isArray(input); - }; - - lib$es6$promise$enumerator$$Enumerator.prototype._validationError = function() { - return new Error('Array Methods must be provided an Array'); - }; - - lib$es6$promise$enumerator$$Enumerator.prototype._init = function() { - this._result = new Array(this.length); - }; - - var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator; - - lib$es6$promise$enumerator$$Enumerator.prototype._enumerate = function() { - var enumerator = this; - - var length = enumerator.length; - var promise = enumerator.promise; - var input = enumerator._input; - - for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) { - enumerator._eachEntry(input[i], i); - } - }; - - lib$es6$promise$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) { - var enumerator = this; - var c = enumerator._instanceConstructor; - - if (lib$es6$promise$utils$$isMaybeThenable(entry)) { - if (entry.constructor === c && entry._state !== lib$es6$promise$$internal$$PENDING) { - entry._onerror = null; - enumerator._settledAt(entry._state, i, entry._result); - } else { - enumerator._willSettleAt(c.resolve(entry), i); - } - } else { - enumerator._remaining--; - enumerator._result[i] = entry; - } - }; - - lib$es6$promise$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) { - var enumerator = this; - var promise = enumerator.promise; - - if (promise._state === lib$es6$promise$$internal$$PENDING) { - enumerator._remaining--; - - if (state === lib$es6$promise$$internal$$REJECTED) { - lib$es6$promise$$internal$$reject(promise, value); - } else { - enumerator._result[i] = value; - } - } - - if (enumerator._remaining === 0) { - lib$es6$promise$$internal$$fulfill(promise, enumerator._result); - } - }; - - lib$es6$promise$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) { - var enumerator = this; - - lib$es6$promise$$internal$$subscribe(promise, undefined, function(value) { - enumerator._settledAt(lib$es6$promise$$internal$$FULFILLED, i, value); - }, function(reason) { - enumerator._settledAt(lib$es6$promise$$internal$$REJECTED, i, reason); - }); - }; - function lib$es6$promise$promise$all$$all(entries) { - return new lib$es6$promise$enumerator$$default(this, entries).promise; - } - var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all; - function lib$es6$promise$promise$race$$race(entries) { - /*jshint validthis:true */ - var Constructor = this; - - var promise = new Constructor(lib$es6$promise$$internal$$noop); - - if (!lib$es6$promise$utils$$isArray(entries)) { - lib$es6$promise$$internal$$reject(promise, new TypeError('You must pass an array to race.')); - return promise; - } - - var length = entries.length; - - function onFulfillment(value) { - lib$es6$promise$$internal$$resolve(promise, value); - } - - function onRejection(reason) { - lib$es6$promise$$internal$$reject(promise, reason); - } - - for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) { - lib$es6$promise$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection); - } - - return promise; - } - var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race; - function lib$es6$promise$promise$resolve$$resolve(object) { - /*jshint validthis:true */ - var Constructor = this; - - if (object && typeof object === 'object' && object.constructor === Constructor) { - return object; - } - - var promise = new Constructor(lib$es6$promise$$internal$$noop); - lib$es6$promise$$internal$$resolve(promise, object); - return promise; - } - var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve; - function lib$es6$promise$promise$reject$$reject(reason) { - /*jshint validthis:true */ - var Constructor = this; - var promise = new Constructor(lib$es6$promise$$internal$$noop); - lib$es6$promise$$internal$$reject(promise, reason); - return promise; - } - var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject; - - var lib$es6$promise$promise$$counter = 0; - - function lib$es6$promise$promise$$needsResolver() { - throw new TypeError('You must pass a resolver function as the first argument to the promise constructor'); - } - - function lib$es6$promise$promise$$needsNew() { - throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); - } - - var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise; - /** - Promise objects represent the eventual result of an asynchronous operation. The - primary way of interacting with a promise is through its `then` method, which - registers callbacks to receive either a promise's eventual value or the reason - why the promise cannot be fulfilled. - - Terminology - ----------- - - - `promise` is an object or function with a `then` method whose behavior conforms to this specification. - - `thenable` is an object or function that defines a `then` method. - - `value` is any legal JavaScript value (including undefined, a thenable, or a promise). - - `exception` is a value that is thrown using the throw statement. - - `reason` is a value that indicates why a promise was rejected. - - `settled` the final resting state of a promise, fulfilled or rejected. - - A promise can be in one of three states: pending, fulfilled, or rejected. - - Promises that are fulfilled have a fulfillment value and are in the fulfilled - state. Promises that are rejected have a rejection reason and are in the - rejected state. A fulfillment value is never a thenable. - - Promises can also be said to *resolve* a value. If this value is also a - promise, then the original promise's settled state will match the value's - settled state. So a promise that *resolves* a promise that rejects will - itself reject, and a promise that *resolves* a promise that fulfills will - itself fulfill. - - - Basic Usage: - ------------ - - ```js - var promise = new Promise(function(resolve, reject) { - // on success - resolve(value); - - // on failure - reject(reason); - }); - - promise.then(function(value) { - // on fulfillment - }, function(reason) { - // on rejection - }); - ``` - - Advanced Usage: - --------------- - - Promises shine when abstracting away asynchronous interactions such as - `XMLHttpRequest`s. - - ```js - function getJSON(url) { - return new Promise(function(resolve, reject){ - var xhr = new XMLHttpRequest(); - - xhr.open('GET', url); - xhr.onreadystatechange = handler; - xhr.responseType = 'json'; - xhr.setRequestHeader('Accept', 'application/json'); - xhr.send(); - - function handler() { - if (this.readyState === this.DONE) { - if (this.status === 200) { - resolve(this.response); - } else { - reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']')); - } - } - }; - }); - } - - getJSON('/posts.json').then(function(json) { - // on fulfillment - }, function(reason) { - // on rejection - }); - ``` - - Unlike callbacks, promises are great composable primitives. - - ```js - Promise.all([ - getJSON('/posts'), - getJSON('/comments') - ]).then(function(values){ - values[0] // => postsJSON - values[1] // => commentsJSON - - return values; - }); - ``` - - @class Promise - @param {function} resolver - Useful for tooling. - @constructor - */ - function lib$es6$promise$promise$$Promise(resolver) { - this._id = lib$es6$promise$promise$$counter++; - this._state = undefined; - this._result = undefined; - this._subscribers = []; - - if (lib$es6$promise$$internal$$noop !== resolver) { - if (!lib$es6$promise$utils$$isFunction(resolver)) { - lib$es6$promise$promise$$needsResolver(); - } - - if (!(this instanceof lib$es6$promise$promise$$Promise)) { - lib$es6$promise$promise$$needsNew(); - } - - lib$es6$promise$$internal$$initializePromise(this, resolver); - } - } - - lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default; - lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default; - lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default; - lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default; - lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler; - lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap; - lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap; - - lib$es6$promise$promise$$Promise.prototype = { - constructor: lib$es6$promise$promise$$Promise, - - /** - The primary way of interacting with a promise is through its `then` method, - which registers callbacks to receive either a promise's eventual value or the - reason why the promise cannot be fulfilled. - - ```js - findUser().then(function(user){ - // user is available - }, function(reason){ - // user is unavailable, and you are given the reason why - }); - ``` - - Chaining - -------- - - The return value of `then` is itself a promise. This second, 'downstream' - promise is resolved with the return value of the first promise's fulfillment - or rejection handler, or rejected if the handler throws an exception. - - ```js - findUser().then(function (user) { - return user.name; - }, function (reason) { - return 'default name'; - }).then(function (userName) { - // If `findUser` fulfilled, `userName` will be the user's name, otherwise it - // will be `'default name'` - }); - - findUser().then(function (user) { - throw new Error('Found user, but still unhappy'); - }, function (reason) { - throw new Error('`findUser` rejected and we're unhappy'); - }).then(function (value) { - // never reached - }, function (reason) { - // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. - // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. - }); - ``` - If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. - - ```js - findUser().then(function (user) { - throw new PedagogicalException('Upstream error'); - }).then(function (value) { - // never reached - }).then(function (value) { - // never reached - }, function (reason) { - // The `PedgagocialException` is propagated all the way down to here - }); - ``` - - Assimilation - ------------ - - Sometimes the value you want to propagate to a downstream promise can only be - retrieved asynchronously. This can be achieved by returning a promise in the - fulfillment or rejection handler. The downstream promise will then be pending - until the returned promise is settled. This is called *assimilation*. - - ```js - findUser().then(function (user) { - return findCommentsByAuthor(user); - }).then(function (comments) { - // The user's comments are now available - }); - ``` - - If the assimliated promise rejects, then the downstream promise will also reject. - - ```js - findUser().then(function (user) { - return findCommentsByAuthor(user); - }).then(function (comments) { - // If `findCommentsByAuthor` fulfills, we'll have the value here - }, function (reason) { - // If `findCommentsByAuthor` rejects, we'll have the reason here - }); - ``` - - Simple Example - -------------- - - Synchronous Example - - ```javascript - var result; - - try { - result = findResult(); - // success - } catch(reason) { - // failure - } - ``` - - Errback Example - - ```js - findResult(function(result, err){ - if (err) { - // failure - } else { - // success - } - }); - ``` - - Promise Example; - - ```javascript - findResult().then(function(result){ - // success - }, function(reason){ - // failure - }); - ``` - - Advanced Example - -------------- - - Synchronous Example - - ```javascript - var author, books; - - try { - author = findAuthor(); - books = findBooksByAuthor(author); - // success - } catch(reason) { - // failure - } - ``` - - Errback Example - - ```js - - function foundBooks(books) { - - } - - function failure(reason) { - - } - - findAuthor(function(author, err){ - if (err) { - failure(err); - // failure - } else { - try { - findBoooksByAuthor(author, function(books, err) { - if (err) { - failure(err); - } else { - try { - foundBooks(books); - } catch(reason) { - failure(reason); - } - } - }); - } catch(error) { - failure(err); - } - // success - } - }); - ``` - - Promise Example; - - ```javascript - findAuthor(). - then(findBooksByAuthor). - then(function(books){ - // found books - }).catch(function(reason){ - // something went wrong - }); - ``` - - @method then - @param {Function} onFulfilled - @param {Function} onRejected - Useful for tooling. - @return {Promise} - */ - then: function(onFulfillment, onRejection) { - var parent = this; - var state = parent._state; - - if (state === lib$es6$promise$$internal$$FULFILLED && !onFulfillment || state === lib$es6$promise$$internal$$REJECTED && !onRejection) { - return this; - } - - var child = new this.constructor(lib$es6$promise$$internal$$noop); - var result = parent._result; - - if (state) { - var callback = arguments[state - 1]; - lib$es6$promise$asap$$asap(function(){ - lib$es6$promise$$internal$$invokeCallback(state, child, callback, result); - }); - } else { - lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection); - } - - return child; - }, - - /** - `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same - as the catch block of a try/catch statement. - - ```js - function findAuthor(){ - throw new Error('couldn't find that author'); - } - - // synchronous - try { - findAuthor(); - } catch(reason) { - // something went wrong - } - - // async with promises - findAuthor().catch(function(reason){ - // something went wrong - }); - ``` - - @method catch - @param {Function} onRejection - Useful for tooling. - @return {Promise} - */ - 'catch': function(onRejection) { - return this.then(null, onRejection); - } - }; - function lib$es6$promise$polyfill$$polyfill() { - var local; - - if (typeof global !== 'undefined') { - local = global; - } else if (typeof self !== 'undefined') { - local = self; - } else { - try { - local = Function('return this')(); - } catch (e) { - throw new Error('polyfill failed because global object is unavailable in this environment'); - } - } - - var P = local.Promise; - - if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) { - return; - } - - local.Promise = lib$es6$promise$promise$$default; - } - var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill; - - var lib$es6$promise$umd$$ES6Promise = { - 'Promise': lib$es6$promise$promise$$default, - 'polyfill': lib$es6$promise$polyfill$$default - }; - - /* global define:true module:true window: true */ - if (typeof define === 'function' && define['amd']) { - define(function() { return lib$es6$promise$umd$$ES6Promise; }); - } else if (typeof module !== 'undefined' && module['exports']) { - module['exports'] = lib$es6$promise$umd$$ES6Promise; - } else if (typeof this !== 'undefined') { - this['ES6Promise'] = lib$es6$promise$umd$$ES6Promise; - } - - lib$es6$promise$polyfill$$default(); -}).call(this); - - -/** - * @constructor - */ -function DefaultHttpRequest() { - - /** - * @name _promiseFactory - * @type DefaultPromiseFactory - */ - - /** - * @param {XMLHttpRequest} xhr - * @param {object.} headers - */ - function setHeaders(xhr, headers) { - var keys = Object.keys(headers); - - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - var value = headers[key]; - - xhr.setRequestHeader(key, value); - } - } - - /** - * @param {string} url - * @param {{ headers: object. }} [config] - * @returns {Promise} - */ - this.getJSON = function (url, config) { - return _promiseFactory.create(function (resolve, reject) { - - try { - var xhr = new XMLHttpRequest(); - xhr.open("GET", url); - xhr.responseType = "json"; - - if (config) { - if (config.headers) { - setHeaders(xhr, config.headers); - } - } - - xhr.onload = function () { - try { - if (xhr.status === 200) { - var response = ""; - // To support IE9 get the response from xhr.responseText not xhr.response - if (window.XDomainRequest) { - response = xhr.responseText; - } else { - response = xhr.response; - } - if (typeof response === "string") { - response = JSON.parse(response); - } - resolve(response); - } - else { - reject(Error(xhr.statusText + "(" + xhr.status + ")")); - } - } - catch (err) { - reject(err); - } - }; - - xhr.onerror = function () { - reject(Error("Network error")); - }; - - xhr.send(); - } - catch (err) { - return reject(err); - } - }); - }; -} - -_httpRequest = new DefaultHttpRequest(); - -/** - * @constructor - * @param {Promise} promise - */ -function DefaultPromise(promise) { - - /** - * @param {function(*):*} successCallback - * @param {function(*):*} errorCallback - * @returns {DefaultPromise} - */ - this.then = function (successCallback, errorCallback) { - var childPromise = promise.then(successCallback, errorCallback); - - return new DefaultPromise(childPromise); - }; - - /** - * - * @param {function(*):*} errorCallback - * @returns {DefaultPromise} - */ - this.catch = function (errorCallback) { - var childPromise = promise.catch(errorCallback); - - return new DefaultPromise(childPromise); - }; -} - -/** - * @constructor - */ -function DefaultPromiseFactory() { - - this.resolve = function (value) { - return new DefaultPromise(Promise.resolve(value)); - }; - - this.reject = function (reason) { - return new DefaultPromise(Promise.reject(reason)); - }; - - /** - * @param {function(resolve:function, reject:function)} callback - * @returns {DefaultPromise} - */ - this.create = function (callback) { - return new DefaultPromise(new Promise(callback)); - }; -} - -_promiseFactory = new DefaultPromiseFactory(); -/* - * Copyright 2015 Dominick Baier, Brock Allen - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -function log() { - //var param = [].join.call(arguments); - //console.log(param); -} - -function copy(obj, target) { - target = target || {}; - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - target[key] = obj[key]; - } - } - return target; -} - -function rand() { - return ((Date.now() + Math.random()) * Math.random()).toString().replace(".", ""); -} - -function resolve(param) { - return _promiseFactory.resolve(param); -} - -function error(message) { - return _promiseFactory.reject(Error(message)); -} - -function parseOidcResult(queryString) { - log("parseOidcResult"); - - queryString = queryString || location.hash; - - var idx = queryString.lastIndexOf("#"); - if (idx >= 0) { - queryString = queryString.substr(idx + 1); - } - - var params = {}, - regex = /([^&=]+)=([^&]*)/g, - m; - - var counter = 0; - while (m = regex.exec(queryString)) { - params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]); - if (counter++ > 50) { - return { - error: "Response exceeded expected number of parameters" - }; - } - } - - for (var prop in params) { - return params; - } -} - -function getJson(url, token) { - log("getJson", url); - - var config = {}; - - if (token) { - config.headers = {"Authorization": "Bearer " + token}; - } - - return _httpRequest.getJSON(url, config); -} - -function OidcClient(settings) { - this._settings = settings || {}; - - if (!this._settings.request_state_key) { - this._settings.request_state_key = "OidcClient.request_state"; - } - - if (!this._settings.request_state_store) { - this._settings.request_state_store = window.localStorage; - } - - if (typeof this._settings.load_user_profile === 'undefined') { - this._settings.load_user_profile = true; - } - - if (typeof this._settings.filter_protocol_claims === 'undefined') { - this._settings.filter_protocol_claims = true; - } - - if (this._settings.authority && this._settings.authority.indexOf('.well-known/openid-configuration') < 0) { - if (this._settings.authority[this._settings.authority.length - 1] !== '/') { - this._settings.authority += '/'; - } - this._settings.authority += '.well-known/openid-configuration'; - } - - if (!this._settings.response_type) { - this._settings.response_type = "id_token token"; - } - - Object.defineProperty(this, "isOidc", { - get: function () { - if (this._settings.response_type) { - var result = this._settings.response_type.split(/\s+/g).filter(function (item) { - return item === "id_token"; - }); - return !!(result[0]); - } - return false; - } - }); - - Object.defineProperty(this, "isOAuth", { - get: function () { - if (this._settings.response_type) { - var result = this._settings.response_type.split(/\s+/g).filter(function (item) { - return item === "token"; - }); - return !!(result[0]); - } - return false; - } - }); -} - -OidcClient.parseOidcResult = parseOidcResult; - -OidcClient.prototype.loadMetadataAsync = function () { - log("OidcClient.loadMetadataAsync"); - - var settings = this._settings; - - if (settings.metadata) { - return resolve(settings.metadata); - } - - if (!settings.authority) { - return error("No authority configured"); - } - - return getJson(settings.authority) - .then(function (metadata) { - settings.metadata = metadata; - return metadata; - }, function (err) { - return error("Failed to load metadata (" + err && err.message + ")"); - }); -}; - -OidcClient.prototype.loadX509SigningKeyAsync = function () { - log("OidcClient.loadX509SigningKeyAsync"); - - var settings = this._settings; - - function getKeyAsync(jwks) { - if (!jwks.keys || !jwks.keys.length) { - return error("Signing keys empty"); - } - - var key = jwks.keys[0]; - if (key.kty !== "RSA") { - return error("Signing key not RSA"); - } - - if (!key.x5c || !key.x5c.length) { - return error("RSA keys empty"); - } - - return resolve(key.x5c[0]); - } - - if (settings.jwks) { - return getKeyAsync(settings.jwks); - } - - return this.loadMetadataAsync().then(function (metadata) { - if (!metadata.jwks_uri) { - return error("Metadata does not contain jwks_uri"); - } - - return getJson(metadata.jwks_uri).then(function (jwks) { - settings.jwks = jwks; - return getKeyAsync(jwks); - }, function (err) { - return error("Failed to load signing keys (" + err && err.message + ")"); - }); - }); -}; - -OidcClient.prototype.loadUserProfile = function (access_token) { - log("OidcClient.loadUserProfile"); - - return this.loadMetadataAsync().then(function (metadata) { - - if (!metadata.userinfo_endpoint) { - return error("Metadata does not contain userinfo_endpoint"); - } - - return getJson(metadata.userinfo_endpoint, access_token); - }); -} - -OidcClient.prototype.loadAuthorizationEndpoint = function () { - log("OidcClient.loadAuthorizationEndpoint"); - - if (this._settings.authorization_endpoint) { - return resolve(this._settings.authorization_endpoint); - } - - if (!this._settings.authority) { - return error("No authorization_endpoint configured"); - } - - return this.loadMetadataAsync().then(function (metadata) { - if (!metadata.authorization_endpoint) { - return error("Metadata does not contain authorization_endpoint"); - } - - return metadata.authorization_endpoint; - }); -}; - -OidcClient.prototype.createTokenRequestAsync = function () { - log("OidcClient.createTokenRequestAsync"); - - var client = this; - var settings = client._settings; - - return client.loadAuthorizationEndpoint().then(function (authorization_endpoint) { - - var state = rand(); - var url = authorization_endpoint + "?state=" + encodeURIComponent(state); - - if (client.isOidc) { - var nonce = rand(); - url += "&nonce=" + encodeURIComponent(nonce); - } - - var required = ["client_id", "redirect_uri", "response_type", "scope"]; - required.forEach(function (key) { - var value = settings[key]; - if (value) { - url += "&" + key + "=" + encodeURIComponent(value); - } - }); - - var optional = ["prompt", "display", "max_age", "ui_locales", "id_token_hint", "login_hint", "acr_values"]; - optional.forEach(function (key) { - var value = settings[key]; - if (value) { - url += "&" + key + "=" + encodeURIComponent(value); - } - }); - - var request_state = { - oidc: client.isOidc, - oauth: client.isOAuth, - state: state - }; - - if (nonce) { - request_state["nonce"] = nonce; - } - - settings.request_state_store.setItem(settings.request_state_key, JSON.stringify(request_state)); - - return { - request_state: request_state, - url: url - }; - }); -} - -OidcClient.prototype.createLogoutRequestAsync = function (id_token_hint) { - log("OidcClient.createLogoutRequestAsync"); - - var settings = this._settings; - return this.loadMetadataAsync().then(function (metadata) { - if (!metadata.end_session_endpoint) { - return error("No end_session_endpoint in metadata"); - } - - var url = metadata.end_session_endpoint; - if (id_token_hint && settings.post_logout_redirect_uri) { - url += "?post_logout_redirect_uri=" + encodeURIComponent(settings.post_logout_redirect_uri); - url += "&id_token_hint=" + encodeURIComponent(id_token_hint); - } - return url; - }); -} - -OidcClient.prototype.validateIdTokenAsync = function (id_token, nonce, access_token) { - log("OidcClient.validateIdTokenAsync"); - - var client = this; - var settings = client._settings; - - return client.loadX509SigningKeyAsync().then(function (cert) { - - var jws = new KJUR.jws.JWS(); - if (jws.verifyJWSByPemX509Cert(id_token, cert)) { - var id_token_contents = JSON.parse(jws.parsedJWS.payloadS); - - if (nonce !== id_token_contents.nonce) { - return error("Invalid nonce"); - } - - return client.loadMetadataAsync().then(function (metadata) { - - if (id_token_contents.iss !== metadata.issuer) { - return error("Invalid issuer"); - } - - if (id_token_contents.aud !== settings.client_id) { - return error("Invalid audience"); - } - - var now = parseInt(Date.now() / 1000); - - // accept tokens issues up to 5 mins ago - var diff = now - id_token_contents.iat; - if (diff > (5 * 60)) { - return error("Token issued too long ago"); - } - - if (id_token_contents.exp < now) { - return error("Token expired"); - } - - if (access_token && settings.load_user_profile) { - // if we have an access token, then call user info endpoint - return client.loadUserProfile(access_token, id_token_contents).then(function (profile) { - return copy(profile, id_token_contents); - }); - } - else { - // no access token, so we have all our claims - return id_token_contents; - } - - }); - } - else { - return error("JWT failed to validate"); - } - - }); - -}; - -OidcClient.prototype.validateAccessTokenAsync = function (id_token_contents, access_token) { - log("OidcClient.validateAccessTokenAsync"); - - if (!id_token_contents.at_hash) { - return error("No at_hash in id_token"); - } - - var hash = KJUR.crypto.Util.sha256(access_token); - var left = hash.substr(0, hash.length / 2); - var left_b64u = hextob64u(left); - - if (left_b64u !== id_token_contents.at_hash) { - return error("at_hash failed to validate"); - } - - return resolve(); -}; - -OidcClient.prototype.validateIdTokenAndAccessTokenAsync = function (id_token, nonce, access_token) { - log("OidcClient.validateIdTokenAndAccessTokenAsync"); - - var client = this; - - return client.validateIdTokenAsync(id_token, nonce, access_token).then(function (id_token_contents) { - - return client.validateAccessTokenAsync(id_token_contents, access_token).then(function () { - - return id_token_contents; - - }); - - }); -} - -OidcClient.prototype.processResponseAsync = function (queryString) { - log("OidcClient.processResponseAsync"); - - var client = this; - var settings = client._settings; - - var request_state = settings.request_state_store.getItem(settings.request_state_key); - settings.request_state_store.removeItem(settings.request_state_key); - - if (!request_state) { - return error("No request state loaded"); - } - - request_state = JSON.parse(request_state); - if (!request_state) { - return error("No request state loaded"); - } - - if (!request_state.state) { - return error("No state loaded"); - } - - var result = parseOidcResult(queryString); - if (!result) { - return error("No OIDC response"); - } - - if (result.error) { - return error(result.error); - } - - if (result.state !== request_state.state) { - return error("Invalid state"); - } - - if (request_state.oidc) { - if (!result.id_token) { - return error("No identity token"); - } - - if (!request_state.nonce) { - return error("No nonce loaded"); - } - } - - if (request_state.oauth) { - if (!result.access_token) { - return error("No access token"); - } - - if (!result.token_type || result.token_type.toLowerCase() !== "bearer") { - return error("Invalid token type"); - } - - if (!result.expires_in) { - return error("No token expiration"); - } - } - - var promise = resolve(); - if (request_state.oidc && request_state.oauth) { - promise = client.validateIdTokenAndAccessTokenAsync(result.id_token, request_state.nonce, result.access_token); - } - else if (request_state.oidc) { - promise = client.validateIdTokenAsync(result.id_token, request_state.nonce); - } - - return promise.then(function (profile) { - if (profile && settings.filter_protocol_claims) { - var remove = ["nonce", "at_hash", "iat", "nbf", "exp", "aud", "iss"]; - remove.forEach(function (key) { - delete profile[key]; - }); - } - - return { - profile: profile, - id_token: result.id_token, - access_token: result.access_token, - expires_in: result.expires_in, - scope: result.scope, - session_state : result.session_state - }; - }); -} - - // exports - OidcClient._promiseFactory = _promiseFactory; - OidcClient._httpRequest = _httpRequest; - window.OidcClient = OidcClient; -})(); -(function () { - -/* -* Copyright 2014-2016 Dominick Baier, Brock Allen -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -// globals -var _promiseFactory = OidcClient._promiseFactory; -var _httpRequest = OidcClient._httpRequest; - -function copy(obj, target) { - target = target || {}; - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - target[key] = obj[key]; - } - } - return target; -} - -function Token(other) { - if (other) { - this.profile = other.profile; - this.id_token = other.id_token; - this.access_token = other.access_token; - if (other.access_token) { - this.expires_at = parseInt(other.expires_at); - } - else if (other.id_token) { - this.expires_at = other.profile.exp; - } - else { - throw Error("Either access_token or id_token required."); - } - this.scope = other.scope; - this.session_state = other.session_state; - } - else { - this.expires_at = 0; - } - - Object.defineProperty(this, "scopes", { - get: function () { - return (this.scope || "").split(" "); - } - }); - - Object.defineProperty(this, "expired", { - get: function () { - var now = parseInt(Date.now() / 1000); - return this.expires_at < now; - } - }); - - Object.defineProperty(this, "expires_in", { - get: function () { - var now = parseInt(Date.now() / 1000); - return this.expires_at - now; - } - }); -} - -Token.fromResponse = function (response) { - if (response.access_token) { - var now = parseInt(Date.now() / 1000); - response.expires_at = now + parseInt(response.expires_in); - } - return new Token(response); -} - -Token.fromJSON = function (json) { - if (json) { - try { - var obj = JSON.parse(json); - return new Token(obj); - } - catch (e) { - } - } - return new Token(null); -} - -Token.prototype.toJSON = function () { - return JSON.stringify({ - profile: this.profile, - id_token: this.id_token, - access_token: this.access_token, - expires_at: this.expires_at, - scope: this.scopes.join(" "), - session_state: this.session_state - }); -} - -function FrameLoader(url, config) { - this.url = url; - config = config || {}; - config.cancelDelay = config.cancelDelay || 5000; - this.config = config; -} - -FrameLoader.prototype.loadAsync = function (url) { - var self = this; - url = url || this.url; - - if (!url) { - return _promiseFactory.reject(Error("No url provided")); - } - - return _promiseFactory.create(function (resolve, reject) { - var frame = window.document.createElement("iframe"); - frame.style.display = "none"; - - function cleanup() { - window.removeEventListener("message", message, false); - if (handle) { - window.clearTimeout(handle); - } - handle = null; - window.document.body.removeChild(frame); - } - - function cancel(e) { - cleanup(); - reject(); - } - - function message(e) { - if (handle && e.origin === location.protocol + "//" + location.host && e.source == frame.contentWindow) { - cleanup(); - resolve(e.data); - } - } - - var handle = window.setTimeout(cancel, self.config.cancelDelay); - window.addEventListener("message", message, false); - window.document.body.appendChild(frame); - frame.src = url; - }); -} - -function loadToken(mgr) { - mgr._token = null; - if (mgr._settings.persist) { - var tokenJson = mgr._settings.store.getItem(mgr._settings.persistKey); - if (tokenJson) { - var token = Token.fromJSON(tokenJson); - if (!token.expired) { - mgr._token = token; - } - } - } -} - -function configureTokenExpiring(mgr) { - - function callback() { - handle = null; - mgr._callTokenExpiring(); - } - - var handle = null; - - function cancel() { - if (handle) { - window.clearTimeout(handle); - handle = null; - } - } - - function setup(duration) { - handle = window.setTimeout(callback, duration * 1000); - } - - function configure() { - cancel(); - - if (!mgr.expired) { - var duration = mgr.expires_in; - if (duration > 60) { - setup(duration - 60); - } - else { - callback(); - } - } - } - - configure(); - - mgr.addOnTokenObtained(configure); - mgr.addOnTokenRemoved(cancel); -} - -function configureAutoRenewToken(mgr) { - - if (mgr._settings.silent_redirect_uri && mgr._settings.silent_renew) { - - mgr.addOnTokenExpiring(function () { - mgr.renewTokenSilentAsync().catch(function (e) { - mgr._callSilentTokenRenewFailed(); - console.error(e && e.message || "Unknown error"); - }); - }); - - } -} - -function configureTokenExpired(mgr) { - - function callback() { - handle = null; - - if (mgr._token) { - mgr.saveToken(null); - } - - mgr._callTokenExpired(); - } - - var handle = null; - - function cancel() { - if (handle) { - window.clearTimeout(handle); - handle = null; - } - } - - function setup(duration) { - handle = window.setTimeout(callback, duration * 1000); - } - - function configure() { - cancel(); - if (mgr.expires_in > 0) { - // register 1 second beyond expiration so we don't get into edge conditions for expiration - setup(mgr.expires_in + 1); - } - } - - configure(); - - mgr.addOnTokenObtained(configure); - mgr.addOnTokenRemoved(cancel); -} - -function TokenManager(settings) { - this._settings = settings || {}; - - if (typeof this._settings.persist === 'undefined') { - this._settings.persist = true; - } - this._settings.store = this._settings.store || window.localStorage; - this._settings.persistKey = this._settings.persistKey || "TokenManager.token"; - - this.oidcClient = new OidcClient(this._settings); - - this._callbacks = { - tokenRemovedCallbacks: [], - tokenExpiringCallbacks: [], - tokenExpiredCallbacks: [], - tokenObtainedCallbacks: [], - silentTokenRenewFailedCallbacks: [] - }; - - Object.defineProperty(this, "profile", { - get: function () { - if (this._token) { - return this._token.profile; - } - } - }); - Object.defineProperty(this, "id_token", { - get: function () { - if (this._token) { - return this._token.id_token; - } - } - }); - Object.defineProperty(this, "access_token", { - get: function () { - if (this._token && !this._token.expired) { - return this._token.access_token; - } - } - }); - Object.defineProperty(this, "expired", { - get: function () { - if (this._token) { - return this._token.expired; - } - return true; - } - }); - Object.defineProperty(this, "expires_in", { - get: function () { - if (this._token) { - return this._token.expires_in; - } - return 0; - } - }); - Object.defineProperty(this, "expires_at", { - get: function () { - if (this._token) { - return this._token.expires_at; - } - return 0; - } - }); - Object.defineProperty(this, "scope", { - get: function () { - return this._token && this._token.scope; - } - }); - Object.defineProperty(this, "scopes", { - get: function () { - if (this._token) { - return [].concat(this._token.scopes); - } - return []; - } - }); - Object.defineProperty(this, "session_state", { - get: function () { - if (this._token) { - return this._token.session_state; - } - } - }); - - var mgr = this; - loadToken(mgr); - if (mgr._settings.store instanceof window.localStorage.constructor) { - window.addEventListener("storage", function (e) { - if (e.key === mgr._settings.persistKey) { - loadToken(mgr); - - if (mgr._token) { - mgr._callTokenObtained(); - } - else { - mgr._callTokenRemoved(); - } - } - }); - } - configureTokenExpired(mgr); - configureAutoRenewToken(mgr); - - // delay this so consuming apps can register for callbacks first - window.setTimeout(function () { - configureTokenExpiring(mgr); - }, 0); -} - -/** - * @param {{ create:function(successCallback:function(), errorCallback:function()):Promise, resolve:function(value:*):Promise, reject:function():Promise}} promiseFactory - */ -TokenManager.setPromiseFactory = function (promiseFactory) { - _promiseFactory = promiseFactory; -}; - -/** - * @param {{getJSON:function(url:string, config:{ headers: object. })}} httpRequest - */ -TokenManager.setHttpRequest = function (httpRequest) { - if ((typeof httpRequest !== 'object') || (typeof httpRequest.getJSON !== 'function')) { - throw Error('The provided value is not a valid http request.'); - } - - _httpRequest = httpRequest; -}; - -TokenManager.prototype._callTokenRemoved = function () { - this._callbacks.tokenRemovedCallbacks.forEach(function (cb) { - cb(); - }); -} - -TokenManager.prototype._callTokenExpiring = function () { - this._callbacks.tokenExpiringCallbacks.forEach(function (cb) { - cb(); - }); -} - -TokenManager.prototype._callTokenExpired = function () { - this._callbacks.tokenExpiredCallbacks.forEach(function (cb) { - cb(); - }); -} - -TokenManager.prototype._callTokenObtained = function () { - this._callbacks.tokenObtainedCallbacks.forEach(function (cb) { - cb(); - }); -} - -TokenManager.prototype._callSilentTokenRenewFailed = function () { - this._callbacks.silentTokenRenewFailedCallbacks.forEach(function (cb) { - cb(); - }); -} - -TokenManager.prototype.saveToken = function (token) { - if (token && !(token instanceof Token)) { - token = Token.fromResponse(token); - } - - this._token = token; - - if (this._settings.persist && !this.expired) { - this._settings.store.setItem(this._settings.persistKey, token.toJSON()); - } - else { - this._settings.store.removeItem(this._settings.persistKey); - } - - if (token) { - this._callTokenObtained(); - } - else { - this._callTokenRemoved(); - } -} - -TokenManager.prototype.addOnTokenRemoved = function (cb) { - this._callbacks.tokenRemovedCallbacks.push(cb); -} - -TokenManager.prototype.addOnTokenObtained = function (cb) { - this._callbacks.tokenObtainedCallbacks.push(cb); -} - -TokenManager.prototype.addOnTokenExpiring = function (cb) { - this._callbacks.tokenExpiringCallbacks.push(cb); -} - -TokenManager.prototype.addOnTokenExpired = function (cb) { - this._callbacks.tokenExpiredCallbacks.push(cb); -} - -TokenManager.prototype.addOnSilentTokenRenewFailed = function (cb) { - this._callbacks.silentTokenRenewFailedCallbacks.push(cb); -} - -TokenManager.prototype.removeToken = function () { - this.saveToken(null); -} - -TokenManager.prototype.redirectForToken = function () { - var oidc = this.oidcClient; - return oidc.createTokenRequestAsync().then(function (request) { - window.location = request.url; - }, function (err) { - console.error("TokenManager.redirectForToken error: " + (err && err.message || "Unknown error")); - return _promiseFactory.reject(err); - }); -} - -TokenManager.prototype.redirectForLogout = function () { - var mgr = this; - return mgr.oidcClient.createLogoutRequestAsync(mgr.id_token).then(function (url) { - mgr.removeToken(); - window.location = url; - }, function (err) { - console.error("TokenManager.redirectForLogout error: " + (err && err.message || "Unknown error")); - return _promiseFactory.reject(err); - }); -} - -TokenManager.prototype.processTokenCallbackAsync = function (queryString) { - var mgr = this; - return mgr.oidcClient.processResponseAsync(queryString).then(function (token) { - mgr.saveToken(token); - }); -} - -TokenManager.prototype.renewTokenSilentAsync = function () { - var mgr = this; - - if (!mgr._settings.silent_redirect_uri) { - return _promiseFactory.reject(Error("silent_redirect_uri not configured")); - } - - var settings = copy(mgr._settings); - settings.redirect_uri = settings.silent_redirect_uri; - if (!settings.prompt) { - settings.prompt = "none"; - } - - var oidc = new OidcClient(settings); - return oidc.createTokenRequestAsync().then(function (request) { - var frame = new FrameLoader(request.url, { cancelDelay: mgr._settings.silent_renew_timeout }); - return frame.loadAsync().then(function (hash) { - return oidc.processResponseAsync(hash).then(function (token) { - mgr.saveToken(token); - }); - }); - }); -} - -TokenManager.prototype.processTokenCallbackSilent = function (hash) { - if (window.parent && window !== window.parent) { - var hash = hash || window.location.hash; - if (hash) { - window.parent.postMessage(hash, location.protocol + "//" + location.host); - } - } -} - -TokenManager.prototype.openPopupForTokenAsync = function (popupSettings) { - popupSettings = popupSettings || {}; - popupSettings.features = popupSettings.features || "location=no,toolbar=no"; - popupSettings.target = popupSettings.target || "_blank"; - - var callback_prefix = "tokenmgr_callback_"; - - // this is a shared callback - if (!window.openPopupForTokenAsyncCallback) { - window.openPopupForTokenAsyncCallback = function (hash) { - var result = OidcClient.parseOidcResult(hash); - if (result && result.state && window[callback_prefix + result.state]) { - window[callback_prefix + result.state](hash); - } - } - } - - var mgr = this; - var settings = copy(mgr._settings); - settings.redirect_uri = settings.popup_redirect_uri || settings.redirect_uri; - - if (mgr._pendingPopup) { - return _promiseFactory.create(function (resolve, reject) { - reject(Error("Already a pending popup token request.")); - }); - } - - var popup = window.open(settings.redirect_uri, popupSettings.target, popupSettings.features); - if (!popup) { - return _promiseFactory.create(function (resolve, reject) { - reject(Error("Error opening popup.")); - }); - } - - mgr._pendingPopup = true; - - function cleanup(name) { - if (handle) { - window.clearInterval(handle); - } - popup.close(); - delete mgr._pendingPopup; - if (name) { - delete window[name]; - } - } - - var reject_popup; - function checkClosed() { - if (!popup.window) { - cleanup(); - reject_popup(Error("Popup closed")); - } - } - var handle = window.setInterval(checkClosed, 1000); - - return _promiseFactory.create(function (resolve, reject) { - reject_popup = reject; - - var oidc = new OidcClient(settings); - oidc.createTokenRequestAsync().then(function (request) { - - var callback_name = callback_prefix + request.request_state.state; - window[callback_name] = function (hash) { - cleanup(callback_name); - - oidc.processResponseAsync(hash).then(function (token) { - mgr.saveToken(token); - resolve(); - }, function (err) { - reject(err); - }); - }; - - // give the popup 5 seconds to ready itself, otherwise fail - var seconds_to_wait = 5; - var interval = 500; - var total_times = (seconds_to_wait*1000) / interval; - var count = 0; - function redirectPopup() { - if (popup.setUrl) { - popup.setUrl(request.url); - } - else if (count < total_times) { - count++; - window.setTimeout(redirectPopup, interval); - } - else { - cleanup(callback_name); - reject(Error("Timeout error on popup")); - } - } - redirectPopup(); - }, function (err) { - cleanup(); - reject(err); - }); - }); -} - -TokenManager.prototype.processTokenPopup = function (hash) { - hash = hash || window.location.hash; - - window.setUrl = function (url) { - window.location = url; - } - - if (hash) { - window.opener.openPopupForTokenAsyncCallback(hash); - } -} - - - // exports - window.OidcTokenManager = TokenManager; -})(); diff --git a/src/Services/Basket/Basket.API/Auth/Client/popup.html b/src/Services/Basket/Basket.API/Auth/Client/popup.html deleted file mode 100644 index 364f8d7dd..000000000 --- a/src/Services/Basket/Basket.API/Auth/Client/popup.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/src/Services/Basket/Basket.API/Auth/Server/AuthorizationHeaderParameterOperationFilter.cs b/src/Services/Basket/Basket.API/Auth/Server/AuthorizationHeaderParameterOperationFilter.cs deleted file mode 100644 index 2acda7be8..000000000 --- a/src/Services/Basket/Basket.API/Auth/Server/AuthorizationHeaderParameterOperationFilter.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Basket.API.Auth.Server; - -public class AuthorizationHeaderParameterOperationFilter : IOperationFilter -{ - public void Apply(OpenApiOperation operation, OperationFilterContext context) - { - var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors; - var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter); - var allowAnonymous = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter); - - if (isAuthorized && !allowAnonymous) - { - operation.Parameters ??= new List(); - - - operation.Parameters.Add(new OpenApiParameter - { - Name = "Authorization", - In = ParameterLocation.Header, - Description = "access token", - Required = true - }); - } - } -} diff --git a/src/Services/Basket/Basket.API/GlobalUsings.cs b/src/Services/Basket/Basket.API/GlobalUsings.cs index a24875d35..84a9edcbb 100644 --- a/src/Services/Basket/Basket.API/GlobalUsings.cs +++ b/src/Services/Basket/Basket.API/GlobalUsings.cs @@ -1,8 +1,15 @@ -global using Autofac; +global using System; +global using System.Collections.Generic; +global using System.ComponentModel.DataAnnotations; +global using System.Linq; +global using System.Net; +global using System.Security.Claims; +global using System.Text.Json; +global using System.Threading.Tasks; +global using Autofac; global using Basket.API.Infrastructure.ActionResults; global using Basket.API.Infrastructure.Exceptions; global using Basket.API.Infrastructure.Filters; -global using Basket.API.Infrastructure.Middlewares; global using Basket.API.IntegrationEvents.EventHandling; global using Basket.API.IntegrationEvents.Events; global using Basket.API.Model; @@ -12,32 +19,19 @@ global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.Hosting; global using Microsoft.AspNetCore.Http; -global using Microsoft.AspNetCore.Mvc.Authorization; -global using Microsoft.AspNetCore.Mvc.Filters; global using Microsoft.AspNetCore.Mvc; +global using Microsoft.AspNetCore.Mvc.Filters; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; +global using Microsoft.eShopOnContainers.Services.Basket.API; global using Microsoft.eShopOnContainers.Services.Basket.API.Infrastructure.Repositories; global using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.EventHandling; global using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Events; global using Microsoft.eShopOnContainers.Services.Basket.API.Model; global using Microsoft.eShopOnContainers.Services.Basket.API.Services; -global using Microsoft.eShopOnContainers.Services.Basket.API; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; -global using Microsoft.OpenApi.Models; global using Serilog.Context; -global using Serilog; global using StackExchange.Redis; -global using Swashbuckle.AspNetCore.SwaggerGen; -global using System.Collections.Generic; -global using System.ComponentModel.DataAnnotations; -global using System.IO; -global using System.Linq; -global using System.Net; -global using System.Security.Claims; -global using System.Text.Json; -global using System.Threading.Tasks; -global using System; diff --git a/src/Services/Basket/Basket.API/Infrastructure/Exceptions/FailingMiddlewareAppBuilderExtensions.cs b/src/Services/Basket/Basket.API/Infrastructure/Exceptions/FailingMiddlewareAppBuilderExtensions.cs deleted file mode 100644 index 66f55dddd..000000000 --- a/src/Services/Basket/Basket.API/Infrastructure/Exceptions/FailingMiddlewareAppBuilderExtensions.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Basket.API.Infrastructure.Middlewares; - -public static class FailingMiddlewareAppBuilderExtensions -{ - public static IApplicationBuilder UseFailingMiddleware(this IApplicationBuilder builder) - { - return UseFailingMiddleware(builder, null); - } - - public static IApplicationBuilder UseFailingMiddleware(this IApplicationBuilder builder, Action action) - { - var options = new FailingOptions(); - action?.Invoke(options); - builder.UseMiddleware(options); - return builder; - } -} - diff --git a/src/Services/Basket/Basket.API/Infrastructure/Middlewares/AuthorizeCheckOperationFilter.cs b/src/Services/Basket/Basket.API/Infrastructure/Middlewares/AuthorizeCheckOperationFilter.cs deleted file mode 100644 index 9608ec0a7..000000000 --- a/src/Services/Basket/Basket.API/Infrastructure/Middlewares/AuthorizeCheckOperationFilter.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Basket.API.Infrastructure.Filters; - -public class AuthorizeCheckOperationFilter : IOperationFilter -{ - public void Apply(OpenApiOperation operation, OperationFilterContext context) - { - // Check for authorize attribute - var hasAuthorize = context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType().Any() || - context.MethodInfo.GetCustomAttributes(true).OfType().Any(); - - if (!hasAuthorize) return; - - operation.Responses.TryAdd("401", new OpenApiResponse { Description = "Unauthorized" }); - operation.Responses.TryAdd("403", new OpenApiResponse { Description = "Forbidden" }); - - var oAuthScheme = new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" } - }; - - operation.Security = new List - { - new() - { - [ oAuthScheme ] = new [] { "basketapi" } - } - }; - } -} diff --git a/src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingMiddleware.cs b/src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingMiddleware.cs deleted file mode 100644 index 60fbdb655..000000000 --- a/src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingMiddleware.cs +++ /dev/null @@ -1,90 +0,0 @@ -namespace Basket.API.Infrastructure.Middlewares; - -using Microsoft.Extensions.Logging; - -public class FailingMiddleware -{ - private readonly RequestDelegate _next; - private bool _mustFail; - private readonly FailingOptions _options; - private readonly ILogger _logger; - - public FailingMiddleware(RequestDelegate next, ILogger logger, FailingOptions options) - { - _next = next; - _options = options; - _mustFail = false; - _logger = logger; - } - - public async Task Invoke(HttpContext context) - { - var path = context.Request.Path; - if (path.Equals(_options.ConfigPath, StringComparison.OrdinalIgnoreCase)) - { - await ProcessConfigRequest(context); - return; - } - - if (MustFail(context)) - { - _logger.LogInformation("Response for path {Path} will fail.", path); - context.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError; - context.Response.ContentType = "text/plain"; - await context.Response.WriteAsync("Failed due to FailingMiddleware enabled."); - } - else - { - await _next.Invoke(context); - } - } - - private async Task ProcessConfigRequest(HttpContext context) - { - var enable = context.Request.Query.Keys.Any(k => k == "enable"); - var disable = context.Request.Query.Keys.Any(k => k == "disable"); - - if (enable && disable) - { - throw new ArgumentException("Must use enable or disable querystring values, but not both"); - } - - if (disable) - { - _mustFail = false; - await SendOkResponse(context, "FailingMiddleware disabled. Further requests will be processed."); - return; - } - if (enable) - { - _mustFail = true; - await SendOkResponse(context, "FailingMiddleware enabled. Further requests will return HTTP 500"); - return; - } - - // If reach here, that means that no valid parameter has been passed. Just output status - await SendOkResponse(context, string.Format("FailingMiddleware is {0}", _mustFail ? "enabled" : "disabled")); - return; - } - - private async Task SendOkResponse(HttpContext context, string message) - { - context.Response.StatusCode = (int)System.Net.HttpStatusCode.OK; - context.Response.ContentType = "text/plain"; - await context.Response.WriteAsync(message); - } - - private bool MustFail(HttpContext context) - { - var rpath = context.Request.Path.Value; - - if (_options.NotFilteredPaths.Any(p => p.Equals(rpath, StringComparison.InvariantCultureIgnoreCase))) - { - return false; - } - - return _mustFail && - (_options.EndpointPaths.Any(x => x == rpath) - || _options.EndpointPaths.Count == 0); - } -} diff --git a/src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingOptions.cs b/src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingOptions.cs deleted file mode 100644 index 7818938d2..000000000 --- a/src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingOptions.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Basket.API.Infrastructure.Middlewares; - -public class FailingOptions -{ - public string ConfigPath = "/Failing"; - public List EndpointPaths { get; set; } = new List(); - - public List NotFilteredPaths { get; set; } = new List(); -} - diff --git a/src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingStartupFilter.cs b/src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingStartupFilter.cs deleted file mode 100644 index 74da62b5d..000000000 --- a/src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingStartupFilter.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Basket.API.Infrastructure.Middlewares; - -public class FailingStartupFilter : IStartupFilter -{ - private readonly Action _options; - public FailingStartupFilter(Action optionsAction) - { - _options = optionsAction; - } - - public Action Configure(Action next) - { - return app => - { - app.UseFailingMiddleware(_options); - next(app); - }; - } -} - diff --git a/src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingWebHostBuilderExtensions.cs b/src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingWebHostBuilderExtensions.cs deleted file mode 100644 index 8a8ba9523..000000000 --- a/src/Services/Basket/Basket.API/Infrastructure/Middlewares/FailingWebHostBuilderExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Basket.API.Infrastructure.Middlewares; - -public static class WebHostBuildertExtensions -{ - public static IWebHostBuilder UseFailing(this IWebHostBuilder builder, Action options) - { - builder.ConfigureServices(services => - { - services.AddSingleton(new FailingStartupFilter(options)); - }); - return builder; - } -} - diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index 63ae7ce25..9c7d98d03 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -45,7 +45,6 @@ - diff --git a/src/Services/Catalog/Catalog.API/GlobalUsings.cs b/src/Services/Catalog/Catalog.API/GlobalUsings.cs index 19d407fbb..812aa9960 100644 --- a/src/Services/Catalog/Catalog.API/GlobalUsings.cs +++ b/src/Services/Catalog/Catalog.API/GlobalUsings.cs @@ -1,48 +1,47 @@ -global using Autofac; -global using Microsoft.eShopOnContainers.Services.Catalog.API.Extensions; -global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.ActionResults; -global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.Exceptions; -global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents; +global using System; +global using System.Collections.Generic; +global using System.Data.Common; +global using System.Data.SqlClient; +global using System.Globalization; +global using System.IO; +global using System.IO.Compression; +global using System.Linq; +global using System.Net; +global using System.Text.RegularExpressions; +global using System.Threading.Tasks; global using Grpc.Core; +global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.Hosting; global using Microsoft.AspNetCore.Http; -global using Microsoft.AspNetCore.Builder; -global using Microsoft.AspNetCore.Mvc.Filters; global using Microsoft.AspNetCore.Mvc; -global using Microsoft.Extensions.Logging; +global using Microsoft.AspNetCore.Mvc.Filters; +global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Design; global using Microsoft.EntityFrameworkCore.Metadata.Builders; -global using Microsoft.EntityFrameworkCore; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; +global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Utilities; -global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; +global using Microsoft.eShopOnContainers.Services.Catalog.API; +global using Microsoft.eShopOnContainers.Services.Catalog.API.Extensions; +global using Microsoft.eShopOnContainers.Services.Catalog.API.Grpc; global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; +global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.ActionResults; global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.EntityConfigurations; -global using Microsoft.eShopOnContainers.Services.Catalog.API; +global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.Exceptions; +global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.Filters; +global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents; +global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling; global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events; global using Microsoft.eShopOnContainers.Services.Catalog.API.Model; global using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel; -global using Microsoft.eShopOnContainers.Services.Catalog.API.Grpc; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.FileProviders; global using Microsoft.Extensions.Hosting; +global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; -global using Polly.Retry; global using Polly; +global using Polly.Retry; global using Serilog.Context; -global using System.Collections.Generic; -global using System.Data.Common; -global using System.Data.SqlClient; -global using System.Globalization; -global using System.IO.Compression; -global using System.IO; -global using System.Linq; -global using System.Net; -global using System.Text.RegularExpressions; -global using System.Threading.Tasks; -global using System; -global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.Filters; -global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling; -global using Microsoft.Extensions.FileProviders; From bff808016e902ed40ae61ed593406780d6c96b62 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Wed, 3 May 2023 08:07:50 -0700 Subject: [PATCH 027/118] Remove the UseVault and use the existance of the section --- .../Basket/Basket.API/appsettings.json | 6 -- .../Catalog/Catalog.API/appsettings.json | 6 -- .../Services.Common/CommonExtensions.cs | 58 ++++++++++++------- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json index 46a21d4c2..e628394a8 100644 --- a/src/Services/Basket/Basket.API/appsettings.json +++ b/src/Services/Basket/Basket.API/appsettings.json @@ -19,12 +19,6 @@ "ApplicationInsights": { "InstrumentationKey": "" }, - "UseVault": false, - "Vault": { - "Name": "eshop", - "ClientId": "your-client-id", - "ClientSecret": "your-client-secret" - }, "OpenApi": { "Endpoint": { "Name": "" diff --git a/src/Services/Catalog/Catalog.API/appsettings.json b/src/Services/Catalog/Catalog.API/appsettings.json index dda8c7a17..c05acb89b 100644 --- a/src/Services/Catalog/Catalog.API/appsettings.json +++ b/src/Services/Catalog/Catalog.API/appsettings.json @@ -17,12 +17,6 @@ "ApplicationInsights": { "InstrumentationKey": "" }, - "UseVault": false, - "Vault": { - "Name": "eshop", - "ClientId": "your-client-id", - "ClientSecret": "your-client-secret" - }, "OpenApi": { "Endpoint": { "Name": "" diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index a26e59722..d03764ce2 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -1,5 +1,6 @@ using System.IdentityModel.Tokens.Jwt; using System.Net; +using Autofac.Core; using Azure.Identity; using HealthChecks.UI.Client; using Microsoft.AspNetCore.Builder; @@ -79,6 +80,13 @@ public static class CommonExtensions public static IApplicationBuilder UseDefaultOpenApi(this IApplicationBuilder app, IConfiguration configuration) { + var openApiSection = configuration.GetRequiredSection("OpenApi"); + + if (!openApiSection.Exists()) + { + return app; + } + app.UseSwagger(); app.UseSwaggerUI(setup => { @@ -95,7 +103,6 @@ public static class CommonExtensions /// } var pathBase = configuration["PATH_BASE"]; - var openApiSection = configuration.GetRequiredSection("OpenApi"); var authSection = openApiSection.GetSection("Auth"); var endpointSection = openApiSection.GetRequiredSection("Endpoint"); @@ -113,11 +120,17 @@ public static class CommonExtensions return app; } - public static IServiceCollection AddDefaultOpenApi(this IServiceCollection services, IConfiguration configuration) => - services.AddSwaggerGen(options => + public static IServiceCollection AddDefaultOpenApi(this IServiceCollection services, IConfiguration configuration) + { + var openApi = configuration.GetRequiredSection("OpenApi"); + + if (!openApi.Exists()) { - var openApi = configuration.GetRequiredSection("OpenApi"); + return services; + } + return services.AddSwaggerGen(options => + { /// { /// "OpenApi": { /// "Document": { @@ -174,6 +187,7 @@ public static class CommonExtensions options.OperationFilter(); }); + } public static IServiceCollection AddDefaultAuthentication(this IServiceCollection services, IConfiguration configuration) { @@ -243,27 +257,29 @@ public static class CommonExtensions public static ConfigurationManager AddKeyVault(this ConfigurationManager configuration) { - if (configuration.GetValue("UseVault", false)) - { - // { - // "Vault": { - // "Name": "myvault", - // "TenantId": "mytenantid", - // "ClientId": "myclientid", - // } - // } + // { + // "Vault": { + // "Name": "myvault", + // "TenantId": "mytenantid", + // "ClientId": "myclientid", + // } + // } - var vaultSection = configuration.GetRequiredSection("Vault"); + var vaultSection = configuration.GetSection("Vault"); - var credential = new ClientSecretCredential( - vaultSection.GetRequiredValue("TenantId"), - vaultSection.GetRequiredValue("ClientId"), - vaultSection.GetRequiredValue("ClientSecret")); + if (!vaultSection.Exists()) + { + return configuration; + } - var name = vaultSection.GetRequiredValue("Name"); + var credential = new ClientSecretCredential( + vaultSection.GetRequiredValue("TenantId"), + vaultSection.GetRequiredValue("ClientId"), + vaultSection.GetRequiredValue("ClientSecret")); - configuration.AddAzureKeyVault(new Uri($"https://{name}.vault.azure.net/"), credential); - } + var name = vaultSection.GetRequiredValue("Name"); + + configuration.AddAzureKeyVault(new Uri($"https://{name}.vault.azure.net/"), credential); return configuration; } From 45a04e4a6d853e08786059cc337019910ab00d8f Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 01:10:34 -0700 Subject: [PATCH 028/118] Make services run individually and outside of docker - Removed manual port binding code - Disable Seq and logstash if config is null - Disable serilog for now - Remove IIS from some launch profiles - Clean up some logging. --- .../Basket/Basket.API/Basket.API.csproj | 67 +++++------------ .../Basket/Basket.API/GlobalUsings.cs | 1 + src/Services/Basket/Basket.API/Program.cs | 12 +-- .../Basket.API/Properties/launchSettings.json | 22 +----- .../Basket/Basket.API/appsettings.json | 30 +++----- .../Properties/launchSettings.json | 21 +----- .../Identity/Identity.API/appsettings.json | 5 +- .../Services.Common/CommonExtensions.cs | 75 +++++-------------- 8 files changed, 60 insertions(+), 173 deletions(-) diff --git a/src/Services/Basket/Basket.API/Basket.API.csproj b/src/Services/Basket/Basket.API/Basket.API.csproj index c9d7929a8..bab47e191 100644 --- a/src/Services/Basket/Basket.API/Basket.API.csproj +++ b/src/Services/Basket/Basket.API/Basket.API.csproj @@ -1,54 +1,23 @@  - - net7.0 - $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; - ..\..\..\..\docker-compose.dcproj - false - true - + + net7.0 + ..\..\..\..\docker-compose.dcproj + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - + + + + + - - - - - - + + + diff --git a/src/Services/Basket/Basket.API/GlobalUsings.cs b/src/Services/Basket/Basket.API/GlobalUsings.cs index 84a9edcbb..bef9dcdae 100644 --- a/src/Services/Basket/Basket.API/GlobalUsings.cs +++ b/src/Services/Basket/Basket.API/GlobalUsings.cs @@ -34,4 +34,5 @@ global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; global using Serilog.Context; +global using Services.Common; global using StackExchange.Redis; diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index e7dd796e2..0563867fb 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -1,6 +1,4 @@ -using Services.Common; - -var builder = WebApplication.CreateBuilder(args); +var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); @@ -25,10 +23,10 @@ builder.Services.AddTransient(); var app = builder.Build(); -app.MapGet("/", () => Results.Redirect("/swagger")); - app.UseServiceDefaults(); +app.MapGet("/", () => Results.Redirect("/swagger")); + app.MapGrpcService(); app.MapControllers(); @@ -39,10 +37,6 @@ eventBus.Subscribe p.Key, p => p.Value); + var scopes = identitySection.GetRequiredSection("Scopes").GetChildren().ToDictionary(p => p.Key, p => p.Value); options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { @@ -194,8 +188,7 @@ public static class CommonExtensions // { // "Identity": { // "Url": "http://identity", - // "Audience": "basket", - // "Scope": "basket" + // "Audience": "basket" // } // } @@ -221,40 +214,9 @@ public static class CommonExtensions options.TokenValidationParameters.ValidateAudience = false; }); - services.AddAuthorization(options => - { - var scope = identitySection.GetRequiredValue("Scope"); - - options.AddPolicy("ApiScope", policy => - { - policy.RequireAuthenticatedUser(); - policy.RequireClaim("scope", scope); - }); - }); - return services; } - public static IWebHostBuilder UseDefaultPorts(this IWebHostBuilder builder, IConfiguration configuration) - { - builder.UseKestrel(options => - { - var (httpPort, grpcPort) = GetDefinedPorts(configuration); - - options.Listen(IPAddress.Any, httpPort, listenOptions => - { - listenOptions.Protocols = HttpProtocols.Http1AndHttp2; - }); - - options.Listen(IPAddress.Any, grpcPort, listenOptions => - { - listenOptions.Protocols = HttpProtocols.Http2; - }); - }); - - return builder; - } - public static ConfigurationManager AddKeyVault(this ConfigurationManager configuration) { // { @@ -432,15 +394,25 @@ public static class CommonExtensions { var seqServerUrl = configuration["Serilog:SeqServerUrl"]; var logstashUrl = configuration["Serilog:LogstashgUrl"]; - return new LoggerConfiguration() + + var loggingConfiguration = new LoggerConfiguration() .MinimumLevel.Verbose() .Enrich.WithProperty("ApplicationContext", name) .Enrich.FromLogContext() .WriteTo.Console() - .WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl) - .WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl, null) - .ReadFrom.Configuration(configuration) - .CreateLogger(); + .ReadFrom.Configuration(configuration); + + if (!string.IsNullOrEmpty(seqServerUrl)) + { + loggingConfiguration.WriteTo.Seq(seqServerUrl); + } + + if (!string.IsNullOrEmpty(logstashUrl)) + { + loggingConfiguration.WriteTo.Http(logstashUrl, null); + } + + return loggingConfiguration.CreateLogger(); } } @@ -458,13 +430,6 @@ public static class CommonExtensions }); } - static (int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config) - { - var grpcPort = config.GetValue("GRPC_PORT", 5001); - var port = config.GetValue("PORT", 80); - return (port, grpcPort); - } - private static string GetRequiredValue(this IConfiguration configuration, string name) => configuration[name] ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":" + name : name)}"); } From 41056e54d8f0fc93f8686f1c2b4ef1267e0ce0c0 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 01:45:33 -0700 Subject: [PATCH 029/118] Update grpc reference --- src/Directory.Packages.props | 1 + src/Services/Basket/Basket.API/Basket.API.csproj | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index fc3d89ee9..6114b6a05 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -29,6 +29,7 @@ + diff --git a/src/Services/Basket/Basket.API/Basket.API.csproj b/src/Services/Basket/Basket.API/Basket.API.csproj index bab47e191..bf480f2dc 100644 --- a/src/Services/Basket/Basket.API/Basket.API.csproj +++ b/src/Services/Basket/Basket.API/Basket.API.csproj @@ -5,9 +5,7 @@ - - - + From b48ba7b74b28cda8d7c02d7dbb6c08a5d388b57e Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 01:47:30 -0700 Subject: [PATCH 030/118] More clean up --- src/Services/Basket/Basket.API/Basket.API.csproj | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Services/Basket/Basket.API/Basket.API.csproj b/src/Services/Basket/Basket.API/Basket.API.csproj index bf480f2dc..644b865bb 100644 --- a/src/Services/Basket/Basket.API/Basket.API.csproj +++ b/src/Services/Basket/Basket.API/Basket.API.csproj @@ -10,9 +10,7 @@
- - - + From 56d47db91ee8fba312e69b3b593b85388a8d40a6 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 02:08:09 -0700 Subject: [PATCH 031/118] Read from the connection strings section --- .../Basket/Basket.API/Basket.API.csproj | 1 + .../Properties/serviceDependencies.json | 12 ++++++++++++ .../Properties/serviceDependencies.local.json | 16 ++++++++++++++++ .../Basket/Basket.API/appsettings.json | 4 ++-- .../Identity.API/ProgramExtensions.cs | 4 ++-- .../Properties/serviceDependencies.json | 9 +++++++++ .../Properties/serviceDependencies.local.json | 14 ++++++++++++++ .../Identity/Identity.API/appsettings.json | 1 - .../Services.Common/CommonExtensions.cs | 19 ++++++++++++------- 9 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 src/Services/Basket/Basket.API/Properties/serviceDependencies.json create mode 100644 src/Services/Basket/Basket.API/Properties/serviceDependencies.local.json create mode 100644 src/Services/Identity/Identity.API/Properties/serviceDependencies.json create mode 100644 src/Services/Identity/Identity.API/Properties/serviceDependencies.local.json diff --git a/src/Services/Basket/Basket.API/Basket.API.csproj b/src/Services/Basket/Basket.API/Basket.API.csproj index 644b865bb..850660fdc 100644 --- a/src/Services/Basket/Basket.API/Basket.API.csproj +++ b/src/Services/Basket/Basket.API/Basket.API.csproj @@ -2,6 +2,7 @@ net7.0 ..\..\..\..\docker-compose.dcproj + 2964ec8e-0d48-4541-b305-94cab537f867 diff --git a/src/Services/Basket/Basket.API/Properties/serviceDependencies.json b/src/Services/Basket/Basket.API/Properties/serviceDependencies.json new file mode 100644 index 000000000..696e09f1b --- /dev/null +++ b/src/Services/Basket/Basket.API/Properties/serviceDependencies.json @@ -0,0 +1,12 @@ +{ + "dependencies": { + "secrets1": { + "type": "secrets" + }, + "rabbitmq1": { + "type": "rabbitmq", + "connectionId": "eventbus", + "dynamicId": null + } + } +} \ No newline at end of file diff --git a/src/Services/Basket/Basket.API/Properties/serviceDependencies.local.json b/src/Services/Basket/Basket.API/Properties/serviceDependencies.local.json new file mode 100644 index 000000000..81f47080f --- /dev/null +++ b/src/Services/Basket/Basket.API/Properties/serviceDependencies.local.json @@ -0,0 +1,16 @@ +{ + "dependencies": { + "secrets1": { + "type": "secrets.user" + }, + "rabbitmq1": { + "containerPorts": "5672:5672,15672:15672", + "secretStore": "LocalSecretsFile", + "containerName": "rabbitmq", + "containerImage": "rabbitmq:3-management-alpine", + "type": "rabbitmq.container", + "connectionId": "eventbus", + "dynamicId": null + } + } +} \ No newline at end of file diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json index 171521d27..f425b8f17 100644 --- a/src/Services/Basket/Basket.API/appsettings.json +++ b/src/Services/Basket/Basket.API/appsettings.json @@ -20,7 +20,8 @@ } }, "ConnectionStrings": { - "Redis": "localhost" + "Redis": "localhost", + "EventBus": "localhost" }, "Identity": { "Audience": "basket", @@ -30,7 +31,6 @@ }, "EventBus": { "SubscriptionClientName": "Basket", - "ConnectionString": "localhost", "RetryCount": 5 } } diff --git a/src/Services/Identity/Identity.API/ProgramExtensions.cs b/src/Services/Identity/Identity.API/ProgramExtensions.cs index ac869b6ae..19f5e71d2 100644 --- a/src/Services/Identity/Identity.API/ProgramExtensions.cs +++ b/src/Services/Identity/Identity.API/ProgramExtensions.cs @@ -41,7 +41,7 @@ public static class ProgramExtensions public static void AddCustomDatabase(this WebApplicationBuilder builder) => builder.Services.AddDbContext( - options => options.UseSqlServer(builder.Configuration["ConnectionString"])); + options => options.UseSqlServer(builder.Configuration.GetConnectionString("IdentityDb"))); public static void AddCustomIdentity(this WebApplicationBuilder builder) { @@ -82,7 +82,7 @@ public static class ProgramExtensions { builder.Services.AddHealthChecks() .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddSqlServer(builder.Configuration["ConnectionString"], + .AddSqlServer(builder.Configuration.GetConnectionString("IdentityDb"), name: "IdentityDB-check", tags: new string[] { "IdentityDB" }); } diff --git a/src/Services/Identity/Identity.API/Properties/serviceDependencies.json b/src/Services/Identity/Identity.API/Properties/serviceDependencies.json new file mode 100644 index 000000000..718987b23 --- /dev/null +++ b/src/Services/Identity/Identity.API/Properties/serviceDependencies.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "mssql1": { + "type": "mssql", + "connectionId": "ConnectionString", + "dynamicId": null + } + } +} \ No newline at end of file diff --git a/src/Services/Identity/Identity.API/Properties/serviceDependencies.local.json b/src/Services/Identity/Identity.API/Properties/serviceDependencies.local.json new file mode 100644 index 000000000..cae5e3931 --- /dev/null +++ b/src/Services/Identity/Identity.API/Properties/serviceDependencies.local.json @@ -0,0 +1,14 @@ +{ + "dependencies": { + "mssql1": { + "serviceConnectorResourceId": "", + "containerPorts": "1433:1433", + "secretStore": "LocalSecretsFile", + "containerName": "identity-sql", + "containerImage": "mcr.microsoft.com/mssql/server:2019-latest", + "type": "mssql.container", + "connectionId": "ConnectionString", + "dynamicId": null + } + } +} \ No newline at end of file diff --git a/src/Services/Identity/Identity.API/appsettings.json b/src/Services/Identity/Identity.API/appsettings.json index 1f239f782..cc37da9fe 100644 --- a/src/Services/Identity/Identity.API/appsettings.json +++ b/src/Services/Identity/Identity.API/appsettings.json @@ -1,5 +1,4 @@ { - "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true;", "IsClusterEnv": "False", "MvcClient": "http://localhost:5100", "SpaClient": "http://localhost:5104", diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index a523eef83..bd1297682 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -271,12 +271,12 @@ public static class CommonExtensions // { // "EventBus": { // "ProviderName": "ServiceBus | RabbitMQ", - // "ConnectionString": "..." + // } // } var eventBusSection = configuration.GetRequiredSection("EventBus"); - var eventBusConnectionString = eventBusSection.GetRequiredValue("ConnectionString"); + var eventBusConnectionString = configuration.GetRequiredConnectionString("EventBus"); return eventBusSection["ProviderName"]?.ToLowerInvariant() switch { @@ -295,10 +295,14 @@ public static class CommonExtensions public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) { + // { + // "ConnectionStrings": { + // "EventBus": "..." + // }, + // { // "EventBus": { // "ProviderName": "ServiceBus | RabbitMQ", - // "ConnectionString": "...", // ... // } // } @@ -306,7 +310,6 @@ public static class CommonExtensions // { // "EventBus": { // "ProviderName": "ServiceBus", - // "ConnectionString": "..." // "SubscriptionClientName": "eshop_event_bus" // } // } @@ -314,7 +317,6 @@ public static class CommonExtensions // { // "EventBus": { // "ProviderName": "RabbitMQ", - // "ConnectionString": "...", // "SubscriptionClientName": "...", // "UserName": "...", // "Password": "...", @@ -327,7 +329,7 @@ public static class CommonExtensions { services.AddSingleton(sp => { - var serviceBusConnectionString = eventBusSection.GetRequiredValue("ConnectionString"); + var serviceBusConnectionString = configuration.GetRequiredConnectionString("EventBus"); return new DefaultServiceBusPersisterConnection(serviceBusConnectionString); }); @@ -351,7 +353,7 @@ public static class CommonExtensions var factory = new ConnectionFactory() { - HostName = eventBusSection.GetRequiredValue("ConnectionString"), + HostName = configuration.GetRequiredConnectionString("EventBus"), DispatchConsumersAsync = true }; @@ -432,4 +434,7 @@ public static class CommonExtensions private static string GetRequiredValue(this IConfiguration configuration, string name) => configuration[name] ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":" + name : name)}"); + + private static string GetRequiredConnectionString(this IConfiguration configuration, string name) => + configuration.GetConnectionString(name) ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":ConnectionStrings:" + name : "ConnectionStrings:" + name)}"); } From c59e66861fa6fe935d59992d9f2fa7298982f398 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 02:31:14 -0700 Subject: [PATCH 032/118] - Add redis health check - Add health checks on startup --- .../Basket/Basket.API/Basket.API.csproj | 1 + .../Basket.API/CustomExtensionMethods.cs | 7 ++++ src/Services/Basket/Basket.API/Program.cs | 40 ++++++++++++++----- .../Properties/serviceDependencies.json | 5 +++ .../Properties/serviceDependencies.local.json | 10 +++++ .../Services.Common/CommonExtensions.cs | 8 ++-- 6 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/Services/Basket/Basket.API/Basket.API.csproj b/src/Services/Basket/Basket.API/Basket.API.csproj index 850660fdc..5c4a66df3 100644 --- a/src/Services/Basket/Basket.API/Basket.API.csproj +++ b/src/Services/Basket/Basket.API/Basket.API.csproj @@ -7,6 +7,7 @@ + diff --git a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs index 67ee876b0..d92432521 100644 --- a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs +++ b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs @@ -4,6 +4,13 @@ public static class CustomExtensionMethods { public static IServiceCollection AddRedis(this IServiceCollection services, IConfiguration configuration) { + services.AddHealthChecks() + .AddRedis(_ => + { + return configuration.GetConnectionString("redis"); + }, + "redis", tags: new[] { "ready", "liveness" }); + return services.AddSingleton(sp => { var redisConfig = ConfigurationOptions.Parse(configuration.GetConnectionString("redis"), true); diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index 0563867fb..664a152fb 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -1,4 +1,6 @@ -var builder = WebApplication.CreateBuilder(args); +using Microsoft.Extensions.Diagnostics.HealthChecks; + +var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); @@ -23,20 +25,38 @@ builder.Services.AddTransient(); var app = builder.Build(); -app.UseServiceDefaults(); +try +{ + app.Logger.LogInformation("Running health checks..."); -app.MapGet("/", () => Results.Redirect("/swagger")); + // Do a health check on startup, this will throw an exception if any of the checks fail + var report = await app.Services.GetRequiredService().CheckHealthAsync(); -app.MapGrpcService(); -app.MapControllers(); + if (report.Status == HealthStatus.Unhealthy) + { + app.Logger.LogCritical("Health checks failed!"); + foreach (var entry in report.Entries) + { + if (entry.Value.Status == HealthStatus.Unhealthy) + { + app.Logger.LogCritical("{Check}: {Status}", entry.Key, entry.Value.Status); + } + } + return 1; + } -var eventBus = app.Services.GetRequiredService(); + app.UseServiceDefaults(); -eventBus.Subscribe(); -eventBus.Subscribe(); + app.MapGet("/", () => Results.Redirect("/swagger")); + + app.MapGrpcService(); + app.MapControllers(); + + var eventBus = app.Services.GetRequiredService(); + + eventBus.Subscribe(); + eventBus.Subscribe(); -try -{ await app.RunAsync(); return 0; diff --git a/src/Services/Basket/Basket.API/Properties/serviceDependencies.json b/src/Services/Basket/Basket.API/Properties/serviceDependencies.json index 696e09f1b..adb08c8f2 100644 --- a/src/Services/Basket/Basket.API/Properties/serviceDependencies.json +++ b/src/Services/Basket/Basket.API/Properties/serviceDependencies.json @@ -7,6 +7,11 @@ "type": "rabbitmq", "connectionId": "eventbus", "dynamicId": null + }, + "redis1": { + "type": "redis", + "connectionId": "ConnectionStrings:Redis", + "dynamicId": null } } } \ No newline at end of file diff --git a/src/Services/Basket/Basket.API/Properties/serviceDependencies.local.json b/src/Services/Basket/Basket.API/Properties/serviceDependencies.local.json index 81f47080f..8fb5df48a 100644 --- a/src/Services/Basket/Basket.API/Properties/serviceDependencies.local.json +++ b/src/Services/Basket/Basket.API/Properties/serviceDependencies.local.json @@ -11,6 +11,16 @@ "type": "rabbitmq.container", "connectionId": "eventbus", "dynamicId": null + }, + "redis1": { + "serviceConnectorResourceId": "", + "containerPorts": "6379:6379", + "secretStore": "LocalSecretsFile", + "containerName": "basket-redis", + "containerImage": "redis:alpine", + "type": "redis.container", + "connectionId": "ConnectionStrings:Redis", + "dynamicId": null } } } \ No newline at end of file diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index bd1297682..7971b11a3 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -283,13 +283,13 @@ public static class CommonExtensions "servicebus" => hcBuilder.AddAzureServiceBusTopic( eventBusConnectionString, topicName: "eshop_event_bus", - name: "servicebus-check", - tags: new string[] { "servicebus" }), + name: "servicebus", + tags: new string[] { "ready" }), _ => hcBuilder.AddRabbitMQ( $"amqp://{eventBusConnectionString}", - name: "rabbitmqbus-check", - tags: new string[] { "rabbitmqbus" }) + name: "rabbitmq", + tags: new string[] { "ready" }) }; } From d96e4db08c6a48cd45d2f3a454142c57f0cea9cf Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 07:48:07 -0700 Subject: [PATCH 033/118] Remove Program --- .../Basket/Basket.API/Basket.API.csproj | 4 ++ .../Controllers/BasketController.cs | 2 +- .../OrderStartedIntegrationEventHandler.cs | 4 +- ...ductPriceChangedIntegrationEventHandler.cs | 4 +- src/Services/Basket/Basket.API/Program.cs | 8 +--- .../Base/BasketScenarioBase.cs | 44 ++++++++++--------- .../RedisBasketRepositoryTests.cs | 6 ++- 7 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/Services/Basket/Basket.API/Basket.API.csproj b/src/Services/Basket/Basket.API/Basket.API.csproj index 5c4a66df3..173169da1 100644 --- a/src/Services/Basket/Basket.API/Basket.API.csproj +++ b/src/Services/Basket/Basket.API/Basket.API.csproj @@ -18,4 +18,8 @@ + + + + diff --git a/src/Services/Basket/Basket.API/Controllers/BasketController.cs b/src/Services/Basket/Basket.API/Controllers/BasketController.cs index 54c13a982..4bb3b22f6 100644 --- a/src/Services/Basket/Basket.API/Controllers/BasketController.cs +++ b/src/Services/Basket/Basket.API/Controllers/BasketController.cs @@ -71,7 +71,7 @@ public class BasketController : ControllerBase } catch (Exception ex) { - _logger.LogError(ex, "ERROR Publishing integration event: {IntegrationEventId} from {AppName}", eventMessage.Id, Program.AppName); + _logger.LogError(ex, "ERROR Publishing integration event: {IntegrationEventId}", eventMessage.Id); throw; } diff --git a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs index 2c93f82fd..d5cf14e1b 100644 --- a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs +++ b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs @@ -15,9 +15,9 @@ public class OrderStartedIntegrationEventHandler : IIntegrationEventHandler +public class BasketScenarioBase { private const string ApiUrlBase = "api/v1/basket"; public TestServer CreateServer() { - return Server; + var factory = new BasketApplicaton(); + return factory.Server; } public static class Get @@ -26,33 +27,36 @@ public class BasketScenarioBase : WebApplicationFactory public static string CheckoutOrder = $"{ApiUrlBase}/checkout"; } - protected override IHost CreateHost(IHostBuilder builder) + private class BasketApplicaton : WebApplicationFactory { - builder.ConfigureServices(services => + protected override IHost CreateHost(IHostBuilder builder) { - services.AddSingleton(); - }); + builder.ConfigureServices(services => + { + services.AddSingleton(); + }); - builder.ConfigureAppConfiguration(c => - { - var directory = Path.GetDirectoryName(typeof(BasketScenarioBase).Assembly.Location)!; + builder.ConfigureAppConfiguration(c => + { + var directory = Path.GetDirectoryName(typeof(BasketScenarioBase).Assembly.Location)!; - c.AddJsonFile(Path.Combine(directory, "appsettings.json"), optional: false); - }); + c.AddJsonFile(Path.Combine(directory, "appsettings.json"), optional: false); + }); - return base.CreateHost(builder); - } + return base.CreateHost(builder); + } - private class AuthStartupFilter : IStartupFilter - { - public Action Configure(Action next) + private class AuthStartupFilter : IStartupFilter { - return app => + public Action Configure(Action next) { - app.UseMiddleware(); + return app => + { + app.UseMiddleware(); - next(app); - }; + next(app); + }; + } } } } diff --git a/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs b/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs index 217a85ec2..835146c2e 100644 --- a/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs +++ b/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs @@ -9,7 +9,8 @@ namespace Basket.FunctionalTests [Fact] public async Task UpdateBasket_return_and_add_basket() { - var redis = Services.GetRequiredService(); + var server = CreateServer(); + var redis = server.Services.GetRequiredService(); var redisBasketRepository = BuildBasketRepository(redis); @@ -26,7 +27,8 @@ namespace Basket.FunctionalTests [Fact] public async Task Delete_Basket_return_null() { - var redis = Services.GetRequiredService(); + var server = CreateServer(); + var redis = server.Services.GetRequiredService(); var redisBasketRepository = BuildBasketRepository(redis); From 7d28625959ffede81ab87deef54abdbc8a9a4433 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 07:52:40 -0700 Subject: [PATCH 034/118] Remove Serilog from Web.Shopping.HttpAggregator --- .../aggregator/GlobalUsings.cs | 2 - .../Web.Bff.Shopping/aggregator/Program.cs | 39 ++----------------- .../Web.Shopping.HttpAggregator.csproj | 2 - 3 files changed, 3 insertions(+), 40 deletions(-) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/GlobalUsings.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/GlobalUsings.cs index 9aff586f4..c008e8b3e 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/GlobalUsings.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/GlobalUsings.cs @@ -24,7 +24,6 @@ global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using Microsoft.OpenApi.Models; -global using Serilog; global using Swashbuckle.AspNetCore.SwaggerGen; global using System.Collections.Generic; global using System.IdentityModel.Tokens.Jwt; @@ -37,4 +36,3 @@ global using System.Threading.Tasks; global using System.Threading; global using System; global using Microsoft.IdentityModel.Tokens; -global using Serilog.Context; diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs index dc792b866..50df67c3e 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs @@ -1,6 +1,6 @@ var builder = WebApplication.CreateBuilder(args); -builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration)); +builder.Logging.AddConsole(); builder.Services.AddHealthChecks() .AddCheck("self", () => HealthCheckResult.Healthy()) .AddUrlGroup(new Uri(builder.Configuration["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" }) @@ -21,6 +21,7 @@ else { app.UseExceptionHandler("/Home/Error"); } + var pathBase = builder.Configuration["PATH_BASE"]; if (!string.IsNullOrEmpty(pathBase)) { @@ -56,41 +57,7 @@ app.MapHealthChecks("/liveness", new HealthCheckOptions Predicate = r => r.Name.Contains("self") }); -try -{ - Log.Information("Starts Web Application ({ApplicationContext})...", Program.AppName); - await app.RunAsync(); - - return 0; -} -catch (Exception ex) -{ - Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName); - return 1; -} -finally -{ - Log.CloseAndFlush(); -} - -Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) -{ - var seqServerUrl = configuration["Serilog:SeqServerUrl"]; - var logstashUrl = configuration["Serilog:LogstashgUrl"]; - return new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("ApplicationContext", Program.AppName) - .Enrich.FromLogContext() - .WriteTo.Console() - .ReadFrom.Configuration(configuration) - .CreateLogger(); -} -public partial class Program -{ - - public static string Namespace = typeof(Program).Assembly.GetName().Name; - public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1); -} +await app.RunAsync(); public static class ServiceCollectionExtensions { diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj index 782c730ab..5d486d3c6 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj @@ -26,8 +26,6 @@ - - From 3f5f0b94ed33c90bb87344516e0ce380bddd7b20 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 08:02:40 -0700 Subject: [PATCH 035/118] Remove Program from Catalog.API --- ...ductPriceChangedIntegrationEventHandler.cs | 2 +- .../Base/BasketScenarioBase.cs | 4 +- .../Catalog/Catalog.API/Catalog.API.csproj | 4 ++ .../CatalogIntegrationEventService.cs | 4 +- ...aitingValidationIntegrationEventHandler.cs | 4 +- ...tusChangedToPaidIntegrationEventHandler.cs | 4 +- src/Services/Catalog/Catalog.API/Program.cs | 20 +------- .../CatalogScenarioBase.cs | 51 +++++++++++-------- ...ePeriodConfirmedIntegrationEventHandler.cs | 2 +- ...derPaymentFailedIntegrationEventHandler.cs | 2 +- ...PaymentSucceededIntegrationEventHandler.cs | 2 +- ...erStockConfirmedIntegrationEventHandler.cs | 2 +- ...derStockRejectedIntegrationEventHandler.cs | 2 +- ...CheckoutAcceptedIntegrationEventHandler.cs | 2 +- ...aitingValidationIntegrationEventHandler.cs | 2 +- ...angedToCancelledIntegrationEventHandler.cs | 2 +- ...tusChangedToPaidIntegrationEventHandler.cs | 2 +- ...ChangedToShippedIntegrationEventHandler.cs | 2 +- ...ToStockConfirmedIntegrationEventHandler.cs | 2 +- ...angedToSubmittedIntegrationEventHandler.cs | 2 +- ...ToStockConfirmedIntegrationEventHandler.cs | 2 +- 21 files changed, 58 insertions(+), 61 deletions(-) diff --git a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs index c09ba2346..560c43d2a 100644 --- a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs +++ b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs @@ -17,7 +17,7 @@ public class ProductPriceChangedIntegrationEventHandler : IIntegrationEventHandl { using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}")) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var userIds = _repository.GetUsers(); diff --git a/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs index ddf920e14..8f56d94c3 100644 --- a/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs +++ b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs @@ -9,7 +9,7 @@ public class BasketScenarioBase public TestServer CreateServer() { - var factory = new BasketApplicaton(); + var factory = new BasketApplication(); return factory.Server; } @@ -27,7 +27,7 @@ public class BasketScenarioBase public static string CheckoutOrder = $"{ApiUrlBase}/checkout"; } - private class BasketApplicaton : WebApplicationFactory + private class BasketApplication : WebApplicationFactory { protected override IHost CreateHost(IHostBuilder builder) { diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index 9c7d98d03..0d834939a 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -37,6 +37,10 @@ + + + + diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs index 282bea5b3..15cbb7ff7 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs @@ -26,7 +26,7 @@ public class CatalogIntegrationEventService : ICatalogIntegrationEventService, I { try { - _logger.LogInformation("----- Publishing integration event: {IntegrationEventId_published} from {AppName} - ({@IntegrationEvent})", evt.Id, Program.AppName, evt); + _logger.LogInformation("----- Publishing integration event: {IntegrationEventId_published} - ({@IntegrationEvent})", evt.Id, evt); await _eventLogService.MarkEventAsInProgressAsync(evt.Id); _eventBus.Publish(evt); @@ -34,7 +34,7 @@ public class CatalogIntegrationEventService : ICatalogIntegrationEventService, I } catch (Exception ex) { - _logger.LogError(ex, "ERROR Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", evt.Id, Program.AppName, evt); + _logger.LogError(ex, "ERROR Publishing integration event: {IntegrationEventId} - ({@IntegrationEvent})", evt.Id, evt); await _eventLogService.MarkEventAsFailedAsync(evt.Id); } } diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs index 01fb5dfa9..81c9ff909 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs @@ -19,9 +19,9 @@ public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler : public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var confirmedOrderStockItems = new List(); diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs index 8882e78a6..c0f87139a 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs @@ -16,9 +16,9 @@ public class OrderStatusChangedToPaidIntegrationEventHandler : public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); //we're not blocking stock/inventory foreach (var orderStockItem in @event.OrderStockItems) diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index 01287d8be..c39d369c8 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -41,11 +41,8 @@ var eventBus = app.Services.GetRequiredService(); eventBus.Subscribe(); eventBus.Subscribe(); -try +using (var scope = app.Services.CreateScope()) { - app.Logger.LogInformation("Configuring web host ({ApplicationContext})...", AppName); - - using var scope = app.Services.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var settings = app.Services.GetService>(); var logger = app.Services.GetService>(); @@ -54,19 +51,6 @@ try await new CatalogContextSeed().SeedAsync(context, app.Environment, settings, logger); var integEventContext = scope.ServiceProvider.GetRequiredService(); await integEventContext.Database.MigrateAsync(); - app.Logger.LogInformation("Starting web host ({ApplicationName})...", AppName); - await app.RunAsync(); - - return 0; -} -catch (Exception ex) -{ - app.Logger.LogCritical(ex, "Program terminated unexpectedly ({ApplicationContext})!", AppName); - return 1; } -public partial class Program -{ - public static string Namespace = typeof(Program).Assembly.GetName().Name; - public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1); -} +await app.RunAsync(); diff --git a/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs b/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs index 224896537..ee7bb21a8 100644 --- a/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs +++ b/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs @@ -2,36 +2,45 @@ namespace Catalog.FunctionalTests; -public class CatalogScenariosBase : WebApplicationFactory +public class CatalogScenariosBase { public TestServer CreateServer() { - Services - .MigrateDbContext((context, services) => - { - var env = services.GetService(); - var settings = services.GetService>(); - var logger = services.GetService>(); - - new CatalogContextSeed() - .SeedAsync(context, env, settings, logger) - .Wait(); - }) - .MigrateDbContext((_, __) => { }); - - return Server; + var factory = new CatalogApplication(); + return factory.CreateServer(); } - protected override IHost CreateHost(IHostBuilder builder) + private class CatalogApplication : WebApplicationFactory { - builder.ConfigureAppConfiguration(c => + public TestServer CreateServer() + { + Services + .MigrateDbContext((context, services) => + { + var env = services.GetService(); + var settings = services.GetService>(); + var logger = services.GetService>(); + + new CatalogContextSeed() + .SeedAsync(context, env, settings, logger) + .Wait(); + }) + .MigrateDbContext((_, __) => { }); + + return Server; + } + + protected override IHost CreateHost(IHostBuilder builder) { - var directory = Path.GetDirectoryName(typeof(CatalogScenariosBase).Assembly.Location)!; + builder.ConfigureAppConfiguration(c => + { + var directory = Path.GetDirectoryName(typeof(CatalogScenariosBase).Assembly.Location)!; - c.AddJsonFile(Path.Combine(directory, "appsettings.json"), optional: false); - }); + c.AddJsonFile(Path.Combine(directory, "appsettings.json"), optional: false); + }); - return base.CreateHost(builder); + return base.CreateHost(builder); + } } public static class Get diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs index 55a8a39b9..a6056041c 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs @@ -23,7 +23,7 @@ public class GracePeriodConfirmedIntegrationEventHandler : IIntegrationEventHand /// public async Task Handle(GracePeriodConfirmedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs index 4170ac18f..8725408b4 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs @@ -16,7 +16,7 @@ public class OrderPaymentFailedIntegrationEventHandler : public async Task Handle(OrderPaymentFailedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSucceededIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSucceededIntegrationEventHandler.cs index af9817696..c0a69268e 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSucceededIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSucceededIntegrationEventHandler.cs @@ -16,7 +16,7 @@ public class OrderPaymentSucceededIntegrationEventHandler : public async Task Handle(OrderPaymentSucceededIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs index e5ed967a9..e99b49f5e 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs @@ -16,7 +16,7 @@ public class OrderStockConfirmedIntegrationEventHandler : public async Task Handle(OrderStockConfirmedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs index 4fa61b9b5..2468e25a6 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs @@ -14,7 +14,7 @@ public class OrderStockRejectedIntegrationEventHandler : IIntegrationEventHandle public async Task Handle(OrderStockRejectedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs index a5a15c06c..f1c3cc964 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs @@ -24,7 +24,7 @@ public class UserCheckoutAcceptedIntegrationEventHandler : IIntegrationEventHand /// public async Task Handle(UserCheckoutAcceptedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs index 341b781ab..f42889d98 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs @@ -16,7 +16,7 @@ public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler : IIn public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs index aba5091b9..fa2b75ebc 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs @@ -16,7 +16,7 @@ public class OrderStatusChangedToCancelledIntegrationEventHandler : IIntegration public async Task Handle(OrderStatusChangedToCancelledIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs index 03fc04356..bc8ea3d4b 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs @@ -16,7 +16,7 @@ public class OrderStatusChangedToPaidIntegrationEventHandler : IIntegrationEvent public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs index 663f7ae3a..f6356268d 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs @@ -16,7 +16,7 @@ public class OrderStatusChangedToShippedIntegrationEventHandler : IIntegrationEv public async Task Handle(OrderStatusChangedToShippedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs index aa662065d..3289dff9a 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs @@ -17,7 +17,7 @@ public class OrderStatusChangedToStockConfirmedIntegrationEventHandler : public async Task Handle(OrderStatusChangedToStockConfirmedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs index 0f8042013..144a5e7c6 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs @@ -17,7 +17,7 @@ public class OrderStatusChangedToSubmittedIntegrationEventHandler : public async Task Handle(OrderStatusChangedToSubmittedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); diff --git a/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs b/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs index 8c8fac9d0..0712f8908 100644 --- a/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs @@ -21,7 +21,7 @@ public class OrderStatusChangedToStockConfirmedIntegrationEventHandler : public async Task Handle(OrderStatusChangedToStockConfirmedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); From 5342c86af0c4b10d1c80534c87cf3a9859df619d Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 08:22:34 -0700 Subject: [PATCH 036/118] Remove Serilog from Identity.API and clean up --- .../Identity/Identity.API/GlobalUsings.cs | 3 +- .../Identity/Identity.API/Identity.API.csproj | 6 - src/Services/Identity/Identity.API/Program.cs | 86 ++++++------- .../Identity.API/ProgramExtensions.cs | 117 ------------------ 4 files changed, 44 insertions(+), 168 deletions(-) delete mode 100644 src/Services/Identity/Identity.API/ProgramExtensions.cs diff --git a/src/Services/Identity/Identity.API/GlobalUsings.cs b/src/Services/Identity/Identity.API/GlobalUsings.cs index bbbe458c9..a4ecca85f 100644 --- a/src/Services/Identity/Identity.API/GlobalUsings.cs +++ b/src/Services/Identity/Identity.API/GlobalUsings.cs @@ -1,4 +1,4 @@ -global using Azure.Core; +global using Azure.Core; global using Azure.Identity; global using HealthChecks.UI.Client; global using IdentityModel; @@ -41,7 +41,6 @@ global using System.Collections.Generic; global using System.ComponentModel.DataAnnotations; global using System.Data.SqlClient; global using System.IdentityModel.Tokens.Jwt; -global using System.IO; global using System.Linq; global using System.Security.Claims; global using System.Text.RegularExpressions; diff --git a/src/Services/Identity/Identity.API/Identity.API.csproj b/src/Services/Identity/Identity.API/Identity.API.csproj index 58f550997..93bf5b3a5 100644 --- a/src/Services/Identity/Identity.API/Identity.API.csproj +++ b/src/Services/Identity/Identity.API/Identity.API.csproj @@ -37,12 +37,6 @@ - - - - - - diff --git a/src/Services/Identity/Identity.API/Program.cs b/src/Services/Identity/Identity.API/Program.cs index 2dafe5cbe..c0fa8fa7c 100644 --- a/src/Services/Identity/Identity.API/Program.cs +++ b/src/Services/Identity/Identity.API/Program.cs @@ -1,5 +1,4 @@ -var appName = "Identity.API"; -var builder = WebApplication.CreateBuilder(); +var builder = WebApplication.CreateBuilder(args); if (builder.Configuration.GetValue("UseVault", false)) { @@ -10,21 +9,43 @@ if (builder.Configuration.GetValue("UseVault", false)) builder.Configuration.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential); } -builder.AddCustomConfiguration(); -builder.AddCustomSerilog(); -builder.AddCustomMvc(); -builder.AddCustomDatabase(); -builder.AddCustomIdentity(); -builder.AddCustomIdentityServer(); -builder.AddCustomAuthentication(); -builder.AddCustomHealthChecks(); -builder.AddCustomApplicationServices(); +builder.Services.AddControllersWithViews(); +builder.Services.AddControllers(); +builder.Services.AddRazorPages(); -var app = builder.Build(); -if (app.Environment.IsDevelopment()) +builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("IdentityDb"))); +builder.Services.AddIdentity() + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + +builder.Services.AddIdentityServer(options => { - app.UseDeveloperExceptionPage(); -} + options.IssuerUri = "null"; + options.Authentication.CookieLifetime = TimeSpan.FromHours(2); + + options.Events.RaiseErrorEvents = true; + options.Events.RaiseInformationEvents = true; + options.Events.RaiseFailureEvents = true; + options.Events.RaiseSuccessEvents = true; +}) +.AddInMemoryIdentityResources(Config.GetResources()) +.AddInMemoryApiScopes(Config.GetApiScopes()) +.AddInMemoryApiResources(Config.GetApis()) +.AddInMemoryClients(Config.GetClients(builder.Configuration)) +.AddAspNetIdentity() +.AddDeveloperSigningCredential(); // Not recommended for production - you need to store your key material somewhere secure + +builder.Services.AddAuthentication(); +builder.Services.AddHealthChecks() + .AddCheck("self", () => HealthCheckResult.Healthy()) + .AddSqlServer(builder.Configuration.GetConnectionString("IdentityDb"), + name: "IdentityDB-check", + tags: new string[] { "IdentityDB" }); +builder.Services.AddTransient(); +builder.Services.AddTransient, EFLoginService>(); +builder.Services.AddTransient(); + +var app = builder.Build(); var pathBase = builder.Configuration["PATH_BASE"]; if (!string.IsNullOrEmpty(pathBase)) @@ -35,16 +56,11 @@ app.UseStaticFiles(); // This cookie policy fixes login issues with Chrome 80+ using HHTP app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.Lax }); - app.UseRouting(); - app.UseIdentityServer(); - - app.UseAuthorization(); app.MapDefaultControllerRoute(); - app.MapHealthChecks("/hc", new HealthCheckOptions() { Predicate = _ => true, @@ -54,29 +70,13 @@ app.MapHealthChecks("/liveness", new HealthCheckOptions { Predicate = r => r.Name.Contains("self") }); -try -{ - app.Logger.LogInformation("Seeding database ({ApplicationName})...", appName); - - // Apply database migration automatically. Note that this approach is not - // recommended for production scenarios. Consider generating SQL scripts from - // migrations instead. - using (var scope = app.Services.CreateScope()) - { - await SeedData.EnsureSeedData(scope, app.Configuration, app.Logger); - } - app.Logger.LogInformation("Starting web host ({ApplicationName})...", appName); - app.Run(); - - return 0; -} -catch (Exception ex) +// Apply database migration automatically. Note that this approach is not +// recommended for production scenarios. Consider generating SQL scripts from +// migrations instead. +using (var scope = app.Services.CreateScope()) { - app.Logger.LogCritical(ex, "Host terminated unexpectedly ({ApplicationName})...", appName); - return 1; + await SeedData.EnsureSeedData(scope, app.Configuration, app.Logger); } -finally -{ - Serilog.Log.CloseAndFlush(); -} \ No newline at end of file + +await app.RunAsync(); diff --git a/src/Services/Identity/Identity.API/ProgramExtensions.cs b/src/Services/Identity/Identity.API/ProgramExtensions.cs deleted file mode 100644 index 19f5e71d2..000000000 --- a/src/Services/Identity/Identity.API/ProgramExtensions.cs +++ /dev/null @@ -1,117 +0,0 @@ -using Serilog; - -namespace Microsoft.eShopOnContainers.Services.Identity.API; - -public static class ProgramExtensions -{ - private const string AppName = "Identity API"; - - public static void AddCustomConfiguration(this WebApplicationBuilder builder) - { - builder.Configuration.AddConfiguration(GetConfiguration()).Build(); - - } - - public static void AddCustomSerilog(this WebApplicationBuilder builder) - { - var seqServerUrl = builder.Configuration["SeqServerUrl"]; - var logstashUrl = builder.Configuration["LogstashgUrl"]; - - Log.Logger = new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("ApplicationContext", AppName) - .Enrich.FromLogContext() - .WriteTo.Console() - .WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl) - .WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://localhost:8080" : logstashUrl, null) - .ReadFrom.Configuration(builder.Configuration) - .CreateLogger(); - - builder.Host.UseSerilog(); - } - - public static void AddCustomMvc(this WebApplicationBuilder builder) - { - builder.Services.AddControllersWithViews(); - builder.Services.AddControllers(); - builder.Services.AddRazorPages(); - - } - - - public static void AddCustomDatabase(this WebApplicationBuilder builder) => - builder.Services.AddDbContext( - options => options.UseSqlServer(builder.Configuration.GetConnectionString("IdentityDb"))); - - public static void AddCustomIdentity(this WebApplicationBuilder builder) - { - builder.Services.AddIdentity() - .AddEntityFrameworkStores() - .AddDefaultTokenProviders(); - } - - - public static void AddCustomIdentityServer(this WebApplicationBuilder builder) - { - var identityServerBuilder = builder.Services.AddIdentityServer(options => - { - options.IssuerUri = "null"; - options.Authentication.CookieLifetime = TimeSpan.FromHours(2); - - options.Events.RaiseErrorEvents = true; - options.Events.RaiseInformationEvents = true; - options.Events.RaiseFailureEvents = true; - options.Events.RaiseSuccessEvents = true; - }) - .AddInMemoryIdentityResources(Config.GetResources()) - .AddInMemoryApiScopes(Config.GetApiScopes()) - .AddInMemoryApiResources(Config.GetApis()) - .AddInMemoryClients(Config.GetClients(builder.Configuration)) - .AddAspNetIdentity(); - - // not recommended for production - you need to store your key material somewhere secure - identityServerBuilder.AddDeveloperSigningCredential(); - } - - public static void AddCustomAuthentication(this WebApplicationBuilder builder) - { - builder.Services.AddAuthentication(); - } - - public static void AddCustomHealthChecks(this WebApplicationBuilder builder) - { - builder.Services.AddHealthChecks() - .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddSqlServer(builder.Configuration.GetConnectionString("IdentityDb"), - name: "IdentityDB-check", - tags: new string[] { "IdentityDB" }); - } - - public static void AddCustomApplicationServices(this WebApplicationBuilder builder) - { - builder.Services.AddTransient(); - builder.Services.AddTransient, EFLoginService>(); - builder.Services.AddTransient(); - } - - static IConfiguration GetConfiguration() - { - var builder = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) - .AddEnvironmentVariables(); - - var config = builder.Build(); - - if (config.GetValue("UseVault", false)) - { - TokenCredential credential = new ClientSecretCredential( - config["Vault:TenantId"], - config["Vault:ClientId"], - config["Vault:ClientSecret"]); - builder.AddAzureKeyVault(new Uri($"https://{config["Vault:Name"]}.vault.azure.net/"), credential); - } - - return builder.Build(); - } -} From 8da0a81514bb7d9ad33935472ef7f42343d26a98 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 08:39:37 -0700 Subject: [PATCH 037/118] Remove Serilog usage --- .../aggregator/GlobalUsings.cs | 1 - .../Mobile.Shopping.HttpAggregator.csproj | 2 - .../Mobile.Bff.Shopping/aggregator/Program.cs | 11 +- .../TestIntegrationEventHandler.cs | 3 +- .../TestIntegrationOtherEventHandler.cs | 3 +- src/Directory.Packages.props | 6 - .../Basket/Basket.API/GlobalUsings.cs | 1 - .../OrderStartedIntegrationEventHandler.cs | 2 +- ...ductPriceChangedIntegrationEventHandler.cs | 2 +- .../Basket.API/appsettings.Development.json | 10 -- .../Catalog/Catalog.API/Catalog.API.csproj | 6 - .../Catalog/Catalog.API/GlobalUsings.cs | 1 - ...aitingValidationIntegrationEventHandler.cs | 2 +- ...tusChangedToPaidIntegrationEventHandler.cs | 2 +- .../Properties/launchSettings.json | 4 +- .../Catalog.API/appsettings.Development.json | 10 -- .../Catalog/Catalog.API/appsettings.json | 12 -- src/Services/Catalog/Catalog.API/web.config | 2 - .../Identity/Identity.API/appsettings.json | 11 -- .../Behaviors/TransactionBehavior.cs | 2 +- ...ePeriodConfirmedIntegrationEventHandler.cs | 4 +- ...derPaymentFailedIntegrationEventHandler.cs | 4 +- ...PaymentSucceededIntegrationEventHandler.cs | 4 +- ...erStockConfirmedIntegrationEventHandler.cs | 4 +- ...derStockRejectedIntegrationEventHandler.cs | 4 +- ...CheckoutAcceptedIntegrationEventHandler.cs | 6 +- .../OrderingIntegrationEventService.cs | 4 +- .../Extensions/BasketItemExtensions.cs | 1 - .../Ordering/Ordering.API/GlobalUsings.cs | 2 - .../Ordering/Ordering.API/Ordering.API.csproj | 9 +- src/Services/Ordering/Ordering.API/Program.cs | 106 ++-------------- .../Ordering/Ordering.API/appsettings.json | 12 -- .../Extensions/CustomExtensionMethods.cs | 25 +--- .../Ordering.BackgroundTasks/GlobalUsings.cs | 8 +- .../Ordering.BackgroundTasks.csproj | 6 - .../Ordering.BackgroundTasks/Program.cs | 36 +----- .../Services/GracePeriodManagerService.cs | 11 +- .../Ordering.BackgroundTasks/appsettings.json | 12 -- .../OrderingScenarioBase.cs | 57 +++++---- .../Ordering.SignalrHub/GlobalUsings.cs | 3 +- ...aitingValidationIntegrationEventHandler.cs | 4 +- ...angedToCancelledIntegrationEventHandler.cs | 10 +- ...tusChangedToPaidIntegrationEventHandler.cs | 8 +- ...ChangedToShippedIntegrationEventHandler.cs | 5 +- ...ToStockConfirmedIntegrationEventHandler.cs | 8 +- ...angedToSubmittedIntegrationEventHandler.cs | 6 +- .../Ordering.SignalrHub.csproj | 6 - .../Ordering/Ordering.SignalrHub/Program.cs | 32 +---- .../Ordering.SignalrHub/appsettings.json | 12 -- .../Payment/Payment.API/GlobalUsings.cs | 2 - ...ToStockConfirmedIntegrationEventHandler.cs | 10 +- .../Payment/Payment.API/Payment.API.csproj | 6 - src/Services/Payment/Payment.API/Program.cs | 39 +----- .../Payment/Payment.API/appsettings.json | 12 -- .../Services.Common/CommonExtensions.cs | 36 ------ .../Services.Common/Services.Common.csproj | 6 - .../WebMVC/Controllers/AccountController.cs | 2 +- .../WebMVC/Infrastructure/WebContextSeed.cs | 18 ++- src/Web/WebMVC/Program.cs | 23 +--- src/Web/WebMVC/WebMVC.csproj | 6 - src/Web/WebMVC/appsettings.Development.json | 5 - src/Web/WebMVC/appsettings.json | 7 -- src/Web/WebMVC/globalusings.cs | 3 +- src/Web/WebSPA/GlobalUsings.cs | 1 - src/Web/WebSPA/Program.cs | 10 -- src/Web/WebSPA/WebSPA.csproj | 3 - src/Web/WebStatus/GlobalUsings.cs | 6 - src/Web/WebStatus/Program.cs | 113 +++++++----------- src/Web/WebStatus/WebStatus.csproj | 6 - .../WebStatus/appsettings.Development.json | 5 - src/Web/WebStatus/appsettings.json | 12 -- src/docker-compose.override.yml | 5 - 72 files changed, 174 insertions(+), 664 deletions(-) diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/GlobalUsings.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/GlobalUsings.cs index 2fbd09b57..6f18651cf 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/GlobalUsings.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/GlobalUsings.cs @@ -25,7 +25,6 @@ global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using Microsoft.OpenApi.Models; -global using Serilog; global using Swashbuckle.AspNetCore.SwaggerGen; global using System.Collections.Generic; global using System.IdentityModel.Tokens.Jwt; diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj index 78b2d6780..a25016890 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj @@ -25,8 +25,6 @@ - - diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs index 92e7e3a37..d6f7ae482 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs @@ -1,4 +1,4 @@ -await BuildWebHost(args).RunAsync(); +await BuildWebHost(args).RunAsync(); IWebHost BuildWebHost(string[] args) => WebHost .CreateDefaultBuilder(args) @@ -13,11 +13,4 @@ IWebHost BuildWebHost(string[] args) => }); }) .UseStartup() - .UseSerilog((builderContext, config) => - { - config - .MinimumLevel.Information() - .Enrich.FromLogContext() - .WriteTo.Console(); - }) - .Build(); \ No newline at end of file + .Build(); diff --git a/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationEventHandler.cs b/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationEventHandler.cs index 8545dc893..b82ac6a5f 100644 --- a/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationEventHandler.cs +++ b/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationEventHandler.cs @@ -12,9 +12,10 @@ namespace EventBus.Tests Handled = false; } - public async Task Handle(TestIntegrationEvent @event) + public Task Handle(TestIntegrationEvent @event) { Handled = true; + return Task.CompletedTask; } } } diff --git a/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationOtherEventHandler.cs b/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationOtherEventHandler.cs index b4ea66bb4..82ea25baa 100644 --- a/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationOtherEventHandler.cs +++ b/src/BuildingBlocks/EventBus/EventBus.Tests/TestIntegrationOtherEventHandler.cs @@ -12,9 +12,10 @@ namespace EventBus.Tests Handled = false; } - public async Task Handle(TestIntegrationEvent @event) + public Task Handle(TestIntegrationEvent @event) { Handled = true; + return Task.CompletedTask; } } } diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 6114b6a05..4f8a92814 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -83,12 +83,6 @@ - - - - - - diff --git a/src/Services/Basket/Basket.API/GlobalUsings.cs b/src/Services/Basket/Basket.API/GlobalUsings.cs index bef9dcdae..768af4a41 100644 --- a/src/Services/Basket/Basket.API/GlobalUsings.cs +++ b/src/Services/Basket/Basket.API/GlobalUsings.cs @@ -33,6 +33,5 @@ global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; -global using Serilog.Context; global using Services.Common; global using StackExchange.Redis; diff --git a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs index d5cf14e1b..df18a065c 100644 --- a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs +++ b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs @@ -15,7 +15,7 @@ public class OrderStartedIntegrationEventHandler : IIntegrationEventHandler> { new ("IntegrationEventContext", @event.Id) })) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); diff --git a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs index 560c43d2a..cff2faa05 100644 --- a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs +++ b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs @@ -15,7 +15,7 @@ public class ProductPriceChangedIntegrationEventHandler : IIntegrationEventHandl public async Task Handle(ProductPriceChangedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}")) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); diff --git a/src/Services/Basket/Basket.API/appsettings.Development.json b/src/Services/Basket/Basket.API/appsettings.Development.json index f4a3b9407..0c8e39c3c 100644 --- a/src/Services/Basket/Basket.API/appsettings.Development.json +++ b/src/Services/Basket/Basket.API/appsettings.Development.json @@ -1,14 +1,4 @@ { - "Serilog": { - "MinimumLevel": { - "Default": "Debug", - "Override": { - "Microsoft": "Warning", - "Microsoft.eShopOnContainers": "Debug", - "System": "Warning" - } - } - }, "IdentityUrlExternal": "http://localhost:5105", "IdentityUrl": "http://localhost:5105", "ConnectionString": "127.0.0.1", diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index 0d834939a..29573e967 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -60,12 +60,6 @@ - - - - - - diff --git a/src/Services/Catalog/Catalog.API/GlobalUsings.cs b/src/Services/Catalog/Catalog.API/GlobalUsings.cs index 812aa9960..fdd190250 100644 --- a/src/Services/Catalog/Catalog.API/GlobalUsings.cs +++ b/src/Services/Catalog/Catalog.API/GlobalUsings.cs @@ -44,4 +44,3 @@ global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using Polly; global using Polly.Retry; -global using Serilog.Context; diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs index 81c9ff909..fb79b96e9 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs @@ -19,7 +19,7 @@ public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler : public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs index c0f87139a..99b755568 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs @@ -16,7 +16,7 @@ public class OrderStatusChangedToPaidIntegrationEventHandler : public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); diff --git a/src/Services/Catalog/Catalog.API/Properties/launchSettings.json b/src/Services/Catalog/Catalog.API/Properties/launchSettings.json index 71aab05ab..a85ce1869 100644 --- a/src/Services/Catalog/Catalog.API/Properties/launchSettings.json +++ b/src/Services/Catalog/Catalog.API/Properties/launchSettings.json @@ -14,10 +14,8 @@ "launchUrl": "/swagger", "environmentVariables": { "ConnectionString": "server=localhost,5433;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word", - "Serilog:LogstashgUrl": "http://locahost:8080", "ASPNETCORE_ENVIRONMENT": "Development", - "EventBusConnection": "localhost", - "Serilog:SeqServerUrl": "http://locahost:5340" + "EventBusConnection": "localhost" } }, "Microsoft.eShopOnContainers.Services.Catalog.API": { diff --git a/src/Services/Catalog/Catalog.API/appsettings.Development.json b/src/Services/Catalog/Catalog.API/appsettings.Development.json index 1d5574f63..b41dc527c 100644 --- a/src/Services/Catalog/Catalog.API/appsettings.Development.json +++ b/src/Services/Catalog/Catalog.API/appsettings.Development.json @@ -1,15 +1,5 @@ { "ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word", "PicBaseUrl": "http://localhost:5101/api/v1/catalog/items/[0]/pic/", - "Serilog": { - "MinimumLevel": { - "Default": "Debug", - "Override": { - "Microsoft": "Warning", - "Microsoft.eShopOnContainers": "Debug", - "System": "Warning" - } - } - }, "EventBusConnection": "localhost" } \ No newline at end of file diff --git a/src/Services/Catalog/Catalog.API/appsettings.json b/src/Services/Catalog/Catalog.API/appsettings.json index c05acb89b..0141b6a7b 100644 --- a/src/Services/Catalog/Catalog.API/appsettings.json +++ b/src/Services/Catalog/Catalog.API/appsettings.json @@ -1,17 +1,5 @@ { "UseCustomizationData": false, - "Serilog": { - "SeqServerUrl": null, - "LogstashgUrl": null, - "MinimumLevel": { - "Default": "Information", - "Override": { - "Microsoft": "Warning", - "Microsoft.eShopOnContainers": "Information", - "System": "Warning" - } - } - }, "AzureServiceBusEnabled": false, "AzureStorageEnabled": false, "ApplicationInsights": { diff --git a/src/Services/Catalog/Catalog.API/web.config b/src/Services/Catalog/Catalog.API/web.config index 498dea85d..3bc0d036f 100644 --- a/src/Services/Catalog/Catalog.API/web.config +++ b/src/Services/Catalog/Catalog.API/web.config @@ -8,10 +8,8 @@ - - diff --git a/src/Services/Identity/Identity.API/appsettings.json b/src/Services/Identity/Identity.API/appsettings.json index cc37da9fe..955033706 100644 --- a/src/Services/Identity/Identity.API/appsettings.json +++ b/src/Services/Identity/Identity.API/appsettings.json @@ -4,17 +4,6 @@ "SpaClient": "http://localhost:5104", "XamarinCallback": "http://localhost:5105/xamarincallback", "UseCustomizationData": false, - "Serilog": { - "SeqServerUrl": null, - "LogstashgUrl": null, - "MinimumLevel": { - "Default": "Information", - "Override": { - "Microsoft.AspNetCore": "Warning", - "Microsoft.EntityFramework": "Warning" - } - } - }, "ApplicationInsights": { "InstrumentationKey": "" }, diff --git a/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehavior.cs b/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehavior.cs index 6974c3cf9..c27865a1e 100644 --- a/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehavior.cs +++ b/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehavior.cs @@ -36,7 +36,7 @@ public class TransactionBehavior : IPipelineBehavior> { new ("TransactionContext", transaction.TransactionId) })) { _logger.LogInformation("----- Begin transaction {TransactionId} for {CommandName} ({@Command})", transaction.TransactionId, typeName, request); diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs index a6056041c..82d3a0b3a 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs @@ -23,9 +23,9 @@ public class GracePeriodConfirmedIntegrationEventHandler : IIntegrationEventHand /// public async Task Handle(GracePeriodConfirmedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var command = new SetAwaitingValidationOrderStatusCommand(@event.OrderId); diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs index 8725408b4..870d63d60 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs @@ -16,9 +16,9 @@ public class OrderPaymentFailedIntegrationEventHandler : public async Task Handle(OrderPaymentFailedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var command = new CancelOrderCommand(@event.OrderId); diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSucceededIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSucceededIntegrationEventHandler.cs index c0a69268e..e1e6a9e86 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSucceededIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSucceededIntegrationEventHandler.cs @@ -16,9 +16,9 @@ public class OrderPaymentSucceededIntegrationEventHandler : public async Task Handle(OrderPaymentSucceededIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var command = new SetPaidOrderStatusCommand(@event.OrderId); diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs index e99b49f5e..68f2ec066 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs @@ -16,9 +16,9 @@ public class OrderStockConfirmedIntegrationEventHandler : public async Task Handle(OrderStockConfirmedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var command = new SetStockConfirmedOrderStatusCommand(@event.OrderId); diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs index 2468e25a6..4fa90ae0d 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs @@ -14,9 +14,9 @@ public class OrderStockRejectedIntegrationEventHandler : IIntegrationEventHandle public async Task Handle(OrderStockRejectedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var orderStockRejectedItems = @event.OrderStockItems .FindAll(c => !c.HasStock) diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs index f1c3cc964..d30ad98b5 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs @@ -24,15 +24,15 @@ public class UserCheckoutAcceptedIntegrationEventHandler : IIntegrationEventHand /// public async Task Handle(UserCheckoutAcceptedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var result = false; if (@event.RequestId != Guid.Empty) { - using (LogContext.PushProperty("IdentifiedCommandId", @event.RequestId)) + using (_logger.BeginScope(new List> { new ("IdentifiedCommandId", @event.RequestId) })) { var createOrderCommand = new CreateOrderCommand(@event.Basket.Items, @event.UserId, @event.UserName, @event.City, @event.Street, @event.State, @event.Country, @event.ZipCode, diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs index e2545cae5..a38179f5f 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs @@ -27,7 +27,7 @@ public class OrderingIntegrationEventService : IOrderingIntegrationEventService foreach (var logEvt in pendingLogEvents) { - _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", logEvt.EventId, Program.AppName, logEvt.IntegrationEvent); + _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} - ({@IntegrationEvent})", logEvt.EventId, logEvt.IntegrationEvent); try { @@ -37,7 +37,7 @@ public class OrderingIntegrationEventService : IOrderingIntegrationEventService } catch (Exception ex) { - _logger.LogError(ex, "ERROR publishing integration event: {IntegrationEventId} from {AppName}", logEvt.EventId, Program.AppName); + _logger.LogError(ex, "ERROR publishing integration event: {IntegrationEventId}", logEvt.EventId); await _eventLogService.MarkEventAsFailedAsync(logEvt.EventId); } diff --git a/src/Services/Ordering/Ordering.API/Extensions/BasketItemExtensions.cs b/src/Services/Ordering/Ordering.API/Extensions/BasketItemExtensions.cs index 4bf4f7575..918780f4a 100644 --- a/src/Services/Ordering/Ordering.API/Extensions/BasketItemExtensions.cs +++ b/src/Services/Ordering/Ordering.API/Extensions/BasketItemExtensions.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models; -using static Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands.CreateOrderCommand; public static class BasketItemExtensions { diff --git a/src/Services/Ordering/Ordering.API/GlobalUsings.cs b/src/Services/Ordering/Ordering.API/GlobalUsings.cs index e1cca922a..1ae71968a 100644 --- a/src/Services/Ordering/Ordering.API/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.API/GlobalUsings.cs @@ -64,8 +64,6 @@ global using Microsoft.OpenApi.Models; global using Polly.Retry; global using Polly; global using RabbitMQ.Client; -global using Serilog.Context; -global using Serilog; global using Swashbuckle.AspNetCore.SwaggerGen; global using System.Collections.Generic; global using System.Data.Common; diff --git a/src/Services/Ordering/Ordering.API/Ordering.API.csproj b/src/Services/Ordering/Ordering.API/Ordering.API.csproj index 991dd07be..da1157d59 100644 --- a/src/Services/Ordering/Ordering.API/Ordering.API.csproj +++ b/src/Services/Ordering/Ordering.API/Ordering.API.csproj @@ -19,6 +19,9 @@
+ + + @@ -60,12 +63,6 @@ - - - - - - diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index 0649ea2dc..c6b30c355 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -24,14 +24,10 @@ builder.WebHost.ConfigureKestrel(options => }); }); -builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration)); +builder.Services.AddGrpc(options => options.EnableDetailedErrors = true); +builder.Services.AddApplicationInsightsTelemetry(builder.Configuration); +builder.Services.AddApplicationInsightsKubernetesEnricher(); builder.Services - .AddGrpc(options => - { - options.EnableDetailedErrors = true; - }) - .Services - .AddApplicationInsights(builder.Configuration) .AddCustomMvc() .AddHealthChecks(builder.Configuration) .AddCustomDbContext(builder.Configuration) @@ -58,41 +54,6 @@ var services = builder.Services; cfg.AddOpenBehavior(typeof(TransactionBehavior<,>)); }); -/* - // Register all the command handlers. - services.AddSingleton, CancelOrderCommandHandler>(); - services.AddSingleton, bool>, CancelOrderIdentifiedCommandHandler>(); - - services.AddSingleton, CreateOrderCommandHandler>(); - services.AddSingleton, bool>, CreateOrderIdentifiedCommandHandler>(); - - services.AddSingleton, CreateOrderDraftCommandHandler>(); - - services.AddSingleton, bool>, SetAwaitingValidationIdentifiedOrderStatusCommandHandler>(); - services.AddSingleton, SetAwaitingValidationOrderStatusCommandHandler>(); - - services.AddSingleton, bool>, SetPaidIdentifiedOrderStatusCommandHandler>(); - services.AddSingleton, SetPaidOrderStatusCommandHandler>(); - - services.AddSingleton, bool>, SetStockConfirmedOrderStatusIdentifiedCommandHandler>(); - services.AddSingleton, SetStockConfirmedOrderStatusCommandHandler>(); - - services.AddSingleton, bool>, SetStockRejectedOrderStatusIdentifiedCommandHandler>(); - services.AddSingleton, SetStockRejectedOrderStatusCommandHandler>(); - - services.AddSingleton, bool>, ShipOrderIdentifiedCommandHandler>(); - services.AddSingleton, ShipOrderCommandHandler>(); - - // Register the DomainEventHandler classes (they implement INotificationHandler<>) in assembly holding the Domain Events - services.AddSingleton, OrderCancelledDomainEventHandler>(); - services.AddSingleton, OrderShippedDomainEventHandler>(); - services.AddSingleton, OrderStatusChangedToAwaitingValidationDomainEventHandler>(); - services.AddSingleton, OrderStatusChangedToPaidDomainEventHandler>(); - services.AddSingleton, OrderStatusChangedToStockConfirmedDomainEventHandler>(); - services.AddSingleton, UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler>(); - services.AddSingleton, ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler>(); -*/ - // Register the command validators for the validator behavior (validators based on FluentValidation library) services.AddSingleton, CancelOrderCommandValidator>(); services.AddSingleton, CreateOrderCommandValidator>(); @@ -135,13 +96,12 @@ if (!string.IsNullOrEmpty(pathBase)) { app.UsePathBase(pathBase); } -app.UseSwagger() - .UseSwaggerUI(c => - { - c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Ordering.API V1"); - c.OAuthClientId("orderingswaggerui"); - c.OAuthAppName("Ordering Swagger UI"); - }); +app.UseSwagger().UseSwaggerUI(c => +{ + c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Ordering.API V1"); + c.OAuthClientId("orderingswaggerui"); + c.OAuthAppName("Ordering Swagger UI"); +}); app.UseRouting(); app.UseCors("CorsPolicy"); @@ -174,10 +134,9 @@ app.MapHealthChecks("/liveness", new HealthCheckOptions Predicate = r => r.Name.Contains("self") }); ConfigureEventBus(app); -try + +using (var scope = app.Services.CreateScope()) { - Log.Information("Applying migrations ({ApplicationContext})...", Program.AppName); - using var scope = app.Services.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var env = app.Services.GetService(); var settings = app.Services.GetService>(); @@ -187,21 +146,10 @@ try await new OrderingContextSeed().SeedAsync(context, env, settings, logger); var integEventContext = scope.ServiceProvider.GetRequiredService(); await integEventContext.Database.MigrateAsync(); +} - Log.Information("Starting web host ({ApplicationContext})...", Program.AppName); - await app.RunAsync(); +await app.RunAsync(); - return 0; -} -catch (Exception ex) -{ - Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName); - return 1; -} -finally -{ - Log.CloseAndFlush(); -} void ConfigureEventBus(IApplicationBuilder app) { var eventBus = app.ApplicationServices.GetRequiredService(); @@ -213,37 +161,9 @@ void ConfigureEventBus(IApplicationBuilder app) eventBus.Subscribe>(); eventBus.Subscribe>(); } -Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) -{ - var seqServerUrl = configuration["Serilog:SeqServerUrl"]; - var logstashUrl = configuration["Serilog:LogstashgUrl"]; - return new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("ApplicationContext", Program.AppName) - .Enrich.FromLogContext() - .WriteTo.Console() - .WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl) - .WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl, null) - .ReadFrom.Configuration(configuration) - .CreateLogger(); -} - -public partial class Program -{ - private static string Namespace = typeof(Program).Assembly.GetName().Name; - public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1); -} static class CustomExtensionsMethods { - public static IServiceCollection AddApplicationInsights(this IServiceCollection services, IConfiguration configuration) - { - services.AddApplicationInsightsTelemetry(configuration); - services.AddApplicationInsightsKubernetesEnricher(); - - return services; - } - public static IServiceCollection AddCustomMvc(this IServiceCollection services) { // Add framework services. diff --git a/src/Services/Ordering/Ordering.API/appsettings.json b/src/Services/Ordering/Ordering.API/appsettings.json index a10f3358b..19a922b58 100644 --- a/src/Services/Ordering/Ordering.API/appsettings.json +++ b/src/Services/Ordering/Ordering.API/appsettings.json @@ -2,18 +2,6 @@ "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;TrustServerCertificate=true", "IdentityUrl": "http://localhost:5105", "UseCustomizationData": false, - "Serilog": { - "SeqServerUrl": null, - "LogstashgUrl": null, - "MinimumLevel": { - "Default": "Information", - "Override": { - "Microsoft": "Warning", - "Microsoft.eShopOnContainers": "Information", - "System": "Warning" - } - } - }, "AzureServiceBusEnabled": false, "SubscriptionClientName": "Ordering", "GracePeriodTime": "1", diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Extensions/CustomExtensionMethods.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Extensions/CustomExtensionMethods.cs index 53d3f0aea..aa05e0006 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Extensions/CustomExtensionMethods.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Extensions/CustomExtensionMethods.cs @@ -1,14 +1,9 @@ -using Autofac; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; -using Microsoft.Extensions.Logging; using RabbitMQ.Client; -using Serilog; namespace Ordering.BackgroundTasks.Extensions { @@ -120,23 +115,5 @@ namespace Ordering.BackgroundTasks.Extensions return services; } - - public static ILoggingBuilder UseSerilog(this ILoggingBuilder builder, IConfiguration configuration) - { - var seqServerUrl = configuration["Serilog:SeqServerUrl"]; - var logstashUrl = configuration["Serilog:LogstashgUrl"]; - - Log.Logger = new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("ApplicationContext", Program.AppName) - .Enrich.FromLogContext() - .WriteTo.Console() - .WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl) - .WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl, null) - .ReadFrom.Configuration(configuration) - .CreateLogger(); - - return builder; - } } } diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/GlobalUsings.cs b/src/Services/Ordering/Ordering.BackgroundTasks/GlobalUsings.cs index 43b0981b8..f15742736 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/GlobalUsings.cs @@ -1,17 +1,13 @@ -global using Autofac.Extensions.DependencyInjection; -global using Microsoft.AspNetCore.Hosting; +global using Microsoft.AspNetCore.Hosting; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.Hosting; global using Ordering.BackgroundTasks.Extensions; -global using Serilog; global using System.IO; global using HealthChecks.UI.Client; global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.Diagnostics.HealthChecks; -global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Logging; -global using Ordering.BackgroundTasks.Extensions; global using Ordering.BackgroundTasks.Services; global using System; -global using Ordering.BackgroundTasks; \ No newline at end of file +global using Ordering.BackgroundTasks; diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj b/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj index 0b81c1cfa..1ac347d86 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj @@ -18,12 +18,6 @@ - - - - - -
diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs index ef12360db..35f066fed 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs @@ -1,5 +1,4 @@ -var appName = "Ordering.BackgroundTasks"; -var builder = WebApplication.CreateBuilder(new WebApplicationOptions +var builder = WebApplication.CreateBuilder(new WebApplicationOptions { Args = args, ApplicationName = typeof(Program).Assembly.FullName @@ -8,7 +7,6 @@ builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()); builder.Configuration.AddJsonFile("appsettings.json", optional: true); builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true); builder.Configuration.AddEnvironmentVariables(); -builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration)); builder.Services.AddCustomHealthCheck(builder.Configuration) .Configure(builder.Configuration) .AddOptions() @@ -35,37 +33,7 @@ app.MapHealthChecks("/liveness", new HealthCheckOptions Predicate = r => r.Name.Contains("self") }); -try -{ - Log.Information("Starting web host ({ApplicationContext})...", Program.AppName); - await app.RunAsync(); - - return 0; -} -catch (Exception ex) -{ - Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName); - return 1; -} -finally -{ - Log.CloseAndFlush(); -} - -Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) -{ - var seqServerUrl = configuration["Serilog:SeqServerUrl"]; - var logstashUrl = configuration["Serilog:LogstashgUrl"]; - return new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("ApplicationContext", Program.AppName) - .Enrich.FromLogContext() - .WriteTo.Console() - .WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl) - .WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl, null) - .ReadFrom.Configuration(configuration) - .CreateLogger(); -} +await app.RunAsync(); public partial class Program { diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Services/GracePeriodManagerService.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Services/GracePeriodManagerService.cs index b494377fb..a801ac831 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Services/GracePeriodManagerService.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Services/GracePeriodManagerService.cs @@ -36,14 +36,7 @@ namespace Ordering.BackgroundTasks.Services _logger.LogDebug("GracePeriodManagerService background task is doing background work."); CheckConfirmedGracePeriodOrders(); - try - { - await Task.Delay(_settings.CheckUpdateTime, stoppingToken); - } - catch (TaskCanceledException exception) - { - _logger.LogCritical(exception, "TaskCanceledException Error", exception.Message); - } + await Task.Delay(_settings.CheckUpdateTime, stoppingToken); } _logger.LogDebug("GracePeriodManagerService background task is stopping."); @@ -59,7 +52,7 @@ namespace Ordering.BackgroundTasks.Services { var confirmGracePeriodEvent = new GracePeriodConfirmedIntegrationEvent(orderId); - _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", confirmGracePeriodEvent.Id, Program.AppName, confirmGracePeriodEvent); + _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} - ({@IntegrationEvent})", confirmGracePeriodEvent.Id, confirmGracePeriodEvent); _eventBus.Publish(confirmGracePeriodEvent); } diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json b/src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json index 88e5d6858..2069c7db2 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json +++ b/src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json @@ -1,17 +1,5 @@ { "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", - "Serilog": { - "SeqServerUrl": null, - "LogstashgUrl": null, - "MinimumLevel": { - "Default": "Information", - "Override": { - "Microsoft": "Warning", - "Microsoft.eShopOnContainers": "Information", - "System": "Warning" - } - } - }, "SubscriptionClientName": "BackgroundTasks", "GracePeriodTime": "1", "CheckUpdateTime": "1000", diff --git a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs index 81832f32e..2bf493a4d 100644 --- a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs +++ b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs @@ -3,40 +3,49 @@ using Microsoft.Extensions.Hosting; namespace Ordering.FunctionalTests; -public class OrderingScenarioBase : WebApplicationFactory +public class OrderingScenarioBase { - public TestServer CreateServer() + private class OrderingApplication : WebApplicationFactory { - Services.MigrateDbContext((context, services) => + public TestServer CreateServer() { - var env = services.GetService(); - var settings = services.GetService>(); - var logger = services.GetService>(); + Services.MigrateDbContext((context, services) => + { + var env = services.GetService(); + var settings = services.GetService>(); + var logger = services.GetService>(); - new OrderingContextSeed() - .SeedAsync(context, env, settings, logger) - .Wait(); - }) - .MigrateDbContext((_, __) => { }); + new OrderingContextSeed() + .SeedAsync(context, env, settings, logger) + .Wait(); + }) + .MigrateDbContext((_, __) => { }); - return Server; - } + return Server; + } - protected override IHost CreateHost(IHostBuilder builder) - { - builder.ConfigureServices(servies => + protected override IHost CreateHost(IHostBuilder builder) { - servies.AddSingleton(); - }); + builder.ConfigureServices(servies => + { + servies.AddSingleton(); + }); - builder.ConfigureAppConfiguration(c => - { - var directory = Path.GetDirectoryName(typeof(OrderingScenarioBase).Assembly.Location)!; + builder.ConfigureAppConfiguration(c => + { + var directory = Path.GetDirectoryName(typeof(OrderingScenarioBase).Assembly.Location)!; + + c.AddJsonFile(Path.Combine(directory, "appsettings.json"), optional: false); + }); - c.AddJsonFile(Path.Combine(directory, "appsettings.json"), optional: false); - }); + return base.CreateHost(builder); + } + } - return base.CreateHost(builder); + public TestServer CreateServer() + { + var factory = new OrderingApplication(); + return factory.CreateServer(); } public static class Get diff --git a/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs b/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs index b913f56bf..a6c14a022 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs @@ -23,8 +23,7 @@ global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.AutofacMod global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub; global using RabbitMQ.Client; -global using Serilog.Context; -global using Serilog; +global using System.Collections.Generic; global using System.IdentityModel.Tokens.Jwt; global using System.IO; global using System.Reflection; diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs index f42889d98..9c460365c 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs @@ -16,9 +16,9 @@ public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler : IIn public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); await _hubContext.Clients .Group(@event.BuyerName) diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs index fa2b75ebc..1c3ea4623 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs @@ -1,4 +1,6 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; +using System.Collections.Generic; + +namespace Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; public class OrderStatusChangedToCancelledIntegrationEventHandler : IIntegrationEventHandler { @@ -16,13 +18,13 @@ public class OrderStatusChangedToCancelledIntegrationEventHandler : IIntegration public async Task Handle(OrderStatusChangedToCancelledIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); await _hubContext.Clients .Group(@event.BuyerName) .SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus }); } } -} \ No newline at end of file +} diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs index bc8ea3d4b..fe66f7dbe 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs @@ -1,4 +1,6 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; +using System.Collections.Generic; + +namespace Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; public class OrderStatusChangedToPaidIntegrationEventHandler : IIntegrationEventHandler { @@ -16,9 +18,9 @@ public class OrderStatusChangedToPaidIntegrationEventHandler : IIntegrationEvent public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); await _hubContext.Clients .Group(@event.BuyerName) diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs index f6356268d..2f612bbfb 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs @@ -13,12 +13,11 @@ public class OrderStatusChangedToShippedIntegrationEventHandler : IIntegrationEv _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } - public async Task Handle(OrderStatusChangedToShippedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); await _hubContext.Clients .Group(@event.BuyerName) diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs index 3289dff9a..7deb6c854 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs @@ -1,4 +1,6 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; +using System.Collections.Generic; + +namespace Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; public class OrderStatusChangedToStockConfirmedIntegrationEventHandler : IIntegrationEventHandler @@ -17,9 +19,9 @@ public class OrderStatusChangedToStockConfirmedIntegrationEventHandler : public async Task Handle(OrderStatusChangedToStockConfirmedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); await _hubContext.Clients .Group(@event.BuyerName) diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs index 144a5e7c6..0fa7ad8a5 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; + namespace Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; public class OrderStatusChangedToSubmittedIntegrationEventHandler : @@ -17,9 +19,9 @@ public class OrderStatusChangedToSubmittedIntegrationEventHandler : public async Task Handle(OrderStatusChangedToSubmittedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); await _hubContext.Clients .Group(@event.BuyerName) diff --git a/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj b/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj index 92e65dd6b..787776c41 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj +++ b/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj @@ -23,12 +23,6 @@ - - - - - - diff --git a/src/Services/Ordering/Ordering.SignalrHub/Program.cs b/src/Services/Ordering/Ordering.SignalrHub/Program.cs index 03288fe33..00b61d63b 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Program.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Program.cs @@ -8,7 +8,6 @@ builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()); builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); builder.Configuration.AddEnvironmentVariables(); builder.WebHost.CaptureStartupErrors(false); -builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration)); builder.Services .AddCustomHealthCheck(builder.Configuration) @@ -110,22 +109,8 @@ app.MapHealthChecks("/liveness", new HealthCheckOptions app.MapHub("/hub/notificationhub"); ConfigureEventBus(app); -try -{ - Log.Information("Starting web host ({ApplicationContext})...", Program.AppName); - await app.RunAsync(); +await app.RunAsync(); - return 0; -} -catch (Exception ex) -{ - Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName); - return 1; -} -finally -{ - Log.CloseAndFlush(); -} void ConfigureEventBus(IApplicationBuilder app) { var eventBus = app.ApplicationServices.GetRequiredService(); @@ -137,6 +122,7 @@ void ConfigureEventBus(IApplicationBuilder app) eventBus.Subscribe(); eventBus.Subscribe(); } + void ConfigureAuthService(IServiceCollection services, IConfiguration configuration) { // prevent from mapping "sub" claim to nameidentifier. @@ -210,20 +196,6 @@ void RegisterEventBus(IServiceCollection services, IConfiguration configuration) services.AddSingleton(); } -static Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) -{ - var seqServerUrl = configuration["Serilog:SeqServerUrl"]; - var logstashUrl = configuration["Serilog:LogstashgUrl"]; - return new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("ApplicationContext", Program.AppName) - .Enrich.FromLogContext() - .WriteTo.Console() - .WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl) - .WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl, null) - .ReadFrom.Configuration(configuration) - .CreateLogger(); -} public partial class Program { public static string Namespace = typeof(Program).Assembly.GetName().Name; diff --git a/src/Services/Ordering/Ordering.SignalrHub/appsettings.json b/src/Services/Ordering/Ordering.SignalrHub/appsettings.json index e43c354a3..be528bb8b 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/appsettings.json +++ b/src/Services/Ordering/Ordering.SignalrHub/appsettings.json @@ -1,17 +1,5 @@ { "IdentityUrl": "http://localhost:5105", - "Serilog": { - "SeqServerUrl": null, - "LogstashgUrl": null, - "MinimumLevel": { - "Default": "Information", - "Override": { - "Microsoft": "Warning", - "Microsoft.eShopOnContainers": "Information", - "System": "Warning" - } - } - }, "AzureServiceBusEnabled": false, "SubscriptionClientName": "Ordering.signalrhub", "EventBusRetryCount": 5, diff --git a/src/Services/Payment/Payment.API/GlobalUsings.cs b/src/Services/Payment/Payment.API/GlobalUsings.cs index 01ba3682b..b064110ab 100644 --- a/src/Services/Payment/Payment.API/GlobalUsings.cs +++ b/src/Services/Payment/Payment.API/GlobalUsings.cs @@ -20,8 +20,6 @@ global using Microsoft.Extensions.Logging; global using Microsoft.eShopOnContainers.Payment.API.IntegrationEvents.EventHandling; global using Microsoft.eShopOnContainers.Payment.API; global using RabbitMQ.Client; -global using Serilog.Context; -global using Serilog; global using System.Threading.Tasks; global using System; global using System.IO; diff --git a/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs b/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs index 0712f8908..d88bad3db 100644 --- a/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs @@ -1,4 +1,6 @@ -namespace Microsoft.eShopOnContainers.Payment.API.IntegrationEvents.EventHandling; +using System.Collections.Generic; + +namespace Microsoft.eShopOnContainers.Payment.API.IntegrationEvents.EventHandling; public class OrderStatusChangedToStockConfirmedIntegrationEventHandler : IIntegrationEventHandler @@ -21,9 +23,9 @@ public class OrderStatusChangedToStockConfirmedIntegrationEventHandler : public async Task Handle(OrderStatusChangedToStockConfirmedIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", @event.Id)) + using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); IntegrationEvent orderPaymentIntegrationEvent; @@ -42,7 +44,7 @@ public class OrderStatusChangedToStockConfirmedIntegrationEventHandler : orderPaymentIntegrationEvent = new OrderPaymentFailedIntegrationEvent(@event.OrderId); } - _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", orderPaymentIntegrationEvent.Id, Program.AppName, orderPaymentIntegrationEvent); + _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} - ({@IntegrationEvent})", orderPaymentIntegrationEvent.Id, orderPaymentIntegrationEvent); _eventBus.Publish(orderPaymentIntegrationEvent); diff --git a/src/Services/Payment/Payment.API/Payment.API.csproj b/src/Services/Payment/Payment.API/Payment.API.csproj index 61cfd2050..4e72c131e 100644 --- a/src/Services/Payment/Payment.API/Payment.API.csproj +++ b/src/Services/Payment/Payment.API/Payment.API.csproj @@ -20,12 +20,6 @@ - - - - - - diff --git a/src/Services/Payment/Payment.API/Program.cs b/src/Services/Payment/Payment.API/Program.cs index e6f92f4e3..60c7d947f 100644 --- a/src/Services/Payment/Payment.API/Program.cs +++ b/src/Services/Payment/Payment.API/Program.cs @@ -1,9 +1,4 @@ -var builder = WebApplication.CreateBuilder(new WebApplicationOptions -{ - Args = args, - ApplicationName = typeof(Program).Assembly.FullName, - ContentRootPath = Directory.GetCurrentDirectory() -}); +var builder = WebApplication.CreateBuilder(args); if (builder.Configuration.GetValue("UseVault", false)) { TokenCredential credential = new ClientSecretCredential( @@ -16,7 +11,6 @@ builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()); builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); builder.Configuration.AddEnvironmentVariables(); builder.WebHost.CaptureStartupErrors(false); -builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration)); builder.Services .AddCustomHealthCheck(builder.Configuration); builder.Services.Configure(builder.Configuration); @@ -88,22 +82,8 @@ app.MapHealthChecks("/liveness", new HealthCheckOptions { Predicate = r => r.Name.Contains("self") }); -try -{ - Log.Information("Starting web host ({ApplicationContext})...", Program.AppName); - await app.RunAsync(); - return 0; -} -catch (Exception ex) -{ - Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName); - return 1; -} -finally -{ - Log.CloseAndFlush(); -} +await app.RunAsync(); void RegisterEventBus(IServiceCollection services) { @@ -149,21 +129,6 @@ void ConfigureEventBus(IApplicationBuilder app) eventBus.Subscribe(); } -Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) -{ - var seqServerUrl = configuration["Serilog:SeqServerUrl"]; - var logstashUrl = configuration["Serilog:LogstashgUrl"]; - return new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("ApplicationContext", Program.AppName) - .Enrich.FromLogContext() - .WriteTo.Console() - .WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl) - .WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl, null) - .ReadFrom.Configuration(configuration) - .CreateLogger(); -} - public partial class Program { public static string Namespace = typeof(Program).Assembly.GetName().Name; diff --git a/src/Services/Payment/Payment.API/appsettings.json b/src/Services/Payment/Payment.API/appsettings.json index 9964a8bd2..41de245fb 100644 --- a/src/Services/Payment/Payment.API/appsettings.json +++ b/src/Services/Payment/Payment.API/appsettings.json @@ -1,16 +1,4 @@ { - "Serilog": { - "SeqServerUrl": null, - "LogstashgUrl": null, - "MinimumLevel": { - "Default": "Information", - "Override": { - "Microsoft": "Warning", - "Microsoft.eShopOnContainers": "Information", - "System": "Warning" - } - } - }, "PaymentSucceeded": true, "AzureServiceBusEnabled": false, "SubscriptionClientName": "Payment", diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index 7971b11a3..5a5e52cd7 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -16,7 +16,6 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Models; using RabbitMQ.Client; -using Serilog; namespace Services.Common; @@ -33,11 +32,6 @@ public static class CommonExtensions // Default health checks assume the event bus and self health checks builder.Services.AddDefaultHealthChecks(builder.Configuration); - // Configure the default logging for this application - // builder.Host.UseDefaultSerilog(builder.Configuration, builder.Environment.ApplicationName); - - // Customizations for this application - // Add the event bus builder.Services.AddEventBus(builder.Configuration); @@ -388,36 +382,6 @@ public static class CommonExtensions return services; } - public static void UseDefaultSerilog(this IHostBuilder builder, IConfiguration configuration, string name) - { - builder.UseSerilog(CreateSerilogLogger(configuration)); - - Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) - { - var seqServerUrl = configuration["Serilog:SeqServerUrl"]; - var logstashUrl = configuration["Serilog:LogstashgUrl"]; - - var loggingConfiguration = new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("ApplicationContext", name) - .Enrich.FromLogContext() - .WriteTo.Console() - .ReadFrom.Configuration(configuration); - - if (!string.IsNullOrEmpty(seqServerUrl)) - { - loggingConfiguration.WriteTo.Seq(seqServerUrl); - } - - if (!string.IsNullOrEmpty(logstashUrl)) - { - loggingConfiguration.WriteTo.Http(logstashUrl, null); - } - - return loggingConfiguration.CreateLogger(); - } - } - public static void MapDefaultHealthChecks(this IEndpointRouteBuilder routes) { routes.MapHealthChecks("/hc", new HealthCheckOptions() diff --git a/src/Services/Services.Common/Services.Common.csproj b/src/Services/Services.Common/Services.Common.csproj index 0eb7de774..89ff64893 100644 --- a/src/Services/Services.Common/Services.Common.csproj +++ b/src/Services/Services.Common/Services.Common.csproj @@ -41,12 +41,6 @@ - - - - - - diff --git a/src/Web/WebMVC/Controllers/AccountController.cs b/src/Web/WebMVC/Controllers/AccountController.cs index 78282f9a9..9daf98275 100644 --- a/src/Web/WebMVC/Controllers/AccountController.cs +++ b/src/Web/WebMVC/Controllers/AccountController.cs @@ -16,7 +16,7 @@ public class AccountController : Controller var user = User as ClaimsPrincipal; var token = await HttpContext.GetTokenAsync("access_token"); - _logger.LogInformation("----- User {@User} authenticated into {AppName}", user, Program.AppName); + _logger.LogInformation("----- User {@User} authenticated", user); if (token != null) { diff --git a/src/Web/WebMVC/Infrastructure/WebContextSeed.cs b/src/Web/WebMVC/Infrastructure/WebContextSeed.cs index cc03c1797..c20f39690 100644 --- a/src/Web/WebMVC/Infrastructure/WebContextSeed.cs +++ b/src/Web/WebMVC/Infrastructure/WebContextSeed.cs @@ -1,14 +1,12 @@ namespace WebMVC.Infrastructure; -using Serilog; public class WebContextSeed { public static void Seed(IApplicationBuilder applicationBuilder, IWebHostEnvironment env) { - var log = Log.Logger; - - var settings = (AppSettings)applicationBuilder + var settings = applicationBuilder .ApplicationServices.GetRequiredService>().Value; + var log = applicationBuilder.ApplicationServices.GetRequiredService>(); var useCustomizationData = settings.UseCustomizationData; var contentRootPath = env.ContentRootPath; @@ -29,7 +27,7 @@ public class WebContextSeed string overrideCssFile = Path.Combine(contentRootPath, "Setup", "override.css"); if (!File.Exists(overrideCssFile)) { - log.Error("Override css file '{FileName}' does not exists.", overrideCssFile); + log.LogError("Override css file '{FileName}' does not exists.", overrideCssFile); return; } @@ -38,7 +36,7 @@ public class WebContextSeed } catch (Exception ex) { - log.Error(ex, "EXCEPTION ERROR: {Message}", ex.Message); + log.LogError(ex, "Error getting preconfigured css"); } } @@ -49,7 +47,7 @@ public class WebContextSeed string imagesZipFile = Path.Combine(contentRootPath, "Setup", "images.zip"); if (!File.Exists(imagesZipFile)) { - log.Error("Zip file '{ZipFileName}' does not exists.", imagesZipFile); + log.LogError("Zip file '{ZipFileName}' does not exists.", imagesZipFile); return; } @@ -70,14 +68,14 @@ public class WebContextSeed } else { - log.Warning("Skipped file '{FileName}' in zipfile '{ZipFileName}'", entry.Name, imagesZipFile); + log.LogWarning("Skipped file '{FileName}' in zip file '{ZipFileName}'", entry.Name, imagesZipFile); } } } catch (Exception ex) { - log.Error(ex, "EXCEPTION ERROR: {Message}", ex.Message); + log.LogError(ex, "Error getting preconfigured images"); } } -} \ No newline at end of file +} diff --git a/src/Web/WebMVC/Program.cs b/src/Web/WebMVC/Program.cs index ae56982a6..3d5eb1511 100644 --- a/src/Web/WebMVC/Program.cs +++ b/src/Web/WebMVC/Program.cs @@ -8,7 +8,6 @@ AddHttpClientServices(builder); AddCustomAuthentication(builder); builder.WebHost.CaptureStartupErrors(false); -builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration)); var app = builder.Build(); @@ -58,26 +57,6 @@ app.MapHealthChecks("/hc", new HealthCheckOptions() await app.RunAsync(); -Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) -{ - var seqServerUrl = configuration["Serilog:SeqServerUrl"]; - var logstashUrl = configuration["Serilog:LogstashgUrl"]; - var cfg = new LoggerConfiguration() - .ReadFrom.Configuration(configuration) - .Enrich.WithProperty("ApplicationContext", AppName) - .Enrich.FromLogContext() - .WriteTo.Console(); - if (!string.IsNullOrWhiteSpace(seqServerUrl)) - { - cfg.WriteTo.Seq(seqServerUrl); - } - if (!string.IsNullOrWhiteSpace(logstashUrl)) - { - cfg.WriteTo.Http(logstashUrl, null); - } - return cfg.CreateLogger(); -} - static void AddApplicationInsights(WebApplicationBuilder builder) { builder.Services.AddApplicationInsightsTelemetry(builder.Configuration); @@ -174,4 +153,4 @@ static void AddCustomAuthentication(WebApplicationBuilder builder) public partial class Program { public static readonly string AppName = typeof(Program).Assembly.GetName().Name; -} \ No newline at end of file +} diff --git a/src/Web/WebMVC/WebMVC.csproj b/src/Web/WebMVC/WebMVC.csproj index da5b499f6..e0b3fff05 100644 --- a/src/Web/WebMVC/WebMVC.csproj +++ b/src/Web/WebMVC/WebMVC.csproj @@ -35,12 +35,6 @@ - - - - - - diff --git a/src/Web/WebMVC/appsettings.Development.json b/src/Web/WebMVC/appsettings.Development.json index a96c927e8..0f530c147 100644 --- a/src/Web/WebMVC/appsettings.Development.json +++ b/src/Web/WebMVC/appsettings.Development.json @@ -1,7 +1,2 @@ { - "Serilog": { - "MinimumLevel": { - "Default": "Debug" - } - } } diff --git a/src/Web/WebMVC/appsettings.json b/src/Web/WebMVC/appsettings.json index 7c169c27c..55561ef75 100644 --- a/src/Web/WebMVC/appsettings.json +++ b/src/Web/WebMVC/appsettings.json @@ -9,13 +9,6 @@ "UseLoadTest": false, "ActivateCampaignDetailFunction": "False", "UseCustomizationData": false, - "Serilog": { - "SeqServerUrl": null, - "LogstashgUrl": null, - "MinimumLevel": { - "Default": "Information" - } - }, "ApplicationInsights": { "InstrumentationKey": "" }, diff --git a/src/Web/WebMVC/globalusings.cs b/src/Web/WebMVC/globalusings.cs index 4aa6c9038..aff8f2e62 100644 --- a/src/Web/WebMVC/globalusings.cs +++ b/src/Web/WebMVC/globalusings.cs @@ -26,7 +26,6 @@ global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using Microsoft.IdentityModel.Logging; -global using Serilog; global using StackExchange.Redis; global using System.Collections.Generic; global using System.ComponentModel.DataAnnotations; @@ -46,4 +45,4 @@ global using System.Threading.Tasks; global using System.Threading; global using System; global using WebMVC.Infrastructure; -global using WebMVC.Services.ModelDTOs; \ No newline at end of file +global using WebMVC.Services.ModelDTOs; diff --git a/src/Web/WebSPA/GlobalUsings.cs b/src/Web/WebSPA/GlobalUsings.cs index 0b82464fd..07c26ded8 100644 --- a/src/Web/WebSPA/GlobalUsings.cs +++ b/src/Web/WebSPA/GlobalUsings.cs @@ -3,7 +3,6 @@ global using Microsoft.AspNetCore; global using Microsoft.AspNetCore.Hosting; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.Logging; -global using Serilog; global using System.IO; global using eShopOnContainers.WebSPA; global using HealthChecks.UI.Client; diff --git a/src/Web/WebSPA/Program.cs b/src/Web/WebSPA/Program.cs index b3cb021de..52f090b67 100644 --- a/src/Web/WebSPA/Program.cs +++ b/src/Web/WebSPA/Program.cs @@ -37,16 +37,6 @@ builder.Services.AddSpaStaticFiles(configuration => builder.Logging.AddConfiguration(builder.Configuration.GetSection("Logging")); builder.Logging.AddAzureWebAppDiagnostics(); -builder.Host.UseSerilog((builderContext, config) => -{ - config - .MinimumLevel.Information() - .Enrich.FromLogContext() - .WriteTo.Seq("http://seq") - .ReadFrom.Configuration(builderContext.Configuration) - .WriteTo.Console(); -}) -.UseConsoleLifetime(); var app = builder.Build(); diff --git a/src/Web/WebSPA/WebSPA.csproj b/src/Web/WebSPA/WebSPA.csproj index a6c152ea2..8a842a792 100644 --- a/src/Web/WebSPA/WebSPA.csproj +++ b/src/Web/WebSPA/WebSPA.csproj @@ -42,9 +42,6 @@ - - - diff --git a/src/Web/WebStatus/GlobalUsings.cs b/src/Web/WebStatus/GlobalUsings.cs index 986d4ee76..0efba33ad 100644 --- a/src/Web/WebStatus/GlobalUsings.cs +++ b/src/Web/WebStatus/GlobalUsings.cs @@ -1,14 +1,9 @@ global using Microsoft.AspNetCore.Mvc; global using Microsoft.Extensions.Configuration; global using System.Linq; -global using Microsoft.AspNetCore; global using Microsoft.AspNetCore.Hosting; -global using Serilog; global using System; global using System.Collections.Generic; -global using System.IO; -global using System.Reflection; -global using WebStatus; global using Azure.Identity; global using Azure.Core; global using Microsoft.AspNetCore.Builder; @@ -16,4 +11,3 @@ global using Microsoft.AspNetCore.Diagnostics.HealthChecks; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Diagnostics.HealthChecks; global using Microsoft.Extensions.Hosting; -global using Microsoft.Extensions.Logging; diff --git a/src/Web/WebStatus/Program.cs b/src/Web/WebStatus/Program.cs index 6cfbc1d1e..ddecc6a9e 100644 --- a/src/Web/WebStatus/Program.cs +++ b/src/Web/WebStatus/Program.cs @@ -1,83 +1,60 @@ -try +var builder = WebApplication.CreateBuilder(args); +if (builder.Configuration.GetValue("UseVault", false)) { - var builder = WebApplication.CreateBuilder(args); - if (builder.Configuration.GetValue("UseVault", false)) - { - TokenCredential credential = new ClientSecretCredential( - builder.Configuration["Vault:TenantId"], - builder.Configuration["Vault:ClientId"], - builder.Configuration["Vault:ClientSecret"]); - builder.Configuration.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential); - } - - builder.Host.UseSerilog(CreateLogger(builder.Configuration)); - builder.WebHost.CaptureStartupErrors(false); - builder.Services.AddApplicationInsightsTelemetry(builder.Configuration); - builder.Services.AddApplicationInsightsKubernetesEnricher(); - builder.Services.AddMvc(); - builder.Services.AddOptions(); - builder.Services.AddHealthChecks() - .AddCheck("self", () => HealthCheckResult.Healthy()); - builder.Services - .AddHealthChecksUI() - .AddInMemoryStorage(); - - var app = builder.Build(); - - if (app.Environment.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseExceptionHandler("/Home/Error"); - } - - var pathBase = app.Configuration["PATH_BASE"]; - if (!string.IsNullOrEmpty(pathBase)) - { - app.UsePathBase(pathBase); - } - - app.UseHealthChecksUI(config => - { - config.ResourcesPath = string.IsNullOrEmpty(pathBase) ? "/ui/resources" : $"{pathBase}/ui/resources"; - config.UIPath = "/hc-ui"; - }); + TokenCredential credential = new ClientSecretCredential( + builder.Configuration["Vault:TenantId"], + builder.Configuration["Vault:ClientId"], + builder.Configuration["Vault:ClientSecret"]); + builder.Configuration.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential); +} - app.UseStaticFiles(); +builder.WebHost.CaptureStartupErrors(false); +builder.Services.AddApplicationInsightsTelemetry(builder.Configuration); +builder.Services.AddApplicationInsightsKubernetesEnricher(); +builder.Services.AddMvc(); +builder.Services.AddOptions(); +builder.Services.AddHealthChecks() + .AddCheck("self", () => HealthCheckResult.Healthy()); +builder.Services + .AddHealthChecksUI() + .AddInMemoryStorage(); - app.UseRouting(); - app.MapDefaultControllerRoute(); - app.MapHealthChecks("/liveness", new HealthCheckOptions - { - Predicate = r => r.Name.Contains("self") - }); +var app = builder.Build(); - await app.RunAsync(); +if (app.Environment.IsDevelopment()) +{ + app.UseDeveloperExceptionPage(); } -catch (Exception exception) +else { - Console.WriteLine(exception); + app.UseExceptionHandler("/Home/Error"); } -Serilog.ILogger CreateLogger(IConfiguration configuration) +var pathBase = app.Configuration["PATH_BASE"]; +if (!string.IsNullOrEmpty(pathBase)) { - var seqServerUrl = configuration["Serilog:SeqServerUrl"]; - var logstashUrl = configuration["Serilog:LogstashgUrl"]; - return new LoggerConfiguration() - .MinimumLevel.Verbose() - .Enrich.WithProperty("ApplicationContext", Program.AppName) - .Enrich.FromLogContext() - .WriteTo.Console() - .WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl) - .WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl, null) - .ReadFrom.Configuration(configuration) - .CreateLogger(); + app.UsePathBase(pathBase); } +app.UseHealthChecksUI(config => +{ + config.ResourcesPath = string.IsNullOrEmpty(pathBase) ? "/ui/resources" : $"{pathBase}/ui/resources"; + config.UIPath = "/hc-ui"; +}); + +app.UseStaticFiles(); + +app.UseRouting(); +app.MapDefaultControllerRoute(); +app.MapHealthChecks("/liveness", new HealthCheckOptions +{ + Predicate = r => r.Name.Contains("self") +}); + +await app.RunAsync(); + public partial class Program { private static readonly string _namespace = typeof(Program).Assembly.GetName().Name; public static readonly string AppName = _namespace; -} \ No newline at end of file +} diff --git a/src/Web/WebStatus/WebStatus.csproj b/src/Web/WebStatus/WebStatus.csproj index 20b3e6903..22e65f96b 100644 --- a/src/Web/WebStatus/WebStatus.csproj +++ b/src/Web/WebStatus/WebStatus.csproj @@ -19,12 +19,6 @@ - - - - - - diff --git a/src/Web/WebStatus/appsettings.Development.json b/src/Web/WebStatus/appsettings.Development.json index a96c927e8..0f530c147 100644 --- a/src/Web/WebStatus/appsettings.Development.json +++ b/src/Web/WebStatus/appsettings.Development.json @@ -1,7 +1,2 @@ { - "Serilog": { - "MinimumLevel": { - "Default": "Debug" - } - } } diff --git a/src/Web/WebStatus/appsettings.json b/src/Web/WebStatus/appsettings.json index a7b130e1a..e1f07fa2b 100644 --- a/src/Web/WebStatus/appsettings.json +++ b/src/Web/WebStatus/appsettings.json @@ -1,16 +1,4 @@ { - "Serilog": { - "SeqServerUrl": null, - "LogstashgUrl": null, - "MinimumLevel": { - "Default": "Information", - "Override": { - "Microsoft": "Warning", - "Microsoft.eShopOnContainers": "Information", - "System": "Warning" - } - } - }, "Webhooks": [ { "Name": "", diff --git a/src/docker-compose.override.yml b/src/docker-compose.override.yml index dd1a95f3d..20dfee96f 100644 --- a/src/docker-compose.override.yml +++ b/src/docker-compose.override.yml @@ -117,8 +117,6 @@ services: - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - OrchestratorType=${ORCHESTRATOR_TYPE} - UseLoadTest=${USE_LOADTEST:-False} - - Serilog__MinimumLevel__Override__Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ=Verbose - - Serilog__MinimumLevel__Override__ordering-api=Verbose - PATH_BASE=/ordering-api - GRPC_PORT=81 - PORT=80 @@ -141,7 +139,6 @@ services: - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - OrchestratorType=${ORCHESTRATOR_TYPE} - UseLoadTest=${USE_LOADTEST:-False} - - Serilog__MinimumLevel__Override__Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ=Verbose ports: - "5111:80" @@ -155,8 +152,6 @@ services: - AzureServiceBusEnabled=False - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - OrchestratorType=${ORCHESTRATOR_TYPE} - - Serilog__MinimumLevel__Override__payment-api.IntegrationEvents.EventHandling=Verbose - - Serilog__MinimumLevel__Override__Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ=Verbose ports: - "5108:80" From da024f9812a49363083d1826b115a0dff54a8be1 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 09:15:40 -0700 Subject: [PATCH 038/118] Remove Program.AppName --- .../EventBus/EventBusServiceBus/EventBusServiceBus.cs | 5 ++--- src/Services/Ordering/Ordering.BackgroundTasks/Program.cs | 6 ------ src/Services/Ordering/Ordering.SignalrHub/Program.cs | 5 ----- src/Services/Payment/Payment.API/Program.cs | 5 ----- src/Web/WebMVC/Program.cs | 5 ----- src/Web/WebStatus/Program.cs | 6 ------ 6 files changed, 2 insertions(+), 30 deletions(-) diff --git a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs index 0b350967d..c409717d6 100644 --- a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs +++ b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; @@ -12,7 +12,6 @@ public class EventBusServiceBus : IEventBus, IAsyncDisposable private readonly string _subscriptionName; private readonly ServiceBusSender _sender; private readonly ServiceBusProcessor _processor; - private readonly string AUTOFAC_SCOPE_NAME = "eshop_event_bus"; private const string INTEGRATION_EVENT_SUFFIX = "IntegrationEvent"; public EventBusServiceBus(IServiceBusPersisterConnection serviceBusPersisterConnection, @@ -198,4 +197,4 @@ public class EventBusServiceBus : IEventBus, IAsyncDisposable _subsManager.Clear(); await _processor.CloseAsync(); } -} \ No newline at end of file +} diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs index 35f066fed..de689fd33 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs @@ -34,9 +34,3 @@ app.MapHealthChecks("/liveness", new HealthCheckOptions }); await app.RunAsync(); - -public partial class Program -{ - public static string Namespace = typeof(Program).Assembly.GetName().Name; - public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1); -} diff --git a/src/Services/Ordering/Ordering.SignalrHub/Program.cs b/src/Services/Ordering/Ordering.SignalrHub/Program.cs index 00b61d63b..160855613 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Program.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Program.cs @@ -196,11 +196,6 @@ void RegisterEventBus(IServiceCollection services, IConfiguration configuration) services.AddSingleton(); } -public partial class Program -{ - public static string Namespace = typeof(Program).Assembly.GetName().Name; - public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1); -} public static class CustomExtensionMethods { public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) diff --git a/src/Services/Payment/Payment.API/Program.cs b/src/Services/Payment/Payment.API/Program.cs index 60c7d947f..8c95c4b0d 100644 --- a/src/Services/Payment/Payment.API/Program.cs +++ b/src/Services/Payment/Payment.API/Program.cs @@ -129,11 +129,6 @@ void ConfigureEventBus(IApplicationBuilder app) eventBus.Subscribe(); } -public partial class Program -{ - public static string Namespace = typeof(Program).Assembly.GetName().Name; - public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1); -} public static class CustomExtensionMethods { public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) diff --git a/src/Web/WebMVC/Program.cs b/src/Web/WebMVC/Program.cs index 3d5eb1511..55e7a1027 100644 --- a/src/Web/WebMVC/Program.cs +++ b/src/Web/WebMVC/Program.cs @@ -149,8 +149,3 @@ static void AddCustomAuthentication(WebApplicationBuilder builder) options.Scope.Add("webhooks"); }); } - -public partial class Program -{ - public static readonly string AppName = typeof(Program).Assembly.GetName().Name; -} diff --git a/src/Web/WebStatus/Program.cs b/src/Web/WebStatus/Program.cs index ddecc6a9e..96c91271e 100644 --- a/src/Web/WebStatus/Program.cs +++ b/src/Web/WebStatus/Program.cs @@ -52,9 +52,3 @@ app.MapHealthChecks("/liveness", new HealthCheckOptions }); await app.RunAsync(); - -public partial class Program -{ - private static readonly string _namespace = typeof(Program).Assembly.GetName().Name; - public static readonly string AppName = _namespace; -} From 02c163246b0773641d16b0b8a18567b617b97252 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 09:31:28 -0700 Subject: [PATCH 039/118] Add EventBus connection string to Catalog.API --- src/Services/Catalog/Catalog.API/appsettings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Services/Catalog/Catalog.API/appsettings.json b/src/Services/Catalog/Catalog.API/appsettings.json index 0141b6a7b..35596836f 100644 --- a/src/Services/Catalog/Catalog.API/appsettings.json +++ b/src/Services/Catalog/Catalog.API/appsettings.json @@ -17,11 +17,11 @@ } }, "ConnectionStrings": { + "EventBus": "localhost", "CatalogDB": "" }, "EventBus": { "SubscriptionClientName": "Catalog", - "ConnectionString": "localhost", "RetryCount": 5 } } From b9f48faf99057d392ea3de987084a1a0573dd1b9 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 09:33:36 -0700 Subject: [PATCH 040/118] Use simpler syntax for default --- .../Catalog.API/Extensions/LinqSelectExtensions.cs | 2 +- .../Application/Commands/IdentifiedCommandHandler.cs | 2 +- .../Ordering.API/Extensions/LinqSelectExtensions.cs | 2 +- .../Ordering/Ordering.Domain/SeedWork/Entity.cs | 2 +- .../Ordering/Ordering.Domain/SeedWork/IUnitOfWork.cs | 4 ++-- .../Ordering.Infrastructure/OrderingContext.cs | 8 ++++---- .../Application/IdentifiedCommandHandlerTest.cs | 11 +++++------ .../Application/NewOrderCommandHandlerTest.cs | 2 +- .../Application/OrdersWebApiTest.cs | 8 ++++---- src/Web/WebMVC/Extensions/SessionExtensions.cs | 2 +- 10 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/Services/Catalog/Catalog.API/Extensions/LinqSelectExtensions.cs b/src/Services/Catalog/Catalog.API/Extensions/LinqSelectExtensions.cs index 85fa9300c..65d72c1d2 100644 --- a/src/Services/Catalog/Catalog.API/Extensions/LinqSelectExtensions.cs +++ b/src/Services/Catalog/Catalog.API/Extensions/LinqSelectExtensions.cs @@ -13,7 +13,7 @@ public static class LinqSelectExtensions } catch (Exception ex) { - returnedValue = new SelectTryResult(element, default(TResult), ex); + returnedValue = new SelectTryResult(element, default, ex); } yield return returnedValue; } diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs index 43f6c8dcc..3864da446 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs @@ -98,7 +98,7 @@ public abstract class IdentifiedCommandHandler : IRequestHandler(element, default(TResult), ex); + returnedValue = new SelectTryResult(element, default, ex); } yield return returnedValue; } diff --git a/src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs b/src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs index a8e5c23ad..1a577361a 100644 --- a/src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs +++ b/src/Services/Ordering/Ordering.Domain/SeedWork/Entity.cs @@ -37,7 +37,7 @@ public abstract class Entity public bool IsTransient() { - return this.Id == default(Int32); + return this.Id == default; } public override bool Equals(object obj) diff --git a/src/Services/Ordering/Ordering.Domain/SeedWork/IUnitOfWork.cs b/src/Services/Ordering/Ordering.Domain/SeedWork/IUnitOfWork.cs index b9c121655..408815e11 100644 --- a/src/Services/Ordering/Ordering.Domain/SeedWork/IUnitOfWork.cs +++ b/src/Services/Ordering/Ordering.Domain/SeedWork/IUnitOfWork.cs @@ -2,6 +2,6 @@ public interface IUnitOfWork : IDisposable { - Task SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken)); - Task SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken)); + Task SaveChangesAsync(CancellationToken cancellationToken = default); + Task SaveEntitiesAsync(CancellationToken cancellationToken = default); } diff --git a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs index 8693664c3..66af0bbd5 100644 --- a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs +++ b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs @@ -38,7 +38,7 @@ public class OrderingContext : DbContext, IUnitOfWork modelBuilder.ApplyConfiguration(new BuyerEntityTypeConfiguration()); } - public async Task SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken)) + public async Task SaveEntitiesAsync(CancellationToken cancellationToken = default) { // Dispatch Domain Events collection. // Choices: @@ -120,12 +120,12 @@ public class OrderingContextDesignFactory : IDesignTimeDbContextFactory CreateStream(IStreamRequest request, CancellationToken cancellationToken = default) { - return default(IAsyncEnumerable); + return default; } public IAsyncEnumerable CreateStream(object request, CancellationToken cancellationToken = default) { - return default(IAsyncEnumerable); + return default; } public Task Publish(TNotification notification, CancellationToken cancellationToken = default) where TNotification : INotification @@ -140,7 +140,7 @@ public class OrderingContextDesignFactory : IDesignTimeDbContextFactory Send(IRequest request, CancellationToken cancellationToken = default) { - return Task.FromResult(default(TResponse)); + return Task.FromResult(default); } public Task Send(object request, CancellationToken cancellationToken = default) diff --git a/src/Services/Ordering/Ordering.UnitTests/Application/IdentifiedCommandHandlerTest.cs b/src/Services/Ordering/Ordering.UnitTests/Application/IdentifiedCommandHandlerTest.cs index 37755202c..cf84bd880 100644 --- a/src/Services/Ordering/Ordering.UnitTests/Application/IdentifiedCommandHandlerTest.cs +++ b/src/Services/Ordering/Ordering.UnitTests/Application/IdentifiedCommandHandlerTest.cs @@ -23,7 +23,7 @@ public class IdentifiedCommandHandlerTest _requestManager.Setup(x => x.ExistAsync(It.IsAny())) .Returns(Task.FromResult(false)); - _mediator.Setup(x => x.Send(It.IsAny>(), default(System.Threading.CancellationToken))) + _mediator.Setup(x => x.Send(It.IsAny>(), default)) .Returns(Task.FromResult(true)); //Act @@ -33,7 +33,7 @@ public class IdentifiedCommandHandlerTest //Assert Assert.True(result); - _mediator.Verify(x => x.Send(It.IsAny>(), default(System.Threading.CancellationToken)), Times.Once()); + _mediator.Verify(x => x.Send(It.IsAny>(), default), Times.Once()); } [Fact] @@ -46,17 +46,16 @@ public class IdentifiedCommandHandlerTest _requestManager.Setup(x => x.ExistAsync(It.IsAny())) .Returns(Task.FromResult(true)); - _mediator.Setup(x => x.Send(It.IsAny>(), default(System.Threading.CancellationToken))) + _mediator.Setup(x => x.Send(It.IsAny>(), default)) .Returns(Task.FromResult(true)); //Act var handler = new CreateOrderIdentifiedCommandHandler(_mediator.Object, _requestManager.Object, _loggerMock.Object); - var cltToken = new System.Threading.CancellationToken(); - var result = await handler.Handle(fakeOrderCmd, cltToken); + var result = await handler.Handle(fakeOrderCmd, CancellationToken.None); //Assert Assert.False(result); - _mediator.Verify(x => x.Send(It.IsAny>(), default(System.Threading.CancellationToken)), Times.Never()); + _mediator.Verify(x => x.Send(It.IsAny>(), default), Times.Never()); } private CreateOrderCommand FakeOrderRequest(Dictionary args = null) diff --git a/src/Services/Ordering/Ordering.UnitTests/Application/NewOrderCommandHandlerTest.cs b/src/Services/Ordering/Ordering.UnitTests/Application/NewOrderCommandHandlerTest.cs index 184a5f5d2..734435cc6 100644 --- a/src/Services/Ordering/Ordering.UnitTests/Application/NewOrderCommandHandlerTest.cs +++ b/src/Services/Ordering/Ordering.UnitTests/Application/NewOrderCommandHandlerTest.cs @@ -31,7 +31,7 @@ public class NewOrderRequestHandlerTest _orderRepositoryMock.Setup(orderRepo => orderRepo.GetAsync(It.IsAny())) .Returns(Task.FromResult(FakeOrder())); - _orderRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default(CancellationToken))) + _orderRepositoryMock.Setup(buyerRepo => buyerRepo.UnitOfWork.SaveChangesAsync(default)) .Returns(Task.FromResult(1)); _identityServiceMock.Setup(svc => svc.GetUserIdentity()).Returns(buyerId); diff --git a/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs b/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs index 748701891..df6004e17 100644 --- a/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs +++ b/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs @@ -21,7 +21,7 @@ public class OrdersWebApiTest public async Task Cancel_order_with_requestId_success() { //Arrange - _mediatorMock.Setup(x => x.Send(It.IsAny>(), default(CancellationToken))) + _mediatorMock.Setup(x => x.Send(It.IsAny>(), default)) .Returns(Task.FromResult(true)); //Act @@ -37,7 +37,7 @@ public class OrdersWebApiTest public async Task Cancel_order_bad_request() { //Arrange - _mediatorMock.Setup(x => x.Send(It.IsAny>(), default(CancellationToken))) + _mediatorMock.Setup(x => x.Send(It.IsAny>(), default)) .Returns(Task.FromResult(true)); //Act @@ -52,7 +52,7 @@ public class OrdersWebApiTest public async Task Ship_order_with_requestId_success() { //Arrange - _mediatorMock.Setup(x => x.Send(It.IsAny>(), default(System.Threading.CancellationToken))) + _mediatorMock.Setup(x => x.Send(It.IsAny>(), default)) .Returns(Task.FromResult(true)); //Act @@ -68,7 +68,7 @@ public class OrdersWebApiTest public async Task Ship_order_bad_request() { //Arrange - _mediatorMock.Setup(x => x.Send(It.IsAny>(), default(System.Threading.CancellationToken))) + _mediatorMock.Setup(x => x.Send(It.IsAny>(), default)) .Returns(Task.FromResult(true)); //Act diff --git a/src/Web/WebMVC/Extensions/SessionExtensions.cs b/src/Web/WebMVC/Extensions/SessionExtensions.cs index c7d87034d..f2edb3c8b 100644 --- a/src/Web/WebMVC/Extensions/SessionExtensions.cs +++ b/src/Web/WebMVC/Extensions/SessionExtensions.cs @@ -7,7 +7,7 @@ { var value = session.GetString(key); - return value == null ? default(T) : JsonSerializer.Deserialize(value, new JsonSerializerOptions + return value == null ? default : JsonSerializer.Deserialize(value, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); From fea08c78bb6c832b27c4cd33e965e085d885fe56 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 09:41:56 -0700 Subject: [PATCH 041/118] Finish removing Autofac --- .../EventBusRabbitMQ/EventBusRabbitMQ.cs | 1 - .../EventBusRabbitMQ/EventBusRabbitMQ.csproj | 1 - .../EventBus/EventBusRabbitMQ/GlobalUsings.cs | 1 - .../EventBusServiceBus.csproj | 1 - .../EventBusServiceBus/GlobalUsings.cs | 1 - src/Directory.Packages.props | 2 -- .../Basket/Basket.API/GlobalUsings.cs | 1 - .../Identity/Identity.API/Identity.API.csproj | 1 - .../Ordering/Ordering.API/GlobalUsings.cs | 2 -- .../AutofacModules/ApplicationModule.cs | 20 ------------------- .../AutofacModules/MediatorModule.cs | 9 --------- .../Ordering/Ordering.API/Ordering.API.csproj | 5 ++--- src/Services/Ordering/Ordering.API/Program.cs | 5 ----- .../Ordering.BackgroundTasks.csproj | 2 -- .../AutofacModules/ApplicationModule.cs | 20 ------------------- .../Ordering.SignalrHub/GlobalUsings.cs | 5 +---- .../Ordering.SignalrHub.csproj | 1 - .../Ordering/Ordering.SignalrHub/Program.cs | 11 +++++++--- .../IdentifiedCommandHandlerTest.cs | 3 +-- .../Payment/Payment.API/GlobalUsings.cs | 4 +--- .../Payment/Payment.API/Payment.API.csproj | 1 - .../Services.Common/Services.Common.csproj | 1 - .../Webhooks/Webhooks.API/GlobalUsings.cs | 4 +--- src/Services/Webhooks/Webhooks.API/Startup.cs | 7 ++----- .../Webhooks/Webhooks.API/Webhooks.API.csproj | 1 - 25 files changed, 16 insertions(+), 94 deletions(-) delete mode 100644 src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs delete mode 100644 src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs delete mode 100644 src/Services/Ordering/Ordering.SignalrHub/AutofacModules/ApplicationModule.cs diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs index b8312d7c1..8826b88e6 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs @@ -4,7 +4,6 @@ using Microsoft.Extensions.DependencyInjection; public class EventBusRabbitMQ : IEventBus, IDisposable { const string BROKER_NAME = "eshop_event_bus"; - const string AUTOFAC_SCOPE_NAME = "eshop_event_bus"; private readonly IRabbitMQPersistentConnection _persistentConnection; private readonly ILogger _logger; diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj index bf442f8b1..329cc99e1 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj @@ -6,7 +6,6 @@ - diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/GlobalUsings.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/GlobalUsings.cs index 6fa5f0bf4..d63437f0e 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/GlobalUsings.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/GlobalUsings.cs @@ -7,7 +7,6 @@ global using RabbitMQ.Client.Exceptions; global using System; global using System.IO; global using System.Net.Sockets; -global using Autofac; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; diff --git a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj index 545f190ed..8b1785e6f 100644 --- a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj +++ b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj @@ -6,7 +6,6 @@ - diff --git a/src/BuildingBlocks/EventBus/EventBusServiceBus/GlobalUsings.cs b/src/BuildingBlocks/EventBus/EventBusServiceBus/GlobalUsings.cs index 73eb45c1f..836f5ae52 100644 --- a/src/BuildingBlocks/EventBus/EventBusServiceBus/GlobalUsings.cs +++ b/src/BuildingBlocks/EventBus/EventBusServiceBus/GlobalUsings.cs @@ -2,7 +2,6 @@ global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; global using System.Threading.Tasks; global using System; -global using Autofac; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; global using Microsoft.Extensions.Logging; global using System.Text; diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 4f8a92814..4437cc543 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -14,8 +14,6 @@ - - diff --git a/src/Services/Basket/Basket.API/GlobalUsings.cs b/src/Services/Basket/Basket.API/GlobalUsings.cs index 768af4a41..c0c12186a 100644 --- a/src/Services/Basket/Basket.API/GlobalUsings.cs +++ b/src/Services/Basket/Basket.API/GlobalUsings.cs @@ -6,7 +6,6 @@ global using System.Net; global using System.Security.Claims; global using System.Text.Json; global using System.Threading.Tasks; -global using Autofac; global using Basket.API.Infrastructure.ActionResults; global using Basket.API.Infrastructure.Exceptions; global using Basket.API.Infrastructure.Filters; diff --git a/src/Services/Identity/Identity.API/Identity.API.csproj b/src/Services/Identity/Identity.API/Identity.API.csproj index 93bf5b3a5..4afd80c1c 100644 --- a/src/Services/Identity/Identity.API/Identity.API.csproj +++ b/src/Services/Identity/Identity.API/Identity.API.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Services/Ordering/Ordering.API/GlobalUsings.cs b/src/Services/Ordering/Ordering.API/GlobalUsings.cs index 1ae71968a..e52b97941 100644 --- a/src/Services/Ordering/Ordering.API/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.API/GlobalUsings.cs @@ -1,7 +1,5 @@ global using ApiModels = Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models; global using AppCommand = Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; -global using Autofac.Extensions.DependencyInjection; -global using Autofac; global using Azure.Core; global using Azure.Identity; global using Dapper; diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs deleted file mode 100644 index 451b2b7d8..000000000 --- a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules; - -public class ApplicationModule - : Autofac.Module -{ - - public string QueriesConnectionString { get; } - - public ApplicationModule(string qconstr) - { - QueriesConnectionString = qconstr; - - } - - protected override void Load(ContainerBuilder builder) - { - - - } -} diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs deleted file mode 100644 index c343d8290..000000000 --- a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules; - -public class MediatorModule : Autofac.Module -{ - protected override void Load(ContainerBuilder builder) - { - - } -} diff --git a/src/Services/Ordering/Ordering.API/Ordering.API.csproj b/src/Services/Ordering/Ordering.API/Ordering.API.csproj index da1157d59..a3abadcab 100644 --- a/src/Services/Ordering/Ordering.API/Ordering.API.csproj +++ b/src/Services/Ordering/Ordering.API/Ordering.API.csproj @@ -20,7 +20,7 @@ - + @@ -44,7 +44,6 @@ - @@ -74,4 +73,4 @@ - + \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index c6b30c355..26ab83a3a 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -38,11 +38,6 @@ builder.Services .AddCustomConfiguration(builder.Configuration) .AddEventBus(builder.Configuration); -builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); -// Register your own things directly with Autofac here. Don't -// call builder.Populate(), that happens in AutofacServiceProviderFactory -// for you. - var services = builder.Services; services.AddMediatR(cfg => diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj b/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj index 1ac347d86..0b9cabbcc 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj @@ -12,8 +12,6 @@ - - diff --git a/src/Services/Ordering/Ordering.SignalrHub/AutofacModules/ApplicationModule.cs b/src/Services/Ordering/Ordering.SignalrHub/AutofacModules/ApplicationModule.cs deleted file mode 100644 index 9d28154ea..000000000 --- a/src/Services/Ordering/Ordering.SignalrHub/AutofacModules/ApplicationModule.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.AutofacModules; - -public class ApplicationModule - : Autofac.Module -{ - - public string QueriesConnectionString { get; } - - public ApplicationModule() - { - } - - protected override void Load(ContainerBuilder builder) - { - - builder.RegisterAssemblyTypes(typeof(OrderStatusChangedToAwaitingValidationIntegrationEvent).GetTypeInfo().Assembly) - .AsClosedTypesOf(typeof(IIntegrationEventHandler<>)); - - } -} diff --git a/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs b/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs index a6c14a022..5d956ba77 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs @@ -1,6 +1,4 @@ -global using Autofac.Extensions.DependencyInjection; -global using Autofac; -global using HealthChecks.UI.Client; +global using HealthChecks.UI.Client; global using Microsoft.AspNetCore.Authentication.JwtBearer; global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; @@ -19,7 +17,6 @@ global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Diagnostics.HealthChecks; global using Microsoft.Extensions.Logging; -global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.AutofacModules; global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub; global using RabbitMQ.Client; diff --git a/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj b/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj index 787776c41..0eab4e6cb 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj +++ b/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Services/Ordering/Ordering.SignalrHub/Program.cs b/src/Services/Ordering/Ordering.SignalrHub/Program.cs index 160855613..718f7760d 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Program.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Program.cs @@ -74,11 +74,16 @@ else return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); }); } + ConfigureAuthService(builder.Services, builder.Configuration); RegisterEventBus(builder.Services, builder.Configuration); -builder.Services.AddOptions(); -builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); -builder.Host.ConfigureContainer(conBuilder => conBuilder.RegisterModule(new ApplicationModule())); +builder.Services.AddSingleton, OrderStatusChangedToAwaitingValidationIntegrationEventHandler>(); +builder.Services.AddSingleton, OrderStatusChangedToCancelledIntegrationEventHandler>(); +builder.Services.AddSingleton, OrderStatusChangedToPaidIntegrationEventHandler>(); +builder.Services.AddSingleton, OrderStatusChangedToShippedIntegrationEventHandler>(); +builder.Services.AddSingleton, OrderStatusChangedToStockConfirmedIntegrationEventHandler>(); +builder.Services.AddSingleton, OrderStatusChangedToSubmittedIntegrationEventHandler>(); + var app = builder.Build(); if (app.Environment.IsDevelopment()) { diff --git a/src/Services/Ordering/Ordering.UnitTests/Application/IdentifiedCommandHandlerTest.cs b/src/Services/Ordering/Ordering.UnitTests/Application/IdentifiedCommandHandlerTest.cs index cf84bd880..79e17b234 100644 --- a/src/Services/Ordering/Ordering.UnitTests/Application/IdentifiedCommandHandlerTest.cs +++ b/src/Services/Ordering/Ordering.UnitTests/Application/IdentifiedCommandHandlerTest.cs @@ -28,8 +28,7 @@ public class IdentifiedCommandHandlerTest //Act var handler = new CreateOrderIdentifiedCommandHandler(_mediator.Object, _requestManager.Object, _loggerMock.Object); - var cltToken = new System.Threading.CancellationToken(); - var result = await handler.Handle(fakeOrderCmd, cltToken); + var result = await handler.Handle(fakeOrderCmd, CancellationToken.None); //Assert Assert.True(result); diff --git a/src/Services/Payment/Payment.API/GlobalUsings.cs b/src/Services/Payment/Payment.API/GlobalUsings.cs index b064110ab..023296a1c 100644 --- a/src/Services/Payment/Payment.API/GlobalUsings.cs +++ b/src/Services/Payment/Payment.API/GlobalUsings.cs @@ -1,6 +1,4 @@ -global using Autofac.Extensions.DependencyInjection; -global using Autofac; -global using Azure.Core; +global using Azure.Core; global using Azure.Identity; global using HealthChecks.UI.Client; global using Microsoft.AspNetCore.Diagnostics.HealthChecks; diff --git a/src/Services/Payment/Payment.API/Payment.API.csproj b/src/Services/Payment/Payment.API/Payment.API.csproj index 4e72c131e..f6b9637f0 100644 --- a/src/Services/Payment/Payment.API/Payment.API.csproj +++ b/src/Services/Payment/Payment.API/Payment.API.csproj @@ -12,7 +12,6 @@ - diff --git a/src/Services/Services.Common/Services.Common.csproj b/src/Services/Services.Common/Services.Common.csproj index 89ff64893..7756c425d 100644 --- a/src/Services/Services.Common/Services.Common.csproj +++ b/src/Services/Services.Common/Services.Common.csproj @@ -15,7 +15,6 @@ - diff --git a/src/Services/Webhooks/Webhooks.API/GlobalUsings.cs b/src/Services/Webhooks/Webhooks.API/GlobalUsings.cs index a2b8516f1..133a01cb1 100644 --- a/src/Services/Webhooks/Webhooks.API/GlobalUsings.cs +++ b/src/Services/Webhooks/Webhooks.API/GlobalUsings.cs @@ -1,6 +1,4 @@ -global using Autofac.Extensions.DependencyInjection; -global using Autofac; -global using HealthChecks.UI.Client; +global using HealthChecks.UI.Client; global using Microsoft.AspNetCore.Authentication.JwtBearer; global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; diff --git a/src/Services/Webhooks/Webhooks.API/Startup.cs b/src/Services/Webhooks/Webhooks.API/Startup.cs index 10a923972..64cfe62e3 100644 --- a/src/Services/Webhooks/Webhooks.API/Startup.cs +++ b/src/Services/Webhooks/Webhooks.API/Startup.cs @@ -1,4 +1,4 @@ -namespace Webhooks.API; +namespace Webhooks.API; public class Startup { public IConfiguration Configuration { get; } @@ -26,10 +26,7 @@ public class Startup .AddTransient() .AddTransient() .AddTransient(); - - var container = new ContainerBuilder(); - container.Populate(services); - return new AutofacServiceProvider(container.Build()); + return services.BuildServiceProvider(); } public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) diff --git a/src/Services/Webhooks/Webhooks.API/Webhooks.API.csproj b/src/Services/Webhooks/Webhooks.API/Webhooks.API.csproj index 1bcdc8d69..4357a1520 100644 --- a/src/Services/Webhooks/Webhooks.API/Webhooks.API.csproj +++ b/src/Services/Webhooks/Webhooks.API/Webhooks.API.csproj @@ -12,7 +12,6 @@ - From 83200f9331b9b2f2569699b6b8e096d4c230170a Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 09:50:44 -0700 Subject: [PATCH 042/118] Fix Dockerfiles to include Services.Common --- src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile | 1 + src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile | 1 + src/Services/Basket/Basket.API/Dockerfile | 1 + src/Services/Catalog/Catalog.API/Dockerfile | 1 + src/Services/Identity/Identity.API/Dockerfile | 1 + src/Services/Ordering/Ordering.API/Dockerfile | 1 + src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile | 1 + src/Services/Ordering/Ordering.SignalrHub/Dockerfile | 1 + src/Services/Payment/Payment.API/Dockerfile | 1 + src/Services/Webhooks/Webhooks.API/Dockerfile | 1 + src/Web/WebMVC/Dockerfile | 1 + src/Web/WebSPA/Dockerfile | 1 + src/Web/WebStatus/Dockerfile | 1 + src/Web/WebhookClient/Dockerfile | 1 + 14 files changed, 14 insertions(+) diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile index 4143cdb2c..9a6b83be8 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Dockerfile @@ -32,6 +32,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile b/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile index d28a12d47..e8bd952a2 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Dockerfile @@ -32,6 +32,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" diff --git a/src/Services/Basket/Basket.API/Dockerfile b/src/Services/Basket/Basket.API/Dockerfile index 83e268825..71bfc1547 100644 --- a/src/Services/Basket/Basket.API/Dockerfile +++ b/src/Services/Basket/Basket.API/Dockerfile @@ -32,6 +32,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" diff --git a/src/Services/Catalog/Catalog.API/Dockerfile b/src/Services/Catalog/Catalog.API/Dockerfile index 2752c5c66..9138482c1 100644 --- a/src/Services/Catalog/Catalog.API/Dockerfile +++ b/src/Services/Catalog/Catalog.API/Dockerfile @@ -33,6 +33,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" diff --git a/src/Services/Identity/Identity.API/Dockerfile b/src/Services/Identity/Identity.API/Dockerfile index 0aa3105af..574eb277a 100644 --- a/src/Services/Identity/Identity.API/Dockerfile +++ b/src/Services/Identity/Identity.API/Dockerfile @@ -32,6 +32,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" diff --git a/src/Services/Ordering/Ordering.API/Dockerfile b/src/Services/Ordering/Ordering.API/Dockerfile index f3dc3ad49..bb3268238 100644 --- a/src/Services/Ordering/Ordering.API/Dockerfile +++ b/src/Services/Ordering/Ordering.API/Dockerfile @@ -32,6 +32,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile b/src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile index 506238148..3bebc9661 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Dockerfile @@ -32,6 +32,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" diff --git a/src/Services/Ordering/Ordering.SignalrHub/Dockerfile b/src/Services/Ordering/Ordering.SignalrHub/Dockerfile index ef1417617..12529612d 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Dockerfile +++ b/src/Services/Ordering/Ordering.SignalrHub/Dockerfile @@ -32,6 +32,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" diff --git a/src/Services/Payment/Payment.API/Dockerfile b/src/Services/Payment/Payment.API/Dockerfile index f2d45cbf1..d1bcc6bda 100644 --- a/src/Services/Payment/Payment.API/Dockerfile +++ b/src/Services/Payment/Payment.API/Dockerfile @@ -32,6 +32,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" diff --git a/src/Services/Webhooks/Webhooks.API/Dockerfile b/src/Services/Webhooks/Webhooks.API/Dockerfile index 83f8af2cf..63d8fdb6b 100644 --- a/src/Services/Webhooks/Webhooks.API/Dockerfile +++ b/src/Services/Webhooks/Webhooks.API/Dockerfile @@ -32,6 +32,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" diff --git a/src/Web/WebMVC/Dockerfile b/src/Web/WebMVC/Dockerfile index c47b7737f..ee0adb5b2 100644 --- a/src/Web/WebMVC/Dockerfile +++ b/src/Web/WebMVC/Dockerfile @@ -32,6 +32,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" diff --git a/src/Web/WebSPA/Dockerfile b/src/Web/WebSPA/Dockerfile index 2d7dd45f5..383a46f2c 100644 --- a/src/Web/WebSPA/Dockerfile +++ b/src/Web/WebSPA/Dockerfile @@ -43,6 +43,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" diff --git a/src/Web/WebStatus/Dockerfile b/src/Web/WebStatus/Dockerfile index c1e3fff41..c9ec1f58d 100644 --- a/src/Web/WebStatus/Dockerfile +++ b/src/Web/WebStatus/Dockerfile @@ -32,6 +32,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" diff --git a/src/Web/WebhookClient/Dockerfile b/src/Web/WebhookClient/Dockerfile index 164f862c1..722c59977 100644 --- a/src/Web/WebhookClient/Dockerfile +++ b/src/Web/WebhookClient/Dockerfile @@ -33,6 +33,7 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj" COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj" +COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj" COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj" From 16b63001df621c8873938ed737992c30d8de0670 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 13:39:29 -0700 Subject: [PATCH 043/118] Add Identity sections to config and consume (likely broken). Simplify integration tests --- .../Mobile.Bff.Shopping/aggregator/Startup.cs | 5 +- .../aggregator/appsettings.json | 4 + .../aggregator/appsettings.localhost.json | 6 +- .../Web.Bff.Shopping/aggregator/Program.cs | 5 +- .../aggregator/appsettings.json | 4 + .../Basket.API/appsettings.Development.json | 2 - .../Basket/Basket.API/appsettings.json | 2 + .../Base/BasketScenarioBase.cs | 5 ++ .../Catalog/Catalog.API/appsettings.json | 8 ++ .../CatalogScenarioBase.cs | 5 ++ .../Catalog.FunctionalTests/appsettings.json | 6 +- src/Services/Ordering/Ordering.API/Program.cs | 2 +- .../Ordering/Ordering.API/appsettings.json | 8 +- src/Services/Webhooks/Webhooks.API/Startup.cs | 5 +- .../Application.FunctionalTests.csproj | 14 +-- .../GlobalUsings.cs | 21 +---- .../Services/Basket/BasketScenariosBase.cs | 66 -------------- .../Services/Basket/appsettings.json | 16 ---- .../Services/Catalog/CatalogScenariosBase.cs | 55 ------------ .../Services/Catalog/appsettings.json | 9 -- .../Services/IntegrationEventsScenarios.cs | 11 ++- .../Ordering/OrderingScenariosBase.cs | 85 ------------------- .../Services/Ordering/appsettings.json | 11 --- .../{Ordering => }/OrderingScenarios.cs | 24 +++--- src/docker-compose.override.yml | 24 +++--- src/docker-compose.prod.yml | 8 +- 26 files changed, 95 insertions(+), 316 deletions(-) delete mode 100644 src/Tests/Services/Application.FunctionalTests/Services/Basket/BasketScenariosBase.cs delete mode 100644 src/Tests/Services/Application.FunctionalTests/Services/Basket/appsettings.json delete mode 100644 src/Tests/Services/Application.FunctionalTests/Services/Catalog/CatalogScenariosBase.cs delete mode 100644 src/Tests/Services/Application.FunctionalTests/Services/Catalog/appsettings.json delete mode 100644 src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenariosBase.cs delete mode 100644 src/Tests/Services/Application.FunctionalTests/Services/Ordering/appsettings.json rename src/Tests/Services/Application.FunctionalTests/Services/{Ordering => }/OrderingScenarios.cs (85%) diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs index 55b25cd62..8ece91d56 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs @@ -92,6 +92,7 @@ public static class ServiceCollectionExtensions Version = "v1", Description = "Shopping Aggregator for Mobile Clients" }); + var identityUrl = configuration.GetSection("Identity").GetValue("ExternalUrl"); options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2, @@ -99,8 +100,8 @@ public static class ServiceCollectionExtensions { Implicit = new OpenApiOAuthFlow() { - AuthorizationUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize"), - TokenUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/token"), + AuthorizationUrl = new Uri($"{identityUrl}/connect/authorize"), + TokenUrl = new Uri($"{identityUrl}/connect/token"), Scopes = new Dictionary() { diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json index e240b78f9..b5a1dcc87 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.json @@ -1,4 +1,8 @@ { + "Identity": { + "Url": "http://localhost:5105", + "Audience": "mobileshoppingagg" + }, "Logging": { "Debug": { "IncludeScopes": false, diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json index 9f033c482..ce1d6cfbd 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/appsettings.localhost.json @@ -8,8 +8,10 @@ "grpcCatalog": "http://localhost:81", "grpcOrdering": "http://localhost:5581" }, - "IdentityUrlExternal": "http://localhost:5105", - "IdentityUrl": "http://localhost:5105", + "Identity": { + "ExternalUrl": "http://localhost:5105", + "Url": "http://localhost:5105", + }, "Logging": { "Debug": { "IncludeScopes": false, diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs index 50df67c3e..691f8975a 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs @@ -96,6 +96,7 @@ public static class ServiceCollectionExtensions Version = "v1", Description = "Shopping Aggregator for Web Clients" }); + var identityUrl = configuration.GetSection("Identity").GetValue("ExternalUrl"); options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2, @@ -103,8 +104,8 @@ public static class ServiceCollectionExtensions { Implicit = new OpenApiOAuthFlow() { - AuthorizationUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize"), - TokenUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/token"), + AuthorizationUrl = new Uri($"{identityUrl}/connect/authorize"), + TokenUrl = new Uri($"{identityUrl}/connect/token"), Scopes = new Dictionary() { { "webshoppingagg", "Shopping Aggregator for Web Clients" } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json index e240b78f9..67de4d78b 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json @@ -1,4 +1,8 @@ { + "Identity": { + "Url": "http://localhost:5105", + "Audience": "webshoppingagg" + }, "Logging": { "Debug": { "IncludeScopes": false, diff --git a/src/Services/Basket/Basket.API/appsettings.Development.json b/src/Services/Basket/Basket.API/appsettings.Development.json index 0c8e39c3c..4088044ae 100644 --- a/src/Services/Basket/Basket.API/appsettings.Development.json +++ b/src/Services/Basket/Basket.API/appsettings.Development.json @@ -1,6 +1,4 @@ { - "IdentityUrlExternal": "http://localhost:5105", - "IdentityUrl": "http://localhost:5105", "ConnectionString": "127.0.0.1", "AzureServiceBusEnabled": false, "EventBusConnection": "localhost" diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json index f425b8f17..158aa6809 100644 --- a/src/Services/Basket/Basket.API/appsettings.json +++ b/src/Services/Basket/Basket.API/appsettings.json @@ -25,6 +25,8 @@ }, "Identity": { "Audience": "basket", + "Url": "http://localhost:5105", + "ExternalUrl": "http://localhost:5105", "Scopes": { "basket": "Basket API" } diff --git a/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs index 8f56d94c3..9f72fec75 100644 --- a/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs +++ b/src/Services/Basket/Basket.FunctionalTests/Base/BasketScenarioBase.cs @@ -19,6 +19,11 @@ public class BasketScenarioBase { return $"{ApiUrlBase}/{id}"; } + + public static string GetBasketByCustomer(string customerId) + { + return $"{ApiUrlBase}/{customerId}"; + } } public static class Post diff --git a/src/Services/Catalog/Catalog.API/appsettings.json b/src/Services/Catalog/Catalog.API/appsettings.json index 35596836f..3711850cc 100644 --- a/src/Services/Catalog/Catalog.API/appsettings.json +++ b/src/Services/Catalog/Catalog.API/appsettings.json @@ -5,6 +5,14 @@ "ApplicationInsights": { "InstrumentationKey": "" }, + "Identity": { + "Url": "http://localhost:5105", + "ExternalUrl": "http://localhost:5105", + "Audience": "catalog", + "Scopes": { + "catalog": "Catalog API" + } + }, "OpenApi": { "Endpoint": { "Name": "" diff --git a/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs b/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs index ee7bb21a8..c8bd8806b 100644 --- a/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs +++ b/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs @@ -83,4 +83,9 @@ public class CatalogScenariosBase return $"?pageIndex={pageIndex}&pageSize={pageCount}"; } } + + public static class Put + { + public static string UpdateCatalogProduct = "api/v1/catalog/items"; + } } diff --git a/src/Services/Catalog/Catalog.FunctionalTests/appsettings.json b/src/Services/Catalog/Catalog.FunctionalTests/appsettings.json index 2f05bebc8..65abc02e2 100644 --- a/src/Services/Catalog/Catalog.FunctionalTests/appsettings.json +++ b/src/Services/Catalog/Catalog.FunctionalTests/appsettings.json @@ -1,6 +1,10 @@ { "ExternalCatalogBaseUrl": "http://localhost:5101", - "IdentityUrl": "http://localhost:5105", + "Identity": { + "Url": "http://localhost:5105", + "ExternalUrl": "http://localhost:5105", + "Audience": "catalog" + }, "isTest": "true", "PicBaseUrl": "http://localhost:5101/api/v1/catalog/items/[0]/pic/", diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index 26ab83a3a..a65e7a246 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -255,7 +255,7 @@ static class CustomExtensionsMethods Description = "The Ordering Service HTTP API" }); - var identityUrl = configuration["IdentityUrlExternal"]; + var identityUrl = configuration.GetSection("Identity")["ExternalUrl"]; options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { diff --git a/src/Services/Ordering/Ordering.API/appsettings.json b/src/Services/Ordering/Ordering.API/appsettings.json index 19a922b58..d920b2d86 100644 --- a/src/Services/Ordering/Ordering.API/appsettings.json +++ b/src/Services/Ordering/Ordering.API/appsettings.json @@ -1,6 +1,10 @@ { "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;TrustServerCertificate=true", - "IdentityUrl": "http://localhost:5105", + "Identity": { + "Url": "http://localhost:5105", + "ExternalUrl": "http://localhost:5105", + "Audience": "orders" + }, "UseCustomizationData": false, "AzureServiceBusEnabled": false, "SubscriptionClientName": "Ordering", @@ -17,4 +21,4 @@ "ClientId": "your-client-id", "ClientSecret": "your-client-secret" } -} + } diff --git a/src/Services/Webhooks/Webhooks.API/Startup.cs b/src/Services/Webhooks/Webhooks.API/Startup.cs index 64cfe62e3..32153a5cf 100644 --- a/src/Services/Webhooks/Webhooks.API/Startup.cs +++ b/src/Services/Webhooks/Webhooks.API/Startup.cs @@ -142,6 +142,7 @@ internal static class CustomExtensionMethods Description = "The Webhooks Microservice HTTP API. This is a simple webhooks CRUD registration entrypoint" }); + var identityUrl = configuration.GetSection("Identity").GetValue("ExternalUrl"); options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2, @@ -149,8 +150,8 @@ internal static class CustomExtensionMethods { Implicit = new OpenApiOAuthFlow() { - AuthorizationUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize"), - TokenUrl = new Uri($"{configuration.GetValue("IdentityUrlExternal")}/connect/token"), + AuthorizationUrl = new Uri($"{identityUrl}/connect/authorize"), + TokenUrl = new Uri($"{identityUrl}/connect/token"), Scopes = new Dictionary() { { "webhooks", "Webhooks API" } diff --git a/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj b/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj index dab397d78..e4b6e2c89 100644 --- a/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj +++ b/src/Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj @@ -11,12 +11,10 @@ - - @@ -32,15 +30,6 @@ Always - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - @@ -56,8 +45,11 @@ + + + diff --git a/src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs b/src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs index 493b29f63..a56d1d34b 100644 --- a/src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs +++ b/src/Tests/Services/Application.FunctionalTests/GlobalUsings.cs @@ -1,19 +1,8 @@ -global using Microsoft.AspNetCore.TestHost; -global using System; +global using System; global using System.Net.Http; global using Microsoft.AspNetCore.Http; global using System.Security.Claims; global using System.Threading.Tasks; -global using Microsoft.AspNetCore.Hosting; -global using Microsoft.Extensions.Configuration; -global using System.IO; -global using System.Reflection; -global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; -global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; -global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Logging; -global using Microsoft.Extensions.Options; -global using FunctionalTests.Services.Basket; global using Microsoft.eShopOnContainers.Services.Basket.API.Model; global using Microsoft.eShopOnContainers.WebMVC.ViewModels; global using System.Text.Json; @@ -22,12 +11,4 @@ global using System.Linq; global using System.Text; global using WebMVC.Services.ModelDTOs; global using Xunit; -global using Microsoft.eShopOnContainers.Services.Ordering.API; -global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure; -global using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; -global using FunctionalTests.Services.Catalog; -// This is a bit of a hack, since we need to differentiate each of these app's program -global using BasketProgram = Microsoft.eShopOnContainers.Services.Basket.API.BasketSettings; -global using CatalogProgram = Microsoft.eShopOnContainers.Services.Catalog.API.CatalogSettings; -global using OrderingProgram = Microsoft.eShopOnContainers.Services.Ordering.API.OrderingSettings; diff --git a/src/Tests/Services/Application.FunctionalTests/Services/Basket/BasketScenariosBase.cs b/src/Tests/Services/Application.FunctionalTests/Services/Basket/BasketScenariosBase.cs deleted file mode 100644 index 88ab903bf..000000000 --- a/src/Tests/Services/Application.FunctionalTests/Services/Basket/BasketScenariosBase.cs +++ /dev/null @@ -1,66 +0,0 @@ -using FunctionalTests.Middleware; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Mvc.Testing; -using Microsoft.Extensions.Hosting; - -namespace FunctionalTests.Services.Basket; - -public class BasketScenariosBase : WebApplicationFactory -{ - private const string ApiUrlBase = "api/v1/basket"; - - public TestServer CreateServer() - { - return Server; - } - - - protected override IHost CreateHost(IHostBuilder builder) - { - builder.ConfigureServices(servies => - { - servies.AddSingleton(); - }); - - builder.ConfigureAppConfiguration(c => - { - var directory = Path.GetDirectoryName(typeof(BasketScenariosBase).Assembly.Location)!; - - c.AddJsonFile(Path.Combine(directory, "Services/Basket/appsettings.json"), optional: false); - }); - - return base.CreateHost(builder); - } - - public static class Get - { - public static string GetBasket(int id) - { - return $"{ApiUrlBase}/{id}"; - } - - public static string GetBasketByCustomer(string customerId) - { - return $"{ApiUrlBase}/{customerId}"; - } - } - - public static class Post - { - public static string CreateBasket = $"{ApiUrlBase}/"; - public static string CheckoutOrder = $"{ApiUrlBase}/checkout"; - } - - private class AuthStartupFilter : IStartupFilter - { - public Action Configure(Action next) - { - return app => - { - app.UseMiddleware(); - - next(app); - }; - } - } -} diff --git a/src/Tests/Services/Application.FunctionalTests/Services/Basket/appsettings.json b/src/Tests/Services/Application.FunctionalTests/Services/Basket/appsettings.json deleted file mode 100644 index 3ed325899..000000000 --- a/src/Tests/Services/Application.FunctionalTests/Services/Basket/appsettings.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - }, - "IdentityUrl": "http://localhost:5105", - "IdentityUrlExternal": "http://localhost:5105", - "ConnectionString": "127.0.0.1", - "isTest": "true", - "EventBusConnection": "localhost", - "SubscriptionClientName": "Basket" -} diff --git a/src/Tests/Services/Application.FunctionalTests/Services/Catalog/CatalogScenariosBase.cs b/src/Tests/Services/Application.FunctionalTests/Services/Catalog/CatalogScenariosBase.cs deleted file mode 100644 index 830d24d97..000000000 --- a/src/Tests/Services/Application.FunctionalTests/Services/Catalog/CatalogScenariosBase.cs +++ /dev/null @@ -1,55 +0,0 @@ -namespace FunctionalTests.Services.Catalog; - -using FunctionalTests.Services.Ordering; -using Microsoft.AspNetCore.Mvc.Testing; -using Microsoft.eShopOnContainers.Services.Catalog.API; -using Microsoft.Extensions.Hosting; - -public class CatalogScenariosBase : WebApplicationFactory -{ - public TestServer CreateServer() - { - Services.MigrateDbContext((context, services) => - { - var env = services.GetService(); - var settings = services.GetService>(); - var logger = services.GetService>(); - - new CatalogContextSeed() - .SeedAsync(context, env, settings, logger) - .Wait(); - }) - .MigrateDbContext((_, __) => { }); - - return Server; - } - - protected override IHost CreateHost(IHostBuilder builder) - { - builder.ConfigureAppConfiguration(c => - { - var directory = Path.GetDirectoryName(typeof(CatalogScenariosBase).Assembly.Location)!; - - c.AddJsonFile(Path.Combine(directory, "Services/Catalog/appsettings.json"), optional: false); - }); - - return base.CreateHost(builder); - } - - public static class Get - { - public static string Orders = "api/v1/orders"; - - public static string Items = "api/v1/catalog/items"; - - public static string ProductByName(string name) - { - return $"api/v1/catalog/items/withname/{name}"; - } - } - - public static class Put - { - public static string UpdateCatalogProduct = "api/v1/catalog/items"; - } -} diff --git a/src/Tests/Services/Application.FunctionalTests/Services/Catalog/appsettings.json b/src/Tests/Services/Application.FunctionalTests/Services/Catalog/appsettings.json deleted file mode 100644 index 708598b8a..000000000 --- a/src/Tests/Services/Application.FunctionalTests/Services/Catalog/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true", - "ExternalCatalogBaseUrl": "http://localhost:5101", - "IdentityUrl": "http://localhost:5105", - "isTest": "true", - "EventBusConnection": "localhost", - "PicBaseUrl": "http://localhost:5101/api/v1/catalog/items/[0]/pic/", - "SubscriptionClientName": "Catalog" -} diff --git a/src/Tests/Services/Application.FunctionalTests/Services/IntegrationEventsScenarios.cs b/src/Tests/Services/Application.FunctionalTests/Services/IntegrationEventsScenarios.cs index 86466766f..f7b348631 100644 --- a/src/Tests/Services/Application.FunctionalTests/Services/IntegrationEventsScenarios.cs +++ b/src/Tests/Services/Application.FunctionalTests/Services/IntegrationEventsScenarios.cs @@ -1,4 +1,7 @@ namespace FunctionalTests.Services; + +using global::Basket.FunctionalTests.Base; +using global::Catalog.FunctionalTests; using Microsoft.eShopOnContainers.Services.Basket.API.Model; using Microsoft.eShopOnContainers.Services.Catalog.API.Model; using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel; @@ -12,7 +15,7 @@ public class IntegrationEventsScenarios string userId = "JohnId"; using var catalogServer = new CatalogScenariosBase().CreateServer(); - using var basketServer = new BasketScenariosBase().CreateServer(); + using var basketServer = new BasketScenarioBase().CreateServer(); var catalogClient = catalogServer.CreateClient(); var basketClient = basketServer.CreateClient(); @@ -22,7 +25,7 @@ public class IntegrationEventsScenarios // AND a user basket filled with products var basket = ComposeBasket(userId, originalCatalogProducts.Data.Take(3)); var res = await basketClient.PostAsync( - BasketScenariosBase.Post.CreateBasket, + BasketScenarioBase.Post.Basket, new StringContent(JsonSerializer.Serialize(basket), UTF8Encoding.UTF8, "application/json") ); @@ -60,7 +63,7 @@ public class IntegrationEventsScenarios while (continueLoop && counter < 20) { //get the basket and verify that the price of the modified product is updated - var basketGetResponse = await basketClient.GetAsync(BasketScenariosBase.Get.GetBasketByCustomer(userId)); + var basketGetResponse = await basketClient.GetAsync(BasketScenarioBase.Get.GetBasketByCustomer(userId)); var basketUpdated = JsonSerializer.Deserialize(await basketGetResponse.Content.ReadAsStringAsync(), new JsonSerializerOptions { PropertyNameCaseInsensitive = true @@ -84,7 +87,7 @@ public class IntegrationEventsScenarios private async Task> GetCatalogAsync(HttpClient catalogClient) { - var response = await catalogClient.GetAsync(CatalogScenariosBase.Get.Items); + var response = await catalogClient.GetAsync(CatalogScenariosBase.Get.Items(paginated: false)); var items = await response.Content.ReadAsStringAsync(); return JsonSerializer.Deserialize>(items, new JsonSerializerOptions { diff --git a/src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenariosBase.cs b/src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenariosBase.cs deleted file mode 100644 index 906cf70a5..000000000 --- a/src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenariosBase.cs +++ /dev/null @@ -1,85 +0,0 @@ -using FunctionalTests.Middleware; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Mvc.Testing; -using Microsoft.Extensions.Hosting; - -namespace FunctionalTests.Services.Ordering; - -public class OrderingScenariosBase : WebApplicationFactory -{ - public TestServer CreateServer() - { - Services - .MigrateDbContext((context, services) => - { - var env = services.GetService(); - var settings = services.GetService>(); - var logger = services.GetService>(); - - new OrderingContextSeed() - .SeedAsync(context, env, settings, logger) - .Wait(); - }) - .MigrateDbContext((_, __) => { }); - - return Server; - } - - protected override IHost CreateHost(IHostBuilder builder) - { - builder.ConfigureServices(servies => - { - servies.AddSingleton(); - }); - - builder.ConfigureAppConfiguration(c => - { - var directory = Path.GetDirectoryName(typeof(OrderingScenariosBase).Assembly.Location)!; - - c.AddJsonFile(Path.Combine(directory, "Services/Ordering/appsettings.json"), optional: false); - }); - - return base.CreateHost(builder); - } - - public static class Get - { - public static string Orders = "api/v1/orders"; - - public static string OrderBy(int id) - { - return $"api/v1/orders/{id}"; - } - } - - public static class Post - { - public static string AddNewOrder = "api/v1/orders/new"; - } - - public static class Put - { - public static string CancelOrder = "api/v1/orders/cancel"; - } - - public static class Delete - { - public static string OrderBy(int id) - { - return $"api/v1/orders/{id}"; - } - } - - private class AuthStartupFilter : IStartupFilter - { - public Action Configure(Action next) - { - return app => - { - app.UseMiddleware(); - - next(app); - }; - } - } -} diff --git a/src/Tests/Services/Application.FunctionalTests/Services/Ordering/appsettings.json b/src/Tests/Services/Application.FunctionalTests/Services/Ordering/appsettings.json deleted file mode 100644 index 18efe0185..000000000 --- a/src/Tests/Services/Application.FunctionalTests/Services/Ordering/appsettings.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true", - "ExternalCatalogBaseUrl": "http://localhost:5101", - "IdentityUrl": "http://localhost:5105", - "isTest": "true", - "EventBusConnection": "localhost", - "CheckUpdateTime": "30000", - "GracePeriodTime": "1", - "SubscriptionClientName": "Ordering", - "IdentityUrlExternal": "http://localhost:5105" -} diff --git a/src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenarios.cs b/src/Tests/Services/Application.FunctionalTests/Services/OrderingScenarios.cs similarity index 85% rename from src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenarios.cs rename to src/Tests/Services/Application.FunctionalTests/Services/OrderingScenarios.cs index 35ee35f1a..e006a6998 100644 --- a/src/Tests/Services/Application.FunctionalTests/Services/Ordering/OrderingScenarios.cs +++ b/src/Tests/Services/Application.FunctionalTests/Services/OrderingScenarios.cs @@ -1,12 +1,15 @@ -namespace FunctionalTests.Services.Ordering; +using Basket.FunctionalTests.Base; +using Ordering.FunctionalTests; -public class OrderingScenarios : OrderingScenariosBase +namespace FunctionalTests.Services.Ordering; + +public class OrderingScenarios { [Fact] public async Task Cancel_basket_and_check_order_status_cancelled() { - using var orderServer = new OrderingScenariosBase().CreateServer(); - using var basketServer = new BasketScenariosBase().CreateServer(); + using var orderServer = new OrderingScenarioBase().CreateServer(); + using var basketServer = new BasketScenarioBase().CreateServer(); // Expected data var cityExpected = $"city-{Guid.NewGuid()}"; var orderStatusExpected = "cancelled"; @@ -19,11 +22,11 @@ public class OrderingScenarios : OrderingScenariosBase { Headers = { { "x-requestid", Guid.NewGuid().ToString() } } }; - await basketClient.PostAsync(BasketScenariosBase.Post.CreateBasket, contentBasket); + await basketClient.PostAsync(BasketScenarioBase.Post.Basket, contentBasket); // AND basket checkout is sent await basketClient.PostAsync( - BasketScenariosBase.Post.CheckoutOrder, + BasketScenarioBase.Post.CheckoutOrder, new StringContent(BuildCheckout(cityExpected), UTF8Encoding.UTF8, "application/json") { Headers = { { "x-requestid", Guid.NewGuid().ToString() } } @@ -31,9 +34,10 @@ public class OrderingScenarios : OrderingScenariosBase // WHEN Order is created in Ordering.api var newOrder = await TryGetNewOrderCreated(cityExpected, orderClient); + Assert.NotNull(newOrder); // AND Order is cancelled in Ordering.api - await orderClient.PutAsync(OrderingScenariosBase.Put.CancelOrder, new StringContent(BuildCancelOrder(newOrder.OrderNumber), UTF8Encoding.UTF8, "application/json") + await orderClient.PutAsync(OrderingScenarioBase.Put.CancelOrder, new StringContent(BuildCancelOrder(newOrder.OrderNumber), UTF8Encoding.UTF8, "application/json") { Headers = { { "x-requestid", Guid.NewGuid().ToString() } } }); @@ -47,7 +51,7 @@ public class OrderingScenarios : OrderingScenariosBase async Task TryGetOrder(string orderNumber, HttpClient orderClient) { - var ordersGetResponse = await orderClient.GetStringAsync(OrderingScenariosBase.Get.Orders); + var ordersGetResponse = await orderClient.GetStringAsync(OrderingScenarioBase.Get.Orders); var orders = JsonSerializer.Deserialize>(ordersGetResponse, new JsonSerializerOptions { PropertyNameCaseInsensitive = true @@ -64,7 +68,7 @@ public class OrderingScenarios : OrderingScenariosBase while (counter < 20) { //get the orders and verify that the new order has been created - var ordersGetResponse = await orderClient.GetStringAsync(OrderingScenariosBase.Get.Orders); + var ordersGetResponse = await orderClient.GetStringAsync(OrderingScenarioBase.Get.Orders); var orders = JsonSerializer.Deserialize>(ordersGetResponse, new JsonSerializerOptions { PropertyNameCaseInsensitive = true @@ -79,7 +83,7 @@ public class OrderingScenarios : OrderingScenariosBase var lastOrder = orders.OrderByDescending(o => o.Date).First(); int.TryParse(lastOrder.OrderNumber, out int id); - var orderDetails = await orderClient.GetStringAsync(OrderingScenariosBase.Get.OrderBy(id)); + var orderDetails = await orderClient.GetStringAsync(OrderingScenarioBase.Get.OrderBy(id)); order = JsonSerializer.Deserialize(orderDetails, new JsonSerializerOptions { PropertyNameCaseInsensitive = true diff --git a/src/docker-compose.override.yml b/src/docker-compose.override.yml index 20dfee96f..ac2c1872c 100644 --- a/src/docker-compose.override.yml +++ b/src/docker-compose.override.yml @@ -63,8 +63,8 @@ services: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basketdata} - - identityUrl=http://identity-api - - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - Identity__Url=http://identity-api + - Identity__ExternalUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} @@ -106,8 +106,8 @@ services: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} - - identityUrl=http://identity-api - - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - Identity__Url=http://identity-api + - Identity__ExternalUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} @@ -163,8 +163,8 @@ services: - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - - IdentityUrl=http://identity-api - - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - Identity__Url=http://identity-api + - Identity__ExternalUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 ports: - "5113:80" @@ -197,7 +197,8 @@ services: - IdentityUrlHC=http://identity-api/hc - BasketUrlHC=http://basket-api/hc - PaymentUrlHC=http://payment-api/hc - - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - Identity__Url=http://identity-api + - Identity__ExternalUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 ports: - "5120:80" @@ -216,7 +217,8 @@ services: - IdentityUrlHC=http://identity-api/hc - BasketUrlHC=http://basket-api/hc - PaymentUrlHC=http://payment-api/hc - - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - Identity__Url=http://identity-api + - Identity__ExternalUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 ports: - "5121:80" @@ -269,7 +271,7 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Production - ASPNETCORE_URLS=http://0.0.0.0:80 - - IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - Identity__Url=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - PurchaseUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202 - IdentityUrlHC=http://identity-api/hc - UseCustomizationData=True @@ -284,7 +286,7 @@ services: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - PurchaseUrl=http://webshoppingapigw - - IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - Identity__Url=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202 - IdentityUrlHC=http://identity-api/hc - UseCustomizationData=True @@ -298,7 +300,7 @@ services: environment: - ASPNETCORE_URLS=http://0.0.0.0:80 - Token=6168DB8D-DC58-4094-AF24-483278923590 # Webhooks are registered with this token (any value is valid) but the client won't check it - - IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - Identity__Url=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - CallBackUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5114 - WebhooksUrl=http://webhooks-api - SelfUrl=http://webhooks-client/ diff --git a/src/docker-compose.prod.yml b/src/docker-compose.prod.yml index 3ff3aa2f2..0bc2cd1d2 100644 --- a/src/docker-compose.prod.yml +++ b/src/docker-compose.prod.yml @@ -21,7 +21,7 @@ services: - ASPNETCORE_URLS=http://0.0.0.0:80 - ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basket.data} - identityUrl=http://identity-api #Local: You need to open your local dev-machine firewall at range 5100-5110. - - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 + - Identity__Url=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} @@ -75,8 +75,8 @@ services: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word} - - identityUrl=http://identity-api #Local: You need to open your local dev-machine firewall at range 5100-5110. - - IdentityUrlExternal=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 + - Identity__Url=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - Identity__ExternalUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} @@ -111,7 +111,7 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105. + - Identity__Url=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - PurchaseUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5202 - CatalogUrlHC=http://catalog-api/hc - OrderingUrlHC=http://ordering-api/hc From f8abb36bc608db62c092eed129fcb1e68563b578 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 13:48:04 -0700 Subject: [PATCH 044/118] Remove non-existent wwwroot from HttpAggregator projects --- .../aggregator/Mobile.Shopping.HttpAggregator.csproj | 5 ++++- .../aggregator/Web.Shopping.HttpAggregator.csproj | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj index a25016890..dfa3275ba 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj @@ -10,7 +10,10 @@ - + + + + diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj index 5d486d3c6..c718a77bd 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj @@ -10,7 +10,10 @@ - + + + + From e2d8590a26fd8f87bbbc65f813eff75161462de3 Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 13:58:48 -0700 Subject: [PATCH 045/118] Use WebApplicationBuilder in Mobile.Shopping.HttpAggregator --- .../Models/UpdateBasketItemsRequest.cs | 1 - .../Mobile.Bff.Shopping/aggregator/Program.cs | 158 +++++++++++-- .../aggregator/Services/IBasketService.cs | 1 - .../Mobile.Bff.Shopping/aggregator/Startup.cs | 211 ------------------ 4 files changed, 144 insertions(+), 227 deletions(-) delete mode 100644 src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs index d0686ef51..f7e807d8d 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Models/UpdateBasketItemsRequest.cs @@ -2,7 +2,6 @@ public class UpdateBasketItemsRequest { - public string BasketId { get; set; } public ICollection Updates { get; set; } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs index d6f7ae482..4f31b1da9 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs @@ -1,16 +1,146 @@ -await BuildWebHost(args).RunAsync(); -IWebHost BuildWebHost(string[] args) => - WebHost - .CreateDefaultBuilder(args) - .ConfigureAppConfiguration(cb => +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddHealthChecks() + .AddCheck("self", () => HealthCheckResult.Healthy()) + .AddUrlGroup(new Uri(builder.Configuration["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" }) + .AddUrlGroup(new Uri(builder.Configuration["OrderingUrlHC"]), name: "orderingapi-check", tags: new string[] { "orderingapi" }) + .AddUrlGroup(new Uri(builder.Configuration["BasketUrlHC"]), name: "basketapi-check", tags: new string[] { "basketapi" }) + .AddUrlGroup(new Uri(builder.Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }) + .AddUrlGroup(new Uri(builder.Configuration["PaymentUrlHC"]), name: "paymentapi-check", tags: new string[] { "paymentapi" }); + +builder.Services.Configure(builder.Configuration.GetSection("urls")); + +builder.Services.AddControllers() + .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true); + +builder.Services.AddSwaggerGen(options => +{ + //options.DescribeAllEnumsAsStrings(); + options.SwaggerDoc("v1", new OpenApiInfo + { + Title = "Shopping Aggregator for Mobile Clients", + Version = "v1", + Description = "Shopping Aggregator for Mobile Clients" + }); + var identityUrl = builder.Configuration.GetSection("Identity").GetValue("ExternalUrl"); + options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme + { + Type = SecuritySchemeType.OAuth2, + Flows = new OpenApiOAuthFlows() { - var sources = cb.Sources; - sources.Insert(3, new Microsoft.Extensions.Configuration.Json.JsonConfigurationSource() + Implicit = new OpenApiOAuthFlow() { - Optional = true, - Path = "appsettings.localhost.json", - ReloadOnChange = false - }); - }) - .UseStartup() - .Build(); + AuthorizationUrl = new Uri($"{identityUrl}/connect/authorize"), + TokenUrl = new Uri($"{identityUrl}/connect/token"), + + Scopes = new Dictionary() + { + { "mobileshoppingagg", "Shopping Aggregator for Mobile Clients" } + } + } + } + }); + + options.OperationFilter(); +}); + +builder.Services.AddCors(options => +{ + options.AddPolicy("CorsPolicy", + builder => builder + .AllowAnyMethod() + .AllowAnyHeader() + .SetIsOriginAllowed((host) => true) + .AllowCredentials()); +}); + +JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); + +var identityUrl = builder.Configuration.GetValue("urls:identity"); + +builder.Services.AddAuthentication(options => +{ + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + +}) +.AddJwtBearer(options => +{ + options.Authority = identityUrl; + options.RequireHttpsMetadata = false; + options.Audience = "mobileshoppingagg"; + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateAudience = false + }; +}); + +builder.Services.AddAuthorization(options => +{ + options.AddPolicy("ApiScope", policy => + { + policy.RequireAuthenticatedUser(); + policy.RequireClaim("scope", "mobileshoppingagg"); + }); +}); + +builder.Services.AddTransient(); +builder.Services.AddSingleton(); +builder.Services.AddHttpClient(); + +builder.Services.AddTransient(); +builder.Services.AddScoped(); +builder.Services.AddGrpcClient((services, options) => +{ + var basketApi = services.GetRequiredService>().Value.GrpcBasket; + options.Address = new Uri(basketApi); +}).AddInterceptor(); +builder.Services.AddScoped(); +builder.Services.AddGrpcClient((services, options) => +{ + var catalogApi = services.GetRequiredService>().Value.GrpcCatalog; + options.Address = new Uri(catalogApi); +}).AddInterceptor(); +builder.Services.AddScoped(); +builder.Services.AddGrpcClient((services, options) => +{ + var orderingApi = services.GetRequiredService>().Value.GrpcOrdering; + options.Address = new Uri(orderingApi); +}).AddInterceptor(); + +var app = builder.Build(); + +var pathBase = app.Configuration["PATH_BASE"]; + +if (!string.IsNullOrEmpty(pathBase)) +{ + app.UsePathBase(pathBase); +} + +app.UseSwagger().UseSwaggerUI(c => +{ + c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Purchase BFF V1"); + + c.OAuthClientId("mobileshoppingaggswaggerui"); + c.OAuthClientSecret(string.Empty); + c.OAuthRealm(string.Empty); + c.OAuthAppName("Purchase BFF Swagger UI"); +}); + +app.UseRouting(); +app.UseCors("CorsPolicy"); +app.UseAuthentication(); +app.UseAuthorization(); +app.MapDefaultControllerRoute(); +app.MapControllers(); +app.MapHealthChecks("/hc", new HealthCheckOptions() +{ + Predicate = _ => true, + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse +}); +app.MapHealthChecks("/liveness", new HealthCheckOptions +{ + Predicate = r => r.Name.Contains("self") +}); + +await app.RunAsync(); diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs index e1c9a24bf..bf9c1b7e9 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Services/IBasketService.cs @@ -5,5 +5,4 @@ public interface IBasketService Task GetByIdAsync(string id); Task UpdateAsync(BasketData currentBasket); - } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs deleted file mode 100644 index 8ece91d56..000000000 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs +++ /dev/null @@ -1,211 +0,0 @@ -namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator; - -public class Startup -{ - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - services.AddHealthChecks() - .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddUrlGroup(new Uri(Configuration["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" }) - .AddUrlGroup(new Uri(Configuration["OrderingUrlHC"]), name: "orderingapi-check", tags: new string[] { "orderingapi" }) - .AddUrlGroup(new Uri(Configuration["BasketUrlHC"]), name: "basketapi-check", tags: new string[] { "basketapi" }) - .AddUrlGroup(new Uri(Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }) - .AddUrlGroup(new Uri(Configuration["PaymentUrlHC"]), name: "paymentapi-check", tags: new string[] { "paymentapi" }); - - services.AddCustomMvc(Configuration) - .AddCustomAuthentication(Configuration) - .AddHttpServices() - .AddGrpcServices(); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) - { - var pathBase = Configuration["PATH_BASE"]; - - if (!string.IsNullOrEmpty(pathBase)) - { - loggerFactory.CreateLogger().LogDebug("Using PATH BASE '{pathBase}'", pathBase); - app.UsePathBase(pathBase); - } - - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - - app.UseSwagger().UseSwaggerUI(c => - { - c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Purchase BFF V1"); - - c.OAuthClientId("mobileshoppingaggswaggerui"); - c.OAuthClientSecret(string.Empty); - c.OAuthRealm(string.Empty); - c.OAuthAppName("Purchase BFF Swagger UI"); - }); - - app.UseRouting(); - app.UseCors("CorsPolicy"); - app.UseAuthentication(); - app.UseAuthorization(); - app.UseEndpoints(endpoints => - { - endpoints.MapDefaultControllerRoute(); - endpoints.MapControllers(); - endpoints.MapHealthChecks("/hc", new HealthCheckOptions() - { - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse - }); - endpoints.MapHealthChecks("/liveness", new HealthCheckOptions - { - Predicate = r => r.Name.Contains("self") - }); - }); - } -} - -public static class ServiceCollectionExtensions -{ - public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) - { - services.AddOptions(); - services.Configure(configuration.GetSection("urls")); - - services.AddControllers() - .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true); - - services.AddSwaggerGen(options => - { - //options.DescribeAllEnumsAsStrings(); - options.SwaggerDoc("v1", new OpenApiInfo - { - Title = "Shopping Aggregator for Mobile Clients", - Version = "v1", - Description = "Shopping Aggregator for Mobile Clients" - }); - var identityUrl = configuration.GetSection("Identity").GetValue("ExternalUrl"); - options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme - { - Type = SecuritySchemeType.OAuth2, - Flows = new OpenApiOAuthFlows() - { - Implicit = new OpenApiOAuthFlow() - { - AuthorizationUrl = new Uri($"{identityUrl}/connect/authorize"), - TokenUrl = new Uri($"{identityUrl}/connect/token"), - - Scopes = new Dictionary() - { - { "mobileshoppingagg", "Shopping Aggregator for Mobile Clients" } - } - } - } - }); - - options.OperationFilter(); - }); - - services.AddCors(options => - { - options.AddPolicy("CorsPolicy", - builder => builder - .AllowAnyMethod() - .AllowAnyHeader() - .SetIsOriginAllowed((host) => true) - .AllowCredentials()); - }); - - return services; - } - public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) - { - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); - - var identityUrl = configuration.GetValue("urls:identity"); - - services.AddAuthentication(options => - { - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - - }) - .AddJwtBearer(options => - { - options.Authority = identityUrl; - options.RequireHttpsMetadata = false; - options.Audience = "mobileshoppingagg"; - options.TokenValidationParameters = new TokenValidationParameters - { - ValidateAudience = false - }; - }); - - return services; - } - public static IServiceCollection AddCustomAuthorization(this IServiceCollection services, IConfiguration configuration) - { - services.AddAuthorization(options => - { - options.AddPolicy("ApiScope", policy => - { - policy.RequireAuthenticatedUser(); - policy.RequireClaim("scope", "mobileshoppingagg"); - }); - }); - return services; - } - - public static IServiceCollection AddHttpServices(this IServiceCollection services) - { - //register delegating handlers - services.AddTransient(); - services.AddSingleton(); - - //register http services - - services.AddHttpClient(); - - return services; - } - - public static IServiceCollection AddGrpcServices(this IServiceCollection services) - { - services.AddTransient(); - - services.AddScoped(); - - services.AddGrpcClient((services, options) => - { - var basketApi = services.GetRequiredService>().Value.GrpcBasket; - options.Address = new Uri(basketApi); - }).AddInterceptor(); - - services.AddScoped(); - - services.AddGrpcClient((services, options) => - { - var catalogApi = services.GetRequiredService>().Value.GrpcCatalog; - options.Address = new Uri(catalogApi); - }).AddInterceptor(); - - services.AddScoped(); - - services.AddGrpcClient((services, options) => - { - var orderingApi = services.GetRequiredService>().Value.GrpcOrdering; - options.Address = new Uri(orderingApi); - }).AddInterceptor(); - - return services; - } - -} From 917764273b0f2bfa4d4ca2010e17e56151c9822a Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 14:05:47 -0700 Subject: [PATCH 046/118] Remove superfluous UseDeveloperExceptionPage() and AddOptions() calls --- .../Mobile.Bff.Shopping/aggregator/Program.cs | 1 - .../Web.Bff.Shopping/aggregator/Program.cs | 8 +--- src/Services/Ordering/Ordering.API/Program.cs | 42 +++++++------------ .../Ordering.BackgroundTasks/Program.cs | 8 +--- .../Ordering/Ordering.SignalrHub/Program.cs | 8 ++-- src/Services/Payment/Payment.API/Program.cs | 8 ++-- src/Web/WebMVC/Program.cs | 9 +--- src/Web/WebSPA/Program.cs | 5 --- src/Web/WebStatus/Program.cs | 7 +--- src/Web/WebhookClient/Startup.cs | 10 ++--- 10 files changed, 31 insertions(+), 75 deletions(-) diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs index 4f31b1da9..945124164 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Program.cs @@ -15,7 +15,6 @@ builder.Services.AddControllers() builder.Services.AddSwaggerGen(options => { - //options.DescribeAllEnumsAsStrings(); options.SwaggerDoc("v1", new OpenApiInfo { Title = "Shopping Aggregator for Mobile Clients", diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs index 691f8975a..8bc62923c 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs @@ -1,6 +1,5 @@ var builder = WebApplication.CreateBuilder(args); -builder.Logging.AddConsole(); builder.Services.AddHealthChecks() .AddCheck("self", () => HealthCheckResult.Healthy()) .AddUrlGroup(new Uri(builder.Configuration["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" }) @@ -13,11 +12,7 @@ builder.Services.AddCustomMvc(builder.Configuration) .AddApplicationServices() .AddGrpcServices(); var app = builder.Build(); -if (app.Environment.IsDevelopment()) -{ - app.UseDeveloperExceptionPage(); -} -else +if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); } @@ -82,7 +77,6 @@ public static class ServiceCollectionExtensions } public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) { - services.AddOptions(); services.Configure(configuration.GetSection("urls")); services.AddControllers() diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index a65e7a246..71b202f6a 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -40,27 +40,20 @@ builder.Services var services = builder.Services; - services.AddMediatR(cfg => - { - cfg.RegisterServicesFromAssemblyContaining(typeof(Program)); - - cfg.AddOpenBehavior(typeof(LoggingBehavior<,>)); - cfg.AddOpenBehavior(typeof(ValidatorBehavior<,>)); - cfg.AddOpenBehavior(typeof(TransactionBehavior<,>)); - }); - - // Register the command validators for the validator behavior (validators based on FluentValidation library) - services.AddSingleton, CancelOrderCommandValidator>(); - services.AddSingleton, CreateOrderCommandValidator>(); - services.AddSingleton>, IdentifiedCommandValidator>(); - services.AddSingleton, ShipOrderCommandValidator>(); +services.AddMediatR(cfg => +{ + cfg.RegisterServicesFromAssemblyContaining(typeof(Program)); + + cfg.AddOpenBehavior(typeof(LoggingBehavior<,>)); + cfg.AddOpenBehavior(typeof(ValidatorBehavior<,>)); + cfg.AddOpenBehavior(typeof(TransactionBehavior<,>)); +}); -/* - // Build the MediatR pipeline - services.AddSingleton(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>)); - services.AddSingleton(typeof(IPipelineBehavior<,>), typeof(ValidatorBehavior<,>)); - services.AddSingleton(typeof(IPipelineBehavior<,>), typeof(TransactionBehavior<,>)); -*/ +// Register the command validators for the validator behavior (validators based on FluentValidation library) +services.AddSingleton, CancelOrderCommandValidator>(); +services.AddSingleton, CreateOrderCommandValidator>(); +services.AddSingleton>, IdentifiedCommandValidator>(); +services.AddSingleton, ShipOrderCommandValidator>(); var queriesConnectionString = builder.Configuration["ConnectionString"]; @@ -78,19 +71,17 @@ services.AddSingleton, UserCheckoutAcceptedIntegrationEventHandler>(); var app = builder.Build(); -if (app.Environment.IsDevelopment()) -{ - app.UseDeveloperExceptionPage(); -} -else +if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); } + var pathBase = app.Configuration["PATH_BASE"]; if (!string.IsNullOrEmpty(pathBase)) { app.UsePathBase(pathBase); } + app.UseSwagger().UseSwaggerUI(c => { c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Ordering.API V1"); @@ -336,7 +327,6 @@ static class CustomExtensionsMethods public static IServiceCollection AddCustomConfiguration(this IServiceCollection services, IConfiguration configuration) { - services.AddOptions(); services.Configure(configuration); services.Configure(options => { diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs index de689fd33..0be966e96 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs @@ -9,18 +9,14 @@ builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.Environment builder.Configuration.AddEnvironmentVariables(); builder.Services.AddCustomHealthCheck(builder.Configuration) .Configure(builder.Configuration) - .AddOptions() .AddHostedService() .AddEventBus(builder.Configuration); var app = builder.Build(); -if (app.Environment.IsDevelopment()) -{ - app.UseDeveloperExceptionPage(); -} -else +if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); } + app.UseRouting(); app.MapHealthChecks("/hc", new HealthCheckOptions() diff --git a/src/Services/Ordering/Ordering.SignalrHub/Program.cs b/src/Services/Ordering/Ordering.SignalrHub/Program.cs index 718f7760d..96fc26e0b 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Program.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Program.cs @@ -85,19 +85,17 @@ builder.Services.AddSingleton, OrderStatusChangedToSubmittedIntegrationEventHandler>(); var app = builder.Build(); -if (app.Environment.IsDevelopment()) -{ - app.UseDeveloperExceptionPage(); -} -else +if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); } + var pathBase = builder.Configuration["PATH_BASE"]; if (!string.IsNullOrEmpty(pathBase)) { app.UsePathBase(pathBase); } + app.UseRouting(); app.UseCors("CorsPolicy"); app.UseAuthentication(); diff --git a/src/Services/Payment/Payment.API/Program.cs b/src/Services/Payment/Payment.API/Program.cs index 8c95c4b0d..c1d2fe5f1 100644 --- a/src/Services/Payment/Payment.API/Program.cs +++ b/src/Services/Payment/Payment.API/Program.cs @@ -57,19 +57,17 @@ else } RegisterEventBus(builder.Services); var app = builder.Build(); -if (app.Environment.IsDevelopment()) -{ - app.UseDeveloperExceptionPage(); -} -else +if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); } + var pathBase = app.Configuration["PATH_BASE"]; if (!string.IsNullOrEmpty(pathBase)) { app.UsePathBase(pathBase); } + ConfigureEventBus(app); app.UseRouting(); diff --git a/src/Web/WebMVC/Program.cs b/src/Web/WebMVC/Program.cs index 55e7a1027..fff566c19 100644 --- a/src/Web/WebMVC/Program.cs +++ b/src/Web/WebMVC/Program.cs @@ -12,11 +12,7 @@ builder.WebHost.CaptureStartupErrors(false); var app = builder.Build(); JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); -if (app.Environment.IsDevelopment()) -{ - app.UseDeveloperExceptionPage(); -} -else +if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); } @@ -72,8 +68,7 @@ static void AddHealthChecks(WebApplicationBuilder builder) static void AddCustomMvc(WebApplicationBuilder builder) { - builder.Services.AddOptions() - .Configure(builder.Configuration) + builder.Services.Configure(builder.Configuration) .AddSession() .AddDistributedMemoryCache(); diff --git a/src/Web/WebSPA/Program.cs b/src/Web/WebSPA/Program.cs index 52f090b67..145151df7 100644 --- a/src/Web/WebSPA/Program.cs +++ b/src/Web/WebSPA/Program.cs @@ -40,11 +40,6 @@ builder.Logging.AddAzureWebAppDiagnostics(); var app = builder.Build(); -if (app.Environment.IsDevelopment()) -{ - app.UseDeveloperExceptionPage(); -} - // Here we add Angular default Anti-forgery cookie name on first load. https://angular.io/guide/http#security-xsrf-protection // This cookie will be read by Angular app and its value will be sent back to the application as the header configured in .AddAntiforgery() var antiForgery = app.Services.GetRequiredService(); diff --git a/src/Web/WebStatus/Program.cs b/src/Web/WebStatus/Program.cs index 96c91271e..d9eadc5d5 100644 --- a/src/Web/WebStatus/Program.cs +++ b/src/Web/WebStatus/Program.cs @@ -12,7 +12,6 @@ builder.WebHost.CaptureStartupErrors(false); builder.Services.AddApplicationInsightsTelemetry(builder.Configuration); builder.Services.AddApplicationInsightsKubernetesEnricher(); builder.Services.AddMvc(); -builder.Services.AddOptions(); builder.Services.AddHealthChecks() .AddCheck("self", () => HealthCheckResult.Healthy()); builder.Services @@ -21,11 +20,7 @@ builder.Services var app = builder.Build(); -if (app.Environment.IsDevelopment()) -{ - app.UseDeveloperExceptionPage(); -} -else +if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); } diff --git a/src/Web/WebhookClient/Startup.cs b/src/Web/WebhookClient/Startup.cs index af68fa66f..61d91030f 100644 --- a/src/Web/WebhookClient/Startup.cs +++ b/src/Web/WebhookClient/Startup.cs @@ -1,4 +1,4 @@ -namespace WebhookClient; +namespace WebhookClient; public class Startup { @@ -36,15 +36,12 @@ public class Startup app.UsePathBase(pathBase); } - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else + if (!env.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. } + app.Map("/check", capp => { capp.Run(async (context) => @@ -97,7 +94,6 @@ static class ServiceExtensions { public static IServiceCollection AddConfiguration(this IServiceCollection services, IConfiguration configuration) { - services.AddOptions(); services.Configure(configuration); return services; } From 3056418c92829debf836f6e37b2df5b8aa942f60 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 15:32:25 -0700 Subject: [PATCH 047/118] Made a health check api --- src/Services/Basket/Basket.API/Program.cs | 18 +------------- .../Services.Common/CommonExtensions.cs | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index 6d3f85d9b..effabdd01 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -27,23 +27,7 @@ var app = builder.Build(); try { - app.Logger.LogInformation("Running health checks..."); - - // Do a health check on startup, this will throw an exception if any of the checks fail - var report = await app.Services.GetRequiredService().CheckHealthAsync(); - - if (report.Status == HealthStatus.Unhealthy) - { - app.Logger.LogCritical("Health checks failed!"); - foreach (var entry in report.Entries) - { - if (entry.Value.Status == HealthStatus.Unhealthy) - { - app.Logger.LogCritical("{Check}: {Status}", entry.Key, entry.Value.Status); - } - } - return 1; - } + await app.CheckHealthAsync(); app.UseServiceDefaults(); diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index 5a5e52cd7..91ce1af5c 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -66,6 +66,30 @@ public static class CommonExtensions return app; } + public static async Task CheckHealthAsync(this WebApplication app) + { + app.Logger.LogInformation("Running health checks..."); + + // Do a health check on startup, this will throw an exception if any of the checks fail + var report = await app.Services.GetRequiredService().CheckHealthAsync(); + + if (report.Status == HealthStatus.Unhealthy) + { + app.Logger.LogCritical("Health checks failed!"); + foreach (var entry in report.Entries) + { + if (entry.Value.Status == HealthStatus.Unhealthy) + { + app.Logger.LogCritical("{Check}: {Status}", entry.Key, entry.Value.Status); + } + } + + return false; + } + + return true; + } + public static IApplicationBuilder UseDefaultOpenApi(this IApplicationBuilder app, IConfiguration configuration) { var openApiSection = configuration.GetSection("OpenApi"); From a381a6923ccb60c155db8dd4e97d76cbda8860d0 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 15:40:31 -0700 Subject: [PATCH 048/118] Removed filters and special errors handling from MVC --- .../Basket/Basket.API/GlobalUsings.cs | 6 --- .../InternalServerErrorObjectResult.cs | 11 ----- .../Exceptions/BasketDomainException.cs | 16 ------- .../Filters/HttpGlobalExceptionFilter.cs | 47 ------------------- .../Filters/JsonErrorResponse.cs | 9 ---- .../Filters/ValidateModelStateFilter.cs | 26 ---------- src/Services/Basket/Basket.API/Program.cs | 17 ++----- 7 files changed, 4 insertions(+), 128 deletions(-) delete mode 100644 src/Services/Basket/Basket.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs delete mode 100644 src/Services/Basket/Basket.API/Infrastructure/Exceptions/BasketDomainException.cs delete mode 100644 src/Services/Basket/Basket.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs delete mode 100644 src/Services/Basket/Basket.API/Infrastructure/Filters/JsonErrorResponse.cs delete mode 100644 src/Services/Basket/Basket.API/Infrastructure/Filters/ValidateModelStateFilter.cs diff --git a/src/Services/Basket/Basket.API/GlobalUsings.cs b/src/Services/Basket/Basket.API/GlobalUsings.cs index c0c12186a..708cf1207 100644 --- a/src/Services/Basket/Basket.API/GlobalUsings.cs +++ b/src/Services/Basket/Basket.API/GlobalUsings.cs @@ -6,9 +6,6 @@ global using System.Net; global using System.Security.Claims; global using System.Text.Json; global using System.Threading.Tasks; -global using Basket.API.Infrastructure.ActionResults; -global using Basket.API.Infrastructure.Exceptions; -global using Basket.API.Infrastructure.Filters; global using Basket.API.IntegrationEvents.EventHandling; global using Basket.API.IntegrationEvents.Events; global using Basket.API.Model; @@ -16,10 +13,8 @@ global using Grpc.Core; global using GrpcBasket; global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; -global using Microsoft.AspNetCore.Hosting; global using Microsoft.AspNetCore.Http; global using Microsoft.AspNetCore.Mvc; -global using Microsoft.AspNetCore.Mvc.Filters; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; global using Microsoft.eShopOnContainers.Services.Basket.API; @@ -30,7 +25,6 @@ global using Microsoft.eShopOnContainers.Services.Basket.API.Model; global using Microsoft.eShopOnContainers.Services.Basket.API.Services; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; global using Services.Common; global using StackExchange.Redis; diff --git a/src/Services/Basket/Basket.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs b/src/Services/Basket/Basket.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs deleted file mode 100644 index 5f95e586e..000000000 --- a/src/Services/Basket/Basket.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Basket.API.Infrastructure.ActionResults; - -public class InternalServerErrorObjectResult : ObjectResult -{ - public InternalServerErrorObjectResult(object error) - : base(error) - { - StatusCode = StatusCodes.Status500InternalServerError; - } -} - diff --git a/src/Services/Basket/Basket.API/Infrastructure/Exceptions/BasketDomainException.cs b/src/Services/Basket/Basket.API/Infrastructure/Exceptions/BasketDomainException.cs deleted file mode 100644 index 0502b7924..000000000 --- a/src/Services/Basket/Basket.API/Infrastructure/Exceptions/BasketDomainException.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Basket.API.Infrastructure.Exceptions; - -public class BasketDomainException : Exception -{ - public BasketDomainException() - { } - - public BasketDomainException(string message) - : base(message) - { } - - public BasketDomainException(string message, Exception innerException) - : base(message, innerException) - { } -} - diff --git a/src/Services/Basket/Basket.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs b/src/Services/Basket/Basket.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs deleted file mode 100644 index 00b0b5195..000000000 --- a/src/Services/Basket/Basket.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace Basket.API.Infrastructure.Filters; - -public partial class HttpGlobalExceptionFilter : IExceptionFilter -{ - private readonly IWebHostEnvironment env; - private readonly ILogger logger; - - public HttpGlobalExceptionFilter(IWebHostEnvironment env, ILogger logger) - { - this.env = env; - this.logger = logger; - } - - public void OnException(ExceptionContext context) - { - logger.LogError(new EventId(context.Exception.HResult), - context.Exception, - context.Exception.Message); - - if (context.Exception.GetType() == typeof(BasketDomainException)) - { - var json = new JsonErrorResponse - { - Messages = new[] { context.Exception.Message } - }; - - context.Result = new BadRequestObjectResult(json); - context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; - } - else - { - var json = new JsonErrorResponse - { - Messages = new[] { "An error occurred. Try it again." } - }; - - if (env.IsDevelopment()) - { - json.DeveloperMessage = context.Exception; - } - - context.Result = new InternalServerErrorObjectResult(json); - context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError; - } - context.ExceptionHandled = true; - } -} diff --git a/src/Services/Basket/Basket.API/Infrastructure/Filters/JsonErrorResponse.cs b/src/Services/Basket/Basket.API/Infrastructure/Filters/JsonErrorResponse.cs deleted file mode 100644 index 88bc02eda..000000000 --- a/src/Services/Basket/Basket.API/Infrastructure/Filters/JsonErrorResponse.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Basket.API.Infrastructure.Filters; - -public class JsonErrorResponse -{ - public string[] Messages { get; set; } - - public object DeveloperMessage { get; set; } -} - diff --git a/src/Services/Basket/Basket.API/Infrastructure/Filters/ValidateModelStateFilter.cs b/src/Services/Basket/Basket.API/Infrastructure/Filters/ValidateModelStateFilter.cs deleted file mode 100644 index 5c97b85dc..000000000 --- a/src/Services/Basket/Basket.API/Infrastructure/Filters/ValidateModelStateFilter.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Basket.API.Infrastructure.Filters; - -public class ValidateModelStateFilter : ActionFilterAttribute -{ - public override void OnActionExecuting(ActionExecutingContext context) - { - if (context.ModelState.IsValid) - { - return; - } - - var validationErrors = context.ModelState - .Keys - .SelectMany(k => context.ModelState[k].Errors) - .Select(e => e.ErrorMessage) - .ToArray(); - - var json = new JsonErrorResponse - { - Messages = validationErrors - }; - - context.Result = new BadRequestObjectResult(json); - } -} - diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index effabdd01..96773a768 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -1,19 +1,10 @@ -using Microsoft.Extensions.Diagnostics.HealthChecks; - -var builder = WebApplication.CreateBuilder(args); +var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); -builder.Services.AddGrpc(options => -{ - options.EnableDetailedErrors = true; -}); - -builder.Services.AddControllers(options => -{ - options.Filters.Add(typeof(HttpGlobalExceptionFilter)); - options.Filters.Add(typeof(ValidateModelStateFilter)); -}); +builder.Services.AddGrpc(); +builder.Services.AddControllers(); +builder.Services.AddProblemDetails(); builder.Services.AddRedis(builder.Configuration); From 34fc9496fd0ab507fe8e87981f13ba3f17937336 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 15:41:49 -0700 Subject: [PATCH 049/118] Small clean up to error handling code --- src/Services/Basket/Basket.API/Program.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index 96773a768..9c11243e6 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -18,7 +18,10 @@ var app = builder.Build(); try { - await app.CheckHealthAsync(); + if (!await app.CheckHealthAsync()) + { + return 1; + } app.UseServiceDefaults(); From 0fd20ee9625c33bfda8b7f07d110d681844ded60 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 16:06:24 -0700 Subject: [PATCH 050/118] More clean up - Make the catalog API runnable - Delete some cruft --- .../Catalog/Catalog.API/Catalog.API.csproj | 2 +- .../Catalog.API/CustomExtensionMethods.cs | 15 +++-- .../Catalog/Catalog.API/GlobalUsings.cs | 4 -- .../InternalServerErrorObjectResult.cs | 10 ---- .../Filters/HttpGlobalExceptionFilter.cs | 58 ------------------- src/Services/Catalog/Catalog.API/Program.cs | 9 +-- .../Properties/launchSettings.json | 22 +------ .../Properties/serviceDependencies.json | 14 +++++ .../Properties/serviceDependencies.local.json | 23 ++++++++ .../Catalog/Catalog.API/appsettings.json | 11 +--- 10 files changed, 50 insertions(+), 118 deletions(-) delete mode 100644 src/Services/Catalog/Catalog.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs delete mode 100644 src/Services/Catalog/Catalog.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs create mode 100644 src/Services/Catalog/Catalog.API/Properties/serviceDependencies.json create mode 100644 src/Services/Catalog/Catalog.API/Properties/serviceDependencies.local.json diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index 29573e967..3ffc06f01 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -38,7 +38,7 @@ - + diff --git a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs index 4524c150b..962108297 100644 --- a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs +++ b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs @@ -12,7 +12,7 @@ public static class CustomExtensionMethods .AddSqlServer( connectionString, name: "CatalogDB-check", - tags: new string[] { "catalogdb" }); + tags: new string[] { "live", "ready" }); } var accountName = configuration["AzureStorageAccountName"]; @@ -24,7 +24,7 @@ public static class CustomExtensionMethods .AddAzureBlobStorage( $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net", name: "catalog-storage-check", - tags: new string[] { "catalogstorage" }); + tags: new string[] { "live", "ready" }); } return services; @@ -41,13 +41,12 @@ public static class CustomExtensionMethods sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); }; - services.AddEntityFrameworkSqlServer() - .AddDbContext(options => - { - var connectionString = configuration.GetRequiredConnectionString("CatalogDB"); + services.AddDbContext(options => + { + var connectionString = configuration.GetRequiredConnectionString("CatalogDB"); - options.UseSqlServer(connectionString, ConfigureSqlOptions); - }); + options.UseSqlServer(connectionString, ConfigureSqlOptions); + }); services.AddDbContext(options => { diff --git a/src/Services/Catalog/Catalog.API/GlobalUsings.cs b/src/Services/Catalog/Catalog.API/GlobalUsings.cs index fdd190250..bd9e2d862 100644 --- a/src/Services/Catalog/Catalog.API/GlobalUsings.cs +++ b/src/Services/Catalog/Catalog.API/GlobalUsings.cs @@ -14,7 +14,6 @@ global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.Hosting; global using Microsoft.AspNetCore.Http; global using Microsoft.AspNetCore.Mvc; -global using Microsoft.AspNetCore.Mvc.Filters; global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Design; global using Microsoft.EntityFrameworkCore.Metadata.Builders; @@ -27,10 +26,8 @@ global using Microsoft.eShopOnContainers.Services.Catalog.API; global using Microsoft.eShopOnContainers.Services.Catalog.API.Extensions; global using Microsoft.eShopOnContainers.Services.Catalog.API.Grpc; global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; -global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.ActionResults; global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.EntityConfigurations; global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.Exceptions; -global using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.Filters; global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents; global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling; global using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events; @@ -39,7 +36,6 @@ global using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.FileProviders; -global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using Polly; diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs b/src/Services/Catalog/Catalog.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs deleted file mode 100644 index 53af0f0b8..000000000 --- a/src/Services/Catalog/Catalog.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.ActionResults; - -public class InternalServerErrorObjectResult : ObjectResult -{ - public InternalServerErrorObjectResult(object error) - : base(error) - { - StatusCode = StatusCodes.Status500InternalServerError; - } -} diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs b/src/Services/Catalog/Catalog.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs deleted file mode 100644 index 66ee35e7b..000000000 --- a/src/Services/Catalog/Catalog.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.Filters; - -public class HttpGlobalExceptionFilter : IExceptionFilter -{ - private readonly IWebHostEnvironment env; - private readonly ILogger logger; - - public HttpGlobalExceptionFilter(IWebHostEnvironment env, ILogger logger) - { - this.env = env; - this.logger = logger; - } - - public void OnException(ExceptionContext context) - { - logger.LogError(new EventId(context.Exception.HResult), - context.Exception, - context.Exception.Message); - - if (context.Exception.GetType() == typeof(CatalogDomainException)) - { - var problemDetails = new ValidationProblemDetails() - { - Instance = context.HttpContext.Request.Path, - Status = StatusCodes.Status400BadRequest, - Detail = "Please refer to the errors property for additional details." - }; - - problemDetails.Errors.Add("DomainValidations", new string[] { context.Exception.Message.ToString() }); - - context.Result = new BadRequestObjectResult(problemDetails); - context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; - } - else - { - var json = new JsonErrorResponse - { - Messages = new[] { "An error ocurred." } - }; - - if (env.IsDevelopment()) - { - json.DeveloperMessage = context.Exception; - } - - context.Result = new InternalServerErrorObjectResult(json); - context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError; - } - context.ExceptionHandled = true; - } - - private class JsonErrorResponse - { - public string[] Messages { get; set; } - - public object DeveloperMessage { get; set; } - } -} diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index c39d369c8..57e9c929f 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -4,14 +4,10 @@ var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); -builder.Services.AddControllers(options => -{ - options.Filters.Add(typeof(HttpGlobalExceptionFilter)); -}) -.AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true); - builder.Services.AddGrpc(); +builder.Services.AddControllers(); +// Applcation specific services builder.Services.AddDbContexts(builder.Configuration); builder.Services.AddApplicationOptions(builder.Configuration); builder.Services.AddHealthChecks(builder.Configuration); @@ -33,7 +29,6 @@ app.UseFileServer(new FileServerOptions app.MapGet("/", () => Results.Redirect("/swagger")); app.MapControllers(); - app.MapGrpcService(); var eventBus = app.Services.GetRequiredService(); diff --git a/src/Services/Catalog/Catalog.API/Properties/launchSettings.json b/src/Services/Catalog/Catalog.API/Properties/launchSettings.json index a85ce1869..e16d546a4 100644 --- a/src/Services/Catalog/Catalog.API/Properties/launchSettings.json +++ b/src/Services/Catalog/Catalog.API/Properties/launchSettings.json @@ -1,27 +1,9 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:57424/", - "sslPort": 0 - } - }, "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "/swagger", - "environmentVariables": { - "ConnectionString": "server=localhost,5433;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word", - "ASPNETCORE_ENVIRONMENT": "Development", - "EventBusConnection": "localhost" - } - }, - "Microsoft.eShopOnContainers.Services.Catalog.API": { + "Catalog.API": { "commandName": "Project", "launchBrowser": true, - "launchUrl": "http://localhost:55101/", + "applicationUrl": "http://localhost:5226/", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Services/Catalog/Catalog.API/Properties/serviceDependencies.json b/src/Services/Catalog/Catalog.API/Properties/serviceDependencies.json new file mode 100644 index 000000000..62b84ead2 --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Properties/serviceDependencies.json @@ -0,0 +1,14 @@ +{ + "dependencies": { + "rabbitmq1": { + "type": "rabbitmq", + "connectionId": "ConnectionStrings:EventBus", + "dynamicId": null + }, + "mssql1": { + "type": "mssql", + "connectionId": "ConnectionStrings:CatalogDB", + "dynamicId": null + } + } +} \ No newline at end of file diff --git a/src/Services/Catalog/Catalog.API/Properties/serviceDependencies.local.json b/src/Services/Catalog/Catalog.API/Properties/serviceDependencies.local.json new file mode 100644 index 000000000..9dcbd89ce --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Properties/serviceDependencies.local.json @@ -0,0 +1,23 @@ +{ + "dependencies": { + "rabbitmq1": { + "containerPorts": "5672:5672,15672:15672", + "secretStore": "LocalSecretsFile", + "containerName": "rabbitmq", + "containerImage": "rabbitmq:3-management-alpine", + "type": "rabbitmq.container", + "connectionId": "ConnectionStrings:EventBus", + "dynamicId": null + }, + "mssql1": { + "serviceConnectorResourceId": "", + "containerPorts": "1434:1433", + "secretStore": "LocalSecretsFile", + "containerName": "catalog-mssql", + "containerImage": "mcr.microsoft.com/mssql/server:2019-latest", + "type": "mssql.container", + "connectionId": "ConnectionStrings:CatalogDB", + "dynamicId": null + } + } +} \ No newline at end of file diff --git a/src/Services/Catalog/Catalog.API/appsettings.json b/src/Services/Catalog/Catalog.API/appsettings.json index 3711850cc..eb811f017 100644 --- a/src/Services/Catalog/Catalog.API/appsettings.json +++ b/src/Services/Catalog/Catalog.API/appsettings.json @@ -5,20 +5,11 @@ "ApplicationInsights": { "InstrumentationKey": "" }, - "Identity": { - "Url": "http://localhost:5105", - "ExternalUrl": "http://localhost:5105", - "Audience": "catalog", - "Scopes": { - "catalog": "Catalog API" - } - }, "OpenApi": { "Endpoint": { - "Name": "" + "Name": "Catalog.API V1" }, "Document": { - "Name": "Catalog.API V1", "Description": "The Catalog Microservice HTTP API. This is a Data-Driven/CRUD microservice sample", "Title": "eShopOnContainers - Catalog HTTP API", "Version": "v1" From 5397e8d5c8dc9d08880e185e92c948776953d15f Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 16:23:24 -0700 Subject: [PATCH 051/118] Made small tweak to startup --- src/Services/Basket/Basket.API/Program.cs | 32 +++++++------------ src/Services/Catalog/Catalog.API/Program.cs | 7 +++- .../Catalog/Catalog.API/appsettings.json | 20 ++++++++---- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index 9c11243e6..06d354f06 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -16,31 +16,21 @@ builder.Services.AddTransient(); var app = builder.Build(); -try +if (!await app.CheckHealthAsync()) { - if (!await app.CheckHealthAsync()) - { - return 1; - } - - app.UseServiceDefaults(); + return; +} - app.MapGet("/", () => Results.Redirect("/swagger")); +app.UseServiceDefaults(); - app.MapGrpcService(); - app.MapControllers(); +app.MapGet("/", () => Results.Redirect("/swagger")); - var eventBus = app.Services.GetRequiredService(); +app.MapGrpcService(); +app.MapControllers(); - eventBus.Subscribe(); - eventBus.Subscribe(); +var eventBus = app.Services.GetRequiredService(); - await app.RunAsync(); +eventBus.Subscribe(); +eventBus.Subscribe(); - return 0; -} -catch (Exception ex) -{ - app.Logger.LogCritical(ex, "Program terminated unexpectedly"); - return 1; -} +await app.RunAsync(); diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index 57e9c929f..9559e57cb 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -7,7 +7,7 @@ builder.AddServiceDefaults(); builder.Services.AddGrpc(); builder.Services.AddControllers(); -// Applcation specific services +// Application specific services builder.Services.AddDbContexts(builder.Configuration); builder.Services.AddApplicationOptions(builder.Configuration); builder.Services.AddHealthChecks(builder.Configuration); @@ -18,6 +18,11 @@ builder.Services.AddTransient() var app = builder.Build(); +if (!await app.CheckHealthAsync()) +{ + return; +} + app.UseServiceDefaults(); app.UseFileServer(new FileServerOptions diff --git a/src/Services/Catalog/Catalog.API/appsettings.json b/src/Services/Catalog/Catalog.API/appsettings.json index eb811f017..427b0bd95 100644 --- a/src/Services/Catalog/Catalog.API/appsettings.json +++ b/src/Services/Catalog/Catalog.API/appsettings.json @@ -1,9 +1,9 @@ { - "UseCustomizationData": false, - "AzureServiceBusEnabled": false, - "AzureStorageEnabled": false, - "ApplicationInsights": { - "InstrumentationKey": "" + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } }, "OpenApi": { "Endpoint": { @@ -22,6 +22,12 @@ "EventBus": { "SubscriptionClientName": "Catalog", "RetryCount": 5 - } + }, + "ApplicationInsights": { + "InstrumentationKey": "" + }, + "UseCustomizationData": false, + "AzureServiceBusEnabled": false, + "AzureStorageEnabled": false } - + From cf02e90aad5a2d04d238bae6bca5f59ced76404f Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Thu, 4 May 2023 16:18:22 -0700 Subject: [PATCH 052/118] Migrate from ILoggerFactory to ILogger and use Logging Source Generator --- .../Repositories/RedisBasketRepository.cs | 6 +-- .../RedisBasketRepositoryTests.cs | 6 ++- .../OrderCancelledDomainEventHandler.cs | 18 ++++----- .../OrderShippedDomainEventHandler.cs | 16 ++++---- ...dToAwaitingValidationDomainEventHandler.cs | 21 +++++----- ...erStatusChangedToPaidDomainEventHandler.cs | 24 +++++------- ...angedToStockConfirmedDomainEventHandler.cs | 16 ++++---- ...tomerWhenOrderStartedDomainEventHandler.cs | 15 ------- ...PaymentMethodVerifiedDomainEventHandler.cs | 21 +++++----- ...egateWhenOrderStartedDomainEventHandler.cs | 39 ++++++++----------- .../Extensions/OrderingApiTrace.cs | 13 +++++++ .../BuyerAggregate/PaymentMethod.cs | 5 +-- src/Services/Webhooks/Webhooks.API/Startup.cs | 5 +-- src/Web/WebSPA/Program.cs | 5 +-- .../Server/Infrastructure/WebContextSeed.cs | 14 +++---- 15 files changed, 98 insertions(+), 126 deletions(-) delete mode 100644 src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/SendEmailToCustomerWhenOrderStartedDomainEventHandler.cs create mode 100644 src/Services/Ordering/Ordering.API/Extensions/OrderingApiTrace.cs diff --git a/src/Services/Basket/Basket.API/Infrastructure/Repositories/RedisBasketRepository.cs b/src/Services/Basket/Basket.API/Infrastructure/Repositories/RedisBasketRepository.cs index 7db463f20..1834fd2cc 100644 --- a/src/Services/Basket/Basket.API/Infrastructure/Repositories/RedisBasketRepository.cs +++ b/src/Services/Basket/Basket.API/Infrastructure/Repositories/RedisBasketRepository.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Basket.API.Infrastructure.Repositories; +namespace Microsoft.eShopOnContainers.Services.Basket.API.Infrastructure.Repositories; public class RedisBasketRepository : IBasketRepository { @@ -6,9 +6,9 @@ public class RedisBasketRepository : IBasketRepository private readonly ConnectionMultiplexer _redis; private readonly IDatabase _database; - public RedisBasketRepository(ILoggerFactory loggerFactory, ConnectionMultiplexer redis) + public RedisBasketRepository(ILogger logger, ConnectionMultiplexer redis) { - _logger = loggerFactory.CreateLogger(); + _logger = logger; _redis = redis; _database = redis.GetDatabase(); } diff --git a/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs b/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs index 835146c2e..540b01ccd 100644 --- a/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs +++ b/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs @@ -1,5 +1,7 @@  +using Microsoft.Extensions.Logging.Abstractions; + namespace Basket.FunctionalTests { public class RedisBasketRepositoryTests @@ -48,8 +50,8 @@ namespace Basket.FunctionalTests RedisBasketRepository BuildBasketRepository(ConnectionMultiplexer connMux) { - var loggerFactory = new LoggerFactory(); - return new RedisBasketRepository(loggerFactory, connMux); + var logger = NullLoggerFactory.Instance.CreateLogger(); + return new RedisBasketRepository(logger, connMux); } List BuildBasketItems() diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelledDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelledDomainEventHandler.cs index e53a233d9..dc9944c83 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelledDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderCancelledDomainEventHandler.cs @@ -1,16 +1,16 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; -public class OrderCancelledDomainEventHandler +public partial class OrderCancelledDomainEventHandler : INotificationHandler { private readonly IOrderRepository _orderRepository; private readonly IBuyerRepository _buyerRepository; - private readonly ILoggerFactory _logger; + private readonly ILogger _logger; private readonly IOrderingIntegrationEventService _orderingIntegrationEventService; public OrderCancelledDomainEventHandler( IOrderRepository orderRepository, - ILoggerFactory logger, + ILogger logger, IBuyerRepository buyerRepository, IOrderingIntegrationEventService orderingIntegrationEventService) { @@ -20,16 +20,14 @@ public class OrderCancelledDomainEventHandler _orderingIntegrationEventService = orderingIntegrationEventService; } - public async Task Handle(OrderCancelledDomainEvent orderCancelledDomainEvent, CancellationToken cancellationToken) + public async Task Handle(OrderCancelledDomainEvent domainEvent, CancellationToken cancellationToken) { - _logger.CreateLogger() - .LogTrace("Order with Id: {OrderId} has been successfully updated to status {Status} ({Id})", - orderCancelledDomainEvent.Order.Id, nameof(OrderStatus.Cancelled), OrderStatus.Cancelled.Id); + OrderingApiTrace.LogOrderStatusUpdated(_logger, domainEvent.Order.Id, nameof(OrderStatus.Cancelled), OrderStatus.Cancelled.Id); - var order = await _orderRepository.GetAsync(orderCancelledDomainEvent.Order.Id); + var order = await _orderRepository.GetAsync(domainEvent.Order.Id); var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString()); - var orderStatusChangedToCancelledIntegrationEvent = new OrderStatusChangedToCancelledIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name); - await _orderingIntegrationEventService.AddAndSaveEventAsync(orderStatusChangedToCancelledIntegrationEvent); + var integrationEvent = new OrderStatusChangedToCancelledIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name); + await _orderingIntegrationEventService.AddAndSaveEventAsync(integrationEvent); } } diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderShippedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderShippedDomainEventHandler.cs index aba9d8923..3bdb035e7 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderShippedDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderShippedDomainEventHandler.cs @@ -6,11 +6,11 @@ public class OrderShippedDomainEventHandler private readonly IOrderRepository _orderRepository; private readonly IBuyerRepository _buyerRepository; private readonly IOrderingIntegrationEventService _orderingIntegrationEventService; - private readonly ILoggerFactory _logger; + private readonly ILogger _logger; public OrderShippedDomainEventHandler( IOrderRepository orderRepository, - ILoggerFactory logger, + ILogger logger, IBuyerRepository buyerRepository, IOrderingIntegrationEventService orderingIntegrationEventService) { @@ -20,16 +20,14 @@ public class OrderShippedDomainEventHandler _orderingIntegrationEventService = orderingIntegrationEventService; } - public async Task Handle(OrderShippedDomainEvent orderShippedDomainEvent, CancellationToken cancellationToken) + public async Task Handle(OrderShippedDomainEvent domainEvent, CancellationToken cancellationToken) { - _logger.CreateLogger() - .LogTrace("Order with Id: {OrderId} has been successfully updated to status {Status} ({Id})", - orderShippedDomainEvent.Order.Id, nameof(OrderStatus.Shipped), OrderStatus.Shipped.Id); + OrderingApiTrace.LogOrderStatusUpdated(_logger, domainEvent.Order.Id, nameof(OrderStatus.Shipped), OrderStatus.Shipped.Id); - var order = await _orderRepository.GetAsync(orderShippedDomainEvent.Order.Id); + var order = await _orderRepository.GetAsync(domainEvent.Order.Id); var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString()); - var orderStatusChangedToShippedIntegrationEvent = new OrderStatusChangedToShippedIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name); - await _orderingIntegrationEventService.AddAndSaveEventAsync(orderStatusChangedToShippedIntegrationEvent); + var integrationEvent = new OrderStatusChangedToShippedIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name); + await _orderingIntegrationEventService.AddAndSaveEventAsync(integrationEvent); } } diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs index e280d06c3..4b8553f50 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs @@ -4,12 +4,13 @@ public class OrderStatusChangedToAwaitingValidationDomainEventHandler : INotificationHandler { private readonly IOrderRepository _orderRepository; - private readonly ILoggerFactory _logger; + private readonly ILogger _logger; private readonly IBuyerRepository _buyerRepository; private readonly IOrderingIntegrationEventService _orderingIntegrationEventService; public OrderStatusChangedToAwaitingValidationDomainEventHandler( - IOrderRepository orderRepository, ILoggerFactory logger, + IOrderRepository orderRepository, + ILogger logger, IBuyerRepository buyerRepository, IOrderingIntegrationEventService orderingIntegrationEventService) { @@ -19,21 +20,17 @@ public class OrderStatusChangedToAwaitingValidationDomainEventHandler _orderingIntegrationEventService = orderingIntegrationEventService; } - public async Task Handle(OrderStatusChangedToAwaitingValidationDomainEvent orderStatusChangedToAwaitingValidationDomainEvent, CancellationToken cancellationToken) + public async Task Handle(OrderStatusChangedToAwaitingValidationDomainEvent domainEvent, CancellationToken cancellationToken) { - _logger.CreateLogger() - .LogTrace("Order with Id: {OrderId} has been successfully updated to status {Status} ({Id})", - orderStatusChangedToAwaitingValidationDomainEvent.OrderId, nameof(OrderStatus.AwaitingValidation), OrderStatus.AwaitingValidation.Id); - - var order = await _orderRepository.GetAsync(orderStatusChangedToAwaitingValidationDomainEvent.OrderId); + OrderingApiTrace.LogOrderStatusUpdated(_logger, domainEvent.OrderId, nameof(OrderStatus.AwaitingValidation), OrderStatus.AwaitingValidation.Id); + var order = await _orderRepository.GetAsync(domainEvent.OrderId); var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString()); - var orderStockList = orderStatusChangedToAwaitingValidationDomainEvent.OrderItems + var orderStockList = domainEvent.OrderItems .Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits())); - var orderStatusChangedToAwaitingValidationIntegrationEvent = new OrderStatusChangedToAwaitingValidationIntegrationEvent( - order.Id, order.OrderStatus.Name, buyer.Name, orderStockList); - await _orderingIntegrationEventService.AddAndSaveEventAsync(orderStatusChangedToAwaitingValidationIntegrationEvent); + var integrationEvent = new OrderStatusChangedToAwaitingValidationIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name, orderStockList); + await _orderingIntegrationEventService.AddAndSaveEventAsync(integrationEvent); } } diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToPaidDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToPaidDomainEventHandler.cs index e5cc83a75..761313a4d 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToPaidDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToPaidDomainEventHandler.cs @@ -1,17 +1,15 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; -public class OrderStatusChangedToPaidDomainEventHandler - : INotificationHandler +public class OrderStatusChangedToPaidDomainEventHandler : INotificationHandler { private readonly IOrderRepository _orderRepository; - private readonly ILoggerFactory _logger; + private readonly ILogger _logger; private readonly IBuyerRepository _buyerRepository; private readonly IOrderingIntegrationEventService _orderingIntegrationEventService; - public OrderStatusChangedToPaidDomainEventHandler( IOrderRepository orderRepository, - ILoggerFactory logger, + ILogger logger, IBuyerRepository buyerRepository, IOrderingIntegrationEventService orderingIntegrationEventService) { @@ -21,24 +19,22 @@ public class OrderStatusChangedToPaidDomainEventHandler _orderingIntegrationEventService = orderingIntegrationEventService ?? throw new ArgumentNullException(nameof(orderingIntegrationEventService)); } - public async Task Handle(OrderStatusChangedToPaidDomainEvent orderStatusChangedToPaidDomainEvent, CancellationToken cancellationToken) + public async Task Handle(OrderStatusChangedToPaidDomainEvent domainEvent, CancellationToken cancellationToken) { - _logger.CreateLogger() - .LogInformation("Order with Id: {OrderId} has been successfully updated to status {Status} ({Id})", - orderStatusChangedToPaidDomainEvent.OrderId, nameof(OrderStatus.Paid), OrderStatus.Paid.Id); + OrderingApiTrace.LogOrderStatusUpdated(_logger, domainEvent.OrderId, nameof(OrderStatus.Paid), OrderStatus.Paid.Id); - var order = await _orderRepository.GetAsync(orderStatusChangedToPaidDomainEvent.OrderId); + var order = await _orderRepository.GetAsync(domainEvent.OrderId); var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString()); - var orderStockList = orderStatusChangedToPaidDomainEvent.OrderItems + var orderStockList = domainEvent.OrderItems .Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits())); - var orderStatusChangedToPaidIntegrationEvent = new OrderStatusChangedToPaidIntegrationEvent( - orderStatusChangedToPaidDomainEvent.OrderId, + var integrationEvent = new OrderStatusChangedToPaidIntegrationEvent( + domainEvent.OrderId, order.OrderStatus.Name, buyer.Name, orderStockList); - await _orderingIntegrationEventService.AddAndSaveEventAsync(orderStatusChangedToPaidIntegrationEvent); + await _orderingIntegrationEventService.AddAndSaveEventAsync(integrationEvent); } } diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToStockConfirmedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToStockConfirmedDomainEventHandler.cs index 00548c802..26aae4736 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToStockConfirmedDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStatusChangedToStockConfirmedDomainEventHandler.cs @@ -5,13 +5,13 @@ public class OrderStatusChangedToStockConfirmedDomainEventHandler { private readonly IOrderRepository _orderRepository; private readonly IBuyerRepository _buyerRepository; - private readonly ILoggerFactory _logger; + private readonly ILogger _logger; private readonly IOrderingIntegrationEventService _orderingIntegrationEventService; public OrderStatusChangedToStockConfirmedDomainEventHandler( IOrderRepository orderRepository, IBuyerRepository buyerRepository, - ILoggerFactory logger, + ILogger logger, IOrderingIntegrationEventService orderingIntegrationEventService) { _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); @@ -20,16 +20,14 @@ public class OrderStatusChangedToStockConfirmedDomainEventHandler _orderingIntegrationEventService = orderingIntegrationEventService; } - public async Task Handle(OrderStatusChangedToStockConfirmedDomainEvent orderStatusChangedToStockConfirmedDomainEvent, CancellationToken cancellationToken) + public async Task Handle(OrderStatusChangedToStockConfirmedDomainEvent domainEvent, CancellationToken cancellationToken) { - _logger.CreateLogger() - .LogTrace("Order with Id: {OrderId} has been successfully updated to status {Status} ({Id})", - orderStatusChangedToStockConfirmedDomainEvent.OrderId, nameof(OrderStatus.StockConfirmed), OrderStatus.StockConfirmed.Id); + OrderingApiTrace.LogOrderStatusUpdated(_logger, domainEvent.OrderId, nameof(OrderStatus.StockConfirmed), OrderStatus.StockConfirmed.Id); - var order = await _orderRepository.GetAsync(orderStatusChangedToStockConfirmedDomainEvent.OrderId); + var order = await _orderRepository.GetAsync(domainEvent.OrderId); var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString()); - var orderStatusChangedToStockConfirmedIntegrationEvent = new OrderStatusChangedToStockConfirmedIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name); - await _orderingIntegrationEventService.AddAndSaveEventAsync(orderStatusChangedToStockConfirmedIntegrationEvent); + var integrationEvent = new OrderStatusChangedToStockConfirmedIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name); + await _orderingIntegrationEventService.AddAndSaveEventAsync(integrationEvent); } } diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/SendEmailToCustomerWhenOrderStartedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/SendEmailToCustomerWhenOrderStartedDomainEventHandler.cs deleted file mode 100644 index 7350c16cd..000000000 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/SendEmailToCustomerWhenOrderStartedDomainEventHandler.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; - -public class SendEmailToCustomerWhenOrderStartedDomainEventHandler -//: IAsyncNotificationHandler -{ - public SendEmailToCustomerWhenOrderStartedDomainEventHandler() - { - - } - - //public async Task Handle(OrderStartedDomainEvent orderNotification) - //{ - // //TBD - Send email logic - //} -} diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler.cs index 5202bf50f..5c14ac65c 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler.cs @@ -1,13 +1,13 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; -public class UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler - : INotificationHandler +public class UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler : INotificationHandler { private readonly IOrderRepository _orderRepository; - private readonly ILoggerFactory _logger; + private readonly ILogger _logger; public UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler( - IOrderRepository orderRepository, ILoggerFactory logger) + IOrderRepository orderRepository, + ILogger logger) { _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); @@ -16,14 +16,11 @@ public class UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler // Domain Logic comment: // When the Buyer and Buyer's payment method have been created or verified that they existed, // then we can update the original Order with the BuyerId and PaymentId (foreign keys) - public async Task Handle(BuyerAndPaymentMethodVerifiedDomainEvent buyerPaymentMethodVerifiedEvent, CancellationToken cancellationToken) + public async Task Handle(BuyerAndPaymentMethodVerifiedDomainEvent domainEvent, CancellationToken cancellationToken) { - var orderToUpdate = await _orderRepository.GetAsync(buyerPaymentMethodVerifiedEvent.OrderId); - orderToUpdate.SetBuyerId(buyerPaymentMethodVerifiedEvent.Buyer.Id); - orderToUpdate.SetPaymentId(buyerPaymentMethodVerifiedEvent.Payment.Id); - - _logger.CreateLogger() - .LogTrace("Order with Id: {OrderId} has been successfully updated with a payment method {PaymentMethod} ({Id})", - buyerPaymentMethodVerifiedEvent.OrderId, nameof(buyerPaymentMethodVerifiedEvent.Payment), buyerPaymentMethodVerifiedEvent.Payment.Id); + var orderToUpdate = await _orderRepository.GetAsync(domainEvent.OrderId); + orderToUpdate.SetBuyerId(domainEvent.Buyer.Id); + orderToUpdate.SetPaymentId(domainEvent.Payment.Id); + OrderingApiTrace.LogOrderPaymentMethodUpdated(_logger, domainEvent.OrderId, nameof(domainEvent.Payment), domainEvent.Payment.Id); } } diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs index 9940c5114..a613e3794 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler.cs @@ -3,53 +3,48 @@ public class ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler : INotificationHandler { - private readonly ILoggerFactory _logger; + private readonly ILogger _logger; private readonly IBuyerRepository _buyerRepository; - private readonly IIdentityService _identityService; private readonly IOrderingIntegrationEventService _orderingIntegrationEventService; public ValidateOrAddBuyerAggregateWhenOrderStartedDomainEventHandler( - ILoggerFactory logger, + ILogger logger, IBuyerRepository buyerRepository, - IIdentityService identityService, IOrderingIntegrationEventService orderingIntegrationEventService) { _buyerRepository = buyerRepository ?? throw new ArgumentNullException(nameof(buyerRepository)); - _identityService = identityService ?? throw new ArgumentNullException(nameof(identityService)); _orderingIntegrationEventService = orderingIntegrationEventService ?? throw new ArgumentNullException(nameof(orderingIntegrationEventService)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } - public async Task Handle(OrderStartedDomainEvent orderStartedEvent, CancellationToken cancellationToken) + public async Task Handle(OrderStartedDomainEvent domainEvent, CancellationToken cancellationToken) { - var cardTypeId = orderStartedEvent.CardTypeId != 0 ? orderStartedEvent.CardTypeId : 1; - var buyer = await _buyerRepository.FindAsync(orderStartedEvent.UserId); - var buyerOriginallyExisted = buyer == null ? false : true; + var cardTypeId = domainEvent.CardTypeId != 0 ? domainEvent.CardTypeId : 1; + var buyer = await _buyerRepository.FindAsync(domainEvent.UserId); + var buyerExisted = buyer is not null; - if (!buyerOriginallyExisted) + if (!buyerExisted) { - buyer = new Buyer(orderStartedEvent.UserId, orderStartedEvent.UserName); + buyer = new Buyer(domainEvent.UserId, domainEvent.UserName); } buyer.VerifyOrAddPaymentMethod(cardTypeId, $"Payment Method on {DateTime.UtcNow}", - orderStartedEvent.CardNumber, - orderStartedEvent.CardSecurityNumber, - orderStartedEvent.CardHolderName, - orderStartedEvent.CardExpiration, - orderStartedEvent.Order.Id); + domainEvent.CardNumber, + domainEvent.CardSecurityNumber, + domainEvent.CardHolderName, + domainEvent.CardExpiration, + domainEvent.Order.Id); - var buyerUpdated = buyerOriginallyExisted ? + var buyerUpdated = buyerExisted ? _buyerRepository.Update(buyer) : _buyerRepository.Add(buyer); await _buyerRepository.UnitOfWork .SaveEntitiesAsync(cancellationToken); - var orderStatusChangedToSubmittedIntegrationEvent = new OrderStatusChangedToSubmittedIntegrationEvent(orderStartedEvent.Order.Id, orderStartedEvent.Order.OrderStatus.Name, buyer.Name); - await _orderingIntegrationEventService.AddAndSaveEventAsync(orderStatusChangedToSubmittedIntegrationEvent); - _logger.CreateLogger() - .LogTrace("Buyer {BuyerId} and related payment method were validated or updated for orderId: {OrderId}.", - buyerUpdated.Id, orderStartedEvent.Order.Id); + var integrationEvent = new OrderStatusChangedToSubmittedIntegrationEvent(domainEvent.Order.Id, domainEvent.Order.OrderStatus.Name, buyer.Name); + await _orderingIntegrationEventService.AddAndSaveEventAsync(integrationEvent); + OrderingApiTrace.LogOrderBuyerAndPaymentValidatedOrUpdated(_logger, buyerUpdated.Id, domainEvent.Order.Id); } } diff --git a/src/Services/Ordering/Ordering.API/Extensions/OrderingApiTrace.cs b/src/Services/Ordering/Ordering.API/Extensions/OrderingApiTrace.cs new file mode 100644 index 000000000..dfd2a78e5 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Extensions/OrderingApiTrace.cs @@ -0,0 +1,13 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; + +internal static partial class OrderingApiTrace +{ + [LoggerMessage(EventId = 1, EventName = "OrderStatusUpdated", Level = LogLevel.Trace, Message = "Order with Id: {OrderId} has been successfully updated to status {Status} ({Id})")] + public static partial void LogOrderStatusUpdated(ILogger logger, int orderId, string status, int id); + + [LoggerMessage(EventId = 2, EventName = "PaymentMethodUpdated", Level = LogLevel.Trace, Message = "Order with Id: {OrderId} has been successfully updated with a payment method {PaymentMethod} ({Id})")] + public static partial void LogOrderPaymentMethodUpdated(ILogger logger, int orderId, string paymentMethod, int id); + + [LoggerMessage(EventId = 3, EventName = "BuyerAndPaymentValidatedOrUpdated", Level = LogLevel.Trace, Message = "Buyer {BuyerId} and related payment method were validated or updated for order Id: {OrderId}.")] + public static partial void LogOrderBuyerAndPaymentValidatedOrUpdated(ILogger logger, int buyerId, int orderId); +} diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/PaymentMethod.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/PaymentMethod.cs index e4e490488..2a95e98b9 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/PaymentMethod.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/PaymentMethod.cs @@ -1,7 +1,6 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; -public class PaymentMethod - : Entity +public class PaymentMethod : Entity { private string _alias; private string _cardNumber; @@ -12,12 +11,10 @@ public class PaymentMethod private int _cardTypeId; public CardType CardType { get; private set; } - protected PaymentMethod() { } public PaymentMethod(int cardTypeId, string alias, string cardNumber, string securityNumber, string cardHolderName, DateTime expiration) { - _cardNumber = !string.IsNullOrWhiteSpace(cardNumber) ? cardNumber : throw new OrderingDomainException(nameof(cardNumber)); _securityNumber = !string.IsNullOrWhiteSpace(securityNumber) ? securityNumber : throw new OrderingDomainException(nameof(securityNumber)); _cardHolderName = !string.IsNullOrWhiteSpace(cardHolderName) ? cardHolderName : throw new OrderingDomainException(nameof(cardHolderName)); diff --git a/src/Services/Webhooks/Webhooks.API/Startup.cs b/src/Services/Webhooks/Webhooks.API/Startup.cs index 32153a5cf..c79ea4b2e 100644 --- a/src/Services/Webhooks/Webhooks.API/Startup.cs +++ b/src/Services/Webhooks/Webhooks.API/Startup.cs @@ -8,7 +8,6 @@ public class Startup Configuration = configuration; } - public IServiceProvider ConfigureServices(IServiceCollection services) { services @@ -29,13 +28,13 @@ public class Startup return services.BuildServiceProvider(); } - public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app, ILogger logger) { var pathBase = Configuration["PATH_BASE"]; if (!string.IsNullOrEmpty(pathBase)) { - loggerFactory.CreateLogger("init").LogDebug("Using PATH BASE '{PathBase}'", pathBase); + logger.LogDebug("Using PATH BASE '{PathBase}'", pathBase); app.UsePathBase(pathBase); } diff --git a/src/Web/WebSPA/Program.cs b/src/Web/WebSPA/Program.cs index 145151df7..82cf6feed 100644 --- a/src/Web/WebSPA/Program.cs +++ b/src/Web/WebSPA/Program.cs @@ -61,14 +61,13 @@ app.Use(next => context => }); // Seed Data -var loggerFactory = app.Services.GetRequiredService(); -WebContextSeed.Seed(app, app.Environment, loggerFactory); +WebContextSeed.Seed(app, app.Environment, app.Services.GetRequiredService>()); var pathBase = app.Configuration["PATH_BASE"]; if (!string.IsNullOrEmpty(pathBase)) { - loggerFactory.CreateLogger().LogDebug("Using PATH_BASE '{PathBase}'", pathBase); + app.Services.GetRequiredService>().LogDebug("Using PATH_BASE '{PathBase}'", pathBase); app.UsePathBase(pathBase); } diff --git a/src/Web/WebSPA/Server/Infrastructure/WebContextSeed.cs b/src/Web/WebSPA/Server/Infrastructure/WebContextSeed.cs index 483d3f9ce..1dc07b4f6 100644 --- a/src/Web/WebSPA/Server/Infrastructure/WebContextSeed.cs +++ b/src/Web/WebSPA/Server/Infrastructure/WebContextSeed.cs @@ -4,10 +4,8 @@ using Microsoft.Extensions.Logging; public class WebContextSeed { - public static void Seed(IApplicationBuilder applicationBuilder, IWebHostEnvironment env, ILoggerFactory loggerFactory) + public static void Seed(IApplicationBuilder applicationBuilder, IWebHostEnvironment env, ILogger logger) { - var log = loggerFactory.CreateLogger(); - var settings = applicationBuilder .ApplicationServices.GetRequiredService>().Value; @@ -17,18 +15,18 @@ public class WebContextSeed if (useCustomizationData) { - GetPreconfiguredImages(contentRootPath, webroot, log); + GetPreconfiguredImages(contentRootPath, webroot, logger); } } - static void GetPreconfiguredImages(string contentRootPath, string webroot, ILogger log) + static void GetPreconfiguredImages(string contentRootPath, string webroot, ILogger logger) { try { string imagesZipFile = Path.Combine(contentRootPath, "Setup", "images.zip"); if (!File.Exists(imagesZipFile)) { - log.LogError("Zip file '{ZipFileName}' does not exists.", imagesZipFile); + logger.LogError("Zip file '{ZipFileName}' does not exists.", imagesZipFile); return; } @@ -53,13 +51,13 @@ public class WebContextSeed } else { - log.LogWarning("Skipped file '{FileName}' in zipfile '{ZipFileName}'", entry.Name, imagesZipFile); + logger.LogWarning("Skipped file '{FileName}' in zipfile '{ZipFileName}'", entry.Name, imagesZipFile); } } } catch (Exception ex) { - log.LogError(ex, "ERROR in GetPreconfiguredImages: {Message}", ex.Message); + logger.LogError(ex, "ERROR in GetPreconfiguredImages: {Message}", ex.Message); } } } From ccaad9dc204d12d2da13a5c06c9eeed13d8003b2 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 17:35:22 -0700 Subject: [PATCH 053/118] Removed unneeded project deps --- .../Catalog/Catalog.API/Catalog.API.csproj | 29 ++----------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index 3ffc06f01..42fb57023 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -2,14 +2,10 @@ net7.0 - portable - true Catalog.API Catalog.API aspnet-Catalog.API-20161122013618 ..\..\..\..\docker-compose.dcproj - false - true @@ -32,9 +28,7 @@ - - - + @@ -42,27 +36,11 @@ - - - - - - - - - - - - - - + - - - @@ -72,9 +50,6 @@ - - - From 7681405eaff6342c92c39d6db7137e01f2afd72b Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 17:39:11 -0700 Subject: [PATCH 054/118] More clean up --- .../Catalog/Catalog.API/Catalog.API.csproj | 3 --- src/Services/Catalog/Catalog.API/web.config | 16 ---------------- 2 files changed, 19 deletions(-) delete mode 100644 src/Services/Catalog/Catalog.API/web.config diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index 42fb57023..9c96ff461 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -22,9 +22,6 @@ PreserveNewest - - PreserveNewest - diff --git a/src/Services/Catalog/Catalog.API/web.config b/src/Services/Catalog/Catalog.API/web.config deleted file mode 100644 index 3bc0d036f..000000000 --- a/src/Services/Catalog/Catalog.API/web.config +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file From 08e7c3424d0d09cf72a1e7ab1e547d8b3d0d3a66 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 21:42:29 -0700 Subject: [PATCH 055/118] Delete more cruft - Remove migration from the tests --- .../Catalog.API/CustomExtensionMethods.cs | 12 ++-- .../Extensions/WebHostExtensions.cs | 68 ------------------- src/Services/Catalog/Catalog.API/Program.cs | 1 + .../Catalog/Catalog.API/appsettings.json | 3 +- .../CatalogScenarioBase.cs | 20 +----- .../Catalog.FunctionalTests/appsettings.json | 8 +-- 6 files changed, 8 insertions(+), 104 deletions(-) delete mode 100644 src/Services/Catalog/Catalog.API/Extensions/WebHostExtensions.cs diff --git a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs index 962108297..7779d791d 100644 --- a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs +++ b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs @@ -6,14 +6,10 @@ public static class CustomExtensionMethods { var hcBuilder = services.AddHealthChecks(); - if (configuration.GetConnectionString("CatalogDB") is string connectionString) - { - hcBuilder - .AddSqlServer( - connectionString, - name: "CatalogDB-check", - tags: new string[] { "live", "ready" }); - } + hcBuilder + .AddSqlServer(_ => configuration.GetConnectionString("CatalogDB"), + name: "CatalogDB-check", + tags: new string[] { "live", "ready" }); var accountName = configuration["AzureStorageAccountName"]; var accountKey = configuration["AzureStorageAccountKey"]; diff --git a/src/Services/Catalog/Catalog.API/Extensions/WebHostExtensions.cs b/src/Services/Catalog/Catalog.API/Extensions/WebHostExtensions.cs deleted file mode 100644 index d4a452aed..000000000 --- a/src/Services/Catalog/Catalog.API/Extensions/WebHostExtensions.cs +++ /dev/null @@ -1,68 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Catalog.API.Extensions; - -public static class WebHostExtensions -{ - public static bool IsInKubernetes(this IServiceProvider services) - { - var cfg = services.GetService(); - var orchestratorType = cfg.GetValue("OrchestratorType"); - return orchestratorType?.ToUpper() == "K8S"; - } - - public static IServiceProvider MigrateDbContext(this IServiceProvider services, Action seeder) where TContext : DbContext - { - var underK8s = services.IsInKubernetes(); - - using var scope = services.CreateScope(); - var scopedServices = scope.ServiceProvider; - - var logger = scopedServices.GetRequiredService>(); - - var context = scopedServices.GetService(); - - try - { - logger.LogInformation("Migrating database associated with context {DbContextName}", typeof(TContext).Name); - - if (underK8s) - { - InvokeSeeder(seeder, context, scopedServices); - } - else - { - var retry = Policy.Handle() - .WaitAndRetry(new TimeSpan[] - { - TimeSpan.FromSeconds(3), - TimeSpan.FromSeconds(5), - TimeSpan.FromSeconds(8), - }); - - //if the sql server container is not created on run docker compose this - //migration can't fail for network related exception. The retry options for DbContext only - //apply to transient exceptions - // Note that this is NOT applied when running some orchestrators (let the orchestrator to recreate the failing service) - retry.Execute(() => InvokeSeeder(seeder, context, scopedServices)); - } - - logger.LogInformation("Migrated database associated with context {DbContextName}", typeof(TContext).Name); - } - catch (Exception ex) - { - logger.LogError(ex, "An error occurred while migrating the database used on context {DbContextName}", typeof(TContext).Name); - if (underK8s) - { - throw; // Rethrow under k8s because we rely on k8s to re-run the pod - } - } - - return services; - } - - private static void InvokeSeeder(Action seeder, TContext context, IServiceProvider services) - where TContext : DbContext - { - context.Database.Migrate(); - seeder(context, services); - } -} diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index 9559e57cb..f15724b83 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -41,6 +41,7 @@ var eventBus = app.Services.GetRequiredService(); eventBus.Subscribe(); eventBus.Subscribe(); +// REVIEW: This is done fore development east but shouldn't be here in production using (var scope = app.Services.CreateScope()) { var context = scope.ServiceProvider.GetRequiredService(); diff --git a/src/Services/Catalog/Catalog.API/appsettings.json b/src/Services/Catalog/Catalog.API/appsettings.json index 427b0bd95..937a2a3a8 100644 --- a/src/Services/Catalog/Catalog.API/appsettings.json +++ b/src/Services/Catalog/Catalog.API/appsettings.json @@ -16,8 +16,7 @@ } }, "ConnectionStrings": { - "EventBus": "localhost", - "CatalogDB": "" + "EventBus": "localhost" }, "EventBus": { "SubscriptionClientName": "Catalog", diff --git a/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs b/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs index c8bd8806b..63324cc2f 100644 --- a/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs +++ b/src/Services/Catalog/Catalog.FunctionalTests/CatalogScenarioBase.cs @@ -7,29 +7,11 @@ public class CatalogScenariosBase public TestServer CreateServer() { var factory = new CatalogApplication(); - return factory.CreateServer(); + return factory.Server; } private class CatalogApplication : WebApplicationFactory { - public TestServer CreateServer() - { - Services - .MigrateDbContext((context, services) => - { - var env = services.GetService(); - var settings = services.GetService>(); - var logger = services.GetService>(); - - new CatalogContextSeed() - .SeedAsync(context, env, settings, logger) - .Wait(); - }) - .MigrateDbContext((_, __) => { }); - - return Server; - } - protected override IHost CreateHost(IHostBuilder builder) { builder.ConfigureAppConfiguration(c => diff --git a/src/Services/Catalog/Catalog.FunctionalTests/appsettings.json b/src/Services/Catalog/Catalog.FunctionalTests/appsettings.json index 65abc02e2..2489ef0a1 100644 --- a/src/Services/Catalog/Catalog.FunctionalTests/appsettings.json +++ b/src/Services/Catalog/Catalog.FunctionalTests/appsettings.json @@ -1,10 +1,5 @@ { "ExternalCatalogBaseUrl": "http://localhost:5101", - "Identity": { - "Url": "http://localhost:5105", - "ExternalUrl": "http://localhost:5105", - "Audience": "catalog" - }, "isTest": "true", "PicBaseUrl": "http://localhost:5101/api/v1/catalog/items/[0]/pic/", @@ -13,7 +8,6 @@ }, "EventBus": { - "SubscriptionClientName": "Catalog", - "ConnectionString": "localhost" + "SubscriptionClientName": "Catalog" } } From a41560544c73d6e6cb1afcb4b10cff33f749c64c Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 21:56:26 -0700 Subject: [PATCH 056/118] Split redis and health checks for redis --- .../Basket/Basket.API/CustomExtensionMethods.cs | 13 +++++++------ src/Services/Basket/Basket.API/Program.cs | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs index d92432521..7d28de8f9 100644 --- a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs +++ b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs @@ -2,15 +2,16 @@ public static class CustomExtensionMethods { - public static IServiceCollection AddRedis(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) { services.AddHealthChecks() - .AddRedis(_ => - { - return configuration.GetConnectionString("redis"); - }, - "redis", tags: new[] { "ready", "liveness" }); + .AddRedis(_ => configuration.GetConnectionString("redis"), "redis", tags: new[] { "ready", "liveness" }); + + return services; + } + public static IServiceCollection AddRedis(this IServiceCollection services, IConfiguration configuration) + { return services.AddSingleton(sp => { var redisConfig = ConfigurationOptions.Parse(configuration.GetConnectionString("redis"), true); diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index 06d354f06..907f42b88 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -6,6 +6,7 @@ builder.Services.AddGrpc(); builder.Services.AddControllers(); builder.Services.AddProblemDetails(); +builder.Services.AddHealthChecks(builder.Configuration); builder.Services.AddRedis(builder.Configuration); builder.Services.AddTransient(); From 909f08675b8d63195f59a8763e0469f46a7ca42f Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 22:45:35 -0700 Subject: [PATCH 057/118] Make the ordering API use the commmon services --- .../Controllers/HomeController.cs | 10 - .../Ordering.API/CustomExtensionsMethods.cs | 79 ++++ .../Ordering/Ordering.API/GlobalUsings.cs | 58 +-- .../InternalServerErrorObjectResult.cs | 10 - ...orizationHeaderParameterOperationFilter.cs | 27 -- .../Filters/AuthorizeCheckOperationFilter.cs | 29 -- .../Filters/HttpGlobalExceptionFilter.cs | 60 --- .../Ordering/Ordering.API/Ordering.API.csproj | 6 +- src/Services/Ordering/Ordering.API/Program.cs | 387 ++---------------- .../Properties/launchSettings.json | 20 +- .../Ordering/Ordering.API/appsettings.json | 53 ++- src/Services/Ordering/Ordering.API/web.config | 14 - .../OrderingScenarioBase.cs | 12 - .../OrderingScenarios.cs | 1 + .../Ordering.FunctionalTests/appsettings.json | 5 +- 15 files changed, 168 insertions(+), 603 deletions(-) delete mode 100644 src/Services/Ordering/Ordering.API/Controllers/HomeController.cs create mode 100644 src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs delete mode 100644 src/Services/Ordering/Ordering.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs delete mode 100644 src/Services/Ordering/Ordering.API/Infrastructure/Auth/AuthorizationHeaderParameterOperationFilter.cs delete mode 100644 src/Services/Ordering/Ordering.API/Infrastructure/Filters/AuthorizeCheckOperationFilter.cs delete mode 100644 src/Services/Ordering/Ordering.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs delete mode 100644 src/Services/Ordering/Ordering.API/web.config diff --git a/src/Services/Ordering/Ordering.API/Controllers/HomeController.cs b/src/Services/Ordering/Ordering.API/Controllers/HomeController.cs deleted file mode 100644 index 601b7ab6d..000000000 --- a/src/Services/Ordering/Ordering.API/Controllers/HomeController.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers; - -public class HomeController : Controller -{ - // GET: // - public IActionResult Index() - { - return new RedirectResult("~/swagger"); - } -} diff --git a/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs b/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs new file mode 100644 index 000000000..d0849b832 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs @@ -0,0 +1,79 @@ +using Microsoft.EntityFrameworkCore.Infrastructure; + +static class CustomExtensionsMethods +{ + public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) + { + var hcBuilder = services.AddHealthChecks(); + + hcBuilder + .AddSqlServer(_ => + configuration.GetRequiredConnectionString("OrderingDB"), + name: "OrderingDB-check", + tags: new string[] { "live", "ready" }); + + return services; + } + + public static IServiceCollection AddDbContexts(this IServiceCollection services, IConfiguration configuration) + { + static void ConfigureSqlOptions(SqlServerDbContextOptionsBuilder sqlOptions) + { + sqlOptions.MigrationsAssembly(typeof(Program).Assembly.FullName); + + // Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency + + sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); + }; + + services.AddDbContext(options => + { + options.UseSqlServer(configuration.GetRequiredConnectionString("OrderingDB"), ConfigureSqlOptions); + }); + + services.AddDbContext(options => + { + options.UseSqlServer(configuration.GetRequiredConnectionString("OrderingDB"), ConfigureSqlOptions); + }); + + return services; + } + + public static IServiceCollection AddCustomIntegrations(this IServiceCollection services, IConfiguration configuration) + { + services.AddTransient(); + services.AddTransient>( + sp => (DbConnection c) => new IntegrationEventLogService(c)); + + services.AddTransient(); + + return services; + } + + public static IServiceCollection AddCustomConfiguration(this IServiceCollection services, IConfiguration configuration) + { + services.Configure(configuration); + services.Configure(options => + { + options.InvalidModelStateResponseFactory = context => + { + var problemDetails = new ValidationProblemDetails(context.ModelState) + { + Instance = context.HttpContext.Request.Path, + Status = StatusCodes.Status400BadRequest, + Detail = "Please refer to the errors property for additional details." + }; + + return new BadRequestObjectResult(problemDetails) + { + ContentTypes = { "application/problem+json", "application/problem+xml" } + }; + }; + }); + + return services; + } + + private static string GetRequiredConnectionString(this IConfiguration configuration, string name) => + configuration.GetConnectionString(name) ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":ConnectionStrings:" + name : "ConnectionStrings:" + name)}"); +} diff --git a/src/Services/Ordering/Ordering.API/GlobalUsings.cs b/src/Services/Ordering/Ordering.API/GlobalUsings.cs index e52b97941..be14d664d 100644 --- a/src/Services/Ordering/Ordering.API/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.API/GlobalUsings.cs @@ -1,77 +1,57 @@ -global using ApiModels = Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models; -global using AppCommand = Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; -global using Azure.Core; +global using System; +global using System.Collections.Generic; +global using System.Data.Common; +global using System.Data.SqlClient; +global using System.IO; +global using System.Linq; +global using System.Net; +global using System.Runtime.Serialization; +global using System.Threading; +global using System.Threading.Tasks; global using Azure.Identity; global using Dapper; global using FluentValidation; global using Google.Protobuf.Collections; global using Grpc.Core; -global using HealthChecks.UI.Client; global using MediatR; global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; -global using Microsoft.AspNetCore.Diagnostics.HealthChecks; global using Microsoft.AspNetCore.Hosting; global using Microsoft.AspNetCore.Http; -global using Microsoft.AspNetCore.Mvc.Authorization; -global using Microsoft.AspNetCore.Mvc.Filters; global using Microsoft.AspNetCore.Mvc; -global using Microsoft.AspNetCore.Server.Kestrel.Core; -global using Microsoft.AspNetCore; -global using Microsoft.EntityFrameworkCore.Design; global using Microsoft.EntityFrameworkCore; +global using Microsoft.EntityFrameworkCore.Design; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Extensions; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; -global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; +global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; +global using Microsoft.eShopOnContainers.Services.Ordering.API; global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Behaviors; global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; -global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers; global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents; -global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events; global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.EventHandling; +global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events; global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models; global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries; global using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Validations; -global using Microsoft.eShopOnContainers.Services.Ordering.API.Controllers; global using Microsoft.eShopOnContainers.Services.Ordering.API.Extensions; -global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.ActionResults; -global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Filters; -global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services; global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure; -global using Microsoft.eShopOnContainers.Services.Ordering.API; +global using Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Services; global using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; global using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; global using Microsoft.eShopOnContainers.Services.Ordering.Domain.Events; global using Microsoft.eShopOnContainers.Services.Ordering.Domain.Exceptions; global using Microsoft.eShopOnContainers.Services.Ordering.Domain.SeedWork; +global using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; global using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency; global using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositories; -global using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Diagnostics.HealthChecks; -global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; -global using Microsoft.OpenApi.Models; -global using Polly.Retry; global using Polly; -global using RabbitMQ.Client; +global using Polly.Retry; global using Swashbuckle.AspNetCore.SwaggerGen; -global using System.Collections.Generic; -global using System.Data.Common; -global using System.Data.SqlClient; -global using System.IdentityModel.Tokens.Jwt; -global using System.IO; -global using System.Linq; -global using System.Net; -global using System.Reflection; -global using System.Runtime.Serialization; -global using System.Threading.Tasks; -global using System.Threading; -global using System; +global using AppCommand = Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; +global using ApiModels = Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models; diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs b/src/Services/Ordering/Ordering.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs deleted file mode 100644 index d886bf371..000000000 --- a/src/Services/Ordering/Ordering.API/Infrastructure/ActionResults/InternalServerErrorObjectResult.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.ActionResults; - -public class InternalServerErrorObjectResult : ObjectResult -{ - public InternalServerErrorObjectResult(object error) - : base(error) - { - StatusCode = StatusCodes.Status500InternalServerError; - } -} diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Auth/AuthorizationHeaderParameterOperationFilter.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Auth/AuthorizationHeaderParameterOperationFilter.cs deleted file mode 100644 index dbf8cf97c..000000000 --- a/src/Services/Ordering/Ordering.API/Infrastructure/Auth/AuthorizationHeaderParameterOperationFilter.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Auth; - -public class AuthorizationHeaderParameterOperationFilter : IOperationFilter -{ - public void Apply(OpenApiOperation operation, OperationFilterContext context) - { - var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors; - var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter); - var allowAnonymous = filterPipeline.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter); - - if (isAuthorized && !allowAnonymous) - { - if (operation.Parameters == null) - operation.Parameters = new List(); - - - operation.Parameters.Add(new OpenApiParameter - { - Name = "Authorization", - In = ParameterLocation.Header, - Description = "access token", - Required = true - }); - } - } - -} diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Filters/AuthorizeCheckOperationFilter.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Filters/AuthorizeCheckOperationFilter.cs deleted file mode 100644 index b4689bf9a..000000000 --- a/src/Services/Ordering/Ordering.API/Infrastructure/Filters/AuthorizeCheckOperationFilter.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Filters; - -public class AuthorizeCheckOperationFilter : IOperationFilter -{ - public void Apply(OpenApiOperation operation, OperationFilterContext context) - { - // Check for authorize attribute - var hasAuthorize = context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType().Any() || - context.MethodInfo.GetCustomAttributes(true).OfType().Any(); - - if (!hasAuthorize) return; - - operation.Responses.TryAdd("401", new OpenApiResponse { Description = "Unauthorized" }); - operation.Responses.TryAdd("403", new OpenApiResponse { Description = "Forbidden" }); - - var oAuthScheme = new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" } - }; - - operation.Security = new List - { - new() - { - [ oAuthScheme ] = new [] { "orderingapi" } - } - }; - } -} diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs b/src/Services/Ordering/Ordering.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs deleted file mode 100644 index eef48c502..000000000 --- a/src/Services/Ordering/Ordering.API/Infrastructure/Filters/HttpGlobalExceptionFilter.cs +++ /dev/null @@ -1,60 +0,0 @@ -namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.Filters; - -public class HttpGlobalExceptionFilter : IExceptionFilter -{ - private readonly IWebHostEnvironment env; - private readonly ILogger logger; - - public HttpGlobalExceptionFilter(IWebHostEnvironment env, ILogger logger) - { - this.env = env; - this.logger = logger; - } - - public void OnException(ExceptionContext context) - { - logger.LogError(new EventId(context.Exception.HResult), - context.Exception, - context.Exception.Message); - - if (context.Exception.GetType() == typeof(OrderingDomainException)) - { - var problemDetails = new ValidationProblemDetails() - { - Instance = context.HttpContext.Request.Path, - Status = StatusCodes.Status400BadRequest, - Detail = "Please refer to the errors property for additional details." - }; - - problemDetails.Errors.Add("DomainValidations", new string[] { context.Exception.Message.ToString() }); - - context.Result = new BadRequestObjectResult(problemDetails); - context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; - } - else - { - var json = new JsonErrorResponse - { - Messages = new[] { "An error occur.Try it again." } - }; - - if (env.IsDevelopment()) - { - json.DeveloperMessage = context.Exception; - } - - // Result asigned to a result object but in destiny the response is empty. This is a known bug of .net core 1.1 - // It will be fixed in .net core 1.1.2. See https://github.com/aspnet/Mvc/issues/5594 for more information - context.Result = new InternalServerErrorObjectResult(json); - context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError; - } - context.ExceptionHandled = true; - } - - private class JsonErrorResponse - { - public string[] Messages { get; set; } - - public object DeveloperMessage { get; set; } - } -} diff --git a/src/Services/Ordering/Ordering.API/Ordering.API.csproj b/src/Services/Ordering/Ordering.API/Ordering.API.csproj index a3abadcab..dc8bf637b 100644 --- a/src/Services/Ordering/Ordering.API/Ordering.API.csproj +++ b/src/Services/Ordering/Ordering.API/Ordering.API.csproj @@ -11,9 +11,6 @@ - - PreserveNewest - PreserveNewest @@ -34,7 +31,8 @@ - + + diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index 71b202f6a..862914e08 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -1,49 +1,23 @@ -var builder = WebApplication.CreateBuilder(args); +using Services.Common; -if (builder.Configuration.GetValue("UseVault", false)) -{ - TokenCredential credential = new ClientSecretCredential( - builder.Configuration["Vault:TenantId"], - builder.Configuration["Vault:ClientId"], - builder.Configuration["Vault:ClientSecret"]); - builder.Configuration.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential); -} +var builder = WebApplication.CreateBuilder(args); -builder.WebHost.ConfigureKestrel(options => -{ - var httpPort = builder.Configuration.GetValue("PORT", 80); - options.Listen(IPAddress.Any, httpPort, listenOptions => - { - listenOptions.Protocols = HttpProtocols.Http1AndHttp2; - }); +builder.AddServiceDefaults(); - var grpcPort = builder.Configuration.GetValue("GRPC_PORT", 5001); - options.Listen(IPAddress.Any, grpcPort, listenOptions => - { - listenOptions.Protocols = HttpProtocols.Http2; - }); -}); +builder.Services.AddGrpc(); +builder.Services.AddControllers(); -builder.Services.AddGrpc(options => options.EnableDetailedErrors = true); -builder.Services.AddApplicationInsightsTelemetry(builder.Configuration); -builder.Services.AddApplicationInsightsKubernetesEnricher(); -builder.Services - .AddCustomMvc() - .AddHealthChecks(builder.Configuration) - .AddCustomDbContext(builder.Configuration) - .AddCustomSwagger(builder.Configuration) - .AddCustomAuthentication(builder.Configuration) - .AddCustomAuthorization(builder.Configuration) - .AddCustomIntegrations(builder.Configuration) - .AddCustomConfiguration(builder.Configuration) - .AddEventBus(builder.Configuration); +builder.Services.AddHealthChecks(builder.Configuration); +builder.Services.AddDbContexts(builder.Configuration); +builder.Services.AddCustomIntegrations(builder.Configuration); +builder.Services.AddCustomConfiguration(builder.Configuration); var services = builder.Services; services.AddMediatR(cfg => { cfg.RegisterServicesFromAssemblyContaining(typeof(Program)); - + cfg.AddOpenBehavior(typeof(LoggingBehavior<,>)); cfg.AddOpenBehavior(typeof(ValidatorBehavior<,>)); cfg.AddOpenBehavior(typeof(TransactionBehavior<,>)); @@ -55,9 +29,7 @@ services.AddSingleton, CreateOrderCommandValidato services.AddSingleton>, IdentifiedCommandValidator>(); services.AddSingleton, ShipOrderCommandValidator>(); -var queriesConnectionString = builder.Configuration["ConnectionString"]; - -services.AddScoped(sp => new OrderQueries(queriesConnectionString)); +services.AddScoped(sp => new OrderQueries(builder.Configuration.GetConnectionString("OrderingDB"))); services.AddScoped(); services.AddScoped(); services.AddScoped(); @@ -71,55 +43,27 @@ services.AddSingleton, UserCheckoutAcceptedIntegrationEventHandler>(); var app = builder.Build(); -if (!app.Environment.IsDevelopment()) -{ - app.UseExceptionHandler("/Home/Error"); -} -var pathBase = app.Configuration["PATH_BASE"]; -if (!string.IsNullOrEmpty(pathBase)) +if (!await app.CheckHealthAsync()) { - app.UsePathBase(pathBase); + return; } -app.UseSwagger().UseSwaggerUI(c => -{ - c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Ordering.API V1"); - c.OAuthClientId("orderingswaggerui"); - c.OAuthAppName("Ordering Swagger UI"); -}); +app.UseServiceDefaults(); + +app.MapGet("/", () => Results.Redirect("/swagger")); -app.UseRouting(); -app.UseCors("CorsPolicy"); -app.UseAuthentication(); -app.UseAuthorization(); app.MapGrpcService(); -app.MapDefaultControllerRoute(); app.MapControllers(); -app.MapGet("/_proto/", async ctx => -{ - ctx.Response.ContentType = "text/plain"; - using var fs = new FileStream(Path.Combine(app.Environment.ContentRootPath, "Proto", "basket.proto"), FileMode.Open, FileAccess.Read); - using var sr = new StreamReader(fs); - while (!sr.EndOfStream) - { - var line = await sr.ReadLineAsync(); - if (line != "/* >>" || line != "<< */") - { - await ctx.Response.WriteAsync(line); - } - } -}); -app.MapHealthChecks("/hc", new HealthCheckOptions() -{ - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse -}); -app.MapHealthChecks("/liveness", new HealthCheckOptions -{ - Predicate = r => r.Name.Contains("self") -}); -ConfigureEventBus(app); + +var eventBus = app.Services.GetRequiredService(); + +eventBus.Subscribe>(); +eventBus.Subscribe>(); +eventBus.Subscribe>(); +eventBus.Subscribe>(); +eventBus.Subscribe>(); +eventBus.Subscribe>(); using (var scope = app.Services.CreateScope()) { @@ -135,284 +79,3 @@ using (var scope = app.Services.CreateScope()) } await app.RunAsync(); - -void ConfigureEventBus(IApplicationBuilder app) -{ - var eventBus = app.ApplicationServices.GetRequiredService(); - - eventBus.Subscribe>(); - eventBus.Subscribe>(); - eventBus.Subscribe>(); - eventBus.Subscribe>(); - eventBus.Subscribe>(); - eventBus.Subscribe>(); -} - -static class CustomExtensionsMethods -{ - public static IServiceCollection AddCustomMvc(this IServiceCollection services) - { - // Add framework services. - services.AddControllers(options => - { - options.Filters.Add(typeof(HttpGlobalExceptionFilter)); - }) - // Added for functional tests - .AddApplicationPart(typeof(OrdersController).Assembly) - .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true); - - services.AddCors(options => - { - options.AddPolicy("CorsPolicy", - builder => builder - .SetIsOriginAllowed((host) => true) - .AllowAnyMethod() - .AllowAnyHeader() - .AllowCredentials()); - }); - - return services; - } - - public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) - { - var hcBuilder = services.AddHealthChecks(); - - hcBuilder.AddCheck("self", () => HealthCheckResult.Healthy()); - - hcBuilder - .AddSqlServer( - configuration["ConnectionString"], - name: "OrderingDB-check", - tags: new string[] { "orderingdb" }); - - if (configuration.GetValue("AzureServiceBusEnabled")) - { - hcBuilder - .AddAzureServiceBusTopic( - configuration["EventBusConnection"], - topicName: "eshop_event_bus", - name: "ordering-servicebus-check", - tags: new string[] { "servicebus" }); - } - else - { - hcBuilder - .AddRabbitMQ( - $"amqp://{configuration["EventBusConnection"]}", - name: "ordering-rabbitmqbus-check", - tags: new string[] { "rabbitmqbus" }); - } - - return services; - } - - public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration) - { - services.AddDbContext(options => - { - options.UseSqlServer(configuration["ConnectionString"], - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name); - sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - }); - }, - ServiceLifetime.Scoped //Showing explicitly that the DbContext is shared across the HTTP request scope (graph of objects started in the HTTP request) - ); - - services.AddDbContext(options => - { - options.UseSqlServer(configuration["ConnectionString"], - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name); - //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency - sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - }); - }); - - return services; - } - - public static IServiceCollection AddCustomSwagger(this IServiceCollection services, IConfiguration configuration) - { - return services.AddSwaggerGen(options => - { - options.SwaggerDoc("v1", new OpenApiInfo - { - Title = "eShopOnContainers - Ordering HTTP API", - Version = "v1", - Description = "The Ordering Service HTTP API" - }); - - var identityUrl = configuration.GetSection("Identity")["ExternalUrl"]; - - options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme - { - Type = SecuritySchemeType.OAuth2, - Flows = new OpenApiOAuthFlows() - { - Implicit = new OpenApiOAuthFlow() - { - AuthorizationUrl = new Uri($"{identityUrl}/connect/authorize"), - TokenUrl = new Uri($"{identityUrl}/connect/token"), - Scopes = new Dictionary() - { - { "orders", "Ordering API" } - } - } - } - }); - - options.OperationFilter(); - }); - } - - public static IServiceCollection AddCustomIntegrations(this IServiceCollection services, IConfiguration configuration) - { - services.AddSingleton(); - services.AddTransient(); - services.AddTransient>( - sp => (DbConnection c) => new IntegrationEventLogService(c)); - - services.AddTransient(); - - if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var serviceBusConnectionString = configuration["EventBusConnection"]; - - var subscriptionClientName = configuration["SubscriptionClientName"]; - - return new DefaultServiceBusPersisterConnection(serviceBusConnectionString); - }); - } - else - { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - - var factory = new ConnectionFactory() - { - HostName = configuration["EventBusConnection"], - DispatchConsumersAsync = true - }; - - if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) - { - factory.UserName = configuration["EventBusUserName"]; - } - - if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) - { - factory.Password = configuration["EventBusPassword"]; - } - - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); - } - - return services; - } - - public static IServiceCollection AddCustomConfiguration(this IServiceCollection services, IConfiguration configuration) - { - services.Configure(configuration); - services.Configure(options => - { - options.InvalidModelStateResponseFactory = context => - { - var problemDetails = new ValidationProblemDetails(context.ModelState) - { - Instance = context.HttpContext.Request.Path, - Status = StatusCodes.Status400BadRequest, - Detail = "Please refer to the errors property for additional details." - }; - - return new BadRequestObjectResult(problemDetails) - { - ContentTypes = { "application/problem+json", "application/problem+xml" } - }; - }; - }); - - return services; - } - - public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) - { - if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubscriptionsManager = sp.GetRequiredService(); - string subscriptionName = configuration["SubscriptionClientName"]; - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, eventBusSubscriptionsManager, sp, subscriptionName); - }); - } - else - { - services.AddSingleton(sp => - { - var subscriptionClientName = configuration["SubscriptionClientName"]; - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubscriptionsManager = sp.GetRequiredService(); - - if (!int.TryParse(configuration["EventBusRetryCount"], out var retryCount)) - { - retryCount = 5; - } - - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubscriptionsManager, subscriptionClientName, retryCount); - }); - } - - services.AddSingleton(); - - return services; - } - - public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) - { - // prevent from mapping "sub" claim to nameidentifier. - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); - - var identityUrl = configuration.GetValue("IdentityUrl"); - - services.AddAuthentication("Bearer").AddJwtBearer(options => - { - options.Authority = identityUrl; - options.RequireHttpsMetadata = false; - options.Audience = "orders"; - options.TokenValidationParameters.ValidateAudience = false; - }); - - return services; - } - public static IServiceCollection AddCustomAuthorization(this IServiceCollection services, IConfiguration configuration) - { - services.AddAuthorization(options => - { - options.AddPolicy("ApiScope", policy => - { - policy.RequireAuthenticatedUser(); - policy.RequireClaim("scope", "orders"); - }); - }); - return services; - } -} diff --git a/src/Services/Ordering/Ordering.API/Properties/launchSettings.json b/src/Services/Ordering/Ordering.API/Properties/launchSettings.json index 9d9a76490..f05bc8e5c 100644 --- a/src/Services/Ordering/Ordering.API/Properties/launchSettings.json +++ b/src/Services/Ordering/Ordering.API/Properties/launchSettings.json @@ -1,25 +1,9 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:55102/", - "sslPort": 0 - } - }, "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "/swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "Microsoft.eShopOnContainers.Services.Ordering.API": { + "Ordering.API": { "commandName": "Project", "launchBrowser": true, - "launchUrl": "http://localhost:55102/", + "applicationUrl": "http://localhost:5228/", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Services/Ordering/Ordering.API/appsettings.json b/src/Services/Ordering/Ordering.API/appsettings.json index d920b2d86..3f54fb3ce 100644 --- a/src/Services/Ordering/Ordering.API/appsettings.json +++ b/src/Services/Ordering/Ordering.API/appsettings.json @@ -1,24 +1,43 @@ { - "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;TrustServerCertificate=true", + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "OpenApi": { + "Endpoint": { + "Name": "Ordering.API V1" + }, + "Document": { + "Description": "The Ordering Service HTTP API", + "Title": "eShopOnContainers - Ordering HTTP API", + "Version": "v1" + }, + "Auth": { + "ClientId": "orderingswaggerui", + "AppName": "Ordering Swagger UI" + } + }, + "ConnectionStrings": { + "EventBus": "localhost" + }, + "EventBus": { + "SubscriptionClientName": "Ordering", + "RetryCount": 5 + }, + "ApplicationInsights": { + "InstrumentationKey": "" + }, "Identity": { "Url": "http://localhost:5105", "ExternalUrl": "http://localhost:5105", - "Audience": "orders" + "Audience": "orders", + "Scopes": { + "orders": "Ordering API" + } }, "UseCustomizationData": false, - "AzureServiceBusEnabled": false, - "SubscriptionClientName": "Ordering", "GracePeriodTime": "1", - "CheckUpdateTime": "30000", - "ApplicationInsights": { - "InstrumentationKey": "" - }, - "EventBusRetryCount": 5, - "EventBusConnection": "localhost", - "UseVault": false, - "Vault": { - "Name": "eshop", - "ClientId": "your-client-id", - "ClientSecret": "your-client-secret" - } - } + "CheckUpdateTime": "30000" +} diff --git a/src/Services/Ordering/Ordering.API/web.config b/src/Services/Ordering/Ordering.API/web.config deleted file mode 100644 index 3d49211e5..000000000 --- a/src/Services/Ordering/Ordering.API/web.config +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs index 2bf493a4d..2d25c78f1 100644 --- a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs +++ b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarioBase.cs @@ -9,18 +9,6 @@ public class OrderingScenarioBase { public TestServer CreateServer() { - Services.MigrateDbContext((context, services) => - { - var env = services.GetService(); - var settings = services.GetService>(); - var logger = services.GetService>(); - - new OrderingContextSeed() - .SeedAsync(context, env, settings, logger) - .Wait(); - }) - .MigrateDbContext((_, __) => { }); - return Server; } diff --git a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs index 4ed21ba1b..85dd4ab3d 100644 --- a/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs +++ b/src/Services/Ordering/Ordering.FunctionalTests/OrderingScenarios.cs @@ -30,6 +30,7 @@ namespace Ordering.FunctionalTests var response = await server.CreateClient() .PutAsync(Put.CancelOrder, content); + var s = await response.Content.ReadAsStringAsync(); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); } diff --git a/src/Services/Ordering/Ordering.FunctionalTests/appsettings.json b/src/Services/Ordering/Ordering.FunctionalTests/appsettings.json index fa0fae4af..69307ec18 100644 --- a/src/Services/Ordering/Ordering.FunctionalTests/appsettings.json +++ b/src/Services/Ordering/Ordering.FunctionalTests/appsettings.json @@ -1,6 +1,9 @@ { + "ConnectionStrings": { + "OrderingDb": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true", + "EventBus": "localhost" + }, "CheckUpdateTime": "30000", - "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true", "EventBusConnection": "localhost", "ExternalCatalogBaseUrl": "http://localhost:5101", "GracePeriodTime": "1", From 3357c70bc1a44b6d4e5641814ee04b74a3f8f66a Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 22:48:36 -0700 Subject: [PATCH 058/118] Clean up excess in project file --- .../Ordering/Ordering.API/Ordering.API.csproj | 31 ++----------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/src/Services/Ordering/Ordering.API/Ordering.API.csproj b/src/Services/Ordering/Ordering.API/Ordering.API.csproj index dc8bf637b..a09fb61fe 100644 --- a/src/Services/Ordering/Ordering.API/Ordering.API.csproj +++ b/src/Services/Ordering/Ordering.API/Ordering.API.csproj @@ -3,10 +3,7 @@ net7.0 aspnet-Ordering.API-20161122013547 - $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; ..\..\..\..\docker-compose.dcproj - false - true Microsoft.eShopOnContainers.Services.Ordering.API @@ -21,47 +18,23 @@ - - - + - - - - - - - - - - - - + - - - - - - - - - - - From 6e69a2472e57596d9a452a2754d8e19cdfa40300 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 22:52:18 -0700 Subject: [PATCH 059/118] Small naming tweaks for consistency --- src/Services/Catalog/Catalog.API/Program.cs | 2 +- src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs | 4 ++-- src/Services/Ordering/Ordering.API/Program.cs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index f15724b83..3299da2f6 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -8,9 +8,9 @@ builder.Services.AddGrpc(); builder.Services.AddControllers(); // Application specific services +builder.Services.AddHealthChecks(builder.Configuration); builder.Services.AddDbContexts(builder.Configuration); builder.Services.AddApplicationOptions(builder.Configuration); -builder.Services.AddHealthChecks(builder.Configuration); builder.Services.AddIntegrationServices(); builder.Services.AddTransient(); diff --git a/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs b/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs index d0849b832..116c70ce0 100644 --- a/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs +++ b/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs @@ -39,7 +39,7 @@ static class CustomExtensionsMethods return services; } - public static IServiceCollection AddCustomIntegrations(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddIntegrationServices(this IServiceCollection services) { services.AddTransient(); services.AddTransient>( @@ -50,7 +50,7 @@ static class CustomExtensionsMethods return services; } - public static IServiceCollection AddCustomConfiguration(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddApplicationOptions(this IServiceCollection services, IConfiguration configuration) { services.Configure(configuration); services.Configure(options => diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index 862914e08..2ec56b692 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -9,8 +9,8 @@ builder.Services.AddControllers(); builder.Services.AddHealthChecks(builder.Configuration); builder.Services.AddDbContexts(builder.Configuration); -builder.Services.AddCustomIntegrations(builder.Configuration); -builder.Services.AddCustomConfiguration(builder.Configuration); +builder.Services.AddApplicationOptions(builder.Configuration); +builder.Services.AddIntegrationServices(); var services = builder.Services; From 9743c832215fddd81c417ac4922190b26b6aa6c7 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 23:35:14 -0700 Subject: [PATCH 060/118] Use the common services in the Ordering.SignalRHub project --- .../CustomExtensionMethods.cs | 42 ++++ .../Ordering.SignalrHub/GlobalUsings.cs | 15 +- .../Ordering.SignalrHub/NotificationHub.cs | 1 - .../Ordering.SignalrHub.csproj | 1 + .../Ordering/Ordering.SignalrHub/Program.cs | 230 ++---------------- .../Properties/launchSettings.json | 19 +- .../Ordering.SignalrHub/appsettings.json | 22 +- 7 files changed, 88 insertions(+), 242 deletions(-) create mode 100644 src/Services/Ordering/Ordering.SignalrHub/CustomExtensionMethods.cs diff --git a/src/Services/Ordering/Ordering.SignalrHub/CustomExtensionMethods.cs b/src/Services/Ordering/Ordering.SignalrHub/CustomExtensionMethods.cs new file mode 100644 index 000000000..dd6a3d442 --- /dev/null +++ b/src/Services/Ordering/Ordering.SignalrHub/CustomExtensionMethods.cs @@ -0,0 +1,42 @@ +using Microsoft.AspNetCore.Http; + +public static class CustomExtensionMethods +{ + public static IServiceCollection AddSignalR(this IServiceCollection services, IConfiguration configuration) + { + if (configuration.GetConnectionString("redis") is string redisConnection) + { + // Add a redis health check + services.AddSignalR().AddStackExchangeRedis(redisConnection); + } + else + { + services.AddSignalR(); + } + + // Configure hub auth (grab the token from the query string) + return services.Configure(JwtBearerDefaults.AuthenticationScheme, options => + { + options.Events = new JwtBearerEvents + { + OnMessageReceived = context => + { + var accessToken = context.Request.Query["access_token"]; + + var endpoint = context.HttpContext.GetEndpoint(); + + // Make sure this is a Hub endpoint. + if (endpoint?.Metadata.GetMetadata() is null) + { + return Task.CompletedTask; + } + + context.Token = accessToken; + + return Task.CompletedTask; + } + }; + }); + } + +} diff --git a/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs b/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs index 5d956ba77..df4552c08 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs @@ -1,29 +1,16 @@ -global using HealthChecks.UI.Client; -global using Microsoft.AspNetCore.Authentication.JwtBearer; +global using Microsoft.AspNetCore.Authentication.JwtBearer; global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; -global using Microsoft.AspNetCore.Diagnostics.HealthChecks; -global using Microsoft.AspNetCore.Hosting; global using Microsoft.AspNetCore.SignalR; -global using Microsoft.AspNetCore; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.Events; global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Diagnostics.HealthChecks; global using Microsoft.Extensions.Logging; global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub; -global using RabbitMQ.Client; global using System.Collections.Generic; -global using System.IdentityModel.Tokens.Jwt; -global using System.IO; -global using System.Reflection; global using System.Threading.Tasks; global using System; -global using Microsoft.Extensions.Hosting; diff --git a/src/Services/Ordering/Ordering.SignalrHub/NotificationHub.cs b/src/Services/Ordering/Ordering.SignalrHub/NotificationHub.cs index 9f545bba4..b22960096 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/NotificationHub.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/NotificationHub.cs @@ -3,7 +3,6 @@ [Authorize] public class NotificationsHub : Hub { - public override async Task OnConnectedAsync() { await Groups.AddToGroupAsync(Context.ConnectionId, Context.User.Identity.Name); diff --git a/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj b/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj index 0eab4e6cb..8013fc7b4 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj +++ b/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj @@ -28,6 +28,7 @@ + diff --git a/src/Services/Ordering/Ordering.SignalrHub/Program.cs b/src/Services/Ordering/Ordering.SignalrHub/Program.cs index 96fc26e0b..8ad09b8f6 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Program.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Program.cs @@ -1,82 +1,21 @@ -var builder = WebApplication.CreateBuilder(new WebApplicationOptions -{ - Args = args, - ApplicationName = typeof(Program).Assembly.FullName, - ContentRootPath = Directory.GetCurrentDirectory() -}); -builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()); -builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); -builder.Configuration.AddEnvironmentVariables(); -builder.WebHost.CaptureStartupErrors(false); - -builder.Services - .AddCustomHealthCheck(builder.Configuration) - .AddCors(options => - { - options.AddPolicy("CorsPolicy", - builder => builder - .AllowAnyMethod() - .AllowAnyHeader() - .SetIsOriginAllowed((host) => true) - .AllowCredentials()); - }); -if (builder.Configuration.GetValue("IsClusterEnv") == bool.TrueString) -{ - builder.Services - .AddSignalR() - .AddStackExchangeRedis(builder.Configuration["SignalrStoreConnectionString"]); -} -else -{ - builder.Services.AddSignalR(); -} +using Services.Common; -if (builder.Configuration.GetValue("AzureServiceBusEnabled")) -{ - builder.Services.AddSingleton(sp => - { - var serviceBusConnectionString = builder.Configuration["EventBusConnection"]; +var builder = WebApplication.CreateBuilder(args); - var subscriptionClientName = builder.Configuration["SubscriptionClientName"]; +builder.AddServiceDefaults(); - return new DefaultServiceBusPersisterConnection(serviceBusConnectionString); - }); -} -else +builder.Services.AddCors(options => { - builder.Services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - - var factory = new ConnectionFactory() - { - HostName = builder.Configuration["EventBusConnection"], - DispatchConsumersAsync = true - }; - - if (!string.IsNullOrEmpty(builder.Configuration["EventBusUserName"])) - { - factory.UserName = builder.Configuration["EventBusUserName"]; - } - - if (!string.IsNullOrEmpty(builder.Configuration["EventBusPassword"])) - { - factory.Password = builder.Configuration["EventBusPassword"]; - } - - var retryCount = 5; - if (!string.IsNullOrEmpty(builder.Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(builder.Configuration["EventBusRetryCount"]); - } + options.AddPolicy("CorsPolicy", + builder => builder + .AllowAnyMethod() + .AllowAnyHeader() + .SetIsOriginAllowed((host) => true) + .AllowCredentials()); +}); - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); -} +builder.Services.AddSignalR(builder.Configuration); -ConfigureAuthService(builder.Services, builder.Configuration); -RegisterEventBus(builder.Services, builder.Configuration); builder.Services.AddSingleton, OrderStatusChangedToAwaitingValidationIntegrationEventHandler>(); builder.Services.AddSingleton, OrderStatusChangedToCancelledIntegrationEventHandler>(); builder.Services.AddSingleton, OrderStatusChangedToPaidIntegrationEventHandler>(); @@ -85,146 +24,27 @@ builder.Services.AddSingleton, OrderStatusChangedToSubmittedIntegrationEventHandler>(); var app = builder.Build(); -if (!app.Environment.IsDevelopment()) -{ - app.UseExceptionHandler("/Home/Error"); -} -var pathBase = builder.Configuration["PATH_BASE"]; -if (!string.IsNullOrEmpty(pathBase)) +if (!await app.CheckHealthAsync()) { - app.UsePathBase(pathBase); + return; } -app.UseRouting(); +app.UseServiceDefaults(); + app.UseCors("CorsPolicy"); app.UseAuthentication(); app.UseAuthorization(); -app.MapHealthChecks("/hc", new HealthCheckOptions() -{ - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse -}); -app.MapHealthChecks("/liveness", new HealthCheckOptions -{ - Predicate = r => r.Name.Contains("self") -}); -app.MapHub("/hub/notificationhub"); - -ConfigureEventBus(app); -await app.RunAsync(); - -void ConfigureEventBus(IApplicationBuilder app) -{ - var eventBus = app.ApplicationServices.GetRequiredService(); - - eventBus.Subscribe(); - eventBus.Subscribe(); - eventBus.Subscribe(); - eventBus.Subscribe(); - eventBus.Subscribe(); - eventBus.Subscribe(); -} - -void ConfigureAuthService(IServiceCollection services, IConfiguration configuration) -{ - // prevent from mapping "sub" claim to nameidentifier. - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); - - var identityUrl = configuration.GetValue("IdentityUrl"); - - services.AddAuthentication("Bearer").AddJwtBearer(options => - { - options.Authority = identityUrl; - options.RequireHttpsMetadata = false; - options.Audience = "orders.signalrhub"; - options.TokenValidationParameters.ValidateAudience = false; - options.Events = new JwtBearerEvents - { - OnMessageReceived = context => - { - var accessToken = context.Request.Query["access_token"]; - var path = context.HttpContext.Request.Path; - if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/hub/notificationhub"))) - { - context.Token = accessToken; - } - return Task.CompletedTask; - } - }; - }); - services.AddAuthorization(options => - { - options.AddPolicy("ApiScope", policy => - { - policy.RequireAuthenticatedUser(); - policy.RequireClaim("scope", "orders.signalrhub"); - }); - }); -} -void RegisterEventBus(IServiceCollection services, IConfiguration configuration) -{ - if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - string subscriptionName = configuration["SubscriptionClientName"]; - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, sp, subscriptionName); - }); - } - else - { - services.AddSingleton(sp => - { - var subscriptionClientName = configuration["SubscriptionClientName"]; - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubcriptionsManager, subscriptionClientName, retryCount); - }); - } - - services.AddSingleton(); -} -public static class CustomExtensionMethods -{ - public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) - { - var hcBuilder = services.AddHealthChecks(); +app.MapHub("/hub/notificationhub"); - hcBuilder.AddCheck("self", () => HealthCheckResult.Healthy()); +var eventBus = app.Services.GetRequiredService(); - if (configuration.GetValue("AzureServiceBusEnabled")) - { - hcBuilder - .AddAzureServiceBusTopic( - configuration["EventBusConnection"], - topicName: "eshop_event_bus", - name: "signalr-servicebus-check", - tags: new string[] { "servicebus" }); - } - else - { - hcBuilder - .AddRabbitMQ( - $"amqp://{configuration["EventBusConnection"]}", - name: "signalr-rabbitmqbus-check", - tags: new string[] { "rabbitmqbus" }); - } +eventBus.Subscribe(); +eventBus.Subscribe(); +eventBus.Subscribe(); +eventBus.Subscribe(); +eventBus.Subscribe(); +eventBus.Subscribe(); - return services; - } -} +await app.RunAsync(); diff --git a/src/Services/Ordering/Ordering.SignalrHub/Properties/launchSettings.json b/src/Services/Ordering/Ordering.SignalrHub/Properties/launchSettings.json index 3ff683a08..9bcb7d2d3 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Properties/launchSettings.json +++ b/src/Services/Ordering/Ordering.SignalrHub/Properties/launchSettings.json @@ -1,27 +1,12 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:51311/", - "sslPort": 0 - } - }, "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, "Ordering.SignalrHub": { "commandName": "Project", "launchBrowser": true, + "applicationUrl": "http://localhost:5223/", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:51312/" + } } } } diff --git a/src/Services/Ordering/Ordering.SignalrHub/appsettings.json b/src/Services/Ordering/Ordering.SignalrHub/appsettings.json index be528bb8b..bf7ffc1e2 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/appsettings.json +++ b/src/Services/Ordering/Ordering.SignalrHub/appsettings.json @@ -1,7 +1,19 @@ { - "IdentityUrl": "http://localhost:5105", - "AzureServiceBusEnabled": false, - "SubscriptionClientName": "Ordering.signalrhub", - "EventBusRetryCount": 5, - "EventBusConnection": "localhost" + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Identity": { + "Audience": "orders.signalrhub", + "Url": "http://localhost:5105" + }, + "EventBus": { + "SubscriptionClientName": "Ordering.signalrhub", + "RetryCount": 5 + }, + "ConnectionStrings": { + "EventBus": "localhost" + } } \ No newline at end of file From 0cb6b0830072e2958d791f2115385f744d306414 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 4 May 2023 23:45:50 -0700 Subject: [PATCH 061/118] Clean up the project --- .../Ordering.SignalrHub.csproj | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj b/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj index 8013fc7b4..a870e20ee 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj +++ b/src/Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj @@ -3,31 +3,14 @@ net7.0 ..\..\..\..\docker-compose.dcproj - false - true - - - - - - - - - - - - - - - From c41cd3830c561bc9cc1b2e0015ebd2f3bb678bf4 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 5 May 2023 00:12:34 -0700 Subject: [PATCH 062/118] Updated background tasks to use common service logic --- .../Basket.API/CustomExtensionMethods.cs | 4 +- .../Catalog.API/CustomExtensionMethods.cs | 5 +- .../Ordering.API/CustomExtensionsMethods.cs | 3 - .../Ordering/Ordering.API/GlobalUsings.cs | 1 + src/Services/Ordering/Ordering.API/Program.cs | 4 +- .../Extensions/CustomExtensionMethods.cs | 126 +++--------------- .../Ordering.BackgroundTasks/GlobalUsings.cs | 15 +-- .../Ordering.BackgroundTasks.csproj | 1 + .../Ordering.BackgroundTasks/Program.cs | 38 ++---- .../Ordering.BackgroundTasks/appsettings.json | 25 ++-- .../Ordering.SignalrHub/GlobalUsings.cs | 15 ++- .../Ordering/Ordering.SignalrHub/Program.cs | 4 +- .../Services.Common/CommonExtensions.cs | 6 - .../ConfigurationExtensions.cs | 10 ++ 14 files changed, 73 insertions(+), 184 deletions(-) create mode 100644 src/Services/Services.Common/ConfigurationExtensions.cs diff --git a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs index 7d28de8f9..b98ab6b3f 100644 --- a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs +++ b/src/Services/Basket/Basket.API/CustomExtensionMethods.cs @@ -5,7 +5,7 @@ public static class CustomExtensionMethods public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) { services.AddHealthChecks() - .AddRedis(_ => configuration.GetConnectionString("redis"), "redis", tags: new[] { "ready", "liveness" }); + .AddRedis(_ => configuration.GetRequiredConnectionString("redis"), "redis", tags: new[] { "ready", "liveness" }); return services; } @@ -14,7 +14,7 @@ public static class CustomExtensionMethods { return services.AddSingleton(sp => { - var redisConfig = ConfigurationOptions.Parse(configuration.GetConnectionString("redis"), true); + var redisConfig = ConfigurationOptions.Parse(configuration.GetRequiredConnectionString("redis"), true); return ConnectionMultiplexer.Connect(redisConfig); }); diff --git a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs index 7779d791d..ed74e4619 100644 --- a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs +++ b/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs @@ -7,7 +7,7 @@ public static class CustomExtensionMethods var hcBuilder = services.AddHealthChecks(); hcBuilder - .AddSqlServer(_ => configuration.GetConnectionString("CatalogDB"), + .AddSqlServer(_ => configuration.GetRequiredConnectionString("CatalogDB"), name: "CatalogDB-check", tags: new string[] { "live", "ready" }); @@ -89,7 +89,4 @@ public static class CustomExtensionMethods return services; } - - private static string GetRequiredConnectionString(this IConfiguration configuration, string name) => - configuration.GetConnectionString(name) ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":ConnectionStrings:" + name : "ConnectionStrings:" + name)}"); } diff --git a/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs b/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs index 116c70ce0..a7d7cd523 100644 --- a/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs +++ b/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs @@ -73,7 +73,4 @@ static class CustomExtensionsMethods return services; } - - private static string GetRequiredConnectionString(this IConfiguration configuration, string name) => - configuration.GetConnectionString(name) ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":ConnectionStrings:" + name : "ConnectionStrings:" + name)}"); } diff --git a/src/Services/Ordering/Ordering.API/GlobalUsings.cs b/src/Services/Ordering/Ordering.API/GlobalUsings.cs index be14d664d..70255b36a 100644 --- a/src/Services/Ordering/Ordering.API/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.API/GlobalUsings.cs @@ -52,6 +52,7 @@ global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using Polly; global using Polly.Retry; +global using Services.Common; global using Swashbuckle.AspNetCore.SwaggerGen; global using AppCommand = Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; global using ApiModels = Microsoft.eShopOnContainers.Services.Ordering.API.Application.Models; diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index 2ec56b692..70faa5022 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -1,6 +1,4 @@ -using Services.Common; - -var builder = WebApplication.CreateBuilder(args); +var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Extensions/CustomExtensionMethods.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Extensions/CustomExtensionMethods.cs index aa05e0006..b8f7514a9 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Extensions/CustomExtensionMethods.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Extensions/CustomExtensionMethods.cs @@ -1,119 +1,25 @@ -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; -using Microsoft.Extensions.Diagnostics.HealthChecks; -using RabbitMQ.Client; +namespace Ordering.BackgroundTasks.Extensions; -namespace Ordering.BackgroundTasks.Extensions +public static class CustomExtensionMethods { - public static class CustomExtensionMethods + public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) { - public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) - { - var hcBuilder = services.AddHealthChecks(); - - hcBuilder.AddCheck("self", () => HealthCheckResult.Healthy()); - - hcBuilder.AddSqlServer( - configuration["ConnectionString"], - name: "OrderingTaskDB-check", - tags: new string[] { "orderingtaskdb" }); + var hcBuilder = services.AddHealthChecks(); - if (configuration.GetValue("AzureServiceBusEnabled")) - { - hcBuilder.AddAzureServiceBusTopic( - configuration["EventBusConnection"], - topicName: "eshop_event_bus", - name: "orderingtask-servicebus-check", - tags: new string[] { "servicebus" }); - } - else - { - hcBuilder.AddRabbitMQ( - $"amqp://{configuration["EventBusConnection"]}", - name: "orderingtask-rabbitmqbus-check", - tags: new string[] { "rabbitmqbus" }); - } + hcBuilder.AddSqlServer(_ => + configuration.GetRequiredConnectionString("OrderingDb"), + name: "OrderingTaskDB-check", + tags: new string[] { "live", "ready" }); - return services; - } + return services; + } - public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddApplicationOptions(this IServiceCollection services, IConfiguration configuration) + { + return services.Configure(configuration) + .Configure(o => { - var subscriptionClientName = configuration["SubscriptionClientName"]; - - if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var serviceBusConnectionString = configuration["EventBusConnection"]; - - return new DefaultServiceBusPersisterConnection(serviceBusConnectionString); - }); - - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - string subscriptionName = configuration["SubscriptionClientName"]; - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, eventBusSubcriptionsManager, sp, subscriptionName); - }); - } - else - { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - var factory = new ConnectionFactory() - { - HostName = configuration["EventBusConnection"], - DispatchConsumersAsync = true - }; - - if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) - { - factory.UserName = configuration["EventBusUserName"]; - } - - if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) - { - factory.Password = configuration["EventBusPassword"]; - } - - var retryCount = 5; - - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); - - services.AddSingleton(sp => - { - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - var retryCount = 5; - - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubcriptionsManager, subscriptionClientName, retryCount); - }); - } - - services.AddSingleton(); - - return services; - } + o.ConnectionString = configuration.GetRequiredConnectionString("OrderingDb"); + }); } } diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/GlobalUsings.cs b/src/Services/Ordering/Ordering.BackgroundTasks/GlobalUsings.cs index f15742736..72205c528 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/GlobalUsings.cs @@ -1,13 +1,10 @@ -global using Microsoft.AspNetCore.Hosting; -global using Microsoft.Extensions.Configuration; -global using Microsoft.Extensions.Hosting; -global using Ordering.BackgroundTasks.Extensions; -global using System.IO; -global using HealthChecks.UI.Client; +global using System; global using Microsoft.AspNetCore.Builder; -global using Microsoft.AspNetCore.Diagnostics.HealthChecks; +global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; -global using Ordering.BackgroundTasks.Services; -global using System; global using Ordering.BackgroundTasks; +global using Ordering.BackgroundTasks.Extensions; +global using Ordering.BackgroundTasks.Services; +global using Services.Common; diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj b/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj index 0b9cabbcc..8acc2a97b 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj @@ -23,5 +23,6 @@ + diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs index 0be966e96..3fe853c75 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Program.cs @@ -1,32 +1,18 @@ -var builder = WebApplication.CreateBuilder(new WebApplicationOptions -{ - Args = args, - ApplicationName = typeof(Program).Assembly.FullName -}); -builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()); -builder.Configuration.AddJsonFile("appsettings.json", optional: true); -builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true); -builder.Configuration.AddEnvironmentVariables(); -builder.Services.AddCustomHealthCheck(builder.Configuration) - .Configure(builder.Configuration) - .AddHostedService() - .AddEventBus(builder.Configuration); +var builder = WebApplication.CreateBuilder(args); + +builder.AddServiceDefaults(); + +builder.Services.AddHealthChecks(builder.Configuration); +builder.Services.AddApplicationOptions(builder.Configuration); +builder.Services.AddHostedService(); + var app = builder.Build(); -if (!app.Environment.IsDevelopment()) + +if (!await app.CheckHealthAsync()) { - app.UseExceptionHandler("/Home/Error"); + return; } -app.UseRouting(); - -app.MapHealthChecks("/hc", new HealthCheckOptions() -{ - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse -}); -app.MapHealthChecks("/liveness", new HealthCheckOptions -{ - Predicate = r => r.Name.Contains("self") -}); +app.UseServiceDefaults(); await app.RunAsync(); diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json b/src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json index 2069c7db2..bb061ce40 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json +++ b/src/Services/Ordering/Ordering.BackgroundTasks/appsettings.json @@ -1,14 +1,17 @@ { - "ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;", - "SubscriptionClientName": "BackgroundTasks", - "GracePeriodTime": "1", - "CheckUpdateTime": "1000", - "ApplicationInsights": { - "InstrumentationKey": "" + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "ConnectionStrings": { + "EventBus": "localhost" }, - "AzureServiceBusEnabled": false, - "EventBusRetryCount": 5, - "EventBusConnection": "", - "EventBusUserName": "", - "EventBusPassword": "" + "EventBus": { + "SubscriptionClientName": "BackgroundTasks", + "RetryCount": 5 + }, + "GracePeriodTime": "1", + "CheckUpdateTime": "1000" } \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs b/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs index df4552c08..16b8b6bda 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/GlobalUsings.cs @@ -1,16 +1,17 @@ -global using Microsoft.AspNetCore.Authentication.JwtBearer; +global using System; +global using System.Collections.Generic; +global using System.Threading.Tasks; +global using Microsoft.AspNetCore.Authentication.JwtBearer; global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.SignalR; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; -global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.Events; +global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub; global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents; +global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; +global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.Events; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Logging; -global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub.IntegrationEvents.EventHandling; -global using Microsoft.eShopOnContainers.Services.Ordering.SignalrHub; -global using System.Collections.Generic; -global using System.Threading.Tasks; -global using System; +global using Services.Common; diff --git a/src/Services/Ordering/Ordering.SignalrHub/Program.cs b/src/Services/Ordering/Ordering.SignalrHub/Program.cs index 8ad09b8f6..4583e9025 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Program.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Program.cs @@ -1,6 +1,4 @@ -using Services.Common; - -var builder = WebApplication.CreateBuilder(args); +var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index 91ce1af5c..c3b9672a5 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -419,10 +419,4 @@ public static class CommonExtensions Predicate = r => r.Name.Contains("self") }); } - - private static string GetRequiredValue(this IConfiguration configuration, string name) => - configuration[name] ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":" + name : name)}"); - - private static string GetRequiredConnectionString(this IConfiguration configuration, string name) => - configuration.GetConnectionString(name) ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":ConnectionStrings:" + name : "ConnectionStrings:" + name)}"); } diff --git a/src/Services/Services.Common/ConfigurationExtensions.cs b/src/Services/Services.Common/ConfigurationExtensions.cs new file mode 100644 index 000000000..8d8c11cdd --- /dev/null +++ b/src/Services/Services.Common/ConfigurationExtensions.cs @@ -0,0 +1,10 @@ +namespace Microsoft.Extensions.Configuration; + +public static class ConfigurationExtensions +{ + public static string GetRequiredValue(this IConfiguration configuration, string name) => + configuration[name] ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":" + name : name)}"); + + public static string GetRequiredConnectionString(this IConfiguration configuration, string name) => + configuration.GetConnectionString(name) ?? throw new InvalidOperationException($"Configuration missing value for: {(configuration is IConfigurationSection s ? s.Path + ":ConnectionStrings:" + name : "ConnectionStrings:" + name)}"); +} From 2a4a6abf9bf2b361773df9989b83b7ced9687cd9 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 5 May 2023 00:20:37 -0700 Subject: [PATCH 063/118] Small tweaks - Fix the payment profile's launch profile - Added Services.Common to global usings --- .../Catalog/Catalog.API/GlobalUsings.cs | 1 + src/Services/Catalog/Catalog.API/Program.cs | 4 +--- .../Properties/launchSettings.json | 21 ++----------------- 3 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/Services/Catalog/Catalog.API/GlobalUsings.cs b/src/Services/Catalog/Catalog.API/GlobalUsings.cs index bd9e2d862..cc82d36bd 100644 --- a/src/Services/Catalog/Catalog.API/GlobalUsings.cs +++ b/src/Services/Catalog/Catalog.API/GlobalUsings.cs @@ -40,3 +40,4 @@ global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using Polly; global using Polly.Retry; +global using Services.Common; diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index 3299da2f6..cac05401e 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -1,6 +1,4 @@ -using Services.Common; - -var builder = WebApplication.CreateBuilder(args); +var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); diff --git a/src/Services/Payment/Payment.API/Properties/launchSettings.json b/src/Services/Payment/Payment.API/Properties/launchSettings.json index 5eac4c092..007e0eace 100644 --- a/src/Services/Payment/Payment.API/Properties/launchSettings.json +++ b/src/Services/Payment/Payment.API/Properties/launchSettings.json @@ -1,29 +1,12 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:63336/", - "sslPort": 0 - } - }, "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "api/values", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, "Payment.API": { "commandName": "Project", "launchBrowser": true, - "launchUrl": "api/values", + "applicationUrl": "http://localhost:5226", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:3331" + } } } } \ No newline at end of file From a37b0430b2a7bb5314671aeb9d00d16e9561f3dc Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 5 May 2023 00:21:22 -0700 Subject: [PATCH 064/118] Remove unneeded dependencies --- .../Ordering.BackgroundTasks.csproj | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj b/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj index 8acc2a97b..85328e8bd 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Ordering.BackgroundTasks.csproj @@ -3,26 +3,16 @@ net7.0 dotnet-Ordering.BackgroundTasks-9D3E1DD6-405B-447F-8AAB-1708B36D260E - false Linux - - - - - - - - - From 57d9baf106dedda48713b2feb52ec70969ad3048 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 5 May 2023 00:29:55 -0700 Subject: [PATCH 065/118] Make the payment API use the common code --- .../Payment/Payment.API/GlobalUsings.cs | 24 +-- .../Payment/Payment.API/Payment.API.csproj | 21 +-- src/Services/Payment/Payment.API/Program.cs | 154 +----------------- .../Payment/Payment.API/appsettings.json | 21 ++- .../Services.Common/CommonExtensions.cs | 8 +- 5 files changed, 32 insertions(+), 196 deletions(-) diff --git a/src/Services/Payment/Payment.API/GlobalUsings.cs b/src/Services/Payment/Payment.API/GlobalUsings.cs index 023296a1c..a29434a61 100644 --- a/src/Services/Payment/Payment.API/GlobalUsings.cs +++ b/src/Services/Payment/Payment.API/GlobalUsings.cs @@ -1,25 +1,11 @@ -global using Azure.Core; -global using Azure.Identity; -global using HealthChecks.UI.Client; -global using Microsoft.AspNetCore.Diagnostics.HealthChecks; +global using System.Threading.Tasks; global using Microsoft.AspNetCore.Builder; -global using Microsoft.AspNetCore; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; +global using Microsoft.eShopOnContainers.Payment.API; +global using Microsoft.eShopOnContainers.Payment.API.IntegrationEvents.EventHandling; global using Microsoft.eShopOnContainers.Payment.API.IntegrationEvents.Events; -global using Microsoft.Extensions.Diagnostics.HealthChecks; -global using Microsoft.Extensions.Options; -global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Logging; -global using Microsoft.eShopOnContainers.Payment.API.IntegrationEvents.EventHandling; -global using Microsoft.eShopOnContainers.Payment.API; -global using RabbitMQ.Client; -global using System.Threading.Tasks; -global using System; -global using System.IO; -global using Microsoft.AspNetCore.Hosting; -global using Microsoft.Extensions.Hosting; +global using Microsoft.Extensions.Options; +global using Services.Common; diff --git a/src/Services/Payment/Payment.API/Payment.API.csproj b/src/Services/Payment/Payment.API/Payment.API.csproj index f6b9637f0..6dc523a2e 100644 --- a/src/Services/Payment/Payment.API/Payment.API.csproj +++ b/src/Services/Payment/Payment.API/Payment.API.csproj @@ -3,29 +3,10 @@ net7.0 ..\..\..\..\docker-compose.dcproj - $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; - false - true - - - - - - - - - - - - - - - - - + diff --git a/src/Services/Payment/Payment.API/Program.cs b/src/Services/Payment/Payment.API/Program.cs index c1d2fe5f1..89daeb463 100644 --- a/src/Services/Payment/Payment.API/Program.cs +++ b/src/Services/Payment/Payment.API/Program.cs @@ -1,158 +1,22 @@ var builder = WebApplication.CreateBuilder(args); -if (builder.Configuration.GetValue("UseVault", false)) -{ - TokenCredential credential = new ClientSecretCredential( - builder.Configuration["Vault:TenantId"], - builder.Configuration["Vault:ClientId"], - builder.Configuration["Vault:ClientSecret"]); - builder.Configuration.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential); -} -builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()); -builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); -builder.Configuration.AddEnvironmentVariables(); -builder.WebHost.CaptureStartupErrors(false); -builder.Services - .AddCustomHealthCheck(builder.Configuration); -builder.Services.Configure(builder.Configuration); -builder.Services.AddApplicationInsightsTelemetry(builder.Configuration); -if (builder.Configuration.GetValue("AzureServiceBusEnabled")) -{ - builder.Services.AddSingleton(sp => - { - var serviceBusConnectionString = builder.Configuration["EventBusConnection"]; - var subscriptionClientName = builder.Configuration["SubscriptionClientName"]; - return new DefaultServiceBusPersisterConnection(serviceBusConnectionString); - }); -} -else -{ - builder.Services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - var factory = new ConnectionFactory() - { - HostName = builder.Configuration["EventBusConnection"], - DispatchConsumersAsync = true - }; +builder.AddServiceDefaults(); - if (!string.IsNullOrEmpty(builder.Configuration["EventBusUserName"])) - { - factory.UserName = builder.Configuration["EventBusUserName"]; - } - - if (!string.IsNullOrEmpty(builder.Configuration["EventBusPassword"])) - { - factory.Password = builder.Configuration["EventBusPassword"]; - } +builder.Services.Configure(builder.Configuration); - var retryCount = 5; - if (!string.IsNullOrEmpty(builder.Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(builder.Configuration["EventBusRetryCount"]); - } +builder.Services.AddTransient(); - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); -} -RegisterEventBus(builder.Services); var app = builder.Build(); -if (!app.Environment.IsDevelopment()) -{ - app.UseExceptionHandler("/Home/Error"); -} - -var pathBase = app.Configuration["PATH_BASE"]; -if (!string.IsNullOrEmpty(pathBase)) -{ - app.UsePathBase(pathBase); -} - -ConfigureEventBus(app); -app.UseRouting(); -app.MapHealthChecks("/hc", new HealthCheckOptions() +if (!await app.CheckHealthAsync()) { - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse -}); -app.MapHealthChecks("/liveness", new HealthCheckOptions -{ - Predicate = r => r.Name.Contains("self") -}); - -await app.RunAsync(); - -void RegisterEventBus(IServiceCollection services) -{ - if (builder.Configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - string subscriptionName = builder.Configuration["SubscriptionClientName"]; - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, sp, subscriptionName); - }); - } - else - { - services.AddSingleton(sp => - { - var subscriptionClientName = builder.Configuration["SubscriptionClientName"]; - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - var retryCount = 5; - if (!string.IsNullOrEmpty(builder.Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(builder.Configuration["EventBusRetryCount"]); - } - - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubcriptionsManager, subscriptionClientName, retryCount); - }); - } - - services.AddTransient(); - services.AddSingleton(); + return; } -void ConfigureEventBus(IApplicationBuilder app) -{ - var eventBus = app.ApplicationServices.GetRequiredService(); - eventBus.Subscribe(); -} +app.UseServiceDefaults(); -public static class CustomExtensionMethods -{ - public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) - { - var hcBuilder = services.AddHealthChecks(); +var eventBus = app.Services.GetRequiredService(); - hcBuilder.AddCheck("self", () => HealthCheckResult.Healthy()); +eventBus.Subscribe(); - if (configuration.GetValue("AzureServiceBusEnabled")) - { - hcBuilder - .AddAzureServiceBusTopic( - configuration["EventBusConnection"], - topicName: "eshop_event_bus", - name: "payment-servicebus-check", - tags: new string[] { "servicebus" }); - } - else - { - hcBuilder - .AddRabbitMQ( - $"amqp://{configuration["EventBusConnection"]}", - name: "payment-rabbitmqbus-check", - tags: new string[] { "rabbitmqbus" }); - } - - return services; - } -} +await app.RunAsync(); diff --git a/src/Services/Payment/Payment.API/appsettings.json b/src/Services/Payment/Payment.API/appsettings.json index 41de245fb..71e1aa6af 100644 --- a/src/Services/Payment/Payment.API/appsettings.json +++ b/src/Services/Payment/Payment.API/appsettings.json @@ -1,9 +1,16 @@ { - "PaymentSucceeded": true, - "AzureServiceBusEnabled": false, - "SubscriptionClientName": "Payment", - "ApplicationInsights": { - "InstrumentationKey": "" + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } }, - "EventBusRetryCount": 5 -} + "ConnectionStrings": { + "EventBus": "localhost" + }, + "EventBus": { + "SubscriptionClientName": "Payment", + "RetryCount": 5 + }, + "PaymentSucceeded": true +} \ No newline at end of file diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index c3b9672a5..b922d6cc4 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -289,23 +289,21 @@ public static class CommonExtensions // { // "EventBus": { // "ProviderName": "ServiceBus | RabbitMQ", - // } // } var eventBusSection = configuration.GetRequiredSection("EventBus"); - var eventBusConnectionString = configuration.GetRequiredConnectionString("EventBus"); return eventBusSection["ProviderName"]?.ToLowerInvariant() switch { "servicebus" => hcBuilder.AddAzureServiceBusTopic( - eventBusConnectionString, - topicName: "eshop_event_bus", + _ => configuration.GetRequiredConnectionString("EventBus"), + _ => "eshop_event_bus", name: "servicebus", tags: new string[] { "ready" }), _ => hcBuilder.AddRabbitMQ( - $"amqp://{eventBusConnectionString}", + _ => $"amqp://{configuration.GetRequiredConnectionString("EventBus")}", name: "rabbitmq", tags: new string[] { "ready" }) }; From bcb1374d1e6b06778d18716c93f499e160f0ce5d Mon Sep 17 00:00:00 2001 From: Reuben Bond Date: Fri, 5 May 2023 07:06:28 -0700 Subject: [PATCH 066/118] Avoid logging exception details twice in a given log, clean up --- .../GrpcExceptionInterceptor.cs | 2 +- .../GrpcExceptionInterceptor.cs | 2 +- .../DefaultRabbitMQPersistentConnection.cs | 4 +-- .../EventBusRabbitMQ/EventBusRabbitMQ.cs | 4 +-- .../EventBusServiceBus/EventBusServiceBus.cs | 2 +- .../WebHostExtensions.cs | 2 +- .../Controllers/BasketController.cs | 2 +- .../OrderStartedIntegrationEventHandler.cs | 2 +- ...ductPriceChangedIntegrationEventHandler.cs | 4 +-- .../Application/CartControllerTest.cs | 2 +- .../Infrastructure/CatalogContextSeed.cs | 34 +++++++++---------- .../CatalogIntegrationEventService.cs | 6 ++-- ...aitingValidationIntegrationEventHandler.cs | 2 +- ...tusChangedToPaidIntegrationEventHandler.cs | 2 +- .../Identity.API/IWebHostExtensions.cs | 4 +-- .../Quickstart/Account/LoginViewModel.cs | 2 +- .../Quickstart/Consent/ConsentController.cs | 2 +- .../Identity/Identity.API/SeedData.cs | 13 ++----- .../Application/Behaviors/LoggingBehavior.cs | 4 +-- .../Behaviors/TransactionBehavior.cs | 6 ++-- .../Behaviors/ValidatorBehavior.cs | 2 +- .../Commands/CreateOrderCommandHandler.cs | 2 +- .../Commands/IdentifiedCommandHandler.cs | 4 +-- ...ePeriodConfirmedIntegrationEventHandler.cs | 4 +-- ...derPaymentFailedIntegrationEventHandler.cs | 4 +-- ...PaymentSucceededIntegrationEventHandler.cs | 4 +-- ...erStockConfirmedIntegrationEventHandler.cs | 4 +-- ...derStockRejectedIntegrationEventHandler.cs | 4 +-- ...CheckoutAcceptedIntegrationEventHandler.cs | 6 ++-- .../OrderingIntegrationEventService.cs | 6 ++-- .../CancelOrderCommandValidator.cs | 2 +- .../CreateOrderCommandValidator.cs | 2 +- .../Validations/IdentifiedCommandValidator.cs | 2 +- .../Validations/ShipOrderCommandValidator.cs | 2 +- .../Controllers/OrdersController.cs | 6 ++-- .../Ordering.API/Grpc/OrderingService.cs | 2 +- .../Infrastructure/OrderingContextSeed.cs | 14 ++++---- .../Services/GracePeriodManagerService.cs | 4 +-- .../AggregatesModel/OrderAggregate/Address.cs | 10 +++--- .../OrderAggregate/OrderStatus.cs | 6 ++-- ...aitingValidationIntegrationEventHandler.cs | 2 +- ...angedToCancelledIntegrationEventHandler.cs | 2 +- ...tusChangedToPaidIntegrationEventHandler.cs | 2 +- ...ChangedToShippedIntegrationEventHandler.cs | 2 +- ...ToStockConfirmedIntegrationEventHandler.cs | 2 +- ...angedToSubmittedIntegrationEventHandler.cs | 2 +- .../Application/OrdersWebApiTest.cs | 4 +-- ...ToStockConfirmedIntegrationEventHandler.cs | 4 +-- .../WebMVC/Controllers/AccountController.cs | 2 +- .../WebMVC/Extensions/HttpClientExtensions.cs | 2 +- .../Server/Infrastructure/WebContextSeed.cs | 4 +-- 51 files changed, 105 insertions(+), 114 deletions(-) diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/GrpcExceptionInterceptor.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/GrpcExceptionInterceptor.cs index c434074d3..ec159a0ea 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/GrpcExceptionInterceptor.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Infrastructure/GrpcExceptionInterceptor.cs @@ -28,7 +28,7 @@ public class GrpcExceptionInterceptor : Interceptor } catch (RpcException e) { - _logger.LogError("Error calling via grpc: {Status} - {Message}", e.Status, e.Message); + _logger.LogError(e, "Error calling via gRPC: {Status}", e.Status); return default; } } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Infrastructure/GrpcExceptionInterceptor.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Infrastructure/GrpcExceptionInterceptor.cs index 20adb2fc7..9611c6177 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Infrastructure/GrpcExceptionInterceptor.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Infrastructure/GrpcExceptionInterceptor.cs @@ -28,7 +28,7 @@ public class GrpcExceptionInterceptor : Interceptor } catch (RpcException e) { - _logger.LogError("Error calling via grpc: {Status} - {Message}", e.Status, e.Message); + _logger.LogError(e, "Error calling via gRPC: {Status}", e.Status); return default; } } diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/DefaultRabbitMQPersistentConnection.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/DefaultRabbitMQPersistentConnection.cs index 48714cd2f..4f3f573f5 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/DefaultRabbitMQPersistentConnection.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/DefaultRabbitMQPersistentConnection.cs @@ -59,7 +59,7 @@ public class DefaultRabbitMQPersistentConnection .Or() .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) => { - _logger.LogWarning(ex, "RabbitMQ Client could not connect after {TimeOut}s ({ExceptionMessage})", $"{time.TotalSeconds:n1}", ex.Message); + _logger.LogWarning(ex, "RabbitMQ Client could not connect after {TimeOut}s", $"{time.TotalSeconds:n1}"); } ); @@ -81,7 +81,7 @@ public class DefaultRabbitMQPersistentConnection } else { - _logger.LogCritical("FATAL ERROR: RabbitMQ connections could not be created and opened"); + _logger.LogCritical("Fatal error: RabbitMQ connections could not be created and opened"); return false; } diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs index 8826b88e6..aa4dc17ef 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs @@ -57,7 +57,7 @@ public class EventBusRabbitMQ : IEventBus, IDisposable .Or() .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) => { - _logger.LogWarning(ex, "Could not publish event: {EventId} after {Timeout}s ({ExceptionMessage})", @event.Id, $"{time.TotalSeconds:n1}", ex.Message); + _logger.LogWarning(ex, "Could not publish event: {EventId} after {Timeout}s", @event.Id, $"{time.TotalSeconds:n1}"); }); var eventName = @event.GetType().Name; @@ -193,7 +193,7 @@ public class EventBusRabbitMQ : IEventBus, IDisposable } catch (Exception ex) { - _logger.LogWarning(ex, "----- ERROR Processing message \"{Message}\"", message); + _logger.LogWarning(ex, "Error Processing message \"{Message}\"", message); } // Even on exception we take the message off the queue. diff --git a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs index c409717d6..10abbfafc 100644 --- a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs +++ b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs @@ -140,7 +140,7 @@ public class EventBusServiceBus : IEventBus, IAsyncDisposable var ex = args.Exception; var context = args.ErrorSource; - _logger.LogError(ex, "ERROR handling message: {ExceptionMessage} - Context: {@ExceptionContext}", ex.Message, context); + _logger.LogError(ex, "Error handling message - Context: {@ExceptionContext}", context); return Task.CompletedTask; } diff --git a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs index aff7df81b..f4dbee68e 100644 --- a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs +++ b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs @@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Hosting sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), onRetry: (exception, timeSpan, retry, ctx) => { - logger.LogWarning(exception, "[{prefix}] Exception {ExceptionType} with message {Message} detected on attempt {retry} of {retries}", nameof(TContext), exception.GetType().Name, exception.Message, retry, retries); + logger.LogWarning(exception, "[{prefix}] Error migrating database (attempt {retry} of {retries})", nameof(TContext), retry, retries); }); //if the sql server container is not created on run docker compose this diff --git a/src/Services/Basket/Basket.API/Controllers/BasketController.cs b/src/Services/Basket/Basket.API/Controllers/BasketController.cs index 4bb3b22f6..b971c96e9 100644 --- a/src/Services/Basket/Basket.API/Controllers/BasketController.cs +++ b/src/Services/Basket/Basket.API/Controllers/BasketController.cs @@ -71,7 +71,7 @@ public class BasketController : ControllerBase } catch (Exception ex) { - _logger.LogError(ex, "ERROR Publishing integration event: {IntegrationEventId}", eventMessage.Id); + _logger.LogError(ex, "Error Publishing integration event: {IntegrationEventId}", eventMessage.Id); throw; } diff --git a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs index df18a065c..8796197c0 100644 --- a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs +++ b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/OrderStartedIntegrationEventHandler.cs @@ -17,7 +17,7 @@ public class OrderStartedIntegrationEventHandler : IIntegrationEventHandler> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); await _repository.DeleteBasketAsync(@event.UserId.ToString()); } diff --git a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs index cff2faa05..94c39cd5e 100644 --- a/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs +++ b/src/Services/Basket/Basket.API/IntegrationEvents/EventHandling/ProductPriceChangedIntegrationEventHandler.cs @@ -17,7 +17,7 @@ public class ProductPriceChangedIntegrationEventHandler : IIntegrationEventHandl { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var userIds = _repository.GetUsers(); @@ -36,7 +36,7 @@ public class ProductPriceChangedIntegrationEventHandler : IIntegrationEventHandl if (itemsToUpdate != null) { - _logger.LogInformation("----- ProductPriceChangedIntegrationEventHandler - Updating items in basket for user: {BuyerId} ({@Items})", basket.BuyerId, itemsToUpdate); + _logger.LogInformation("ProductPriceChangedIntegrationEventHandler - Updating items in basket for user: {BuyerId} ({@Items})", basket.BuyerId, itemsToUpdate); foreach (var item in itemsToUpdate) { diff --git a/src/Services/Basket/Basket.UnitTests/Application/CartControllerTest.cs b/src/Services/Basket/Basket.UnitTests/Application/CartControllerTest.cs index 4231d6a9e..44d565f39 100644 --- a/src/Services/Basket/Basket.UnitTests/Application/CartControllerTest.cs +++ b/src/Services/Basket/Basket.UnitTests/Application/CartControllerTest.cs @@ -79,7 +79,7 @@ public class CartControllerTest //Arrange var fakeCatalogItem = GetFakeCatalogItem(); - _basketServiceMock.Setup(x => x.AddItemToBasket(It.IsAny(), It.IsAny())) + _basketServiceMock.Setup(x => x.AddItemToBasket(It.IsAny(), It.IsAny())) .Returns(Task.FromResult(1)); //Act diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContextSeed.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContextSeed.cs index db154cb7f..472f392c9 100644 --- a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContextSeed.cs +++ b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContextSeed.cs @@ -60,14 +60,14 @@ public class CatalogContextSeed } catch (Exception ex) { - logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); + logger.LogError(ex, "Error reading CSV headers"); return GetPreconfiguredCatalogBrands(); } return File.ReadAllLines(csvFileCatalogBrands) .Skip(1) // skip header row - .SelectTry(x => CreateCatalogBrand(x)) - .OnCaughtException(ex => { logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); return null; }) + .SelectTry(CreateCatalogBrand) + .OnCaughtException(ex => { logger.LogError(ex, "Error creating brand while seeding database"); return null; }) .Where(x => x != null); } @@ -75,9 +75,9 @@ public class CatalogContextSeed { brand = brand.Trim('"').Trim(); - if (String.IsNullOrEmpty(brand)) + if (string.IsNullOrEmpty(brand)) { - throw new Exception("catalog Brand Name is empty"); + throw new Exception("Catalog Brand Name is empty"); } return new CatalogBrand @@ -115,14 +115,14 @@ public class CatalogContextSeed } catch (Exception ex) { - logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); + logger.LogError(ex, "Error reading CSV headers"); return GetPreconfiguredCatalogTypes(); } return File.ReadAllLines(csvFileCatalogTypes) .Skip(1) // skip header row .SelectTry(x => CreateCatalogType(x)) - .OnCaughtException(ex => { logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); return null; }) + .OnCaughtException(ex => { logger.LogError(ex, "Error creating catalog type while seeding database"); return null; }) .Where(x => x != null); } @@ -130,7 +130,7 @@ public class CatalogContextSeed { type = type.Trim('"').Trim(); - if (String.IsNullOrEmpty(type)) + if (string.IsNullOrEmpty(type)) { throw new Exception("catalog Type Name is empty"); } @@ -170,7 +170,7 @@ public class CatalogContextSeed } catch (Exception ex) { - logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); + logger.LogError(ex, "Error reading CSV headers"); return GetPreconfiguredItems(); } @@ -181,11 +181,11 @@ public class CatalogContextSeed .Skip(1) // skip header row .Select(row => Regex.Split(row, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)")) .SelectTry(column => CreateCatalogItem(column, csvheaders, catalogTypeIdLookup, catalogBrandIdLookup)) - .OnCaughtException(ex => { logger.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); return null; }) + .OnCaughtException(ex => { logger.LogError(ex, "Error creating catalog item while seeding database"); return null; }) .Where(x => x != null); } - private CatalogItem CreateCatalogItem(string[] column, string[] headers, Dictionary catalogTypeIdLookup, Dictionary catalogBrandIdLookup) + private CatalogItem CreateCatalogItem(string[] column, string[] headers, Dictionary catalogTypeIdLookup, Dictionary catalogBrandIdLookup) { if (column.Count() != headers.Count()) { @@ -205,7 +205,7 @@ public class CatalogContextSeed } string priceString = column[Array.IndexOf(headers, "price")].Trim('"').Trim(); - if (!Decimal.TryParse(priceString, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out Decimal price)) + if (!decimal.TryParse(priceString, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out decimal price)) { throw new Exception($"price={priceString}is not a valid decimal number"); } @@ -224,7 +224,7 @@ public class CatalogContextSeed if (availableStockIndex != -1) { string availableStockString = column[availableStockIndex].Trim('"').Trim(); - if (!String.IsNullOrEmpty(availableStockString)) + if (!string.IsNullOrEmpty(availableStockString)) { if (int.TryParse(availableStockString, out int availableStock)) { @@ -241,7 +241,7 @@ public class CatalogContextSeed if (restockThresholdIndex != -1) { string restockThresholdString = column[restockThresholdIndex].Trim('"').Trim(); - if (!String.IsNullOrEmpty(restockThresholdString)) + if (!string.IsNullOrEmpty(restockThresholdString)) { if (int.TryParse(restockThresholdString, out int restockThreshold)) { @@ -258,7 +258,7 @@ public class CatalogContextSeed if (maxStockThresholdIndex != -1) { string maxStockThresholdString = column[maxStockThresholdIndex].Trim('"').Trim(); - if (!String.IsNullOrEmpty(maxStockThresholdString)) + if (!string.IsNullOrEmpty(maxStockThresholdString)) { if (int.TryParse(maxStockThresholdString, out int maxStockThreshold)) { @@ -275,7 +275,7 @@ public class CatalogContextSeed if (onReorderIndex != -1) { string onReorderString = column[onReorderIndex].Trim('"').Trim(); - if (!String.IsNullOrEmpty(onReorderString)) + if (!string.IsNullOrEmpty(onReorderString)) { if (bool.TryParse(onReorderString, out bool onReorder)) { @@ -361,7 +361,7 @@ public class CatalogContextSeed sleepDurationProvider: retry => TimeSpan.FromSeconds(5), onRetry: (exception, timeSpan, retry, ctx) => { - logger.LogWarning(exception, "[{prefix}] Exception {ExceptionType} with message {Message} detected on attempt {retry} of {retries}", prefix, exception.GetType().Name, exception.Message, retry, retries); + logger.LogWarning(exception, "[{prefix}] Error seeding database (attempt {retry} of {retries})", prefix, retry, retries); } ); } diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs index 15cbb7ff7..44c7b8c75 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs @@ -26,7 +26,7 @@ public class CatalogIntegrationEventService : ICatalogIntegrationEventService, I { try { - _logger.LogInformation("----- Publishing integration event: {IntegrationEventId_published} - ({@IntegrationEvent})", evt.Id, evt); + _logger.LogInformation("Publishing integration event: {IntegrationEventId_published} - ({@IntegrationEvent})", evt.Id, evt); await _eventLogService.MarkEventAsInProgressAsync(evt.Id); _eventBus.Publish(evt); @@ -34,14 +34,14 @@ public class CatalogIntegrationEventService : ICatalogIntegrationEventService, I } catch (Exception ex) { - _logger.LogError(ex, "ERROR Publishing integration event: {IntegrationEventId} - ({@IntegrationEvent})", evt.Id, evt); + _logger.LogError(ex, "Error Publishing integration event: {IntegrationEventId} - ({@IntegrationEvent})", evt.Id, evt); await _eventLogService.MarkEventAsFailedAsync(evt.Id); } } public async Task SaveEventAndCatalogContextChangesAsync(IntegrationEvent evt) { - _logger.LogInformation("----- CatalogIntegrationEventService - Saving changes and integrationEvent: {IntegrationEventId}", evt.Id); + _logger.LogInformation("CatalogIntegrationEventService - Saving changes and integrationEvent: {IntegrationEventId}", evt.Id); //Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction(): //See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs index fb79b96e9..6ad0a3867 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs @@ -21,7 +21,7 @@ public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler : { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var confirmedOrderStockItems = new List(); diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs index 99b755568..48e7fe571 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs @@ -18,7 +18,7 @@ public class OrderStatusChangedToPaidIntegrationEventHandler : { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); //we're not blocking stock/inventory foreach (var orderStockItem in @event.OrderStockItems) diff --git a/src/Services/Identity/Identity.API/IWebHostExtensions.cs b/src/Services/Identity/Identity.API/IWebHostExtensions.cs index 734ae3fde..a9e002d74 100644 --- a/src/Services/Identity/Identity.API/IWebHostExtensions.cs +++ b/src/Services/Identity/Identity.API/IWebHostExtensions.cs @@ -1,4 +1,4 @@ -namespace Microsoft.AspNetCore.Hosting +namespace Microsoft.AspNetCore.Hosting { public static class IWebHostExtensions { @@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Hosting sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), onRetry: (exception, timeSpan, retry, ctx) => { - logger.LogWarning(exception, "[{prefix}] Exception {ExceptionType} with message {Message} detected on attempt {retry} of {retries}", nameof(TContext), exception.GetType().Name, exception.Message, retry, retries); + logger.LogWarning(exception, "[{prefix}] Error seeding database (attempt {retry} of {retries})", nameof(TContext), retry, retries); }); //if the sql server container is not created on run docker compose this diff --git a/src/Services/Identity/Identity.API/Quickstart/Account/LoginViewModel.cs b/src/Services/Identity/Identity.API/Quickstart/Account/LoginViewModel.cs index 753f4773e..f539c70e9 100644 --- a/src/Services/Identity/Identity.API/Quickstart/Account/LoginViewModel.cs +++ b/src/Services/Identity/Identity.API/Quickstart/Account/LoginViewModel.cs @@ -10,7 +10,7 @@ public class LoginViewModel : LoginInputModel public bool EnableLocalLogin { get; set; } = true; public IEnumerable ExternalProviders { get; set; } = Enumerable.Empty(); - public IEnumerable VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName)); + public IEnumerable VisibleExternalProviders => ExternalProviders.Where(x => !string.IsNullOrWhiteSpace(x.DisplayName)); public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1; public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null; diff --git a/src/Services/Identity/Identity.API/Quickstart/Consent/ConsentController.cs b/src/Services/Identity/Identity.API/Quickstart/Consent/ConsentController.cs index 1255df44a..2cdf323ec 100644 --- a/src/Services/Identity/Identity.API/Quickstart/Consent/ConsentController.cs +++ b/src/Services/Identity/Identity.API/Quickstart/Consent/ConsentController.cs @@ -217,7 +217,7 @@ public class ConsentController : Controller public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check) { var displayName = apiScope.DisplayName ?? apiScope.Name; - if (!String.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter)) + if (!string.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter)) { displayName += ":" + parsedScopeValue.ParsedParameter; } diff --git a/src/Services/Identity/Identity.API/SeedData.cs b/src/Services/Identity/Identity.API/SeedData.cs index 1ce95871f..b8f5baa5b 100644 --- a/src/Services/Identity/Identity.API/SeedData.cs +++ b/src/Services/Identity/Identity.API/SeedData.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Identity.API; +namespace Microsoft.eShopOnContainers.Services.Identity.API; public class SeedData { @@ -104,16 +104,7 @@ public class SeedData return Policy.Handle(). WaitAndRetryForeverAsync( sleepDurationProvider: retry => TimeSpan.FromSeconds(5), - onRetry: (exception, retry, timeSpan) => - { - logger.LogWarning( - exception, - "Exception {ExceptionType} with message {Message} detected during database migration (retry attempt {retry})", - exception.GetType().Name, - exception.Message, - retry); - } - ); + onRetry: (exception, retry, timeSpan) => logger.LogWarning(exception, "Error migrating database (retry attempt {retry})", retry)); } return Policy.NoOpAsync(); diff --git a/src/Services/Ordering/Ordering.API/Application/Behaviors/LoggingBehavior.cs b/src/Services/Ordering/Ordering.API/Application/Behaviors/LoggingBehavior.cs index 9ed7d1772..838697c8c 100644 --- a/src/Services/Ordering/Ordering.API/Application/Behaviors/LoggingBehavior.cs +++ b/src/Services/Ordering/Ordering.API/Application/Behaviors/LoggingBehavior.cs @@ -6,9 +6,9 @@ public class LoggingBehavior : IPipelineBehavior Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) { - _logger.LogInformation("----- Handling command {CommandName} ({@Command})", request.GetGenericTypeName(), request); + _logger.LogInformation("Handling command {CommandName} ({@Command})", request.GetGenericTypeName(), request); var response = await next(); - _logger.LogInformation("----- Command {CommandName} handled - response: {@Response}", request.GetGenericTypeName(), response); + _logger.LogInformation("Command {CommandName} handled - response: {@Response}", request.GetGenericTypeName(), response); return response; } diff --git a/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehavior.cs b/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehavior.cs index c27865a1e..acebd9cda 100644 --- a/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehavior.cs +++ b/src/Services/Ordering/Ordering.API/Application/Behaviors/TransactionBehavior.cs @@ -38,11 +38,11 @@ public class TransactionBehavior : IPipelineBehavior> { new ("TransactionContext", transaction.TransactionId) })) { - _logger.LogInformation("----- Begin transaction {TransactionId} for {CommandName} ({@Command})", transaction.TransactionId, typeName, request); + _logger.LogInformation("Begin transaction {TransactionId} for {CommandName} ({@Command})", transaction.TransactionId, typeName, request); response = await next(); - _logger.LogInformation("----- Commit transaction {TransactionId} for {CommandName}", transaction.TransactionId, typeName); + _logger.LogInformation("Commit transaction {TransactionId} for {CommandName}", transaction.TransactionId, typeName); await _dbContext.CommitTransactionAsync(transaction); @@ -56,7 +56,7 @@ public class TransactionBehavior : IPipelineBehavior : IPipelineBehavior v.Validate(request)) diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs index e445e5de1..b1b5be3dd 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs @@ -44,7 +44,7 @@ public class CreateOrderCommandHandler order.AddOrderItem(item.ProductId, item.ProductName, item.UnitPrice, item.Discount, item.PictureUrl, item.Units); } - _logger.LogInformation("----- Creating Order - Order: {@Order}", order); + _logger.LogInformation("Creating Order - Order: {@Order}", order); _orderRepository.Add(order); diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs index 3864da446..0852bdc10 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/IdentifiedCommandHandler.cs @@ -77,7 +77,7 @@ public abstract class IdentifiedCommandHandler : IRequestHandler : IRequestHandler> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var command = new SetAwaitingValidationOrderStatusCommand(@event.OrderId); _logger.LogInformation( - "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", + "Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", command.GetGenericTypeName(), nameof(command.OrderNumber), command.OrderNumber, diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs index 870d63d60..6982a5a25 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs @@ -18,12 +18,12 @@ public class OrderPaymentFailedIntegrationEventHandler : { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var command = new CancelOrderCommand(@event.OrderId); _logger.LogInformation( - "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", + "Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", command.GetGenericTypeName(), nameof(command.OrderNumber), command.OrderNumber, diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSucceededIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSucceededIntegrationEventHandler.cs index e1e6a9e86..31606ead2 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSucceededIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSucceededIntegrationEventHandler.cs @@ -18,12 +18,12 @@ public class OrderPaymentSucceededIntegrationEventHandler : { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var command = new SetPaidOrderStatusCommand(@event.OrderId); _logger.LogInformation( - "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", + "Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", command.GetGenericTypeName(), nameof(command.OrderNumber), command.OrderNumber, diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs index 68f2ec066..a9faea465 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs @@ -18,12 +18,12 @@ public class OrderStockConfirmedIntegrationEventHandler : { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var command = new SetStockConfirmedOrderStatusCommand(@event.OrderId); _logger.LogInformation( - "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", + "Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", command.GetGenericTypeName(), nameof(command.OrderNumber), command.OrderNumber, diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs index 4fa90ae0d..0d47e7a84 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs @@ -16,7 +16,7 @@ public class OrderStockRejectedIntegrationEventHandler : IIntegrationEventHandle { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var orderStockRejectedItems = @event.OrderStockItems .FindAll(c => !c.HasStock) @@ -26,7 +26,7 @@ public class OrderStockRejectedIntegrationEventHandler : IIntegrationEventHandle var command = new SetStockRejectedOrderStatusCommand(@event.OrderId, orderStockRejectedItems); _logger.LogInformation( - "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", + "Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", command.GetGenericTypeName(), nameof(command.OrderNumber), command.OrderNumber, diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs index d30ad98b5..731bc986f 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs @@ -26,7 +26,7 @@ public class UserCheckoutAcceptedIntegrationEventHandler : IIntegrationEventHand { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); var result = false; @@ -42,7 +42,7 @@ public class UserCheckoutAcceptedIntegrationEventHandler : IIntegrationEventHand var requestCreateOrder = new IdentifiedCommand(createOrderCommand, @event.RequestId); _logger.LogInformation( - "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", + "Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", requestCreateOrder.GetGenericTypeName(), nameof(requestCreateOrder.Id), requestCreateOrder.Id, @@ -52,7 +52,7 @@ public class UserCheckoutAcceptedIntegrationEventHandler : IIntegrationEventHand if (result) { - _logger.LogInformation("----- CreateOrderCommand suceeded - RequestId: {RequestId}", @event.RequestId); + _logger.LogInformation("CreateOrderCommand suceeded - RequestId: {RequestId}", @event.RequestId); } else { diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs index a38179f5f..29e9a7ab4 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs @@ -27,7 +27,7 @@ public class OrderingIntegrationEventService : IOrderingIntegrationEventService foreach (var logEvt in pendingLogEvents) { - _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} - ({@IntegrationEvent})", logEvt.EventId, logEvt.IntegrationEvent); + _logger.LogInformation("Publishing integration event: {IntegrationEventId} - ({@IntegrationEvent})", logEvt.EventId, logEvt.IntegrationEvent); try { @@ -37,7 +37,7 @@ public class OrderingIntegrationEventService : IOrderingIntegrationEventService } catch (Exception ex) { - _logger.LogError(ex, "ERROR publishing integration event: {IntegrationEventId}", logEvt.EventId); + _logger.LogError(ex, "Error publishing integration event: {IntegrationEventId}", logEvt.EventId); await _eventLogService.MarkEventAsFailedAsync(logEvt.EventId); } @@ -46,7 +46,7 @@ public class OrderingIntegrationEventService : IOrderingIntegrationEventService public async Task AddAndSaveEventAsync(IntegrationEvent evt) { - _logger.LogInformation("----- Enqueuing integration event {IntegrationEventId} to repository ({@IntegrationEvent})", evt.Id, evt); + _logger.LogInformation("Enqueuing integration event {IntegrationEventId} to repository ({@IntegrationEvent})", evt.Id, evt); await _eventLogService.SaveEventAsync(evt, _orderingContext.GetCurrentTransaction()); } diff --git a/src/Services/Ordering/Ordering.API/Application/Validations/CancelOrderCommandValidator.cs b/src/Services/Ordering/Ordering.API/Application/Validations/CancelOrderCommandValidator.cs index 7d901b1fe..80fbcfcc4 100644 --- a/src/Services/Ordering/Ordering.API/Application/Validations/CancelOrderCommandValidator.cs +++ b/src/Services/Ordering/Ordering.API/Application/Validations/CancelOrderCommandValidator.cs @@ -6,6 +6,6 @@ public class CancelOrderCommandValidator : AbstractValidator { RuleFor(order => order.OrderNumber).NotEmpty().WithMessage("No orderId found"); - logger.LogTrace("----- INSTANCE CREATED - {ClassName}", GetType().Name); + logger.LogTrace("INSTANCE CREATED - {ClassName}", GetType().Name); } } diff --git a/src/Services/Ordering/Ordering.API/Application/Validations/CreateOrderCommandValidator.cs b/src/Services/Ordering/Ordering.API/Application/Validations/CreateOrderCommandValidator.cs index eb61082e7..51953b25d 100644 --- a/src/Services/Ordering/Ordering.API/Application/Validations/CreateOrderCommandValidator.cs +++ b/src/Services/Ordering/Ordering.API/Application/Validations/CreateOrderCommandValidator.cs @@ -18,7 +18,7 @@ public class CreateOrderCommandValidator : AbstractValidator RuleFor(command => command.CardTypeId).NotEmpty(); RuleFor(command => command.OrderItems).Must(ContainOrderItems).WithMessage("No order items found"); - logger.LogTrace("----- INSTANCE CREATED - {ClassName}", GetType().Name); + logger.LogTrace("INSTANCE CREATED - {ClassName}", GetType().Name); } private bool BeValidExpirationDate(DateTime dateTime) diff --git a/src/Services/Ordering/Ordering.API/Application/Validations/IdentifiedCommandValidator.cs b/src/Services/Ordering/Ordering.API/Application/Validations/IdentifiedCommandValidator.cs index bde2d771f..4d98fc14c 100644 --- a/src/Services/Ordering/Ordering.API/Application/Validations/IdentifiedCommandValidator.cs +++ b/src/Services/Ordering/Ordering.API/Application/Validations/IdentifiedCommandValidator.cs @@ -6,6 +6,6 @@ public class IdentifiedCommandValidator : AbstractValidator command.Id).NotEmpty(); - logger.LogTrace("----- INSTANCE CREATED - {ClassName}", GetType().Name); + logger.LogTrace("INSTANCE CREATED - {ClassName}", GetType().Name); } } diff --git a/src/Services/Ordering/Ordering.API/Application/Validations/ShipOrderCommandValidator.cs b/src/Services/Ordering/Ordering.API/Application/Validations/ShipOrderCommandValidator.cs index 0341c6028..dea55a4e3 100644 --- a/src/Services/Ordering/Ordering.API/Application/Validations/ShipOrderCommandValidator.cs +++ b/src/Services/Ordering/Ordering.API/Application/Validations/ShipOrderCommandValidator.cs @@ -6,6 +6,6 @@ public class ShipOrderCommandValidator : AbstractValidator { RuleFor(order => order.OrderNumber).NotEmpty().WithMessage("No orderId found"); - logger.LogTrace("----- INSTANCE CREATED - {ClassName}", GetType().Name); + logger.LogTrace("INSTANCE CREATED - {ClassName}", GetType().Name); } } diff --git a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs index 2cfd4063f..5b9ca5f70 100644 --- a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs +++ b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs @@ -40,7 +40,7 @@ public class OrdersController : ControllerBase var requestCancelOrder = new IdentifiedCommand(command, guid); _logger.LogInformation( - "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", + "Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", requestCancelOrder.GetGenericTypeName(), nameof(requestCancelOrder.Command.OrderNumber), requestCancelOrder.Command.OrderNumber, @@ -70,7 +70,7 @@ public class OrdersController : ControllerBase var requestShipOrder = new IdentifiedCommand(command, guid); _logger.LogInformation( - "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", + "Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", requestShipOrder.GetGenericTypeName(), nameof(requestShipOrder.Command.OrderNumber), requestShipOrder.Command.OrderNumber, @@ -132,7 +132,7 @@ public class OrdersController : ControllerBase public async Task> CreateOrderDraftFromBasketDataAsync([FromBody] CreateOrderDraftCommand createOrderDraftCommand) { _logger.LogInformation( - "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", + "Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", createOrderDraftCommand.GetGenericTypeName(), nameof(createOrderDraftCommand.BuyerId), createOrderDraftCommand.BuyerId, diff --git a/src/Services/Ordering/Ordering.API/Grpc/OrderingService.cs b/src/Services/Ordering/Ordering.API/Grpc/OrderingService.cs index 28f1a183d..23525d5bf 100644 --- a/src/Services/Ordering/Ordering.API/Grpc/OrderingService.cs +++ b/src/Services/Ordering/Ordering.API/Grpc/OrderingService.cs @@ -20,7 +20,7 @@ public class OrderingService : OrderingGrpc.OrderingGrpcBase { _logger.LogInformation("Begin grpc call from method {Method} for ordering get order draft {CreateOrderDraftCommand}", context.Method, createOrderDraftCommand); _logger.LogTrace( - "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", + "Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", createOrderDraftCommand.GetGenericTypeName(), nameof(createOrderDraftCommand.BuyerId), createOrderDraftCommand.BuyerId, diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs b/src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs index c392bb00d..d7f8663fd 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs @@ -59,7 +59,7 @@ public class OrderingContextSeed } catch (Exception ex) { - log.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); + log.LogError(ex, "Error reading CSV headers"); return GetPredefinedCardTypes(); } @@ -67,13 +67,13 @@ public class OrderingContextSeed return File.ReadAllLines(csvFileCardTypes) .Skip(1) // skip header column .SelectTry(x => CreateCardType(x, ref id)) - .OnCaughtException(ex => { log.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); return null; }) + .OnCaughtException(ex => { log.LogError(ex, "Error creating card while seeding database"); return null; }) .Where(x => x != null); } private CardType CreateCardType(string value, ref int id) { - if (String.IsNullOrEmpty(value)) + if (string.IsNullOrEmpty(value)) { throw new Exception("Orderstatus is null or empty"); } @@ -103,7 +103,7 @@ public class OrderingContextSeed } catch (Exception ex) { - log.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); + log.LogError(ex, "Error reading CSV headers"); return GetPredefinedOrderStatus(); } @@ -111,13 +111,13 @@ public class OrderingContextSeed return File.ReadAllLines(csvFileOrderStatus) .Skip(1) // skip header row .SelectTry(x => CreateOrderStatus(x, ref id)) - .OnCaughtException(ex => { log.LogError(ex, "EXCEPTION ERROR: {Message}", ex.Message); return null; }) + .OnCaughtException(ex => { log.LogError(ex, "Error creating order status while seeding database"); return null; }) .Where(x => x != null); } private OrderStatus CreateOrderStatus(string value, ref int id) { - if (String.IsNullOrEmpty(value)) + if (string.IsNullOrEmpty(value)) { throw new Exception("Orderstatus is null or empty"); } @@ -167,7 +167,7 @@ public class OrderingContextSeed sleepDurationProvider: retry => TimeSpan.FromSeconds(5), onRetry: (exception, timeSpan, retry, ctx) => { - logger.LogWarning(exception, "[{prefix}] Exception {ExceptionType} with message {Message} detected on attempt {retry} of {retries}", prefix, exception.GetType().Name, exception.Message, retry, retries); + logger.LogWarning(exception, "[{prefix}] Error seeding database (attempt {retry} of {retries})", prefix, retry, retries); } ); } diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Services/GracePeriodManagerService.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Services/GracePeriodManagerService.cs index a801ac831..bded89eb9 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Services/GracePeriodManagerService.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Services/GracePeriodManagerService.cs @@ -52,7 +52,7 @@ namespace Ordering.BackgroundTasks.Services { var confirmGracePeriodEvent = new GracePeriodConfirmedIntegrationEvent(orderId); - _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} - ({@IntegrationEvent})", confirmGracePeriodEvent.Id, confirmGracePeriodEvent); + _logger.LogInformation("Publishing integration event: {IntegrationEventId} - ({@IntegrationEvent})", confirmGracePeriodEvent.Id, confirmGracePeriodEvent); _eventBus.Publish(confirmGracePeriodEvent); } @@ -74,7 +74,7 @@ namespace Ordering.BackgroundTasks.Services } catch (SqlException exception) { - _logger.LogCritical(exception, "FATAL ERROR: Database connections could not be opened: {Message}", exception.Message); + _logger.LogCritical(exception, "Fatal error establishing database connection"); } diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs index c58f81b16..0d4b819ae 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs @@ -4,11 +4,11 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O public class Address : ValueObject { - public String Street { get; private set; } - public String City { get; private set; } - public String State { get; private set; } - public String Country { get; private set; } - public String ZipCode { get; private set; } + public string Street { get; private set; } + public string City { get; private set; } + public string State { get; private set; } + public string Country { get; private set; } + public string ZipCode { get; private set; } public Address() { } diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs index aae09bc6a..8c3cc50fb 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs @@ -23,11 +23,11 @@ public class OrderStatus public static OrderStatus FromName(string name) { var state = List() - .SingleOrDefault(s => String.Equals(s.Name, name, StringComparison.CurrentCultureIgnoreCase)); + .SingleOrDefault(s => string.Equals(s.Name, name, StringComparison.CurrentCultureIgnoreCase)); if (state == null) { - throw new OrderingDomainException($"Possible values for OrderStatus: {String.Join(",", List().Select(s => s.Name))}"); + throw new OrderingDomainException($"Possible values for OrderStatus: {string.Join(",", List().Select(s => s.Name))}"); } return state; @@ -39,7 +39,7 @@ public class OrderStatus if (state == null) { - throw new OrderingDomainException($"Possible values for OrderStatus: {String.Join(",", List().Select(s => s.Name))}"); + throw new OrderingDomainException($"Possible values for OrderStatus: {string.Join(",", List().Select(s => s.Name))}"); } return state; diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs index 9c460365c..4210830dc 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs @@ -18,7 +18,7 @@ public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler : IIn { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); await _hubContext.Clients .Group(@event.BuyerName) diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs index 1c3ea4623..d0642702a 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToCancelledIntegrationEventHandler.cs @@ -20,7 +20,7 @@ public class OrderStatusChangedToCancelledIntegrationEventHandler : IIntegration { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); await _hubContext.Clients .Group(@event.BuyerName) diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs index fe66f7dbe..5b96fd7da 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs @@ -20,7 +20,7 @@ public class OrderStatusChangedToPaidIntegrationEventHandler : IIntegrationEvent { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); await _hubContext.Clients .Group(@event.BuyerName) diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs index 2f612bbfb..283c6f8a2 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToShippedIntegrationEventHandler.cs @@ -17,7 +17,7 @@ public class OrderStatusChangedToShippedIntegrationEventHandler : IIntegrationEv { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); await _hubContext.Clients .Group(@event.BuyerName) diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs index 7deb6c854..eea86552d 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs @@ -21,7 +21,7 @@ public class OrderStatusChangedToStockConfirmedIntegrationEventHandler : { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); await _hubContext.Clients .Group(@event.BuyerName) diff --git a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs index 0fa7ad8a5..7a536971c 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/IntegrationEvents/EventHandling/OrderStatusChangedToSubmittedIntegrationEventHandler.cs @@ -21,7 +21,7 @@ public class OrderStatusChangedToSubmittedIntegrationEventHandler : { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); await _hubContext.Clients .Group(@event.BuyerName) diff --git a/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs b/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs index df6004e17..bb8f8844b 100644 --- a/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs +++ b/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs @@ -42,7 +42,7 @@ public class OrdersWebApiTest //Act var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object, _loggerMock.Object); - var actionResult = await orderController.CancelOrderAsync(new CancelOrderCommand(1), String.Empty) as BadRequestResult; + var actionResult = await orderController.CancelOrderAsync(new CancelOrderCommand(1), string.Empty) as BadRequestResult; //Assert Assert.Equal((int)System.Net.HttpStatusCode.BadRequest, actionResult.StatusCode); @@ -73,7 +73,7 @@ public class OrdersWebApiTest //Act var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object, _loggerMock.Object); - var actionResult = await orderController.ShipOrderAsync(new ShipOrderCommand(1), String.Empty) as BadRequestResult; + var actionResult = await orderController.ShipOrderAsync(new ShipOrderCommand(1), string.Empty) as BadRequestResult; //Assert Assert.Equal((int)System.Net.HttpStatusCode.BadRequest, actionResult.StatusCode); diff --git a/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs b/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs index d88bad3db..c68ab0959 100644 --- a/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs @@ -25,7 +25,7 @@ public class OrderStatusChangedToStockConfirmedIntegrationEventHandler : { using (_logger.BeginScope(new List> { new ("IntegrationEventContext", @event.Id) })) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); + _logger.LogInformation("Handling integration event: {IntegrationEventId} - ({@IntegrationEvent})", @event.Id, @event); IntegrationEvent orderPaymentIntegrationEvent; @@ -44,7 +44,7 @@ public class OrderStatusChangedToStockConfirmedIntegrationEventHandler : orderPaymentIntegrationEvent = new OrderPaymentFailedIntegrationEvent(@event.OrderId); } - _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} - ({@IntegrationEvent})", orderPaymentIntegrationEvent.Id, orderPaymentIntegrationEvent); + _logger.LogInformation("Publishing integration event: {IntegrationEventId} - ({@IntegrationEvent})", orderPaymentIntegrationEvent.Id, orderPaymentIntegrationEvent); _eventBus.Publish(orderPaymentIntegrationEvent); diff --git a/src/Web/WebMVC/Controllers/AccountController.cs b/src/Web/WebMVC/Controllers/AccountController.cs index 9daf98275..f86a6e200 100644 --- a/src/Web/WebMVC/Controllers/AccountController.cs +++ b/src/Web/WebMVC/Controllers/AccountController.cs @@ -16,7 +16,7 @@ public class AccountController : Controller var user = User as ClaimsPrincipal; var token = await HttpContext.GetTokenAsync("access_token"); - _logger.LogInformation("----- User {@User} authenticated", user); + _logger.LogInformation("User {@User} authenticated", user); if (token != null) { diff --git a/src/Web/WebMVC/Extensions/HttpClientExtensions.cs b/src/Web/WebMVC/Extensions/HttpClientExtensions.cs index d1b11c9f7..3c95e0254 100644 --- a/src/Web/WebMVC/Extensions/HttpClientExtensions.cs +++ b/src/Web/WebMVC/Extensions/HttpClientExtensions.cs @@ -21,7 +21,7 @@ public class BasicAuthenticationHeaderValue : AuthenticationHeaderValue private static string EncodeCredential(string userName, string password) { Encoding encoding = Encoding.GetEncoding("iso-8859-1"); - string credential = String.Format("{0}:{1}", userName, password); + string credential = string.Format("{0}:{1}", userName, password); return Convert.ToBase64String(encoding.GetBytes(credential)); } diff --git a/src/Web/WebSPA/Server/Infrastructure/WebContextSeed.cs b/src/Web/WebSPA/Server/Infrastructure/WebContextSeed.cs index 1dc07b4f6..89f559873 100644 --- a/src/Web/WebSPA/Server/Infrastructure/WebContextSeed.cs +++ b/src/Web/WebSPA/Server/Infrastructure/WebContextSeed.cs @@ -51,13 +51,13 @@ public class WebContextSeed } else { - logger.LogWarning("Skipped file '{FileName}' in zipfile '{ZipFileName}'", entry.Name, imagesZipFile); + logger.LogWarning("Skipped file '{FileName}' in zip file '{ZipFileName}'", entry.Name, imagesZipFile); } } } catch (Exception ex) { - logger.LogError(ex, "ERROR in GetPreconfiguredImages: {Message}", ex.Message); + logger.LogError(ex, "Error getting preconfigured images"); } } } From e166b28a0a2ea1e25ae115f4e0d8deffb719527a Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 5 May 2023 15:08:40 -0700 Subject: [PATCH 067/118] Update the webhooks project to use service common --- .../Ordering/Ordering.API/appsettings.json | 1 + .../Controllers/HomeController.cs | 11 - .../Webhooks.API/CustomExtensionMethods.cs | 47 +++ .../Webhooks/Webhooks.API/GlobalUsings.cs | 42 +-- .../InternalServerErrorObjectResult.cs | 9 - .../AuthorizeCheckOperationFilter.cs | 29 -- .../HttpGlobalExceptionFilter.cs | 58 ---- src/Services/Webhooks/Webhooks.API/Program.cs | 61 ++-- .../Properties/launchSettings.json | 19 +- src/Services/Webhooks/Webhooks.API/Startup.cs | 318 ------------------ .../Webhooks/Webhooks.API/Webhooks.API.csproj | 18 +- .../Webhooks.API/appsettings.Development.json | 4 +- .../Webhooks/Webhooks.API/appsettings.json | 40 ++- 13 files changed, 144 insertions(+), 513 deletions(-) delete mode 100644 src/Services/Webhooks/Webhooks.API/Controllers/HomeController.cs create mode 100644 src/Services/Webhooks/Webhooks.API/CustomExtensionMethods.cs delete mode 100644 src/Services/Webhooks/Webhooks.API/Infrastructure/ActionResult/InternalServerErrorObjectResult.cs delete mode 100644 src/Services/Webhooks/Webhooks.API/Infrastructure/AuthorizeCheckOperationFilter.cs delete mode 100644 src/Services/Webhooks/Webhooks.API/Infrastructure/HttpGlobalExceptionFilter.cs delete mode 100644 src/Services/Webhooks/Webhooks.API/Startup.cs diff --git a/src/Services/Ordering/Ordering.API/appsettings.json b/src/Services/Ordering/Ordering.API/appsettings.json index 3f54fb3ce..7c110dc0c 100644 --- a/src/Services/Ordering/Ordering.API/appsettings.json +++ b/src/Services/Ordering/Ordering.API/appsettings.json @@ -5,6 +5,7 @@ "Microsoft.AspNetCore": "Warning" } }, + "AllowedHosts": "*", "OpenApi": { "Endpoint": { "Name": "Ordering.API V1" diff --git a/src/Services/Webhooks/Webhooks.API/Controllers/HomeController.cs b/src/Services/Webhooks/Webhooks.API/Controllers/HomeController.cs deleted file mode 100644 index 2a7951ec3..000000000 --- a/src/Services/Webhooks/Webhooks.API/Controllers/HomeController.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Webhooks.API.Controllers; - -public class HomeController : Controller -{ - // GET: // - public IActionResult Index() - { - return new RedirectResult("~/swagger"); - } - -} diff --git a/src/Services/Webhooks/Webhooks.API/CustomExtensionMethods.cs b/src/Services/Webhooks/Webhooks.API/CustomExtensionMethods.cs new file mode 100644 index 000000000..2a2f5df06 --- /dev/null +++ b/src/Services/Webhooks/Webhooks.API/CustomExtensionMethods.cs @@ -0,0 +1,47 @@ +internal static class CustomExtensionMethods +{ + public static IServiceCollection AddDbContexts(this IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext(options => + { + options.UseSqlServer(configuration.GetRequiredConnectionString("WebHooksDb"), + sqlServerOptionsAction: sqlOptions => + { + sqlOptions.MigrationsAssembly(typeof(Program).Assembly.FullName); + + //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency + sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); + }); + }); + + return services; + } + + public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) + { + var hcBuilder = services.AddHealthChecks(); + + hcBuilder + .AddSqlServer(_ => + configuration.GetRequiredConnectionString("WebHooksDb"), + name: "WebhooksApiDb-check", + tags: new string[] { "ready", "live" }); + + return services; + } + + public static IServiceCollection AddHttpClientServices(this IServiceCollection services) + { + // Add http client services + services.AddHttpClient("GrantClient") + .SetHandlerLifetime(TimeSpan.FromMinutes(5)); + + return services; + } + + public static IServiceCollection AddIntegrationServices(this IServiceCollection services) + { + return services.AddTransient>( + sp => (DbConnection c) => new IntegrationEventLogService(c)); + } +} diff --git a/src/Services/Webhooks/Webhooks.API/GlobalUsings.cs b/src/Services/Webhooks/Webhooks.API/GlobalUsings.cs index 133a01cb1..2ef5c1bd7 100644 --- a/src/Services/Webhooks/Webhooks.API/GlobalUsings.cs +++ b/src/Services/Webhooks/Webhooks.API/GlobalUsings.cs @@ -1,46 +1,28 @@ -global using HealthChecks.UI.Client; -global using Microsoft.AspNetCore.Authentication.JwtBearer; +global using System; +global using System.Collections.Generic; +global using System.ComponentModel.DataAnnotations; +global using System.Data.Common; +global using System.Linq; +global using System.Net; +global using System.Net.Http; +global using System.Text; +global using System.Text.Json; +global using System.Threading.Tasks; global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; -global using Microsoft.AspNetCore.Diagnostics.HealthChecks; global using Microsoft.AspNetCore.Hosting; global using Microsoft.AspNetCore.Http; -global using Microsoft.AspNetCore.Mvc.Filters; global using Microsoft.AspNetCore.Mvc; -global using Microsoft.AspNetCore; -global using Microsoft.EntityFrameworkCore.Design; global using Microsoft.EntityFrameworkCore; +global using Microsoft.EntityFrameworkCore.Design; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; -global using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; global using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Diagnostics.HealthChecks; -global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; -global using Microsoft.OpenApi.Models; -global using RabbitMQ.Client; -global using Swashbuckle.AspNetCore.SwaggerGen; -global using System.Collections.Generic; -global using System.ComponentModel.DataAnnotations; -global using System.Data.Common; -global using System.IdentityModel.Tokens.Jwt; -global using System.Linq; -global using System.Net.Http; -global using System.Net; -global using System.Reflection; -global using System.Text.Json; -global using System.Text; -global using System.Threading.Tasks; -global using System.Threading; -global using System; -global using Webhooks.API.Exceptions; -global using Webhooks.API.Infrastructure.ActionResult; +global using Services.Common; global using Webhooks.API.Infrastructure; global using Webhooks.API.IntegrationEvents; global using Webhooks.API.Model; global using Webhooks.API.Services; -global using Webhooks.API; diff --git a/src/Services/Webhooks/Webhooks.API/Infrastructure/ActionResult/InternalServerErrorObjectResult.cs b/src/Services/Webhooks/Webhooks.API/Infrastructure/ActionResult/InternalServerErrorObjectResult.cs deleted file mode 100644 index d71e8b55f..000000000 --- a/src/Services/Webhooks/Webhooks.API/Infrastructure/ActionResult/InternalServerErrorObjectResult.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Webhooks.API.Infrastructure.ActionResult; - -class InternalServerErrorObjectResult : ObjectResult -{ - public InternalServerErrorObjectResult(object error) : base(error) - { - StatusCode = StatusCodes.Status500InternalServerError; - } -} diff --git a/src/Services/Webhooks/Webhooks.API/Infrastructure/AuthorizeCheckOperationFilter.cs b/src/Services/Webhooks/Webhooks.API/Infrastructure/AuthorizeCheckOperationFilter.cs deleted file mode 100644 index 13b0fcbdb..000000000 --- a/src/Services/Webhooks/Webhooks.API/Infrastructure/AuthorizeCheckOperationFilter.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Webhooks.API.Infrastructure; - -public class AuthorizeCheckOperationFilter : IOperationFilter -{ - public void Apply(OpenApiOperation operation, OperationFilterContext context) - { - // Check for authorize attribute - var hasAuthorize = context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType().Any() || - context.MethodInfo.GetCustomAttributes(true).OfType().Any(); - - if (!hasAuthorize) return; - - operation.Responses.TryAdd("401", new OpenApiResponse { Description = "Unauthorized" }); - operation.Responses.TryAdd("403", new OpenApiResponse { Description = "Forbidden" }); - - var oAuthScheme = new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" } - }; - - operation.Security = new List - { - new() - { - [ oAuthScheme ] = new [] { "webhooksapi" } - } - }; - } -} diff --git a/src/Services/Webhooks/Webhooks.API/Infrastructure/HttpGlobalExceptionFilter.cs b/src/Services/Webhooks/Webhooks.API/Infrastructure/HttpGlobalExceptionFilter.cs deleted file mode 100644 index 58e2e1656..000000000 --- a/src/Services/Webhooks/Webhooks.API/Infrastructure/HttpGlobalExceptionFilter.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace Webhooks.API.Infrastructure; - -public class HttpGlobalExceptionFilter : IExceptionFilter -{ - private readonly IWebHostEnvironment _env; - private readonly ILogger _logger; - - public HttpGlobalExceptionFilter(IWebHostEnvironment env, ILogger logger) - { - _env = env; - _logger = logger; - } - - public void OnException(ExceptionContext context) - { - _logger.LogError(new EventId(context.Exception.HResult), - context.Exception, - context.Exception.Message); - - if (context.Exception.GetType() == typeof(WebhooksDomainException)) - { - var problemDetails = new ValidationProblemDetails() - { - Instance = context.HttpContext.Request.Path, - Status = StatusCodes.Status400BadRequest, - Detail = "Please refer to the errors property for additional details." - }; - - problemDetails.Errors.Add("DomainValidations", new[] { context.Exception.Message }); - - context.Result = new BadRequestObjectResult(problemDetails); - context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; - } - else - { - var json = new JsonErrorResponse - { - Messages = new[] { "An error occurred." } - }; - - if (_env.IsDevelopment()) - { - json.DeveloperMessage = context.Exception; - } - - context.Result = new InternalServerErrorObjectResult(json); - context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError; - } - context.ExceptionHandled = true; - } - - private class JsonErrorResponse - { - public string[] Messages { get; set; } - - public object DeveloperMessage { get; set; } - } -} diff --git a/src/Services/Webhooks/Webhooks.API/Program.cs b/src/Services/Webhooks/Webhooks.API/Program.cs index bc5d6c29f..ccebe59bb 100644 --- a/src/Services/Webhooks/Webhooks.API/Program.cs +++ b/src/Services/Webhooks/Webhooks.API/Program.cs @@ -1,20 +1,41 @@ -// TODO: Don't do this twice... -var host = CreateWebHostBuilder(args).Build(); -host.Services.MigrateDbContext((_, __) => { }); -host.Run(); - - -IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseStartup() - .ConfigureAppConfiguration((builderContext, config) => - { - config.AddEnvironmentVariables(); - }) - .ConfigureLogging((hostingContext, builder) => - { - builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); - builder.AddConsole(); - builder.AddDebug(); - builder.AddAzureWebAppDiagnostics(); - }); +var builder = WebApplication.CreateBuilder(args); + +builder.AddServiceDefaults(); + +builder.Services.AddControllers(); +builder.Services.AddDbContexts(builder.Configuration); +builder.Services.AddHealthChecks(builder.Configuration); +builder.Services.AddHttpClientServices(); +builder.Services.AddIntegrationServices(); + +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); + +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); + +var app = builder.Build(); + +if (!await app.CheckHealthAsync()) +{ + return; +} + +app.UseServiceDefaults(); + +app.MapGet("/", () => Results.Redirect("/swagger")); +app.MapControllers(); + + +var eventBus = app.Services.GetRequiredService(); + +eventBus.Subscribe(); +eventBus.Subscribe(); +eventBus.Subscribe(); + +app.Services.MigrateDbContext((_, __) => { }); + +await app.RunAsync(); diff --git a/src/Services/Webhooks/Webhooks.API/Properties/launchSettings.json b/src/Services/Webhooks/Webhooks.API/Properties/launchSettings.json index 533291599..859a2ae16 100644 --- a/src/Services/Webhooks/Webhooks.API/Properties/launchSettings.json +++ b/src/Services/Webhooks/Webhooks.API/Properties/launchSettings.json @@ -1,27 +1,12 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:62486", - "sslPort": 0 - } - }, "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, "Webhooks.API": { "commandName": "Project", "launchBrowser": true, + "applicationUrl": "http://localhost:5222", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:5000" + } }, "Docker": { "commandName": "Docker", diff --git a/src/Services/Webhooks/Webhooks.API/Startup.cs b/src/Services/Webhooks/Webhooks.API/Startup.cs deleted file mode 100644 index c79ea4b2e..000000000 --- a/src/Services/Webhooks/Webhooks.API/Startup.cs +++ /dev/null @@ -1,318 +0,0 @@ -namespace Webhooks.API; -public class Startup -{ - public IConfiguration Configuration { get; } - - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IServiceProvider ConfigureServices(IServiceCollection services) - { - services - .AddAppInsight(Configuration) - .AddCustomRouting(Configuration) - .AddCustomDbContext(Configuration) - .AddSwagger(Configuration) - .AddCustomHealthCheck(Configuration) - .AddHttpClientServices(Configuration) - .AddIntegrationServices(Configuration) - .AddEventBus(Configuration) - .AddCustomAuthentication(Configuration) - .AddSingleton() - .AddTransient() - .AddTransient() - .AddTransient() - .AddTransient(); - return services.BuildServiceProvider(); - } - - public void Configure(IApplicationBuilder app, ILogger logger) - { - var pathBase = Configuration["PATH_BASE"]; - - if (!string.IsNullOrEmpty(pathBase)) - { - logger.LogDebug("Using PATH BASE '{PathBase}'", pathBase); - app.UsePathBase(pathBase); - } - - app.UseRouting(); - app.UseCors("CorsPolicy"); - ConfigureAuth(app); - - app.UseEndpoints(endpoints => - { - endpoints.MapDefaultControllerRoute(); - endpoints.MapControllers(); - endpoints.MapHealthChecks("/hc", new HealthCheckOptions() - { - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse - }); - endpoints.MapHealthChecks("/liveness", new HealthCheckOptions - { - Predicate = r => r.Name.Contains("self") - }); - }); - - app.UseSwagger() - .UseSwaggerUI(c => - { - c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Webhooks.API V1"); - c.OAuthClientId("webhooksswaggerui"); - c.OAuthAppName("WebHooks Service Swagger UI"); - }); - - ConfigureEventBus(app); - } - - protected virtual void ConfigureAuth(IApplicationBuilder app) - { - app.UseAuthentication(); - app.UseAuthorization(); - } - - protected virtual void ConfigureEventBus(IApplicationBuilder app) - { - var eventBus = app.ApplicationServices.GetRequiredService(); - eventBus.Subscribe(); - eventBus.Subscribe(); - eventBus.Subscribe(); - } -} - -internal static class CustomExtensionMethods -{ - public static IServiceCollection AddAppInsight(this IServiceCollection services, IConfiguration configuration) - { - services.AddApplicationInsightsTelemetry(configuration); - services.AddApplicationInsightsKubernetesEnricher(); - - return services; - } - - public static IServiceCollection AddCustomRouting(this IServiceCollection services, IConfiguration configuration) - { - services.AddControllers(options => - { - options.Filters.Add(typeof(HttpGlobalExceptionFilter)); - }); - - services.AddCors(options => - { - options.AddPolicy("CorsPolicy", - builder => builder - .SetIsOriginAllowed((host) => true) - .AllowAnyMethod() - .AllowAnyHeader() - .AllowCredentials()); - }); - - return services; - } - - public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration) - { - services.AddEntityFrameworkSqlServer() - .AddDbContext(options => - { - options.UseSqlServer(configuration["ConnectionString"], - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name); - //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency - sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - }); - }); - - return services; - } - - public static IServiceCollection AddSwagger(this IServiceCollection services, IConfiguration configuration) - { - services.AddSwaggerGen(options => - { - options.SwaggerDoc("v1", new OpenApiInfo - { - Title = "eShopOnContainers - Webhooks HTTP API", - Version = "v1", - Description = "The Webhooks Microservice HTTP API. This is a simple webhooks CRUD registration entrypoint" - }); - - var identityUrl = configuration.GetSection("Identity").GetValue("ExternalUrl"); - options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme - { - Type = SecuritySchemeType.OAuth2, - Flows = new OpenApiOAuthFlows() - { - Implicit = new OpenApiOAuthFlow() - { - AuthorizationUrl = new Uri($"{identityUrl}/connect/authorize"), - TokenUrl = new Uri($"{identityUrl}/connect/token"), - Scopes = new Dictionary() - { - { "webhooks", "Webhooks API" } - } - } - } - }); - - options.OperationFilter(); - }); - - return services; - } - public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) - { - if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubscriptionManager = sp.GetRequiredService(); - string subscriptionName = configuration["SubscriptionClientName"]; - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubscriptionManager, sp, subscriptionName); - }); - - } - else - { - services.AddSingleton(sp => - { - var subscriptionClientName = configuration["SubscriptionClientName"]; - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubscriptionManager = sp.GetRequiredService(); - - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubscriptionManager, subscriptionClientName, retryCount); - }); - } - - services.AddSingleton(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - return services; - } - - public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) - { - var hcBuilder = services.AddHealthChecks(); - - hcBuilder - .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddSqlServer( - configuration["ConnectionString"], - name: "WebhooksApiDb-check", - tags: new string[] { "webhooksdb" }); - - return services; - } - - public static IServiceCollection AddHttpClientServices(this IServiceCollection services, IConfiguration configuration) - { - services.AddSingleton(); - services.AddHttpClient("extendedhandlerlifetime").SetHandlerLifetime(Timeout.InfiniteTimeSpan); - //add http client services - services.AddHttpClient("GrantClient") - .SetHandlerLifetime(TimeSpan.FromMinutes(5)); - return services; - } - - public static IServiceCollection AddIntegrationServices(this IServiceCollection services, IConfiguration configuration) - { - services.AddTransient>( - sp => (DbConnection c) => new IntegrationEventLogService(c)); - - if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var subscriptionClientName = configuration["SubscriptionClientName"]; - return new DefaultServiceBusPersisterConnection(configuration["EventBusConnection"]); - }); - } - else - { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - var factory = new ConnectionFactory() - { - HostName = configuration["EventBusConnection"], - DispatchConsumersAsync = true - }; - - if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) - { - factory.UserName = configuration["EventBusUserName"]; - } - - if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) - { - factory.Password = configuration["EventBusPassword"]; - } - - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); - } - - return services; - } - - public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) - { - // prevent from mapping "sub" claim to nameidentifier. - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); - - var identityUrl = configuration.GetValue("IdentityUrl"); - - services.AddAuthentication(options => - { - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - - }).AddJwtBearer(options => - { - options.Authority = identityUrl; - options.RequireHttpsMetadata = false; - options.Audience = "webhooks"; - options.TokenValidationParameters.ValidateAudience = false; - }); - - return services; - } - - - public static IServiceCollection AddCustomAuthorization(this IServiceCollection services, IConfiguration configuration) - { - services.AddAuthorization(options => - { - options.AddPolicy("ApiScope", policy => - { - policy.RequireAuthenticatedUser(); - policy.RequireClaim("scope", "webhooks"); - }); - }); - return services; - } -} diff --git a/src/Services/Webhooks/Webhooks.API/Webhooks.API.csproj b/src/Services/Webhooks/Webhooks.API/Webhooks.API.csproj index 4357a1520..979154074 100644 --- a/src/Services/Webhooks/Webhooks.API/Webhooks.API.csproj +++ b/src/Services/Webhooks/Webhooks.API/Webhooks.API.csproj @@ -2,33 +2,17 @@ net7.0 - InProcess Linux - $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; - false - true - - - - - - - - - - - - - + diff --git a/src/Services/Webhooks/Webhooks.API/appsettings.Development.json b/src/Services/Webhooks/Webhooks.API/appsettings.Development.json index f4f8f9d26..37de2515b 100644 --- a/src/Services/Webhooks/Webhooks.API/appsettings.Development.json +++ b/src/Services/Webhooks/Webhooks.API/appsettings.Development.json @@ -6,5 +6,7 @@ "Microsoft": "Information" } }, - "ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word;TrustServerCertificate=true" + "ConnectionStrings": { + "WebHooksDb": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word;TrustServerCertificate=true" + } } diff --git a/src/Services/Webhooks/Webhooks.API/appsettings.json b/src/Services/Webhooks/Webhooks.API/appsettings.json index 200ea4c96..470c0839a 100644 --- a/src/Services/Webhooks/Webhooks.API/appsettings.json +++ b/src/Services/Webhooks/Webhooks.API/appsettings.json @@ -1,10 +1,44 @@ { "Logging": { "LogLevel": { - "Default": "Warning" + "Default": "Information", + "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", - "SubscriptionClientName": "Webhooks", - "EventBusRetryCount": 5 + "OpenApi": { + "Endpoint": { + "Name": "Webhooks.API V1" + }, + "Document": { + "Description": "The Webhooks Microservice HTTP API. This is a simple webhooks CRUD registration entrypoint", + "Title": "eShopOnContainers - Webhooks HTTP API", + "Version": "v1" + }, + "Auth": { + "ClientId": "webhooksswaggerui", + "AppName": "WebHooks Service Swagger UI" + } + }, + "ConnectionStrings": { + "EventBus": "localhost" + }, + "EventBus": { + "SubscriptionClientName": "Webhooks", + "RetryCount": 5 + }, + "ApplicationInsights": { + "InstrumentationKey": "" + }, + "Identity": { + "Url": "http://localhost:5105", + "ExternalUrl": "http://localhost:5105", + "Audience": "webhooks", + "Scopes": { + "webhooks": "Webhooks API" + } + }, + "UseCustomizationData": false, + "GracePeriodTime": "1", + "CheckUpdateTime": "30000" } From 702796756865df000514440b772aedcdd2d354fa Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 5 May 2023 15:27:37 -0700 Subject: [PATCH 068/118] More random clean up --- .../EventBus/EventBus/Abstractions/IEventBus.cs | 6 ------ .../Services/GracePeriodManagerService.cs | 13 +++++-------- src/Services/Services.Common/Services.Common.csproj | 2 -- src/Services/Webhooks/Webhooks.API/Program.cs | 1 - 4 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs b/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs index 492a10e42..cab6338e8 100644 --- a/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs +++ b/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs @@ -8,12 +8,6 @@ public interface IEventBus where T : IntegrationEvent where TH : IIntegrationEventHandler; - void SubscribeDynamic(string eventName) - where TH : IDynamicIntegrationEventHandler; - - void UnsubscribeDynamic(string eventName) - where TH : IDynamicIntegrationEventHandler; - void Unsubscribe() where TH : IIntegrationEventHandler where T : IntegrationEvent; diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Services/GracePeriodManagerService.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Services/GracePeriodManagerService.cs index bded89eb9..5f6409546 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Services/GracePeriodManagerService.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Services/GracePeriodManagerService.cs @@ -1,14 +1,11 @@ -using Dapper; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Ordering.BackgroundTasks.Events; -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Data.SqlClient; using System.Threading; using System.Threading.Tasks; +using Dapper; +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; +using Microsoft.Extensions.Options; +using Ordering.BackgroundTasks.Events; namespace Ordering.BackgroundTasks.Services { diff --git a/src/Services/Services.Common/Services.Common.csproj b/src/Services/Services.Common/Services.Common.csproj index 7756c425d..5f45aac7b 100644 --- a/src/Services/Services.Common/Services.Common.csproj +++ b/src/Services/Services.Common/Services.Common.csproj @@ -38,10 +38,8 @@ - - diff --git a/src/Services/Webhooks/Webhooks.API/Program.cs b/src/Services/Webhooks/Webhooks.API/Program.cs index ccebe59bb..8aedaa8a8 100644 --- a/src/Services/Webhooks/Webhooks.API/Program.cs +++ b/src/Services/Webhooks/Webhooks.API/Program.cs @@ -29,7 +29,6 @@ app.UseServiceDefaults(); app.MapGet("/", () => Results.Redirect("/swagger")); app.MapControllers(); - var eventBus = app.Services.GetRequiredService(); eventBus.Subscribe(); From acd9a6d04b5288e80dfd228aecb71d80a77231c4 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 5 May 2023 20:05:45 -0700 Subject: [PATCH 069/118] Clean up the identity project and make it use services common --- .../Identity/Identity.API/GlobalUsings.cs | 46 ++++-------- .../Identity.API/IWebHostExtensions.cs | 69 ----------------- .../Identity/Identity.API/Identity.API.csproj | 74 ++++++++----------- src/Services/Identity/Identity.API/Program.cs | 38 +++------- .../Identity/Identity.API/appsettings.json | 12 +-- src/Services/Identity/Identity.API/web.config | 17 ----- .../Services.Common/CommonExtensions.cs | 15 +++- 7 files changed, 76 insertions(+), 195 deletions(-) delete mode 100644 src/Services/Identity/Identity.API/IWebHostExtensions.cs delete mode 100644 src/Services/Identity/Identity.API/web.config diff --git a/src/Services/Identity/Identity.API/GlobalUsings.cs b/src/Services/Identity/Identity.API/GlobalUsings.cs index a4ecca85f..439583c53 100644 --- a/src/Services/Identity/Identity.API/GlobalUsings.cs +++ b/src/Services/Identity/Identity.API/GlobalUsings.cs @@ -1,7 +1,11 @@ -global using Azure.Core; -global using Azure.Identity; -global using HealthChecks.UI.Client; -global using IdentityModel; +global using System; +global using System.Collections.Generic; +global using System.ComponentModel.DataAnnotations; +global using System.IdentityModel.Tokens.Jwt; +global using System.Linq; +global using System.Security.Claims; +global using System.Text.RegularExpressions; +global using System.Threading.Tasks; global using Duende.IdentityServer; global using Duende.IdentityServer.Configuration; global using Duende.IdentityServer.Events; @@ -10,53 +14,33 @@ global using Duende.IdentityServer.Models; global using Duende.IdentityServer.Services; global using Duende.IdentityServer.Stores; global using Duende.IdentityServer.Validation; +global using IdentityModel; global using Microsoft.AspNetCore.Authentication; global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; -global using Microsoft.AspNetCore.Diagnostics.HealthChecks; global using Microsoft.AspNetCore.Hosting; -global using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +global using Microsoft.AspNetCore.Http; global using Microsoft.AspNetCore.Identity; -global using Microsoft.AspNetCore.Mvc.Rendering; +global using Microsoft.AspNetCore.Identity.EntityFrameworkCore; global using Microsoft.AspNetCore.Mvc; global using Microsoft.AspNetCore.Mvc.Filters; +global using Microsoft.AspNetCore.Mvc.Rendering; +global using Microsoft.EntityFrameworkCore; global using Microsoft.EntityFrameworkCore.Infrastructure; global using Microsoft.EntityFrameworkCore.Metadata; global using Microsoft.EntityFrameworkCore.Migrations; -global using Microsoft.EntityFrameworkCore; - global using Microsoft.eShopOnContainers.Services.Identity.API; -global using Microsoft.eShopOnContainers.Services.Identity.API.Data; global using Microsoft.eShopOnContainers.Services.Identity.API.Configuration; +global using Microsoft.eShopOnContainers.Services.Identity.API.Data; global using Microsoft.eShopOnContainers.Services.Identity.API.Models; global using Microsoft.eShopOnContainers.Services.Identity.API.Services; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Diagnostics.HealthChecks; global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; global using Polly; -global using System.Collections.Generic; -global using System.ComponentModel.DataAnnotations; -global using System.Data.SqlClient; -global using System.IdentityModel.Tokens.Jwt; -global using System.Linq; -global using System.Security.Claims; -global using System.Text.RegularExpressions; -global using System.Threading.Tasks; -global using System; -global using Microsoft.AspNetCore.Http; - - - - - - - - - - +global using Services.Common; diff --git a/src/Services/Identity/Identity.API/IWebHostExtensions.cs b/src/Services/Identity/Identity.API/IWebHostExtensions.cs deleted file mode 100644 index a9e002d74..000000000 --- a/src/Services/Identity/Identity.API/IWebHostExtensions.cs +++ /dev/null @@ -1,69 +0,0 @@ -namespace Microsoft.AspNetCore.Hosting -{ - public static class IWebHostExtensions - { - public static bool IsInKubernetes(this IWebHost webHost) - { - var cfg = webHost.Services.GetService(); - var orchestratorType = cfg.GetValue("OrchestratorType"); - return orchestratorType?.ToUpper() == "K8S"; - } - - public static IWebHost MigrateDbContext(this IWebHost webHost, Action seeder) where TContext : DbContext - { - var underK8s = webHost.IsInKubernetes(); - - using var scope = webHost.Services.CreateScope(); - var services = scope.ServiceProvider; - var logger = services.GetRequiredService>(); - var context = services.GetService(); - - try - { - logger.LogInformation("Migrating database associated with context {DbContextName}", typeof(TContext).Name); - - if (underK8s) - { - InvokeSeeder(seeder, context, services); - } - else - { - var retries = 10; - var retry = Policy.Handle() - .WaitAndRetry( - retryCount: retries, - sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), - onRetry: (exception, timeSpan, retry, ctx) => - { - logger.LogWarning(exception, "[{prefix}] Error seeding database (attempt {retry} of {retries})", nameof(TContext), retry, retries); - }); - - //if the sql server container is not created on run docker compose this - //migration can't fail for network related exception. The retry options for DbContext only - //apply to transient exceptions - // Note that this is NOT applied when running some orchestrators (let the orchestrator to recreate the failing service) - retry.Execute(() => InvokeSeeder(seeder, context, services)); - } - - logger.LogInformation("Migrated database associated with context {DbContextName}", typeof(TContext).Name); - } - catch (Exception ex) - { - logger.LogError(ex, "An error occurred while migrating the database used on context {DbContextName}", typeof(TContext).Name); - if (underK8s) - { - throw; // Rethrow under k8s because we rely on k8s to re-run the pod - } - } - - return webHost; - } - - private static void InvokeSeeder(Action seeder, TContext context, IServiceProvider services) - where TContext : DbContext - { - context.Database.Migrate(); - seeder(context, services); - } - } -} diff --git a/src/Services/Identity/Identity.API/Identity.API.csproj b/src/Services/Identity/Identity.API/Identity.API.csproj index 4afd80c1c..ee587a6bf 100644 --- a/src/Services/Identity/Identity.API/Identity.API.csproj +++ b/src/Services/Identity/Identity.API/Identity.API.csproj @@ -4,68 +4,54 @@ net7.0 aspnet-eShopOnContainers.Identity-90487118-103c-4ff0-b9da-e5e26f7ab0c5 ..\..\..\..\docker-compose.dcproj - false - true - - - - - - - - - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Services/Identity/Identity.API/Program.cs b/src/Services/Identity/Identity.API/Program.cs index c0fa8fa7c..c8a04cd73 100644 --- a/src/Services/Identity/Identity.API/Program.cs +++ b/src/Services/Identity/Identity.API/Program.cs @@ -1,19 +1,12 @@ var builder = WebApplication.CreateBuilder(args); -if (builder.Configuration.GetValue("UseVault", false)) -{ - TokenCredential credential = new ClientSecretCredential( - builder.Configuration["Vault:TenantId"], - builder.Configuration["Vault:ClientId"], - builder.Configuration["Vault:ClientSecret"]); - builder.Configuration.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential); -} +builder.AddServiceDefaults(); builder.Services.AddControllersWithViews(); -builder.Services.AddControllers(); -builder.Services.AddRazorPages(); -builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("IdentityDb"))); +builder.Services.AddDbContext(options => + options.UseSqlServer(builder.Configuration.GetConnectionString("IdentityDb"))); + builder.Services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); @@ -35,23 +28,25 @@ builder.Services.AddIdentityServer(options => .AddAspNetIdentity() .AddDeveloperSigningCredential(); // Not recommended for production - you need to store your key material somewhere secure -builder.Services.AddAuthentication(); builder.Services.AddHealthChecks() - .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddSqlServer(builder.Configuration.GetConnectionString("IdentityDb"), + .AddSqlServer(_ => + builder.Configuration.GetRequiredConnectionString("IdentityDb"), name: "IdentityDB-check", tags: new string[] { "IdentityDB" }); + builder.Services.AddTransient(); builder.Services.AddTransient, EFLoginService>(); builder.Services.AddTransient(); var app = builder.Build(); -var pathBase = builder.Configuration["PATH_BASE"]; -if (!string.IsNullOrEmpty(pathBase)) +if (!await app.CheckHealthAsync()) { - app.UsePathBase(pathBase); + return; } + +app.UseServiceDefaults(); + app.UseStaticFiles(); // This cookie policy fixes login issues with Chrome 80+ using HHTP @@ -61,15 +56,6 @@ app.UseIdentityServer(); app.UseAuthorization(); app.MapDefaultControllerRoute(); -app.MapHealthChecks("/hc", new HealthCheckOptions() -{ - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse -}); -app.MapHealthChecks("/liveness", new HealthCheckOptions -{ - Predicate = r => r.Name.Contains("self") -}); // Apply database migration automatically. Note that this approach is not // recommended for production scenarios. Consider generating SQL scripts from diff --git a/src/Services/Identity/Identity.API/appsettings.json b/src/Services/Identity/Identity.API/appsettings.json index 955033706..48e4ff569 100644 --- a/src/Services/Identity/Identity.API/appsettings.json +++ b/src/Services/Identity/Identity.API/appsettings.json @@ -1,4 +1,10 @@ { + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, "IsClusterEnv": "False", "MvcClient": "http://localhost:5100", "SpaClient": "http://localhost:5104", @@ -7,12 +13,6 @@ "ApplicationInsights": { "InstrumentationKey": "" }, - "UseVault": false, - "Vault": { - "Name": "eshop", - "ClientId": "your-client-id", - "ClientSecret": "your-client-secret" - }, "TokenLifetimeMinutes": 120, "PermanentTokenLifetimeDays": 365 } diff --git a/src/Services/Identity/Identity.API/web.config b/src/Services/Identity/Identity.API/web.config deleted file mode 100644 index a2cf1fe26..000000000 --- a/src/Services/Identity/Identity.API/web.config +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index b922d6cc4..2c8510b0b 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -292,7 +292,12 @@ public static class CommonExtensions // } // } - var eventBusSection = configuration.GetRequiredSection("EventBus"); + var eventBusSection = configuration.GetSection("EventBus"); + + if (!eventBusSection.Exists()) + { + return hcBuilder; + } return eventBusSection["ProviderName"]?.ToLowerInvariant() switch { @@ -340,7 +345,13 @@ public static class CommonExtensions // } // } - var eventBusSection = configuration.GetRequiredSection("EventBus"); + var eventBusSection = configuration.GetSection("EventBus"); + + if (eventBusSection.Exists()) + { + return services; + } + if (string.Equals(eventBusSection["ProviderName"], "ServiceBus", StringComparison.OrdinalIgnoreCase)) { services.AddSingleton(sp => From 5ea034106cf143a8842c1edb7590ac658b48446d Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 5 May 2023 20:25:36 -0700 Subject: [PATCH 070/118] Move extensions to Extensions folder --- .../Basket.API/{ => Extensions}/CustomExtensionMethods.cs | 3 +-- .../Catalog.API/{ => Extensions}/CustomExtensionMethods.cs | 4 ++-- .../Ordering.API/{ => Extensions}/CustomExtensionsMethods.cs | 2 +- .../{ => Extensions}/CustomExtensionMethods.cs | 0 .../Webhooks.API/{ => Extensions}/CustomExtensionMethods.cs | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) rename src/Services/Basket/Basket.API/{ => Extensions}/CustomExtensionMethods.cs (92%) rename src/Services/Catalog/Catalog.API/{ => Extensions}/CustomExtensionMethods.cs (96%) rename src/Services/Ordering/Ordering.API/{ => Extensions}/CustomExtensionsMethods.cs (98%) rename src/Services/Ordering/Ordering.SignalrHub/{ => Extensions}/CustomExtensionMethods.cs (100%) rename src/Services/Webhooks/Webhooks.API/{ => Extensions}/CustomExtensionMethods.cs (97%) diff --git a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs b/src/Services/Basket/Basket.API/Extensions/CustomExtensionMethods.cs similarity index 92% rename from src/Services/Basket/Basket.API/CustomExtensionMethods.cs rename to src/Services/Basket/Basket.API/Extensions/CustomExtensionMethods.cs index b98ab6b3f..00cea7367 100644 --- a/src/Services/Basket/Basket.API/CustomExtensionMethods.cs +++ b/src/Services/Basket/Basket.API/Extensions/CustomExtensionMethods.cs @@ -1,5 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Basket.API; - + public static class CustomExtensionMethods { public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) diff --git a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs b/src/Services/Catalog/Catalog.API/Extensions/CustomExtensionMethods.cs similarity index 96% rename from src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs rename to src/Services/Catalog/Catalog.API/Extensions/CustomExtensionMethods.cs index ed74e4619..f1320f00f 100644 --- a/src/Services/Catalog/Catalog.API/CustomExtensionMethods.cs +++ b/src/Services/Catalog/Catalog.API/Extensions/CustomExtensionMethods.cs @@ -9,7 +9,7 @@ public static class CustomExtensionMethods hcBuilder .AddSqlServer(_ => configuration.GetRequiredConnectionString("CatalogDB"), name: "CatalogDB-check", - tags: new string[] { "live", "ready" }); + tags: new string[] { "ready" }); var accountName = configuration["AzureStorageAccountName"]; var accountKey = configuration["AzureStorageAccountKey"]; @@ -20,7 +20,7 @@ public static class CustomExtensionMethods .AddAzureBlobStorage( $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net", name: "catalog-storage-check", - tags: new string[] { "live", "ready" }); + tags: new string[] { "ready" }); } return services; diff --git a/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs b/src/Services/Ordering/Ordering.API/Extensions/CustomExtensionsMethods.cs similarity index 98% rename from src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs rename to src/Services/Ordering/Ordering.API/Extensions/CustomExtensionsMethods.cs index a7d7cd523..9ad366a1a 100644 --- a/src/Services/Ordering/Ordering.API/CustomExtensionsMethods.cs +++ b/src/Services/Ordering/Ordering.API/Extensions/CustomExtensionsMethods.cs @@ -10,7 +10,7 @@ static class CustomExtensionsMethods .AddSqlServer(_ => configuration.GetRequiredConnectionString("OrderingDB"), name: "OrderingDB-check", - tags: new string[] { "live", "ready" }); + tags: new string[] { "ready" }); return services; } diff --git a/src/Services/Ordering/Ordering.SignalrHub/CustomExtensionMethods.cs b/src/Services/Ordering/Ordering.SignalrHub/Extensions/CustomExtensionMethods.cs similarity index 100% rename from src/Services/Ordering/Ordering.SignalrHub/CustomExtensionMethods.cs rename to src/Services/Ordering/Ordering.SignalrHub/Extensions/CustomExtensionMethods.cs diff --git a/src/Services/Webhooks/Webhooks.API/CustomExtensionMethods.cs b/src/Services/Webhooks/Webhooks.API/Extensions/CustomExtensionMethods.cs similarity index 97% rename from src/Services/Webhooks/Webhooks.API/CustomExtensionMethods.cs rename to src/Services/Webhooks/Webhooks.API/Extensions/CustomExtensionMethods.cs index 2a2f5df06..8a962781e 100644 --- a/src/Services/Webhooks/Webhooks.API/CustomExtensionMethods.cs +++ b/src/Services/Webhooks/Webhooks.API/Extensions/CustomExtensionMethods.cs @@ -25,7 +25,7 @@ .AddSqlServer(_ => configuration.GetRequiredConnectionString("WebHooksDb"), name: "WebhooksApiDb-check", - tags: new string[] { "ready", "live" }); + tags: new string[] { "ready" }); return services; } From 031996d87cdd6349c26874cca240107e93deb80c Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sat, 6 May 2023 00:21:50 -0700 Subject: [PATCH 071/118] Fixed check --- src/Services/Services.Common/CommonExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index 2c8510b0b..acad801e6 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -347,7 +347,7 @@ public static class CommonExtensions var eventBusSection = configuration.GetSection("EventBus"); - if (eventBusSection.Exists()) + if (!eventBusSection.Exists()) { return services; } From 3c00be38f954f9d479c656b449b24bea56830781 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sat, 6 May 2023 01:09:47 -0700 Subject: [PATCH 072/118] Make BFF work and clean up ports --- .../aggregator/Controllers/HomeController.cs | 11 -- .../Extensions/ServiceCollectionExtensions.cs | 57 ++++++ .../Filters/AuthorizeCheckOperationFilter.cs | 34 ---- .../aggregator/GlobalUsings.cs | 35 ++-- .../Web.Bff.Shopping/aggregator/Program.cs | 177 +++--------------- .../aggregator/Properties/launchSettings.json | 27 +-- .../Web.Shopping.HttpAggregator.csproj | 20 +- .../aggregator/appsettings.Development.json | 14 +- .../aggregator/appsettings.json | 37 ++-- .../Basket.API/Properties/launchSettings.json | 5 +- .../Basket/Basket.API/appsettings.json | 1 - .../Properties/launchSettings.json | 2 +- .../Properties/launchSettings.json | 4 +- .../Properties/launchSettings.json | 2 +- .../Ordering/Ordering.API/appsettings.json | 1 - .../Properties/launchSettings.json | 2 +- .../Services.Common/CommonExtensions.cs | 2 +- .../Properties/launchSettings.json | 2 +- .../Webhooks/Webhooks.API/appsettings.json | 1 - 19 files changed, 140 insertions(+), 294 deletions(-) delete mode 100644 src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/HomeController.cs create mode 100644 src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/ServiceCollectionExtensions.cs delete mode 100644 src/ApiGateways/Web.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/HomeController.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/HomeController.cs deleted file mode 100644 index 55df5880b..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/HomeController.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers; - -[Route("")] -public class HomeController : Controller -{ - [HttpGet] - public IActionResult Index() - { - return new RedirectResult("~/swagger"); - } -} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/ServiceCollectionExtensions.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 000000000..c39149111 --- /dev/null +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,57 @@ +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) + { + services.AddHealthChecks() + .AddUrlGroup(_ => new Uri(configuration.GetRequiredValue("CatalogUrlHC")), name: "catalogapi-check", tags: new string[] { "catalogapi" }) + .AddUrlGroup(_ => new Uri(configuration.GetRequiredValue("OrderingUrlHC")), name: "orderingapi-check", tags: new string[] { "orderingapi" }) + .AddUrlGroup(_ => new Uri(configuration.GetRequiredValue("BasketUrlHC")), name: "basketapi-check", tags: new string[] { "basketapi" }) + .AddUrlGroup(_ => new Uri(configuration.GetRequiredValue("IdentityUrlHC")), name: "identityapi-check", tags: new string[] { "identityapi" }); + + return services; + } + + public static IServiceCollection AddApplicationServices(this IServiceCollection services) + { + // Register delegating handlers + services.AddTransient(); + + // Register http services + + services.AddHttpClient() + .AddHttpMessageHandler(); + + return services; + } + + public static IServiceCollection AddGrpcServices(this IServiceCollection services) + { + services.AddTransient(); + + services.AddScoped(); + + services.AddGrpcClient((services, options) => + { + var basketApi = services.GetRequiredService>().Value.GrpcBasket; + options.Address = new Uri(basketApi); + }).AddInterceptor(); + + services.AddScoped(); + + services.AddGrpcClient((services, options) => + { + var catalogApi = services.GetRequiredService>().Value.GrpcCatalog; + options.Address = new Uri(catalogApi); + }).AddInterceptor(); + + services.AddScoped(); + + services.AddGrpcClient((services, options) => + { + var orderingApi = services.GetRequiredService>().Value.GrpcOrdering; + options.Address = new Uri(orderingApi); + }).AddInterceptor(); + + return services; + } +} diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs deleted file mode 100644 index 99bf07048..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Filters/AuthorizeCheckOperationFilter.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters -{ - namespace Basket.API.Infrastructure.Filters - { - public class AuthorizeCheckOperationFilter : IOperationFilter - { - public void Apply(OpenApiOperation operation, OperationFilterContext context) - { - // Check for authorize attribute - var hasAuthorize = context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType().Any() || - context.MethodInfo.GetCustomAttributes(true).OfType().Any(); - - if (!hasAuthorize) return; - - operation.Responses.TryAdd("401", new OpenApiResponse { Description = "Unauthorized" }); - operation.Responses.TryAdd("403", new OpenApiResponse { Description = "Forbidden" }); - - var oAuthScheme = new OpenApiSecurityScheme - { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" } - }; - - operation.Security = new List - { - new() - { - [ oAuthScheme ] = new[] { "Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator" } - } - }; - } - } - } - -} \ No newline at end of file diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/GlobalUsings.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/GlobalUsings.cs index c008e8b3e..97b9e1222 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/GlobalUsings.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/GlobalUsings.cs @@ -1,38 +1,27 @@ -global using CatalogApi; -global using Grpc.Core.Interceptors; +global using System; +global using System.Collections.Generic; +global using System.Linq; +global using System.Net; +global using System.Net.Http; +global using System.Net.Http.Headers; +global using System.Text.Json; +global using System.Threading; +global using System.Threading.Tasks; +global using CatalogApi; global using Grpc.Core; +global using Grpc.Core.Interceptors; global using GrpcBasket; -global using HealthChecks.UI.Client; global using Microsoft.AspNetCore.Authentication; global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; -global using Microsoft.AspNetCore.Diagnostics.HealthChecks; -global using Microsoft.AspNetCore.Hosting; global using Microsoft.AspNetCore.Http; global using Microsoft.AspNetCore.Mvc; -global using Microsoft.AspNetCore; global using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config; -global using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters; global using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure; global using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; global using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services; -global using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Diagnostics.HealthChecks; -global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; -global using Microsoft.OpenApi.Models; -global using Swashbuckle.AspNetCore.SwaggerGen; -global using System.Collections.Generic; -global using System.IdentityModel.Tokens.Jwt; -global using System.Linq; -global using System.Net.Http.Headers; -global using System.Net.Http; -global using System.Net; -global using System.Text.Json; -global using System.Threading.Tasks; -global using System.Threading; -global using System; -global using Microsoft.IdentityModel.Tokens; +global using Services.Common; diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs index 8bc62923c..2adccb59f 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs @@ -1,169 +1,42 @@ var builder = WebApplication.CreateBuilder(args); -builder.Services.AddHealthChecks() - .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddUrlGroup(new Uri(builder.Configuration["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" }) - .AddUrlGroup(new Uri(builder.Configuration["OrderingUrlHC"]), name: "orderingapi-check", tags: new string[] { "orderingapi" }) - .AddUrlGroup(new Uri(builder.Configuration["BasketUrlHC"]), name: "basketapi-check", tags: new string[] { "basketapi" }) - .AddUrlGroup(new Uri(builder.Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }) - .AddUrlGroup(new Uri(builder.Configuration["PaymentUrlHC"]), name: "paymentapi-check", tags: new string[] { "paymentapi" }); -builder.Services.AddCustomMvc(builder.Configuration) - .AddCustomAuthentication(builder.Configuration) - .AddApplicationServices() - .AddGrpcServices(); -var app = builder.Build(); -if (!app.Environment.IsDevelopment()) -{ - app.UseExceptionHandler("/Home/Error"); -} - -var pathBase = builder.Configuration["PATH_BASE"]; -if (!string.IsNullOrEmpty(pathBase)) -{ - app.UsePathBase(pathBase); -} +builder.AddServiceDefaults(); -app.UseHttpsRedirection(); +builder.Services.AddControllers(); -app.UseSwagger().UseSwaggerUI(c => +builder.Services.AddHealthChecks(builder.Configuration); +builder.Services.AddCors(options => { - c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Purchase BFF V1"); - - c.OAuthClientId("webshoppingaggswaggerui"); - c.OAuthClientSecret(string.Empty); - c.OAuthRealm(string.Empty); - c.OAuthAppName("web shopping bff Swagger UI"); + options.AddPolicy("CorsPolicy", + builder => builder + .SetIsOriginAllowed((host) => true) + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials()); }); -app.UseRouting(); -app.UseCors("CorsPolicy"); -app.UseAuthentication(); -app.UseAuthorization(); +builder.Services.AddApplicationServices(); +builder.Services.AddGrpcServices(); -app.MapDefaultControllerRoute(); -app.MapControllers(); -app.MapHealthChecks("/hc", new HealthCheckOptions() -{ - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse -}); -app.MapHealthChecks("/liveness", new HealthCheckOptions -{ - Predicate = r => r.Name.Contains("self") -}); +builder.Services.Configure(builder.Configuration.GetSection("urls")); -await app.RunAsync(); +var app = builder.Build(); -public static class ServiceCollectionExtensions +if (!await app.CheckHealthAsync()) { - public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) - { - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); - - var identityUrl = configuration.GetValue("urls:identity"); - services.AddAuthentication("Bearer") - .AddJwtBearer(options => - { - options.Authority = identityUrl; - options.RequireHttpsMetadata = false; - options.Audience = "webshoppingagg"; - options.TokenValidationParameters = new TokenValidationParameters - { - ValidateAudience = false - }; - }); - - return services; - } - public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) - { - services.Configure(configuration.GetSection("urls")); - - services.AddControllers() - .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true); - - services.AddSwaggerGen(options => - { - options.SwaggerDoc("v1", new OpenApiInfo - { - Title = "Shopping Aggregator for Web Clients", - Version = "v1", - Description = "Shopping Aggregator for Web Clients" - }); - var identityUrl = configuration.GetSection("Identity").GetValue("ExternalUrl"); - options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme - { - Type = SecuritySchemeType.OAuth2, - Flows = new OpenApiOAuthFlows() - { - Implicit = new OpenApiOAuthFlow() - { - AuthorizationUrl = new Uri($"{identityUrl}/connect/authorize"), - TokenUrl = new Uri($"{identityUrl}/connect/token"), - Scopes = new Dictionary() - { - { "webshoppingagg", "Shopping Aggregator for Web Clients" } - } - } - } - }); - - options.OperationFilter(); - }); - services.AddCors(options => - { - options.AddPolicy("CorsPolicy", - builder => builder - .SetIsOriginAllowed((host) => true) - .AllowAnyMethod() - .AllowAnyHeader() - .AllowCredentials()); - }); - - return services; - } - public static IServiceCollection AddApplicationServices(this IServiceCollection services) - { - //register delegating handlers - services.AddTransient(); - services.AddSingleton(); - - //register http services - - services.AddHttpClient() - .AddHttpMessageHandler(); - - return services; - } - - public static IServiceCollection AddGrpcServices(this IServiceCollection services) - { - services.AddTransient(); - - services.AddScoped(); + return; +} - services.AddGrpcClient((services, options) => - { - var basketApi = services.GetRequiredService>().Value.GrpcBasket; - options.Address = new Uri(basketApi); - }).AddInterceptor(); +app.UseServiceDefaults(); - services.AddScoped(); +app.UseHttpsRedirection(); - services.AddGrpcClient((services, options) => - { - var catalogApi = services.GetRequiredService>().Value.GrpcCatalog; - options.Address = new Uri(catalogApi); - }).AddInterceptor(); +app.UseCors("CorsPolicy"); +app.UseAuthentication(); +app.UseAuthorization(); - services.AddScoped(); +app.MapGet("/", () => Results.Redirect("/swagger")); - services.AddGrpcClient((services, options) => - { - var orderingApi = services.GetRequiredService>().Value.GrpcOrdering; - options.Address = new Uri(orderingApi); - }).AddInterceptor(); +app.MapControllers(); - return services; - } -} +await app.RunAsync(); diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json index 925e70b0d..0e4ac481a 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json @@ -1,29 +1,16 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:57425/", - "sslPort": 0 - } - }, "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "api/values", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "PurchaseForMvc": { + "Web.Shopping.HttpAggregator": { "commandName": "Project", "launchBrowser": true, - "launchUrl": "api/values", + "applicationUrl": "http://localhost:61632/", "environmentVariables": { + "CatalogUrlHC": "http://localhost:5222/hc", + "OrderingUrlHC": "http://localhost:5224/hc", + "BasketUrlHC": "http://localhost:5221/hc", + "IdentityUrlHC": "http://localhost:5223/hc", "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:61632/" + } } } } \ No newline at end of file diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj index c718a77bd..b6d698cdc 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj @@ -5,31 +5,19 @@ Web.Shopping.HttpAggregator Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator ..\..\..\docker-compose.dcproj - false - true - - - - - - - - - - - - - - + + + + diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.Development.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.Development.json index 9480db9c1..b0bacf428 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.Development.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.Development.json @@ -1,16 +1,8 @@ { "Logging": { - "Debug": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Debug" - } - }, - "Console": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Debug" - } + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" } } } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json index 67de4d78b..dfa9ce18f 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json @@ -1,20 +1,29 @@ { - "Identity": { - "Url": "http://localhost:5105", - "Audience": "webshoppingagg" - }, "Logging": { - "Debug": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Warning" - } + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "OpenApi": { + "Endpoint": { + "Name": "Purchase BFF V1" }, - "Console": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Warning" - } + "Document": { + "Description": "Shopping Aggregator for Web Clients", + "Title": "Shopping Aggregator for Web Clients", + "Version": "v1" + }, + "Auth": { + "ClientId": "webshoppingaggswaggerui", + "AppName": "web shopping bff Swagger UI" + } + }, + "Identity": { + "Url": "http://localhost:5105", + "Audience": "webshoppingagg", + "Scopes": { + "webshoppingagg": "Shopping Aggregator for Web Clients" } } } diff --git a/src/Services/Basket/Basket.API/Properties/launchSettings.json b/src/Services/Basket/Basket.API/Properties/launchSettings.json index 5cb0a5315..d54621f97 100644 --- a/src/Services/Basket/Basket.API/Properties/launchSettings.json +++ b/src/Services/Basket/Basket.API/Properties/launchSettings.json @@ -3,10 +3,9 @@ "Basket.API": { "commandName": "Project", "launchBrowser": true, - "applicationUrl": "http://localhost:5222", + "applicationUrl": "http://localhost:5221", "environmentVariables": { - "Identity__Url": "http://localhost:5225", - "Identity__ExternalUrl": "http://localhost:5225", + "Identity__Url": "http://localhost:5223", "ASPNETCORE_ENVIRONMENT": "Development" } } diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json index 158aa6809..ba0d4072e 100644 --- a/src/Services/Basket/Basket.API/appsettings.json +++ b/src/Services/Basket/Basket.API/appsettings.json @@ -26,7 +26,6 @@ "Identity": { "Audience": "basket", "Url": "http://localhost:5105", - "ExternalUrl": "http://localhost:5105", "Scopes": { "basket": "Basket API" } diff --git a/src/Services/Catalog/Catalog.API/Properties/launchSettings.json b/src/Services/Catalog/Catalog.API/Properties/launchSettings.json index e16d546a4..1b56eefed 100644 --- a/src/Services/Catalog/Catalog.API/Properties/launchSettings.json +++ b/src/Services/Catalog/Catalog.API/Properties/launchSettings.json @@ -3,7 +3,7 @@ "Catalog.API": { "commandName": "Project", "launchBrowser": true, - "applicationUrl": "http://localhost:5226/", + "applicationUrl": "http://localhost:5222/", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Services/Identity/Identity.API/Properties/launchSettings.json b/src/Services/Identity/Identity.API/Properties/launchSettings.json index 83fe7f511..9b6496bd6 100644 --- a/src/Services/Identity/Identity.API/Properties/launchSettings.json +++ b/src/Services/Identity/Identity.API/Properties/launchSettings.json @@ -3,9 +3,9 @@ "Identity.API": { "commandName": "Project", "launchBrowser": true, - "applicationUrl": "http://localhost:5225", + "applicationUrl": "http://localhost:5223", "environmentVariables": { - "BasketApiClient": "http://localhost:5222", + "BasketApiClient": "http://localhost:5221", "ASPNETCORE_ENVIRONMENT": "Development" } } diff --git a/src/Services/Ordering/Ordering.API/Properties/launchSettings.json b/src/Services/Ordering/Ordering.API/Properties/launchSettings.json index f05bc8e5c..64d021926 100644 --- a/src/Services/Ordering/Ordering.API/Properties/launchSettings.json +++ b/src/Services/Ordering/Ordering.API/Properties/launchSettings.json @@ -3,7 +3,7 @@ "Ordering.API": { "commandName": "Project", "launchBrowser": true, - "applicationUrl": "http://localhost:5228/", + "applicationUrl": "http://localhost:5224/", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Services/Ordering/Ordering.API/appsettings.json b/src/Services/Ordering/Ordering.API/appsettings.json index 7c110dc0c..05de4f280 100644 --- a/src/Services/Ordering/Ordering.API/appsettings.json +++ b/src/Services/Ordering/Ordering.API/appsettings.json @@ -32,7 +32,6 @@ }, "Identity": { "Url": "http://localhost:5105", - "ExternalUrl": "http://localhost:5105", "Audience": "orders", "Scopes": { "orders": "Ordering API" diff --git a/src/Services/Ordering/Ordering.SignalrHub/Properties/launchSettings.json b/src/Services/Ordering/Ordering.SignalrHub/Properties/launchSettings.json index 9bcb7d2d3..b6f21c57b 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Properties/launchSettings.json +++ b/src/Services/Ordering/Ordering.SignalrHub/Properties/launchSettings.json @@ -3,7 +3,7 @@ "Ordering.SignalrHub": { "commandName": "Project", "launchBrowser": true, - "applicationUrl": "http://localhost:5223/", + "applicationUrl": "http://localhost:5225/", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index acad801e6..96c9828cb 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -180,7 +180,7 @@ public static class CommonExtensions // } // } - var identityUrlExternal = identitySection.GetRequiredValue("ExternalUrl"); + var identityUrlExternal = identitySection["ExternalUrl"] ?? identitySection.GetRequiredValue("Url"); var scopes = identitySection.GetRequiredSection("Scopes").GetChildren().ToDictionary(p => p.Key, p => p.Value); options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme diff --git a/src/Services/Webhooks/Webhooks.API/Properties/launchSettings.json b/src/Services/Webhooks/Webhooks.API/Properties/launchSettings.json index 859a2ae16..1fdcd55ad 100644 --- a/src/Services/Webhooks/Webhooks.API/Properties/launchSettings.json +++ b/src/Services/Webhooks/Webhooks.API/Properties/launchSettings.json @@ -3,7 +3,7 @@ "Webhooks.API": { "commandName": "Project", "launchBrowser": true, - "applicationUrl": "http://localhost:5222", + "applicationUrl": "http://localhost:5227", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Services/Webhooks/Webhooks.API/appsettings.json b/src/Services/Webhooks/Webhooks.API/appsettings.json index 470c0839a..1071feb1b 100644 --- a/src/Services/Webhooks/Webhooks.API/appsettings.json +++ b/src/Services/Webhooks/Webhooks.API/appsettings.json @@ -32,7 +32,6 @@ }, "Identity": { "Url": "http://localhost:5105", - "ExternalUrl": "http://localhost:5105", "Audience": "webhooks", "Scopes": { "webhooks": "Webhooks API" From d086d278e842ae2f2e358643cc7911b16de22726 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sat, 6 May 2023 01:26:01 -0700 Subject: [PATCH 073/118] Moved repository to top level folder --- .../Basket/Basket.API/GlobalUsings.cs | 3 +-- .../Repositories/RedisBasketRepository.cs | 2 +- .../Basket.FunctionalTests/GlobalUsings.cs | 22 ++++++++----------- .../RedisBasketRepositoryTests.cs | 8 +++---- 4 files changed, 14 insertions(+), 21 deletions(-) rename src/Services/Basket/Basket.API/{Infrastructure => }/Repositories/RedisBasketRepository.cs (94%) diff --git a/src/Services/Basket/Basket.API/GlobalUsings.cs b/src/Services/Basket/Basket.API/GlobalUsings.cs index 708cf1207..9a8376d4d 100644 --- a/src/Services/Basket/Basket.API/GlobalUsings.cs +++ b/src/Services/Basket/Basket.API/GlobalUsings.cs @@ -9,6 +9,7 @@ global using System.Threading.Tasks; global using Basket.API.IntegrationEvents.EventHandling; global using Basket.API.IntegrationEvents.Events; global using Basket.API.Model; +global using Basket.API.Repositories; global using Grpc.Core; global using GrpcBasket; global using Microsoft.AspNetCore.Authorization; @@ -17,8 +18,6 @@ global using Microsoft.AspNetCore.Http; global using Microsoft.AspNetCore.Mvc; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; global using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; -global using Microsoft.eShopOnContainers.Services.Basket.API; -global using Microsoft.eShopOnContainers.Services.Basket.API.Infrastructure.Repositories; global using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.EventHandling; global using Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Events; global using Microsoft.eShopOnContainers.Services.Basket.API.Model; diff --git a/src/Services/Basket/Basket.API/Infrastructure/Repositories/RedisBasketRepository.cs b/src/Services/Basket/Basket.API/Repositories/RedisBasketRepository.cs similarity index 94% rename from src/Services/Basket/Basket.API/Infrastructure/Repositories/RedisBasketRepository.cs rename to src/Services/Basket/Basket.API/Repositories/RedisBasketRepository.cs index 1834fd2cc..bca10ca33 100644 --- a/src/Services/Basket/Basket.API/Infrastructure/Repositories/RedisBasketRepository.cs +++ b/src/Services/Basket/Basket.API/Repositories/RedisBasketRepository.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.Services.Basket.API.Infrastructure.Repositories; +namespace Basket.API.Repositories; public class RedisBasketRepository : IBasketRepository { diff --git a/src/Services/Basket/Basket.FunctionalTests/GlobalUsings.cs b/src/Services/Basket/Basket.FunctionalTests/GlobalUsings.cs index d3657c2d3..219e4ce57 100644 --- a/src/Services/Basket/Basket.FunctionalTests/GlobalUsings.cs +++ b/src/Services/Basket/Basket.FunctionalTests/GlobalUsings.cs @@ -1,23 +1,19 @@ -global using Basket.FunctionalTests.Base; +global using System; +global using System.Collections.Generic; +global using System.IO; +global using System.Net.Http; +global using System.Security.Claims; +global using System.Text; +global using System.Text.Json; +global using System.Threading.Tasks; +global using Basket.FunctionalTests.Base; global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.Hosting; global using Microsoft.AspNetCore.Http; -global using Microsoft.AspNetCore.Routing; global using Microsoft.AspNetCore.TestHost; -global using Microsoft.eShopOnContainers.Services.Basket.API.Infrastructure.Repositories; global using Microsoft.eShopOnContainers.Services.Basket.API.Model; -global using Microsoft.eShopOnContainers.Services.Basket.API; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Logging; global using StackExchange.Redis; -global using System.Collections.Generic; -global using System.IO; -global using System.Net.Http; -global using System.Reflection; -global using System.Security.Claims; -global using System.Text.Json; -global using System.Text; -global using System.Threading.Tasks; -global using System; global using Xunit; diff --git a/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs b/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs index 540b01ccd..639f36bb8 100644 --- a/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs +++ b/src/Services/Basket/Basket.FunctionalTests/RedisBasketRepositoryTests.cs @@ -1,6 +1,4 @@ - - -using Microsoft.Extensions.Logging.Abstractions; +using Basket.API.Repositories; namespace Basket.FunctionalTests { @@ -50,8 +48,8 @@ namespace Basket.FunctionalTests RedisBasketRepository BuildBasketRepository(ConnectionMultiplexer connMux) { - var logger = NullLoggerFactory.Instance.CreateLogger(); - return new RedisBasketRepository(logger, connMux); + var loggerFactory = new LoggerFactory(); + return new RedisBasketRepository(loggerFactory.CreateLogger(), connMux); } List BuildBasketItems() From 6b8992153a1a0ceb904ce967391a6622d52341e2 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sat, 6 May 2023 01:29:09 -0700 Subject: [PATCH 074/118] Rename extensions to extensions --- .../{ServiceCollectionExtensions.cs => Extensions.cs} | 3 +-- .../Extensions/{CustomExtensionMethods.cs => Extensions.cs} | 3 +-- .../Extensions/{CustomExtensionMethods.cs => Extensions.cs} | 2 +- .../Extensions/{CustomExtensionsMethods.cs => Extensions.cs} | 2 +- .../Extensions/{CustomExtensionMethods.cs => Extensions.cs} | 4 ++-- .../Extensions/{CustomExtensionMethods.cs => Extensions.cs} | 2 +- 6 files changed, 7 insertions(+), 9 deletions(-) rename src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/{ServiceCollectionExtensions.cs => Extensions.cs} (97%) rename src/Services/Basket/Basket.API/Extensions/{CustomExtensionMethods.cs => Extensions.cs} (93%) rename src/Services/Catalog/Catalog.API/Extensions/{CustomExtensionMethods.cs => Extensions.cs} (98%) rename src/Services/Ordering/Ordering.API/Extensions/{CustomExtensionsMethods.cs => Extensions.cs} (98%) rename src/Services/Ordering/Ordering.SignalrHub/Extensions/{CustomExtensionMethods.cs => Extensions.cs} (93%) rename src/Services/Webhooks/Webhooks.API/Extensions/{CustomExtensionMethods.cs => Extensions.cs} (97%) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/ServiceCollectionExtensions.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs similarity index 97% rename from src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/ServiceCollectionExtensions.cs rename to src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs index c39149111..d1ead0af6 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/ServiceCollectionExtensions.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs @@ -1,4 +1,4 @@ -public static class ServiceCollectionExtensions +internal static class Extensions { public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) { @@ -17,7 +17,6 @@ services.AddTransient(); // Register http services - services.AddHttpClient() .AddHttpMessageHandler(); diff --git a/src/Services/Basket/Basket.API/Extensions/CustomExtensionMethods.cs b/src/Services/Basket/Basket.API/Extensions/Extensions.cs similarity index 93% rename from src/Services/Basket/Basket.API/Extensions/CustomExtensionMethods.cs rename to src/Services/Basket/Basket.API/Extensions/Extensions.cs index 00cea7367..7fce10b50 100644 --- a/src/Services/Basket/Basket.API/Extensions/CustomExtensionMethods.cs +++ b/src/Services/Basket/Basket.API/Extensions/Extensions.cs @@ -1,5 +1,4 @@ - -public static class CustomExtensionMethods +public static class Extensions { public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) { diff --git a/src/Services/Catalog/Catalog.API/Extensions/CustomExtensionMethods.cs b/src/Services/Catalog/Catalog.API/Extensions/Extensions.cs similarity index 98% rename from src/Services/Catalog/Catalog.API/Extensions/CustomExtensionMethods.cs rename to src/Services/Catalog/Catalog.API/Extensions/Extensions.cs index f1320f00f..490c5ede4 100644 --- a/src/Services/Catalog/Catalog.API/Extensions/CustomExtensionMethods.cs +++ b/src/Services/Catalog/Catalog.API/Extensions/Extensions.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Infrastructure; -public static class CustomExtensionMethods +public static class Extensions { public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) { diff --git a/src/Services/Ordering/Ordering.API/Extensions/CustomExtensionsMethods.cs b/src/Services/Ordering/Ordering.API/Extensions/Extensions.cs similarity index 98% rename from src/Services/Ordering/Ordering.API/Extensions/CustomExtensionsMethods.cs rename to src/Services/Ordering/Ordering.API/Extensions/Extensions.cs index 9ad366a1a..52de0f4cf 100644 --- a/src/Services/Ordering/Ordering.API/Extensions/CustomExtensionsMethods.cs +++ b/src/Services/Ordering/Ordering.API/Extensions/Extensions.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Infrastructure; -static class CustomExtensionsMethods +internal static class Extensions { public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) { diff --git a/src/Services/Ordering/Ordering.SignalrHub/Extensions/CustomExtensionMethods.cs b/src/Services/Ordering/Ordering.SignalrHub/Extensions/Extensions.cs similarity index 93% rename from src/Services/Ordering/Ordering.SignalrHub/Extensions/CustomExtensionMethods.cs rename to src/Services/Ordering/Ordering.SignalrHub/Extensions/Extensions.cs index dd6a3d442..40b8d1ff6 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Extensions/CustomExtensionMethods.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Extensions/Extensions.cs @@ -1,12 +1,12 @@ using Microsoft.AspNetCore.Http; -public static class CustomExtensionMethods +internal static class Extensions { public static IServiceCollection AddSignalR(this IServiceCollection services, IConfiguration configuration) { if (configuration.GetConnectionString("redis") is string redisConnection) { - // Add a redis health check + // TODO: Add a redis health check services.AddSignalR().AddStackExchangeRedis(redisConnection); } else diff --git a/src/Services/Webhooks/Webhooks.API/Extensions/CustomExtensionMethods.cs b/src/Services/Webhooks/Webhooks.API/Extensions/Extensions.cs similarity index 97% rename from src/Services/Webhooks/Webhooks.API/Extensions/CustomExtensionMethods.cs rename to src/Services/Webhooks/Webhooks.API/Extensions/Extensions.cs index 8a962781e..d8369382c 100644 --- a/src/Services/Webhooks/Webhooks.API/Extensions/CustomExtensionMethods.cs +++ b/src/Services/Webhooks/Webhooks.API/Extensions/Extensions.cs @@ -1,4 +1,4 @@ -internal static class CustomExtensionMethods +internal static class Extensions { public static IServiceCollection AddDbContexts(this IServiceCollection services, IConfiguration configuration) { From e1ec790ddf2a58829690a77e88b0d5039a0e13b9 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sat, 6 May 2023 10:29:37 -0700 Subject: [PATCH 075/118] Make more things work with docker compose --- .../Web.Shopping.HttpAggregator.csproj | 2 - .../Catalog/Catalog.API/Catalog.API.csproj | 13 ----- .../Catalog.API/Controllers/PicController.cs | 5 +- src/Services/Catalog/Catalog.API/Program.cs | 6 -- src/docker-compose.override.yml | 58 +++++++++---------- 5 files changed, 30 insertions(+), 54 deletions(-) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj index b6d698cdc..f5156ca94 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj @@ -11,8 +11,6 @@ - - diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index 9c96ff461..8a4669c16 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -12,9 +12,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -50,14 +47,4 @@ - - - - PreserveNewest - - - PreserveNewest - - - diff --git a/src/Services/Catalog/Catalog.API/Controllers/PicController.cs b/src/Services/Catalog/Catalog.API/Controllers/PicController.cs index dfb6f0d03..3db794f02 100644 --- a/src/Services/Catalog/Catalog.API/Controllers/PicController.cs +++ b/src/Services/Catalog/Catalog.API/Controllers/PicController.cs @@ -31,15 +31,14 @@ public class PicController : ControllerBase if (item != null) { - var webRoot = _env.WebRootPath; - var path = Path.Combine(webRoot, item.PictureFileName); + var path = Path.Combine(_env.ContentRootPath, "Pics", item.PictureFileName); string imageFileExtension = Path.GetExtension(item.PictureFileName); string mimetype = GetImageMimeTypeFromImageFileExtension(imageFileExtension); var buffer = await System.IO.File.ReadAllBytesAsync(path); - return File(buffer, mimetype); + return PhysicalFile(path, mimetype); } return NotFound(); diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index cac05401e..006a8b29b 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -23,12 +23,6 @@ if (!await app.CheckHealthAsync()) app.UseServiceDefaults(); -app.UseFileServer(new FileServerOptions -{ - FileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "Pics")), - RequestPath = "/pics" -}); - app.MapGet("/", () => Results.Redirect("/swagger")); app.MapControllers(); diff --git a/src/docker-compose.override.yml b/src/docker-compose.override.yml index ac2c1872c..428228c9c 100644 --- a/src/docker-compose.override.yml +++ b/src/docker-compose.override.yml @@ -44,7 +44,7 @@ services: - ASPNETCORE_URLS=http://0.0.0.0:80 - SpaClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5104 - XamarinCallback=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105/xamarincallback - - ConnectionString=${ESHOP_AZURE_IDENTITY_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} + - ConnectionStrings__IdentityDb=${ESHOP_AZURE_IDENTITY_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} - MvcClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5100 - BasketApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5103 - OrderingApiClient=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5102 @@ -62,13 +62,12 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basketdata} + - ConnectionStrings__Redis=${ESHOP_AZURE_REDIS_BASKET_DB:-basketdata} + - ConnectionStrings__EventBus=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - Identity__Url=http://identity-api - Identity__ExternalUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} - - AzureServiceBusEnabled=False + - EventBus__UserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBus__Password=${ESHOP_SERVICE_BUS_PASSWORD} - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - OrchestratorType=${ORCHESTRATOR_TYPE} - UseLoadTest=${USE_LOADTEST:-False} @@ -82,15 +81,14 @@ services: catalog-api: environment: - ASPNETCORE_ENVIRONMENT=Development - - ConnectionString=${ESHOP_AZURE_CATALOG_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} + - ConnectionStrings__CatalogDb=${ESHOP_AZURE_CATALOG_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} + - ConnectionStrings__EventBus=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - PicBaseUrl=${ESHOP_STORAGE_CATALOG_URL} - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} + - EventBus__UserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBus__Password=${ESHOP_SERVICE_BUS_PASSWORD} - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_CATALOG_NAME} - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_CATALOG_KEY} - UseCustomizationData=True - - AzureServiceBusEnabled=False - AzureStorageEnabled=False - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - OrchestratorType=${ORCHESTRATOR_TYPE} @@ -105,12 +103,12 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} + - ConnectionStrings__OrderingDb=${ESHOP_AZURE_ORDERING_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} + - ConnectionStrings__EventBus=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - Identity__Url=http://identity-api - Identity__ExternalUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} + - EventBus__UserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBus__Password=${ESHOP_SERVICE_BUS_PASSWORD} - UseCustomizationData=True - AzureServiceBusEnabled=False - CheckUpdateTime=30000 @@ -128,10 +126,10 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=${ESHOP_AZURE_ORDERING_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} + - ConnectionStrings__OrderingDb=${ESHOP_AZURE_ORDERING_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} + - ConnectionStrings__EventBus=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - EventBus__UserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBus__Password=${ESHOP_SERVICE_BUS_PASSWORD} - UseCustomizationData=True - AzureServiceBusEnabled=False - CheckUpdateTime=30000 @@ -146,9 +144,9 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} + - ConnectionStrings__EventBus=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - EventBus__UserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBus__Password=${ESHOP_SERVICE_BUS_PASSWORD} - AzureServiceBusEnabled=False - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - OrchestratorType=${ORCHESTRATOR_TYPE} @@ -159,10 +157,10 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - ConnectionString=${ESHOP_AZURE_WEBHOOKS_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.WebhooksDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} + - ConnectionStrings__WebhooksDb=${ESHOP_AZURE_WEBHOOKS_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.WebhooksDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} + - ConnectionStrings__EventBus=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - EventBus__UserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBus__Password=${ESHOP_SERVICE_BUS_PASSWORD} - Identity__Url=http://identity-api - Identity__ExternalUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 ports: @@ -226,13 +224,13 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME} - - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD} + - ConnectionStrings__EventBus=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} + - EventBus__UserName=${ESHOP_SERVICE_BUS_USERNAME} + - EventBus__Password=${ESHOP_SERVICE_BUS_PASSWORD} - AzureServiceBusEnabled=False - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - OrchestratorType=${ORCHESTRATOR_TYPE} - - identityUrl=http://identity-api + - Identity__Url=http://identity-api ports: - "5112:80" From d0c710ebdca0ff168dcaaa2bcd6c8ff2567e5546 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sat, 6 May 2023 16:14:56 -0700 Subject: [PATCH 076/118] Docker compose works --- .../Web.Bff.Shopping/aggregator/Program.cs | 9 ++------- .../aggregator/appsettings.json | 3 ++- src/Services/Catalog/Catalog.API/Program.cs | 5 ----- src/Services/Identity/Identity.API/Program.cs | 5 ----- src/Services/Ordering/Ordering.API/Program.cs | 17 ++++++----------- .../Ordering/Ordering.SignalrHub/Program.cs | 5 ----- src/Services/Payment/Payment.API/Program.cs | 5 ----- .../Services.Common/CommonExtensions.cs | 10 ++++++++++ src/Services/Webhooks/Webhooks.API/Program.cs | 5 ----- src/docker-compose.override.yml | 17 ++++++++++------- 10 files changed, 30 insertions(+), 51 deletions(-) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs index 2adccb59f..880d9b921 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs @@ -22,21 +22,16 @@ builder.Services.Configure(builder.Configuration.GetSection("urls")) var app = builder.Build(); -if (!await app.CheckHealthAsync()) -{ - return; -} - app.UseServiceDefaults(); app.UseHttpsRedirection(); -app.UseCors("CorsPolicy"); +app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); app.MapGet("/", () => Results.Redirect("/swagger")); -app.MapControllers(); +app.MapControllers().RequireCors("CorsPolicy"); await app.RunAsync(); diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json index dfa9ce18f..26e436a4e 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json @@ -2,7 +2,8 @@ "Logging": { "LogLevel": { "Default": "Information", - "Microsoft.AspNetCore": "Warning" + "Microsoft.AspNetCore": "Warning", + "System.Net.Http": "Warning" } }, "OpenApi": { diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index 006a8b29b..d450b022a 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -16,11 +16,6 @@ builder.Services.AddTransient() var app = builder.Build(); -if (!await app.CheckHealthAsync()) -{ - return; -} - app.UseServiceDefaults(); app.MapGet("/", () => Results.Redirect("/swagger")); diff --git a/src/Services/Identity/Identity.API/Program.cs b/src/Services/Identity/Identity.API/Program.cs index c8a04cd73..38bbbca42 100644 --- a/src/Services/Identity/Identity.API/Program.cs +++ b/src/Services/Identity/Identity.API/Program.cs @@ -40,11 +40,6 @@ builder.Services.AddTransient(); var app = builder.Build(); -if (!await app.CheckHealthAsync()) -{ - return; -} - app.UseServiceDefaults(); app.UseStaticFiles(); diff --git a/src/Services/Ordering/Ordering.API/Program.cs b/src/Services/Ordering/Ordering.API/Program.cs index 70faa5022..6b8dce4c2 100644 --- a/src/Services/Ordering/Ordering.API/Program.cs +++ b/src/Services/Ordering/Ordering.API/Program.cs @@ -33,20 +33,15 @@ services.AddScoped(); services.AddScoped(); // Add integration event handlers. -services.AddSingleton, GracePeriodConfirmedIntegrationEventHandler>(); -services.AddSingleton, OrderPaymentFailedIntegrationEventHandler>(); -services.AddSingleton, OrderPaymentSucceededIntegrationEventHandler>(); -services.AddSingleton, OrderStockConfirmedIntegrationEventHandler>(); -services.AddSingleton, OrderStockRejectedIntegrationEventHandler>(); -services.AddSingleton, UserCheckoutAcceptedIntegrationEventHandler>(); +services.AddTransient, GracePeriodConfirmedIntegrationEventHandler>(); +services.AddTransient, OrderPaymentFailedIntegrationEventHandler>(); +services.AddTransient, OrderPaymentSucceededIntegrationEventHandler>(); +services.AddTransient, OrderStockConfirmedIntegrationEventHandler>(); +services.AddTransient, OrderStockRejectedIntegrationEventHandler>(); +services.AddTransient, UserCheckoutAcceptedIntegrationEventHandler>(); var app = builder.Build(); -if (!await app.CheckHealthAsync()) -{ - return; -} - app.UseServiceDefaults(); app.MapGet("/", () => Results.Redirect("/swagger")); diff --git a/src/Services/Ordering/Ordering.SignalrHub/Program.cs b/src/Services/Ordering/Ordering.SignalrHub/Program.cs index 4583e9025..a030d5eb0 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Program.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Program.cs @@ -23,11 +23,6 @@ builder.Services.AddSingleton(); diff --git a/src/Services/Services.Common/CommonExtensions.cs b/src/Services/Services.Common/CommonExtensions.cs index 96c9828cb..104a66e3b 100644 --- a/src/Services/Services.Common/CommonExtensions.cs +++ b/src/Services/Services.Common/CommonExtensions.cs @@ -57,6 +57,16 @@ public static class CommonExtensions if (!string.IsNullOrEmpty(pathBase)) { app.UsePathBase(pathBase); + app.UseRouting(); + + var identitySection = app.Configuration.GetSection("Identity"); + + if (identitySection.Exists()) + { + // We have to add the auth middleware to the pipeline here + app.UseAuthentication(); + app.UseAuthorization(); + } } app.UseDefaultOpenApi(app.Configuration); diff --git a/src/Services/Webhooks/Webhooks.API/Program.cs b/src/Services/Webhooks/Webhooks.API/Program.cs index 8aedaa8a8..ad227b906 100644 --- a/src/Services/Webhooks/Webhooks.API/Program.cs +++ b/src/Services/Webhooks/Webhooks.API/Program.cs @@ -19,11 +19,6 @@ builder.Services.AddTransient() var app = builder.Build(); -if (!await app.CheckHealthAsync()) -{ - return; -} - app.UseServiceDefaults(); app.MapGet("/", () => Results.Redirect("/swagger")); diff --git a/src/docker-compose.override.yml b/src/docker-compose.override.yml index 428228c9c..46c762515 100644 --- a/src/docker-compose.override.yml +++ b/src/docker-compose.override.yml @@ -61,7 +61,9 @@ services: basket-api: environment: - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 + - Kestrel__Endpoints__HTTP__Url=http://0.0.0.0:80 + - Kestrel__Endpoints__GRPC__Url=http://0.0.0.0:81 + - Kestrel__Endpoints__GRPC__Protocols=Http2 - ConnectionStrings__Redis=${ESHOP_AZURE_REDIS_BASKET_DB:-basketdata} - ConnectionStrings__EventBus=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - Identity__Url=http://identity-api @@ -72,8 +74,6 @@ services: - OrchestratorType=${ORCHESTRATOR_TYPE} - UseLoadTest=${USE_LOADTEST:-False} - PATH_BASE=/basket-api - - GRPC_PORT=81 - - PORT=80 ports: - "5103:80" - "9103:81" @@ -81,6 +81,9 @@ services: catalog-api: environment: - ASPNETCORE_ENVIRONMENT=Development + - Kestrel__Endpoints__HTTP__Url=http://0.0.0.0:80 + - Kestrel__Endpoints__GRPC__Url=http://0.0.0.0:81 + - Kestrel__Endpoints__GRPC__Protocols=Http2 - ConnectionStrings__CatalogDb=${ESHOP_AZURE_CATALOG_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} - ConnectionStrings__EventBus=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - PicBaseUrl=${ESHOP_STORAGE_CATALOG_URL} @@ -92,8 +95,6 @@ services: - AzureStorageEnabled=False - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} - OrchestratorType=${ORCHESTRATOR_TYPE} - - GRPC_PORT=81 - - PORT=80 - PATH_BASE=/catalog-api ports: - "5101:80" @@ -102,7 +103,9 @@ services: ordering-api: environment: - ASPNETCORE_ENVIRONMENT=Development - - ASPNETCORE_URLS=http://0.0.0.0:80 + - Kestrel__Endpoints__HTTP__Url=http://0.0.0.0:80 + - Kestrel__Endpoints__GRPC__Url=http://0.0.0.0:81 + - Kestrel__Endpoints__GRPC__Protocols=Http2 - ConnectionStrings__OrderingDb=${ESHOP_AZURE_ORDERING_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;Encrypt=False;TrustServerCertificate=true} - ConnectionStrings__EventBus=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq} - Identity__Url=http://identity-api @@ -284,7 +287,7 @@ services: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - PurchaseUrl=http://webshoppingapigw - - Identity__Url=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 + - IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202 - IdentityUrlHC=http://identity-api/hc - UseCustomizationData=True From 69b28c6add43da8de001f9c7c883a249b83e5956 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sat, 6 May 2023 16:44:27 -0700 Subject: [PATCH 077/118] Added gRPC and HTTP endpoints via config --- src/Services/Basket/Basket.API/appsettings.json | 11 +++++++++++ src/Services/Catalog/Catalog.API/appsettings.json | 11 +++++++++++ src/Services/Ordering/Ordering.API/appsettings.json | 11 +++++++++++ 3 files changed, 33 insertions(+) diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json index ba0d4072e..85c3b39ec 100644 --- a/src/Services/Basket/Basket.API/appsettings.json +++ b/src/Services/Basket/Basket.API/appsettings.json @@ -5,6 +5,17 @@ "Microsoft.AspNetCore": "Warning" } }, + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://localhost:5221" + }, + "gRPC": { + "Url": "http://localhost:6221", + "Protocols": "Http2" + } + } + }, "OpenApi": { "Endpoint": { "Name": "Basket.API V1" diff --git a/src/Services/Catalog/Catalog.API/appsettings.json b/src/Services/Catalog/Catalog.API/appsettings.json index 937a2a3a8..3ddd8ff25 100644 --- a/src/Services/Catalog/Catalog.API/appsettings.json +++ b/src/Services/Catalog/Catalog.API/appsettings.json @@ -5,6 +5,17 @@ "Microsoft.AspNetCore": "Warning" } }, + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://localhost:5222" + }, + "gRPC": { + "Url": "http://localhost:6222", + "Protocols": "Http2" + } + } + }, "OpenApi": { "Endpoint": { "Name": "Catalog.API V1" diff --git a/src/Services/Ordering/Ordering.API/appsettings.json b/src/Services/Ordering/Ordering.API/appsettings.json index 05de4f280..bb8590ba3 100644 --- a/src/Services/Ordering/Ordering.API/appsettings.json +++ b/src/Services/Ordering/Ordering.API/appsettings.json @@ -6,6 +6,17 @@ } }, "AllowedHosts": "*", + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://localhost:5224" + }, + "gRPC": { + "Url": "http://localhost:6224", + "Protocols": "Http2" + } + } + }, "OpenApi": { "Endpoint": { "Name": "Ordering.API V1" From 670a9452e108c1881ac77071b77457c4796e9c2d Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sat, 6 May 2023 17:10:30 -0700 Subject: [PATCH 078/118] Remove health check --- src/Services/Basket/Basket.API/Program.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Services/Basket/Basket.API/Program.cs b/src/Services/Basket/Basket.API/Program.cs index 907f42b88..7ea0fd8ce 100644 --- a/src/Services/Basket/Basket.API/Program.cs +++ b/src/Services/Basket/Basket.API/Program.cs @@ -17,11 +17,6 @@ builder.Services.AddTransient(); var app = builder.Build(); -if (!await app.CheckHealthAsync()) -{ - return; -} - app.UseServiceDefaults(); app.MapGet("/", () => Results.Redirect("/swagger")); From 5a2d38575e4c085ed596973d8cedd2205fa8f36f Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 01:09:04 -0700 Subject: [PATCH 079/118] Fixed identity url --- src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json | 2 +- src/Services/Basket/Basket.API/appsettings.json | 2 +- src/Services/Ordering/Ordering.API/appsettings.json | 2 +- src/Services/Ordering/Ordering.SignalrHub/appsettings.json | 2 +- src/Services/Payment/Payment.API/Properties/launchSettings.json | 2 +- src/Services/Webhooks/Webhooks.API/appsettings.json | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json index 26e436a4e..f55fc195a 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json @@ -21,7 +21,7 @@ } }, "Identity": { - "Url": "http://localhost:5105", + "Url": "http://localhost:5223", "Audience": "webshoppingagg", "Scopes": { "webshoppingagg": "Shopping Aggregator for Web Clients" diff --git a/src/Services/Basket/Basket.API/appsettings.json b/src/Services/Basket/Basket.API/appsettings.json index 85c3b39ec..3a4547555 100644 --- a/src/Services/Basket/Basket.API/appsettings.json +++ b/src/Services/Basket/Basket.API/appsettings.json @@ -36,7 +36,7 @@ }, "Identity": { "Audience": "basket", - "Url": "http://localhost:5105", + "Url": "http://localhost:5223", "Scopes": { "basket": "Basket API" } diff --git a/src/Services/Ordering/Ordering.API/appsettings.json b/src/Services/Ordering/Ordering.API/appsettings.json index bb8590ba3..091b53626 100644 --- a/src/Services/Ordering/Ordering.API/appsettings.json +++ b/src/Services/Ordering/Ordering.API/appsettings.json @@ -42,7 +42,7 @@ "InstrumentationKey": "" }, "Identity": { - "Url": "http://localhost:5105", + "Url": "http://localhost:5223", "Audience": "orders", "Scopes": { "orders": "Ordering API" diff --git a/src/Services/Ordering/Ordering.SignalrHub/appsettings.json b/src/Services/Ordering/Ordering.SignalrHub/appsettings.json index bf7ffc1e2..887e4afdd 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/appsettings.json +++ b/src/Services/Ordering/Ordering.SignalrHub/appsettings.json @@ -7,7 +7,7 @@ }, "Identity": { "Audience": "orders.signalrhub", - "Url": "http://localhost:5105" + "Url": "http://localhost:5223" }, "EventBus": { "SubscriptionClientName": "Ordering.signalrhub", diff --git a/src/Services/Payment/Payment.API/Properties/launchSettings.json b/src/Services/Payment/Payment.API/Properties/launchSettings.json index 007e0eace..8d137d73f 100644 --- a/src/Services/Payment/Payment.API/Properties/launchSettings.json +++ b/src/Services/Payment/Payment.API/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Payment.API": { "commandName": "Project", - "launchBrowser": true, + "launchBrowser": false, "applicationUrl": "http://localhost:5226", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" diff --git a/src/Services/Webhooks/Webhooks.API/appsettings.json b/src/Services/Webhooks/Webhooks.API/appsettings.json index 1071feb1b..8d103c53e 100644 --- a/src/Services/Webhooks/Webhooks.API/appsettings.json +++ b/src/Services/Webhooks/Webhooks.API/appsettings.json @@ -31,7 +31,7 @@ "InstrumentationKey": "" }, "Identity": { - "Url": "http://localhost:5105", + "Url": "http://localhost:5223", "Audience": "webhooks", "Scopes": { "webhooks": "Webhooks API" From f76a8c61db3b94905b3ab529db3a8093295a6197 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 01:22:52 -0700 Subject: [PATCH 080/118] Make default URLs work --- .../aggregator/Properties/launchSettings.json | 6 +----- .../Web.Bff.Shopping/aggregator/appsettings.json | 15 ++++++++++++++- .../aggregator/appsettings.localhost.json | 11 ----------- .../Identity.API/Properties/launchSettings.json | 1 - .../Identity/Identity.API/appsettings.json | 6 +++++- 5 files changed, 20 insertions(+), 19 deletions(-) delete mode 100644 src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json index 0e4ac481a..4525154b7 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Properties/launchSettings.json @@ -3,12 +3,8 @@ "Web.Shopping.HttpAggregator": { "commandName": "Project", "launchBrowser": true, - "applicationUrl": "http://localhost:61632/", + "applicationUrl": "http://localhost:5229/", "environmentVariables": { - "CatalogUrlHC": "http://localhost:5222/hc", - "OrderingUrlHC": "http://localhost:5224/hc", - "BasketUrlHC": "http://localhost:5221/hc", - "IdentityUrlHC": "http://localhost:5223/hc", "ASPNETCORE_ENVIRONMENT": "Development" } } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json index f55fc195a..cd51126df 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json @@ -26,5 +26,18 @@ "Scopes": { "webshoppingagg": "Shopping Aggregator for Web Clients" } - } + }, + "Urls": { + "Basket": "http://localhost:5221", + "Catalog": "http://localhost:5222", + "Orders": "http://localhost:5224", + "Identity": "http://localhost:5223", + "GrpcBasket": "http://localhost:6221", + "GrpcCatalog": "http://localhost:6222", + "GrpcOrdering": "http://localhost:6224" + }, + "CatalogUrlHC": "http://localhost:5222/hc", + "OrderingUrlHC": "http://localhost:5224/hc", + "BasketUrlHC": "http://localhost:5221/hc", + "IdentityUrlHC": "http://localhost:5223/hc" } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json deleted file mode 100644 index 055bcfc7f..000000000 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.localhost.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "urls": { - "basket": "http://localhost:55103", - "catalog": "http://localhost:55101", - "orders": "http://localhost:55102", - "identity": "http://localhost:55105", - "grpcBasket": "http://localhost:5580", - "grpcCatalog": "http://localhost:81", - "grpcOrdering": "http://localhost:5581" - } -} diff --git a/src/Services/Identity/Identity.API/Properties/launchSettings.json b/src/Services/Identity/Identity.API/Properties/launchSettings.json index 9b6496bd6..485a5f313 100644 --- a/src/Services/Identity/Identity.API/Properties/launchSettings.json +++ b/src/Services/Identity/Identity.API/Properties/launchSettings.json @@ -5,7 +5,6 @@ "launchBrowser": true, "applicationUrl": "http://localhost:5223", "environmentVariables": { - "BasketApiClient": "http://localhost:5221", "ASPNETCORE_ENVIRONMENT": "Development" } } diff --git a/src/Services/Identity/Identity.API/appsettings.json b/src/Services/Identity/Identity.API/appsettings.json index 48e4ff569..99f585c38 100644 --- a/src/Services/Identity/Identity.API/appsettings.json +++ b/src/Services/Identity/Identity.API/appsettings.json @@ -14,5 +14,9 @@ "InstrumentationKey": "" }, "TokenLifetimeMinutes": 120, - "PermanentTokenLifetimeDays": 365 + "PermanentTokenLifetimeDays": 365, + "BasketApiClient": "http://localhost:5221", + "OrderingApiClient": "http://localhost:5224", + "WebShoppingAggClient": "http://localhost:5229", + "WebhooksApiClient": "http://localhost:5227" } From 50952bed1092c0aab8a226563ac7345d6ee2d6f6 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 08:40:48 -0700 Subject: [PATCH 081/118] Sort usings and delete web.config --- .../WebHost.Customization/WebHostExtensions.cs | 6 +++--- src/Web/WebMVC/web.config | 13 ------------- 2 files changed, 3 insertions(+), 16 deletions(-) delete mode 100644 src/Web/WebMVC/web.config diff --git a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs index f4dbee68e..45bedc2c4 100644 --- a/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs +++ b/src/BuildingBlocks/WebHostCustomization/WebHost.Customization/WebHostExtensions.cs @@ -1,10 +1,10 @@ -using Microsoft.EntityFrameworkCore; +using System; +using System.Data.SqlClient; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Polly; -using System; -using System.Data.SqlClient; namespace Microsoft.AspNetCore.Hosting { diff --git a/src/Web/WebMVC/web.config b/src/Web/WebMVC/web.config deleted file mode 100644 index 84838df92..000000000 --- a/src/Web/WebMVC/web.config +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - From 06d74d1658d52805cfe50c7ecfddd99621f88cf6 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 08:58:11 -0700 Subject: [PATCH 082/118] Small tweaks to make the MVC application run locally --- src/Web/WebMVC/Program.cs | 6 +-- src/Web/WebMVC/Properties/launchSettings.json | 16 +------ src/Web/WebMVC/appsettings.json | 10 ++-- src/Web/WebMVC/globalusings.cs | 46 +++++++++---------- 4 files changed, 32 insertions(+), 46 deletions(-) diff --git a/src/Web/WebMVC/Program.cs b/src/Web/WebMVC/Program.cs index fff566c19..ce7d33208 100644 --- a/src/Web/WebMVC/Program.cs +++ b/src/Web/WebMVC/Program.cs @@ -63,7 +63,7 @@ static void AddHealthChecks(WebApplicationBuilder builder) { builder.Services.AddHealthChecks() .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddUrlGroup(new Uri(builder.Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }); + .AddUrlGroup(_ => new Uri(builder.Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }); } static void AddCustomMvc(WebApplicationBuilder builder) @@ -85,7 +85,7 @@ static void AddCustomMvc(WebApplicationBuilder builder) // Adds all Http client services static void AddHttpClientServices(WebApplicationBuilder builder) { - builder.Services.AddSingleton(); + builder.Services.AddHttpContextAccessor(); //register delegating handlers builder.Services.AddTransient() @@ -116,7 +116,7 @@ static void AddCustomAuthentication(WebApplicationBuilder builder) var callBackUrl = builder.Configuration.GetValue("CallBackUrl"); var sessionCookieLifetime = builder.Configuration.GetValue("SessionCookieLifetimeMinutes", 60); - // Add Authentication services + // Add Authentication services builder.Services.AddAuthentication(options => { diff --git a/src/Web/WebMVC/Properties/launchSettings.json b/src/Web/WebMVC/Properties/launchSettings.json index bf529db40..cc41e62fe 100644 --- a/src/Web/WebMVC/Properties/launchSettings.json +++ b/src/Web/WebMVC/Properties/launchSettings.json @@ -1,23 +1,9 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:5100", - "sslPort": 0 - } - }, "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, "Microsoft.eShopOnContainers.WebMVC": { "commandName": "Project", "launchBrowser": true, - "launchUrl": "http://localhost:5000", + "applicationUrl": "http://localhost:5331", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/src/Web/WebMVC/appsettings.json b/src/Web/WebMVC/appsettings.json index 55561ef75..e0d07178a 100644 --- a/src/Web/WebMVC/appsettings.json +++ b/src/Web/WebMVC/appsettings.json @@ -1,8 +1,10 @@ { - "CatalogUrl": "http://localhost:5101", - "OrderingUrl": "http://localhost:5102", - "BasketUrl": "http://localhost:5103", - "IdentityUrl": "http://localhost:5105", + "PurchaseUrl": "http://localhost:5229", + "CatalogUrl": "http://localhost:5222", + "OrderingUrl": "http://localhost:5224", + "BasketUrl": "http://localhost:5221", + "IdentityUrl": "http://localhost:5223", + "IdentityUrlHC": "http://localhost:5223/hc", "CallBackUrl": "http://localhost:5100/", "IsClusterEnv": "False", "UseResilientHttp": "True", diff --git a/src/Web/WebMVC/globalusings.cs b/src/Web/WebMVC/globalusings.cs index aff8f2e62..1fe624e28 100644 --- a/src/Web/WebMVC/globalusings.cs +++ b/src/Web/WebMVC/globalusings.cs @@ -1,7 +1,24 @@ -global using HealthChecks.UI.Client; +global using System; +global using System.Collections.Generic; +global using System.ComponentModel; +global using System.ComponentModel.DataAnnotations; +global using System.IdentityModel.Tokens.Jwt; +global using System.IO; +global using System.IO.Compression; +global using System.Linq; +global using System.Net.Http; +global using System.Net.Http.Headers; +global using System.Security.Claims; +global using System.Security.Principal; +global using System.Text; +global using System.Text.Json; +global using System.Text.Json.Serialization; +global using System.Threading; +global using System.Threading.Tasks; +global using HealthChecks.UI.Client; +global using Microsoft.AspNetCore.Authentication; global using Microsoft.AspNetCore.Authentication.Cookies; global using Microsoft.AspNetCore.Authentication.OpenIdConnect; -global using Microsoft.AspNetCore.Authentication; global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.DataProtection; @@ -9,40 +26,21 @@ global using Microsoft.AspNetCore.Diagnostics.HealthChecks; global using Microsoft.AspNetCore.Hosting; global using Microsoft.AspNetCore.Http; global using Microsoft.AspNetCore.Identity; -global using Microsoft.AspNetCore.Mvc.Rendering; global using Microsoft.AspNetCore.Mvc; -global using Microsoft.AspNetCore; +global using Microsoft.AspNetCore.Mvc.Rendering; +global using Microsoft.eShopOnContainers.WebMVC; global using Microsoft.eShopOnContainers.WebMVC.Services; +global using Microsoft.eShopOnContainers.WebMVC.ViewModels; global using Microsoft.eShopOnContainers.WebMVC.ViewModels.Annotations; global using Microsoft.eShopOnContainers.WebMVC.ViewModels.CartViewModels; global using Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels; global using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination; -global using Microsoft.eShopOnContainers.WebMVC.ViewModels; -global using Microsoft.eShopOnContainers.WebMVC; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Diagnostics.HealthChecks; global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; -global using Microsoft.IdentityModel.Logging; global using StackExchange.Redis; -global using System.Collections.Generic; -global using System.ComponentModel.DataAnnotations; -global using System.ComponentModel; -global using System.IdentityModel.Tokens.Jwt; -global using System.IO.Compression; -global using System.IO; -global using System.Linq; -global using System.Net.Http.Headers; -global using System.Net.Http; -global using System.Security.Claims; -global using System.Security.Principal; -global using System.Text.Json.Serialization; -global using System.Text.Json; -global using System.Text; -global using System.Threading.Tasks; -global using System.Threading; -global using System; global using WebMVC.Infrastructure; global using WebMVC.Services.ModelDTOs; From 30ed0011cbc84f28803ac399ad0017bcd85839c0 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 11:09:41 -0700 Subject: [PATCH 083/118] Added YARP as an API gateway - It will eventually replace envoy --- .../Yarp/ApiGateway/ApiGateway.csproj | 17 +++++ src/ApiGateways/Yarp/ApiGateway/Program.cs | 71 +++++++++++++++++++ .../ApiGateway/Properties/launchSettings.json | 22 ++++++ .../ApiGateway/appsettings.Development.json | 8 +++ .../Yarp/ApiGateway/appsettings.json | 16 +++++ src/Directory.Packages.props | 4 +- src/Web/WebMVC/appsettings.json | 5 +- src/eShopOnContainers-ServicesAndWebApps.sln | 56 ++++++++++++++- 8 files changed, 192 insertions(+), 7 deletions(-) create mode 100644 src/ApiGateways/Yarp/ApiGateway/ApiGateway.csproj create mode 100644 src/ApiGateways/Yarp/ApiGateway/Program.cs create mode 100644 src/ApiGateways/Yarp/ApiGateway/Properties/launchSettings.json create mode 100644 src/ApiGateways/Yarp/ApiGateway/appsettings.Development.json create mode 100644 src/ApiGateways/Yarp/ApiGateway/appsettings.json diff --git a/src/ApiGateways/Yarp/ApiGateway/ApiGateway.csproj b/src/ApiGateways/Yarp/ApiGateway/ApiGateway.csproj new file mode 100644 index 000000000..432df38e3 --- /dev/null +++ b/src/ApiGateways/Yarp/ApiGateway/ApiGateway.csproj @@ -0,0 +1,17 @@ + + + + net7.0 + enable + enable + + + + + + + + + + + diff --git a/src/ApiGateways/Yarp/ApiGateway/Program.cs b/src/ApiGateways/Yarp/ApiGateway/Program.cs new file mode 100644 index 000000000..acc40633e --- /dev/null +++ b/src/ApiGateways/Yarp/ApiGateway/Program.cs @@ -0,0 +1,71 @@ +using Services.Common; +using Yarp.ReverseProxy.Configuration; +using Yarp.ReverseProxy.Transforms; + +var builder = WebApplication.CreateBuilder(args); + +builder.AddServiceDefaults(); + +var services = new (string, string, string)[] +{ + ("c-short", "c", "catalog"), + ("c-long", "catalog-api", "catalog"), + + ("b-short", "b", "basket"), + ("b-long", "basket-api", "basket"), + + ("o-short", "o", "orders"), + ("o-long", "ordering-api", "orders"), + + ("h-long", "hub/notificationhub", "signalr") +}; + +var routes = new List(); +var clusters = new Dictionary(); +var urls = builder.Configuration.GetRequiredSection("Urls"); + +foreach (var (routeId, prefix, clusterId) in services) +{ + var destination = urls.GetRequiredValue(clusterId); + + routes.Add(new() + { + RouteId = routeId, + ClusterId = clusterId, + Match = new() + { + Path = $"/{prefix}/{{**catch-all}}" + }, + Metadata = new Dictionary() + { + ["prefix"] = prefix + } + }); + + clusters[clusterId] = new() + { + ClusterId = clusterId, + Destinations = new Dictionary() + { + { clusterId, new DestinationConfig() { Address = destination } } + } + }; +} + +builder.Services.AddReverseProxy() + .LoadFromMemory(routes, clusters.Values.ToList()) + .AddTransforms(builder => + { + if (builder.Route?.Metadata?["prefix"] is string prefix) + { + builder.AddPathRemovePrefix($"/{prefix}"); + } + }); + +var app = builder.Build(); + +app.UseServiceDefaults(); + +app.MapReverseProxy(); + +app.Run(); diff --git a/src/ApiGateways/Yarp/ApiGateway/Properties/launchSettings.json b/src/ApiGateways/Yarp/ApiGateway/Properties/launchSettings.json new file mode 100644 index 000000000..4ebe30168 --- /dev/null +++ b/src/ApiGateways/Yarp/ApiGateway/Properties/launchSettings.json @@ -0,0 +1,22 @@ +{ + "profiles": { + "Gateway.Http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5291", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Gateway.Https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7132;http://localhost:5291", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/ApiGateways/Yarp/ApiGateway/appsettings.Development.json b/src/ApiGateways/Yarp/ApiGateway/appsettings.Development.json new file mode 100644 index 000000000..0c208ae91 --- /dev/null +++ b/src/ApiGateways/Yarp/ApiGateway/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/ApiGateways/Yarp/ApiGateway/appsettings.json b/src/ApiGateways/Yarp/ApiGateway/appsettings.json new file mode 100644 index 000000000..61ff2f8b7 --- /dev/null +++ b/src/ApiGateways/Yarp/ApiGateway/appsettings.json @@ -0,0 +1,16 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "Urls": { + "Basket": "http://localhost:5221", + "Catalog": "http://localhost:5222", + "Orders": "http://localhost:5224", + "Identity": "http://localhost:5223", + "Signalr": "http://localhost:5225" + } +} diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 4437cc543..b48ea8c13 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -3,7 +3,6 @@ true true - @@ -88,5 +87,6 @@ + - + \ No newline at end of file diff --git a/src/Web/WebMVC/appsettings.json b/src/Web/WebMVC/appsettings.json index e0d07178a..401ef7d8f 100644 --- a/src/Web/WebMVC/appsettings.json +++ b/src/Web/WebMVC/appsettings.json @@ -1,8 +1,5 @@ { - "PurchaseUrl": "http://localhost:5229", - "CatalogUrl": "http://localhost:5222", - "OrderingUrl": "http://localhost:5224", - "BasketUrl": "http://localhost:5221", + "PurchaseUrl": "http://localhost:5291", "IdentityUrl": "http://localhost:5223", "IdentityUrlHC": "http://localhost:5223/hc", "CallBackUrl": "http://localhost:5100/", diff --git a/src/eShopOnContainers-ServicesAndWebApps.sln b/src/eShopOnContainers-ServicesAndWebApps.sln index 65aff4d0e..b3467e5eb 100644 --- a/src/eShopOnContainers-ServicesAndWebApps.sln +++ b/src/eShopOnContainers-ServicesAndWebApps.sln @@ -122,10 +122,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{373D8AA1 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBus.Tests", "BuildingBlocks\EventBus\EventBus.Tests\EventBus.Tests.csproj", "{95D735BE-2899-4495-BE3F-2600E93B4E3C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Services.Common", "Services\Services.Common\Services.Common.csproj", "{CD430CE4-D5E0-4C96-84F5-AEC9162651B5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Services.Common", "Services\Services.Common\Services.Common.csproj", "{CD430CE4-D5E0-4C96-84F5-AEC9162651B5}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{42B85D0F-2ED6-4C00-91FA-103DACC3D5E2}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Yarp", "Yarp", "{63F5F157-504F-4CE8-86B7-0A6F087BD888}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiGateway", "ApiGateways\Yarp\ApiGateway\ApiGateway.csproj", "{98C6B254-E9D0-4401-BF7A-89E87A38B87E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -1532,6 +1536,54 @@ Global {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|x64.Build.0 = Release|Any CPU {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|x86.ActiveCfg = Release|Any CPU {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|x86.Build.0 = Release|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|ARM.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|iPhone.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|x64.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|x64.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|x86.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|x86.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|ARM.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|ARM.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|iPhone.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|x64.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|x64.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|x86.ActiveCfg = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|x86.Build.0 = Debug|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|Any CPU.Build.0 = Release|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|ARM.ActiveCfg = Release|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|ARM.Build.0 = Release|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|iPhone.ActiveCfg = Release|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|iPhone.Build.0 = Release|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|x64.ActiveCfg = Release|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|x64.Build.0 = Release|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|x86.ActiveCfg = Release|Any CPU + {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1590,6 +1642,8 @@ Global {95D735BE-2899-4495-BE3F-2600E93B4E3C} = {373D8AA1-36BE-49EC-89F0-6CB736666285} {CD430CE4-D5E0-4C96-84F5-AEC9162651B5} = {42B85D0F-2ED6-4C00-91FA-103DACC3D5E2} {42B85D0F-2ED6-4C00-91FA-103DACC3D5E2} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} + {63F5F157-504F-4CE8-86B7-0A6F087BD888} = {77849D35-37D4-4802-81DC-9477B2775A40} + {98C6B254-E9D0-4401-BF7A-89E87A38B87E} = {63F5F157-504F-4CE8-86B7-0A6F087BD888} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9} From c3efea0293e02a27ebfb418a07919a2cce61fbce Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 11:43:21 -0700 Subject: [PATCH 084/118] Add YARP to the BFF directly. - This avoids the extra process hop --- .../aggregator/Extensions/Extensions.cs | 66 ++++++++++++++++- .../Web.Bff.Shopping/aggregator/Program.cs | 2 + .../Web.Shopping.HttpAggregator.csproj | 1 + .../aggregator/appsettings.json | 1 + .../Yarp/ApiGateway/ApiGateway.csproj | 17 ----- src/ApiGateways/Yarp/ApiGateway/Program.cs | 71 ------------------- .../ApiGateway/Properties/launchSettings.json | 22 ------ .../ApiGateway/appsettings.Development.json | 8 --- .../Yarp/ApiGateway/appsettings.json | 16 ----- src/Web/WebMVC/appsettings.json | 2 +- src/eShopOnContainers-ServicesAndWebApps.sln | 54 -------------- 11 files changed, 70 insertions(+), 190 deletions(-) delete mode 100644 src/ApiGateways/Yarp/ApiGateway/ApiGateway.csproj delete mode 100644 src/ApiGateways/Yarp/ApiGateway/Program.cs delete mode 100644 src/ApiGateways/Yarp/ApiGateway/Properties/launchSettings.json delete mode 100644 src/ApiGateways/Yarp/ApiGateway/appsettings.Development.json delete mode 100644 src/ApiGateways/Yarp/ApiGateway/appsettings.json diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs index d1ead0af6..feb217502 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs @@ -1,5 +1,69 @@ -internal static class Extensions +using Yarp.ReverseProxy.Configuration; +using Yarp.ReverseProxy.Transforms; + +internal static class Extensions { + public static IServiceCollection AddReverseProxy(this IServiceCollection services, IConfiguration configuration) + { + // REVIEW: This should come from configuration + var s = new (string, string, string)[] + { + ("c-short", "c", "catalog"), + ("c-long", "catalog-api", "catalog"), + + ("b-short", "b", "basket"), + ("b-long", "basket-api", "basket"), + + ("o-short", "o", "orders"), + ("o-long", "ordering-api", "orders"), + + ("h-long", "hub/notificationhub", "signalr") + }; + + var routes = new List(); + var clusters = new Dictionary(); + var urls = configuration.GetRequiredSection("Urls"); + + foreach (var (routeId, prefix, clusterId) in s) + { + var destination = urls.GetRequiredValue(clusterId); + + routes.Add(new() + { + RouteId = routeId, + ClusterId = clusterId, + Match = new() + { + Path = $"/{prefix}/{{**catch-all}}" + }, + Metadata = new Dictionary() + { + ["prefix"] = prefix + } + }); + + clusters[clusterId] = new() + { + ClusterId = clusterId, + Destinations = new Dictionary() + { + { clusterId, new DestinationConfig() { Address = destination } } + } + }; + } + + services.AddReverseProxy().LoadFromMemory(routes, clusters.Values.ToList()) + .AddTransforms(builder => + { + if (builder.Route?.Metadata?["prefix"] is string prefix) + { + builder.AddPathRemovePrefix($"/{prefix}"); + } + }); + + return services; + } + public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) { services.AddHealthChecks() diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs index 880d9b921..647fb422d 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs @@ -2,6 +2,7 @@ builder.AddServiceDefaults(); +builder.Services.AddReverseProxy(builder.Configuration); builder.Services.AddControllers(); builder.Services.AddHealthChecks(builder.Configuration); @@ -33,5 +34,6 @@ app.UseAuthorization(); app.MapGet("/", () => Results.Redirect("/swagger")); app.MapControllers().RequireCors("CorsPolicy"); +app.MapReverseProxy(); await app.RunAsync(); diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj index f5156ca94..d7523af19 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj @@ -8,6 +8,7 @@ + diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json index cd51126df..f3f1f44c7 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json @@ -32,6 +32,7 @@ "Catalog": "http://localhost:5222", "Orders": "http://localhost:5224", "Identity": "http://localhost:5223", + "Signalr": "http://localhost:5225", "GrpcBasket": "http://localhost:6221", "GrpcCatalog": "http://localhost:6222", "GrpcOrdering": "http://localhost:6224" diff --git a/src/ApiGateways/Yarp/ApiGateway/ApiGateway.csproj b/src/ApiGateways/Yarp/ApiGateway/ApiGateway.csproj deleted file mode 100644 index 432df38e3..000000000 --- a/src/ApiGateways/Yarp/ApiGateway/ApiGateway.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - net7.0 - enable - enable - - - - - - - - - - - diff --git a/src/ApiGateways/Yarp/ApiGateway/Program.cs b/src/ApiGateways/Yarp/ApiGateway/Program.cs deleted file mode 100644 index acc40633e..000000000 --- a/src/ApiGateways/Yarp/ApiGateway/Program.cs +++ /dev/null @@ -1,71 +0,0 @@ -using Services.Common; -using Yarp.ReverseProxy.Configuration; -using Yarp.ReverseProxy.Transforms; - -var builder = WebApplication.CreateBuilder(args); - -builder.AddServiceDefaults(); - -var services = new (string, string, string)[] -{ - ("c-short", "c", "catalog"), - ("c-long", "catalog-api", "catalog"), - - ("b-short", "b", "basket"), - ("b-long", "basket-api", "basket"), - - ("o-short", "o", "orders"), - ("o-long", "ordering-api", "orders"), - - ("h-long", "hub/notificationhub", "signalr") -}; - -var routes = new List(); -var clusters = new Dictionary(); -var urls = builder.Configuration.GetRequiredSection("Urls"); - -foreach (var (routeId, prefix, clusterId) in services) -{ - var destination = urls.GetRequiredValue(clusterId); - - routes.Add(new() - { - RouteId = routeId, - ClusterId = clusterId, - Match = new() - { - Path = $"/{prefix}/{{**catch-all}}" - }, - Metadata = new Dictionary() - { - ["prefix"] = prefix - } - }); - - clusters[clusterId] = new() - { - ClusterId = clusterId, - Destinations = new Dictionary() - { - { clusterId, new DestinationConfig() { Address = destination } } - } - }; -} - -builder.Services.AddReverseProxy() - .LoadFromMemory(routes, clusters.Values.ToList()) - .AddTransforms(builder => - { - if (builder.Route?.Metadata?["prefix"] is string prefix) - { - builder.AddPathRemovePrefix($"/{prefix}"); - } - }); - -var app = builder.Build(); - -app.UseServiceDefaults(); - -app.MapReverseProxy(); - -app.Run(); diff --git a/src/ApiGateways/Yarp/ApiGateway/Properties/launchSettings.json b/src/ApiGateways/Yarp/ApiGateway/Properties/launchSettings.json deleted file mode 100644 index 4ebe30168..000000000 --- a/src/ApiGateways/Yarp/ApiGateway/Properties/launchSettings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "profiles": { - "Gateway.Http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "applicationUrl": "http://localhost:5291", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "Gateway.Https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "applicationUrl": "https://localhost:7132;http://localhost:5291", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/src/ApiGateways/Yarp/ApiGateway/appsettings.Development.json b/src/ApiGateways/Yarp/ApiGateway/appsettings.Development.json deleted file mode 100644 index 0c208ae91..000000000 --- a/src/ApiGateways/Yarp/ApiGateway/appsettings.Development.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} diff --git a/src/ApiGateways/Yarp/ApiGateway/appsettings.json b/src/ApiGateways/Yarp/ApiGateway/appsettings.json deleted file mode 100644 index 61ff2f8b7..000000000 --- a/src/ApiGateways/Yarp/ApiGateway/appsettings.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*", - "Urls": { - "Basket": "http://localhost:5221", - "Catalog": "http://localhost:5222", - "Orders": "http://localhost:5224", - "Identity": "http://localhost:5223", - "Signalr": "http://localhost:5225" - } -} diff --git a/src/Web/WebMVC/appsettings.json b/src/Web/WebMVC/appsettings.json index 401ef7d8f..12c8e251b 100644 --- a/src/Web/WebMVC/appsettings.json +++ b/src/Web/WebMVC/appsettings.json @@ -1,5 +1,5 @@ { - "PurchaseUrl": "http://localhost:5291", + "PurchaseUrl": "http://localhost:5229", "IdentityUrl": "http://localhost:5223", "IdentityUrlHC": "http://localhost:5223/hc", "CallBackUrl": "http://localhost:5100/", diff --git a/src/eShopOnContainers-ServicesAndWebApps.sln b/src/eShopOnContainers-ServicesAndWebApps.sln index b3467e5eb..203d5b54d 100644 --- a/src/eShopOnContainers-ServicesAndWebApps.sln +++ b/src/eShopOnContainers-ServicesAndWebApps.sln @@ -126,10 +126,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Services.Common", "Services EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{42B85D0F-2ED6-4C00-91FA-103DACC3D5E2}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Yarp", "Yarp", "{63F5F157-504F-4CE8-86B7-0A6F087BD888}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiGateway", "ApiGateways\Yarp\ApiGateway\ApiGateway.csproj", "{98C6B254-E9D0-4401-BF7A-89E87A38B87E}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -1536,54 +1532,6 @@ Global {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|x64.Build.0 = Release|Any CPU {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|x86.ActiveCfg = Release|Any CPU {CD430CE4-D5E0-4C96-84F5-AEC9162651B5}.Release|x86.Build.0 = Release|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|x64.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Ad-Hoc|x86.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|Any CPU.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|ARM.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|ARM.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|iPhone.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|x64.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|x64.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|x86.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.AppStore|x86.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|ARM.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|ARM.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|iPhone.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|x64.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|x64.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|x86.ActiveCfg = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Debug|x86.Build.0 = Debug|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|Any CPU.Build.0 = Release|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|ARM.ActiveCfg = Release|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|ARM.Build.0 = Release|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|iPhone.ActiveCfg = Release|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|iPhone.Build.0 = Release|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|x64.ActiveCfg = Release|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|x64.Build.0 = Release|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|x86.ActiveCfg = Release|Any CPU - {98C6B254-E9D0-4401-BF7A-89E87A38B87E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1642,8 +1590,6 @@ Global {95D735BE-2899-4495-BE3F-2600E93B4E3C} = {373D8AA1-36BE-49EC-89F0-6CB736666285} {CD430CE4-D5E0-4C96-84F5-AEC9162651B5} = {42B85D0F-2ED6-4C00-91FA-103DACC3D5E2} {42B85D0F-2ED6-4C00-91FA-103DACC3D5E2} = {91CF7717-08AB-4E65-B10E-0B426F01E2E8} - {63F5F157-504F-4CE8-86B7-0A6F087BD888} = {77849D35-37D4-4802-81DC-9477B2775A40} - {98C6B254-E9D0-4401-BF7A-89E87A38B87E} = {63F5F157-504F-4CE8-86B7-0A6F087BD888} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {25728519-5F0F-4973-8A64-0A81EB4EA8D9} From 6a2fceb57c6d7f8e709e938924c1d67ba96e5854 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 17:01:29 -0700 Subject: [PATCH 085/118] Fix more urls --- .../Catalog/Catalog.API/appsettings.Development.json | 3 +-- src/Services/Identity/Identity.API/appsettings.json | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Services/Catalog/Catalog.API/appsettings.Development.json b/src/Services/Catalog/Catalog.API/appsettings.Development.json index b41dc527c..95e5cf490 100644 --- a/src/Services/Catalog/Catalog.API/appsettings.Development.json +++ b/src/Services/Catalog/Catalog.API/appsettings.Development.json @@ -1,5 +1,4 @@ { "ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word", - "PicBaseUrl": "http://localhost:5101/api/v1/catalog/items/[0]/pic/", - "EventBusConnection": "localhost" + "PicBaseUrl": "http://localhost:5222/api/v1/catalog/items/[0]/pic/" } \ No newline at end of file diff --git a/src/Services/Identity/Identity.API/appsettings.json b/src/Services/Identity/Identity.API/appsettings.json index 99f585c38..cc633ba9e 100644 --- a/src/Services/Identity/Identity.API/appsettings.json +++ b/src/Services/Identity/Identity.API/appsettings.json @@ -6,8 +6,6 @@ } }, "IsClusterEnv": "False", - "MvcClient": "http://localhost:5100", - "SpaClient": "http://localhost:5104", "XamarinCallback": "http://localhost:5105/xamarincallback", "UseCustomizationData": false, "ApplicationInsights": { @@ -18,5 +16,7 @@ "BasketApiClient": "http://localhost:5221", "OrderingApiClient": "http://localhost:5224", "WebShoppingAggClient": "http://localhost:5229", - "WebhooksApiClient": "http://localhost:5227" + "WebhooksApiClient": "http://localhost:5227", + "MvcClient": "http://localhost:5331", + "SpaClient": "http://localhost:5104" } From 561d48bc62f1b5e32a389a1b92e36abb31c393c5 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 17:35:58 -0700 Subject: [PATCH 086/118] Fix cors and prefix rewriting --- .../aggregator/Extensions/Extensions.cs | 22 +++++++++---------- .../Web.Bff.Shopping/aggregator/Program.cs | 4 ++-- src/Web/WebMVC/appsettings.json | 1 + 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs index feb217502..b57429ede 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs @@ -6,25 +6,25 @@ internal static class Extensions public static IServiceCollection AddReverseProxy(this IServiceCollection services, IConfiguration configuration) { // REVIEW: This should come from configuration - var s = new (string, string, string)[] + var s = new (string, string, string, bool)[] { - ("c-short", "c", "catalog"), - ("c-long", "catalog-api", "catalog"), + ("c-short", "c", "catalog", true), + ("c-long", "catalog-api", "catalog", true), - ("b-short", "b", "basket"), - ("b-long", "basket-api", "basket"), + ("b-short", "b", "basket", true), + ("b-long", "basket-api", "basket", true), - ("o-short", "o", "orders"), - ("o-long", "ordering-api", "orders"), + ("o-short", "o", "orders", true) , + ("o-long", "ordering-api", "orders", true), - ("h-long", "hub/notificationhub", "signalr") + ("h-long", "hub/notificationhub", "signalr", false) }; var routes = new List(); var clusters = new Dictionary(); var urls = configuration.GetRequiredSection("Urls"); - foreach (var (routeId, prefix, clusterId) in s) + foreach (var (routeId, prefix, clusterId, rewritePrefix) in s) { var destination = urls.GetRequiredValue(clusterId); @@ -36,10 +36,10 @@ internal static class Extensions { Path = $"/{prefix}/{{**catch-all}}" }, - Metadata = new Dictionary() + Metadata = rewritePrefix ? new Dictionary() { ["prefix"] = prefix - } + } : null }); clusters[clusterId] = new() diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs index 647fb422d..0babb8802 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs @@ -27,13 +27,13 @@ app.UseServiceDefaults(); app.UseHttpsRedirection(); -app.UseCors(); +app.UseCors("CorsPolicy"); app.UseAuthentication(); app.UseAuthorization(); app.MapGet("/", () => Results.Redirect("/swagger")); -app.MapControllers().RequireCors("CorsPolicy"); +app.MapControllers(); app.MapReverseProxy(); await app.RunAsync(); diff --git a/src/Web/WebMVC/appsettings.json b/src/Web/WebMVC/appsettings.json index 12c8e251b..ba45dbdd8 100644 --- a/src/Web/WebMVC/appsettings.json +++ b/src/Web/WebMVC/appsettings.json @@ -1,5 +1,6 @@ { "PurchaseUrl": "http://localhost:5229", + "SignalrHubUrl": "http://localhost:5229", "IdentityUrl": "http://localhost:5223", "IdentityUrlHC": "http://localhost:5223/hc", "CallBackUrl": "http://localhost:5100/", From 84c6b11c698f6c39642ab4afa151f090d89439bd Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 17:41:36 -0700 Subject: [PATCH 087/118] Remove cors from the signalr service - The frontend hits the gateway which does the preflight request --- .../Ordering/Ordering.SignalrHub/Program.cs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/Services/Ordering/Ordering.SignalrHub/Program.cs b/src/Services/Ordering/Ordering.SignalrHub/Program.cs index a030d5eb0..1b0abd099 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Program.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Program.cs @@ -2,16 +2,6 @@ builder.AddServiceDefaults(); -builder.Services.AddCors(options => -{ - options.AddPolicy("CorsPolicy", - builder => builder - .AllowAnyMethod() - .AllowAnyHeader() - .SetIsOriginAllowed((host) => true) - .AllowCredentials()); -}); - builder.Services.AddSignalR(builder.Configuration); builder.Services.AddSingleton, OrderStatusChangedToAwaitingValidationIntegrationEventHandler>(); @@ -25,10 +15,6 @@ var app = builder.Build(); app.UseServiceDefaults(); -app.UseCors("CorsPolicy"); -app.UseAuthentication(); -app.UseAuthorization(); - app.MapHub("/hub/notificationhub"); var eventBus = app.Services.GetRequiredService(); From bd745121b23061dcec2944201eaba023ee7e7daf Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 17:43:58 -0700 Subject: [PATCH 088/118] Added comment about allowed origins --- src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs index 0babb8802..b50806c94 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Program.cs @@ -8,6 +8,7 @@ builder.Services.AddControllers(); builder.Services.AddHealthChecks(builder.Configuration); builder.Services.AddCors(options => { + // TODO: Read allowed origins from configuration options.AddPolicy("CorsPolicy", builder => builder .SetIsOriginAllowed((host) => true) From 758d4bbe8857d6eb840d7e9633701d673c7beddd Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 17:53:05 -0700 Subject: [PATCH 089/118] Specify routes in config --- .../aggregator/Extensions/Extensions.cs | 19 ++++++------------- .../aggregator/appsettings.json | 12 ++++++++++++ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs index b57429ede..3ed7ca906 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs @@ -5,20 +5,13 @@ internal static class Extensions { public static IServiceCollection AddReverseProxy(this IServiceCollection services, IConfiguration configuration) { - // REVIEW: This should come from configuration - var s = new (string, string, string, bool)[] + // REVIEW: We could load the routes and clusters from configuration instead of code + // using YARP's default schema, it's slightly more verbose but also reloable. + var s = new List<(string, string, string, bool)>(); + foreach (var c in configuration.GetRequiredSection("Routes").GetChildren()) { - ("c-short", "c", "catalog", true), - ("c-long", "catalog-api", "catalog", true), - - ("b-short", "b", "basket", true), - ("b-long", "basket-api", "basket", true), - - ("o-short", "o", "orders", true) , - ("o-long", "ordering-api", "orders", true), - - ("h-long", "hub/notificationhub", "signalr", false) - }; + s.Add((c["0"], c["1"], c["2"], c.GetValue("3", false))); + } var routes = new List(); var clusters = new Dictionary(); diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json index f3f1f44c7..729dd5011 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json @@ -27,6 +27,18 @@ "webshoppingagg": "Shopping Aggregator for Web Clients" } }, + "Routes": [ + [ "c-short", "c", "catalog", true ], + [ "c-long", "catalog-api", "catalog", true ], + + [ "b-short", "b", "basket", true ], + [ "b-long", "basket-api", "basket", true ], + + [ "o-short", "o", "orders", true ], + [ "o-long", "ordering-api", "orders", true ], + + [ "h-long", "hub/notificationhub", "signalr", false ] + ], "Urls": { "Basket": "http://localhost:5221", "Catalog": "http://localhost:5222", From 69476a317543db7ae485a8f5dd770b07170ba092 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 18:12:17 -0700 Subject: [PATCH 090/118] Use the default YARP configuration --- .../aggregator/Extensions/Extensions.cs | 45 +------- .../aggregator/appsettings.json | 105 ++++++++++++++++-- 2 files changed, 96 insertions(+), 54 deletions(-) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs index 3ed7ca906..0c9aee1c2 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs @@ -1,51 +1,10 @@ -using Yarp.ReverseProxy.Configuration; -using Yarp.ReverseProxy.Transforms; +using Yarp.ReverseProxy.Transforms; internal static class Extensions { public static IServiceCollection AddReverseProxy(this IServiceCollection services, IConfiguration configuration) { - // REVIEW: We could load the routes and clusters from configuration instead of code - // using YARP's default schema, it's slightly more verbose but also reloable. - var s = new List<(string, string, string, bool)>(); - foreach (var c in configuration.GetRequiredSection("Routes").GetChildren()) - { - s.Add((c["0"], c["1"], c["2"], c.GetValue("3", false))); - } - - var routes = new List(); - var clusters = new Dictionary(); - var urls = configuration.GetRequiredSection("Urls"); - - foreach (var (routeId, prefix, clusterId, rewritePrefix) in s) - { - var destination = urls.GetRequiredValue(clusterId); - - routes.Add(new() - { - RouteId = routeId, - ClusterId = clusterId, - Match = new() - { - Path = $"/{prefix}/{{**catch-all}}" - }, - Metadata = rewritePrefix ? new Dictionary() - { - ["prefix"] = prefix - } : null - }); - - clusters[clusterId] = new() - { - ClusterId = clusterId, - Destinations = new Dictionary() - { - { clusterId, new DestinationConfig() { Address = destination } } - } - }; - } - - services.AddReverseProxy().LoadFromMemory(routes, clusters.Values.ToList()) + services.AddReverseProxy().LoadFromConfig(configuration.GetRequiredSection("ReverseProxy")) .AddTransforms(builder => { if (builder.Route?.Metadata?["prefix"] is string prefix) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json index 729dd5011..f9f077bc5 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json @@ -27,18 +27,101 @@ "webshoppingagg": "Shopping Aggregator for Web Clients" } }, - "Routes": [ - [ "c-short", "c", "catalog", true ], - [ "c-long", "catalog-api", "catalog", true ], - [ "b-short", "b", "basket", true ], - [ "b-long", "basket-api", "basket", true ], - - [ "o-short", "o", "orders", true ], - [ "o-long", "ordering-api", "orders", true ], - - [ "h-long", "hub/notificationhub", "signalr", false ] - ], + "ReverseProxy": { + "Routes": { + "c-short": { + "ClusterId": "catalog", + "Match": { + "Path": "c/{**catch-all}" + }, + "Metadata": { + "prefix": "c" + } + }, + "c-long": { + "ClusterId": "catalog", + "Match": { + "Path": "catalog-api/{**catch-all}" + }, + "Metadata": { + "prefix": "catalog-api" + } + }, + "b-short": { + "ClusterId": "basket", + "Match": { + "Path": "b/{**catch-all}" + }, + "Metadata": { + "prefix": "b" + } + }, + "b-long": { + "ClusterId": "basket", + "Match": { + "Path": "basket-api/{**catch-all}" + }, + "Metadata": { + "prefix": "basket-api" + } + }, + "o-short": { + "ClusterId": "orders", + "Match": { + "Path": "o/{**catch-all}" + }, + "Metadata": { + "prefix": "o" + } + }, + "o-long": { + "ClusterId": "orders", + "Match": { + "Path": "ordering-api/{**catch-all}" + }, + "Metadata": { + "prefix": "ordering-api" + } + }, + "h-long": { + "ClusterId": "signalr", + "Match": { + "Path": "hub/notificationhub/{**catch-all}" + } + } + }, + "Clusters": { + "basket": { + "Destinations": { + "basket/destination0": { + "Address": "http://localhost:5221" + } + } + }, + "catalog": { + "Destinations": { + "catalog/destination0": { + "Address": "http://localhost:5222" + } + } + }, + "orders": { + "Destinations": { + "orders/destination0": { + "Address": "http://localhost:5224" + } + } + }, + "signalr": { + "Destinations": { + "signalr/destination0": { + "Address": "http://localhost:5225" + } + } + } + } + }, "Urls": { "Basket": "http://localhost:5221", "Catalog": "http://localhost:5222", From 64a2d69e92c6b6f04652a1a42fe3c5643e827025 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 18:18:22 -0700 Subject: [PATCH 091/118] Use YARP native config --- .../aggregator/Extensions/Extensions.cs | 9 +---- .../aggregator/appsettings.json | 36 +++++++++---------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs index 0c9aee1c2..2e7be2107 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs @@ -4,14 +4,7 @@ internal static class Extensions { public static IServiceCollection AddReverseProxy(this IServiceCollection services, IConfiguration configuration) { - services.AddReverseProxy().LoadFromConfig(configuration.GetRequiredSection("ReverseProxy")) - .AddTransforms(builder => - { - if (builder.Route?.Metadata?["prefix"] is string prefix) - { - builder.AddPathRemovePrefix($"/{prefix}"); - } - }); + services.AddReverseProxy().LoadFromConfig(configuration.GetRequiredSection("ReverseProxy")); return services; } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json index f9f077bc5..ee2b43e35 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json @@ -35,54 +35,54 @@ "Match": { "Path": "c/{**catch-all}" }, - "Metadata": { - "prefix": "c" - } + "Transforms": [ + { "PathRemovePrefix": "/c" } + ] }, "c-long": { "ClusterId": "catalog", "Match": { "Path": "catalog-api/{**catch-all}" }, - "Metadata": { - "prefix": "catalog-api" - } + "Transforms": [ + { "PathRemovePrefix": "/catalog-api" } + ] }, "b-short": { "ClusterId": "basket", "Match": { "Path": "b/{**catch-all}" }, - "Metadata": { - "prefix": "b" - } + "Transforms": [ + { "PathRemovePrefix": "/b" } + ] }, "b-long": { "ClusterId": "basket", "Match": { "Path": "basket-api/{**catch-all}" }, - "Metadata": { - "prefix": "basket-api" - } + "Transforms": [ + { "PathRemovePrefix": "/basket-api" } + ] }, "o-short": { "ClusterId": "orders", "Match": { "Path": "o/{**catch-all}" }, - "Metadata": { - "prefix": "o" - } + "Transforms": [ + { "PathRemovePrefix": "/o" } + ] }, "o-long": { "ClusterId": "orders", "Match": { "Path": "ordering-api/{**catch-all}" }, - "Metadata": { - "prefix": "ordering-api" - } + "Transforms": [ + { "PathRemovePrefix": "/ordering-api" } + ] }, "h-long": { "ClusterId": "signalr", From 62a6f1759521793769adc437aeecb5c413db5d99 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 18:52:48 -0700 Subject: [PATCH 092/118] Removed unneeded usings --- .../Web.Bff.Shopping/aggregator/Extensions/Extensions.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs index 2e7be2107..fefb4f351 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Extensions/Extensions.cs @@ -1,6 +1,4 @@ -using Yarp.ReverseProxy.Transforms; - -internal static class Extensions +internal static class Extensions { public static IServiceCollection AddReverseProxy(this IServiceCollection services, IConfiguration configuration) { From 40315c69d7908053939c6cda536543869123b10d Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 19:28:55 -0700 Subject: [PATCH 093/118] Make docker use the reverse proxy --- .../Web.Bff.Shopping/aggregator/appsettings.json | 8 ++++---- src/docker-compose.override.yml | 8 ++++++-- src/docker-compose.yml | 1 - 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json index ee2b43e35..233d14be5 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/appsettings.json @@ -94,28 +94,28 @@ "Clusters": { "basket": { "Destinations": { - "basket/destination0": { + "destination0": { "Address": "http://localhost:5221" } } }, "catalog": { "Destinations": { - "catalog/destination0": { + "destination0": { "Address": "http://localhost:5222" } } }, "orders": { "Destinations": { - "orders/destination0": { + "destination0": { "Address": "http://localhost:5224" } } }, "signalr": { "Destinations": { - "signalr/destination0": { + "destination0": { "Address": "http://localhost:5225" } } diff --git a/src/docker-compose.override.yml b/src/docker-compose.override.yml index 46c762515..f60cde8b7 100644 --- a/src/docker-compose.override.yml +++ b/src/docker-compose.override.yml @@ -213,6 +213,10 @@ services: - urls__grpcBasket=http://basket-api:81 - urls__grpcCatalog=http://catalog-api:81 - urls__grpcOrdering=http://ordering-api:81 + - ReverseProxy__Clusters__basket__Destinations__destination0__Address=http://basket-api + - ReverseProxy__Clusters__catalog__Destinations__destination0__Address=http://catalog-api + - ReverseProxy__Clusters__orders__Destinations__destination0__Address=http://ordering-api + - ReverseProxy__Clusters__signalr__Destinations__destination0__Address=http://ordering-signalrhub - CatalogUrlHC=http://catalog-api/hc - OrderingUrlHC=http://ordering-api/hc - IdentityUrlHC=http://identity-api/hc @@ -286,9 +290,9 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_URLS=http://0.0.0.0:80 - - PurchaseUrl=http://webshoppingapigw + - PurchaseUrl=http://webshoppingagg - IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 - - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202 + - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5121 - IdentityUrlHC=http://identity-api/hc - UseCustomizationData=True - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY} diff --git a/src/docker-compose.yml b/src/docker-compose.yml index 327b6f7ac..6a9a48310 100644 --- a/src/docker-compose.yml +++ b/src/docker-compose.yml @@ -147,7 +147,6 @@ services: dockerfile: Web/WebMVC/Dockerfile depends_on: - webshoppingagg - - webshoppingapigw webhooks-client: image: ${REGISTRY:-eshop}/webhooks.client:${PLATFORM:-linux}-${TAG:-latest} From 8c2ca8dbd9b0f9149d2fdedd755e56e662f6e513 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 22:21:52 -0700 Subject: [PATCH 094/118] Make WebMVC use the service common helpers --- src/Web/WebMVC/Extensions/Extensions.cs | 86 +++++++++++++++ src/Web/WebMVC/Program.cs | 132 ++---------------------- src/Web/WebMVC/WebMVC.csproj | 13 +-- src/Web/WebMVC/appsettings.json | 7 ++ src/Web/WebMVC/globalusings.cs | 5 +- 5 files changed, 105 insertions(+), 138 deletions(-) create mode 100644 src/Web/WebMVC/Extensions/Extensions.cs diff --git a/src/Web/WebMVC/Extensions/Extensions.cs b/src/Web/WebMVC/Extensions/Extensions.cs new file mode 100644 index 000000000..58ad01203 --- /dev/null +++ b/src/Web/WebMVC/Extensions/Extensions.cs @@ -0,0 +1,86 @@ +// Fix samesite issue when running eShop from docker-compose locally as by default http protocol is being used +// Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391 +internal static class Extensions +{ + public static void AddHealthChecks(this WebApplicationBuilder builder) + { + builder.Services.AddHealthChecks() + .AddUrlGroup(_ => new Uri(builder.Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }); + } + + public static void AddApplicationSevices(this WebApplicationBuilder builder) + { + builder.Services.Configure(builder.Configuration) + .AddSession() + .AddDistributedMemoryCache(); + + if (builder.Configuration["DPConnectionString"] is string redisConnection) + { + builder.Services.AddDataProtection(opts => + { + opts.ApplicationDiscriminator = "eshop.webmvc"; + }) + .PersistKeysToStackExchangeRedis(ConnectionMultiplexer.Connect(redisConnection), "DataProtection-Keys"); + } + } + + // Adds all Http client services + public static void AddHttpClientServices(this WebApplicationBuilder builder) + { + // Register delegating handlers + builder.Services.AddTransient() + .AddTransient(); + + // Add http client services + builder.Services.AddHttpClient() + .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Sample. Default lifetime is 2 minutes + .AddHttpMessageHandler(); + + builder.Services.AddHttpClient(); + + builder.Services.AddHttpClient() + .AddHttpMessageHandler() + .AddHttpMessageHandler(); + + + //add custom application services + builder.Services.AddTransient, IdentityParser>(); + } + + public static void AddAuthenticationServices(this WebApplicationBuilder builder) + { + JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); + + var identityUrl = builder.Configuration.GetRequiredValue("IdentityUrl"); + var callBackUrl = builder.Configuration.GetRequiredValue("CallBackUrl"); + var sessionCookieLifetime = builder.Configuration.GetValue("SessionCookieLifetimeMinutes", 60); + + // Add Authentication services + + builder.Services.AddAuthentication(options => + { + options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; + }) + .AddCookie(options => options.ExpireTimeSpan = TimeSpan.FromMinutes(sessionCookieLifetime)) + .AddOpenIdConnect(options => + { + options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; + options.Authority = identityUrl; + options.SignedOutRedirectUri = callBackUrl; + options.ClientId = "mvc"; + options.ClientSecret = "secret"; + options.ResponseType = "code"; + options.SaveTokens = true; + options.GetClaimsFromUserInfoEndpoint = true; + options.RequireHttpsMetadata = false; + options.Scope.Add("openid"); + options.Scope.Add("profile"); + options.Scope.Add("orders"); + options.Scope.Add("basket"); + options.Scope.Add("webshoppingagg"); + options.Scope.Add("orders.signalrhub"); + options.Scope.Add("webhooks"); + }); + } +} diff --git a/src/Web/WebMVC/Program.cs b/src/Web/WebMVC/Program.cs index ce7d33208..fac986d73 100644 --- a/src/Web/WebMVC/Program.cs +++ b/src/Web/WebMVC/Program.cs @@ -1,34 +1,21 @@ var builder = WebApplication.CreateBuilder(args); -builder.Services.AddControllersWithViews(); - -AddApplicationInsights(builder); -AddHealthChecks(builder); -AddCustomMvc(builder); -AddHttpClientServices(builder); -AddCustomAuthentication(builder); -builder.WebHost.CaptureStartupErrors(false); +builder.AddServiceDefaults(); -var app = builder.Build(); +builder.Services.AddControllersWithViews(); -JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); -if (!app.Environment.IsDevelopment()) -{ - app.UseExceptionHandler("/Error"); -} +builder.AddHealthChecks(); +builder.AddApplicationSevices(); +builder.AddHttpClientServices(); +builder.AddAuthenticationServices(); -var pathBase = builder.Configuration["PATH_BASE"]; +var app = builder.Build(); -if (!string.IsNullOrEmpty(pathBase)) -{ - app.UsePathBase(pathBase); -} +app.UseServiceDefaults(); app.UseStaticFiles(); app.UseSession(); -WebContextSeed.Seed(app, app.Environment); - // Fix samesite issue when running eShop from docker-compose locally as by default http protocol is being used // Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391 app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.Lax }); @@ -41,106 +28,7 @@ app.UseAuthorization(); app.MapControllerRoute("default", "{controller=Catalog}/{action=Index}/{id?}"); app.MapControllerRoute("defaultError", "{controller=Error}/{action=Error}"); app.MapControllers(); -app.MapHealthChecks("/liveness", new HealthCheckOptions -{ - Predicate = r => r.Name.Contains("self") -}); -app.MapHealthChecks("/hc", new HealthCheckOptions() -{ - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse -}); - -await app.RunAsync(); - -static void AddApplicationInsights(WebApplicationBuilder builder) -{ - builder.Services.AddApplicationInsightsTelemetry(builder.Configuration); - builder.Services.AddApplicationInsightsKubernetesEnricher(); -} - -static void AddHealthChecks(WebApplicationBuilder builder) -{ - builder.Services.AddHealthChecks() - .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddUrlGroup(_ => new Uri(builder.Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }); -} - -static void AddCustomMvc(WebApplicationBuilder builder) -{ - builder.Services.Configure(builder.Configuration) - .AddSession() - .AddDistributedMemoryCache(); - if (builder.Configuration.GetValue("IsClusterEnv") == bool.TrueString) - { - builder.Services.AddDataProtection(opts => - { - opts.ApplicationDiscriminator = "eshop.webmvc"; - }) - .PersistKeysToStackExchangeRedis(ConnectionMultiplexer.Connect(builder.Configuration["DPConnectionString"]), "DataProtection-Keys"); - } -} - -// Adds all Http client services -static void AddHttpClientServices(WebApplicationBuilder builder) -{ - builder.Services.AddHttpContextAccessor(); - - //register delegating handlers - builder.Services.AddTransient() - .AddTransient(); - - //set 5 min as the lifetime for each HttpMessageHandler int the pool - builder.Services.AddHttpClient("extendedhandlerlifetime").SetHandlerLifetime(TimeSpan.FromMinutes(5)); - - //add http client services - builder.Services.AddHttpClient() - .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Sample. Default lifetime is 2 minutes - .AddHttpMessageHandler(); - - builder.Services.AddHttpClient(); - - builder.Services.AddHttpClient() - .AddHttpMessageHandler() - .AddHttpMessageHandler(); - - - //add custom application services - builder.Services.AddTransient, IdentityParser>(); -} - -static void AddCustomAuthentication(WebApplicationBuilder builder) -{ - var identityUrl = builder.Configuration.GetValue("IdentityUrl"); - var callBackUrl = builder.Configuration.GetValue("CallBackUrl"); - var sessionCookieLifetime = builder.Configuration.GetValue("SessionCookieLifetimeMinutes", 60); - - // Add Authentication services +WebContextSeed.Seed(app, app.Environment); - builder.Services.AddAuthentication(options => - { - options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; - }) - .AddCookie(setup => setup.ExpireTimeSpan = TimeSpan.FromMinutes(sessionCookieLifetime)) - .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options => - { - options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; - options.Authority = identityUrl.ToString(); - options.SignedOutRedirectUri = callBackUrl.ToString(); - options.ClientId = "mvc"; - options.ClientSecret = "secret"; - options.ResponseType = "code"; - options.SaveTokens = true; - options.GetClaimsFromUserInfoEndpoint = true; - options.RequireHttpsMetadata = false; - options.Scope.Add("openid"); - options.Scope.Add("profile"); - options.Scope.Add("orders"); - options.Scope.Add("basket"); - options.Scope.Add("webshoppingagg"); - options.Scope.Add("orders.signalrhub"); - options.Scope.Add("webhooks"); - }); -} +await app.RunAsync(); diff --git a/src/Web/WebMVC/WebMVC.csproj b/src/Web/WebMVC/WebMVC.csproj index e0b3fff05..cad1a70be 100644 --- a/src/Web/WebMVC/WebMVC.csproj +++ b/src/Web/WebMVC/WebMVC.csproj @@ -5,8 +5,6 @@ aspnet-Microsoft.eShopOnContainers-946ae052-8305-4a99-965b-ec8636ddbae3 ..\..\..\docker-compose.dcproj 3.0 - false - true @@ -24,21 +22,12 @@ - - - - - - - - - - + diff --git a/src/Web/WebMVC/appsettings.json b/src/Web/WebMVC/appsettings.json index ba45dbdd8..bcf097610 100644 --- a/src/Web/WebMVC/appsettings.json +++ b/src/Web/WebMVC/appsettings.json @@ -1,4 +1,11 @@ { + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", "PurchaseUrl": "http://localhost:5229", "SignalrHubUrl": "http://localhost:5229", "IdentityUrl": "http://localhost:5223", diff --git a/src/Web/WebMVC/globalusings.cs b/src/Web/WebMVC/globalusings.cs index 1fe624e28..d315d7434 100644 --- a/src/Web/WebMVC/globalusings.cs +++ b/src/Web/WebMVC/globalusings.cs @@ -15,14 +15,12 @@ global using System.Text.Json; global using System.Text.Json.Serialization; global using System.Threading; global using System.Threading.Tasks; -global using HealthChecks.UI.Client; global using Microsoft.AspNetCore.Authentication; global using Microsoft.AspNetCore.Authentication.Cookies; global using Microsoft.AspNetCore.Authentication.OpenIdConnect; global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.DataProtection; -global using Microsoft.AspNetCore.Diagnostics.HealthChecks; global using Microsoft.AspNetCore.Hosting; global using Microsoft.AspNetCore.Http; global using Microsoft.AspNetCore.Identity; @@ -37,10 +35,9 @@ global using Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels; global using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination; global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Diagnostics.HealthChecks; -global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Options; +global using Services.Common; global using StackExchange.Redis; global using WebMVC.Infrastructure; global using WebMVC.Services.ModelDTOs; From 0a07aea4ff01705f24bbe8befaecb618e55ead16 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 22:34:58 -0700 Subject: [PATCH 095/118] Small refactoring of the helper methods --- src/Web/WebMVC/Extensions/Extensions.cs | 41 ++++++++++++------------- src/Web/WebMVC/Program.cs | 13 +++----- 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/Web/WebMVC/Extensions/Extensions.cs b/src/Web/WebMVC/Extensions/Extensions.cs index 58ad01203..4118f167a 100644 --- a/src/Web/WebMVC/Extensions/Extensions.cs +++ b/src/Web/WebMVC/Extensions/Extensions.cs @@ -2,21 +2,21 @@ // Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391 internal static class Extensions { - public static void AddHealthChecks(this WebApplicationBuilder builder) + public static void AddHealthChecks(this IServiceCollection services, IConfiguration configuration) { - builder.Services.AddHealthChecks() - .AddUrlGroup(_ => new Uri(builder.Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }); + services.AddHealthChecks() + .AddUrlGroup(_ => new Uri(configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }); } - public static void AddApplicationSevices(this WebApplicationBuilder builder) + public static void AddApplicationSevices(this IServiceCollection services, IConfiguration configuration) { - builder.Services.Configure(builder.Configuration) - .AddSession() - .AddDistributedMemoryCache(); + services.Configure(configuration) + .AddSession() + .AddDistributedMemoryCache(); - if (builder.Configuration["DPConnectionString"] is string redisConnection) + if (configuration["DPConnectionString"] is string redisConnection) { - builder.Services.AddDataProtection(opts => + services.AddDataProtection(opts => { opts.ApplicationDiscriminator = "eshop.webmvc"; }) @@ -25,39 +25,38 @@ internal static class Extensions } // Adds all Http client services - public static void AddHttpClientServices(this WebApplicationBuilder builder) + public static void AddHttpClientServices(this IServiceCollection services) { // Register delegating handlers - builder.Services.AddTransient() + services.AddTransient() .AddTransient(); // Add http client services - builder.Services.AddHttpClient() + services.AddHttpClient() .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Sample. Default lifetime is 2 minutes .AddHttpMessageHandler(); - builder.Services.AddHttpClient(); + services.AddHttpClient(); - builder.Services.AddHttpClient() + services.AddHttpClient() .AddHttpMessageHandler() .AddHttpMessageHandler(); //add custom application services - builder.Services.AddTransient, IdentityParser>(); + services.AddTransient, IdentityParser>(); } - public static void AddAuthenticationServices(this WebApplicationBuilder builder) + public static void AddAuthenticationServices(this IServiceCollection services, IConfiguration configuration) { JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); - var identityUrl = builder.Configuration.GetRequiredValue("IdentityUrl"); - var callBackUrl = builder.Configuration.GetRequiredValue("CallBackUrl"); - var sessionCookieLifetime = builder.Configuration.GetValue("SessionCookieLifetimeMinutes", 60); + var identityUrl = configuration.GetRequiredValue("IdentityUrl"); + var callBackUrl = configuration.GetRequiredValue("CallBackUrl"); + var sessionCookieLifetime = configuration.GetValue("SessionCookieLifetimeMinutes", 60); // Add Authentication services - - builder.Services.AddAuthentication(options => + services.AddAuthentication(options => { options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; diff --git a/src/Web/WebMVC/Program.cs b/src/Web/WebMVC/Program.cs index fac986d73..8939a24c9 100644 --- a/src/Web/WebMVC/Program.cs +++ b/src/Web/WebMVC/Program.cs @@ -4,10 +4,10 @@ builder.AddServiceDefaults(); builder.Services.AddControllersWithViews(); -builder.AddHealthChecks(); -builder.AddApplicationSevices(); -builder.AddHttpClientServices(); -builder.AddAuthenticationServices(); +builder.Services.AddHealthChecks(builder.Configuration); +builder.Services.AddApplicationSevices(builder.Configuration); +builder.Services.AddAuthenticationServices(builder.Configuration); +builder.Services.AddHttpClientServices(); var app = builder.Build(); @@ -20,11 +20,6 @@ app.UseSession(); // Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391 app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.Lax }); -app.UseRouting(); - -app.UseAuthentication(); -app.UseAuthorization(); - app.MapControllerRoute("default", "{controller=Catalog}/{action=Index}/{id?}"); app.MapControllerRoute("defaultError", "{controller=Error}/{action=Error}"); app.MapControllers(); From a7cdb1df684f57848015e82ce6905e9a83f95077 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 22:52:55 -0700 Subject: [PATCH 096/118] Remove unused code --- .../WebMVC/Extensions/HttpClientExtensions.cs | 28 ------------------- .../WebMVC/Extensions/SessionExtensions.cs | 16 ----------- 2 files changed, 44 deletions(-) delete mode 100644 src/Web/WebMVC/Extensions/HttpClientExtensions.cs delete mode 100644 src/Web/WebMVC/Extensions/SessionExtensions.cs diff --git a/src/Web/WebMVC/Extensions/HttpClientExtensions.cs b/src/Web/WebMVC/Extensions/HttpClientExtensions.cs deleted file mode 100644 index 3c95e0254..000000000 --- a/src/Web/WebMVC/Extensions/HttpClientExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace Microsoft.eShopOnContainers.WebMVC.Extensions; - -public static class HttpClientExtensions -{ - public static void SetBasicAuthentication(this HttpClient client, string userName, string password) => - client.DefaultRequestHeaders.Authorization = new BasicAuthenticationHeaderValue(userName, password); - - public static void SetToken(this HttpClient client, string scheme, string token) => - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(scheme, token); - - public static void SetBearerToken(this HttpClient client, string token) => - client.SetToken(JwtConstants.TokenType, token); -} - -public class BasicAuthenticationHeaderValue : AuthenticationHeaderValue -{ - public BasicAuthenticationHeaderValue(string userName, string password) - : base("Basic", EncodeCredential(userName, password)) - { } - - private static string EncodeCredential(string userName, string password) - { - Encoding encoding = Encoding.GetEncoding("iso-8859-1"); - string credential = string.Format("{0}:{1}", userName, password); - - return Convert.ToBase64String(encoding.GetBytes(credential)); - } -} diff --git a/src/Web/WebMVC/Extensions/SessionExtensions.cs b/src/Web/WebMVC/Extensions/SessionExtensions.cs deleted file mode 100644 index f2edb3c8b..000000000 --- a/src/Web/WebMVC/Extensions/SessionExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -public static class SessionExtensions -{ - public static void SetObject(this ISession session, string key, object value) => - session.SetString(key, JsonSerializer.Serialize(value)); - - public static T GetObject(this ISession session, string key) - { - var value = session.GetString(key); - - return value == null ? default : JsonSerializer.Deserialize(value, new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true - }); - } -} - From 992b58d4bc14fd8f26ecc90606ebd0f0e18c9b54 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Sun, 7 May 2023 23:42:55 -0700 Subject: [PATCH 097/118] Fixed cookies --- src/Web/WebMVC/Program.cs | 5 +++++ src/Web/WebMVC/appsettings.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Web/WebMVC/Program.cs b/src/Web/WebMVC/Program.cs index 8939a24c9..71748a750 100644 --- a/src/Web/WebMVC/Program.cs +++ b/src/Web/WebMVC/Program.cs @@ -20,6 +20,11 @@ app.UseSession(); // Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391 app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = SameSiteMode.Lax }); +app.UseRouting(); + +app.UseAuthentication(); +app.UseAuthorization(); + app.MapControllerRoute("default", "{controller=Catalog}/{action=Index}/{id?}"); app.MapControllerRoute("defaultError", "{controller=Error}/{action=Error}"); app.MapControllers(); diff --git a/src/Web/WebMVC/appsettings.json b/src/Web/WebMVC/appsettings.json index bcf097610..a520f002e 100644 --- a/src/Web/WebMVC/appsettings.json +++ b/src/Web/WebMVC/appsettings.json @@ -10,7 +10,7 @@ "SignalrHubUrl": "http://localhost:5229", "IdentityUrl": "http://localhost:5223", "IdentityUrlHC": "http://localhost:5223/hc", - "CallBackUrl": "http://localhost:5100/", + "CallBackUrl": "http://localhost:5331/", "IsClusterEnv": "False", "UseResilientHttp": "True", "UseLoadTest": false, From 6933d9997d7b780fff3b076a5a9fd5f567743d23 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Mon, 8 May 2023 00:03:14 -0700 Subject: [PATCH 098/118] Forward SignalR requests through the web app --- src/Web/WebMVC/AppSettings.cs | 1 - src/Web/WebMVC/Extensions/Extensions.cs | 25 +++++++++++++++++ src/Web/WebMVC/Program.cs | 2 ++ src/Web/WebMVC/Views/Shared/_Layout.cshtml | 32 ++++++---------------- src/Web/WebMVC/WebMVC.csproj | 1 + 5 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/Web/WebMVC/AppSettings.cs b/src/Web/WebMVC/AppSettings.cs index 8879abf2e..b1a8b6851 100644 --- a/src/Web/WebMVC/AppSettings.cs +++ b/src/Web/WebMVC/AppSettings.cs @@ -3,6 +3,5 @@ public class AppSettings { public string PurchaseUrl { get; set; } - public string SignalrHubUrl { get; set; } public bool UseCustomizationData { get; set; } } diff --git a/src/Web/WebMVC/Extensions/Extensions.cs b/src/Web/WebMVC/Extensions/Extensions.cs index 4118f167a..8c8a6843c 100644 --- a/src/Web/WebMVC/Extensions/Extensions.cs +++ b/src/Web/WebMVC/Extensions/Extensions.cs @@ -1,5 +1,7 @@ // Fix samesite issue when running eShop from docker-compose locally as by default http protocol is being used // Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391 +using Yarp.ReverseProxy.Forwarder; + internal static class Extensions { public static void AddHealthChecks(this IServiceCollection services, IConfiguration configuration) @@ -82,4 +84,27 @@ internal static class Extensions options.Scope.Add("webhooks"); }); } + + public static IEndpointConventionBuilder MapForwardSignalR(this WebApplication app) + { + // Forward the SignalR traffic to the bff + var destination = app.Configuration.GetRequiredValue("PurchaseUrl"); + var authTransformer = new BffAuthTransfomer(); + var requestConfig = new ForwarderRequestConfig(); + + return app.MapForwarder("/hub/notificationhub/{**any}", destination, requestConfig, authTransformer); + } + + private sealed class BffAuthTransfomer : HttpTransformer + { + public override async ValueTask TransformRequestAsync(HttpContext httpContext, HttpRequestMessage proxyRequest, string destinationPrefix, CancellationToken cancellationToken) + { + // Set the access token as a bearer token for the outgoing request + var accessToken = await httpContext.GetTokenAsync("access_token"); + + proxyRequest.Headers.Authorization = new("Bearer", accessToken); + + await base.TransformRequestAsync(httpContext, proxyRequest, destinationPrefix, cancellationToken); + } + } } diff --git a/src/Web/WebMVC/Program.cs b/src/Web/WebMVC/Program.cs index 71748a750..aa55b2cb7 100644 --- a/src/Web/WebMVC/Program.cs +++ b/src/Web/WebMVC/Program.cs @@ -2,6 +2,7 @@ builder.AddServiceDefaults(); +builder.Services.AddHttpForwarder(); builder.Services.AddControllersWithViews(); builder.Services.AddHealthChecks(builder.Configuration); @@ -28,6 +29,7 @@ app.UseAuthorization(); app.MapControllerRoute("default", "{controller=Catalog}/{action=Index}/{id?}"); app.MapControllerRoute("defaultError", "{controller=Error}/{action=Error}"); app.MapControllers(); +app.MapForwardSignalR(); WebContextSeed.Seed(app, app.Environment); diff --git a/src/Web/WebMVC/Views/Shared/_Layout.cshtml b/src/Web/WebMVC/Views/Shared/_Layout.cshtml index 9a634b78a..6cb3f43fb 100644 --- a/src/Web/WebMVC/Views/Shared/_Layout.cshtml +++ b/src/Web/WebMVC/Views/Shared/_Layout.cshtml @@ -86,35 +86,23 @@ @RenderSection("scripts", required: false) - - @using Microsoft.AspNetCore.Authentication; - @using Microsoft.Extensions.Options - @inject IOptions settings -