From 1bf4ab95124e3c0d3323f7723b50240517ae33fe Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Tue, 11 Jun 2024 07:30:36 +0200 Subject: [PATCH 01/40] Squashed commit of the following: commit a2cc0e4b8b9d4cf96cecb45dd6f64f5756f6a794 Author: bunsenstraat Date: Tue Jun 11 07:13:32 2024 +0200 console commit 537026cdf2cf8b3e513f64de1855d258cb629938 Author: bunsenstraat Date: Tue Jun 11 07:09:16 2024 +0200 warning commit 0af14a0b8fc223bb36ecb4486abdb985b7e22088 Author: bunsenstraat Date: Tue Jun 11 06:59:24 2024 +0200 remixd disable commit c5915b0ad644d559d4dfc87b8087a315e2ed7919 Merge: 7f1c2b6ad 14cdb7711 Author: Your Name Date: Mon Jun 10 17:08:56 2024 +0200 Merge branch 'master' of https://github.com/ethereum/remix-project into git4refactor2 commit 7f1c2b6adbd3162c77bad1a12247d79729f78f05 Author: Your Name Date: Mon Jun 10 16:55:27 2024 +0200 UploadToGists commit cc78028f3661e55b4be24ea70c99512887ebcf50 Author: Your Name Date: Mon Jun 10 16:54:28 2024 +0200 flaky commit 7c9dff36c9f6c7722507a208fad3113980079837 Author: Your Name Date: Mon Jun 10 16:45:08 2024 +0200 flaky commit e940a616c67bdd0d43b1513b9168dd5f5040ecc0 Author: Your Name Date: Mon Jun 10 16:32:22 2024 +0200 add pause commit 18290370bf3d8429336f4863a39dce5a89992731 Author: Your Name Date: Mon Jun 10 16:26:13 2024 +0200 vyper test commit 11f70933b2e3ae9caaff6982d140d869231c5ed3 Author: Your Name Date: Mon Jun 10 16:13:14 2024 +0200 workspace tests commit c7d991257b35903d91df8ae6f2f0bca89e3c01bf Author: Your Name Date: Mon Jun 10 15:36:16 2024 +0200 lint commit 089e9cdf5dc68f667c1a84aff678cae0adbe1f87 Author: Your Name Date: Mon Jun 10 15:35:50 2024 +0200 remotes test commit 357a8890767cf81c4c903c328979c5e76339a7d7 Author: Your Name Date: Mon Jun 10 14:58:36 2024 +0200 workspace test commit cb98efeebd215cf56344e68a53f1e0c82a8c6674 Author: Your Name Date: Mon Jun 10 14:56:59 2024 +0200 fix upstream commit ec5e66e32ae11ff4e9ee9d059cb9973eb2dfdf38 Author: Your Name Date: Mon Jun 10 14:37:23 2024 +0200 workspace test commit d29472da6b98e820d418953e87cdc2f65866c218 Author: Your Name Date: Mon Jun 10 14:13:15 2024 +0200 fp test commit c29043621649e623ae5f28b060460cf9c2aaf554 Author: Your Name Date: Mon Jun 10 14:04:23 2024 +0200 linting commit 870c260a409b965c512470bfc4811f928352cc62 Author: Your Name Date: Mon Jun 10 14:03:44 2024 +0200 add test commit ef2014c3e678cb5524b9058de396aa2b85f5a6a2 Author: Your Name Date: Mon Jun 10 13:53:33 2024 +0200 fix undo commit 36a16b812a97c83a7dcf2b747ca7d06d9e25813f Author: Your Name Date: Mon Jun 10 12:31:44 2024 +0200 commands test commit 21b3e732ef5b2e136f1a8404569f97f2978cd818 Author: Your Name Date: Mon Jun 10 12:12:42 2024 +0200 upstream commit 02567607e1947ea206df274261985cb3a46e2a9d Author: Your Name Date: Mon Jun 10 12:03:58 2024 +0200 flaky commit b62c54bbe1460d526436da9aa7a0c66c68584d86 Author: Your Name Date: Mon Jun 10 11:43:05 2024 +0200 remote test commit 918a1662a4efd1037250f0ce55d4957ddd9d6eb5 Author: Your Name Date: Mon Jun 10 10:11:07 2024 +0200 github tests commit 2f9a0b8005a3945014322939f44a577bbbe302c0 Author: Your Name Date: Mon Jun 10 09:00:18 2024 +0200 lint commit 1af49cb949906fc9ab6794204fbd01e1ced73590 Author: Your Name Date: Mon Jun 10 08:52:12 2024 +0200 branch testing commit 5de0383552388b69f3525704674ccb3fc2a2227d Author: Your Name Date: Sun Jun 9 19:21:32 2024 +0200 lint commit d769014d60f82d2ca0ade2a85634d71672dadbbc Author: Your Name Date: Sun Jun 9 19:04:19 2024 +0200 branch testing commit fb9c7f57b261d059ade3a42c3d030ffe5c515ae3 Author: Your Name Date: Sun Jun 9 18:49:46 2024 +0200 branch test commit 2e7af0d4f5f911272d764ef6dcdf3d902bfc07af Author: Your Name Date: Sun Jun 9 18:26:00 2024 +0200 more testing commit 61090a9c65dbdba7d5787eac942e51b7029c6eed Author: Your Name Date: Sun Jun 9 15:40:12 2024 +0200 change data-id commit b6438d0623f8f5cb1f3260c6e69c88b7afae2d58 Author: Your Name Date: Sun Jun 9 15:38:14 2024 +0200 lint commit 57cfec65167b9911a61e439522776559d6648dbb Author: Your Name Date: Sun Jun 9 15:29:15 2024 +0200 expand test commit 33e90077d3faa8adf1772ecdd3629238bb6a6875 Author: Your Name Date: Sun Jun 9 14:37:56 2024 +0200 add file test commit 97802c9a63a223002f8bc0daaa4287c70bb1aedc Author: Your Name Date: Sun Jun 9 14:14:03 2024 +0200 add test commit 087dd2c26247b33a88f313e0116d0d654ed16cfa Author: Your Name Date: Sun Jun 9 13:37:35 2024 +0200 fix proxy commit c0497fbd4d221201788c982dfacf2e52fb714676 Author: Your Name Date: Sun Jun 9 13:32:04 2024 +0200 fix submodule commit 5781a0cae4b381a1519c0d51b5fc0e15d45e73a2 Author: Your Name Date: Sun Jun 9 13:04:02 2024 +0200 basic test setup commit 9da8d51f935874ce0595080c375a293f722ee05e Author: Your Name Date: Sun Jun 9 07:01:19 2024 +0200 git http backend commit 543beec2bf55d20b6a2f8ffa8532817f57d1f5bd Author: Your Name Date: Sun Jun 9 06:55:53 2024 +0200 bugs commit db7ac5d068eb8261ee3eb7cc9668ddac6738b54c Author: filip mertens Date: Thu Jun 6 19:59:32 2024 +0200 lint commit 3675958113dbb7ee731966a76164029957760010 Author: filip mertens Date: Thu Jun 6 19:52:51 2024 +0200 scope warning commit 31bca3eb20bfaecbe0add62b5291f84a6eae8bb9 Author: filip mertens Date: Thu Jun 6 19:44:14 2024 +0200 rm comments commit ab840aac4917008b42610a3a935a0bb096317ff4 Author: filip mertens Date: Thu Jun 6 19:38:41 2024 +0200 comment commit 0e621ce35d3b56d61b6207e91f37294f1ce795f8 Author: filip mertens Date: Thu Jun 6 19:37:23 2024 +0200 fix commit 8b7d51d3b075db778466e67c79bbddd1cb4d1a25 Author: filip mertens Date: Thu Jun 6 19:33:01 2024 +0200 lsisteners commit 3809386edb935105727cf2bf0fc856a05544fad8 Author: filip mertens Date: Thu Jun 6 19:27:33 2024 +0200 rm comment commit b76f022248b55347c4c426a891c358f19bd0eccb Author: filip mertens Date: Thu Jun 6 19:26:15 2024 +0200 rm lint script commit f9877e2c074e0d6da68c2566e3ce3b371d0952c8 Merge: 8d5cda9d7 b1648a705 Author: filip mertens Date: Thu Jun 6 19:25:25 2024 +0200 Merge branch 'master' of https://github.com/ethereum/remix-project into git4refactor2 commit 8d5cda9d7e0f29b21533903ac24d1fecf7864fec Author: filip mertens Date: Thu Jun 6 19:23:45 2024 +0200 lint commit deea4edbd2de38b7ba3f52fe716f76c0eafa1e47 Author: filip mertens Date: Thu Jun 6 17:00:36 2024 +0200 scope test commit b5dcbc6ba3990dd0ead823651209339bd9894b58 Author: filip mertens Date: Thu Jun 6 16:39:15 2024 +0200 openPanel commit 62782ebe7173c54cf369e8590d0715926db459c9 Author: filip mertens Date: Thu Jun 6 15:53:35 2024 +0200 save creds commit 8695d259bfe4123c66ce87ecff75acbd66c493b9 Author: filip mertens Date: Thu Jun 6 15:15:12 2024 +0200 fixes commit fea8d9c5f6efa6aab57889c0d3af25efd7ce10f5 Author: filip mertens Date: Wed Jun 5 12:45:23 2024 +0200 vyper commit 2e06f8534c6b98dbdc3e62d7dbdc0a4e266b6920 Author: filip mertens Date: Wed Jun 5 12:43:15 2024 +0200 vyper commit a01e309e6a41bd0816877e5b0333196afcab2fd7 Author: filip mertens Date: Wed Jun 5 12:42:25 2024 +0200 vyper commit 8c1a134a56425c2d4b4be9aa38d42753edea0b19 Author: filip mertens Date: Wed Jun 5 12:16:58 2024 +0200 lint commit b277fab6e49993d13b1711abe911ff5a6f0564f2 Author: filip mertens Date: Wed Jun 5 12:11:26 2024 +0200 console commit 38d518d551f4da1ec0eb063076dc0b2e42f06fe8 Author: filip mertens Date: Wed Jun 5 12:08:12 2024 +0200 fix user load commit 2c9ecd01c02967230e206e3733111d75f69e3f84 Author: filip mertens Date: Wed Jun 5 12:02:46 2024 +0200 vyper commit f874259cebb14a5de2112ea3104d0df6f0641355 Author: filip mertens Date: Wed Jun 5 11:36:41 2024 +0200 fix local plugin commit 4ad97eed80a3d31da61521761c8a6296ba763452 Author: filip mertens Date: Wed Jun 5 10:44:43 2024 +0200 fix plugin test commit 1a35705510c032801a1569f398213364ca243182 Author: filip mertens Date: Wed Jun 5 09:28:20 2024 +0200 zoom test commit 2324e82c6b19ecb3f19015f94e97ded373687896 Author: filip mertens Date: Wed Jun 5 09:24:51 2024 +0200 lint commit 9c850f7bbee162fb3420770048250ee463b9fc71 Author: filip mertens Date: Wed Jun 5 09:24:18 2024 +0200 clean up commit d95bfe1797ba294214888a659d5e67ac48d6113e Author: filip mertens Date: Wed Jun 5 08:55:56 2024 +0200 fix checkout commit 82f70f8a842ddc5b2a66f49f426df2da37f5b2a4 Author: filip mertens Date: Wed Jun 5 08:20:51 2024 +0200 lint commit 86ebcd0c1ee06e9249c316be8b0e9ef29a1b1244 Author: filip mertens Date: Wed Jun 5 08:12:17 2024 +0200 rm ratelimit commit 597a5599921dbcc244fa685fae7ebc7c98ccfb22 Author: filip mertens Date: Wed Jun 5 07:11:02 2024 +0200 vyper fix commit 30100b39ef946aee25532d5aec78bd529f786220 Author: filip mertens Date: Wed Jun 5 06:49:50 2024 +0200 lint commit 2dd6e7dec6be2bda380d1a78b2e37deb6733a1a9 Author: filip mertens Date: Wed Jun 5 06:49:08 2024 +0200 zoom test commit 10b2a27ce512a9c6ba285d72f837bef17c277430 Author: filip mertens Date: Wed Jun 5 06:36:07 2024 +0200 hometab commit c1435c41cd3b3fc25a2e740d5d0c71652c278b80 Author: filip mertens Date: Wed Jun 5 06:27:20 2024 +0200 fix editor mounted commit e8b6a2fe92276070eb82a490c948584b38f4978c Author: filip mertens Date: Wed Jun 5 05:22:45 2024 +0200 lint commit 3866568488e1961ab838fe8837e3edeca22170d6 Author: filip mertens Date: Wed Jun 5 05:21:52 2024 +0200 editor test commit b93dea93250caba249cfc020f7a707030e0f05e2 Merge: 601a9f1a0 a895218f2 Author: filip mertens Date: Wed Jun 5 05:15:57 2024 +0200 Merge branch 'master' of https://github.com/ethereum/remix-project into git4refactor2 commit 601a9f1a0847875f461dce4e8c61e9f8e10f8c38 Author: filip mertens Date: Tue Jun 4 14:02:07 2024 +0200 fix editor commit c790b92a0c5f5afd73f7b4e4f342e0c4baaaa261 Author: filip mertens Date: Tue Jun 4 11:33:39 2024 +0200 fix bugs commit 067be4a40c47a2166ea8459b33044176f0b4ddd3 Author: filip mertens Date: Tue Jun 4 11:17:49 2024 +0200 fix editors commit a403c9f9811cdb1461063ea3602d379ed1024afa Author: filip mertens Date: Tue Jun 4 10:46:06 2024 +0200 ifx bug commit dff89e191d56ca8e668ceba34b174855ec7bdef0 Merge: dda0afa9a 91aaf32ab Author: filip mertens Date: Tue Jun 4 08:18:56 2024 +0200 Merge branch 'git4refactor2' of https://github.com/ethereum/remix-project into git4refactor2 commit 91aaf32ab8cc1035d5d865bde51b4f4e63d05a20 Author: filip mertens Date: Mon Jun 3 09:29:23 2024 +0200 lint commit 5964cfd619a3d069595ea8a25efb4d5d117b16cc Author: filip mertens Date: Mon Jun 3 09:15:32 2024 +0200 fix lint commit 652b3b3ef709634e6664a45c8ef535d604bdf934 Author: filip mertens Date: Mon Jun 3 09:14:16 2024 +0200 delay activation commit 200ab4d557dfa0ed5cb63173aa246edc1607e4c9 Merge: 9459e23d0 d03f078a8 Author: filip mertens Date: Mon Jun 3 08:49:46 2024 +0200 Merge branch 'master' of https://github.com/ethereum/remix-project into git4refactor2 commit 9459e23d0e8820d2112c4eb2fdf151b0b1187cce Author: filip mertens Date: Mon Jun 3 08:48:04 2024 +0200 add init method commit a61d3304a11df2cfed89366746dd5fb8d197667a Author: filip mertens Date: Sun Jun 2 11:08:09 2024 +0200 event duplication commit 75642c450df5ecf3b678b1d82a1382b374f7866d Author: filip mertens Date: Thu May 30 14:33:05 2024 +0200 change url commit 320f4420bdc9d2dad16401098710de0ee320cd7e Author: filip mertens Date: Wed May 22 08:24:00 2024 +0200 add action types commit 9b0389616e3bd561e605ac884009dffdc5d1ceb4 Author: filip mertens Date: Mon May 13 08:15:51 2024 +0200 fix app bug commit 1d332e412cf2d37f7f3877d7bc693dc50cb8f0a1 Author: filip mertens Date: Mon May 13 08:09:22 2024 +0200 start setup commit 40b0b9355851bf8deff5a3c4b2dc8b967bbc083b Author: filip mertens Date: Mon May 13 07:45:49 2024 +0200 add api commit aec183366f0933aab2784f44d5612a9a4998f3d8 Author: filip mertens Date: Mon May 13 06:57:25 2024 +0200 move api commit 1b25d568276a9311a35ed1528accf6060123a4a0 Author: bunsenstraat Date: Mon May 13 06:29:47 2024 +0200 cleanup commit e7bf5d32a811fdff7b7416bc053c485a15eb7fd1 Author: bunsenstraat Date: Fri May 10 13:52:59 2024 +0200 fix bug commit 4341ce70947c2651a0803a0e85909b8c121187bf Author: bunsenstraat Date: Fri May 10 13:23:10 2024 +0200 fix bug commit cbc2da066c5b69176a6eb484d5cd582999374fee Author: bunsenstraat Date: Fri May 10 13:07:34 2024 +0200 prefix bug commit c0357ae03e196d6898a65adc3bb4c21438d6b650 Author: bunsenstraat Date: Mon May 6 14:16:20 2024 +0200 refactoring commit 12c587ff573e80999e48e2d2a05382538dba7251 Author: filip mertens Date: Sat May 4 07:34:18 2024 +0200 remote refactor commit 0a6c9527267ef1247189feffba710e78ed8a0a6e Author: filip mertens Date: Sat May 4 06:22:51 2024 +0200 faglobe commit 74a872f0aca6cb4025cc2a6850dc521397a308ef Author: filip mertens Date: Fri May 3 08:47:50 2024 +0200 fetching after push commit 819202ba09d8faba87808b5cacbbe1008a73d813 Author: filip mertens Date: Fri May 3 07:51:10 2024 +0200 refresh commit 53eee900705e85e0e6bbe00e1030625859a2bbd7 Author: filip mertens Date: Fri May 3 07:25:03 2024 +0200 fixes commit 353b5670adba5eb3357f819a5ed27832098d7fdf Author: filip mertens Date: Thu May 2 21:54:03 2024 +0200 listeners commit 36ec094dd4ea416916f8030f5971654613b0906c Author: filip mertens Date: Thu May 2 15:19:33 2024 +0200 openremote commit 9ade399399fd9bbfd1f446383f7eda4e7671857b Author: filip mertens Date: Thu May 2 13:21:05 2024 +0200 ahead of commit 0933d6689679c04c5509496bb84aee4bd8b0327f Author: filip mertens Date: Thu May 2 08:34:54 2024 +0200 git buttons commit 86865ccccb9c81feeb2608cefdf43190d1dfa415 Author: filip mertens Date: Thu May 2 07:58:31 2024 +0200 git json commit 6cddc4a2100d255b550d16db6eb067d3b883d986 Merge: c03bb3553 aecd0e6e4 Author: filip mertens Date: Wed May 1 06:23:52 2024 +0200 Merge branch 'master' of https://github.com/ethereum/remix-project into git4 commit c03bb355339099e4b937674dc26901ed4a431efc Author: filip mertens Date: Wed May 1 06:15:42 2024 +0200 remix-lib lint commit c3db5384c9026321c2af912e6246cebc4b9e86fc Author: filip mertens Date: Wed May 1 06:15:21 2024 +0200 lint remix-ui commit 32d9abf08914f28ac7690375e21ab8fa4c45332a Author: filip mertens Date: Wed May 1 06:08:14 2024 +0200 lint ide commit 7da0d585f33a781be708f3d025abd1ca509d5f5e Merge: 29cb47159 cc49cc54c Author: filip mertens Date: Wed May 1 06:06:56 2024 +0200 Merge branch 'git4' of https://github.com/ethereum/remix-project into git4 commit 29cb47159001e0fe2d59f482c6301944fd379f55 Author: filip mertens Date: Wed May 1 06:06:47 2024 +0200 sc base commit cc49cc54cf49fbfabcab31af095e039d17e3eb8e Author: bunsenstraat Date: Tue Apr 30 21:36:22 2024 +0200 lmit script commit 6a16d5423a63a6e43e28eafc935ebe194ad5442e Author: bunsenstraat Date: Tue Apr 30 21:35:37 2024 +0200 lint config commit 1e840f49add1cbb2d37c78831f2eab13547c32a5 Author: filip mertens Date: Tue Apr 30 08:16:53 2024 +0200 fix sourcecontrol buttons commit c46e18139414dfd75cebcf96152d2915c7195d7f Author: filip mertens Date: Tue Apr 30 07:17:58 2024 +0200 bugfix commit e1c1d94336bd800e329280cce1620b2224f69fe7 Author: filip mertens Date: Mon Apr 29 11:19:16 2024 +0200 change upstream object commit 5b3df39c374249a1743ebecb35db6045807b6cdf Author: filip mertens Date: Mon Apr 29 09:48:08 2024 +0200 rm lint target commit 27e2c1d93dfc257e313746406ae3937474b5bf1a Author: filip mertens Date: Mon Apr 29 09:44:06 2024 +0200 diff commit f8a72e6043953adfb24ecda95c4364bd1ab2da58 Merge: d1544424b 8be0ff8b4 Author: filip mertens Date: Sun Apr 28 07:46:41 2024 +0200 Merge branch 'master' of https://github.com/ethereum/remix-project into git4 commit d1544424b4a989751b7d2fb72964333715b4dc32 Author: filip mertens Date: Sun Apr 28 07:46:32 2024 +0200 FM diff commit d843e5c03607ebeaff4d76eb20ff36a084a65978 Author: filip mertens Date: Sat Apr 27 13:10:36 2024 +0200 remote branches commit aa7d58bad10805337afd2ef6bf35e905a7b601a9 Author: filip mertens Date: Wed Apr 24 08:03:22 2024 +0200 add logger commit e1fc893076789603840e594613ac71abf13043af Author: filip mertens Date: Tue Apr 23 16:33:41 2024 +0200 add logger commit 86c877989a4f88e12dbba7684f503f76ce277e91 Author: filip mertens Date: Tue Apr 23 12:00:04 2024 +0200 rm gql commit aee09192507dcdac864cf2b995c706881dd2a09d Author: filip mertens Date: Tue Apr 23 11:50:33 2024 +0200 paged fetching data commit c4dce2d804441f3d18f1a5d9c4f9cfff14115970 Author: filip mertens Date: Mon Apr 22 13:26:09 2024 +0200 add device flow commit 777f635f7575201c6a518141a3bf47a33f54a242 Author: filip mertens Date: Mon Apr 22 11:56:19 2024 +0200 add device code commit be0be4c078ddc888df48f16531fa933565037eac Author: filip mertens Date: Mon Apr 22 09:06:13 2024 +0200 add gui button commit 9024f6e5581a32cf5c0cb8c47e2cde728b3d7765 Author: filip mertens Date: Mon Apr 22 06:46:46 2024 +0200 loaders commit 02e1d29084afdd36a188f7630fcbb896930c73dd Author: filip mertens Date: Fri Apr 19 16:27:50 2024 +0200 BranchDifferences commit b3252a04a6cdb67b9c500c15e298ef6e98fb6885 Author: filip mertens Date: Fri Apr 19 11:34:09 2024 +0200 setdefaultremote commit ede22d886a220cbe8dcb1f74088d2cdf640f1aa1 Author: filip mertens Date: Fri Apr 19 10:48:29 2024 +0200 branch diffs commit 59ac71f571b01eb7cc39f538d0b64b04d7e1c469 Author: filip mertens Date: Thu Apr 18 13:53:59 2024 +0200 rename branchcommits commit 5c0a0a610fdf97188bd82094e028c0c651f78a1d Merge: d791ff029 220ab69ac Author: filip mertens Date: Thu Apr 18 07:46:52 2024 +0200 Merge branch 'master' of https://github.com/ethereum/remix-project into git4 commit d791ff0296967e189d07b0d6f9f3c0ba4245c2a5 Author: filip mertens Date: Sun Apr 7 09:22:30 2024 +0200 ignore commit 891f10aab843ebb4cae24e3ee0b3fac2bca152d0 Author: filip mertens Date: Thu Apr 4 11:17:18 2024 +0200 git provider commit f298ba1e50d1b38a3d720f359fa3c399ab6998ac Merge: 8a304c09d d1e5f8727 Author: filip mertens Date: Thu Apr 4 11:08:36 2024 +0200 Merge branch 'master' of https://github.com/ethereum/remix-project into git4 commit 8a304c09d2cbece7d4949ba8bcbf2455396de8a6 Author: filip mertens Date: Wed Apr 3 16:56:22 2024 +0200 pagecommits commit 88c13ff961a4872db6c4b9dae4ed60f373ccd7e2 Merge: 019ed19fc 7bd23c128 Author: filip mertens Date: Sat Mar 30 09:37:17 2024 +0100 Merge branch 'master' of https://github.com/ethereum/remix-project into git4 commit 019ed19fc968e54abe4a02be1494890dea3c9e6b Merge: affc3e6ce 92c5ca942 Author: filip mertens Date: Fri Mar 29 07:59:00 2024 +0100 Merge branch 'master' of https://github.com/ethereum/remix-project into git4 commit affc3e6ce886d3e6d9ff36b9fdb07b35c39a70e0 Author: filip mertens Date: Thu Feb 29 14:34:21 2024 +0100 use octo commit f4380cece5e0b803acbbd6713cb8a4a43d943235 Author: filip mertens Date: Wed Feb 28 07:48:56 2024 +0100 types for gql commit 66ef29f129351597952d194997fd105b9cf23652 Author: bunsenstraat Date: Mon Feb 26 09:09:48 2024 +0100 restore ts commit 4ff34b68fde4d11841658cf5e5b69d285553882a Merge: 4fa723899 65ef75f96 Author: bunsenstraat Date: Mon Feb 26 09:00:10 2024 +0100 Merge branch 'master' of https://github.com/ethereum/remix-project into git4 commit 4fa7238999ca1ae3a879e1afbc7753d853e78071 Author: filip mertens Date: Mon Feb 26 08:53:08 2024 +0100 codegen commit 0a5d2e2c8423288fd4a12ad3ac69ce21db43553a Author: filip mertens Date: Mon Feb 26 08:23:18 2024 +0100 add gql commit 6beeda8c6f52ba4a2637db3de63b91bb4de8fa6c Author: filip mertens Date: Sat Feb 24 09:50:07 2024 +0100 remote commits commit 82caba939fccb6ae768c34153fdd18d2532e5db9 Author: filip mertens Date: Fri Feb 23 10:40:59 2024 +0100 refactor commit 88cef7b6bf56d28248df5957a3a3f5285caae498 Author: filip mertens Date: Fri Feb 23 08:19:23 2024 +0100 context commit 63c15f03d61686e1e56316476fd27ae19b27cf8f Author: filip mertens Date: Thu Feb 15 09:00:53 2024 +0100 translations commit 933ae65fb8d55fa11e9f9b53111960b6bc69f448 Author: filip mertens Date: Mon Feb 12 13:34:11 2024 +0100 font awesome commit 51b2d20cb84f13bb8357e8c71a28fdc450d3f32d Author: filip mertens Date: Fri Feb 9 09:57:40 2024 +0100 add react select commit 236b3095f4167ac3123770718f81f2fc24cf3335 Author: filip mertens Date: Fri Feb 9 09:27:43 2024 +0100 octokit dgitprovider commit eded03fbcf15a92293cdd23d4b290dd1c1b70793 Author: filip mertens Date: Fri Feb 9 08:46:13 2024 +0100 add git to tsconfig paths commit a769356ee15c645f5cda1d901b755fb01cb1357d Author: filip mertens Date: Fri Feb 9 08:38:27 2024 +0100 add appman hack commit 097f528d29b8efbf8f9c520e8796facad1f1c4cf Author: filip mertens Date: Fri Feb 9 08:37:19 2024 +0100 add dgit to app.js commit afce79d418c1308dcb5fdfd8b4823d4d837b45e0 Author: filip mertens Date: Fri Feb 9 08:35:27 2024 +0100 add git plugin commit df103f9870870683901dbd2bc57c48fdd8f7f853 Author: filip mertens Date: Fri Feb 9 08:33:06 2024 +0100 add git components --- .gitignore | 4 +- apps/remix-ide-e2e/src/commands/addFile.ts | 15 +- .../src/githttpbackend/package.json | 13 + .../src/githttpbackend/server.ts | 48 + .../remix-ide-e2e/src/githttpbackend/setup.sh | 7 + .../src/githttpbackend/yarn.lock | 511 +++++ .../src/local-plugin/src/app/app.tsx | 8 +- .../src/tests/dgit_github.test.ts | 312 +++ .../src/tests/dgit_local.test.ts | 520 +++++ apps/remix-ide-e2e/src/tests/editor.test.ts | 4 +- apps/remix-ide-e2e/src/tests/gist.test.ts | 2 +- apps/remix-ide-e2e/src/tests/plugin_api.ts | 16 +- apps/remix-ide-e2e/src/tests/remixd.test.ts | 30 +- .../remix-ide-e2e/src/tests/vyper_api.test.ts | 8 +- .../src/tests/workspace_git.test.ts | 219 +- apps/remix-ide-e2e/src/types/index.d.ts | 2 +- apps/remix-ide/src/app.js | 8 +- apps/remix-ide/src/app/editor/editor.js | 35 +- apps/remix-ide/src/app/files/dgitProvider.ts | 635 ++++-- apps/remix-ide/src/app/files/fileManager.ts | 40 +- apps/remix-ide/src/app/panels/layout.ts | 11 + apps/remix-ide/src/app/panels/tab-proxy.js | 17 + apps/remix-ide/src/app/plugins/git.tsx | 40 + .../src/app/tabs/locales/en/filePanel.json | 2 +- .../src/app/tabs/locales/en/git.json | 20 + apps/remix-ide/src/app/udapp/run-tab.js | 1 - apps/remix-ide/src/remixAppManager.js | 4 +- apps/remix-ide/src/remixEngine.js | 2 +- apps/remixdesktop/src/plugins/isoGitPlugin.ts | 14 +- apps/remixdesktop/src/types/index.ts | 9 + apps/vyper/src/app/utils/remix-client.tsx | 24 +- apps/vyper/src/main.tsx | 4 +- libs/remix-api/src/index.ts | 1 + libs/remix-api/src/lib/plugins/config-api.ts | 11 + .../src/lib/plugins/fileSystem-api.ts | 10 + .../src/lib/plugins/filedecorator-api.ts | 11 + .../src/lib/plugins/notification-api.ts | 31 + .../remix-api/src/lib/plugins/settings-api.ts | 11 + libs/remix-api/src/lib/remix-api.ts | 19 + .../remix-ui/editor/src/lib/actions/editor.ts | 82 +- .../editor/src/lib/remix-ui-editor.tsx | 50 +- .../git/src/components/branchHeader.tsx | 70 + .../src/components/buttons/commitmessage.tsx | 147 ++ .../src/components/buttons/gituibutton.tsx | 24 + .../components/buttons/sourceControlBase.tsx | 90 + .../buttons/sourcecontrolbuttons.tsx | 98 + libs/remix-ui/git/src/components/disabled.tsx | 12 + .../src/components/github/branchselect.tsx | 50 + .../git/src/components/github/devicecode.tsx | 131 ++ .../components/github/repositoryselect.tsx | 87 + .../github/selectandclonerepositories.tsx | 59 + libs/remix-ui/git/src/components/gitui.tsx | 245 +++ .../components/navigation/branchedetails.tsx | 97 + .../src/components/navigation/branches.tsx | 32 + .../git/src/components/navigation/clone.tsx | 29 + .../src/components/navigation/commands.tsx | 35 + .../components/navigation/commitdetails.tsx | 37 + .../git/src/components/navigation/commits.tsx | 63 + .../git/src/components/navigation/github.tsx | 29 + .../components/navigation/loaderindicator.tsx | 20 + .../git/src/components/navigation/log.tsx | 87 + .../navigation/menu/sourcecontrolmenu.tsx | 49 + .../git/src/components/navigation/remotes.tsx | 32 + .../components/navigation/remotesdetails.tsx | 68 + .../src/components/navigation/settings.tsx | 41 + .../components/navigation/sourcecontrol.tsx | 42 + .../navigation/sourcecontrolgroup.tsx | 52 + .../git/src/components/panels/branches.tsx | 60 + .../branches/branchdifferencedetails.tsx | 48 + .../panels/branches/branchdifferences.tsx | 39 + .../panels/branches/localbranchdetails.tsx | 86 + .../panels/branches/remotebranchedetails.tsx | 111 + .../git/src/components/panels/clone.tsx | 102 + .../git/src/components/panels/commands.tsx | 14 + .../src/components/panels/commands/fetch.tsx | 25 + .../src/components/panels/commands/merge.tsx | 57 + .../components/panels/commands/pushpull.tsx | 196 ++ .../git/src/components/panels/commits.tsx | 64 + .../panels/commits/commitdetails.tsx | 60 + .../panels/commits/commitdetailsitem.tsx | 51 + .../panels/commits/commitsummary.tsx | 70 + .../components/panels/githubcredentials.tsx | 90 + .../git/src/components/panels/init.tsx | 29 + .../git/src/components/panels/log.tsx | 39 + .../git/src/components/panels/remotes.tsx | 53 + .../src/components/panels/remoteselect.tsx | 37 + .../src/components/panels/remotesimport.tsx | 82 + .../git/src/components/panels/settings.tsx | 48 + .../git/src/components/panels/setup.tsx | 36 + .../sourcecontrol/sourcecontrolgroup.tsx | 38 + .../sourcecontrol/sourcecontrolitem.tsx | 65 + .../sourcecontrol/sourcontrolitembuttons.tsx | 76 + .../git/src/components/panels/sourcontrol.tsx | 49 + .../src/components/panels/tokenWarning.tsx | 12 + .../git/src/hooks/useLocalStorage.tsx | 37 + libs/remix-ui/git/src/index.ts | 4 + libs/remix-ui/git/src/lib/fileHelpers.ts | 56 + libs/remix-ui/git/src/lib/gitactions.ts | 852 ++++++++ libs/remix-ui/git/src/lib/listeners.ts | 201 ++ libs/remix-ui/git/src/lib/pluginActions.ts | 100 + libs/remix-ui/git/src/state/actions.ts | 52 + libs/remix-ui/git/src/state/context.tsx | 59 + libs/remix-ui/git/src/state/gitpayload.ts | 220 ++ libs/remix-ui/git/src/state/gitreducer.tsx | 208 ++ libs/remix-ui/git/src/state/loaderReducer.ts | 11 + libs/remix-ui/git/src/style/index.css | 36 + libs/remix-ui/git/src/types/index.ts | 436 ++++ libs/remix-ui/git/src/types/styles.ts | 53 + libs/remix-ui/git/src/utils/index.ts | 3 + .../src/lib/components/homeTabGetStarted.tsx | 11 +- .../workspace/src/lib/actions/payload.ts | 3 +- .../workspace/src/lib/actions/workspace.ts | 98 +- .../workspace/src/lib/contexts/index.ts | 7 +- .../src/lib/providers/FileSystemProvider.tsx | 7 +- .../workspace/src/lib/reducers/workspace.ts | 8 +- .../workspace/src/lib/remix-ui-workspace.tsx | 18 +- .../remix-ui/workspace/src/lib/types/index.ts | 21 +- package.json | 13 +- tsconfig.paths.json | 7 +- yarn.lock | 1854 ++++++++++++++++- 120 files changed, 10054 insertions(+), 495 deletions(-) create mode 100644 apps/remix-ide-e2e/src/githttpbackend/package.json create mode 100644 apps/remix-ide-e2e/src/githttpbackend/server.ts create mode 100755 apps/remix-ide-e2e/src/githttpbackend/setup.sh create mode 100644 apps/remix-ide-e2e/src/githttpbackend/yarn.lock create mode 100644 apps/remix-ide-e2e/src/tests/dgit_github.test.ts create mode 100644 apps/remix-ide-e2e/src/tests/dgit_local.test.ts create mode 100644 apps/remix-ide/src/app/plugins/git.tsx create mode 100644 apps/remix-ide/src/app/tabs/locales/en/git.json create mode 100644 apps/remixdesktop/src/types/index.ts create mode 100644 libs/remix-api/src/index.ts create mode 100644 libs/remix-api/src/lib/plugins/config-api.ts create mode 100644 libs/remix-api/src/lib/plugins/fileSystem-api.ts create mode 100644 libs/remix-api/src/lib/plugins/filedecorator-api.ts create mode 100644 libs/remix-api/src/lib/plugins/notification-api.ts create mode 100644 libs/remix-api/src/lib/plugins/settings-api.ts create mode 100644 libs/remix-api/src/lib/remix-api.ts create mode 100644 libs/remix-ui/git/src/components/branchHeader.tsx create mode 100644 libs/remix-ui/git/src/components/buttons/commitmessage.tsx create mode 100644 libs/remix-ui/git/src/components/buttons/gituibutton.tsx create mode 100644 libs/remix-ui/git/src/components/buttons/sourceControlBase.tsx create mode 100644 libs/remix-ui/git/src/components/buttons/sourcecontrolbuttons.tsx create mode 100644 libs/remix-ui/git/src/components/disabled.tsx create mode 100644 libs/remix-ui/git/src/components/github/branchselect.tsx create mode 100644 libs/remix-ui/git/src/components/github/devicecode.tsx create mode 100644 libs/remix-ui/git/src/components/github/repositoryselect.tsx create mode 100644 libs/remix-ui/git/src/components/github/selectandclonerepositories.tsx create mode 100644 libs/remix-ui/git/src/components/gitui.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/branchedetails.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/branches.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/clone.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/commands.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/commitdetails.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/commits.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/github.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/loaderindicator.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/log.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/menu/sourcecontrolmenu.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/remotes.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/remotesdetails.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/settings.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/sourcecontrol.tsx create mode 100644 libs/remix-ui/git/src/components/navigation/sourcecontrolgroup.tsx create mode 100644 libs/remix-ui/git/src/components/panels/branches.tsx create mode 100644 libs/remix-ui/git/src/components/panels/branches/branchdifferencedetails.tsx create mode 100644 libs/remix-ui/git/src/components/panels/branches/branchdifferences.tsx create mode 100644 libs/remix-ui/git/src/components/panels/branches/localbranchdetails.tsx create mode 100644 libs/remix-ui/git/src/components/panels/branches/remotebranchedetails.tsx create mode 100644 libs/remix-ui/git/src/components/panels/clone.tsx create mode 100644 libs/remix-ui/git/src/components/panels/commands.tsx create mode 100644 libs/remix-ui/git/src/components/panels/commands/fetch.tsx create mode 100644 libs/remix-ui/git/src/components/panels/commands/merge.tsx create mode 100644 libs/remix-ui/git/src/components/panels/commands/pushpull.tsx create mode 100644 libs/remix-ui/git/src/components/panels/commits.tsx create mode 100644 libs/remix-ui/git/src/components/panels/commits/commitdetails.tsx create mode 100644 libs/remix-ui/git/src/components/panels/commits/commitdetailsitem.tsx create mode 100644 libs/remix-ui/git/src/components/panels/commits/commitsummary.tsx create mode 100644 libs/remix-ui/git/src/components/panels/githubcredentials.tsx create mode 100644 libs/remix-ui/git/src/components/panels/init.tsx create mode 100644 libs/remix-ui/git/src/components/panels/log.tsx create mode 100644 libs/remix-ui/git/src/components/panels/remotes.tsx create mode 100644 libs/remix-ui/git/src/components/panels/remoteselect.tsx create mode 100644 libs/remix-ui/git/src/components/panels/remotesimport.tsx create mode 100644 libs/remix-ui/git/src/components/panels/settings.tsx create mode 100644 libs/remix-ui/git/src/components/panels/setup.tsx create mode 100644 libs/remix-ui/git/src/components/panels/sourcecontrol/sourcecontrolgroup.tsx create mode 100644 libs/remix-ui/git/src/components/panels/sourcecontrol/sourcecontrolitem.tsx create mode 100644 libs/remix-ui/git/src/components/panels/sourcecontrol/sourcontrolitembuttons.tsx create mode 100644 libs/remix-ui/git/src/components/panels/sourcontrol.tsx create mode 100644 libs/remix-ui/git/src/components/panels/tokenWarning.tsx create mode 100644 libs/remix-ui/git/src/hooks/useLocalStorage.tsx create mode 100644 libs/remix-ui/git/src/index.ts create mode 100644 libs/remix-ui/git/src/lib/fileHelpers.ts create mode 100644 libs/remix-ui/git/src/lib/gitactions.ts create mode 100644 libs/remix-ui/git/src/lib/listeners.ts create mode 100644 libs/remix-ui/git/src/lib/pluginActions.ts create mode 100644 libs/remix-ui/git/src/state/actions.ts create mode 100644 libs/remix-ui/git/src/state/context.tsx create mode 100644 libs/remix-ui/git/src/state/gitpayload.ts create mode 100644 libs/remix-ui/git/src/state/gitreducer.tsx create mode 100644 libs/remix-ui/git/src/state/loaderReducer.ts create mode 100644 libs/remix-ui/git/src/style/index.css create mode 100644 libs/remix-ui/git/src/types/index.ts create mode 100644 libs/remix-ui/git/src/types/styles.ts create mode 100644 libs/remix-ui/git/src/utils/index.ts diff --git a/.gitignore b/.gitignore index a9157706ae..ef8b36916c 100644 --- a/.gitignore +++ b/.gitignore @@ -64,4 +64,6 @@ apps/remixdesktop/release/ apps/remix-ide/src/assets/list.json apps/remix-ide/src/assets/esbuild.wasm apps/remixdesktop/build* -logs \ No newline at end of file +apps/remixdesktop/reports/ +apps/remixdesktop/logs/ +logs diff --git a/apps/remix-ide-e2e/src/commands/addFile.ts b/apps/remix-ide-e2e/src/commands/addFile.ts index a3296e8848..f2040f749f 100644 --- a/apps/remix-ide-e2e/src/commands/addFile.ts +++ b/apps/remix-ide-e2e/src/commands/addFile.ts @@ -2,9 +2,11 @@ import { NightwatchBrowser, NightwatchContractContent } from 'nightwatch' import EventEmitter from 'events' class AddFile extends EventEmitter { - command(this: NightwatchBrowser, name: string, content: NightwatchContractContent): NightwatchBrowser { + command(this: NightwatchBrowser, name: string, content: NightwatchContractContent, readMeFile?:string): NightwatchBrowser { + if(!readMeFile) + readMeFile = 'README.txt' this.api.perform((done) => { - addFile(this.api, name, content, () => { + addFile(this.api, name, content, readMeFile, () => { done() this.emit('complete') }) @@ -13,7 +15,8 @@ class AddFile extends EventEmitter { } } -function addFile(browser: NightwatchBrowser, name: string, content: NightwatchContractContent, done: VoidFunction) { +function addFile(browser: NightwatchBrowser, name: string, content: NightwatchContractContent, readMeFile:string, done: VoidFunction) { + const readmeSelector = `li[data-id="treeViewLitreeViewItem${readMeFile}"]` browser .isVisible({ selector: "//*[@data-id='sidePanelSwapitTitle' and contains(.,'File explorer')]", @@ -25,9 +28,9 @@ function addFile(browser: NightwatchBrowser, name: string, content: NightwatchCo browser.clickLaunchIcon('filePanel') } }) - .scrollInto('li[data-id="treeViewLitreeViewItemREADME.txt"]') - .waitForElementVisible('li[data-id="treeViewLitreeViewItemREADME.txt"]') - .click('li[data-id="treeViewLitreeViewItemREADME.txt"]').pause(1000) // focus on root directory + .scrollInto(readmeSelector) + .waitForElementVisible(readmeSelector) + .click(readmeSelector).pause(1000) // focus on root directory .isVisible({ selector: `//*[@data-id="treeViewLitreeViewItem${name}"]`, locateStrategy: 'xpath', diff --git a/apps/remix-ide-e2e/src/githttpbackend/package.json b/apps/remix-ide-e2e/src/githttpbackend/package.json new file mode 100644 index 0000000000..3e44990386 --- /dev/null +++ b/apps/remix-ide-e2e/src/githttpbackend/package.json @@ -0,0 +1,13 @@ +{ + "scripts": { + "start:server": "npx ts-node server.ts" + }, + "dependencies": { + "body-parser": "^1.20.2", + "child_process": "^1.0.2", + "express": "^4.19.2", + "git-http-backend": "^1.1.2", + "path": "^0.12.7", + "zlib": "^1.0.5" + } +} diff --git a/apps/remix-ide-e2e/src/githttpbackend/server.ts b/apps/remix-ide-e2e/src/githttpbackend/server.ts new file mode 100644 index 0000000000..5f2654670a --- /dev/null +++ b/apps/remix-ide-e2e/src/githttpbackend/server.ts @@ -0,0 +1,48 @@ +import * as http from 'http'; +import { spawn } from 'child_process'; +import * as path from 'path'; +let backend = require('git-http-backend'); +import * as zlib from 'zlib'; + +const directory = process.argv[2]; + +if (!directory) { + console.error('Please provide a directory as a command line argument.'); + process.exit(1); +} + +const server = http.createServer((req, res) => { + + // Set CORS headers + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); + res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); + res.setHeader('Access-Control-Allow-Credentials', 'true'); + + if (req.method === 'OPTIONS') { + // Handle preflight request + res.writeHead(204); + res.end(); + return; + } + + const repo = req.url?.split('/')[1]; + const dir = path.join(directory, 'git', repo || ''); + console.log(dir); + const reqStream = req.headers['content-encoding'] === 'gzip' ? req.pipe(zlib.createGunzip()) : req; + + reqStream.pipe(backend(req.url || '', (err, service) => { + if (err) return res.end(err + '\n'); + + res.setHeader('content-type', service.type); + console.log(service.action, repo, service.fields); + + const ps = spawn(service.cmd, [...service.args, dir]); + ps.stdout.pipe(service.createStream()).pipe(ps.stdin); + + })).pipe(res); +}); + +server.listen(6868, () => { + console.log('Server is listening on port 6868'); +}); diff --git a/apps/remix-ide-e2e/src/githttpbackend/setup.sh b/apps/remix-ide-e2e/src/githttpbackend/setup.sh new file mode 100755 index 0000000000..5d2644ddb1 --- /dev/null +++ b/apps/remix-ide-e2e/src/githttpbackend/setup.sh @@ -0,0 +1,7 @@ + +cd /tmp/ +rm -rf git/bare.git +rm -rf git +mkdir -p git +cd git +git clone --bare https://github.com/ethereum/awesome-remix bare.git diff --git a/apps/remix-ide-e2e/src/githttpbackend/yarn.lock b/apps/remix-ide-e2e/src/githttpbackend/yarn.lock new file mode 100644 index 0000000000..8548a19555 --- /dev/null +++ b/apps/remix-ide-e2e/src/githttpbackend/yarn.lock @@ -0,0 +1,511 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +body-parser@1.20.2, body-parser@^1.20.2: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +child_process@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/child_process/-/child_process-1.0.2.tgz#b1f7e7fc73d25e7fd1d455adc94e143830182b5a" + integrity sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +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" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +express@^4.19.2: + version "4.19.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.6.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +git-http-backend@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/git-http-backend/-/git-http-backend-1.1.2.tgz#fb6c7b261251df8c2bdf9dc30876a96ce323f545" + integrity sha512-Gx7n/kyCEXGFZlCGmbsEsyeyabLs8XWeb+E/6842up7p3PktQS2/8rlNfB6hCagnW0pJ13Tn8E3yhOkKS6ihdg== + dependencies: + git-side-band-message "~0.0.3" + inherits "~2.0.1" + +git-side-band-message@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/git-side-band-message/-/git-side-band-message-0.0.3.tgz#b8a5348c2dcbf1949fd295c506014e26c3f26a46" + integrity sha512-4Rq4xm1+zqCkmuHxRbGdA5ActF7F4UfgK8uI0B7ZfSkByZfikRuF7mqHlvqmycvqos7jpXNkgsZK7DThLLHG3w== + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +hasown@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +inherits@2.0.4, inherits@~2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +object-inspect@^1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path@^0.12.7: + version "0.12.7" + resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" + integrity sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q== + dependencies: + process "^0.11.1" + util "^0.10.3" + +process@^0.11.1: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +safe-buffer@5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +side-channel@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +zlib@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/zlib/-/zlib-1.0.5.tgz#6e7c972fc371c645a6afb03ab14769def114fcc0" + integrity sha512-40fpE2II+Cd3k8HWTWONfeKE2jL+P42iWJ1zzps5W51qcTsOUKM5Q5m2PFb0CLxlmFAaUuUdJGc3OfZy947v0w== diff --git a/apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx b/apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx index 2b1479dda1..840b8d377b 100644 --- a/apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx +++ b/apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx @@ -3,7 +3,6 @@ import {RemixPlugin} from './Client' import {Logger} from './logger' import {filePanelProfile} from '@remixproject/plugin-api' import {filSystemProfile} from '@remixproject/plugin-api' -import {dGitProfile} from '@remixproject/plugin-api' import {editorProfile} from '@remixproject/plugin-api' import {settingsProfile} from '@remixproject/plugin-api' import {networkProfile} from '@remixproject/plugin-api' @@ -12,8 +11,13 @@ import {compilerProfile} from '@remixproject/plugin-api' import {contentImportProfile} from '@remixproject/plugin-api' import {windowProfile} from '@remixproject/plugin-api' import {pluginManagerProfile} from '@remixproject/plugin-api' -import {Profile} from '@remixproject/plugin-utils' +import {LibraryProfile, Profile} from '@remixproject/plugin-utils' + +export const dGitProfile: LibraryProfile = { + name: 'dgitApi', + methods: ['status', 'log', 'commit', 'add', 'branches'], +} import './app.css' const client = new RemixPlugin() diff --git a/apps/remix-ide-e2e/src/tests/dgit_github.test.ts b/apps/remix-ide-e2e/src/tests/dgit_github.test.ts new file mode 100644 index 0000000000..6c8f8cfa08 --- /dev/null +++ b/apps/remix-ide-e2e/src/tests/dgit_github.test.ts @@ -0,0 +1,312 @@ +import { ChildProcess, spawn } from "child_process" +import init from "../helpers/init" +import { Nightwatch, NightwatchBrowser } from "nightwatch" + + +module.exports = { + '@disabled': true, + before: function (browser, done) { + init(browser, done) + }, + after: function (browser: NightwatchBrowser) { + browser.perform((done) => { + done() + }) + }, + 'Update settings for git #group1 #group2': function (browser: NightwatchBrowser) { + browser. + clickLaunchIcon('dgit') + .waitForElementVisible('*[data-id="initgit-btn"]') + .click('*[data-id="initgit-btn"]') + .setValue('*[data-id="githubToken"]', process.env.dgit_token) + .setValue('*[data-id="gitubUsername"]', 'git') + .setValue('*[data-id="githubEmail"]', 'git@example.com') + .click('*[data-id="saveGitHubCredentials"]') + }, + 'check if the settings are loaded #group1 #group2': function (browser: NightwatchBrowser) { + browser. + click('*[data-id="github-panel"]') + .waitForElementVisible('*[data-id="connected-as-bunsenstraat"]') + .waitForElementVisible('*[data-id="connected-img-bunsenstraat"]') + .waitForElementVisible('*[data-id="connected-link-bunsenstraat"]') + }, + 'clone a repository #group1': function (browser: NightwatchBrowser) { + browser + .click('*[data-id="clone-panel"]') + .click({ + selector: '//*[@data-id="clone-panel-content"]//*[@data-id="fetch-repositories"]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="clone-panel-content"]//*[@id="repository-select"]', + locateStrategy: 'xpath' + }) + .click({ + selector: '//*[@data-id="clone-panel-content"]//*[@id="repository-select"]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="clone-panel-content"]//*[contains(text(), "awesome-remix")]', + locateStrategy: 'xpath' + }) + .click({ + selector: '//*[@data-id="clone-panel-content"]//*[contains(text(), "awesome-remix")]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="clone-panel-content"]//*[@id="branch-select"]', + locateStrategy: 'xpath' + }) + .click({ + selector: '//*[@data-id="clone-panel-content"]//*[@id="branch-select"]', + locateStrategy: 'xpath' + }) + .click({ + selector: '//*[@data-id="clone-panel-content"]//*[contains(text(), "master")]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="clone-panel-content"]//*[@data-id="clonebtn-ethereum/awesome-remix-master"]', + locateStrategy: 'xpath' + }) + .click({ + selector: '//*[@data-id="clone-panel-content"]//*[@data-id="clonebtn-ethereum/awesome-remix-master"]', + locateStrategy: 'xpath' + }) + }, + 'check if there is a README.md file #group1': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('filePanel') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemREADME.md"]') + }, + 'check the commands panel #group1': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('dgit') + .click('*[data-id="commands-panel"]') + .waitForElementVisible({ + selector: "//div[@id='commands-remote-branch-select']//div[contains(@class, 'singleValue') and contains(text(), 'master')]", + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: "//div[@id='commands-remote-origin-select']//div[contains(@class, 'singleValue') and contains(text(), 'origin')]", + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: "//div[@id='commands-local-branch-select']//div[contains(@class, 'singleValue') and contains(text(), 'master')]", + locateStrategy: 'xpath' + }) + }, + 'check the remotes #group1': function (browser: NightwatchBrowser) { + browser + + .click('*[data-id="remotes-panel"]') + .waitForElementVisible('*[data-id="remotes-panel-content"]') + .click({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="remote-detail-origin"]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="branches-current-branch-master"]', + locateStrategy: 'xpath' + }) + .click({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="remote-sync-origin"]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="branches-branch-links"]', + locateStrategy: 'xpath' + }) + + }, + 'check the commits of branch links #group1': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="branches-branch-links"]', + locateStrategy: 'xpath' + }) + .click({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="branches-branch-links"]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="commit-summary-linking fixed-"]', + locateStrategy: 'xpath' + }) + }, + 'switch to branch links #group1': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="branches-branch-links"]', + locateStrategy: 'xpath' + }) + .click({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="branches-toggle-branch-links"]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="branches-toggle-current-branch-links"]', + locateStrategy: 'xpath' + }) + }, + 'check the local branches #group1': function (browser: NightwatchBrowser) { + browser + .click('*[data-id="branches-panel"]') + .waitForElementVisible({ + selector: '//*[@data-id="branches-panel-content"]//*[@data-id="branches-toggle-current-branch-links"]', + locateStrategy: 'xpath' + }) + }, + 'check the local commits #group1': function (browser: NightwatchBrowser) { + browser + .click('*[data-id="commits-panel"]') + .pause(1000) + .waitForElementVisible({ + selector: '//*[@data-id="commits-current-branch-links"]//*[@data-id="commit-summary-linking fixed-"]', + locateStrategy: 'xpath' + }) + .click({ + selector: '//*[@data-id="commits-current-branch-links"]//*[@data-id="commit-summary-linking fixed-"]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="commits-current-branch-links"]//*[@data-id="commit-change-modified-README.md"]', + locateStrategy: 'xpath' + }) + }, + 'check the commands panel for links #group1': function (browser: NightwatchBrowser) { + browser + .click('*[data-id="commands-panel"]') + .waitForElementVisible({ + selector: "//div[@id='commands-remote-branch-select']//div[contains(@class, 'singleValue') and contains(text(), 'links')]", + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: "//div[@id='commands-remote-origin-select']//div[contains(@class, 'singleValue') and contains(text(), 'origin')]", + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: "//div[@id='commands-local-branch-select']//div[contains(@class, 'singleValue') and contains(text(), 'links')]", + locateStrategy: 'xpath' + }) + }, + + 'add a remote #group2': function (browser: NightwatchBrowser) { + browser + .pause(1000) + .click('*[data-id="remotes-panel"]') + .click({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="fetch-repositories"]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="remotes-panel-content"]//*[@id="repository-select"]', + locateStrategy: 'xpath' + }) + .click({ + selector: '//*[@data-id="remotes-panel-content"]//*[@id="repository-select"]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="remotes-panel-content"]//*[contains(text(), "awesome-remix")]', + locateStrategy: 'xpath' + }) + .click({ + selector: '//*[@data-id="remotes-panel-content"]//*[contains(text(), "awesome-remix")]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="remote-panel-remotename"]', + locateStrategy: 'xpath' + }) + .setValue({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="remote-panel-remotename"]', + locateStrategy: 'xpath' + }, 'newremote') + .waitForElementVisible({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="remote-panel-addremote"]', + locateStrategy: 'xpath' + }) + .click({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="remote-panel-addremote"]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="remote-detail-newremote"]', + locateStrategy: 'xpath' + }) + }, + 'check the commands panel for newremote #group2': function (browser: NightwatchBrowser) { + browser + .pause(1000) + .click('*[data-id="commands-panel"]') + .waitForElementVisible({ + selector: "//div[@id='commands-remote-branch-select']//div[contains(@class, 'singleValue') and contains(text(), 'main')]", + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: "//div[@id='commands-remote-origin-select']//div[contains(@class, 'singleValue') and contains(text(), 'newremote')]", + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: "//div[@id='commands-local-branch-select']//div[contains(@class, 'singleValue') and contains(text(), 'main')]", + locateStrategy: 'xpath' + }) + .getAttribute({ + selector: '//*[@data-id="sourcecontrol-pull"]', + locateStrategy: 'xpath' + }, 'disabled', (result) => { + if (result.value) { + browser.assert.fail('Button is disabled') + } else { + browser.assert.ok(true) + } + }) + }, + 'remove the remove #group2': function (browser: NightwatchBrowser) { + browser + .pause(1000) + .click('*[data-id="remotes-panel"]') + .waitForElementVisible({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="remote-rm-newremote"]', + locateStrategy: 'xpath' + }) + .pause(2000) + .click({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="remote-rm-newremote"]', + locateStrategy: 'xpath' + }) + .pause(1000) + .waitForElementNotPresent({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="remote-detail-newremote"]', + locateStrategy: 'xpath' + }) + }, + 'check the commands panel for removed remote #group2': function (browser: NightwatchBrowser) { + browser + .pause(1000) + .click('*[data-id="commands-panel"]') + .waitForElementVisible({ + selector: "//div[@id='commands-remote-branch-select']//div[contains(@class, 'singleValue') and contains(text(), 'main')]", + locateStrategy: 'xpath' + }) + .waitForElementNotPresent({ + selector: "//div[@id='commands-remote-origin-select']//div[contains(@class, 'singleValue') and contains(text(), 'newremote')]", + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: "//div[@id='commands-local-branch-select']//div[contains(@class, 'singleValue') and contains(text(), 'main')]", + locateStrategy: 'xpath' + }) + .getAttribute({ + selector: '//*[@data-id="sourcecontrol-pull"]', + locateStrategy: 'xpath' + }, 'disabled', (result) => { + if (result.value) { + browser.assert.ok(true) + } else { + browser.assert.fail('Button is not disabled') + } + }) + }, +} diff --git a/apps/remix-ide-e2e/src/tests/dgit_local.test.ts b/apps/remix-ide-e2e/src/tests/dgit_local.test.ts new file mode 100644 index 0000000000..fb0c87ed08 --- /dev/null +++ b/apps/remix-ide-e2e/src/tests/dgit_local.test.ts @@ -0,0 +1,520 @@ +import { ChildProcess, spawn } from "child_process" +import kill from 'tree-kill' +import init from "../helpers/init" +import { Nightwatch, NightwatchBrowser } from "nightwatch" +let gitserver: ChildProcess + +/* +/ uses the git-http-backend package to create a git server ( if needed kill the server: kill -9 $(sudo lsof -t -i:6868) ) +/ GROUP 1: file operations PUSH PULL COMMIT SYNC FETCH CLONE ADD +/ GROUP 2: branch operations CREATE & PUBLISH +/ GROUP 3: file operations rename delete +*/ + +module.exports = { + '@disabled': true, + before: function (browser, done) { + init(browser, done) + }, + after: function (browser: NightwatchBrowser) { + browser.perform((done) => { + console.log('kill server', gitserver.pid) + kill(gitserver.pid) + done() + }) + }, + + 'run server #group1 #group2 #group3': function (browser: NightwatchBrowser) { + browser.perform(async (done) => { + gitserver = await spawnGitServer('/tmp/') + console.log('working directory', process.cwd()) + done() + }) + }, + 'Update settings for git #group1 #group2 #group3': function (browser: NightwatchBrowser) { + browser. + clickLaunchIcon('dgit') + .waitForElementVisible('*[data-id="initgit-btn"]') + .click('*[data-id="initgit-btn"]') + .setValue('*[data-id="gitubUsername"]', 'git') + .setValue('*[data-id="githubEmail"]', 'git@example.com') + .click('*[data-id="saveGitHubCredentials"]') + .modalFooterOKClick('github-credentials-error') + .pause(2000) + }, + 'clone a repo #group1 #group2 #group3': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="clone-panel"]') + .click('*[data-id="clone-panel"]') + .waitForElementVisible('*[data-id="clone-url"]') + .setValue('*[data-id="clone-url"]', 'http://localhost:6868/bare.git') + .waitForElementVisible('*[data-id="clone-btn"]') + .click('*[data-id="clone-btn"]') + .clickLaunchIcon('filePanel') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemREADME.md"]') + }, + + // GROUP 1 + + 'check file added #group1 #group3': function (browser: NightwatchBrowser) { + browser. + addFile('test.txt', { content: 'hello world' }, 'README.md') + .clickLaunchIcon('dgit') + .click('*[data-id="sourcecontrol-panel"]') + .waitForElementVisible({ + selector: "//*[@data-status='new-untracked' and @data-file='/test.txt']", + locateStrategy: 'xpath' + }) + .waitForElementVisible('*[data-id="addToGitChangestest.txt"]') + .pause(1000) + .click('*[data-id="addToGitChangestest.txt"]') + .waitForElementVisible({ + selector: "//*[@data-status='added-staged' and @data-file='/test.txt']", + locateStrategy: 'xpath' + }) + .setValue('*[data-id="commitMessage"]', 'testcommit') + .click('*[data-id="commitButton"]') + }, + 'look at the commit #group1': function (browser: NightwatchBrowser) { + browser + .click('*[data-id="commits-panel"]') + .waitForElementPresent({ + selector: '//*[@data-id="commit-summary-testcommit-ahead"]', + locateStrategy: 'xpath' + }) + }, + 'sync the commit #group1': function (browser: NightwatchBrowser) { + browser + .pause(1000) + .waitForElementVisible('*[data-id="sourcecontrol-panel"]') + .click('*[data-id="sourcecontrol-panel"]') + .waitForElementVisible('*[data-id="syncButton"]') + .click('*[data-id="syncButton"]') + .pause(2000) + .waitForElementVisible('*[data-id="commitButton"]') + .click('*[data-id="commits-panel"]') + .waitForElementPresent({ + selector: '//*[@data-id="commit-summary-testcommit-"]', + locateStrategy: 'xpath' + }) + }, + 'check the log #group1': async function (browser: NightwatchBrowser) { + const logs = await getGitLog('/tmp/git/bare.git') + console.log(logs) + browser.assert.ok(logs.includes('testcommit')) + }, + 'change a file #group1': function (browser: NightwatchBrowser) { + browser. + openFile('test.txt'). + pause(1000). + setEditorValue('changes', null) + }, + 'stage changed file #group1': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('dgit') + .click('*[data-id="sourcecontrol-panel"]') + .waitForElementVisible({ + selector: "//*[@data-status='modified-unstaged' and @data-file='/test.txt']", + locateStrategy: 'xpath' + }) + .waitForElementVisible('*[data-id="addToGitChangestest.txt"]') + .click('*[data-id="addToGitChangestest.txt"]') + .waitForElementVisible({ + selector: "//*[@data-status='modified-staged' and @data-file='/test.txt']", + locateStrategy: 'xpath' + }) + .setValue('*[data-id="commitMessage"]', 'testcommit2') + .click('*[data-id="commitButton"]') + }, + 'push the commit #group1': function (browser: NightwatchBrowser) { + browser + .click('*[data-id="commands-panel"]') + .waitForElementVisible('*[data-id="sourcecontrol-push"]') + .click('*[data-id="sourcecontrol-push"]') + .pause(2000) + .click('*[data-id="commits-panel"]') + .waitForElementPresent({ + selector: '//*[@data-id="commit-summary-testcommit2-"]', + locateStrategy: 'xpath' + }).pause(2000) + }, + 'check the log for testcommit2 #group1': async function (browser: NightwatchBrowser) { + const logs = await getGitLog('/tmp/git/bare.git') + console.log(logs) + browser.assert.ok(logs.includes('testcommit2')) + }, + 'clone locally and add a file and push #group1': async function (browser: NightwatchBrowser) { + await cloneOnServer('http://localhost:6868/bare.git', '/tmp/') + await onLocalGitRepoAddFile('/tmp/bare/', 'test2.txt') + await createCommitOnLocalServer('/tmp/bare/', 'testlocal') + await onLocalGitRepoPush('/tmp/bare/', 'master') + }, + 'run a git fetch #group1': function (browser: NightwatchBrowser) { + browser + .pause(2000) + .click('*[data-id="commands-panel"]') + .waitForElementVisible('*[data-id="sourcecontrol-fetch-branch"]') + .click('*[data-id="sourcecontrol-fetch-branch"]') + .pause(2000) + .click('*[data-id="commits-panel"]') + .click('*[data-id="commits-panel-behind"]') + .waitForElementPresent({ + selector: '//*[@data-id="commit-summary-testlocal-"]', + locateStrategy: 'xpath' + }) + }, + 'run pull from the header #group1': function (browser: NightwatchBrowser) { + browser. + click('*[data-id="sourcecontrol-button-pull"]') + .waitForElementNotPresent('*[data-id="commits-panel-behind"]') + }, + 'check if the file is added #group1': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('filePanel') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemtest2.txt"]') + }, + + // group 3 + 'rename a file #group3': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('filePanel') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemtest.txt"]') + .click('*[data-id="treeViewLitreeViewItemtest.txt"]') + .renamePath('test.txt', 'test_rename', 'test_rename.txt') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemtest_rename.txt"]') + .pause(1000) + }, + 'stage renamed file #group3': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('dgit') + .waitForElementVisible({ + selector: "//*[@data-status='deleted-unstaged' and @data-file='/test.txt']", + locateStrategy: 'xpath' + }) + .waitForElementVisible('*[data-id="addToGitChangestest.txt"]') + .waitForElementVisible({ + selector: "//*[@data-status='new-untracked' and @data-file='/test_rename.txt']", + locateStrategy: 'xpath' + }) + .click('*[data-id="sourcecontrol-add-all"]') + .pause(2000) + .waitForElementVisible({ + selector: "//*[@data-status='deleted-staged' and @data-file='/test.txt']", + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: "//*[@data-status='added-staged' and @data-file='/test_rename.txt']", + locateStrategy: 'xpath' + }) + }, + 'undo the rename #group3': function (browser: NightwatchBrowser) { + browser + + .click('*[data-id="unDoStagedtest.txt"]') + .pause(1000) + .waitForElementNotPresent({ + selector: "//*[@data-file='/test.txt']", + locateStrategy: 'xpath' + }) + }, + 'check if file is returned #group3': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('filePanel') + .waitForElementVisible('*[data-id="treeViewLitreeViewItemtest.txt"]') + }, + + + // GROUP 2 + 'create a branch #group2': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('dgit') + .click('*[data-id="branches-panel"]') + .waitForElementVisible('*[data-id="newbranchname"]') + .setValue('*[data-id="newbranchname"]', 'testbranch') + .click('*[data-id="sourcecontrol-create-branch"]') + .waitForElementVisible('*[data-id="branches-current-branch-testbranch"]') + .pause(1000) + }, + 'check if the branch is in the filePanel #group2': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('filePanel') + .click('[data-id="workspaceGitBranchesDropdown"]') + .expect.element('[data-id="workspaceGit-testbranch"]').text.to.contain('✓ ') + }, + 'publish the branch #group2': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('dgit') + .waitForElementVisible('*[data-id="sourcecontrol-panel"]') + .click('*[data-id="sourcecontrol-panel"]') + .pause(1000) + .click('*[data-id="publishBranchButton"]') + .pause(2000) + .waitForElementNotVisible('*[data-id="publishBranchButton"]') + }, + 'check if the branch is published #group2': async function (browser: NightwatchBrowser) { + const branches = await getBranches('/tmp/git/bare.git') + browser.assert.ok(branches.includes('testbranch')) + }, + 'add file to new branch #group2': function (browser: NightwatchBrowser) { + browser + .pause(1000) + .addFile('test.txt', { content: 'hello world' }, 'README.md') + .clickLaunchIcon('dgit') + .waitForElementVisible({ + selector: "//*[@data-status='new-untracked' and @data-file='/test.txt']", + locateStrategy: 'xpath' + }) + .waitForElementVisible('*[data-id="addToGitChangestest.txt"]') + .pause(1000) + .click('*[data-id="addToGitChangestest.txt"]') + .waitForElementVisible({ + selector: "//*[@data-status='added-staged' and @data-file='/test.txt']", + locateStrategy: 'xpath' + }) + .setValue('*[data-id="commitMessage"]', 'testcommit') + .click('*[data-id="commitButton"]') + .pause(1000) + }, + 'check if the commit is ahead in the branches list #group2': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible('*[data-id="branches-panel"]') + .click('*[data-id="branches-panel"]') + .waitForElementVisible('*[data-id="branches-current-branch-testbranch"]') + .click({ + selector: "//*[@data-id='branches-panel-content']//*[@data-id='branches-current-branch-testbranch']", + locateStrategy: 'xpath', + suppressNotFoundErrors: true + }) + .click({ + selector: "//*[@data-id='branches-panel-content']//*[@data-id='commits-panel-ahead']", + locateStrategy: 'xpath', + suppressNotFoundErrors: true + }) + .click({ + selector: "//*[@data-id='branches-panel-content']//*[@data-id='branchdifference-commits-testbranch-ahead']//*[@data-id='commit-summary-testcommit-ahead']", + locateStrategy: 'xpath', + }) + .click({ + selector: "//*[@data-id='branches-panel-content']//*[@data-id='branchdifference-commits-testbranch-ahead']//*[@data-id='commit-change-added-test.txt']", + locateStrategy: 'xpath', + }) + .click({ + selector: "//*[@data-id='branches-panel-content']//*[@data-id='local-branch-commits-testbranch']//*[@data-id='commit-summary-testcommit-ahead']", + locateStrategy: 'xpath', + }) + .waitForElementVisible({ + selector: "//*[@data-id='branches-panel-content']//*[@data-id='local-branch-commits-testbranch']//*[@data-id='commit-change-added-test.txt']", + locateStrategy: 'xpath', + }) + }, + 'switch back to master #group2': function (browser: NightwatchBrowser) { + browser + .click({ + selector: "//*[@data-id='branches-panel-content']//*[@data-id='branches-toggle-branch-master']", + locateStrategy: 'xpath', + }) + .waitForElementVisible({ + selector: "//*[@data-id='branches-panel-content']//*[@data-id='branches-toggle-current-branch-master']", + locateStrategy: 'xpath', + }) + }, + 'check if test file is gone #group2': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('filePanel') + .waitForElementNotPresent('*[data-id="treeViewLitreeViewItemtest.txt"]') + } +} + +async function getBranches(path: string): Promise { + return new Promise((resolve, reject) => { + const git = spawn('git', ['branch'], { cwd: path }) + let branches = '' + git.stdout.on('data', function (data) { + console.log('stdout git branches', data.toString()) + branches += data.toString() + }) + git.stderr.on('data', function (data) { + console.log('stderr git branches', data.toString()) + reject(data.toString()) + }) + git.on('close', function () { + resolve(branches) + }) + }) +} + +async function getGitLog(path: string): Promise { + return new Promise((resolve, reject) => { + const git = spawn('git', ['log'], { cwd: path }) + let logs = '' + git.stdout.on('data', function (data) { + logs += data.toString() + }) + git.stderr.on('err', function (data) { + reject(data.toString()) + }) + git.on('close', function () { + resolve(logs) + }) + }) +} + +async function cloneOnServer(repo: string, path: string) { + console.log('cloning', repo, path) + return new Promise((resolve, reject) => { + const git = spawn('rm -rf bare && git', ['clone', repo], { cwd: path, shell: true, detached: true }); + + git.stdout.on('data', function (data) { + console.log('stdout data cloning', data.toString()); + if (data.toString().includes('done')) { + resolve(git); + } + }); + + git.stderr.on('data', function (data) { + console.log('stderr data cloning', data.toString()); + if (data.toString().includes('into')) { + setTimeout(() => { + resolve(git); + }, 5000) + } + }); + + git.on('error', (error) => { + reject(`Process error: ${error.message}`); + }); + + git.on('exit', (code, signal) => { + if (code !== 0) { + reject(`Process exited with code: ${code} and signal: ${signal}`); + } + }); + }); +} + +async function onLocalGitRepoAddFile(path: string, file: string) { + console.log('adding file', file) + return new Promise((resolve, reject) => { + const git = spawn('touch', [file], { cwd: path }); + + git.stdout.on('data', function (data) { + console.log('stdout data adding file', data.toString()); + if (data.toString().includes('done')) { + resolve(git); + } + }); + + git.stderr.on('data', function (data) { + console.error('stderr adding file', data.toString()); + reject(data.toString()); + }); + + git.on('error', (error) => { + reject(`Process error: ${error.message}`); + }); + + git.on('exit', (code, signal) => { + if (code !== 0) { + reject(`Process exited with code: ${code} and signal: ${signal}`); + } else { + resolve(git); + } + }); + }); +} + +async function onLocalGitRepoPush(path: string, branch: string = 'master') { + console.log('pushing', path) + return new Promise((resolve, reject) => { + const git = spawn('git', ['push', 'origin', branch], { cwd: path, shell: true, detached: true }); + + git.stdout.on('data', function (data) { + console.log('stdout data pushing', data.toString()); + if (data.toString().includes('done')) { + resolve(git); + } + }); + + git.stderr.on('data', function (data) { + console.error('stderr data pushing', data.toString()); + if (data.toString().includes(branch)) { + resolve(git); + } + }); + + git.on('error', (error) => { + reject(`Process error: ${error.message}`); + }); + + git.on('exit', (code, signal) => { + if (code !== 0) { + reject(`Process exited with code: ${code} and signal: ${signal}`); + } else { + resolve(git); + } + }); + }); +} + + +async function createCommitOnLocalServer(path: string, message: string) { + console.log('committing', message, path) + return new Promise((resolve, reject) => { + const git = spawn('git add . && git', ['commit', '-m', message], { cwd: path, shell: true, detached: true }); + + git.stdout.on('data', function (data) { + console.log('data stdout committing', data.toString()); + if (data.toString().includes(message)) { + setTimeout(() => { + resolve(git); + }, 1000) + } + }); + + git.stderr.on('data', function (data) { + console.error('data commiting', data.toString()); + reject(data.toString()); + }); + + git.on('error', (error) => { + console.error('error', error); + reject(`Process error: ${error.message}`); + }); + + git.on('exit', (code, signal) => { + if (code !== 0) { + console.error('exit', code, signal); + reject(`Process exited with code: ${code} and signal: ${signal}`); + } else { + resolve(git); + } + }); + }); +} + + +async function spawnGitServer(path: string): Promise { + console.log(process.cwd()) + try { + const server = spawn('yarn && sh setup.sh && npx ts-node server.ts', [`${path}`], { cwd: process.cwd() + '/apps/remix-ide-e2e/src/githttpbackend/', shell: true, detached: true }) + console.log('spawned', server.stdout.closed, server.stderr.closed) + return new Promise((resolve, reject) => { + server.stdout.on('data', function (data) { + console.log(data.toString()) + if ( + data.toString().includes('is listening') + || data.toString().includes('address already in use') + ) { + console.log('resolving') + resolve(server) + } + }) + server.stderr.on('err', function (data) { + console.log(data.toString()) + reject(data.toString()) + }) + }) + } catch (e) { + console.log(e) + } +} \ No newline at end of file diff --git a/apps/remix-ide-e2e/src/tests/editor.test.ts b/apps/remix-ide-e2e/src/tests/editor.test.ts index f78a229498..00d3292fef 100644 --- a/apps/remix-ide-e2e/src/tests/editor.test.ts +++ b/apps/remix-ide-e2e/src/tests/editor.test.ts @@ -20,13 +20,13 @@ module.exports = { .checkElementStyle('.view-lines', 'font-size', '14px') .click('*[data-id="tabProxyZoomIn"]') .click('*[data-id="tabProxyZoomIn"]') - .checkElementStyle('.view-lines', 'font-size', '16.8px') + .checkElementStyle('.view-lines', 'font-size', '19.6px') }, 'Should zoom out editor #group1': function (browser: NightwatchBrowser) { browser .waitForElementVisible('#editorView') - .checkElementStyle('.view-lines', 'font-size', '16.8px') + .checkElementStyle('.view-lines', 'font-size', '19.6px') .click('*[data-id="tabProxyZoomOut"]') .click('*[data-id="tabProxyZoomOut"]') .checkElementStyle('.view-lines', 'font-size', '14px') diff --git a/apps/remix-ide-e2e/src/tests/gist.test.ts b/apps/remix-ide-e2e/src/tests/gist.test.ts index 5b025e95f0..4f4d34c8a4 100644 --- a/apps/remix-ide-e2e/src/tests/gist.test.ts +++ b/apps/remix-ide-e2e/src/tests/gist.test.ts @@ -39,7 +39,7 @@ module.exports = { // .perform((done) => { if (runtimeBrowser === 'chrome') { browser.openFile('gists') } done() }) .waitForElementVisible(`[data-id="treeViewLitreeViewItemREADME.txt"]`) - .openFile(`README.txt`) + //.openFile(`README.txt`) // Remix publish to gist /* .click('*[data-id="fileExplorerNewFilepublishToGist"]') .pause(2000) diff --git a/apps/remix-ide-e2e/src/tests/plugin_api.ts b/apps/remix-ide-e2e/src/tests/plugin_api.ts index 69bbc140ca..b42f082b3e 100644 --- a/apps/remix-ide-e2e/src/tests/plugin_api.ts +++ b/apps/remix-ide-e2e/src/tests/plugin_api.ts @@ -10,7 +10,7 @@ declare global { const localPluginData: Profile & LocationProfile & ExternalProfile = { name: 'localPlugin', displayName: 'Local Plugin', - canActivate: ['dGitProvider', 'flattener', 'solidityUnitTesting', 'udapp', 'hardhat-provider'], + canActivate: ['dgitApi', 'flattener', 'solidityUnitTesting', 'udapp', 'hardhat-provider'], url: 'http://localhost:9999', location: 'sidePanel' } @@ -319,24 +319,24 @@ module.exports = { // DGIT 'Should have changes on new workspace #group3': async function (browser: NightwatchBrowser) { await clickAndCheckLog(browser, 'filePanel:createWorkspace', null, null, 'dgit') - await clickAndCheckLog(browser, 'dGitProvider:status', [[".prettierrc.json",0,2,0], ["README.txt",0,2,0],["contracts/1_Storage.sol",0,2,0],["contracts/2_Owner.sol",0,2,0],["contracts/3_Ballot.sol",0,2,0],["scripts/deploy_with_ethers.ts",0,2,0],["scripts/deploy_with_web3.ts",0,2,0],["scripts/ethers-lib.ts",0,2,0],["scripts/web3-lib.ts",0,2,0],["tests/Ballot_test.sol",0,2,0],["tests/storage.test.js",0,2,0]], null, null) + await clickAndCheckLog(browser, 'dgitApi:status', [[".prettierrc.json",0,2,0], ["README.txt",0,2,0],["contracts/1_Storage.sol",0,2,0],["contracts/2_Owner.sol",0,2,0],["contracts/3_Ballot.sol",0,2,0],["scripts/deploy_with_ethers.ts",0,2,0],["scripts/deploy_with_web3.ts",0,2,0],["scripts/ethers-lib.ts",0,2,0],["scripts/web3-lib.ts",0,2,0],["tests/Ballot_test.sol",0,2,0],["tests/storage.test.js",0,2,0]], null, null) }, 'Should stage contract #group3': async function (browser: NightwatchBrowser) { - await clickAndCheckLog(browser, 'dGitProvider:add', null, null, { + await clickAndCheckLog(browser, 'dgitApi:add', null, null, { filepath: 'contracts/1_Storage.sol' }) - await clickAndCheckLog(browser, 'dGitProvider:status', [[".prettierrc.json",0,2,0],["README.txt",0,2,0],["contracts/1_Storage.sol",0,2,2],["contracts/2_Owner.sol",0,2,0],["contracts/3_Ballot.sol",0,2,0],["scripts/deploy_with_ethers.ts",0,2,0],["scripts/deploy_with_web3.ts",0,2,0],["scripts/ethers-lib.ts",0,2,0],["scripts/web3-lib.ts",0,2,0],["tests/Ballot_test.sol",0,2,0],["tests/storage.test.js",0,2,0]], null, null) + await clickAndCheckLog(browser, 'dgitApi:status', [[".prettierrc.json",0,2,0],["README.txt",0,2,0],["contracts/1_Storage.sol",0,2,2],["contracts/2_Owner.sol",0,2,0],["contracts/3_Ballot.sol",0,2,0],["scripts/deploy_with_ethers.ts",0,2,0],["scripts/deploy_with_web3.ts",0,2,0],["scripts/ethers-lib.ts",0,2,0],["scripts/web3-lib.ts",0,2,0],["tests/Ballot_test.sol",0,2,0],["tests/storage.test.js",0,2,0]], null, null) }, 'Should commit changes #group3': async function (browser: NightwatchBrowser) { - await clickAndCheckLog(browser, 'dGitProvider:commit', null, null, { author: { name: 'Remix', email: 'Remix' }, message: 'commit-message' }) - await clickAndCheckLog(browser, 'dGitProvider:log', 'commit-message', null, null) + await clickAndCheckLog(browser, 'dgitApi:commit', null, null, { author: { name: 'Remix', email: 'Remix' }, message: 'commit-message' }) + await clickAndCheckLog(browser, 'dgitApi:log', 'commit-message', null, null) }, 'Should have git log #group3': async function (browser: NightwatchBrowser) { - await clickAndCheckLog(browser, 'dGitProvider:log', 'commit-message', null, null) + await clickAndCheckLog(browser, 'dgitApi:log', 'commit-message', null, null) }, 'Should have branches #group3': async function (browser: NightwatchBrowser) { - await clickAndCheckLog(browser, 'dGitProvider:branches', [{ name: 'main' }], null, null) + await clickAndCheckLog(browser, 'dgitApi:branches', [{ name: 'main' }], null, null) }, // resolver 'Should resolve url #group4': async function (browser: NightwatchBrowser) { diff --git a/apps/remix-ide-e2e/src/tests/remixd.test.ts b/apps/remix-ide-e2e/src/tests/remixd.test.ts index ceebe0d553..880ccb47cb 100644 --- a/apps/remix-ide-e2e/src/tests/remixd.test.ts +++ b/apps/remix-ide-e2e/src/tests/remixd.test.ts @@ -254,6 +254,28 @@ module.exports = { }) + }, + 'Should disable git when running remixd #group9': function (browser: NightwatchBrowser) { + + browser.perform(async (done) => { + remixd = await spawnRemixd(join(process.cwd(), '/apps/remix-ide', '/contracts/hardhat')) + console.log('working directory', process.cwd()) + connectRemixd(browser, done) + }) + browser + .clickLaunchIcon('dgit') + .waitForElementVisible('*[data-id="disabled"]') + .pause(2000) + .clickLaunchIcon('filePanel') + .switchWorkspace('default_workspace') + .click({ + selector:'[data-path="connectionAlert-modal-footer-ok-react"]', + suppressNotFoundErrors: true, + timeout: 2000 + }) + .pause(2000) + .clickLaunchIcon('dgit') + .waitForElementNotPresent('*[data-id="disabled"]') } } @@ -310,11 +332,11 @@ async function spawnRemixd(path: string): Promise { const remixd = spawn('chmod +x dist/libs/remixd/src/bin/remixd.js && dist/libs/remixd/src/bin/remixd.js --remix-ide http://127.0.0.1:8080', [`-s ${path}`], { cwd: process.cwd(), shell: true, detached: true }) return new Promise((resolve, reject) => { remixd.stdout.on('data', function (data) { - if( - data.toString().includes('is listening') + if ( + data.toString().includes('is listening') || data.toString().includes('There is already a client running') - ) { - + ) { + resolve(remixd) } }) diff --git a/apps/remix-ide-e2e/src/tests/vyper_api.test.ts b/apps/remix-ide-e2e/src/tests/vyper_api.test.ts index 356752a56a..1174b58fc6 100644 --- a/apps/remix-ide-e2e/src/tests/vyper_api.test.ts +++ b/apps/remix-ide-e2e/src/tests/vyper_api.test.ts @@ -29,18 +29,14 @@ module.exports = { .waitForElementVisible({ selector: "//*[@data-id='workspacesSelect' and contains(.,'snekmate')]", locateStrategy: 'xpath', - timeout: 60000 + timeout: 120000 }) .currentWorkspaceIs('snekmate') .waitForElementVisible({ selector: "//*[@data-id='treeViewLitreeViewItemsrc' and contains(.,'src')]", locateStrategy: 'xpath', - timeout: 60000 + timeout: 1200000 }) - .openFile('src') - .openFile('src/snekmate') - .openFile('src/snekmate/tokens') - .openFile('src/snekmate/tokens/ERC721.vy') }, // 'Add vyper file to run tests #group1': function (browser: NightwatchBrowser) { // browser.addFile('TestBallot.sol', sources[0]['TestBallot.sol']) diff --git a/apps/remix-ide-e2e/src/tests/workspace_git.test.ts b/apps/remix-ide-e2e/src/tests/workspace_git.test.ts index 16870069e3..6ffc7b6b85 100644 --- a/apps/remix-ide-e2e/src/tests/workspace_git.test.ts +++ b/apps/remix-ide-e2e/src/tests/workspace_git.test.ts @@ -40,6 +40,7 @@ module.exports = { .click('[data-id="settingsTabSaveGistToken"]') }, + 'Should create and initialize a GIT repository #group1': function (browser: NightwatchBrowser) { browser .clickLaunchIcon('filePanel') @@ -59,6 +60,20 @@ module.exports = { .waitForElementVisible('[data-id="workspaceGitPanel"]') .waitForElementContainsText('[data-id="workspaceGitBranchesDropdown"]', 'main') }, + 'check git for the commit #group1': function (browser: NightwatchBrowser) { + browser. + clickLaunchIcon('dgit') + .click('*[data-id="commits-panel"]') + .waitForElementPresent({ + selector: '//*[@data-id="commits-current-branch-main"]//*[@data-id="commit-summary-Initial commit: remix template blank-"]', + locateStrategy: 'xpath' + }) + .click('*[data-id="branches-panel"]') + .waitForElementPresent({ + selector: '//*[@data-id="branches-panel-content"]//*[@data-id="branches-current-branch-main"]', + locateStrategy: 'xpath' + }) + }, // CLONE REPOSITORY E2E START @@ -139,7 +154,7 @@ module.exports = { .click('[data-id="fileSystem-modal-footer-ok-react"]') .pause(5000) .waitForElementVisible('[data-id="cloneGitRepositoryModalDialogModalBody-react"]') - .waitForElementContainsText('[data-id="cloneGitRepositoryModalDialogModalBody-react"]', 'An error occurred: Please check that you have the correct URL for the repo. If the repo is private, you need to add your github credentials (with the valid token permissions) in Settings plugin') + .waitForElementContainsText('[data-id="cloneGitRepositoryModalDialogModalBody-react"]', 'An error occurred: Please check that you have the correct URL for the repo. If the repo is private, you need to add your github credentials (with the valid token permissions) in the Git plugin') .click('[data-id="cloneGitRepository-modal-footer-ok-react"]') }, @@ -311,66 +326,66 @@ module.exports = { }, 'When switching branches the submodules should disappear #group4': function (browser: NightwatchBrowser) { browser - .waitForElementVisible('[data-id="workspaceGitBranchesDropdown"]') - .click('[data-id="workspaceGitBranchesDropdown"]') - .waitForElementVisible('[data-id="custom-dropdown-menu"]') - .waitForElementContainsText('[data-id="custom-dropdown-items"]', 'origin/empty') - .waitForElementPresent('[data-id="workspaceGit-origin/empty"]') - .click('[data-id="workspaceGit-origin/empty"]') - .waitForElementNotPresent('[data-id="treeViewDivtreeViewItemlibdeep"]') - .waitForElementNotPresent('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive"]') - .waitForElementNotPresent('[data-id="treeViewDivtreeViewItemtest-branch-submodule-2"]') + .waitForElementVisible('[data-id="workspaceGitBranchesDropdown"]') + .click('[data-id="workspaceGitBranchesDropdown"]') + .waitForElementVisible('[data-id="custom-dropdown-menu"]') + .waitForElementContainsText('[data-id="custom-dropdown-items"]', 'origin/empty') + .waitForElementPresent('[data-id="workspaceGit-origin/empty"]') + .click('[data-id="workspaceGit-origin/empty"]') + .waitForElementNotPresent('[data-id="treeViewDivtreeViewItemlibdeep"]') + .waitForElementNotPresent('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive"]') + .waitForElementNotPresent('[data-id="treeViewDivtreeViewItemtest-branch-submodule-2"]') }, 'When switching to main update the modules #group4': function (browser: NightwatchBrowser) { browser - .waitForElementVisible('[data-id="workspaceGitBranchesDropdown"]') - .click('[data-id="workspaceGitBranchesDropdown"]') - .waitForElementVisible('[data-id="custom-dropdown-menu"]') - .waitForElementContainsText('[data-id="custom-dropdown-items"]', 'origin/main') - .waitForElementPresent('[data-id="workspaceGit-origin/main"]') - .click('[data-id="workspaceGit-origin/main"]') - .waitForElementVisible('[data-id="updatesubmodules"]') - .click('[data-id="updatesubmodules"]') - .waitForElementPresent('.fa-spinner') - .waitForElementVisible({ - selector: '*[data-id="treeViewLitreeViewItem.git"]', - timeout: 240000 - }) - .pause(2000) - // check recursive submodule - .waitForElementVisible('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive"]') - .click('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive"]') - .click('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive"]') - .waitForElementVisible('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive/test-branch-submodule-2"]') - .click('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive/test-branch-submodule-2"]') - .waitForElementVisible('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive/test-branch-submodule-2/submodule2.ts"]') - // check test-branch-submodule-2 submodule - .waitForElementVisible('[data-id="treeViewDivtreeViewItemtest-branch-submodule-2"]') - .click('[data-id="treeViewDivtreeViewItemtest-branch-submodule-2"]') - .click('[data-id="treeViewDivtreeViewItemtest-branch-submodule-2"]') - .waitForElementVisible('[data-id="treeViewDivtreeViewItemtest-branch-submodule-2/submodule2.ts"]') - // check libdeep submodule - .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep"]') - .click('[data-id="treeViewDivtreeViewItemlibdeep"]') - .click('[data-id="treeViewDivtreeViewItemlibdeep"]') - .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep/test-branch-submodule-2"]') - .click('[data-id="treeViewDivtreeViewItemlibdeep/test-branch-submodule-2"]') - .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep/test-branch-submodule-2/submodule2.ts"]') - // check libdeep2 submodule - .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep2"]') - .click('[data-id="treeViewDivtreeViewItemlibdeep2"]') - .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep2/recursive"]') - .click('[data-id="treeViewDivtreeViewItemlibdeep2/recursive"]') - .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep2/recursive/test-branch-submodule-2"]') - .click('[data-id="treeViewDivtreeViewItemlibdeep2/recursive/test-branch-submodule-2"]') - .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep2/recursive/test-branch-submodule-2/submodule2.ts"]') + .waitForElementVisible('[data-id="workspaceGitBranchesDropdown"]') + .click('[data-id="workspaceGitBranchesDropdown"]') + .waitForElementVisible('[data-id="custom-dropdown-menu"]') + .waitForElementContainsText('[data-id="custom-dropdown-items"]', 'origin/main') + .waitForElementPresent('[data-id="workspaceGit-origin/main"]') + .click('[data-id="workspaceGit-origin/main"]') + .waitForElementVisible('[data-id="updatesubmodules"]') + .click('[data-id="updatesubmodules"]') + .waitForElementPresent('.fa-spinner') + .waitForElementVisible({ + selector: '*[data-id="treeViewLitreeViewItem.git"]', + timeout: 240000 + }) + .pause(2000) + // check recursive submodule + .waitForElementVisible('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive"]') + .click('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive"]') + .click('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive"]') + .waitForElementVisible('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive/test-branch-submodule-2"]') + .click('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive/test-branch-submodule-2"]') + .waitForElementVisible('[data-id="treeViewDivtreeViewItemtest-branch-submodule-recursive/test-branch-submodule-2/submodule2.ts"]') + // check test-branch-submodule-2 submodule + .waitForElementVisible('[data-id="treeViewDivtreeViewItemtest-branch-submodule-2"]') + .click('[data-id="treeViewDivtreeViewItemtest-branch-submodule-2"]') + .click('[data-id="treeViewDivtreeViewItemtest-branch-submodule-2"]') + .waitForElementVisible('[data-id="treeViewDivtreeViewItemtest-branch-submodule-2/submodule2.ts"]') + // check libdeep submodule + .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep"]') + .click('[data-id="treeViewDivtreeViewItemlibdeep"]') + .click('[data-id="treeViewDivtreeViewItemlibdeep"]') + .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep/test-branch-submodule-2"]') + .click('[data-id="treeViewDivtreeViewItemlibdeep/test-branch-submodule-2"]') + .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep/test-branch-submodule-2/submodule2.ts"]') + // check libdeep2 submodule + .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep2"]') + .click('[data-id="treeViewDivtreeViewItemlibdeep2"]') + .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep2/recursive"]') + .click('[data-id="treeViewDivtreeViewItemlibdeep2/recursive"]') + .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep2/recursive/test-branch-submodule-2"]') + .click('[data-id="treeViewDivtreeViewItemlibdeep2/recursive/test-branch-submodule-2"]') + .waitForElementVisible('[data-id="treeViewDivtreeViewItemlibdeep2/recursive/test-branch-submodule-2/submodule2.ts"]') }, - // GIT SUBMODULES E2E ENDS + // GIT SUBMODULES E2E ENDS - // GIT WORKSPACE E2E STARTS + // GIT WORKSPACE E2E STARTS - 'Should create a git workspace (uniswapV4Template) #group4': function (browser: NightwatchBrowser) { + 'Should create a git workspace (uniswapV4Template) #group4': function (browser: NightwatchBrowser) { browser .click('*[data-id="workspacesMenuDropdown"]') .click('*[data-id="workspacecreate"]') @@ -388,8 +403,102 @@ module.exports = { .getEditorValue((content) => { browser.assert.ok(content.indexOf(`contract Counter is BaseHook {`) !== -1, 'Incorrect content') + }).pause() + }, + + 'Should create Remix default workspace with files #group5': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('filePanel') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') + .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') + .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') + // eslint-disable-next-line dot-notation + .click('select[id="wstemplate"]') + .click('select[id="wstemplate"] option[value=ozerc20]') + .execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'new_workspace' }) + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .waitForElementVisible('*[data-id="treeViewDivDraggableItemtests/MyToken_test.sol"]') + }, + 'Update settings for git #group5': function (browser: NightwatchBrowser) { + browser. + clickLaunchIcon('dgit') + .waitForElementVisible('*[data-id="initgit-btn"]') + .click('*[data-id="initgit-btn"]') + .setValue('*[data-id="gitubUsername"]', 'git') + .setValue('*[data-id="githubEmail"]', 'git@example.com') + .click('*[data-id="saveGitHubCredentials"]') + .modalFooterOKClick('github-credentials-error') + }, + 'check source controle panel #group5': function (browser: NightwatchBrowser) { + browser + .waitForElementVisible({ + selector: "//*[@data-status='new-untracked' and @data-file='/tests/MyToken_test.sol']", + locateStrategy: 'xpath' + }) + }, + 'switch workspace and check git #group5': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('filePanel') + .switchWorkspace('default_workspace') + }, + 'check source controle panel again #group5': function (browser: NightwatchBrowser) { + browser + .pause(1000) + .clickLaunchIcon('dgit') + .waitForElementVisible({ + selector: '*[data-id="initgit-btn"]', + suppressNotFoundErrors: true + }) + .click({ + selector:'*[data-id="initgit-btn"]', + suppressNotFoundErrors: true + }) + .pause(2000) + .waitForElementVisible({ + selector: "//*[@data-status='new-untracked' and @data-file='/tests/storage.test.js']", + locateStrategy: 'xpath' + }) + }, + 'Should create a git workspace (uniswapV4Template) #group5': function (browser: NightwatchBrowser) { + browser + .clickLaunchIcon('filePanel') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') + .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') + .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') + .click('select[id="wstemplate"]') + .click('select[id="wstemplate"] option[value=uniswapV4Template]') + .waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') + .execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() }) + .pause(100) + .waitForElementVisible('*[data-id="treeViewLitreeViewItemsrc"]') + .openFile('src') + .openFile('src/Counter.sol') + .pause(1000) + .getEditorValue((content) => { + browser.assert.ok(content.indexOf(`contract Counter is BaseHook {`) !== -1, + 'Incorrect content') + }) + }, + 'check source controle panel for uniswap #group5': function (browser: NightwatchBrowser) { + browser + .pause(5000) + .clickLaunchIcon('dgit') + .click('*[data-id="remotes-panel"]') + .waitForElementVisible('*[data-id="remotes-panel-content"]') + .click({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="remote-detail-origin"]', + locateStrategy: 'xpath' + }) + .waitForElementVisible({ + selector: '//*[@data-id="remotes-panel-content"]//*[@data-id="remote-detail-origin" and contains(.,"v4-template")]', + locateStrategy: 'xpath' }) - }, + }, + + // GIT WORKSPACE E2E ENDS diff --git a/apps/remix-ide-e2e/src/types/index.d.ts b/apps/remix-ide-e2e/src/types/index.d.ts index b97d053f79..33f14fb169 100644 --- a/apps/remix-ide-e2e/src/types/index.d.ts +++ b/apps/remix-ide-e2e/src/types/index.d.ts @@ -11,7 +11,7 @@ declare module 'nightwatch' { scrollInto(target: string): NightwatchBrowser testContracts(fileName: string, contractCode: NightwatchContractContent, compiledContractNames: string[]): NightwatchBrowser setEditorValue(value: string, callback?: () => void): NightwatchBrowser - addFile(name: string, content: NightwatchContractContent): NightwatchBrowser + addFile(name: string, content: NightwatchContractContent, readMeFile?: string): NightwatchBrowser verifyContracts(compiledContractNames: string[], opts?: {wait: number; version?: string; runs?: string}): NightwatchBrowser selectAccount(account?: string): NightwatchBrowser clickFunction(fnFullName: string, expectedInput?: NightwatchClickFunctionExpectedInput): NightwatchBrowser diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 5a2ddf2a47..2277dd6aa8 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -54,6 +54,8 @@ import { electronTemplates } from './app/plugins/electron/templatesPlugin' import { xtermPlugin } from './app/plugins/electron/xtermPlugin' import { ripgrepPlugin } from './app/plugins/electron/ripgrepPlugin' import { compilerLoaderPlugin, compilerLoaderPluginDesktop } from './app/plugins/electron/compilerLoaderPlugin' +import { GitPlugin } from './app/plugins/git' + import {SolCoder} from './app/plugins/solcoderAI' const isElectron = require('is-electron') @@ -217,6 +219,9 @@ class AppComponent { //---- templates const templates = new TemplatesPlugin() + //---- git + const git = new GitPlugin() + //---------------- Solidity UML Generator ------------------------- const solidityumlgen = new SolidityUmlGen(appManager) @@ -350,6 +355,7 @@ class AppComponent { solidityScript, templates, solcoder, + git, pluginStateLogger ]) @@ -490,7 +496,7 @@ class AppComponent { ]) await this.appManager.activatePlugin(['settings']) - await this.appManager.activatePlugin(['walkthrough', 'storage', 'search', 'compileAndRun', 'recorder']) + await this.appManager.activatePlugin(['walkthrough', 'storage', 'search', 'compileAndRun', 'recorder', 'dgit']) await this.appManager.activatePlugin(['solidity-script', 'remix-templates']) if (isElectron()){ diff --git a/apps/remix-ide/src/app/editor/editor.js b/apps/remix-ide/src/app/editor/editor.js index 9647c88ad4..92e0a637a9 100644 --- a/apps/remix-ide/src/app/editor/editor.js +++ b/apps/remix-ide/src/app/editor/editor.js @@ -5,6 +5,7 @@ import { EditorUI } from '@remix-ui/editor' // eslint-disable-line import { Plugin } from '@remixproject/engine' import * as packageJson from '../../../../../package.json' import { PluginViewWrapper } from '@remix-ui/helper' +import { commitChange } from '@remix-ui/git' const EventManager = require('../../lib/events') @@ -13,7 +14,7 @@ const profile = { name: 'editor', description: 'service - editor', version: packageJson.version, - methods: ['highlight', 'discardHighlight', 'clearAnnotations', 'addLineText', 'discardLineTexts', 'addAnnotation', 'gotoLine', 'revealRange', 'getCursorPosition', 'open', 'addModel','addErrorMarker', 'clearErrorMarkers', 'getText', 'getPositionAt'], + methods: ['highlight', 'discardHighlight', 'clearAnnotations', 'addLineText', 'discardLineTexts', 'addAnnotation', 'gotoLine', 'revealRange', 'getCursorPosition', 'open', 'addModel','addErrorMarker', 'clearErrorMarkers', 'getText', 'getPositionAt', 'openReadOnly'], } class Editor extends Plugin { @@ -63,7 +64,8 @@ class Editor extends Plugin { onBreakPointAdded: (file, line) => this.triggerEvent('breakpointAdded', [file, line]), onBreakPointCleared: (file, line) => this.triggerEvent('breakpointCleared', [file, line]), onDidChangeContent: (file) => this._onChange(file), - onEditorMounted: () => this.triggerEvent('editorMounted', []) + onEditorMounted: () => this.triggerEvent('editorMounted', []), + onDiffEditorMounted: () => this.triggerEvent('diffEditorMounted', []) } // to be implemented by the react component @@ -81,8 +83,10 @@ class Editor extends Plugin { editorAPI={state.api} themeType={state.currentThemeType} currentFile={state.currentFile} + currentDiffFile={state.currentDiffFile} events={state.events} plugin={state.plugin} + isDiff={state.isDiff} /> } @@ -111,6 +115,8 @@ class Editor extends Plugin { api: this.api, currentThemeType: this.currentThemeType, currentFile: this.currentFile, + currentDiffFile: this.currentDiffFile, + isDiff: this.isDiff, events: this.events, plugin: this }) @@ -183,9 +189,10 @@ class Editor extends Plugin { } _switchSession (path) { - if (path === this.currentFile) return - this.triggerEvent('sessionSwitched', []) - this.currentFile = path + if (path !== this.currentFile) { + this.triggerEvent('sessionSwitched', []) + this.currentFile = path + } this.renderComponent() } @@ -241,10 +248,10 @@ class Editor extends Plugin { * @param {string} content Content of the file to open * @param {string} mode Mode for this file [Default is `text`] */ - async _createSession (path, content, mode) { + async _createSession (path, content, mode, readOnly) { if (!this.activated) return - this.emit('addModel', content, mode, path, this.readOnlySessions[path]) + this.emit('addModel', content, mode, path, readOnly || this.readOnlySessions[path]) return { path, language: mode, @@ -314,6 +321,7 @@ class Editor extends Plugin { - URL prepended with "browser" - URL not prepended with the file explorer. We assume (as it is in the whole app, that this is a "browser" URL */ + this.isDiff = false if (!this.sessions[path]) { this.readOnlySessions[path] = false const session = await this._createSession(path, content, this._getMode(path)) @@ -335,9 +343,22 @@ class Editor extends Plugin { const session = await this._createSession(path, content, this._getMode(path)) this.sessions[path] = session } + this.isDiff = false this._switchSession(path) } + async openDiff(change) { + console.log('openDiff', change) + const hashedPathModified = change.readonly ? change.path + change.hashModified : change.path + const hashedPathOriginal = change.path + change.hashOriginal + const session = await this._createSession(hashedPathModified, change.modified, this._getMode(change.path), change.readonly) + await this._createSession(hashedPathOriginal, change.original, this._getMode(change.path), change.readonly) + this.sessions[hashedPathModified] = session + this.currentDiffFile = hashedPathOriginal + this.isDiff = true + this._switchSession(hashedPathModified) + } + /** * Content of the current session * @return {String} content of the file referenced by @arg path diff --git a/apps/remix-ide/src/app/files/dgitProvider.ts b/apps/remix-ide/src/app/files/dgitProvider.ts index 10d2c76c7a..89f18d0f2b 100644 --- a/apps/remix-ide/src/app/files/dgitProvider.ts +++ b/apps/remix-ide/src/app/files/dgitProvider.ts @@ -3,7 +3,7 @@ import { Plugin } from '@remixproject/engine' -import git from 'isomorphic-git' +import git, { ReadBlobResult, ReadCommitResult, StatusRow } from 'isomorphic-git' import IpfsHttpClient from 'ipfs-http-client' import { saveAs @@ -15,14 +15,27 @@ import path from 'path' import FormData from 'form-data' import axios from 'axios' import { Registry } from '@remix-project/remix-lib' +import { Octokit, App } from "octokit" +import { OctokitResponse } from '@octokit/types' +import { Endpoints } from "@octokit/types" +import { IndexedDBStorage } from './filesystems/indexedDB' +import { GitHubUser, branch, commitChange, remote, pagedCommits, remoteCommitsInputType, cloneInputType, fetchInputType, pullInputType, pushInputType, currentBranchInput, branchInputType, addInput, rmInput, resolveRefInput, readBlobInput, repositoriesInput, commitInput, branchDifference, compareBranchesInput, initInput, userEmails, checkoutInput } from '@remix-ui/git' +import { LibraryProfile, StatusEvents } from '@remixproject/plugin-utils' +import { ITerminal } from '@remixproject/plugin-api/src/lib/terminal' +import { partial } from 'lodash' + +declare global { + interface Window { remixFileSystemCallback: IndexedDBStorage; remixFileSystem: any; } +} -const profile = { - name: 'dGitProvider', +const profile: LibraryProfile = { + name: 'dgitApi', displayName: 'Decentralized git', description: 'Decentralized git provider', icon: 'assets/img/fileManager.webp', version: '0.0.1', - methods: ['init', 'localStorageUsed', 'addremote', 'delremote', 'remotes', 'fetch', 'clone', 'export', 'import', 'status', 'log', 'commit', 'add', 'remove', 'reset', 'rm', 'lsfiles', 'readblob', 'resolveref', 'branches', 'branch', 'checkout', 'currentbranch', 'push', 'pin', 'pull', 'pinList', 'unPin', 'setIpfsConfig', 'zip', 'setItem', 'getItem', 'version', 'updateSubmodules'], + methods: ['init', 'localStorageUsed', 'addremote', 'delremote', 'remotes', 'fetch', 'clone', 'export', 'import', 'status', 'log', 'commit', 'add', 'remove', 'reset', 'rm', 'lsfiles', 'readblob', 'resolveref', 'branches', 'branch', 'checkout', 'currentbranch', 'push', 'pull', 'setIpfsConfig', 'zip', 'setItem', 'getItem', 'version', 'updateSubmodules' + , 'getGitHubUser', 'remotebranches', 'remotecommits', 'repositories', 'getCommitChanges', 'compareBranches'], kind: 'file-system' } class DGitProvider extends Plugin { @@ -55,7 +68,7 @@ class DGitProvider extends Plugin { this.ipfsSources = [this.remixIPFS, this.globalIPFSConfig, this.ipfsconfig] } - async getGitConfig(dir = '') { + async addIsomorphicGitConfigFS(dir = '') { if ((Registry.getInstance().get('platform').api.isDesktop())) { return { @@ -73,33 +86,99 @@ class DGitProvider extends Plugin { } } - async parseInput(input) { - return { + async addIsomorphicGitConfig(input) { + + const token = await this.call('config' as any, 'getAppParameter', 'settings/gist-access-token') + + let config = { corsProxy: 'https://corsproxy.remixproject.org/', http, onAuth: url => { url const auth = { - username: input.token, + username: input.token || token, password: '' } return auth } } + if (input.url) { + + const url = new URL(input.url) + if (url.hostname.includes('localhost')) { + config = { + ...config, + corsProxy: null + } + } + } + if ((input.remote && input.remote.url)) { + + const url = new URL(input.remote.url) + if (url.hostname.includes('localhost')) { + config = { + ...config, + corsProxy: null, + } + } + } + + if (input.provider && input.provider === 'github') { + config = { + ...config, + corsProxy: 'https://corsproxy.remixproject.org/', + } + } + + if (input.provider && input.provider === 'localhost') { + config = { + ...config, + corsProxy: null + } + } + + return config + } + + async getCommandUser(input) { + const author = { + name: '', + email: '' + } + if (input && input.name && input.email) { + author.name = input.name + author.email = input.email + } else { + const username = await this.call('config' as any, 'getAppParameter', 'settings/github-user-name') + const email = await this.call('config' as any, 'getAppParameter', 'settings/github-email') + const token = await this.call('config' as any, 'getAppParameter', 'settings/gist-access-token') + if (username && email) { + author.name = username + author.email = email + } else if (token) { + + const gitHubUser = await this.getGitHubUser({ token }) + + if (gitHubUser) { + author.name = gitHubUser.user.login + } + } + } + return author } - async init(input?) { + async init(input?: initInput): Promise { if ((Registry.getInstance().get('platform').api.isDesktop())) { await this.call('isogit', 'init', { - defaultBranch: (input && input.branch) || 'main' + defaultBranch: (input && input.defaultBranch) || 'main' }) this.emit('init') return } await git.init({ - ...await this.getGitConfig(), - defaultBranch: (input && input.branch) || 'main' + ...await this.addIsomorphicGitConfigFS(), + defaultBranch: (input && input.defaultBranch) || 'main' }) this.emit('init') } @@ -113,7 +192,7 @@ class DGitProvider extends Plugin { return version } - async status(cmd) { + async status(cmd): Promise> { if ((Registry.getInstance().get('platform').api.isDesktop())) { const status = await this.call('isogit', 'status', cmd) @@ -122,20 +201,20 @@ class DGitProvider extends Plugin { } const status = await git.statusMatrix({ - ...await this.getGitConfig(), + ...await this.addIsomorphicGitConfigFS(), ...cmd }) return status } - async add(cmd) { + async add(cmd: addInput): Promise { if ((Registry.getInstance().get('platform').api.isDesktop())) { await this.call('isogit', 'add', cmd) } else { await git.add({ - ...await this.getGitConfig(), + ...await this.addIsomorphicGitConfigFS(), ...cmd }) } @@ -143,13 +222,13 @@ class DGitProvider extends Plugin { this.emit('add') } - async rm(cmd) { + async rm(cmd: rmInput) { if ((Registry.getInstance().get('platform').api.isDesktop())) { await this.call('isogit', 'rm', cmd) } else { await git.remove({ - ...await this.getGitConfig(), + ...await this.addIsomorphicGitConfigFS(), ...cmd }) this.emit('rm') @@ -163,7 +242,7 @@ class DGitProvider extends Plugin { await this.call('isogit', 'reset', cmd) } else { await git.resetIndex({ - ...await this.getGitConfig(), + ...await this.addIsomorphicGitConfigFS(), ...cmd }) this.emit('rm') @@ -171,14 +250,14 @@ class DGitProvider extends Plugin { } } - async checkout(cmd, refresh = true) { + async checkout(cmd: checkoutInput): Promise { if ((Registry.getInstance().get('platform').api.isDesktop())) { await this.call('isogit', 'checkout', cmd) } else { const gitmodules = await this.parseGitmodules() || [] await git.checkout({ - ...await this.getGitConfig(), + ...await this.addIsomorphicGitConfigFS(), ...cmd }) const newgitmodules = await this.parseGitmodules() || [] @@ -190,12 +269,12 @@ class DGitProvider extends Plugin { }) for (const module of toRemove) { - const path = (await this.getGitConfig(module.path)).dir + const path = (await this.addIsomorphicGitConfigFS(module.path)).dir if (await window.remixFileSystem.exists(path)) { const stat = await window.remixFileSystem.stat(path) try { if (stat.isDirectory()) { - await window.remixFileSystem.unlink((await this.getGitConfig(module.path)).dir) + await window.remixFileSystem.unlink((await this.addIsomorphicGitConfigFS(module.path)).dir) } } catch (e) { // do nothing @@ -203,7 +282,7 @@ class DGitProvider extends Plugin { } } } - if (refresh) { + if (cmd.refresh) { setTimeout(async () => { await this.call('fileManager', 'refresh') }, 1000) @@ -212,7 +291,7 @@ class DGitProvider extends Plugin { this.emit('checkout') } - async log(cmd) { + async log(cmd: { ref: string }): Promise { if ((Registry.getInstance().get('platform').api.isDesktop())) { const status = await this.call('isogit', 'log', { @@ -224,39 +303,118 @@ class DGitProvider extends Plugin { } const status = await git.log({ - ...await this.getGitConfig(), + ...await this.addIsomorphicGitConfigFS(), ...cmd, - depth: 10 }) return status } - async remotes(config) { + async compareBranches({ branch, remote }: compareBranchesInput): Promise { + // Get current branch commits + const headCommits = await git.log({ + ...await this.addIsomorphicGitConfigFS(), + ref: branch.name, + }); + + // Get remote branch commits + const remoteCommits = await git.log({ + ...await this.addIsomorphicGitConfigFS(), + ref: `${remote.name}/${branch.name}`, + }); + + // Convert arrays of commit objects to sets of commit SHAs + const headCommitSHAs = new Set(headCommits.map(commit => commit.oid)); + const remoteCommitSHAs = new Set(remoteCommits.map(commit => commit.oid)); + + // Filter out commits that are only in the remote branch + const uniqueRemoteCommits = remoteCommits.filter(commit => !headCommitSHAs.has(commit.oid)); + + // filter out commits that are only in the local branch + const uniqueHeadCommits = headCommits.filter(commit => !remoteCommitSHAs.has(commit.oid)); + + return { + uniqueHeadCommits, + uniqueRemoteCommits, + }; + } + + async getCommitChanges(commitHash1: string, commitHash2: string): Promise { + const result: commitChange[] = await git.walk({ + ...await this.addIsomorphicGitConfigFS(), + trees: [git.TREE({ ref: commitHash1 }), git.TREE({ ref: commitHash2 })], + map: async function (filepath, [A, B]) { + + if (filepath === '.') { + return + } + try { + if ((A && await A.type()) === 'tree' || B && (await B.type()) === 'tree') { + return + } + } catch (e) { + // ignore + } + + // generate ids + const Aoid = A && await A.oid() || undefined + const Boid = B && await B.oid() || undefined + + const commitChange: Partial = { + hashModified: commitHash1, + hashOriginal: commitHash2, + path: filepath, + } + + // determine modification type + if (Aoid !== Boid) { + commitChange.type = "modified" + } + if (Aoid === undefined) { + commitChange.type = "deleted" + } + if (Boid === undefined || !commitHash2) { + commitChange.type = "added" + } + if (Aoid === undefined && Boid === undefined) { + commitChange.type = "unknown" + } + if (commitChange.type) + return commitChange + else + return undefined + }, + }) + + return result + } + + async remotes(config): Promise { if ((Registry.getInstance().get('platform').api.isDesktop())) { return await this.call('isogit', 'remotes', config) } - let remotes = [] + let remotes: remote[] = [] try { - remotes = await git.listRemotes({ ...config ? config : await this.getGitConfig() }) + remotes = (await git.listRemotes({ ...config ? config : await this.addIsomorphicGitConfigFS() })).map((remote) => { return { name: remote.remote, url: remote.url } } + ) } catch (e) { // do nothing } return remotes } - async branch(cmd, refresh = true) { + async branch(cmd: branchInputType): Promise { let status if ((Registry.getInstance().get('platform').api.isDesktop())) { status = await this.call('isogit', 'branch', cmd) } else { status = await git.branch({ - ...await this.getGitConfig(), + ...await this.addIsomorphicGitConfigFS(), ...cmd }) } - if (refresh) { + if (cmd.refresh) { setTimeout(async () => { await this.call('fileManager', 'refresh') }, 1000) @@ -265,47 +423,68 @@ class DGitProvider extends Plugin { return status } - async currentbranch(config) { + async currentbranch(config: currentBranchInput): Promise { if ((Registry.getInstance().get('platform').api.isDesktop())) { return await this.call('isogit', 'currentbranch') } try { - const defaultConfig = await this.getGitConfig() + const defaultConfig = await this.addIsomorphicGitConfigFS() const cmd = config ? defaultConfig ? { ...defaultConfig, ...config } : config : defaultConfig const name = await git.currentBranch(cmd) + let remote: remote = undefined + try { + const remoteName = await git.getConfig({ + ...defaultConfig, + path: `branch.${name}.remote` + }) + if (remoteName) { + const remoteUrl = await git.getConfig({ + ...defaultConfig, + path: `remote.${remoteName}.url` + }) + remote = { name: remoteName, url: remoteUrl } + } - return name + } catch (e) { + // do nothing + } + + return { + remote: remote, + name: name || '' + } } catch (e) { - return '' + return undefined } } - async branches(config) { + async branches(config): Promise { if ((Registry.getInstance().get('platform').api.isDesktop())) { return await this.call('isogit', 'branches') } try { - const defaultConfig = await this.getGitConfig() + const defaultConfig = await this.addIsomorphicGitConfigFS() const cmd = config ? defaultConfig ? { ...defaultConfig, ...config } : config : defaultConfig const remotes = await this.remotes(config) - let branches = [] + let branches: branch[] = [] branches = (await git.listBranches(cmd)).map((branch) => { return { remote: undefined, name: branch } }) for (const remote of remotes) { - cmd.remote = remote.remote - const remotebranches = (await git.listBranches(cmd)).map((branch) => { return { remote: remote.remote, name: branch } }) + cmd.remote = remote.name + const remotebranches = (await git.listBranches(cmd)).map((branch) => { return { remote: remote, name: branch } }) branches = [...branches, ...remotebranches] } return branches } catch (e) { + console.log(e) return [] } } - async commit(cmd) { + async commit(cmd: commitInput): Promise { if ((Registry.getInstance().get('platform').api.isDesktop())) { try { @@ -321,7 +500,7 @@ class DGitProvider extends Plugin { await this.init() try { const sha = await git.commit({ - ...await this.getGitConfig(), + ...await this.addIsomorphicGitConfigFS(), ...cmd }) this.emit('commit') @@ -339,32 +518,32 @@ class DGitProvider extends Plugin { } const filesInStaging = await git.listFiles({ - ...await this.getGitConfig(), + ...await this.addIsomorphicGitConfigFS(), ...cmd }) return filesInStaging } - async resolveref(cmd) { + async resolveref(cmd: resolveRefInput): Promise { if ((Registry.getInstance().get('platform').api.isDesktop())) { return await this.call('isogit', 'resolveref', cmd) } const oid = await git.resolveRef({ - ...await this.getGitConfig(), + ...await this.addIsomorphicGitConfigFS(), ...cmd }) return oid } - async readblob(cmd) { + async readblob(cmd: readBlobInput): Promise { if ((Registry.getInstance().get('platform').api.isDesktop())) { const readBlobResult = await this.call('isogit', 'readblob', cmd) return readBlobResult } const readBlobResult = await git.readBlob({ - ...await this.getGitConfig(), + ...await this.addIsomorphicGitConfigFS(), ...cmd }) @@ -388,27 +567,27 @@ class DGitProvider extends Plugin { } } - async addremote(input) { + async addremote(input: remote): Promise { if ((Registry.getInstance().get('platform').api.isDesktop())) { - await this.call('isogit', 'addremote', { url: input.url, remote: input.remote }) + await this.call('isogit', 'addremote', { url: input.url, remote: input.name }) return } - await git.addRemote({ ...await this.getGitConfig(), url: input.url, remote: input.remote }) + await git.addRemote({ ...await this.addIsomorphicGitConfigFS(), url: input.url, remote: input.name }) } - async delremote(input) { + async delremote(input: remote) { if ((Registry.getInstance().get('platform').api.isDesktop())) { - await this.call('isogit', 'delremote', { remote: input.remote }) + await this.call('isogit', 'delremote', { remote: input.name }) return } - await git.deleteRemote({ ...await this.getGitConfig(), remote: input.remote }) + await git.deleteRemote({ ...await this.addIsomorphicGitConfigFS(), remote: input.name }) } async localStorageUsed() { return this.calculateLocalStorage() } - async clone(input, workspaceName, workspaceExists = false) { + async clone(input: cloneInputType) { if ((Registry.getInstance().get('platform').api.isDesktop())) { const folder = await this.call('fs', 'selectFolder', null, 'Select or create a folder to clone the repository in', 'Select as Repository Destination') @@ -426,7 +605,7 @@ class DGitProvider extends Plugin { const result = await this.call('isogit', 'clone', cmd) this.call('fs', 'openWindow', folder) return result - } catch (e){ + } catch (e) { this.call('notification', 'alert', { id: 'dgitAlert', message: 'Unexpected error while cloning the repository: \n' + e.toString(), @@ -436,18 +615,19 @@ class DGitProvider extends Plugin { const permission = await this.askUserPermission('clone', 'Import multiple files into your workspaces.') if (!permission) return false if (parseFloat(this.calculateLocalStorage()) > 10000) throw new Error('The local storage of the browser is full.') - if (!workspaceExists) await this.call('filePanel', 'createWorkspace', workspaceName || `workspace_${Date.now()}`, true) + if (!input.workspaceExists) await this.call('filePanel', 'createWorkspace', input.workspaceName || `workspace_${Date.now()}`, true) const cmd = { url: input.url, singleBranch: input.singleBranch, ref: input.branch, depth: input.depth || 10, - ...await this.parseInput(input), - ...await this.getGitConfig() + ...await this.addIsomorphicGitConfig(input), + ...await this.addIsomorphicGitConfigFS() } + this.call('terminal', 'logHtml', `Cloning ${input.url}...`) const result = await git.clone(cmd) - if (!workspaceExists) { + if (!input.workspaceExists) { setTimeout(async () => { await this.call('fileManager', 'refresh') }, 1000) @@ -457,12 +637,12 @@ class DGitProvider extends Plugin { } } - async parseGitmodules (dir = '') { + async parseGitmodules(dir = '') { try { const gitmodules = await this.call('fileManager', 'readFile', path.join(dir, '.gitmodules')) if (gitmodules) { const lines = gitmodules.split('\n') - let currentModule:any = {} + let currentModule: any = {} const modules = [] for (let line of lines) { line = line.trim() @@ -497,7 +677,7 @@ class DGitProvider extends Plugin { if (gitmodules) { for (const module of gitmodules) { const dir = path.join(currentDir, module.path) - const targetPath = (await this.getGitConfig(dir)).dir + const targetPath = (await this.addIsomorphicGitConfigFS(dir)).dir if (await window.remixFileSystem.exists(targetPath)) { const stat = await window.remixFileSystem.stat(targetPath) try { @@ -520,20 +700,23 @@ class DGitProvider extends Plugin { url: module.url, singleBranch: true, depth: 1, - ...await this.parseInput(input), - ...await this.getGitConfig(dir) + ...await this.addIsomorphicGitConfig({ + ...input, + provider: 'github' + }), + ...await this.addIsomorphicGitConfigFS(dir) } this.call('terminal', 'logHtml', `Cloning submodule ${dir}...`) await git.clone(cmd) this.call('terminal', 'logHtml', `Cloned successfully submodule ${dir}...`) const commitHash = await git.resolveRef({ - ...await this.getGitConfig(currentDir), + ...await this.addIsomorphicGitConfigFS(currentDir), ref: 'HEAD' }) const result = await git.walk({ - ...await this.getGitConfig(currentDir), + ...await this.addIsomorphicGitConfigFS(currentDir), trees: [git.TREE({ ref: commitHash })], map: async function (filepath, [A]) { if (filepath === module.path) { @@ -544,27 +727,31 @@ class DGitProvider extends Plugin { if (result && result.length) { this.call('terminal', 'logHtml', `Checking out submodule ${dir} to ${result[0]} in directory ${dir}`) await git.fetch({ - ...await this.parseInput(input), - ...await this.getGitConfig(dir), + ...await this.addIsomorphicGitConfig({ + ...input, + provider: 'github' + }), + ...await this.addIsomorphicGitConfigFS(dir), singleBranch: true, ref: result[0] }) await git.checkout({ - ...await this.getGitConfig(dir), + ...await this.addIsomorphicGitConfigFS(dir), ref: result[0] }) const log = await git.log({ - ...await this.getGitConfig(dir), + ...await this.addIsomorphicGitConfigFS(dir), }) if (log[0].oid !== result[0]) { this.call('terminal', 'log', { type: 'error', value: `Could not checkout submodule to ${result[0]}` - })} else { - this.call('terminal', 'logHtml',`Checked out submodule ${dir} to ${result[0]}`) + }) + } else { + this.call('terminal', 'logHtml', `Checked out submodule ${dir} to ${result[0]}`) } } @@ -588,16 +775,14 @@ class DGitProvider extends Plugin { } } - async push(input) { + async push(input: pushInputType) { + const cmd = { force: input.force, - ref: input.ref, - remoteRef: input.remoteRef, - remote: input.remote, - author: { - name: input.name, - email: input.email - }, + ref: input.ref.name, + remoteRef: input.remoteRef && input.remoteRef.name, + remote: input.remote.name, + author: await this.getCommandUser(input), input, } if ((Registry.getInstance().get('platform').api.isDesktop())) { @@ -606,25 +791,26 @@ class DGitProvider extends Plugin { const cmd2 = { ...cmd, - ...await this.parseInput(input), + ...await this.addIsomorphicGitConfig(input), } - return await git.push({ - ...await this.getGitConfig(), + + const result = await git.push({ + ...await this.addIsomorphicGitConfigFS(), ...cmd2 }) + return result + } } - async pull(input) { + async pull(input: pullInputType) { + const cmd = { - ref: input.ref, - remoteRef: input.remoteRef, - author: { - name: input.name, - email: input.email - }, - remote: input.remote, + ref: input.ref.name, + remoteRef: input.remoteRef && input.remoteRef.name, + author: await this.getCommandUser(input), + remote: input.remote.name, input, } let result @@ -634,10 +820,10 @@ class DGitProvider extends Plugin { else { const cmd2 = { ...cmd, - ...await this.parseInput(input), + ...await this.addIsomorphicGitConfig(input), } result = await git.pull({ - ...await this.getGitConfig(), + ...await this.addIsomorphicGitConfigFS(), ...cmd2 }) } @@ -647,30 +833,33 @@ class DGitProvider extends Plugin { return result } - async fetch(input) { + async fetch(input: fetchInputType) { const cmd = { - ref: input.ref, - remoteRef: input.remoteRef, - author: { - name: input.name, - email: input.email - }, - remote: input.remote, + ref: input.ref && input.ref.name, + remoteRef: input.remoteRef && input.remoteRef.name, + author: await this.getCommandUser(input), + remote: input.remote && input.remote.name, + depth: input.depth || 5, + singleBranch: input.singleBranch, + relative: input.relative, input } + let result if ((Registry.getInstance().get('platform').api.isDesktop())) { result = await this.call('isogit', 'fetch', cmd) } else { const cmd2 = { ...cmd, - ...await this.parseInput(input), + ...await this.addIsomorphicGitConfig(input), } result = await git.fetch({ - ...await this.getGitConfig(), + ...await this.addIsomorphicGitConfigFS(), ...cmd2 }) + } + setTimeout(async () => { await this.call('fileManager', 'refresh') }, 1000) @@ -683,7 +872,7 @@ class DGitProvider extends Plugin { const files = await this.getDirectory('/') this.filesToSend = [] for (const file of files) { - const c = await window.remixFileSystem.readFile(`${workspace.absolutePath}/${file}`) + const c = await window.remixFileSystem.readFile(`${workspace.absolutePath}/${file}`, null) const ob = { path: file, content: c @@ -697,108 +886,6 @@ class DGitProvider extends Plugin { return r.cid.string } - async pin(pinataApiKey, pinataSecretApiKey) { - const workspace = await this.call('filePanel', 'getCurrentWorkspace') - const files = await this.getDirectory('/') - this.filesToSend = [] - - const data = new FormData() - for (const file of files) { - const c = await window.remixFileSystem.readFile(`${workspace.absolutePath}/${file}`) - data.append('file', new Blob([c]), `base/${file}`) - } - // get last commit data - let ob - try { - const commits = await this.log({ ref: 'HEAD' }) - ob = { - ref: commits[0].oid, - message: commits[0].commit.message, - commits: JSON.stringify(commits.map((commit) => { - return { - oid: commit.oid, - commit: { - parent: commit.commit?.parent, - tree: commit.commit?.tree, - message: commit.commit?.message, - committer: { - timestamp: commit.commit?.committer?.timestamp - } - } - } - })) - } - } catch (e) { - ob = { - ref: 'no commits', - message: 'no commits' - } - } - const today = new Date() - const metadata = JSON.stringify({ - name: `remix - ${workspace.name} - ${today.toLocaleString()}`, - keyvalues: ob - }) - const pinataOptions = JSON.stringify({ - wrapWithDirectory: false - }) - data.append('pinataOptions', pinataOptions) - data.append('pinataMetadata', metadata) - const url = 'https://api.pinata.cloud/pinning/pinFileToIPFS' - try { - const result = await axios - .post(url, data, { - maxBodyLength: 'Infinity', - headers: { - 'Content-Type': `multipart/form-data; boundary=${(data as any)._boundary}`, - pinata_api_key: pinataApiKey, - pinata_secret_api_key: pinataSecretApiKey - } - } as any).catch((e) => { - console.log(e) - }) - // also commit to remix IPFS for availability after pinning to Pinata - return await this.export(this.remixIPFS) || (result as any).data.IpfsHash - } catch (error) { - throw new Error(error) - } - } - - async pinList(pinataApiKey, pinataSecretApiKey) { - const url = 'https://api.pinata.cloud/data/pinList?status=pinned' - try { - const result = await axios - .get(url, { - maxBodyLength: 'Infinity', - headers: { - pinata_api_key: pinataApiKey, - pinata_secret_api_key: pinataSecretApiKey - } - } as any).catch((e) => { - console.log('Pinata unreachable') - }) - return (result as any).data - } catch (error) { - throw new Error(error) - } - } - - async unPin(pinataApiKey, pinataSecretApiKey, hashToUnpin) { - const url = `https://api.pinata.cloud/pinning/unpin/${hashToUnpin}` - try { - await axios - .delete(url, { - headers: { - pinata_api_key: pinataApiKey, - pinata_secret_api_key: pinataSecretApiKey - } - }) - return true - } catch (error) { - throw new Error(error) - } - } - async importIPFSFiles(config, cid, workspace) { const ipfs = IpfsHttpClient(config) let result = false @@ -819,7 +906,7 @@ class DGitProvider extends Plugin { await this.createDirectories(`${workspace.absolutePath}/${dir}`) } catch (e) { throw new Error(e) } try { - await window.remixFileSystem.writeFile(`${workspace.absolutePath}/${file.path}`, Buffer.concat(content) || new Uint8Array()) + await window.remixFileSystem.writeFile(`${workspace.absolutePath}/${file.path}`, Buffer.concat(content) || new Uint8Array(), null) } catch (e) { throw new Error(e) } } } catch (e) { @@ -885,7 +972,7 @@ class DGitProvider extends Plugin { const files = await this.getDirectory('/') this.filesToSend = [] for (const file of files) { - const c = await window.remixFileSystem.readFile(`${workspace.absolutePath}/${file}`) + const c = await window.remixFileSystem.readFile(`${workspace.absolutePath}/${file}`, null) zip.file(file, c) } await zip.generateAsync({ @@ -935,6 +1022,134 @@ class DGitProvider extends Plugin { } return result } + + // OCTOKIT FEATURES + + async remotebranches(input: { owner: string, repo: string, token: string, page: number, per_page: number }) { + + const octokit = new Octokit({ + auth: input.token + }) + + const data = await octokit.request('GET /repos/{owner}/{repo}/branches{?protected,per_page,page}', { + owner: input.owner, + repo: input.repo, + per_page: input.per_page || 100, + page: input.page || 1 + }) + + return data.data + } + + async getGitHubUser(input: { token: string }): Promise<{ + user: GitHubUser, + emails: userEmails, + scopes: string[] + }> { + try { + const octokit = new Octokit({ + auth: input.token + }) + + const user = await octokit.request('GET /user') + const emails = await octokit.request('GET /user/emails') + + const scopes = user.headers['x-oauth-scopes'] || '' + + return { + user: user.data, + emails: emails.data, + scopes: scopes && scopes.split(',') + } + } catch (e) { + return null + } + } + + async remotecommits(input: remoteCommitsInputType): Promise { + const octokit = new Octokit({ + auth: input.token + }) + input.length = input.length || 5 + input.page = input.page || 1 + const response = await octokit.request('GET /repos/{owner}/{repo}/commits', { + owner: input.owner, + repo: input.repo, + sha: input.branch, + per_page: input.length, + page: input.page + }) + const pages: pagedCommits[] = [] + const readCommitResults: ReadCommitResult[] = [] + for (const githubApiCommit of response.data) { + const readCommitResult = { + oid: githubApiCommit.sha, + commit: { + author: { + name: githubApiCommit.commit.author.name, + email: githubApiCommit.commit.author.email, + timestamp: new Date(githubApiCommit.commit.author.date).getTime() / 1000, + timezoneOffset: new Date(githubApiCommit.commit.author.date).getTimezoneOffset() + }, + committer: { + name: githubApiCommit.commit.committer.name, + email: githubApiCommit.commit.committer.email, + timestamp: new Date(githubApiCommit.commit.committer.date).getTime() / 1000, + timezoneOffset: new Date(githubApiCommit.commit.committer.date).getTimezoneOffset() + }, + message: githubApiCommit.commit.message, + tree: githubApiCommit.commit.tree.sha, + parent: githubApiCommit.parents.map(parent => parent.sha) + }, + payload: '' // You may need to reconstruct the commit object in Git's format if necessary + } + readCommitResults.push(readCommitResult) + } + + // Check for the Link header to determine pagination + const linkHeader = response.headers.link; + + let hasNextPage = false; + if (linkHeader) { + // A simple check for the presence of a 'next' relation in the Link header + hasNextPage = linkHeader.includes('rel="next"'); + } + + pages.push({ + page: input.page, + perPage: input.length, + total: response.data.length, + hasNextPage: hasNextPage, + commits: readCommitResults + }) + return pages + } + + async repositories(input: repositoriesInput) { + + const accessToken = input.token; + + const page = input.page || 1 + const perPage = input.per_page || 10 + + const baseURL = 'https://api.github.com/user/repos' + const repositories = [] + const sort = 'updated' + const direction = 'desc' + + const headers = { + 'Authorization': `Bearer ${accessToken}`, // Include your GitHub access token + 'Accept': 'application/vnd.github.v3+json', // GitHub API v3 media type + }; + + const url = `${baseURL}?visibility=private,public&page=${page}&per_page=${perPage}&sort=${sort}&direction=${direction}`; + const response = await axios.get(url, { headers }); + + repositories.push(...response.data); + + return repositories + } + } const addSlash = (file) => { diff --git a/apps/remix-ide/src/app/files/fileManager.ts b/apps/remix-ide/src/app/files/fileManager.ts index b2d0117246..c9f1c1d93d 100644 --- a/apps/remix-ide/src/app/files/fileManager.ts +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -8,6 +8,7 @@ import { Registry } from '@remix-project/remix-lib' import { fileChangedToastMsg, recursivePasteToastMsg, storageFullMessage } from '@remix-ui/helper' import helper from '../../lib/helper.js' import { RemixAppManager } from '../../remixAppManager' +import { commitChange } from '@remix-ui/git' /* attach to files event (removed renamed) @@ -24,7 +25,7 @@ const profile = { methods: ['closeAllFiles', 'closeFile', 'file', 'exists', 'open', 'writeFile', 'writeMultipleFiles', 'writeFileNoRewrite', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'dirList', 'fileList', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath', - 'saveCurrentFile', 'setBatchFiles', 'isGitRepo', 'isFile', 'isDirectory', 'hasGitSubmodule', 'copyFolderToJson' + 'saveCurrentFile', 'setBatchFiles', 'isGitRepo', 'isFile', 'isDirectory', 'hasGitSubmodule', 'copyFolderToJson', 'diff' ], kind: 'file-system' } @@ -702,6 +703,37 @@ class FileManager extends Plugin { this.emit('noFileSelected') } + async diff(change: commitChange) { + await this.saveCurrentFile() + this._deps.config.set('currentFile', '') + // TODO: Only keep `this.emit` (issue#2210) + this.emit('noFileSelected') + + if (!change.readonly){ + let file = this.normalize(change.path) + const resolved = this.getPathFromUrl(file) + file = resolved.file + this._deps.config.set('currentFile', file) + this.openedFiles[file] = file + } + + await this.editor.openDiff(change) + this.emit('openDiff', change) + } + + async closeDiff(change: commitChange) { + if (!change.readonly){ + const file = this.normalize(change.path) + delete this.openedFiles[file] + if (!Object.keys(this.openedFiles).length) { + this._deps.config.set('currentFile', '') + // TODO: Only keep `this.emit` (issue#2210) + this.emit('noFileSelected') + } + } + this.emit('closeDiff', change) + } + async openFile(file?: string) { if (!file) { this.emit('noFileSelected') @@ -710,16 +742,17 @@ class FileManager extends Plugin { const resolved = this.getPathFromUrl(file) file = resolved.file await this.saveCurrentFile() - if (this.currentFile() === file) return + // we always open the file in the editor, even if it's the same as the current one if the editor is in diff mode + if (this.currentFile() === file && !this.editor.isDiff) return const provider = resolved.provider this._deps.config.set('currentFile', file) + this.openedFiles[file] = file let content = '' try { content = await provider.get(file) - } catch (error) { console.log(error) throw error @@ -736,6 +769,7 @@ class FileManager extends Plugin { } else { await this.editor.open(file, content) } + // TODO: Only keep `this.emit` (issue#2210) this.emit('currentFileChanged', file) return true } diff --git a/apps/remix-ide/src/app/panels/layout.ts b/apps/remix-ide/src/app/panels/layout.ts index fa564370f4..90896c2041 100644 --- a/apps/remix-ide/src/app/panels/layout.ts +++ b/apps/remix-ide/src/app/panels/layout.ts @@ -43,6 +43,11 @@ export class Layout extends Plugin { this.panels.main.active = false this.event.emit('change', null) }) + this.on('fileManager', 'openDiff', () => { + this.panels.editor.active = true + this.panels.main.active = false + this.event.emit('change', null) + }) this.on('tabs', 'openFile', () => { this.panels.editor.active = true this.panels.main.active = false @@ -59,6 +64,12 @@ export class Layout extends Plugin { this.panels.main.active = false this.event.emit('change', null) }) + this.on('tabs', 'openDiff', () => { + console.log('openDiff') + this.panels.editor.active = true + this.panels.main.active = false + this.event.emit('change', null) + }) this.on('manager', 'activate', (profile: Profile) => { switch (profile.name) { case 'filePanel': diff --git a/apps/remix-ide/src/app/panels/tab-proxy.js b/apps/remix-ide/src/app/panels/tab-proxy.js index fa6521023a..8eda6d6202 100644 --- a/apps/remix-ide/src/app/panels/tab-proxy.js +++ b/apps/remix-ide/src/app/panels/tab-proxy.js @@ -146,6 +146,23 @@ export class TabProxy extends Plugin { } }) + this.on('fileManager', 'openDiff', (commit) => { + const hash = commit.hashModified? commit.hashModified.substring(0,6): 'Working Tree' + const name = `${commit.path} (${hash})` + this.addTab(name, name, async () => { + await this.fileManager.diff(commit) + this.event.emit('openDiff', commit) + this.emit('openDiff', commit) + }, + async () => { + this.removeTab(name) + await this.fileManager.closeDiff(commit) + this.event.emit('closeDiff', commit) + this.emit('closeDiff', commit) + }) + this.tabsApi.activateTab(name) + }) + this.on('manager', 'pluginActivated', ({ name, location, displayName, icon, description }) => { if (location === 'mainPanel') { this.addTab( diff --git a/apps/remix-ide/src/app/plugins/git.tsx b/apps/remix-ide/src/app/plugins/git.tsx new file mode 100644 index 0000000000..35129dfceb --- /dev/null +++ b/apps/remix-ide/src/app/plugins/git.tsx @@ -0,0 +1,40 @@ +'use strict' +import { ViewPlugin } from '@remixproject/engine-web'; +import React from 'react' // eslint-disable-line +import { gitState, GitUI } from '@remix-ui/git'; +import * as packageJson from '../../../../../package.json' + +const profile = { + name: 'dgit', + desciption: 'Git plugin for Remix', + methods: ['pull', 'track', 'diff', 'clone', 'open'], + events: [''], + version: packageJson.version, + maintainedBy: 'Remix', + permission: true, + description: 'Use this plugin to interact with your git repositories', + location: 'sidePanel', + icon: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTIxLjAwNyA4LjIyMTY4QzIxLjAxMDUgNy41Mjc5MiAyMC44MjA3IDYuODQ2ODkgMjAuNDU5MSA2LjI1NDg1QzIwLjA5NzQgNS42NjI4MSAxOS41NzggNS4xODMxNSAxOC45NTkyIDQuODY5NTdDMTguMzQwMyA0LjU1NiAxNy42NDYzIDQuNDIwOTEgMTYuOTU1MSA0LjQ3OTQxQzE2LjI2MzcgNC41Mzc5MyAxNS42MDI1IDQuNzg3NzMgMTUuMDQ1IDUuMjAwODVDMTQuNDg3NyA1LjYxMzk3IDE0LjA1NjMgNi4xNzQwOSAxMy43OTkzIDYuODE4NUMxMy41NDI0IDcuNDYyOSAxMy40Njk3IDguMTY2MTMgMTMuNTg5OCA4Ljg0OTQ0QzEzLjcwOTkgOS41MzI3NCAxNC4wMTc3IDEwLjE2OTIgMTQuNDc4OSAxMC42ODc0QzE0Ljk0MDIgMTEuMjA1NiAxNS41MzY3IDExLjU4NTIgMTYuMjAxNSAxMS43ODM2QzE1Ljk1NiAxMi4yODI0IDE1LjU3NjMgMTIuNzAzIDE1LjEwNDkgMTIuOTk3OUMxNC42MzM2IDEzLjI5MjkgMTQuMDg5NCAxMy40NTA1IDEzLjUzMzQgMTMuNDUzMkgxMC41NDRDOS40MzcyNiAxMy40NTcxIDguMzcxNjMgMTMuODcyNyA3LjU1NDUxIDE0LjYxOTFWNy4zOTgwOUM4LjQ2MTg0IDcuMjEyODggOS4yNjgwOCA2LjY5NzM3IDkuODE2OTIgNS45NTE1MUMxMC4zNjU4IDUuMjA1NjUgMTAuNjE4MSA0LjI4MjU2IDEwLjUyNSAzLjM2MTIxQzEwLjQzMTkgMi40Mzk4NyAxMC4wMDAxIDEuNTg1OSA5LjMxMzE2IDAuOTY0ODczQzguNjI2MjQgMC4zNDM4NDUgNy43MzMxOSAwIDYuODA3MTYgMEM1Ljg4MTEyIDAgNC45ODgwNyAwLjM0Mzg0NSA0LjMwMTE0IDAuOTY0ODczQzMuNjE0MjIgMS41ODU5IDMuMTgyMzYgMi40Mzk4NyAzLjA4OTI4IDMuMzYxMjFDMi45OTYyIDQuMjgyNTYgMy4yNDg1NSA1LjIwNTY1IDMuNzk3MzkgNS45NTE1MUM0LjM0NjIzIDYuNjk3MzcgNS4xNTI0NyA3LjIxMjg4IDYuMDU5OCA3LjM5ODA5VjE2LjUxNTlDNS4xNTQxOCAxNi42ODkxIDQuMzQzMjMgMTcuMTg3NyAzLjc3OTkzIDE3LjkxNzZDMy4yMTY2MyAxOC42NDc2IDIuOTM5OTIgMTkuNTU4NSAzLjAwMTk3IDIwLjQ3ODVDMy4wNjQwMyAyMS4zOTg0IDMuNDYwNTcgMjIuMjYzOSA0LjExNjggMjIuOTExNUM0Ljc3MzAzIDIzLjU1OTIgNS42NDM2IDIzLjk0NDQgNi41NjQyNyAyMy45OTQ0QzcuNDg0OTYgMjQuMDQ0NSA4LjM5MjExIDIzLjc1NTggOS4xMTQ2NCAyMy4xODNDOS44MzcxOCAyMi42MTAyIDEwLjMyNTEgMjEuNzkyOCAxMC40ODY1IDIwLjg4NUMxMC42NDc4IDE5Ljk3NzEgMTAuNDcxNCAxOS4wNDE3IDkuOTkwNDggMTguMjU1QzkuNTA5NTcgMTcuNDY4MyA4Ljc1NzQxIDE2Ljg4NDggNy44NzU4OCAxNi42MTQ1QzguMTIxNzYgMTYuMTE2MiA4LjUwMTY3IDE1LjY5NjMgOC45NzI5NiAxNS40MDE5QzkuNDQ0MjYgMTUuMTA3NCA5Ljk4ODI3IDE0Ljk1MDMgMTAuNTQ0IDE0Ljk0NzlIMTMuNTMzNEMxNC40NjYxIDE0Ljk0MzYgMTUuMzc0MiAxNC42NDg2IDE2LjEzMTMgMTQuMTAzOUMxNi44ODg0IDEzLjU1OTIgMTcuNDU2OCAxMi43OTIgMTcuNzU3NSAxMS45MDkxQzE4LjY1MzQgMTEuNzkxNCAxOS40NzYzIDExLjM1MjggMjAuMDczOCAxMC42NzQ4QzIwLjY3MTMgOS45OTY4IDIxLjAwMjggOS4xMjUzMyAyMS4wMDcgOC4yMjE2OFpNNC41NjUwOCAzLjczNzUyQzQuNTY1MDggMy4yOTQwOCA0LjY5NjU3IDIuODYwNiA0Ljk0MjkzIDIuNDkxOUM1LjE4OTMgMi4xMjMxOSA1LjUzOTQ3IDEuODM1ODEgNS45NDkxNSAxLjY2NjExQzYuMzU4ODQgMS40OTY0MiA2LjgwOTY1IDEuNDUyMDIgNy4yNDQ1NiAxLjUzODU0QzcuNjc5NDggMS42MjUwNCA4LjA3ODk4IDEuODM4NTcgOC4zOTI1NCAyLjE1MjE0QzguNzA2MTEgMi40NjU3IDguOTE5NjQgMi44NjUyIDkuMDA2MTUgMy4zMDAxMkM5LjA5MjY2IDMuNzM1MDQgOS4wNDgyNyA0LjE4NTg1IDguODc4NTcgNC41OTU1M0M4LjcwODg3IDUuMDA1MjEgOC40MjE0OSA1LjM1NTM5IDguMDUyNzggNS42MDE3NUM3LjY4NDA4IDUuODQ4MTEgNy4yNTA2IDUuOTc5NiA2LjgwNzE2IDUuOTc5NkM2LjIxMjUyIDUuOTc5NiA1LjY0MjI0IDUuNzQzMzkgNS4yMjE3NyA1LjMyMjkxQzQuODAxMjkgNC45MDI0NSA0LjU2NTA4IDQuMzMyMTYgNC41NjUwOCAzLjczNzUyWk05LjA0OTIzIDIwLjE3OTRDOS4wNDkyMyAyMC42MjI5IDguOTE3NzQgMjEuMDU2MyA4LjY3MTM4IDIxLjQyNUM4LjQyNTAxIDIxLjc5MzcgOC4wNzQ4NSAyMi4wODExIDcuNjY1MTYgMjIuMjUwOEM3LjI1NTQ3IDIyLjQyMDUgNi44MDQ2NiAyMi40NjQ5IDYuMzY5NzUgMjIuMzc4NEM1LjkzNDgzIDIyLjI5MiA1LjUzNTMzIDIyLjA3ODQgNS4yMjE3NyAyMS43NjQ4QzQuOTA4MjEgMjEuNDUxMiA0LjY5NDY3IDIxLjA1MTcgNC42MDgxNiAyMC42MTY5QzQuNTIxNjUgMjAuMTgxOSA0LjU2NjA1IDE5LjczMTEgNC43MzU3NSAxOS4zMjE0QzQuOTA1NDUgMTguOTExNyA1LjE5MjgyIDE4LjU2MTUgNS41NjE1MyAxOC4zMTUyQzUuOTMwMjMgMTguMDY4OSA2LjM2MzcxIDE3LjkzNzMgNi44MDcxNiAxNy45MzczQzcuNDAxNzkgMTcuOTM3MyA3Ljk3MjA3IDE4LjE3MzYgOC4zOTI1NCAxOC41OTRDOC44MTMwMiAxOS4wMTQ1IDkuMDQ5MjMgMTkuNTg0OCA5LjA0OTIzIDIwLjE3OTRaTTE3LjI3MDIgMTAuNDYzOEMxNi44MjY3IDEwLjQ2MzggMTYuMzkzMyAxMC4zMzIyIDE2LjAyNDYgMTAuMDg1OUMxNS42NTU5IDkuODM5NTQgMTUuMzY4NSA5LjQ4OTM3IDE1LjE5ODggOS4wNzk2OUMxNS4wMjkxIDguNjcgMTQuOTg0NyA4LjIxOTIgMTUuMDcxMiA3Ljc4NDI3QzE1LjE1NzYgNy4zNDkzNSAxNS4zNzEyIDYuOTQ5ODUgMTUuNjg0OCA2LjYzNjI5QzE1Ljk5ODQgNi4zMjI3MyAxNi4zOTc5IDYuMTA5MTkgMTYuODMyNyA2LjAyMjY4QzE3LjI2NzcgNS45MzYxNyAxNy43MTg1IDUuOTgwNTggMTguMTI4MSA2LjE1MDI3QzE4LjUzNzkgNi4zMTk5NyAxOC44ODgxIDYuNjA3MzQgMTkuMTM0NCA2Ljk3NjA1QzE5LjM4MDcgNy4zNDQ3NiAxOS41MTIzIDcuNzc4MjMgMTkuNTEyMyA4LjIyMTY4QzE5LjUxMjMgOC44MTYzMiAxOS4yNzYgOS4zODY2IDE4Ljg1NTYgOS44MDcwNkMxOC40MzUxIDEwLjIyNzUgMTcuODY0OCAxMC40NjM4IDE3LjI3MDIgMTAuNDYzOFoiIGZpbGw9IiM0MjQyNDIiLz4KPC9zdmc+Cg==" +} + +export class GitPlugin extends ViewPlugin { + + constructor() { + + super(profile) + } + + onDeactivation(): void { + this.call('fileDecorator', 'clearFileDecorators') + this.call('manager', 'activatePlugin', 'dgitApi') + } + + async open(panel:string) { + this.emit('openPanel', panel) + } + + render() { + return
+ } + +} diff --git a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json index 5f033c3aad..9c189262e8 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json +++ b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json @@ -78,7 +78,7 @@ "filePanel.checkoutGitBranch": "Checkout Git Branch", "filePanel.findOrCreateABranch": "Find or create a branch.", "filePanel.initGitRepositoryLabel": "Initialize workspace as a new git repository", - "filePanel.initGitRepositoryWarning": "To use Git features, add username and email to the Github section of the Settings panel.", + "filePanel.initGitRepositoryWarning": "To use Git features, add username and email to the Github section of the Git plugin.", "filePanel.workspaceName": "Workspace name", "filePanel.customizeTemplate": "Customize template", "filePanel.features": "Features", diff --git a/apps/remix-ide/src/app/tabs/locales/en/git.json b/apps/remix-ide/src/app/tabs/locales/en/git.json new file mode 100644 index 0000000000..c5f4fa6a09 --- /dev/null +++ b/apps/remix-ide/src/app/tabs/locales/en/git.json @@ -0,0 +1,20 @@ +{ + "git.push": "push", + "git.pull": "pull", + "git.commit": "commit", + "git.sync": "sync", + "git.syncchanges": "sync changes", + "git.publish": "publish", + "git.ignore": "ignore", + "git.createBranch": "create branch", + "git.deleteBranch": "delete branch", + "git.mergeBranch": "merge branch", + "git.rebaseBranch": "rebase branch", + "git.checkout": "checkout", + "git.fetch": "fetch", + "git.refresh": "refresh", + "git.unstageall": "unstage all", + "git.stageall": "stage all", + "git.noremote": "this repo has no remotes", + "git.init": "Initialize repository" +} \ No newline at end of file diff --git a/apps/remix-ide/src/app/udapp/run-tab.js b/apps/remix-ide/src/app/udapp/run-tab.js index 515e0093b9..837e8d97ba 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.js +++ b/apps/remix-ide/src/app/udapp/run-tab.js @@ -161,7 +161,6 @@ export class RunTab extends ViewPlugin { await addProvider(position, name, displayName, true, false, false) } const registerInjectedProvider = async (event) => { - console.log('registerInjectedProvider', event) const name = 'injected-' + event.detail.info.name const displayName = 'Injected Provider - ' + event.detail.info.name await this.engine.register([new InjectedProviderDefault(event.detail.provider, name)]) diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index c52b50c081..a307711b10 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -35,7 +35,7 @@ let requiredModules = [ // services + layout views + system views 'pluginManager', 'tabs', 'udapp', - 'dGitProvider', + 'dgitApi', 'solidity', 'solidity-logic', 'gistHandler', @@ -77,6 +77,7 @@ let requiredModules = [ // services + layout views + system views 'doc-gen', 'remix-templates', 'solhint', + 'dgit', 'pinnedPanel', 'pluginStateLogger' ] @@ -247,6 +248,7 @@ export class RemixAppManager extends PluginManager { const res = await fetch(this.pluginsDirectory) plugins = await res.json() plugins = plugins.filter((plugin) => { + if (plugin.name === 'dgit') return false if (plugin.targets && Array.isArray(plugin.targets) && plugin.targets.length > 0) { return plugin.targets.includes('remix') } diff --git a/apps/remix-ide/src/remixEngine.js b/apps/remix-ide/src/remixEngine.js index baaf75deda..4806f3719a 100644 --- a/apps/remix-ide/src/remixEngine.js +++ b/apps/remix-ide/src/remixEngine.js @@ -10,7 +10,7 @@ export class RemixEngine extends Engine { setPluginOption ({ name, kind }) { if (kind === 'provider') return { queueTimeout: 60000 * 2 } if (name === 'LearnEth') return { queueTimeout: 60000 } - if (name === 'dGitProvider') return { queueTimeout: 60000 * 4 } + if (name === 'dgitApi') return { queueTimeout: 60000 * 4 } if (name === 'slither') return { queueTimeout: 60000 * 4 } // Requires when a solc version is installed if (name === 'hardhat') return { queueTimeout: 60000 * 4 } if (name === 'truffle') return { queueTimeout: 60000 * 4 } diff --git a/apps/remixdesktop/src/plugins/isoGitPlugin.ts b/apps/remixdesktop/src/plugins/isoGitPlugin.ts index 62a3451a63..fad68d02da 100644 --- a/apps/remixdesktop/src/plugins/isoGitPlugin.ts +++ b/apps/remixdesktop/src/plugins/isoGitPlugin.ts @@ -6,6 +6,7 @@ import git from 'isomorphic-git' import { dialog } from "electron"; import http from 'isomorphic-git/http/web' import { gitProxy } from "../tools/git"; +import { remote } from "../types"; const profile: Profile = { name: 'isogit', @@ -328,9 +329,9 @@ class IsoGitPluginClient extends ElectronBasePluginClient { async clone(cmd: any) { if (this.gitIsInstalled) { - try{ + try { await gitProxy.clone(cmd.url, cmd.dir) - }catch(e){ + } catch (e) { throw e } } else { @@ -376,8 +377,9 @@ class IsoGitPluginClient extends ElectronBasePluginClient { if (!this.workingDir || this.workingDir === '') { return [] } - let remotes = [] - remotes = await git.listRemotes({ ...await this.getGitConfig() }) + let remotes: remote[] = [] + remotes = (await git.listRemotes({ ...await this.getGitConfig() })).map((remote) => { return { name: remote.remote, url: remote.url } } + ) return remotes } @@ -408,10 +410,10 @@ class IsoGitPluginClient extends ElectronBasePluginClient { for (const remote of remotes) { cmd = { ...cmd, - remote: remote.remote + remote: remote.name } - const remotebranches = (await git.listBranches(cmd)).map((branch) => { return { remote: remote.remote, name: branch } }) + const remotebranches = (await git.listBranches(cmd)).map((branch) => { return { remote: remote.name, name: branch } }) branches = [...branches, ...remotebranches] } diff --git a/apps/remixdesktop/src/types/index.ts b/apps/remixdesktop/src/types/index.ts new file mode 100644 index 0000000000..8c0087b62e --- /dev/null +++ b/apps/remixdesktop/src/types/index.ts @@ -0,0 +1,9 @@ +export type branch = { + name: string + remote: remote +} + +export type remote = { + name: string + url: string +} \ No newline at end of file diff --git a/apps/vyper/src/app/utils/remix-client.tsx b/apps/vyper/src/app/utils/remix-client.tsx index cbfa5eb87e..91bfc41ed2 100644 --- a/apps/vyper/src/app/utils/remix-client.tsx +++ b/apps/vyper/src/app/utils/remix-client.tsx @@ -5,9 +5,11 @@ import {PluginClient} from '@remixproject/plugin' import {Contract, compileContract} from './compiler' import {ExampleContract} from '../components/VyperResult' import EventEmitter from 'events' +import { Plugin } from "@remixproject/engine"; +import { CustomRemixApi } from '@remix-api' export type VyperComplierAddress = 'https://vyper2.remixproject.org/' | 'http://localhost:8000/' -export class RemixClient extends PluginClient { +export class RemixClient extends PluginClient { private client = createClient>(this) compilerUrl: VyperComplierAddress = 'https://vyper2.remixproject.org/' compilerOutput: any @@ -80,15 +82,23 @@ export class RemixClient extends PluginClient { async cloneVyperRepo() { try { // @ts-ignore - this.call('notification', 'toast', 'cloning Snekmate Vyper repository...') - await this.call('manager', 'activatePlugin', 'dGitProvider') + this.call('notification', 'toast', 'cloning Snekmate Vyper repository...') await this.call( - 'dGitProvider', + 'dgitApi', 'clone', - {url: 'https://github.com/pcaversaccio/snekmate', token: null, branch: 'v0.0.5'}, - // @ts-ignore - 'snekmate' + {url: 'https://github.com/pcaversaccio/snekmate', token: null, branch: 'main', singleBranch: false, workspaceName: 'snekmate'}, + ) + + await this.call( + 'dgitApi', + 'checkout', + { + ref:'v0.0.5', + force: true, + refresh: true, + } ) + this.call( // @ts-ignore 'notification', diff --git a/apps/vyper/src/main.tsx b/apps/vyper/src/main.tsx index 374becdd57..cc6581c6be 100644 --- a/apps/vyper/src/main.tsx +++ b/apps/vyper/src/main.tsx @@ -6,8 +6,8 @@ import App from './app/app' const container = document.getElementById('root'); if (container) { - createRoot(container).render( + createRoot(container).render( - ); + ); } diff --git a/libs/remix-api/src/index.ts b/libs/remix-api/src/index.ts new file mode 100644 index 0000000000..71e343fc8a --- /dev/null +++ b/libs/remix-api/src/index.ts @@ -0,0 +1 @@ +export * from './lib/remix-api' \ No newline at end of file diff --git a/libs/remix-api/src/lib/plugins/config-api.ts b/libs/remix-api/src/lib/plugins/config-api.ts new file mode 100644 index 0000000000..e5f072712f --- /dev/null +++ b/libs/remix-api/src/lib/plugins/config-api.ts @@ -0,0 +1,11 @@ +import { StatusEvents } from "@remixproject/plugin-utils" + +export interface IConfigApi { + events: { + configChanged: () => void + } & StatusEvents, + methods: { + getAppParameter(key: string): Promise, + setAppParameter(key: string, value: any): Promise + } +} \ No newline at end of file diff --git a/libs/remix-api/src/lib/plugins/fileSystem-api.ts b/libs/remix-api/src/lib/plugins/fileSystem-api.ts new file mode 100644 index 0000000000..04d0a2a0af --- /dev/null +++ b/libs/remix-api/src/lib/plugins/fileSystem-api.ts @@ -0,0 +1,10 @@ +import { commitChange } from "@remix-ui/git"; +import { IFileSystem } from "@remixproject/plugin-api" + +// Extended interface with 'diff' method +export interface IExtendedFileSystem extends IFileSystem { + methods: IFileSystem['methods'] & { + /** Compare the differences between two files */ + diff(change: commitChange): Promise + }; +} \ No newline at end of file diff --git a/libs/remix-api/src/lib/plugins/filedecorator-api.ts b/libs/remix-api/src/lib/plugins/filedecorator-api.ts new file mode 100644 index 0000000000..a787489002 --- /dev/null +++ b/libs/remix-api/src/lib/plugins/filedecorator-api.ts @@ -0,0 +1,11 @@ +import { fileDecoration } from '@remix-ui/file-decorators' +import { StatusEvents } from '@remixproject/plugin-utils' + +export interface IFileDecoratorApi { + events: { + } & StatusEvents + methods: { + clearFileDecorators(path?: string): void + setFileDecorators(decorators: fileDecoration[]): void + } +} diff --git a/libs/remix-api/src/lib/plugins/notification-api.ts b/libs/remix-api/src/lib/plugins/notification-api.ts new file mode 100644 index 0000000000..8d5b2b61a3 --- /dev/null +++ b/libs/remix-api/src/lib/plugins/notification-api.ts @@ -0,0 +1,31 @@ +import { ModalTypes } from "@remix-ui/app" +import { StatusEvents } from "@remixproject/plugin-utils" + +export interface INotificationApi { + events: { + + } & StatusEvents, + methods: { + toast(key: string): Promise, + alert({ + title, + message, + id + }:{ + title: string, + message: string, + id: string + }): Promise, + modal({ + title, + message, + okLabel, + type + }:{ + title: string, + message: string, + okLabel: string, + type: ModalTypes + }): Promise, + } +} \ No newline at end of file diff --git a/libs/remix-api/src/lib/plugins/settings-api.ts b/libs/remix-api/src/lib/plugins/settings-api.ts new file mode 100644 index 0000000000..dd7323ac73 --- /dev/null +++ b/libs/remix-api/src/lib/plugins/settings-api.ts @@ -0,0 +1,11 @@ +import { StatusEvents } from '@remixproject/plugin-utils' + +export interface ISettings { + events: { + configChanged: () => void, + } & StatusEvents + methods: { + getGithubAccessToken(): string + get(key: string): Promise + } +} diff --git a/libs/remix-api/src/lib/remix-api.ts b/libs/remix-api/src/lib/remix-api.ts new file mode 100644 index 0000000000..8469d9e057 --- /dev/null +++ b/libs/remix-api/src/lib/remix-api.ts @@ -0,0 +1,19 @@ +import { IGitApi } from "@remix-ui/git" +import { IRemixApi } from "@remixproject/plugin-api" +import { StatusEvents } from "@remixproject/plugin-utils" +import { IConfigApi } from "./plugins/config-api" +import { IFileDecoratorApi } from "./plugins/filedecorator-api" +import { IExtendedFileSystem } from "./plugins/fileSystem-api" +import { INotificationApi } from "./plugins/notification-api" +import { ISettings } from "./plugins/settings-api" + +export interface ICustomRemixApi extends IRemixApi { + dgitApi: IGitApi + config: IConfigApi + notification: INotificationApi + settings: ISettings + fileDecorator: IFileDecoratorApi + fileManager: IExtendedFileSystem +} + +export declare type CustomRemixApi = Readonly \ No newline at end of file diff --git a/libs/remix-ui/editor/src/lib/actions/editor.ts b/libs/remix-ui/editor/src/lib/actions/editor.ts index d533823af1..2ba1f57611 100644 --- a/libs/remix-ui/editor/src/lib/actions/editor.ts +++ b/libs/remix-ui/editor/src/lib/actions/editor.ts @@ -1,20 +1,21 @@ import { monacoTypes } from '@remix-ui/editor'; +import { commitChange } from '@remix-ui/git'; export interface Action { type: string; payload: Record monaco: any, - editor: any + editors: any[] } export const initialState = {} export const reducerActions = (models = initialState, action: Action) => { const monaco = action.monaco - const editor = action.editor + const editors = action.editors as any[] switch (action.type) { case 'ADD_MODEL': { - if (!editor) return models + if (!editors) return models const uri = action.payload.uri const value = action.payload.value const language = action.payload.language @@ -22,6 +23,7 @@ export const reducerActions = (models = initialState, action: Action) => { if (models[uri]) return models // already existing models[uri] = { language, uri, readOnly } let model + try { model = monaco.editor.createModel(value, language, monaco.Uri.parse(uri)) } catch (e) { @@ -38,8 +40,12 @@ export const reducerActions = (models = initialState, action: Action) => { delete models[uri] return models } + case 'ADD_DIFF': { + if (!editors) return models + return models + } case 'SET_VALUE': { - if (!editor) return models + if (!editors) return models const uri = action.payload.uri const value = action.payload.value const model = models[uri]?.model @@ -49,15 +55,19 @@ export const reducerActions = (models = initialState, action: Action) => { return models } case 'REVEAL_LINE': { - if (!editor) return models + if (!editors) return models const line = action.payload.line const column = action.payload.column - editor.revealLine(line) - editor.setPosition({ column, lineNumber: line }) + + editors.map((editor) => { + + editor.revealLine(line) + editor.setPosition({ column, lineNumber: line }) + }) return models } case 'REVEAL_RANGE': { - if (!editor) return models + if (!editors) return models const range: monacoTypes.IRange = { startLineNumber: action.payload.startLineNumber + 1, startColumn: action.payload.startColumn, @@ -66,48 +76,60 @@ export const reducerActions = (models = initialState, action: Action) => { } // reset to start of line if (action.payload.startColumn < 100) { - editor.revealRange({ + editors.map(editor => editor.revealRange({ startLineNumber: range.startLineNumber, startColumn: 1, endLineNumber: range.endLineNumber, endColumn: 1 - }) + })) } else { - editor.revealRangeInCenter(range) + editors.map(editor => editor.revealRangeInCenter(range)) } return models } case 'FOCUS': { - if (!editor) return models - editor.focus() + if (!editors) return models + editors.map(editor => editor.focus()) return models } case 'SET_FONTSIZE': { - if (!editor) return models + if (!editors) return models const size = action.payload.size - if (size === 1) { - editor.trigger('keyboard', 'editor.action.fontZoomIn', {}); - } else { - editor.trigger('keyboard', 'editor.action.fontZoomOut', {}); - } + editors.map((editor) => { + if (size === 1) { + editor.trigger('keyboard', 'editor.action.fontZoomIn', {}); + } else { + editor.trigger('keyboard', 'editor.action.fontZoomOut', {}); + } + }) return models } case 'SET_WORDWRAP': { - if (!editor) return models + if (!editors) return models const wrap = action.payload.wrap - editor.updateOptions({ wordWrap: wrap ? 'on' : 'off' }) + editors.map(editor => + editor.updateOptions({ wordWrap: wrap ? 'on' : 'off' })) return models } } } -export const reducerListener = (plugin, dispatch, monaco, editor, events) => { +export const reducerListener = (plugin, dispatch, monaco, editors: any[], events) => { plugin.on('editor', 'addModel', (value, language, uri, readOnly) => { dispatch({ type: 'ADD_MODEL', payload: { uri, value, language, readOnly, events }, monaco, - editor + editors + }) + }) + + plugin.on('editor', 'addDiff', (value: commitChange) => { + dispatch({ + type: 'ADD_DIFF', + payload: { value }, + monaco, + editors }) }) @@ -116,7 +138,7 @@ export const reducerListener = (plugin, dispatch, monaco, editor, events) => { type: 'DISPOSE_MODEL', payload: { uri }, monaco, - editor + editors }) }) @@ -125,7 +147,7 @@ export const reducerListener = (plugin, dispatch, monaco, editor, events) => { type: 'SET_VALUE', payload: { uri, value }, monaco, - editor + editors }) }) @@ -134,7 +156,7 @@ export const reducerListener = (plugin, dispatch, monaco, editor, events) => { type: 'REVEAL_LINE', payload: { line, column }, monaco, - editor + editors }) }) @@ -148,7 +170,7 @@ export const reducerListener = (plugin, dispatch, monaco, editor, events) => { endColumn }, monaco, - editor + editors }) }) @@ -157,7 +179,7 @@ export const reducerListener = (plugin, dispatch, monaco, editor, events) => { type: 'FOCUS', payload: {}, monaco, - editor + editors }) }) @@ -166,7 +188,7 @@ export const reducerListener = (plugin, dispatch, monaco, editor, events) => { type: 'SET_FONTSIZE', payload: { size }, monaco, - editor + editors }) }) @@ -175,7 +197,7 @@ export const reducerListener = (plugin, dispatch, monaco, editor, events) => { type: 'SET_WORDWRAP', payload: { wrap }, monaco, - editor + editors }) }) } diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx index ed28f65618..17840aacae 100644 --- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx +++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx @@ -1,7 +1,7 @@ import React, { useState, useRef, useEffect, useReducer } from 'react' // eslint-disable-line import { FormattedMessage, useIntl } from 'react-intl' import { isArray } from 'lodash' -import Editor, { loader, Monaco } from '@monaco-editor/react' +import Editor, { DiffEditor, loader, Monaco } from '@monaco-editor/react' import { AlertModal } from '@remix-ui/app' import { ConsoleLogs, QueryParams } from '@remix-project/remix-lib' import { reducerActions, reducerListener, initialState } from './actions/editor' @@ -135,6 +135,8 @@ export interface EditorUIProps { activated: boolean themeType: string currentFile: string + currentDiffFile: string + isDiff: boolean events: { onBreakPointAdded: (file: string, line: number) => void onBreakPointCleared: (file: string, line: number) => void @@ -147,6 +149,8 @@ export interface EditorUIProps { export const EditorUI = (props: EditorUIProps) => { const intl = useIntl() const [, setCurrentBreakpoints] = useState({}) + const [isDiff, setIsDiff] = useState(false) + const [isSplit, setIsSplit] = useState(true) const defaultEditorValue = ` \t\t\t\t\t\t\t ____ _____ __ __ ___ __ __ ___ ____ _____ \t\t\t\t\t\t\t| _ \\ | ____| | \\/ | |_ _| \\ \\/ / |_ _| | _ \\ | ____| @@ -171,6 +175,8 @@ export const EditorUI = (props: EditorUIProps) => { const pasteCodeRef = useRef(false) const editorRef = useRef(null) const monacoRef = useRef(null) + const diffEditorRef = useRef(null) + const currentFunction = useRef('') const currentFileRef = useRef('') const currentUrlRef = useRef('') @@ -326,11 +332,19 @@ export const EditorUI = (props: EditorUIProps) => { }) useEffect(() => { - if (!editorRef.current || !props.currentFile) return + if (!(editorRef.current || diffEditorRef.current ) || !props.currentFile) return currentFileRef.current = props.currentFile props.plugin.call('fileManager', 'getUrlFromPath', currentFileRef.current).then((url) => (currentUrlRef.current = url.file)) const file = editorModelsState[props.currentFile] + + props.isDiff && diffEditorRef && diffEditorRef.current && diffEditorRef.current.setModel({ + original: editorModelsState[props.currentDiffFile].model, + modified: file.model + }) + + props.isDiff && diffEditorRef.current.getModifiedEditor().updateOptions({ readOnly: editorModelsState[props.currentFile].readOnly }) + editorRef.current.setModel(file.model) editorRef.current.updateOptions({ readOnly: editorModelsState[props.currentFile].readOnly, @@ -348,7 +362,7 @@ export const EditorUI = (props: EditorUIProps) => { } else if (file.language === 'toml') { monacoRef.current.editor.setModelLanguage(file.model, 'remix-toml') } - }, [props.currentFile]) + }, [props.currentFile, props.isDiff]) const convertToMonacoDecoration = (decoration: lineText | sourceAnnotation | sourceMarker, typeOfDecoration: string) => { if (typeOfDecoration === 'sourceAnnotationsPerFile') { @@ -520,6 +534,7 @@ export const EditorUI = (props: EditorUIProps) => { for (const filePath in allMarkersPerfile) { const model = editorModelsState[filePath]?.model if (model) { + console.log('MONACO REF CURRENT', monacoRef.current) monacoRef.current.editor.setModelMarkers(model, from, allMarkersPerfile[filePath]) } } @@ -545,6 +560,7 @@ export const EditorUI = (props: EditorUIProps) => { props.editorAPI.getValue = (uri: string) => { if (!editorRef.current) return + const model = editorModelsState[uri]?.model if (model) { return model.getValue() @@ -614,10 +630,21 @@ export const EditorUI = (props: EditorUIProps) => { } } + function setReducerListener() { + if (diffEditorRef.current && diffEditorRef.current.getModifiedEditor() && editorRef.current){ + reducerListener(props.plugin, dispatch, monacoRef.current, [diffEditorRef.current.getModifiedEditor(), editorRef.current], props.events) + } + } + + function handleDiffEditorDidMount(editor: any) { + diffEditorRef.current = editor + setReducerListener() + } + function handleEditorDidMount(editor) { editorRef.current = editor defineAndSetTheme(monacoRef.current) - reducerListener(props.plugin, dispatch, monacoRef.current, editorRef.current, props.events) + setReducerListener() props.events.onEditorMounted() editor.onMouseUp((e) => { // see https://microsoft.github.io/monaco-editor/typedoc/enums/editor.MouseTargetType.html @@ -928,8 +955,22 @@ export const EditorUI = (props: EditorUIProps) => { return (
+ + { } }} defaultValue={defaultEditorValue} + className={props.isDiff ? "d-none" : "d-block"} /> {editorModelsState[props.currentFile]?.readOnly && ( diff --git a/libs/remix-ui/git/src/components/branchHeader.tsx b/libs/remix-ui/git/src/components/branchHeader.tsx new file mode 100644 index 0000000000..debb86bd5a --- /dev/null +++ b/libs/remix-ui/git/src/components/branchHeader.tsx @@ -0,0 +1,70 @@ +import React, { useEffect, useState } from 'react' +import { gitActionsContext, pluginActionsContext } from '../state/context' +import { ReadCommitResult } from "isomorphic-git" +import { gitPluginContext } from './gitui' +export const BranchHeader = () => { + + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + const pluginActions = React.useContext(pluginActionsContext) + const [changed, setChanged] = useState(false) + const [isDetached, setIsDetached] = useState(false) + const [latestCommit, setLatestCommit] = useState(null) + + useEffect(() => { + if (context.currentBranch) { + actions.getBranchDifferences(context.currentBranch, null, context) + } + if (!context.currentBranch || (context.currentBranch && context.currentBranch.name === '')) { + if (context.currentHead === '') { + setIsDetached(false) + } else { + setIsDetached(true) + } + } else { + setIsDetached(false) + } + setLatestCommit(null) + if (context.currentHead !== '') { + if (context.commits && context.commits.length > 0) { + const commit = context.commits.find(commit => commit.oid === context.currentHead) + if (commit) { + setLatestCommit(commit) + } + } + } + }, [context.currentBranch, context.commits, context.branches, context.remotes, context.currentHead]) + + useEffect(() => { + if (context.fileStatusResult) { + const total = context.allchangesnotstaged.length + const badges = total + context.staged.length + setChanged((context.deleted.length > 0 || context.staged.length > 0 || context.untracked.length > 0 || context.modified.length > 0)) + } + }, [context.fileStatusResult, context.modified, context.allchangesnotstaged, context.untracked, context.deleted]) + + const showDetachedWarningText = async () => { + await pluginActions.showAlert({ + message: `You are in 'detached HEAD' state. This means you are not on a branch because you checkout a tag or a specific commit. If you want to commit changes, you will need to create a new branch.`, + title: 'Warning' + }) + } + + return (<> +
+
+ + {changed ? '*' : ''}{context.currentBranch && context.currentBranch.name} +
+ {latestCommit ? +
+ {latestCommit.commit && latestCommit.commit.message ? latestCommit.commit.message : ''} +
: null} + {isDetached ? +
+ You are in a detached state +
: null} +
+
+ ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/buttons/commitmessage.tsx b/libs/remix-ui/git/src/components/buttons/commitmessage.tsx new file mode 100644 index 0000000000..17fc807a79 --- /dev/null +++ b/libs/remix-ui/git/src/components/buttons/commitmessage.tsx @@ -0,0 +1,147 @@ +import React, { useEffect } from "react" +import { useState } from "react" +import { gitActionsContext } from "../../state/context" +import { gitPluginContext } from "../gitui" +import { faArrowDown, faArrowUp, faCheck, faCloudArrowUp, faSync } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { syncStateContext } from "./sourceControlBase"; + +enum buttonStateValues { + Commit, + Sync = 1, + PublishBranch = 2 +} + +export const CommitMessage = () => { + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + const syncState = React.useContext(syncStateContext) + const [buttonState, setButtonState] = useState(buttonStateValues.Commit) + + const [message, setMessage] = useState({ value: '' }) + + const handleChange = (e: React.ChangeEvent) => { + setMessage({ value: e.currentTarget.value }) + } + + const commit = async () => { + if (context.staged.length === 0 && context.allchangesnotstaged.length == 0) return + if (context.staged.length === 0) + await actions.addall(context.allchangesnotstaged) + await actions.commit(message.value) + setMessage({ value: '' }) + } + + const getRemote = () => { + return context.upstream ? context.upstream : context.defaultRemote ? context.defaultRemote : null + } + + const sync = async () => { + await actions.pull({ + remote: getRemote(), + ref: context.currentBranch + }) + await actions.push({ + remote: getRemote(), + ref: context.currentBranch + }) + await actions.pull({ + remote: getRemote(), + ref: context.currentBranch + }) + } + + const commitNotAllowed = () => { + return context.canCommit === false || message.value === "" || (context.staged.length === 0 && context.allchangesnotstaged.length == 0) + } + + const commitMessagePlaceholder = () => { + if (context.currentBranch === undefined || context.currentBranch.name === "") + return `message` + return `message ( commit on ${context.currentBranch.name} )` + } + + const syncEnabled = () => { + return syncState.commitsAhead.length > 0 || syncState.commitsBehind.length > 0 + } + + const upDownArrows = () => { + return ( + <> + {syncState.commitsBehind && syncState.commitsBehind.length ? <>{syncState.commitsBehind.length} : null} + {syncState.commitsAhead && syncState.commitsAhead.length ? <>{syncState.commitsAhead.length} : null} + + ) + } + + const publishEnabled = () => { + const remoteEquivalentBranch = context.branches.find((b) => b.name === context.currentBranch.name && b.remote) + return remoteEquivalentBranch === undefined && getRemote() !== null + } + + const publishBranch = async () => { + if (context.currentBranch === undefined || context.currentBranch.name === "") + return + await actions.push({ + remote: getRemote(), + ref: context.currentBranch + }) + await actions.fetch({ + remote: getRemote(), + ref: context.currentBranch, + singleBranch: false, + relative: true + }) + + } + + const messageEnabled = () => { + return context.canCommit && (context.allchangesnotstaged.length > 0 || context.staged.length > 0) + } + + const setButtonStateValues = () => { + + if (!commitNotAllowed() || context.allchangesnotstaged.length > 0 || context.staged.length > 0) { + if (context.allchangesnotstaged.length == 0 && context.staged.length == 0 && message.value === "" && publishEnabled()) { + setButtonState(buttonStateValues.PublishBranch) + return + } + setButtonState(buttonStateValues.Commit) + return + } + if (syncEnabled()) { + setButtonState(buttonStateValues.Sync) + return + } + if (publishEnabled()) { + setButtonState(buttonStateValues.PublishBranch) + return + } + setButtonState(buttonStateValues.Commit) + } + + useEffect(() => { + setButtonStateValues() + }, [context.canCommit, context.staged, context.allchangesnotstaged, context.currentBranch, syncState.commitsAhead, syncState.commitsBehind, message.value]) + + return ( + <> +
+ +
+ + + +
+ + ); +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/buttons/gituibutton.tsx b/libs/remix-ui/git/src/components/buttons/gituibutton.tsx new file mode 100644 index 0000000000..7556829c13 --- /dev/null +++ b/libs/remix-ui/git/src/components/buttons/gituibutton.tsx @@ -0,0 +1,24 @@ +import React, { useContext } from 'react' +import { gitPluginContext } from '../gitui' + +interface ButtonWithContextProps { + onClick: React.MouseEventHandler; + children: React.ReactNode; + disabledCondition?: boolean; // Optional additional disabling condition + // You can add other props if needed, like 'type', 'className', etc. + [key: string]: any; // Allow additional props to be passed +} + +// This component extends a button, disabling it when loading is true +const GitUIButton = ({ children, disabledCondition = false, ...rest }:ButtonWithContextProps) => { + const { loading } = React.useContext(gitPluginContext) + + const isDisabled = loading || disabledCondition + return ( + + ); +}; + +export default GitUIButton; \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/buttons/sourceControlBase.tsx b/libs/remix-ui/git/src/components/buttons/sourceControlBase.tsx new file mode 100644 index 0000000000..7856059c2c --- /dev/null +++ b/libs/remix-ui/git/src/components/buttons/sourceControlBase.tsx @@ -0,0 +1,90 @@ +import { faArrowDown, faArrowUp, faArrowsUpDown, faArrowRotateRight } from "@fortawesome/free-solid-svg-icons" +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" +import { CustomTooltip } from "@remix-ui/helper" +import { ReadCommitResult } from "isomorphic-git" +import React, { createContext, useEffect, useState } from "react" +import { FormattedMessage } from "react-intl" +import { gitActionsContext } from "../../state/context" +import { branch, remote } from "../../types" +import { gitPluginContext } from "../gitui" +import GitUIButton from "./gituibutton" + +interface SourceControlButtonsProps { + remote?: remote, + branch?: branch, + children: React.ReactNode +} + +export const syncStateContext = createContext<{ + commitsAhead: ReadCommitResult[], + commitsBehind: ReadCommitResult[] + branch: branch, + remote: remote +}> +({ commitsAhead: [], commitsBehind: [], branch: undefined, remote: undefined }) + +export const SourceControlBase = (props: SourceControlButtonsProps) => { + const [branch, setBranch] = useState(props.branch) + const [remote, setRemote] = useState(props.remote) + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + const [commitsAhead, setCommitsAhead] = useState([]) + const [commitsBehind, setCommitsBehind] = useState([]) + + useEffect(() => { + + setDefaultRemote() + if (remote && branch && context.branchDifferences && context.branchDifferences[`${remote.name}/${branch.name}`]) { + setCommitsAhead(context.branchDifferences[`${remote.name}/${branch.name}`]?.uniqueHeadCommits) + setCommitsBehind(context.branchDifferences[`${remote.name}/${branch.name}`]?.uniqueRemoteCommits) + } else { + setCommitsAhead([]) + setCommitsBehind([]) + } + }, [context.branchDifferences, context.currentBranch, branch, remote]) + + const setDefaultRemote = () => { + + if (context.remotes.length > 0) { + // find remote called origin + const origin = context.remotes.find(remote => remote.name === 'origin') + if (origin) { + setRemote(origin) + } else { + setRemote(context.remotes[0]) + } + return origin + } + return null + } + + useEffect(() => { + if (!props.branch) { + setBranch(context.currentBranch) + } + if (!props.remote) { + setRemote(context.defaultRemote) + } else { + setDefaultRemote() + } + }, []) + + useEffect(() => { + + if (!props.branch) { + setBranch(context.currentBranch) + } + if (!props.remote) { + setRemote(context.defaultRemote) + } else { + setDefaultRemote() + } + }, [context.defaultRemote, context.currentBranch]) + + return (<> + + {props.children} + + ) + +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/buttons/sourcecontrolbuttons.tsx b/libs/remix-ui/git/src/components/buttons/sourcecontrolbuttons.tsx new file mode 100644 index 0000000000..b01cc67a40 --- /dev/null +++ b/libs/remix-ui/git/src/components/buttons/sourcecontrolbuttons.tsx @@ -0,0 +1,98 @@ +import { faArrowDown, faArrowUp, faArrowsUpDown, faArrowRotateRight } from "@fortawesome/free-solid-svg-icons" +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" +import { CustomTooltip } from "@remix-ui/helper" +import React, { useEffect, useState } from "react" +import { FormattedMessage } from "react-intl" +import { gitActionsContext } from "../../state/context" +import { branch, remote } from "../../types" +import { gitPluginContext } from "../gitui" +import GitUIButton from "./gituibutton" +import { syncStateContext } from "./sourceControlBase" + +export const SourceControlButtons = () => { + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + const syncState = React.useContext(syncStateContext) + const [branch, setBranch] = useState(syncState.branch) + const [remote, setRemote] = useState(syncState.remote) + + const getRemote = () => { + return remote ? remote : context.upstream ? context.upstream : context.defaultRemote ? context.defaultRemote : null + } + + const getRemoteName = () => { + return getRemote() ? getRemote().name : '' + } + + const pull = async () => { + await actions.pull({ + remote: getRemote(), + ref: branch ? branch : context.currentBranch + }) + } + + const push = async () => { + await actions.push({ + remote: getRemote(), + ref: branch ? branch : context.currentBranch + }) + await actions.fetch({ + remote: getRemote(), + ref: branch ? branch : context.currentBranch, + relative: false, + depth: 1, + singleBranch: true + }) + } + + const sync = async () => { + await pull() + await push() + } + + const refresh = async() => { + await actions.getFileStatusMatrix(null) + await actions.gitlog() + } + + const buttonsDisabled = () => { + return (!context.upstream) || context.remotes.length === 0 + } + + const getTooltipText = (id: string) => { + if (buttonsDisabled()) return + return <> {getRemoteName()} + } + + return ( + + + +
+ {syncState.commitsBehind.length ?
+ {syncState.commitsBehind.length} +
: null} + +
+
+
+ + +
+ {syncState.commitsAhead.length ?
+ {syncState.commitsAhead.length} +
: null} + +
+
+
+ + + + }> + + +
+ + ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/disabled.tsx b/libs/remix-ui/git/src/components/disabled.tsx new file mode 100644 index 0000000000..fbd54d6177 --- /dev/null +++ b/libs/remix-ui/git/src/components/disabled.tsx @@ -0,0 +1,12 @@ +import React, { useEffect, useState } from 'react' + +export const Disabled = () => { + + return ( +
+ Git is currently disabled.

+ If you are using RemixD you can use git on the terminal.

+
+ ) + +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/github/branchselect.tsx b/libs/remix-ui/git/src/components/github/branchselect.tsx new file mode 100644 index 0000000000..a90d259369 --- /dev/null +++ b/libs/remix-ui/git/src/components/github/branchselect.tsx @@ -0,0 +1,50 @@ +import React, { useState, useCallback, useEffect } from 'react'; +import Select from 'react-select'; +import { gitActionsContext } from '../../state/context'; +import { selectStyles, selectTheme } from '../../types/styles'; +import { gitPluginContext } from '../gitui'; + +interface BranchySelectProps { + select: (branch:{ name: string }) => void; +} + +export const BranchSelect = (props: BranchySelectProps) => { + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + const [branchOptions, setBranchOptions] = useState([]); + + useEffect(() => { + if (context.remoteBranches && context.remoteBranches.length > 0) { + const options = context.remoteBranches && context.remoteBranches.length > 0 && context.remoteBranches.map(branch => { + return { value: branch.name, label: branch.name } + } + ) + setBranchOptions(options) + } else { + setBranchOptions(null) + } + }, [context.remoteBranches]) + + const selectRemoteBranch = async (e: any) => { + if (!e || !e.value) { + props.select(null) + return + } + const value = e && e.value + props.select({ name: value.toString() }) + } + + return (<>{branchOptions && branchOptions.length ? + +
+ +
+
+

+ Step 2: Authorize the app here +

{gitHubResponse.verification_uri} +


+ Step 3: When you are done, click on the button below: + + + } + { + (context.gitHubUser && context.gitHubUser.login) ? +
+ +
: null + } + { + (context.gitHubUser && context.gitHubUser.login) ? +
+ + + Connected as {context.gitHubUser.login} + + + {context.gitHubUser.html_url} + {context.userEmails && context.userEmails.filter((email: any) => email.primary).map((email: any) => { + return

{email.email}
+ })} +
+
+
+ +
: null + } + + ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/github/repositoryselect.tsx b/libs/remix-ui/git/src/components/github/repositoryselect.tsx new file mode 100644 index 0000000000..c4f9da7864 --- /dev/null +++ b/libs/remix-ui/git/src/components/github/repositoryselect.tsx @@ -0,0 +1,87 @@ +import React, { useState, useEffect } from 'react'; +import { Button } from 'react-bootstrap'; +import Select from 'react-select'; +import { gitActionsContext } from '../../state/context'; +import { repository } from '../../types'; +import { selectStyles, selectTheme } from '../../types/styles'; +import { gitPluginContext } from '../gitui'; +import { TokenWarning } from '../panels/tokenWarning'; + +interface RepositorySelectProps { + select: (repo: repository) => void; +} + +const RepositorySelect = (props: RepositorySelectProps) => { + const [repoOtions, setRepoOptions] = useState([]); + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + const [loading, setLoading] = useState(false) + const [show, setShow] = useState(false) + + useEffect(() => { + if (context.repositories && context.repositories.length > 0) { + // map context.repositories to options + const options = context.repositories && context.repositories.length > 0 && context.repositories.map(repo => { + return { value: repo.id, label: repo.full_name } + }) + + setRepoOptions(options) + setShow(options.length > 0) + } else { + setRepoOptions(null) + setShow(false) + } + setLoading(false) + + }, [context.repositories]) + + const selectRepo = async (e: any) => { + if (!e || !e.value) { + props.select(null) + return + } + const value = e && e.value + + const repo = context.repositories.find(repo => { + return repo.id.toString() === value.toString() + }) + + if (repo) { + props.select(repo) + await actions.remoteBranches(repo.owner.login, repo.name) + } + } + + const fetchRepositories = async () => { + try { + setShow(true) + setLoading(true) + setRepoOptions([]) + await actions.repositories() + } catch (e) { + // do nothing + } + }; + + return ( + <> + { + show ? + + + actions.createBranch(newBranch.value)} + className="btn w-md-25 w-100 btn-primary" + id="createbranch-btn" + > + create new branch + + + + ); +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/branches/branchdifferencedetails.tsx b/libs/remix-ui/git/src/components/panels/branches/branchdifferencedetails.tsx new file mode 100644 index 0000000000..62ce46a696 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/branches/branchdifferencedetails.tsx @@ -0,0 +1,48 @@ +import { ReadCommitResult } from "isomorphic-git"; +import { Accordion } from "react-bootstrap"; +import React, { useEffect, useState } from "react"; +import { CommitDetails } from "../commits/commitdetails"; +import { CommitsNavigation } from "../../navigation/commits"; +import { branch, remote } from "../../../types"; +import { gitActionsContext } from "../../../state/context"; +import { gitPluginContext } from "../../gitui"; + +export interface BrancheDifferenceProps { + commits: ReadCommitResult[]; + title: string, + remote?: remote, + branch?: branch + ahead?: boolean, + behind?: boolean +} + +export const BranchDifferenceDetails = (props: BrancheDifferenceProps) => { + const { commits, title, branch, remote, ahead, behind } = props; + const [activePanel, setActivePanel] = useState(""); + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + + if (commits.length === 0) return null + + const getRemote = () => { + return remote ? remote : context.upstream ? context.upstream : context.defaultRemote ? context.defaultRemote : null + } + + const getCommitChanges = async (commit: ReadCommitResult) => { + await actions.getCommitChanges(commit.oid, commit.commit.parent[0], null, getRemote()) + } + + return ( + + + +
+ {commits && commits.map((commit, index) => { + return ( + {}} commit={commit}> + ); + })} +
+
+
) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/branches/branchdifferences.tsx b/libs/remix-ui/git/src/components/panels/branches/branchdifferences.tsx new file mode 100644 index 0000000000..846d0230d1 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/branches/branchdifferences.tsx @@ -0,0 +1,39 @@ +import { branch, remote } from "../../../types"; +import React, { useEffect, useState } from "react"; +import { gitPluginContext } from "../../gitui"; +import { CommitDetails } from "../commits/commitdetails"; +import { BranchDifferenceDetails } from "./branchdifferencedetails"; + +export interface BrancheDetailsProps { + branch: branch; + showSummary?: boolean; +} + +export const BranchDifferences = (props: BrancheDetailsProps) => { + const { branch, showSummary } = props; + const context = React.useContext(gitPluginContext) + + const getRemote = (): remote | null => { + return context.upstream ? context.upstream : context.defaultRemote ? context.defaultRemote : null + } + + const commitsAhead = (remote: remote) => { + if (!remote) return []; + return context.branchDifferences[`${remote.name}/${branch.name}`]?.uniqueHeadCommits || []; + } + + const commitsBehind = (remote: remote) => { + if (!remote) return []; + return context.branchDifferences[`${remote.name}/${branch.name}`]?.uniqueRemoteCommits || []; + } + + if (!getRemote()) return null; + + return ( + +
+ + + {commitsAhead(getRemote()).length === 0 && commitsBehind(getRemote()).length === 0 ? null :
} +
) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/branches/localbranchdetails.tsx b/libs/remix-ui/git/src/components/panels/branches/localbranchdetails.tsx new file mode 100644 index 0000000000..c3fe63e752 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/branches/localbranchdetails.tsx @@ -0,0 +1,86 @@ +import { ReadCommitResult } from "isomorphic-git" +import React, { useEffect, useState } from "react"; +import { Accordion } from "react-bootstrap"; +import { CommitDetailsNavigation } from "../../navigation/commitdetails"; +import { gitActionsContext } from "../../../state/context"; +import { gitPluginContext } from "../../gitui"; +import { branch } from "../../../types"; +import { BrancheDetailsNavigation } from "../../navigation/branchedetails"; +import { CommitDetailsItems } from "../commits/commitdetailsitem"; +import { CommitDetails } from "../commits/commitdetails"; +import { BranchDifferences } from "./branchdifferences"; +import GitUIButton from "../../buttons/gituibutton"; + +export interface BrancheDetailsProps { + branch: branch; +} + +export const LocalBranchDetails = (props: BrancheDetailsProps) => { + const { branch } = props; + const actions = React.useContext(gitActionsContext) + const context = React.useContext(gitPluginContext) + const [activePanel, setActivePanel] = useState(""); + const [hasNextPage, setHasNextPage] = useState(false) + const [lastPageNumber, setLastPageNumber] = useState(0) + + useEffect(() => { + if (activePanel === "0") { + + if (lastPageNumber === 0) + actions.getBranchCommits(branch, 1) + actions.getBranchDifferences(branch, null, context) + } + }, [activePanel]) + + const checkout = (branch: branch) => { + actions.checkout({ + ref: branch.name, + remote: branch.remote && branch.remote.name || null, + refresh: true + }); + } + + const loadNextPage = () => { + actions.getBranchCommits(branch, lastPageNumber + 1) + } + + const checkoutCommit = async (oid: string) => { + try { + + actions.checkout({ ref: oid }) + ; + } catch (e) { + // + } + }; + + const getRemote = () => { + return context.upstream ? context.upstream : context.defaultRemote ? context.defaultRemote : null + } + + const getCommitChanges = async (commit: ReadCommitResult) => { + await actions.getCommitChanges(commit.oid, commit.commit.parent[0], null, getRemote()) + } + + return ( + + + <> +
+ +
+ {context.localBranchCommits && Object.entries(context.localBranchCommits).map(([key, value]) => { + + if (key == branch.name) { + return value.map((commit, index) => { + return () + }) + } + })} +
+
+ {hasNextPage && Load more} + +
+
) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/branches/remotebranchedetails.tsx b/libs/remix-ui/git/src/components/panels/branches/remotebranchedetails.tsx new file mode 100644 index 0000000000..1b21e1eb76 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/branches/remotebranchedetails.tsx @@ -0,0 +1,111 @@ +import { ReadCommitResult } from "isomorphic-git" +import React, { useEffect, useState } from "react"; +import { Accordion } from "react-bootstrap"; +import { CommitDetailsNavigation } from "../../navigation/commitdetails"; +import { gitActionsContext } from "../../../state/context"; +import { gitPluginContext } from "../../gitui"; +import { branch } from "../../../types"; +import { BrancheDetailsNavigation } from "../../navigation/branchedetails"; +import { CommitDetailsItems } from "../commits/commitdetailsitem"; +import { CommitDetails } from "../commits/commitdetails"; +import GitUIButton from "../../buttons/gituibutton"; + +export interface BrancheDetailsProps { + branch: branch; +} + +export const RemoteBranchDetails = (props: BrancheDetailsProps) => { + const { branch } = props; + const actions = React.useContext(gitActionsContext) + const context = React.useContext(gitPluginContext) + const [activePanel, setActivePanel] = useState(""); + const [hasNextPage, setHasNextPage] = useState(false) + const [lastPageNumber, setLastPageNumber] = useState(0) + + useEffect(() => { + if (activePanel === "0") { + + if (lastPageNumber === 0) + actions.getBranchCommits(branch, 1) + } + }, [activePanel]) + + useEffect(() => { + let hasNextPage = false + let lastPageNumber = 0 + context.remoteBranchCommits && Object.entries(context.remoteBranchCommits).map(([key, value]) => { + if (key == branch.name) { + value.map((page, index) => { + hasNextPage = page.hasNextPage + lastPageNumber = page.page + }) + } + }) + setHasNextPage(hasNextPage) + setLastPageNumber(lastPageNumber) + }, [context.remoteBranchCommits]) + + const checkout = async (branch: branch) => { + await actions.fetch({ + remote: branch.remote, + ref: branch, + depth: 20, + singleBranch: true, + relative: false, + quiet: true + }) + await actions.checkout({ + ref: branch.name, + remote: branch.remote && branch.remote.name || null, + refresh: true + }); + await actions.getBranches() + } + + const loadNextPage = () => { + actions.getBranchCommits(branch, lastPageNumber + 1) + } + + const checkoutCommit = async (oid: string) => { + try { + actions.checkout({ ref: oid }) + } catch (e) { + // + } + }; + + const getCommitChanges = async (commit: ReadCommitResult) => { + const changes = await actions.getCommitChanges(commit.oid, commit.commit.parent[0], branch, branch.remote) + if (!changes) { + await actions.fetch({ + remote: branch.remote, + ref: branch, + depth: 20, + singleBranch: true, + relative: false, + quiet: true + }) + } + } + + return ( + + + <> +
+ {context.remoteBranchCommits && Object.entries(context.remoteBranchCommits).map(([key, value]) => { + if (key == branch.name) { + return value.map((page, index) => { + return page.commits.map((commit, index) => { + return () + }) + }) + } + })} + +
+ {hasNextPage && Load more} + +
+
) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/clone.tsx b/libs/remix-ui/git/src/components/panels/clone.tsx new file mode 100644 index 0000000000..fedd6dfa4a --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/clone.tsx @@ -0,0 +1,102 @@ + +import React, { useState } from "react"; +import { Alert, Form, FormControl, InputGroup } from "react-bootstrap"; +import { useLocalStorage } from "../../hooks/useLocalStorage"; +import { gitActionsContext } from "../../state/context"; +import { gitPluginContext } from "../gitui"; +import { SelectAndCloneRepositories } from "../github/selectandclonerepositories"; +import { RemixUiCheckbox } from "@remix-ui/checkbox"; +import GitUIButton from "../buttons/gituibutton"; + +export const Clone = () => { + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + const [cloneUrl, setCloneUrl] = useLocalStorage( + "CLONE_URL", + '' + ); + + const [cloneDepth, setCloneDepth] = useLocalStorage( + "CLONE_DEPTH", + 1 + ); + + const [cloneBranch, setCloneBranch] = useLocalStorage( + "CLONE_BRANCH", + '' + ); + + const [url, setUrl] = useLocalStorage( + "GITHUB_URL", + '' + ); + + const clone = async () => { + await actions.clone({ + url: cloneUrl, + branch: cloneBranch, + depth: cloneDepth, + singleBranch: !cloneAllBranches + }) + //await actions.clone(cloneUrl, cloneBranch, cloneDepth, !cloneAllBranches) + } + + const onCloneBranchChange = (value: string) => { + setCloneBranch(value) + } + + const onGitHubCloneUrlChange = (value: string) => { + setCloneUrl(value) + } + + const onDepthChange = (value: number) => { + setCloneDepth(value) + } + + const [cloneAllBranches, setcloneAllBranches] = useLocalStorage( + "GITHUB_CLONE_ALL_BRANCES", + false + ); + + const onAllBranchChange = () => { + setcloneAllBranches((e: any) => !e) + } + + return ( + <> +
+ + onGitHubCloneUrlChange(e.target.value)} aria-describedby="urlprepend" /> + + + onCloneBranchChange(e.target.value)} value={cloneBranch} className="form-control mb-1 mt-2" placeholder="branch" type="text" id="clonebranch" /> + { + clone() + }}>clone +
+ +
+ + + + + --depth + + + onDepthChange(parseInt(e.target.value))} aria-describedby="clonedepthprepend" /> + + + onAllBranchChange()} + checked={cloneAllBranches} + onChange={() => { }} + /> + +
+
+ ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/commands.tsx b/libs/remix-ui/git/src/components/panels/commands.tsx new file mode 100644 index 0000000000..f1b9cfc952 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/commands.tsx @@ -0,0 +1,14 @@ +import React, { useEffect, useState } from "react"; +import { PushPull } from "./commands/pushpull"; +import { Fetch } from "./commands/fetch"; +import { Merge } from "./commands/merge"; + +export const Commands = () => { + + return ( + <> + +
+ + ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/commands/fetch.tsx b/libs/remix-ui/git/src/components/panels/commands/fetch.tsx new file mode 100644 index 0000000000..d7b8ee0c30 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/commands/fetch.tsx @@ -0,0 +1,25 @@ +import React, { useEffect, useState } from "react"; +import { gitActionsContext } from "../../../state/context"; +import GitUIButton from "../../buttons/gituibutton"; +import { gitPluginContext } from "../../gitui"; + +export const Fetch = () => { + const actions = React.useContext(gitActionsContext) + const context = React.useContext(gitPluginContext) + + const fetchIsDisabled = () => { + return (!context.upstream) || context.remotes.length === 0 + } + return ( + <> +
+ actions.fetch({ + remote: context.upstream, + })} className="btn btn-primary mr-1 w-50">
Fetch {context.upstream && context.upstream.name}
+ actions.fetch({ + remote: context.upstream, + ref: context.currentBranch + })} className="btn btn-primary w-50 long-and-truncated">Fetch {context.currentBranch.name} +
+ ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/commands/merge.tsx b/libs/remix-ui/git/src/components/panels/commands/merge.tsx new file mode 100644 index 0000000000..c3341d23d8 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/commands/merge.tsx @@ -0,0 +1,57 @@ +import React, { useEffect, useState } from "react"; +import { gitActionsContext } from "../../../state/context"; +import { gitPluginContext } from "../../gitui"; +import { selectStyles, selectTheme } from "../../../types/styles"; +import Select from 'react-select' +import GitUIButton from "../../buttons/gituibutton"; + +export const Merge = () => { + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + const [localBranch, setLocalBranch] = useState('') + const [localBranchOptions, setLocalBranchOptions] = useState([]); + + useEffect(() => { + setLocalBranch(context.currentBranch.name) + }, [context.currentBranch]) + + const onLocalBranchChange = (value: any) => { + setLocalBranch(value) + } + + const merge = async () => { + //gitservice.push(currentRemote, branch || '', remoteBranch, force) + } + + useEffect(() => { + // map context.repositories to options + const localBranches = context.branches && context.branches.length > 0 && context.branches + .filter(branch => !branch.remote) + .map(repo => { + return { value: repo.name, label: repo.name } + }) + setLocalBranchOptions(localBranches) + + }, [context.branches]) + + return ( + <> + +
+ merge()} className="btn btn-primary mr-1">Merge +
+ + + e && onLocalBranchChange(e.value)} + theme={selectTheme} + styles={selectStyles} + isClearable={true} + value={{ value: localBranch, label: localBranch }} + placeholder="Type to search for a branch..." + /> + + + e && onRemoteChange(e.value)} + theme={selectTheme} + styles={selectStyles} + isClearable={true} + value={{ value: context.upstream && context.upstream.name, label: context.upstream && context.upstream.name }} + placeholder="Type to search for a branch..." + /> + +
+ onForceChange(e)} className="remixui_autocompile custom-control-input" type="checkbox" data-id="compilerContainerAutoCompile" id="forcepush" title="Force Push" /> + +
+ + ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/commits.tsx b/libs/remix-ui/git/src/components/panels/commits.tsx new file mode 100644 index 0000000000..8fa50a9d99 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/commits.tsx @@ -0,0 +1,64 @@ +import { checkout, ReadCommitResult } from "isomorphic-git"; +import React from "react"; +import { gitActionsContext } from "../../state/context"; +import GitUIButton from "../buttons/gituibutton"; +import { gitPluginContext } from "../gitui"; +import LoaderIndicator from "../navigation/loaderindicator"; +import { BranchDifferences } from "./branches/branchdifferences"; +import { CommitDetails } from "./commits/commitdetails"; +import { CommitSummary } from "./commits/commitsummary"; + +export const Commits = () => { + const [hasNextPage, setHasNextPage] = React.useState(true) + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + + const checkout = async (oid: string) => { + try { + actions.checkout({ ref: oid }) + } catch (e) { + // + } + }; + + const loadNextPage = () => { + actions.fetch({ + remote: null, + ref: context.currentBranch, + relative: true, + depth: 5, + singleBranch: true + }) + + } + + const getRemote = () => { + return context.upstream ? context.upstream : context.defaultRemote ? context.defaultRemote : null + } + + const getCommitChanges = async (commit: ReadCommitResult) => { + await actions.getCommitChanges(commit.oid, commit.commit.parent[0],null, getRemote()) + } + + const fetchIsDisabled = () => { + return (!context.upstream)|| context.remotes.length === 0 + } + + return ( + <> + {context.commits && context.commits.length ? + <>
+
+ {context.commits && context.commits.map((commit, index) => { + return ( + + ); + })} +
+
+ {hasNextPage && Load more} + + :
No commits
} + + ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/commits/commitdetails.tsx b/libs/remix-ui/git/src/components/panels/commits/commitdetails.tsx new file mode 100644 index 0000000000..c706611486 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/commits/commitdetails.tsx @@ -0,0 +1,60 @@ +import { ReadCommitResult } from "isomorphic-git" +import React, { useEffect, useState } from "react"; +import { Accordion } from "react-bootstrap"; +import { CommitDetailsNavigation } from "../../navigation/commitdetails"; +import { gitActionsContext } from "../../../state/context"; +import { gitPluginContext } from "../../gitui"; +import { CommitDetailsItems } from "./commitdetailsitem"; +import { branch, remote } from "@remix-ui/git"; + +export interface CommitDetailsProps { + commit: ReadCommitResult; + checkout: (oid: string) => void; + getCommitChanges: (commit: ReadCommitResult) => void; + branch: branch +} + +export const CommitDetails = (props: CommitDetailsProps) => { + const { commit, checkout, getCommitChanges, branch } = props; + const actions = React.useContext(gitActionsContext) + const context = React.useContext(gitPluginContext) + const [activePanel, setActivePanel] = useState(""); + + useEffect(() => { + if (activePanel === "0") { + getCommitChanges(commit) + } + }, [activePanel]) + + const getRemote = (): remote | null => { + return context.upstream ? context.upstream : context.defaultRemote ? context.defaultRemote : null + } + + const commitsAhead = (remote: remote) => { + if (!remote) return []; + return context.branchDifferences[`${remote.name}/${branch.name}`]?.uniqueHeadCommits || []; + } + + const isAheadOfRepo = () => { + return commitsAhead(getRemote()).findIndex((c) => c.oid === commit.oid) > -1 + } + + const openFileOnRemote = (file: string, hash: string) => { + if (!getRemote()) return + window.open(`${getRemote() ? `${getRemote().url}/blob/${hash}/${file}` : ""}`, "_blank") + } + + return ( + + + <> + {context.commitChanges && context.commitChanges.filter( + (change) => change.hashModified === commit.oid && change.hashOriginal === commit.commit.parent[0] + ).map((change, index) => { + return () + })} + + + + ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/commits/commitdetailsitem.tsx b/libs/remix-ui/git/src/components/panels/commits/commitdetailsitem.tsx new file mode 100644 index 0000000000..7115347618 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/commits/commitdetailsitem.tsx @@ -0,0 +1,51 @@ +import { branch, commitChange } from "../../../types"; +import React from "react"; +import path from "path"; +import { gitActionsContext, pluginActionsContext } from "../../../state/context"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faGlobe } from "@fortawesome/free-solid-svg-icons"; + +export interface CCommitDetailsItemsProps { + commitChange: commitChange; + isAheadOfRepo: boolean; + openFileOnRemote: (file: string, hash: string) => void; +} + +export const CommitDetailsItems = (props: CCommitDetailsItemsProps) => { + const { commitChange, isAheadOfRepo, openFileOnRemote } = props; + const actions = React.useContext(gitActionsContext) + const pluginActions = React.useContext(pluginActionsContext) + + const openChanges = async (change: commitChange) => { + await actions.diff(change) + await pluginActions.openDiff(change) + } + + const openRemote = () => { + openFileOnRemote(commitChange.path, commitChange.hashModified) + } + + function FunctionStatusIcons() { + const status = commitChange.type + return (<> + + {status && status.indexOf("modified") === -1 ? <> : M} + {status && status.indexOf("deleted") === -1 ? <> : D} + {status && status.indexOf("added") === -1 ? <> : A} + + ) + } + return (<> +
+
await openChanges(commitChange)}> + {path.basename(commitChange.path)} +
{commitChange.path}
+
+
+ {!isAheadOfRepo ? + openRemote()} className="pointer mr-1 align-self-center" /> : <>} + +
+
+ ) +} diff --git a/libs/remix-ui/git/src/components/panels/commits/commitsummary.tsx b/libs/remix-ui/git/src/components/panels/commits/commitsummary.tsx new file mode 100644 index 0000000000..1672b883e0 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/commits/commitsummary.tsx @@ -0,0 +1,70 @@ +import { ReadCommitResult } from "isomorphic-git" +import { default as dateFormat } from "dateformat"; +import React from "react"; +import { faGlobe } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { remote } from "@remix-ui/git"; +import GitUIButton from "../../buttons/gituibutton"; +import { gitPluginContext } from "../../gitui"; + +export interface CommitSummaryProps { + commit: ReadCommitResult; + checkout: (oid: string) => void; + isAheadOfRepo: boolean +} + +export const CommitSummary = (props: CommitSummaryProps) => { + const { commit, checkout, isAheadOfRepo } = props; + const context = React.useContext(gitPluginContext) + + const getDate = (commit: ReadCommitResult) => { + const timestamp = commit.commit.author.timestamp; + + if (timestamp) { + // calculate the difference between the current time and the commit time in days or hours or minutes + const diff = Math.floor((Date.now() - timestamp * 1000) / 1000 / 60 / 60 / 24); + + if (diff == 0) { + return "today at " + dateFormat(timestamp * 1000, "HH:MM"); + } else + + if (diff < 1) { + // return how many hours ago + return `${Math.floor(diff * 24)} hour(s) ago`; + } + + if (diff < 7) { + // return how many days ago + return `${diff} day(s) ago`; + } + if (diff < 365) { + return dateFormat(timestamp * 1000, "mmm dd"); + } + return dateFormat(timestamp * 1000, "mmm dd yyyy"); + } + return ""; + }; + + const getRemote = (): remote | null => { + return context.upstream ? context.upstream : context.defaultRemote ? context.defaultRemote : null + } + + const openRemote = () => { + if (getRemote()) + window.open(`${getRemote().url}/commit/${commit.oid}`, '_blank'); + } + function removeLineBreaks(str: string): string { + return str.replace(/(\r\n|\n|\r)/gm, ''); + } + + return ( + <> +
+ {commit.commit.message} +
+ {commit.commit.author.name || ""} + {getDate(commit)} + {getRemote() && getRemote()?.url && !isAheadOfRepo && openRemote()}>} + + ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/githubcredentials.tsx b/libs/remix-ui/git/src/components/panels/githubcredentials.tsx new file mode 100644 index 0000000000..300e6797f0 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/githubcredentials.tsx @@ -0,0 +1,90 @@ +import React, { useEffect } from "react"; +import { gitActionsContext, pluginActionsContext } from "../../state/context"; +import { gitPluginContext, loaderContext } from "../gitui"; +import { CustomTooltip } from "@remix-ui/helper"; + +import { useIntl, FormattedMessage } from "react-intl"; +import { CopyToClipboard } from "@remix-ui/clipboard"; + +export const GitHubCredentials = () => { + const context = React.useContext(gitPluginContext) + const pluginactions = React.useContext(pluginActionsContext) + const loader = React.useContext(loaderContext) + const actions = React.useContext(gitActionsContext) + const [githubToken, setGithubToken] = React.useState('') + const [githubUsername, setGithubUsername] = React.useState('') + const [githubEmail, setGithubEmail] = React.useState('') + const [scopeWarning, setScopeWarning] = React.useState(false) + const intl = useIntl() + + useEffect(() => { + refresh() + if (context.gitHubUser){ + setScopeWarning(!(context.gitHubScopes && context.gitHubScopes.length > 0)) + } else { + setScopeWarning(false) + } + }, [loader.plugin, context.gitHubAccessToken, context.userEmails, context.gitHubUser, context.gitHubScopes]) + + function handleChangeTokenState(e: string): void { + setGithubToken(e) + } + + function handleChangeUserNameState(e: string): void { + setGithubUsername(e) + } + + function handleChangeEmailState(e: string): void { + setGithubEmail(e) + } + + async function saveGithubToken() { + await pluginactions.saveGitHubCredentials({ + username: githubUsername, + email: githubEmail, + token: githubToken + }) + } + + async function refresh() { + const credentials = await pluginactions.getGitHubCredentialsFromLocalStorage() + if (!credentials) return + setGithubToken(credentials.token || '') + setGithubUsername(credentials.username || '') + setGithubEmail(credentials.email || '') + } + + function removeToken(): void { + setGithubToken('') + setGithubUsername('') + setGithubEmail('') + pluginactions.saveGitHubCredentials({ + username: '', + email: '', + token: '' + }) + } + + return ( + <> +
+ handleChangeTokenState(e.target.value)} /> +
+ +
+
+ handleChangeUserNameState(e.target.value)} value={githubUsername} className="form-control mb-1" placeholder="Git username" type="text" id="githubUsername" /> + handleChangeEmailState(e.target.value)} value={githubEmail} className="form-control mb-1" placeholder="Git email" type="text" id="githubEmail" /> +
+ + +
+ {scopeWarning? +
Your GitHub token may not have the correct permissions. Please use the login with GitHub feature.
:null} +
+ + ); +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/init.tsx b/libs/remix-ui/git/src/components/panels/init.tsx new file mode 100644 index 0000000000..e58163460f --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/init.tsx @@ -0,0 +1,29 @@ +import { CustomTooltip } from '@remix-ui/helper'; +import { pull } from 'lodash'; +import React, { useContext } from 'react'; +import { FormattedMessage } from 'react-intl'; +import { gitActionsContext } from '../../state/context'; +import GitUIButton from '../buttons/gituibutton'; + +export const Init = () => { + + const actions = React.useContext(gitActionsContext) + + const init = async () => { + actions.init() + } + + return ( + <> +
+
+ +
+
+ + ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/log.tsx b/libs/remix-ui/git/src/components/panels/log.tsx new file mode 100644 index 0000000000..6f1aeba5e6 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/log.tsx @@ -0,0 +1,39 @@ +// src/LogViewer.tsx +import React, { useContext } from 'react'; +import { gitPluginContext } from '../gitui'; + +const LogViewer = () => { + const context = useContext(gitPluginContext); + + const typeToCssClass = (type: string) => { + switch (type) { + case 'error': + return 'text-danger'; + case 'warning': + return 'text-warning'; + case 'info': + return 'text-info'; + case 'debug': + return 'text-secondary'; + default: + return 'text-success'; + } + }; + + if (context.log && context.log.length > 0) { + + return ( +
+ {context.log && context.log.reverse().map((log, index) => ( +
+ [{log.type.toUpperCase()}] {log.message} +
+ ))} +
+ ); + } else { + return
No logs
+ } +}; + +export default LogViewer; diff --git a/libs/remix-ui/git/src/components/panels/remotes.tsx b/libs/remix-ui/git/src/components/panels/remotes.tsx new file mode 100644 index 0000000000..cf8ea2fc58 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/remotes.tsx @@ -0,0 +1,53 @@ +import React, { useEffect } from "react"; +import { gitActionsContext } from "../../state/context"; +import { gitPluginContext } from "../gitui"; +import { Remoteselect } from "./remoteselect"; +import { RemotesImport } from "./remotesimport"; + +export const Remotes = () => { + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + const [remoteName, setRemoteName] = React.useState('') + const [url, setUrl] = React.useState('') + + const onRemoteNameChange = (value: string) => { + setRemoteName(value) + } + const onUrlChange = (value: string) => { + setUrl(value) + } + + const addRemote = async () => { + actions.addRemote({ + name: remoteName, + url: url + }) + } + + return ( + <> +
+ {context.remotes && context.remotes.length ? + <> + + {context.remotes && context.remotes.map((remote, index) => { + + return ( + + ); + })} + : <>No remotes} +
+ + onRemoteNameChange(e.target.value)} value={remoteName} className="form-control mb-2" type="text" id="remotename" /> + onUrlChange(e.target.value)} value={url} className="form-control" type="text" id="remoteurl" /> + + +
+ +
+
+ ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/remoteselect.tsx b/libs/remix-ui/git/src/components/panels/remoteselect.tsx new file mode 100644 index 0000000000..f2eedadfb3 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/remoteselect.tsx @@ -0,0 +1,37 @@ +import { branch, checkout, ReadCommitResult } from "isomorphic-git"; +import React, { useEffect, useState } from "react"; +import { gitActionsContext } from "../../state/context"; +import { gitPluginContext } from "../gitui"; +import { default as dateFormat } from "dateformat"; +import { RemotesDetailsNavigation } from "../navigation/remotesdetails"; +import { Accordion } from "react-bootstrap"; +import { remote } from "../../types"; +import { RemoteBranchDetails } from "./branches/remotebranchedetails"; + +export interface RemoteSelectProps { + remote: remote +} + +export const Remoteselect = (props: RemoteSelectProps) => { + const { remote } = props; + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + const [activePanel, setActivePanel] = useState(""); + + return ( + <> + + + + <> + {context.branches && context.branches.filter((branch, index) => branch.remote && branch.remote.name === remote.name ).map((branch, index) => { + return ( + + ); + })} + + + + + ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/remotesimport.tsx b/libs/remix-ui/git/src/components/panels/remotesimport.tsx new file mode 100644 index 0000000000..646546c1a4 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/remotesimport.tsx @@ -0,0 +1,82 @@ +import React, { useEffect, useState } from "react"; +import { Alert, Button } from "react-bootstrap"; +import { gitActionsContext } from "../../state/context"; +import { repository } from "../../types"; +import { gitPluginContext } from "../gitui"; +import Select from 'react-select' +import { selectStyles, selectTheme } from "../../types/styles"; +import { TokenWarning } from "./tokenWarning"; +import RepositorySelect from "../github/repositoryselect"; + +export const RemotesImport = () => { + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + const [repo, setRepo] = useState(null); + const [repoOtions, setRepoOptions] = useState([]); + const [loading, setLoading] = useState(false) + const [show, setShow] = useState(false) + const [remoteName, setRemoteName] = useState('') + + useEffect(() => { + if (context.repositories && context.repositories.length > 0) { + // map context.repositories to options + const options = context.repositories && context.repositories.length > 0 && context.repositories.map(repo => { + return { value: repo.id, label: repo.full_name } + }) + setRepoOptions(options) + } else { + setRepoOptions(null) + setShow(false) + } + setLoading(false) + + }, [context.repositories]) + + const fetchRepositories = async () => { + try { + setShow(true) + setLoading(true) + setRepoOptions([]) + await actions.repositories() + } catch (e) { + // do nothing + } + }; + + const selectRepo = async (repo: repository) => { + setRepo(repo) + } + + const addRemote = async () => { + try { + actions.addRemote({ + name: remoteName, + url: repo.html_url + }) + } catch (e) { + // do nothing + } + + }; + const onRemoteNameChange = (value: string) => { + setRemoteName(value) + } + + return ( + <> + + + + {repo ? + onRemoteNameChange(e.target.value)} value={remoteName} className="form-control mb-2" type="text" id="remotename" /> + : null} + + {repo && remoteName ? + : null} + + + ) +} + diff --git a/libs/remix-ui/git/src/components/panels/settings.tsx b/libs/remix-ui/git/src/components/panels/settings.tsx new file mode 100644 index 0000000000..5267a72e24 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/settings.tsx @@ -0,0 +1,48 @@ +import { checkout, clone, ReadCommitResult } from "isomorphic-git"; +import React from "react"; +import { gitActionsContext } from "../../state/context"; +import { gitPluginContext } from "../gitui"; +import { CustomTooltip } from "@remix-ui/helper"; + +import { useIntl, FormattedMessage } from "react-intl"; +import { CopyToClipboard } from "@remix-ui/clipboard"; +import { FormControl, InputGroup } from "react-bootstrap"; + +export const Settings = () => { + + const [githubToken, setGithubToken] = React.useState('') + const [githubUsername, setGithubUsername] = React.useState('') + const [githubEmail, setGithubEmail] = React.useState('') + const intl = useIntl() + + const gitAccessTokenLink = 'https://github.com/settings/tokens/new?scopes=gist,repo&description=Remix%20IDE%20Token' + + function handleChangeTokenState(e: string): void { + throw new Error("Function not implemented."); + } + + function handleChangeUserNameState(e: string): void { + throw new Error("Function not implemented."); + } + + function handleChangeEmailState(e: string): void { + throw new Error("Function not implemented."); + } + + function saveGithubToken(): void { + throw new Error("Function not implemented."); + } + + function removeToken(): void { + throw new Error("Function not implemented."); + } + + return ( + <> + handleChangeUserNameState(e.target.value)} value={githubToken} className="form-control mb-2" placeholder="GitHub token" type="text" id="githubToken" /> + handleChangeUserNameState(e.target.value)} value={githubUsername} className="form-control mb-2" placeholder="GitHub username" type="text" id="githubUsername" /> + handleChangeEmailState(e.target.value)} value={githubEmail} className="form-control mb-1" placeholder="GitHub email" type="text" id="githubEmail" /> +
+ + ); +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/setup.tsx b/libs/remix-ui/git/src/components/panels/setup.tsx new file mode 100644 index 0000000000..42a68014ae --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/setup.tsx @@ -0,0 +1,36 @@ +import React, { useEffect, useState } from 'react' +import { GetDeviceCode } from '../github/devicecode' +import { GitHubCredentials } from './githubcredentials' + +export const Setup = () => { + + const [screen, setScreen] = useState(0) + + if (screen === 0) { + return ( + <> +
SETUP
+
+
+ To ensure that your commits are properly attributed in Git, you need to configure a username and email address. + These will be used to identify the author of the commit. +
+ +
+ +
+ + ) + } else if (screen === 1) { + return ( + <> +
SETUP
+
Step 2
+
+ To ensure that your commits are properly attributed in Git, you need to configure your username and email address. + +
+ + ) + } +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/sourcecontrol/sourcecontrolgroup.tsx b/libs/remix-ui/git/src/components/panels/sourcecontrol/sourcecontrolgroup.tsx new file mode 100644 index 0000000000..1b17cb2b31 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/sourcecontrol/sourcecontrolgroup.tsx @@ -0,0 +1,38 @@ +import { ReadCommitResult } from "isomorphic-git" +import React, { useEffect, useState } from "react"; +import { Accordion } from "react-bootstrap"; +import { gitActionsContext } from "../../../state/context"; +import { gitPluginContext } from "../../gitui"; +import { sourceControlGroup } from "../../../types"; +import { SourceControlGroupNavigation } from "../../navigation/sourcecontrolgroup"; +import { SourceControlItem } from "./sourcecontrolitem"; + +export interface SourceControGroupProps { + group: sourceControlGroup +} + +export const SourceControGroup = (props: SourceControGroupProps) => { + const { group } = props; + const actions = React.useContext(gitActionsContext) + const context = React.useContext(gitPluginContext) + const [activePanel, setActivePanel] = useState("0"); + + useEffect(() => { + if (activePanel === "0") { + } + }, [activePanel]) + + return (<> + {group.group.length > 0 ? + + + + <> + {group.group.map((file, index) => { + return () + })} + + + : <>} + ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/sourcecontrol/sourcecontrolitem.tsx b/libs/remix-ui/git/src/components/panels/sourcecontrol/sourcecontrolitem.tsx new file mode 100644 index 0000000000..64617b17e1 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/sourcecontrol/sourcecontrolitem.tsx @@ -0,0 +1,65 @@ +import { commitChange, fileStatusResult, sourceControlGroup } from "../../../types"; +import React from "react"; +import path from "path"; +import { gitActionsContext, pluginActionsContext } from "../../../state/context"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faGlobe } from "@fortawesome/free-solid-svg-icons"; +import { SourceControlItemButtons } from "./sourcontrolitembuttons"; +import { removeSlash } from "../../../utils"; + +export interface SourceControlItemProps { + file: fileStatusResult; + group: sourceControlGroup; +} + +export const SourceControlItem = (props: SourceControlItemProps) => { + const { file, group } = props; + const actions = React.useContext(gitActionsContext) + const pluginActions = React.useContext(pluginActionsContext) + + async function fileClick(file: fileStatusResult) { + if (file.statusNames && file.statusNames.indexOf("modified") !== -1) { + const headHash = await actions.resolveRef("HEAD") + const change: commitChange = { + path: removeSlash(file.filename), + type: "modified", + hashOriginal: headHash, + hashModified: '', + readonly: false, + } + await actions.diff(change) + await pluginActions.openDiff(change) + } else { + await pluginActions.openFile(file.filename) + //await client.call('fileManager', 'open', file.filename) + } + } + + function FunctionStatusIcons() { + + const status = file.statusNames + + return (<> + + {status && status.indexOf("modified") === -1 ? <> :
M
} + {status && status.indexOf("deleted") === -1 ? <> : D} + {status && status.indexOf("added") === -1 ? <> : A} + {status && status.indexOf("untracked") === -1 ? <> : U} + ) + } + + if (!file.statusNames || file.statusNames.length === 0) return null + + return (<> +
+
await fileClick(file)}> + {path.basename(file.filename)} +
{file.filename}
+
+
+ + +
+
+ ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/sourcecontrol/sourcontrolitembuttons.tsx b/libs/remix-ui/git/src/components/panels/sourcecontrol/sourcontrolitembuttons.tsx new file mode 100644 index 0000000000..d1ba05ef1f --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/sourcecontrol/sourcontrolitembuttons.tsx @@ -0,0 +1,76 @@ +import { commitChange, fileStatusResult, sourceControlGroup } from "../../../types"; +import React from "react"; +import path from "path"; +import { gitActionsContext, pluginActionsContext } from "../../../state/context"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faGlobe, faMinus, faPlus, faUndo } from "@fortawesome/free-solid-svg-icons"; + +export interface SourceControlItemButtonsProps { + file: fileStatusResult, + group: sourceControlGroup +} + +export const SourceControlItemButtons = (props: SourceControlItemButtonsProps) => { + const { file, group } = props; + const actions = React.useContext(gitActionsContext) + const pluginActions = React.useContext(pluginActionsContext) + + function RenderButtons() { + const status = file.statusNames + + if (group.name === 'Staged') { + return <> + + {status && status.indexOf("modified") === -1 ? <> : + + } + {status && status.indexOf("deleted") === -1 ? <> : + + } + {status && status.indexOf("deleted") !== -1 ? <> : + + } + + + } + if (group.name === 'Changes') { + return <> + + {status && status.indexOf("deleted") === -1 ? <> : + <> + } + {status && status.indexOf("modified") === -1 ? <> : + + } + {(status && status.indexOf("unstaged") !== -1 || status && status.indexOf("deleted") !== -1) ? <> : + + } + {(status && status.indexOf("unstaged") !== -1 && status && status.indexOf("modified") !== -1) ? + : + <> + } + + } + return <> + } + + return + +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/sourcontrol.tsx b/libs/remix-ui/git/src/components/panels/sourcontrol.tsx new file mode 100644 index 0000000000..ad54852073 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/sourcontrol.tsx @@ -0,0 +1,49 @@ +import React, { useEffect, useState } from 'react' +import { gitActionsContext, pluginActionsContext } from '../../state/context' +import { gitPluginContext } from '../gitui' +import { sourceControlGroup } from '../../types' +import { SourceControGroup } from './sourcecontrol/sourcecontrolgroup' + +export const SourceControl = () => { + const context = React.useContext(gitPluginContext) + const actions = React.useContext(gitActionsContext) + const pluginactions = React.useContext(pluginActionsContext) + const [show, setShow] = useState(false) + + useEffect(() => { + if (context.fileStatusResult) { + const total = context.allchangesnotstaged.length + const badges = total + context.staged.length + pluginactions.statusChanged(badges) + setShow((context.deleted.length > 0 || context.staged.length > 0 || context.untracked.length > 0 || context.modified.length > 0)) + } + }, [context.fileStatusResult, context.modified, context.allchangesnotstaged, context.untracked, context.deleted]) + + function RenderGroups() { + const groups: sourceControlGroup[] = [{ name: 'Staged', group: context.staged }, { name: 'Changes', group: context.allchangesnotstaged }] + return (<> + { + groups.map((ob: sourceControlGroup, index: number) => { + return ( + + ) + }) + } + + ) + } + + return ( + <> + {show ? + <> +
+ +
+ : <> + + } + + ); + +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/components/panels/tokenWarning.tsx b/libs/remix-ui/git/src/components/panels/tokenWarning.tsx new file mode 100644 index 0000000000..4188c07c93 --- /dev/null +++ b/libs/remix-ui/git/src/components/panels/tokenWarning.tsx @@ -0,0 +1,12 @@ +import { gitPluginContext } from "../gitui" +import React, { useEffect, useState } from "react"; +export const TokenWarning = () => { + const context = React.useContext(gitPluginContext) + return (<> + {(context.gitHubUser && context.gitHubUser.login) ? null : +
  • + To use add a GitHub token to the settings.
  • + } + + ) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/hooks/useLocalStorage.tsx b/libs/remix-ui/git/src/hooks/useLocalStorage.tsx new file mode 100644 index 0000000000..dbef5378a8 --- /dev/null +++ b/libs/remix-ui/git/src/hooks/useLocalStorage.tsx @@ -0,0 +1,37 @@ +import { useState } from "react" + +export function useLocalStorage(key: string, initialValue: any) { + // State to store our value + // Pass initial state function to useState so logic is only executed once + const [storedValue, setStoredValue] = useState(() => { + try { + // Get from local storage by key + const item = window.localStorage.getItem(key) + // Parse stored json or if none return initialValue + return item ? JSON.parse(item) : initialValue + } catch (error) { + // If error also return initialValue + console.error(error) + return initialValue + } + }) + + // Return a wrapped version of useState's setter function that ... + // ... persists the new value to localStorage. + const setValue = (value: any) => { + try { + // Allow value to be a function so we have same API as useState + const valueToStore = + value instanceof Function ? value(storedValue) : value + // Save state + setStoredValue(valueToStore) + // Save to local storage + window.localStorage.setItem(key, JSON.stringify(valueToStore)) + } catch (error) { + // A more advanced implementation would handle the error case + console.error(error) + } + } + + return [storedValue, setValue] +} diff --git a/libs/remix-ui/git/src/index.ts b/libs/remix-ui/git/src/index.ts new file mode 100644 index 0000000000..677c174059 --- /dev/null +++ b/libs/remix-ui/git/src/index.ts @@ -0,0 +1,4 @@ +export * from './types' +export { GitUI } from './components/gitui' +export { commitChange, commitChangeType, remote, branch } from './types' +export * from './types/styles' \ No newline at end of file diff --git a/libs/remix-ui/git/src/lib/fileHelpers.ts b/libs/remix-ui/git/src/lib/fileHelpers.ts new file mode 100644 index 0000000000..6076cac43e --- /dev/null +++ b/libs/remix-ui/git/src/lib/fileHelpers.ts @@ -0,0 +1,56 @@ +import { fileStatusResult, gitState } from "../types"; + +export const getFilesCountByStatus = (status: string, files: fileStatusResult[]) => { + let count = 0; + + files.map((m) => { + if (m.statusNames !== undefined) { + if (m.statusNames && m.statusNames.indexOf(status) > -1) { + count++; + } + } + }); + return count; +} + +export const getFilesByStatus = (status: string, files: fileStatusResult[]): fileStatusResult[] => { + const result: fileStatusResult[] = [] + files.map((m) => { + if (m.statusNames !== undefined) { + if (m.statusNames && m.statusNames.indexOf(status) > -1) { + result.push(m) + } + } + }); + return result; +} + +export const getFilesWithNotModifiedStatus = (files: fileStatusResult[]): fileStatusResult[] => { + const result: fileStatusResult[] = [] + + files.map((m) => { + + if (m.statusNames !== undefined) { + if (m.statusNames && m.statusNames.indexOf("unmodified") === -1) { + result.push(m) + } + } + }); + return result; +} + +export const allChangedButNotStagedFiles = (files: fileStatusResult[]): fileStatusResult[] => { + let allfiles = getFilesWithNotModifiedStatus(files) + const staged = getFilesByStatus("staged", files) + allfiles = allfiles.filter((trackedFile) => { + return staged.findIndex((stagedFile) => stagedFile.filename === trackedFile.filename) === -1 + }) + return allfiles; +} + +export const getFileStatusForFile = (filename: string, files: fileStatusResult[]) => { + for (let i: number = 0; i < files.length; i++) { + if (files[i].filename === filename) + return files[i].statusNames; + } +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/lib/gitactions.ts b/libs/remix-ui/git/src/lib/gitactions.ts new file mode 100644 index 0000000000..314d9143e5 --- /dev/null +++ b/libs/remix-ui/git/src/lib/gitactions.ts @@ -0,0 +1,852 @@ +import { ReadBlobResult, ReadCommitResult } from "isomorphic-git"; +import React from "react"; +import { fileStatus, fileStatusMerge, setRemoteBranchCommits, resetRemoteBranchCommits, setBranches, setCanCommit, setCommitChanges, setCommits, setCurrentBranch, setGitHubUser, setLoading, setRemoteBranches, setRemotes, setRepos, setUpstream, setLocalBranchCommits, setBranchDifferences, setRemoteAsDefault, setScopes, setLog, clearLog, setUserEmails, setCurrenHead } from "../state/gitpayload"; +import { GitHubUser, branch, commitChange, gitActionDispatch, statusMatrixType, gitState, branchDifference, remote, gitLog, fileStatusResult, customGitApi, IGitApi, cloneInputType, fetchInputType, pullInputType, pushInputType, checkoutInput, rmInput, addInput, repository, userEmails } from '../types'; +import { removeSlash } from "../utils"; +import { disableCallBacks, enableCallBacks } from "./listeners"; +import { ModalTypes } from "@remix-ui/app"; +import { setFileDecorators } from "./pluginActions"; +import { Plugin } from "@remixproject/engine"; +import { CustomRemixApi } from "@remix-api"; +import { file } from "jszip"; + +export const fileStatuses = [ + ["new,untracked", 0, 2, 0], // new, untracked + ["added,staged", 0, 2, 2], // + ["added,staged,with unstaged changes", 0, 2, 3], // added, staged, with unstaged changes + ["unmodified", 1, 1, 1], // unmodified + ["modified,unstaged", 1, 2, 1], // modified, unstaged + ["modified,staged", 1, 2, 2], // modified, staged + ["modified,staged,with unstaged changes", 1, 2, 3], // modified, staged, with unstaged changes + ["deleted,unstaged", 1, 0, 1], // deleted, unstaged + ["deleted,staged", 1, 0, 0], + ["unmodified", 1, 1, 3], + ["deleted,not in git", 0, 0, 3], + ["unstaged,modified", 1, 2, 0] +]; + +const statusmatrix: statusMatrixType[] = fileStatuses.map((x: any) => { + return { + matrix: x.shift().split(","), + status: x, + }; +}); + +let plugin: Plugin, dispatch: React.Dispatch + +export const setPlugin = (p: Plugin, dispatcher: React.Dispatch) => { + plugin = p + dispatch = dispatcher +} + +export const init = async () => { + + await plugin.call('dgitApi', "init"); + await gitlog(); + await getBranches(); +} + +export const getBranches = async () => { + + const branches = await plugin.call('dgitApi', "branches") + + dispatch(setBranches(branches)); +} +export const getRemotes = async () => { + + const remotes: remote[] = await plugin.call('dgitApi', "remotes"); + + dispatch(setRemotes(remotes)); +} + +export const setUpstreamRemote = async (remote: remote) => { + dispatch(setUpstream(remote)); +} + +export const getFileStatusMatrix = async (filepaths: string[]) => { + dispatch(setLoading(true)) + const fileStatusResult = await statusMatrix(filepaths); + fileStatusResult.map((m) => { + statusmatrix.map((sm) => { + if (JSON.stringify(sm.status) === JSON.stringify(m.status)) { + m.statusNames = sm.matrix; + } + }); + }); + if (!filepaths) { + dispatch(fileStatus(fileStatusResult)) + } else { + dispatch(fileStatusMerge(fileStatusResult)) + setFileDecorators(fileStatusResult) + } + dispatch(setLoading(false)) +} + +export const getCommits = async () => { + + try { + const commits: ReadCommitResult[] = await plugin.call( + 'dgitApi', + "log", + { ref: "HEAD" } + ); + + return commits; + } catch (e) { + return []; + } +} + +export const gitlog = async () => { + dispatch(setLoading(true)) + let commits = [] + try { + commits = await getCommits() + } catch (e) { + } + dispatch(setCommits(commits)) + await showCurrentBranch() + dispatch(setLoading(false)) +} + +export const showCurrentBranch = async () => { + try { + const branch = await currentBranch(); + dispatch(setCanCommit((branch && branch.name !== ""))); + dispatch(setCurrentBranch(branch)); + } catch (e) { + console.log(e) + dispatch(setCanCommit(false)); + dispatch(setCurrentBranch({ name: "", remote: { name: "", url: "" } })); + } + + try { + const currentHead = await getCommitFromRef('HEAD'); + dispatch(setCurrenHead(currentHead)); + } catch (e) { + console.log(e) + dispatch(setCurrenHead('')); + } + +} + +export const currentBranch = async () => { + + const branch: branch = + (await plugin.call('dgitApi', "currentbranch")) || { + name: "", + remote: { + name: "", + url: "", + }, + }; + return branch; + +} + +export const createBranch = async (name: string = "") => { + dispatch(setLoading(true)) + if (name) { + await plugin.call('dgitApi', 'branch', { ref: name, force: true, checkout: true }); + } + dispatch(setLoading(false)) +} + +export const getCommitFromRef = async (ref: string) => { + const commitOid = await plugin.call('dgitApi', "resolveref", { + ref: ref, + }); + return commitOid; +} + +const settingsWarning = async () => { + const username = await plugin.call('config', 'getAppParameter', 'settings/github-user-name') + const email = await plugin.call('config', 'getAppParameter', 'settings/github-email') + if (!username || !email) { + plugin.call('notification', 'toast', 'Please set your github username and email in the settings') + return false; + } else { + return { + username, + email + }; + } +} + +export const commit = async (message: string = "") => { + + try { + const credentials = await settingsWarning() + if (!credentials) { + dispatch(setLoading(false)) + return + } + + const sha = await plugin.call('dgitApi', 'commit', { + author: { + name: credentials.username, + email: credentials.email, + }, + message: message, + }); + + sendToGitLog({ + type: 'success', + message: `Commited: ${sha}` + }) + + } catch (err) { + plugin.call('notification', 'toast', `${err}`) + } + +} + +export const addall = async (files: fileStatusResult[]) => { + try { + const filesToAdd = files + .filter(f => !f.statusNames.includes('deleted')) + .map(f => removeSlash(f.filename)) + const filesToRemove = files + .filter(f => f.statusNames.includes('deleted')) + .map(f => removeSlash(f.filename)) + try { + add({ filepath: filesToAdd }) + } catch (e) { } + sendToGitLog({ + type: 'success', + message: `Added all files to git` + }) + + try { + filesToRemove.map(f => rm({ filepath: f })) + } catch (e) { } + + } catch (e) { + plugin.call('notification', 'toast', `${e}`) + } +} + +export const add = async (filepath: addInput) => { + try { + if (typeof filepath.filepath === "string") { + filepath.filepath = removeSlash(filepath.filepath) + } + await plugin.call('dgitApi', 'add', filepath); + sendToGitLog({ + type: 'success', + message: `Added to git` + }) + } catch (e) { + plugin.call('notification', 'toast', `${e}`) + } + +} + +const getLastCommmit = async () => { + try { + let currentcommitoid = ""; + currentcommitoid = await getCommitFromRef("HEAD"); + return currentcommitoid; + } catch (e) { + return false; + } +} + +export const rm = async (args: rmInput) => { + await plugin.call('dgitApi', 'rm', { + filepath: removeSlash(args.filepath), + }); + sendToGitLog({ + type: 'success', + message: `Removed from git` + }) +} + +export const checkoutfile = async (filename: string) => { + const oid = await getLastCommmit(); + if (oid) + try { + const commitOid = await plugin.call('dgitApi', 'resolveref', { + ref: oid, + }); + const { blob } = await plugin.call('dgitApi', 'readblob', { + oid: commitOid, + filepath: removeSlash(filename), + }); + const original = Buffer.from(blob).toString("utf8"); + //(original, filename); + await disableCallBacks(); + await plugin.call( + "fileManager", + "setFile", + removeSlash(filename), + original + ); + await enableCallBacks(); + } catch (e) { + plugin.call('notification', 'toast', `No such file`) + } +} + +export const checkout = async (cmd: checkoutInput) => { + + await disableCallBacks(); + await plugin.call('fileManager', 'closeAllFiles') + try { + await plugin.call('dgitApi', 'checkout', cmd) + } catch (e) { + console.log(e) + plugin.call('notification', 'toast', `${e}`) + } + await enableCallBacks(); +} + +export const clone = async (input: cloneInputType) => { + + dispatch(setLoading(true)) + const urlParts = input.url.split("/"); + const lastPart = urlParts[urlParts.length - 1]; + const repoName = lastPart.split(".")[0]; + const timestamp = new Date().getTime(); + const repoNameWithTimestamp = `${repoName}-${timestamp}`; + + try { + await disableCallBacks() + const token = await plugin.call('config' as any, 'getAppParameter' as any, 'settings/gist-access-token') + + await plugin.call('dgitApi', 'clone', { ...input, workspaceName: repoNameWithTimestamp }); + await enableCallBacks() + + sendToGitLog({ + type: 'success', + message: `Cloned ${input.url} to ${repoNameWithTimestamp}` + }) + + } catch (e: any) { + await parseError(e) + } + dispatch(setLoading(false)) +} + +export const fetch = async (input: fetchInputType) => { + dispatch(setLoading(true)) + await disableCallBacks() + try { + await plugin.call('dgitApi', 'fetch', input); + if (!input.quiet) { + await gitlog() + await getBranches() + } + } catch (e: any) { + console.log(e) + await parseError(e) + } + dispatch(setLoading(false)) + await enableCallBacks() +} + +export const pull = async (input: pullInputType) => { + dispatch(setLoading(true)) + await disableCallBacks() + try { + await plugin.call('dgitApi', 'pull', input) + await gitlog() + } catch (e: any) { + console.log(e) + await parseError(e) + } + dispatch(setLoading(false)) + await enableCallBacks() +} + +export const push = async (input: pushInputType) => { + dispatch(setLoading(true)) + await disableCallBacks() + try { + await plugin.call('dgitApi', 'push', input) + } catch (e: any) { + console.log(e) + await parseError(e) + } + dispatch(setLoading(false)) + await enableCallBacks() +} + +const tokenWarning = async () => { + const token = await plugin.call('config' as any, 'getAppParameter' as any, 'settings/gist-access-token') + if (!token) { + return false; + } else { + return token; + } +} + +const parseError = async (e: any) => { + console.trace(e) + // if message conttains 401 Unauthorized, show token warning + if (e.message.includes('401')) { + const result = await plugin.call('notification', 'modal' as any, { + title: 'The GitHub token may be missing or invalid', + message: 'Please check the GitHub token and try again. Error: 401 Unauthorized', + okLabel: 'Go to settings', + cancelLabel: 'Close', + type: ModalTypes.confirm + }) + } + // if message contains 404 Not Found, show repo not found + else if (e.message.includes('404')) { + await plugin.call('notification', 'modal' as any, { + title: 'Repository not found', + message: 'Please check the URL and try again.', + okLabel: 'Go to settings', + cancelLabel: 'Close', + type: ModalTypes.confirm + }) + } + // if message contains 403 Forbidden + else if (e.message.includes('403')) { + await plugin.call('notification', 'modal' as any, { + title: 'The GitHub token may be missing or invalid', + message: 'Please check the GitHub token and try again. Error: 403 Forbidden', + okLabel: 'Go to settings', + cancelLabel: 'Close', + type: ModalTypes.confirm + }) + } else if (e.toString().includes('NotFoundError') && !e.toString().includes('fetch')) { + await plugin.call('notification', 'modal', { + title: 'Remote branch not found', + message: 'The branch you are trying to fetch does not exist on the remote. If you have forked this branch from another branch, you may need to fetch the original branch first or publish this branch on the remote.', + okLabel: 'OK', + type: ModalTypes.alert + }) + } else { + await plugin.call('notification', 'alert' as any, { + title: 'Error', + message: e.message + }) + } +} + +export const repositories = async () => { + try { + const token = await tokenWarning(); + if (token) { + let repos = await plugin.call('dgitApi', 'repositories', { token, per_page: 100 }) + dispatch(setRepos(repos)) + let page = 2 + let hasMoreData = true + const per_page = 100 + while (hasMoreData) { + const pagedResponse = await plugin.call('dgitApi', 'repositories', { token, page: page, per_page: per_page }) + if (pagedResponse.length < per_page) { + hasMoreData = false + } + repos = [...repos, ...pagedResponse] + dispatch(setRepos(repos)) + page++ + } + + } else { + plugin.call('notification', 'alert', { + id: 'github-token-error', + title: 'Error getting repositories', + message: `Please check your GitHub token in the GitHub settings... cannot connect to GitHub` + }) + dispatch(setRepos([])) + } + } catch (e) { + console.log(e) + plugin.call('notification', 'alert', { + id: 'github-token-error', + title: 'Error getting repositories', + message: `${e.message}: Please check your GitHub token in the GitHub settings.` + }) + dispatch(setRepos([])) + } +} + +export const remoteBranches = async (owner: string, repo: string) => { + try { + const token = await tokenWarning(); + if (token) { + let branches = await plugin.call('dgitApi' as any, 'remotebranches', { token, owner, repo, per_page: 100 }); + dispatch(setRemoteBranches(branches)) + let page = 2 + let hasMoreData = true + const per_page = 100 + while (hasMoreData) { + const pagedResponse = await plugin.call('dgitApi' as any, 'remotebranches', { token, owner, repo, page: page, per_page: per_page }) + if (pagedResponse.length < per_page) { + hasMoreData = false + } + branches = [...branches, ...pagedResponse] + dispatch(setRemoteBranches(branches)) + page++ + } + } else { + plugin.call('notification', 'alert', { + title: 'Error getting branches', + id: 'github-token-error', + message: `Please check your GitHub token in the GitHub settings. It needs to have access to the branches.` + }) + dispatch(setRemoteBranches([])) + } + } catch (e) { + console.log(e) + plugin.call('notification', 'alert', { + title: 'Error', + id: 'github-error', + message: e.message + }) + dispatch(setRemoteBranches([])) + } +} + +export const remoteCommits = async (url: string, branch: string, length: number) => { + const urlParts = url.split("/"); + + // check if it's github + if (!urlParts[urlParts.length - 3].includes('github')) { + return + } + + const owner = urlParts[urlParts.length - 2]; + const repo = urlParts[urlParts.length - 1].split(".")[0]; + + try { + const token = await tokenWarning(); + if (token) { + + const commits = await plugin.call('dgitApi' as any, 'remotecommits', { token, owner, repo, branch, length }); + + } else { + sendToGitLog({ + type: 'error', + message: `Please check your GitHub token in the GitHub settings.` + }) + } + } catch (e) { + // do nothing + } +} + +export const saveGitHubCredentials = async (credentials: { username: string, email: string, token: string }) => { + + try { + const storedEmail = await plugin.call('config', 'getAppParameter', 'settings/github-email') + const storedUsername = await plugin.call('config', 'getAppParameter', 'settings/github-user-name') + const storedToken = await plugin.call('config', 'getAppParameter', 'settings/gist-access-token') + + if (storedUsername !== credentials.username) await plugin.call('config', 'setAppParameter', 'settings/github-user-name', credentials.username) + if (storedEmail !== credentials.email) await plugin.call('config', 'setAppParameter', 'settings/github-email', credentials.email) + if (storedToken !== credentials.token) await plugin.call('config', 'setAppParameter', 'settings/gist-access-token', credentials.token) + + const userFetched = await loadGitHubUserFromToken() + if (!userFetched) { + if (credentials.username && credentials.email) { + await plugin.call('notification', 'alert', { + title: 'Error', + id: 'github-credentials-error', + message: `Could not retreive the user from GitHub. You can continue to use the app, but you will not be able to push or pull.` + }) + } + dispatch(setGitHubUser({ + login: credentials.username, + })) + dispatch(setUserEmails([{ + email: credentials.email, + primary: true, + verified: null, + visibility: null + }])) + dispatch(setScopes([])) + } + + } catch (e) { + console.log(e) + } +} + +export const getGitHubCredentialsFromLocalStorage = async () => { + if (!plugin) return + try { + const username = await plugin.call('config', 'getAppParameter', 'settings/github-user-name') + const email = await plugin.call('config', 'getAppParameter', 'settings/github-email') + const token = await plugin.call('config', 'getAppParameter', 'settings/gist-access-token') + return { + username, + email, + token + } + } catch (e) { + console.log(e) + } +} + +export const showAlert = async ({ title, message }: { title: string, message: string }) => { + await plugin.call('notification', 'alert', { + id: 'github-alert', + title: title, + message: message + }) +} + +export const loadGitHubUserFromToken = async () => { + if (!plugin) return + try { + const token = await tokenWarning(); + if (token) { + const data: { + user: GitHubUser, + scopes: string[] + emails: userEmails + } = await plugin.call('dgitApi' as any, 'getGitHubUser', { token }); + + if (data && data.emails && data.user && data.user.login) { + + const primaryEmail = data.emails.find(email => email.primary) + + const storedEmail = await plugin.call('config', 'getAppParameter', 'settings/github-email') + if (primaryEmail && storedEmail !== primaryEmail.email) await plugin.call('config', 'setAppParameter', 'settings/github-email', primaryEmail.email) + const storedUsername = await plugin.call('config', 'getAppParameter', 'settings/github-user-name') + if (data.user && data.user.login && (storedUsername !== data.user.login)) await plugin.call('config', 'setAppParameter', 'settings/github-user-name', data.user.login) + + dispatch(setGitHubUser(data.user)) + dispatch(setScopes(data.scopes)) + dispatch(setUserEmails(data.emails)) + sendToGitLog({ + type: 'success', + message: `Github user loaded...` + }) + return true + } else { + sendToGitLog({ + type: 'error', + message: `Please check your GitHub token in the GitHub settings.` + }) + dispatch(setGitHubUser(null)) + return false + } + } else { + sendToGitLog({ + type: 'error', + message: `Please check your GitHub token in the GitHub settings.` + }) + dispatch(setGitHubUser(null)) + return false + } + } catch (e) { + console.log(e) + return false + } +} + +export const statusMatrix = async (filepaths: string[]) => { + const matrix = await plugin.call('dgitApi', 'status', { ref: "HEAD", filepaths: filepaths || ['.']}); + const result = (matrix || []).map((x) => { + return { + filename: `/${x.shift()}`, + status: x, + statusNames: [] + }; + }); + + return result; +} + +export const resolveRef = async (ref: string) => { + const oid = await plugin.call('dgitApi', "resolveref", { + ref, + }); + return oid; +} + +export const diff = async (commitChange: commitChange) => { + + if (!commitChange.hashModified) { + const newcontent = await plugin.call( + "fileManager", + "readFile",// + removeSlash(commitChange.path) + ); + commitChange.modified = newcontent; + commitChange.readonly = false; + + } else { + + try { + const modifiedContentReadBlobResult: ReadBlobResult = await plugin.call('dgitApi', "readblob", { + oid: commitChange.hashModified, + filepath: removeSlash(commitChange.path), + }); + + const modifiedContent = Buffer.from(modifiedContentReadBlobResult.blob).toString("utf8"); + + commitChange.modified = modifiedContent; + commitChange.readonly = true; + } catch (e) { + commitChange.modified = ""; + } + } + + try { + const originalContentReadBlobResult: ReadBlobResult = await plugin.call('dgitApi', "readblob", { + oid: commitChange.hashOriginal, + filepath: removeSlash(commitChange.path), + }); + + const originalContent = Buffer.from(originalContentReadBlobResult.blob).toString("utf8"); + + commitChange.original = originalContent; + } catch (e) { + commitChange.original = ""; + } + +} + +export const getCommitChanges = async (oid1: string, oid2: string, branch?: branch, remote?: remote) => { + try { + let log + try { + // check if oid2 exists + log = await plugin.call('dgitApi', 'log', { + ref: branch ? branch.name : 'HEAD', + }) + + } catch (e) { + console.log(e, 'log error') + } + if (log) { + const foundCommit = log.find((commit: ReadCommitResult) => commit.oid === oid2) + if (!foundCommit && remote) { + + //await fetch(remote ? remote.name : null, branch ? branch.name : null, null, 5, true, true) + await fetch({ + remote: remote, + singleBranch: true, + quiet: true, + relative: true, + depth: 5, + ref: branch, + remoteRef: null + }) + } + } + const result: commitChange[] = await plugin.call('dgitApi', 'getCommitChanges', oid1, oid2) + dispatch(setCommitChanges(result)) + return result + } catch (e) { + console.log(e) + return false + } +} + +async function getRepoDetails(url: string) { + // Extract the owner and repo name from the URL + const pathParts = new URL(url).pathname.split('/').filter(part => part); + if (pathParts.length < 2) { + throw new Error("URL must be in the format 'https://github.com/[owner]/[repository]'"); + } + const owner = pathParts[0]; + const repo = pathParts[1]; + return { owner, repo }; +} + +export const fetchBranch = async (branch: branch, page: number) => { + if (!branch.remote || !branch.remote.url) return + const token = await tokenWarning(); + if (page == 1) { + dispatch(resetRemoteBranchCommits({ branch })) + } + try { + const { owner, repo } = await getRepoDetails(branch.remote.url); + const rc = await plugin.call('dgitApi', 'remotecommits', { token, owner: owner, repo: repo, branch: branch.name, length, page }); + dispatch(setRemoteBranchCommits({ branch, commits: rc })) + } catch (e) { + sendToGitLog({ + type: 'error', + message: `Error fetching remote commits: ${e.message}` + }) + } + return +} + +export const getBranchDifferences = async (branch: branch, remote: remote, state: gitState) => { + if (!remote && state) { + if (state.defaultRemote) { + remote = state.defaultRemote + } else { + remote = state.remotes.find((remote: remote) => remote.name === 'origin') + } + if (!remote && state.remotes[0]) { + remote = state.remotes[0] + } + } + if (!remote) return + try { + + const branchDifference: branchDifference = await plugin.call('dgitApi', 'compareBranches', { + branch, + remote + }) + + dispatch(setBranchDifferences( + { + branch, + remote, + branchDifference: branchDifference + })) + } catch (e) { + // do nothing + } +} + +export const getBranchCommits = async (branch: branch, page: number) => { + dispatch(setLoading(true)) + await disableCallBacks() + try { + if (!branch.remote) { + const commits: ReadCommitResult[] = await plugin.call('dgitApi', 'log', { + ref: branch.name, + }) + dispatch(setLocalBranchCommits({ branch, commits })) + } else { + await fetchBranch(branch, page) + } + } catch (e) { + console.trace(e) + await fetchBranch(branch, page) + } + dispatch(setLoading(false)) + await enableCallBacks() +} + +export const setDefaultRemote = async (remote: remote) => { + dispatch(setRemoteAsDefault(remote)) +} + +export const addRemote = async (remote: remote) => { + try { + await plugin.call('dgitApi', 'addremote', remote) + await getRemotes() + } catch (e) { + console.log(e) + } +} + +export const removeRemote = async (remote: remote) => { + try { + await plugin.call('dgitApi', 'delremote', remote) + await getRemotes() + } catch (e) { + console.log(e) + } +} + +export const sendToGitLog = async (message: gitLog) => { + dispatch(setLog(message)) +} + +export const clearGitLog = async () => { + dispatch(clearLog()) +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/lib/listeners.ts b/libs/remix-ui/git/src/lib/listeners.ts new file mode 100644 index 0000000000..66c94bdd8d --- /dev/null +++ b/libs/remix-ui/git/src/lib/listeners.ts @@ -0,0 +1,201 @@ + +import React from "react"; +import { setCanUseApp, setLoading, setRepoName, setGItHubToken, setLog, setGitHubUser, setUserEmails } from "../state/gitpayload"; +import { gitActionDispatch } from "../types"; +import { Plugin } from "@remixproject/engine"; +import { getBranches, getFileStatusMatrix, loadGitHubUserFromToken, getRemotes, gitlog, setPlugin } from "./gitactions"; +import { Profile } from "@remixproject/plugin-utils"; +import { CustomRemixApi } from "@remix-api"; +import { statusChanged } from "./pluginActions"; + +let plugin: Plugin, gitDispatch: React.Dispatch, loaderDispatch: React.Dispatch, loadFileQueue: AsyncDebouncedQueue +let callBackEnabled: boolean = false + +type AsyncCallback = () => Promise; + +class AsyncDebouncedQueue { + private queues: Map; + + constructor(private delay: number = 300) { + this.queues = new Map(); + } + + enqueue(callback: AsyncCallback, customDelay?:number): void { + if (this.queues.has(callback)) { + clearTimeout(this.queues.get(callback)!.timer); + } + + const timer = setTimeout(async () => { + await callback(); + this.queues.delete(callback); + }, customDelay || this.delay); + + this.queues.set(callback, { timer, lastCall: Date.now() }); + } +} + +export const setCallBacks = (viewPlugin: Plugin, gitDispatcher: React.Dispatch, loaderDispatcher: React.Dispatch, setAtivePanel: React.Dispatch>) => { + plugin = viewPlugin + gitDispatch = gitDispatcher + loaderDispatch = loaderDispatcher + loadFileQueue = new AsyncDebouncedQueue() + + setPlugin(viewPlugin, gitDispatcher) + + plugin.on("fileManager", "fileSaved", async (file: string) => { + loadFileQueue.enqueue(async () => { + loadFiles() + }) + }); + + plugin.on("fileManager", "fileAdded", async (e) => { + loadFileQueue.enqueue(async () => { + loadFiles() + }) + }); + + plugin.on("fileManager", "fileRemoved", async (e) => { + loadFileQueue.enqueue(async () => { + loadFiles() + }) + }); + + plugin.on("fileManager", "fileRenamed", async (oldfile, newfile) => { + loadFileQueue.enqueue(async () => { + loadFiles() + }) + }); + + plugin.on("filePanel", "setWorkspace", async (x: any) => { + gitDispatch(setCanUseApp(x && !x.isLocalhost && x.name)) + loadFileQueue.enqueue(async () => { + loadFiles() + }) + loadFileQueue.enqueue(async () => { + gitlog() + }) + loadFileQueue.enqueue(async () => { + getBranches() + }) + loadFileQueue.enqueue(async () => { + getRemotes() + }) + }); + + plugin.on('dgitApi', 'checkout', async () => { + loadFileQueue.enqueue(async () => { + gitlog() + }) + loadFileQueue.enqueue(async () => { + getBranches() + }) + gitDispatch(setLog({ + message: "Checkout", + type: "success" + })) + }) + plugin.on('dgitApi', 'init', async () => { + loadFileQueue.enqueue(async () => { + loadFiles() + }, 10) + }) + plugin.on('dgitApi', 'add', async () => { + loadFileQueue.enqueue(async () => { + loadFiles() + }, 10) + }) + plugin.on('dgitApi', 'rm', async () => { + loadFileQueue.enqueue(async () => { + loadFiles() + }, 10) + }) + plugin.on('dgitApi', 'commit', async () => { + loadFileQueue.enqueue(async () => { + gitlog() + }, 10) + loadFileQueue.enqueue(async () => { + getBranches() + }, 20) + gitDispatch(setLog({ + message: 'Committed changes...', + type: 'success' + })) + }) + plugin.on('dgitApi', 'branch', async () => { + loadFileQueue.enqueue(async () => { + gitlog() + }) + loadFileQueue.enqueue(async () => { + getBranches() + }) + gitDispatch(setLog({ + message: "Created Branch", + type: "success" + })) + }) + plugin.on('dgitApi', 'clone', async () => { + gitDispatch(setLog({ + message: "Cloned Repository", + type: "success" + })) + loadFileQueue.enqueue(async () => { + loadFiles() + }) + }) + plugin.on('manager', 'pluginActivated', async (p: Profile) => { + if (p.name === 'dgitApi') { + loadGitHubUserFromToken(); + plugin.off('manager', 'pluginActivated'); + } + }) + + plugin.on('config', 'configChanged', async () => { + await getGitConfig() + }) + plugin.on('settings', 'configChanged', async () => { + await getGitConfig() + }) + + plugin.on('dgit' as any, 'openPanel', async (panel: string) => { + const panels = { + 'branches': '2' + } + const panelNumber = panels[panel] + setAtivePanel(panelNumber) + }) + + callBackEnabled = true; +} + +export const getGitConfig = async () => { + const username = await plugin.call('settings', 'get', 'settings/github-user-name') + const email = await plugin.call('settings', 'get', 'settings/github-email') + const token = await plugin.call('settings', 'get', 'settings/gist-access-token') + const config = { username, email, token } + + loadGitHubUserFromToken() + return + +} + +export const loadFiles = async (filepaths: string[] = null) => { + try { + const branch = await plugin.call('dgitApi', "currentbranch") + if (branch) { + await getFileStatusMatrix(filepaths); + } else { + await plugin.call('fileDecorator', 'clearFileDecorators') + statusChanged(0) + } + } catch (e) { + console.error(e); + } +} + +export const disableCallBacks = async () => { + callBackEnabled = false; +} +export const enableCallBacks = async () => { + callBackEnabled = true; +} + diff --git a/libs/remix-ui/git/src/lib/pluginActions.ts b/libs/remix-ui/git/src/lib/pluginActions.ts new file mode 100644 index 0000000000..ece2b3953a --- /dev/null +++ b/libs/remix-ui/git/src/lib/pluginActions.ts @@ -0,0 +1,100 @@ + +import { commitChange, fileStatusResult, gitActionDispatch, gitState } from "../types" +import { fileDecoration, fileDecorationType } from "@remix-ui/file-decorators" +import { removeSlash } from "../utils" +import { getFilesByStatus } from "./fileHelpers" +import { CustomRemixApi } from "@remix-api"; +import { Plugin } from "@remixproject/engine"; + +let plugin: Plugin, gitDispatch: React.Dispatch, loaderDispatch: React.Dispatch + +export const setPlugin = (p: Plugin, gitDispatcher: React.Dispatch, loaderDispatcher: React.Dispatch) => { + plugin = p + gitDispatch = gitDispatcher + loaderDispatch = loaderDispatcher +} + +export const statusChanged = (badges: number) => { + if (!plugin) return + plugin.emit('statusChanged', { + key: badges === 0 ? 'none' : badges, + type: badges === 0 ? '' : 'success', + title: 'Git changes' + }) +} + +export const openFile = async (path: string) => { + if (!plugin) return + await plugin.call('fileManager', 'open', path) +} + +export const openDiff = async (change: commitChange) => { + if (!plugin) return + plugin.call('fileManager', 'diff', change) +} + +export const saveToken = async (token: string) => { + if (!plugin) return + await plugin.call('config', 'setAppParameter', 'settings/gist-access-token', token) +} + +export const setFileDecorators = async (files: fileStatusResult[]) => { + + if (!plugin) return + const modified = getFilesByStatus('modified', files) + const untracked = getFilesByStatus('untracked', files) + const unmodified = getFilesByStatus('unmodified', files) + + await setModifiedDecorator(modified) + await setUntrackedDecorator(untracked) + unmodified.forEach((file) => { + clearFileDecorator(removeSlash(file.filename)) + }) +} + +export const setModifiedDecorator = async (files: fileStatusResult[]) => { + const decorators: fileDecoration[] = [] + for (const file of files) { + const decorator: fileDecoration = { + path: removeSlash(file.filename), + isDirectory: false, + fileStateType: fileDecorationType.Custom, + fileStateLabelClass: 'text-warning', + fileStateIconClass: 'text-warning', + fileStateIcon: '', + text: 'M', + owner: 'git', + bubble: true, + comment: 'Modified' + } + decorators.push(decorator) + } + + await plugin.call('fileDecorator', 'setFileDecorators', decorators) +} + +export const setUntrackedDecorator = async (files: fileStatusResult[]) => { + const decorators: fileDecoration[] = [] + for (const file of files) { + const decorator: fileDecoration = { + path: removeSlash(file.filename), + isDirectory: false, + fileStateType: fileDecorationType.Custom, + fileStateLabelClass: 'text-success', + fileStateIconClass: 'text-success', + fileStateIcon: '', + text: 'U', + owner: 'git', + bubble: true, + comment: 'Untracked' + } + decorators.push(decorator) + } + + await plugin.call('fileDecorator', 'setFileDecorators', decorators) +} + +export const clearFileDecorator = async(path: string) => { + await plugin.call('fileDecorator', 'clearFileDecorators', path) +} + diff --git a/libs/remix-ui/git/src/state/actions.ts b/libs/remix-ui/git/src/state/actions.ts new file mode 100644 index 0000000000..4d35aa1b8c --- /dev/null +++ b/libs/remix-ui/git/src/state/actions.ts @@ -0,0 +1,52 @@ +import { ReadCommitResult } from "isomorphic-git" +import { branch, branchDifference, commitChange, fileStatusResult, GitHubUser, gitLog, pagedCommits, remote, remoteBranch, repository, userEmails } from "../types" + +export interface ActionPayloadTypes { + FILE_STATUS: fileStatusResult[], + FILE_STATUS_MERGE: fileStatusResult[] + SET_COMMITS: ReadCommitResult[] + SET_BRANCHES: branch[] + SET_CURRENT_BRANCH: branch + SET_CURRENT_HEAD: string + SET_CAN_USE_APP: boolean + SET_REPO_NAME: string + SET_LOADING: boolean + SET_REPOS: repository[] + SET_REMOTE_BRANCHES: remoteBranch[] + SET_CAN_COMMIT: boolean + SET_REMOTES: remote[] + SET_UPSTREAM: remote + SET_COMMIT_CHANGES: commitChange[] + RESET_REMOTE_BRANCH_COMMITS: { + branch: branch + pagedCommits: pagedCommits[] + } + SET_REMOTE_BRANCH_COMMITS: { + branch: branch + commits: pagedCommits[] + } + SET_LOCAL_BRANCH_COMMITS: { + branch: branch + commits: ReadCommitResult[] + } + SET_BRANCH_DIFFERENCES: { + branch: branch + remote: remote + branchDifference: branchDifference + } + SET_GITHUB_USER: GitHubUser + SET_RATE_LIMIT: any + SET_GITHUB_ACCESS_TOKEN: string + SET_SCOPES: string[] + SET_DEFAULT_REMOTE: remote + SET_LOG: gitLog + CLEAR_LOG: void + SET_USER_EMAILS: userEmails +} + +export interface Action { + type: T, + payload: ActionPayloadTypes[T] +} + +export type Actions = {[A in keyof ActionPayloadTypes]: Action}[keyof ActionPayloadTypes] \ No newline at end of file diff --git a/libs/remix-ui/git/src/state/context.tsx b/libs/remix-ui/git/src/state/context.tsx new file mode 100644 index 0000000000..4608406a7f --- /dev/null +++ b/libs/remix-ui/git/src/state/context.tsx @@ -0,0 +1,59 @@ +import { ReadCommitResult } from "isomorphic-git" +import React from "react" +import { addInput, branch, checkoutInput, cloneInputType, commitChange, fetchInputType, fileStatusResult, gitLog, gitState, pullInputType, pushInputType, remote, rmInput } from "../types" + +export interface gitActions { + removeRemote(remote: remote): void + clone(input: cloneInputType): Promise + add(input: addInput): Promise + rm(input: rmInput): Promise + commit(message: string): Promise + addall(files: fileStatusResult[]): Promise + push(input: pushInputType): Promise + pull(input: pullInputType): Promise + fetch(input: fetchInputType): Promise + repositories(): Promise + checkoutfile(file: string): Promise + checkout(input: checkoutInput): Promise + createBranch(branch: string): Promise + remoteBranches(owner: string, repo: string): Promise + getCommitChanges(oid1: string, oid2: string, branch?: branch, remote?: remote): Promise + getBranchCommits(branch: branch, page: number): Promise + getBranchDifferences(branch: branch, remote?: remote, state?: gitState): Promise + loadGitHubUserFromToken(): Promise + diff(commitChange: commitChange): Promise + resolveRef(ref: string): Promise + setUpstreamRemote(upstream: remote): Promise + getBranches: () => Promise + getRemotes: () => Promise + setDefaultRemote: (remote: remote) => Promise + addRemote: (remote: remote) => Promise + sendToGitLog: (message: gitLog) => Promise + clearGitLog: () => Promise + getFileStatusMatrix(filespaths:[]): Promise + gitlog(): Promise + init(): Promise +} + +export const gitActionsContext = React.createContext(null) + +export interface pluginActions { + statusChanged(data: any): void + loadFiles(): void + openFile(path: string): Promise + openDiff(change: commitChange): Promise + saveToken(token: string): Promise + saveGitHubCredentials({ + username, + email, + token + }): Promise + getGitHubCredentialsFromLocalStorage(): Promise<{ + username: string + email: string + token: string + }> + showAlert({ title, message }:{title: string, message: string}): Promise +} + +export const pluginActionsContext = React.createContext(null) \ No newline at end of file diff --git a/libs/remix-ui/git/src/state/gitpayload.ts b/libs/remix-ui/git/src/state/gitpayload.ts new file mode 100644 index 0000000000..c075331d6e --- /dev/null +++ b/libs/remix-ui/git/src/state/gitpayload.ts @@ -0,0 +1,220 @@ +import { ReadCommitResult } from "isomorphic-git" +import { GitHubUser, branch, commitChange, fileStatusResult, remote, pagedCommits, branchDifference, gitLog, repository, userEmails } from "../types" +import { Endpoints } from "@octokit/types" + +export const fileStatus = (files: fileStatusResult[]) => { + return { + type: 'FILE_STATUS', + payload: files + } +} + +export const fileStatusMerge = (files: fileStatusResult[]) => { + return { + type: 'FILE_STATUS_MERGE', + payload: files + } +} + +export const setCommits = (commits: ReadCommitResult[]) => { + return { + type: 'SET_COMMITS', + payload: commits + } +} + +export const setBranches = (branches: any[]) => { + return { + type: 'SET_BRANCHES', + payload: branches + } +} + +export const setRepos = (repos: repository[]) => { + return { + type: 'SET_REPOS', + payload: repos + } +} + +export const setRemoteBranches = (branches: any[]) => { + return { + type: 'SET_REMOTE_BRANCHES', + payload: branches + } +} + +export const setGitHubUser = (user: GitHubUser) => { + + return { + type: 'SET_GITHUB_USER', + payload: user + } +} + +export const setUserEmails = (emails: userEmails) => { + return { + type: 'SET_USER_EMAILS', + payload: emails + } +} + +export const setScopes = (scopes: string[]) => { + return { + type: 'SET_SCOPES', + payload: scopes + } +} + +export const setGitHubAccessToken = (token: string) => { + return { + type: 'SET_GITHUB_ACCESS_TOKEN', + payload: token + } +} + +export const setLoading = (loading: boolean) => { + return { + type: 'SET_LOADING', + payload: loading + } +} + +export const setCanUseApp = (canUseApp: boolean) => { + return { + type: 'SET_CAN_USE_APP', + payload: canUseApp + } +} + +export const setRepoName = (reponame: string) => { + return { + type: 'SET_REPO_NAME', + payload: reponame + } +} + +export const setCurrentBranch = (currentBranch: branch) => { + return { + type: 'SET_CURRENT_BRANCH', + payload: currentBranch + } +} + +export const setCurrenHead = (currentHead: string) => { + return { + type: 'SET_CURRENT_HEAD', + payload: currentHead + } +} + +export const setCanCommit = (canCommit: boolean) => { + return { + type: 'SET_CAN_COMMIT', + payload: canCommit + } +} + +export const setRemotes = (remotes: remote[]) => { + return { + type: 'SET_REMOTES', + payload: remotes + } +} + +export const setUpstream = (upstream: remote) => { + return { + type: 'SET_UPSTREAM', + payload: upstream + } +} + +export const setCommitChanges = (commitChanges: commitChange[]) => { + return { + type: 'SET_COMMIT_CHANGES', + payload: commitChanges + } +} + +export const setRemoteBranchCommits = ({ branch, commits }:{ + branch: branch, + commits: pagedCommits[] +}):{ + type: string; + payload: { branch: branch; commits: pagedCommits[] }; +} => { + return { + type: 'SET_REMOTE_BRANCH_COMMITS', + payload: { branch, commits } + } +} + +export const resetRemoteBranchCommits = ({ branch }:{ + branch: branch, +}):{ + type: string; + payload: { branch: branch }; +} => { + return { + type: 'RESET_REMOTE_BRANCH_COMMITS', + payload: { branch } + } +} + +export const setLocalBranchCommits = ({ + branch, + commits +}: { + branch: branch; + commits: ReadCommitResult[]; +}): { + type: string; + payload: { branch: branch; commits: ReadCommitResult[] }; +} => { + return { + type: 'SET_LOCAL_BRANCH_COMMITS', + payload: { branch, commits } + }; +}; + +export const setBranchDifferences = ({ + branch, + remote, + branchDifference +}:{ + branch: branch; + remote: remote; + branchDifference: branchDifference; +}) => { + return { + type: 'SET_BRANCH_DIFFERENCES', + payload: { branch, remote, branchDifference } + } +} + +export const setGItHubToken = (token: string) => { + return { + type: 'SET_GITHUB_ACCESS_TOKEN', + payload: token + } +} + +export const setRemoteAsDefault = (remote: remote) => { + return { + type: 'SET_DEFAULT_REMOTE', + payload: remote + } +} + +export const setLog = (message: gitLog) => { + return { + type: 'SET_LOG', + payload: message + } +} + +export const clearLog = () => { + return { + type: 'CLEAR_LOG' + } +} diff --git a/libs/remix-ui/git/src/state/gitreducer.tsx b/libs/remix-ui/git/src/state/gitreducer.tsx new file mode 100644 index 0000000000..674e1e69a5 --- /dev/null +++ b/libs/remix-ui/git/src/state/gitreducer.tsx @@ -0,0 +1,208 @@ +import { ReadCommitResult } from "isomorphic-git" +import { allChangedButNotStagedFiles, getFilesByStatus, getFilesWithNotModifiedStatus } from "../lib/fileHelpers" +import { branch, commitChange, defaultGitState, fileStatusResult, gitState, setRemoteBranchCommitsAction, setLocalBranchCommitsAction, setBranchDifferencesAction, setDefaultRemoteAction, setRemotesAction, setUpstreamAction } from "../types" +import { Actions } from "./actions" + +export const gitReducer = (state: gitState = defaultGitState, action: Actions): gitState => { + switch (action.type) { + + case 'FILE_STATUS': + return { + ...state, + fileStatusResult: action.payload, + staged: getFilesByStatus("staged", action.payload), + modified: getFilesByStatus("modified", action.payload), + untracked: getFilesByStatus("untracked", action.payload), + deleted: getFilesByStatus("deleted", action.payload), + allchangesnotstaged: allChangedButNotStagedFiles(action.payload) + } + + case 'FILE_STATUS_MERGE': + action.payload.map((fileStatusResult: fileStatusResult) => { + const file = state.fileStatusResult.find(stateFile => { + return stateFile.filename === fileStatusResult.filename + }) + if (file) { + file.status = fileStatusResult.status + file.statusNames = fileStatusResult.statusNames + } + }) + + return { + ...state, + staged: getFilesByStatus("staged", state.fileStatusResult), + modified: getFilesByStatus("modified", state.fileStatusResult), + untracked: getFilesByStatus("untracked", state.fileStatusResult), + deleted: getFilesByStatus("deleted", state.fileStatusResult), + allchangesnotstaged: allChangedButNotStagedFiles(state.fileStatusResult) + } + + case 'SET_COMMITS': + return { + ...state, + commits: action.payload, + localCommitCount: action.payload.length + } + + case 'SET_BRANCHES': + return { + ...state, + branches: action.payload + } + + case 'SET_CURRENT_BRANCH': + return { + ...state, + currentBranch: action.payload + } + + case 'SET_CURRENT_HEAD': + return { + ...state, + currentHead: action.payload + } + + case 'SET_CAN_USE_APP': + return { + ...state, + canUseApp: action.payload + } + case 'SET_REPO_NAME': + return { + ...state, + reponame: action.payload + } + case 'SET_LOADING': + return { + ...state, + loading: action.payload + } + + case 'SET_REPOS': + return { + ...state, + repositories: action.payload + } + + case 'SET_REMOTE_BRANCHES': + return { + ...state, + remoteBranches: action.payload + } + + case 'SET_CAN_COMMIT': + return { + ...state, + canCommit: action.payload + } + + case 'SET_REMOTES': + return { + ...state, + remotes: action.payload + } + + case 'SET_UPSTREAM': + return { + ...state, + upstream: action.payload + } + + case 'SET_COMMIT_CHANGES': + + action.payload.forEach((change: commitChange) => { + state.commitChanges.find((c) => c.hashModified === change.hashModified && c.hashOriginal === change.hashOriginal && c.path === change.path) ? null : state.commitChanges.push(change) + }) + + return { + ...state, + commitChanges: [...state.commitChanges] + } + + case 'RESET_REMOTE_BRANCH_COMMITS': + if (state.remoteBranchCommits[action.payload.branch.name]) { + delete state.remoteBranchCommits[action.payload.branch.name] + } + return { + ...state, + remoteBranchCommits: { ...state.remoteBranchCommits } + } + + case 'SET_REMOTE_BRANCH_COMMITS': + if (state.remoteBranchCommits[action.payload.branch.name]) { + state.remoteBranchCommits[action.payload.branch.name].push(...action.payload.commits) + } else { + state.remoteBranchCommits[action.payload.branch.name] = action.payload.commits + } + return { + ...state, + remoteBranchCommits: { ...state.remoteBranchCommits } + } + + case 'SET_LOCAL_BRANCH_COMMITS': + + state.localBranchCommits[action.payload.branch.name] = action.payload.commits + return { + ...state, + localBranchCommits: { ...state.localBranchCommits } + } + + case 'SET_BRANCH_DIFFERENCES': + + state.branchDifferences[`${action.payload.remote.name}/${action.payload.branch.name}`] = action.payload.branchDifference + + return { + ...state, + branchDifferences: { ...state.branchDifferences } + } + + case 'SET_GITHUB_USER': + return { + ...state, + gitHubUser: action.payload + } + + case 'SET_GITHUB_ACCESS_TOKEN': + return { + ...state, + gitHubAccessToken: action.payload + } + + case 'SET_SCOPES': + return { + ...state, + gitHubScopes: action.payload + } + + case 'SET_USER_EMAILS': + return { + ...state, + userEmails: action.payload + } + + case 'SET_DEFAULT_REMOTE': + return { + ...state, + defaultRemote: action.payload + } + + case 'SET_LOG': + if (state.log.length > 0 && state.log[[...state.log].length - 1].message === action.payload.message) { + return { + ...state, + log: [...state.log] + } + } + return { + ...state, + log: [...state.log, action.payload] + } + + case 'CLEAR_LOG': + return { + ...state, + log: [] + } + + } +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/state/loaderReducer.ts b/libs/remix-ui/git/src/state/loaderReducer.ts new file mode 100644 index 0000000000..dccd7439de --- /dev/null +++ b/libs/remix-ui/git/src/state/loaderReducer.ts @@ -0,0 +1,11 @@ +import { defaultLoaderState, loaderState } from "../types"; + +interface Action { + type: string + payload: any +} + +export const loaderReducer = (state: loaderState = defaultLoaderState, action: Action): loaderState => { + state[action.type] = action.payload + return state +} \ No newline at end of file diff --git a/libs/remix-ui/git/src/style/index.css b/libs/remix-ui/git/src/style/index.css new file mode 100644 index 0000000000..973889c15c --- /dev/null +++ b/libs/remix-ui/git/src/style/index.css @@ -0,0 +1,36 @@ +.nav { + cursor: pointer; +} + +.pointer { + cursor: pointer; +} + +.long-and-truncated { + flex: 1; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + +.commit-navigation{ + align-items: center; +} + +.commit-navigation:hover { + background-color: var(--custom-select); +} + +.commitdetailsitem { + align-items: baseline; +} + +.gitfile:hover { + background-color : var(--custom-select); +} + +hr { + background-color: var(--custom-select); +} + + diff --git a/libs/remix-ui/git/src/types/index.ts b/libs/remix-ui/git/src/types/index.ts new file mode 100644 index 0000000000..795646b84d --- /dev/null +++ b/libs/remix-ui/git/src/types/index.ts @@ -0,0 +1,436 @@ +import { Endpoints } from "@octokit/types" +import { IRemixApi } from "@remixproject/plugin-api" +import { LibraryProfile, StatusEvents } from "@remixproject/plugin-utils" +import { CommitObject, ReadBlobResult, ReadCommitResult, StatusRow } from "isomorphic-git" +export type GitHubUser = Partial +export type userEmails = Endpoints["GET /user/emails"]["response"]["data"] + +export interface IGitApi { + events: { + "checkout": () => void + "clone": () => void + "add": () => void + "rm": () => void + "commit": () => void + "branch": () => void + "init": () => void + } & StatusEvents, + methods: { + getCommitChanges(oid1: string, oid2: string): Promise + repositories(input: repositoriesInput): Promise + clone(input: cloneInputType): Promise + branches(input?: branchesInput): Promise, + remotes(): Promise, + log(cmd: { ref: string }): Promise, + remotecommits(input: remoteCommitsInputType): Promise + fetch(input: fetchInputType): Promise + pull(input: pullInputType): Promise + push(input: pushInputType): Promise + currentbranch(input?: currentBranchInput): Promise + branch(input: branchInputType): Promise + checkout(input: checkoutInput): Promise + add(input: addInput): Promise + rm(input: rmInput): Promise + resolveref(input: resolveRefInput): Promise + readblob(input: readBlobInput): Promise + commit(input: commitInput): Promise + addremote(input: remote): Promise + delremote(input: remote): Promise + status(input?: statusInput): Promise> + compareBranches(input: compareBranchesInput): Promise + init(input?: initInput): Promise + updateSubmodules: (input: updateSubmodulesInput) => Promise + } +} + +export type initInput = { + defaultBranch: string +} + +export type updateSubmodulesInput = { + dir?: string + token?: string +} + +export type remoteCommitsInputType = { + owner: string, repo: string, token: string, branch: string, length: number, page: number +} + +export type compareBranchesInput = { + branch: branch, remote: remote +} + +export type fetchInputType = { + remote: remote, + ref?: branch, + remoteRef?: branch, + depth?: number, + singleBranch?: boolean, + relative?: boolean, + quiet?: boolean +} + +export type pullInputType = { + remote: remote, ref: branch, remoteRef?: branch +} + +export type pushInputType = { + remote: remote, ref: branch, remoteRef?: branch, force?: boolean +} + +export type branchInputType = { + ref: string, + checkout?: boolean + refresh?: boolean + force?: boolean +} + +export type currentBranchInput = { + fs: any, + dir: string +} + +export type checkoutInput = { + ref: string, + force?: boolean, + remote?: string + refresh?: boolean + fetch?: boolean +} + +export type addInput = { + filepath: string | string[] +} + +export type rmInput = { + filepath: string +} + +export type resolveRefInput = { + ref: string +} + +export type readBlobInput = { + oid: string, + filepath: string +} + +export type commitInput = { + author: { + name: string, + email: string, + }, + message: string, +} + +export type branchesInput = { + fs?: any + dir?: string +} + +export interface cloneInputType { + url: string, + branch?: string, + depth?: number, + singleBranch?: boolean + workspaceName?: string + workspaceExists?: boolean + token?: string +} + +export interface repositoriesInput { token: string, page?: number, per_page?: number } + +export interface statusInput { ref: string, filepaths?: string[] } + +export const dGitProfile: LibraryProfile = { + name: 'dgitApi', + methods: ['clone', 'branches', 'remotes', 'getCommitChanges', 'log', 'remotecommits'], +} + +export interface customGitApi extends IRemixApi { + dgit: IGitApi +} + +export type gitState = { + currentBranch: branch + currentHead: string + commits: ReadCommitResult[] + branch: string + canCommit: boolean + branches: branch[] + remotes: remote[] + defaultRemote: remote + fileStatusResult: fileStatusResult[] + canUseApp: boolean + loading: boolean + storageUsed: any + reponame: string + staged: fileStatusResult[] + untracked: fileStatusResult[] + deleted: fileStatusResult[] + modified: fileStatusResult[] + allchangesnotstaged: fileStatusResult[], + repositories: repository[] + remoteBranches: remoteBranch[] + commitChanges: commitChange[] + remoteBranchCommits: Record + localBranchCommits: Record + branchDifferences: Record + syncStatus: syncStatus, + localCommitCount: number + remoteCommitCount: number + upstream: remote + gitHubUser: GitHubUser + userEmails: userEmails + gitHubScopes: string[] + gitHubAccessToken: string + log: gitLog[] +} +export type gitLog = { + type: 'error' | 'warning' | 'info' | 'success', + message: string +} + +export type remoteBranchIdentifier = `${string}/${string}` + +export type branchDifference = { + uniqueHeadCommits: ReadCommitResult[], + uniqueRemoteCommits: ReadCommitResult[], +} + +export type pagedCommits = { + page: number, + perPage: number, + total: number, + hasNextPage: boolean, + commits: ReadCommitResult[] +} + +export type loaderState = { + branches: boolean + remotes: boolean + commits: boolean + sourcecontrol: boolean + plugin: boolean +} + +export type commitChangeTypes = { + "deleted": "D" + "modified": "M" + "added": "A", + "unknown": "?" +} + +export enum syncStatus { + "sync" = "sync", + "publishBranch" = "publishBranch", + "none" = "none", +} + +export type commitChangeType = keyof commitChangeTypes + +export type commitChange = { + type: commitChangeType + path: string, + hashModified: string, + hashOriginal: string, + original?: string, + modified?: string, + readonly?: boolean +} + +export type repository = { + name: string + html_url: string + owner: { + login: string + }, + full_name: string + default_branch: string + id: number + url: string +} + +export type branch = { + name: string + remote: remote +} + +export type remote = { + name: string + url: string +} + +export type remoteBranch = { + name: string +} + +export const defaultGitState: gitState = { + currentBranch: { name: "", remote: { name: "", url: "" } }, + currentHead: "", + commits: [], + branch: "", + canCommit: true, + branches: [], + remotes: [], + defaultRemote: null, + fileStatusResult: [], + staged: [], + untracked: [], + deleted: [], + modified: [], + allchangesnotstaged: [], + canUseApp: false, + loading: false, + storageUsed: {}, + reponame: "", + repositories: [], + remoteBranches: [], + commitChanges: [], + remoteBranchCommits: {}, + localBranchCommits: {}, + branchDifferences: {}, + syncStatus: syncStatus.none, + localCommitCount: 0, + remoteCommitCount: 0, + upstream: null, + gitHubUser: {} as GitHubUser, + userEmails: [] as userEmails, + gitHubScopes: [], + gitHubAccessToken: "", + log: [] +} + +export const defaultLoaderState: loaderState = { + branches: false, + commits: false, + sourcecontrol: false, + remotes: false, + plugin: false +} + +export type fileStatusResult = { + filename: string, + status?: fileStatus + statusNames?: string[] +} + +export type fileStatus = [string, 0 | 1, 0 | 1 | 2, 0 | 1 | 2 | 3] + +export type statusMatrixType = { matrix: string[] | undefined; status: string[] } + +export type sourceControlGroup = { + group: fileStatusResult[], + name: string +} + +export interface fileStatusAction { + type: string, + payload: fileStatusResult[] +} + +export interface setCommitsAction { + type: string, + payload: ReadCommitResult[] +} + +export interface setBranchesAction { + type: string, + payload: any[] +} + +export interface setReposAction { + type: string, + payload: any[] +} + +export interface setRemoteBranchesAction { + type: string, + payload: any[] +} + +export interface setGitHubUserAction { + type: string, + payload: any +} + +export interface setLoadingAction { + type: string, + payload: boolean +} + +export interface setCanUseAppAction { + type: string, + payload: boolean +} + +export interface setRepoNameAction { + type: string, + payload: string +} + +export interface setCurrentBranchAction { + type: string, + payload: branch +} + +export interface setCurrentHeadAction { + type: string, + payload: string +} + +export interface setRemotesAction { + type: string, + payload: remote[] +} + +export interface setUpstreamAction { + type: string, + payload: remote +} + +export interface setRemoteBranchCommitsAction { + type: string, + payload: { + branch: branch, + commits: pagedCommits[] + } +} + +export interface setLocalBranchCommitsAction { + type: string, + payload: { + branch: branch, + commits: ReadCommitResult[] + } +} + +export interface setBranchDifferencesAction { + type: string, + payload: { + branch: branch, + remote: remote, + branchDifference: branchDifference + } +} + +export interface setTokenAction { + type: string, + payload: string +} + +export interface setDefaultRemoteAction { + type: string, + payload: remote +} + +export interface setLogAction { + type: string, + payload: gitLog +} + +export interface clearLogAction { + type: string +} + +export type gitActionDispatch = setCurrentHeadAction | clearLogAction | setLogAction | setDefaultRemoteAction | setTokenAction | setUpstreamAction | setRemoteBranchCommitsAction | setLocalBranchCommitsAction | setBranchDifferencesAction | setRemotesAction | setCurrentBranchAction | fileStatusAction | setLoadingAction | setCanUseAppAction | setRepoNameAction | setCommitsAction | setBranchesAction | setReposAction | setRemoteBranchesAction \ No newline at end of file diff --git a/libs/remix-ui/git/src/types/styles.ts b/libs/remix-ui/git/src/types/styles.ts new file mode 100644 index 0000000000..928a981dff --- /dev/null +++ b/libs/remix-ui/git/src/types/styles.ts @@ -0,0 +1,53 @@ +import { StylesConfig } from 'react-select' +export const selectStyles: StylesConfig = { + option: (baseStyles, state) => { + return { + ...baseStyles, + color: 'var(--text)', + } + }, + input(base, props) { + return { + ...base, + color: 'var(--text)', + } + }, + singleValue: (baseStyles, state) => { + return { + ...baseStyles, + color: 'var(--text)', + } + }, + control: (baseStyles, state) => ({ + ...baseStyles, + color: 'var(--text)', + backgroundColor: 'var(--custom-select)', + border: 'none', + }), + menu: (baseStyles, state) => { + return { + ...baseStyles, + backgroundColor: 'var(--custom-select)', + color: 'var(--text)', + } + }, + menuList: (baseStyles, props) => { + return { + ...baseStyles, + backgroundColor: 'var(--custom-select)', + color: 'var(--text)', + } + }, +} + +export const selectTheme = (theme) => ({ + ...theme, + borderRadius: 0, + colors: { + ...theme.colors, + primary25: 'var(--primary)', + primary: 'var(--primary)', + primary50: 'var(--primary)', + primary75: 'var(--primary)', + }, +}) \ No newline at end of file diff --git a/libs/remix-ui/git/src/utils/index.ts b/libs/remix-ui/git/src/utils/index.ts new file mode 100644 index 0000000000..8aab076424 --- /dev/null +++ b/libs/remix-ui/git/src/utils/index.ts @@ -0,0 +1,3 @@ +export const removeSlash = (s: string) => { + return s.replace(/^\/+/, ""); +}; diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx index e7629edea1..7275b90616 100644 --- a/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx @@ -8,7 +8,8 @@ import WorkspaceTemplate from './workspaceTemplate' import 'react-multi-carousel/lib/styles.css' import CustomNavButtons from './customNavButtons' import { appPlatformTypes, platformContext } from '@remix-ui/app' - +import { Plugin } from "@remixproject/engine"; +import { CustomRemixApi } from '@remix-api' declare global { interface Window { _paq: any @@ -69,9 +70,15 @@ function HomeTabGetStarted({ plugin }: HomeTabGetStartedProps) { let templateDisplayName = TEMPLATE_NAMES[templateName] const metadata = TEMPLATE_METADATA[templateName] + if (metadata) { if (metadata.type === 'git') { - await plugin.call('dGitProvider', 'clone', { url: metadata.url, branch: metadata.branch }, templateDisplayName) + await (plugin as Plugin).call('dgitApi', 'clone', + { + url: metadata.url, + branch: metadata.branch, + workspaceName: templateDisplayName + }) } else if (metadata && metadata.type === 'plugin') { await plugin.appManager.activatePlugin('filePanel') templateDisplayName = await plugin.call('filePanel', 'getAvailableWorkspaceName', templateDisplayName) diff --git a/libs/remix-ui/workspace/src/lib/actions/payload.ts b/libs/remix-ui/workspace/src/lib/actions/payload.ts index c19e93f4c5..59d0bc276d 100644 --- a/libs/remix-ui/workspace/src/lib/actions/payload.ts +++ b/libs/remix-ui/workspace/src/lib/actions/payload.ts @@ -1,4 +1,5 @@ import { fileDecoration } from '@remix-ui/file-decorators' +import { branch } from '@remix-ui/git'; import { Action, ActionPayloadTypes, FileTree, WorkspaceElement, action } from '../types' export const setCurrentWorkspace = (workspace: { name: string; isGitRepo: boolean; }): Action<'SET_CURRENT_WORKSPACE'> => { @@ -280,7 +281,7 @@ export const setCurrentWorkspaceBranches = (branches?: { remote: any, name: stri } } -export const setCurrentWorkspaceCurrentBranch = (currentBranch?: string): Action<'SET_CURRENT_WORKSPACE_CURRENT_BRANCH'> => { +export const setCurrentWorkspaceCurrentBranch = (currentBranch?: branch): Action<'SET_CURRENT_WORKSPACE_CURRENT_BRANCH'> => { return { type: 'SET_CURRENT_WORKSPACE_CURRENT_BRANCH', payload: currentBranch diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index fd79dd961c..0cea011610 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -42,7 +42,10 @@ import { ROOT_PATH, slitherYml, solTestYml, tsSolTestYml } from '../utils/consta import { IndexedDBStorage } from '../../../../../../apps/remix-ide/src/app/files/filesystems/indexedDB' import { getUncommittedFiles } from '../utils/gitStatusFilter' import { AppModal, ModalTypes } from '@remix-ui/app' +import { branch, cloneInputType, IGitApi } from '@remix-ui/git' import * as templates from '@remix-project/remix-ws-templates' +import { Plugin } from "@remixproject/engine"; +import { CustomRemixApi } from '@remix-api' declare global { interface Window { @@ -55,27 +58,28 @@ const NO_WORKSPACE = ' - none - ' const ELECTRON = 'electron' const queryParams = new QueryParams() const _paq = (window._paq = window._paq || []) //eslint-disable-line -let plugin, dispatch: React.Dispatch +let plugin: any, dgitPlugin: Plugin,dispatch: React.Dispatch export const setPlugin = (filePanelPlugin, reducerDispatch) => { plugin = filePanelPlugin + dgitPlugin = filePanelPlugin dispatch = reducerDispatch - plugin.on('dGitProvider', 'checkout', async () => { + dgitPlugin.on('dgitApi', 'checkout', async () => { await checkGit() }) - plugin.on('dGitProvider', 'init', async () => { + dgitPlugin.on('dgitApi', 'init', async () => { await checkGit() }) - plugin.on('dGitProvider', 'add', async () => { + dgitPlugin.on('dgitApi', 'add', async () => { await checkGit() }) - plugin.on('dGitProvider', 'commit', async () => { + dgitPlugin.on('dgitApi', 'commit', async () => { await checkGit() }) - plugin.on('dGitProvider', 'branch', async () => { + dgitPlugin.on('dgitApi', 'branch', async () => { await checkGit() }) - plugin.on('dGitProvider', 'clone', async () => { + dgitPlugin.on('dgitApi', 'clone', async () => { await checkGit() }) plugin.on('config', 'configChanged', async () => { @@ -152,31 +156,31 @@ export const createWorkspace = async ( if (isGitRepo && createCommit) { const name = await plugin.call('settings', 'get', 'settings/github-user-name') const email = await plugin.call('settings', 'get', 'settings/github-email') - const currentBranch = await plugin.call('dGitProvider', 'currentbranch') + const currentBranch: branch = await dgitPlugin.call('dgitApi', 'currentbranch') if (!currentBranch) { if (!name || !email) { - await plugin.call('notification', 'toast', 'To use Git features, add username and email to the Github section of the Settings panel.') + await plugin.call('notification', 'toast', 'To use Git features, add username and email to the Github section of the Git plugin.') } else { // commit the template as first commit plugin.call('notification', 'toast', 'Creating initial git commit ...') - await plugin.call('dGitProvider', 'init') + await dgitPlugin.call('dgitApi', 'init') if (!isEmpty) await loadWorkspacePreset(workspaceTemplateName, opts) - const status = await plugin.call('dGitProvider', 'status', { ref: 'HEAD' }) + const status = await dgitPlugin.call('dgitApi', 'status', { ref: 'HEAD' }) Promise.all( status.map(([filepath, , worktreeStatus]) => worktreeStatus - ? plugin.call('dGitProvider', 'add', { + ? dgitPlugin.call('dgitApi', 'add', { filepath: removeSlash(filepath), }) - : plugin.call('dGitProvider', 'rm', { + : dgitPlugin.call('dgitApi', 'rm', { filepath: removeSlash(filepath), }) ) ).then(async () => { - await plugin.call('dGitProvider', 'commit', { + await dgitPlugin.call('dgitApi', 'commit', { author: { name, email, @@ -200,11 +204,7 @@ export const createWorkspace = async ( }, 5000) } else if (!isEmpty && !(isGitRepo && createCommit)) await loadWorkspacePreset(workspaceTemplateName, opts) cb && cb(null, workspaceName) - if (isGitRepo) { - await checkGit() - const isActive = await plugin.call('manager', 'isActive', 'dgit') - if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') - } + if (workspaceTemplateName === 'semaphore' || workspaceTemplateName === 'hashchecker' || workspaceTemplateName === 'rln') { const isCircomActive = await plugin.call('manager', 'isActive', 'circuit-compiler') if (!isCircomActive) await plugin.call('manager', 'activatePlugin', 'circuit-compiler') @@ -224,7 +224,7 @@ export const createWorkspaceTemplate = async (workspaceName: string, template: W if ((await workspaceExists(workspaceName)) && template === 'remixDefault') throw new Error('workspace already exists') else if (metadata && metadata.type === 'git') { dispatch(cloneRepositoryRequest()) - await plugin.call('dGitProvider', 'clone', { url: metadata.url, branch: metadata.branch }, workspaceName) + await dgitPlugin.call('dgitApi', 'clone', { url: metadata.url, branch: metadata.branch, workspaceName: workspaceName }) dispatch(cloneRepositorySuccess()) } else { const workspaceProvider = plugin.fileProviders.workspace @@ -509,10 +509,7 @@ export const switchToWorkspace = async (name: string) => { await plugin.fileProviders.workspace.setWorkspace(name) await plugin.setWorkspace({ name, isLocalhost: false }) const isGitRepo = await plugin.fileManager.isGitRepo() - if (isGitRepo) { - const isActive = await plugin.call('manager', 'isActive', 'dgit') - if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') - } + dispatch(setMode('browser')) dispatch(setCurrentWorkspace({ name, isGitRepo })) dispatch(setReadOnlyMode(false)) @@ -648,11 +645,11 @@ export const getWorkspaces = async (): Promise<{ name: string; isGitRepo: boolea export const cloneRepository = async (url: string) => { const config = plugin.registry.get('config').api const token = config.get('settings/gist-access-token') - const repoConfig = { url, token } + const repoConfig: cloneInputType = { url, token } if (plugin.registry.get('platform').api.isDesktop()) { try { - await plugin.call('dGitProvider', 'clone', repoConfig) + await dgitPlugin.call('dgitApi', 'clone', repoConfig) } catch (e) { console.log(e) plugin.call('notification', 'alert', { @@ -665,7 +662,7 @@ export const cloneRepository = async (url: string) => { const repoName = await getRepositoryTitle(url) await createWorkspace(repoName, 'blank', null, true, null, true, false) - const promise = plugin.call('dGitProvider', 'clone', repoConfig, repoName, true) + const promise = dgitPlugin.call('dgitApi', 'clone', { ...repoConfig, workspaceExists: true, workspaceName: repoName }) dispatch(cloneRepositoryRequest()) promise @@ -687,7 +684,7 @@ export const cloneRepository = async (url: string) => { id: 'cloneGitRepository', title: 'Clone Git Repository', message: - 'An error occurred: Please check that you have the correct URL for the repo. If the repo is private, you need to add your github credentials (with the valid token permissions) in Settings plugin', + 'An error occurred: Please check that you have the correct URL for the repo. If the repo is private, you need to add your github credentials (with the valid token permissions) in the Git plugin', modalType: 'modal', okLabel: plugin.registry.get('platform').api.isDesktop() ? 'Select or create folder':'OK', okFn: async () => { @@ -714,7 +711,7 @@ export const checkGit = async () => { dispatch(setCurrentWorkspaceIsGitRepo(isGitRepo)) dispatch(setCurrentWorkspaceHasGitSubmodules(hasGitSubmodule)) await refreshBranches() - const currentBranch = await plugin.call('dGitProvider', 'currentbranch') + const currentBranch: branch = await dgitPlugin.call('dgitApi', 'currentbranch') dispatch(setCurrentWorkspaceCurrentBranch(currentBranch)) } catch (e) {} } @@ -743,7 +740,7 @@ export const getGitRepoBranches = async (workspacePath: string) => { fs: window.remixFileSystemCallback, dir: addSlash(workspacePath), } - const branches: { remote: any; name: string }[] = await plugin.call('dGitProvider', 'branches', { ...gitConfig }) + const branches: branch[] = await dgitPlugin.call('dgitApi', 'branches', { ...gitConfig }) return branches } @@ -752,7 +749,7 @@ export const getGitRepoCurrentBranch = async (workspaceName: string) => { fs: window.remixFileSystemCallback, dir: addSlash(workspaceName), } - const currentBranch: string = await plugin.call('dGitProvider', 'currentbranch', { ...gitConfig }) + const currentBranch: branch = await dgitPlugin.call('dgitApi', 'currentbranch', { ...gitConfig }) return currentBranch } @@ -781,7 +778,8 @@ const refreshBranches = async () => { dispatch(setCurrentWorkspaceBranches(branches)) } -export const switchBranch = async (branch: string) => { +export const switchBranch = async (branch: branch) => { + console.log('switch', branch) await plugin.call('fileManager', 'closeAllFiles') const localChanges = await hasLocalChanges() @@ -796,8 +794,8 @@ export const switchBranch = async (branch: string) => { okLabel: 'Force Checkout', okFn: async () => { dispatch(cloneRepositoryRequest()) - plugin - .call('dGitProvider', 'checkout', { ref: branch, force: true }, false) + dgitPlugin + .call('dgitApi', 'checkout', { ref: branch.name, force: true, refresh: false }) .then(async () => { await fetchWorkspaceDirectory(ROOT_PATH) dispatch(setCurrentWorkspaceCurrentBranch(branch)) @@ -814,8 +812,8 @@ export const switchBranch = async (branch: string) => { plugin.call('notification', 'modal', cloneModal) } else { dispatch(cloneRepositoryRequest()) - plugin - .call('dGitProvider', 'checkout', { ref: branch, force: true }, false) + dgitPlugin + .call('dgitApi', 'checkout', { ref: branch.name, force: true, refresh: false }) .then(async () => { await fetchWorkspaceDirectory(ROOT_PATH) dispatch(setCurrentWorkspaceCurrentBranch(branch)) @@ -828,13 +826,16 @@ export const switchBranch = async (branch: string) => { } export const createNewBranch = async (branch: string) => { - const promise = plugin.call('dGitProvider', 'branch', { ref: branch, checkout: true }, false) + const promise = dgitPlugin.call('dgitApi', 'branch', { ref: branch, checkout: true, refresh: false }) dispatch(cloneRepositoryRequest()) promise .then(async () => { await fetchWorkspaceDirectory(ROOT_PATH) - dispatch(setCurrentWorkspaceCurrentBranch(branch)) + dispatch(setCurrentWorkspaceCurrentBranch({ + remote: null, + name: branch, + })) const workspacesPath = plugin.fileProviders.workspace.workspacesPath const workspaceName = plugin.fileProviders.workspace.workspace const branches = await getGitRepoBranches(workspacesPath + '/' + workspaceName) @@ -880,11 +881,11 @@ export const updateGitSubmodules = async () => { const config = plugin.registry.get('config').api const token = config.get('settings/gist-access-token') const repoConfig = { token } - await plugin.call('dGitProvider', 'updateSubmodules', repoConfig) + await dgitPlugin.call('dgitApi', 'updateSubmodules', repoConfig) dispatch(cloneRepositorySuccess()) } -export const checkoutRemoteBranch = async (branch: string, remote: string) => { +export const checkoutRemoteBranch = async (branch: branch) => { const localChanges = await hasLocalChanges() if (Array.isArray(localChanges) && localChanges.length > 0) { @@ -898,8 +899,11 @@ export const checkoutRemoteBranch = async (branch: string, remote: string) => { okLabel: 'Force Checkout', okFn: async () => { dispatch(cloneRepositoryRequest()) - plugin - .call('dGitProvider', 'checkout', { ref: branch, remote, force: true }, false) + dgitPlugin + .call('dgitApi', 'checkout', { + ref: branch.name, + force: true, + }) .then(async () => { await fetchWorkspaceDirectory(ROOT_PATH) dispatch(setCurrentWorkspaceCurrentBranch(branch)) @@ -921,8 +925,12 @@ export const checkoutRemoteBranch = async (branch: string, remote: string) => { plugin.call('notification', 'modal', cloneModal) } else { dispatch(cloneRepositoryRequest()) - plugin - .call('dGitProvider', 'checkout', { ref: branch, remote, force: true }, false) + dgitPlugin + .call('dgitApi', 'checkout',{ + ref: branch.name, + force: true, + refresh: false, + }) .then(async () => { await fetchWorkspaceDirectory(ROOT_PATH) dispatch(setCurrentWorkspaceCurrentBranch(branch)) @@ -955,7 +963,7 @@ export const removeRecentElectronFolder = async (path: string) => { } export const hasLocalChanges = async () => { - const filesStatus = await plugin.call('dGitProvider', 'status') + const filesStatus = await dgitPlugin.call('dgitApi', 'status') const uncommittedFiles = getUncommittedFiles(filesStatus) return uncommittedFiles diff --git a/libs/remix-ui/workspace/src/lib/contexts/index.ts b/libs/remix-ui/workspace/src/lib/contexts/index.ts index 7e297ffb0d..4269b8b647 100644 --- a/libs/remix-ui/workspace/src/lib/contexts/index.ts +++ b/libs/remix-ui/workspace/src/lib/contexts/index.ts @@ -1,3 +1,4 @@ +import { branch } from '@remix-ui/git' import { customAction } from '@remixproject/plugin-api' import { createContext, SyntheticEvent } from 'react' import { BrowserState } from '../reducers/workspace' @@ -40,9 +41,9 @@ export const FileSystemContext = createContext<{ dispatchMoveFile: (src: string, dest: string) => Promise, dispatchMoveFolder: (src: string, dest: string) => Promise, dispatchShowAllBranches: () => Promise, - dispatchSwitchToBranch: (branch: string) => Promise, - dispatchCreateNewBranch: (branch: string) => Promise, - dispatchCheckoutRemoteBranch: (branch: string, remote: string) => Promise, + dispatchSwitchToBranch: (branch: branch) => Promise, + dispatchCreateNewBranch: (name: string) => Promise, + dispatchCheckoutRemoteBranch: (branch: branch) => Promise, dispatchCreateSolidityGithubAction: () => Promise, dispatchCreateTsSolGithubAction: () => Promise, dispatchCreateSlitherGithubAction: () => Promise diff --git a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx index 481991dd12..af2caab30f 100644 --- a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx +++ b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx @@ -5,6 +5,7 @@ import {Toaster} from '@remix-ui/toaster' // eslint-disable-line // eslint-disable-next-line @typescript-eslint/no-unused-vars import { FileSystemContext } from '../contexts' import { browserReducer, browserInitialState } from '../reducers/workspace' +import { branch } from '@remix-ui/git' import { initWorkspace, fetchDirectory, @@ -209,7 +210,7 @@ export const FileSystemProvider = (props: WorkspaceProps) => { await showAllBranches() } - const dispatchSwitchToBranch = async (branch: string) => { + const dispatchSwitchToBranch = async (branch: branch) => { await switchBranch(branch) } @@ -217,8 +218,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => { await createNewBranch(branch) } - const dispatchCheckoutRemoteBranch = async (branch: string, remote: string) => { - await checkoutRemoteBranch(branch, remote) + const dispatchCheckoutRemoteBranch = async (branch: branch) => { + await checkoutRemoteBranch(branch) } const dispatchCreateSolidityGithubAction = async () => { diff --git a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts index f86929ca23..b2febcc602 100644 --- a/libs/remix-ui/workspace/src/lib/reducers/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/reducers/workspace.ts @@ -5,6 +5,7 @@ import { fileDecoration } from '@remix-ui/file-decorators' import { ROOT_PATH } from '../utils/constants' import isElectron from 'is-electron' import { fileKeySort } from '../utils' +import { branch } from '@remix-ui/git' export interface BrowserState { browser: { currentWorkspace: string @@ -12,11 +13,8 @@ export interface BrowserState { name: string isGitRepo: boolean hasGitSubmodules?: boolean - branches?: { - remote: any - name: string - }[] - currentBranch?: string + branches?: branch[] + currentBranch?: branch isGist: string }[] files: {[x: string]: Record} diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 2368fc6a83..b35f750a8d 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -16,6 +16,7 @@ import { customAction } from '@remixproject/plugin-api' import { appPlatformTypes, platformContext } from '@remix-ui/app' import { ElectronMenu } from './components/electron-menu' import { ElectronWorkspaceName } from './components/electron-workspace-name' +import { branch } from '@remix-ui/git' const _paq = (window._paq = window._paq || []) @@ -693,13 +694,14 @@ export function Workspace() { global.dispatchShowAllBranches() } - const switchToBranch = async (branch: {remote: string; name: string}) => { + const switchToBranch = async (branch: branch) => { + console.log('switchToBranch', branch) try { if (branch.remote) { - await global.dispatchCheckoutRemoteBranch(branch.name, branch.remote) + await global.dispatchCheckoutRemoteBranch(branch) _paq.push(['trackEvent', 'Workspace', 'GIT', 'checkout_remote_branch']) } else { - await global.dispatchSwitchToBranch(branch.name) + await global.dispatchSwitchToBranch(branch) _paq.push(['trackEvent', 'Workspace', 'GIT', 'switch_to_exisiting_branch']) } } catch (e) { @@ -1219,7 +1221,7 @@ export function Workspace() { className="btn btn-light btn-block w-100 d-inline-block border border-dark form-control h-100 p-0 pl-2 pr-2 text-dark" icon={null} > - {global.fs.browser.isRequestingCloning ? : currentBranch || '-none-'} + {global.fs.browser.isRequestingCloning ? : (currentBranch && currentBranch.name) || '-none-'} @@ -1259,8 +1261,8 @@ export function Workspace() { }} title={intl.formatMessage({ id: `filePanel.switchToBranch${branch.remote ? 'Title1' : 'Title2'}` })} > -
    - {currentBranch === branch.name && !branch.remote ? ( +
    + {currentBranch && currentBranch.name === branch.name && !branch.remote ? ( {branch.name} @@ -1268,7 +1270,7 @@ export function Workspace() { ) : ( - {branch.remote ? `${branch.remote}/${branch.name}` : branch.name} + {branch.remote ? `${branch.remote.name}/${branch.name}` : branch.name} )}
    @@ -1280,7 +1282,7 @@ export function Workspace() {
    - : {branchFilter} from '{currentBranch}' + : {branchFilter} from '{currentBranch && currentBranch.name}'
    diff --git a/libs/remix-ui/workspace/src/lib/types/index.ts b/libs/remix-ui/workspace/src/lib/types/index.ts index 7d812c75ec..4c7cd5b1b0 100644 --- a/libs/remix-ui/workspace/src/lib/types/index.ts +++ b/libs/remix-ui/workspace/src/lib/types/index.ts @@ -6,6 +6,7 @@ import { RemixAppManager } from 'libs/remix-ui/plugin-manager/src/types' import { ViewPlugin } from '@remixproject/engine-web' import { appPlatformTypes } from '@remix-ui/app' import { Placement } from 'react-bootstrap/esm/Overlay' +import { branch } from '@remix-ui/git' export type action = { name: string, type?: Array, path?: string[], extension?: string[], pattern?: string[], id: string, multiselect: boolean, label: string, sticky?: boolean, group: number, platform?: appPlatformTypes } export interface JSONStandardInput { @@ -51,8 +52,8 @@ export type WorkspaceMetadata = { name: string isGitRepo: boolean hasGitSubmodules?: boolean - branches?: {remote: any; name: string}[] - currentBranch?: string + branches?: branch[] + currentBranch?: branch isGist: string } @@ -244,14 +245,14 @@ export interface ActionPayloadTypes { SET_CURRENT_WORKSPACE: { name: string isGitRepo: boolean - branches?: {remote: string | undefined; name: string}[] - currentBranch?: string + branches?: branch[] + currentBranch?: branch }, SET_WORKSPACES: { name: string isGitRepo: boolean - branches?: {remote: string | undefined; name: string}[] - currentBranch?: string + branches?: branch[] + currentBranch?: branch }[], SET_MODE: 'browser' | 'localhost', FETCH_DIRECTORY_REQUEST: undefined | null, @@ -293,8 +294,8 @@ export interface ActionPayloadTypes { CREATE_WORKSPACE_SUCCESS: { name: string isGitRepo: boolean - branches?: { remote: string | undefined; name: string }[] - currentBranch?: string + branches?: branch[] + currentBranch?: branch }, CREATE_WORKSPACE_ERROR: string, RENAME_WORKSPACE: { oldName: string; workspaceName: string }, @@ -317,8 +318,8 @@ export interface ActionPayloadTypes { CLONE_REPOSITORY_FAILED: undefined | null, FS_INITIALIZATION_COMPLETED: undefined | null, SET_FILE_DECORATION_SUCCESS: fileDecoration[], - SET_CURRENT_WORKSPACE_BRANCHES: { remote: string | undefined; name: string }[], - SET_CURRENT_WORKSPACE_CURRENT_BRANCH: string, + SET_CURRENT_WORKSPACE_BRANCHES: branch[], + SET_CURRENT_WORKSPACE_CURRENT_BRANCH: branch, SET_CURRENT_WORKSPACE_IS_GITREPO: boolean, SET_CURRENT_WORKSPACE_HAS_GIT_SUBMODULES: boolean, SET_GIT_CONFIG: { diff --git a/package.json b/package.json index 75166c9aca..647bda7c65 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "build-contracts": "find ./node_modules/@openzeppelin/contracts | grep -i '.sol' > libs/remix-ui/editor/src/lib/providers/completion/contracts/contracts.txt && find ./node_modules/@uniswap/v3-core/contracts | grep -i '.sol' >> libs/remix-ui/editor/src/lib/providers/completion/contracts/contracts.txt" }, "dependencies": { + "@apollo/client": "^3.9.5", "@babel/plugin-proposal-class-properties": "^7.16.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@erebos/bzz-node": "^0.13.0", @@ -97,6 +98,9 @@ "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", "@ethersphere/bee-js": "^3.2.0", + "@fortawesome/fontawesome-svg-core": "^6.5.1", + "@fortawesome/free-solid-svg-icons": "^6.5.1", + "@fortawesome/react-fontawesome": "^0.2.0", "@gradio/client": "^0.10.1", "@isomorphic-git/lightning-fs": "^4.4.1", "@microlink/react-json-view": "^1.23.0", @@ -149,11 +153,12 @@ "from-exponential": "1.1.1", "fs-extra": "^3.0.1", "ganache": "^7.9.1", + "graphql": "^16.8.1", "html-react-parser": "^3.0.4", "http-server": "^14.1.1", "intro.js": "^4.1.0", "isbinaryfile": "^3.0.2", - "isomorphic-git": "^1.25.0", + "isomorphic-git": "^1.25.7", "jquery": "^3.3.1", "js-yaml": "^4.1.0", "jspdf": "^2.5.1", @@ -167,6 +172,7 @@ "path-browserify": "^1.0.1", "prettier": "^2.8.4", "prettier-plugin-solidity": "^1.0.0-beta.24", + "ra-data-graphql": "^4.16.11", "raw-loader": "^4.0.2", "react": "^18.2.0", "react-beautiful-dnd": "^13.1.0", @@ -177,6 +183,7 @@ "react-markdown": "^8.0.5", "react-multi-carousel": "^2.8.2", "react-router-dom": "^6.16.0", + "react-select": "^5.8.0", "react-spinners": "^0.13.8", "react-tabs": "^6.0.2", "react-toastify": "^10.0.3", @@ -224,6 +231,9 @@ "@babel/register": "^7.4.4", "@electron-forge/cli": "^6.1.1", "@fortawesome/fontawesome-free": "^5.8.1", + "@graphql-codegen/cli": "^5.0.2", + "@graphql-codegen/client-preset": "^4.2.4", + "@graphql-typed-document-node/core": "^3.2.0", "@monaco-editor/react": "4.6.0", "@nrwl/cli": "15.7.1", "@nrwl/eslint-plugin-nx": "15.7.1", @@ -235,6 +245,7 @@ "@nrwl/web": "15.7.1", "@nrwl/webpack": "15.7.1", "@nrwl/workspace": "15.7.1", + "@octokit/types": "^12.4.0", "@openzeppelin/contracts-upgradeable": "^5.0.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", "@svgr/webpack": "^6.5.1", diff --git a/tsconfig.paths.json b/tsconfig.paths.json index 479658b4a9..27b4cf0fbf 100644 --- a/tsconfig.paths.json +++ b/tsconfig.paths.json @@ -172,7 +172,12 @@ "@remix-ui/xterm": [ "libs/remix-ui/xterm/src/index.ts" ], - + "@remix-ui/git": [ + "libs/remix-ui/git/src/index.ts" + ], + "@remix-api": [ + "libs/remix-api/src/index.ts" + ] } } } diff --git a/yarn.lock b/yarn.lock index 34d352ac8e..e0b092a4cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25,6 +25,56 @@ "@jridgewell/gen-mapping" "^0.1.0" "@jridgewell/trace-mapping" "^0.3.9" +"@apollo/client@^3.3.19", "@apollo/client@^3.9.5": + version "3.9.5" + resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.9.5.tgz#502ec191756a7f44788b5f08cbe7b8de594a7656" + integrity sha512-7y+c8MTPU+hhTwvcGVtMMGIgWduzrvG1mz5yJMRyqYbheBkkky3Lki6ADWVSBXG1lZoOtPYvB2zDgVfKb2HSsw== + dependencies: + "@graphql-typed-document-node/core" "^3.1.1" + "@wry/caches" "^1.0.0" + "@wry/equality" "^0.5.6" + "@wry/trie" "^0.5.0" + graphql-tag "^2.12.6" + hoist-non-react-statics "^3.3.2" + optimism "^0.18.0" + prop-types "^15.7.2" + rehackt "0.0.5" + response-iterator "^0.2.6" + symbol-observable "^4.0.0" + ts-invariant "^0.10.3" + tslib "^2.3.0" + zen-observable-ts "^1.2.5" + +"@ardatan/relay-compiler@12.0.0": + version "12.0.0" + resolved "https://registry.yarnpkg.com/@ardatan/relay-compiler/-/relay-compiler-12.0.0.tgz#2e4cca43088e807adc63450e8cab037020e91106" + integrity sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q== + dependencies: + "@babel/core" "^7.14.0" + "@babel/generator" "^7.14.0" + "@babel/parser" "^7.14.0" + "@babel/runtime" "^7.0.0" + "@babel/traverse" "^7.14.0" + "@babel/types" "^7.0.0" + babel-preset-fbjs "^3.4.0" + chalk "^4.0.0" + fb-watchman "^2.0.0" + fbjs "^3.0.0" + glob "^7.1.1" + immutable "~3.7.6" + invariant "^2.2.4" + nullthrows "^1.1.1" + relay-runtime "12.0.0" + signedsource "^1.0.0" + yargs "^15.3.1" + +"@ardatan/sync-fetch@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@ardatan/sync-fetch/-/sync-fetch-0.0.1.tgz#3385d3feedceb60a896518a1db857ec1e945348f" + integrity sha512-xhlTqH0m31mnsG0tIP4ETgfSB6gXDaYYsUWTrlUV93fFQPI9dd8hE0Ot6MHLCtqgB32hwJAC3YZMWlXZw7AleA== + dependencies: + node-fetch "^2.6.1" + "@babel/cli@^7.19.3": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.21.0.tgz#1868eb70e9824b427fc607610cce8e9e7889e7e1" @@ -70,6 +120,14 @@ "@babel/highlight" "^7.22.13" chalk "^2.4.2" +"@babel/code-frame@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== + dependencies: + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" + "@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8", "@babel/compat-data@^7.19.1": version "7.19.1" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.1.tgz#72d647b4ff6a4f82878d184613353af1dd0290f9" @@ -90,6 +148,11 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.0.tgz#c241dc454e5b5917e40d37e525e2f4530c399298" integrity sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g== +"@babel/compat-data@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" + integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== + "@babel/core@^7.11.6": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.0.tgz#1341aefdcc14ccc7553fcc688dd8986a2daffc13" @@ -132,6 +195,27 @@ semver "^6.3.0" source-map "^0.5.0" +"@babel/core@^7.14.0", "@babel/core@^7.22.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.9.tgz#b028820718000f267870822fec434820e9b1e4d1" + integrity sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.9" + "@babel/parser" "^7.23.9" + "@babel/template" "^7.23.9" + "@babel/traverse" "^7.23.9" + "@babel/types" "^7.23.9" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + "@babel/core@^7.15.0": version "7.19.3" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.3.tgz#2519f62a51458f43b682d61583c3810e7dcee64c" @@ -183,6 +267,16 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.14.0", "@babel/generator@^7.18.13", "@babel/generator@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" + integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== + dependencies: + "@babel/types" "^7.23.6" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + "@babel/generator@^7.15.8", "@babel/generator@^7.21.0", "@babel/generator@^7.4.0", "@babel/generator@^7.7.2": version "7.21.1" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.1.tgz#951cc626057bc0af2c35cd23e9c64d384dea83dd" @@ -235,6 +329,13 @@ dependencies: "@babel/types" "^7.18.6" +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz#acd4edfd7a566d1d51ea975dff38fd52906981bb" @@ -274,6 +375,17 @@ browserslist "^4.21.3" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" + integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== + dependencies: + "@babel/compat-data" "^7.23.5" + "@babel/helper-validator-option" "^7.23.5" + browserslist "^4.22.2" + lru-cache "^5.1.1" + semver "^6.3.1" + "@babel/helper-create-class-features-plugin@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.0.tgz#090d4d166b342a03a9fec37ef4fd5aeb9c7c6a4b" @@ -404,6 +516,13 @@ dependencies: "@babel/types" "^7.18.9" +"@babel/helper-member-expression-to-functions@^7.22.15": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" + integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== + dependencies: + "@babel/types" "^7.23.0" + "@babel/helper-module-imports@^7.0.0-beta.44": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz#90538e60b672ecf1b448f5f4f5433d37e79a3ec3" @@ -418,6 +537,13 @@ dependencies: "@babel/types" "^7.21.4" +"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + "@babel/helper-module-imports@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" @@ -481,6 +607,17 @@ "@babel/traverse" "^7.21.0" "@babel/types" "^7.21.0" +"@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + "@babel/helper-optimise-call-expression@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz#cecdb145d70c54096b1564f8e9f10cd7d193b338" @@ -495,6 +632,13 @@ dependencies: "@babel/types" "^7.18.6" +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" @@ -510,6 +654,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== +"@babel/helper-plugin-utils@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + "@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" @@ -541,6 +690,15 @@ "@babel/traverse" "^7.19.1" "@babel/types" "^7.19.0" +"@babel/helper-replace-supers@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" + integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-simple-access@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" @@ -562,6 +720,13 @@ dependencies: "@babel/types" "^7.20.2" +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818" @@ -569,6 +734,13 @@ dependencies: "@babel/types" "^7.18.9" +"@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-split-export-declaration@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438" @@ -610,6 +782,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== + "@babel/helper-validator-identifier@^7.15.7": version "7.15.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" @@ -630,6 +807,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== +"@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== + "@babel/helper-wrap-function@^7.18.9": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz#89f18335cff1152373222f76a4b37799636ae8b1" @@ -667,6 +849,15 @@ "@babel/traverse" "^7.19.4" "@babel/types" "^7.19.4" +"@babel/helpers@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.9.tgz#c3e20bbe7f7a7e10cb9b178384b4affdf5995c7d" + integrity sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ== + dependencies: + "@babel/template" "^7.23.9" + "@babel/traverse" "^7.23.9" + "@babel/types" "^7.23.9" + "@babel/highlight@^7.14.5", "@babel/highlight@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a" @@ -694,11 +885,25 @@ chalk "^2.4.2" js-tokens "^4.0.0" +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.21.0", "@babel/parser@^7.7.0": version "7.21.1" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.1.tgz#a8f81ee2fe872af23faea4b17a08fcc869de7bcc" integrity sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg== +"@babel/parser@^7.14.0", "@babel/parser@^7.16.8", "@babel/parser@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.9.tgz#7b903b6149b0f8fa7ad564af646c4c38a77fc44b" + integrity sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA== + "@babel/parser@^7.15.8", "@babel/parser@^7.4.3": version "7.21.2" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.2.tgz#dacafadfc6d7654c3051a66d6fe55b6cb2f2a0b3" @@ -760,6 +965,14 @@ "@babel/helper-remap-async-to-generator" "^7.18.9" "@babel/plugin-syntax-async-generators" "^7.8.4" +"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.16.0", "@babel/plugin-proposal-class-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-proposal-class-properties@^7.14.5": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.0.tgz#c029618267ddebc7280fa286e0f8ca2a278a2d1a" @@ -768,14 +981,6 @@ "@babel/helper-create-class-features-plugin" "^7.16.0" "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-proposal-class-properties@^7.16.0", "@babel/plugin-proposal-class-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" - integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-proposal-class-static-block@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020" @@ -844,6 +1049,17 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-numeric-separator" "^7.10.4" +"@babel/plugin-proposal-object-rest-spread@^7.0.0": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" + integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== + dependencies: + "@babel/compat-data" "^7.20.5" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.20.7" + "@babel/plugin-proposal-object-rest-spread@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz#f9434f6beb2c8cae9dfcf97d2a5941bbbf9ad4e7" @@ -931,7 +1147,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": +"@babel/plugin-syntax-class-properties@^7.0.0", "@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== @@ -966,6 +1182,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" +"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz#084564e0f3cc21ea6c70c44cff984a1c0509729a" + integrity sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-import-assertions@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz#cd6190500a4fa2fe31990a963ffab4b63e4505e4" @@ -973,6 +1196,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" +"@babel/plugin-syntax-import-assertions@^7.20.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz#9c05a7f592982aff1a2768260ad84bcd3f0c77fc" + integrity sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" @@ -987,6 +1217,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473" + integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-jsx@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" @@ -1015,7 +1252,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.8.3": +"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== @@ -1071,6 +1308,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.19.0" +"@babel/plugin-transform-arrow-functions@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz#94c6dcfd731af90f27a79509f9ab7fb2120fc38b" + integrity sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-arrow-functions@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe" @@ -1087,6 +1331,13 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/helper-remap-async-to-generator" "^7.18.6" +"@babel/plugin-transform-block-scoped-functions@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz#fe1177d715fb569663095e04f3598525d98e8c77" + integrity sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-block-scoped-functions@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" @@ -1094,6 +1345,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" +"@babel/plugin-transform-block-scoping@^7.0.0": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz#b2d38589531c6c80fbe25e6b58e763622d2d3cf5" + integrity sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-block-scoping@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz#f9b7e018ac3f373c81452d6ada8bd5a18928926d" @@ -1108,6 +1366,20 @@ dependencies: "@babel/helper-plugin-utils" "^7.19.0" +"@babel/plugin-transform-classes@^7.0.0": + version "7.23.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz#d08ae096c240347badd68cdf1b6d1624a6435d92" + integrity sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-split-export-declaration" "^7.22.6" + globals "^11.1.0" + "@babel/plugin-transform-classes@^7.19.0": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz#0e61ec257fba409c41372175e7c1e606dc79bb20" @@ -1123,6 +1395,14 @@ "@babel/helper-split-export-declaration" "^7.18.6" globals "^11.1.0" +"@babel/plugin-transform-computed-properties@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz#652e69561fcc9d2b50ba4f7ac7f60dcf65e86474" + integrity sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.15" + "@babel/plugin-transform-computed-properties@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e" @@ -1130,6 +1410,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.9" +"@babel/plugin-transform-destructuring@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz#8c9ee68228b12ae3dff986e56ed1ba4f3c446311" + integrity sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-destructuring@^7.18.13": version "7.18.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz#9e03bc4a94475d62b7f4114938e6c5c33372cbf5" @@ -1175,6 +1462,22 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" +"@babel/plugin-transform-flow-strip-types@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz#cfa7ca159cc3306fab526fc67091556b51af26ff" + integrity sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-flow" "^7.23.3" + +"@babel/plugin-transform-for-of@^7.0.0": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz#81c37e24171b37b370ba6aaffa7ac86bcb46f94e" + integrity sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-for-of@^7.18.8": version "7.18.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" @@ -1182,6 +1485,15 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" +"@babel/plugin-transform-function-name@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz#8f424fcd862bf84cb9a1a6b42bc2f47ed630f8dc" + integrity sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw== + dependencies: + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-function-name@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" @@ -1191,6 +1503,13 @@ "@babel/helper-function-name" "^7.18.9" "@babel/helper-plugin-utils" "^7.18.9" +"@babel/plugin-transform-literals@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz#8214665f00506ead73de157eba233e7381f3beb4" + integrity sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-literals@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" @@ -1198,6 +1517,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.9" +"@babel/plugin-transform-member-expression-literals@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz#e37b3f0502289f477ac0e776b05a833d853cabcc" + integrity sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-member-expression-literals@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" @@ -1214,6 +1540,15 @@ "@babel/helper-plugin-utils" "^7.18.6" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-commonjs@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz#661ae831b9577e52be57dd8356b734f9700b53b4" + integrity sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/plugin-transform-modules-commonjs@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz#afd243afba166cca69892e24a8fd8c9f2ca87883" @@ -1274,6 +1609,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" +"@babel/plugin-transform-object-super@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz#81fdb636dcb306dd2e4e8fd80db5b2362ed2ebcd" + integrity sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/plugin-transform-object-super@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" @@ -1282,6 +1625,13 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/helper-replace-supers" "^7.18.6" +"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.20.7": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz#83ef5d1baf4b1072fa6e54b2b0999a7b2527e2af" + integrity sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-parameters@^7.18.8": version "7.18.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz#ee9f1a0ce6d78af58d0956a9378ea3427cccb48a" @@ -1289,6 +1639,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" +"@babel/plugin-transform-property-literals@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz#54518f14ac4755d22b92162e4a852d308a560875" + integrity sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-property-literals@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" @@ -1303,6 +1660,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.20.2" +"@babel/plugin-transform-react-display-name@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz#70529f034dd1e561045ad3c8152a267f0d7b6200" + integrity sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-react-display-name@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz#8b1125f919ef36ebdfff061d664e266c666b9415" @@ -1317,6 +1681,17 @@ dependencies: "@babel/plugin-transform-react-jsx" "^7.18.6" +"@babel/plugin-transform-react-jsx@^7.0.0": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz#393f99185110cea87184ea47bcb4a7b0c2e39312" + integrity sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/types" "^7.23.4" + "@babel/plugin-transform-react-jsx@^7.18.6": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz#b3cbb7c3a00b92ec8ae1027910e331ba5c500eb9" @@ -1363,6 +1738,13 @@ babel-plugin-polyfill-regenerator "^0.4.1" semver "^6.3.0" +"@babel/plugin-transform-shorthand-properties@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz#97d82a39b0e0c24f8a981568a8ed851745f59210" + integrity sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-shorthand-properties@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" @@ -1370,6 +1752,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" +"@babel/plugin-transform-spread@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz#41d17aacb12bde55168403c6f2d6bdca563d362c" + integrity sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-spread@^7.19.0": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6" @@ -1385,6 +1775,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" +"@babel/plugin-transform-template-literals@^7.0.0": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz#5f0f028eb14e50b5d0f76be57f90045757539d07" + integrity sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-template-literals@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" @@ -1663,6 +2060,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.12.0", "@babel/runtime@^7.18.3": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" + integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.14.8": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259" @@ -1713,6 +2117,31 @@ "@babel/parser" "^7.22.15" "@babel/types" "^7.22.15" +"@babel/template@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.23.9.tgz#f881d0487cba2828d3259dcb9ef5005a9731011a" + integrity sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/parser" "^7.23.9" + "@babel/types" "^7.23.9" + +"@babel/traverse@^7.14.0", "@babel/traverse@^7.16.8", "@babel/traverse@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.9.tgz#2f9d6aead6b564669394c5ce0f9302bb65b9d950" + integrity sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.9" + "@babel/types" "^7.23.9" + debug "^4.3.1" + globals "^11.1.0" + "@babel/traverse@^7.15.4", "@babel/traverse@^7.16.0", "@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.19.3", "@babel/traverse@^7.19.4", "@babel/traverse@^7.19.6", "@babel/traverse@^7.21.0", "@babel/traverse@^7.21.2", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.3.tgz#26ee5f252e725aa7aca3474aa5b324eaf7908b5b" @@ -1746,6 +2175,15 @@ "@babel/helper-validator-identifier" "^7.15.7" to-fast-properties "^2.0.0" +"@babel/types@^7.16.8", "@babel/types@^7.18.13", "@babel/types@^7.23.4", "@babel/types@^7.23.6", "@babel/types@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.9.tgz#1dd7b59a9a2b5c87f8b41e52770b5ecbf492e002" + integrity sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.0.tgz#75f21d73d73dc0351f3368d28db73465f4814600" @@ -2103,6 +2541,94 @@ minimatch "^3.0.4" plist "^3.0.4" +"@emotion/babel-plugin@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" + integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/serialize" "^1.1.2" + babel-plugin-macros "^3.1.0" + convert-source-map "^1.5.0" + escape-string-regexp "^4.0.0" + find-root "^1.1.0" + source-map "^0.5.7" + stylis "4.2.0" + +"@emotion/cache@^11.11.0", "@emotion/cache@^11.4.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff" + integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/sheet" "^1.2.2" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + stylis "4.2.0" + +"@emotion/hash@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" + integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== + +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + +"@emotion/react@^11.8.1": + version "11.11.3" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.3.tgz#96b855dc40a2a55f52a72f518a41db4f69c31a25" + integrity sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/cache" "^11.11.0" + "@emotion/serialize" "^1.1.3" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + hoist-non-react-statics "^3.3.1" + +"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.3.tgz#84b77bfcfe3b7bb47d326602f640ccfcacd5ffb0" + integrity sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA== + dependencies: + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/unitless" "^0.8.1" + "@emotion/utils" "^1.2.1" + csstype "^3.0.2" + +"@emotion/sheet@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" + integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== + +"@emotion/unitless@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" + integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== + +"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963" + integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== + +"@emotion/utils@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4" + integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== + +"@emotion/weak-memoize@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" + integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== + "@erebos/bzz-node@^0.13.0": version "0.13.0" resolved "https://registry.yarnpkg.com/@erebos/bzz-node/-/bzz-node-0.13.0.tgz#495240c8b4fa67fa920c52a2d8db2cf82e673e1a" @@ -2846,6 +3372,26 @@ resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.0.0.tgz#f22824caff3ae506b18207bad4126dbc6ccdb6b8" integrity sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ== +"@floating-ui/core@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.0.tgz#fa41b87812a16bf123122bf945946bae3fdf7fc1" + integrity sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g== + dependencies: + "@floating-ui/utils" "^0.2.1" + +"@floating-ui/dom@^1.0.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.1.tgz#d552e8444f77f2d88534372369b3771dc3a2fa5d" + integrity sha512-iA8qE43/H5iGozC3W0YSnVSW42Vh522yyM1gj+BqRwVsTNOyr231PsXDaV04yT39PsO0QL2QpbI/M0ZaLUQgRQ== + dependencies: + "@floating-ui/core" "^1.6.0" + "@floating-ui/utils" "^0.2.1" + +"@floating-ui/utils@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" + integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== + "@formatjs/ecma402-abstract@1.11.7": version "1.11.7" resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.7.tgz#47f1a854f679f813d9baa1ee55adae94880ec706" @@ -2916,11 +3462,37 @@ intl-messageformat "10.1.0" tslib "2.4.0" +"@fortawesome/fontawesome-common-types@6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz#fdb1ec4952b689f5f7aa0bffe46180bb35490032" + integrity sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A== + "@fortawesome/fontawesome-free@^5.8.1": version "5.15.4" resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg== +"@fortawesome/fontawesome-svg-core@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz#9d56d46bddad78a7ebb2043a97957039fcebcf0a" + integrity sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ== + dependencies: + "@fortawesome/fontawesome-common-types" "6.5.1" + +"@fortawesome/free-solid-svg-icons@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz#737b8d787debe88b400ab7528f47be333031274a" + integrity sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ== + dependencies: + "@fortawesome/fontawesome-common-types" "6.5.1" + +"@fortawesome/react-fontawesome@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz#d90dd8a9211830b4e3c08e94b63a0ba7291ddcf4" + integrity sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw== + dependencies: + prop-types "^15.8.1" + "@gar/promisify@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" @@ -2935,6 +3507,444 @@ semiver "^1.1.0" ws "^8.13.0" +"@graphql-codegen/add@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@graphql-codegen/add/-/add-5.0.2.tgz#71b3ae0465a4537172dddb84531b6967ca5545f2" + integrity sha512-ouBkSvMFUhda5VoKumo/ZvsZM9P5ZTyDsI8LW18VxSNWOjrTeLXBWHG8Gfaai0HwhflPtCYVABbriEcOmrRShQ== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + tslib "~2.6.0" + +"@graphql-codegen/cli@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@graphql-codegen/cli/-/cli-5.0.2.tgz#07ff691c16da4c3dcc0e1995d3231530379ab317" + integrity sha512-MBIaFqDiLKuO4ojN6xxG9/xL9wmfD3ZjZ7RsPjwQnSHBCUXnEkdKvX+JVpx87Pq29Ycn8wTJUguXnTZ7Di0Mlw== + dependencies: + "@babel/generator" "^7.18.13" + "@babel/template" "^7.18.10" + "@babel/types" "^7.18.13" + "@graphql-codegen/client-preset" "^4.2.2" + "@graphql-codegen/core" "^4.0.2" + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-tools/apollo-engine-loader" "^8.0.0" + "@graphql-tools/code-file-loader" "^8.0.0" + "@graphql-tools/git-loader" "^8.0.0" + "@graphql-tools/github-loader" "^8.0.0" + "@graphql-tools/graphql-file-loader" "^8.0.0" + "@graphql-tools/json-file-loader" "^8.0.0" + "@graphql-tools/load" "^8.0.0" + "@graphql-tools/prisma-loader" "^8.0.0" + "@graphql-tools/url-loader" "^8.0.0" + "@graphql-tools/utils" "^10.0.0" + "@whatwg-node/fetch" "^0.8.0" + chalk "^4.1.0" + cosmiconfig "^8.1.3" + debounce "^1.2.0" + detect-indent "^6.0.0" + graphql-config "^5.0.2" + inquirer "^8.0.0" + is-glob "^4.0.1" + jiti "^1.17.1" + json-to-pretty-yaml "^1.2.2" + listr2 "^4.0.5" + log-symbols "^4.0.0" + micromatch "^4.0.5" + shell-quote "^1.7.3" + string-env-interpolation "^1.0.1" + ts-log "^2.2.3" + tslib "^2.4.0" + yaml "^2.3.1" + yargs "^17.0.0" + +"@graphql-codegen/client-preset@^4.2.2", "@graphql-codegen/client-preset@^4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@graphql-codegen/client-preset/-/client-preset-4.2.4.tgz#a20e85b07b77282bb27b2e8e014bed5d491443e7" + integrity sha512-k1c8v2YxJhhITGQGxViG9asLAoop9m7X9duU7Zztqjc98ooxsUzXICfvAWsH3mLAUibXAx4Ax6BPzKsTtQmBPg== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/template" "^7.20.7" + "@graphql-codegen/add" "^5.0.2" + "@graphql-codegen/gql-tag-operations" "4.0.6" + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-codegen/typed-document-node" "^5.0.6" + "@graphql-codegen/typescript" "^4.0.6" + "@graphql-codegen/typescript-operations" "^4.2.0" + "@graphql-codegen/visitor-plugin-common" "^5.1.0" + "@graphql-tools/documents" "^1.0.0" + "@graphql-tools/utils" "^10.0.0" + "@graphql-typed-document-node/core" "3.2.0" + tslib "~2.6.0" + +"@graphql-codegen/core@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@graphql-codegen/core/-/core-4.0.2.tgz#7e6ec266276f54bbf02f60599d9e518f4a59d85e" + integrity sha512-IZbpkhwVqgizcjNiaVzNAzm/xbWT6YnGgeOLwVjm4KbJn3V2jchVtuzHH09G5/WkkLSk2wgbXNdwjM41JxO6Eg== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-tools/schema" "^10.0.0" + "@graphql-tools/utils" "^10.0.0" + tslib "~2.6.0" + +"@graphql-codegen/gql-tag-operations@4.0.6": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@graphql-codegen/gql-tag-operations/-/gql-tag-operations-4.0.6.tgz#d16ee0306cfdea60217c025a1bc21649452d7da3" + integrity sha512-y6iXEDpDNjwNxJw3WZqX1/Znj0QHW7+y8O+t2V8qvbTT+3kb2lr9ntc8By7vCr6ctw9tXI4XKaJgpTstJDOwFA== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-codegen/visitor-plugin-common" "5.1.0" + "@graphql-tools/utils" "^10.0.0" + auto-bind "~4.0.0" + tslib "~2.6.0" + +"@graphql-codegen/plugin-helpers@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-5.0.3.tgz#7027b9d911d7cb594663590fcf5d63e9cf7ec2ff" + integrity sha512-yZ1rpULIWKBZqCDlvGIJRSyj1B2utkEdGmXZTBT/GVayP4hyRYlkd36AJV/LfEsVD8dnsKL5rLz2VTYmRNlJ5Q== + dependencies: + "@graphql-tools/utils" "^10.0.0" + change-case-all "1.0.15" + common-tags "1.8.2" + import-from "4.0.0" + lodash "~4.17.0" + tslib "~2.6.0" + +"@graphql-codegen/schema-ast@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@graphql-codegen/schema-ast/-/schema-ast-4.0.2.tgz#aeaa104e4555cca73a058f0a9350b4b0e290b377" + integrity sha512-5mVAOQQK3Oz7EtMl/l3vOQdc2aYClUzVDHHkMvZlunc+KlGgl81j8TLa+X7ANIllqU4fUEsQU3lJmk4hXP6K7Q== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-tools/utils" "^10.0.0" + tslib "~2.6.0" + +"@graphql-codegen/typed-document-node@^5.0.6": + version "5.0.6" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typed-document-node/-/typed-document-node-5.0.6.tgz#54750f4a7c6e963defeb6c27a9ea280a2a8bc2a3" + integrity sha512-US0J95hOE2/W/h42w4oiY+DFKG7IetEN1mQMgXXeat1w6FAR5PlIz4JrRrEkiVfVetZ1g7K78SOwBD8/IJnDiA== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-codegen/visitor-plugin-common" "5.1.0" + auto-bind "~4.0.0" + change-case-all "1.0.15" + tslib "~2.6.0" + +"@graphql-codegen/typescript-operations@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-operations/-/typescript-operations-4.2.0.tgz#0c6bbaf41cb325809b7e9e2b9d85ab01f11d142f" + integrity sha512-lmuwYb03XC7LNRS8oo9M4/vlOrq/wOKmTLBHlltK2YJ1BO/4K/Q9Jdv/jDmJpNydHVR1fmeF4wAfsIp1f9JibA== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-codegen/typescript" "^4.0.6" + "@graphql-codegen/visitor-plugin-common" "5.1.0" + auto-bind "~4.0.0" + tslib "~2.6.0" + +"@graphql-codegen/typescript@^4.0.6": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-4.0.6.tgz#2c9b70dc1eafda912de5e31c119c757b1aa5fca1" + integrity sha512-IBG4N+Blv7KAL27bseruIoLTjORFCT3r+QYyMC3g11uY3/9TPpaUyjSdF70yBe5GIQ6dAgDU+ENUC1v7EPi0rw== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-codegen/schema-ast" "^4.0.2" + "@graphql-codegen/visitor-plugin-common" "5.1.0" + auto-bind "~4.0.0" + tslib "~2.6.0" + +"@graphql-codegen/visitor-plugin-common@5.1.0", "@graphql-codegen/visitor-plugin-common@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-5.1.0.tgz#4edf7edb53460e71762a5fd8bbf5269bc3d9200b" + integrity sha512-eamQxtA9bjJqI2lU5eYoA1GbdMIRT2X8m8vhWYsVQVWD3qM7sx/IqJU0kx0J3Vd4/CSd36BzL6RKwksibytDIg== + dependencies: + "@graphql-codegen/plugin-helpers" "^5.0.3" + "@graphql-tools/optimize" "^2.0.0" + "@graphql-tools/relay-operation-optimizer" "^7.0.0" + "@graphql-tools/utils" "^10.0.0" + auto-bind "~4.0.0" + change-case-all "1.0.15" + dependency-graph "^0.11.0" + graphql-tag "^2.11.0" + parse-filepath "^1.0.2" + tslib "~2.6.0" + +"@graphql-tools/apollo-engine-loader@^8.0.0": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-8.0.1.tgz#1ec8718af6130ff8039cd653991412472cdd7e55" + integrity sha512-NaPeVjtrfbPXcl+MLQCJLWtqe2/E4bbAqcauEOQ+3sizw1Fc2CNmhHRF8a6W4D0ekvTRRXAMptXYgA2uConbrA== + dependencies: + "@ardatan/sync-fetch" "^0.0.1" + "@graphql-tools/utils" "^10.0.13" + "@whatwg-node/fetch" "^0.9.0" + tslib "^2.4.0" + +"@graphql-tools/batch-execute@^9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@graphql-tools/batch-execute/-/batch-execute-9.0.4.tgz#11601409c0c33491971fc82592de12390ec58be2" + integrity sha512-kkebDLXgDrep5Y0gK1RN3DMUlLqNhg60OAz0lTCqrYeja6DshxLtLkj+zV4mVbBA4mQOEoBmw6g1LZs3dA84/w== + dependencies: + "@graphql-tools/utils" "^10.0.13" + dataloader "^2.2.2" + tslib "^2.4.0" + value-or-promise "^1.0.12" + +"@graphql-tools/code-file-loader@^8.0.0": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/code-file-loader/-/code-file-loader-8.1.1.tgz#517c37d4f8a20b2c6558b10cbe9a6f9bcfe98918" + integrity sha512-q4KN25EPSUztc8rA8YUU3ufh721Yk12xXDbtUA+YstczWS7a1RJlghYMFEfR1HsHSYbF7cUqkbnTKSGM3o52bQ== + dependencies: + "@graphql-tools/graphql-tag-pluck" "8.3.0" + "@graphql-tools/utils" "^10.0.13" + globby "^11.0.3" + tslib "^2.4.0" + unixify "^1.0.0" + +"@graphql-tools/delegate@^10.0.4": + version "10.0.4" + resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-10.0.4.tgz#7c38240f11e42ec2dd45d0a569ca6433ce4cb8dc" + integrity sha512-WswZRbQZMh/ebhc8zSomK9DIh6Pd5KbuiMsyiKkKz37TWTrlCOe+4C/fyrBFez30ksq6oFyCeSKMwfrCbeGo0Q== + dependencies: + "@graphql-tools/batch-execute" "^9.0.4" + "@graphql-tools/executor" "^1.2.1" + "@graphql-tools/schema" "^10.0.3" + "@graphql-tools/utils" "^10.0.13" + dataloader "^2.2.2" + tslib "^2.5.0" + +"@graphql-tools/documents@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/documents/-/documents-1.0.0.tgz#e3ed97197cc22ec830ca227fd7d17e86d8424bdf" + integrity sha512-rHGjX1vg/nZ2DKqRGfDPNC55CWZBMldEVcH+91BThRa6JeT80NqXknffLLEZLRUxyikCfkwMsk6xR3UNMqG0Rg== + dependencies: + lodash.sortby "^4.7.0" + tslib "^2.4.0" + +"@graphql-tools/executor-graphql-ws@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@graphql-tools/executor-graphql-ws/-/executor-graphql-ws-1.1.2.tgz#2bf959d2319692460b39400c0fe1515dfbb9f034" + integrity sha512-+9ZK0rychTH1LUv4iZqJ4ESbmULJMTsv3XlFooPUngpxZkk00q6LqHKJRrsLErmQrVaC7cwQCaRBJa0teK17Lg== + dependencies: + "@graphql-tools/utils" "^10.0.13" + "@types/ws" "^8.0.0" + graphql-ws "^5.14.0" + isomorphic-ws "^5.0.0" + tslib "^2.4.0" + ws "^8.13.0" + +"@graphql-tools/executor-http@^1.0.9": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@graphql-tools/executor-http/-/executor-http-1.0.9.tgz#87ca8b99a32241eb0cc30a9c500d2672e92d58b7" + integrity sha512-+NXaZd2MWbbrWHqU4EhXcrDbogeiCDmEbrAN+rMn4Nu2okDjn2MTFDbTIab87oEubQCH4Te1wDkWPKrzXup7+Q== + dependencies: + "@graphql-tools/utils" "^10.0.13" + "@repeaterjs/repeater" "^3.0.4" + "@whatwg-node/fetch" "^0.9.0" + extract-files "^11.0.0" + meros "^1.2.1" + tslib "^2.4.0" + value-or-promise "^1.0.12" + +"@graphql-tools/executor-legacy-ws@^1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@graphql-tools/executor-legacy-ws/-/executor-legacy-ws-1.0.6.tgz#4ed311b731db8fd5c99e66a66361afbf9c2109fc" + integrity sha512-lDSxz9VyyquOrvSuCCnld3256Hmd+QI2lkmkEv7d4mdzkxkK4ddAWW1geQiWrQvWmdsmcnGGlZ7gDGbhEExwqg== + dependencies: + "@graphql-tools/utils" "^10.0.13" + "@types/ws" "^8.0.0" + isomorphic-ws "^5.0.0" + tslib "^2.4.0" + ws "^8.15.0" + +"@graphql-tools/executor@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/executor/-/executor-1.2.1.tgz#9aa132ac1839679fbd14810f7ad8a65e82c0db44" + integrity sha512-BP5UI1etbNOXmTSt7q4NL1+zsURFgh2pG+Hyt9K/xO0LlsfbSx59L5dHLerqZP7Js0xI6GYqrUQ4m29rUwUHJg== + dependencies: + "@graphql-tools/utils" "^10.0.13" + "@graphql-typed-document-node/core" "3.2.0" + "@repeaterjs/repeater" "^3.0.4" + tslib "^2.4.0" + value-or-promise "^1.0.12" + +"@graphql-tools/git-loader@^8.0.0": + version "8.0.5" + resolved "https://registry.yarnpkg.com/@graphql-tools/git-loader/-/git-loader-8.0.5.tgz#77f9c2a35fdb3a403d33660ed11702720d4b016e" + integrity sha512-P97/1mhruDiA6D5WUmx3n/aeGPLWj2+4dpzDOxFGGU+z9NcI/JdygMkeFpGZNHeJfw+kHfxgPcMPnxHcyhAoVA== + dependencies: + "@graphql-tools/graphql-tag-pluck" "8.3.0" + "@graphql-tools/utils" "^10.0.13" + is-glob "4.0.3" + micromatch "^4.0.4" + tslib "^2.4.0" + unixify "^1.0.0" + +"@graphql-tools/github-loader@^8.0.0": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/github-loader/-/github-loader-8.0.1.tgz#011e1f9495d42a55139a12f576cc6bb04943ecf4" + integrity sha512-W4dFLQJ5GtKGltvh/u1apWRFKBQOsDzFxO9cJkOYZj1VzHCpRF43uLST4VbCfWve+AwBqOuKr7YgkHoxpRMkcg== + dependencies: + "@ardatan/sync-fetch" "^0.0.1" + "@graphql-tools/executor-http" "^1.0.9" + "@graphql-tools/graphql-tag-pluck" "^8.0.0" + "@graphql-tools/utils" "^10.0.13" + "@whatwg-node/fetch" "^0.9.0" + tslib "^2.4.0" + value-or-promise "^1.0.12" + +"@graphql-tools/graphql-file-loader@^8.0.0": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-file-loader/-/graphql-file-loader-8.0.1.tgz#03869b14cb91d0ef539df8195101279bb2df9c9e" + integrity sha512-7gswMqWBabTSmqbaNyWSmRRpStWlcCkBc73E6NZNlh4YNuiyKOwbvSkOUYFOqFMfEL+cFsXgAvr87Vz4XrYSbA== + dependencies: + "@graphql-tools/import" "7.0.1" + "@graphql-tools/utils" "^10.0.13" + globby "^11.0.3" + tslib "^2.4.0" + unixify "^1.0.0" + +"@graphql-tools/graphql-tag-pluck@8.3.0", "@graphql-tools/graphql-tag-pluck@^8.0.0": + version "8.3.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-8.3.0.tgz#11bb8c627253137b39b34fb765cd6ebe506388b9" + integrity sha512-gNqukC+s7iHC7vQZmx1SEJQmLnOguBq+aqE2zV2+o1hxkExvKqyFli1SY/9gmukFIKpKutCIj+8yLOM+jARutw== + dependencies: + "@babel/core" "^7.22.9" + "@babel/parser" "^7.16.8" + "@babel/plugin-syntax-import-assertions" "^7.20.0" + "@babel/traverse" "^7.16.8" + "@babel/types" "^7.16.8" + "@graphql-tools/utils" "^10.0.13" + tslib "^2.4.0" + +"@graphql-tools/import@7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-7.0.1.tgz#4e0d181c63350b1c926ae91b84a4cbaf03713c2c" + integrity sha512-935uAjAS8UAeXThqHfYVr4HEAp6nHJ2sximZKO1RzUTq5WoALMAhhGARl0+ecm6X+cqNUwIChJbjtaa6P/ML0w== + dependencies: + "@graphql-tools/utils" "^10.0.13" + resolve-from "5.0.0" + tslib "^2.4.0" + +"@graphql-tools/json-file-loader@^8.0.0": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/json-file-loader/-/json-file-loader-8.0.1.tgz#3fcfe869f22d8129a74369da69bf491c0bff7c2d" + integrity sha512-lAy2VqxDAHjVyqeJonCP6TUemrpYdDuKt25a10X6zY2Yn3iFYGnuIDQ64cv3ytyGY6KPyPB+Kp+ZfOkNDG3FQA== + dependencies: + "@graphql-tools/utils" "^10.0.13" + globby "^11.0.3" + tslib "^2.4.0" + unixify "^1.0.0" + +"@graphql-tools/load@^8.0.0": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@graphql-tools/load/-/load-8.0.2.tgz#47d9916bf96dea05df27f11b53812f4327d9b6d2" + integrity sha512-S+E/cmyVmJ3CuCNfDuNF2EyovTwdWfQScXv/2gmvJOti2rGD8jTt9GYVzXaxhblLivQR9sBUCNZu/w7j7aXUCA== + dependencies: + "@graphql-tools/schema" "^10.0.3" + "@graphql-tools/utils" "^10.0.13" + p-limit "3.1.0" + tslib "^2.4.0" + +"@graphql-tools/merge@^9.0.0", "@graphql-tools/merge@^9.0.3": + version "9.0.3" + resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-9.0.3.tgz#4d0b467132e6f788b69fab803d31480b8ce4b61a" + integrity sha512-FeKv9lKLMwqDu0pQjPpF59GY3HReUkWXKsMIuMuJQOKh9BETu7zPEFUELvcw8w+lwZkl4ileJsHXC9+AnsT2Lw== + dependencies: + "@graphql-tools/utils" "^10.0.13" + tslib "^2.4.0" + +"@graphql-tools/optimize@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/optimize/-/optimize-2.0.0.tgz#7a9779d180824511248a50c5a241eff6e7a2d906" + integrity sha512-nhdT+CRGDZ+bk68ic+Jw1OZ99YCDIKYA5AlVAnBHJvMawSx9YQqQAIj4refNc1/LRieGiuWvhbG3jvPVYho0Dg== + dependencies: + tslib "^2.4.0" + +"@graphql-tools/prisma-loader@^8.0.0": + version "8.0.3" + resolved "https://registry.yarnpkg.com/@graphql-tools/prisma-loader/-/prisma-loader-8.0.3.tgz#a41acb41629cf5327834bedd259939024cf774ba" + integrity sha512-oZhxnMr3Jw2WAW1h9FIhF27xWzIB7bXWM8olz4W12oII4NiZl7VRkFw9IT50zME2Bqi9LGh9pkmMWkjvbOpl+Q== + dependencies: + "@graphql-tools/url-loader" "^8.0.2" + "@graphql-tools/utils" "^10.0.13" + "@types/js-yaml" "^4.0.0" + "@types/json-stable-stringify" "^1.0.32" + "@whatwg-node/fetch" "^0.9.0" + chalk "^4.1.0" + debug "^4.3.1" + dotenv "^16.0.0" + graphql-request "^6.0.0" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.0" + jose "^5.0.0" + js-yaml "^4.0.0" + json-stable-stringify "^1.0.1" + lodash "^4.17.20" + scuid "^1.1.0" + tslib "^2.4.0" + yaml-ast-parser "^0.0.43" + +"@graphql-tools/relay-operation-optimizer@^7.0.0": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-7.0.1.tgz#8ac33e1d2626b6816d9283769c4a05c062b8065a" + integrity sha512-y0ZrQ/iyqWZlsS/xrJfSir3TbVYJTYmMOu4TaSz6F4FRDTQ3ie43BlKkhf04rC28pnUOS4BO9pDcAo1D30l5+A== + dependencies: + "@ardatan/relay-compiler" "12.0.0" + "@graphql-tools/utils" "^10.0.13" + tslib "^2.4.0" + +"@graphql-tools/schema@^10.0.0", "@graphql-tools/schema@^10.0.3": + version "10.0.3" + resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-10.0.3.tgz#48c14be84cc617c19c4c929258672b6ab01768de" + integrity sha512-p28Oh9EcOna6i0yLaCFOnkcBDQECVf3SCexT6ktb86QNj9idnkhI+tCxnwZDh58Qvjd2nURdkbevvoZkvxzCog== + dependencies: + "@graphql-tools/merge" "^9.0.3" + "@graphql-tools/utils" "^10.0.13" + tslib "^2.4.0" + value-or-promise "^1.0.12" + +"@graphql-tools/url-loader@^8.0.0", "@graphql-tools/url-loader@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-8.0.2.tgz#ee8e10a85d82c72662f6bc6bbc7b408510a36ebd" + integrity sha512-1dKp2K8UuFn7DFo1qX5c1cyazQv2h2ICwA9esHblEqCYrgf69Nk8N7SODmsfWg94OEaI74IqMoM12t7eIGwFzQ== + dependencies: + "@ardatan/sync-fetch" "^0.0.1" + "@graphql-tools/delegate" "^10.0.4" + "@graphql-tools/executor-graphql-ws" "^1.1.2" + "@graphql-tools/executor-http" "^1.0.9" + "@graphql-tools/executor-legacy-ws" "^1.0.6" + "@graphql-tools/utils" "^10.0.13" + "@graphql-tools/wrap" "^10.0.2" + "@types/ws" "^8.0.0" + "@whatwg-node/fetch" "^0.9.0" + isomorphic-ws "^5.0.0" + tslib "^2.4.0" + value-or-promise "^1.0.11" + ws "^8.12.0" + +"@graphql-tools/utils@^10.0.0", "@graphql-tools/utils@^10.0.13": + version "10.1.0" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-10.1.0.tgz#d8c23a8b8636a5df59b14991bf25eae5ac15d314" + integrity sha512-wLPqhgeZ9BZJPRoaQbsDN/CtJDPd/L4qmmtPkjI3NuYJ39x+Eqz1Sh34EAGMuDh+xlOHqBwHczkZUpoK9tvzjw== + dependencies: + "@graphql-typed-document-node/core" "^3.1.1" + cross-inspect "1.0.0" + dset "^3.1.2" + tslib "^2.4.0" + +"@graphql-tools/wrap@^10.0.2": + version "10.0.2" + resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-10.0.2.tgz#87f510b5f35db2771e7743bc3d71059ee4adaf09" + integrity sha512-nb/YjBcyF02KBCy3hiyw0nBKIC+qkiDY/tGMCcIe4pM6BPEcnreaPhXA28Rdge7lKtySF4Mhbc86XafFH5bIkQ== + dependencies: + "@graphql-tools/delegate" "^10.0.4" + "@graphql-tools/schema" "^10.0.3" + "@graphql-tools/utils" "^10.0.13" + tslib "^2.4.0" + value-or-promise "^1.0.12" + +"@graphql-typed-document-node/core@3.2.0", "@graphql-typed-document-node/core@^3.1.1", "@graphql-typed-document-node/core@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861" + integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ== + "@humanwhocodes/config-array@^0.11.10": version "0.11.10" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" @@ -3266,6 +4276,11 @@ dependencies: glob-to-regexp "^0.4.1" +"@kamilkisiela/fast-url-parser@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@kamilkisiela/fast-url-parser/-/fast-url-parser-1.1.4.tgz#9d68877a489107411b953c54ea65d0658b515809" + integrity sha512-gbkePEBupNydxCelHCESvFSFM8XPh1Zs/OAVRW/rKpEqPAl5PbOM90Si8mv9bvnR53uPD2s/FiRxdvSejpRJew== + "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" @@ -5222,6 +6237,33 @@ "@parcel/watcher-win32-ia32" "2.4.0" "@parcel/watcher-win32-x64" "2.4.0" +"@peculiar/asn1-schema@^2.3.8": + version "2.3.8" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-schema/-/asn1-schema-2.3.8.tgz#04b38832a814e25731232dd5be883460a156da3b" + integrity sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA== + dependencies: + asn1js "^3.0.5" + pvtsutils "^1.3.5" + tslib "^2.6.2" + +"@peculiar/json-schema@^1.1.12": + version "1.1.12" + resolved "https://registry.yarnpkg.com/@peculiar/json-schema/-/json-schema-1.1.12.tgz#fe61e85259e3b5ba5ad566cb62ca75b3d3cd5339" + integrity sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w== + dependencies: + tslib "^2.0.0" + +"@peculiar/webcrypto@^1.4.0": + version "1.4.5" + resolved "https://registry.yarnpkg.com/@peculiar/webcrypto/-/webcrypto-1.4.5.tgz#424bed6b0d133b772f5cbffd143d0468a90f40a0" + integrity sha512-oDk93QCDGdxFRM8382Zdminzs44dg3M2+E5Np+JWkpqLDyJC9DviMh8F8mEJkYuUcUOGA5jHO5AJJ10MFWdbZw== + dependencies: + "@peculiar/asn1-schema" "^2.3.8" + "@peculiar/json-schema" "^1.1.12" + pvtsutils "^1.3.5" + tslib "^2.6.2" + webcrypto-core "^1.7.8" + "@phenomnomnominal/tsquery@4.1.1": version "4.1.1" resolved "https://registry.yarnpkg.com/@phenomnomnominal/tsquery/-/tsquery-4.1.1.tgz#42971b83590e9d853d024ddb04a18085a36518df" @@ -5443,6 +6485,11 @@ "@remixproject/plugin-utils" "0.3.42" events "3.2.0" +"@repeaterjs/repeater@^3.0.4": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@repeaterjs/repeater/-/repeater-3.0.5.tgz#b77571685410217a548a9c753aa3cdfc215bfc78" + integrity sha512-l3YHBLAol6d/IKnB9LhpD0cEZWAoe3eFKUyTYWmFmCO2Q/WOckxLQAUyMZWwZV2M/m3+4vgRoaolFqaII82/TA== + "@restart/context@^2.1.4": version "2.1.4" resolved "https://registry.yarnpkg.com/@restart/context/-/context-2.1.4.tgz#a99d87c299a34c28bd85bb489cb07bfd23149c02" @@ -6324,6 +7371,11 @@ dependencies: "@types/istanbul-lib-report" "*" +"@types/js-yaml@^4.0.0": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.9.tgz#cd82382c4f902fed9691a2ed79ec68c5898af4c2" + integrity sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg== + "@types/json-schema@*", "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" @@ -6334,6 +7386,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== +"@types/json-stable-stringify@^1.0.32": + version "1.0.36" + resolved "https://registry.yarnpkg.com/@types/json-stable-stringify/-/json-stable-stringify-1.0.36.tgz#fe6c6001a69ff8160a772da08779448a333c7ddd" + integrity sha512-b7bq23s4fgBB76n34m2b3RBf6M369B0Z9uRR8aHTMd8kZISRkmDEpPD8hhpYvDFzr3bJCPES96cm3Q6qRNDbQw== + "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" @@ -6550,7 +7607,7 @@ "@types/history" "*" "@types/react" "*" -"@types/react-transition-group@^4.4.1": +"@types/react-transition-group@^4.4.0", "@types/react-transition-group@^4.4.1": version "4.4.10" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.10.tgz#6ee71127bdab1f18f11ad8fb3322c6da27c327ac" integrity sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q== @@ -6720,6 +7777,13 @@ dependencies: "@types/node" "*" +"@types/ws@^8.0.0": + version "8.5.10" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" + integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "20.2.1" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" @@ -7424,6 +8488,92 @@ resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== +"@whatwg-node/events@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@whatwg-node/events/-/events-0.0.3.tgz#13a65dd4f5893f55280f766e29ae48074927acad" + integrity sha512-IqnKIDWfXBJkvy/k6tzskWTc2NK3LcqHlb+KHGCrjOCH4jfQckRX0NAiIcC/vIqQkzLYw2r2CTSwAxcrtcD6lA== + +"@whatwg-node/events@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@whatwg-node/events/-/events-0.1.1.tgz#0ca718508249419587e130da26d40e29d99b5356" + integrity sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w== + +"@whatwg-node/fetch@^0.8.0": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@whatwg-node/fetch/-/fetch-0.8.8.tgz#48c6ad0c6b7951a73e812f09dd22d75e9fa18cae" + integrity sha512-CdcjGC2vdKhc13KKxgsc6/616BQ7ooDIgPeTuAiE8qfCnS0mGzcfCOoZXypQSz73nxI+GWc7ZReIAVhxoE1KCg== + dependencies: + "@peculiar/webcrypto" "^1.4.0" + "@whatwg-node/node-fetch" "^0.3.6" + busboy "^1.6.0" + urlpattern-polyfill "^8.0.0" + web-streams-polyfill "^3.2.1" + +"@whatwg-node/fetch@^0.9.0": + version "0.9.16" + resolved "https://registry.yarnpkg.com/@whatwg-node/fetch/-/fetch-0.9.16.tgz#c833eb714f41f5d2caf1a345bed7a05f56db7b16" + integrity sha512-mqasZiUNquRe3ea9+aCAuo81BR6vq5opUKprPilIHTnrg8a21Z1T1OrI+KiMFX8OmwO5HUJe/vro47lpj2JPWQ== + dependencies: + "@whatwg-node/node-fetch" "^0.5.5" + urlpattern-polyfill "^10.0.0" + +"@whatwg-node/node-fetch@^0.3.6": + version "0.3.6" + resolved "https://registry.yarnpkg.com/@whatwg-node/node-fetch/-/node-fetch-0.3.6.tgz#e28816955f359916e2d830b68a64493124faa6d0" + integrity sha512-w9wKgDO4C95qnXZRwZTfCmLWqyRnooGjcIwG0wADWjw9/HN0p7dtvtgSvItZtUyNteEvgTrd8QojNEqV6DAGTA== + dependencies: + "@whatwg-node/events" "^0.0.3" + busboy "^1.6.0" + fast-querystring "^1.1.1" + fast-url-parser "^1.1.3" + tslib "^2.3.1" + +"@whatwg-node/node-fetch@^0.5.5": + version "0.5.6" + resolved "https://registry.yarnpkg.com/@whatwg-node/node-fetch/-/node-fetch-0.5.6.tgz#3ec2044ff66dd78134492b5f2f841bedf1cc73c9" + integrity sha512-cmAsGMHoI0S3AHi3CmD3ma1Q234ZI2JNmXyDyM9rLtbXejBKxU3ZWdhS+mzRIAyUxZCMGlFW1tHmROv0MDdxpw== + dependencies: + "@kamilkisiela/fast-url-parser" "^1.1.4" + "@whatwg-node/events" "^0.1.0" + busboy "^1.6.0" + fast-querystring "^1.1.1" + tslib "^2.3.1" + +"@wry/caches@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@wry/caches/-/caches-1.0.1.tgz#8641fd3b6e09230b86ce8b93558d44cf1ece7e52" + integrity sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA== + dependencies: + tslib "^2.3.0" + +"@wry/context@^0.7.0": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.7.4.tgz#e32d750fa075955c4ab2cfb8c48095e1d42d5990" + integrity sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ== + dependencies: + tslib "^2.3.0" + +"@wry/equality@^0.5.6": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.5.7.tgz#72ec1a73760943d439d56b7b1e9985aec5d497bb" + integrity sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw== + dependencies: + tslib "^2.3.0" + +"@wry/trie@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.4.3.tgz#077d52c22365871bf3ffcbab8e95cb8bc5689af4" + integrity sha512-I6bHwH0fSf6RqQcnnXLJKhkSXG45MFral3GxPaY4uAl0LYDZM+YDVDAiU9bYwjTuysy1S0IeecWtmq1SZA3M1w== + dependencies: + tslib "^2.3.0" + +"@wry/trie@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.5.0.tgz#11e783f3a53f6e4cd1d42d2d1323f5bc3fa99c94" + integrity sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA== + dependencies: + tslib "^2.3.0" + "@xenova/transformers@^2.7.0": version "2.7.0" resolved "https://registry.yarnpkg.com/@xenova/transformers/-/transformers-2.7.0.tgz#0aabc8700d32ed8e28f6aa61abf8653f62fb1678" @@ -7657,6 +8807,13 @@ agent-base@6, agent-base@^6.0.2: dependencies: debug "4" +agent-base@^7.0.2, agent-base@^7.1.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317" + integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA== + dependencies: + debug "^4.3.4" + agent-base@~4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -8241,6 +9398,15 @@ asn1@~0.2.3: resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" integrity sha512-6i37w/+EhlWlGUJff3T/Q8u1RGmP5wgbiwYnOnbOqvtrPxT63/sYFyP9RcpxtxGymtfA075IvmOnL7ycNOWl3w== +asn1js@^3.0.1, asn1js@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/asn1js/-/asn1js-3.0.5.tgz#5ea36820443dbefb51cc7f88a2ebb5b462114f38" + integrity sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ== + dependencies: + pvtsutils "^1.3.2" + pvutils "^1.1.3" + tslib "^2.4.0" + assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" @@ -8373,6 +9539,11 @@ author-regex@^1.0.0: resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450" integrity sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g== +auto-bind@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-4.0.0.tgz#e3589fc6c2da8f7ca43ba9f84fa52a744fc997fb" + integrity sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ== + autoprefixer@^10.4.9: version "10.4.12" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.12.tgz#183f30bf0b0722af54ee5ef257f7d4320bb33129" @@ -8693,6 +9864,15 @@ babel-plugin-macros@^2.8.0: cosmiconfig "^6.0.0" resolve "^1.12.0" +babel-plugin-macros@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" + integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== + dependencies: + "@babel/runtime" "^7.12.5" + cosmiconfig "^7.0.0" + resolve "^1.19.0" + babel-plugin-module-resolver@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz#22a4f32f7441727ec1fbf4967b863e1e3e9f33e2" @@ -8758,6 +9938,11 @@ babel-plugin-syntax-trailing-function-commas@^6.22.0: resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" integrity sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ== +babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: + version "7.0.0-beta.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf" + integrity sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ== + babel-plugin-syntax-typescript@7.0.0-alpha.19: version "7.0.0-alpha.19" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-typescript/-/babel-plugin-syntax-typescript-7.0.0-alpha.19.tgz#fc5876863db297549f5d840d248eac3310241f84" @@ -9067,6 +10252,39 @@ babel-preset-env@^1.7.0: invariant "^2.2.2" semver "^5.3.0" +babel-preset-fbjs@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz#38a14e5a7a3b285a3f3a86552d650dca5cf6111c" + integrity sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow== + dependencies: + "@babel/plugin-proposal-class-properties" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-class-properties" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-block-scoped-functions" "^7.0.0" + "@babel/plugin-transform-block-scoping" "^7.0.0" + "@babel/plugin-transform-classes" "^7.0.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.0.0" + "@babel/plugin-transform-flow-strip-types" "^7.0.0" + "@babel/plugin-transform-for-of" "^7.0.0" + "@babel/plugin-transform-function-name" "^7.0.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-member-expression-literals" "^7.0.0" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/plugin-transform-object-super" "^7.0.0" + "@babel/plugin-transform-parameters" "^7.0.0" + "@babel/plugin-transform-property-literals" "^7.0.0" + "@babel/plugin-transform-react-display-name" "^7.0.0" + "@babel/plugin-transform-react-jsx" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-template-literals" "^7.0.0" + babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" + babel-preset-jest@^28.1.3: version "28.1.3" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz#5dfc20b99abed5db994406c2b9ab94c73aaa419d" @@ -9774,6 +10992,16 @@ browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4 node-releases "^2.0.6" update-browserslist-db "^1.0.9" +browserslist@^4.22.2: + version "4.23.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" + integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== + dependencies: + caniuse-lite "^1.0.30001587" + electron-to-chromium "^1.4.668" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + bs58@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" @@ -9920,6 +11148,13 @@ builtins@^1.0.3: resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== +busboy@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + byline@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" @@ -10190,6 +11425,11 @@ caniuse-lite@^1.0.30001400: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001412.tgz#30f67d55a865da43e0aeec003f073ea8764d5d7c" integrity sha512-+TeEIee1gS5bYOiuf+PS/kp2mrXic37Hl66VY6EAfxasIk5fELTktK2oOezYed12H8w7jt3s512PpulQidPjwA== +caniuse-lite@^1.0.30001587: + version "1.0.30001589" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001589.tgz#7ad6dba4c9bf6561aec8291976402339dc157dfb" + integrity sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg== + canvg@^3.0.6: version "3.0.10" resolved "https://registry.yarnpkg.com/canvg/-/canvg-3.0.10.tgz#8e52a2d088b6ffa23ac78970b2a9eebfae0ef4b3" @@ -10306,7 +11546,7 @@ chalk@^2.0.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4 escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -10314,7 +11554,23 @@ chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -change-case@^4.1.1: +change-case-all@1.0.15: + version "1.0.15" + resolved "https://registry.yarnpkg.com/change-case-all/-/change-case-all-1.0.15.tgz#de29393167fc101d646cd76b0ef23e27d09756ad" + integrity sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ== + dependencies: + change-case "^4.1.2" + is-lower-case "^2.0.2" + is-upper-case "^2.0.2" + lower-case "^2.0.2" + lower-case-first "^2.0.2" + sponge-case "^1.0.1" + swap-case "^2.0.2" + title-case "^3.0.3" + upper-case "^2.0.2" + upper-case-first "^2.0.2" + +change-case@^4.1.1, change-case@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/change-case/-/change-case-4.1.2.tgz#fedfc5f136045e2398c0410ee441f95704641e12" integrity sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A== @@ -10670,6 +11926,11 @@ cli-width@^2.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== +cli-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" + integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== + clipboardy@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-4.0.0.tgz#e73ced93a76d19dd379ebf1f297565426dffdca1" @@ -10928,7 +12189,7 @@ colorette@^2.0.10, colorette@^2.0.14: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== -colorette@^2.0.19: +colorette@^2.0.16, colorette@^2.0.19: version "2.0.20" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== @@ -11045,6 +12306,11 @@ common-path-prefix@^3.0.0: resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== +common-tags@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" + integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -11312,6 +12578,11 @@ convert-source-map@^1.4.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + convert-source-map@~1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860" @@ -11499,6 +12770,16 @@ cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" +cosmiconfig@^8.1.0, cosmiconfig@^8.1.3: + version "8.3.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== + dependencies: + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + path-type "^4.0.0" + crc-32@^1.2.0, crc-32@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" @@ -11576,6 +12857,13 @@ cross-fetch@^4.0.0: dependencies: node-fetch "^2.6.12" +cross-inspect@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cross-inspect/-/cross-inspect-1.0.0.tgz#5fda1af759a148594d2d58394a9e21364f6849af" + integrity sha512-4PFfn4b5ZN6FMNGSZlyb7wUhuN8wvj8t/VQHZdM4JsDcruGJ8L2kf9zao98QIrBPFCpdk27qst/AGTl7pL3ypQ== + dependencies: + tslib "^2.4.0" + cross-spawn-async@^2.1.1: version "2.2.5" resolved "https://registry.yarnpkg.com/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz#845ff0c0834a3ded9d160daca6d390906bb288cc" @@ -11999,6 +13287,11 @@ data-uri-to-buffer@^3.0.1: resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== +dataloader@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.2.2.tgz#216dc509b5abe39d43a9b9d97e6e5e473dfbe3e0" + integrity sha512-8YnDaaf7N3k/q5HnTJVuzSyLETjoZjVmHc4AeKAzOvKHEFQKcn64OKBfzHYtE9zGjctNM7V9I0MfnUVLpi7M5g== + dateformat@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" @@ -12017,6 +13310,11 @@ deasync@^0.1.9: bindings "^1.5.0" node-addon-api "^1.7.1" +debounce@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" + integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== + debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -12333,6 +13631,11 @@ depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +dependency-graph@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.11.0.tgz#ac0ce7ed68a54da22165a85e97a01d53f5eb2e27" + integrity sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg== + deprecation@^2.0.0, deprecation@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" @@ -12386,6 +13689,11 @@ detect-indent@^5.0.0: resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= +detect-indent@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" + integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== + detect-libc@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" @@ -12678,6 +13986,11 @@ dotenv@10.0.0, dotenv@~10.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== +dotenv@^16.0.0: + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== + dotenv@^8.2.0: version "8.6.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" @@ -12690,6 +14003,11 @@ dotignore@~0.1.2: dependencies: minimatch "^3.0.4" +dset@^3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/dset/-/dset-3.1.3.tgz#c194147f159841148e8e34ca41f638556d9542d2" + integrity sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ== + duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" @@ -12834,6 +14152,11 @@ electron-to-chromium@^1.4.251: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.264.tgz#2f68a062c38b7a04bf57f3e6954b868672fbdcd3" integrity sha512-AZ6ZRkucHOQT8wke50MktxtmcWZr67kE17X/nAXFf62NIdMdgY6xfsaJD5Szoy84lnkuPWH+4tTNE3s2+bPCiw== +electron-to-chromium@^1.4.668: + version "1.4.681" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.681.tgz#5f23fad8aa7e1f64cbb7dd9d15c7e39a1cd7e6e3" + integrity sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg== + electron@^24.4.0: version "24.4.0" resolved "https://registry.yarnpkg.com/electron/-/electron-24.4.0.tgz#48d05561dab6a5835ec1a3a96852797f69824eea" @@ -14114,6 +15437,11 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +extract-files@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-11.0.0.tgz#b72d428712f787eef1f5193aff8ab5351ca8469a" + integrity sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ== + extract-zip@2.0.1, extract-zip@^2.0.0, extract-zip@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" @@ -14151,6 +15479,11 @@ fast-async@^7.0.6: nodent-runtime "^3.2.1" nodent-transform "^3.2.4" +fast-decode-uri-component@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543" + integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -14215,6 +15548,13 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-querystring@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fast-querystring/-/fast-querystring-1.1.2.tgz#a6d24937b4fc6f791b4ee31dcb6f53aeafb89f53" + integrity sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg== + dependencies: + fast-decode-uri-component "^1.0.1" + fast-redact@^3.0.0: version "3.3.0" resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.3.0.tgz#7c83ce3a7be4898241a46560d51de10f653f7634" @@ -14230,6 +15570,13 @@ fast-text-encoding@^1.0.0: resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz#ec02ac8e01ab8a319af182dae2681213cfe9ce53" integrity sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig== +fast-url-parser@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" + integrity sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ== + dependencies: + punycode "^1.3.2" + fastest-levenshtein@^1.0.12: version "1.0.16" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" @@ -14340,7 +15687,7 @@ figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== -figures@3.2.0: +figures@3.2.0, figures@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== @@ -14497,6 +15844,11 @@ find-cache-dir@^3.3.2: make-dir "^3.0.2" pkg-dir "^4.1.0" +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + find-up@5.0.0, find-up@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" @@ -15608,7 +16960,7 @@ globby@10.0.1: merge2 "^1.2.3" slash "^3.0.0" -globby@^11.1.0: +globby@^11.0.3, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -15737,6 +17089,48 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +graphql-config@^5.0.2: + version "5.0.3" + resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-5.0.3.tgz#d9aa2954cf47a927f9cb83cdc4e42ae55d0b321e" + integrity sha512-BNGZaoxIBkv9yy6Y7omvsaBUHOzfFcII3UN++tpH8MGOKFPFkCPZuwx09ggANMt8FgyWP1Od8SWPmrUEZca4NQ== + dependencies: + "@graphql-tools/graphql-file-loader" "^8.0.0" + "@graphql-tools/json-file-loader" "^8.0.0" + "@graphql-tools/load" "^8.0.0" + "@graphql-tools/merge" "^9.0.0" + "@graphql-tools/url-loader" "^8.0.0" + "@graphql-tools/utils" "^10.0.0" + cosmiconfig "^8.1.0" + jiti "^1.18.2" + minimatch "^4.2.3" + string-env-interpolation "^1.0.1" + tslib "^2.4.0" + +graphql-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-6.1.0.tgz#f4eb2107967af3c7a5907eb3131c671eac89be4f" + integrity sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw== + dependencies: + "@graphql-typed-document-node/core" "^3.2.0" + cross-fetch "^3.1.5" + +graphql-tag@^2.11.0, graphql-tag@^2.12.6: + version "2.12.6" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1" + integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg== + dependencies: + tslib "^2.1.0" + +graphql-ws@^5.14.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-5.15.0.tgz#2db79e1b42468a8363bf5ca6168d076e2f8fdebc" + integrity sha512-xWGAtm3fig9TIhSaNsg0FaDZ8Pyn/3re3RFlP4rhQcmjRDIPpk1EhRuNB+YSJtLzttyuToaDiNhwT1OMoGnJnw== + +graphql@^16.8.1: + version "16.8.1" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.1.tgz#1930a965bef1170603702acdb68aedd3f3cf6f07" + integrity sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw== + growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -16158,7 +17552,7 @@ hoek@2.x.x: resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0= -hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -16330,6 +17724,14 @@ http-proxy-agent@^5.0.0: agent-base "6" debug "4" +http-proxy-agent@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" + integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== + dependencies: + agent-base "^7.1.0" + debug "^4.3.4" + http-proxy-middleware@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" @@ -16429,6 +17831,14 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +https-proxy-agent@^7.0.0: + version "7.0.4" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz#8e97b841a029ad8ddc8731f26595bad868cb4168" + integrity sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg== + dependencies: + agent-base "^7.0.2" + debug "4" + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -16566,6 +17976,11 @@ immutable@^4.0.0-rc.12: resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.2.4.tgz#83260d50889526b4b531a5e293709a77f7c55a2a" integrity sha512-WDxL3Hheb1JkRN3sQkyujNlL/xRjAo3rJtaU5xeufUauG66JdMr32bLj4gF+vWl84DIA3Zxw7tiAjneYzRRw+w== +immutable@~3.7.6: + version "3.7.6" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.7.6.tgz#13b4d3cb12befa15482a26fe1b2ebae640071e4b" + integrity sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw== + import-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-3.0.0.tgz#20845547718015126ea9b3676b7592fb8bd4cf92" @@ -16581,7 +17996,7 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: +import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -16589,6 +18004,11 @@ import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" +import-from@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-4.0.0.tgz#2710b8d66817d232e16f4166e319248d3d5492e2" + integrity sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ== + import-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/import-from/-/import-from-3.0.0.tgz#055cfec38cd5a27d8057ca51376d7d3bf0891966" @@ -16731,6 +18151,27 @@ inquirer@^6.2.0: strip-ansi "^5.1.0" through "^2.3.6" +inquirer@^8.0.0: + version "8.2.6" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.6.tgz#733b74888195d8d400a67ac332011b5fae5ea562" + integrity sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.1" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.21" + mute-stream "0.0.8" + ora "^5.4.1" + run-async "^2.4.0" + rxjs "^7.5.5" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + wrap-ansi "^6.0.1" + insert-css@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/insert-css/-/insert-css-0.2.0.tgz#d15789971662d9899c28977fb6220d5381d2451a" @@ -17277,6 +18718,13 @@ is-generator-function@^1.0.7: dependencies: has-tostringtag "^1.0.0" +is-glob@4.0.3, is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -17291,13 +18739,6 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - is-hex-prefixed@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" @@ -17327,6 +18768,13 @@ is-lambda@^1.0.1: resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== +is-lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-2.0.2.tgz#1c0884d3012c841556243483aa5d522f47396d2a" + integrity sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ== + dependencies: + tslib "^2.0.3" + is-map@^2.0.1, is-map@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" @@ -17590,6 +19038,13 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-upper-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-2.0.2.tgz#f1105ced1fe4de906a5f39553e7d3803fd804649" + integrity sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ== + dependencies: + tslib "^2.0.3" + is-utf8@^0.2.0, is-utf8@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" @@ -17707,10 +19162,10 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isomorphic-git@^1.25.0: - version "1.25.0" - resolved "https://registry.yarnpkg.com/isomorphic-git/-/isomorphic-git-1.25.0.tgz#3a04d7e70f75ebdbb991f9fa87cfec90e3742c9f" - integrity sha512-F8X7z74gL+jN4bd6qB6a3Z0QQzonWPkiQ3nK/oFWlrc2pIwVM9Uksl3YMFh99ltswsqoCoOthgasybX08/fiGg== +isomorphic-git@^1.25.7: + version "1.25.7" + resolved "https://registry.yarnpkg.com/isomorphic-git/-/isomorphic-git-1.25.7.tgz#f6f6fae81ee67d3982edad8c90ca0f096e39267c" + integrity sha512-KE10ejaIsEpQ+I/apS33qqTjyzCXgOniEaL32DwNbXtboKG8H3cu+RiBcdp3G9w4MpOOTQfGPsWp4i8UxRfDLg== dependencies: async-lock "^1.1.0" clean-git-ref "^2.0.1" @@ -18318,7 +19773,7 @@ jest-worker@^29.1.2: merge-stream "^2.0.0" supports-color "^8.0.0" -jiti@^1.21.0: +jiti@^1.17.1, jiti@^1.18.2, jiti@^1.21.0: version "1.21.0" resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d" integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== @@ -18335,6 +19790,11 @@ jodid25519@^1.0.0: dependencies: jsbn "~0.1.0" +jose@^5.0.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/jose/-/jose-5.2.2.tgz#b91170e9ba6dbe609b0c0a86568f9a1fbe4335c0" + integrity sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg== + jquery@^3.3.1: version "3.6.0" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" @@ -18387,7 +19847,7 @@ js-yaml@4.0.0: dependencies: argparse "^2.0.1" -js-yaml@4.1.0, js-yaml@^4.1.0: +js-yaml@4.1.0, js-yaml@^4.0.0, js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== @@ -18503,6 +19963,14 @@ json-text-sequence@~0.1.0: dependencies: delimit-stream "0.1.0" +json-to-pretty-yaml@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz#f4cd0bd0a5e8fe1df25aaf5ba118b099fd992d5b" + integrity sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A== + dependencies: + remedial "^1.0.7" + remove-trailing-spaces "^1.0.6" + json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" @@ -18515,7 +19983,7 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.2, json5@^2.2.1, json5@^2.2.2: +json5@^2.1.2, json5@^2.2.1, json5@^2.2.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -19096,6 +20564,20 @@ listhen@^1.5.5: untun "^0.1.3" uqr "^0.1.2" +listr2@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-4.0.5.tgz#9dcc50221583e8b4c71c43f9c7dfd0ef546b75d5" + integrity sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA== + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.16" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.5.5" + through "^2.3.8" + wrap-ansi "^7.0.0" + listr2@^5.0.3, listr2@^5.0.7: version "5.0.8" resolved "https://registry.yarnpkg.com/listr2/-/listr2-5.0.8.tgz#a9379ffeb4bd83a68931a65fb223a11510d6ba23" @@ -19535,7 +21017,7 @@ lodash.without@~4.4.0: resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" integrity sha1-PNRXSgC2e643OpS3SHcmQFB7eqw= -lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.2.1: +lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.2.1, lodash@~4.17.0, lodash@~4.17.5: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -19625,6 +21107,13 @@ loupe@^2.3.1: dependencies: get-func-name "^2.0.0" +lower-case-first@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-2.0.2.tgz#64c2324a2250bf7c37c5901e76a5b5309301160b" + integrity sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg== + dependencies: + tslib "^2.0.3" + lower-case@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" @@ -20077,6 +21566,11 @@ memfs@^3.4.1, memfs@^3.4.3: resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== +memoize-one@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045" + integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw== + memoizee@^0.4.15: version "0.4.15" resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72" @@ -20194,6 +21688,11 @@ merge@^2.1.1: resolved "https://registry.yarnpkg.com/merge/-/merge-2.1.1.tgz#59ef4bf7e0b3e879186436e8481c06a6c162ca98" integrity sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w== +meros@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/meros/-/meros-1.3.0.tgz#c617d2092739d55286bf618129280f362e6242f2" + integrity sha512-2BNGOimxEz5hmjUG2FwoxCt5HN7BXdaWyFqEwxPTrJzVdABtrL4TiHTcsWSFAxPQ/tOnEaQEJh3qWq71QRMY+w== + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -20657,6 +22156,13 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +minimatch@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.3.tgz#b4dcece1d674dee104bb0fb833ebb85a78cbbca6" + integrity sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng== + dependencies: + brace-expansion "^1.1.7" + minimatch@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" @@ -21198,6 +22704,11 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + mute-stream@~0.0.4: version "0.0.5" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" @@ -21609,6 +23120,11 @@ node-notifier@^4.2.3: shellwords "^0.1.0" which "^1.0.5" +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== + node-releases@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" @@ -22083,6 +23599,11 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" +nullthrows@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" + integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== + number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" @@ -22501,6 +24022,16 @@ opener@~1.4.3: resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" integrity sha1-XG2ixdflgx6P+jlklQ+NZnSskLg= +optimism@^0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.18.0.tgz#e7bb38b24715f3fdad8a9a7fc18e999144bbfa63" + integrity sha512-tGn8+REwLRNFnb9WmcY5IfpOqeX2kpaYJ1s6Ae3mn12AeydLkR3j+jSCmVQFoXqU8D41PAJ1RG1rCRNWmNZVmQ== + dependencies: + "@wry/caches" "^1.0.0" + "@wry/context" "^0.7.0" + "@wry/trie" "^0.4.3" + tslib "^2.3.0" + optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" @@ -22538,7 +24069,7 @@ options@>=0.0.5: resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" integrity sha512-bOj3L1ypm++N+n7CEbbe473A414AB7z+amKYshRb//iuL3MpdDCLhPnw6aVTdKB9g5ZRVHIEp8eUln6L2NUStg== -ora@5.4.1, ora@^5.1.0: +ora@5.4.1, ora@^5.1.0, ora@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== @@ -22669,6 +24200,13 @@ p-is-promise@^2.0.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== +p-limit@3.1.0, p-limit@^3.0.2, p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -22690,13 +24228,6 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.2, p-limit@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -22890,7 +24421,7 @@ parse-duration@^0.4.4: resolved "https://registry.yarnpkg.com/parse-duration/-/parse-duration-0.4.4.tgz#11c0f51a689e97d06c57bd772f7fda7dc013243c" integrity sha512-KbAJuYGUhZkB9gotDiKLnZ7Z3VTacK3fgwmDdB6ZVDtJbMBT6MfLga0WJaYpPDu0mzqT0NgHtHDt5PY4l0nidg== -parse-filepath@^1.0.1: +parse-filepath@^1.0.1, parse-filepath@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE= @@ -23338,6 +24869,11 @@ plur@^1.0.0: resolved "https://registry.yarnpkg.com/plur/-/plur-1.0.0.tgz#db85c6814f5e5e5a3b49efc28d604fec62975156" integrity sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY= +pluralize@~7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== + pngjs@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb" @@ -23936,7 +25472,7 @@ prop-types-extra@^1.1.0: react-is "^16.3.2" warning "^4.0.0" -prop-types@^15.0.0, prop-types@^15.8.1: +prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -24145,6 +25681,18 @@ pure-color@^1.2.0: resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e" integrity sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA== +pvtsutils@^1.3.2, pvtsutils@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/pvtsutils/-/pvtsutils-1.3.5.tgz#b8705b437b7b134cd7fd858f025a23456f1ce910" + integrity sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA== + dependencies: + tslib "^2.6.1" + +pvutils@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/pvutils/-/pvutils-1.1.3.tgz#f35fc1d27e7cd3dfbd39c0826d173e806a03f5a3" + integrity sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ== + q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -24247,6 +25795,15 @@ r1csfile@0.0.45: fastfile "0.0.20" ffjavascript "0.2.57" +ra-data-graphql@^4.16.11: + version "4.16.11" + resolved "https://registry.yarnpkg.com/ra-data-graphql/-/ra-data-graphql-4.16.11.tgz#974e87ea178aec547407372c2c32018333c2ac52" + integrity sha512-mJ1xWYjdgJu8mKwMRZfU/0+ZdLC3y6QES0hpc2kLuVvB2t3OtecYMB0WwfQnyekt+qZ1Chj6sMLtEvUCAZcpkA== + dependencies: + "@apollo/client" "^3.3.19" + lodash "~4.17.5" + pluralize "~7.0.0" + radix3@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/radix3/-/radix3-1.1.0.tgz#9745df67a49c522e94a33d0a93cf743f104b6e0d" @@ -24540,6 +26097,21 @@ react-router@6.21.0: dependencies: "@remix-run/router" "1.14.0" +react-select@^5.8.0: + version "5.8.0" + resolved "https://registry.yarnpkg.com/react-select/-/react-select-5.8.0.tgz#bd5c467a4df223f079dd720be9498076a3f085b5" + integrity sha512-TfjLDo58XrhP6VG5M/Mi56Us0Yt8X7xD6cDybC7yoRMUNm7BGO7qk8J0TLQOua/prb8vUOtsfnXZwfm30HGsAA== + dependencies: + "@babel/runtime" "^7.12.0" + "@emotion/cache" "^11.4.0" + "@emotion/react" "^11.8.1" + "@floating-ui/dom" "^1.0.1" + "@types/react-transition-group" "^4.4.0" + memoize-one "^6.0.0" + prop-types "^15.6.0" + react-transition-group "^4.3.0" + use-isomorphic-layout-effect "^1.1.2" + react-spinners@^0.13.8: version "0.13.8" resolved "https://registry.yarnpkg.com/react-spinners/-/react-spinners-0.13.8.tgz#5262571be0f745d86bbd49a1e6b49f9f9cb19acc" @@ -24569,7 +26141,7 @@ react-toastify@^10.0.3: dependencies: clsx "^2.1.0" -react-transition-group@^4.4.1: +react-transition-group@^4.3.0, react-transition-group@^4.4.1: version "4.4.5" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== @@ -25177,6 +26749,11 @@ regjsparser@^0.9.1: dependencies: jsesc "~0.5.0" +rehackt@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/rehackt/-/rehackt-0.0.5.tgz#184c82ea369d5b0b989ede0593ebea8b2bcfb1d6" + integrity sha512-BI1rV+miEkaHj8zd2n+gaMgzu/fKz7BGlb4zZ6HAiY9adDmJMkaDcmuXlJFv0eyKUob+oszs3/2gdnXUrzx2Tg== + rehype-raw@^6.0.0: version "6.1.1" resolved "https://registry.yarnpkg.com/rehype-raw/-/rehype-raw-6.1.1.tgz#81bbef3793bd7abacc6bf8335879d1b6c868c9d4" @@ -25186,6 +26763,15 @@ rehype-raw@^6.0.0: hast-util-raw "^7.2.0" unified "^10.0.0" +relay-runtime@12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/relay-runtime/-/relay-runtime-12.0.0.tgz#1e039282bdb5e0c1b9a7dc7f6b9a09d4f4ff8237" + integrity sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug== + dependencies: + "@babel/runtime" "^7.0.0" + fbjs "^3.0.0" + invariant "^2.2.4" + release-zalgo@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" @@ -25222,6 +26808,11 @@ remark-rehype@^10.0.0: mdast-util-to-hast "^12.1.0" unified "^10.0.0" +remedial@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/remedial/-/remedial-1.0.8.tgz#a5e4fd52a0e4956adbaf62da63a5a46a78c578a0" + integrity sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg== + remove-bom-buffer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" @@ -25244,6 +26835,11 @@ remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0: resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= +remove-trailing-spaces@^1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/remove-trailing-spaces/-/remove-trailing-spaces-1.0.8.tgz#4354d22f3236374702f58ee373168f6d6887ada7" + integrity sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA== + repeat-element@^1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" @@ -25396,6 +26992,11 @@ resolve-dir@^1.0.0, resolve-dir@^1.0.1: expand-tilde "^2.0.0" global-modules "^1.0.0" +resolve-from@5.0.0, resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" @@ -25406,11 +27007,6 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - resolve-options@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" @@ -25481,6 +27077,11 @@ resolve@^2.0.0-next.3: is-core-module "^2.2.0" path-parse "^1.0.6" +response-iterator@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/response-iterator/-/response-iterator-0.2.6.tgz#249005fb14d2e4eeb478a3f735a28fd8b4c9f3da" + integrity sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw== + responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" @@ -25695,7 +27296,7 @@ rss-parser@^3.12.0: entities "^2.0.3" xml2js "^0.4.19" -run-async@^2.2.0: +run-async@^2.2.0, run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== @@ -25752,7 +27353,7 @@ rxjs@^6.4.0, rxjs@^6.5.4: dependencies: tslib "^1.9.0" -rxjs@^7.8.0: +rxjs@^7.5.5, rxjs@^7.8.0: version "7.8.1" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== @@ -25882,6 +27483,11 @@ scrypt-js@3.0.1, scrypt-js@^3.0.0: resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== +scuid@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/scuid/-/scuid-1.1.0.tgz#d3f9f920956e737a60f72d0e4ad280bf324d5dab" + integrity sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg== + secp256k1@4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" @@ -25974,6 +27580,11 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semve resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + semver@^7.1.3, semver@^7.2.1, semver@^7.3.2: version "7.5.1" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" @@ -26207,6 +27818,11 @@ shell-quote@^1.6.1: resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== +shell-quote@^1.7.3: + version "1.8.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== + shelljs@^0.7.5: version "0.7.8" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" @@ -26266,6 +27882,11 @@ signed-varint@^2.0.1: dependencies: varint "~5.0.0" +signedsource@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/signedsource/-/signedsource-1.0.0.tgz#1ddace4981798f93bd833973803d80d52e93ad6a" + integrity sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww== + simple-concat@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" @@ -26764,6 +28385,13 @@ split@^1.0.0: dependencies: through "2" +sponge-case@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sponge-case/-/sponge-case-1.0.1.tgz#260833b86453883d974f84854cdb63aecc5aef4c" + integrity sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA== + dependencies: + tslib "^2.0.3" + sprintf-js@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" @@ -26950,6 +28578,11 @@ stream-to-it@^0.2.0, stream-to-it@^0.2.1: dependencies: get-iterator "^1.0.2" +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== + streamx@^2.15.0: version "2.15.1" resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.1.tgz#396ad286d8bc3eeef8f5cea3f029e81237c024c6" @@ -26968,6 +28601,11 @@ string-argv@^0.3.1: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== +string-env-interpolation@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz#ad4397ae4ac53fe6c91d1402ad6f6a52862c7152" + integrity sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg== + string-hash@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" @@ -27347,6 +28985,11 @@ stylehacks@^5.1.1: browserslist "^4.21.4" postcss-selector-parser "^6.0.4" +stylis@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== + stylus-loader@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-7.1.0.tgz#19e09a98b19075c246e6e3f65e38b8cb89d2d6fb" @@ -27494,6 +29137,18 @@ svgpath@^2.3.0: resolved "https://registry.yarnpkg.com/svgpath/-/svgpath-2.6.0.tgz#5b160ef3d742b7dfd2d721bf90588d3450d7a90d" integrity sha512-OIWR6bKzXvdXYyO4DK/UWa1VA1JeKq8E+0ug2DG98Y/vOmMpfZNj+TIG988HjfYSqtcy/hFOtZq/n/j5GSESNg== +swap-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-2.0.2.tgz#671aedb3c9c137e2985ef51c51f9e98445bf70d9" + integrity sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw== + dependencies: + tslib "^2.0.3" + +symbol-observable@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205" + integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ== + syntax-error@^1.1.1: version "1.4.0" resolved "https://registry.yarnpkg.com/syntax-error/-/syntax-error-1.4.0.tgz#2d9d4ff5c064acb711594a3e3b95054ad51d907c" @@ -27847,6 +29502,13 @@ tiny-warning@^1.0.2: resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== +title-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/title-case/-/title-case-3.0.3.tgz#bc689b46f02e411f1d1e1d081f7c3deca0489982" + integrity sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA== + dependencies: + tslib "^2.0.3" + tmp@0.0.33, tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -28054,6 +29716,13 @@ tryer@^1.0.1: resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== +ts-invariant@^0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.10.3.tgz#3e048ff96e91459ffca01304dbc7f61c1f642f6c" + integrity sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ== + dependencies: + tslib "^2.1.0" + ts-loader@^9.2.6: version "9.2.6" resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.6.tgz#9937c4dd0a1e3dbbb5e433f8102a6601c6615d74" @@ -28074,6 +29743,11 @@ ts-loader@^9.3.1: micromatch "^4.0.0" semver "^7.3.4" +ts-log@^2.2.3: + version "2.2.5" + resolved "https://registry.yarnpkg.com/ts-log/-/ts-log-2.2.5.tgz#aef3252f1143d11047e2cb6f7cfaac7408d96623" + integrity sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA== + ts-node@10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -28151,7 +29825,7 @@ tslib@^2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.2.tgz#1b6f07185c881557b0ffa84b111a0106989e8338" integrity sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA== -tslib@^2.3.1: +tslib@^2.3.1, tslib@^2.5.0, tslib@^2.6.1, tslib@^2.6.2, tslib@~2.6.0: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== @@ -28749,6 +30423,13 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== +unixify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unixify/-/unixify-1.0.0.tgz#3a641c8c2ffbce4da683a5c70f03a462940c2090" + integrity sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg== + dependencies: + normalize-path "^2.1.1" + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -28798,6 +30479,14 @@ upath@^1.1.1, upath@^1.2.0: resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + update-browserslist-db@^1.0.9: version "1.0.9" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz#2924d3927367a38d5c555413a7ce138fc95fcb18" @@ -28883,12 +30572,22 @@ url@^0.11.0, url@~0.11.0: punycode "1.3.2" querystring "0.2.0" +urlpattern-polyfill@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz#f0a03a97bfb03cdf33553e5e79a2aadd22cac8ec" + integrity sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg== + +urlpattern-polyfill@^8.0.0: + version "8.0.2" + resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz#99f096e35eff8bf4b5a2aa7d58a1523d6ebc7ce5" + integrity sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ== + use-composed-ref@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.3.0.tgz#3d8104db34b7b264030a9d916c5e94fbe280dbda" integrity sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ== -use-isomorphic-layout-effect@^1.1.1: +use-isomorphic-layout-effect@^1.1.1, use-isomorphic-layout-effect@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb" integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA== @@ -29099,6 +30798,11 @@ value-or-function@^3.0.0: resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" integrity sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM= +value-or-promise@^1.0.11, value-or-promise@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.12.tgz#0e5abfeec70148c78460a849f6b003ea7986f15c" + integrity sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q== + varint@^5.0.0, varint@^5.0.2, varint@~5.0.0: version "5.0.2" resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" @@ -29322,6 +31026,11 @@ web-streams-polyfill@^3.1.0: resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz#a6b74026b38e4885869fb5c589e90b95ccfc7965" integrity sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA== +web-streams-polyfill@^3.2.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz#2073b91a2fdb1fbfbd401e7de0ac9f8214cecb4b" + integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw== + web-worker@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/web-worker/-/web-worker-1.2.0.tgz#5d85a04a7fbc1e7db58f66595d7a3ac7c9c180da" @@ -29562,6 +31271,17 @@ web3@^4.1.0: web3-utils "^4.0.7" web3-validator "^2.0.3" +webcrypto-core@^1.7.8: + version "1.7.8" + resolved "https://registry.yarnpkg.com/webcrypto-core/-/webcrypto-core-1.7.8.tgz#056918036e846c72cfebbb04052e283f57f1114a" + integrity sha512-eBR98r9nQXTqXt/yDRtInszPMjTaSAMJAFDg2AHsgrnczawT1asx9YNBX6k5p+MekbPF4+s/UJJrr88zsTqkSg== + dependencies: + "@peculiar/asn1-schema" "^2.3.8" + "@peculiar/json-schema" "^1.1.12" + asn1js "^3.0.1" + pvtsutils "^1.3.5" + tslib "^2.6.2" + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -29960,7 +31680,7 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" -wrap-ansi@^6.2.0: +wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== @@ -30079,7 +31799,7 @@ ws@^7.3.1, ws@^7.4.6, ws@^7.5.1: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== -ws@^8.13.0: +ws@^8.12.0, ws@^8.13.0, ws@^8.15.0: version "8.16.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== @@ -30162,6 +31882,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml-ast-parser@^0.0.43: + version "0.0.43" + resolved "https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz#e8a23e6fb4c38076ab92995c5dca33f3d3d7c9bb" + integrity sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A== + yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" @@ -30172,6 +31897,11 @@ yaml@^2.2.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== +yaml@^2.3.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.0.tgz#2376db1083d157f4b3a452995803dbcf43b08140" + integrity sha512-j9iR8g+/t0lArF4V6NE/QCfT+CO7iLqrXAHZbJdo+LfjqP1vR8Fg5bSiaq6Q2lOD1AUEVrEVIgABvBFYojJVYQ== + yargs-parser@20.2.4, yargs-parser@^20.2.2: version "20.2.4" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" @@ -30319,7 +32049,7 @@ yargs@^15.3.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^17.0.1: +yargs@^17.0.0, yargs@^17.0.1: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== @@ -30400,6 +32130,18 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +zen-observable-ts@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz#6c6d9ea3d3a842812c6e9519209365a122ba8b58" + integrity sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg== + dependencies: + zen-observable "0.8.15" + +zen-observable@0.8.15: + version "0.8.15" + resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" + integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== + zod@3.22.4, zod@^3.21.4: version "3.22.4" resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff" From b0d7d80b6fd3f95cf1c96d82d0bbdc93a3909d63 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Tue, 11 Jun 2024 07:35:35 +0200 Subject: [PATCH 02/40] canuseapptrue --- libs/remix-ui/git/src/types/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/git/src/types/index.ts b/libs/remix-ui/git/src/types/index.ts index 795646b84d..9ed9a292ed 100644 --- a/libs/remix-ui/git/src/types/index.ts +++ b/libs/remix-ui/git/src/types/index.ts @@ -280,7 +280,7 @@ export const defaultGitState: gitState = { deleted: [], modified: [], allchangesnotstaged: [], - canUseApp: false, + canUseApp: true, loading: false, storageUsed: {}, reponame: "", From 38e435362eaffff9a7d5e5214f3f8afaa5db2be9 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Tue, 11 Jun 2024 07:49:22 +0200 Subject: [PATCH 03/40] add pause --- apps/remix-ide-e2e/src/tests/dgit_local.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/remix-ide-e2e/src/tests/dgit_local.test.ts b/apps/remix-ide-e2e/src/tests/dgit_local.test.ts index fb0c87ed08..86d766a753 100644 --- a/apps/remix-ide-e2e/src/tests/dgit_local.test.ts +++ b/apps/remix-ide-e2e/src/tests/dgit_local.test.ts @@ -260,6 +260,7 @@ module.exports = { .pause(1000) .addFile('test.txt', { content: 'hello world' }, 'README.md') .clickLaunchIcon('dgit') + .pause(2000) .waitForElementVisible({ selector: "//*[@data-status='new-untracked' and @data-file='/test.txt']", locateStrategy: 'xpath' From 06610bc0726773b82577ff1ce6059792612f1eea Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Tue, 11 Jun 2024 07:53:47 +0200 Subject: [PATCH 04/40] rm console --- libs/remix-ui/editor/src/lib/remix-ui-editor.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx index 17840aacae..616013f308 100644 --- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx +++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx @@ -534,7 +534,6 @@ export const EditorUI = (props: EditorUIProps) => { for (const filePath in allMarkersPerfile) { const model = editorModelsState[filePath]?.model if (model) { - console.log('MONACO REF CURRENT', monacoRef.current) monacoRef.current.editor.setModelMarkers(model, from, allMarkersPerfile[filePath]) } } From 8dca277d52dcc4094dc0c4eba95677fe0449ab3a Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 26 Jun 2024 11:52:16 +0200 Subject: [PATCH 05/40] vyper test --- .../remix-ide-e2e/src/tests/vyper_api.test.ts | 71 +++++++++---------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/vyper_api.test.ts b/apps/remix-ide-e2e/src/tests/vyper_api.test.ts index 0ec2759a2e..1174b58fc6 100644 --- a/apps/remix-ide-e2e/src/tests/vyper_api.test.ts +++ b/apps/remix-ide-e2e/src/tests/vyper_api.test.ts @@ -27,7 +27,7 @@ module.exports = { .frameParent() .clickLaunchIcon('filePanel') .waitForElementVisible({ - selector: "//*[@data-id='workspacesSelect' and contains(.,'vyper-lang')]", + selector: "//*[@data-id='workspacesSelect' and contains(.,'snekmate')]", locateStrategy: 'xpath', timeout: 120000 }) @@ -38,16 +38,15 @@ module.exports = { timeout: 1200000 }) }, - - // '@sources': () => sources, - // 'Context menu click to compile blind_auction should succeed #group1': function (browser: NightwatchBrowser) { - // browser - // .addFileSnekmate('blind_auction.vy', sources[0]['blindAuction']) - + // 'Add vyper file to run tests #group1': function (browser: NightwatchBrowser) { + // browser.addFile('TestBallot.sol', sources[0]['TestBallot.sol']) + // }, + '@sources': () => sources, 'Context menu click to compile blind_auction should succeed #group1': function (browser: NightwatchBrowser) { browser - .click('*[data-id="treeViewDivtreeViewItemexamples/auctions/blind_auction.vy"]') - .rightClick('*[data-id="treeViewDivtreeViewItemexamples/auctions/blind_auction.vy"]') + .addFileSnekmate('blind_auction.vy', sources[0]['blindAuction']) + .click('*[data-id="treeViewLitreeViewItemblind_auction.vy"]') + .rightClick('*[data-id="treeViewLitreeViewItemblind_auction.vy"]') .waitForElementPresent('[data-id="contextMenuItemvyper"]') .click('[data-id="contextMenuItemvyper"]') .clickLaunchIcon('vyper') @@ -146,32 +145,32 @@ module.exports = { }) }, - // 'Compile Ownable contract from snekmate #group1': function (browser: NightwatchBrowser) { - // let contractAddress - // browser - // .frameParent() - // .clickLaunchIcon('filePanel') - // .switchWorkspace('snekmate') - // .openFile('src') - // .openFile('src/snekmate') - // .openFile('src/snekmate/auth') - // .openFile('src/snekmate/auth/Ownable.vy') - // .rightClick('*[data-id="treeViewLitreeViewItemsrc/snekmate/auth/Ownable.vy"]') - // .waitForElementVisible('*[data-id="contextMenuItemvyper"]') - // .click('*[data-id="contextMenuItemvyper"]') - // .clickLaunchIcon('vyper') - // // @ts-ignore - // .frame(0) - // .click('[data-id="compile"]') - // .waitForElementVisible({ - // selector:'[data-id="compilation-details"]', - // timeout: 60000 - // }) - // .click('[data-id="compilation-details"]') - // .frameParent() - // .waitForElementVisible('[data-id="copy-abi"]') - // .end() - // } + 'Compile Ownable contract from snekmate #group1': function (browser: NightwatchBrowser) { + let contractAddress + browser + .frameParent() + .clickLaunchIcon('filePanel') + .switchWorkspace('snekmate') + .openFile('src') + .openFile('src/snekmate') + .openFile('src/snekmate/auth') + .openFile('src/snekmate/auth/Ownable.vy') + .rightClick('*[data-id="treeViewLitreeViewItemsrc/snekmate/auth/Ownable.vy"]') + .waitForElementVisible('*[data-id="contextMenuItemvyper"]') + .click('*[data-id="contextMenuItemvyper"]') + .clickLaunchIcon('vyper') + // @ts-ignore + .frame(0) + .click('[data-id="compile"]') + .waitForElementVisible({ + selector:'[data-id="compilation-details"]', + timeout: 60000 + }) + .click('[data-id="compilation-details"]') + .frameParent() + .waitForElementVisible('[data-id="copy-abi"]') + .end() + } } const testContract = ` @@ -385,6 +384,6 @@ def auctionEnd(): # Transfer funds to beneficiary send(self.beneficiary, self.highestBid) -` } +`} } ] From 3c9480538c10c53ed348171e7b9dd0e75abaf93e Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 27 Jun 2024 09:02:50 +0100 Subject: [PATCH 06/40] fix crash --- libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx b/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx index fa93315167..e3a26919ae 100644 --- a/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx +++ b/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx @@ -52,7 +52,6 @@ export default function GitStatus({ plugin, gitBranchName, setGitBranchName }: G await plugin.call('dGitProvider', 'init') const isActive = await plugin.call('manager', 'isActive', 'dgit') if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') - // plugin.verticalIcons.select('dgit') } return ( @@ -63,10 +62,10 @@ export default function GitStatus({ plugin, gitBranchName, setGitBranchName }: G className="d-flex flex-row pl-3 text-white justify-content-center align-items-center remixui_statusbar_gitstatus" onClick={async () => await lightDgitUp()} > - {gitBranchName.length > 0 && gitBranchName !== 'Not a git repo' ? + {gitBranchName && gitBranchName !== 'Not a git repo' && gitBranchName.length > 0 ? : Initialize as git repo} - {gitBranchName.length > 0 && gitBranchName !== 'Not a git repo' && {gitBranchName}} - {gitBranchName.length > 0 && gitBranchName !== 'Not a git repo' && } + {gitBranchName && gitBranchName !== 'Not a git repo' && gitBranchName.length > 0 && {gitBranchName}} + {gitBranchName && gitBranchName !== 'Not a git repo' && gitBranchName.length > 0 && }
    ) From c85590563bd205e900fb5f4a6a389345aa380898 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 27 Jun 2024 10:11:34 +0100 Subject: [PATCH 07/40] add localhost check --- .../src/lib/components/gitStatus.tsx | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx b/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx index e3a26919ae..b8f1ec224b 100644 --- a/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx +++ b/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, Dispatch } from 'react' +import React, { useEffect, Dispatch, useState } from 'react' // eslint-disable-next-line @nrwl/nx/enforce-module-boundaries import { StatusBar } from 'apps/remix-ide/src/app/components/status-bar' import '../../css/statusbar.css' @@ -11,10 +11,12 @@ export interface GitStatusProps { } export default function GitStatus({ plugin, gitBranchName, setGitBranchName }: GitStatusProps) { + const [isLocalHost, setIsLocalHost] = useState(false) useEffect(() => { plugin.on('filePanel', 'setWorkspace', async (workspace) => { const isGit = await plugin.call('fileManager', 'isGitRepo') + setIsLocalHost(workspace.isLocalhost) if (isGit) { setGitBranchName(workspace.name) } else { @@ -23,6 +25,7 @@ export default function GitStatus({ plugin, gitBranchName, setGitBranchName }: G }) plugin.on('filePanel', 'workspaceInitializationCompleted', async () => { const isGit = await plugin.call('fileManager', 'isGitRepo') + console.log('complete', gitBranchName) if (isGit) { const workspace = localStorage.getItem('currentWorkspace') setGitBranchName(workspace) @@ -37,6 +40,7 @@ export default function GitStatus({ plugin, gitBranchName, setGitBranchName }: G setGitBranchName(workspace) } }) + }, []) const lightDgitUp = async () => { @@ -51,9 +55,14 @@ export default function GitStatus({ plugin, gitBranchName, setGitBranchName }: G const initializeNewGitRepo = async () => { await plugin.call('dGitProvider', 'init') const isActive = await plugin.call('manager', 'isActive', 'dgit') - if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') + if (isLocalHost === false) { + if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') + } } + const checkBranchName = ()=> { + return gitBranchName && gitBranchName !== 'Not a git repo' && gitBranchName.length > 0 + } return ( await lightDgitUp()} > - {gitBranchName && gitBranchName !== 'Not a git repo' && gitBranchName.length > 0 ? + {checkBranchName() && isLocalHost === false ? : Initialize as git repo} - {gitBranchName && gitBranchName !== 'Not a git repo' && gitBranchName.length > 0 && {gitBranchName}} - {gitBranchName && gitBranchName !== 'Not a git repo' && gitBranchName.length > 0 && } + {checkBranchName() && isLocalHost === false && {gitBranchName}} + {checkBranchName() && isLocalHost === false && } ) From 896bcafaf59a212a341b10052330e3a983421fbc Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Thu, 27 Jun 2024 10:15:17 +0100 Subject: [PATCH 08/40] remove console log --- libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx b/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx index b8f1ec224b..07c299c132 100644 --- a/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx +++ b/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx @@ -25,7 +25,6 @@ export default function GitStatus({ plugin, gitBranchName, setGitBranchName }: G }) plugin.on('filePanel', 'workspaceInitializationCompleted', async () => { const isGit = await plugin.call('fileManager', 'isGitRepo') - console.log('complete', gitBranchName) if (isGit) { const workspace = localStorage.getItem('currentWorkspace') setGitBranchName(workspace) From 42499d5e80dedc341251eb5badd1d8702f892637 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 27 Jun 2024 15:56:39 +0530 Subject: [PATCH 09/40] minor text updates --- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 3da9063576..5cc578419b 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -1350,7 +1350,7 @@ export function Workspace() { {selectedWorkspace.hasGitSubmodules?
    {global.fs.browser.isRequestingCloning ?
    updating submodules
    : -
    update submodules
    } +
    Update submodules
    }
    : null}
    From e01d879f00ea286a6b80b099db21be58610f0738 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 27 Jun 2024 16:03:05 +0530 Subject: [PATCH 10/40] link updated --- libs/remix-ui/home-tab/src/lib/components/homeTabTitle.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabTitle.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabTitle.tsx index c6273a8545..b4049a661c 100644 --- a/libs/remix-ui/home-tab/src/lib/components/homeTabTitle.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/homeTabTitle.tsx @@ -25,7 +25,7 @@ const iconButtons: HometabIconSection[] = [ { textToolip: , matomoTrackingEntry: ['trackEvent', 'hometab', 'socialMedia', 'twitter'], - urlLink: 'https://twitter.com/EthereumRemix', + urlLink: 'https://x.com/EthereumRemix', iconClass: 'fa-x-twitter', placement: 'top' }, From 0eec3f52fe731c6f2734544ef36935eae10578fc Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 27 Jun 2024 16:08:55 +0530 Subject: [PATCH 11/40] twitter to X --- README.md | 4 ++-- apps/remix-ide/src/app/tabs/locales/en/home.json | 2 +- apps/remix-ide/src/app/tabs/locales/es/home.json | 2 +- apps/remix-ide/src/app/tabs/locales/fr/home.json | 2 +- apps/remix-ide/src/app/tabs/locales/it/home.json | 2 +- apps/remix-ide/src/app/tabs/locales/ru/home.json | 2 +- libs/remix-ui/editor/src/lib/remix-ui-editor.tsx | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 61071ea937..9059e6318c 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ [![Awesome Remix](https://img.shields.io/badge/Awesome--Remix-resources-green?logo=awesomelists)](https://github.com/ethereum/awesome-remix) ![GitHub](https://img.shields.io/github/license/ethereum/remix-project) [![Discord](https://img.shields.io/badge/join-discord-brightgreen.svg?style=flat&logo=discord)](https://discord.gg/mh9hFCKkEq) -[![Twitter Follow](https://img.shields.io/twitter/follow/ethereumremix?style=flat&logo=twitter&color=green)](https://twitter.com/ethereumremix) +[![X Follow](https://img.shields.io/twitter/follow/ethereumremix?style=flat&logo=x&color=green)](https://x.com/ethereumremix)
    @@ -266,5 +266,5 @@ parameters: - Official documentation: https://remix-ide.readthedocs.io/en/latest/ - Curated list of Remix resources: https://github.com/ethereum/awesome-remix - Medium: https://medium.com/remix-ide -- Twitter: https://twitter.com/ethereumremix +- X: https://x.com/ethereumremix - Join Discord: https://discord.gg/mh9hFCKkEq diff --git a/apps/remix-ide/src/app/tabs/locales/en/home.json b/apps/remix-ide/src/app/tabs/locales/en/home.json index 99389282e1..d0e98ee5eb 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/home.json +++ b/apps/remix-ide/src/app/tabs/locales/en/home.json @@ -45,7 +45,7 @@ "home.remixAdvanced": "Deploying with Libraries", "home.remixAdvancedDesc": "Learn to deploy with libraries in Remix", "home.remixYoutubePlaylist": "Remix Youtube Playlist", - "home.remixTwitterProfile": "Remix Twitter Profile", + "home.remixTwitterProfile": "Remix X Profile", "home.remixLinkedinProfile": "Remix Linkedin Profile", "home.remixMediumPosts": "Remix Medium Posts", "home.joinUsOnDiscord": "Join us on Discord", diff --git a/apps/remix-ide/src/app/tabs/locales/es/home.json b/apps/remix-ide/src/app/tabs/locales/es/home.json index 5d0ab22fdd..a3d62f2665 100644 --- a/apps/remix-ide/src/app/tabs/locales/es/home.json +++ b/apps/remix-ide/src/app/tabs/locales/es/home.json @@ -44,7 +44,7 @@ "home.remixAdvanced": "Publicando con Librearías", "home.remixAdvancedDesc": "Aprende a publicar con librearías en Remix", "home.remixYoutubePlaylist": "Lista de reproducción en YouTube de Remix", - "home.remixTwitterProfile": "Perfil en Twitter de Remix", + "home.remixTwitterProfile": "Perfil en X de Remix", "home.remixLinkedinProfile": "Perfil en Linkedin de Remix", "home.remixMediumPosts": "Publicaciones en Medium de Remix", "home.joinUsOnDiscord": "Únete a nosotros en Discord", diff --git a/apps/remix-ide/src/app/tabs/locales/fr/home.json b/apps/remix-ide/src/app/tabs/locales/fr/home.json index 802d22bef4..8d40e51b86 100644 --- a/apps/remix-ide/src/app/tabs/locales/fr/home.json +++ b/apps/remix-ide/src/app/tabs/locales/fr/home.json @@ -42,7 +42,7 @@ "home.remixAdvanced": "Deploying with Libraries", "home.remixAdvancedDesc": "Learn to deploy with libraries in Remix", "home.remixYoutubePlaylist": "Remix Youtube Playlist", - "home.remixTwitterProfile": "Remix Twitter Profile", + "home.remixTwitterProfile": "Remix X Profile", "home.remixLinkedinProfile": "Remix Linkedin Profile", "home.remixMediumPosts": "Remix Medium Posts", "home.remixGitterChannel": "Join us on Discord", diff --git a/apps/remix-ide/src/app/tabs/locales/it/home.json b/apps/remix-ide/src/app/tabs/locales/it/home.json index 1a4b73379d..c8082f34bf 100644 --- a/apps/remix-ide/src/app/tabs/locales/it/home.json +++ b/apps/remix-ide/src/app/tabs/locales/it/home.json @@ -44,7 +44,7 @@ "home.remixAdvanced": "Distribuire con le Librerie", "home.remixAdvancedDesc": "Impara a fare deployment con le librerie in Remix", "home.remixYoutubePlaylist": "Playlist Youtube di Remix", - "home.remixTwitterProfile": "Profilo Twitter di Remix", + "home.remixTwitterProfile": "Profilo X di Remix", "home.remixLinkedinProfile": "Profilo LinkedIn di Remix", "home.remixMediumPosts": "Post in Medium di Remix", "home.joinUsOnDiscord": "Unisciti a noi su Discord", diff --git a/apps/remix-ide/src/app/tabs/locales/ru/home.json b/apps/remix-ide/src/app/tabs/locales/ru/home.json index 6de3fd10e8..48044db76d 100644 --- a/apps/remix-ide/src/app/tabs/locales/ru/home.json +++ b/apps/remix-ide/src/app/tabs/locales/ru/home.json @@ -44,7 +44,7 @@ "home.remixAdvanced": "Развертывание с Библиотеками", "home.remixAdvancedDesc": "Научитесь развертывать с библиотеками в Remix", "home.remixYoutubePlaylist": "Плейлист Remix на Youtube", - "home.remixTwitterProfile": "Remix Twitter Профиль", + "home.remixTwitterProfile": "Remix X Профиль", "home.remixLinkedinProfile": "Remix Linkedin профиль", "home.remixMediumPosts": "Remix Medium публикации", "home.joinUsOnDiscord": "Присоединяйтесь к нам в Discord", diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx index 7805223b87..7c3c4b4ae6 100644 --- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx +++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx @@ -166,9 +166,9 @@ export const EditorUI = (props: EditorUIProps) => { \t\t\t\t\t\t\t\t${intl.formatMessage({ id: 'editor.importantLinks.text1' })}: https://remix-project.org/\n \t\t\t\t\t\t\t\t${intl.formatMessage({ id: 'editor.importantLinks.text2' })}: https://remix-ide.readthedocs.io/en/latest/\n \t\t\t\t\t\t\t\tGithub: https://github.com/ethereum/remix-project\n - \t\t\t\t\t\t\t\tGitter: https://gitter.im/ethereum/remix\n + \t\t\t\t\t\t\t\tDiscord: https://discord.gg/mh9hFCKkEq\n \t\t\t\t\t\t\t\tMedium: https://medium.com/remix-ide\n - \t\t\t\t\t\t\t\tTwitter: https://twitter.com/ethereumremix\n + \t\t\t\t\t\t\t\tX: https://x.com/ethereumremix\n ` const pasteCodeRef = useRef(false) const editorRef = useRef(null) From a7fa397a0d19ff279442d93767d9a6050c1e9b4e Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Fri, 28 Jun 2024 09:30:54 +0200 Subject: [PATCH 12/40] run tests on master --- .../src/tests/etherscan_api.test.ts | 10 +- .../src/tests/runAndDeploy_injected.test.ts | 9 +- apps/remix-ide-e2e/src/tests/terminal.test.ts | 172 ++++++++++-------- 3 files changed, 109 insertions(+), 82 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/etherscan_api.test.ts b/apps/remix-ide-e2e/src/tests/etherscan_api.test.ts index 48c208b58e..c9592d684f 100644 --- a/apps/remix-ide-e2e/src/tests/etherscan_api.test.ts +++ b/apps/remix-ide-e2e/src/tests/etherscan_api.test.ts @@ -6,7 +6,7 @@ declare global { interface Window { testplugin: { name: string, url: string }; } } -module.exports = { +const tests = { '@disabled': true, before: function (browser: NightwatchBrowser, done: VoidFunction) { init(browser, done, null) @@ -58,6 +58,14 @@ module.exports = { } } +const branch = process.env.CIRCLE_BRANCH; +const isMasterBranch = branch === 'master'; + +module.exports = { + ...(branch ? (isMasterBranch ? tests : {}) : tests), +}; + + const verifiedContract = ` // SPDX-License-Identifier: GPL-3.0 diff --git a/apps/remix-ide-e2e/src/tests/runAndDeploy_injected.test.ts b/apps/remix-ide-e2e/src/tests/runAndDeploy_injected.test.ts index 8f29fbd5ca..331dec221d 100644 --- a/apps/remix-ide-e2e/src/tests/runAndDeploy_injected.test.ts +++ b/apps/remix-ide-e2e/src/tests/runAndDeploy_injected.test.ts @@ -25,7 +25,7 @@ const checkAlerts = function (browser: NightwatchBrowser){ }) } -module.exports = { +const tests = { '@disabled': true, before: function (browser: NightwatchBrowser, done: VoidFunction) { init(browser, done) @@ -232,6 +232,13 @@ module.exports = { } } +const branch = process.env.CIRCLE_BRANCH; +const isMasterBranch = branch === 'master'; + +module.exports = { + ...(branch ? (isMasterBranch ? tests : {}) : tests), +}; + const localsCheck = { to: { value: '0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB', diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index eb5074e3ca..8b83042ab7 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -2,6 +2,10 @@ import { NightwatchBrowser } from 'nightwatch' import init from '../helpers/init' +const branch = process.env.CIRCLE_BRANCH; +const isMasterBranch = branch === 'master'; +const runMasterTests: boolean = (branch ? (isMasterBranch ? true : false) : true) + module.exports = { '@disabled': true, before: function (browser: NightwatchBrowser, done: VoidFunction) { @@ -209,26 +213,28 @@ module.exports = { }, 'Should run a script which log transaction and block using web3.js and ethers #group7': function (browser: NightwatchBrowser) { + if(runMasterTests){ browser - .clickLaunchIcon('udapp') - .switchEnvironment('basic-http-provider') - .waitForElementPresent('[data-id="basic-http-provider-modal-footer-ok-react"]') - .execute(() => { - (document.querySelector('*[data-id="basic-http-providerModalDialogContainer-react"] input[data-id="modalDialogCustomPromp"]') as any).focus() - }, [], () => { }) - .setValue('[data-id="modalDialogCustomPromp"]', 'https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9') - .modalFooterOKClick('basic-http-provider') - .clickLaunchIcon('filePanel') - .openFile('README.txt') - .addFile('scripts/log_tx_block.js', { content: scriptBlockAndTransaction }) - .pause(1000) - .executeScriptInTerminal('remix.execute(\'scripts/log_tx_block.js\')') - // check if the input of the transaction is being logged (web3 call) - .waitForElementContainsText('*[data-id="terminalJournal"]', '0x2b0006fa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e9e0000000000000000000000000000000000000000000000000000000000004ea373ded44d6900b8b479935bee9c82176261653e334586e0fd282f569357c0777bd9d084474837ac94bf96f2e26590222a2b8e46545657c7cf06ce2833d267bd6f131b5b3fd36cb1ca3e07cf422224df0766d1a677bbdb7ee4cc0d634efa5367a302a94dac422a16b9b8d5c10fe0555924f8189f6b498bef507b1d32e7915bd4df184f51e6d79ae6a1b11d5745ce7d625cecc3bd0dc50af4f999ffb927225f5e5c019b499f5e1fdcbc70c45df61df76013d1b0d45cdf6a267dac1b4620c0db2efd251f6548509c9c69f5bd9d1ee38ac0df0c73be2774f7d2e1fb7ef5129010f29d091e3c48aed0f035fc29804c99927d33ff2a19ff526979355ac50b2542bc5d8f2d41e4f850d5981e0420807469e828b03173b96b757fbaeacda335e11b3ab8b02a48456fab35d41ca26abde751d5fca8ef5e7ba5295278b6e46ce2aab6c10b3d185a6137d3e5c28bb8dd3a797feaf35520fcb949ea074e1869e0011ef01f8162135e44bb797d3d6215ff74ffbee972c97264fc15d11c840e6a7e796dc1a418572f6dbcc842594a558e1a9e3cb7a159284e16fec758bbc303d13edc28fb6d8bb110c3a398e4ded1748da9854eb84679ad0c99bc59bea7956b521db3ed0a9057510cc11365858704989690f0d891af81b213b1f2e91e41e4998a467656eac87e7025ac2840c17f2b106df7d32a0139036bdf5d87344ca37e9ce770e0dbeb5e021d03a7d496a6695eb06d3de9258b43f3883ce155767962b52083504b19d6d609090a2f96e9724902bf1adbf57359ac1dda48a8ffe596b8d95cac1429378769a6ec2ff1c8a9c0bc343b0a6468f36696bfb202cde9f6cd5241b814096d777751b44f0cc2ac9e7ba142227e8d5f2dd8da62573953540da1abce82c59287b2f7a87a111851758c2505d8c1ded6c42a49fc5577451ee56126d2275da490baa645c3bcac0c31dabee7aa35e6cdffb56ac0d952c2583c6f50f906dfb96f5a98c49a5919031cff880bffbe371a50162a7bd0fa0398a5898eaf6ad6db868a7d807846a3592325bb4207d67ad96bac76435368962ba8944d0201c2f620fb29373a6f35c815d101af98111e9b4cc61e8ae77fc63ce375068328ec8d05b49486666fb0f756f99d2fe747c95b2a553965f304a324879393897315d310841f0a200cd156f6ca4ed2', 120000) - // check if the logsBloom is being logged (web3 call) - .waitForElementContainsText('*[data-id="terminalJournal"]', '0x0fbbd94c448fe6949f848380a1d145a974f386624b4b10aa40f9afb212b3ddeb', 120000) // hash of 4757766 - // check if the logsBloom is being logged (ethers.js call) - .waitForElementContainsText('*[data-id="terminalJournal"]', '0x9db899cb75888a630ba50a1644c243b83d2eb38525eb828a06a5e8bb5663c0b0', 120000) // hash of 4757767 + .clickLaunchIcon('udapp') + .switchEnvironment('basic-http-provider') + .waitForElementPresent('[data-id="basic-http-provider-modal-footer-ok-react"]') + .execute(() => { + (document.querySelector('*[data-id="basic-http-providerModalDialogContainer-react"] input[data-id="modalDialogCustomPromp"]') as any).focus() + }, [], () => { }) + .setValue('[data-id="modalDialogCustomPromp"]', 'https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9') + .modalFooterOKClick('basic-http-provider') + .clickLaunchIcon('filePanel') + .openFile('README.txt') + .addFile('scripts/log_tx_block.js', { content: scriptBlockAndTransaction }) + .pause(1000) + .executeScriptInTerminal('remix.execute(\'scripts/log_tx_block.js\')') + // check if the input of the transaction is being logged (web3 call) + .waitForElementContainsText('*[data-id="terminalJournal"]', '0x2b0006fa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e9e0000000000000000000000000000000000000000000000000000000000004ea373ded44d6900b8b479935bee9c82176261653e334586e0fd282f569357c0777bd9d084474837ac94bf96f2e26590222a2b8e46545657c7cf06ce2833d267bd6f131b5b3fd36cb1ca3e07cf422224df0766d1a677bbdb7ee4cc0d634efa5367a302a94dac422a16b9b8d5c10fe0555924f8189f6b498bef507b1d32e7915bd4df184f51e6d79ae6a1b11d5745ce7d625cecc3bd0dc50af4f999ffb927225f5e5c019b499f5e1fdcbc70c45df61df76013d1b0d45cdf6a267dac1b4620c0db2efd251f6548509c9c69f5bd9d1ee38ac0df0c73be2774f7d2e1fb7ef5129010f29d091e3c48aed0f035fc29804c99927d33ff2a19ff526979355ac50b2542bc5d8f2d41e4f850d5981e0420807469e828b03173b96b757fbaeacda335e11b3ab8b02a48456fab35d41ca26abde751d5fca8ef5e7ba5295278b6e46ce2aab6c10b3d185a6137d3e5c28bb8dd3a797feaf35520fcb949ea074e1869e0011ef01f8162135e44bb797d3d6215ff74ffbee972c97264fc15d11c840e6a7e796dc1a418572f6dbcc842594a558e1a9e3cb7a159284e16fec758bbc303d13edc28fb6d8bb110c3a398e4ded1748da9854eb84679ad0c99bc59bea7956b521db3ed0a9057510cc11365858704989690f0d891af81b213b1f2e91e41e4998a467656eac87e7025ac2840c17f2b106df7d32a0139036bdf5d87344ca37e9ce770e0dbeb5e021d03a7d496a6695eb06d3de9258b43f3883ce155767962b52083504b19d6d609090a2f96e9724902bf1adbf57359ac1dda48a8ffe596b8d95cac1429378769a6ec2ff1c8a9c0bc343b0a6468f36696bfb202cde9f6cd5241b814096d777751b44f0cc2ac9e7ba142227e8d5f2dd8da62573953540da1abce82c59287b2f7a87a111851758c2505d8c1ded6c42a49fc5577451ee56126d2275da490baa645c3bcac0c31dabee7aa35e6cdffb56ac0d952c2583c6f50f906dfb96f5a98c49a5919031cff880bffbe371a50162a7bd0fa0398a5898eaf6ad6db868a7d807846a3592325bb4207d67ad96bac76435368962ba8944d0201c2f620fb29373a6f35c815d101af98111e9b4cc61e8ae77fc63ce375068328ec8d05b49486666fb0f756f99d2fe747c95b2a553965f304a324879393897315d310841f0a200cd156f6ca4ed2', 120000) + // check if the logsBloom is being logged (web3 call) + .waitForElementContainsText('*[data-id="terminalJournal"]', '0x0fbbd94c448fe6949f848380a1d145a974f386624b4b10aa40f9afb212b3ddeb', 120000) // hash of 4757766 + // check if the logsBloom is being logged (ethers.js call) + .waitForElementContainsText('*[data-id="terminalJournal"]', '0x9db899cb75888a630ba50a1644c243b83d2eb38525eb828a06a5e8bb5663c0b0', 120000) // hash of 4757767 + } }, 'Should listen on all transactions #group8': function (browser: NightwatchBrowser) { @@ -291,47 +297,51 @@ module.exports = { }, 'Should connect to mainnet fork and run web3.eth.getCode in the terminal #group9': function (browser: NightwatchBrowser) { - browser - .clickLaunchIcon('udapp') - .switchEnvironment('vm-mainnet-fork') - .waitForElementPresent({ - locateStrategy: 'css selector', - selector: 'select[data-id="runTabSelectAccount"] option[value="0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]', - timeout: 240000 - }) - .executeScriptInTerminal(`web3.eth.getCode('0x180587b00c8642e2c7ac3a758712d97e6f7bdcc7')`) // mainnet contract - .waitForElementContainsText('*[data-id="terminalJournal"]', '0x608060405260043610601f5760003560e01c80635c60da1b14603157602b565b36602b576029605f565b005b6029605f565b348015603c57600080fd5b5060436097565b6040516001600160a01b03909116815260200160405180910390f35b609560917f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b60d1565b565b600060c97f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b90565b3660008037600080366000845af43d6000803e80801560ef573d6000f35b3d6000fdfea2646970667358221220969dbb4b1d8aec2bb348e26488dc1a33b6bcf0190f567d161312ab7ca9193d8d64736f6c63430008110033', 120000) - .click('*[data-id="terminalClearConsole"]') + if (runMasterTests) { + browser + .clickLaunchIcon('udapp') + .switchEnvironment('vm-mainnet-fork') + .waitForElementPresent({ + locateStrategy: 'css selector', + selector: 'select[data-id="runTabSelectAccount"] option[value="0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]', + timeout: 240000 + }) + .executeScriptInTerminal(`web3.eth.getCode('0x180587b00c8642e2c7ac3a758712d97e6f7bdcc7')`) // mainnet contract + .waitForElementContainsText('*[data-id="terminalJournal"]', '0x608060405260043610601f5760003560e01c80635c60da1b14603157602b565b36602b576029605f565b005b6029605f565b348015603c57600080fd5b5060436097565b6040516001600160a01b03909116815260200160405180910390f35b609560917f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b60d1565b565b600060c97f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b90565b3660008037600080366000845af43d6000803e80801560ef573d6000f35b3d6000fdfea2646970667358221220969dbb4b1d8aec2bb348e26488dc1a33b6bcf0190f567d161312ab7ca9193d8d64736f6c63430008110033', 120000) + .click('*[data-id="terminalClearConsole"]') + } }, 'Should connect to the sepolia fork and run web3.eth.getCode in the terminal #group9': function (browser: NightwatchBrowser) { - browser - .switchEnvironment('vm-custom-fork') - .waitForElementVisible('[data-id="vm-custom-fork-modal-footer-ok-react"]') - .execute(() => { + if (runMasterTests) { + browser + .switchEnvironment('vm-custom-fork') + .waitForElementVisible('[data-id="vm-custom-fork-modal-footer-ok-react"]') + .execute(() => { (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkNodeUrl"]') as any).focus() - }, [], () => { }) - .clearValue('*[data-id="CustomForkNodeUrl"]').pause(1000).setValue('*[data-id="CustomForkNodeUrl"]', 'https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9') - .execute(() => { - (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkBlockNumber"]') as any).focus() - }, [], () => { }) - .clearValue('*[data-id="CustomForkBlockNumber"]').setValue('*[data-id="CustomForkBlockNumber"]', 'latest') - .execute(() => { - (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkEvmType"]') as any).focus() - }, [], () => { }) - .click('*[data-id="CustomForkEvmType"] [value="cancun"]') - .pause(5000) - .modalFooterOKClick('vm-custom-fork') - .waitForElementPresent({ - locateStrategy: 'css selector', - selector: 'select[data-id="runTabSelectAccount"] option[value="0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]', - timeout: 240000 - }) - .pause(5000) - .executeScriptInTerminal(`web3.eth.getCode('0x75F509A4eDA030470272DfBAf99A47D587E76709')`) // sepolia contract - .waitForElementContainsText('*[data-id="terminalJournal"]', byteCodeInSepolia, 120000) - .click('*[data-id="terminalClearConsole"]') - }, + }, [], () => { }) + .clearValue('*[data-id="CustomForkNodeUrl"]').pause(1000).setValue('*[data-id="CustomForkNodeUrl"]', 'https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9') + .execute(() => { + (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkBlockNumber"]') as any).focus() + }, [], () => { }) + .clearValue('*[data-id="CustomForkBlockNumber"]').setValue('*[data-id="CustomForkBlockNumber"]', 'latest') + .execute(() => { + (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkEvmType"]') as any).focus() + }, [], () => { }) + .click('*[data-id="CustomForkEvmType"] [value="cancun"]') + .pause(5000) + .modalFooterOKClick('vm-custom-fork') + .waitForElementPresent({ + locateStrategy: 'css selector', + selector: 'select[data-id="runTabSelectAccount"] option[value="0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]', + timeout: 240000 + }) + .pause(5000) + .executeScriptInTerminal(`web3.eth.getCode('0x75F509A4eDA030470272DfBAf99A47D587E76709')`) // sepolia contract + .waitForElementContainsText('*[data-id="terminalJournal"]', byteCodeInSepolia, 120000) + .click('*[data-id="terminalClearConsole"]') + } + }, 'Should run a free function while being connected to mainnet #group9': function (browser: NightwatchBrowser) { const script = ` @@ -354,31 +364,33 @@ module.exports = { console.log(resolver.addr(node)); } ` - browser - // .clickLaunchIcon('udapp') - .switchEnvironment('vm-mainnet-fork') - .clickLaunchIcon('filePanel') - .addFile('test_mainnet.sol', { content: script }) - - const path = "//*[@class='view-line' and contains(.,'resolveENS') and contains(.,'view')]//span//span[contains(.,'(')]" - const pathRunFunction = `//li//*[@aria-label='Run the free function "resolveENS"']` - browser.waitForElementVisible('#editorView') - //.waitForElementPresent(pathRunFunction) - .pause(10000) // the parser need to parse the code - .useXpath() - .scrollToLine(16) - .click(path) - .perform(function () { - const actions = this.actions({ async: true }); - return actions - .keyDown(this.Keys.SHIFT) - .keyDown(this.Keys.ALT) - .sendKeys('r') - }) - .useCss() - .waitForElementContainsText('*[data-id="terminalJournal"]', '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', 120000) + if (runMasterTests) { + browser + // .clickLaunchIcon('udapp') + .switchEnvironment('vm-mainnet-fork') + .clickLaunchIcon('filePanel') + .addFile('test_mainnet.sol', { content: script }) + + const path = "//*[@class='view-line' and contains(.,'resolveENS') and contains(.,'view')]//span//span[contains(.,'(')]" + const pathRunFunction = `//li//*[@aria-label='Run the free function "resolveENS"']` + browser.waitForElementVisible('#editorView') + //.waitForElementPresent(pathRunFunction) + .pause(10000) // the parser need to parse the code + .useXpath() + .scrollToLine(16) + .click(path) + .perform(function () { + const actions = this.actions({ async: true }); + return actions + .keyDown(this.Keys.SHIFT) + .keyDown(this.Keys.ALT) + .sendKeys('r') + }) + .useCss() + .waitForElementContainsText('*[data-id="terminalJournal"]', '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', 120000) + } }, - + 'Should run free function which logs in the terminal #group10': function (browser: NightwatchBrowser) { const script = `import "hardhat/console.sol"; From faba0eeb1490629f619da75fc6e7eef587e39239 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Fri, 28 Jun 2024 10:00:01 +0200 Subject: [PATCH 13/40] terminal --- apps/remix-ide-e2e/src/tests/terminal.test.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index eb5074e3ca..4275793df4 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -2,6 +2,11 @@ import { NightwatchBrowser } from 'nightwatch' import init from '../helpers/init' + +const branch = process.env.CIRCLE_BRANCH; +const isMasterBranch = branch === 'master'; +const runMasterTests: boolean = (branch ? (isMasterBranch ? true : false) : true) + module.exports = { '@disabled': true, before: function (browser: NightwatchBrowser, done: VoidFunction) { @@ -209,6 +214,7 @@ module.exports = { }, 'Should run a script which log transaction and block using web3.js and ethers #group7': function (browser: NightwatchBrowser) { + if(runMasterTests){ browser .clickLaunchIcon('udapp') .switchEnvironment('basic-http-provider') @@ -229,6 +235,7 @@ module.exports = { .waitForElementContainsText('*[data-id="terminalJournal"]', '0x0fbbd94c448fe6949f848380a1d145a974f386624b4b10aa40f9afb212b3ddeb', 120000) // hash of 4757766 // check if the logsBloom is being logged (ethers.js call) .waitForElementContainsText('*[data-id="terminalJournal"]', '0x9db899cb75888a630ba50a1644c243b83d2eb38525eb828a06a5e8bb5663c0b0', 120000) // hash of 4757767 + } }, 'Should listen on all transactions #group8': function (browser: NightwatchBrowser) { @@ -291,6 +298,7 @@ module.exports = { }, 'Should connect to mainnet fork and run web3.eth.getCode in the terminal #group9': function (browser: NightwatchBrowser) { + if(runMasterTests){ browser .clickLaunchIcon('udapp') .switchEnvironment('vm-mainnet-fork') @@ -302,9 +310,11 @@ module.exports = { .executeScriptInTerminal(`web3.eth.getCode('0x180587b00c8642e2c7ac3a758712d97e6f7bdcc7')`) // mainnet contract .waitForElementContainsText('*[data-id="terminalJournal"]', '0x608060405260043610601f5760003560e01c80635c60da1b14603157602b565b36602b576029605f565b005b6029605f565b348015603c57600080fd5b5060436097565b6040516001600160a01b03909116815260200160405180910390f35b609560917f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b60d1565b565b600060c97f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b90565b3660008037600080366000845af43d6000803e80801560ef573d6000f35b3d6000fdfea2646970667358221220969dbb4b1d8aec2bb348e26488dc1a33b6bcf0190f567d161312ab7ca9193d8d64736f6c63430008110033', 120000) .click('*[data-id="terminalClearConsole"]') + } }, 'Should connect to the sepolia fork and run web3.eth.getCode in the terminal #group9': function (browser: NightwatchBrowser) { + if(runMasterTests){ browser .switchEnvironment('vm-custom-fork') .waitForElementVisible('[data-id="vm-custom-fork-modal-footer-ok-react"]') @@ -331,6 +341,7 @@ module.exports = { .executeScriptInTerminal(`web3.eth.getCode('0x75F509A4eDA030470272DfBAf99A47D587E76709')`) // sepolia contract .waitForElementContainsText('*[data-id="terminalJournal"]', byteCodeInSepolia, 120000) .click('*[data-id="terminalClearConsole"]') + } }, 'Should run a free function while being connected to mainnet #group9': function (browser: NightwatchBrowser) { @@ -354,6 +365,7 @@ module.exports = { console.log(resolver.addr(node)); } ` + if(runMasterTests){ browser // .clickLaunchIcon('udapp') .switchEnvironment('vm-mainnet-fork') @@ -377,6 +389,7 @@ module.exports = { }) .useCss() .waitForElementContainsText('*[data-id="terminalJournal"]', '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', 120000) + } }, 'Should run free function which logs in the terminal #group10': function (browser: NightwatchBrowser) { From cff9d30dc0d795e77a17c819913d2d930983c01b Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Fri, 28 Jun 2024 10:09:20 +0200 Subject: [PATCH 14/40] revert --- apps/remix-ide-e2e/src/tests/terminal.test.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index 4275793df4..eb5074e3ca 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -2,11 +2,6 @@ import { NightwatchBrowser } from 'nightwatch' import init from '../helpers/init' - -const branch = process.env.CIRCLE_BRANCH; -const isMasterBranch = branch === 'master'; -const runMasterTests: boolean = (branch ? (isMasterBranch ? true : false) : true) - module.exports = { '@disabled': true, before: function (browser: NightwatchBrowser, done: VoidFunction) { @@ -214,7 +209,6 @@ module.exports = { }, 'Should run a script which log transaction and block using web3.js and ethers #group7': function (browser: NightwatchBrowser) { - if(runMasterTests){ browser .clickLaunchIcon('udapp') .switchEnvironment('basic-http-provider') @@ -235,7 +229,6 @@ module.exports = { .waitForElementContainsText('*[data-id="terminalJournal"]', '0x0fbbd94c448fe6949f848380a1d145a974f386624b4b10aa40f9afb212b3ddeb', 120000) // hash of 4757766 // check if the logsBloom is being logged (ethers.js call) .waitForElementContainsText('*[data-id="terminalJournal"]', '0x9db899cb75888a630ba50a1644c243b83d2eb38525eb828a06a5e8bb5663c0b0', 120000) // hash of 4757767 - } }, 'Should listen on all transactions #group8': function (browser: NightwatchBrowser) { @@ -298,7 +291,6 @@ module.exports = { }, 'Should connect to mainnet fork and run web3.eth.getCode in the terminal #group9': function (browser: NightwatchBrowser) { - if(runMasterTests){ browser .clickLaunchIcon('udapp') .switchEnvironment('vm-mainnet-fork') @@ -310,11 +302,9 @@ module.exports = { .executeScriptInTerminal(`web3.eth.getCode('0x180587b00c8642e2c7ac3a758712d97e6f7bdcc7')`) // mainnet contract .waitForElementContainsText('*[data-id="terminalJournal"]', '0x608060405260043610601f5760003560e01c80635c60da1b14603157602b565b36602b576029605f565b005b6029605f565b348015603c57600080fd5b5060436097565b6040516001600160a01b03909116815260200160405180910390f35b609560917f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b60d1565b565b600060c97f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b90565b3660008037600080366000845af43d6000803e80801560ef573d6000f35b3d6000fdfea2646970667358221220969dbb4b1d8aec2bb348e26488dc1a33b6bcf0190f567d161312ab7ca9193d8d64736f6c63430008110033', 120000) .click('*[data-id="terminalClearConsole"]') - } }, 'Should connect to the sepolia fork and run web3.eth.getCode in the terminal #group9': function (browser: NightwatchBrowser) { - if(runMasterTests){ browser .switchEnvironment('vm-custom-fork') .waitForElementVisible('[data-id="vm-custom-fork-modal-footer-ok-react"]') @@ -341,7 +331,6 @@ module.exports = { .executeScriptInTerminal(`web3.eth.getCode('0x75F509A4eDA030470272DfBAf99A47D587E76709')`) // sepolia contract .waitForElementContainsText('*[data-id="terminalJournal"]', byteCodeInSepolia, 120000) .click('*[data-id="terminalClearConsole"]') - } }, 'Should run a free function while being connected to mainnet #group9': function (browser: NightwatchBrowser) { @@ -365,7 +354,6 @@ module.exports = { console.log(resolver.addr(node)); } ` - if(runMasterTests){ browser // .clickLaunchIcon('udapp') .switchEnvironment('vm-mainnet-fork') @@ -389,7 +377,6 @@ module.exports = { }) .useCss() .waitForElementContainsText('*[data-id="terminalJournal"]', '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', 120000) - } }, 'Should run free function which logs in the terminal #group10': function (browser: NightwatchBrowser) { From 04d5f1f8725fe5f16a967cbe63989581fe87b1e8 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Fri, 28 Jun 2024 10:10:01 +0200 Subject: [PATCH 15/40] revert --- apps/remix-ide-e2e/src/tests/terminal.test.ts | 161 +++++++++--------- 1 file changed, 79 insertions(+), 82 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index eb5074e3ca..69e4cdc946 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -100,7 +100,7 @@ module.exports = { .switchEnvironment('vm-london') .click('*[data-id="terminalClearConsole"]') // clear the terminal .clickLaunchIcon('filePanel') - .click('*[data-id="treeViewDivMenu"]') // make sure we create the file at the root folder + .click('*[data-id="treeViewUltreeViewMenu"]') // make sure we create the file at the root folder .addFile('deployWithEthersJs.js', { content: deployWithEthersJs }) // .openFile('deployWithEthersJs.js') .pause(1000) @@ -167,7 +167,7 @@ module.exports = { }, 'Should print hardhat logs #group4': function (browser: NightwatchBrowser) { browser - .addFile('printHardhatlog.sol', { content: hardhatLog }) + .addFile('printHardhatlog.sol', { content: hardhatLog }) .clickLaunchIcon('solidity') .click('*[data-id="terminalClearConsole"]') // clear the terminal .waitForElementVisible('[for="autoCompile"]') @@ -266,22 +266,22 @@ module.exports = { if (Array.isArray(result.value) && result.value.length > 0) { console.log('Found ' + result.value.length + ' transactions') browser - .click({ - selector: '[data-id="listenNetworkCheckInput"]', - }) - .click({ - selector: '*[data-id="terminalClearConsole"]', - }) - .click({ - selector: '*[data-id="compilerContainerCompileAndRunBtn"]', - }) - .pause(10000) - .waitForElementNotPresent({ - locateStrategy: 'xpath', - selector: "//*[@class='remix_ui_terminal_log' and contains(.,'to:') and contains(.,'from:')]", - timeout: 120000 - }) - .end() + .click({ + selector: '[data-id="listenNetworkCheckInput"]', + }) + .click({ + selector: '*[data-id="terminalClearConsole"]', + }) + .click({ + selector: '*[data-id="compilerContainerCompileAndRunBtn"]', + }) + .pause(10000) + .waitForElementNotPresent({ + locateStrategy: 'xpath', + selector: "//*[@class='remix_ui_terminal_log' and contains(.,'to:') and contains(.,'from:')]", + timeout: 120000 + }) + .end() } else { browser .assert.fail('No transaction found') @@ -309,7 +309,7 @@ module.exports = { .switchEnvironment('vm-custom-fork') .waitForElementVisible('[data-id="vm-custom-fork-modal-footer-ok-react"]') .execute(() => { - (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkNodeUrl"]') as any).focus() + (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkNodeUrl"]') as any).focus() }, [], () => { }) .clearValue('*[data-id="CustomForkNodeUrl"]').pause(1000).setValue('*[data-id="CustomForkNodeUrl"]', 'https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9') .execute(() => { @@ -331,7 +331,7 @@ module.exports = { .executeScriptInTerminal(`web3.eth.getCode('0x75F509A4eDA030470272DfBAf99A47D587E76709')`) // sepolia contract .waitForElementContainsText('*[data-id="terminalJournal"]', byteCodeInSepolia, 120000) .click('*[data-id="terminalClearConsole"]') - }, + }, 'Should run a free function while being connected to mainnet #group9': function (browser: NightwatchBrowser) { const script = ` @@ -359,10 +359,10 @@ module.exports = { .switchEnvironment('vm-mainnet-fork') .clickLaunchIcon('filePanel') .addFile('test_mainnet.sol', { content: script }) - - const path = "//*[@class='view-line' and contains(.,'resolveENS') and contains(.,'view')]//span//span[contains(.,'(')]" + + const path = "//*[@class='view-line' and contains(.,'resolveENS') and contains(.,'view')]//span//span[contains(.,'(')]" const pathRunFunction = `//li//*[@aria-label='Run the free function "resolveENS"']` - browser.waitForElementVisible('#editorView') + browser.waitForElementVisible('#editorView') //.waitForElementPresent(pathRunFunction) .pause(10000) // the parser need to parse the code .useXpath() @@ -371,25 +371,25 @@ module.exports = { .perform(function () { const actions = this.actions({ async: true }); return actions - .keyDown(this.Keys.SHIFT) - .keyDown(this.Keys.ALT) - .sendKeys('r') + .keyDown(this.Keys.SHIFT) + .keyDown(this.Keys.ALT) + .sendKeys('r') }) .useCss() .waitForElementContainsText('*[data-id="terminalJournal"]', '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', 120000) }, - + 'Should run free function which logs in the terminal #group10': function (browser: NightwatchBrowser) { const script = `import "hardhat/console.sol"; function runSomething () view { console.log("test running free function"); - } + } ` browser .addFile('test.sol', { content: script }) .scrollToLine(3) - const path = "//*[@class='view-line' and contains(.,'runSomething') and contains(.,'view')]//span//span[contains(.,'(')]" + const path = "//*[@class='view-line' and contains(.,'runSomething') and contains(.,'view')]//span//span[contains(.,'(')]" const pathRunFunction = `//li//*[@aria-label='Run the free function "runSomething"']` browser.waitForElementVisible('#editorView') .useXpath() @@ -398,18 +398,15 @@ module.exports = { .perform(function () { const actions = this.actions({ async: true }); return actions - .keyDown(this.Keys.SHIFT) - .keyDown(this.Keys.ALT) - .sendKeys('r') + .keyDown(this.Keys.SHIFT) + .keyDown(this.Keys.ALT) + .sendKeys('r') }) .useCss() .waitForElementContainsText('*[data-id="terminalJournal"]', 'test running free function', 120000) } } - - - const asyncAwait = ` var p = function () { return new Promise(function (resolve, reject) { @@ -417,7 +414,7 @@ const asyncAwait = ` resolve("Promise Resolved") }, 5000) }) - } + } var run = async () => { console.log('Waiting Promise') @@ -455,7 +452,7 @@ const resolveExternalUrlAndSave = ` } catch (e) { console.log(e.message) } -})() +})() ` const resolveExternalUrlAndSaveToaPath = ` @@ -466,7 +463,7 @@ const resolveExternalUrlAndSaveToaPath = ` } catch (e) { console.log(e.message) } -})() +})() ` const resolveUrl = ` @@ -477,7 +474,7 @@ const resolveUrl = ` } catch (e) { console.log(e.message) } -})() +})() ` const deployWithEthersJs = ` @@ -485,32 +482,32 @@ const deployWithEthersJs = ` (async () => { try { console.log('Running deployWithEthers script...') - + const constructorArgs = [] // Put constructor args (if any) here for your contract // Note that the script needs the ABI which is generated from the compilation artifact. // Make sure contract is compiled and artifacts are generated const artifactsPath = 'contracts/artifacts/Owner.json' // Change this for different path - + const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath)) // 'web3Provider' is a remix global variable object const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner() - + let factory = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer) - + let contract = await factory.deploy(...constructorArgs); - + console.log('Contract Address: ', contract.address); - + // The contract is NOT deployed yet; we must wait until it is mined await contract.deployed() console.log('Deployment successful.') - + contract.on('OwnerSet', (previousOwner, newOwner) => { console.log('previousOwner' , previousOwner) console.log('newOwner' , newOwner) }) - + console.log('ok') } catch (e) { console.log(e.message) @@ -577,12 +574,12 @@ contract StorageWithLib { * @dev Store valrue in variable * @param num value to store */ - function store(uint256 num) public { - number = num; + function store(uint256 num) public { + number = num; } /** - * @dev Return value + * @dev Return value * @return value of 'number' */ function retrieve() public view returns (uint256){ @@ -629,11 +626,11 @@ describe("Storage", function () { deployedLinkReferences: metadata.data.deployedBytecode.linkReferences, } const options = { - libraries: { + libraries: { 'Lib': lib.address } } - + const factory = await ethers.getContractFactoryFromArtifact(artifact, options) const storage = await factory.deploy(); await storage.deployed() @@ -657,10 +654,10 @@ import "hardhat/console.sol"; contract OwnerTest { address private owner; - + // event for EVM logging event OwnerSet(address indexed oldOwner, address indexed newOwner); - + // modifier to check if caller is owner modifier isOwner() { // If the first argument of 'require' evaluates to 'false', execution terminates and all @@ -671,7 +668,7 @@ contract OwnerTest { require(msg.sender == owner, "Caller is not owner"); _; } - + /** * @dev Set contract deployer as owner */ @@ -692,7 +689,7 @@ contract OwnerTest { } /** - * @dev Return owner address + * @dev Return owner address * @return address of owner */ function getOwner() external view returns (address) { @@ -705,39 +702,39 @@ const scriptAutoExec = { contract: `// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.8.2 <0.9.0; - + library lib { function test () public view returns (uint) { - + return 147; } } - + /** * @title Storage * @dev Store & retrieve value inr a variable * @custom:dev-run-script ./scripts/deploy_storage.js */ contract Storage { - + uint256 number; - + /** * @dev Store valrue in variable * @param num value to store */ function store(uint256 num) public { - number = num; + number = num; } - + /** - * @dev Return value + * @dev Return value * @return value of 'number' */ function retrieve() public view returns (uint256){ return number; } - + function getFromLib() public view returns (uint) { return lib.test(); } @@ -747,16 +744,16 @@ const scriptAutoExec = { // Right click on the script name and hit "Run" to execute const { expect } = require("chai"); const { ethers } = require("hardhat"); - + (async () => { try { // function getContractFactoryFromArtifact(artifact: Artifact, signer?: ethers.Signer): Promise; - + // function getContractFactoryFromArtifact(artifact: Artifact, factoryOptions: FactoryOptions): Promise; - + const metadataLib = JSON.parse(await remix.call('fileManager', 'readFile', 'contracts/artifacts/lib.json')) console.log('deploying lib:') - + const artifactLib = { contractName: 'Lib', sourceName: 'contracts/1_Storage.sol', @@ -767,15 +764,15 @@ const scriptAutoExec = { deployedLinkReferences: metadataLib.data.deployedBytecode.linkReferences, } const optionsLib = {} - + const factoryLib = await ethers.getContractFactoryFromArtifact(artifactLib, optionsLib) - + const lib = await factoryLib.deploy(); - + await lib.deployed() - + console.log('lib deployed', lib.address) - + const metadata = JSON.parse(await remix.call('fileManager', 'readFile', 'contracts/artifacts/Storage.json')) const artifact = { contractName: 'Storage', @@ -787,25 +784,25 @@ const scriptAutoExec = { deployedLinkReferences: metadata.data.deployedBytecode.linkReferences, } const options = { - libraries: { + libraries: { 'lib': lib.address } } - + const factory = await ethers.getContractFactoryFromArtifact(artifact, options) - + const storage = await factory.deploy(); - + await storage.deployed() - + const storeValue = await storage.store(333); - + // wait until the transaction is mined await storeValue.wait(); - + console.log((await storage.getFromLib()).toString()) // expect((await storage.getFromLib()).toString()).to.equal('34'); - + } catch (e) { console.error(e.message) } From 39f48f6440a5555df4dc160fc99044630fa5ded1 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Fri, 28 Jun 2024 10:11:48 +0200 Subject: [PATCH 16/40] terminal --- apps/remix-ide-e2e/src/tests/terminal.test.ts | 132 ++++++++++-------- 1 file changed, 70 insertions(+), 62 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index 69e4cdc946..9ee515b5af 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -2,6 +2,10 @@ import { NightwatchBrowser } from 'nightwatch' import init from '../helpers/init' +const branch = process.env.CIRCLE_BRANCH; +const isMasterBranch = branch === 'master'; +const runMasterTests: boolean = (branch ? (isMasterBranch ? true : false) : true) + module.exports = { '@disabled': true, before: function (browser: NightwatchBrowser, done: VoidFunction) { @@ -209,26 +213,27 @@ module.exports = { }, 'Should run a script which log transaction and block using web3.js and ethers #group7': function (browser: NightwatchBrowser) { - browser - .clickLaunchIcon('udapp') - .switchEnvironment('basic-http-provider') - .waitForElementPresent('[data-id="basic-http-provider-modal-footer-ok-react"]') - .execute(() => { - (document.querySelector('*[data-id="basic-http-providerModalDialogContainer-react"] input[data-id="modalDialogCustomPromp"]') as any).focus() - }, [], () => { }) - .setValue('[data-id="modalDialogCustomPromp"]', 'https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9') - .modalFooterOKClick('basic-http-provider') - .clickLaunchIcon('filePanel') - .openFile('README.txt') - .addFile('scripts/log_tx_block.js', { content: scriptBlockAndTransaction }) - .pause(1000) - .executeScriptInTerminal('remix.execute(\'scripts/log_tx_block.js\')') - // check if the input of the transaction is being logged (web3 call) - .waitForElementContainsText('*[data-id="terminalJournal"]', '0x2b0006fa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e9e0000000000000000000000000000000000000000000000000000000000004ea373ded44d6900b8b479935bee9c82176261653e334586e0fd282f569357c0777bd9d084474837ac94bf96f2e26590222a2b8e46545657c7cf06ce2833d267bd6f131b5b3fd36cb1ca3e07cf422224df0766d1a677bbdb7ee4cc0d634efa5367a302a94dac422a16b9b8d5c10fe0555924f8189f6b498bef507b1d32e7915bd4df184f51e6d79ae6a1b11d5745ce7d625cecc3bd0dc50af4f999ffb927225f5e5c019b499f5e1fdcbc70c45df61df76013d1b0d45cdf6a267dac1b4620c0db2efd251f6548509c9c69f5bd9d1ee38ac0df0c73be2774f7d2e1fb7ef5129010f29d091e3c48aed0f035fc29804c99927d33ff2a19ff526979355ac50b2542bc5d8f2d41e4f850d5981e0420807469e828b03173b96b757fbaeacda335e11b3ab8b02a48456fab35d41ca26abde751d5fca8ef5e7ba5295278b6e46ce2aab6c10b3d185a6137d3e5c28bb8dd3a797feaf35520fcb949ea074e1869e0011ef01f8162135e44bb797d3d6215ff74ffbee972c97264fc15d11c840e6a7e796dc1a418572f6dbcc842594a558e1a9e3cb7a159284e16fec758bbc303d13edc28fb6d8bb110c3a398e4ded1748da9854eb84679ad0c99bc59bea7956b521db3ed0a9057510cc11365858704989690f0d891af81b213b1f2e91e41e4998a467656eac87e7025ac2840c17f2b106df7d32a0139036bdf5d87344ca37e9ce770e0dbeb5e021d03a7d496a6695eb06d3de9258b43f3883ce155767962b52083504b19d6d609090a2f96e9724902bf1adbf57359ac1dda48a8ffe596b8d95cac1429378769a6ec2ff1c8a9c0bc343b0a6468f36696bfb202cde9f6cd5241b814096d777751b44f0cc2ac9e7ba142227e8d5f2dd8da62573953540da1abce82c59287b2f7a87a111851758c2505d8c1ded6c42a49fc5577451ee56126d2275da490baa645c3bcac0c31dabee7aa35e6cdffb56ac0d952c2583c6f50f906dfb96f5a98c49a5919031cff880bffbe371a50162a7bd0fa0398a5898eaf6ad6db868a7d807846a3592325bb4207d67ad96bac76435368962ba8944d0201c2f620fb29373a6f35c815d101af98111e9b4cc61e8ae77fc63ce375068328ec8d05b49486666fb0f756f99d2fe747c95b2a553965f304a324879393897315d310841f0a200cd156f6ca4ed2', 120000) - // check if the logsBloom is being logged (web3 call) - .waitForElementContainsText('*[data-id="terminalJournal"]', '0x0fbbd94c448fe6949f848380a1d145a974f386624b4b10aa40f9afb212b3ddeb', 120000) // hash of 4757766 - // check if the logsBloom is being logged (ethers.js call) - .waitForElementContainsText('*[data-id="terminalJournal"]', '0x9db899cb75888a630ba50a1644c243b83d2eb38525eb828a06a5e8bb5663c0b0', 120000) // hash of 4757767 + if (runMasterTests) + browser + .clickLaunchIcon('udapp') + .switchEnvironment('basic-http-provider') + .waitForElementPresent('[data-id="basic-http-provider-modal-footer-ok-react"]') + .execute(() => { + (document.querySelector('*[data-id="basic-http-providerModalDialogContainer-react"] input[data-id="modalDialogCustomPromp"]') as any).focus() + }, [], () => { }) + .setValue('[data-id="modalDialogCustomPromp"]', 'https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9') + .modalFooterOKClick('basic-http-provider') + .clickLaunchIcon('filePanel') + .openFile('README.txt') + .addFile('scripts/log_tx_block.js', { content: scriptBlockAndTransaction }) + .pause(1000) + .executeScriptInTerminal('remix.execute(\'scripts/log_tx_block.js\')') + // check if the input of the transaction is being logged (web3 call) + .waitForElementContainsText('*[data-id="terminalJournal"]', '0x2b0006fa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e9e0000000000000000000000000000000000000000000000000000000000004ea373ded44d6900b8b479935bee9c82176261653e334586e0fd282f569357c0777bd9d084474837ac94bf96f2e26590222a2b8e46545657c7cf06ce2833d267bd6f131b5b3fd36cb1ca3e07cf422224df0766d1a677bbdb7ee4cc0d634efa5367a302a94dac422a16b9b8d5c10fe0555924f8189f6b498bef507b1d32e7915bd4df184f51e6d79ae6a1b11d5745ce7d625cecc3bd0dc50af4f999ffb927225f5e5c019b499f5e1fdcbc70c45df61df76013d1b0d45cdf6a267dac1b4620c0db2efd251f6548509c9c69f5bd9d1ee38ac0df0c73be2774f7d2e1fb7ef5129010f29d091e3c48aed0f035fc29804c99927d33ff2a19ff526979355ac50b2542bc5d8f2d41e4f850d5981e0420807469e828b03173b96b757fbaeacda335e11b3ab8b02a48456fab35d41ca26abde751d5fca8ef5e7ba5295278b6e46ce2aab6c10b3d185a6137d3e5c28bb8dd3a797feaf35520fcb949ea074e1869e0011ef01f8162135e44bb797d3d6215ff74ffbee972c97264fc15d11c840e6a7e796dc1a418572f6dbcc842594a558e1a9e3cb7a159284e16fec758bbc303d13edc28fb6d8bb110c3a398e4ded1748da9854eb84679ad0c99bc59bea7956b521db3ed0a9057510cc11365858704989690f0d891af81b213b1f2e91e41e4998a467656eac87e7025ac2840c17f2b106df7d32a0139036bdf5d87344ca37e9ce770e0dbeb5e021d03a7d496a6695eb06d3de9258b43f3883ce155767962b52083504b19d6d609090a2f96e9724902bf1adbf57359ac1dda48a8ffe596b8d95cac1429378769a6ec2ff1c8a9c0bc343b0a6468f36696bfb202cde9f6cd5241b814096d777751b44f0cc2ac9e7ba142227e8d5f2dd8da62573953540da1abce82c59287b2f7a87a111851758c2505d8c1ded6c42a49fc5577451ee56126d2275da490baa645c3bcac0c31dabee7aa35e6cdffb56ac0d952c2583c6f50f906dfb96f5a98c49a5919031cff880bffbe371a50162a7bd0fa0398a5898eaf6ad6db868a7d807846a3592325bb4207d67ad96bac76435368962ba8944d0201c2f620fb29373a6f35c815d101af98111e9b4cc61e8ae77fc63ce375068328ec8d05b49486666fb0f756f99d2fe747c95b2a553965f304a324879393897315d310841f0a200cd156f6ca4ed2', 120000) + // check if the logsBloom is being logged (web3 call) + .waitForElementContainsText('*[data-id="terminalJournal"]', '0x0fbbd94c448fe6949f848380a1d145a974f386624b4b10aa40f9afb212b3ddeb', 120000) // hash of 4757766 + // check if the logsBloom is being logged (ethers.js call) + .waitForElementContainsText('*[data-id="terminalJournal"]', '0x9db899cb75888a630ba50a1644c243b83d2eb38525eb828a06a5e8bb5663c0b0', 120000) // hash of 4757767 }, 'Should listen on all transactions #group8': function (browser: NightwatchBrowser) { @@ -291,46 +296,48 @@ module.exports = { }, 'Should connect to mainnet fork and run web3.eth.getCode in the terminal #group9': function (browser: NightwatchBrowser) { - browser - .clickLaunchIcon('udapp') - .switchEnvironment('vm-mainnet-fork') - .waitForElementPresent({ - locateStrategy: 'css selector', - selector: 'select[data-id="runTabSelectAccount"] option[value="0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]', - timeout: 240000 - }) - .executeScriptInTerminal(`web3.eth.getCode('0x180587b00c8642e2c7ac3a758712d97e6f7bdcc7')`) // mainnet contract - .waitForElementContainsText('*[data-id="terminalJournal"]', '0x608060405260043610601f5760003560e01c80635c60da1b14603157602b565b36602b576029605f565b005b6029605f565b348015603c57600080fd5b5060436097565b6040516001600160a01b03909116815260200160405180910390f35b609560917f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b60d1565b565b600060c97f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b90565b3660008037600080366000845af43d6000803e80801560ef573d6000f35b3d6000fdfea2646970667358221220969dbb4b1d8aec2bb348e26488dc1a33b6bcf0190f567d161312ab7ca9193d8d64736f6c63430008110033', 120000) - .click('*[data-id="terminalClearConsole"]') + if (runMasterTests) + browser + .clickLaunchIcon('udapp') + .switchEnvironment('vm-mainnet-fork') + .waitForElementPresent({ + locateStrategy: 'css selector', + selector: 'select[data-id="runTabSelectAccount"] option[value="0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]', + timeout: 240000 + }) + .executeScriptInTerminal(`web3.eth.getCode('0x180587b00c8642e2c7ac3a758712d97e6f7bdcc7')`) // mainnet contract + .waitForElementContainsText('*[data-id="terminalJournal"]', '0x608060405260043610601f5760003560e01c80635c60da1b14603157602b565b36602b576029605f565b005b6029605f565b348015603c57600080fd5b5060436097565b6040516001600160a01b03909116815260200160405180910390f35b609560917f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b60d1565b565b600060c97f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b90565b3660008037600080366000845af43d6000803e80801560ef573d6000f35b3d6000fdfea2646970667358221220969dbb4b1d8aec2bb348e26488dc1a33b6bcf0190f567d161312ab7ca9193d8d64736f6c63430008110033', 120000) + .click('*[data-id="terminalClearConsole"]') }, 'Should connect to the sepolia fork and run web3.eth.getCode in the terminal #group9': function (browser: NightwatchBrowser) { - browser - .switchEnvironment('vm-custom-fork') - .waitForElementVisible('[data-id="vm-custom-fork-modal-footer-ok-react"]') - .execute(() => { - (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkNodeUrl"]') as any).focus() - }, [], () => { }) - .clearValue('*[data-id="CustomForkNodeUrl"]').pause(1000).setValue('*[data-id="CustomForkNodeUrl"]', 'https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9') - .execute(() => { - (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkBlockNumber"]') as any).focus() - }, [], () => { }) - .clearValue('*[data-id="CustomForkBlockNumber"]').setValue('*[data-id="CustomForkBlockNumber"]', 'latest') - .execute(() => { - (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkEvmType"]') as any).focus() - }, [], () => { }) - .click('*[data-id="CustomForkEvmType"] [value="cancun"]') - .pause(5000) - .modalFooterOKClick('vm-custom-fork') - .waitForElementPresent({ - locateStrategy: 'css selector', - selector: 'select[data-id="runTabSelectAccount"] option[value="0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]', - timeout: 240000 - }) - .pause(5000) - .executeScriptInTerminal(`web3.eth.getCode('0x75F509A4eDA030470272DfBAf99A47D587E76709')`) // sepolia contract - .waitForElementContainsText('*[data-id="terminalJournal"]', byteCodeInSepolia, 120000) - .click('*[data-id="terminalClearConsole"]') + if (runMasterTests) + browser + .switchEnvironment('vm-custom-fork') + .waitForElementVisible('[data-id="vm-custom-fork-modal-footer-ok-react"]') + .execute(() => { + (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkNodeUrl"]') as any).focus() + }, [], () => { }) + .clearValue('*[data-id="CustomForkNodeUrl"]').pause(1000).setValue('*[data-id="CustomForkNodeUrl"]', 'https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9') + .execute(() => { + (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkBlockNumber"]') as any).focus() + }, [], () => { }) + .clearValue('*[data-id="CustomForkBlockNumber"]').setValue('*[data-id="CustomForkBlockNumber"]', 'latest') + .execute(() => { + (document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkEvmType"]') as any).focus() + }, [], () => { }) + .click('*[data-id="CustomForkEvmType"] [value="cancun"]') + .pause(5000) + .modalFooterOKClick('vm-custom-fork') + .waitForElementPresent({ + locateStrategy: 'css selector', + selector: 'select[data-id="runTabSelectAccount"] option[value="0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]', + timeout: 240000 + }) + .pause(5000) + .executeScriptInTerminal(`web3.eth.getCode('0x75F509A4eDA030470272DfBAf99A47D587E76709')`) // sepolia contract + .waitForElementContainsText('*[data-id="terminalJournal"]', byteCodeInSepolia, 120000) + .click('*[data-id="terminalClearConsole"]') }, 'Should run a free function while being connected to mainnet #group9': function (browser: NightwatchBrowser) { @@ -354,11 +361,12 @@ module.exports = { console.log(resolver.addr(node)); } ` - browser - // .clickLaunchIcon('udapp') - .switchEnvironment('vm-mainnet-fork') - .clickLaunchIcon('filePanel') - .addFile('test_mainnet.sol', { content: script }) + if (runMasterTests) + browser + // .clickLaunchIcon('udapp') + .switchEnvironment('vm-mainnet-fork') + .clickLaunchIcon('filePanel') + .addFile('test_mainnet.sol', { content: script }) const path = "//*[@class='view-line' and contains(.,'resolveENS') and contains(.,'view')]//span//span[contains(.,'(')]" const pathRunFunction = `//li//*[@aria-label='Run the free function "resolveENS"']` From 808d92e9b95f2060d1c3fa8927d1c46f718e6a21 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Fri, 28 Jun 2024 10:13:05 +0200 Subject: [PATCH 17/40] wrap --- apps/remix-ide-e2e/src/tests/terminal.test.ts | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/terminal.test.ts b/apps/remix-ide-e2e/src/tests/terminal.test.ts index 9ee515b5af..e1335c856d 100644 --- a/apps/remix-ide-e2e/src/tests/terminal.test.ts +++ b/apps/remix-ide-e2e/src/tests/terminal.test.ts @@ -361,30 +361,31 @@ module.exports = { console.log(resolver.addr(node)); } ` - if (runMasterTests) + if (runMasterTests) { browser // .clickLaunchIcon('udapp') .switchEnvironment('vm-mainnet-fork') .clickLaunchIcon('filePanel') .addFile('test_mainnet.sol', { content: script }) - const path = "//*[@class='view-line' and contains(.,'resolveENS') and contains(.,'view')]//span//span[contains(.,'(')]" - const pathRunFunction = `//li//*[@aria-label='Run the free function "resolveENS"']` - browser.waitForElementVisible('#editorView') - //.waitForElementPresent(pathRunFunction) - .pause(10000) // the parser need to parse the code - .useXpath() - .scrollToLine(16) - .click(path) - .perform(function () { - const actions = this.actions({ async: true }); - return actions - .keyDown(this.Keys.SHIFT) - .keyDown(this.Keys.ALT) - .sendKeys('r') - }) - .useCss() - .waitForElementContainsText('*[data-id="terminalJournal"]', '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', 120000) + const path = "//*[@class='view-line' and contains(.,'resolveENS') and contains(.,'view')]//span//span[contains(.,'(')]" + const pathRunFunction = `//li//*[@aria-label='Run the free function "resolveENS"']` + browser.waitForElementVisible('#editorView') + //.waitForElementPresent(pathRunFunction) + .pause(10000) // the parser need to parse the code + .useXpath() + .scrollToLine(16) + .click(path) + .perform(function () { + const actions = this.actions({ async: true }); + return actions + .keyDown(this.Keys.SHIFT) + .keyDown(this.Keys.ALT) + .sendKeys('r') + }) + .useCss() + .waitForElementContainsText('*[data-id="terminalJournal"]', '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', 120000) + } }, 'Should run free function which logs in the terminal #group10': function (browser: NightwatchBrowser) { From fbf1ef4491879b73ef43c7cb86d92fab788a966c Mon Sep 17 00:00:00 2001 From: lianahus Date: Thu, 27 Jun 2024 14:29:28 +0200 Subject: [PATCH 18/40] layout update for FE bottom --- .../src/app/tabs/locales/en/filePanel.json | 3 +- .../workspace/src/lib/remix-ui-workspace.tsx | 34 +++++++++++++------ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json index 8159675a7e..9804377ea9 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json +++ b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json @@ -141,5 +141,6 @@ "filePanel.movingFolderFailed": "Moving Folder Failed", "filePanel.movingFolderFailedMsg": "Unexpected error while moving folder: {src}", "filePanel.workspaceActions": "Workspace actions", - "filePanel.saveCodeSample": "This code-sample workspace will not be persisted. Click here to save it." + "filePanel.saveCodeSample": "This code-sample workspace will not be persisted. Click here to save it.", + "filePanel.updateSubmodules": "Update all submodules." } diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 3da9063576..450df30360 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -1343,22 +1343,34 @@ export function Workspace() { - {selectedWorkspace && ( + { selectedWorkspace && (
    -
    -
    GIT
    - {selectedWorkspace.hasGitSubmodules? -
    - {global.fs.browser.isRequestingCloning ?
    updating submodules
    : -
    update submodules
    } -
    +
    +
    GIT
    + { selectedWorkspace.hasGitSubmodules? + } + > +
    + {global.fs.browser.isRequestingCloning ? : + } +
    +
    : null} -
    - +
    + {global.fs.browser.isRequestingCloning ? : currentBranch || '-none-'} From 836b6ddd2dda56faae8c5336838511c3aa088541 Mon Sep 17 00:00:00 2001 From: lianahus Date: Thu, 27 Jun 2024 14:32:05 +0200 Subject: [PATCH 19/40] tooltip[ update --- apps/remix-ide/src/app/tabs/locales/en/filePanel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json index 9804377ea9..158f3772b2 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json +++ b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json @@ -142,5 +142,5 @@ "filePanel.movingFolderFailedMsg": "Unexpected error while moving folder: {src}", "filePanel.workspaceActions": "Workspace actions", "filePanel.saveCodeSample": "This code-sample workspace will not be persisted. Click here to save it.", - "filePanel.updateSubmodules": "Update all submodules." + "filePanel.updateSubmodules": "Update all submodules of repository. Click to pull dependencies." } From 364df8b14cd8f68d5e654fc58a0fe1d57ee0a83b Mon Sep 17 00:00:00 2001 From: lianahus Date: Thu, 27 Jun 2024 17:45:44 +0200 Subject: [PATCH 20/40] ttoltips and internal element layout fix for FE bottom menu --- .../src/lib/components/custom-dropdown.tsx | 2 +- .../src/lib/components/homeTabFeatured.tsx | 2 +- .../src/lib/css/remix-ui-workspace.css | 4 + .../workspace/src/lib/remix-ui-workspace.tsx | 175 +++++++++--------- 4 files changed, 97 insertions(+), 86 deletions(-) diff --git a/libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx b/libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx index f429cd0d04..14c7838a89 100644 --- a/libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx +++ b/libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx @@ -29,7 +29,7 @@ export const CustomToggle = React.forwardRef( className={className.replace('dropdown-toggle', '')} >
    -
    {children}
    +
    {children}
    {icon && (
    diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx index bc5fb49f62..7f1eb98d59 100644 --- a/libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx +++ b/libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx @@ -12,7 +12,7 @@ function HomeTabFeatured() { const themeFilter = useContext(ThemeContext) return ( -
    +
    diff --git a/libs/remix-ui/workspace/src/lib/css/remix-ui-workspace.css b/libs/remix-ui/workspace/src/lib/css/remix-ui-workspace.css index 24c7d462c6..7d8aa0c276 100644 --- a/libs/remix-ui/workspace/src/lib/css/remix-ui-workspace.css +++ b/libs/remix-ui/workspace/src/lib/css/remix-ui-workspace.css @@ -77,6 +77,10 @@ background: var(--custom-select); } + .branches-dropdown { + max-width: 16rem; + } + .custom-dropdown-items a { border-radius: .25rem; text-transform: none; diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 450df30360..6099599695 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -1364,93 +1364,100 @@ export function Workspace() { }
    - : null} -
    - - - {global.fs.browser.isRequestingCloning ? : currentBranch || '-none-'} - - - -
    -
    - - - -
    { - toggleBranches(false) - }} - > - + : null + } + +
    + + + {global.fs.browser.isRequestingCloning ? : currentBranch || '-none-'} + + +
    +
    + + + +
    { + toggleBranches(false) + }} + > + +
    -
    -
    - -
    -
    - {filteredBranches.length > 0 ? ( - filteredBranches.map((branch, index) => { - return ( - { - switchToBranch(branch) - }} - title={intl.formatMessage({ id: `filePanel.switchToBranch${branch.remote ? 'Title1' : 'Title2'}` })} - > -
    - {currentBranch === branch.name && !branch.remote ? ( - - ✓ - {branch.name} - - ) : ( - - - {branch.remote ? `${branch.remote}/${branch.name}` : branch.name} - - )} -
    -
    - ) - }) - ) : ( - -
    - - - : {branchFilter} from '{currentBranch}' - -
    -
    +
    + +
    +
    + {filteredBranches.length > 0 ? ( + filteredBranches.map((branch, index) => { + return ( + { + switchToBranch(branch) + }} + title={intl.formatMessage({ id: `filePanel.switchToBranch${branch.remote ? 'Title1' : 'Title2'}` })} + > +
    + {currentBranch === branch.name && !branch.remote ? ( + + ✓ + {branch.name} + + ) : ( + + + {branch.remote ? `${branch.remote}/${branch.name}` : branch.name} + + )} +
    +
    + ) + }) + ) : ( + +
    + + + : {branchFilter} from '{currentBranch}' + +
    +
    + )} +
    + {(selectedWorkspace.branches || []).length > 4 && ( +
    + +
    )}
    - {(selectedWorkspace.branches || []).length > 4 && ( -
    - -
    - )} -
    - - -
    + + +
    +
    )} From ebdd1e7d27e6828a067d72d38291040e1061bafb Mon Sep 17 00:00:00 2001 From: lianahus Date: Fri, 28 Jun 2024 11:54:56 +0200 Subject: [PATCH 21/40] fixed spinner --- .../workspace/src/lib/remix-ui-workspace.tsx | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 6099599695..6540eb1e09 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -1355,11 +1355,11 @@ export function Workspace() { tooltipText={} >
    - {global.fs.browser.isRequestingCloning ? : - }
    @@ -1367,17 +1367,17 @@ export function Workspace() { : null }
    - + {global.fs.browser.isRequestingCloning ? : currentBranch || '-none-'} @@ -1447,11 +1447,9 @@ export function Workspace() { )}
    {(selectedWorkspace.branches || []).length > 4 && ( -
    - -
    + )}
    From 8833c01eb0b8b59ea13b5228d84a708d5e9becc6 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Fri, 28 Jun 2024 16:29:36 +0530 Subject: [PATCH 22/40] fix linting --- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 6540eb1e09..005ae1d821 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -1355,13 +1355,13 @@ export function Workspace() { tooltipText={} >
    - { global.fs.browser.isRequestingCloning ? : - : + } + }
    : null From 115eff8d23d60a642aae47c83684a2058fb9c722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Tetsing?= Date: Wed, 26 Jun 2024 15:16:17 +0200 Subject: [PATCH 23/40] added matomo events for accepted completions --- .../lib/providers/inlineCompletionProvider.ts | 19 ++++++++++++----- .../editor/src/lib/remix-ui-editor.tsx | 21 ++++++++++++++++++- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts index ce274d57b5..57ed6b09a4 100644 --- a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts +++ b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts @@ -4,6 +4,7 @@ import { CompletionTimer } from './completionTimer'; import axios, { AxiosResponse } from 'axios' import { slice } from 'lodash'; +import { activateService } from '@remixproject/plugin-utils'; const _paq = (window._paq = window._paq || []) const controller = new AbortController(); @@ -14,6 +15,9 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli props: EditorUIProps monaco: any completionEnabled: boolean + task: string + currentCompletion + constructor(props: any, monaco: any) { this.props = props this.monaco = monaco @@ -28,6 +32,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli const lineRange = model.getFullModelRange().setStartPosition(lineNumber, 1).setEndPosition(lineNumber + 1, 1); return model.getValueInRange(lineRange); } + // get text before the position of the completion const word = model.getValueInRange({ startLineNumber: 1, @@ -65,6 +70,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli // use the code generation model, only take max 1000 word as context this.props.plugin.call('terminal', 'log', { type: 'aitypewriterwarning', value: 'Solcoder - generating code for following comment: ' + ask.replace('///', '') }) + this.task = 'code_generation' const data = await this.props.plugin.call('solcoder', 'code_generation', word) const parsedData = data[0].trimStart() //JSON.parse(data).trimStart() @@ -103,15 +109,16 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli if (word.replace(/ +$/, '').endsWith('\n')){ // Code insertion try { + this.task = 'code_insertion' const output = await this.props.plugin.call('solcoder', 'code_insertion', word, word_after) const generatedText = output[0] // no need to clean it. should already be - + console.log('generatedText', generatedText) const item: monacoTypes.languages.InlineCompletion = { insertText: generatedText }; this.completionEnabled = false - const handleCompletionTimer = new CompletionTimer(5000, () => { this.completionEnabled = true }); + const handleCompletionTimer = new CompletionTimer(1000, () => { this.completionEnabled = true }); handleCompletionTimer.start() return { @@ -127,6 +134,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli let result try { // Code completion + this.task = 'code_completion' const output = await this.props.plugin.call('solcoder', 'code_completion', word) const generatedText = output[0] let clean = generatedText @@ -168,14 +176,15 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli } handleItemDidShow?(completions: monacoTypes.languages.InlineCompletions, item: monacoTypes.languages.InlineCompletion, updatedInsertText: string): void { - + this.currentCompletion = { 'item':item, 'task':this.task } + _paq.push(['trackEvent', 'ai', 'solcoder', this.task + '_did_show']) } handlePartialAccept?(completions: monacoTypes.languages.InlineCompletions, item: monacoTypes.languages.InlineCompletion, acceptedCharacters: number): void { - + _paq.push(['trackEvent', 'ai', 'solcoder', this.task + '_partial_accept']) } freeInlineCompletions(completions: monacoTypes.languages.InlineCompletions): void { - } + groupId?: string; yieldsToGroupIds?: string[]; toString?(): string { diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx index 7805223b87..c3e7e1cd88 100644 --- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx +++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx @@ -354,6 +354,8 @@ export const EditorUI = (props: EditorUIProps) => { } }, [props.currentFile]) + const inlineCompletionProvider = new RemixInLineCompletionProvider(props, monacoRef.current) + const convertToMonacoDecoration = (decoration: lineText | sourceAnnotation | sourceMarker, typeOfDecoration: string) => { if (typeOfDecoration === 'sourceAnnotationsPerFile') { decoration = decoration as sourceAnnotation @@ -618,6 +620,12 @@ export const EditorUI = (props: EditorUIProps) => { } } + function handleAcceptedCompletion(completion, type: 'full' | 'partial') { + // Handle the accepted completion here + // For example, you might want to send analytics, update UI, etc. + console.log(`Handling ${type} completion:`, completion); + } + function handleEditorDidMount(editor) { editorRef.current = editor defineAndSetTheme(monacoRef.current) @@ -674,6 +682,17 @@ export const EditorUI = (props: EditorUIProps) => { } }) + editor.onDidChangeModelContent((e) => { + if (inlineCompletionProvider.currentCompletion) { + const changes = e.changes; + // Check if the change matches the current completion + if (changes.some(change => change.text === inlineCompletionProvider.currentCompletion.item.insertText)) { + _paq.push(['trackEvent', 'ai', 'solcoder', inlineCompletionProvider.currentCompletion.task + '_accepted']) + inlineCompletionProvider.currentCompletion = null; + } + } + }); + // add context menu items const zoominAction = { id: 'zoomIn', @@ -977,7 +996,7 @@ export const EditorUI = (props: EditorUIProps) => { monacoRef.current.languages.registerReferenceProvider('remix-solidity', new RemixReferenceProvider(props, monaco)) monacoRef.current.languages.registerHoverProvider('remix-solidity', new RemixHoverProvider(props, monaco)) monacoRef.current.languages.registerCompletionItemProvider('remix-solidity', new RemixCompletionProvider(props, monaco)) - monacoRef.current.languages.registerInlineCompletionsProvider('remix-solidity', new RemixInLineCompletionProvider(props, monaco)) + monacoRef.current.languages.registerInlineCompletionsProvider('remix-solidity', inlineCompletionProvider) monaco.languages.registerCodeActionProvider('remix-solidity', new RemixCodeActionProvider(props, monaco)) loadTypes(monacoRef.current) From 59f6ec6467a873097afa09ac31ffe4e14e404257 Mon Sep 17 00:00:00 2001 From: STetsing <41009393+STetsing@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:11:29 +0200 Subject: [PATCH 24/40] rm console log inlineCompletionProvider.ts --- .../editor/src/lib/providers/inlineCompletionProvider.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts index 57ed6b09a4..6c0b67e705 100644 --- a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts +++ b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts @@ -112,7 +112,6 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli this.task = 'code_insertion' const output = await this.props.plugin.call('solcoder', 'code_insertion', word, word_after) const generatedText = output[0] // no need to clean it. should already be - console.log('generatedText', generatedText) const item: monacoTypes.languages.InlineCompletion = { insertText: generatedText }; From 84b74b68ded79440811e0d4b1602ad54c3b2e08a Mon Sep 17 00:00:00 2001 From: STetsing <41009393+STetsing@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:13:45 +0200 Subject: [PATCH 25/40] Update remix-ui-editor.tsx rm handleAcceptedCompletion --- libs/remix-ui/editor/src/lib/remix-ui-editor.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx index c3e7e1cd88..f01b6e8b7e 100644 --- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx +++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx @@ -620,12 +620,6 @@ export const EditorUI = (props: EditorUIProps) => { } } - function handleAcceptedCompletion(completion, type: 'full' | 'partial') { - // Handle the accepted completion here - // For example, you might want to send analytics, update UI, etc. - console.log(`Handling ${type} completion:`, completion); - } - function handleEditorDidMount(editor) { editorRef.current = editor defineAndSetTheme(monacoRef.current) From d76cc67cdbc3821a3e352d06b1e78630fa333e44 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Fri, 28 Jun 2024 17:53:16 +0530 Subject: [PATCH 26/40] increase timeout --- .../remix-ide-e2e/src/tests/runAndDeploy_injected.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide-e2e/src/tests/runAndDeploy_injected.test.ts b/apps/remix-ide-e2e/src/tests/runAndDeploy_injected.test.ts index 331dec221d..20a252a729 100644 --- a/apps/remix-ide-e2e/src/tests/runAndDeploy_injected.test.ts +++ b/apps/remix-ide-e2e/src/tests/runAndDeploy_injected.test.ts @@ -50,10 +50,10 @@ const tests = { .pause(5000) .switchBrowserWindow(extension_url, 'MetaMask', (browser) => { browser - .waitForElementVisible('*[data-testid="page-container-footer-next"]') + .waitForElementVisible('*[data-testid="page-container-footer-next"]', 60000) .click('*[data-testid="page-container-footer-next"]') // this connects the metamask account to remix .pause(2000) - .waitForElementVisible('*[data-testid="page-container-footer-next"]') + .waitForElementVisible('*[data-testid="page-container-footer-next"]', 60000) .click('*[data-testid="page-container-footer-next"]') // .waitForElementVisible('*[data-testid="popover-close"]') // .click('*[data-testid="popover-close"]') @@ -162,7 +162,7 @@ const tests = { .perform((done) => { browser.switchBrowserWindow(extension_url, 'MetaMask', (browser) => { browser - .waitForElementPresent('[data-testid="page-container-footer-next"]') + .waitForElementPresent('[data-testid="page-container-footer-next"]', 60000) .click('[data-testid="page-container-footer-next"]') // approve the tx .switchBrowserTab(0) // back to remix .waitForElementContainsText('*[data-id="terminalJournal"]', 'view on etherscan', 60000) @@ -177,7 +177,7 @@ const tests = { .perform((done) => { // call delegate browser.switchBrowserWindow(extension_url, 'MetaMask', (browser) => { browser - .waitForElementPresent('[data-testid="page-container-footer-next"]') + .waitForElementPresent('[data-testid="page-container-footer-next"]', 60000) .click('[data-testid="page-container-footer-next"]') // approve the tx .switchBrowserTab(0) // back to remix .waitForElementContainsText('*[data-id="terminalJournal"]', 'view on etherscan', 60000) From 60246c664f12832218e5790adcf08116db2e3bcc Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Fri, 28 Jun 2024 18:57:05 +0530 Subject: [PATCH 27/40] publish libs for v0.51.0 --- libs/ghaction-helper/package.json | 8 ++++---- libs/remix-analyzer/package.json | 8 ++++---- libs/remix-astwalker/package.json | 6 +++--- libs/remix-debug/package.json | 12 ++++++------ libs/remix-lib/package.json | 4 ++-- libs/remix-simulator/package.json | 6 +++--- libs/remix-solidity/package.json | 6 +++--- libs/remix-tests/package.json | 10 +++++----- libs/remix-url-resolver/package.json | 4 ++-- libs/remix-ws-templates/package.json | 4 ++-- libs/remixd/package.json | 4 ++-- 11 files changed, 36 insertions(+), 36 deletions(-) diff --git a/libs/ghaction-helper/package.json b/libs/ghaction-helper/package.json index fa94e43b04..68a24ab98f 100644 --- a/libs/ghaction-helper/package.json +++ b/libs/ghaction-helper/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/ghaction-helper", - "version": "0.1.30", + "version": "0.1.31", "description": "Solidity Tests GitHub Action Helper", "main": "src/index.js", "scripts": { @@ -19,17 +19,17 @@ }, "homepage": "https://github.com/ethereum/remix-project#readme", "devDependencies": { - "@remix-project/remix-solidity": "^0.5.36", + "@remix-project/remix-solidity": "^0.5.37", "@types/chai": "^4.3.4", "typescript": "^4.9.3" }, "dependencies": { "@ethereum-waffle/chai": "^3.4.4", - "@remix-project/remix-simulator": "^0.2.50", + "@remix-project/remix-simulator": "^0.2.51", "chai": "^4.3.7", "ethers": "^5.7.2", "web3": "^4.1.1" }, "types": "./src/index.d.ts", - "gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986" + "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f" } \ No newline at end of file diff --git a/libs/remix-analyzer/package.json b/libs/remix-analyzer/package.json index 3721bcdf2d..463ad2ac0f 100644 --- a/libs/remix-analyzer/package.json +++ b/libs/remix-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-analyzer", - "version": "0.5.59", + "version": "0.5.60", "description": "Tool to perform static analysis on Solidity smart contracts", "scripts": { "test": "./../../node_modules/.bin/ts-node --project ../../tsconfig.base.json --require tsconfig-paths/register ./../../node_modules/.bin/tape ./test/tests.ts" @@ -25,8 +25,8 @@ "@ethereumjs/tx": "5.3.0", "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", - "@remix-project/remix-astwalker": "^0.0.80", - "@remix-project/remix-lib": "^0.5.57", + "@remix-project/remix-astwalker": "^0.0.81", + "@remix-project/remix-lib": "^0.5.58", "async": "^2.6.2", "ethers": "^5.4.2", "ethjs-util": "^0.1.6", @@ -50,6 +50,6 @@ "typescript": "^3.7.5" }, "typings": "src/index.d.ts", - "gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986", + "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f", "main": "./src/index.js" } \ No newline at end of file diff --git a/libs/remix-astwalker/package.json b/libs/remix-astwalker/package.json index 2dd6fa1daf..865b18d586 100644 --- a/libs/remix-astwalker/package.json +++ b/libs/remix-astwalker/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-astwalker", - "version": "0.0.80", + "version": "0.0.81", "description": "Tool to walk through Solidity AST", "main": "src/index.js", "scripts": { @@ -37,7 +37,7 @@ "@ethereumjs/tx": "5.3.0", "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", - "@remix-project/remix-lib": "^0.5.57", + "@remix-project/remix-lib": "^0.5.58", "@types/tape": "^4.2.33", "async": "^2.6.2", "ethers": "^5.4.2", @@ -53,6 +53,6 @@ "tap-spec": "^5.0.0" }, "typings": "src/index.d.ts", - "gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986", + "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f", "types": "./src/index.d.ts" } \ No newline at end of file diff --git a/libs/remix-debug/package.json b/libs/remix-debug/package.json index 2a18fa3f39..cc6a015eec 100644 --- a/libs/remix-debug/package.json +++ b/libs/remix-debug/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-debug", - "version": "0.5.50", + "version": "0.5.51", "description": "Tool to debug Ethereum transactions", "contributors": [ { @@ -26,10 +26,10 @@ "@ethereumjs/tx": "5.3.0", "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", - "@remix-project/remix-astwalker": "^0.0.80", - "@remix-project/remix-lib": "^0.5.57", - "@remix-project/remix-simulator": "^0.2.50", - "@remix-project/remix-solidity": "^0.5.36", + "@remix-project/remix-astwalker": "^0.0.81", + "@remix-project/remix-lib": "^0.5.58", + "@remix-project/remix-simulator": "^0.2.51", + "@remix-project/remix-solidity": "^0.5.37", "ansi-gray": "^0.1.1", "async": "^2.6.2", "color-support": "^1.1.3", @@ -69,6 +69,6 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-debug#readme", "typings": "src/index.d.ts", - "gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986", + "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f", "types": "./src/index.d.ts" } \ No newline at end of file diff --git a/libs/remix-lib/package.json b/libs/remix-lib/package.json index e4a5bc6a3f..98f680a8c5 100644 --- a/libs/remix-lib/package.json +++ b/libs/remix-lib/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-lib", - "version": "0.5.57", + "version": "0.5.58", "description": "Library to various Remix tools", "contributors": [ { @@ -55,6 +55,6 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme", "typings": "src/index.d.ts", - "gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986", + "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f", "types": "./src/index.d.ts" } \ No newline at end of file diff --git a/libs/remix-simulator/package.json b/libs/remix-simulator/package.json index 830630fc53..218e5d139f 100644 --- a/libs/remix-simulator/package.json +++ b/libs/remix-simulator/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-simulator", - "version": "0.2.50", + "version": "0.2.51", "description": "Ethereum IDE and tools for the web", "contributors": [ { @@ -22,7 +22,7 @@ "@ethereumjs/tx": "5.3.0", "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", - "@remix-project/remix-lib": "^0.5.57", + "@remix-project/remix-lib": "^0.5.58", "ansi-gray": "^0.1.1", "async": "^3.1.0", "body-parser": "^1.18.2", @@ -70,6 +70,6 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-simulator#readme", "typings": "src/index.d.ts", - "gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986", + "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f", "types": "./src/index.d.ts" } \ No newline at end of file diff --git a/libs/remix-solidity/package.json b/libs/remix-solidity/package.json index 262df35233..2bcc8c96aa 100644 --- a/libs/remix-solidity/package.json +++ b/libs/remix-solidity/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-solidity", - "version": "0.5.36", + "version": "0.5.37", "description": "Tool to load and run Solidity compiler", "main": "src/index.js", "types": "src/index.d.ts", @@ -19,7 +19,7 @@ "@ethereumjs/tx": "5.3.0", "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", - "@remix-project/remix-lib": "^0.5.57", + "@remix-project/remix-lib": "^0.5.58", "async": "^2.6.2", "eslint-scope": "^5.0.0", "ethers": "^5.4.2", @@ -57,5 +57,5 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme", "typings": "src/index.d.ts", - "gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986" + "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f" } \ No newline at end of file diff --git a/libs/remix-tests/package.json b/libs/remix-tests/package.json index 6a66b91c18..81d56885a5 100644 --- a/libs/remix-tests/package.json +++ b/libs/remix-tests/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-tests", - "version": "0.2.50", + "version": "0.2.51", "description": "Tool to test Solidity smart contracts", "main": "src/index.js", "types": "./src/index.d.ts", @@ -41,9 +41,9 @@ "@ethereumjs/tx": "5.3.0", "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", - "@remix-project/remix-lib": "^0.5.57", - "@remix-project/remix-simulator": "^0.2.50", - "@remix-project/remix-solidity": "^0.5.36", + "@remix-project/remix-lib": "^0.5.58", + "@remix-project/remix-simulator": "^0.2.51", + "@remix-project/remix-solidity": "^0.5.37", "@remix-project/remix-url-resolver": "^0.0.42", "ansi-gray": "^0.1.1", "async": "^2.6.0", @@ -89,5 +89,5 @@ "@ethereumjs/trie": "6.2.0" }, "typings": "src/index.d.ts", - "gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986" + "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f" } \ No newline at end of file diff --git a/libs/remix-url-resolver/package.json b/libs/remix-url-resolver/package.json index 45827abc31..98ec48c64b 100644 --- a/libs/remix-url-resolver/package.json +++ b/libs/remix-url-resolver/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-url-resolver", - "version": "0.0.79", + "version": "0.0.80", "description": "Solidity import url resolver engine", "main": "src/index.js", "types": "src/index.d.ts", @@ -41,5 +41,5 @@ "typescript": "^3.1.6" }, "typings": "src/index.d.ts", - "gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986" + "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f" } \ No newline at end of file diff --git a/libs/remix-ws-templates/package.json b/libs/remix-ws-templates/package.json index d17478da57..d5220d8596 100644 --- a/libs/remix-ws-templates/package.json +++ b/libs/remix-ws-templates/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-ws-templates", - "version": "1.0.44", + "version": "1.0.45", "description": "Create a Remix IDE workspace using different templates", "main": "src/index.js", "types": "src/index.d.ts", @@ -24,5 +24,5 @@ "ethers": "^5.4.2", "web3": "^4.1.1" }, - "gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986" + "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f" } \ No newline at end of file diff --git a/libs/remixd/package.json b/libs/remixd/package.json index d0153806c8..57635186db 100644 --- a/libs/remixd/package.json +++ b/libs/remixd/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remixd", - "version": "0.6.33", + "version": "0.6.34", "description": "remix server: allow accessing file system from remix.ethereum.org and start a dev environment (see help section)", "main": "index.js", "types": "./index.d.ts", @@ -27,11 +27,11 @@ }, "homepage": "https://github.com/ethereum/remix-project#readme", "dependencies": { + "@remix-project/remix-solidity": "^0.5.36", "@remixproject/plugin": "0.3.33", "@remixproject/plugin-api": "0.3.33", "@remixproject/plugin-utils": "0.3.33", "@remixproject/plugin-ws": "0.3.33", - "@remix-project/remix-solidity": "^0.5.36", "axios": "1.6.0", "chokidar": "^2.1.8", "commander": "^9.4.1", From 660acdec5a8edf6b171ae6526c8719e7b57dfd5b Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Fri, 28 Jun 2024 19:13:32 +0530 Subject: [PATCH 28/40] add dep and re publish --- libs/ghaction-helper/package.json | 8 ++++---- libs/remix-analyzer/package.json | 8 ++++---- libs/remix-astwalker/package.json | 6 +++--- libs/remix-debug/package.json | 12 ++++++------ libs/remix-lib/package.json | 4 ++-- libs/remix-simulator/package.json | 7 ++++--- libs/remix-solidity/package.json | 6 +++--- libs/remix-tests/package.json | 10 +++++----- libs/remix-url-resolver/package.json | 4 ++-- libs/remix-ws-templates/package.json | 4 ++-- 10 files changed, 35 insertions(+), 34 deletions(-) diff --git a/libs/ghaction-helper/package.json b/libs/ghaction-helper/package.json index 68a24ab98f..2290c89071 100644 --- a/libs/ghaction-helper/package.json +++ b/libs/ghaction-helper/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/ghaction-helper", - "version": "0.1.31", + "version": "0.1.32", "description": "Solidity Tests GitHub Action Helper", "main": "src/index.js", "scripts": { @@ -19,17 +19,17 @@ }, "homepage": "https://github.com/ethereum/remix-project#readme", "devDependencies": { - "@remix-project/remix-solidity": "^0.5.37", + "@remix-project/remix-solidity": "^0.5.38", "@types/chai": "^4.3.4", "typescript": "^4.9.3" }, "dependencies": { "@ethereum-waffle/chai": "^3.4.4", - "@remix-project/remix-simulator": "^0.2.51", + "@remix-project/remix-simulator": "^0.2.52", "chai": "^4.3.7", "ethers": "^5.7.2", "web3": "^4.1.1" }, "types": "./src/index.d.ts", - "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f" + "gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55" } \ No newline at end of file diff --git a/libs/remix-analyzer/package.json b/libs/remix-analyzer/package.json index 463ad2ac0f..6550d471ce 100644 --- a/libs/remix-analyzer/package.json +++ b/libs/remix-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-analyzer", - "version": "0.5.60", + "version": "0.5.61", "description": "Tool to perform static analysis on Solidity smart contracts", "scripts": { "test": "./../../node_modules/.bin/ts-node --project ../../tsconfig.base.json --require tsconfig-paths/register ./../../node_modules/.bin/tape ./test/tests.ts" @@ -25,8 +25,8 @@ "@ethereumjs/tx": "5.3.0", "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", - "@remix-project/remix-astwalker": "^0.0.81", - "@remix-project/remix-lib": "^0.5.58", + "@remix-project/remix-astwalker": "^0.0.82", + "@remix-project/remix-lib": "^0.5.59", "async": "^2.6.2", "ethers": "^5.4.2", "ethjs-util": "^0.1.6", @@ -50,6 +50,6 @@ "typescript": "^3.7.5" }, "typings": "src/index.d.ts", - "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f", + "gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55", "main": "./src/index.js" } \ No newline at end of file diff --git a/libs/remix-astwalker/package.json b/libs/remix-astwalker/package.json index 865b18d586..a6a82f6cac 100644 --- a/libs/remix-astwalker/package.json +++ b/libs/remix-astwalker/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-astwalker", - "version": "0.0.81", + "version": "0.0.82", "description": "Tool to walk through Solidity AST", "main": "src/index.js", "scripts": { @@ -37,7 +37,7 @@ "@ethereumjs/tx": "5.3.0", "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", - "@remix-project/remix-lib": "^0.5.58", + "@remix-project/remix-lib": "^0.5.59", "@types/tape": "^4.2.33", "async": "^2.6.2", "ethers": "^5.4.2", @@ -53,6 +53,6 @@ "tap-spec": "^5.0.0" }, "typings": "src/index.d.ts", - "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f", + "gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55", "types": "./src/index.d.ts" } \ No newline at end of file diff --git a/libs/remix-debug/package.json b/libs/remix-debug/package.json index cc6a015eec..72b01e0e9c 100644 --- a/libs/remix-debug/package.json +++ b/libs/remix-debug/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-debug", - "version": "0.5.51", + "version": "0.5.52", "description": "Tool to debug Ethereum transactions", "contributors": [ { @@ -26,10 +26,10 @@ "@ethereumjs/tx": "5.3.0", "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", - "@remix-project/remix-astwalker": "^0.0.81", - "@remix-project/remix-lib": "^0.5.58", - "@remix-project/remix-simulator": "^0.2.51", - "@remix-project/remix-solidity": "^0.5.37", + "@remix-project/remix-astwalker": "^0.0.82", + "@remix-project/remix-lib": "^0.5.59", + "@remix-project/remix-simulator": "^0.2.52", + "@remix-project/remix-solidity": "^0.5.38", "ansi-gray": "^0.1.1", "async": "^2.6.2", "color-support": "^1.1.3", @@ -69,6 +69,6 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-debug#readme", "typings": "src/index.d.ts", - "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f", + "gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55", "types": "./src/index.d.ts" } \ No newline at end of file diff --git a/libs/remix-lib/package.json b/libs/remix-lib/package.json index 98f680a8c5..fac86e3732 100644 --- a/libs/remix-lib/package.json +++ b/libs/remix-lib/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-lib", - "version": "0.5.58", + "version": "0.5.59", "description": "Library to various Remix tools", "contributors": [ { @@ -55,6 +55,6 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme", "typings": "src/index.d.ts", - "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f", + "gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55", "types": "./src/index.d.ts" } \ No newline at end of file diff --git a/libs/remix-simulator/package.json b/libs/remix-simulator/package.json index 218e5d139f..8a9a1a0bbc 100644 --- a/libs/remix-simulator/package.json +++ b/libs/remix-simulator/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-simulator", - "version": "0.2.51", + "version": "0.2.52", "description": "Ethereum IDE and tools for the web", "contributors": [ { @@ -22,7 +22,8 @@ "@ethereumjs/tx": "5.3.0", "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", - "@remix-project/remix-lib": "^0.5.58", + "@metamask/eth-sig-util": "^7.0.2", + "@remix-project/remix-lib": "^0.5.59", "ansi-gray": "^0.1.1", "async": "^3.1.0", "body-parser": "^1.18.2", @@ -70,6 +71,6 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-simulator#readme", "typings": "src/index.d.ts", - "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f", + "gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55", "types": "./src/index.d.ts" } \ No newline at end of file diff --git a/libs/remix-solidity/package.json b/libs/remix-solidity/package.json index 2bcc8c96aa..7a61d805e6 100644 --- a/libs/remix-solidity/package.json +++ b/libs/remix-solidity/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-solidity", - "version": "0.5.37", + "version": "0.5.38", "description": "Tool to load and run Solidity compiler", "main": "src/index.js", "types": "src/index.d.ts", @@ -19,7 +19,7 @@ "@ethereumjs/tx": "5.3.0", "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", - "@remix-project/remix-lib": "^0.5.58", + "@remix-project/remix-lib": "^0.5.59", "async": "^2.6.2", "eslint-scope": "^5.0.0", "ethers": "^5.4.2", @@ -57,5 +57,5 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme", "typings": "src/index.d.ts", - "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f" + "gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55" } \ No newline at end of file diff --git a/libs/remix-tests/package.json b/libs/remix-tests/package.json index 81d56885a5..f9db3aae99 100644 --- a/libs/remix-tests/package.json +++ b/libs/remix-tests/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-tests", - "version": "0.2.51", + "version": "0.2.52", "description": "Tool to test Solidity smart contracts", "main": "src/index.js", "types": "./src/index.d.ts", @@ -41,9 +41,9 @@ "@ethereumjs/tx": "5.3.0", "@ethereumjs/util": "9.0.3", "@ethereumjs/vm": "8.0.0", - "@remix-project/remix-lib": "^0.5.58", - "@remix-project/remix-simulator": "^0.2.51", - "@remix-project/remix-solidity": "^0.5.37", + "@remix-project/remix-lib": "^0.5.59", + "@remix-project/remix-simulator": "^0.2.52", + "@remix-project/remix-solidity": "^0.5.38", "@remix-project/remix-url-resolver": "^0.0.42", "ansi-gray": "^0.1.1", "async": "^2.6.0", @@ -89,5 +89,5 @@ "@ethereumjs/trie": "6.2.0" }, "typings": "src/index.d.ts", - "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f" + "gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55" } \ No newline at end of file diff --git a/libs/remix-url-resolver/package.json b/libs/remix-url-resolver/package.json index 98ec48c64b..3f90eb236b 100644 --- a/libs/remix-url-resolver/package.json +++ b/libs/remix-url-resolver/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-url-resolver", - "version": "0.0.80", + "version": "0.0.81", "description": "Solidity import url resolver engine", "main": "src/index.js", "types": "src/index.d.ts", @@ -41,5 +41,5 @@ "typescript": "^3.1.6" }, "typings": "src/index.d.ts", - "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f" + "gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55" } \ No newline at end of file diff --git a/libs/remix-ws-templates/package.json b/libs/remix-ws-templates/package.json index d5220d8596..f897a2d623 100644 --- a/libs/remix-ws-templates/package.json +++ b/libs/remix-ws-templates/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-ws-templates", - "version": "1.0.45", + "version": "1.0.46", "description": "Create a Remix IDE workspace using different templates", "main": "src/index.js", "types": "src/index.d.ts", @@ -24,5 +24,5 @@ "ethers": "^5.4.2", "web3": "^4.1.1" }, - "gitHead": "b8afcf838b114094f5202aef5b8092e83a98ee2f" + "gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55" } \ No newline at end of file From 2147e6716a4b348c5f711be8e88baa3ba833f29a Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 1 Jul 2024 08:17:41 +0200 Subject: [PATCH 29/40] fix workspace --- libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 0d048c0e44..534bd07481 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -1382,7 +1382,7 @@ export function Workspace() { className="btn btn-sm btn-light d-inline-block border border-dark form-control h-100 p-0 pl-2 pr-2 text-dark" icon={null} > - {global.fs.browser.isRequestingCloning ? : currentBranch.name || '-none-'} + {global.fs.browser.isRequestingCloning ? : (currentBranch && currentBranch.name) || '-none-'}
    @@ -1421,8 +1421,8 @@ export function Workspace() { }} title={intl.formatMessage({ id: `filePanel.switchToBranch${branch.remote ? 'Title1' : 'Title2'}` })} > -
    - {currentBranch.name === branch.name && !branch.remote ? ( +
    + {currentBranch && currentBranch.name === branch.name && !branch.remote ? ( {branch.name} @@ -1430,7 +1430,7 @@ export function Workspace() { ) : ( - {branch.remote ? `${branch.remote}/${branch.name}` : branch.name} + {branch.remote ? `${branch.remote.name}/${branch.name}` : branch.name} )}
    @@ -1442,7 +1442,7 @@ export function Workspace() {
    - : {branchFilter} from '{currentBranch.name}' + : {branchFilter} from '{currentBranch && currentBranch.name}'
    From 206882e11ac8f7be9eebd43035b0ddf7478c6ced Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Mon, 1 Jul 2024 11:27:37 +0530 Subject: [PATCH 30/40] bump dev version --- .github/workflows/pr-reminder.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-reminder.yml b/.github/workflows/pr-reminder.yml index 315cc5b5ad..de3e43802a 100644 --- a/.github/workflows/pr-reminder.yml +++ b/.github/workflows/pr-reminder.yml @@ -14,4 +14,4 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} - freeze-date: '2024-06-17T18:00:00Z' + freeze-date: '2024-07-15T18:00:00Z' diff --git a/package.json b/package.json index e49a728d3c..bf44266318 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "remix-project", - "version": "0.51.0-dev", + "version": "0.52.0-dev", "license": "MIT", "description": "Ethereum Remix Monorepo", "main": "index.js", From e0566c2e358ad9628576496c8b17f87bea74f8ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 02:16:18 +0000 Subject: [PATCH 31/40] Bump ws from 7.5.5 to 7.5.10 Bumps [ws](https://github.com/websockets/ws) from 7.5.5 to 7.5.10. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/7.5.5...7.5.10) --- updated-dependencies: - dependency-name: ws dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- yarn.lock | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/yarn.lock b/yarn.lock index c5ea40bc83..5f806e83b0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -30190,7 +30190,7 @@ ws@7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== -ws@8.13.0, ws@^8.8.1: +ws@8.13.0: version "8.13.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== @@ -30200,10 +30200,10 @@ ws@8.5.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== -ws@>=8.7.0: - version "8.8.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" - integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== +ws@>=8.7.0, ws@^8.13.0, ws@^8.4.2, ws@^8.8.1: + version "8.16.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" + integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== ws@^1.1.1: version "1.1.5" @@ -30213,25 +30213,10 @@ ws@^1.1.1: options ">=0.0.5" ultron "1.0.x" -ws@^7.3.0, ws@^7.5.0: - version "7.5.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" - integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== - -ws@^7.3.1, ws@^7.4.6, ws@^7.5.1: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== - -ws@^8.13.0: - version "8.16.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" - integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== - -ws@^8.4.2: - version "8.9.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.9.0.tgz#2a994bb67144be1b53fe2d23c53c028adeb7f45e" - integrity sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg== +ws@^7.3.0, ws@^7.3.1, ws@^7.4.6, ws@^7.5.0, ws@^7.5.1: + version "7.5.10" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== xdg-basedir@^3.0.0: version "3.0.0" From 9876466f1eedf151ac82896ce255338b322f5cff Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Tue, 2 Jul 2024 08:24:38 +0200 Subject: [PATCH 32/40] resolve issues --- .../git/src/components/github/branchselect.tsx | 13 +++++++------ .../git/src/components/github/devicecode.tsx | 4 ---- .../src/components/navigation/branchedetails.tsx | 2 +- libs/remix-ui/git/src/components/panels/clone.tsx | 1 - 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/libs/remix-ui/git/src/components/github/branchselect.tsx b/libs/remix-ui/git/src/components/github/branchselect.tsx index a90d259369..e272f266f9 100644 --- a/libs/remix-ui/git/src/components/github/branchselect.tsx +++ b/libs/remix-ui/git/src/components/github/branchselect.tsx @@ -5,7 +5,7 @@ import { selectStyles, selectTheme } from '../../types/styles'; import { gitPluginContext } from '../gitui'; interface BranchySelectProps { - select: (branch:{ name: string }) => void; + select: (branch: { name: string }) => void; } export const BranchSelect = (props: BranchySelectProps) => { @@ -15,10 +15,11 @@ export const BranchSelect = (props: BranchySelectProps) => { useEffect(() => { if (context.remoteBranches && context.remoteBranches.length > 0) { - const options = context.remoteBranches && context.remoteBranches.length > 0 && context.remoteBranches.map(branch => { - return { value: branch.name, label: branch.name } - } - ) + const options = context.remoteBranches + && context.remoteBranches.length > 0 + && context.remoteBranches.map(branch => { + return { value: branch.name, label: branch.name } + }) setBranchOptions(options) } else { setBranchOptions(null) @@ -39,7 +40,7 @@ export const BranchSelect = (props: BranchySelectProps) => { options={branchOptions} className="mt-1" id="branch-select" - onChange={(e: any) =>selectRemoteBranch(e)} + onChange={(e: any) => selectRemoteBranch(e)} theme={selectTheme} styles={selectStyles} isClearable={true} diff --git a/libs/remix-ui/git/src/components/github/devicecode.tsx b/libs/remix-ui/git/src/components/github/devicecode.tsx index 65233b6bc4..cd611efe4d 100644 --- a/libs/remix-ui/git/src/components/github/devicecode.tsx +++ b/libs/remix-ui/git/src/components/github/devicecode.tsx @@ -54,10 +54,6 @@ export const GetDeviceCode = () => { // convert response to json const response = await accestokenresponse.data; - if (response.error) { - - } - if (response.access_token) { setAuthorized(true) await pluginActions.saveToken(response.access_token) diff --git a/libs/remix-ui/git/src/components/navigation/branchedetails.tsx b/libs/remix-ui/git/src/components/navigation/branchedetails.tsx index 2fe9218d7d..ee3ee88e24 100644 --- a/libs/remix-ui/git/src/components/navigation/branchedetails.tsx +++ b/libs/remix-ui/git/src/components/navigation/branchedetails.tsx @@ -52,7 +52,7 @@ export const BrancheDetailsNavigation = (props: BrancheDetailsNavigationProps) = singleBranch: true, relative: true }) - //actions.fetch(null, branch.name, null, null, false, true) + } return ( diff --git a/libs/remix-ui/git/src/components/panels/clone.tsx b/libs/remix-ui/git/src/components/panels/clone.tsx index fedd6dfa4a..e72cf984af 100644 --- a/libs/remix-ui/git/src/components/panels/clone.tsx +++ b/libs/remix-ui/git/src/components/panels/clone.tsx @@ -38,7 +38,6 @@ export const Clone = () => { depth: cloneDepth, singleBranch: !cloneAllBranches }) - //await actions.clone(cloneUrl, cloneBranch, cloneDepth, !cloneAllBranches) } const onCloneBranchChange = (value: string) => { From 0e0f9f3cea80996513158d13a9f209f1114a9874 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Tue, 2 Jul 2024 08:59:03 +0200 Subject: [PATCH 33/40] limit desktop to 'desktop' branches --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c8be5e0d7a..d5a065c41d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -499,7 +499,7 @@ workflows: - build-desktop: filters: branches: - only: ['master', /.*desktop.*/] + only: [/.*desktop.*/] - build-remixdesktop-mac: requires: - build-desktop From 1a1e2da8ea026e369dddeb2094647f38bf402b64 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Wed, 3 Jul 2024 08:23:44 +0200 Subject: [PATCH 34/40] fix plugin api & statusbar --- apps/remix-ide/src/app/components/status-bar.tsx | 5 +++-- libs/remix-api/src/lib/plugins/filePanel-api.ts | 12 ++++++++++++ libs/remix-api/src/lib/plugins/fileSystem-api.ts | 2 +- libs/remix-api/src/lib/plugins/settings-api.ts | 2 ++ libs/remix-api/src/lib/remix-api.ts | 3 +++ .../statusbar/src/lib/components/gitStatus.tsx | 4 ++-- .../workspace/src/lib/remix-ui-workspace.tsx | 2 +- 7 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 libs/remix-api/src/lib/plugins/filePanel-api.ts diff --git a/apps/remix-ide/src/app/components/status-bar.tsx b/apps/remix-ide/src/app/components/status-bar.tsx index 088e0b4da1..c264fdd434 100644 --- a/apps/remix-ide/src/app/components/status-bar.tsx +++ b/apps/remix-ide/src/app/components/status-bar.tsx @@ -7,6 +7,7 @@ import { PluginProfile, StatusBarInterface } from '../../types' import { RemixUIStatusBar } from '@remix-ui/statusbar' import { FilePanelType } from '@remix-ui/workspace' import { VerticalIcons } from './vertical-icons' +import { CustomRemixApi } from '@remix-api' const statusBarProfile: PluginProfile = { name: 'statusBar', @@ -16,7 +17,7 @@ const statusBarProfile: PluginProfile = { version: packageJson.version, } -export class StatusBar extends Plugin implements StatusBarInterface { +export class StatusBar extends Plugin implements StatusBarInterface { htmlElement: HTMLDivElement events: EventEmitter filePanelPlugin: FilePanelType @@ -75,7 +76,7 @@ export class StatusBar extends Plugin implements StatusBarInterface { const workspaceName = localStorage.getItem('currentWorkspace') workspaceName && workspaceName.length > 0 ? this.currentWorkspaceName = workspaceName : this.currentWorkspaceName = 'error' }) - this.on('settings', 'copilotChoiceChanged', (isAiActive) => { + this.on('settings', 'copilotChoiceChanged', (isAiActive: boolean) => { this.isAiActive = isAiActive }) this.renderComponent() diff --git a/libs/remix-api/src/lib/plugins/filePanel-api.ts b/libs/remix-api/src/lib/plugins/filePanel-api.ts new file mode 100644 index 0000000000..02255c26ba --- /dev/null +++ b/libs/remix-api/src/lib/plugins/filePanel-api.ts @@ -0,0 +1,12 @@ +import { IFilePanel } from '@remixproject/plugin-api' +import { StatusEvents } from '@remixproject/plugin-utils' + +export interface IFilePanelApi { + events: IFilePanel['events'] & { + workspaceInitializationCompleted: () => void; + switchToWorkspace: (workspace: string) => Promise; + } & StatusEvents + methods: IFilePanel['methods'] & { + + } +} diff --git a/libs/remix-api/src/lib/plugins/fileSystem-api.ts b/libs/remix-api/src/lib/plugins/fileSystem-api.ts index 04d0a2a0af..cba69f007e 100644 --- a/libs/remix-api/src/lib/plugins/fileSystem-api.ts +++ b/libs/remix-api/src/lib/plugins/fileSystem-api.ts @@ -4,7 +4,7 @@ import { IFileSystem } from "@remixproject/plugin-api" // Extended interface with 'diff' method export interface IExtendedFileSystem extends IFileSystem { methods: IFileSystem['methods'] & { - /** Compare the differences between two files */ diff(change: commitChange): Promise + isGitRepo(): Promise }; } \ No newline at end of file diff --git a/libs/remix-api/src/lib/plugins/settings-api.ts b/libs/remix-api/src/lib/plugins/settings-api.ts index dd7323ac73..a9251b3f78 100644 --- a/libs/remix-api/src/lib/plugins/settings-api.ts +++ b/libs/remix-api/src/lib/plugins/settings-api.ts @@ -3,6 +3,8 @@ import { StatusEvents } from '@remixproject/plugin-utils' export interface ISettings { events: { configChanged: () => void, + copilotChoiceUpdated: (isChecked: boolean) => void, + copilotChoiceChanged: (isChecked: boolean) => void, } & StatusEvents methods: { getGithubAccessToken(): string diff --git a/libs/remix-api/src/lib/remix-api.ts b/libs/remix-api/src/lib/remix-api.ts index 8469d9e057..2dff94abdc 100644 --- a/libs/remix-api/src/lib/remix-api.ts +++ b/libs/remix-api/src/lib/remix-api.ts @@ -6,6 +6,8 @@ import { IFileDecoratorApi } from "./plugins/filedecorator-api" import { IExtendedFileSystem } from "./plugins/fileSystem-api" import { INotificationApi } from "./plugins/notification-api" import { ISettings } from "./plugins/settings-api" +import { IFilePanelApi } from "./plugins/filePanel-api" +import { Plugin } from "@remixproject/engine" export interface ICustomRemixApi extends IRemixApi { dgitApi: IGitApi @@ -14,6 +16,7 @@ export interface ICustomRemixApi extends IRemixApi { settings: ISettings fileDecorator: IFileDecoratorApi fileManager: IExtendedFileSystem + filePanel: IFilePanelApi } export declare type CustomRemixApi = Readonly \ No newline at end of file diff --git a/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx b/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx index 07c299c132..68201b7c9f 100644 --- a/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx +++ b/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx @@ -32,7 +32,7 @@ export default function GitStatus({ plugin, gitBranchName, setGitBranchName }: G setGitBranchName('Not a git repo') } }) - plugin.on('dGitProvider', 'init', async () => { + plugin.on('dgitApi', 'init', async () => { const isGit = await plugin.call('fileManager', 'isGitRepo') if (isGit) { const workspace = localStorage.getItem('currentWorkspace') @@ -52,7 +52,7 @@ export default function GitStatus({ plugin, gitBranchName, setGitBranchName }: G } const initializeNewGitRepo = async () => { - await plugin.call('dGitProvider', 'init') + await plugin.call('dgitApi', 'init') const isActive = await plugin.call('manager', 'isActive', 'dgit') if (isLocalHost === false) { if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 534bd07481..03d807808a 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -257,7 +257,7 @@ export function Workspace() { } } - global.plugin.on('dGitProvider', 'repositoryWithSubmodulesCloned', () => { + global.plugin.on('dgitApi', 'repositoryWithSubmodulesCloned', () => { setHighlightUpdateSubmodules(true) }) }, []) From 82b5baa420986b71535f833971599dbe7e4453b0 Mon Sep 17 00:00:00 2001 From: lianahus Date: Wed, 3 Jul 2024 10:22:48 +0200 Subject: [PATCH 35/40] updated the colors of black theme to fix the status bar colors --- apps/remix-ide/src/assets/css/themes/remix-black_undtds.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/remix-ide/src/assets/css/themes/remix-black_undtds.css b/apps/remix-ide/src/assets/css/themes/remix-black_undtds.css index 75d64e2ed1..990598205f 100644 --- a/apps/remix-ide/src/assets/css/themes/remix-black_undtds.css +++ b/apps/remix-ide/src/assets/css/themes/remix-black_undtds.css @@ -11,10 +11,10 @@ --green: #1ea171; --teal: #20c997; --cyan: #053c64; - --white: #d5d5d5; + --white: #ececec; --gray: #868e96; --gray-dark: #343a40; - --primary: #b5b4bc; + --primary: #717171; --secondary: #3d3e44; --success: #6bceaa; --info: #086CB5; @@ -241,7 +241,7 @@ textarea { font-size: inherit; line-height: inherit; background-color: #2b2b2b; - color: #d5d5d5d5d5d5; + color: #d5d5d5; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 0 2px rgba(79, 86, 89, 0.25); } button, From 35af3b6431ffb420da9a5bd06b0171dc1a768189 Mon Sep 17 00:00:00 2001 From: lianahus Date: Wed, 3 Jul 2024 10:35:13 +0200 Subject: [PATCH 36/40] color fixes in status bar --- apps/remix-ide/src/assets/css/themes/remix-black_undtds.css | 4 ++-- libs/remix-ui/statusbar/src/css/statusbar.css | 2 +- libs/remix-ui/statusbar/src/lib/remixui-statusbar-panel.tsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide/src/assets/css/themes/remix-black_undtds.css b/apps/remix-ide/src/assets/css/themes/remix-black_undtds.css index 990598205f..a55010caa0 100644 --- a/apps/remix-ide/src/assets/css/themes/remix-black_undtds.css +++ b/apps/remix-ide/src/assets/css/themes/remix-black_undtds.css @@ -11,10 +11,10 @@ --green: #1ea171; --teal: #20c997; --cyan: #053c64; - --white: #ececec; + --white: #d5d5d5; --gray: #868e96; --gray-dark: #343a40; - --primary: #717171; + --primary: #b5b4bc; --secondary: #3d3e44; --success: #6bceaa; --info: #086CB5; diff --git a/libs/remix-ui/statusbar/src/css/statusbar.css b/libs/remix-ui/statusbar/src/css/statusbar.css index 5d2f461026..a66bd945e1 100644 --- a/libs/remix-ui/statusbar/src/css/statusbar.css +++ b/libs/remix-ui/statusbar/src/css/statusbar.css @@ -18,7 +18,7 @@ * approximately same height with vscode statusbar **/ .remixui_statusbar_height { - height: 21px; + height: 1.6rem; } .remixui_statusbar_activelink { diff --git a/libs/remix-ui/statusbar/src/lib/remixui-statusbar-panel.tsx b/libs/remix-ui/statusbar/src/lib/remixui-statusbar-panel.tsx index 77e8f3cc50..679a5e0b65 100644 --- a/libs/remix-ui/statusbar/src/lib/remixui-statusbar-panel.tsx +++ b/libs/remix-ui/statusbar/src/lib/remixui-statusbar-panel.tsx @@ -71,7 +71,7 @@ export function RemixUIStatusBar({ statusBarPlugin }: RemixUIStatusBarProps) { )} -
    +
    From fff0d4d61009bbd8c117426f453acb95fee8bf39 Mon Sep 17 00:00:00 2001 From: lianahus Date: Wed, 3 Jul 2024 10:45:34 +0200 Subject: [PATCH 37/40] status bar hierarchy change --- .../assets/css/themes/remix-dark_tvx1s2.css | 2 +- .../app/src/lib/remix-app/remix-app.tsx | 76 ++++++++++--------- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css b/apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css index 84f61e9658..8db3e60b5e 100644 --- a/apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css +++ b/apps/remix-ide/src/assets/css/themes/remix-dark_tvx1s2.css @@ -5663,7 +5663,7 @@ button.bg-success:hover { background-color: #27926b !important; } .bg-info { - background-color: #274458 !important; + background-color: #35576e !important; } a.bg-info:focus, a.bg-info:hover, diff --git a/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx b/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx index aa1cc69fc6..192f8411b7 100644 --- a/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx @@ -179,45 +179,47 @@ const RemixApp = (props: IRemixAppUi) => { setShowEnterDialog(true)}> {showEnterDialog && handleUserChosenType(type)}>}
    -
    - {props.app.menuicons.render()} -
    -
    - {props.app.sidePanel.render()} -
    - -
    - -
    -
    - {props.app.pinnedPanel.render()} -
    - { - !hidePinnedPanel && +
    +
    + {props.app.menuicons.render()} +
    +
    + {props.app.sidePanel.render()} +
    - } -
    {props.app.hiddenPanel.render()}
    +
    + +
    +
    + {props.app.pinnedPanel.render()} +
    + { + !hidePinnedPanel && + + } +
    {props.app.hiddenPanel.render()}
    +
    {props.app.statusBar.render()}
    From 34b899c477d73a2cd29e4d510939a6756c72c9dc Mon Sep 17 00:00:00 2001 From: lianahus Date: Wed, 3 Jul 2024 11:01:24 +0200 Subject: [PATCH 38/40] fixing e2e --- libs/remix-ui/app/src/lib/remix-app/remix-app.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx b/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx index 192f8411b7..ab0d2b951c 100644 --- a/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx @@ -178,8 +178,8 @@ const RemixApp = (props: IRemixAppUi) => { setShowEnterDialog(true)}> {showEnterDialog && handleUserChosenType(type)}>} -
    -
    +
    +
    {props.app.menuicons.render()}
    From a490079f1e50ce983b57ea8957d2aef1e5d2c9a5 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Fri, 5 Jul 2024 12:51:33 +0200 Subject: [PATCH 39/40] fix hasgitsubmodules call --- apps/remix-ide/src/app/files/fileManager.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/remix-ide/src/app/files/fileManager.ts b/apps/remix-ide/src/app/files/fileManager.ts index c9f1c1d93d..e232c2a132 100644 --- a/apps/remix-ide/src/app/files/fileManager.ts +++ b/apps/remix-ide/src/app/files/fileManager.ts @@ -25,7 +25,8 @@ const profile = { methods: ['closeAllFiles', 'closeFile', 'file', 'exists', 'open', 'writeFile', 'writeMultipleFiles', 'writeFileNoRewrite', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'dirList', 'fileList', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath', - 'saveCurrentFile', 'setBatchFiles', 'isGitRepo', 'isFile', 'isDirectory', 'hasGitSubmodule', 'copyFolderToJson', 'diff' + 'saveCurrentFile', 'setBatchFiles', 'isGitRepo', 'isFile', 'isDirectory', 'hasGitSubmodule', 'copyFolderToJson', 'diff', + 'hasGitSubmodules' ], kind: 'file-system' } From 2289172f6813dec341c816139c68fda863650e74 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Fri, 5 Jul 2024 08:23:50 +0200 Subject: [PATCH 40/40] add matomo plugin --- apps/remix-ide/src/app.js | 10 +++++++-- apps/remix-ide/src/app/plugins/matomo.ts | 26 ++++++++++++++++++++++++ apps/remix-ide/src/remixAppManager.js | 3 ++- 3 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 apps/remix-ide/src/app/plugins/matomo.ts diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index b59568e70b..3e0eacdeb0 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -56,6 +56,7 @@ import { xtermPlugin } from './app/plugins/electron/xtermPlugin' import { ripgrepPlugin } from './app/plugins/electron/ripgrepPlugin' import { compilerLoaderPlugin, compilerLoaderPluginDesktop } from './app/plugins/electron/compilerLoaderPlugin' import { GitPlugin } from './app/plugins/git' +import { Matomo } from './app/plugins/matomo' import {SolCoder} from './app/plugins/solcoderAI' @@ -223,6 +224,9 @@ class AppComponent { //---- git const git = new GitPlugin() + //---- matomo + const matomo = new Matomo() + //---------------- Solidity UML Generator ------------------------- const solidityumlgen = new SolidityUmlGen(appManager) @@ -357,7 +361,8 @@ class AppComponent { templates, solcoder, git, - pluginStateLogger + pluginStateLogger, + matomo ]) //---- fs plugin @@ -476,7 +481,8 @@ class AppComponent { 'network', 'web3Provider', 'offsetToLineColumnConverter', - 'pluginStateLogger' + 'pluginStateLogger', + 'matomo' ]) await this.appManager.activatePlugin(['mainPanel', 'menuicons', 'tabs']) await this.appManager.activatePlugin(['statusBar']) diff --git a/apps/remix-ide/src/app/plugins/matomo.ts b/apps/remix-ide/src/app/plugins/matomo.ts new file mode 100644 index 0000000000..9495d1ddd7 --- /dev/null +++ b/apps/remix-ide/src/app/plugins/matomo.ts @@ -0,0 +1,26 @@ +'use strict' +import { Plugin } from '@remixproject/engine' + +const _paq = window._paq = window._paq || [] + +const profile = { + name: 'matomo', + description: 'send analytics to Matomo', + methods: ['track'], + events: [''], + version: '1.0.0' +} + +const allowedPlugins = ['LearnEth', 'etherscan', 'vyper', 'circuit-compiler', 'doc-gen', 'doc-viewer', 'solhint', 'walletconnect', 'scriptRunner'] + +export class Matomo extends Plugin { + + constructor() { + super(profile) + } + + async track(data: string[]) { + if (!allowedPlugins.includes(this.currentRequest.from)) return + _paq.push(data) + } +} \ No newline at end of file diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index d430d678d7..20b69d984f 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -81,7 +81,8 @@ let requiredModules = [ // services + layout views + system views 'dgit', 'pinnedPanel', 'pluginStateLogger', - 'remixGuide' + 'remixGuide', + 'matomo' ]