diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index fc1fa06..c295da3 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -41,6 +41,16 @@ jobs: run: yarn test:ci env: REDIS_URL: redis://localhost:6767 + IDP_MILO_CONSEILLER_AUTHORIZATION_URL: ${{ secrets.IDP_MILO_CONSEILLER_AUTHORIZATION_URL }} + IDP_MILO_CONSEILLER_CLIENT_ID: ${{ secrets.IDP_MILO_CONSEILLER_CLIENT_ID }} + IDP_MILO_CONSEILLER_CLIENT_SECRET: ${{ secrets.IDP_MILO_CONSEILLER_CLIENT_SECRET }} + IDP_MILO_CONSEILLER_ISSUER: ${{ secrets.IDP_MILO_CONSEILLER_ISSUER }} + IDP_MILO_CONSEILLER_JWKS: ${{ secrets.IDP_MILO_CONSEILLER_JWKS }} + IDP_MILO_CONSEILLER_REDIRECT_URI: ${{ secrets.IDP_MILO_CONSEILLER_REDIRECT_URI }} + IDP_MILO_CONSEILLER_SCOPES: ${{ secrets.IDP_MILO_CONSEILLER_SCOPES }} + IDP_MILO_CONSEILLER_TOKEN_URL: ${{ secrets.IDP_MILO_CONSEILLER_TOKEN_URL }} + IDP_MILO_CONSEILLER_USERINFO: ${{ secrets.IDP_MILO_CONSEILLER_USERINFO }} + TEST_MILO_CONSEILLER_OFFLINE_TOKEN: ${{ secrets.TEST_MILO_CONSEILLER_OFFLINE_TOKEN }} - name: SonarCloud Scan uses: SonarSource/sonarcloud-github-action@master env: diff --git a/.vault b/.vault index 0626f8c..8a18206 100644 --- a/.vault +++ b/.vault @@ -4,5 +4,5 @@ "begin": "# BEGIN VAULT", "end": "# END VAULT" }, - "data": "af29c7061e085ac50edc754e2c9707607ac86350e85f02d4115c2b6024715a98dae98f0e37a47447c9f2fd3c2a6539aafc2e54dcf300c1618f83d9d5f5fba62586997a48627230d5f3ab326d9101d3b4fcddd2c4efa5a0db34601dc29ac0e71d77c37215ff6b77f38ee3a5c328759a756a9fde19dbb4fbf0cac13af08eb63ebf6187057367b8cdc489ccf26dc548b856aaa61db467d59180fab83a03cdd41f97c912ad1295f4a87814ef130663329edf5b9cc9c647bd80c451493bbc3006ebe107edc35b6b4f3bb5f6f188ff98d341b7aa00258268ff44e4d168c791dfefe96f2d0e406a4d537507b811bde978c291057b8c689c5a0374a719cacb1dc3a04cdaeed636586103d23c3ec641dcd959b0629574c57ccf28609d392f2d6cb41eccbfc8466659a4917805473dd8c9e652956e234642ef3c85647c6087d84b21ff8dd093baff24362708c024dc12385abcc78c673ae9cf782463c8c7430e92c53a874c1373f79b800d1b09231664bbf3511eaf95d1d081208dd5fbfd1b4715a40468d713ea0e13a2bcf130a6f4ef292b35f9e9c44065651139cff1384b4d5d5eba60bd31c92134c797de4bd652bab11f3ca01544ba6a6bdb2426955a6701e08670a837b502a34fea8d17641573f4c0c3376b424b78c095398b83ff0a05efcdf90fd4e63063c86c20f686c2f7fdf130355607fef5d71cad7bc311090312bd6e11c13c90b2d3c927c542d0125da9088f55b6d5ff0cad14ff3ae9e7c7f7cb93827db299e3b396803e74421cbeca8b1b9b5adbc0b0f6668bf92c81c4afcbe5c8efe24ea9d1e92975993d43ea45190023fd90b85ee453a3dca658b8bfce5c80a605fd62cc20321fa96e8df0a3de789163631631614483185dce117ae4266b152f6f4f426cf6ce77049cd999db480f3604b3d8902470ccdb68e4326431e3d9d211c09a019e3071d6fbe253f8ac355efdc2a292f90cfdc130085f941c1fd9fbef1427c585e5106de360e49e81b52bbcdf3148eb0a068b84d412d7e42b2253dcba93b19bdd900a816fa4e098945cbe9ee1e05f11d9bdc12a4c48e8167d38ca0341da487a6515f7ae0b9ece4e50f5f97b265e6afe699ee3362120e632ff95793db5776fb3c8b62e0d628fcea23349355aa0fbd1ce877fdb744c4e9591936391c482c8c8e67c27240a6c2703a435ccfb814554a1cd9a10a61fd101341cbcf1ccf2013909ad5821e6a0afda093990366623048c959dd32dd833e979a280831641c1cbcbedd3c06c60558e807d5188828132a65f585e621577c216538bdd1e8638172af6dd60be764f6584ffd767877fdc1ed4757b31695124522fe786cbd42b4c553105c1ee6ad4b6019979763c2258b3c7bfba300932d57cfe3d3147b318f91f2534bc68a506df7e55c6b02dea5483392d8df87bd15eb8cfa0a1b5a8c786e0ca6dcfeba4475ffaa1d29ee4d0aeb6b4a4b9f1e6188ac1de1a1609c325e842f3b92fb506027343dd17db3ecd5bf2767a21afe185f842fd452b6634719df0f656faa068c30c6ec7c39fb67f62bb4b0a2f7a4b8e72b830223e494025c134b257d5448f74f3afbc58269770c16ab5f099024ab5f5f9140f2215b06c5576605b04fae8c84087563dda1a1f177f3f4cd519f73e6a4aa244b784e60304fafd919a34e96f987037d1029abe2f28bf782b365b51c60a5f8ebda1701a760680e7fcbdae90dd8b0b1d7ca1c30d156da45ec221446c88f58a846fe595fe4212ca159fccb3ce31801785c199312afc18b17918178fcab6f18a41ac3c2602b1b0f560fdec91aece7eba42b5c2c7cdc75bbf3d5db107ca4d2be1fb0a282a60267c44f37cc6a52a5fb187fb09fa272936c6e940017a526b13e3695a0200f3f44bbade8305cd90cb8a66040d37569ad341311edb9db66b9c7f1337ead244e6e4f6f5267f8f958b2c39d5f0009dcd12f85ba893a8c580b21c50c66641f53b42e92a267083797e95d7691db9d20f182f42eeeaf7836c743f2cade60609b7f9ca7c1a5680cda919e6ef51b3fdef745f0bf32cdde9c39566e9a1b90249e19af207011d93f20a4a8544b39dfbb76922f16a25c535f9e5d6da82cb7fcd0ad60ed2bc1fb7fef92da97b61df08dd0c79aad4b08ddcb7a727eee4674afe4a230caf5380673a376ff32c017b1f070882e94a4b75b8a5679c0e83977ba20198fc1ece0394d5c0109deacd5d8cadf43b5f4d5b1add546acefc28fd1f179e1e1a930873d7162c5a40e11f106934743a37bdbba1457ddd5b8308f24a837669301bbfc374ac39edbba1c0da490fb72ea7fa64736bf932ba0f55fa15ea305ccc156586371bf6ec6349d2d8c2af5be4cbbd723978ba5e248bb56f3ed27e4dcac4d1e619d01d391259d4f71bfba22af180379bd9a657dee715684b7f71cc8bb421827b6ce367c4c26c859a3ed8d9734a353992efe9d7e8c4dc69487c79ab01cd3dccbd90e1ef7a65b168d90bee5b0fbdd041fdb9416e9b8d317fa9a062288f3028ec9f93ac34588d17a43487a3734dc8d22466401006b7339f0ec691ba1e56a085e4a7a7aed54cd6e4fce293d363e1d0aaa59f05c1f137d4fa53bef9498a0bfcf0c373a4c756f8ea346b2d74427aaab1d70ab65e0d7da9235a78f0039688aca7be0de60d89fcf7fd341031ae88e69209fbd06f267781867ea4d9dcf1dc79a39696eb68119d3b50570547f64521e3922edd3adccfa8e1a5b88effd47b8c3762e2cc5a9a90a192f82eda12c469e588944cd3e19c45bebbc5ff4adf8d7146571c1192779de57c9700c6d7e4379d150831110c95ff66a82a6b98abde507e6de78397ea8e3b9025b076bc4c6eb0d4924b4d169a377d08a62a83bf13f7840ce51f9aeb8acc1adea54ee30283cd1f5480e77fdf7437e4c466f086930e195ee3d76c08896232f9aef61fec3fd18c62a9bd896f1c731cf1c13b677bb4833af655c6f0ed1307a6ddb6f6801ce9474d3ac9b1076a2d2b71757a1668d0504e77ecd4ec44a30531d9f2c3964e2b16e98523c4423c0e07ab8de190894929c9e5bc98ce2a8638aacbeaac6c5be091a77f679317587f520bcb399b780e9c90b8f85a41046cb563c2c634e90408966c0567a855e4c6f9cbdf81acb23eee074d12eadb8f5914060fa5b10a41884ba3d26c43bcabffb5ef4ea295e90b11e3488f7b71e9ffbfa4099418dee4f034fdb3042da07533b3cc69f35c133d62463e5275c3f135cc1da8e64d1dc389cd3a83a35ca2fd8df8f85709740f25d1050f45067e77cbf2421c6eac7f831c03ba30844670c27b000f1d58ba86008b7936809310e858a96620f572111fd7f42f6047af2a4e5fe6a70245c6222fb0a318bd7edcbb5a2863624fdd38982f2f69c7cdec5c1d5fcff7ebbef981c1cc0a5e27374b8d8d627041f7eb6f99481619a9991da3bb0e5752c616a0b8948710e4aba8962d1e35a7eb609fd779471f4a500444070cc71c5f2b972d77c857993c61c53699a373340197f697328d060c09ad8330043cb8322c2e52c392d8f3cb9a4198309cc57793b90b6b433be916c7fdee167a1296e56474ebddd023a2f399b69ac463f9914e3dd0ab95fdc47154abc00f40d13ded451c345aa7a1e80b89f4dd0c041e47a3aad2a3d1a55d19e720740f922eb493df338b687aff124652288273702a03547b396a86e1e1f28618ba1f6ff872a30de16ad82ab23aec295c23cd5b5b39461be10cd080c52b3903612972b38151b71a95155c98a1517aa14506dab013a4d4d10a985d4863f12778b9e75856ecd741cd1c96d96e5e8c062a9e52de25dd45702155d4ec561f638d548bfd35e981902aa9eb3dbb2a7bc637c5c51abf7d3205f7816b7ca4c8c83e0592dde4cc36e11b0082a4dade4a1761cad57dd76f25fbafcfc14e0a76ee28c603257ecf831d5468e6d63dc0b78e181a1ab387f49705b935444e1615f2a47e3693103ce08808242a9d0b3624cc85d632563b90da24950a121660bcd4d7faa5ac16b6e8db4c686747262c7dbdb9ed9063de9c31d10bdd7eb79311657ce7ef56d4cd8c3a20d153e5cde1529c35f9174efadccd129de345aa22d2afee6edd59536ebde234044702bb77bae465ec767fe5fbc6548eefa41b0d0f8fb8563cc633ff903b3ad4301be97d4c147406651361b24f2c80d89cec00bf0325ba1def78f4a4a6609213fe27ed192e86069a9254228f98d18de248df693a429e8e7e2ef5f83eb509ed29ae0843100f52523c02f0017a6729f8af0d87b6fef13d257afeda03eaa4f92604189883a46c5bc76341922ed25dafdcacca900b91b5fda726ee19d550c540373424f6e309c753c1149c82cf422c2863e64928688beb761b009093f507b1a1419292d0e8f72dfaeded6345038819c6a0b5560dcb09e3882eba77a27956536914cc9977a62467d6be52c4e05a222dd6aec807cb13c46382a1fe981bbc17fdbce84dd988bd2de9067b5192c6c20007773e4fb34e8859c6c68912f103198d274f6aaba2d88ed0d78c31d9715ea4a61ca29871d9a386b2085c71b8efaf3fc1c37243691e776bfb2efc57b2130e6a09b0a657784fda585c6ed4786eb0a9a56653a2105898d98b07c66d508d6e90897b5660db0d0d00f0216c0ff18bc29e1ec1598ff8e8ef94cca9fc0c91314534b5790be9141eb1dee6131587eee85f3639f01f6651583b652bb9490ac949661abdf7a0560e4ca948780c04e685f8a8ab44297fdfaa09f5fee327dd4641c0272947acfd7c28cfc193ff10126bd59feea490f85460704eeb09548670c101abffd3363727c9af23699a939c558887596468b6672771c7b88e5ca3812fb0c22a2d3161b183593e0a3eeea69c5cdc9c0816b57785bde373ee5d7aade9ff169c05e8be5929ce16cf1c63561c1d033ae80900fcfa04afb1f17734b912b94ce5c0d0177a0fca80bf0bc0acf4accd8cd629dd6f862014c677fffa1f6daf831d1d28d6ec6ec86ba00f9fa5748521f2a5082003f81c097454464d98eba43cf98d9157a55f1dd91536af427cfca9d8e44a74d7d116f3d942831795b1eebe6ebebc77db6964846e1da50e5a427b30d95f9833388c0d7a19596e30f58bb71b9af1c577576e0a8e38ff3545ebc9ef9ac19586adcbee2b57b7b91c01424cc7238da5b16d065601437f3b93820d9909d5fe3642199a055a36d9ef79a9e4dd0471f4630e70d336575ee5a4bd75781ed2e804692eaa231491e0e538ff5d02d2eb033328134cf66fcad482bdea55c44edb0d5c7f1630c66745fcb472a31e07598e39d91947abd753fa39083f591d818338832cc7f311d2caa696fd21728677e9a6dee61ccbf25670d6fdac3ede0bb5e23e3a6ba360a3a56cb90cfbaa7406c0d946bfaee364874c79bf5fe7e58600d920f82f60882509267d9772f37e0158f4245ba6fc408e81f84c1232d220c3596392fac82c09e17e0af34a32be29b829f771de502c9a976eb5d980da672ce47e76d7f37bdc42dfe4405dea8c78644a3a6c8748ff1122d9f892623e059c42bbe41375d3b9d8091230a609c9204d1d90462c7535b16a05c9496aec18387b20b2e91cd4f972ed3741be30c1a6d347c981d26f9666dd855ca7421cd5fecb707a7ee13d13509680be9aeb267c31f7e74b2b78bbc399bfe8ae75fcdfe6bef1368fad5dab1cacb6ca7a3da66af7d2df9c87375bfd1cb427f1bd0d3c14969e0b01aec77d497052d2422e66f2a8ba37b909684e38a566acb9829ca99ebebf38131a4c7988e134d97e33bbbfada9eea3dd9dcd08e06af9b7ac57fc3768031f29d4e8073faf76ba0ecdfda31922493626fe9b305ca68b7f454cc1b83529903e1b0b4404159d3548b1c866987b905dab18aa1f1dd6a11001c8112a4a5be0ceabcd71938c7ad5714c1619a96a9f1fbd686ff58b81f705cb7ecf8983b95df0dcb5d329c6ad3cfbd2b2d75a13b72b5424d9626319a8c227134ccc2b8f3654ab286416998590f7c0c10cce38b72683c7f807d210e1c05695805b0ba3e1e04b80b1af6a4c54aef682c6baedb0e843bdbed9b963b87702d9f45e98ccdea9bca25043026a528cfc3fe9ce4623b3e4bca34c20638c53a609d7cb690c5764982958b65c6bece167efe225f1f4d0123a51d41223423b28436d025621bdb82d1921d150b2123e61c22e7dcf579c8fc5bde60dbf43acb3ab607df6a5ac5cfc14f7b100bd02864d98b27d2e37b0989a592ab30e85bf08171c818b2a5db5269bbeab44711d238250d299e00160cd520873e5b7f32552659ce847c2accd23cba6af236f90289f67b0e2626283f35b81634caddf35d54d934aa8580e4b300972b04f8492cde8c077fd94025e88888dc4be9c3377ed86ea79f2d8db211bac9fd39d5f910e5ed9a91069aa5d2474dea0f046f6bfda5db9bcec1d25b43149fdb6fa35df1d70c28205940caa5da31f6fd40d0f7f44de89cd8b3973c088f722c9833450ab7b5137b2cf3283f0b678c6cf844610fd16dc4229670b6681bb8bfc83ea8bdd0b3e1d29644209dc093fe9214f5aa5efff4f6a40272e55773b258ac64fd6b4f320beaf4072bc0fa9d5aafc202316cc38b5c4d5596a44af006e14ee4f65e91f34285a0efc8f7593b601e79f0f051788ee002b3cb38cec479f0ce69a288af692b81a853e664b1e86b0f6181d2493dac6ed22e7a3a45e9f920b92da43ce5e88348bf8b5fbd899f1826f4a628bf41df3d604da4b2ff2af767d6092e58d5e99f33ff817db4a1c89fb24d93d11b9e534aff80b6f9ecc9cdf3677a57beda81fba38e9f1f195d0df5404f641de7de56ee5e821cd03fde3574599b604c8803ba3d9997e076a06f3fce65f42a3f70c55bd2844f90d35dea473e9b97c30af271d39f890a52eb80a58ad5bf17f984c6ff778399f2d0a4eb050248564284ea08ee563c83324145b74f276578305bb2c20542ed38125d0c28d511b6296ec828f2e08108e7d518363d9fd42f4074eaaf5cdf90e9b4bc9d1bc8496416cde424bbf113b4c7f75a02d4fbe139d9051ab7b3f05ad1e3812e7991d217faa67572fe2896d58f10098a8e1227f132623f1c69cfaafbc5a33683e4e4d7a86721488dd40888d36cb28c710f3173a33ffd1326e5f735ec2f58806ef562ac4c115583c66153740f4aa42cebe104df3cd220e8697ab54ab23789d3b3c30e1ec667a83b1433375baf451f5ced03cc749c4c035a9959275f5bb500bf5add8a2a27177a691e4224128b27c19e060dfdc78a209cd19edfb33637a47bf121dd25491cf4feb29c4a2e05b73c4d60cbb3d382cb7deb5ca139a9dd384a128dd895b3a680e4aec7b7d4144f07eca8086a29693459e17f8ab9414d5067fffa745e8c9c39fda5bfe204fbec0cda6f8e0ba5f21c1cdc605523e08ba707ff335b02b445af44617d7234ed18de3abad4e22b30dd519db6025e3a057cc524e937539598cc467a7ff37e8fb23fd9929799d46b6bbcc25e0bcd88e5aa3e07bd523575651670fbb2df8b44ff303cb7b25fcb7d0a8bf33ea8a642ccf3d097799b649409223e5df42bf33bbd055b44bd0d292ace0c96c0a46586ada7108b09e77dd559c1d343cc8221a2c142e14823604e03e6be731cc3ea69b29f03d0d63fd2ba49ca86c3bd1103c615700c3f35b131f7792f75b6ae6b9da7ebffdd9b08867a2a0bd3d6a26762ac245afe91ad305027685ccebd285263b209b817cce5c4f67ea6c62a2b042f5d5bbc3ca6f15540f0b2bcc2fa7bec8e552b6a0e5c90f96ba9e409d48002e8b6af601acad9b441de8e08ab682a3975db836631916f2384bf0559effc656319a5224b20eeb7658072bdf756aa1fff458cff53da621cd9c8d194860031d56b6b850e969bba7f17a3f4e162e481c859eca96ed6902b8bf5c145676d079dd002919d4fdbf9d8db25695475b3f34d118c12b456af6ce0e0cf3997c0e6e3e1a2dcebc76901d090ef6961010265298bc37cb97bbb903e094b709539b477cfeb4421969bd58be837cdf653d1f377f012ce3ce24954d406cbffa85cc311836e4c3d7e3229824b27361fb54b0d21114dc471a6fa44511852e922dcefbabaa07427714bb1942a4473b2d785a7cbdfad72ed7de266b182ee59d5da437e2b6b8cc40cbcc83c33ff0c63a95afbeeff2a8826142885fd2642cf52a493815d463ac6a988bf5245715c2758012f2f9685745dcd17f1af5340993efd7b86957674d60dd17040c34e241b46c54233d6487f939b27738b263315b2f71bc24c4a47acd96568a754958f9915905cb2640971fdf252852afdee9de77424051853e659ac4299ab912a944e24968dbb004123a18e93d4956d1f33afdcfae9af1deaa6d6f75871c8106057c5a1987b64ff4d4e82277e2dbe8eba65f5bdd3810f44a6329d7289e1fea1dfc7924aa5a47516c24c5417d3ffc605d2a7d3ca78b4a284e7c8f4d267d554f104674c5480add239d0e0123a482fc7c7af7b254eb90be81135674b386e846cd60777b1d7050dd4059f7e805738c6d4a15d0cef4db55af1bae67bcecaab656e97f566c510d5145400dcf3f4359cda3a83fba0c6367ea7480a4a8a8cf473b48b8e6dc5ad422c781ba31156b43bfd0186d634b30a4a997fafaa4d030db4ca32d7b06071c4c209ed0f64daeb77726787b921bdeaf9e87fd17ad8de1f60651b136d36def8cb56d935a0ae783fcc5c35d8d4c51634eab5fed002f637c269504ea27dd4609979cb9f3b5afc7558708c5d94ef5ae0c565a48343e2f70c262024cf16d698817d98374e6c4abd1cd3fc725a666a9ca7491c30a3695599dd22e7a70b6ad0df5a8d2741266fa6171d80cf63e2a8b73cdfccbda0325819d56bc7430f65be5813edd2060c3437a622006fd099381eb3537afa961d04a01e09686c4283f96154949b8fc0503224b3d7835cddfc8016f02390ccb858449880c082cdee67cc0a20472354edfa4ad91e2c6c7de117898926efd0c11188c3e2f9af4862362364cf280270dc35bdc2442d840908b00831ef6cf5edbb34153c7641c45dfc14a92d5351ed68430ec3c7dc85e53bb9d452e856d60b5342cc9da140a4b4938a94163f6d11a12f515943b7221f0f94b2ab003d96baf23b65e2a845ee7db5855ce796ce3515ace2407489d2c877f65919fb754e35946ca227ea6be73575e1dc31549aedd28e55f10350875febd08ec9bf58d48e3013f09a70790f3bbf0f5f8b91c94e0abdba8f4ec6bcfc9bd1f2848e72fe490a98300439a808f2c3a3ab387d21370804c53a0ff75bdd9736b2decdc47c589e91f9958b973a065b1e88fc8d4092f2c7a85400f8131648e15296dc16709c63906a3a7406e7c9aabc2e93a0acfba6dd669e362fd4dbb7732e6d66709a1569088e483cc0440489451b0e9a2fefab3ab0209b5905721f0865141d8a6a64940e3cce222ed6752394bfe7e2ced1b91ce930fc73a807fcd454f75c54a2264a5dac105a63a6919cc1c4f5a4897172d60038b035344cea4e984a454bd33eee2f8ca8552c23b705eb314475930880d938cf504e9e1f749baafc649e7cf7ed6bc08850d2352af3d69b3d7697aac5557563517a49d52bda3aead030bc9a0db264833b9db826e8a94af27db4d20a5199cd8259f8883c35ed345a42fbe789b76b926973f0330fc8ae9341d20593bede8bb986ea51a2f3c40401e489b9c0f914a3a15eba594e861af2d0a34256ea5e59bb9175e18940b22eea2fa7dbb2fa70d8349909ae3e206e1930153e5b7ec24a730eaea7b820254fb9566026cc9bbc82be1dbb1394aab90b6a28f3eddeceb699005134d4b6cc9c7b41c96fe7a222647829f0a7c83b5430ccf7a41cb1625f81be907c748baf157fd8c7fa8a4a0094e947350bfa356a5bd027b2d6ceccbfa5187c795479e20ddea7d3164b427588ef64bcbc2051c6513f0e65c3a6e656caa1574d71836b4eef1d7a8d77d758a7a0cefa110747f4d0a60aae092ccaedeb19920cd67fb55225db15403468f19296864cf6655761b06061cf3ff614f693c3cad51885932ad9c83ce753239c12f63d7854b482282c2de764e9cf8cb3bab78a69974ff9bd4fcd94852a5b2ba2dcbe472625fd7bf4325a70a71077b344bfa2c4f25be88cb08ccd6fe086f358f066fb42908f37369acbe170c5d441e43a65fc27008587d21305b385bf9f477013a3cea3f774330c8df0164d8638b7307d9ff29bdfd833e4fa9d4453d6d78827a5174f99b8035bb7bb0dbaf4becc8c5fde2659e3cb3719ada3882046b8cdf775444a527899bcc4dd72f26082d93b729651e6e3a1abdcbcb7c196b2b40109e2962a9e97c42cc991dc882deb82599f336fd8a1345e736f083b36b0559b11069187c21a4d5f555c0331ed55ba87c8af5c37d977e6cfead0668c85559eefa5194466d4bbb5dbcda81f8f4be734fe06bda9edb935e9eb9bcb9082cb7b82a4cd6e8485a95dcfaad99f58c2ae16135b72ec96bd6527325de354dd069d266d9234f00a1569e013f00faaca02aaa56fbc8b134e2db49a458d3c4a4ffed70c1bb8823b27e9c3a39d0dbfcf3e9ececfb915b914c0e93f94ef76df559afc84c9a1fbc1d993a32ee40cfb3221390ba56f2b6d85e8356c0f73b06ebfe04729f76003789aa0b72e8e25773d3fea6b40ded7403fe82525a895c11c9cef1bb7c82f461fad4a6e42518fdbaae43217bcf7f9ae7ada1579c513774c0b051075fc77615d3772003de0ca89a9faeec25baba292805d6477afe7e61ec3ef0b09ff56abae7f080bd183cfa1e867a841631d1314832f67edabc4674104714afe6046c60d946ee75e50273658a661bac78ea64551765a8f5eb43efa312a122125786e32a4c740657830c06d7268d4d05b36a422914ff8c1202dff3ff4699c996cf56dd88ff33f9078f717d6cebe99261ed278a539f4a6dd42505099a1d6d6f30af97b3a5a0e64fb1dbf2984c69fa4ae843931177ed080d51ffcb732325dd20a444ed2c417555872203ab61380d5082706924b29a8c4482939fe070b0e0651377e0cd06e851e4a3d38840bbcaf49ab7f2d21acb865bc22870b1e50e217f5f2257a0600e1ae5c1be68a16c290c40409e7c5996564015f859b1eb96c4f309cba95aa0954486d4635f44f2f2724b01ece387dabc465e44af4bb3f0fd4a692d9a24a2c2cf5b827c918aee6a40522a60edc193f00ee9a0340c4e91fcd2048d80b32eb17560743a888f19d58f2c7fbea8890c819cdbb6ea7eeffcff5fb095ead5f86733c6b0c253109d3a3ce7b6171dfed0e74164a870894eec30d63ba7173eb8f51aee5ddff27f45bcc33670ab650279d3dd58040f9f8c56264e22933ff1f2f9ed3536d1f228910bb8c75917fe5e912beaaeb6d8b4df39ea33689e709f4696bc095d1a7282c2338ddd961739b3a11dab473789c5ea54e36a1ac7748e8e715078e325e34831d0fc5324975236b903671c500989047d3c2b675006f00a8a757a8a00657aa66c31a6b638b462bc5712e9d431efa48912ef910d9ea7d571d77c7601b4aa1ff623d597d092a3a6069f2f76e2bc580be07239ad1fe90b83fd9bb202126acc65935f6c974bf845b8ac869963474a0d4486898d733fa6798dda80f604439d93a1370c5d7b57a6ddf598511546b73e3a0557ff1975f267983be9d98088ebecf6b30e9b6888f8966d543dbab35d52df8ecb6041c561436e6edf7ce42b93dffc30d991f2a2ade02c8e17f172417b0bb5bd2505cf06d7867a7d62d8985862abd8ab960c88e65ee8f603224f60a71d3b77449c5c56af4b415223037edd5ca9e21d70b3ed3f37e7dcb4b5ebd4601a894e6658a7bb7dc9eb8c6ca5dfc5388f012739381c7eae369a4cca841d84696af55a1adce66ab0cacd787e3b2466348d7548e8a16241f7bfa01f6cdb14927947107e71d7812a910f993c00977fdf4496c8b991cdc9e52cb61a2621f4721352cde35b98effc0d3564de5d81418371005699354c657ef4b25982fabfafa02749480bd83f95b4a4d1c3067cdda23d80d7d2e4eacf5ed2f894bfcb8316282c03f81aeb019acf1bc73662fb2b5cab151bf6673329ea51c81f5d2ae5c07fc7d548789a1962f438997bb6ef21a783f0c3c46aed0135c150766c15444e972d3b0bbc432287d8001c70d9c379612fe0b469355909d5093e3de6eabe867e24af389033886fa2bf52d35a003fe3ec14f1783872d637d490a9ef964b95be66ff5997f637ef1b634e2f22c0dd17834d4a8498a7b0a92a61188cd89cdae282feebefa1a1246f7230f350aaebd0bd73cce64d322ee3b0143fc4639ae0160d2d0114c3e09aea42e5ee3cab7db51359c258e4cdb9da2ab261097c946eda72300f9247c373b1ae9862f9d3895e7b2e09f70a6c6429c2f81beb8209d7f3cfecf578840e123a880b624f3c6145a4e3935be537b179efdf673791ae573c689b2d20112ad601af7b052a7748ebe40bdb182317b7ee20e56a22a760c6ea6d8aa9fc946700ec694816e0f181dccc0571091abc1f9398869ebbb914188e904910485fdce16a65c7ed092be89b32f32ac2d3b83f9ef763969f7fbe12faebd11b496a9ae3075d0414ee24240cdf41b925e3842d7946e7c975590d6dfcb268346ab42d4d9ec823150cde5ed0aa8e306201eac0830d3493ee58c5d3f21720735f97ce6e0ab73d12ed6c69bc45b2c8a5bbfd1d964d85657a6b34191e8e92c86c859f4b07a7ffdaf254873313e773c4ee434cdcb49041487b913ce178dd49819f3c8a915b2afface5885f7e2a2e179175b49c8c340129a22b79beb7e7e990db13fe9bafdbca360686c11fd6e4ad05b6e657947d650e72f4a38d7cf67fc4c5ece2321f08ebaeccea56e4d0295b52921fab615369ee432993b3fb7c472245741aa22d9c04c5f34febb53278ea00cbf3c689eeab0848fd4a4b0276d833e0b73d015b404c2ad0a968a0bc8d25dcbb344ab9150061b211c7d879c0bb3c2c9ff715e2e7c3dd40f9e95dfae3049791814474fdc08fa48d6224c6a137f735355c69936404fc986136f50c7d" + "data": "af29c7061e085ac50edc754e2c9707607ac86350e85f02d4115c2b6024715a98dae98f0e37a47447c9f2fd3c2a6539aafc2e54dcf300c1618f83d9d5f5fba62586997a48627230d5f3ab326d9101d3b4fcddd2c4efa5a0db34601dc29ac0e71d77c37215ff6b77f38ee3a5c328759a756a9fde19dbb4fbf0cac13af08eb63ebf6187057367b8cdc489ccf26dc548b856aaa61db467d59180fab83a03cdd41f97c912ad1295f4a87814ef130663329edf5b9cc9c647bd80c451493bbc3006ebe107edc35b6b4f3bb5f6f188ff98d341b7aa00258268ff44e4d168c791dfefe96f2d0e406a4d537507b811bde978c291057b8c689c5a0374a719cacb1dc3a04cdaeed636586103d23c3ec641dcd959b0629574c57ccf28609d392f2d6cb41eccbfc8466659a4917805473dd8c9e652956e234642ef3c85647c6087d84b21ff8dd093baff24362708c024dc12385abcc78c673ae9cf782463c8c7430e92c53a874c1373f79b800d1b09231664bbf3511eaf95d1d081208dd5fbfd1b4715a40468d713ea0e13a2bcf130a6f4ef292b35f9e9c44065651139cff1384b4d5d5eba60bd31c92134c797de4bd652bab11f3ca01544ba6a6bdb2426955a6701e08670a837b502a34fea8d17641573f4c0c3376b424b78c095398b83ff0a05efcdf90fd4e63063c86c20f686c2f7fdf130355607fef5d71cad7bc311090312bd6e11c13c90b2d3c927c542d0125da9088f55b6d5ff0cad14ff3ae9e7c7f7cb93827db299e3b396803e74421cbeca8b1b9b5adbc0b0f6668bf92c81c4afcbe5c8efe24ea9d1e92975993d43ea45190023fd90b85ee453a3dca658b8bfce5c80a605fd62cc20321fa96e8df0a3de789163631631614483185dce117ae4266b152f6f4f426cf6ce77049cd999db480f3604b3d8902470ccdb68e4326431e3d9d211c09a019e3071d6fbe253f8ac355efdc2a292f90cfdc130085f941c1fd9fbef1427c585e5106de360e49e81b52bbcdf3148eb0a068b84d412d7e42b2253dcba93b19bdd900a816fa4e098945cbe9ee1e05f11d9bdc12a4c48e8167d38ca0341da487a6515f7ae0b9ece4e50f5f97b265e6afe699ee3362120e632ff95793db5776fb3c8b62e0d628fcea23349355aa0fbd1ce877fdb744c4e9591936391c482c8c8e67c27240a6c2703a435ccfb814554a1cd9a10a61fd101341cbcf1ccf2013909ad5821e6a0afda093990366623048c959dd32dd833e979a280831641c1cbcbedd3c06c60558e807d5188828132a65f585e621577c216538bdd1e8638172af6dd60be764f6584ffd767877fdc1ed4757b31695124522fe786cbd42b4c553105c1ee6ad4b6019979763c2258b3c7bfba300932d57cfe3d3147b318f91f2534bc68a506df7e55c6b02dea5483392d8df87bd15eb8cfa0a1b5a8c786e0ca6dcfeba4475ffaa1d29ee4d0aeb6b4a4b9f1e6188ac1de1a1609c325e842f3b92fb506027343dd17db3ecd5bf2767a21afe185f842fd452b6634719df0f656faa068c30c6ec7c39fb67f62bb4b0a2f7a4b8e72b830223e494025c134b257d5448f74f3afbc58269770c16ab5f099024ab5f5f9140f2215b06c5576605b04fae8c84087563dda1a1f177f3f4cd519f73e6a4aa244b784e60304fafd919a34e96f987037d1029abe2f28bf782b365b51c60a5f8ebda1701a760680e7fcbdae90dd8b0b1d7ca1c30d156da45ec221446c88f58a846fe595fe4212ca159fccb3ce31801785c199312afc18b17918178fcab6f18a41ac3c2602b1b0f560fdec91aece7eba42b5c2c7cdc75bbf3d5db107ca4d2be1fb0a282a60267c44f37cc6a52a5fb187fb09fa272936c6e940017a526b13e3695a0200f3f44bbade8305cd90cb8a66040d37569ad341311edb9db66b9c7f1337ead244e6e4f6f5267f8f958b2c39d5f0009dcd12f85ba893a8c580b21c50c66641f53b42e92a267083797e95d7691db9d20f182f42eeeaf7836c743f2cade60609b7f9ca7c1a5680cda919e6ef51b3fdef745f0bf32cdde9c39566e9a1b90249e19af207011d93f20a4a8544b39dfbb76922f16a25c535f9e5d6da82cb7fcd0ad60ed2bc1fb7fef92da97b61df08dd0c79aad4b08ddcb7a727eee4674afe4a230caf5380673a376ff32c017b1f070882e94a4b75b8a5679c0e83977ba20198fc1ece0394d5c0109deacd5d8cadf43b5f4d5b1add546acefc28fd1f179e1e1a930873d7162c5a40e11f106934743a37bdbba1457ddd5b8308f24a837669301bbfc374ac39edbba1c0da490fb72ea7fa64736bf932ba0f55fa15ea305ccc156586371bf6ec6349d2d8c2af5be4cbbd723978ba5e248bb56f3ed27e4dcac4d1e619d01d391259d4f71bfba22af180379bd9a657dee715684b7f71cc8bb421827b6ce367c4c26c859a3ed8d9734a353992efe9d7e8c4dc69487c79ab01cd3dccbd90e1ef7a65b168d90bee5b0fbdd041fdb9416e9b8d317fa9a062288f3028ec9f93ac34588d17a43487a3734dc8d22466401006b7339f0ec691ba1e56a085e4a7a7aed54cd6e4fce293d363e1d0aaa59f05c1f137d4fa53bef9498a0bfcf0c373a4c756f8ea346b2d74427aaab1d70ab65e0d7da9235a78f0039688aca7be0de60d89fcf7fd341031ae88e69209fbd06f267781867ea4d9dcf1dc79a39696eb68119d3b50570547f64521e3922edd3adccfa8e1a5b88effd47b8c3762e2cc5a9a90a192f82eda12c469e588944cd3e19c45bebbc5ff4adf8d7146571c1192779de57c9700c6d7e4379d150831110c95ff66a82a6b98abde507e6de78397ea8e3b9025b076bc4c6eb0d4924b4d169a377d08a62a83bf13f7840ce51f9aeb8acc1adea54ee30283cd1f5480e77fdf7437e4c466f086930e195ee3d76c08896232f9aef61fec3fd18c62a9bd896f1c731cf1c13b677bb4833af655c6f0ed1307a6ddb6f6801ce9474d3ac9b1076a2d2b71757a1668d0504e77ecd4ec44a30531d9f2c3964e2b16e98523c4423c0e07ab8de190894929c9e5bc98ce2a8638aacbeaac6c5be091a77f679317587f520bcb399b780e9c90b8f85a41046cb563c2c634e90408966c0567a855e4c6f9cbdf81acb23eee074d12eadb8f5914060fa5b10a41884ba3d26c43bcabffb5ef4ea295e90b11e3488f7b71e9ffbfa4099418dee4f034fdb3042da07533b3cc69f35c133d62463e5275c3f135cc1da8e64d1dc389cd3a83a35ca2fd8df8f85709740f25d1050f45067e77cbf2421c6eac7f831c03ba30844670c27b000f1d58ba86008b7936809310e858a96620f572111fd7f42f6047af2a4e5fe6a70245c6222fb0a318bd7edcbb5a2863624fdd38982f2f69c7cdec5c1d5fcff7ebbef981c1cc0a5e27374b8d8d627041f7eb6f99481619a9991da3bb0e5752c616a0b8948710e4aba8962d1e35a7eb609fd779471f4a500444070cc71c5f2b972d77c857993c61c53699a373340197f697328d060c09ad8330043cb8322c2e52c392d8f3cb9a4198309cc57793b90b6b433be916c7fdee167a1296e56474ebddd023a2f399b69ac463f9914e3dd0ab95fdc47154abc00f40d13ded451c345aa7a1e80b89f4dd0c041e47a3aad2a3d1a55d19e720740f922eb493df338b687aff124652288273702a03547b396a86e1e1f28618ba1f6ff872a30de16ad82ab23aec295c23cd5b5b39461be10cd080c52b3903612972b38151b71a95155c98a1517aa14506dab013a4d4d10a985d4863f12778b9e75856ecd741cd1c96d96e5e8c062a9e52de25dd45702155d4ec561f638d548bfd35e981902aa9eb3dbb2a7bc637c5c51abf7d3205f7816b7ca4c8c83e0592dde4cc36e11b0082a4dade4a1761cad57dd76f25fbafcfc14e0a76ee28c603257ecf831d5468e6d63dc0b78e181a1ab387f49705b935444e1615f2a47e3693103ce08808242a9d0b3624cc85d632563b90da24950a121660bcd4d7faa5ac16b6e8db4c686747262c7dbdb9ed9063de9c31d10bdd7eb79311657ce7ef56d4cd8c3a20d153e5cde1529c35f9174efadccd129de345aa22d2afee6edd59536ebde234044702bb77bae465ec767fe5fbc6548eefa41b0d0f8fb8563cc633ff903b3ad4301be97d4c147406651361b24f2c80d89cec00bf0325ba1def78f4a4a6609213fe27ed192e86069a9254228f98d18de248df693a429e8e7e2ef5f83eb509ed29ae0843100f52523c02f0017a6729f8af0d87b6fef13d257afeda03eaa4f92604189883a46c5bc76341922ed25dafdcacca900b91b5fda726ee19d550c540373424f6e309c753c1149c82cf422c2863e64928688beb761b009093f507b1a1419292d0e8f72dfaeded6345038819c6a0b5560dcb09e3882eba77a27956536914cc9977a62467d6be52c4e05a222dd6aec807cb13c46382a1fe981bbc17fdbce84dd988bd2de9067b5192c6c20007773e4fb34e8859c6c68912f103198d274f6aaba2d88ed0d78c31d9715ea4a61ca29871d9a386b2085c71b8efaf3fc1c37243691e776bfb2efc57b2130e6a09b0a657784fda585c6ed4786eb0a9a56653a2105898d98b07c66d508d6e90897b5660db0d0d00f0216c0ff18bc29e1ec1598ff8e8ef94cca9fc0c91314534b5790be9141eb1dee6131587eee85f3639f01f6651583b652bb9490ac949661abdf7a0560e4ca948780c04e685f8a8ab44297fdfaa09f5fee327dd4641c0272947acfd7c28cfc193ff10126bd59feea490f85460704eeb09548670c101abffd3363727c9af23699a939c558887596468b6672771c7b88e5ca3812fb0c22a2d3161b183593e0a3eeea69c5cdc9c0816b57785bde373ee5d7aade9ff169c05e8be5929ce16cf1c63561c1d033ae80900fcfa04afb1f17734b912b94ce5c0d0177a0fca80bf0bc0acf4accd8cd629dd6f862014c677fffa1f6daf831d1d28d6ec6ec86ba00f9fa5748521f2a5082003f81c097454464d98eba43cf98d9157a55f1dd91536af427cfca9d8e44a74d7d116f3d942831795b1eebe6ebebc77db6964846e1da50e5a427b30d95f9833388c0d7a19596e30f58bb71b9af1c577576e0a8e38ff3545ebc9ef9ac19586adcbee2b57b7b91c01424cc7238da5b16d065601437f3b93820d9909d5fe3642199a055a36d9ef79a9e4dd0471f4630e70d336575ee5a4bd75781ed2e804692eaa231491e0e538ff5d02d2eb033328134cf66fcad482bdea55c44edb0d5c7f1630c66745fcb472a31e07598e39d91947abd753fa39083f591d818338832cc7f311d2caa696fd21728677e9a6dee61ccbf25670d6fdac3ede0bb5e23e3a6ba360a3a56cb90cfbaa7406c0d946bfaee364874c79bf5fe7e58600d920f82f60882509267d9772f37e0158f4245ba6fc408e81f84c1232d220c3596392fac82c09e17e0af34a32be29b829f771de502c9a976eb5d980da672ce47e76d7f37bdc42dfe4405dea8c78644a3a6c8748ff1122d9f892623e059c42bbe41375d3b9d8091230a609c9204d1d90462c7535b16a05c9496aec18387b20b2e91cd4f972ed3741be30c1a6d347c981d26f9666dd855ca7421cd5fecb707a7ee13d13509680be9aeb267c31f7e74b2b78bbc399bfe8ae75fcdfe6bef1368fad5dab1cacb6ca7a3da66af7d2df9c87375bfd1cb427f1bd0d3c14969e0b01aec77d497052d2422e66f2a8ba37b909684e38a566acb9829ca99ebebf38131a4c7988e134d97e33bbbfada9eea3dd9dcd08e06af9b7ac57fc3768031f29d4e8073faf76ba0ecdfda31922493626fe9b305ca68b7f454cc1b83529903e1b0b4404159d3548b1c866987b905dab18aa1f1dd6a11001c8112a4a5be0ceabcd71938c7ad5714c1619a96a9f1fbd686ff58b81f705cb7ecf8983b95df0dcb5d329c6ad3cfbd2b2d75a13b72b5424d9626319a8c227134ccc2b8f3654ab286416998590f7c0c10cce38b72683c7f807d210e1c05695805b0ba3e1e04b80b1af6a4c54aef682c6baedb0e843bdbed9b963b87702d9f45e98ccdea9bca25043026a528cfc3fe9ce4623b3e4bca34c20638c53a609d7cb690c5764982958b65c6bece167efe225f1f4d0123a51d41223423b28436d025621bdb82d1921d150b2123e61c22e7dcf579c8fc5bde60dbf43acb3ab607df6a5ac5cfc14f7b100bd02864d98b27d2e37b0989a592ab30e85bf08171c818b2a5db5269bbeab44711d238250d299e00160cd520873e5b7f32552659ce847c2accd23cba6af236f90289f67b0e2626283f35b81634caddf35d54d934aa8580e4b300972b04f8492cde8c077fd94025e88888dc4be9c3377ed86ea79f2d8db211bac9fd39d5f910e5ed9a91069aa5d2474dea0f046f6bfda5db9bcec1d25b43149fdb6fa35df1d70c28205940caa5da31f6fd40d0f7f44de89cd8b3973c088f722c9833450ab7b5137b2cf3283f0b678c6cf844610fd16dc4229670b6681bb8bfc83ea8bdd0b3e1d29644209dc093fe9214f5aa5efff4f6a40272e55773b258ac64fd6b4f320beaf4072bc0fa9d5aafc202316cc38b5c4d5596a44af006e14ee4f65e91f34285a0efc8f7593b601e79f0f051788ee002b3cb38cec479f0ce69a288af692b81a853e664b1e86b0f6181d2493dac6ed22e7a3a45e9f920b92da43ce5e88348bf8b5fbd899f1826f4a628bf41df3d604da4b2ff2af767d6092e58d5e99f33ff817db4a1c89fb24d93d11b9e534aff80b6f9ecc9cdf3677a57beda81fba38e9f1f195d0df5404f641de7de56ee5e821cd03fde3574599b604c8803ba3d9997e076a06f3fce65f42a3f70c55bd2844f90d35dea473e9b97c30af271d39f890a52eb80a58ad5bf17f984c6ff778399f2d0a4eb050248564284ea08ee563c83324145b74f276578305bb2c20542ed38125d0c28d511b6296ec828f2e08108e7d518363d9fd42f4074eaaf5cdf90e9b4bc9d1bc8496416cde424bbf113b4c7f75a02d4fbe139d9051ab7b3f05ad1e3812e7991d217faa67572fe2896d58f10098a8e1227f132623f1c69cfaafbc5a33683e4e4d7a86721488dd40888d36cb28c710f3173a33ffd1326e5f735ec2f58806ef562ac4c115583c66153740f4aa42cebe104df3cd220e8697ab54ab23789d3b3c30e1ec667a83b1433375baf451f5ced03cc749c4c035a9959275f5bb500bf5add8a2a27177a691e4224128b27c19e060dfdc78a209cd19edfb33637a47bf121dd25491cf4feb29c4a2e05b73c4d60cbb3d382cb7deb5ca139a9dd384a128dd895b3a680e4aec7b7d4144f07eca8086a29693459e17f8ab9414d5067fffa745e8c9c39fda5bfe204fbec0cda6f8e0ba5f21c1cdc605523e08ba707ff335b02b445af44617d7234ed18de3abad4e22b30dd519db6025e3a057cc524e937539598cc467a7ff37e8fb23fd9929799d46b6bbcc25e0bcd88e5aa3e07bd523575651670fbb2df8b44ff303cb7b25fcb7d0a8bf33ea8a642ccf3d097799b649409223e5df42bf33bbd055b44bd0d292ace0c96c0a46586ada7108b09e77dd559c1d343cc8221a2c142e14823604e03e6be731cc3ea69b29f03d0d63fd2ba49ca86c3bd1103c615700c3f35b131f7792f75b6ae6b9da7ebffdd9b08867a2a0bd3d6a26762ac245afe91ad305027685ccebd285263b209b817cce5c4f67ea6c62a2b042f5d5bbc3ca6f15540f0b2bcc2fa7bec8e552b6a0e5c90f96ba9e409d48002e8b6af601acad9b441de8e08ab682a3975db836631916f2384bf0559effc656319a5224b20eeb7658072bdf756aa1fff458cff53da621cd9c8d194860031d56b6b850e969bba7f17a3f4e162e481c859eca96ed6902b8bf5c145676d079dd002919d4fdbf9d8db25695475b3f34d118c12b456af6ce0e0cf3997c0e6e3e1a2dcebc76901d090ef6961010265298bc37cb97bbb903e094b709539b477cfeb4421969bd58be837cdf653d1f377f012ce3ce24954d406cbffa85cc311836e4c3d7e3229824b27361fb54b0d21114dc471a6fa44511852e922dcefbabaa07427714bb1942a4473b2d785a7cbdfad72ed7de266b182ee59d5da437e2b6b8cc40cbcc83c33ff0c63a95afbeeff2a8826142885fd2642cf52a493815d463ac6a988bf5245715c2758012f2f9685745dcd17f1af5340993efd7b86957674d60dd17040c34e241b46c54233d6487f939b27738b263315b2f71bc24c4a47acd96568a754958f9915905cb2640971fdf252852afdee9de77424051853e659ac4299ab912a944e24968dbb004123a18e93d4956d1f33afdcfae9af1deaa6d6f75871c8106057c5a1987b64ff4d4e82277e2dbe8eba65f5bdd3810f44a6329d7289e1fea1dfc7924aa5a47516c24c5417d3ffc605d2a7d3ca78b4a284e7c8f4d267d554f104674c5480add239d0e0123a482fc7c7af7b254eb90be81135674b386e846cd60777b1d7050dd4059f7e805738c6d4a15d0cef4db55af1bae67bcecaab656e97f566c510d5145400dcf3f4359cda3a83fba0c6367ea7480a4a8a8cf473b48b8e6dc5ad422c781ba31156b43bfd0186d634b30a4a997fafaa4d030db4ca32d7b06071c4c209ed0f64daeb77726787b921bdeaf9e87fd17ad8de1f60651b136d36def8cb56d935a0ae783fcc5c35d8d4c51634eab5fed002f637c269504ea27dd4609979cb9f3b5afc7558708c5d94ef5ae0c565a48343e2f70c262024cf16d698817d98374e6c4abd1cd3fc725a666a9ca7491c30a3695599dd22e7a70b6ad0df5a8d2741266fa6171d80cf63e2a8b73cdfccbda0325819d56bc7430f65be5813edd2060c3437a622006fd099381eb3537afa961d04a01e09686c4283f96154949b8fc0503224b3d7835cddfc8016f02390ccb858449880c082cdee67cc0a20472354edfa4ad91e2c6c7de117898926efd0c11188c3e2f9af4862362364cf280270dc35bdc2442d840908b00831ef6cf5edbb34153c7641c45dfc14a92d5351ed68430ec3c7dc85e53bb9d452e856d60b5342cc9da140a4b4938a94163f6d11a12f515943b7221f0f94b2ab003d96baf23b65e2a845ee7db5855ce796ce3515ace2407489d2c877f65919fb754e35946ca227ea6be73575e1dc31549aedd28e55f10350875febd08ec9bf58d48e3013f09a70790f3bbf0f5f8b91c94e0abdba8f4ec6bcfc9bd1f2848e72fe490a98300439a808f2c3a3ab387d21370804c53a0ff75bdd9736b2decdc47c589e91f9958b973a065b1e88fc8d4092f2c7a85400f8131648e15296dc16709c63906a3a7406e7c9aabc2e93a0acfba6dd669e362fd4dbb7732e6d66709a1569088e483cc0440489451b0e9a2fefab3ab0209b5905721f0865141d8a6a64940e3cce222ed6752394bfe7e2ced1b91ce930fc73a807fcd454f75c54a2264a5dac105a63a6919cc1c4f5a4897172d60038b035344cea4e984a454bd33eee2f8ca8552c23b705eb314475930880d938cf504e9e1f749baafc649e7cf7ed6bc08850d2352af3d69b3d7697aac5557563517a49d52bda3aead030bc9a0db264833b9db826e8a94af27db4d20a5199cd8259f8883c35ed345a42fbe789b76b926973f0330fc8ae9341d20593bede8bb986ea51a2f3c40401e489b9c0f914a3a15eba594e861af2d0a34256ea5e59bb9175e18940b22eea2fa7dbb2fa70d8349909ae3e206e1930153e5b7ec24a730eaea7b820254fb9566026cc9bbc82be1dbb1394aab90b6a28f3eddeceb699005134d4b6cc9c7b41c96fe7a222647829f0a7c83b5430ccf7a41cb1625f81be907c748baf157fd8c7fa8a4a0094e947350bfa356a5bd027b2d6ceccbfa5187c795479e20ddea7d3164b427588ef64bcbc2051c6513f0e65c3a6e656caa1574d71836b4eef1d7a8d77d758a7a0cefa110747f4d0a60aae092ccaedeb19920cd67fb55225db15403468f19296864cf6655761b06061cf3ff614f693c3cad51885932ad9c83ce753239c12f63d7854b482282c2de764e9cf8cb3bab78a69974ff9bd4fcd94852a5b2ba2dcbe472625fd7bf4325a70a71077b344bfa2c4f25be88cb08ccd6fe086f358f066fb42908f37369acbe170c5d441e43a65fc27008587d21305b385bf9f477013a3cea3f774330c8df0164d8638b7307d9ff29bdfd833e4fa9d4453d6d78827a5174f99b8035bb7bb0dbaf4becc8c5fde2659e3cb3719ada3882046b8cdf775444a527899bcc4dd72f26082d93b729651e6e3a1abdcbcb7c196b2b40109e2962a9e97c42cc991dc882deb82599f336fd8a1345e736f083b36b0559b11069187c21a4d5f555c0331ed55ba87c8af5c37d977e6cfead0668c85559eefa5194466d4bbb5dbcda81f8f4be734fe06bda9edb935e9eb9bcb9082cb7b82a4cd6e8485a95dcfaad99f58c2ae16135b72ec96bd6527325de354dd069d266d9234f00a1569e013f00faaca02aaa56fbc8b134e2db49a458d3c4a4ffed70c1bb8823b27e9c3a39d0dbfcf3e9ececfb915b914c0e93f94ef76df559afc84c9a1fbc1d993a32ee40cfb3221390ba56f2b6d85e8356c0f73b06ebfe04729f76003789aa0b72e8e25773d3fea6b40ded7403fe82525a895c11c9cef1bb7c82f461fad4a6e42518fdbaae43217bcf7f9ae7ada1579c513774c0b051075fc77615d3772003de0ca89a9faeec25baba292805d6477afe7e61ec3ef0b09ff56abae7f080bd183cfa1e867a841631d1314832f67edabc4674104714afe6046c60d946ee75e50273658a661bac78ea64551765a8f5eb43efa312a122125786e32a4c740657830c06d7268d4d05b36a422914ff8c1202dff3ff4699c996cf56dd88ff33f9078f717d6cebe99261ed278a539f4a6dd42505099a1d6d6f30af97b3a5a0e64fb1dbf2984c69fa4ae843931177ed080d51ffcb732325dd20a444ed2c417555872203ab61380d5082706924b29a8c4482939fe070b0e0651377e0cd06e851e4a3d38840bbcaf49ab7f2d21acb865bc22870b1e50e217f5f2257a0600e1ae5c1be68a16c290c40409e7c5996564015f859b1eb96c4f309cba95aa0954486d4635f44f2f2724b01ece387dabc465e44af4bb3f0fd4a692d9a24a2c2cf5b827c918aee6a40522a60edc193f00ee9a0340c4e91fcd2048d80b32eb17560743a888f19d58f2c7fbea8890c819cdbb6ea7eeffcff5fb095ead5f86733c6b0c253109d3a3ce7b6171dfed0e74164a870894eec30d63ba7173eb8f51aee5ddff27f45bcc33670ab650279d3dd58040f9f8c56264e22933ff1f2f9ed3536d1f228910bb8c75917fe5e912beaaeb6d8b4df39ea33689e709f4696bc095d1a7282c2338ddd961739b3a11dab473789c5ea54e36a1ac7748e8e715078e325e34831d0fc5324975236b903671c500989047d3c2b675006f00a8a757a8a00657aa66c31a6b638b462bc5712e9d431efa48912ef910d9ea7d571d77c7601b4aa1ff623d597d092a3a6069f2f76e2bc580be07239ad1fe90b83fd9bb202126acc65935f6c974bf845b8ac869963474a0d4486898d733fa6798dda80f604439d93a1370c5d7b57a6ddf598511546b73e3a0557ff1975f267983be9d98088ebecf6b30e9b6888f8966d543dbab35d52df8ecb6041c561436e6edf7ce42b93dffc30d991f2a2ade02c8e17f172417b0bb5bd2505cf06d7867a7d62d8985862abd8ab960c88e65ee8f603224f60a71d3b77449c5c56af4b415223037edd5ca9e21d70b3ed3f37e7dcb4b5ebd4601a894e6658a7bb7dc9eb8c6ca5dfc5388f012739381c7eae369a4cca841d84696af55a1adce66ab0cacd787e3b2466348d7548e8a16241f7bfa01f6cdb14927947107e71d7812a910f993c00977fdf4496c8b991cdc9e52cb61a2621f4721352cde35b98effc0d3564de5d81418371005699354c657ef4b25982fabfafa02749480bd83f95b4a4d1c3067cdda23d80d7d2e4eacf5ed2f894bfcb8316282c03f81aeb019acf1bc73662fb2b5cab151bf6673329ea51c81f5d2ae5c07fc7d548789a1962f438997bb6ef21a783f0c3c46aed0135c150766c15444e972d3b0bbc432287d8001c70d9c379612fe0b469355909d5093e3de6eabe867e24af389033886fa2bf52d35a003fe3ec14f1783872d637d490a9ef964b95be66ff5997f637ef1b634e2f22c0dd17834d4a8498a7b0a92a61188cd89cdae282feebefa1a1246f7230f350aaebd0bd73cce64d322ee3b0143fc4639ae0160d2d0114c3e09aea42e5ee3cab7db51359c258e4cdb9da2ab261097c946eda72300f9247c373b1ae9862f9d3895e7b2e09f70a6c6429c2f81beb8209d7f3cfecf578840e123a880b624f3c6145a4e3935be537b179efdf673791ae573c689b2d20112ad601af7b052a7748ebe40bdb182317b7ee20e56a22a760c6ea6d8aa9fc946700ec694816e0f181dccc0571091abc1f9398869ebbb914188e904910485fdce16a65c7ed092be89b32f32ac2d3b83f9ef763969f7fbe12faebd11b496a9ae3075d0414ee24240cdf41b925e3842d7946e7c975590d6dfcb268346ab42d4d9ec823150cde5ed0aa8e306201eac0830d3493ee58c5d3f21720735f97ce6e0ab73d12ed6c69bc45b2c8a5bbfd1d964d85657a6b34191e8e92c86c859f4b07a7ffdaf254873313e773c4ee434cdcb49041487b913ce178dd49819f3c8a915b2afface5885f7e2a2e179175b49c8c340129a22b79beb7e7e990db13fe9bafdbca360686c11fd6e4ad05b6e657947d650e72f4a38d7cf67fc4c5ece2321f08ebaeccea56e4d0295b52921fab615369ee432993b3fb7c472245741aa22d9c04c5f34febb53278ea00cbf3c689eeab0848fd4a4b0276d833e0b73d015b404c2ad0a968a0bc8d25dcbb344ab9150061b211c7d879c0bb3c2c9ff715e2e7c3dd40f9e95dfae3049791814474fdc08fa48d6224c6a1d2acb4415e2a9472219a06c8a19cc5eadd12446df111409cb0a42a40571600f60252ecae9566371d8a7a5aa523ce8a34c0e8b3d4f9f7e9efa71bfd3b752caf8e6ddeafc6427d64fc8b6f52303618e191e4ff0953c557415c08a2cb7b497b12927ad66ac3bd285df50e43e3e5a49fe7efe8b2c90498b73b41890198e9971dd6986b03c957bf9f8c2e169ee1bb4fd9bc5656c2bd263dee54b39b3ffe141cda9ccc2a6fe030446cfbf486f5e7d7f7d10fb84a17ebf7b05843b979054bb7d97eb0fcea6d433ef04ea0e75bc12e8fce8f2976ff62ce887d4e3a20174a068e49de79cc3a2220d7cd24c1958879f32eb4b35f168e0a3d6a180f5190a259c0e41e485a97d93a89f0af3f3dbbfec36526119619be89634e019acf0838e541aa3efd322375b61f691ab5ee2bf9cd2d33b286b46c210aa7b9caec500b3091c15489f3ffd87f9b8a465aed00db9b5d88e659c770085e7a4a9c484c43435e2fb5517d04da329d8c19849ff6bfee59d6442c3d90eeb4c2ded973b552295ff2f2f462b86ab36e0006f02c64df648e2a4d8682e8292aa37483d82941ed875ca19db1e4ae61cb900779c5484fdcd4fdeebbc713a048451b8f311cafbbbf722765b3b30b04000452ba19ad1513401e67a9a121cbc8d307cd7c9a2642b20c04585a2413e01935691634eff31c0b15f9fcdecda64824b5379c226c25e8e9d7794cf82ce57f9b2fb7160014f4377b5b5e0b644ac9a9f1844e769616fa5ca9d11284bc464100b5b0233857ab28bfaeadb370c65186bdf6da9bd2bc65b98f56986265935ba383c32c1341ab45af6653030480a0cfccf0f95c6a3faf61a0c99a9e23de3c7b2cce7f436bc51ba5e3e33abd979087202c5234a284ab9815532b809467540aafae2257f4f6e9575a70319eec6d8420a25c2809a7482e77d1728101418af065ee260ff969de39ff774672f462bc314bfa3cd007c7307b3c346fbaeaf66f62ecf68a4e0640162295bfc2b2cf4ecd8ec09f0f0aa4ea0f7cc8c6350fb2005ebb8b4f7fcf1b2aac2870b9d49e64baed843a60757b620328db50937f84757722e528ed26eaa0a186447e061067868207df5d524b6b4ee4e57600f8d5e98fa979b0965b6e78a5fcf2268a59478645cbb918b9238f94d81ed049d5" } \ No newline at end of file diff --git a/cucumber.js b/cucumber.js new file mode 100644 index 0000000..d66368c --- /dev/null +++ b/cucumber.js @@ -0,0 +1,9 @@ +'use strict' + +module.exports = { + default: { + paths: ['test/integration/features/*.feature'], + requireModule: ['ts-node/register' /*'tsconfig-paths/register'*/], + require: ['test/integration/steps-definitions/*.ts'] + } +} diff --git a/package.json b/package.json index 99243df..228d8f6 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "cover:report": "nyc report --reporter=lcovonly", "test": "yarn cover && yarn cover:report", "test:ci": "nyc --reporter=lcovonly mocha 'test/**/*.test.ts' --exit --timeout 10000", + "test:cucumber": "cucumber-js", "generate-key-pair": "node scripts/generate-key-pair.mjs", "release:patch": "scripts/release-version.sh patch", "release:minor": "scripts/release-version.sh minor", @@ -33,12 +34,14 @@ "@nestjs/platform-express": "^10.3.2", "@nestjs/schematics": "^10.1.0", "@nestjs/swagger": "^7.3.0", + "@nestjs/terminus": "^10.2.3", "@types/express": "^4.17.21", "@types/luxon": "^3.4.2", "@types/mocha": "^10.0.6", "@types/node": "^20.11.16", "@types/oidc-provider": "^8.4.4", "@types/sanitize-html": "^2.11.0", + "@types/uuid": "^9.0.8", "ioredis": "^5.3.2", "joi": "^17.12.2", "jose": "^5.2.4", @@ -62,7 +65,11 @@ "uuid": "9.0.1" }, "devDependencies": { + "@cucumber/cucumber": "^10.8.0", + "@cucumber/messages": "24.1.0", + "@cucumber/pretty-formatter": "^1.0.1", "@nestjs/testing": "^10.3.8", + "@salesforce/ts-sinon": "^1.4.19", "@swc/cli": "^0.3.9", "@swc/core": "^1.4.0", "@types/chai-as-promised": "^7.1.8", @@ -70,12 +77,12 @@ "@types/sinon": "^17.0.3", "@types/sinon-chai": "^3.2.12", "@types/supertest": "^6.0.2", - "@types/uuid": "^9.0.8", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", "chai": "^4.4.1", "chai-as-promised": "^7.1.2", "chai-exclude": "^2.1.0", + "cucumber-tsflow": "^4.4.4", "dirty-chai": "^2.0.1", "dotvault": "^0.0.9", "eslint": "^7.32.0", diff --git a/src/app.controller.ts b/src/app.controller.ts index 99d0463..5412975 100644 --- a/src/app.controller.ts +++ b/src/app.controller.ts @@ -1,9 +1,18 @@ import { Controller, Get } from '@nestjs/common' +import { HealthCheck, HealthCheckService } from '@nestjs/terminus' +import { HealthCheckResult } from '@nestjs/terminus/dist/health-check/health-check-result.interface' @Controller() export class AppController { + constructor(private health: HealthCheckService) {} + @Get() getHello(): string { return 'Hello world!' } + @Get('health') + @HealthCheck() + check(): Promise { + return this.health.check([]) + } } diff --git a/src/app.module.ts b/src/app.module.ts index ddbb145..06de62e 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -7,6 +7,7 @@ import { FrancetravailJeuneModule } from './idp/francetravail-jeune/francetravai import { MiloConseillerModule } from './idp/milo-conseiller/milo-conseiller.module' import { MiloJeuneModule } from './idp/milo-jeune/milo-jeune.module' import { configureLoggerModule } from './logger.module' +import { TerminusModule } from '@nestjs/terminus' @Module({ imports: [ @@ -15,6 +16,7 @@ import { configureLoggerModule } from './logger.module' cache: true, load: [configuration] }), + TerminusModule, configureLoggerModule(), FrancetravailJeuneModule, FrancetravailConseillerModule, @@ -23,4 +25,5 @@ import { configureLoggerModule } from './logger.module' ], controllers: [AppController] }) + export class AppModule {} diff --git a/src/config/configuration.ts b/src/config/configuration.ts index c0a364f..6721683 100644 --- a/src/config/configuration.ts +++ b/src/config/configuration.ts @@ -1,15 +1,31 @@ /* eslint-disable */ import * as Joi from 'joi' import { configurationSchema } from './configuration.schema' +import { User } from '../domain/user' type ClientIdentifier = 'web' | 'app' | 'api' | 'swagger' type Client = Record -export enum IdpConfigIdentifier { +enum IdpConfigIdentifier { MILO_CONSEILLER = 'miloConseiller', MILO_JEUNE = 'miloJeune', FT_CONSEILLER = 'francetravailConseiller', FT_JEUNE = 'francetravailJeune' } +export function getIdpConfigIdentifier( + type: User.Type, + structure: User.Structure +): IdpConfigIdentifier { + switch (structure) { + case User.Structure.MILO: + if (type === User.Type.JEUNE) return IdpConfigIdentifier.MILO_JEUNE + return IdpConfigIdentifier.MILO_CONSEILLER + case User.Structure.POLE_EMPLOI: + case User.Structure.POLE_EMPLOI_AIJ: + case User.Structure.POLE_EMPLOI_BRSA: + if (type === User.Type.JEUNE) return IdpConfigIdentifier.FT_JEUNE + return IdpConfigIdentifier.FT_CONSEILLER + } +} export interface IdpConfig { issuer: string realm?: string @@ -48,7 +64,9 @@ export default () => { port: process.env.PORT ? parseInt(process.env.PORT, 10) : 5050, publicAddress: process.env.PUBLIC_ADDRESS || - `http://localhost:${process.env.PORT ? parseInt(process.env.PORT, 10) : 5050}`, + `http://localhost:${ + process.env.PORT ? parseInt(process.env.PORT, 10) : 5050 + }`, cors: { allowedOrigins: process.env.CORS_ALLOWED_ORIGINS ? JSON.parse(process.env.CORS_ALLOWED_ORIGINS) diff --git a/src/idp/common/idp.service.ts b/src/idp/common/idp.service.ts index f551f0c..272cdb5 100644 --- a/src/idp/common/idp.service.ts +++ b/src/idp/common/idp.service.ts @@ -3,7 +3,7 @@ import { ConfigService } from '@nestjs/config' import { Request, Response } from 'express' import { ClientAuthMethod, InteractionResults } from 'oidc-provider' import { BaseClient, Issuer } from 'openid-client' -import { IdpConfig, IdpConfigIdentifier } from '../../config/configuration' +import { IdpConfig, getIdpConfigIdentifier } from '../../config/configuration' import { ContextKeyType, ContextStorage @@ -28,7 +28,6 @@ export abstract class IdpService { idpName: string, userType: User.Type, userStructure: User.Structure, - idpConfigIdentifier: IdpConfigIdentifier, private readonly contextStorage: ContextStorage, private readonly configService: ConfigService, private readonly oidcService: OidcService, @@ -39,7 +38,10 @@ export abstract class IdpService { this.idpName = idpName this.userType = userType this.userStructure = userStructure - this.idp = this.configService.get('idps')[idpConfigIdentifier]! + this.idp = + this.configService.get('idps')[ + getIdpConfigIdentifier(userType, userStructure) + ]! const issuerConfig = { issuer: this.idp.issuer, @@ -107,7 +109,7 @@ export abstract class IdpService { } const accountId = Account.fromAccountToAccountId(account) - this.tokenService.setToken(account, 'access_token', { + await this.tokenService.setToken(account, 'access_token', { token: tokenSet.access_token!, expiresIn: tokenSet.expires_in || this.idp.accessTokenMaxAge, scope: tokenSet.scope @@ -117,7 +119,7 @@ export abstract class IdpService { try { refreshExpiresIn = tokenSet.refresh_expires_in as number } catch (e) {} - this.tokenService.setToken(account, 'refresh_token', { + await this.tokenService.setToken(account, 'refresh_token', { token: tokenSet.refresh_token, expiresIn: refreshExpiresIn || this.idp.refreshTokenMaxAge, scope: tokenSet.scope diff --git a/src/idp/francetravail-conseiller/francetravail-conseiller-aij.service.ts b/src/idp/francetravail-conseiller/francetravail-conseiller-aij.service.ts index 05ae966..49d3039 100644 --- a/src/idp/francetravail-conseiller/francetravail-conseiller-aij.service.ts +++ b/src/idp/francetravail-conseiller/francetravail-conseiller-aij.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@nestjs/common' import { ConfigService } from '@nestjs/config' -import { IdpConfigIdentifier } from '../../config/configuration' import { ContextStorage } from '../../context-storage/context-storage.provider' import { User } from '../../domain/user' import { OidcService } from '../../oidc-provider/oidc.service' @@ -21,7 +20,6 @@ export class FrancetravailConseillerAIJService extends IdpService { 'FrancetravailConseillerAIJService', User.Type.CONSEILLER, User.Structure.POLE_EMPLOI_AIJ, - IdpConfigIdentifier.FT_CONSEILLER, context, configService, oidcService, diff --git a/src/idp/francetravail-conseiller/francetravail-conseiller-brsa.service.ts b/src/idp/francetravail-conseiller/francetravail-conseiller-brsa.service.ts index b663485..da08cbf 100644 --- a/src/idp/francetravail-conseiller/francetravail-conseiller-brsa.service.ts +++ b/src/idp/francetravail-conseiller/francetravail-conseiller-brsa.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@nestjs/common' import { ConfigService } from '@nestjs/config' -import { IdpConfigIdentifier } from '../../config/configuration' import { ContextStorage } from '../../context-storage/context-storage.provider' import { User } from '../../domain/user' import { OidcService } from '../../oidc-provider/oidc.service' @@ -21,7 +20,6 @@ export class FrancetravailConseillerBRSAService extends IdpService { 'FrancetravailConseillerBRSAService', User.Type.CONSEILLER, User.Structure.POLE_EMPLOI_BRSA, - IdpConfigIdentifier.FT_CONSEILLER, context, configService, oidcService, diff --git a/src/idp/francetravail-conseiller/francetravail-conseiller-cej.service.ts b/src/idp/francetravail-conseiller/francetravail-conseiller-cej.service.ts index e16ee29..0f4292b 100644 --- a/src/idp/francetravail-conseiller/francetravail-conseiller-cej.service.ts +++ b/src/idp/francetravail-conseiller/francetravail-conseiller-cej.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@nestjs/common' import { ConfigService } from '@nestjs/config' -import { IdpConfigIdentifier } from '../../config/configuration' import { ContextStorage } from '../../context-storage/context-storage.provider' import { User } from '../../domain/user' import { OidcService } from '../../oidc-provider/oidc.service' @@ -21,7 +20,6 @@ export class FrancetravailConseillerCEJService extends IdpService { 'FrancetravailConseillerCEJService', User.Type.CONSEILLER, User.Structure.POLE_EMPLOI, - IdpConfigIdentifier.FT_CONSEILLER, context, configService, oidcService, diff --git a/src/idp/francetravail-jeune/francetravail-aij.service.ts b/src/idp/francetravail-jeune/francetravail-aij.service.ts index 1f064c0..8e794b5 100644 --- a/src/idp/francetravail-jeune/francetravail-aij.service.ts +++ b/src/idp/francetravail-jeune/francetravail-aij.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@nestjs/common' import { ConfigService } from '@nestjs/config' -import { IdpConfigIdentifier } from '../../config/configuration' import { ContextStorage } from '../../context-storage/context-storage.provider' import { User } from '../../domain/user' import { OidcService } from '../../oidc-provider/oidc.service' @@ -21,7 +20,6 @@ export class FrancetravailAIJService extends IdpService { 'FrancetravailAIJService', User.Type.JEUNE, User.Structure.POLE_EMPLOI_AIJ, - IdpConfigIdentifier.FT_JEUNE, context, configService, oidcService, diff --git a/src/idp/francetravail-jeune/francetravail-brsa.service.ts b/src/idp/francetravail-jeune/francetravail-brsa.service.ts index 69c5cca..efb15f8 100644 --- a/src/idp/francetravail-jeune/francetravail-brsa.service.ts +++ b/src/idp/francetravail-jeune/francetravail-brsa.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@nestjs/common' import { ConfigService } from '@nestjs/config' -import { IdpConfigIdentifier } from '../../config/configuration' import { ContextStorage } from '../../context-storage/context-storage.provider' import { User } from '../../domain/user' import { OidcService } from '../../oidc-provider/oidc.service' @@ -21,7 +20,6 @@ export class FrancetravailBRSAService extends IdpService { 'FrancetravailBRSAService', User.Type.JEUNE, User.Structure.POLE_EMPLOI_BRSA, - IdpConfigIdentifier.FT_JEUNE, context, configService, oidcService, diff --git a/src/idp/francetravail-jeune/francetravail-jeune.service.ts b/src/idp/francetravail-jeune/francetravail-jeune.service.ts index 0ca0bbd..521157d 100644 --- a/src/idp/francetravail-jeune/francetravail-jeune.service.ts +++ b/src/idp/francetravail-jeune/francetravail-jeune.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@nestjs/common' import { ConfigService } from '@nestjs/config' -import { IdpConfigIdentifier } from '../../config/configuration' import { ContextStorage } from '../../context-storage/context-storage.provider' import { User } from '../../domain/user' import { OidcService } from '../../oidc-provider/oidc.service' @@ -21,7 +20,6 @@ export class FrancetravailJeuneCEJService extends IdpService { 'FrancetravailJeuneCEJService', User.Type.JEUNE, User.Structure.POLE_EMPLOI, - IdpConfigIdentifier.FT_JEUNE, context, configService, oidcService, diff --git a/src/idp/milo-conseiller/milo-conseiller.service.ts b/src/idp/milo-conseiller/milo-conseiller.service.ts index b136666..6ac11b5 100644 --- a/src/idp/milo-conseiller/milo-conseiller.service.ts +++ b/src/idp/milo-conseiller/milo-conseiller.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@nestjs/common' import { ConfigService } from '@nestjs/config' -import { IdpConfigIdentifier } from '../../config/configuration' import { ContextStorage } from '../../context-storage/context-storage.provider' import { User } from '../../domain/user' import { OidcService } from '../../oidc-provider/oidc.service' @@ -21,7 +20,6 @@ export class MiloConseillerService extends IdpService { 'MiloConseillerService', User.Type.CONSEILLER, User.Structure.MILO, - IdpConfigIdentifier.MILO_CONSEILLER, context, configService, oidcService, diff --git a/src/idp/milo-jeune/milo-jeune.service.ts b/src/idp/milo-jeune/milo-jeune.service.ts index addcf45..969ef8f 100644 --- a/src/idp/milo-jeune/milo-jeune.service.ts +++ b/src/idp/milo-jeune/milo-jeune.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@nestjs/common' import { ConfigService } from '@nestjs/config' -import { IdpConfigIdentifier } from '../../config/configuration' import { ContextStorage } from '../../context-storage/context-storage.provider' import { User } from '../../domain/user' import { OidcService } from '../../oidc-provider/oidc.service' @@ -21,7 +20,6 @@ export class MiloJeuneService extends IdpService { 'MiloJeuneService', User.Type.JEUNE, User.Structure.MILO, - IdpConfigIdentifier.MILO_JEUNE, context, configService, oidcService, diff --git a/src/logger.module.ts b/src/logger.module.ts index a8fa5da..da37a25 100644 --- a/src/logger.module.ts +++ b/src/logger.module.ts @@ -52,12 +52,16 @@ export const configureLoggerModule = (): DynamicModule => export interface LogError { message: string - err: Error + err?: Error | string } export function buildError(message: string, error: Error): LogError { return { message, - err: error + err: isEnumerable(error) ? error : error.stack } } + +function isEnumerable(error: Error): boolean { + return Boolean(Object.keys(error).length) +} diff --git a/src/oidc-provider/oidc.service.ts b/src/oidc-provider/oidc.service.ts index 42596f3..2f1343f 100644 --- a/src/oidc-provider/oidc.service.ts +++ b/src/oidc-provider/oidc.service.ts @@ -66,7 +66,7 @@ export class OidcService { client_id: clients.api.id, client_secret: clients.api.secret, grant_types: [tokenExchangeGrantType], - response_types: [] + response_types: [], }, { client_id: clients.web.id, diff --git a/src/oidc-provider/token-exchange.grant.ts b/src/oidc-provider/token-exchange.grant.ts index 2eb3a3f..79976d7 100644 --- a/src/oidc-provider/token-exchange.grant.ts +++ b/src/oidc-provider/token-exchange.grant.ts @@ -5,6 +5,8 @@ import { GetAccessTokenUsecase } from '../token/get-access-token.usecase' import { ValidateJWTUsecase } from '../token/verify-jwt.usecase' import { OIDC_PROVIDER_MODULE, OidcProviderModule } from './provider' import { Account } from '../domain/account' +import { isFailure } from '../result/result' +import { buildError } from '../logger.module' export const gty = 'token_exchange' export const grantType = 'urn:ietf:params:oauth:grant-type:token-exchange' @@ -37,25 +39,21 @@ export class TokenExchangeGrant { context: KoaContextWithOIDC, next: () => Promise ): Promise => { - // Vérifier les paramètres d'input const subjectToken = context.oidc.params?.subject_token as string if (!subjectToken) { const message = 'subject token not found' - this.logger.warn(message) + this.logger.error(message) throw new this.opm.errors.InvalidGrant(message) } - // Vérifie que l'input est un access token valide - // faut-il vérifier les permissions à faire le token exchange ? let tokenPayload - // TODO passer par une erreur métier try { tokenPayload = await this.validateJWTUsecase.execute({ token: subjectToken }) } catch (e) { const message = 'subject token is invalid' - this.logger.warn(message) + this.logger.error(buildError(message, e)) throw new this.opm.errors.InvalidGrant(message) } @@ -64,26 +62,25 @@ export class TokenExchangeGrant { type: tokenPayload.userType! as User.Type, structure: tokenPayload.userStructure! as User.Structure } - const tokenData = await this.getAccessTokenUsecase.execute({ + const resultTokenData = await this.getAccessTokenUsecase.execute({ account }) - if (!tokenData) { + if (isFailure(resultTokenData)) { const message = 'unable to find an access_token' - this.logger.warn(message) + this.logger.error(resultTokenData.error.message) + this.logger.error(message) throw new this.opm.errors.InvalidTarget(message) } context.body = { issued_token_type: 'urn:ietf:params:oauth:token-type:access_token', - access_token: tokenData.token, + access_token: resultTokenData.data.token, token_type: 'bearer', - expires_in: tokenData.expiresIn, - scope: tokenData.scope + expires_in: resultTokenData.data.expiresIn, + scope: resultTokenData.data.scope } - this.logger.debug('End token exchange Grant') - await next() } } diff --git a/src/token/get-access-token.usecase.ts b/src/token/get-access-token.usecase.ts index 38d770b..1fdaeed 100644 --- a/src/token/get-access-token.usecase.ts +++ b/src/token/get-access-token.usecase.ts @@ -1,19 +1,3 @@ -// prend en input un user account et renoive un access token en output -// cherche access token dans le redis -// gerer le cas ou l'access token expire bientot (30s) et du coup lancer le refresh -// si l'access token est valide il le retourne - -// sinon on le refresh en appelant l'idp sur l'url de refresh - -// si reussi, on stock le nouveau acces token -// calul expires at avant de le stocker - -// dès qu'on a une erreur => erreur indépendante de oidc module interprétées comme erreur métier et qu"on puisse renvoyer invalid grant - -// tout à la fin calcule expires in - -// retourne access token, expires in et scope - import { Injectable, Logger } from '@nestjs/common' import { ConfigService } from '@nestjs/config' import { Issuer } from 'openid-client' @@ -23,6 +7,10 @@ import { } from '../context-storage/context-storage.provider' import { Account } from '../domain/account' import { TokenData, TokenService } from './token.service' +import { Result, failure, success } from '../result/result' +import { buildError } from '../logger.module' +import { NonTrouveError } from '../result/error' +import { getIdpConfigIdentifier } from '../config/configuration' const MINIMUM_ACCESS_TOKEN_EXPIRES_IN_SECONDS = 10 @@ -42,7 +30,7 @@ export class GetAccessTokenUsecase { this.logger = new Logger('GetAccessTokenUsecase') } - async execute(query: Inputs): Promise { + async execute(query: Inputs): Promise> { try { const storedAccessTokenData = await this.tokenService.getToken( query.account, @@ -54,20 +42,18 @@ export class GetAccessTokenUsecase { storedAccessTokenData.expiresIn > MINIMUM_ACCESS_TOKEN_EXPIRES_IN_SECONDS ) { - return storedAccessTokenData + return success(storedAccessTokenData) } - this.logger.debug('OK?') - const newAccessTokenData = await this.refresh(query.account) - this.logger.debug('OK!') - return newAccessTokenData + const newTokenDataResult = await this.refresh(query.account) + return newTokenDataResult } catch (e) { - this.logger.error(e) - return undefined + this.logger.error(buildError('Erreur inconnue GET AccessTokenUsecase', e)) + return failure(new NonTrouveError('AcessToken')) } } - private async refresh(account: Account): Promise { + private async refresh(account: Account): Promise> { const refreshToken = await this.tokenService.getToken( account, 'refresh_token' @@ -75,10 +61,11 @@ export class GetAccessTokenUsecase { if (!refreshToken) { this.logger.error("L'utilisateur n'a pas de refresh token") - throw Error("L'utilisateur n'a pas de refresh token") + return failure( + new NonTrouveError("L'utilisateur n'a pas de refresh token") + ) } - this.logger.debug('Refresh token') const [issuerConfig, clientConfig] = await Promise.all([ this.context.get({ userType: account.type, @@ -94,25 +81,33 @@ export class GetAccessTokenUsecase { if (!issuerConfig || !clientConfig) { this.logger.error('Config introuvable pour le refresh') - throw Error('Config introuvable pour le refresh') + return failure(new NonTrouveError('Config introuvable pour le refresh')) } - const issuer = new Issuer(JSON.parse(issuerConfig)) - const client = new issuer.Client(JSON.parse(clientConfig)) - - const tokenSet = await client.refresh(refreshToken.token) - const tokenData: TokenData = { - token: tokenSet.access_token!, - expiresIn: - tokenSet.expires_in ?? - this.configService.get( - 'francetravailConseiller.accessTokenMaxAge' - )!, - scope: tokenSet.scope - } + try { + const issuer = new Issuer(JSON.parse(issuerConfig)) + const client = new issuer.Client(JSON.parse(clientConfig)) + + const tokenSet = await client.refresh(refreshToken.token) + const tokenData: TokenData = { + token: tokenSet.access_token!, + expiresIn: + tokenSet.expires_in ?? + this.configService.get( + `${getIdpConfigIdentifier( + account.type, + account.structure + )}.accessTokenMaxAge` + )!, + scope: tokenSet.scope + } - await this.tokenService.setToken(account, 'access_token', tokenData) + await this.tokenService.setToken(account, 'access_token', tokenData) - return tokenData + return success(tokenData) + } catch (e) { + this.logger.error(buildError('Erreur refresh token', e)) + return failure(new NonTrouveError('Erreur refresh token')) + } } } diff --git a/test/domain/account.test.ts b/test/domain/account.test.ts index a2060f7..bbcbbdd 100644 --- a/test/domain/account.test.ts +++ b/test/domain/account.test.ts @@ -1,5 +1,5 @@ import { Account } from '../../src/domain/account' -import { unAccount } from '../fixtures/fixtures' +import { unAccount } from '../utils/fixtures' import { expect } from '../utils' describe('Account', () => { diff --git a/test/integration/features/hello-world.feature b/test/integration/features/hello-world.feature new file mode 100644 index 0000000..53b63c0 --- /dev/null +++ b/test/integration/features/hello-world.feature @@ -0,0 +1,13 @@ +Feature: Hello World + + Scenario: Say Hello! + Given I am a user + When Call to "/" + Then the response status code should be "200" + And the response should be "Hello World!" + + Scenario: Say Hello! + Given I am a user + When Call to "/" + Then the response status code should be "200" + And the response should be "Hello World!" diff --git a/test/integration/steps-definitions/hello-world.steps.cts b/test/integration/steps-definitions/hello-world.steps.cts new file mode 100644 index 0000000..c78042e --- /dev/null +++ b/test/integration/steps-definitions/hello-world.steps.cts @@ -0,0 +1,49 @@ +import { + binding, + given as Given, + then as Then, + when as When, + before +} from 'cucumber-tsflow' +import { assert } from 'chai' +import { Test, TestingModule } from '@nestjs/testing' +import * as request from 'supertest' +import { AppModule } from '../../../src/app.module' + +class Context { + public app: any + public response: any +} + +// tslint:disable-next-line:max-classes-per-file +@binding([Context]) +export class HelloWorldSteps { + constructor(protected context: Context) {} + + @before() + public async before(): Promise { + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [AppModule] + }).compile() + + this.context.app = moduleFixture.createNestApplication() + await this.context.app.init() + } + + @When(/Call to "([^"]*)"/) + public async callToAPI(url: string) { + this.context.response = await request(this.context.app.getHttpServer()).get( + url + ) + } + + @Then(/the response status code should be "([^"]*)"/) + public statusResponse(status: string) { + assert.equal(this.context.response.status, status) + } + + @Then(/the response should be "([^"]*)"/) + public dataResponse(data: string) { + assert.equal(this.context.response.body.message, data) + } +} diff --git a/test/oidc-provider/token-exchange.grant.test.ts b/test/oidc-provider/token-exchange.grant.test.ts new file mode 100644 index 0000000..b1543f1 --- /dev/null +++ b/test/oidc-provider/token-exchange.grant.test.ts @@ -0,0 +1,152 @@ +import { StubbedType, stubInterface } from '@salesforce/ts-sinon' +import { expect } from 'chai' +import { KoaContextWithOIDC } from 'oidc-provider' +import { OidcProviderModule } from '../../src/oidc-provider/provider' +import { TokenExchangeGrant } from '../../src/oidc-provider/token-exchange.grant' +import { failure, success } from '../../src/result/result' +import { GetAccessTokenUsecase } from '../../src/token/get-access-token.usecase' +import { ValidateJWTUsecase } from '../../src/token/verify-jwt.usecase' +import { StubbedClass, createSandbox, stubClass } from '../utils' +import { unAccount, unTokenData } from '../utils/fixtures' +import { NonTrouveError } from '../../src/result/error' + +describe('TokenExchangeGrant', () => { + let tokenExchangeGrant: TokenExchangeGrant + let opm: StubbedType + let validateJWTUsecase: StubbedClass + let getAccessTokenUsecase: StubbedClass + + beforeEach(() => { + const sandbox = createSandbox() + opm = stubInterface(sandbox) + validateJWTUsecase = stubClass(ValidateJWTUsecase) + getAccessTokenUsecase = stubClass(GetAccessTokenUsecase) + tokenExchangeGrant = new TokenExchangeGrant( + opm, + validateJWTUsecase, + getAccessTokenUsecase + ) + }) + describe('handler', () => { + it('exchange le token quand tout est ok', async () => { + // Given + const context = { + oidc: { params: { subject_token: 'tok' } }, + body: {} + } + validateJWTUsecase.execute.resolves({ + sub: 'CONSEILLER|MILO|id-auth', + userType: 'CONSEILLER', + userStructure: 'MILO' + }) + const tokenData = unTokenData() + getAccessTokenUsecase.execute.resolves(success(tokenData)) + + // When + await tokenExchangeGrant.handler( + context as unknown as KoaContextWithOIDC, + () => { + return Promise.resolve() + } + ) + + // Then + expect(validateJWTUsecase.execute).to.have.been.calledOnceWithExactly({ + token: 'tok' + }) + expect(getAccessTokenUsecase.execute).to.have.been.calledOnceWithExactly({ + account: unAccount({ sub: 'id-auth' }) + }) + expect(context.body).to.deep.equal({ + issued_token_type: 'urn:ietf:params:oauth:token-type:access_token', + access_token: tokenData.token, + token_type: 'bearer', + expires_in: tokenData.expiresIn, + scope: tokenData.scope + }) + }) + it('erreur quand le subject token est introuvable', async () => { + // Given + const context = {} + + try { + // When + await tokenExchangeGrant.handler( + context as unknown as KoaContextWithOIDC, + () => { + return Promise.resolve() + } + ) + expect.fail(null, null, 'handle test did not reject with an error') + } catch (e) { + // Then + expect(validateJWTUsecase.execute).not.to.have.been.called() + expect(getAccessTokenUsecase.execute).not.to.have.been.called() + expect(e).to.be.an.instanceOf(Error) + } + }) + it('erreur quand le subject token est invalide', async () => { + // Given + const context = { + oidc: { params: { subject_token: 'tok' } }, + body: {} + } + validateJWTUsecase.execute.throws() + + try { + // When + await tokenExchangeGrant.handler( + context as unknown as KoaContextWithOIDC, + () => { + return Promise.resolve() + } + ) + expect.fail(null, null, 'handle test did not reject with an error') + } catch (e) { + // Then + expect(validateJWTUsecase.execute).to.have.been.calledOnceWithExactly({ + token: 'tok' + }) + expect(getAccessTokenUsecase.execute).not.to.have.been.called() + expect(e).to.be.an.instanceOf(Error) + } + }) + it('erreur quand impossible de récupérer un access token', async () => { + // Given + const context = { + oidc: { params: { subject_token: 'tok' } }, + body: {} + } + validateJWTUsecase.execute.resolves({ + sub: 'CONSEILLER|MILO|id-auth', + userType: 'CONSEILLER', + userStructure: 'MILO' + }) + getAccessTokenUsecase.execute.resolves( + failure(new NonTrouveError('token')) + ) + + try { + // When + await tokenExchangeGrant.handler( + context as unknown as KoaContextWithOIDC, + () => { + return Promise.resolve() + } + ) + expect.fail(null, null, 'handle test did not reject with an error') + } catch (e) { + // Then + expect(validateJWTUsecase.execute).to.have.been.calledOnceWithExactly({ + token: 'tok' + }) + expect( + getAccessTokenUsecase.execute + ).to.have.been.calledOnceWithExactly({ + account: unAccount({ sub: 'id-auth' }) + }) + expect(e).to.be.an.instanceOf(Error) + } + }) + }) +}) diff --git a/test/pass-emploi-api/pass-emploi-api.service.test.ts b/test/pass-emploi-api/pass-emploi-api.service.test.ts index 8746e76..88c6ed6 100644 --- a/test/pass-emploi-api/pass-emploi-api.service.test.ts +++ b/test/pass-emploi-api/pass-emploi-api.service.test.ts @@ -4,7 +4,7 @@ import * as nock from 'nock' import { PassEmploiAPIService } from '../../src/pass-emploi-api/pass-emploi-api.service' import { NonTraitable, NonTrouveError } from '../../src/result/error' import { failure, success } from '../../src/result/result' -import { unAccount, unPassEmploiUser, unUser } from '../fixtures/fixtures' +import { unAccount, unPassEmploiUser, unUser } from '../utils/fixtures' import { testConfig } from '../utils/module-for-testing' describe('PassEmploiAPIService', () => { diff --git a/test/token/get-access-token.usecase.test.ts b/test/token/get-access-token.usecase.test.ts new file mode 100644 index 0000000..1c17dcb --- /dev/null +++ b/test/token/get-access-token.usecase.test.ts @@ -0,0 +1,191 @@ +import { expect } from 'chai' +import { + IdpConfig, + getIdpConfigIdentifier +} from '../../src/config/configuration' +import { + ContextKeyType, + ContextStorage +} from '../../src/context-storage/context-storage.provider' +import { User } from '../../src/domain/user' +import { NonTrouveError } from '../../src/result/error' +import { failure, success } from '../../src/result/result' +import { GetAccessTokenUsecase } from '../../src/token/get-access-token.usecase' +import { TokenService } from '../../src/token/token.service' +import { unAccount } from '../utils/fixtures' +import { StubbedClass, stubClass } from '../utils' +import { testConfig } from '../utils/module-for-testing' + +describe('GetAccessTokenUsecase', () => { + let getAccessTokenUsecase: GetAccessTokenUsecase + const configService = testConfig() + let tokenService: StubbedClass + let context: StubbedClass + + const idp: IdpConfig = + configService.get('idps')[ + getIdpConfigIdentifier(User.Type.CONSEILLER, User.Structure.MILO) + ]! + + const issuerConfig = { + issuer: idp.issuer, + authorization_endpoint: idp.authorizationUrl, + token_endpoint: idp.tokenUrl, + jwks_uri: idp.jwks, + userinfo_endpoint: idp.userinfo + } + const clientConfig = { + client_id: idp.clientId, + client_secret: idp.clientSecret, + redirect_uris: [idp.redirectUri], + response_types: ['code'], + scope: idp.scopes, + token_endpoint_auth_method: 'client_secret_post' + } + + const offlineToken = configService.get('test.miloConseillerOfflineToken') + + beforeEach(() => { + tokenService = stubClass(TokenService) + context = stubClass(ContextStorage) + getAccessTokenUsecase = new GetAccessTokenUsecase( + configService, + tokenService, + context + ) + }) + describe('execute', () => { + it('retourne le token quand tout est ok et que le token est frais', async () => { + // Given + const query = { + account: unAccount() + } + tokenService.getToken.withArgs(query.account, 'access_token').resolves({ + token: 'string', + expiresIn: 100, + scope: '' + }) + + // When + const result = await getAccessTokenUsecase.execute(query) + + // Then + expect(result).to.deep.equal( + success({ + token: 'string', + expiresIn: 100, + scope: '' + }) + ) + }) + it('refresh et retourne le token quand tout est ok et que le token est expiré', async () => { + // Given + const query = { + account: unAccount() + } + tokenService.getToken.withArgs(query.account, 'access_token').resolves({ + token: 'string', + expiresIn: 10, + scope: '' + }) + tokenService.getToken.withArgs(query.account, 'refresh_token').resolves({ + token: offlineToken, + expiresIn: 100, + scope: 'openid profile offline_access email' + }) + context.get + .withArgs({ + userType: query.account.type, + userStructure: query.account.structure, + key: ContextKeyType.ISSUER + }) + .resolves(JSON.stringify(issuerConfig)) + context.get + .withArgs({ + userType: query.account.type, + userStructure: query.account.structure, + key: ContextKeyType.CLIENT + }) + .resolves(JSON.stringify(clientConfig)) + tokenService.setToken.resolves() + + // When + const result = await getAccessTokenUsecase.execute(query) + + // Then + expect(result._isSuccess).to.equal(true) + if (result._isSuccess) { + expect(result.data.expiresIn).to.be.oneOf([297, 298, 299, 300]) + expect(result.data.scope).to.equal( + 'openid profile offline_access email' + ) + } + }) + it('erreur quand refresh token inexistant', async () => { + // Given + const query = { + account: unAccount() + } + + // When + const result = await getAccessTokenUsecase.execute(query) + + // Then + expect(result).to.deep.equal( + failure(new NonTrouveError("L'utilisateur n'a pas de refresh token")) + ) + }) + it('erreur quand config inexistante', async () => { + // Given + const query = { + account: unAccount() + } + tokenService.getToken.withArgs(query.account, 'refresh_token').resolves({ + token: offlineToken, + expiresIn: 100, + scope: 'openid profile offline_access email' + }) + + // When + const result = await getAccessTokenUsecase.execute(query) + + // Then + expect(result).to.deep.equal( + failure(new NonTrouveError('Config introuvable pour le refresh')) + ) + }) + it('erreur quand mauvais refresh token', async () => { + // Given + const query = { + account: unAccount() + } + tokenService.getToken.withArgs(query.account, 'refresh_token').resolves({ + token: 'mauvais-token', + expiresIn: 100, + scope: 'openid profile offline_access email' + }) + context.get + .withArgs({ + userType: query.account.type, + userStructure: query.account.structure, + key: ContextKeyType.ISSUER + }) + .resolves(JSON.stringify(issuerConfig)) + context.get + .withArgs({ + userType: query.account.type, + userStructure: query.account.structure, + key: ContextKeyType.CLIENT + }) + .resolves(JSON.stringify(clientConfig)) + + // When + const result = await getAccessTokenUsecase.execute(query) + + // Then + expect(result).to.deep.equal( + failure(new NonTrouveError('Erreur refresh token')) + ) + }) + }) +}) diff --git a/test/token/verify-jwt.usecase.test.ts b/test/token/verify-jwt.usecase.test.ts new file mode 100644 index 0000000..22dd7ef --- /dev/null +++ b/test/token/verify-jwt.usecase.test.ts @@ -0,0 +1,27 @@ +import { expect } from 'chai' +import { ValidateJWTUsecase } from '../../src/token/verify-jwt.usecase' +import { unJwtPayloadValide } from '../utils/fixtures' +import { testConfig } from '../utils/module-for-testing' + +describe('ValidateJWTUsecase', () => { + let validateJWTUsecase: ValidateJWTUsecase + const configService = testConfig() + + beforeEach(() => { + validateJWTUsecase = new ValidateJWTUsecase(configService) + }) + describe('execute', () => { + xit('retourne le JWTPayload quand tout est ok', async () => { + // Given + const inputs = { + token: configService.get('test.miloConseillerCEJJWT') + } + + // When + const result = await validateJWTUsecase.execute(inputs) + + // Then + expect(result).to.deep.equal(unJwtPayloadValide()) + }) + }) +}) diff --git a/test/fixtures/fixtures.ts b/test/utils/fixtures.ts similarity index 54% rename from test/fixtures/fixtures.ts rename to test/utils/fixtures.ts index 6cd7d0c..da1632d 100644 --- a/test/fixtures/fixtures.ts +++ b/test/utils/fixtures.ts @@ -1,6 +1,8 @@ +import { JWTPayload } from 'jose' import { Account } from '../../src/domain/account' import { User } from '../../src/domain/user' import { PassEmploiUser } from '../../src/pass-emploi-api/pass-emploi-api.service' +import { TokenData } from '../../src/token/token.service' export const unAccount = (args: Partial = {}): Account => { const defaults: Account = { @@ -41,3 +43,32 @@ export const unPassEmploiUser = ( return { ...defaults, ...args } } + +export const unTokenData = (args: Partial = {}): TokenData => { + const defaults: TokenData = { + token: 'un-token', + expiresIn: 100, + scope: '' + } + + return { ...defaults, ...args } +} + +export const unJwtPayloadValide = (): JWTPayload => ({ + aud: 'https://api.pass-emploi.incubateur.net', + client_id: 'pass-emploi-swagger', + email: 'frep+bdumont@octo.com', + exp: 1717489640, + family_name: 'Bernard', + given_name: 'Dumond', + iat: 1717487840, + iss: 'https://id.pass-emploi.incubateur.net', + jti: 'lv4lwzTINyr8l_WVVFmgn', + preferred_username: 'b.dumont', + scope: 'openid email profile', + sub: 'CONSEILLER|MILO|df095ff0-23e9-48d3-8e26-358c3e614881', + userId: 'cc03c25e-950e-4434-8103-583b8d9c29b3', + userRoles: ['SUPERVISEUR'], + userStructure: 'MILO', + userType: 'CONSEILLER' +}) diff --git a/test/utils/module-for-testing.ts b/test/utils/module-for-testing.ts index 6675924..272d01c 100644 --- a/test/utils/module-for-testing.ts +++ b/test/utils/module-for-testing.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-process-env */ import { HttpModule } from '@nestjs/axios' import { INestApplication, Provider, ValidationPipe } from '@nestjs/common' import { ConfigModule, ConfigService } from '@nestjs/config' @@ -5,6 +6,8 @@ import { SinonSandbox, createSandbox } from 'sinon' import { PassEmploiAPIService } from '../../src/pass-emploi-api/pass-emploi-api.service' import { stubClassSandbox } from './types' import { Test, TestingModuleBuilder } from '@nestjs/testing' +import * as dotenv from 'dotenv' +dotenv.config({ path: '.environment' }) const IDP_FT_CONSEILLER_ACCESS_TOKEN_MAX_AGE = 1800 const IDP_FT_CONSEILLER_REFRESH_TOKEN_MAX_AGE = 3600 * 24 * 42 @@ -91,7 +94,7 @@ export const testConfig = (): ConfigService => { url: 'rsrc', scopes: '' }, - jwks: [], + jwks: JSON.parse(process.env.JWKS!), idps: { francetravailJeune: { issuer: 'ft-jeune.com', @@ -124,15 +127,15 @@ export const testConfig = (): ConfigService => { refreshTokenMaxAge: IDP_FT_CONSEILLER_REFRESH_TOKEN_MAX_AGE }, miloConseiller: { - issuer: 'milo-conseiller.com', - authorizationUrl: 'milo-conseiller.com/authorize', - tokenUrl: 'milo-conseiller.com/token', - jwks: 'milo-conseiller.com/jwks', - userinfo: 'milo-conseiller.com/userinfo', - clientId: 'milo-conseiller', - clientSecret: 'milo-conseiller-secret', - scopes: '', - redirectUri: '', + issuer: process.env.IDP_MILO_CONSEILLER_ISSUER, + authorizationUrl: process.env.IDP_MILO_CONSEILLER_AUTHORIZATION_URL, + tokenUrl: process.env.IDP_MILO_CONSEILLER_TOKEN_URL, + jwks: process.env.IDP_MILO_CONSEILLER_JWKS, + userinfo: process.env.IDP_MILO_CONSEILLER_USERINFO, + clientId: process.env.IDP_MILO_CONSEILLER_CLIENT_ID, + clientSecret: process.env.IDP_MILO_CONSEILLER_CLIENT_SECRET, + scopes: process.env.IDP_MILO_CONSEILLER_SCOPES, + redirectUri: process.env.IDP_MILO_CONSEILLER_REDIRECT_URI, logout: '', accessTokenMaxAge: IDP_MILO_CONSEILLER_ACCESS_TOKEN_MAX_AGE, refreshTokenMaxAge: IDP_MILO_CONSEILLER_REFRESH_TOKEN_MAX_AGE @@ -151,6 +154,11 @@ export const testConfig = (): ConfigService => { accessTokenMaxAge: IDP_MILO_JEUNE_ACCESS_TOKEN_MAX_AGE, refreshTokenMaxAge: IDP_MILO_JEUNE_REFRESH_TOKEN_MAX_AGE } + }, + test: { + miloConseillerOfflineToken: + process.env.TEST_MILO_CONSEILLER_OFFLINE_TOKEN, + miloConseillerCEJJWT: process.env.TEST_MILO_CONSEILLER_CEJ_JWT } }) } diff --git a/tsconfig.json b/tsconfig.json index 3af4e49..25e44a0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,6 +23,8 @@ "noUnusedLocals": false }, "ts-node": { - "files": true + "moduleTypes": { + "test/integration/**/*.ts": "cjs" + } } } diff --git a/yarn.lock b/yarn.lock index b18bbbd..c239d5d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -243,6 +243,126 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@cucumber/ci-environment@10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@cucumber/ci-environment/-/ci-environment-10.0.1.tgz#c8584f1d4a619e4318cf60c01b838db096d72ccd" + integrity sha512-/+ooDMPtKSmvcPMDYnMZt4LuoipfFfHaYspStI4shqw8FyKcfQAmekz6G+QKWjQQrvM+7Hkljwx58MEwPCwwzg== + +"@cucumber/cucumber-expressions@17.1.0": + version "17.1.0" + resolved "https://registry.yarnpkg.com/@cucumber/cucumber-expressions/-/cucumber-expressions-17.1.0.tgz#1a428548a2c98ef3224bd484fc5666b4f7153a72" + integrity sha512-PCv/ppsPynniKPWJr5v566daCVe+pbxQpHGrIu/Ev57cCH9Rv+X0F6lio4Id3Z64TaG7btCRLUGewIgLwmrwOA== + dependencies: + regexp-match-indices "1.0.2" + +"@cucumber/cucumber@^10.8.0": + version "10.8.0" + resolved "https://registry.yarnpkg.com/@cucumber/cucumber/-/cucumber-10.8.0.tgz#d906b451a07a91c254f90b8e2dfed4cf8ade3fcf" + integrity sha512-o8SR6MRQVCKKw4tytWqCqOjfX4cASj9dqpdHKHMi09rZWBCNQHBwH1TO9wj7NKjOa6RfUOTcgvDlayTcjyCH4A== + dependencies: + "@cucumber/ci-environment" "10.0.1" + "@cucumber/cucumber-expressions" "17.1.0" + "@cucumber/gherkin" "28.0.0" + "@cucumber/gherkin-streams" "5.0.1" + "@cucumber/gherkin-utils" "9.0.0" + "@cucumber/html-formatter" "21.3.1" + "@cucumber/message-streams" "4.0.1" + "@cucumber/messages" "24.1.0" + "@cucumber/tag-expressions" "6.1.0" + assertion-error-formatter "^3.0.0" + capital-case "^1.0.4" + chalk "^4.1.2" + cli-table3 "0.6.3" + commander "^10.0.0" + debug "^4.3.4" + error-stack-parser "^2.1.4" + figures "^3.2.0" + glob "^10.3.10" + has-ansi "^4.0.1" + indent-string "^4.0.0" + is-installed-globally "^0.4.0" + is-stream "^2.0.0" + knuth-shuffle-seeded "^1.0.6" + lodash.merge "^4.6.2" + lodash.mergewith "^4.6.2" + luxon "3.2.1" + mkdirp "^2.1.5" + mz "^2.7.0" + progress "^2.0.3" + read-pkg-up "^7.0.1" + resolve-pkg "^2.0.0" + semver "7.5.3" + string-argv "0.3.1" + strip-ansi "6.0.1" + supports-color "^8.1.1" + tmp "0.2.3" + type-fest "^4.8.3" + util-arity "^1.1.0" + xmlbuilder "^15.1.1" + yaml "^2.2.2" + yup "1.2.0" + +"@cucumber/gherkin-streams@5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@cucumber/gherkin-streams/-/gherkin-streams-5.0.1.tgz#8c2142d295cd05644456be7282b4bd756c95c4cd" + integrity sha512-/7VkIE/ASxIP/jd4Crlp4JHXqdNFxPGQokqWqsaCCiqBiu5qHoKMxcWNlp9njVL/n9yN4S08OmY3ZR8uC5x74Q== + dependencies: + commander "9.1.0" + source-map-support "0.5.21" + +"@cucumber/gherkin-utils@9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@cucumber/gherkin-utils/-/gherkin-utils-9.0.0.tgz#944c64c458742d8e73b750e5dde2cf56b161d674" + integrity sha512-clk4q39uj7pztZuZtyI54V8lRsCUz0Y/p8XRjIeHh7ExeEztpWkp4ca9q1FjUOPfQQ8E7OgqFbqoQQXZ1Bx7fw== + dependencies: + "@cucumber/gherkin" "^28.0.0" + "@cucumber/messages" "^24.0.0" + "@teppeis/multimaps" "3.0.0" + commander "12.0.0" + source-map-support "^0.5.21" + +"@cucumber/gherkin@28.0.0", "@cucumber/gherkin@^28.0.0": + version "28.0.0" + resolved "https://registry.yarnpkg.com/@cucumber/gherkin/-/gherkin-28.0.0.tgz#91246da622524807b21430c1692bedd319d3d4bb" + integrity sha512-Ee6zJQq0OmIUPdW0mSnsCsrWA2PZAELNDPICD2pLfs0Oz7RAPgj80UsD2UCtqyAhw2qAR62aqlktKUlai5zl/A== + dependencies: + "@cucumber/messages" ">=19.1.4 <=24" + +"@cucumber/html-formatter@21.3.1": + version "21.3.1" + resolved "https://registry.yarnpkg.com/@cucumber/html-formatter/-/html-formatter-21.3.1.tgz#1c832d95891c1e961d9e6a4da4664c09a1332768" + integrity sha512-M1zbre7e8MsecXheqNv62BKY5J06YJSv1LmsD7sJ3mu5t1jirLjj2It1HqPsX5CQAfg9n69xFRugPgLMSte9TA== + +"@cucumber/message-streams@4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@cucumber/message-streams/-/message-streams-4.0.1.tgz#a5339d3504594bb2edb5732aaae94dddb24d0970" + integrity sha512-Kxap9uP5jD8tHUZVjTWgzxemi/0uOsbGjd4LBOSxcJoOCRbESFwemUzilJuzNTB8pcTQUh8D5oudUyxfkJOKmA== + +"@cucumber/messages@24.1.0", "@cucumber/messages@>=19.1.4 <=24", "@cucumber/messages@^24.0.0": + version "24.1.0" + resolved "https://registry.yarnpkg.com/@cucumber/messages/-/messages-24.1.0.tgz#a212c97b0548144c3ccfae021a96d6c56d3841d3" + integrity sha512-hxVHiBurORcobhVk80I9+JkaKaNXkW6YwGOEFIh/2aO+apAN+5XJgUUWjng9NwqaQrW1sCFuawLB1AuzmBaNdQ== + dependencies: + "@types/uuid" "9.0.8" + class-transformer "0.5.1" + reflect-metadata "0.2.1" + uuid "9.0.1" + +"@cucumber/pretty-formatter@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@cucumber/pretty-formatter/-/pretty-formatter-1.0.1.tgz#65d6c1df436920036a7bd02d08cb44d20e7af0ab" + integrity sha512-A1lU4VVP0aUWdOTmpdzvXOyEYuPtBDI0xYwYJnmoMDplzxMdhcHk86lyyvYDoMoPzzq6OkOE3isuosvUU4X7IQ== + dependencies: + ansi-styles "^5.0.0" + cli-table3 "^0.6.0" + figures "^3.2.0" + ts-dedent "^2.0.0" + +"@cucumber/tag-expressions@6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@cucumber/tag-expressions/-/tag-expressions-6.1.0.tgz#cb7af908bdb43669b7574c606f71fa707196e962" + integrity sha512-+3DwRumrCJG27AtzCIL37A/X+A/gSfxOPLg8pZaruh5SLumsTmpvilwroVWBT2fPzmno/tGXypeK5a7NHU4RzA== + "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -531,10 +651,18 @@ path-to-regexp "3.2.0" swagger-ui-dist "5.11.2" +"@nestjs/terminus@^10.2.3": + version "10.2.3" + resolved "https://registry.yarnpkg.com/@nestjs/terminus/-/terminus-10.2.3.tgz#72c8a66d04df52aeaae807551245480fd7239a75" + integrity sha512-iX7gXtAooePcyQqFt57aDke5MzgdkBeYgF5YsFNNFwOiAFdIQEhfv3PR0G+HlH9F6D7nBCDZt9U87Pks/qHijg== + dependencies: + boxen "5.1.2" + check-disk-space "3.4.0" + "@nestjs/testing@^10.3.8": - version "10.3.8" - resolved "https://registry.yarnpkg.com/@nestjs/testing/-/testing-10.3.8.tgz#44df73ede43c47801400d59a8ebd6ab1fe7df34c" - integrity sha512-hpX9das2TdFTKQ4/2ojhjI6YgXtCfXRKui3A4Qaj54VVzc5+mtK502Jj18Vzji98o9MVS6skmYu+S/UvW3U6Fw== + version "10.3.9" + resolved "https://registry.yarnpkg.com/@nestjs/testing/-/testing-10.3.9.tgz#27fb0e23b129147f8de100ac40645ebf6a865c3a" + integrity sha512-z24SdpZIRtYyM5s2vnu7rbBosXJY/KcAP7oJlwgFa/h/z/wg8gzyoKy5lhibH//OZNO+pYKajV5wczxuy5WeAg== dependencies: tslib "2.6.2" @@ -573,6 +701,22 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@salesforce/ts-sinon@^1.4.19": + version "1.4.19" + resolved "https://registry.yarnpkg.com/@salesforce/ts-sinon/-/ts-sinon-1.4.19.tgz#64157b6c8cf4a3c637867e2ddd90c2d058c334f7" + integrity sha512-vopxKrI6QD0OCtPlge1eGGHFWLkoDee7KaB/dpGeRwioeNfCVJ8ikELN0hv0zq9Ys6gUYWYcdpxzTP1upslCJA== + dependencies: + "@salesforce/ts-types" "^2.0.9" + sinon "^5.1.1" + tslib "^2.6.1" + +"@salesforce/ts-types@^2.0.9": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@salesforce/ts-types/-/ts-types-2.0.9.tgz#66bff7b41720065d6b01631b6f6a3ccca02857c5" + integrity sha512-boUD9jw5vQpTCPCCmK/NFTWjSuuW+lsaxOynkyNXLW+zxOc4GDjhtKc4j0vWZJQvolpafbyS8ZLFHZJvs12gYA== + dependencies: + tslib "^2.6.2" + "@sideway/address@^4.1.5": version "4.1.5" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.5.tgz#4bc149a0076623ced99ca8208ba780d65a99b9d5" @@ -600,6 +744,13 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-5.6.0.tgz#41dd6093d34652cddb5d5bdeee04eafc33826668" integrity sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g== +"@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.7.0": + version "1.8.6" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" + integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== + dependencies: + type-detect "4.0.8" + "@sinonjs/commons@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" @@ -621,6 +772,30 @@ dependencies: "@sinonjs/commons" "^3.0.0" +"@sinonjs/formatio@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2" + integrity sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg== + dependencies: + samsam "1.3.0" + +"@sinonjs/formatio@^3.2.1": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.2.2.tgz#771c60dfa75ea7f2d68e3b94c7e888a78781372c" + integrity sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ== + dependencies: + "@sinonjs/commons" "^1" + "@sinonjs/samsam" "^3.1.0" + +"@sinonjs/samsam@^3.1.0": + version "3.3.3" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-3.3.3.tgz#46682efd9967b259b81136b9f120fd54585feb4a" + integrity sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ== + dependencies: + "@sinonjs/commons" "^1.3.0" + array-from "^2.1.1" + lodash "^4.17.15" + "@sinonjs/samsam@^8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-8.0.0.tgz#0d488c91efb3fa1442e26abea81759dfc8b5ac60" @@ -630,7 +805,7 @@ lodash.get "^4.4.2" type-detect "^4.0.8" -"@sinonjs/text-encoding@^0.7.2": +"@sinonjs/text-encoding@^0.7.1", "@sinonjs/text-encoding@^0.7.2": version "0.7.2" resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz#5981a8db18b56ba38ef0efb7d995b12aa7b51918" integrity sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ== @@ -745,6 +920,11 @@ dependencies: defer-to-connect "^2.0.1" +"@teppeis/multimaps@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@teppeis/multimaps/-/multimaps-3.0.0.tgz#bb9c3f8d569f589e548586fa0bbf423010ddfdc5" + integrity sha512-ID7fosbc50TbT0MK0EG12O+gAP3W3Aa/Pz4DaTtQtEvlc9Odaqi0de+xuZ7Li2GtK4HzEX7IuRWS/JmZLksR3Q== + "@tokenizer/token@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" @@ -963,6 +1143,11 @@ dependencies: undici-types "~5.26.4" +"@types/normalize-package-data@^2.4.0": + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== + "@types/oidc-provider@^8.4.4": version "8.4.4" resolved "https://registry.yarnpkg.com/@types/oidc-provider/-/oidc-provider-8.4.4.tgz#2ec78f52a753be46f59ac13672575d14ef1cfc2c" @@ -1054,7 +1239,7 @@ "@types/methods" "^1.1.4" "@types/superagent" "^8.1.0" -"@types/uuid@^9.0.8": +"@types/uuid@9.0.8", "@types/uuid@^9.0.8": version "9.0.8" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== @@ -1356,7 +1541,7 @@ ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.0.1: +ajv@^8.0.0: version "8.14.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.14.0.tgz#f514ddfd4756abb200e1704414963620a625ebbb" integrity sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA== @@ -1366,6 +1551,23 @@ ajv@^8.0.0, ajv@^8.0.1: require-from-string "^2.0.2" uri-js "^4.4.1" +ajv@^8.0.1: + version "8.15.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.15.0.tgz#d918c661e3e820bbbc65a320e182ee56a1aa978a" + integrity sha512-15BTtQUOsSrmHCy+B4VnAiJAJxJ8IFgu6fcjFQF3jQYZ78nLSQthlFg4ehp+NLIyfvFgOlxNsjKIEhydtFPVHQ== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^2.3.0" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" + ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" @@ -1388,6 +1590,11 @@ ansi-escapes@^6.2.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-6.2.1.tgz#76c54ce9b081dad39acec4b5d53377913825fb0f" integrity sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig== +ansi-regex@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" + integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -1412,11 +1619,21 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + ansi-styles@^6.0.0, ansi-styles@^6.1.0, ansi-styles@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" @@ -1469,6 +1686,11 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== +array-from@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" + integrity sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg== + array-timsort@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/array-timsort/-/array-timsort-1.0.3.tgz#3c9e4199e54fb2b9c3fe5976396a21614ef0d926" @@ -1484,6 +1706,15 @@ asap@^2.0.0: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== +assertion-error-formatter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/assertion-error-formatter/-/assertion-error-formatter-3.0.0.tgz#be9c8825dee6a8a6c72183d915912d9b57d5d265" + integrity sha512-6YyAVLrEze0kQ7CmJfUgrLHb+Y7XghmL2Ie7ijVa2Y9ynP3LV+VDiwFk62Dn0qtqbmY0BT0ss6p1xxpiF2PYbQ== + dependencies: + diff "^4.0.1" + pad-right "^0.2.2" + repeat-string "^1.6.1" + assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" @@ -1580,6 +1811,20 @@ body-parser@1.20.2: type-is "~1.6.18" unpipe "1.0.0" +boxen@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1715,7 +1960,7 @@ call-bind@^1.0.7: get-intrinsic "^1.2.4" set-function-length "^1.2.1" -callsites@^3.0.0: +callsites@^3.0.0, callsites@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== @@ -1725,7 +1970,7 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.0.0: +camelcase@^6.0.0, camelcase@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== @@ -1735,6 +1980,15 @@ caniuse-lite@^1.0.30001587: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001625.tgz#ead1b155ea691d6a87938754d3cb119c24465b03" integrity sha512-4KE9N2gcRH+HQhpeiRZXd+1niLB/XNLAhSy4z7fI8EzcbcPoAqjNInxVHTiTwWfTIV4w096XG8OtCOCQQKPv3w== +capital-case@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/capital-case/-/capital-case-1.0.4.tgz#9d130292353c9249f6b00fa5852bee38a717e669" + integrity sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + upper-case-first "^2.0.2" + chai-as-promised@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.2.tgz#70cd73b74afd519754161386421fb71832c6d041" @@ -1789,6 +2043,11 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +check-disk-space@3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/check-disk-space/-/check-disk-space-3.4.0.tgz#eb8e69eee7a378fd12e35281b8123a8b4c4a8ff7" + integrity sha512-drVkSqfwA+TvuEhFipiR1OC9boEGZL5RrWvVsOthdcvQNXyCCuKkEiTOTXZ7qxSf/GLwq4GvzfrQD/Wz325hgw== + check-error@^1.0.2, check-error@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" @@ -1831,11 +2090,21 @@ chrome-trace-event@^1.0.2: resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== +class-transformer@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336" + integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw== + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + cli-color@^2.0.2: version "2.0.4" resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-2.0.4.tgz#d658080290968816b322248b7306fad2346fb2c8" @@ -1875,6 +2144,15 @@ cli-table3@0.6.3: optionalDependencies: "@colors/colors" "1.5.0" +cli-table3@^0.6.0: + version "0.6.5" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.5.tgz#013b91351762739c16a9567c21a04632e449bf2f" + integrity sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ== + dependencies: + string-width "^4.2.0" + optionalDependencies: + "@colors/colors" "1.5.0" + cli-truncate@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-4.0.0.tgz#6cc28a2924fee9e25ce91e973db56c7066e6172a" @@ -1978,11 +2256,26 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +commander@12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-12.0.0.tgz#b929db6df8546080adfd004ab215ed48cf6f2592" + integrity sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA== + commander@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== +commander@9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.1.0.tgz#a6b263b2327f2e188c6402c42623327909f2dbec" + integrity sha512-i0/MaqBtdbnJ4XQs4Pmyb+oFQl+q0lsAmokVUH92SlSw4fkeAcG3bVon+Qt7hmtF+u3Het6o4VgrcY3qAoEB6w== + +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -2130,6 +2423,16 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +cucumber-tsflow@^4.4.4: + version "4.4.4" + resolved "https://registry.yarnpkg.com/cucumber-tsflow/-/cucumber-tsflow-4.4.4.tgz#052dc4ae2c80b0d8b1fb6aa7b248f84e76324d72" + integrity sha512-oe2fPcAxWljZTc4+u0whbXIxZvjWzXfsieoY/TGuHY4aDLLOCFVLOVIxV8bKEI53PQhxJH809VugWHe2DB+nJg== + dependencies: + callsites "^3.1.0" + log4js "^6.3.0" + source-map-support "^0.5.19" + underscore "^1.8.3" + d@1, d@^1.0.1, d@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/d/-/d-1.0.2.tgz#2aefd554b81981e7dccf72d6842ae725cb17e5de" @@ -2138,6 +2441,11 @@ d@1, d@^1.0.1, d@^1.0.2: es5-ext "^0.10.64" type "^2.7.2" +date-format@^4.0.14: + version "4.0.14" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.14.tgz#7a8e584434fb169a521c8b7aa481f355810d9400" + integrity sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg== + debug@2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -2145,13 +2453,20 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4.3.4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.4: +debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" +debug@^4.0.1: + version "4.3.5" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e" + integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== + dependencies: + ms "2.1.2" + decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -2262,6 +2577,11 @@ diff@5.0.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +diff@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + diff@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" @@ -2411,6 +2731,13 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +error-stack-parser@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" + integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== + dependencies: + stackframe "^1.3.4" + es-define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" @@ -2849,6 +3176,11 @@ fast-safe-stringify@2.1.1, fast-safe-stringify@^2.1.1: resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== +fast-uri@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-2.3.0.tgz#bdae493942483d299e7285dcb4627767d42e2793" + integrity sha512-eel5UKGn369gGEWOqBShmFJWfq/xSJvsgDzgLYC845GneayWvXBf0lJCBn5qTABfewy1ZDPoaR5OZCP+kssfuw== + fastq@^1.6.0: version "1.17.1" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" @@ -2861,7 +3193,7 @@ fclone@^1.0.11: resolved "https://registry.yarnpkg.com/fclone/-/fclone-1.0.11.tgz#10e85da38bfea7fc599341c296ee1d77266ee640" integrity sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw== -figures@^3.0.0: +figures@^3.0.0, figures@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== @@ -2972,7 +3304,7 @@ flat@^5.0.2: resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== -flatted@^3.2.9: +flatted@^3.2.7, flatted@^3.2.9: version "3.3.1" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== @@ -3063,6 +3395,15 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-monkey@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.6.tgz#8ead082953e88d992cf3ff844faa907b26756da2" @@ -3180,6 +3521,17 @@ glob@8.1.0: minimatch "^5.0.1" once "^1.3.0" +glob@^10.3.10: + version "10.4.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.1.tgz#0cfb01ab6a6b438177bfe6a58e2576f6efe909c2" + integrity sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + path-scurry "^1.11.1" + glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -3202,6 +3554,13 @@ glob@^9.2.0: minipass "^4.2.4" path-scurry "^1.6.1" +global-dirs@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.1.tgz#0c488971f066baceda21447aecb1a8b911d22485" + integrity sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA== + dependencies: + ini "2.0.0" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -3277,6 +3636,13 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +has-ansi@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-4.0.1.tgz#f216a8c8d7b129e490dc15f4a62cc1cdb9603ce8" + integrity sha512-Qr4RtTm30xvEdqUXbSBVWDu+PrTokJOwe/FU+VdfJPk+MXAPoeOzKpRyrDTnZIJwAkQ4oBLTU53nu0HrkF/Z2A== + dependencies: + ansi-regex "^4.1.0" + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -3341,6 +3707,11 @@ hexoid@^1.0.0: resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-1.0.0.tgz#ad10c6573fb907de23d9ec63a711267d9dc9bc18" integrity sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g== +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -3475,6 +3846,11 @@ inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + inquirer@8.2.6: version "8.2.6" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.6.tgz#733b74888195d8d400a67ac332011b5fae5ea562" @@ -3597,6 +3973,14 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-installed-globally@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== + dependencies: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" @@ -3607,6 +3991,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-plain-obj@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -3662,6 +4051,11 @@ is-windows@^1.0.2: resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== + isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -3746,6 +4140,15 @@ jackspeak@^2.3.5: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" +jackspeak@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.1.2.tgz#eada67ea949c6b71de50f1b09c92a961897b90ab" + integrity sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jest-worker@^27.4.5: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" @@ -3851,6 +4254,13 @@ jsonc-parser@3.2.1: resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.1.tgz#031904571ccf929d7670ee8c547545081cb37f1a" integrity sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA== +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -3860,6 +4270,11 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +just-extend@^4.0.2: + version "4.2.1" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.2.1.tgz#ef5e589afb61e5d66b24eca749409a8939a8c744" + integrity sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg== + just-extend@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-6.2.0.tgz#b816abfb3d67ee860482e7401564672558163947" @@ -3879,6 +4294,13 @@ keyv@^4.0.0, keyv@^4.5.3: dependencies: json-buffer "3.0.1" +knuth-shuffle-seeded@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/knuth-shuffle-seeded/-/knuth-shuffle-seeded-1.0.6.tgz#01f1b65733aa7540ee08d8b0174164d22081e4e1" + integrity sha512-9pFH0SplrfyKyojCLxZfMcvkhf5hH0d+UwR9nTVJ/DDQJGuzcXjTwB7TP7sDfehSudlGGaOLblmEWqv04ERVWg== + dependencies: + seed-random "~2.2.0" + koa-compose@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" @@ -4016,12 +4438,17 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.mergewith@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + lodash.truncate@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== -lodash@4.17.21, lodash@^4.17.21: +lodash@4.17.21, lodash@^4.17.15, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -4045,6 +4472,29 @@ log-update@^6.0.0: strip-ansi "^7.1.0" wrap-ansi "^9.0.0" +log4js@^6.3.0: + version "6.9.1" + resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.9.1.tgz#aba5a3ff4e7872ae34f8b4c533706753709e38b6" + integrity sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g== + dependencies: + date-format "^4.0.14" + debug "^4.3.4" + flatted "^3.2.7" + rfdc "^1.3.0" + streamroller "^3.1.5" + +lolex@^2.4.2: + version "2.7.5" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.5.tgz#113001d56bfc7e02d56e36291cc5c413d1aa0733" + integrity sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q== + +lolex@^5.0.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" + integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A== + dependencies: + "@sinonjs/commons" "^1.7.0" + loupe@^2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" @@ -4052,6 +4502,13 @@ loupe@^2.3.6: dependencies: get-func-name "^2.0.1" +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + lowercase-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" @@ -4096,6 +4553,11 @@ lru-queue@^0.1.0: dependencies: es5-ext "~0.10.2" +luxon@3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.2.1.tgz#14f1af209188ad61212578ea7e3d518d18cee45f" + integrity sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg== + luxon@^3.4.4: version "3.4.4" resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af" @@ -4263,7 +4725,7 @@ minimatch@^8.0.2: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.1, minimatch@^9.0.3: +minimatch@^9.0.1, minimatch@^9.0.3, minimatch@^9.0.4: version "9.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51" integrity sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw== @@ -4280,7 +4742,7 @@ minipass@^4.2.4: resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.8.tgz#f0010f64393ecfc1d1ccb5f582bcaf45f48e1a3a" integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== @@ -4292,6 +4754,11 @@ mkdirp@^0.5.4: dependencies: minimist "^1.2.6" +mkdirp@^2.1.5: + version "2.1.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19" + integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A== + mocha@^10.4.0: version "10.4.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.4.0.tgz#ed03db96ee9cfc6d20c56f8e2af07b961dbae261" @@ -4356,6 +4823,15 @@ mute-stream@1.0.0: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + nanoid@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" @@ -4399,6 +4875,17 @@ nice-napi@^1.0.2: node-addon-api "^3.0.0" node-gyp-build "^4.2.2" +nise@^1.3.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/nise/-/nise-1.5.3.tgz#9d2cfe37d44f57317766c6e9408a359c5d3ac1f7" + integrity sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ== + dependencies: + "@sinonjs/formatio" "^3.2.1" + "@sinonjs/text-encoding" "^0.7.1" + just-extend "^4.0.2" + lolex "^5.0.1" + path-to-regexp "^1.7.0" + nise@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/nise/-/nise-6.0.0.tgz#ae56fccb5d912037363c3b3f29ebbfa28bde8b48" @@ -4410,6 +4897,14 @@ nise@^6.0.0: just-extend "^6.2.0" path-to-regexp "^6.2.1" +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + nock@^13.5.4: version "13.5.4" resolved "https://registry.yarnpkg.com/nock/-/nock-13.5.4.tgz#8918f0addc70a63736170fef7106a9721e0dc479" @@ -4460,6 +4955,16 @@ node-releases@^2.0.14: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== +normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -4529,7 +5034,7 @@ nyc@^15.1.0: test-exclude "^6.0.0" yargs "^15.0.2" -object-assign@^4, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -4725,6 +5230,13 @@ package-hash@^4.0.0: lodash.flattendeep "^4.4.0" release-zalgo "^1.0.0" +pad-right@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/pad-right/-/pad-right-0.2.2.tgz#6fbc924045d244f2a2a244503060d3bfc6009774" + integrity sha512-4cy8M95ioIGolCoMmm2cMntGR1lPLEbOMzOKu8bzjuJP6JpzEMQcDHmh7hHLYGgob+nKe1YHFMaG4V59HQa89g== + dependencies: + repeat-string "^1.5.2" + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -4732,7 +5244,7 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-json@^5.2.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -4782,7 +5294,7 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.10.1, path-scurry@^1.6.1: +path-scurry@^1.10.1, path-scurry@^1.11.1, path-scurry@^1.6.1: version "1.11.1" resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== @@ -4800,6 +5312,13 @@ path-to-regexp@3.2.0: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-3.2.0.tgz#fa7877ecbc495c601907562222453c43cc204a5f" integrity sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA== +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + path-to-regexp@^6.2.1: version "6.2.2" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.2.tgz#324377a83e5049cbecadc5554d6a63a9a4866b36" @@ -4952,7 +5471,7 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== -progress@^2.0.0: +progress@^2.0.0, progress@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== @@ -4962,6 +5481,11 @@ propagate@^2.0.0: resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45" integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== +property-expr@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.6.tgz#f77bc00d5928a6c748414ad12882e83f24aec1e8" + integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA== + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -5054,6 +5578,25 @@ raw-body@2.5.2, raw-body@^2.5.2: iconv-lite "0.4.24" unpipe "1.0.0" +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + readable-stream@^2.2.2: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" @@ -5125,11 +5668,28 @@ redis-parser@^3.0.0: dependencies: redis-errors "^1.0.0" +reflect-metadata@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.1.tgz#8d5513c0f5ef2b4b9c3865287f3c0940c1f67f74" + integrity sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw== + reflect-metadata@^0.2.1: version "0.2.2" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b" integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== +regexp-match-indices@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regexp-match-indices/-/regexp-match-indices-1.0.2.tgz#cf20054a6f7d5b3e116a701a7b00f82889d10da6" + integrity sha512-DwZuAkt8NF5mKwGGER1EGh2PRqyvhRhhLviH+R8y8dIuaQROlUfXjt4s9ZTXstIsSkptf06BSvwcEmmfheJJWQ== + dependencies: + regexp-tree "^0.1.11" + +regexp-tree@^0.1.11: + version "0.1.27" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.27.tgz#2198f0ef54518ffa743fe74d983b56ffd631b6cd" + integrity sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA== + regexpp@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" @@ -5142,7 +5702,7 @@ release-zalgo@^1.0.0: dependencies: es6-error "^4.0.1" -repeat-string@^1.6.1: +repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== @@ -5177,7 +5737,14 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve@^1.1.6: +resolve-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg/-/resolve-pkg-2.0.0.tgz#ac06991418a7623edc119084edc98b0e6bf05a41" + integrity sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ== + dependencies: + resolve-from "^5.0.0" + +resolve@^1.1.6, resolve@^1.10.0: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -5221,7 +5788,7 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rfdc@^1.3.1: +rfdc@^1.3.0, rfdc@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.1.tgz#2b6d4df52dffe8bb346992a10ea9451f24373a8f" integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg== @@ -5284,6 +5851,11 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +samsam@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50" + integrity sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg== + sanitize-html@^2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.13.0.tgz#71aedcdb777897985a4ea1877bf4f895a1170dae" @@ -5305,6 +5877,11 @@ schema-utils@^3.1.1, schema-utils@^3.2.0: ajv "^6.12.5" ajv-keywords "^3.5.2" +seed-random@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/seed-random/-/seed-random-2.2.0.tgz#2a9b19e250a817099231a5b99a4daf80b7fbed54" + integrity sha512-34EQV6AAHQGhoc0tn/96a9Fsi6v2xdqe/dMUwljGRaFOzR3EgRmECvD0O8vi8X+/uQ50LGHfkNu/Eue5TPKZkQ== + semver-regex@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-4.0.5.tgz#fbfa36c7ba70461311f5debcb3928821eb4f9180" @@ -5317,6 +5894,18 @@ semver-truncate@^3.0.0: dependencies: semver "^7.3.5" +"semver@2 || 3 || 4 || 5": + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@7.5.3: + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== + dependencies: + lru-cache "^6.0.0" + semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" @@ -5462,6 +6051,19 @@ sinon@^18.0.0: nise "^6.0.0" supports-color "^7" +sinon@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-5.1.1.tgz#19c59810ffb733ea6e76a28b94a71fc4c2f523b8" + integrity sha512-h/3uHscbt5pQNxkf7Y/Lb9/OM44YNCicHakcq73ncbrIS8lXg+ZGOZbtuU+/km4YnyiCYfQQEwANaReJz7KDfw== + dependencies: + "@sinonjs/formatio" "^2.0.0" + diff "^3.5.0" + lodash.get "^4.4.2" + lolex "^2.4.2" + nise "^1.3.3" + supports-color "^5.4.0" + type-detect "^4.0.8" + slash@3.0.0, slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -5518,7 +6120,7 @@ source-map-js@^1.2.0: resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== -source-map-support@0.5.21, source-map-support@^0.5.21, source-map-support@~0.5.20: +source-map-support@0.5.21, source-map-support@^0.5.19, source-map-support@^0.5.21, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -5548,6 +6150,32 @@ spawn-wrap@^2.0.0: signal-exit "^3.0.2" which "^2.0.1" +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" + integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.18" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz#22aa922dcf2f2885a6494a261f2d8b75345d0326" + integrity sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ== + split2@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" @@ -5558,6 +6186,11 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +stackframe@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" + integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== + standard-as-callback@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" @@ -5573,17 +6206,40 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +streamroller@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.1.5.tgz#1263182329a45def1ffaef58d31b15d13d2ee7ff" + integrity sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw== + dependencies: + date-format "^4.0.14" + debug "^4.3.4" + fs-extra "^8.1.0" + streamsearch@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== +string-argv@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" + integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== + string-argv@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5624,7 +6280,14 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -5704,14 +6367,14 @@ supertest@^7.0.0: methods "^1.1.2" superagent "^9.0.1" -supports-color@8.1.1, supports-color@^8.0.0: +supports-color@8.1.1, supports-color@^8.0.0, supports-color@^8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" -supports-color@^5.3.0: +supports-color@^5.3.0, supports-color@^5.4.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -5803,6 +6466,20 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + thread-stream@^2.6.0: version "2.7.0" resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-2.7.0.tgz#d8a8e1b3fd538a6cca8ce69dbe5d3d097b601e11" @@ -5823,6 +6500,16 @@ timers-ext@^0.1.7: es5-ext "~0.10.46" next-tick "1" +tiny-case@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03" + integrity sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q== + +tmp@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" + integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -5855,6 +6542,11 @@ token-types@^5.0.0-alpha.2: "@tokenizer/token" "^0.3.0" ieee754 "^1.2.1" +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -5877,6 +6569,11 @@ ts-api-utils@^1.0.1: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== +ts-dedent@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" + integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== + ts-loader@^9.5.1: version "9.5.1" resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.1.tgz#63d5912a86312f1fbe32cef0859fb8b2193d9b89" @@ -5925,7 +6622,7 @@ tsconfig-paths@4.2.0, tsconfig-paths@^4.1.2, tsconfig-paths@^4.2.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@2.6.2, tslib@^2.1.0: +tslib@2.6.2, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.6.1, tslib@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== @@ -5957,11 +6654,26 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -type-fest@^0.8.0: +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + +type-fest@^0.8.0, type-fest@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + +type-fest@^4.8.3: + version "4.18.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.18.3.tgz#5249f96e7c2c3f0f1561625f54050e343f1c8f68" + integrity sha512-Q08/0IrpvM+NMY9PA2rti9Jb+JejTddwmwmVQGskAlhtcrw1wsRzoR6ode6mR+OAabNa75w/dxedSUY2mlphaQ== + type-is@^1.6.16, type-is@^1.6.4, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -6004,11 +6716,21 @@ uid@2.0.2: dependencies: "@lukeed/csprng" "^1.0.0" +underscore@^1.8.3: + version "1.13.6" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441" + integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== + undici-types@~5.26.4: version "5.26.5" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + universalify@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" @@ -6027,6 +6749,13 @@ update-browserslist-db@^1.0.13: escalade "^3.1.2" picocolors "^1.0.1" +upper-case-first@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-2.0.2.tgz#992c3273f882abd19d1e02894cc147117f844324" + integrity sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg== + dependencies: + tslib "^2.0.3" + uri-js@^4.2.2, uri-js@^4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -6034,6 +6763,11 @@ uri-js@^4.2.2, uri-js@^4.4.1: dependencies: punycode "^2.1.0" +util-arity@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/util-arity/-/util-arity-1.1.0.tgz#59d01af1fdb3fede0ac4e632b0ab5f6ce97c9330" + integrity sha512-kkyIsXKwemfSy8ZEoaIz06ApApnWsk5hQO0vLjZS6UkBiGiW++Jsyb8vSBoc0WKlffGoGs5yYy/j5pp8zckrFA== + util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -6064,6 +6798,14 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz#cdada8bec61e15865f05d097c5f4fd30e94dc128" integrity sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw== +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + vary@^1, vary@^1.1.2, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -6156,6 +6898,13 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + word-wrap@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" @@ -6166,8 +6915,7 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: - name wrap-ansi-cjs +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -6185,6 +6933,15 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" @@ -6218,6 +6975,11 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" +xmlbuilder@^15.1.1: + version "15.1.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5" + integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg== + xtend@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -6248,7 +7010,7 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@~2.4.2: +yaml@^2.2.2, yaml@~2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.2.tgz#7a2b30f2243a5fc299e1f14ca58d475ed4bc5362" integrity sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA== @@ -6343,3 +7105,13 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yup@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/yup/-/yup-1.2.0.tgz#9e51af0c63bdfc9be0fdc6c10aa0710899d8aff6" + integrity sha512-PPqYKSAXjpRCgLgLKVGPA33v5c/WgEx3wi6NFjIiegz90zSwyMpvTFp/uGcVnnbx6to28pgnzp/q8ih3QRjLMQ== + dependencies: + property-expr "^2.0.5" + tiny-case "^1.0.3" + toposort "^2.0.2" + type-fest "^2.19.0"